V3FIT
evspline.f
1  subroutine evspline(xget,x,nx,ilinx,f,ict,fval,ier)
2 C
3 C use mkspline to set up spline coefficients...
4 C
5 C evaluate a 1d cubic Spline interpolant -- this is C2
6 C
7 C this subroutine calls two subroutines:
8 C herm1x -- find cell containing (xget)
9 C fvspline -- evaluate interpolant function and (optionally) derivatives
10 C
11 C input arguments:
12 C ================
13 C
14  integer nx ! grid size
15  real xget ! target of this interpolation
16  real x(nx) ! ordered x grid
17  integer ilinx ! ilinx=1 => assume x evenly spaced
18 C
19  real f(0:1,nx) ! function data
20 C
21 C f(0,i) = f @ x(i)
22 C f(1,i) = d2f/dx2 @ x(i)
23 C
24 C (these are spline coefficients selected for continuous 2-
25 C diffentiability, see mkspline.for)
26 C
27  integer ict(3) ! code specifying output desired
28 C
29 C ict(1)=1 -- return f (0, don't)
30 C ict(2)=1 -- return df/dx (0, don't)
31 C ict(3)=1 -- return d2f/dx2 (0, don't)
32 c
33 c set ict(1)=3 to get d3f/dx3 (only)
34 C
35 C output arguments:
36 C =================
37 C
38  real fval(*) ! output data
39  integer ier ! error code =0 ==> no error
40 C
41 C fval(1) receives the first output (depends on ict(...) spec)
42 C fval(2) receives the second output (depends on ict(...) spec)
43 C fval(3) receives the third output (depends on ict(...) spec)
44 C
45 C examples:
46 C on input ict = [1,1,1]
47 C on output fval= [f,df/dx,d2f/dx2]
48 C
49 C on input ict = [1,0,0]
50 C on output fval= [f] ... elements 2 -- 3 never referenced.
51 C
52 C on input ict = [0,0,1]
53 C on output fval= [d2f/dx2] ... elements 2 -- 3 never referenced.
54 C
55 C ier -- completion code: 0 means OK
56 C-------------------
57 C local:
58 C
59  integer i(1) ! cell indices
60 C
61 C normalized displacement from x(i) grid point.
62 C xparam=0 @x(i) xparam=1 @x(i+1)
63 C
64  real xparam(1)
65 C
66 C cell dimensions and
67 C inverse cell dimensions hxi = 1/(x(i+1)-x(i))
68 C
69  real hx(1)
70  real hxi(1)
71 C
72 C 0 .le. xparam .le. 1
73 C
74 C ** the interface is very similar to herm2ev.for; can use herm2xy **
75 C---------------------------------------------------------------------
76 C
77  i(1)=0
78 C
79  call herm1x(xget,x,nx,ilinx,i(1),xparam(1),hx(1),hxi(1),ier)
80  if(ier.ne.0) return
81 c
82  call fvspline(ict,1,1,fval,i,xparam,hx,hxi,f,nx)
83 C
84  return
85  end
86 C---------------------------------------------------------------------
87 C evaluate C1 cubic Hermite function interpolation -- 2d fcn
88 C --vectorized-- dmc 10 Feb 1999
89 C
90  subroutine fvspline(ict,ivec,ivecd,
91  > fval,ii,xparam,hx,hxi,fin,nx)
92 C
93 C use mkspline to set up spline coefficients...
94 C
95  integer ict(3) ! requested output control
96  integer ivec ! vector length
97  integer ivecd ! vector dimension (1st dim of fval)
98 C
99  integer ii(ivec) ! target cells (i)
100  real xparam(ivec)
101  ! normalized displacements from (i) corners
102 C
103  real hx(ivec) ! grid spacing, and
104  real hxi(ivec) ! inverse grid spacing 1/(x(i+1)-x(i))
105 C
106  real fin(0:1,nx) ! interpolant data (cf "evspline")
107 C
108  real fval(ivecd,*) ! output returned
109 C
110 C for detailed description of fin, ict and fval see subroutine
111 C evspline comments. Note ict is not vectorized; the same output
112 C is expected to be returned for all input vector data points.
113 C
114 C note that the index inputs ii and parameter inputs
115 C xparam,hx,hxi, are vectorized, and the
116 C output array fval has a vector ** 1st dimension ** whose
117 C size must be given as a separate argument
118 C
119 C to use this routine in scalar mode, pass in ivec=ivecd=1
120 C
121 C---------------
122 C Spline evaluation consists of a "mixing" of the interpolant
123 C data using the linear functionals xparam, xpi = 1-xparam,
124 C xparam**3-xparam, xpi**3-xpi ...
125 C and their derivatives as needed.
126 C
127  integer v
128 C
129  real sum
130  real sixth
131 C
132  data sixth/0.166666666666666667/
133 C
134 C---------------
135 C ...in x direction
136 C
137  iadr=0
138 C
139  if(ict(1).le.2) then
140 C
141 C normal call
142 C
143  if(ict(1).eq.1) then
144 C
145 C get desired values:
146 C
147  iadr = iadr + 1
148  do v=1,ivec
149  i=ii(v)
150 C
151  xp=xparam(v)
152  xpi=1.0-xp
153  xp2=xp*xp
154  xpi2=xpi*xpi
155 C
156  cx=xp*(xp2-1.0)
157  cxi=xpi*(xpi2-1.0)
158  hx2=hx(v)*hx(v)
159 C
160 C function value:
161 C
162  sum=xpi*fin(0,i) +xp*fin(0,i+1)
163  sum=sum+sixth*hx2*(cxi*fin(1,i) +cx*fin(1,i+1))
164 C
165  fval(v,iadr)=sum
166  enddo
167  endif
168 C
169  if(ict(2).eq.1) then
170 C
171 C df/dx:
172 C
173  iadr=iadr+1
174  do v=1,ivec
175  i=ii(v)
176 C
177  xp=xparam(v)
178  xpi=1.0-xp
179  xp2=xp*xp
180  xpi2=xpi*xpi
181 C
182  cxd=3.0*xp2-1.0
183  cxdi=-3.0*xpi2+1.0
184 
185  sum=hxi(v)*(fin(0,i+1)-fin(0,i))
186  sum=sum+sixth*hx(v)*(cxdi*fin(1,i) +cxd*fin(1,i+1))
187 C
188  fval(v,iadr)=sum
189  enddo
190  endif
191 C
192  if(ict(3).eq.1) then
193 C
194 C d2f/dx2:
195 C
196  iadr=iadr+1
197  do v=1,ivec
198  i=ii(v)
199 C
200  xp=xparam(v)
201  xpi=1.0-xp
202 C
203  sum=xpi*fin(1,i) +xp*fin(1,i+1)
204  fval(v,iadr)=sum
205  enddo
206  endif
207 C
208  else
209 C
210 C return fxxx = d3f/dx3
211 C
212  iadr=1
213  do v=1,ivec
214  i=ii(v)
215  fval(v,iadr)=hxi(v)*(fin(1,i+1)-fin(1,i))
216  enddo
217 C
218  endif
219 C
220  return
221  end