Duffing 방정식에 대한 간단한 한계 사이클을 성공적으로 보여주는 프로그램을 작성했습니다. 그러나 이제는이 경우 Poincaré 섹션을 그려야합니다.푸앵카레 단면도 그리기 방법? (Duffing Oscillator)
t*omega = 2*pi*n
과 같은 일정한 시간 간격으로 위상 공간 다이어그램의 스냅 샷을 찍어서이 작업을 수행해야합니다. 이 경우에 오메가가 1로 설정되어 있기 때문에 이것은 단지 t = 2*pi*n
일 때입니다. 나는 이것을 시도했지만 Poincaré 섹션을 기대하지는 않습니다.
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
일상에서

프로그램에 들여 쓰기를 사용하십시오. 읽을 시간이 매우 어렵습니다. 그래서, 대신에 당신은 무엇을 기대합니까? 음모는 무엇을 보여줍니까? 어떤 변수? 올바른 때 어떻게 보이게해야합니까? –
서브 루틴 rk2에서 k2y는 dydt와 동일한 인수를 가져야하며 k2z는 dzdt와 같아야합니다. 함수 dzdt에서 + B * y가 아닌 -B * y를 가져야합니다. 그러나 rk2를 다시 써서 y (1) = 이전 y와 y (2) = 이전 z와 같이 벡터 인수 y를 취해야합니다. 그런 다음 벡터를 반환하는 함수 dydt가 하나뿐입니다. 이렇게하면 코딩이 더 간단 해지고 위에서 언급 한 첫 번째 오류는 피할 수 있습니다. – user5713492
@VladimirF 감사합니다. 지금 질문을 편집했습니다. – timetabedlidalot