V3FIT
All Classes Namespaces Files Functions Variables Enumerations Macros Pages
bspline.f90
1  module bspline
2  use stel_kinds
3  implicit none
4 !
5 ! VERSION 2.2
6 !
7 ! f90 VERSION
8 !
9 ! This library contains routines for B-spline interpolation in
10 ! one, two, and three dimensions. Part of the routines are based
11 ! on the book by Carl de Boor: A practical guide to Splines (Springer,
12 ! New-York 1978) and have the same calling sequence and names as
13 ! the corresponding routines from the IMSL library. For documen-
14 ! tation see the additional files. NOTE: The results in the demo
15 ! routines may vary slightly on different architectures.
16 !
17 ! by W. Schadow 12/04/99
18 ! last changed by W. Schadow 07/28/2000
19 !
20 !
21 ! Wolfgang Schadow
22 ! TRIUMF
23 ! 4004 Wesbrook Mall
24 ! Vancouver, B.C. V6T 2A3
25 ! Canada
26 !
27 ! email: schadow@triumf.ca or schadow@physik.uni-bonn.de
28 !
29 ! www : http://www.triumf.ca/people/schadow
30 !
31 ! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
32 !!
33 ! Copyright (C) 2000 Wolfgang Schadow
34 !
35 ! This library is free software; you can redistribute it and/or
36 ! modify it under the terms of the GNU Library General Public
37 ! License as published by the Free Software Foundation; either
38 ! version 2 of the License, or (at your option) any later version.
39 !
40 ! This library is distributed in the hope that it will be useful,
41 ! but WITHOUT ANY WARRANTY; without even the implied warranty of
42 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
43 ! Library General Public License for more details.
44 !
45 ! You should have received a copy of the GNU Library General Public
46 ! License along with this library; if not, write to the
47 ! Free Software Foundation, Inc., 59 Temple Place - Suite 330,
48 ! Boston, MA 02111-1307, USA.
49 !
50 !
51 ! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52  real(rprec), parameter :: one=1, zero=0, p5=0.5_dp
53  integer, parameter :: idebug = 0
54 
55 !
56 ! ------------------------------------------------------------------
57 !
58 ! The following routines are included:
59 !
60 ! dbsnak
61 ! dbsint
62 ! dbsval
63 ! dbsder
64 ! dbs1gd
65 ! dbs2in
66 ! dbs2dr
67 ! dbs2vl
68 ! dbs2gd
69 ! dbs3in
70 ! dbs3vl
71 ! dbs3dr
72 ! dbs3gd
73 !
74 ! ------------------------------------------------------------------
75 !
76 
77  private
78 
79  public dbsnak
80  public dbsint, dbsval, dbsder, dbs1gd
81  public dbs2in, dbs2dr, dbs2vl, dbs2gd
82  public dbs3in, dbs3vl, dbs3dr, dbs3gd
83 
84  public dbs3vd
85 
86 contains
87 
88 
89  subroutine dbsnak(nx,xvec,kxord,xknot)
90 
91 !
92 ! Compute the `not-a-knot' spline knot sequence.
93 ! (see de Boor p. 167)
94 !
95 ! nx - number of data points. (input)
96 ! xvec - array of length ndata containing the location of the
97 ! data points. (input)
98 ! kxord - order of the spline. (input)
99 ! xknot - array of length ndata+korder containing the knot
100 ! sequence. (output)
101 !
102  implicit none
103 
104  integer, intent(in) :: nx, kxord
105 
106  real(rprec), dimension(nx), intent(in) :: xvec
107  real(rprec), dimension(nx+kxord), intent(out) :: xknot
108 
109  real(rprec) :: eps
110  integer :: ix
111  logical :: first = .true.
112 
113 ! save first,eps
114 
115 
116 ! if (first) then
117 ! first=.false.
118 ! eps = epsilon(one)
119 ! write(6,*) "subroutine dbsnak: "
120 ! write(6,*) "eps = ",eps
121 ! endif
122  eps = epsilon(one)
123 
124  if((kxord .lt. 0) .or. (kxord .gt. nx)) then
125  write(6,*) "subroutine dbsnak: error"
126  write(6,*) "0 <= kxord <= nx is required."
127  write(6,*) "kxord = ", kxord, " and nx = ", nx, " is given."
128  stop
129  endif
130 
131  do ix = 1, kxord
132  xknot(ix) = xvec(1)
133  end do
134 
135  if(mod(kxord,2) .eq. 0) then
136  do ix = kxord+1, nx
137  xknot(ix) = xvec(ix-kxord/2)
138  end do
139  else
140  do ix = kxord+1, nx
141  xknot(ix) = p5 * (xvec(ix-kxord/2) + xvec(ix-kxord/2-1))
142  end do
143  endif
144 
145  do ix = nx+1, nx+kxord
146  xknot(ix) = xvec(nx) * (one + eps)
147  end do
148 
149  end subroutine dbsnak
150 
151 
152  subroutine dbsint(nx,xvec,xdata,kx,xknot,bcoef)
153 
154 !
155 ! Computes the spline interpolant, returning the B-spline coefficients.
156 ! (see de Boor p. 204)
157 !
158 ! nx - number of data points. (input)
159 ! xvec - array of length nx containing the data point
160 ! abscissas. (input)
161 ! xdata - array of length ndata containing the data point
162 ! ordinates. (input)
163 ! kx - order of the spline. (input)
164 ! korder must be less than or equal to ndata.
165 ! xknot - array of length nx+kx containing the knot
166 ! sequence. (input)
167 ! xknot must be nondecreasing.
168 ! bscoef - array of length ndata containing the B-spline
169 ! coefficients. (output)
170 !
171 
172  implicit none
173 
174  integer, intent(in) :: nx, kx
175  real(rprec), dimension(nx), intent(in) :: xdata, xvec
176  real(rprec), dimension(nx+kx), intent(in) :: xknot
177  real(rprec), dimension(nx), intent(out) :: bcoef
178 
179  integer :: nxp1, kxm1, kpkm2, leftx, lenq
180  integer :: ix, ik,ilp1mx, jj, iflag
181  real(rprec) :: xveci
182  real(rprec), dimension((2*kx-1)*nx) :: work
183 
184 
185  nxp1 = nx + 1
186  kxm1 = kx - 1
187  kpkm2 = 2 * kxm1
188  leftx = kx
189  lenq = nx * (kx + kxm1)
190 
191  do ix = 1, lenq
192  work(ix) = zero
193  end do
194 
195  do ix = 1, nx
196  xveci = xvec(ix)
197  ilp1mx = min(ix+kx,nxp1)
198  leftx = max(leftx,ix)
199  if (xveci .lt. xknot(leftx)) goto 998
200 30 if (xveci .lt. xknot(leftx+1)) go to 40
201  leftx = leftx + 1
202  if (leftx .lt. ilp1mx) go to 30
203  leftx = leftx - 1
204  if (xveci .gt. xknot(leftx+1)) goto 998
205 40 call bsplvb (xknot,nx+kx,kx,1,xveci,leftx,bcoef)
206  jj = ix - leftx + 1 + (leftx - kx) * (kx + kxm1)
207  do ik = 1, kx
208  jj = jj + kpkm2
209  work(jj) = bcoef(ik)
210  end do
211  end do
212 
213  call banfac(work,kx+kxm1,nx,kxm1,kxm1,iflag)
214 
215  if (iflag .ne. 1) then
216  write(6,*) "subroutine dbsint: error"
217  write(6,*) "no solution of linear equation system !!!"
218  stop
219  end if
220 
221  do ix = 1, nx
222  bcoef(ix) = xdata(ix)
223  end do
224 
225  call banslv(work,kx+kxm1,nx,kxm1,kxm1,bcoef)
226 
227  return
228 
229 998 write(6,*) "subroutine dbsint:"
230  write(6,*) "xknot(ix) <= xknot(ix+1) required."
231  write(6,*) ix,xknot(ix),xknot(ix+1)
232 
233  stop
234 
235  end subroutine dbsint
236 
237 
238  function dbsval(x,kx,xknot,nx,bcoef)
239 
240 !
241 ! Evaluates a spline, given its B-spline representation.
242 !
243 ! x - point at which the spline is to be evaluated. (input)
244 ! kx - order of the spline. (input)
245 ! xknot - array of length nx+kx containing the knot
246 ! sequence. (input)
247 ! xknot must be nondecreasing.
248 ! nx - number of B-spline coefficients. (input)
249 ! bcoef - array of length nx containing the B-spline
250 ! coefficients. (input)
251 ! dbsval - value of the spline at x. (output)
252 !
253 
254  implicit none
255 
256  integer, intent(in) :: nx, kx
257  real(rprec) :: dbsval
258  real(rprec) :: x
259  real(rprec), dimension(nx+kx), intent(in) :: xknot
260  real(rprec), dimension(nx), intent(in) :: bcoef
261 
262  integer :: il, ik, ix, leftx
263  real(rprec) :: save1, save2
264  real(rprec), dimension(kx) :: work, dl, dr
265 
266 !
267 ! check if xknot(i) <= xknot(i+1) and calculation of i so that
268 ! xknot(i) <= x < xknot(i+1)
269 !
270 
271  leftx = 0
272 
273  do ix = 1,nx+kx-1
274  if (xknot(ix) .gt. xknot(ix+1)) then
275  write(6,*) "subroutine dbsval:"
276  write(6,*) "xknot(ix) <= xknot(ix+1) required."
277  write(6,*) ix,xknot(ix),xknot(ix+1)
278  stop
279  endif
280  if((xknot(ix) .le. x) .and. (x .lt. xknot(ix+1))) leftx = ix
281  end do
282 
283  if(leftx .eq. 0) then
284  write(6,*) "subroutine dbsval:"
285  write(6,*) "ix with xknot(ix) <= x < xknot(ix+1) required."
286  write(6,*) "x = ", x
287  stop
288  endif
289 
290  do ik = 1, kx-1
291  work(ik) = bcoef(leftx+ik-kx)
292  dl(ik) = x - xknot(leftx+ik-kx)
293  dr(ik) = xknot(leftx+ik) - x
294  end do
295 
296  work(kx) = bcoef(leftx)
297  dl(kx) = x - xknot(leftx)
298 
299  do ik = 1, kx-1
300  save2 = work(ik)
301  do il = ik+1, kx
302  save1 = work(il)
303  work(il) = (dl(il) * work(il) + dr(il-ik) * save2) &
304  & / (dl(il) + dr(il - ik))
305  save2 = save1
306  end do
307  end do
308 
309  dbsval = work(kx)
310 
311  end function dbsval
312 
313 
314  function dbsder(iderx,x,kx,xknot,nx,bcoef)
315 
316 !
317 ! Evaluates the derivative of a spline, given its B-spline representation.
318 !
319 !
320 ! iderx - order of the derivative to be evaluated. (input)
321 ! in particular, iderx = 0 returns the value of the
322 ! spline.
323 ! x - point at which the spline is to be evaluated. (input)
324 ! kx - order of the spline. (input)
325 ! xknot - array of length nx+kx containing the knot
326 ! sequence. (input)
327 ! xknot must be nondecreasing.
328 ! nx - number of B-spline coefficients. (input)
329 ! bcoef - array of length nx containing the B-spline
330 ! coefficients. (input)
331 ! dbsder - value of the iderx-th derivative of the spline at x.
332 ! (output)
333 !
334 
335  implicit none
336 
337  integer, intent(in) :: iderx, kx, nx
338  real(rprec) :: dbsder
339  real(rprec), intent(in) :: x
340  real(rprec), dimension(nx+kx), intent(in) :: xknot
341  real(rprec), dimension(nx), intent(in) :: bcoef
342 
343  integer :: ix, ik, il, leftx
344  real(rprec) :: save0, save1, save2, y, sum, dik
345  real(rprec), dimension(kx) :: work, dl, dr,bsp
346 
347 !
348 ! check if xknot(i) <= xknot(i+1) and calculation of i so that
349 ! xknot(i) <= x < xknot(i+1)
350 !
351 
352  leftx = 0
353  do ix = 1,nx+kx-1
354  if (xknot(ix) .gt. xknot(ix+1)) then
355  write(6,*) "subroutine dbsder:"
356  write(6,*) "xknot(ix) <= xknot(ix+1) required."
357  stop
358  endif
359  if ((xknot(ix) .le. x) .and. (x .lt. xknot(ix+1))) leftx = ix
360  end do
361 
362  if (leftx .eq. 0) then
363  write(6,*) "subroutine dbsder:"
364  write(6,*) "ix with xknot(ix) <= x < xknot(ix+1) required."
365  write(6,*) "xknot(1) = ", xknot(1)
366  write(6,*) "xknot(nx+kx) = ", xknot(nx+kx)
367  write(6,*) " x = ", x
368  stop
369  endif
370 
371  if (iderx .eq. 0) then
372 
373  do ik = 1,kx-1
374  work(ik) = bcoef(leftx+ik-kx)
375  dl(ik) = x - xknot(leftx+ik-kx)
376  dr(ik) = xknot(leftx+ik) - x
377  end do
378 
379  work(kx) = bcoef(leftx)
380  dl(kx) = x - xknot(leftx)
381 
382  do ik = 1,kx-1
383  save2 = work(ik)
384  do il = ik+1,kx
385  save1 = work(il)
386  work(il) = (dl(il) * work(il) + dr(il-ik) * save2) &
387  & / (dl(il) + dr(il - ik))
388  save2 = save1
389  end do
390  end do
391 
392  dbsder = work(kx)
393 
394  elseif ((iderx .ge. 1) .and. (iderx .lt. kx)) then
395 
396  bsp(1) = one
397  do ik = 1,kx-iderx-1
398  dr(ik) = xknot(leftx+ik) - x
399  dl(ik) = x - xknot(leftx+1-ik)
400  save0 = bsp(1)
401  bsp(1) = zero
402  do il = 1, ik
403  y = save0 / (dr(il) + dl(ik+1-il))
404  bsp(il) = bsp(il) + dr(il) * y
405  save0 = bsp(il+1)
406  bsp(il+1) = dl(ik+1-il) * y
407  end do
408  end do
409 
410  do ik = 1, kx
411  work(ik) = bcoef(leftx+ik-kx)
412  dr(ik) = xknot(leftx+ik) - x
413  dl(ik) = x - xknot(leftx+ik-kx)
414  end do
415 
416  do ik = 1, iderx
417  dik = real(kx - ik, kind=dp)
418  save2 = work(ik)
419  do il = ik+1, kx
420  save1 = work(il)
421  work(il) = dik * (work(il) - save2) /(dl(il) + dr(il-ik))
422  save2 = save1
423  end do
424  end do
425 
426  sum = zero
427 
428  do ix = 1, kx-iderx
429  sum = sum + bsp(ix) * work(iderx+ix)
430  end do
431 
432  dbsder = sum
433 
434  else
435  dbsder = zero
436  endif
437 
438  end function dbsder
439 
440 
441  subroutine dbs1gd(iderx,nxvec,xvec,kx,xknot,nx,bcoef,val)
442 
443 !
444 ! Evaluates the derivative of a spline on a grid, given its B-spline
445 ! representation.
446 !
447 ! iderx - order of the derivative to be evaluated. (input)
448 ! in particular, iderx = 0 returns the value of the
449 ! spline.
450 ! nxvec - length of vector xvec. (input)
451 ! xvec - array of length nxvec containing the points at which the
452 ! spline is to be evaluated. (input)
453 ! xvec should be strictly increasing.
454 ! kx - order of the spline. (input)
455 ! xknot - array of length nx+kx containing the knot
456 ! sequence. (input)
457 ! xknot must be nondecreasing.
458 ! nx - number of B-spline coefficients. (input)
459 ! bcoef - array of length nx containing the B-spline
460 ! coefficients. (input)
461 ! val - array of length nxvec containing the values of the
462 ! iderx-th derivative of the spline at the points in
463 ! xvec. (output)
464 !
465 
466  implicit none
467 
468  integer, intent(in) :: iderx, nxvec, kx, nx
469  real(rprec), dimension(nxvec), intent(in) :: xvec
470  real(rprec), dimension(nx), intent(in) :: bcoef
471  real(rprec), dimension(nx+kx), intent(in) :: xknot
472  real(rprec), dimension(nxvec), intent(out) :: val
473 
474  integer :: i, il, ik, ix
475  integer, dimension(nxvec) :: leftx
476  real(rprec) :: dik
477  real(rprec), dimension(nxvec,kx) :: dl, dr, biatx, work
478  real(rprec), dimension(nxvec) :: save1, save2, term
479 
480  logical :: same, next
481 
482 
483  leftx(1) = 0
484 
485  call huntn(xknot,nx+kx,kx,xvec(1),leftx(1))
486 
487  do ix = 2, nxvec
488  leftx(ix) = leftx(ix-1)
489  same = (xknot(leftx(ix)) .le. xvec(ix)) &
490  & .and. (xvec(ix) .le. xknot(leftx(ix)+1))
491  if(.not. same ) then
492  leftx(ix) = leftx(ix) + 1
493  next = (xknot(leftx(ix)) .le. xvec(ix)) &
494  & .and. (xvec(ix) .le. xknot(leftx(ix)+1))
495  if (.not. next) &
496  & call huntn(xknot,nx+kx,kx,xvec(ix),leftx(ix))
497  endif
498  end do
499 
500  do ix = 1, nx+kx-1
501  if (xknot(ix) .gt. xknot(ix+1)) then
502  write(6,*) "subroutine dbs1gd:"
503  write(6,*) "xknot(ix) <= xknot(ix+1) required."
504  write(6,*) ix, xknot(ix), xknot(ix+1)
505  write(6,*)
506  write(6,*) xknot
507  stop
508  endif
509  end do
510 
511  do ix = 1, nxvec
512  if ((xvec(ix).lt.xknot(1)).or.(xvec(ix).gt.xknot(nx+kx))) then
513  write(6,*) "subroutine dbs1gd:"
514  write(6,*) "ix with xknot(ix) <= x < xknot(ix+1) required."
515  write(6,*) "x = ", xvec(ix)
516  stop
517  endif
518  end do
519 
520  if (iderx .eq. 0) then
521 
522  do ix = 1,nxvec
523  biatx(ix,1) = one
524  val(ix) = zero
525  end do
526 
527  do ik = 1, kx-1
528  do ix = 1, nxvec
529  dr(ix,ik) = xknot(leftx(ix)+ik) - xvec(ix)
530  dl(ix,ik) = xvec(ix) - xknot(leftx(ix)+1-ik)
531  save1(ix) = zero
532  end do
533 
534  do il = 1, ik
535  do ix = 1,nxvec
536  term(ix) = biatx(ix,il) &
537  & / (dr(ix,il) + dl(ix,ik+1-il))
538  biatx(ix,il) = save1(ix) + dr(ix,il) * term(ix)
539  save1(ix) = dl(ix,ik+1-il) * term(ix)
540  end do
541  end do
542 
543  do ix = 1, nxvec
544  biatx(ix,ik+1) = save1(ix)
545  end do
546  end do
547 
548  do ik = 1, kx
549  do ix = 1, nxvec
550  val(ix) = val(ix) + biatx(ix,ik) * bcoef(leftx(ix)-kx+ik)
551  end do
552  end do
553 
554  elseif ((iderx .ge. 1) .and. (iderx .lt. kx)) then
555 
556  do ix = 1, nxvec
557  biatx(ix,1) = one
558  val(ix) = zero
559  end do
560 
561  do ik = 1, kx-iderx-1
562  do ix = 1, nxvec
563  dr(ix,ik) = xknot(leftx(ix)+ik) - xvec(ix)
564  dl(ix,ik) = xvec(ix) - xknot(leftx(ix)+1-ik)
565  save1(ix) = biatx(ix,1)
566  biatx(ix,1) = zero
567  do il = 1, ik
568  term(ix) = save1(ix) &
569  & / (dr(ix,il) + dl(ix,ik+1-il))
570  biatx(ix,il) = biatx(ix,il) + dr(ix,il) * term(ix)
571  save1(ix) = biatx(ix,il+1)
572  biatx(ix,il+1) = dl(ix,ik+1-il) * term(ix)
573  end do
574  end do
575  end do
576 
577  do ik = 1, kx
578  do ix = 1, nxvec
579  work(ix,ik) = bcoef(leftx(ix)+ik-kx)
580  dr(ix,ik) = xknot(leftx(ix)+ik) - xvec(ix)
581  dl(ix,ik) = xvec(ix) - xknot(leftx(ix)+ik-kx)
582  end do
583  end do
584 
585  do ik = 1, iderx
586  dik = real(kx-ik, kind=rprec)
587  do ix = 1, nxvec
588  save2(ix) = work(ix,ik)
589  do il = ik+1, kx
590  save1(ix) = work(ix,il)
591  work(ix,il) = dik * (work(ix,il) - save2(ix)) &
592  & /(dl(ix,il) + dr(ix,il-ik))
593  save2(ix) = save1(ix)
594  end do
595  end do
596  end do
597 
598  do i = 1, kx-iderx
599  do ix = 1, nxvec
600  val(ix) = val(ix) + biatx(ix,i) * work(ix,iderx+i)
601  end do
602  end do
603 
604  else
605 
606  do ix = 1, nxvec
607  val(ix) = zero
608  end do
609 
610  endif
611 
612  end subroutine dbs1gd
613 
614 
615  function dbsdca(iderx,x,kx,xknot,nx,bcoef,leftx)
616 ! dir$ inlinealways dbsdca
617 !
618 ! This routine is equivalent to the routine dbsder, but it does not
619 ! check the parameters!!!
620 !
621 ! Evaluates the derivative of a spline, given its B-spline representation.
622 !
623 !
624 ! iderx - order of the derivative to be evaluated. (input)
625 ! in particular, iderx = 0 returns the value of the
626 ! spline.
627 ! x - point at which the spline is to be evaluated. (input)
628 ! kx - order of the spline. (input)
629 ! xknot - array of length nx+kx containing the knot
630 ! sequence. (input)
631 ! xknot must be nondecreasing.
632 ! nx - number of B-spline coefficients. (input)
633 ! bcoef - array of length nx containing the B-spline
634 ! coefficients. (input)
635 ! leftx - number of the intervall of xknot that includes x
636 ! dbsdca - value of the ideriv-th derivative of the spline at x.
637 ! (output)
638 !
639 
640  implicit none
641 
642  integer, intent(in) :: iderx, kx, nx
643  real(rprec) :: dbsdca
644  real(rprec), intent(in) :: x
645  real(rprec), dimension(nx+kx), intent(in) :: xknot
646  real(rprec), dimension(nx), intent(in) :: bcoef
647 
648  integer :: i, ik, il, leftx
649  real(rprec) :: save0, save1, save2, y, sum, dik
650  real(rprec), dimension(kx) :: work, dl, dr,bsp
651 
652 
653  if (iderx .eq. 0) then
654 
655  do ik = 1, kx-1
656  work(ik) = bcoef(leftx+ik-kx)
657  dl(ik) = x - xknot(leftx+ik-kx)
658  dr(ik) = xknot(leftx+ik) - x
659  end do
660 
661  work(kx) = bcoef(leftx)
662  dl(kx) = x - xknot(leftx)
663 
664  do ik = 1, kx-1
665  save2 = work(ik)
666  do il = ik+1, kx
667  save1 = work(il)
668  work(il) = (dl(il) * work(il) + dr(il-ik) * save2) &
669  & / (dl(il) + dr(il - ik))
670  save2 = save1
671  end do
672  end do
673 
674  dbsdca = work(kx)
675 
676  elseif ((iderx .ge. 1) .and. (iderx .lt. kx)) then
677  bsp(1) = one
678  do ik = 1,kx-iderx-1
679  dr(ik) = xknot(leftx+ik) - x
680  dl(ik) = x - xknot(leftx+1-ik)
681  save0 = bsp(1)
682  bsp(1) = zero
683  do il = 1, ik
684  y = save0 / (dr(il) + dl(ik+1-il))
685  bsp(il) = bsp(il) + dr(il) * y
686  save0 = bsp(il+1)
687  bsp(il+1) = dl(ik+1-il) * y
688  end do
689  end do
690 
691  do ik = 1, kx
692  work(ik) = bcoef(leftx+ik-kx)
693  dr(ik) = xknot(leftx+ik) - x
694  dl(ik) = x - xknot(leftx+ik-kx)
695  end do
696 
697  do ik = 1, iderx
698  dik = real(kx - ik, kind=rprec)
699  save2 = work(ik)
700  do il = ik+1, kx
701  save1 = work(il)
702  work(il) = dik * (work(il) - save2) /(dl(il) + dr(il-ik))
703  save2 = save1
704  end do
705  end do
706 
707  sum = zero
708 
709  do i = 1, kx-iderx
710  sum = sum + bsp(i) * work(iderx+i)
711  end do
712 
713  dbsdca = sum
714 
715  else
716  dbsdca = zero
717  endif
718 
719  end function dbsdca
720 
721 
722  subroutine dbs2in(nx,xvec,ny,yvec,xydata,ldf,kx,ky,xknot,yknot,bcoef)
723 
724 !
725 ! Computes a two-dimensional tensor-product spline interpolant,
726 ! returning the tensor-product B-spline coefficients.
727 !
728 ! nx - number of data points in the x-direction. (input)
729 ! xvec - array of length nx containing the data points in
730 ! the x-direction. (input)
731 ! xdata must be strictly increasing.
732 ! ny - number of data points in the y-direction. (input)
733 ! yvec - array of length ny containing the data points in
734 ! the y-direction. (input)
735 ! ydata must be strictly increasing.
736 ! xydata - array of size nx by nydata containing the values to
737 ! be interpolated. (input)
738 ! fdata(i,j) is the value at (xdata(i),ydata(j)).
739 ! ldf - the leading dimension of fdata exactly as specified in
740 ! the dimension statement of the calling program.
741 ! (input)
742 ! kx - order of the spline in the x-direction. (input)
743 ! kxord must be less than or equal to nxdata.
744 ! ky - order of the spline in the y-direction. (input)
745 ! kyord must be less than or equal to nydata.
746 ! xknot - array of length nx+kx containing the knot
747 ! sequence in the x-direction. (input)
748 ! xknot must be nondecreasing.
749 ! yknot - array of length ny+ky containing the knot
750 ! sequence in the y-direction. (input)
751 ! yknot must be nondecreasing.
752 ! bcoef - array of length nx*ny containing the
753 ! tensor-product B-spline coefficients. (output)
754 ! bscoef is treated internally as a matrix of size nxdata
755 ! by nydata.
756 !
757 
758  implicit none
759 
760  integer, intent(in) :: nx, ny, kx, ky, ldf
761 
762  real(rprec), dimension(nx), intent(in) :: xvec
763  real(rprec), dimension(ny), intent(in) :: yvec
764  real(rprec), dimension(nx+kx), intent(in) :: xknot
765  real(rprec), dimension(ny+ky), intent(in) :: yknot
766  real(rprec), dimension(ldf,*), intent(in) :: xydata
767  real(rprec), dimension(nx,ny), intent(out) :: bcoef
768 
769  real(rprec), dimension(max(nx,ny),max(nx,ny)) :: work1
770  real(rprec), dimension(max(nx,ny)) :: work2
771  real(rprec), dimension(max((2*kx-1)*nx,(2*ky-1)*ny)) :: work3
772 
773 
774  call spli2d(xvec,ldf,xydata,xknot,nx,kx,ny,work2,work3,work1)
775  call spli2d(yvec,ny, work1, yknot,ny,ky,nx,work2,work3,bcoef)
776 
777  end subroutine dbs2in
778 
779 
780  subroutine spli2d(xyvec,ld,xydata,xyknot,n,k,m,work2,work3,bcoef)
781 
782  implicit none
783 
784 
785  integer, intent(in) :: ld, n, k, m
786  real(rprec), dimension(n), intent(in) :: xyvec
787  real(rprec), dimension(n+k), intent(in) :: xyknot
788  real(rprec), dimension(ld,m), intent(in) :: xydata
789  real(rprec), dimension(m,n), intent(out) :: bcoef
790 
791  real(rprec), dimension(n), intent(out) :: work2
792  real(rprec), dimension((2*k-1)*n), intent(out) :: work3
793 
794 
795  integer :: np1, km1, kpkm2, left, lenq, i, iflag, ilp1mx, j, jj
796  real(rprec) :: xyveci
797 
798  np1 = n + 1
799  km1 = k - 1
800  kpkm2 = 2 * km1
801  left = k
802  lenq = n * (k + km1)
803 
804  do i = 1,lenq
805  work3(i) = zero
806  end do
807 
808  do i = 1, n
809  xyveci = xyvec(i)
810  ilp1mx = min(i+k,np1)
811  left = max(left,i)
812  if (xyveci .lt. xyknot(left)) go to 998
813 30 if (xyveci .lt. xyknot(left+1)) go to 40
814  left = left + 1
815  if (left .lt. ilp1mx) go to 30
816  left = left - 1
817  if (xyveci .gt. xyknot(left+1)) go to 998
818 40 call bsplvb(xyknot,n+k,k,1,xyveci,left,work2)
819  jj = i - left + 1 + (left - k) * (k + km1)
820  do j = 1, k
821  jj = jj + kpkm2
822  work3(jj) = work2(j)
823  end do
824  end do
825 
826  call banfac(work3,k+km1,n,km1,km1,iflag )
827 
828  if (iflag .ne. 1) then
829  write(6,*) "subroutine dbs2in: error"
830  write(6,*) "no solution of linear equation system !!!"
831  stop
832  end if
833 
834  do j = 1, m
835  do i = 1, n
836  work2(i) = xydata(i,j)
837  end do
838 
839  call banslv(work3,k+km1,n,km1,km1,work2)
840 
841  do i = 1, n
842  bcoef(j,i) = work2(i)
843  end do
844  end do
845 
846  return
847 
848 998 write(6,*) "subroutine db2in:"
849  write(6,*) "i with knot(i) <= x/y < knot(i+1) required."
850  write(6,*) "knot(1) = ", xyknot(1)
851  write(6,*) "knot(n+k) = ", xyknot(n+k)
852  write(6,*) " x/y = ", xyveci
853 
854  stop
855 
856  end subroutine spli2d
857 
858 
859  function dbs2vl(x,y,kx,ky,xknot,yknot,nx,ny,bcoef)
860 
861 !
862 ! evaluates a two-dimensional tensor-product spline, given its
863 ! tensor-product B-spline representation. use stel_kinds
864 !
865 ! x - x-coordinate of the point at which the spline is to be
866 ! evaluated. (input)
867 ! y - y-coordinate of the point at which the spline is to be
868 ! evaluated. (input)
869 ! kx - order of the spline in the x-direction. (input)
870 ! ky - order of the spline in the y-direction. (input)
871 ! xknot - array of length nx+kx containing the knot
872 ! sequence in the x-direction. (input)
873 ! xknot must be nondecreasing.
874 ! yknot - array of length ny+ky containing the knot
875 ! sequence in the y-direction. (input)
876 ! yknot must be nondecreasing.
877 ! nx - number of B-spline coefficients in the x-direction.
878 ! (input)
879 ! ny - number of B-spline coefficients in the y-direction.
880 ! (input)
881 ! bcoef - array of length nx*ny containing the
882 ! tensor-product B-spline coefficients. (input)
883 ! bscoef is treated internally as a matrix of size nx
884 ! by ny.
885 ! dbs2vl - value of the spline at (x,y). (output)
886 !
887 
888  implicit none
889 
890  integer, intent(in) :: nx, ny, kx, ky
891  real(rprec), intent(in) :: x, y
892  real(rprec), dimension(nx+kx), intent(in) :: xknot
893  real(rprec), dimension(ny+ky), intent(in) :: yknot
894  real(rprec), dimension(nx,ny), intent(in) :: bcoef
895  real(rprec) :: dbs2vl
896 
897  integer :: ix, iy, iky, leftx, lefty
898  real(rprec), dimension(ky) :: work
899 
900 !
901 ! check if knot(i) <= knot(i+1) and calculation of i so that
902 ! knot(i) <= x < knot(i+1)
903 !
904 
905  leftx = 0
906 
907  do ix = 1, nx+kx-1
908  if (xknot(ix) .gt. xknot(ix+1)) then
909  write(6,*) "subroutine dbs2vl:"
910  write(6,*) "xknot(ix) <= xknot(ix+1) required."
911  write(6,*) ix, xknot(ix), xknot(ix+1)
912  write(6,*)
913  write(6,*) xknot
914  stop
915  endif
916  if((xknot(ix) .le. x) .and. (x .lt. xknot(ix+1))) leftx = ix
917  end do
918 
919  if(leftx .eq. 0) then
920  write(6,*) "subroutine dbs2vl:"
921  write(6,*) "ix with xknot(ix) <= x < xknot(ix+1) required."
922  write(6,*) "x = ", x
923  write(6,*)
924  write(6,*) xknot
925  stop
926  endif
927 
928  lefty = 0
929 
930  do iy = 1, ny+ky-1
931  if (yknot(iy) .gt. yknot(iy+1)) then
932  write(6,*) "subroutine dbs2vl:"
933  write(6,*) "yknot(iy) <= yknot(iy+1) required."
934  write(6,*) iy, yknot(iy), yknot(iy+1)
935  stop
936  endif
937  if((yknot(iy) .le. y) .and. (y .lt. yknot(iy+1))) lefty = iy
938  end do
939 
940  if(lefty .eq. 0) then
941  write(6,*) "subroutine dbs2vl:"
942  write(6,*) "iy with yknot(iy) <= y < yknot(iy+1) required."
943  write(6,*) "yknot(iy) = ", yknot(iy)
944  write(6,*) " y = ", y
945  write(6,*) "yknot(iy+1) = ", yknot(iy+1)
946  stop
947  endif
948 
949  do iky = 1, ky
950  work(iky) = dbsdca(0,x,kx,xknot,nx,bcoef(1,lefty-ky+iky),leftx)
951  end do
952 
953  dbs2vl = dbsval(y,ky,yknot(lefty-ky+1),ky,work)
954 
955  end function dbs2vl
956 
957 
958  function dbs2dr(iderx,idery,x,y,kx,ky,xknot,yknot,nx,ny,bcoef)
959 
960 !
961 ! Evaluates the derivative of a two-dimensional tensor-product spline,
962 ! given its tensor-product B-spline representation.
963 !
964 ! iderx - order of the derivative in the x-direction. (input)
965 ! idery - order of the derivative in the y-direction. (input)
966 ! x - x-coordinate of the point at which the spline is to be
967 ! evaluated. (input)
968 ! y - y-coordinate of the point at which the spline is to be
969 ! evaluated. (input)
970 ! kx - order of the spline in the x-direction. (input)
971 ! ky - order of the spline in the y-direction. (input)
972 ! xknot - array of length nx+kx containing the knot
973 ! sequence in the x-direction. (input)
974 ! xknot must be nondecreasing.
975 ! yknot - array of length ny+ky containing the knot
976 ! sequence in the y-direction. (input)
977 ! yknot must be nondecreasing.
978 ! nx - number of B-spline coefficients in the x-direction.
979 ! (input)
980 ! ny - number of B-spline coefficients in the y-direction.
981 ! (input)
982 ! bcoef - array of length nx*ny containing the
983 ! tensor-product B-spline coefficients. (input)
984 ! bscoef is treated internally as a matrix of size nx
985 ! by ny.
986 ! dbs2dr - value of the (iderx,idery) derivative of the spline at
987 ! (x,y). (output)
988 !
989 
990  implicit none
991 
992  integer, intent(in) :: iderx, idery
993  integer, intent(in) :: kx, nx, ky, ny
994  real(rprec) :: dbs2dr
995  real(rprec), intent(in) :: x, y
996  real(rprec), dimension(nx+kx), intent(in) :: xknot
997  real(rprec), dimension(ny+ky), intent(in) :: yknot
998  real(rprec), dimension(nx,ny), intent(in) :: bcoef
999 
1000  integer :: ix, iy, iky, nintx, ninty
1001  real(rprec), dimension(ky) :: work
1002 
1003 !
1004 ! check if knot(i) <= knot(i+1) and calculation of i so that
1005 ! knot(i) <= x < knot(i+1)
1006 !
1007 
1008  nintx = 0
1009 
1010  do ix = 1, nx+kx-1
1011  if (xknot(ix) .gt. xknot(ix+1)) then
1012  write(6,*) "subroutine dbs2dr:"
1013  write(6,*) "xknot(ix) <= xknot(ix+1) required."
1014  write(6,*) ix, xknot(ix), xknot(ix+1)
1015  stop
1016  endif
1017  if((xknot(ix) .le. x) .and. (x .lt. xknot(ix+1))) nintx = ix
1018  end do
1019 
1020  if(nintx .eq. 0) then
1021  write(6,*) "subroutine dbs2dr:"
1022  write(6,*) "ix with xknot(ix) <= x < xknot(ix+1) required."
1023  write(6,*) "x = ", x
1024  stop
1025  endif
1026 
1027  ninty = 0
1028 
1029  do iy = 1, ny+ky-1
1030  if (yknot(iy) .gt. yknot(iy+1)) then
1031  write(6,*) "subroutine dbs2dr:"
1032  write(6,*) "yknot(iy) <= yknot(iy+1) required."
1033  write(6,*) iy, yknot(iy), yknot(iy+1)
1034  stop
1035  endif
1036  if ((yknot(iy) .le. y) .and. (y .lt. yknot(iy+1))) ninty = iy
1037  end do
1038 
1039  if(ninty .eq. 0) then
1040  write(6,*) "subroutine dbs2dr:"
1041  write(6,*) "iy with yknot(iy) <= y < yknot(iy+1) required."
1042  write(6,*) "y = ", y
1043  stop
1044  endif
1045 
1046  do iky = 1, ky
1047  work(iky) = dbsdca(iderx,x,kx,xknot,nx,bcoef(1,ninty-ky+iky),nintx)
1048  end do
1049 
1050  dbs2dr = dbsder(idery,y,ky,yknot(ninty-ky+1),ky,work)
1051 
1052  end function dbs2dr
1053 
1054 
1055  subroutine dbs2gd(iderx,idery,nxvec,xvec,nyvec,yvec,kx,ky,xknot,yknot, &
1056  & nx,ny,bcoef,val,ldf)
1057 
1058 !
1059 ! Evaluates the derivative of a two-dimensional tensor-product spline,
1060 ! given its tensor-product B-spline representation on a grid.
1061 !
1062 ! iderx - order of the derivative in the x-direction. (input)
1063 ! idery - order of the derivative in the y-direction. (input)
1064 ! nxvec - number of grid points in the x-direction. (input)
1065 ! xvec - array of length nx containing the x-coordinates at
1066 ! which the spline is to be evaluated. (input)
1067 ! the points in xvec should be strictly increasing.
1068 ! nyvec - number of grid points in the y-direction. (input)
1069 ! yvec - array of length ny containing the y-coordinates at
1070 ! which the spline is to be evaluated. (input)
1071 ! the points in yvec should be strictly increasing.
1072 ! kx - order of the spline in the x-direction. (input)
1073 ! ky - order of the spline in the y-direction. (input)
1074 ! xknot - array of length nx+kx containing the knot
1075 ! sequence in the x-direction. (input)
1076 ! xknot must be nondecreasing.
1077 ! yknot - array of length ny+ky containing the knot
1078 ! sequence in the y-direction. (input)
1079 ! yknot must be nondecreasing.
1080 ! nx - number of B-spline coefficients in the x-direction.
1081 ! (input)
1082 ! ny - number of B-spline coefficients in the y-direction.
1083 ! (input)
1084 ! bcoef - array of length nx*ny containing the
1085 ! tensor-product B-spline coefficients. (input)
1086 ! bscoef is treated internally as a matrix of size nx
1087 ! by ny.
1088 ! val - value of the (iderx,idery) derivative of the spline on
1089 ! the nx by ny grid. (output)
1090 ! value(i,j) contains the derivative of the spline at the
1091 ! point (xvec(i),yvec(j)).
1092 ! ldf - leading dimension of value exactly as specified in the
1093 ! dimension statement of the calling program. (input)
1094 !
1095 
1096  implicit none
1097 
1098  integer, intent(in) :: iderx, idery
1099  integer, intent(in) :: nxvec, nyvec
1100  integer, intent(in) :: kx, nx, ky, ny
1101  integer, intent(in) :: ldf
1102 
1103  real(rprec), dimension(nxvec), intent(in) :: xvec
1104  real(rprec), dimension(nyvec), intent(in) :: yvec
1105  real(rprec), dimension(nx+kx), intent(in) :: xknot
1106  real(rprec), dimension(ny+ky), intent(in) :: yknot
1107  real(rprec), dimension(nx,ny), intent(in) :: bcoef
1108  real(rprec), dimension(ldf,*), intent(out) :: val
1109 
1110  integer :: i, ik, il, ix, iy, ikx, iky
1111  integer, dimension(nxvec) :: leftx
1112  integer, dimension(nyvec) :: lefty
1113  real(rprec), dimension(nxvec,kx) :: dl, dr
1114  real(rprec), dimension(max(nxvec,nyvec)) :: save1
1115  real(rprec), dimension(nxvec,kx) :: biatx
1116  real(rprec), dimension(nyvec,ky) :: biaty
1117  real(rprec), dimension(max(nxvec,nyvec)) :: term
1118  real(rprec), dimension(ky) :: work
1119 
1120  logical :: same,next
1121 
1122 
1123  leftx(1) = 0
1124 
1125  call huntn(xknot,nx+kx,kx,xvec(1),leftx(1))
1126 
1127  do ix = 2, nxvec
1128  leftx(ix) = leftx(ix-1)
1129  same = (xknot(leftx(ix)) .le. xvec(ix)) &
1130  & .and. (xvec(ix) .le. xknot(leftx(ix)+1))
1131  if(.not. same ) then
1132  leftx(ix) = leftx(ix) + 1
1133  next = (xknot(leftx(ix)) .le. xvec(ix)) &
1134  & .and. (xvec(ix) .le. xknot(leftx(ix)+1))
1135  if (.not. next) &
1136  & call huntn(xknot,nx+kx,kx,xvec(ix),leftx(ix))
1137  endif
1138  end do
1139 
1140  do i = 1, nx+kx-1
1141  if (xknot(i) .gt. xknot(i+1)) then
1142  write(6,*) "subroutine dbs2gd:"
1143  write(6,*) "xknot(i) <= xknot(i+1) required."
1144  write(6,*) i, xknot(i), xknot(i+1)
1145  write(6,*)
1146  write(6,*) xknot
1147  stop
1148  endif
1149  end do
1150 
1151  do i = 1, nxvec
1152  if ((xvec(i).lt.xknot(1)).or.(xvec(i).gt.xknot(nx+kx))) then
1153  write(6,*) "subroutine dbs2gd:"
1154  write(6,*) "ix with xknot(ix) <= x < xknot(ix+1) required."
1155  write(6,*) "x = ", xvec(i)
1156  stop
1157  endif
1158  end do
1159 
1160  lefty(1) = 0
1161 
1162  call huntn(yknot,ny+ky,ky,yvec(1),lefty(1))
1163 
1164  do iy = 2, nyvec
1165  lefty(iy) = lefty(iy-1)
1166  same = (yknot(lefty(iy)) .le. yvec(iy)) &
1167  & .and. (yvec(iy) .le. yknot(lefty(iy)+1))
1168  if(.not. same ) then
1169  lefty(iy) = lefty(iy) + 1
1170  next = (yknot(lefty(iy)) .le. yvec(iy)) &
1171  & .and. (yvec(iy) .le. yknot(lefty(iy)+1))
1172  if (.not. next) call huntn(yknot,ny+ky,ky,yvec(iy),lefty(iy))
1173  endif
1174  end do
1175 
1176  do i = 1, ny+ky-1
1177  if (yknot(i) .gt. yknot(i+1)) then
1178  write(6,*) "subroutine dbs2gd:"
1179  write(6,*) "yknot(i) <= yknot(i+1) required."
1180  write(6,*) i, yknot(i), yknot(i+1)
1181  write(6,*)
1182  write(6,*) yknot
1183  stop
1184  endif
1185  end do
1186 
1187  do i = 1, nyvec
1188  if ((yvec(i).lt.yknot(1)).or.(yvec(i).gt.yknot(ny+ky))) then
1189  write(6,*) "subroutine dbs2gd:"
1190  write(6,*) "iy with yknot(iy) <= y < yknot(iy+1) required."
1191  write(6,*) "y = ", yvec(i)
1192  stop
1193  endif
1194  end do
1195 
1196  if ((iderx .eq. 0) .and. (idery .eq. 0)) then
1197 
1198  do ix = 1,nxvec
1199  biatx(ix,1) = one
1200  end do
1201 
1202  do ik = 1, kx-1
1203  do ix = 1,nxvec
1204  dr(ix,ik) = xknot(leftx(ix)+ik) - xvec(ix)
1205  dl(ix,ik) = xvec(ix) - xknot(leftx(ix)+1-ik)
1206  save1(ix) = zero
1207  end do
1208 
1209  do il = 1,ik
1210  do ix = 1,nxvec
1211  term(ix) = biatx(ix,il) &
1212  & / (dr(ix,il) + dl(ix,ik+1-il))
1213  biatx(ix,il) = save1(ix) + dr(ix,il) * term(ix)
1214  save1(ix) = dl(ix,ik+1-il) * term(ix)
1215  end do
1216  end do
1217 
1218  do ix = 1, nxvec
1219  biatx(ix,ik+1) = save1(ix)
1220  end do
1221  end do
1222 
1223  do iy = 1, nyvec
1224  biaty(iy,1) = one
1225  end do
1226 
1227  do ik = 1, ky-1
1228  do iy = 1, nyvec
1229  dr(iy,ik) = yknot(lefty(iy)+ik) - yvec(iy)
1230  dl(iy,ik) = yvec(iy) - yknot(lefty(iy)+1-ik)
1231  save1(iy) = zero
1232  end do
1233 
1234  do il = 1, ik
1235  do iy = 1,nyvec
1236  term(iy) = biaty(iy,il) &
1237  & / (dr(iy,il) + dl(iy,ik+1-il))
1238  biaty(iy,il) = save1(iy) + dr(iy,il) * term(iy)
1239  save1(iy) = dl(iy,ik+1-il) * term(iy)
1240  end do
1241  end do
1242 
1243  do iy = 1, nyvec
1244  biaty(iy,ik+1) = save1(iy)
1245  end do
1246  end do
1247 
1248  do iy = 1, nyvec
1249  do ix = 1, nxvec
1250  val(ix,iy) = zero
1251  end do
1252  end do
1253 
1254  do iky = 1, ky
1255  do ikx = 1, kx
1256  do iy = 1, nyvec
1257  do ix = 1, nxvec
1258  val(ix,iy) = val(ix,iy) &
1259  & + biatx(ix,ikx) * biaty(iy,iky) &
1260  & * bcoef(leftx(ix)-kx+ikx,lefty(iy)-ky+iky)
1261  end do
1262  end do
1263  end do
1264  end do
1265 
1266  elseif (((iderx .ge. 1) .or. (idery .ge. 1)) &
1267  & .and. ( (iderx .lt. kx) .and. (idery .lt. ky))) then
1268 
1269  do iy = 1, nyvec
1270  do ix = 1, nxvec
1271  do iky = 1, ky
1272  work(iky) = dbsdca(iderx,xvec(ix),kx,xknot,nx, &
1273  & bcoef(1,lefty(iy)-ky+iky),leftx(ix))
1274  end do
1275  val(ix,iy) = dbsder(idery,yvec(iy),ky, &
1276  & yknot(lefty(iy)-ky+1),ky,work)
1277  end do
1278  end do
1279 
1280  else
1281 
1282  do iy = 1, nyvec
1283  do ix = 1, nxvec
1284  val(ix,iy) = zero
1285  end do
1286  end do
1287 
1288  endif
1289 
1290  end subroutine dbs2gd
1291 
1292 
1293 
1294  subroutine dbs3in(nx,xvec,ny,yvec,nz,zvec,xyzdata,ldf,mdf,kx,ky,kz, &
1295  & xknot,yknot,zknot,bcoef)
1296 
1297 !
1298 ! Computes a three-dimensional tensor-product spline interpolant,
1299 ! returning the tensor-product B-spline coefficients.
1300 !
1301 ! nx - number of data points in the x-direction. (input)
1302 ! xvec - array of length nxdata containing the data points in
1303 ! the x-direction. (input)
1304 ! xdata must be increasing.
1305 ! ny - number of data points in the y-direction. (input)
1306 ! yvec - array of length nydata containing the data points in
1307 ! the y-direction. (input)
1308 ! ydata must be increasing.
1309 ! nz - number of data points in the z-direction. (input)
1310 ! zvec - array of length nzdata containing the data points in
1311 ! the z-direction. (input)
1312 ! zdata must be increasing.
1313 ! xyzdata - array of size nx by ny by nz containing the
1314 ! values to be interpolated. (input)
1315 ! xyzdata(i,j,k) contains the value at
1316 ! (xvec(i),yvec(j),zvec(k)).
1317 ! ldf - leading dimension of fdata exactly as specified in the
1318 ! dimension statement of the calling program. (input)
1319 ! mdf - middle dimension of fdata exactly as specified in the
1320 ! dimension statement of the calling program. (input)
1321 ! kx - order of the spline in the x-direction. (input)
1322 ! kxord must be less than or equal to nxdata.
1323 ! ky - order of the spline in the y-direction. (input)
1324 ! kyord must be less than or equal to nydata.
1325 ! kz - order of the spline in the z-direction. (input)
1326 ! kzord must be less than or equal to nzdata.
1327 ! xknot - array of length nx+kx containing the knot
1328 ! sequence in the x-direction. (input)
1329 ! xknot must be nondecreasing.
1330 ! yknot - array of length ny+ky containing the knot
1331 ! sequence in the y-direction. (input)
1332 ! yknot must be nondecreasing.
1333 ! zknot - array of length nz+kz containing the knot
1334 ! sequence in the z-direction. (input)
1335 ! zknot must be nondecreasing.
1336 ! bcoef - array of length nx*ny*nz containing the
1337 ! tensor-product B-spline coefficients. (output)
1338 ! bscoef is treated internally as a matrix of size nx
1339 ! by ny by nz.
1340 !
1341 
1342  implicit none
1343 
1344  integer, intent(in) :: nx, ny, nz, kx, ky, kz
1345  integer, intent(in) :: ldf, mdf
1346 
1347  real(rprec), dimension(nx), intent(in) :: xvec
1348  real(rprec), dimension(ny), intent(in) :: yvec
1349  real(rprec), dimension(nz), intent(in) :: zvec
1350  real(rprec), dimension(nx+kx), intent(in) :: xknot
1351  real(rprec), dimension(ny+ky), intent(in) :: yknot
1352  real(rprec), dimension(nz+kz), intent(in) :: zknot
1353  real(rprec), dimension(ldf,mdf,nz), intent(in) :: xyzdata
1354  real(rprec), dimension(nx,ny,nz), intent(out) :: bcoef
1355 
1356  integer :: iz
1357  real(rprec), allocatable :: work1(:,:,:)
1358  real(rprec), dimension(nz) :: work2
1359  real(rprec), dimension((2*kz-1)*nz) :: work3
1360 
1361  allocate (work1(nx,ny,nz), stat=iz)
1362  if (iz .ne. 0) stop 'allocation error in dbs3in'
1363 
1364  call spli3d(zvec,ldf,mdf,xyzdata,zknot,nz,kz,nx,ny,work2,work3,work1, &
1365  & nx,ny,nz)
1366 
1367  do iz = 1, nz
1368  call dbs2in(nx,xvec,ny,yvec,work1(1,1,iz),nx,kx,ky,xknot,yknot, &
1369  & bcoef(1,1,iz))
1370  end do
1371 
1372  deallocate (work1)
1373 
1374  end subroutine dbs3in
1375 
1376 
1377 
1378  subroutine spli3d(xyzvec,ldf,mdf,xyzdata,xyzknot,n,k,m,l,work2,work3, &
1379  & bcoef,nx,ny,nz)
1380 
1381  implicit none
1382 
1383  integer, intent(in) :: ldf, mdf, n, k, m, l
1384  integer, intent(in) :: nx, ny, nz
1385  real(rprec), dimension(n), intent(in) :: xyzvec
1386  real(rprec), dimension(n+k), intent(in) :: xyzknot
1387  real(rprec), dimension(ldf,mdf,*), intent(in) :: xyzdata
1388  real(rprec), dimension(nx,ny,nz), intent(out) :: bcoef
1389  real(rprec), dimension(n), intent(out) :: work2
1390  real(rprec), dimension((2*k-1)*n), intent(out) :: work3
1391 
1392  integer :: np1, km1, kpkm2, left, lenq, i, ilp1mx, j, jj, iflag, in
1393  real(rprec) :: xyzveci
1394 
1395 
1396  np1 = n + 1
1397  km1 = k - 1
1398  kpkm2 = 2 * km1
1399  left = k
1400  lenq = n * (k + km1)
1401 
1402  do i = 1, lenq
1403  work3(i) = zero
1404  end do
1405 
1406  do i = 1, n
1407  xyzveci = xyzvec(i)
1408  ilp1mx = min0(i+k,np1)
1409  left = max0(left,i)
1410  if (xyzveci .lt. xyzknot(left)) go to 998
1411 30 if (xyzveci .lt. xyzknot(left+1)) go to 40
1412  left = left + 1
1413  if (left .lt. ilp1mx) go to 30
1414  left = left - 1
1415  if (xyzveci .gt. xyzknot(left+1)) go to 998
1416 40 call bsplvb(xyzknot,n+k,k,1,xyzveci,left,work2)
1417  jj = i - left + 1 + (left - k) * (k + km1)
1418  do j = 1, k
1419  jj = jj + kpkm2
1420  work3(jj) = work2(j)
1421  end do
1422  end do
1423 
1424  call banfac(work3,k+km1,n,km1,km1,iflag)
1425 
1426  if (iflag .ne. 1) then
1427  write(6,*) "subroutine dbs3in: error"
1428  write(6,*) "no solution of linear equation system !!!"
1429  stop
1430  end if
1431 
1432  do j = 1, l
1433  do i = 1, m
1434  do in = 1, n
1435  work2(in) = xyzdata(i,j,in)
1436  end do
1437 
1438  call banslv(work3,k+km1,n,km1,km1,work2)
1439 
1440  do in = 1, n
1441  bcoef(i,j,in) = work2(in)
1442  end do
1443 
1444  end do
1445  end do
1446 
1447  return
1448 
1449 998 write(6,*) "subroutine db3in:"
1450  write(6,*) "i with knot(i) <= x/y/z < knot(i+1) required."
1451  write(6,*) "knot(1) = ", xyzknot(1)
1452  write(6,*) "knot(n+k) = ", xyzknot(n+k)
1453  write(6,*) " x/y/z = ", xyzveci
1454 
1455  stop
1456 
1457  end subroutine spli3d
1458 
1459 
1460 
1461  function dbs3vl(x,y,z,kx,ky,kz,xknot,yknot,zknot,nx,ny,nz,bcoef)
1462 
1463 !
1464 ! Evaluates a three-dimensional tensor-product spline, given its
1465 ! tensor-product B-spline representation.
1466 !
1467 ! x - x-coordinate of the point at which the spline is to be
1468 ! evaluated. (input)
1469 ! y - y-coordinate of the point at which the spline is to be
1470 ! evaluated. (input)
1471 ! z - z-coordinate of the point at which the spline is to be
1472 ! evaluated. (input)
1473 ! kx - order of the spline in the x-direction. (input)
1474 ! ky - order of the spline in the y-direction. (input)
1475 ! kz - order of the spline in the z-direction. (input)
1476 ! xknot - array of length nx+kx containing the knot
1477 ! sequence in the x-direction. (input)
1478 ! xknot must be nondecreasing.
1479 ! yknot - array of length ny+ky containing the knot
1480 ! sequence in the y-direction. (input)
1481 ! yknot must be nondecreasing.
1482 ! zknot - array of length nz+kz containing the knot
1483 ! sequence in the z-direction. (input)
1484 ! zknot must be nondecreasing.
1485 ! nx - number of B-spline coefficients in the x-direction.
1486 ! (input)
1487 ! ny - number of B-spline coefficients in the y-direction.
1488 ! (input)
1489 ! nz - number of B-spline coefficients in the z-direction.
1490 ! (input)
1491 ! bcoef - array of length nx*ny*nz containing the
1492 ! tensor-product B-spline coefficients. (input)
1493 ! bscoef is treated internally as a matrix of size nx
1494 ! by ny by nz.
1495 ! dbs3vl - value of the spline at (x,y,z). (output)
1496 !
1497 
1498  implicit none
1499 
1500  integer, intent(in) :: nx, ny, nz, kx, ky, kz
1501  real(rprec), intent(in) :: x, y, z
1502  real(rprec), dimension(nx+kx), intent(in) :: xknot
1503  real(rprec), dimension(ny+ky), intent(in) :: yknot
1504  real(rprec), dimension(nz+kz), intent(in) :: zknot
1505  real(rprec), dimension(nx,ny,nz), intent(in) :: bcoef
1506  real(rprec) :: dbs3vl
1507 
1508  integer :: iz, nintz
1509  real(rprec), dimension(kz) :: work
1510 
1511 !
1512 ! check if knot(i) <= knot(i+1) and calculation of i so that
1513 ! knot(i) <= x < knot(i+1)
1514 !
1515 
1516  nintz = 0
1517 
1518  do iz = 1, nz+kz-1
1519  if (zknot(iz) .gt. zknot(iz + 1)) then
1520  write(6,*) "subroutine dbs3vl:"
1521  write(6,*) "zknot(iz) <= zknot(iz+1) required."
1522  write(6,*) iz, zknot(iz), zknot(iz+1)
1523  stop
1524  endif
1525  if((zknot(iz) .le. z) .and. (z .lt. zknot(iz + 1))) nintz = iz
1526  end do
1527 
1528  if(nintz .eq. 0) then
1529  write(6,*) "subroutine dbs3vl:"
1530  write(6,*) "iz with zknot(iz) <= z < zknot(iz+1) required."
1531  write(6,*) "zknot(iz) = ", zknot(iz)
1532  write(6,*) " z = ", z
1533  write(6,*) "zknot(iz+1) = ", zknot(iz+1)
1534  stop
1535  endif
1536 
1537  do iz = 1, kz
1538  work(iz) = dbs2vl(x,y,kx,ky,xknot,yknot,nx,ny,bcoef(1,1,nintz-kz+iz))
1539  end do
1540 
1541  dbs3vl = dbsval(z,kz,zknot(nintz-kz+1),kz,work)
1542 
1543  end function dbs3vl
1544 
1545 
1546 
1547  function dbs3dr(iderx,idery,iderz,x,y,z,kx,ky,kz,xknot,yknot,zknot, &
1548  & nx,ny,nz,bcoef)
1549 
1550 !
1551 ! Evaluates the derivative of a three-dimensional tensor-product spline,
1552 ! given its tensor-product B-spline representation.
1553 !
1554 ! iderx - order of the x-derivative. (input)
1555 ! idery - order of the y-derivative. (input)
1556 ! iderz - order of the z-derivative. (input)
1557 ! x - x-coordinate of the point at which the spline is to be
1558 ! evaluated. (input)
1559 ! y - y-coordinate of the point at which the spline is to be
1560 ! evaluated. (input)
1561 ! z - z-coordinate of the point at which the spline is to be
1562 ! evaluated. (input)
1563 ! kx - order of the spline in the x-direction. (input)
1564 ! ky - order of the spline in the y-direction. (input)
1565 ! kz - order of the spline in the z-direction. (input)
1566 ! xknot - array of length nx+kx containing the knot
1567 ! sequence in the x-direction. (input)
1568 ! xknot must be nondecreasing.
1569 ! yknot - array of length ny+ky containing the knot
1570 ! sequence in the y-direction. (input)
1571 ! yknot must be nondecreasing.
1572 ! zknot - array of length nz+kz containing the knot
1573 ! sequence in the z-direction. (input)
1574 ! zknot must be nondecreasing.
1575 ! nx - number of B-spline coefficients in the x-direction.
1576 ! (input)
1577 ! ny - number of B-spline coefficients in the y-direction.
1578 ! (input)
1579 ! nz - number of B-spline coefficients in the z-direction.
1580 ! (input)
1581 ! bcoef - array of length nx*ny*nz containing the
1582 ! tensor-product B-spline coefficients. (input)
1583 ! bscoef is treated internally as a matrix of size nx
1584 ! by ny by nz.
1585 ! dbs3dr - value of the (iderx,idery,iderz) derivative of the
1586 ! spline at (x,y,z). (output)
1587 !
1588 
1589  implicit none
1590 
1591  integer, intent(in) :: iderx, idery, iderz
1592  integer, intent(in) :: nx, ny, nz, kx, ky, kz
1593  real(rprec), intent(in) :: x, y, z
1594  real(rprec), dimension(nx+kx), intent(in) :: xknot
1595  real(rprec), dimension(ny+ky), intent(in) :: yknot
1596  real(rprec), dimension(nz+kz), intent(in) :: zknot
1597  real(rprec), dimension(nx,ny,nz), intent(in) :: bcoef
1598  real(rprec) :: dbs3dr
1599 
1600  integer :: iz, nintz
1601  real(rprec), dimension(kz) :: work
1602 
1603 !
1604 ! check if knot(i) <= knot(i+1) and calculation of i so that
1605 ! knot(i) <= x < knot(i+1)
1606 !
1607 
1608  nintz = 0
1609 
1610  do iz = 1, nz+kz-1
1611  if (zknot(iz) .gt. zknot(iz + 1)) then
1612  write(6,*) "subroutine dbs3vl:"
1613  write(6,*) "zknot(iz) <= zknot(iz+1) required."
1614  write(6,*) iz, zknot(iz), zknot(iz+1)
1615  stop
1616  endif
1617  if((zknot(iz) .le. z) .and. (z .lt. zknot(iz + 1))) nintz = iz
1618  end do
1619 
1620  if(nintz .eq. 0) then
1621  write(6,*) "subroutine dbs3dr:"
1622  write(6,*) "iz with zknot(iz) <= z < zknot(iz+1) required."
1623  write(6,*) "zknot(iz) = ", zknot(iz)
1624  write(6,*) " z = ", z
1625  write(6,*) "zknot(iz+1) = ", zknot(iz+1)
1626  stop
1627  endif
1628 
1629  do iz = 1, kz
1630  work(iz) = dbs2dr(iderx,idery,x,y,kx,ky,xknot,yknot,nx,ny, &
1631  & bcoef(1,1,nintz-kz+iz))
1632  end do
1633 
1634  dbs3dr = dbsder(iderz,z,kz,zknot(nintz-kz+1),kz,work)
1635 
1636  end function dbs3dr
1637 
1638 
1639  subroutine dbs3gd(iderx,idery,iderz,nxvec,xvec,nyvec,yvec,nzvec,zvec, &
1640  & kx,ky,kz,xknot,yknot,zknot,nx,ny,nz,bcoef,val,ldf,mdf)
1641 
1642 !
1643 ! Evaluates the derivative of a three-dimensional tensor-product spline,
1644 ! given its tensor-product B-spline representation on a grid.
1645 !
1646 ! iderx - order of the x-derivative. (input)
1647 ! idery - order of the y-derivative. (input)
1648 ! iderz - order of the z-derivative. (input)
1649 ! nx - number of grid points in the x-direction. (input)
1650 ! xvec - array of length nx containing the x-coordinates at
1651 ! which the spline is to be evaluated. (input)
1652 ! the points in xvec should be strictly increasing.
1653 ! ny - number of grid points in the y-direction. (input)
1654 ! yvec - array of length ny containing the y-coordinates at
1655 ! which the spline is to be evaluated. (input)
1656 ! the points in yvec should be strictly increasing.
1657 ! nz - number of grid points in the z-direction. (input)
1658 ! zvec - array of length nz containing the z-coordinates at
1659 ! which the spline is to be evaluated. (input)
1660 ! the points in yvec should be strictly increasing.
1661 ! kx - order of the spline in the x-direction. (input)
1662 ! ky - order of the spline in the y-direction. (input)
1663 ! kz - order of the spline in the z-direction. (input)
1664 ! xknot - array of length nx+kx containing the knot
1665 ! sequence in the x-direction. (input)
1666 ! xknot must be nondecreasing.
1667 ! yknot - array of length ny+ky containing the knot
1668 ! sequence in the y-direction. (input)
1669 ! yknot must be nondecreasing.
1670 ! zknot - array of length nz+kz containing the knot
1671 ! sequence in the z-direction. (input)
1672 ! zknot must be nondecreasing.
1673 ! nx - number of B-spline coefficients in the x-direction.
1674 ! (input)
1675 ! ny - number of B-spline coefficients in the y-direction.
1676 ! (input)
1677 ! nz - number of B-spline coefficients in the z-direction.
1678 ! (input)
1679 ! bcoef - array of length nx*ny*nz containing the
1680 ! tensor-product B-spline coefficients. (input)
1681 ! bscoef is treated internally as a matrix of size nx
1682 ! by ny by nz.
1683 ! val - array of size nx by ny by nz containing the values of
1684 ! the (iderx,idery,iderz) derivative of the spline on the
1685 ! nx by ny by nz grid. (output)
1686 ! value(i,j,k) contains the derivative of the spline at
1687 ! the point (xvec(i), yvec(j), zvec(k)).
1688 ! ldf - leading dimension of value exactly as specified in the
1689 ! dimension statement of the calling program. (input)
1690 ! mdf - middle dimension of value exactly as specified in the
1691 ! dimension statement of the calling program. (input)
1692 !
1693 
1694  implicit none
1695 
1696  integer, intent(in) :: iderx, idery, iderz
1697  integer, intent(in) :: nxvec, nyvec, nzvec
1698  integer, intent(in) :: kx, nx, ky, ny, kz, nz
1699  integer, intent(in) :: ldf,mdf
1700 
1701  real(rprec), dimension(nxvec), intent(in) :: xvec
1702  real(rprec), dimension(nyvec), intent(in) :: yvec
1703  real(rprec), dimension(nzvec), intent(in) :: zvec
1704  real(rprec), dimension(nx+kx), intent(in) :: xknot
1705  real(rprec), dimension(ny+ky), intent(in) :: yknot
1706  real(rprec), dimension(nz+kz), intent(in) :: zknot
1707  real(rprec), dimension(nx,ny,nz), intent(in) :: bcoef
1708  real(rprec), dimension(ldf,mdf,*), intent(out) :: val
1709 
1710  integer :: i, ik, il, ix, iy, iz
1711  integer :: ikx, iky, ikz
1712  integer, dimension(nxvec) :: leftx
1713  integer, dimension(nyvec) :: lefty
1714  integer, dimension(nzvec) :: leftz
1715  real(rprec), dimension(nxvec,kx) :: biatx
1716  real(rprec), dimension(nyvec,ky) :: biaty
1717  real(rprec), dimension(nzvec,kz) :: biatz
1718  real(rprec), dimension(max(nxvec,nyvec,nzvec)) :: term, save1
1719 
1720  real(rprec), dimension(max(nxvec,nyvec,nzvec), max(kx,ky,kz)) :: dl, dr
1721 
1722  logical :: same,next
1723 
1724 
1725  do i = 1, nx+kx-1
1726  if (xknot(i) .gt. xknot(i+1)) then
1727  write(6,*) "subroutine dbs3gd:"
1728  write(6,*) "xknot(i) <= xknot(i+1) required."
1729  write(6,*) i, xknot(i), xknot(i+1)
1730  write(6,*)
1731  write(6,*) xknot
1732  stop
1733  endif
1734  end do
1735 
1736  do i = 1, nxvec
1737  if ((xvec(i).lt.xknot(1)).or.(xvec(i).gt.xknot(nx+kx))) then
1738  write(6,*) "subroutine dbs3gd:"
1739  write(6,*) "ix with xknot(ix) <= x < xknot(ix+1) required."
1740  write(6,*) "x = ", xvec(i)
1741 !debug-begin
1742  write(6,*) 'i,xknot(1),xknot(nx+kx) ',i,xknot(1),xknot(nx+kx)
1743 !debug-end
1744 
1745  stop
1746  endif
1747  end do
1748 
1749  leftx(1) = 0
1750 
1751  call huntn(xknot,nx+kx,kx,xvec(1),leftx(1))
1752 
1753  do ix = 2, nxvec
1754  leftx(ix) = leftx(ix-1)
1755  same = (xknot(leftx(ix)) .le. xvec(ix)) &
1756  & .and. (xvec(ix) .le. xknot(leftx(ix)+1))
1757  if(.not. same ) then
1758  leftx(ix) = leftx(ix) + 1
1759  next = (xknot(leftx(ix)) .le. xvec(ix)) &
1760  & .and. (xvec(ix) .le. xknot(leftx(ix)+1))
1761  if (.not. next) call huntn(xknot,nx+kx,kx,xvec(ix),leftx(ix))
1762  endif
1763  end do
1764 
1765  do i = 1, ny+ky-1
1766  if (yknot(i) .gt. yknot(i+1)) then
1767  write(6,*) "subroutine dbs3gd:"
1768  write(6,*) "yknot(i) <= yknot(i+1) required."
1769  write(6,*) i, yknot(i), yknot(i+1)
1770  write(6,*)
1771  write(6,*) yknot
1772  stop
1773  endif
1774  end do
1775 
1776  do i = 1, nyvec
1777  if ((yvec(i).lt.yknot(1)).or.(yvec(i).gt.yknot(ny+ky))) then
1778  write(6,*) "subroutine dbs3gd:"
1779  write(6,*) "iy with yknot(iy) <= y < yknot(iy+1) required."
1780  write(6,*) "y = ", yvec(i)
1781  stop
1782  endif
1783  end do
1784 
1785  lefty(1) = 0
1786 
1787  call huntn(yknot,ny+ky,ky,yvec(1),lefty(1))
1788 
1789  do iy = 2, nyvec
1790  lefty(iy) = lefty(iy-1)
1791  same = (yknot(lefty(iy)) .le. yvec(iy)) &
1792  & .and. (yvec(iy) .le. yknot(lefty(iy)+1))
1793  if(.not. same ) then
1794  lefty(iy) = lefty(iy) + 1
1795  next = (yknot(lefty(iy)) .le. yvec(iy)) &
1796  & .and. (yvec(iy) .le. yknot(lefty(iy)+1))
1797  if (.not. next) call huntn(yknot,ny+ky,ky,yvec(iy),lefty(iy))
1798  endif
1799  end do
1800 
1801  do i = 1,nz+kz-1
1802  if (zknot(i) .gt. zknot(i+1)) then
1803  write(6,*) "subroutine dbs3gd:"
1804  write(6,*) "zknot(i) <= zknot(i+1) required."
1805  write(6,*) i, zknot(i), zknot(i+1)
1806  write(6,*)
1807  write(6,*) zknot
1808  stop
1809  endif
1810  end do
1811 
1812  do i = 1, nzvec
1813  if ((zvec(i).lt.zknot(1)).or.(zvec(i).gt.zknot(nz+kz))) then
1814  write(6,*) "subroutine dbs3gd:"
1815  write(6,*) "iz with zknot(iz) <= z < zknot(iz+1) required."
1816  write(6,*) "z = ", zvec(i)
1817  stop
1818  endif
1819  end do
1820 
1821  leftz(1) = 0
1822 
1823  call huntn(zknot,nz+kz,kz,zvec(1),leftz(1))
1824 
1825  do iz = 2, nzvec
1826  leftz(iz) = leftz(iz-1)
1827  same = (zknot(leftz(iz)) .le. zvec(iz)) &
1828  & .and. (zvec(iz) .le. zknot(leftz(iz)+1))
1829  if(.not. same ) then
1830  leftz(iz) = leftz(iz) + 1
1831  next = (zknot(leftz(iz)) .le. zvec(iz)) &
1832  & .and. (zvec(iz) .le. zknot(leftz(iz)+1))
1833  if (.not. next) call huntn(zknot,nz+kz,kz,zvec(iz),leftz(iz))
1834  endif
1835  end do
1836 
1837  if ((iderx .eq. 0) .and. (idery .eq. 0) .and. (iderz .eq.0)) then
1838 
1839  do ix = 1, nxvec
1840  biatx(ix,1) = one
1841  end do
1842 
1843  do ik = 1, kx-1
1844  do ix = 1, nxvec
1845  dr(ix,ik) = xknot(leftx(ix)+ik) - xvec(ix)
1846  dl(ix,ik) = xvec(ix) - xknot(leftx(ix)+1-ik)
1847  save1(ix) = zero
1848  end do
1849 
1850  do il = 1, ik
1851  do ix = 1, nxvec
1852  term(ix) = biatx(ix,il) / (dr(ix,il) + dl(ix,ik+1-il))
1853  biatx(ix,il) = save1(ix) + dr(ix,il) * term(ix)
1854  save1(ix) = dl(ix,ik+1-il) * term(ix)
1855  end do
1856  end do
1857 
1858  do ix = 1, nxvec
1859  biatx(ix,ik+1) = save1(ix)
1860  end do
1861  end do
1862 
1863  do iy = 1, nyvec
1864  biaty(iy,1) = one
1865  end do
1866 
1867  do ik = 1, ky-1
1868  do iy = 1, nyvec
1869  dr(iy,ik) = yknot(lefty(iy)+ik) - yvec(iy)
1870  dl(iy,ik) = yvec(iy) - yknot(lefty(iy)+1-ik)
1871  save1(iy) = zero
1872  end do
1873 
1874  do il = 1,ik
1875  do iy = 1,nyvec
1876  term(iy) = biaty(iy,il) / (dr(iy,il) + dl(iy,ik+1-il))
1877  biaty(iy,il) = save1(iy) + dr(iy,il) * term(iy)
1878  save1(iy) = dl(iy,ik+1-il) * term(iy)
1879  end do
1880  end do
1881 
1882  do iy = 1,nyvec
1883  biaty(iy,ik+1) = save1(iy)
1884  end do
1885  end do
1886 
1887  do iz = 1,nzvec
1888  biatz(iz,1) = one
1889  end do
1890 
1891  do ik = 1, kz-1
1892  do iz = 1, nzvec
1893  dr(iz,ik) = zknot(leftz(iz)+ik) - zvec(iz)
1894  dl(iz,ik) = zvec(iz) - zknot(leftz(iz)+1-ik)
1895  save1(iz) = zero
1896  end do
1897 
1898  do il = 1, ik
1899  do iz = 1, nzvec
1900  term(iz) = biatz(iz,il) / (dr(iz,il) + dl(iz,ik+1-il))
1901  biatz(iz,il) = save1(iz) + dr(iz,il) * term(iz)
1902  save1(iz) = dl(iz,ik+1-il) * term(iz)
1903  end do
1904  end do
1905 
1906  do iz = 1, nzvec
1907  biatz(iz,ik+1) = save1(iz)
1908  end do
1909  end do
1910 
1911  do iz = 1,nzvec
1912  do iy = 1,nyvec
1913  do ix = 1,nxvec
1914  val(ix,iy,iz) = zero
1915  end do
1916  end do
1917  end do
1918 
1919  do ikz = 1, kz
1920  do iky = 1, ky
1921  do ikx = 1, kx
1922  do iz = 1, nzvec
1923  do iy = 1, nyvec
1924  do ix = 1, nxvec
1925  val(ix,iy,iz) = val(ix,iy,iz) &
1926  & + biatx(ix,ikx) * biaty(iy,iky) &
1927  & * biatz(iz,ikz) &
1928  & * bcoef(leftx(ix)-kx+ikx, &
1929  & lefty(iy)-ky+iky,leftz(iz)-kz+ikz)
1930  end do
1931  end do
1932  end do
1933  end do
1934  end do
1935  end do
1936 
1937  else
1938 
1939 !dir preferstream
1940  do iz = 1, nzvec
1941  do iy = 1, nyvec
1942  do ix = 1, nxvec
1943  val(ix,iy,iz) = dbs3dr0(iderx,idery,iderz,xvec(ix), &
1944  & yvec(iy),zvec(iz),kx,ky,kz,xknot,yknot, &
1945  & zknot,nx,ny,nz,bcoef, &
1946  & leftx(ix),lefty(iy),leftz(iz))
1947  end do
1948  end do
1949  end do
1950 
1951  endif
1952 
1953  end subroutine dbs3gd
1954 
1955 
1956 
1957  subroutine bsplvb(t,n,jhigh,index,x,left,biatx)
1958 
1959  implicit none
1960 
1961  integer, intent(in) :: n, jhigh, index, left
1962 
1963  real(rprec), intent(in) :: x
1964  real(rprec), dimension(n), intent(in) :: t
1965  real(rprec), dimension(jhigh), intent(out) :: biatx
1966 
1967  integer :: j = 1
1968  integer :: i, jp1
1969  real(rprec) :: saved, term
1970  real(rprec), dimension(jhigh) :: dl, dr
1971 
1972 
1973  if (index .eq. 1) then
1974  j = 1
1975  biatx(1) = one
1976  if (j .ge. jhigh) return
1977  end if
1978 
1979 20 jp1 = j + 1
1980 
1981  dr(j) = t(left+j) - x
1982  dl(j) = x - t(left+1-j)
1983  saved = zero
1984 
1985  do i = 1, j
1986  term = biatx(i) / (dr(i) + dl(jp1-i))
1987  biatx(i) = saved + dr(i) * term
1988  saved = dl(jp1-i) * term
1989  end do
1990 
1991  biatx(jp1) = saved
1992  j = jp1
1993 
1994  if (j .lt. jhigh) go to 20
1995 
1996  end subroutine bsplvb
1997 
1998 
1999 
2000  subroutine banfac(w,nroww,nrow,nbandl,nbandu,iflag)
2001 
2002  implicit none
2003 
2004  integer, intent(in) :: nroww,nrow
2005  integer, intent(in) :: nbandl,nbandu
2006  integer, intent(out) :: iflag
2007  real(rprec), dimension(nroww,nrow), intent(inout) :: w
2008 
2009  real(rprec) :: pivot, factor
2010  integer :: middle, nrowm1, jmax, kmax, ipk, midmk, i, j, k
2011 
2012 
2013  iflag = 1
2014  middle = nbandu + 1
2015  nrowm1 = nrow - 1
2016 
2017  if (nrowm1 .lt. 0) goto 999
2018  if (nrowm1 .eq. 0) goto 900
2019  if (nrowm1 .gt. 0) goto 10
2020 
2021 10 if (nbandl .gt. 0) go to 30
2022 
2023  do i = 1, nrowm1
2024  if (w(middle,i) .eq. zero) go to 999
2025  end do
2026 
2027  go to 900
2028 
2029 30 if (nbandu .gt. 0) go to 60
2030 
2031  do i = 1, nrowm1
2032  pivot = w(middle,i)
2033  if(pivot .eq. zero) go to 999
2034  jmax = min0(nbandl, nrow - i)
2035  do j = 1, jmax
2036  w(middle+j,i) = w(middle+j,i) / pivot
2037  end do
2038  end do
2039 
2040  return
2041 
2042 60 do i = 1, nrowm1
2043  pivot = w(middle,i)
2044  if (pivot .eq. zero) go to 999
2045  jmax = min0(nbandl,nrow - i)
2046  do j = 1,jmax
2047  w(middle+j,i) = w(middle+j,i) / pivot
2048  end do
2049 
2050  kmax = min0(nbandu,nrow - i)
2051 
2052  do k = 1, kmax
2053  ipk = i + k
2054  midmk = middle - k
2055  factor = w(midmk,ipk)
2056  do j = 1, jmax
2057  w(midmk+j,ipk) = w(midmk+j,ipk) - w(middle+j,i) &
2058  & * factor
2059  end do
2060  end do
2061  end do
2062 
2063 900 if (w(middle,nrow) .ne. zero) return
2064 999 iflag = 2
2065 
2066  end subroutine banfac
2067 
2068 
2069  subroutine banslv(w,nroww,nrow,nbandl,nbandu,b)
2070 
2071  implicit none
2072 
2073  integer, intent(in) :: nroww,nrow
2074  integer, intent(in) :: nbandl,nbandu
2075  real(rprec), dimension(nroww,nrow), intent(in) :: w
2076  real(rprec), dimension(nrow), intent(inout) :: b
2077 
2078  integer :: middle, nrowm1, jmax, i, j
2079 
2080  middle = nbandu + 1
2081  if (nrow .eq. 1) goto 99
2082  nrowm1 = nrow - 1
2083  if (nbandl .eq. 0) goto 30
2084 
2085  do i = 1, nrowm1
2086  jmax = min0(nbandl, nrow - i)
2087  do j = 1, jmax
2088  b(i+j) = b(i+j) - b(i) * w(middle+j,i)
2089  end do
2090  end do
2091 
2092 30 if (nbandu .gt. 0) goto 50
2093 
2094  do i = 1, nrow
2095  b(i) = b(i) / w(1,i)
2096  end do
2097 
2098  return
2099 
2100 50 do i = nrow, 2, -1
2101  b(i) = b(i)/w(middle,i)
2102  jmax = min0(nbandu,i-1)
2103  do j = 1, jmax
2104  b(i-j) = b(i-j) - b(i) * w(middle-j,i)
2105  end do
2106  end do
2107 
2108 99 b(1) = b(1) / w(middle,1)
2109 
2110  end subroutine banslv
2111 
2112 
2113  subroutine huntn(xx,n,kord,x,jlo)
2114 
2115  implicit none
2116 
2117  integer, intent(in) :: n, kord
2118  real(rprec), intent(in) :: x
2119  real(rprec), dimension(n), intent(in) :: xx
2120 
2121  integer, intent(inout) :: jlo
2122 
2123  integer :: max, null, jhi, jm, inc
2124 
2125 !
2126 ! works only for B-Splines (order n)
2127 !
2128 
2129  max = n - kord
2130  null = kord
2131 
2132  if (jlo.le.null.or.jlo.gt.max) then
2133  jlo = null
2134  jhi = max+1
2135  goto 30
2136  endif
2137 
2138  inc = 1
2139 
2140  if (x .ge. xx(jlo)) then
2141 10 jhi = jlo + inc
2142  if (jhi .gt. max) then
2143  jhi = max + 1
2144  else if (x .ge. xx(jhi)) then
2145  jlo = jhi
2146  inc = inc + inc
2147  goto 10
2148  endif
2149  else
2150  jhi = jlo
2151 20 jlo = jhi - inc
2152  if (jlo .le. null) then
2153  jlo = null
2154  else if (x .lt. xx(jlo)) then
2155  jhi = jlo
2156  inc = inc + inc
2157  goto 20
2158  endif
2159  endif
2160 
2161 30 if (jhi-jlo.eq.1) return
2162 
2163  jm = (jhi + jlo) / 2
2164  if (x .gt. xx(jm)) then
2165  jlo = jm
2166  else
2167  jhi = jm
2168  endif
2169 
2170  goto 30
2171 
2172  end subroutine huntn
2173 
2174 
2175  function dbs2dr0(iderx,idery,x,y,kx,ky,xknot,yknot,nx,ny,bcoef,nintx,ninty)
2176 ! dir$ inlinealways dbs2dr0
2177 
2178 !
2179 ! Evaluates the derivative of a two-dimensional tensor-product spline,
2180 ! given its tensor-product B-spline representation.
2181 !
2182 ! iderx - order of the derivative in the x-direction. (input)
2183 ! idery - order of the derivative in the y-direction. (input)
2184 ! x - x-coordinate of the point at which the spline is to be
2185 ! evaluated. (input)
2186 ! y - y-coordinate of the point at which the spline is to be
2187 ! evaluated. (input)
2188 ! kx - order of the spline in the x-direction. (input)
2189 ! ky - order of the spline in the y-direction. (input)
2190 ! xknot - array of length nx+kx containing the knot
2191 ! sequence in the x-direction. (input)
2192 ! xknot must be nondecreasing.
2193 ! yknot - array of length ny+ky containing the knot
2194 ! sequence in the y-direction. (input)
2195 ! yknot must be nondecreasing.
2196 ! nx - number of B-spline coefficients in the x-direction.
2197 ! (input)
2198 ! ny - number of B-spline coefficients in the y-direction.
2199 ! (input)
2200 ! bcoef - array of length nx*ny containing the
2201 ! tensor-product B-spline coefficients. (input)
2202 ! bscoef is treated internally as a matrix of size nx
2203 ! by ny.
2204 ! dbs2dr0 - value of the (iderx,idery) derivative of the spline at
2205 ! (x,y). (output)
2206 !
2207 
2208 
2209 
2210 ! --------------------------------------------------------------------
2211 !EFD same as dbs2dr except nintx,ninty is passed in and no error checking
2212 ! --------------------------------------------------------------------
2213 
2214  implicit none
2215 
2216  integer, intent(in) :: iderx, idery
2217  integer, intent(in) :: kx, nx, ky, ny
2218  real(rprec) :: dbs2dr0
2219  real(rprec), intent(in) :: x, y
2220  real(rprec), dimension(nx+kx), intent(in) :: xknot
2221  real(rprec), dimension(ny+ky), intent(in) :: yknot
2222  real(rprec), dimension(nx,ny), intent(in) :: bcoef
2223 
2224  integer, intent(in) :: nintx,ninty
2225 
2226  integer :: ix, iy, iky
2227  real(rprec), dimension(ky) :: work
2228 
2229 !
2230 ! check if knot(i) <= knot(i+1) and calculation of i so that
2231 ! knot(i) <= x < knot(i+1)
2232 !
2233 
2234 !EFD nintx = 0
2235 !EFD
2236 !EFD do ix = 1, nx+kx-1
2237 !EFD if (xknot(ix) .gt. xknot(ix+1)) then
2238 !EFD write(6,*) "subroutine dbs2dr0:"
2239 !EFD write(6,*) "xknot(ix) <= xknot(ix+1) required."
2240 !EFD write(6,*) ix, xknot(ix), xknot(ix+1)
2241 !EFD stop
2242 !EFD endif
2243 !EFD if((xknot(ix) .le. x) .and. (x .lt. xknot(ix+1))) nintx = ix
2244 !EFD end do
2245 !EFD
2246 !EFD if(nintx .eq. 0) then
2247 !EFD write(6,*) "subroutine dbs2dr0:"
2248 !EFD write(6,*) "ix with xknot(ix) <= x < xknot(ix+1) required."
2249 !EFD write(6,*) "x = ", x
2250 !EFD stop
2251 !EFD endif
2252 !EFD
2253 !EFD ninty = 0
2254 !EFD
2255 !EFD do iy = 1, ny+ky-1
2256 !EFD if (yknot(iy) .gt. yknot(iy+1)) then
2257 !EFD write(6,*) "subroutine dbs2dr0:"
2258 !EFD write(6,*) "yknot(iy) <= yknot(iy+1) required."
2259 !EFD write(6,*) iy, yknot(iy), yknot(iy+1)
2260 !EFD stop
2261 !EFD endif
2262 !EFD if ((yknot(iy) .le. y) .and. (y .lt. yknot(iy+1))) ninty = iy
2263 !EFD end do
2264 !EFD
2265 !EFD if(ninty .eq. 0) then
2266 !EFD write(6,*) "subroutine dbs2dr0:"
2267 !EFD write(6,*) "iy with yknot(iy) <= y < yknot(iy+1) required."
2268 !EFD write(6,*) "y = ", y
2269 !EFD stop
2270 !EFD endif
2271 
2272  do iky = 1, ky
2273  work(iky) = dbsdca(iderx,x,kx,xknot,nx,bcoef(1,ninty-ky+iky),nintx)
2274  end do
2275 
2276  dbs2dr0 = dbsder0(idery,y,ky,yknot(ninty-ky+1),ky,work)
2277 
2278  end function dbs2dr0
2279 
2280 
2281  function dbs3dr0(iderx,idery,iderz,x,y,z,kx,ky,kz,xknot,yknot,zknot, &
2282  & nx,ny,nz,bcoef, nintx,ninty,nintz)
2283 ! dir$ inlinealways dbs3dr0
2284 !
2285 ! Evaluates the derivative of a three-dimensional tensor-product spline,
2286 ! given its tensor-product B-spline representation.
2287 !
2288 ! iderx - order of the x-derivative. (input)
2289 ! idery - order of the y-derivative. (input)
2290 ! iderz - order of the z-derivative. (input)
2291 ! x - x-coordinate of the point at which the spline is to be
2292 ! evaluated. (input)
2293 ! y - y-coordinate of the point at which the spline is to be
2294 ! evaluated. (input)
2295 ! z - z-coordinate of the point at which the spline is to be
2296 ! evaluated. (input)
2297 ! kx - order of the spline in the x-direction. (input)
2298 ! ky - order of the spline in the y-direction. (input)
2299 ! kz - order of the spline in the z-direction. (input)
2300 ! xknot - array of length nx+kx containing the knot
2301 ! sequence in the x-direction. (input)
2302 ! xknot must be nondecreasing.
2303 ! yknot - array of length ny+ky containing the knot
2304 ! sequence in the y-direction. (input)
2305 ! yknot must be nondecreasing.
2306 ! zknot - array of length nz+kz containing the knot
2307 ! sequence in the z-direction. (input)
2308 ! zknot must be nondecreasing.
2309 ! nx - number of B-spline coefficients in the x-direction.
2310 ! (input)
2311 ! ny - number of B-spline coefficients in the y-direction.
2312 ! (input)
2313 ! nz - number of B-spline coefficients in the z-direction.
2314 ! (input)
2315 ! bcoef - array of length nx*ny*nz containing the
2316 ! tensor-product B-spline coefficients. (input)
2317 ! bscoef is treated internally as a matrix of size nx
2318 ! by ny by nz.
2319 ! dbs3dr0 - value of the (iderx,idery,iderz) derivative of the
2320 ! spline at (x,y,z). (output)
2321 !
2322 
2323  implicit none
2324 
2325  integer, intent(in) :: iderx, idery, iderz
2326  integer, intent(in) :: nx, ny, nz, kx, ky, kz
2327  real(rprec), intent(in) :: x, y, z
2328  real(rprec), dimension(nx+kx), intent(in) :: xknot
2329  real(rprec), dimension(ny+ky), intent(in) :: yknot
2330  real(rprec), dimension(nz+kz), intent(in) :: zknot
2331  real(rprec), dimension(nx,ny,nz), intent(in) :: bcoef
2332  real(rprec) :: dbs3dr0
2333 
2334 
2335 !EFD dbs3dr but without checking and nintx,ninty,nintz passed in
2336 
2337  integer, intent(in) :: nintx,ninty,nintz
2338 
2339  integer :: iz
2340  real(rprec), dimension(kz) :: work
2341  logical :: isok
2342  logical, parameter :: need_check = .false.
2343 
2344 !
2345 ! check if knot(i) <= knot(i+1) and calculation of i so that
2346 ! knot(i) <= x < knot(i+1)
2347 !
2348 
2349 !EFD nintz = 0
2350 !EFD
2351 !EFD do iz = 1, nz+kz-1
2352 !EFD if (zknot(iz) .gt. zknot(iz + 1)) then
2353 !EFD write(6,*) "subroutine dbs3vl:"
2354 !EFD write(6,*) "zknot(iz) <= zknot(iz+1) required."
2355 !EFD write(6,*) iz, zknot(iz), zknot(iz+1)
2356 !EFD stop
2357 !EFD endif
2358 !EFD if((zknot(iz) .le. z) .and. (z .lt. zknot(iz + 1))) nintz = iz
2359 !EFD end do
2360 !EFD
2361 !EFD if(nintz .eq. 0) then
2362 !EFD write(6,*) "subroutine dbs3dr0:"
2363 !EFD write(6,*) "iz with zknot(iz) <= z < zknot(iz+1) required."
2364 !EFD write(6,*) "zknot(iz) = ", zknot(iz)
2365 !EFD write(6,*) " z = ", z
2366 !EFD write(6,*) "zknot(iz+1) = ", zknot(iz+1)
2367 !EFD stop
2368 !EFD endif
2369 
2370 !EFD if (need_check) then
2371 !EFD
2372 !EFD isok = (1.le.nintx).and.(nintx.lt.nx+kx).and. &
2373 !EFD & (xknot(nintx).le.x).and.(x.le.xknot(nintx+1))
2374 !EFD if (.not.isok) then
2375 !EFD write(6,*) 'nintx, x ',nintx,x
2376 !EFD write(6,*) 'xknot(nintx),xknot(nintx+1)', &
2377 !EFD & xknot(nintx),xknot(nintx+1)
2378 !EFD endif
2379 !EFD
2380 !EFD isok = (1.le.ninty).and.(ninty.lt.ny+ky).and. &
2381 !EFD & (yknot(ninty).le.y).and.(y.le.yknot(ninty+1))
2382 !EFD if (.not.isok) then
2383 !EFD write(6,*) 'ninty, y ',ninty,y
2384 !EFD write(6,*) 'yknot(ninty),yknot(ninty+1)', &
2385 !EFD & yknot(ninty),yknot(ninty+1)
2386 !EFD endif
2387 !EFD
2388 !EFD isok = (1.le.nintz).and.(nintz.lt.nz+kz).and. &
2389 !EFD & (zknot(nintz).le.z).and.(z.le.zknot(nintz+1))
2390 !EFD if (.not.isok) then
2391 !EFD write(6,*) 'nintz, z ',nintz,z
2392 !EFD write(6,*) 'zknot(nintz),zknot(nintz+1)', &
2393 !EFD & zknot(nintz),zknot(nintz+1)
2394 !EFD endif
2395 !EFD
2396 !EFD
2397 !EFD endif
2398 
2399 
2400  do iz = 1, kz
2401  work(iz) = dbs2dr0(iderx,idery,x,y,kx,ky,xknot,yknot,nx,ny, &
2402  & bcoef(1,1,nintz-kz+iz), nintx,ninty)
2403  end do
2404 
2405  dbs3dr0 = dbsder0(iderz,z,kz,zknot(nintz-kz+1),kz,work)
2406 
2407  end function dbs3dr0
2408 
2409 
2410 
2411  function dbsder0(iderx,x,kx,xknot,nx,bcoef )
2412 ! dir$ inlinealways dbsder0
2413 
2414 !
2415 ! Evaluates the derivative of a spline, given its B-spline representation.
2416 !
2417 !
2418 ! iderx - order of the derivative to be evaluated. (input)
2419 ! in particular, iderx = 0 returns the value of the
2420 ! spline.
2421 ! x - point at which the spline is to be evaluated. (input)
2422 ! kx - order of the spline. (input)
2423 ! xknot - array of length nx+kx containing the knot
2424 ! sequence. (input)
2425 ! xknot must be nondecreasing.
2426 ! nx - number of B-spline coefficients. (input)
2427 ! bcoef - array of length nx containing the B-spline
2428 ! coefficients. (input)
2429 ! dbsder0 - value of the iderx-th derivative of the spline at x.
2430 ! (output)
2431 !
2432 
2433  implicit none
2434 
2435  integer, intent(in) :: iderx, kx, nx
2436  real(rprec) :: dbsder0
2437  real(rprec), intent(in) :: x
2438  real(rprec), dimension(nx+kx), intent(in) :: xknot
2439  real(rprec), dimension(nx), intent(in) :: bcoef
2440 
2441 
2442 ! ------------------------------------
2443 !EFD no error checking
2444 ! ------------------------------------
2445 
2446 
2447  integer :: ix, ik, il, leftx
2448  real(rprec) :: save, save1, save2, y, sum, dik
2449  real(rprec), dimension(kx) :: work, dl, dr,bsp
2450  logical :: isok
2451  integer :: nxpkxm1
2452 
2453 !
2454 ! check if xknot(i) <= xknot(i+1) and calculation of i so that
2455 ! xknot(i) <= x < xknot(i+1)
2456 !
2457 
2458 !EFD leftx = 0
2459 !EFD do ix = 1,nx+kx-1
2460 !EFD if (xknot(ix) .gt. xknot(ix+1)) then
2461 !EFD write(6,*) "subroutine dbsder0:"
2462 !EFD write(6,*) "xknot(ix) <= xknot(ix+1) required."
2463 !EFD stop
2464 !EFD endif
2465 !EFD if ((xknot(ix) .le. x) .and. (x .lt. xknot(ix+1))) leftx = ix
2466 !EFD end do
2467 !EFD
2468 !EFD if (leftx .eq. 0) then
2469 !EFD write(6,*) "subroutine dbsder0:"
2470 !EFD write(6,*) "ix with xknot(ix) <= x < xknot(ix+1) required."
2471 !EFD write(6,*) "xknot(1) = ", xknot(1)
2472 !EFD write(6,*) "xknot(nx+kx) = ", xknot(nx+kx)
2473 !EFD write(6,*) " x = ", x
2474 !EFD stop
2475 !EFD endif
2476 
2477 
2478 
2479  leftx = 0
2480  nxpkxm1 = nx+kx-1
2481  select case(nxpkxm1)
2482  case (1)
2483  do ix=1,1
2484  if ((xknot(ix).le.x).and.(x.le.xknot(ix+1)) ) then
2485  leftx = ix
2486  exit
2487  endif
2488  enddo
2489  case (2)
2490  do ix=1,2
2491  if ((xknot(ix).le.x).and.(x.le.xknot(ix+1)) ) then
2492  leftx = ix
2493  exit
2494  endif
2495  enddo
2496  case (3)
2497  do ix=1,3
2498  if ((xknot(ix).le.x).and.(x.le.xknot(ix+1)) ) then
2499  leftx = ix
2500  exit
2501  endif
2502  enddo
2503  case (4)
2504  do ix=1,4
2505  if ((xknot(ix).le.x).and.(x.le.xknot(ix+1)) ) then
2506  leftx = ix
2507  exit
2508  endif
2509  enddo
2510  case (5)
2511  do ix=1,5
2512  if ((xknot(ix).le.x).and.(x.le.xknot(ix+1)) ) then
2513  leftx = ix
2514  exit
2515  endif
2516  enddo
2517  case (6)
2518  do ix=1,6
2519  if ((xknot(ix).le.x).and.(x.le.xknot(ix+1)) ) then
2520  leftx = ix
2521  exit
2522  endif
2523  enddo
2524  case (7)
2525  do ix=1,7
2526  if ((xknot(ix).le.x).and.(x.le.xknot(ix+1)) ) then
2527  leftx = ix
2528  exit
2529  endif
2530  enddo
2531  case (8)
2532  do ix=1,8
2533  if ((xknot(ix).le.x).and.(x.le.xknot(ix+1)) ) then
2534  leftx = ix
2535  exit
2536  endif
2537  enddo
2538  case (9)
2539  do ix=1,9
2540  if ((xknot(ix).le.x).and.(x.le.xknot(ix+1)) ) then
2541  leftx = ix
2542  exit
2543  endif
2544  enddo
2545  case (10)
2546  do ix=1,10
2547  if ((xknot(ix).le.x).and.(x.le.xknot(ix+1)) ) then
2548  leftx = ix
2549  exit
2550  endif
2551  enddo
2552  case default
2553  do ix=1,nxpkxm1
2554  if ((xknot(ix).le.x).and.(x.le.xknot(ix+1)) ) then
2555  leftx = ix
2556  exit
2557  endif
2558  enddo
2559  end select
2560 
2561 
2562  dbsder0 = dbsdca(iderx,x,kx,xknot,nx,bcoef,leftx)
2563 
2564  return
2565  end function dbsder0
2566 
2567 
2568  subroutine dbs3vd(iderx,idery,iderz,nxyz,xvec,yvec,zvec, &
2569  & kx,ky,kz,xknot,yknot,zknot,nx,ny,nz,bcoef,val, &
2570  & is_uniformx, is_uniformy, is_uniformz)
2571 
2572 !
2573 ! Evaluates the derivative of a three-dimensional tensor-product spline,
2574 ! given its tensor-product B-spline representation on a grid.
2575 !
2576 ! iderx - order of the x-derivative. (input)
2577 ! idery - order of the y-derivative. (input)
2578 ! iderz - order of the z-derivative. (input)
2579 ! xvec - array of length nx containing the x-coordinates at
2580 ! which the spline is to be evaluated. (input)
2581 ! the points in xvec should be strictly increasing.
2582 ! yvec - array of length ny containing the y-coordinates at
2583 ! which the spline is to be evaluated. (input)
2584 ! the points in yvec should be strictly increasing.
2585 ! zvec - array of length nz containing the z-coordinates at
2586 ! which the spline is to be evaluated. (input)
2587 ! the points in yvec should be strictly increasing.
2588 ! kx - order of the spline in the x-direction. (input)
2589 ! ky - order of the spline in the y-direction. (input)
2590 ! kz - order of the spline in the z-direction. (input)
2591 ! xknot - array of length nx+kx containing the knot
2592 ! sequence in the x-direction. (input)
2593 ! xknot must be nondecreasing.
2594 ! yknot - array of length ny+ky containing the knot
2595 ! sequence in the y-direction. (input)
2596 ! yknot must be nondecreasing.
2597 ! zknot - array of length nz+kz containing the knot
2598 ! sequence in the z-direction. (input)
2599 ! zknot must be nondecreasing.
2600 ! nx - number of B-spline coefficients in the x-direction.
2601 ! (input)
2602 ! ny - number of B-spline coefficients in the y-direction.
2603 ! (input)
2604 ! nz - number of B-spline coefficients in the z-direction.
2605 ! (input)
2606 ! bcoef - array of length nx*ny*nz containing the
2607 ! tensor-product B-spline coefficients. (input)
2608 ! bscoef is treated internally as a matrix of size nx
2609 ! by ny by nz.
2610 ! val - array of size nxyz containing the values of
2611 ! the (iderx,idery,iderz) derivative of the spline (output)
2612 ! value(ijk) contains the derivative of the spline at
2613 ! the point (xvec(ijk), yvec(ijk), zvec(ijk)).
2614 !
2615 
2616  implicit none
2617 
2618  integer, intent(in) :: iderx
2619  integer, intent(in) :: idery
2620  integer, intent(in) :: iderz
2621  integer, intent(in) :: nxyz
2622  integer, intent(in) :: kx, nx
2623  integer, intent(in) :: ky, ny
2624  integer, intent(in) :: kz, nz
2625 
2626  real(rprec), dimension(nxyz), intent(in) :: xvec
2627  real(rprec), dimension(nxyz), intent(in) :: yvec
2628  real(rprec), dimension(nxyz), intent(in) :: zvec
2629  real(rprec), dimension(nx+kx), intent(in) :: xknot
2630  real(rprec), dimension(ny+ky), intent(in) :: yknot
2631  real(rprec), dimension(nz+kz), intent(in) :: zknot
2632  real(rprec), dimension(nx,ny,nz), intent(in) :: bcoef
2633  real(rprec), dimension(nxyz), intent(inout) :: val
2634 
2635  logical, intent(in) :: is_uniformx
2636  logical, intent(in) :: is_uniformy
2637  logical, intent(in) :: is_uniformz
2638 
2639  integer :: i, ik, il
2640  integer :: ix, iy, iz
2641  integer :: ikx, iky, ikz
2642  integer, dimension(nxyz) :: leftx
2643  integer, dimension(nxyz) :: lefty
2644  integer, dimension(nxyz) :: leftz
2645  real(rprec), dimension(nxyz,kx) :: biatx
2646  real(rprec), dimension(nxyz,ky) :: biaty
2647  real(rprec), dimension(nxyz,kz) :: biatz
2648  real(rprec), dimension(nxyz) :: term, save1
2649 
2650  real(rprec), dimension(nxyz, max(kx,ky,kz)) :: dl, dr
2651 
2652 
2653  logical :: use_huntn = .false.
2654  logical :: use_linear = .false.
2655  logical :: use_vsearch = .false.
2656  logical :: use_hash = .true.
2657  logical :: isok, is_uniform
2658  integer :: ileft, ijk, istart,iend
2659  integer :: t1,t2,count_rate
2660  real(rprec) :: delta
2661  real(rprec), parameter :: tol=1.0d-7
2662 
2663  integer :: nintx,ninty,nintz
2664  real(rprec),dimension(kz) :: workz
2665  real(rprec),dimension(ky) :: worky
2666 
2667  real(rprec), parameter :: zero = 0
2668  real(rprec), parameter :: one = 1
2669 
2670  logical, parameter :: use_Axyz = .false.
2671  real(rprec),dimension(kx,ky,kz) :: Axyz
2672  real(rprec),dimension(ky,kz) :: Ayz
2673  real(rprec),dimension(kz) :: Az
2674 
2675 ! -----------------------------
2676 ! double check knot positions
2677 ! -----------------------------
2678  call system_clock(t1,count_rate)
2679  isok = all(xknot(2:(nx+kx)) .ge. xknot(1:(nx+kx-1)))
2680  if (.not.isok) then
2681  do i = 1, nx+kx-1
2682  if (xknot(i) .gt. xknot(i+1)) then
2683  write(6,*) "subroutine dbs3vd:"
2684  write(6,*) "xknot(i) <= xknot(i+1) required."
2685  write(6,*) i, xknot(i), xknot(i+1)
2686  write(6,*)
2687  write(6,*) xknot
2688  stop
2689  endif
2690  end do
2691  endif
2692 
2693 
2694  isok = all(yknot(2:(ny+ky)) .ge. yknot(1:(ny+ky-1)))
2695  if (.not.isok) then
2696  do i = 1, ny+ky-1
2697  if (yknot(i) .gt. yknot(i+1)) then
2698  write(6,*) "subroutine dbs3vd:"
2699  write(6,*) "yknot(i) <= yknot(i+1) required."
2700  write(6,*) i, yknot(i), yknot(i+1)
2701  write(6,*)
2702  write(6,*) yknot
2703  stop
2704  endif
2705  end do
2706  endif
2707 
2708 
2709  isok = all(zknot(2:(nz+kz)) .ge. zknot(1:(nz+kz-1)))
2710  if (.not.isok) then
2711  do i = 1, nz+kz-1
2712  if (zknot(i) .gt. zknot(i+1)) then
2713  write(6,*) "subroutine dbs3vd:"
2714  write(6,*) "zknot(i) <= zknot(i+1) required."
2715  write(6,*) i, zknot(i), zknot(i+1)
2716  write(6,*)
2717  write(6,*) zknot
2718  stop
2719  endif
2720  end do
2721  endif
2722 
2723  call system_clock(t2,count_rate)
2724  if (idebug.ge.2) then
2725  write(*,*) 'time for 1st check ',real(t2-t1)/real(count_rate)
2726  endif
2727 
2728 ! ----------------------------
2729 ! find the location of indices
2730 ! ----------------------------
2731 
2732  call system_clock(t1,count_rate)
2733 
2734  if (use_huntn) then
2735  do i=1,nxyz
2736  ileft = 0
2737  call huntn(xknot,nx+kx,kx,xvec(i),ileft)
2738  leftx(i) = ileft
2739  enddo
2740  do i=1,nxyz
2741  ileft = 0
2742  call huntn(yknot,ny+ky,ky,yvec(i),ileft)
2743  lefty(i) = ileft
2744  enddo
2745  do i=1,nxyz
2746  ileft = 0
2747  call huntn(zknot,nz+kz,kz,zvec(i),ileft)
2748  leftz(i) = ileft
2749  enddo
2750  else if (use_linear) then
2751 
2752  leftx(1:nxyz) = 0
2753  lefty(1:nxyz) = 0
2754  leftz(1:nxyz) = 0
2755  do ijk=1,nxyz
2756  do ix=1,nx+kx-1
2757  if ((xknot(ix).le.xvec(ijk)).and.(xvec(ijk).le.xknot(ix+1)))then
2758  leftx(ijk) = ix
2759  exit
2760  endif
2761  enddo
2762 
2763  do iy=1,ny+ky-1
2764  if ((yknot(iy).le.yvec(ijk)).and.(yvec(ijk).le.yknot(iy+1)))then
2765  lefty(ijk) = iy
2766  exit
2767  endif
2768  enddo
2769 
2770  do iz=1,nz+kz-1
2771  if ((zknot(iz).le.zvec(ijk)).and.(zvec(ijk).le.zknot(iz+1)))then
2772  leftz(ijk) = iz
2773  exit
2774  endif
2775  enddo
2776  enddo
2777  else if (use_vsearch) then
2778  if (idebug.ge.2) then
2779  write(*,*) 'using vsearch '
2780  endif
2781 
2782  call vsearch(nx+kx,xknot, nxyz, xvec, leftx )
2783  call vsearch(ny+ky,yknot, nxyz, yvec, lefty )
2784  call vsearch(nz+kz,zknot, nxyz, zvec, leftz )
2785  else if (use_hash) then
2786 
2787 ! ---------------------------------------------------
2788 ! geometric hashing works only if the grid is uniform
2789 ! ---------------------------------------------------
2790 
2791  istart = kx+1
2792  iend = nx
2793  delta = xknot(istart+1)-xknot(istart)
2794  is_uniform = is_uniformx
2795 
2796  if (is_uniform) then
2797  call vhash(xknot,nx,kx,nxyz,xvec,leftx)
2798  else
2799  call vsearch(nx+kx,xknot, nxyz,xvec,leftx)
2800  endif
2801 
2802 
2803 
2804  istart = ky+1
2805  iend = ny
2806  delta = yknot(istart+1)-yknot(istart)
2807  is_uniform = is_uniformy
2808 
2809  if (is_uniform) then
2810  call vhash(yknot,ny,ky,nxyz,yvec,lefty)
2811  else
2812  call vsearch(ny+ky,yknot, nxyz,yvec,lefty)
2813  endif
2814 
2815 
2816  istart = kz+1
2817  iend = nz
2818  delta = zknot(istart+1)-zknot(istart)
2819  is_uniform = is_uniformz
2820 
2821  if (is_uniform) then
2822  call vhash(zknot,nz,kz,nxyz,zvec,leftz)
2823  else
2824  call vsearch(nz+kz,zknot, nxyz,zvec,leftz)
2825  endif
2826 
2827  endif
2828 
2829 
2830 
2831  call system_clock(t2,count_rate)
2832  if (idebug.ge.2) then
2833  write(*,*) 'time for index search ',real(t2-t1)/real(count_rate)
2834  endif
2835 
2836 
2837 
2838 ! ------------
2839 ! double check
2840 ! ------------
2841  call system_clock(t1,count_rate)
2842 
2843 
2844  isok = .false.
2845  if (all((1.le.leftx(1:nxyz)).and.(leftx(1:nxyz).lt.nx+kx))) then
2846 ! dir$ ivdep
2847  isok = all((xknot( leftx(1:nxyz) ) .le. xvec(1:nxyz)).and. &
2848  & (xvec(1:nxyz).le.xknot( 1+leftx(1:nxyz))) )
2849  endif
2850  if (.not.isok) then
2851  do i=1,nxyz
2852  ileft = leftx(i)
2853  isok = (1.le.ileft).and.(ileft.lt.nx+kx)
2854  if (isok) then
2855  isok= (xknot( ileft ).le. xvec(i)).and. &
2856  & (xvec(i).le.xknot(ileft+1))
2857  endif
2858 
2859  if (.not.isok) then
2860  write(6,*) "subroutine dbs3vd:"
2861  write(6,*) "ix with xknot(ix) <= x < xknot(ix+1) required."
2862  write(6,*) "x = ", xvec(i)
2863  write(6,*) "i,ileft ",i,ileft
2864  write(6,*) 'nx,kx ',nx,kx
2865  do ix=1,nx+kx
2866  write(*,*) 'ix,xknot(ix) ',ix,xknot(ix)
2867  enddo
2868  stop '** error in dbs3vd ** '
2869  endif
2870  enddo
2871  endif
2872 
2873  isok = .false.
2874  if (all((1.le.lefty(1:nxyz)).and.(lefty(1:nxyz).lt.ny+ky))) then
2875 ! dir$ ivdep
2876  isok = all((yknot( lefty(1:nxyz) ) .le. yvec(1:nxyz)).and. &
2877  & (yvec(1:nxyz).le.yknot( 1+lefty(1:nxyz))) )
2878  endif
2879  if (.not.isok) then
2880  do i=1,nxyz
2881  ileft = lefty(i)
2882  isok = (1.le.ileft).and.(ileft.lt.ny+ky)
2883  if (isok) then
2884  isok=(yknot( ileft ).le. yvec(i)).and. &
2885  & (yvec(i).le.yknot(ileft+1))
2886  endif
2887 
2888  if (.not.isok) then
2889  write(6,*) "subroutine dbs3vd:"
2890  write(6,*) "iy with yknot(iy) <= y < yknot(iy+1) required."
2891  write(6,*) "y = ", yvec(i)
2892  write(6,*) "i,ileft ",i,ileft
2893  write(6,*) 'ny,ky ',ny,ky
2894  do iy=1,ny+ky
2895  write(*,*) 'iy,yknot(iy) ',iy,yknot(iy)
2896  enddo
2897  stop '** error in dbs3vd ** '
2898  endif
2899  enddo
2900  endif
2901 
2902  isok = .false.
2903  if (all((1.le.leftz(1:nxyz)).and.(leftz(1:nxyz).lt.nz+kz))) then
2904 ! dir$ ivdep
2905  isok = all((zknot( leftz(1:nxyz) ) .le. zvec(1:nxyz)).and. &
2906  & (zvec(1:nxyz).le.zknot( 1+leftz(1:nxyz))) )
2907  endif
2908  if (.not.isok) then
2909  do i=1,nxyz
2910  ileft = leftz(i)
2911  isok = (1.le.ileft).and.(ileft.lt.nz+kz)
2912  if (isok) then
2913  isok= (zknot( ileft ).le. zvec(i)).and. &
2914  & (zvec(i).le.zknot(ileft+1))
2915  endif
2916 
2917  if (.not.isok) then
2918  write(6,*) "subroutine dbs3vd:"
2919  write(6,*) "iz with zknot(iz) <= z < zknot(iz+1) required."
2920  write(6,*) "z = ", zvec(i)
2921  write(6,*) "i,ileft ",i,ileft
2922  write(6,*) 'nz,kz ',nz,kz
2923  do iz=1,nz+kz
2924  write(*,*) 'iz,zknot(iz) ',iz,zknot(iz)
2925  enddo
2926  stop '** error in dbs3vd ** '
2927  endif
2928  enddo
2929  endif
2930 
2931  call system_clock(t2,count_rate)
2932  if (idebug.ge.2) then
2933  write(*,*) 'time for 2nd check ',real(t2-t1)/real(count_rate)
2934  endif
2935 
2936 
2937  if ((iderx .eq. 0) .and. (idery .eq. 0) .and. (iderz .eq.0)) then
2938 
2939  do ix = 1, nxyz
2940  biatx(ix,1) = one
2941  end do
2942  do ix=1,nxyz
2943  nintx = leftx(ix)
2944 
2945 ! dir$ loop_info min_trips(0) max_trips(8)
2946  do ik=1,kx-1
2947  dr(ix,ik) = xknot(nintx+ik) - xvec(ix)
2948  dl(ix,ik) = xvec(ix) - xknot(nintx+1-ik)
2949  enddo
2950  enddo
2951 
2952 
2953 ! dir$ loop_info min_trips(0) max_trips(8)
2954  do ik = 1, kx-1
2955  do ix = 1, nxyz
2956  save1(ix) = zero
2957  end do
2958 
2959 ! dir$ loop_info min_trips(0) max_trips(8)
2960  do il = 1, ik
2961  do ix = 1, nxyz
2962  term(ix) = biatx(ix,il) / (dr(ix,il) + dl(ix,ik+1-il))
2963  end do
2964  do ix = 1, nxyz
2965  biatx(ix,il) = save1(ix) + dr(ix,il) * term(ix)
2966  end do
2967  do ix = 1, nxyz
2968  save1(ix) = dl(ix,ik+1-il) * term(ix)
2969  end do
2970  end do
2971 
2972  do ix = 1, nxyz
2973  biatx(ix,ik+1) = save1(ix)
2974  end do
2975  end do
2976 
2977  do iy = 1, nxyz
2978  biaty(iy,1) = one
2979  end do
2980 
2981  do iy = 1, nxyz
2982  ninty = lefty(iy)
2983 
2984 ! dir$ loop_info min_trips(0) max_trips(8)
2985  do ik = 1, ky-1
2986  dr(iy,ik) = yknot(ninty+ik) - yvec(iy)
2987  dl(iy,ik) = yvec(iy) - yknot(ninty+1-ik)
2988  enddo
2989  end do
2990 
2991 
2992  do ik = 1, ky-1
2993  do iy = 1, nxyz
2994  save1(iy) = zero
2995  end do
2996 
2997 ! dir$ loop_info min_trips(0) max_trips(8)
2998  do il = 1,ik
2999  do iy = 1,nxyz
3000  term(iy) = biaty(iy,il) / (dr(iy,il) + dl(iy,ik+1-il))
3001  end do
3002  do iy = 1,nxyz
3003  biaty(iy,il) = save1(iy) + dr(iy,il) * term(iy)
3004  end do
3005  do iy = 1,nxyz
3006  save1(iy) = dl(iy,ik+1-il) * term(iy)
3007  end do
3008  end do
3009 
3010  do iy = 1,nxyz
3011  biaty(iy,ik+1) = save1(iy)
3012  end do
3013  end do
3014 
3015  do iz = 1,nxyz
3016  biatz(iz,1) = one
3017  end do
3018  do iz = 1, nxyz
3019  nintz = leftz(iz)
3020 
3021 ! dir$ loop_info min_trips(0) max_trips(8)
3022  do ik = 1, kz-1
3023  dr(iz,ik) = zknot(nintz+ik) - zvec(iz)
3024  dl(iz,ik) = zvec(iz) - zknot(nintz+1-ik)
3025  enddo
3026  enddo
3027 
3028  do ik = 1, kz-1
3029  do iz = 1, nxyz
3030  save1(iz) = zero
3031  end do
3032 
3033 ! dir$ loop_info min_trips(0) max_trips(8)
3034  do il = 1, ik
3035  do iz = 1, nxyz
3036  term(iz) = biatz(iz,il) / (dr(iz,il) + dl(iz,ik+1-il))
3037  end do
3038  do iz = 1, nxyz
3039  biatz(iz,il) = save1(iz) + dr(iz,il) * term(iz)
3040  end do
3041  do iz = 1, nxyz
3042  save1(iz) = dl(iz,ik+1-il) * term(iz)
3043  end do
3044  end do
3045 
3046  do iz = 1, nxyz
3047  biatz(iz,ik+1) = save1(iz)
3048  end do
3049  end do
3050 
3051 
3052  val(1:nxyz) = zero
3053 
3054 !EFD do ikz = 1, kz
3055 !EFD do iky = 1, ky
3056 !EFD do ikx = 1, kx
3057 !EFD do ijk=1,nxyz
3058 !EFD ix = ijk
3059 !EFD iy = ijk
3060 !EFD iz = ijk
3061 
3062 !EFD val(ijk) = val(ijk) &
3063 !EFD & + biatx(ix,ikx) * biaty(iy,iky) &
3064 !EFD & * biatz(iz,ikz) &
3065 !EFD & * bcoef(leftx(ix)-kx+ikx, &
3066 !EFD & lefty(iy)-ky+iky,leftz(iz)-kz+ikz)
3067 !EFD end do
3068 !EFD end do
3069 !EFD end do
3070 !EFD end do
3071 
3072 
3073  call system_clock(t1,count_rate)
3074 
3075  if (use_axyz) then
3076 
3077 
3078 !dir$ vector
3079  do ijk=1,nxyz
3080  ix = ijk
3081  iy = ijk
3082  iz = ijk
3083  nintx = leftx(ix)
3084  ninty = lefty(iy)
3085  nintz = leftz(iz)
3086 
3087 !dir$ unroll
3088  do ikz=1,kz
3089 !dir$ unroll
3090  do iky=1,ky
3091 !dir$ unroll
3092  do ikx=1,kx
3093  axyz(ikx,iky,ikz) = &
3094  & bcoef(nintx-kx+ikx,ninty-ky+iky,nintz-kz+ikz)
3095  enddo
3096  enddo
3097  enddo
3098 
3099 !dir$ unroll
3100  do ikz=1,kz
3101 !dir$ unroll
3102  do iky=1,ky
3103  ayz(iky,ikz) = zero
3104 
3105  enddo
3106  enddo
3107 
3108 
3109 !dir$ unroll
3110  do ikz=1,kz
3111 !dir$ unroll
3112  do iky=1,ky
3113 !dir$ unroll
3114  do ikx=1,kx
3115  ayz(iky,ikz) = ayz(iky,ikz) + &
3116  & axyz(ikx,iky,ikz)*biatx(ix,ikx)
3117  enddo
3118  enddo
3119  enddo
3120 
3121 !dir$ unroll
3122  do ikz=1,kz
3123  az(ikz) = zero
3124  enddo
3125 
3126 !dir$ unroll
3127  do ikz=1,kz
3128 !dir$ unroll
3129  do iky=1,ky
3130  az(ikz) = az(ikz) + ayz(iky,ikz) * biaty(iy,iky)
3131  enddo
3132  enddo
3133 
3134 !dir$ unroll
3135  do ikz=1,kz
3136  val(ijk) = val(ijk) + az(ikz)*biatz(iz,ikz)
3137  enddo
3138 
3139  enddo
3140 
3141  else
3142 
3143 
3144  do ijk=1,nxyz
3145  ix = ijk
3146  iy = ijk
3147  iz = ijk
3148  nintx = leftx(ix)
3149  ninty = lefty(iy)
3150  nintz = leftz(iz)
3151  do ikz = 1, kz
3152  do iky = 1, ky
3153  do ikx = 1, kx
3154 
3155  val(ijk) = val(ijk) + &
3156  & bcoef(nintx-kx+ikx,ninty-ky+iky,nintz-kz+ikz)*biatx(ix,ikx)* &
3157  & biaty(iy,iky)*biatz(iz,ikz)
3158 
3159 
3160  end do
3161  end do
3162  end do
3163  end do
3164 
3165  endif
3166 
3167 
3168  call system_clock(t2,count_rate)
3169  if (idebug.ge.2) then
3170  write(*,*) 'time in val loop ',real(t2-t1)/real(count_rate)
3171  endif
3172 
3173  else
3174 
3175 
3176 !dir$ preferstream
3177  do ijk=1,nxyz
3178  ix = ijk
3179  iy = ijk
3180  iz = ijk
3181 
3182 !dir$ inline
3183  val(ijk) = dbs3dr0(iderx,idery,iderz,xvec(ix), &
3184  & yvec(iy),zvec(iz),kx,ky,kz,xknot,yknot, &
3185  & zknot,nx,ny,nz,bcoef, &
3186  & leftx(ix),lefty(iy),leftz(iz))
3187  enddo
3188 
3189 
3190  endif
3191  return
3192  end subroutine dbs3vd
3193 
3194 
3195 
3196  subroutine vsearch( n, x, m, vxc, vipos )
3197  implicit none
3198  integer, intent(in) :: n
3199  real(rprec), intent(in), dimension(n) :: x
3200  integer, intent(in) :: m
3201  real(rprec), intent(in), dimension(m) :: vxc
3202  integer, intent(inout), dimension(m) :: vipos
3203 
3204 !
3205 ! find ipos such that x(ipos) <= xc <= x(ipos+1)
3206 !
3207  integer :: ipos,i,j, ilo,ihi,imid, nit
3208  integer, dimension(1) :: ipos1
3209  intrinsic :: log
3210  real(rprec) :: xc
3211  integer, parameter :: k64=64*1024
3212  integer, parameter :: k128=128*1024
3213  integer, parameter :: k256=256*1024
3214  integer, parameter :: k512=512*1024
3215  integer, parameter :: m1=1024*1024
3216  integer, parameter :: m2=2*m1
3217  integer, parameter :: m4=4*m1
3218  integer, parameter :: m8=8*m1
3219  integer, parameter :: m16=16*m1
3220  integer, parameter :: m32=32*m1
3221  integer, parameter :: m64=64*m1
3222 
3223  integer itable(25)
3224  save
3225  data itable /2,4,8,16,32, &
3226  & 64,128,256,512,1024, &
3227  & 2048, 4096, 8192,16382, 32768, &
3228  & k64,k128,k512,m1,m2, &
3229  & m4,m8,m16,m32,m64/
3230 
3231  ipos1 = minloc( itable - n, itable .ge. n )
3232  nit = ipos1(1) + 1
3233 
3234 !dir$ preferstream
3235  do j=1,m
3236  xc = vxc(j)
3237  ilo = 1
3238  ihi = n
3239  if ((xc .le. x(1)).or.(xc.ge.x(n))) then
3240  ipos = 0
3241  else
3242 ! bineary search
3243  ihi = n
3244  ilo = 1
3245  ipos = 0
3246  do i=1,nit
3247  imid = (ihi + ilo)/2
3248  if ((x(imid).le.xc).and.(xc.le.x(imid+1))) then
3249  ipos = imid
3250  exit
3251  else if (xc.le.x(imid)) then
3252  ihi = imid
3253  else if (xc.ge.x(imid)) then
3254  ilo = imid
3255  endif
3256  enddo
3257  endif
3258  vipos(j) = ipos
3259  enddo
3260 
3261  return
3262  end subroutine vsearch
3263 
3264 
3265  subroutine vhash(zknot,nz,kz,nxyz,zvec,leftz)
3266  implicit none
3267  integer, intent(in) :: nz,kz,nxyz
3268  real(rprec),dimension(nz+kz),intent(in) :: zknot
3269  real(rprec),dimension(nxyz), intent(in) :: zvec
3270  integer, dimension(nxyz),intent(inout) :: leftz
3271 
3272  integer :: ijk,istart,iend,i,im1,ip1,ileft
3273  real(rprec) :: z,dz
3274 
3275  istart = kz+1
3276  iend = nz
3277  dz = zknot(istart+1)-zknot(istart)
3278 
3279  do ijk=1,nxyz
3280  z = zvec(ijk)
3281 ! -----------------------------------
3282 ! uniform grid in zknot(istart:iend)
3283 !
3284 ! zknot(i) <= z <= zknot(i+1)
3285 ! zknot(istart) + (i-istart)*dz <= z <= zknot(istart) + (i+1-istart)*dz
3286 ! (i-istart) <= (z-zknot(istart))/dz <= i+1-istart
3287 !
3288 ! -----------------------------------
3289  ileft = int((z-zknot(istart))/dz) + istart
3290  leftz(ijk) = max(istart,min(iend-1,ileft) )
3291  enddo
3292  do ijk=1,nxyz
3293  i = leftz(ijk)
3294  z = zvec(ijk)
3295 
3296  if (z.lt.zknot(i)) then
3297  if ((zknot(istart-1).le.z).and.(z.le.zknot(istart))) then
3298  leftz(ijk) = istart-1
3299  else
3300  im1 = max(istart,min(iend-1,i-1))
3301  if ((zknot(im1).le.z).and.(z.le.zknot(im1+1))) then
3302  leftz(ijk) = im1
3303  endif
3304  endif
3305  else if (z.gt.zknot(i+1)) then
3306  if ((zknot(iend).le.z).and.(z.le.zknot(iend+1))) then
3307  leftz(ijk) = iend
3308  else
3309  ip1 = max(istart,min(iend-1,i+1))
3310  if ((zknot(ip1).le.z).and.(z.le.zknot(ip1+1))) then
3311  leftz(ijk) = ip1
3312  endif
3313  endif
3314  endif
3315  enddo
3316  return
3317  end subroutine vhash
3318 
3319 
3320 
3321 
3322 end module bspline