n-body problem#
pour faire cette activité sur votre ordi localement, commencez par télécharger le zip
dans ce TP on vous invite à écrire un simulateur de la trajectoire de n corps qui interagissent entre eux au travers de leur poids, pour produire des sorties de ce genre
on suppose:
on se place dans un monde en 2 dimensions
on fixe au départ le nombre de corps N
chacun est décrit par une masse constante
et au début du monde chacun possède une position et une vitesse
imports#
importer les librairies qui vont bien pour cet exercice; on utilisera le mode ipympl de matplotlib
# à vous
initialisation#
en fixant arbitrairement des limites dans l’espace des positions, des vitesses et des masses, on tire au hasard une configuration de départ pour la simulation
# les bornes pour le tirage au sort initial
mass_max = 3.
x_min, x_max = -10., 10.
y_min, y_max = -10., 10.
speed_max = 1.
# votre code
def init_problem(n):
"""
retourne un tuple masses, positions, speeds
"""
return None, None, None
# pour tester
# normalement vous devez pouvoir faire ceci
masses, positions, speeds = init_problem(10)
# et ceci devrait afficker OK
try:
masses.shape == (10,) and positions.shape == speeds.shape == (2, 10)
print("OK")
except:
print("KO")
KO
les forces#
à présent, on va écrire un fonction qui va calculer les influences de toutes les particules entre elles, suivant la loi de Newton
pour cela on se propose d’écrire la fonction suivante
# votre code
def forces(positions, masses, G=1.0):
"""
returns an array of shape (2, N)
that contains the force felt by each mass from all the others
G is the Newton constant and by default is set to 1
(we have abstract units anyway)
"""
pass
le simulateur#
à présent il nous reste à utiliser cette brique de base pour “faire avancer” le modèle depuis son état initial et sur un nombre fixe d’itérations
cela pourrait se passer dans une fonction qui ressemblerait à ceci
# votre code
def simulate(masses, positions, speeds, dt=0.1, nb_steps=100):
"""
should return the positions across time
so an array of shape (nb_steps, N, 2)
optional dt is the time step
"""
pass
dessiner#
ne reste plus qu’à dessiner
# votre code
def draw(simulation, colors=None):
"""
takes as input the result of simulate() above,
and draws the nb_steps positions of each of the N bodies
ideally it should return a matplotlib Axes object
one can provide a collection of N colors to use for each body
if not provided this is randomized
"""
pass
putting it all together#
on se met dans un état initial reproductible - surtout pour que vous puissiez facilement votre code
import numpy as np
def init3():
# N = 3
# the first element is heavy, at the center, and has no speed
masses = np.array([3, 1, 1], dtype=float)
positions = np.array([[0, 5, -5],[0, 1, -1]], dtype=float)
speeds = np.array([[0, -1, 1],[0, 0, 0]], dtype=float)
return masses, positions, speeds
# décommentez ceci pour tester votre code
# masses, positions, speeds = init3()
# s = simulate(masses, positions, speeds)
# print(f"{s.shape=}")
# draw(s);
et avec ces données vous devriez obtenir plus ou moins une sortie de ce genre