Statistiques
| Révision :

root / src / Splin1D.f90 @ 4

Historique | Voir | Annoter | Télécharger (10,92 ko)

1 1 equemene
       SUBROUTINE spline(x,y,n,yp1,ypn,y2)
2 1 equemene
!Given arrays x(1:n) and y(1:n) containing a tabulated function,
3 1 equemene
! i.e., y i = f(xi), with x1<x2< :::<xN , and given values yp1 and ypn
4 1 equemene
!for the  rst derivative of the inter- polating function at points 1 and n,
5 1 equemene
! respectively, this routine returns an array y2(1:n) of length n
6 1 equemene
!which contains the second derivatives of the interpolating function
7 1 equemene
!at the tabulated points xi.
8 1 equemene
! Ifyp1 and/or ypn are equal to 1*10^30 or larger,
9 1 equemene
! the routine is signaled to set the corresponding boundary
10 1 equemene
!condition for a natural spline,
11 1 equemene
!with zero second derivative on that boundary.
12 1 equemene
13 1 equemene
         Use Vartypes
14 1 equemene
15 1 equemene
         IMPLICIT NONE
16 1 equemene
17 1 equemene
! Number of points
18 1 equemene
         INTEGER(KINT) :: n
19 1 equemene
! Coordinate to spline
20 1 equemene
         REAL(KREAL) :: x(n),y(n)
21 1 equemene
! Coefficients to compute
22 1 equemene
         REAL(KREAL) :: y2(n)
23 1 equemene
! End-points derivatives
24 1 equemene
         REAL(KREAL) ::yp1,ypn
25 1 equemene
26 1 equemene
       INTEGER(KINT), PARAMETER  :: NMAX=500
27 1 equemene
28 1 equemene
       INTEGER(KINT) :: i,k
29 1 equemene
       REAL(KREAL) :: p,qn,sig,un,u(NMAX)
30 1 equemene
       LOGICAL Debug
31 1 equemene
32 1 equemene
  INTERFACE
33 1 equemene
     function valid(string) result (isValid)
34 1 equemene
       CHARACTER(*), intent(in) :: string
35 1 equemene
       logical                  :: isValid
36 1 equemene
     END function VALID
37 1 equemene
38 1 equemene
  END INTERFACE
39 1 equemene
40 1 equemene
       Debug=valid("spline")
41 1 equemene
42 1 equemene
       IF (DEBUG) THEN
43 1 equemene
          WRITE(*,*) "Spline 1D",n
44 1 equemene
          WRITE(*,*) "x:",(x(i),i=1,n)
45 1 equemene
          WRITE(*,*) "y:",(y(i),i=1,n)
46 1 equemene
       END IF
47 1 equemene
48 1 equemene
       if (yp1.gt..99e30) then
49 1 equemene
! The lower boundary condition is set either to be \natural"
50 1 equemene
        y2(1)=0.
51 1 equemene
        u(1)=0.
52 1 equemene
       else
53 1 equemene
! or else to have a speci ed  rst derivative.
54 1 equemene
        y2(1)=-0.5
55 1 equemene
        u(1)=(3./(x(2)-x(1)))*((y(2)-y(1))/(x(2)-x(1))-yp1)
56 1 equemene
      endif
57 1 equemene
      do i=2,n-1
58 1 equemene
! This is the decomposition loop of the tridiagonal algorithm.
59 1 equemene
!y2 and u are used for temporary storage of the decomposed factors.
60 1 equemene
       sig=(x(i)-x(i-1))/(x(i+1)-x(i-1))
61 1 equemene
        p=sig*y2(i-1)+2.
62 1 equemene
       y2(i)=(sig-1.)/p
63 1 equemene
       u(i)=(6.*((y(i+1)-y(i))/(x(i+1)-x(i))-(y(i)-y(i-1)) &
64 1 equemene
                /(x(i)-x(i-1)))/(x(i+1)-x(i-1))-sig*u(i-1))/p
65 1 equemene
       enddo
66 1 equemene
       if (ypn.gt..99e30) then
67 1 equemene
!The upper boundary condition is set either to be \natural"
68 1 equemene
         qn=0.
69 1 equemene
         un=0.
70 1 equemene
        else
71 1 equemene
!or else to have a speci ed  rst derivative.
72 1 equemene
         qn=0.5
73 1 equemene
         un=(3./(x(n)-x(n-1)))*(ypn-(y(n)-y(n-1))/(x(n)-x(n-1)))
74 1 equemene
         endif
75 1 equemene
        y2(n)=(un-qn*u(n-1))/(qn*y2(n-1)+1.)
76 1 equemene
        do k=n-1,1,-1
77 1 equemene
         y2(k)=y2(k)*y2(k+1)+u(k)
78 1 equemene
        enddo
79 1 equemene
80 1 equemene
        IF (DEBUG)  WRITE(*,*) "y2:",(y2(i),i=1,n)
81 1 equemene
         return
82 1 equemene
        END
83 1 equemene
84 1 equemene
85 1 equemene
      SUBROUTINE splint(x,y,N,xa,ya,y2a)
86 1 equemene
87 1 equemene
         Use Vartypes
88 1 equemene
89 1 equemene
         IMPLICIT NONE
90 1 equemene
91 1 equemene
! Number of points
92 1 equemene
         INTEGER(KINT) :: n
93 1 equemene
! Spline coefficients
94 1 equemene
         REAL(KREAL) :: xa(n),ya(n), y2a(n)
95 1 equemene
! Y to compute for a given x
96 1 equemene
         REAL(KREAL) :: x,y
97 1 equemene
98 1 equemene
99 1 equemene
       INTEGER(KINT) :: ind
100 1 equemene
       LOGICAL debug
101 1 equemene
102 1 equemene
! Given the arrays xa(1:n) and ya(1:n) of length n, which tabulate a
103 1 equemene
! function (with the xai's in order), and given the array y2a(1:n),
104 1 equemene
!which is the output from spline above, and given a value of x,
105 1 equemene
! this routine returns a cubic-spline interpolated value y.
106 1 equemene
       INTEGER(KINT) :: k,khi,klo
107 1 equemene
       REAL(KREAL) :: a,b,h
108 1 equemene
109 1 equemene
110 1 equemene
  INTERFACE
111 1 equemene
     function valid(string) result (isValid)
112 1 equemene
       CHARACTER(*), intent(in) :: string
113 1 equemene
       logical                  :: isValid
114 1 equemene
     END function VALID
115 1 equemene
116 1 equemene
  END INTERFACE
117 1 equemene
118 1 equemene
       Debug=valid("splint")
119 1 equemene
120 1 equemene
121 1 equemene
!           if (debug) THEN
122 1 equemene
!       WRITE(*,*) "Splint 1D",n
123 1 equemene
!       WRITE(*,*) "xa:",(xa(i),i=1,n)
124 1 equemene
!       WRITE(*,*) "ya:",(ya(i),i=1,n)
125 1 equemene
!       WRITE(*,*) "y2a:",(y2a(i),i=1,n)
126 1 equemene
!        END IF
127 1 equemene
128 1 equemene
129 1 equemene
130 1 equemene
          klo=1
131 1 equemene
!We will  find the right place in the table by means of bisection.
132 1 equemene
! This is optimal if sequential calls to this routine are at
133 1 equemene
!random values of x. If sequential calls are in order, and closely
134 1 equemene
! spaced, one would do better to store previous values of klo and khi
135 1 equemene
! and test if they remain appropriate on the next call.
136 1 equemene
          khi=n
137 1 equemene
 !         WRITE(*,*) xa(klo),xa(khi),n,x
138 1 equemene
 1        if (khi-klo.gt.1) then
139 1 equemene
             k=(khi+klo)/2
140 1 equemene
             if(xa(k).gt.x) then
141 1 equemene
                khi=k
142 1 equemene
             else
143 1 equemene
                klo=k
144 1 equemene
             endif
145 1 equemene
          goto 1
146 1 equemene
          endif
147 1 equemene
! klo and khi now bracket the input value of x.
148 1 equemene
          h=xa(khi)-xa(klo)
149 1 equemene
! The xa's must be distinct.
150 1 equemene
          if (h.eq.0.) pause 'bad xa input in splint'
151 1 equemene
! Cubic spline polynomial is now evaluated.
152 1 equemene
           a=(xa(khi)-x)/h
153 1 equemene
           b=(x-xa(klo))/h
154 1 equemene
           y=a*ya(klo)+b*ya(khi)+ ((a**3-a)*y2a(klo)+(b**3-b)*y2a(khi)) &
155 1 equemene
                *(h**2)/6.
156 1 equemene
157 1 equemene
!           WRITE(*,*) "Splint1D x,y",x,y
158 1 equemene
          return
159 1 equemene
          END
160 1 equemene
161 1 equemene
162 1 equemene
! SUBROUTINE splinder *************************************************
163 1 equemene
! *********************************************************************
164 1 equemene
165 1 equemene
      SUBROUTINE splinder(x,y,N,xa,ya,y2a)
166 1 equemene
         Use Vartypes
167 1 equemene
168 1 equemene
         IMPLICIT NONE
169 1 equemene
170 1 equemene
! Number of points
171 1 equemene
         INTEGER(KINT) :: n
172 1 equemene
! Spline coefficients
173 1 equemene
         REAL(KREAL) :: xa(n),ya(n), y2a(n)
174 1 equemene
! Y to compute for a given x
175 1 equemene
         REAL(KREAL) :: x,y
176 1 equemene
177 1 equemene
178 1 equemene
       INTEGER(KINT) :: ind
179 1 equemene
       LOGICAL debug
180 1 equemene
181 1 equemene
! Given the arrays xa(1:n) and ya(1:n) of length n, which tabulate a
182 1 equemene
! function (with the xai's in order), and given the array y2a(1:n),
183 1 equemene
! which is the output from spline above, and given a value of x,
184 1 equemene
! this routine returns a cubic-spline interpolated value y first DERIVATIVE.
185 1 equemene
! this routine returns a cubic-spline interpolated value y.
186 1 equemene
       INTEGER(KINT) :: k,khi,klo
187 1 equemene
       REAL(KREAL) :: a,b,h
188 1 equemene
189 1 equemene
190 1 equemene
  INTERFACE
191 1 equemene
     function valid(string) result (isValid)
192 1 equemene
       CHARACTER(*), intent(in) :: string
193 1 equemene
       logical                  :: isValid
194 1 equemene
     END function VALID
195 1 equemene
196 1 equemene
  END INTERFACE
197 1 equemene
198 1 equemene
199 1 equemene
       Debug=valid("splinder")
200 1 equemene
201 1 equemene
202 1 equemene
203 1 equemene
          klo=1
204 1 equemene
! We will  find the right place in the table by means of bisection.
205 1 equemene
! This is optimal if sequential calls to this routine are at
206 1 equemene
!random values of x. If sequential calls are in order, and closely
207 1 equemene
! spaced, one would do better to store previous values of klo and khi
208 1 equemene
! and test if they remain appropriate on the next call.
209 1 equemene
          khi=n
210 1 equemene
 !         WRITE(*,*) xa(klo),xa(khi),n,x
211 1 equemene
 1        if (khi-klo.gt.1) then
212 1 equemene
             k=(khi+klo)/2
213 1 equemene
             if(xa(k).gt.x) then
214 1 equemene
                khi=k
215 1 equemene
             else
216 1 equemene
                klo=k
217 1 equemene
             endif
218 1 equemene
          goto 1
219 1 equemene
          endif
220 1 equemene
! klo and khi now bracket the input value of x.
221 1 equemene
          h=xa(khi)-xa(klo)
222 1 equemene
! The xa's must be distinct.
223 1 equemene
          if (h.eq.0.) pause 'bad xa input in splint'
224 1 equemene
! Cubic spline polynomial is now evaluated.
225 1 equemene
           a=(xa(khi)-x)/h
226 1 equemene
           b=(x-xa(klo))/h
227 1 equemene
! Formula taken from the Numerical Recipies book.
228 1 equemene
           y=(ya(khi)-ya(klo))/h - (3*a**2-1)/6.*h*y2a(klo)+ &
229 1 equemene
                (3*b**2-1)/6.*h*y2a(khi)
230 1 equemene
          return
231 1 equemene
          END
232 1 equemene
233 1 equemene
234 1 equemene
235 1 equemene
! SUBROUTINE splintder *************************************************
236 1 equemene
! *********************************************************************
237 1 equemene
238 1 equemene
      SUBROUTINE splintDer(x,y,der,N,xa,ya,y2a)
239 1 equemene
240 1 equemene
! Given the arrays xa(1:n) and ya(1:n) of length n, which tabulate a
241 1 equemene
! function (with the xai's in order), and given the array y2a(1:n),
242 1 equemene
! which is the output from spline above, and given a value of x,
243 1 equemene
! this routine returns a cubic-spline interpolated value y.
244 1 equemene
! and the derivative der.
245 1 equemene
246 1 equemene
         Use Vartypes
247 1 equemene
248 1 equemene
         IMPLICIT NONE
249 1 equemene
250 1 equemene
! Number of points
251 1 equemene
         INTEGER(KINT) :: n
252 1 equemene
! Spline coefficients
253 1 equemene
         REAL(KREAL) :: xa(n),ya(n), y2a(n)
254 1 equemene
! Y to compute for a given x
255 1 equemene
         REAL(KREAL) :: x,y, der
256 1 equemene
257 1 equemene
258 1 equemene
       INTEGER(KINT) :: ind
259 1 equemene
       LOGICAL debug
260 1 equemene
261 1 equemene
       INTEGER(KINT) :: k,khi,klo
262 1 equemene
       REAL(KREAL) :: a,b,h
263 1 equemene
264 1 equemene
  INTERFACE
265 1 equemene
     function valid(string) result (isValid)
266 1 equemene
       CHARACTER(*), intent(in) :: string
267 1 equemene
       logical                  :: isValid
268 1 equemene
     END function VALID
269 1 equemene
270 1 equemene
  END INTERFACE
271 1 equemene
272 1 equemene
       Debug=valid("splintder")
273 1 equemene
274 1 equemene
275 1 equemene
!           if (debug) THEN
276 1 equemene
!       WRITE(*,*) "SplintDer 1D",n
277 1 equemene
!       WRITE(*,*) "xa:",(xa(i),i=1,n)
278 1 equemene
!       WRITE(*,*) "ya:",(ya(i),i=1,n)
279 1 equemene
!       WRITE(*,*) "y2a:",(y2a(i),i=1,n)
280 1 equemene
!        END IF
281 1 equemene
282 1 equemene
283 1 equemene
284 1 equemene
          klo=1
285 1 equemene
! We will  find the right place in the table by means of bisection.
286 1 equemene
! This is optimal if sequential calls to this routine are at
287 1 equemene
! random values of x. If sequential calls are in order, and closely
288 1 equemene
! spaced, one would do better to store previous values of klo and khi
289 1 equemene
! and test if they remain appropriate on the next call.
290 1 equemene
          khi=n
291 1 equemene
 !         WRITE(*,*) xa(klo),xa(khi),n,x
292 1 equemene
 1        if (khi-klo.gt.1) then
293 1 equemene
             k=(khi+klo)/2
294 1 equemene
             if(xa(k).gt.x) then
295 1 equemene
                khi=k
296 1 equemene
             else
297 1 equemene
                klo=k
298 1 equemene
             endif
299 1 equemene
          goto 1
300 1 equemene
          endif
301 1 equemene
! klo and khi now bracket the input value of x.
302 1 equemene
          h=xa(khi)-xa(klo)
303 1 equemene
! The xa's must be distinct.
304 1 equemene
          if (h.eq.0.) pause 'bad xa input in splint'
305 1 equemene
! Cubic spline polynomial is now evaluated.
306 1 equemene
           a=(xa(khi)-x)/h
307 1 equemene
           b=(x-xa(klo))/h
308 1 equemene
           y=a*ya(klo)+b*ya(khi)+ ((a**3-a)*y2a(klo)+(b**3-b)*y2a(khi)) &
309 1 equemene
                *(h**2)/6.
310 1 equemene
! Formula taken from the Numerical Recipies book.
311 1 equemene
           der=(ya(khi)-ya(klo))/h - (3*a**2-1)/6.*h*y2a(klo)+ &
312 1 equemene
                (3*b**2-1)/6.*h*y2a(khi)
313 1 equemene
          return
314 1 equemene
        END SUBROUTINE splintDer
315 1 equemene
316 1 equemene
317 1 equemene
318 1 equemene
      SUBROUTINE LinearInt(x,y,der,N,xa,ya)
319 1 equemene
320 1 equemene
! Given the arrays xa(1:n) and ya(1:n) of length n, which tabulate a
321 1 equemene
! function (with the xai's in order), and given the array y2a(1:n),
322 1 equemene
! which is the output from spline above, and given a value of x,
323 1 equemene
! this routine returns a cubic-spline interpolated value y.
324 1 equemene
325 1 equemene
         Use Vartypes
326 1 equemene
327 1 equemene
         IMPLICIT NONE
328 1 equemene
329 1 equemene
! Number of points
330 1 equemene
         INTEGER(KINT) :: n
331 1 equemene
! Spline coefficients
332 1 equemene
         REAL(KREAL) :: xa(n),ya(n)
333 1 equemene
! Y to compute for a given x
334 1 equemene
         REAL(KREAL) :: x,y, der
335 1 equemene
336 1 equemene
337 1 equemene
       INTEGER(KINT) :: ind
338 1 equemene
       LOGICAL debug
339 1 equemene
340 1 equemene
       INTEGER(KINT) :: k,khi,klo
341 1 equemene
       REAL(KREAL) :: a,b,h
342 1 equemene
343 1 equemene
  INTERFACE
344 1 equemene
     function valid(string) result (isValid)
345 1 equemene
       CHARACTER(*), intent(in) :: string
346 1 equemene
       logical                  :: isValid
347 1 equemene
     END function VALID
348 1 equemene
349 1 equemene
  END INTERFACE
350 1 equemene
351 1 equemene
       Debug=valid("linearint")
352 1 equemene
353 1 equemene
354 1 equemene
!           if (debug) THEN
355 1 equemene
!       WRITE(*,*) "SplintDer 1D",n
356 1 equemene
!       WRITE(*,*) "xa:",(xa(i),i=1,n)
357 1 equemene
!       WRITE(*,*) "ya:",(ya(i),i=1,n)
358 1 equemene
!       WRITE(*,*) "y2a:",(y2a(i),i=1,n)
359 1 equemene
!        END IF
360 1 equemene
361 1 equemene
362 1 equemene
363 1 equemene
          klo=1
364 1 equemene
! We will  find the right place in the table by means of bisection.
365 1 equemene
! This is optimal if sequential calls to this routine are at
366 1 equemene
! random values of x. If sequential calls are in order, and closely
367 1 equemene
! spaced, one would do better to store previous values of klo and khi
368 1 equemene
! and test if they remain appropriate on the next call.
369 1 equemene
          khi=n
370 1 equemene
 !         WRITE(*,*) xa(klo),xa(khi),n,x
371 1 equemene
 1        if (khi-klo.gt.1) then
372 1 equemene
             k=(khi+klo)/2
373 1 equemene
             if(xa(k).gt.x) then
374 1 equemene
                khi=k
375 1 equemene
             else
376 1 equemene
                klo=k
377 1 equemene
             endif
378 1 equemene
          goto 1
379 1 equemene
          endif
380 1 equemene
! klo and khi now bracket the input value of x.
381 1 equemene
          h=xa(khi)-xa(klo)
382 1 equemene
! The xa's must be distinct.
383 1 equemene
          if (h.eq.0.) pause 'bad xa input in splint'
384 1 equemene
! Linear int now evaluated.
385 1 equemene
           a=(xa(khi)-x)/h
386 1 equemene
           b=(x-xa(klo))/h
387 1 equemene
           y=a*ya(klo)+b*ya(khi)
388 1 equemene
! Formula taken from the Numerical Recipies book.
389 1 equemene
           der=a+b
390 1 equemene
          return
391 1 equemene
        END SUBROUTINE LinearInt