6 double precision ::
tiny
11 subroutine odeint(ystart,nvar,x1,x2,eps,h1,hmin,nok,nbad,derivs,rkqs,ierror)
14 double precision eps,h1,hmin,x1,x2,ystart(nvar)
16 double precision h,hdid,hnext,x,xsav,dydx(NMAX),y(NMAX),yscal(NMAX)
18 double precision dxsav, yp(NMAX,KMAXX), xp(KMAXX)
20 integer,
intent(out) :: ierror
24 COMMON /path/ kmax,kount,dxsav,xp,yp
37 if (kmax.gt.0) xsav=x-2.d0*dxsav
42 yscal(i)=abs(y(i))+abs(h*dydx(i))+
tiny
46 if(abs(x-xsav).gt.abs(dxsav))
then
47 if(kount.lt.kmax-1)
then
58 if((x+h-x2)*(x+h-x1).gt.0.d0) h=x2-x
60 if (any(y(1:nvar) .ne. y(1:nvar)) .or. any(dydx(1:nvar) .ne. dydx(1:nvar)) .or. x .ne. x)
then
61 write(*,*)
"ODEINT BEFORE CALL RKQS: NaN in x, dydx, or y!"
64 write(*,*)
"dydx",dydx
65 write(*,*)
"exiting..."
70 call rkqs(y,dydx,nvar,x,h,eps,yscal,hdid,hnext,derivs)
72 if (any(y(1:nvar) .ne. y(1:nvar)) .or. any(dydx(1:nvar) .ne. dydx(1:nvar)) .or. x .ne. x)
then
73 write(*,*)
"ODEINT AFTER CALL RKQS: NaN in x, dydx, or y!"
76 write(*,*)
"dydx",dydx
77 write(*,*)
"exiting..."
88 if((x-x2)*(x2-x1).ge.0.d0)
then
104 if(abs(hnext).lt.hmin)
then
114 SUBROUTINE rkqs(y,dydx,n,x,htry,eps,yscal,hdid,hnext,derivs)
117 double precision eps,hdid,hnext,htry,x,dydx(n),y(n),yscal(n)
122 double precision errmax,h,xnew,yerr(NMAX),ytemp(NMAX),SAFETY,PGROW,PSHRNK,ERRCON
123 parameter(safety=0.9d0,pgrow=-.2d0,pshrnk=-.25d0,errcon=1.89d-4)
127 if (any(y(1:n) .ne. y(1:n)) .or. any(dydx(1:n) .ne. dydx(1:n)) .or. x .ne. x)
then
128 write(*,*)
"RKQS BEFORE CALL RKCK: NaN in x, dydx, or y!"
131 write(*,*)
"dydx",dydx
132 write(*,*)
"exiting..."
136 1
call rkck(y,dydx,n,x,h,ytemp,yerr,derivs)
137 if (any(y(1:n) .ne. y(1:n)) .or. any(dydx(1:n) .ne. dydx(1:n)) .or. x .ne. x)
then
138 write(*,*)
"RKQS AFTER CALL RKCK: NaN in x, dydx, or y!"
141 write(*,*)
"dydx",dydx
142 write(*,*)
"exiting..."
148 errmax=max(errmax,abs(yerr(i)/yscal(i)))
151 if(errmax.gt.1.d0)
then
152 h=safety*h*(errmax**pshrnk)
157 if(xnew.eq.x)
call stop(
'stepsize underflow in rkqs')
160 if(errmax.gt.errcon)
then
161 hnext=safety*h*(errmax**pgrow)
175 SUBROUTINE rkck(y,dydx,n,x,h,yout,yerr,derivs)
178 double precision h,x,dydx(n),y(n),yerr(n),yout(n)
183 double precision ak2(NMAX),ak3(NMAX),ak4(NMAX),ak5(NMAX),ak6(NMAX),ytemp(NMAX),A2,A3,A4,A5,A6,B21,B31,B32,B41,B42,B43,B51, &
185 B54,B61,B62,B63,B64,B65,C1,C3,C4,C6,DC1,DC3,DC4,DC5,DC6
186 parameter(a2=.2d0,a3=.3d0,a4=.6d0,a5=1.d0, &
187 a6=.875d0,b21=.2d0,b31=3.d0/40.d0,&
188 b32=9.d0/40.d0,b41=.3d0,b42=-.9d0,b43=1.2d0,&
189 b51=-11.d0/54.d0,b52=2.5d0,&
190 b53=-70.d0/27.d0,b54=35.d0/27.d0,b61=1631.d0/55296.d0, &
192 b63=575.d0/13824.d0,b64=44275.d0/110592.d0, &
193 b65=253.d0/4096.d0,c1=37.d0/378.d0,&
194 c3=250.d0/621.d0,c4=125.d0/594.d0,c6=512.d0/1771.d0,&
195 dc1=c1-2825.d0/27648.d0,&
196 dc3=c3-18575.d0/48384.d0,dc4=c4-13525.d0/55296.d0,&
197 dc5=-277.d0/14336.d0,&
199 if (any(y(1:n) .ne. y(1:n)) .or. any(dydx(1:n) .ne. dydx(1:n)))
then
200 write(*,*)
"NaNs IN RKCK, STEP 0!"
201 write(*,*)
"y0",y(1:n)
202 write(*,*)
"derivs",dydx(1:n)
203 write(*,*)
"ABORTING..."
207 ytemp(i)=y(i)+b21*h*dydx(i)
209 call derivs(x+a2*h,ytemp,ak2)
210 if (any(ytemp(1:n) .ne. ytemp(1:n)) .or. any(ak2(1:n) .ne. ak2(1:n)))
then
211 write(*,*)
"NaNs IN RKCK, STEP 1!"
212 write(*,*)
"y1",ytemp(1:n)
213 write(*,*)
"derivs",ak2(1:n)
214 write(*,*)
"ABORTING..."
218 ytemp(i)=y(i)+h*(b31*dydx(i)+b32*ak2(i))
220 call derivs(x+a3*h,ytemp,ak3)
221 if (any(ytemp(1:n) .ne. ytemp(1:n)) .or. any(ak3(1:n) .ne. ak3(1:n)))
then
222 write(*,*)
"NaNs IN RKCK, STEP 2!"
223 write(*,*)
"y2",ytemp(1:n)
224 write(*,*)
"derivs",ak3(1:n)
225 write(*,*)
"ABORTING..."
229 ytemp(i)=y(i)+h*(b41*dydx(i)+b42*ak2(i)+b43*ak3(i))
231 call derivs(x+a4*h,ytemp,ak4)
232 if (any(ytemp(1:n) .ne. ytemp(1:n)) .or. any(ak4(1:n) .ne. ak4(1:n)))
then
233 write(*,*)
"NaNs IN RKCK, STEP 3!"
234 write(*,*)
"y3",ytemp(1:n)
235 write(*,*)
"derivs",ak4(1:n)
236 write(*,*)
"ABORTING..."
240 ytemp(i)=y(i)+h*(b51*dydx(i)+b52*ak2(i)+b53*ak3(i)+b54*ak4(i))
242 call derivs(x+a5*h,ytemp,ak5)
243 if (any(ytemp(1:n) .ne. ytemp(1:n)) .or. any(ak5(1:n) .ne. ak5(1:n)))
then
244 write(*,*)
"NaNs IN RKCK, STEP 4!"
245 write(*,*)
"y4",ytemp(1:n)
246 write(*,*)
"derivs",ak5(1:n)
247 write(*,*)
"ABORTING..."
251 ytemp(i)=y(i)+h*(b61*dydx(i)+b62*ak2(i)+b63*ak3(i)+b64*ak4(i)+b65*ak5(i))
253 call derivs(x+a6*h,ytemp,ak6)
254 if (any(ytemp(1:n) .ne. ytemp(1:n)) .or. any(ak6(1:n) .ne. ak6(1:n)))
then
255 write(*,*)
"NaNs IN RKCK, STEP 1!"
256 write(*,*)
"y15",ytemp(1:n)
257 write(*,*)
"derivs",ak6(1:n)
258 write(*,*)
"ABORTING..."
262 yout(i)=y(i)+h*(c1*dydx(i)+c3*ak3(i)+c4*ak4(i)+c6*ak6(i))
265 yerr(i)=h*(dc1*dydx(i)+dc3*ak3(i)+dc4*ak4(i)+dc5*ak5(i)+dc6*ak6(i))
271 character(len=*),
intent(in) :: text
subroutine mpistop(message)
Exit MPI-AMRVAC with an error message.
This module packages odeint from numerical recipes.
subroutine odeint(ystart, nvar, x1, x2, eps, h1, hmin, nok, nbad, derivs, rkqs, ierror)
subroutine rkqs(y, dydx, n, x, htry, eps, yscal, hdid, hnext, derivs)
subroutine rkck(y, dydx, n, x, h, yout, yerr, derivs)