mirror of
https://codeberg.org/Yael-II/MSc2-Project-Chaos.git
synced 2026-03-15 04:16:26 +01:00
165 lines
5.0 KiB
Python
165 lines
5.0 KiB
Python
#!/usr/bin/env python
|
|
"""
|
|
Initial Conditions
|
|
|
|
Generate initial conditions depending on different criteria
|
|
|
|
@ Author: Moussouni, Yaël (MSc student) & Bhat, Junaid Ramzan (MSc student)
|
|
@ Institution: Université de Strasbourg, CNRS, Observatoire astronomique
|
|
de Strasbourg, UMR 7550, F-67000 Strasbourg, France
|
|
@ Date: 2025-01-01
|
|
|
|
Licence:
|
|
Order and Chaos in a 2D potential
|
|
Copyright (C) 2025 Yaël Moussouni (yael.moussouni@etu.unistra.fr)
|
|
Bhat, Junaid Ramzan (junaid-ramzan.bhat@etu.unistra.fr)
|
|
|
|
initial_conditions.py
|
|
Copyright (C) 2025 Yaël Moussouni (yael.moussouni@etu.unistra.fr)
|
|
Bhat, Junaid Ramzan (junaid-ramzan.bhat@etu.unistra.fr)
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see https://www.gnu.org/licenses/.
|
|
"""
|
|
|
|
import numpy as np
|
|
import matplotlib.pyplot as plt
|
|
POS_MIN = -1
|
|
POS_MAX = +1
|
|
VEL_MIN = -1
|
|
VEL_MAX = +1
|
|
N_PART = 1
|
|
|
|
def mesh_grid(N: int = N_PART,
|
|
xmin: float = POS_MIN,
|
|
xmax: float = POS_MAX,
|
|
ymin: float = POS_MIN,
|
|
ymax: float = POS_MAX) -> np.ndarray:
|
|
"""Generates a set of regularly sampled particles with no velocity
|
|
@ params:
|
|
- N: number of particles
|
|
- xmin: minimum value for position x
|
|
- xmax: maximum value for position x
|
|
- ymin: minimum value for position y
|
|
- ymax: maximum value for position y
|
|
@ returns:
|
|
- W: phase-space vector
|
|
"""
|
|
X = np.linspace(xmin, xmax, N)
|
|
Y = np.linspace(ymin, ymax, N)
|
|
X,Y = np.meshgrid(X,Y, indexing="ij")
|
|
return np.array([X,Y])
|
|
|
|
def one_part(x0: float = 0,
|
|
y0: float = 0,
|
|
u0: float= 0,
|
|
v0: float = 0) -> np.ndarray:
|
|
"""Generates a particle at position (x0, y0)
|
|
with velocities (u0,v0)
|
|
@ params:
|
|
- N: number of particles
|
|
- x0: initial position x
|
|
- y0: initial position y
|
|
- u0: initial velocity u
|
|
- v0: initial velocity v
|
|
@ returns:
|
|
- W: phase-space vector
|
|
"""
|
|
X = x0
|
|
Y = y0
|
|
U = u0
|
|
V = v0
|
|
return np.array([[X,Y], [U,V]])
|
|
|
|
def n_energy_part(potential,
|
|
N: int = N_PART,
|
|
E: float = 0,
|
|
xmin: float = -1,
|
|
xmax: float = +1,
|
|
ymin: float = -0.5,
|
|
ymax: float = +1):
|
|
"""Generates N particles with an energy E in a potential.
|
|
@ params:
|
|
- potential: gravitational potential
|
|
- N: number of particles
|
|
- E: total energy
|
|
- xmin: minimum value for position x
|
|
- xmax: maximum value for position x
|
|
- ymin: minimum value for position y
|
|
- ymax: maximum value for position y
|
|
@ returns:
|
|
- W: an array of all the positions and velocities.
|
|
"""
|
|
X = []
|
|
Y = []
|
|
POT = []
|
|
U = []
|
|
V = []
|
|
while len(X) < N:
|
|
x = np.random.random()*(xmax-xmin)+xmin
|
|
y = np.random.random()*(ymax-ymin)+ymin
|
|
w = np.array([x, y])
|
|
pot = potential(w, position_only=True)[0]
|
|
if pot <= E:
|
|
X.append(x)
|
|
Y.append(y)
|
|
POT.append(pot)
|
|
X = np.array(X)
|
|
Y = np.array(Y)
|
|
POT = np.array(POT)
|
|
U = np.zeros_like(X)
|
|
V = np.zeros_like(Y)
|
|
C = np.sqrt(2 * (E - POT))
|
|
THETA = np.random.random(N)*2*np.pi
|
|
U = C*np.cos(THETA)
|
|
V = C*np.sin(THETA)
|
|
return np.array([[X, Y], [U, V]])
|
|
|
|
def n_energy_2part(potential,
|
|
N: int = N_PART,
|
|
E: float = 0,
|
|
sep: float = 1e-7,
|
|
xmin: float = -1,
|
|
xmax: float = +1,
|
|
ymin: float = -0.5,
|
|
ymax: float = +1):
|
|
"""Generate a sample of 2N particles with the energy E in a potential in
|
|
two sets: one "normal" set (see n_energy_part), and a slightly shifted set
|
|
with a separation sep.
|
|
@ params:
|
|
- potential: gravitational potential
|
|
- N: number of particles
|
|
- E: total energy
|
|
- sep: the separation between the two sets
|
|
- xmin: minimum value for position x
|
|
- xmax: maximum value for position x
|
|
- ymin: minimum value for position y
|
|
- ymax: maximum value for position y
|
|
@ returns:
|
|
- (W1, W2): the two arrays of all the positions and velocities for
|
|
each set.
|
|
"""
|
|
W_1 = n_energy_part(potential, N, E)
|
|
W_2 = np.zeros_like(W_1)
|
|
alpha = np.random.uniform(0, 2*np.pi, N)
|
|
W_2[0, 0] = W_1[0, 0] + sep*np.cos(alpha)
|
|
W_2[0, 1] = W_1[0, 1] + sep*np.sin(alpha)
|
|
W_2[1, 0] = W_1[1, 0]
|
|
W_2[1, 1] = W_1[1, 1]
|
|
return (W_1, W_2)
|
|
|
|
|
|
|
|
|
|
|