File: rgk4.f

package info (click to toggle)
scilab 2.6-4
  • links: PTS
  • area: non-free
  • in suites: woody
  • size: 54,632 kB
  • ctags: 40,267
  • sloc: ansic: 267,851; fortran: 166,549; sh: 10,005; makefile: 4,119; tcl: 1,070; cpp: 233; csh: 143; asm: 135; perl: 130; java: 39
file content (189 lines) | stat: -rw-r--r-- 5,434 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
c     extraits de numerical recipies 
c     runge kutta d'ordre 4 adaptatif 
c     l'interface lsrgk a ete fait en s'inspirant de lsode 
c     voir lsode.f pour comprendre le sens des variables 
C---------------------------------------------------------------------
      subroutine lsrgk (f, neq, y, t, tout, itol, rtol, atol, itask,
     1            istate, iopt, rwork, lrw, iwork, liw, jac, mf)
      external f, jac,rkqc
      integer neq, itol, itask, istate, iopt, lrw, iwork, liw, mf
      double precision y, t, tout, rtol, atol, rwork
      integer nok,nbad
      dimension neq(*), y(*), rtol(*), atol(*), rwork(lrw), iwork(liw)
      integer iero
      common/ierode/iero
      iero=0
      call odeint(y,neq,t,tout,atol(1),1.0d-4,0.0d0,nok,nbad,f,rkqc)
      t=tout
      if (iero.gt.0) istate=-1
      return
      end
C---------
C     subroutine de Num Recipies modifiee pour avoir le meme test 
C     d'arret que lsode
      subroutine odeint(ystart,nvar,x1,x2,eps,h1,hmin,nok,nbad,derivs,rk
     *qc)
C      implicit undefined (a-z)
      external derivs,rkqc
      integer maxstp,nmax,kmax,kount,nvar,i,nok,nbad,nstp
      double precision two,zero,tiny,dxsav,xp(200),yp(10,200),x,h
      parameter (maxstp=10000,nmax=10,two=2.0,zero=0.0,tiny=1.e-30)
      double precision x1,x2,eps,h1,hmin,xsav,hdid,hnext
      double precision ystart(nvar),yscal(nmax),y(nmax),dydx(nmax)
      character*80 messag
      common /path/ kmax,kount,dxsav,xp,yp
      integer iero
      common/ierode/iero
      iero=0
      if ( abs(x2-x1).le.tiny) return
      x=x1
      h=sign(h1,x2-x1)
      nok=0
      nbad=0
      kount=0
      do 11 i=1,nvar
        y(i)=ystart(i)
11    continue
      xsav=x-dxsav*two
      do 16 nstp=1,maxstp
        call derivs(nvar,x,y,dydx)
        if (iero.gt.0) return 
        do 12 i=1,nvar
          yscal(i)=abs(y(i))+abs(h*dydx(i))+tiny
12      continue
        if(kmax.gt.0)then
          if(abs(x-xsav).gt.abs(dxsav)) then
            if(kount.lt.kmax-1)then
              kount=kount+1
              xp(kount)=x
              do 13 i=1,nvar
                yp(i,kount)=y(i)
13            continue
              xsav=x
            endif
          endif
        endif
        if((x+h-x2)*(x+h-x1).gt.zero) h=x2-x
        call rkqc(y,dydx,nvar,x,h,eps,yscal,hdid,hnext,derivs)
        if(iero.gt.0) return
        if(hdid.eq.h)then
          nok=nok+1
        else
          nbad=nbad+1
        endif
        if((x-x2)*(x2-x1).ge.zero)then
          do 14 i=1,nvar
            ystart(i)=y(i)
14        continue
          if(kmax.ne.0)then
            kount=kount+1
            xp(kount)=x
            do 15 i=1,nvar
              yp(i,kount)=y(i)
15          continue
          endif
          return
        endif
        if(abs(hnext).lt.hmin) then
           write(messag, 17) hnext,hmin
           hnext=hmin
        endif
        h=hnext
16    continue
      iero=-1
c      print *, 'Trop d''iterations a faire pour la precision demandee.'
      return
 17   format('stepsize ',e10.3,' smaller than minimum ',e10.3)
      end

      subroutine rk4(y,dydx,n,x,h,yout,derivs)
C      implicit undefined (a-z)
      external derivs
      integer n,i,nmax
      parameter (nmax=10)
      double precision x,h,hh,xh,h6
      double precision y(n),dydx(n),yout(n),yt(nmax),dyt(nmax),dym(nmax)
      integer iero
      common/ierode/iero
      iero=0
      hh=h*0.5
      h6=h/6.
      xh=x+hh
      do 11 i=1,n
        yt(i)=y(i)+hh*dydx(i)
11    continue
      call derivs(n,xh,yt,dyt)
      if (iero.gt.0) return 
      do 12 i=1,n
        yt(i)=y(i)+hh*dyt(i)
12    continue
      call derivs(n,xh,yt,dym)
      if (iero.gt.0) return 
      do 13 i=1,n
        yt(i)=y(i)+h*dym(i)
        dym(i)=dyt(i)+dym(i)
13    continue
      call derivs(n,x+h,yt,dyt)
      if (iero.gt.0) return 
      do 14 i=1,n
        yout(i)=y(i)+h6*(dydx(i)+dyt(i)+2.*dym(i))
14    continue
      return
      end

      subroutine rkqc(y,dydx,n,x,htry,eps,yscal,hdid,hnext,derivs)
C      implicit undefined (a-z)
      integer nmax,n,i
      double precision fcor,one,safety,errcon
      parameter (nmax=10,fcor=.0666666667,
     $     one=1.0,safety=0.9,errcon=6.e-4)
      double precision x,htry,eps,hdid,hnext,pgrow,pshrnk,xsav,hh
      double precision errmax,h,dysav(nmax)
      double precision y(n),dydx(n),yscal(n),ytemp(nmax),ysav(nmax)
     
      external derivs
      integer iero
      common/ierode/iero
      iero=0
      pgrow=-0.20
      pshrnk=-0.25
      xsav=x
      do 11 i=1,n
        ysav(i)=y(i)
        dysav(i)=dydx(i)
11    continue
      h=htry
1     hh=0.5*h
      call rk4(ysav,dysav,n,xsav,hh,ytemp,derivs)
      x=xsav+hh
      call derivs(n,x,ytemp,dydx)
      if (iero.gt.0) return 
      call rk4(ytemp,dydx,n,x,hh,y,derivs)
      x=xsav+h
      if(x.eq.xsav) then 
c         print *, 'stepsize not significant in rkqc.'
         iero=1
         return
      endif
      call rk4(ysav,dysav,n,xsav,h,ytemp,derivs)
      errmax=0.
      do 12 i=1,n
        ytemp(i)=y(i)-ytemp(i)
        errmax=max(errmax,abs(ytemp(i)/(yscal(i)*eps)))
12    continue
      if(errmax.gt.one) then
        h=safety*h*(errmax**pshrnk)
        goto 1
      else
        hdid=h
        if(errmax.gt.errcon)then
          hnext=safety*h*(errmax**pgrow)
        else
          hnext=4.*h
        endif
      endif
      do 13 i=1,n
        y(i)=y(i)+ytemp(i)*fcor
13    continue
      return
      end