Duffing方程式の単純なリミットサイクルを成功裏に示すプログラムを作成しました。しかし、私は今、このケースのためにポアンカレのセクションをプロットする必要があります。ポアンカレ区をプロットする方法は? (Duffing Oscillator)
フェーズスペースダイアグラムのスナップショットを一定の時間間隔(例えば、t*omega = 2*pi*n
)で取得することで、これを行う必要があります。この場合、オメガが1に設定されているので、これはちょうどt = 2*pi*n
のときです。私はこれを試みましたが、私が期待しているポアンカレセクションを得ていません。
はここに私のコードです:
program rungekutta
implicit none
integer, parameter :: dp = selected_real_kind(15,300)
integer :: i, n
real(kind=dp) z, y, t, A, C, D, B, omega, h
open(unit=100, file="rungekutta.dat",status='replace')
n = 0
!constants
omega = 1.0_dp
A = 0.25_dp
B = 1.0_dp
C = 0.1_dp
D = 1.0_dp
y = 0.0_dp
z = 0.0_dp
t = 0.0_dp
do i=1,1000
call rk2(z, y, t, n)
n = n + 1.0_dp
write(100,*) y, z
end do
contains
subroutine rk2(z, y, t, n) !subroutine to implement runge-kutta algorithm
implicit none
integer, parameter :: dp = selected_real_kind(15,300)
integer, intent(inout) :: n
real(kind=dp) :: k1y, k1z, k2y, k2z, y, z, t, pi
pi = 4.0*ATAN(1.0)
h = 0.1_dp
t = n*2*pi
k1y = dydt(y,z,t)*h
k1z = dzdt(y,z,t)*h
k2z = dzdt(y + (0.5_dp*k1y), z + (0.5_dp*k1z), t + (0.5_dp*h))*h
k2y = dydt(y, z +(0.5_dp*k1z), t)*h
y = y + k2y
z = z + k2z
end subroutine
!2nd order ODE split into 2 for coupled Runge-Kutta, useful to define 2
functions
function dzdt(y,z,t)
real(kind=dp) :: y, z, t, dzdt
dzdt = -A*y**3.0_dp + B*y - C*z + D*sin(omega*t)
end function
function dydt(y,z,t)
real(kind=dp) :: z, dydt, y, t
dydt = z
end function
end program
私も自分のポアンカレ断面がどのように見えるかの画像を添付しています。
これはx軸とy軸のyです。
あなたのプログラムではインデントを使用してください。読むのはとても難しいです。では、代わりに何を期待していますか?プロットは何を示していますか?どの変数?正しい時はどのように見えるでしょうか? –
サブルーチンrk2では、k2yはdydtと同じ引数を持ち、k2zはdzdtと同じでなければなりません。関数dzdtでは、+ B * yではなく-B * yを指定する必要があります。しかし、y(1)=前のyとy(2)=前のzのベクトル引数yを取るにはrk2を書き直すべきです。あなたはベクトルを返す関数dydtを1つだけ持っています。これにより、コーディングが簡単になり、上記の最初のエラーが回避されます。 – user5713492
@VladimirFありがとう、私は今質問を編集しました。 – timetabedlidalot