微分方程式の数値解析 #9
太陽を周回する地球の運動について見てみる。
解くべき運動方程式は時刻tでの軌道面における地球の直交座標を(x(t),y(t))として、
である。太陽は原点から動かないものとする。GMは万有引力定数と太陽質量の積である。
program ode use runge_kutta_4 implicit none double precision, parameter :: gm = 9.9069307177135d8 ! prod of gravitational constant and sun mass [(10^4km)^3/day^2] double precision, parameter :: t0 = 0 ! initial t double precision, parameter :: x0(4) = (/1.49597871d4, 0d0, 0d0, 2.572992d2/) ! (x0, y0, vx0, vy0) double precision :: t double precision :: x(4) double precision, parameter :: udiv = 1 ! division unit integer, parameter :: ndiv = 4 ! number of divisions per udiv double precision, parameter :: h = udiv / ndiv ! delta-t integer, parameter :: niter = 366 / udiv * ndiv ! number of iterations integer, parameter :: pdiv = ndiv ! print interval integer :: n type (func_type), dimension(4) :: fns fns(1)%f => f1 fns(2)%f => f2 fns(3)%f => f3 fns(4)%f => f4 call set_func(fns) x = x0 do n = 0, niter t = t0 + n * h if (mod(n, pdiv) == 0) print '(5F13.5)', t, x(1), x(2), x(3), x(4) x = next(t, x, h) end do contains double precision function f1(t, x) double precision, intent(in) :: t double precision, dimension(:), intent(in) :: x f1 = x(3) end function f1 double precision function f2(t, x) double precision, intent(in) :: t double precision, dimension(:), intent(in) :: x f2 = x(4) end function f2 double precision function f3(t, x) double precision, intent(in) :: t double precision, dimension(:), intent(in) :: x f3 = -gm * x(1) * (X(1) ** 2 + X(2) ** 2) ** (-1.5) end function f3 double precision function f4(t, x) double precision, intent(in) :: t double precision, dimension(:), intent(in) :: x f4 = -gm * x(2) * (X(1) ** 2 + X(2) ** 2) ** (-1.5) end function f4 end program ode
結果は、経過時間/day、軌道面でのX座標/10^4km、Y座標/10^4km、X方向の速度/(10^4km/day)、Y方向の速度/(10^4km/day)で、
0.00000 14959.78710 0.00000 0.00000 257.29920 1.00000 14957.57376 257.28651 -4.42657 257.26113 2.00000 14950.93441 514.49689 -8.85182 257.14694 ...snip 364.00000 14957.18459 -278.98864 4.79995 257.25444 365.00000 14959.77135 -21.70561 0.37344 257.29893 366.00000 14957.93144 235.58384 -4.05318 257.26728
であり、刻み幅0.25dayとあまり細かくないにも関わらず365日強で公転する様が再現される。
刻み幅1dayでも以下のようになる。
...snip 364.00000 14957.18459 -278.98843 4.79994 257.25444 365.00000 14959.77134 -21.70540 0.37344 257.29893 366.00000 14957.93143 235.58405 -4.05318 257.26728
刻み幅を1e-3dayにした結果を以下に示す。
...snip 364.00000 14957.18459 -278.98864 4.79995 257.25444 365.00000 14959.77135 -21.70561 0.37344 257.29893 366.00000 14957.93144 235.58384 -4.05318 257.26728
ここまで細かくしなくてもいいことが分かる。