ETS  \$Id: Doxyfile 2162 2020-02-26 14:16:09Z g2dpc $
 All Classes Files Functions Variables Pages
spider_spline.f
Go to the documentation of this file.
1  module spider_spline
2 
3  contains
4 
5  SUBROUTINE intrptau(PXIN,PYIN,PYINNEW,PY2,KNIN,PXOUT,PYOUT,PYOUTP,
6  + pyoutpp,knout,kopt,ptaus,pwork,pamat,mdamat,pbclft,pbcrgt)
7 C =================================================================
8 C
9 C NOTE: THIS ROUTINE INCLUDES THE STANDARD CUBIC SPLINE IF PTAUS=0:
10 C THEN PYINNEW IS NOT USED AND MDAMAT=3 IS SUFFICIENT
11 C (=> PYINNEW(1) OR PYINNEW=PYIN IS OK)
12 C
13 C Interpolate (pxin,pyin) on (pxout,pyout) using
14 C Hirshman fitted cubic spline with ptaus value or
15 C standard cubic spline if PTAUS=0
16 C
17 C KOPT = 0: ONLY INTERPOLATE FUNCTION INTO PYOUT
18 C KOPT = 1: INTERPOLATE FUNCTION INTO PYOUT AND 1ST DER. INTO PYOUTP
19 C KOPT = 2: AS KOPT=1 PLUS 2ND DER. INTO PYOUTPP
20 C
21 C BOUNDARY CONDITIONS FOR CUBIC SPLINE: PBCLFT AND PBCRGT
22 C THEN IF
23 C = 2 : B.C.: 2ND DERIVATIVE (NATURAL)
24 C = 1 : B.C.: 1ST DERIVATIVE FROM CUBIC LAGRANGE INTERPOLATION
25 C = 0 : B.C.: 1ST DERIVATIVE = 0.0
26 C = 3 : B.C.: 1ST DERIVATIVE FROM LINEAR INTERPOLATION
27 C OTHERWISE: B.C: 1ST DERIVATIVE = PBCLFT OR PBCRGT
28 C
29 
30  IMPLICIT REAL*8(a-h,o-z)
31 
32  dimension pxin(knin), pyin(knin), pxout(knout), pyout(knout),
33  + pyoutp(knout), pyoutpp(knout), py2(knin), pwork(knin),
34  + pamat(mdamat,knin), pyinnew(knin)
35 C-----------------------------------------------------------------------
36 C
37  zeps = 1.0d-12
38 C
39 CL 1. PREPARE SPLINE (DEFAULT <=> PKBCOPT.EQ.0)
40 C
41 C LEFT
42 C
43  zyp1 = pbclft
44  IF (abs(pbclft - 1.d0) .LE. zeps) zyp1 = -1.d+32
45  IF (abs(pbclft - 2.d0) .LE. zeps) zyp1 = 1.d+32
46  IF (abs(pbclft - 3.d0) .LE. zeps) zyp1 = -1.d+34
47 C
48 C RIGHT
49 C
50  zypn = pbcrgt
51  IF (abs(pbcrgt - 1.d0) .LE. zeps) zypn = -1.d+32
52  IF (abs(pbcrgt - 2.d0) .LE. zeps) zypn= 1.d+32
53  IF (abs(pbcrgt - 3.d0) .LE. zeps) zypn = -1.d+34
54 C
55  CALL cubsplfit(pxin,pyin,pyinnew,knin,zyp1,zypn,py2,ptaus
56  + ,pwork,pamat,mdamat)
57 C
58 CL 2. COMPUTE INTERPOLATED VALUE AT EACH PXOUT
59 C
60  DO i=1,knout
61  IF (ptaus .EQ. 0.d0) THEN
62 c%OS CALL SPLINT(PXIN,PYIN,PY2,KNIN,PXOUT(I),ZY,ZYP,ZYPP)
63  CALL splintend(pxin,pyin,py2,knin,pxout(i),zy,zyp,zypp,1)
64  ELSE
65 c%OS CALL SPLINT(PXIN,PYINNEW,PY2,KNIN,PXOUT(I),ZY,ZYP,ZYPP)
66  CALL splintend(pxin,pyinnew,py2,knin,pxout(i),zy,zyp,zypp,1)
67  ENDIF
68  pyout(i) = zy
69  IF (kopt .GE. 1) pyoutp(i) = zyp
70  IF (kopt .EQ. 2) pyoutpp(i) = zypp
71  END DO
72 C
73  RETURN
74  END SUBROUTINE
75 C-----------------------------------------------------------------------
76  SUBROUTINE cubsplfit(X,Y,YNEW,N,YP1,YPN,Y2,TAUS,WORK,AMAT,
77  + mdamat)
78 C
79 C PREPARE SECOND DERIVATIVE OF CUBIC SPLINE INTERPOLATION AND NEW
80 C VALUES OF Y AT NODES YNEW FITTED SUCH THAT CHI**2 + TAUS*F''**2
81 C IS MINIMIZED ACCORDING TO HIRSHMAN ET AL, PHYS. PLASMAS 1 (1994) 2280.
82 C TAUS = TAU*SIGMA_K OF PAPER ASSUMING SIGMA_K CONSTANT.
83 C
84 C SETTING TAUS=0., ONE FINDS THE USUAL CUBIC SPLINE INT. WITH CHI**2=0
85 C TAUS LARGE => FIT CLOSER TO STRAIGHT LINE (SECOND DERIV.=0)
86 C
87 C IF LAPACK ROUTINES NOT AVAILABLE, USE NONSYM.F AND REMOVE "c%nonsym"
88 C
89 C IF TAUS=0, YNEW NOT USED => YNEW(1) OR YNEW=Y IS OK
90 C
91 
92  IMPLICIT REAL*8(a-h,o-z)
93 
94  parameter(mnonsym=501)
95  dimension x(n), y(n), y2(n), work(n),
96  + amat(mdamat,n), ynew(n)
97  + ,anonsym(mnonsym*7), ipivot(mnonsym)
98 c%nonsym
99 c%OS INCLUDE 'CUCCCC.inc'
100 c.......................................................................
101 c.......................................................................
102 C*COMDECK CUCCCC
103 C ----------------------------------------------------------------------
104 C -- STATEMENT FUNCTION FOR CUBIC INTERPOLATION --
105 C -- 23.04.88 AR CRPP --
106 C -- --
107 C -- CUBIC INTERPOLATION OF A FUNCTION F(X) --
108 C -- THE EIGHT ARGUMENTS A1,A2,A3,A4,B1,B2,B3,B4 ARE DEFINED BY: --
109 C -- F(B1) = A1 , F(B2) = A2 , F(B3) = A3 , F(B4) = A4 --
110 C ----------------------------------------------------------------------
111 C
112  fa3(a1,a2,a3,a4,b1,b2,b3,b4) =
113  f(a1-a2) / ((b1-b2)*(b2-b4)*(b2-b3)) +
114  f(a1-a3) / ((b4-b3)*(b3-b1)*(b3-b2)) +
115  f(a1-a4) / ((b1-b4)*(b2-b4)*(b3-b4))
116  fa2(a1,a2,a3,a4,b1,b2,b3,b4) =
117  f(a1-a2) / ((b2-b1)*(b3-b2)) +
118  f(a3-a1) / ((b3-b1)*(b3-b2)) -
119  f(b1+b2+b3) * fa3(a1,a2,a3,a4,b1,b2,b3,b4)
120  fa1(a1,a2,a3,a4,b1,b2,b3,b4) =
121  f(a1-a2) / (b1-b2) -
122  f(b1+b2) * fa2(a1,a2,a3,a4,b1,b2,b3,b4) -
123  f(b1*b1+b1*b2+b2*b2) * fa3(a1,a2,a3,a4,b1,b2,b3,b4)
124  fa0(a1,a2,a3,a4,b1,b2,b3,b4) =
125  f a1 -
126  f b1 * (fa1(a1,a2,a3,a4,b1,b2,b3,b4) +
127  f b1 * (fa2(a1,a2,a3,a4,b1,b2,b3,b4) +
128  f b1 * fa3(a1,a2,a3,a4,b1,b2,b3,b4)))
129 C ----------------------------------------------------------------------
130 C -- FCCCC0 GIVES THE VALUE OF THE FUNCTION AT POINT PX: --
131 C -- FCCCC0(......,PX) = F(PX) --
132 C ----------------------------------------------------------------------
133  fcccc0(a1,a2,a3,a4,b1,b2,b3,b4,px) =
134  f fa0(a1,a2,a3,a4,b1,b2,b3,b4) +
135  f px * (fa1(a1,a2,a3,a4,b1,b2,b3,b4) +
136  f px * (fa2(a1,a2,a3,a4,b1,b2,b3,b4) +
137  f px * fa3(a1,a2,a3,a4,b1,b2,b3,b4)))
138 C ----------------------------------------------------------------------
139 C -- FCCCC1 GIVES THE VALUE OF THE FIRST DERIVATIVE OF F(X) AT PX: --
140 C -- FCCCC1(......,PX) = DF/DX (PX) --
141 C ----------------------------------------------------------------------
142  fcccc1(a1,a2,a3,a4,b1,b2,b3,b4,px) =
143  f fa1(a1,a2,a3,a4,b1,b2,b3,b4) +
144  f px * (2.d0 * fa2(a1,a2,a3,a4,b1,b2,b3,b4) +
145  f 3.d0 * px * fa3(a1,a2,a3,a4,b1,b2,b3,b4))
146 C ----------------------------------------------------------------------
147 C -- FCCCC2 GIVES THE VALUE OF THE SECOND DERIVATIVE OF F(X) AT PX: --
148 C -- FCCCC2(......,PX) = D2F/DX2 (PX) --
149 C ----------------------------------------------------------------------
150  fcccc2(a1,a2,a3,a4,b1,b2,b3,b4,px) =
151  f 2.d0 * fa2(a1,a2,a3,a4,b1,b2,b3,b4) +
152  f 6.d0 * fa3(a1,a2,a3,a4,b1,b2,b3,b4) * px
153 C ----------------------------------------------------------------------
154 C -- FCCCC3 GIVES THE VALUE OF THE THIRD DERIVATIVE OF F(X) AT PX: -
155 C -- FCCCC3(......,PX) = D3F/DX3 (PX) -
156 C ----------------------------------------------------------------------
157  fcccc3(a1,a2,a3,a4,b1,b2,b3,b4,px) =
158  f 6.d0* fa3(a1,a2,a3,a4,b1,b2,b3,b4)
159 c.......................................................................
160 c.......................................................................
161 C
162 C-----------------------------------------------------------------------
163 C
164  DO i=1,n
165  y2(i) = 0.d0
166  END DO
167  DO i=1,mdamat
168  DO j=1,n
169  amat(i,j) = 0.d0
170  END DO
171  END DO
172 C
173 C PREPARE 1 / H_K
174 C
175  DO k=1,n-1
176  work(k) = 1.d0/ (x(k+1) - x(k))
177  END DO
178 C
179  ztaueff = taus
180 C
181 C PREPARE BAND WIDTH
182 C
183  iup = 2
184  IF (ztaueff .EQ. 0.d0) iup = 1
185  iband = 2*iup + 1
186 c%OS IDIAG = IUP + 1
187 c%OS IF (MDAMAT .LT. IUP+1) THEN
188 c%OS PRINT *,' MDAMAT= ',MDAMAT,' < IUP+1= ',IUP
189 c%OS STOP
190 c%OS ENDIF
191 c%nonsym
192  idiag = iband
193  IF (mnonsym*7 .LT. (3*iup+1)*n) THEN
194  print *,' MMNONSYM*7= ',mnonsym*7,' < (3*IUP+1)*N= ',(3*iup+1)*n
195  stop
196  ENDIF
197 c%nonsym
198 C
199 C CONSTRUCT MATRIX AND R.H.S
200 C
201 c.......................................................................
202 C AS MATRIX SYMMETRIC, COMPUTE ONLY UPPER PART
203 C
204 C K=2,N-2 (BULK PART)
205 C
206  DO k=2,n-2
207 C A(K,K)
208  amat(idiag,k) = (1.d0/work(k)+1.d0/work(k-1)) / 3.d0
209  + + 2.d0*ztaueff*(work(k)**2 + work(k)*work(k-1)+work(k-1)**2)
210 C A(K,K+1)
211  amat(idiag-1,k+1) = 1.d0/work(k)/6.d0
212  + - ztaueff*work(k)*(work(k+1)+2.d0*work(k)+work(k-1))
213 C A(K,K+2)
214  IF (iup .EQ. 2) amat(idiag-2,k+2) = ztaueff*work(k+1)*work(k)
215 C B(K)
216  y2(k) = (y(k+1)-y(k))*work(k) - (y(k)-y(k-1))*work(k-1)
217 C
218  END DO
219 C
220 C FOR K=1, N-1, N: SAME AS ABOVE WITH WORK1/2(-1;0;N;N+1) = 0
221 C
222 C K=1
223 C
224  k = 1
225  amat(idiag,k) = 1.d0/work(k) / 3.d0
226  + + 2.d0*ztaueff*work(k)**2
227  amat(idiag-1,k+1) = 1.d0/work(k)/6.d0
228  + - ztaueff*work(k)*(work(k+1)+2.d0*work(k))
229  IF (iup .EQ. 2) amat(idiag-2,k+2) = ztaueff*work(k+1)*work(k)
230  y2(k) = (y(k+1)-y(k))*work(k)
231 C
232 C K=N-1
233 C
234  k = n-1
235  amat(idiag,k) = (1.d0/work(k)+1.d0/work(k-1)) / 3.d0
236  + + 2.d0*ztaueff*(work(k)**2 + work(k)*work(k-1)+work(k-1)**2)
237  amat(idiag-1,k+1) = 1.d0/work(k)/6.d0
238  + - ztaueff*work(k)*(2.d0*work(k)+work(k-1))
239  y2(k) = (y(k+1)-y(k))*work(k) - (y(k)-y(k-1))*work(k-1)
240 C
241 C K = N
242 C
243  k = n
244  amat(idiag,k) = 1.d0/work(k-1) / 3.d0
245  + + 2.d0*ztaueff*work(k-1)**2
246  y2(k) = - (y(k)-y(k-1))*work(k-1)
247 C
248 C.......................................................................
249 C BOUNDARY CONDITIONS
250 C
251  IF (yp1 .GT. .99d30) THEN
252 C SECOND DERIVATIVE = 0 (NATURAL B.C.) AND SYMMETRIZE
253  y2(1) = 0.d0
254  amat(idiag,1) = 1.d0
255  amat(idiag-1,2) = 0.d0
256  IF (iup .EQ. 2) amat(idiag-2,3) = 0.d0
257  zyp1 = 0.d0
258  ELSE IF (-yp1 .GT. .99d+34) THEN
259  zyp1 = (y(2)-y(1))/(x(2)-x(1))
260  ELSE IF (-yp1 .GT. .99d+30) THEN
261  zyp1 = fcccc1(y(1),y(2),y(3),y(4),x(1),x(2),x(3),x(4),x(1))
262  ELSE
263  zyp1 = yp1
264  ENDIF
265  IF (ypn .GT. .99d30) THEN
266 C SECOND DERIVATIVE = 0 (NATURAL B.C.) AND SYMMETRIZE
267  y2(n) = 0.d0
268  amat(idiag,n) = 1.d0
269  amat(idiag-1,n) = 0.d0
270  IF (iup .EQ. 2) amat(idiag-2,n) = 0.d0
271  zypn = 0.d0
272  ELSE IF (-ypn .GT. .99d+34) THEN
273  zypn = (y(n)-y(n-1))/(x(n)-x(n-1))
274  ELSE IF (-ypn .GT. .99d+30) THEN
275  zypn = fcccc1(y(n-3),y(n-2),y(n-1),y(n),
276  + x(n-3),x(n-2),x(n-1),x(n),x(n))
277  ELSE
278  zypn = ypn
279  ENDIF
280 C
281  y2(1) = y2(1) - zyp1
282  y2(n) = y2(n) + zypn
283 C
284 C SOLVE SYSTEM
285 C
286  idima = mdamat
287  idimrhs = n
288  irhs = 1
289 c%OSc CRAY
290 c%OSc%OS CALL SPBTRF('U',N,IUP,AMAT,IDIMA,INFO)
291 c%OSC SUN, SGI
292 c%OS CALL DPBTRF('U',N,IUP,AMAT,IDIMA,INFO)
293 c%OS IF (INFO .EQ. 0) THEN
294 c%OSc CRAY
295 c%OSc%OS CALL SPBTRS('U',N,IUP,IRHS,AMAT,IDIMA,Y2,IDIMRHS,INFO2)
296 c%OSC SUN, SGI
297 c%OS CALL DPBTRS('U',N,IUP,IRHS,AMAT,IDIMA,Y2,IDIMRHS,INFO2)
298 c%OS ELSE
299 c%OS PRINT *,' ERROR IN SPBTRF: INFO = ',INFO
300 c%OS STOP 'INFO'
301 c%OS ENDIF
302 C
303 c%nonsym
304  DO i=1,iband*n
305  anonsym(i) = 0.0
306  ENDDO
307  DO i=1,n
308 C UPPER PART
309  DO j=max(1,i),min(i+iup,n)
310  anonsym((i-1)*iband+j-i+iup+1) = amat(idiag+i-j,j)
311  ENDDO
312 C LOWER PART
313  DO j=max(1,i-iup),min(i-1,n-1)
314  anonsym((i-1)*iband+j-i+iup+1) = amat(idiag+j-i,i)
315  ENDDO
316  ENDDO
317  CALL nonsym(anonsym,amat,y2,n,iup,iup,1.0d-06,info2)
318 c%nonsym
319 C
320 C ADAPT Y AT NODES
321 C
322  IF (ztaueff .NE. 0.d0) THEN
323 C
324  DO k=2,n-1
325  ynew(k) = y(k) - ztaueff* ((y2(k+1)-y2(k))*work(k)
326  + - (y2(k)-y2(k-1))*work(k-1))
327  ENDDO
328  ynew(1) = y(1) - ztaueff * (y2(2)-y2(1))*work(1)
329  ynew(n) = y(n) + ztaueff * (y2(n)-y2(n-1))*work(n-1)
330 C
331  ENDIF
332 
333  IF (info2 .LT. 0) THEN
334  print *,' ERROR IN SPBTRS: INFO2 = ',info2
335  stop 'INFO2'
336  ENDIF
337 C
338  RETURN
339  END SUBROUTINE
340 C-----------------------------------------------------------------------
341  SUBROUTINE spline(X,Y,N,YP1,YPN,Y2)
342 
343  IMPLICIT REAL*8(a-h,o-z)
344 
345  parameter(nmax=100)
346  dimension x(n),y(n),y2(n),u(nmax)
347 C
348  IF (n .GT.nmax) THEN
349  print *,' NMAX TOO SMALL IN SPLINE: N,NMAX= ',n,nmax
350  stop
351  ENDIF
352  IF (yp1.GT..99d30) THEN
353  y2(1)=0.d0
354  u(1)=0.d0
355  ELSE
356 C%OS
357  IF (-yp1 .GT. .99d+30) THEN
358  yp1 = (y(2)-y(1))/(x(2)-x(1))
359  ENDIF
360 C%OS
361  y2(1)=-0.5d0
362  u(1)=(3.d0/(x(2)-x(1)))*((y(2)-y(1))/(x(2)-x(1))-yp1)
363  ENDIF
364  DO 11 i=2,n-1
365  sig=(x(i)-x(i-1))/(x(i+1)-x(i-1))
366  p=sig*y2(i-1)+2.d0
367  y2(i)=(sig-1.d0)/p
368  u(i)=(6.d0*((y(i+1)-y(i))/(x(i+1)-x(i))-(y(i)-y(i-1))
369  * /(x(i)-x(i-1)))/(x(i+1)-x(i-1))-sig*u(i-1))/p
370 11 CONTINUE
371  IF (ypn.GT..99d30) THEN
372  qn=0.d0
373  un=0.d0
374  ELSE
375 C%OS
376  IF (-ypn .GT. .99d+30) THEN
377  ypn = (y(n)-y(n-1))/(x(n)-x(n-1))
378  ENDIF
379 C%OS
380  qn=0.5d0
381  un=(3./(x(n)-x(n-1)))*(ypn-(y(n)-y(n-1))/(x(n)-x(n-1)))
382  ENDIF
383  y2(n)=(un-qn*u(n-1))/(qn*y2(n-1)+1.)
384  DO 12 k=n-1,1,-1
385  y2(k)=y2(k)*y2(k+1)+u(k)
386 12 CONTINUE
387  RETURN
388  END SUBROUTINE
389 C-----------------------------------------------------------------------
390  SUBROUTINE splint(XA,YA,Y2A,N,X,Y,YP,YPP)
391 
392  IMPLICIT REAL*8(a-h,o-z)
393 
394  dimension xa(n),ya(n),y2a(n)
395  klo=1
396  khi=n
397 1 IF (khi-klo.GT.1) THEN
398  k=(khi+klo)/2
399  IF(xa(k).GT.x)THEN
400  khi=k
401  ELSE
402  klo=k
403  ENDIF
404  goto 1
405  ENDIF
406  h=xa(khi)-xa(klo)
407  IF (h.EQ.0.) stop 'BAD XA INPUT.'
408  a=(xa(khi)-x)/h
409  b=(x-xa(klo))/h
410  y=a*ya(klo)+b*ya(khi)+
411  * ((a**3-a)*y2a(klo)+(b**3-b)*y2a(khi))*(h**2)/6.
412  yp=(ya(khi)-ya(klo))/h -
413  - ( (3.*a*a-1.)*y2a(klo) - (3.*b*b-1.)*y2a(khi) )*h/6.
414  ypp=a*y2a(klo)+b*y2a(khi)
415  RETURN
416  END SUBROUTINE
417 C-----------------------------------------------------------------------
418  SUBROUTINE splintend(XA,YA,Y2A,N,X,Y,YP,YPP,KOPT)
419 
420  IMPLICIT REAL*8(a-h,o-z)
421 
422  dimension xa(n),ya(n),y2a(n)
423 C KOPT = 0: NOTHING SPECIAL IF X OUT OF BOUND
424 C KOPT = 1: USE QUADRATIC INTERPOLATION IF X OUT OF BOUND
425 C KOPT = 2: USE CUBIC INTERPOLATION IF X OUT OF BOUND
426 C-----------------------------------------------------------------------
427 C*COMDECK CUCDCD
428 C ----------------------------------------------------------------------
429 C -- STATEMENT FUNCTION FOR CUBIC INTERPOLATION --
430 C -- 19.01.87 AR CRPP --
431 C -- --
432 C -- CUBIC INTERPOLATION OF A FUNCTION F(X) --
433 C -- THE SIX ARGUMENTS X1,F1,P1,X2,F2,P2 ARE DEFINED AS FOLLOWS: --
434 C -- F(X1) = F1 , F(X2) = F2 , DF/DX(X1) = P1 , DF/DX(X2) = P2 --
435 C ----------------------------------------------------------------------
436 C
437  fc3(x1,f1,p1,x2,f2,p2) =
438  = (2.d0* (f2 - f1) / (x1 - x2) + (p1 + p2)) /
439  / ((x1 - x2) * (x1 - x2))
440  fc2(x1,f1,p1,x2,f2,p2) =
441  = (3.d0* (x1 + x2) * (f1 - f2) / (x1 - x2) -
442  * p1 * (x1 + 2.d0* x2) - p2 * (x2 + 2.d0* x1)) /
443  / ((x1 - x2) * (x1 - x2))
444  fc1(x1,f1,p1,x2,f2,p2) =
445  = (6.d0* x1 * x2 * (f2 - f1) / (x1 - x2) +
446  * x2 * p1 * (2 * x1 + x2) + x1 * p2 * (x1 + 2.d0* x2)) /
447  / ((x1 - x2) * (x1 - x2))
448  fc0(x1,f1,p1,x2,f2,p2) =
449  = (f1 * x2**2 + f2 * x1**2 - x1 * x2 * (x2 * p1 + x1 * p2) +
450  + 2.d0* x1 * x2 * (f1 * x2 - f2 * x1) / (x1 - x2)) /
451  / ((x1 - x2) * (x1 - x2))
452 C ----------------------------------------------------------------------
453 C -- FCDCD0 GIVES THE VALUE OF THE FUNCTION AT POINT PX --
454 C -- FCDCD0(......,PX) = F(PX) --
455 C ----------------------------------------------------------------------
456  fcdcd0(x1,f1,p1,x2,f2,p2,px) =
457  = fc0(x1,f1,p1,x2,f2,p2) +
458  + px * (fc1(x1,f1,p1,x2,f2,p2) +
459  + px * (fc2(x1,f1,p1,x2,f2,p2) +
460  + px * fc3(x1,f1,p1,x2,f2,p2)))
461 C ----------------------------------------------------------------------
462 C -- FCDCD1 GIVES THE VALUE OF THE FIRST DERIVATIVE OF F(X) AT PX: --
463 C -- FCDCD1(......,PX) = DF/DX (PX) --
464 C ----------------------------------------------------------------------
465  fcdcd1(x1,f1,p1,x2,f2,p2,px) =
466  = fc1(x1,f1,p1,x2,f2,p2) +
467  + px * (2.d0* fc2(x1,f1,p1,x2,f2,p2) +
468  + 3.d0* px * fc3(x1,f1,p1,x2,f2,p2))
469 C ----------------------------------------------------------------------
470 C -- FCDCD2 GIVES THE VALUE OF THE SECOND DERIVATIVE OF F(X) AT PX: --
471 C -- FCDCD2(......,PX) = D2F/DX2 (PX) --
472 C ----------------------------------------------------------------------
473  fcdcd2(x1,f1,p1,x2,f2,p2,px) =
474  = 2.d0* fc2(x1,f1,p1,x2,f2,p2) +
475  + 6.d0* fc3(x1,f1,p1,x2,f2,p2) * px
476 C ----------------------------------------------------------------------
477 C -- FCDCD3 GIVES THE VALUE OF THE THIRD DERIVATIVE OF F(X) AT PX: --
478 C -- FCDCD3(......,PX) = D3F/DX3 (PX) --
479 C ----------------------------------------------------------------------
480  fcdcd3(x1,f1,p1,x2,f2,p2,px) =
481  = 6.d0* fc3(x1,f1,p1,x2,f2,p2)
482 C-----------------------------------------------------------------------
483 C*COMDECK QUAQDQ
484 C ----------------------------------------------------------------------
485 C -- STATEMENT FUNCTION FOR QUADRATIC INTERPOLATION --
486 C -- 19.01.87 AR CRPP --
487 C -- --
488 C -- QUADRATIC INTERPOLATION OF A FUNCTION F(X) --
489 C -- THE FIVE PARAMETERS X1,F1,P1,X2,F2 ARE DEFINED AS FOLLOWS: --
490 C -- F(X1) = F1 , DF/DX(X1) = P1 , F(X2) = F2 --
491 C ----------------------------------------------------------------------
492 C
493  fd2(x1,f1,p1,x2,f2) = ((f2-f1)/(x2-x1) - p1) / (x2-x1)
494  fd1(x1,f1,p1,x2,f2) = p1 - 2.*x1*fd2(x1,f1,p1,x2,f2)
495  fd0(x1,f1,p1,x2,f2) = f1 - x1*(x1*fd2(x1,f1,p1,x2,f2) +
496  + fd1(x1,f1,p1,x2,f2))
497 C ----------------------------------------------------------------------
498 C -- FQDQ0 GIVES THE VALUE OF THE FUNCTION AT POINT PX --
499 C -- FQDQ0(......,PX) = F(PX) --
500 C ----------------------------------------------------------------------
501  fqdq0(x1,f1,p1,x2,f2,px) = fd0(x1,f1,p1,x2,f2) +
502  f px * (fd1(x1,f1,p1,x2,f2) +
503  f px * fd2(x1,f1,p1,x2,f2))
504 C ----------------------------------------------------------------------
505 C -- FQDQ1 GIVES THE VALUE OF THE FIRST DERIVATIVE OF F(X) AT PX --
506 C -- FQDQ1(......,PX) = DF/DX (PX) --
507 C ----------------------------------------------------------------------
508  fqdq1(x1,f1,p1,x2,f2,px) = fd1(x1,f1,p1,x2,f2) +
509  f 2.* px * fd2(x1,f1,p1,x2,f2)
510 C ----------------------------------------------------------------------
511 C -- FQDQ2 GIVES THE VALUE OF THE SECOND DERIVATIVE OF F(X) AT PX --
512 C -- FQDQ2(......,PX) = D2F/DX2 (PX) --
513 C ----------------------------------------------------------------------
514  fqdq2(x1,f1,p1,x2,f2) = 2.d0* fd2(x1,f1,p1,x2,f2)
515 C-----------------------------------------------------------------------
516 
517  klo=1
518  khi=n
519 1 IF (khi-klo.GT.1) THEN
520  k=(khi+klo)/2
521  IF(xa(k).GT.x)THEN
522  khi=k
523  ELSE
524  klo=k
525  ENDIF
526  goto 1
527  ENDIF
528  h=xa(khi)-xa(klo)
529  IF (h.EQ.0.) stop 'BAD XA INPUT.'
530  a=(xa(khi)-x)/h
531  b=(x-xa(klo))/h
532  y=a*ya(klo)+b*ya(khi)+
533  * ((a**3-a)*y2a(klo)+(b**3-b)*y2a(khi))*(h**2)/6.
534  yp=(ya(khi)-ya(klo))/h -
535  - ( (3.*a*a-1.)*y2a(klo) - (3.*b*b-1.)*y2a(khi) )*h/6.
536  ypp=a*y2a(klo)+b*y2a(khi)
537 
538  IF (kopt .EQ. 0) RETURN
539 C
540 C ZEPSILON: DISTANCE OUTSIDE INTERVAL RELATIVE TO H
541 C
542  zepsilon = 1.0d-05
543 c
544 c x outside interval: use quadratic with y and yp at edge and y-1
545 c
546  IF (kopt .EQ. 1) THEN
547 C LEFT END
548  if (b.lt. -zepsilon) then
549  print *,' warning points outside interval at left.',
550  + ' Use quadratic interpolation'
551  a=1.d0
552  b=0.d0
553  ypaklo=(ya(khi)-ya(klo))/h -
554  - ( (3.d0*a*a-1.d0)*y2a(klo) - (3.d0*b*b-1.d0)*y2a(khi) )*h/6.d0
555  a=0.d0
556  b=1.d0
557  ypakhi=(ya(khi)-ya(klo))/h -
558  - ( (3.d0*a*a-1.d0)*y2a(klo) - (3.d0*b*b-1.d0)*y2a(khi) )*h/6.d0
559  y=fqdq0(xa(klo),ya(klo),ypaklo,xa(khi),ya(khi),x)
560  yp=fqdq1(xa(klo),ya(klo),ypaklo,xa(khi),ya(khi),x)
561  ypp=fqdq2(xa(klo),ya(klo),ypaklo,xa(khi),ya(khi))
562  endif
563 C RIGHT END
564  if (a .lt. -zepsilon) then
565  print *,' warning points outside interval at right.',
566  + ' Use quadratic interpolation'
567  a=1.d0
568  b=0.d0
569  ypaklo=(ya(khi)-ya(klo))/h -
570  - ( (3.d0*a*a-1.d0)*y2a(klo) - (3.d0*b*b-1.d0)*y2a(khi) )*h/6.d0
571  a=0.d0
572  b=1.d0
573  ypakhi=(ya(khi)-ya(klo))/h -
574  - ( (3.d0*a*a-1.d0)*y2a(klo) - (3.d0*b*b-1.d0)*y2a(khi) )*h/6.d0
575  y=fqdq0(xa(khi),ya(khi),ypakhi,xa(klo),ya(klo),x)
576  yp=fqdq1(xa(khi),ya(khi),ypakhi,xa(klo),ya(klo),x)
577  ypp=fqdq2(xa(khi),ya(khi),ypakhi,xa(klo),ya(klo))
578  endif
579 
580  RETURN
581  ENDIF
582 c
583 c x outside interval: use CUBIC with y and yp
584 c
585  IF (kopt .EQ. 2) THEN
586 C LEFT OR RIGHT END
587  if (a.lt.-zepsilon .OR. b.LT.-zepsilon) then
588  print *,' warning points outside interval.',
589  + ' Use cubic interpolation'
590  a=1.d0
591  b=0.d0
592  ypaklo=(ya(khi)-ya(klo))/h -
593  - ( (3.d0*a*a-1.d0)*y2a(klo) - (3.d0*b*b-1.d0)*y2a(khi) )*h/6.d0
594  a=0.d0
595  b=1.d0
596  ypakhi=(ya(khi)-ya(klo))/h -
597  - ( (3.d0*a*a-1.d0)*y2a(klo) - (3.d0*b*b-1.d0)*y2a(khi) )*h/6.d0
598  y=fcdcd0(xa(klo),ya(klo),ypaklo,xa(khi),ya(khi),ypakhi,x)
599  yp=fcdcd1(xa(klo),ya(klo),ypaklo,xa(khi),ya(khi),ypakhi,x)
600  ypp=fcdcd2(xa(klo),ya(klo),ypaklo,xa(khi),ya(khi),ypakhi,x)
601  endif
602  RETURN
603  ENDIF
604 
605  RETURN
606  END SUBROUTINE
607 C
608 C
609 C
610  SUBROUTINE nonsym(A,X,C,N,MLEFT,MRIGHT,EPS,NCOND)
611 C *************************************************
612 C
613 C 5.3 SOLVES A REAL VALUED NONSYMMETRIC LINEAR SYSTEM A . X = C
614 C
615 C VERSION 1 APRIL 1988 KA LAUSANNE
616 C VERSION 2 MAI 1992 AJ LAUSANNE
617 C
618 C-----------------------------------------------------------------------
619 
620  IMPLICIT REAL*8(a-h,o-z)
621 
622  dimension a(n*(mleft+mright+1)), x(n), c(n)
623 CMPLX COMPLEX A, X, C, ZPIVOT, ZSUM, ZTOP
624  REAL*8 a, x, c, zpivot, zsum, ztop
625  DATA imess / 0 /
626 C-----------------------------------------------------------------------
627 C
628 C A IS A BANDMATRIX OF RANK N WITH MLEFT/MRIGHT OFF-DIAGONAL
629 C ELEMENTS TO THE LEFT/RIGHT.
630 C :A: AND :C: ARE DESTROYED BY :NONCYM:
631 C AT THE RETURN :C: CONTAINS THE SOLUTION VECTOR, :X: THE SQUARE
632 C ROOT OF THE DIAGONAL ELEMENTS
633 C
634 C THE ELEMENTS ARE HORIZONTALLY NUMBERED ROW AFTER ROW
635 C
636 C FOR EASY NUMBERING, ZERO ELEMENTS HAVE BEEN INTRODUCED IN THE
637 C UPPER LEFT-HAND CORNER AND IN THE LOWER RIGHT-HAND CORNER.
638 C THESE ELEMENTS
639 C M U S T B E S E T T O Z E R O
640 C BEFORE CALLING :NONCYM:
641 C
642 C EXAMPLE FOR NUMBERING MLEFT=2, MRIGHT=3
643 C -------
644 C
645 C A(1) A(2) I A(3) A(4) A(5) A(6)
646 C A(7) I A(8) A(9) A(10) A(11) A(12)
647 C I .
648 C I .
649 C
650 C A PIVOT IS CONSIDERED TO BE BAD IF IT IS BY A FACTOR :EPS: SMALLER
651 C THAN ITS OFF-DIAGONAL ELEMENTS. IF A BAD PIVOT IS ENCOUNTERED
652 C A MESSAGE IS ISSUED (AT MOST TEN TIMES IN A RUN).
653 C THE FLAG :NCOND: IS SET TO -1, OTHERWISE 0.
654 C
655 C-----------------------------------------------------------------------
656 CL 0. INITIALIZATION
657 C
658  moffdi=mleft+mright
659  mband=moffdi+1
660  ratio=0.d0
661  ncond=0
662 C PRELIMINARY CHECK OF PIVOTS
663  ipiv1=mleft+1
664  ipiv2=ipiv1+(n-1)*mband
665  DO 10 j=ipiv1,ipiv2,mband
666 CMPLX IF(CABS(A(J)) .EQ. 0.D0) GO TO 510
667  IF( abs(a(j)) .EQ. 0.d0) go to 510
668  10 CONTINUE
669 C
670 C-----------------------------------------------------------------------
671 CL 1. PRECONDITIONNING: GET ONES ON THE DIAGONAL
672 C
673  DO 130 jp=1,n
674  jpabs=(mleft+1)+(jp-1)*mband
675 CMPLX X(JP)=SQRT(CABS(A(JPABS)))
676  x(jp)=sqrt(abs(a(jpabs)))
677 C
678 C DIVIDE THE EQUATIONS BY THE SQUARE ROOT OF THE PIVOT
679  DO 110 j=-mleft,mright
680  a(jpabs+j)=a(jpabs+j)/x(jp)
681  110 CONTINUE
682  c(jp)=c(jp)/x(jp)
683 C
684 C CHANGE VARIABLES, DIVIDE COLUMN BY SQUARE ROOT OF THE PIVOT
685  DO 120 ja=jpabs-mright*moffdi,jpabs+mleft*moffdi,moffdi
686  IF (ja.GE.ipiv1 .AND. ja.LE.ipiv2) a(ja)=a(ja)/x(jp)
687  120 CONTINUE
688  130 CONTINUE
689 C
690 C-----------------------------------------------------------------------
691 CL 2. CONSTRUCT UPPER TRIANGULAR MATRIX
692 C
693 C INITIALIZATION OF VERTICAL COUNTER
694  idown=mleft
695 C PIVOT INDEX FOR FIRST INCOMPLETE COLUMN
696  incmpl=(n-mleft)*mband+mleft+1
697 C FIRST PIVOT AND LAST BUT ONE
698  ipiv1=mleft+1
699  ipiv2=ipiv1+(n-2)*mband
700 C
701  DO 220 jpivot=ipiv1,ipiv2,mband
702 C COLUMN LENGTH
703  IF(jpivot.GE.incmpl) idown=idown-1
704  zpivot=a(jpivot)
705 C FIRST AND LAST HORIZONTAL ELEMENT INDEX
706  ihor1=jpivot+1
707  ihor2=jpivot+mright
708 C CHECK THE PIVOT
709  zmax=0.d0
710  DO 205 jhoriz=ihor1,ihor2
711 CMPLX ZMAX=AMAX1(ZMAX,CABS(A(JHORIZ)))
712  zmax=amax1(zmax, abs(a(jhoriz)))
713  205 CONTINUE
714 CMPLX IF(CABS(ZPIVOT).EQ.0.D0) GO TO 510
715  IF( abs(zpivot).EQ.0.d0) go to 510
716 CMPLX RATIO=AMAX1(RATIO,ZMAX/CABS(ZPIVOT))
717  ratio=amax1(ratio,zmax/ abs(zpivot))
718 C
719  DO 210 jhoriz=ihor1,ihor2
720  ztop=-a(jhoriz)/zpivot
721  a(jhoriz)=ztop
722 C INITIALIZATION OF ELEMENT INDEX
723  ielem=jhoriz
724 C INITIALIZATION OF RECTANGULAR RULE CORNER ELEMENT
725  icorn=jpivot
726 C LOOP DOWN THE COLUMN
727  DO 211 jdown=1,idown
728  ielem=ielem+moffdi
729  icorn=icorn+moffdi
730  a(ielem)=a(ielem)+ztop*a(icorn)
731  211 CONTINUE
732  210 CONTINUE
733 C TREAT THE CONSTANTS
734 C INDEX OF THE FIRST ONE
735  iconst=jpivot/mband+1
736  ztop=-c(iconst)/zpivot
737  c(iconst)=ztop
738 C INITIALIZATION OF RECTANGULAR RULE CORNER ELEMENT
739  icorn=jpivot
740 C LOOP DOWN THE CONSTANTS
741  DO 221 jdown=1,idown
742  iconst=iconst+1
743  icorn=icorn+moffdi
744  c(iconst)=c(iconst)+ztop*a(icorn)
745  221 CONTINUE
746  220 CONTINUE
747 C
748 C-----------------------------------------------------------------------
749 CL 3. BACKSUBSTITUTION
750 C
751  300 CONTINUE
752 C INITIALIZATION OF SOLUTION INDEX
753  isolut=n
754 C LAST PIVOT
755  jpivot=ipiv2+mband
756 C CHECK LAST PIVOT
757 CMPLX IF(CABS(A(JPIVOT)).EQ.0.D0) RATIO=1.D100
758 c%OS IF( ABS(A(JPIVOT)).EQ.0.D0) RATIO=1.D100
759  IF( abs(a(jpivot)).EQ.0.d0) go to 510
760 C LAST UNKNOWN
761  c(isolut)=c(isolut)/a(jpivot)
762 C INITIALIZATION OF HORIZONTAL RANGE
763  ihor1=jpivot+1
764  ihor2=jpivot+mright
765 C
766  inm1=n-1
767  DO 320 j=1,inm1
768  isolut=isolut-1
769  ihor1=ihor1-mband
770  ihor2=ihor2-mband
771  zsum=-c(isolut)
772  iknown=isolut
773  DO 310 jhoriz=ihor1,ihor2
774  iknown=iknown+1
775  IF(iknown.GT.n) go to 310
776  zsum=zsum+a(jhoriz)*c(iknown)
777  310 CONTINUE
778  c(isolut)=zsum
779  320 CONTINUE
780 C
781 C-----------------------------------------------------------------------
782 CL 4. PRECONDITIONNING: BACK TO ORIGINAL VARIABLES
783 C
784  DO 410 j=1,n
785  c(j)=c(j)/x(j)
786  410 CONTINUE
787 C
788 C-----------------------------------------------------------------------
789 CL 5. HAVE WE ENCOUNTERED A BAD PIVOT ?
790 C
791 C%OS IF(1./RATIO .GT. EPS) RETURN
792  IF(ratio .LT. 1.d0/eps) RETURN
793  ncond=-1
794 C COUNT THE NUMBER OF MESSAGES ISSUED
795  imess=imess+1
796  IF(imess.LE.10) print 9500, ratio
797  RETURN
798 C
799 C ZERO PIVOT ENCOUNTERED
800  510 CONTINUE
801  print 9510
802  stop 'ZERO PIVOT IN NONCYM'
803 C
804 C-----------------------------------------------------------------------
805 CL 9. FORMATS
806 C
807 
808  9500 FORMAT(/////20x,10(1h*),21h message from noncym,2x,10(1h*)///
809  + 20x,'BAD PIVOT ENCOUNTERED, RATIO: ',1pe12.3///
810  + 20x,43(1h*)///)
811  9510 FORMAT(/////20x,10(1h*),' ZERO PIVOT IN NONCYM'///)
812 C
813  END SUBROUTINE
814 
815  end module spider_spline
subroutine splintend(XA, YA, Y2A, N, X, Y, YP, YPP, KOPT)
subroutine nonsym(A, X, C, N, MLEFT, MRIGHT, EPS, NCOND)
subroutine spline(N, X, Y, ALFA, BETA, TYP, A, B, C, D)
Definition: solution6.f90:655
subroutine cubsplfit(X, Y, YNEW, N, YP1, YPN, Y2, TAUS, WORK, AMAT, MDAMAT)
Definition: spider_spline.f:76
real(r8) function b2(a, x, xr, xs, yr, ys, psi, psir, F_dia)
real(r8) function p(a, x, xr, xs, yr, ys, psi, psir, F_dia)
subroutine splint(XA, YA, Y2A, N, X, Y, YP, YPP)
subroutine intrptau(PXIN, PYIN, PYINNEW, PY2, KNIN, PXOUT, PYOUT, PYOUTP, PYOUTPP, KNOUT, KOPT, PTAUS, PWORK, PAMAT, MDAMAT, PBCLFT, PBCRGT)
Definition: spider_spline.f:5