Statistiques
| Révision :

root / src / Splin1D.f90 @ 2

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

1
       SUBROUTINE spline(x,y,n,yp1,ypn,y2)
2
!Given arrays x(1:n) and y(1:n) containing a tabulated function,
3
! i.e., y i = f(xi), with x1<x2< :::<xN , and given values yp1 and ypn
4
!for the  rst derivative of the inter- polating function at points 1 and n,
5
! respectively, this routine returns an array y2(1:n) of length n
6
!which contains the second derivatives of the interpolating function
7
!at the tabulated points xi.
8
! Ifyp1 and/or ypn are equal to 1*10^30 or larger,
9
! the routine is signaled to set the corresponding boundary
10
!condition for a natural spline,
11
!with zero second derivative on that boundary.
12

    
13
         Use Vartypes
14

    
15
         IMPLICIT NONE
16

    
17
! Number of points
18
         INTEGER(KINT) :: n
19
! Coordinate to spline
20
         REAL(KREAL) :: x(n),y(n)
21
! Coefficients to compute
22
         REAL(KREAL) :: y2(n)
23
! End-points derivatives
24
         REAL(KREAL) ::yp1,ypn
25

    
26
       INTEGER(KINT), PARAMETER  :: NMAX=500
27

    
28
       INTEGER(KINT) :: i,k
29
       REAL(KREAL) :: p,qn,sig,un,u(NMAX)
30
       LOGICAL Debug
31

    
32
  INTERFACE
33
     function valid(string) result (isValid)
34
       CHARACTER(*), intent(in) :: string
35
       logical                  :: isValid
36
     END function VALID
37

    
38
  END INTERFACE
39

    
40
       Debug=valid("spline")
41

    
42
       IF (DEBUG) THEN
43
          WRITE(*,*) "Spline 1D",n
44
          WRITE(*,*) "x:",(x(i),i=1,n)
45
          WRITE(*,*) "y:",(y(i),i=1,n)
46
       END IF
47

    
48
       if (yp1.gt..99e30) then
49
! The lower boundary condition is set either to be \natural"
50
        y2(1)=0.
51
        u(1)=0.
52
       else
53
! or else to have a speci ed  rst derivative.
54
        y2(1)=-0.5
55
        u(1)=(3./(x(2)-x(1)))*((y(2)-y(1))/(x(2)-x(1))-yp1)
56
      endif
57
      do i=2,n-1
58
! This is the decomposition loop of the tridiagonal algorithm.
59
!y2 and u are used for temporary storage of the decomposed factors.
60
       sig=(x(i)-x(i-1))/(x(i+1)-x(i-1))
61
        p=sig*y2(i-1)+2.
62
       y2(i)=(sig-1.)/p
63
       u(i)=(6.*((y(i+1)-y(i))/(x(i+1)-x(i))-(y(i)-y(i-1)) &
64
                /(x(i)-x(i-1)))/(x(i+1)-x(i-1))-sig*u(i-1))/p
65
       enddo
66
       if (ypn.gt..99e30) then
67
!The upper boundary condition is set either to be \natural"
68
         qn=0.
69
         un=0.
70
        else
71
!or else to have a speci ed  rst derivative.
72
         qn=0.5
73
         un=(3./(x(n)-x(n-1)))*(ypn-(y(n)-y(n-1))/(x(n)-x(n-1)))
74
         endif
75
        y2(n)=(un-qn*u(n-1))/(qn*y2(n-1)+1.)
76
        do k=n-1,1,-1
77
         y2(k)=y2(k)*y2(k+1)+u(k)
78
        enddo
79

    
80
        IF (DEBUG)  WRITE(*,*) "y2:",(y2(i),i=1,n)
81
         return
82
        END
83

    
84

    
85
      SUBROUTINE splint(x,y,N,xa,ya,y2a)
86

    
87
         Use Vartypes
88

    
89
         IMPLICIT NONE
90

    
91
! Number of points
92
         INTEGER(KINT) :: n
93
! Spline coefficients
94
         REAL(KREAL) :: xa(n),ya(n), y2a(n)
95
! Y to compute for a given x
96
         REAL(KREAL) :: x,y
97

    
98

    
99
       INTEGER(KINT) :: ind
100
       LOGICAL debug
101

    
102
! Given the arrays xa(1:n) and ya(1:n) of length n, which tabulate a
103
! function (with the xai's in order), and given the array y2a(1:n),
104
!which is the output from spline above, and given a value of x,
105
! this routine returns a cubic-spline interpolated value y.
106
       INTEGER(KINT) :: k,khi,klo
107
       REAL(KREAL) :: a,b,h
108

    
109

    
110
  INTERFACE
111
     function valid(string) result (isValid)
112
       CHARACTER(*), intent(in) :: string
113
       logical                  :: isValid
114
     END function VALID
115

    
116
  END INTERFACE
117

    
118
       Debug=valid("splint")
119

    
120

    
121
!           if (debug) THEN
122
!       WRITE(*,*) "Splint 1D",n
123
!       WRITE(*,*) "xa:",(xa(i),i=1,n)
124
!       WRITE(*,*) "ya:",(ya(i),i=1,n)
125
!       WRITE(*,*) "y2a:",(y2a(i),i=1,n)
126
!        END IF
127

    
128

    
129

    
130
          klo=1
131
!We will  find the right place in the table by means of bisection.
132
! This is optimal if sequential calls to this routine are at
133
!random values of x. If sequential calls are in order, and closely
134
! spaced, one would do better to store previous values of klo and khi
135
! and test if they remain appropriate on the next call.
136
          khi=n
137
 !         WRITE(*,*) xa(klo),xa(khi),n,x
138
 1        if (khi-klo.gt.1) then
139
             k=(khi+klo)/2
140
             if(xa(k).gt.x) then
141
                khi=k
142
             else
143
                klo=k
144
             endif
145
          goto 1
146
          endif
147
! klo and khi now bracket the input value of x.
148
          h=xa(khi)-xa(klo)
149
! The xa's must be distinct.
150
          if (h.eq.0.) pause 'bad xa input in splint'
151
! Cubic spline polynomial is now evaluated.
152
           a=(xa(khi)-x)/h
153
           b=(x-xa(klo))/h
154
           y=a*ya(klo)+b*ya(khi)+ ((a**3-a)*y2a(klo)+(b**3-b)*y2a(khi)) &
155
                *(h**2)/6.
156

    
157
!           WRITE(*,*) "Splint1D x,y",x,y
158
          return
159
          END
160

    
161

    
162
! SUBROUTINE splinder *************************************************
163
! *********************************************************************
164

    
165
      SUBROUTINE splinder(x,y,N,xa,ya,y2a)
166
         Use Vartypes
167

    
168
         IMPLICIT NONE
169

    
170
! Number of points
171
         INTEGER(KINT) :: n
172
! Spline coefficients
173
         REAL(KREAL) :: xa(n),ya(n), y2a(n)
174
! Y to compute for a given x
175
         REAL(KREAL) :: x,y
176

    
177

    
178
       INTEGER(KINT) :: ind
179
       LOGICAL debug
180

    
181
! Given the arrays xa(1:n) and ya(1:n) of length n, which tabulate a
182
! function (with the xai's in order), and given the array y2a(1:n),
183
! which is the output from spline above, and given a value of x,
184
! this routine returns a cubic-spline interpolated value y first DERIVATIVE.
185
! this routine returns a cubic-spline interpolated value y.
186
       INTEGER(KINT) :: k,khi,klo
187
       REAL(KREAL) :: a,b,h
188

    
189

    
190
  INTERFACE
191
     function valid(string) result (isValid)
192
       CHARACTER(*), intent(in) :: string
193
       logical                  :: isValid
194
     END function VALID
195

    
196
  END INTERFACE
197

    
198
 
199
       Debug=valid("splinder")
200

    
201

    
202

    
203
          klo=1
204
! We will  find the right place in the table by means of bisection.
205
! This is optimal if sequential calls to this routine are at
206
!random values of x. If sequential calls are in order, and closely
207
! spaced, one would do better to store previous values of klo and khi
208
! and test if they remain appropriate on the next call.
209
          khi=n
210
 !         WRITE(*,*) xa(klo),xa(khi),n,x
211
 1        if (khi-klo.gt.1) then
212
             k=(khi+klo)/2
213
             if(xa(k).gt.x) then
214
                khi=k
215
             else
216
                klo=k
217
             endif
218
          goto 1
219
          endif
220
! klo and khi now bracket the input value of x.
221
          h=xa(khi)-xa(klo)
222
! The xa's must be distinct.
223
          if (h.eq.0.) pause 'bad xa input in splint'
224
! Cubic spline polynomial is now evaluated.
225
           a=(xa(khi)-x)/h
226
           b=(x-xa(klo))/h
227
! Formula taken from the Numerical Recipies book.
228
           y=(ya(khi)-ya(klo))/h - (3*a**2-1)/6.*h*y2a(klo)+ &
229
                (3*b**2-1)/6.*h*y2a(khi)
230
          return
231
          END
232

    
233

    
234

    
235
! SUBROUTINE splintder *************************************************
236
! *********************************************************************
237

    
238
      SUBROUTINE splintDer(x,y,der,N,xa,ya,y2a)
239

    
240
! Given the arrays xa(1:n) and ya(1:n) of length n, which tabulate a
241
! function (with the xai's in order), and given the array y2a(1:n),
242
! which is the output from spline above, and given a value of x,
243
! this routine returns a cubic-spline interpolated value y.
244
! and the derivative der.
245

    
246
         Use Vartypes
247

    
248
         IMPLICIT NONE
249

    
250
! Number of points
251
         INTEGER(KINT) :: n
252
! Spline coefficients
253
         REAL(KREAL) :: xa(n),ya(n), y2a(n)
254
! Y to compute for a given x
255
         REAL(KREAL) :: x,y, der
256

    
257

    
258
       INTEGER(KINT) :: ind
259
       LOGICAL debug
260

    
261
       INTEGER(KINT) :: k,khi,klo
262
       REAL(KREAL) :: a,b,h
263

    
264
  INTERFACE
265
     function valid(string) result (isValid)
266
       CHARACTER(*), intent(in) :: string
267
       logical                  :: isValid
268
     END function VALID
269

    
270
  END INTERFACE
271

    
272
       Debug=valid("splintder")
273

    
274

    
275
!           if (debug) THEN
276
!       WRITE(*,*) "SplintDer 1D",n
277
!       WRITE(*,*) "xa:",(xa(i),i=1,n)
278
!       WRITE(*,*) "ya:",(ya(i),i=1,n)
279
!       WRITE(*,*) "y2a:",(y2a(i),i=1,n)
280
!        END IF
281

    
282

    
283

    
284
          klo=1
285
! We will  find the right place in the table by means of bisection.
286
! This is optimal if sequential calls to this routine are at
287
! random values of x. If sequential calls are in order, and closely
288
! spaced, one would do better to store previous values of klo and khi
289
! and test if they remain appropriate on the next call.
290
          khi=n
291
 !         WRITE(*,*) xa(klo),xa(khi),n,x
292
 1        if (khi-klo.gt.1) then
293
             k=(khi+klo)/2
294
             if(xa(k).gt.x) then
295
                khi=k
296
             else
297
                klo=k
298
             endif
299
          goto 1
300
          endif
301
! klo and khi now bracket the input value of x.
302
          h=xa(khi)-xa(klo)
303
! The xa's must be distinct.
304
          if (h.eq.0.) pause 'bad xa input in splint'
305
! Cubic spline polynomial is now evaluated.
306
           a=(xa(khi)-x)/h
307
           b=(x-xa(klo))/h
308
           y=a*ya(klo)+b*ya(khi)+ ((a**3-a)*y2a(klo)+(b**3-b)*y2a(khi)) &
309
                *(h**2)/6.
310
! Formula taken from the Numerical Recipies book.
311
           der=(ya(khi)-ya(klo))/h - (3*a**2-1)/6.*h*y2a(klo)+ &
312
                (3*b**2-1)/6.*h*y2a(khi)
313
          return
314
        END SUBROUTINE splintDer
315

    
316

    
317

    
318
      SUBROUTINE LinearInt(x,y,der,N,xa,ya)
319

    
320
! Given the arrays xa(1:n) and ya(1:n) of length n, which tabulate a
321
! function (with the xai's in order), and given the array y2a(1:n),
322
! which is the output from spline above, and given a value of x,
323
! this routine returns a cubic-spline interpolated value y.
324

    
325
         Use Vartypes
326

    
327
         IMPLICIT NONE
328

    
329
! Number of points
330
         INTEGER(KINT) :: n
331
! Spline coefficients
332
         REAL(KREAL) :: xa(n),ya(n)
333
! Y to compute for a given x
334
         REAL(KREAL) :: x,y, der
335

    
336

    
337
       INTEGER(KINT) :: ind
338
       LOGICAL debug
339

    
340
       INTEGER(KINT) :: k,khi,klo
341
       REAL(KREAL) :: a,b,h
342

    
343
  INTERFACE
344
     function valid(string) result (isValid)
345
       CHARACTER(*), intent(in) :: string
346
       logical                  :: isValid
347
     END function VALID
348

    
349
  END INTERFACE
350

    
351
       Debug=valid("linearint")
352

    
353

    
354
!           if (debug) THEN
355
!       WRITE(*,*) "SplintDer 1D",n
356
!       WRITE(*,*) "xa:",(xa(i),i=1,n)
357
!       WRITE(*,*) "ya:",(ya(i),i=1,n)
358
!       WRITE(*,*) "y2a:",(y2a(i),i=1,n)
359
!        END IF
360

    
361

    
362

    
363
          klo=1
364
! We will  find the right place in the table by means of bisection.
365
! This is optimal if sequential calls to this routine are at
366
! random values of x. If sequential calls are in order, and closely
367
! spaced, one would do better to store previous values of klo and khi
368
! and test if they remain appropriate on the next call.
369
          khi=n
370
 !         WRITE(*,*) xa(klo),xa(khi),n,x
371
 1        if (khi-klo.gt.1) then
372
             k=(khi+klo)/2
373
             if(xa(k).gt.x) then
374
                khi=k
375
             else
376
                klo=k
377
             endif
378
          goto 1
379
          endif
380
! klo and khi now bracket the input value of x.
381
          h=xa(khi)-xa(klo)
382
! The xa's must be distinct.
383
          if (h.eq.0.) pause 'bad xa input in splint'
384
! Linear int now evaluated.
385
           a=(xa(khi)-x)/h
386
           b=(x-xa(klo))/h
387
           y=a*ya(klo)+b*ya(khi)
388
! Formula taken from the Numerical Recipies book.
389
           der=a+b
390
          return
391
        END SUBROUTINE LinearInt