Fortran 95 的两体问题

计算科学 正则 牛顿法
2021-12-20 08:53:51

我正在尝试使用 Fortran 95 来实现 N 体问题。在将其推广到 N 体之前,我首先尝试计算单个轨道体(下面我的代码中的体 2)围绕一个固定体(体 1 在下面的代码)。问题是输出不正确,但我的方程式找不到错误!这就是我想要实现的:

V2,xV2,xG×M1×(x2x1)r3×dt

V2,yV2,yG×M1×(y2y1)r3×dt

x2x2+V2,x×dt

y2y2+V2,y×dt

这是我的代码:

program gravitation
implicit none

integer :: k, total
real, dimension(2) :: M, x, y, Vx, Vy
real, parameter :: G = 6.6738E-11, pi = 3.1415926
real :: time, dt, r

dt = 1000. ! dt = 1000 seconds
total = 5000 ! total number of points to be output 

M(1)=1.9891E+09 ! Sun's mass
x(1)=0.
y(1)=0.
Vx(1)=0.
Vy(1)=0.

M(2)=5.9736E+03 ! Earth's mass
x(2)=1.4960E+11 ! Earth's average orbit as initial point
y(2)=0.
Vx(2)=0.
Vy(2)=2.9786E+04 ! Earth's average orbital speed

open(unit=101,file="a.txt")
write(101,*) "time, x, y"
write(101,"(E10.4,2(A1,1x,E10.4))") 0., ",", x(2), ",", y(2)

do k=1,total
  r = sqrt( (x(2)-x(1))**2 + (y(2)-y(1))**2 )
  Vx(2) = Vx(2) - G * M(1) * dt * (x(2)-x(1)) / r**3 ! i.e., Vx2 = Vx2 - G.M.dt.(x2-x1)/r^3
  Vy(2) = Vy(2) - G * M(1) * dt * (y(2)-y(1)) / r**3
    x(2) = x(2) + Vx(2) * dt
    y(2) = y(2) + Vy(2) * dt
  write(101,"(E10.4,2(A1,1x,E10.4))") k*dt, ",", x(2), ",", y(2)
enddo

end program gravitation

输出文件显示第二个body的x位置完全没有变化(卡在初始值0.1496E+12),而y位置发生了变化。

有谁看到这里有什么问题?非常感谢。

1个回答

上面代码的唯一问题是群众的价值观。通过简单地将两个天体的质量校正到适当的值,模拟运行得很好。下面,我添加了更正的代码(仍然使用 SI 中的所有单位,即 kg、m、秒);但正如一位用户之前评论过的那样 (TomDickens),这种程序的最佳方法可能是使用天文单位,例如 AU 表示距离,年份表示时间和G×Msun=1关于群众。

program gravitation
implicit none

integer :: k, total
real(8), dimension(2) :: M, x, y, Vx, Vy
real(8), parameter :: G = 6.6738D-11
real(8) :: time, dt, r

dt = 3600. ! dt = 3600 = 1h
total = 10000 ! total number of points to be output 

M(1)=1.9891D+30 ! Sun's mass
x(1)=0.
y(1)=0.
Vx(1)=0.
Vy(1)=0.

M(2)=5.9736D+24 ! Earth's mass
x(2)=1.4960D+11 ! Earth's average orbit as initial point
y(2)=0.
Vx(2)=0.
Vy(2)=2.9786D+04 ! Earth's average orbital speed

open(unit=101,file="2-body_output.txt")
write(101,*) "time, x, y" ! CSV file header
write(101,*) 0., ",", x(2), ",", y(2) ! initial position

do k=1,total
  r = sqrt( ( x(2) - x(1) )**2 + ( y(2) - y(1) )**2 ) ! distance between object 1 and 2
  Vx(2) = Vx(2) - G * M(1) * dt * ( x(2) - x(1) ) / r**3 ! i.e., Vx2 = Vx2 - G.M.dt.(x2-x1)/r^3
  Vy(2) = Vy(2) - G * M(1) * dt * ( y(2) - y(1) ) / r**3
  x(2) = x(2) + Vx(2) * dt ! calculating new x position
  y(2) = y(2) + Vy(2) * dt
  time = k * dt
  write(101,*) time, ",", x(2), ",", y(2)
enddo

end program gravitation