Simulation du mouvement des planètes sous l'effet de la gravité

Fermé
Omega InForce - Modifié par Omega InForce le 25/03/2015 à 07:17
 Utilisateur anonyme - 25 mars 2015 à 08:30
Bonjour.


J'ai voulu essayer de faire un programme qui simule le mouvement de planètes sous l'effet de la gravitation. Voici mon programme:



n=5;
mass=1;
speed=0;
scale=3000;
distance=1;
time=200;
p=0.001;
G=1;

x=distance*(2*rand(1,n)-1);
y=distance*(2*rand(1,n)-1);
m=mass*rand(1,n);
vx=speed*(2*rand(1,n)-1);
vy=speed*(2*rand(1,n)-1);
fx=zeros(1,n);
fy=zeros(1,n);

for t=1:time

for a=1:n

for b=1:n

if b~=a

fx(a)=0;
fy(a)=0;

fx(a)=(G*m(b)/((y(b)-y(a))^2+(x(b)-x(a))^2))*((x(b)-x(a))/sqrt((x(b)-x(a))^2+(y(b)-y(a))^2));
fy(a)=(G*m(b)/((y(b)-y(a))^2+(x(b)-x(a))^2))*((y(b)-y(a))/sqrt((x(b)-x(a))^2+(y(b)-y(a))^2));

vx(a)=vx(a)+fx(a);
vy(a)=vy(a)+fy(a);

x(a)=x(a)+vx(a);
y(a)=y(a)+vy(a);

end

end

plot(x(a),y(a),'o')
xlim([-scale,scale])
ylim([-scale,scale])
hold on

end

pause(p)
hold off

end


Le début ce sont juste des paramètres qu'on peut ajuster. Le paramètre 'n' c'est le nombre de corps présent dans la simulation. 'p' est le temps de pause en secondes entre deux graphiques. 'G' est la valeur de la constante de gravitation. 'fx' c'est la force selon l'axe x, 'fy' la force selon l'axe y. 'vx' c'est la vitesse selon l'axe x, 'vy' la vitesse selon l'axe y. 'x' c'est la position selon l'axe x, 'y' la position selon l'axe y. La position initiale, la vitesse initiale et la masse initiale de chacun des corps est prise au hasard.


Après je compte mettre des valeurs proches de la réalité: G = 6,67 . 10^(-11) qui est la véritable valeur de la constante de gravitation, distance = 10^11 qui est un ordre de grandeur de distance typique dans le système solaire (en mètres), mass = 10^25 qui est un ordre de grandeur pour la masse des planètes (en kg), etc.


Mais le problème c'est que mon programme marche pas du tout: au lieu que les corps s'attire, ils se répulsent ! Mon programme simule de l'anti-gravité !...


Je comprends vraiment pas pourquoi. J'ai lu et re-lu mon programme pendant des heures et n'ai pas trouvé où sont les erreurs... Notez que je ne suis qu'un débutant en programmation, alors y'a peut-être juste quelque chose qui m'échappe.


Merci d'avance pour vos réponses.
A voir également:

1 réponse

Utilisateur anonyme
25 mars 2015 à 08:30
Bonjour

Je ne te réponds pas sur le plan de Matlab, que je ne connais pas, mais sur ta manière de faire les calculs.
Pour autant que je puisse en juger, les signes que tu as programmés sont corrects mais...
Tous les nombres que tu utilises au départ sont de l'ordre de l'unité. Comme les distances initiales sont aussi de l'ordre de l'unité, la plupart d'entre elles sont dès le départ à une distance inférieure à 1, d'où une accélération et un déplacement supérieurs à un. Donc tes planètes doivent plutôt jouer à saute-mouton l'une par-dessus l'autre. Et pour peu qu'elles aient été assez proches au départ, la vitesse initiale est si grande que la planète part à l'infini et que l'attraction des autres ne suffit pas à la ramener.
Simplifie le problème en ne prenant que deux corps, et en les éloignant suffisamment (disons 100) pour avoir le temps d'observer leur mouvement. Bien sûr, ça va être plus lent. Y a-t-il toujours répulsion ?

Par ailleurs, je pense que tes calculs peuvent être largement optimisés.
Avec tes deux boucles imbriquées, tu calcules successivement l'attraction de a sur b, puis celle de b sur a : tout en double. De plus, comme tu as déjà déplacé la planète a, tu ne trouves pas la même attraction dans l'autre sens : les lois de conservation de l'énergie vont en prendre un coup.

À mon humble avis, il vaudrait mieux calculer d'abord la totalité des forces, et ensuite les appliquer. Et pour calculer les efforts, imbriquer une boucle a:n à l'intérieur d'une boucle 1:n-1 pour éviter les calculs en double.
Ça donnerait quelque chose comme ça (méfie-toi, je n'ai jamais écrit un mot de Matlab de ma vie) :
n=5;
mass=1;
speed=0;
scale=3000;
distance=1;
time=200;
p=0.001;
G=1;

x=distance*(2*rand(1,n)-1);
y=distance*(2*rand(1,n)-1);
m=mass*rand(1,n);
vx=speed*(2*rand(1,n)-1);
vy=speed*(2*rand(1,n)-1);

for t=1:time

fx=zeros(1,n);
fy=zeros(1,n);

for a=1:n-1

for b=a:n

ffx=(G*m(b)/((y(b)-y(a))^2+(x(b)-x(a))^2))*((x(b)-x(a))/sqrt((x(b)-x(a))^2+(y(b)-y(a))^2));
ffy=(G*m(b)/((y(b)-y(a))^2+(x(b)-x(a))^2))*((y(b)-y(a))/sqrt((x(b)-x(a))^2+(y(b)-y(a))^2));
fx(a)=fx(a)+ffx
fy(a)=fy(a)+ffy
fx(b)=fx(b)-ffx
fy(b)=fy(b)-ffy

end
end
for a=1:n
vx(a)=vx(a)+fx(a)
vy(a)=vy(a)+fy(a)
x(a)=x(a)+vx(a)
y(a)=y(a)+vy(a)
plot(x(a),y(a),'o')
xlim([-scale,scale])
ylim([-scale,scale])
hold on

end

pause(p)
hold off

end
0