Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_spline_interpolator_1d.F90
Go to the documentation of this file.
1 
6 
8 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 #include "sll_assert.h"
10 #include "sll_errors.h"
11 
12  use sll_m_working_precision, only: f64
13 
15  sll_p_periodic, &
16  sll_p_hermite, &
17  sll_p_greville
18 
21 
22  use sll_m_spline_matrix, only: &
23  sll_c_spline_matrix, &
25 
26  implicit none
27 
28  public :: &
31 
32  private
33 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
34 
36  integer, parameter :: wp = f64
37 
39  integer, parameter :: &
40  allowed_bcs(1:3) = [sll_p_periodic, sll_p_hermite, sll_p_greville]
41 
42  !-----------------------------------------------------------------------------
44  !-----------------------------------------------------------------------------
46 
47  ! Private attributes
48  class(sll_c_bsplines), pointer, private :: bspl => null()
49  integer, private :: bc_xmin
50  integer, private :: bc_xmax
51  integer, private :: nbc_xmin
52  integer, private :: nbc_xmax
53  integer, private :: odd
54  integer, private :: offset
55  real(wp), private :: dx
56  real(wp), allocatable, private :: tau(:)
57  class(sll_c_spline_matrix), allocatable, private :: matrix
58 
59  contains
60 
61  procedure :: init => s_spline_interpolator_1d__init
62  procedure :: free => s_spline_interpolator_1d__free
63  procedure :: get_interp_points => s_spline_interpolator_1d__get_interp_points
64  procedure :: compute_interpolant => s_spline_interpolator_1d__compute_interpolant
65 
67 
68 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
69 contains
70 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
71 
72  !-----------------------------------------------------------------------------
83  !-----------------------------------------------------------------------------
85  degree, &
86  bc_xmin, &
87  bc_xmax, &
88  nipts, &
89  ncells)
90 
91  integer, intent(in) :: degree
92  integer, intent(in) :: bc_xmin
93  integer, intent(in) :: bc_xmax
94  integer, intent(in) :: nipts
95  integer, intent(out) :: ncells
96 
97  ! Sanity checks
98  sll_assert(degree > 0)
99  sll_assert(any(bc_xmin == allowed_bcs))
100  sll_assert(any(bc_xmax == allowed_bcs))
101 
102  if (any([bc_xmin, bc_xmax] == sll_p_periodic) .and. bc_xmin /= bc_xmax) then
103  sll_error("sll_s_spline_1d_compute_num_cells", "Incompatible BCs")
104  end if
105 
106  if (bc_xmin == sll_p_periodic) then
107  ncells = nipts
108  else
109  associate(nbc_xmin => merge(degree/2, 0, bc_xmin == sll_p_hermite), &
110  nbc_xmax => merge(degree/2, 0, bc_xmax == sll_p_hermite))
111  ncells = nipts + nbc_xmin + nbc_xmax - degree
112  end associate
113  end if
114 
115  end subroutine sll_s_spline_1d_compute_num_cells
116 
117  !-----------------------------------------------------------------------------
123  !-----------------------------------------------------------------------------
124  subroutine s_spline_interpolator_1d__init(self, bspl, bc_xmin, bc_xmax)
125 
126  class(sll_t_spline_interpolator_1d), intent(out) :: self
127  class(sll_c_bsplines), target, intent(in) :: bspl
128  integer, intent(in) :: bc_xmin
129  integer, intent(in) :: bc_xmax
130 
131  integer :: kl, ku
132  character(len=32) :: matrix_type
133 
134  ! Sanity checks
135  sll_assert(any(bc_xmin == allowed_bcs))
136  sll_assert(any(bc_xmax == allowed_bcs))
137  if (bspl%periodic) then
138  sll_assert(bc_xmin == sll_p_periodic)
139  sll_assert(bc_xmax == sll_p_periodic)
140  end if
141 
142  ! Check that these are not radial B-splines on polar grid
143  sll_assert(.not. bspl%radial)
144 
145  ! Save pointer to B-splines
146  ! (later needed to verify 1D spline input to 'compute_interpolant')
147  self%bspl => bspl
148 
149  ! Save other data
150  self%bc_xmin = bc_xmin
151  self%bc_xmax = bc_xmax
152  self%nbc_xmin = merge(bspl%degree/2, 0, bc_xmin == sll_p_hermite)
153  self%nbc_xmax = merge(bspl%degree/2, 0, bc_xmax == sll_p_hermite)
154  self%odd = modulo(bspl%degree, 2)
155  self%offset = merge(bspl%degree/2, 0, bspl%periodic)
156 
157  ! Save average cell size for normalization of derivatives
158  self%dx = (bspl%xmax - bspl%xmin)/real(bspl%ncells, f64)
159 
160  ! Compute interpolation points and number of diagonals in linear system
161  if (bspl%uniform) then
162  call s_compute_interpolation_points_uniform(self, self%tau)
163  call s_compute_num_diags_uniform(self, kl, ku)
164  else
165  call s_compute_interpolation_points_non_uniform(self, self%tau)
166  call s_compute_num_diags_non_uniform(self, kl, ku)
167  end if
168 
169  ! Special case: linear spline
170  ! No need for matrix assembly
171  if (self%bspl%degree == 1) return
172 
173  ! Determine matrix storage type and allocate matrix
174  associate(nbasis => self%bspl%nbasis)
175 
176  if (bc_xmin == sll_p_periodic) then
177  if (kl + 1 + ku >= nbasis) then
178  matrix_type = "dense"
179  else
180  matrix_type = "periodic_banded"
181  end if
182  else
183  matrix_type = "banded"
184  end if
185 
186  call sll_s_spline_matrix_new(self%matrix, matrix_type, nbasis, kl, ku)
187 
188  end associate ! nbasis
189 
190  ! Fill in entries A_ij of linear system A*x = b for interpolation
191  call s_build_system(self, self%matrix)
192 
193  ! Factorize matrix A to speed-up solution for any given b
194  call self%matrix%factorize()
195 
196  end subroutine s_spline_interpolator_1d__init
197 
198  !-----------------------------------------------------------------------------
201  !-----------------------------------------------------------------------------
203 
204  class(sll_t_spline_interpolator_1d), intent(inout) :: self
205 
206  nullify (self%bspl)
207  deallocate (self%tau)
208 
209  if (allocated(self%matrix)) then
210  call self%matrix%free()
211  deallocate (self%matrix)
212  end if
213 
214  end subroutine s_spline_interpolator_1d__free
215 
216  !-----------------------------------------------------------------------------
220  !-----------------------------------------------------------------------------
222 
223  class(sll_t_spline_interpolator_1d), intent(in) :: self
224  real(wp), allocatable, intent(out) :: tau(:)
225 
226  sll_assert(allocated(self%tau))
227  allocate (tau(size(self%tau)), source=self%tau)
228 
230 
231  !-----------------------------------------------------------------------------
242  !-----------------------------------------------------------------------------
244  spline, gtau, derivs_xmin, derivs_xmax)
245 
246  class(sll_t_spline_interpolator_1d), intent(in) :: self
247  type(sll_t_spline_1d), intent(inout) :: spline
248  real(wp), intent(in) :: gtau(:)
249  real(wp), optional, intent(in) :: derivs_xmin(:)
250  real(wp), optional, intent(in) :: derivs_xmax(:)
251 
252  character(len=*), parameter :: &
253  this_sub_name = "sll_t_spline_interpolator_1d % compute_interpolant"
254 
255  integer :: i
256 
257  sll_assert(size(gtau) == self%bspl%nbasis - self%nbc_xmin - self%nbc_xmax)
258  sll_assert(spline%belongs_to_space(self%bspl))
259 
260  associate(nbasis => self%bspl%nbasis, &
261  degree => self%bspl%degree, &
262  nbc_xmin => self%nbc_xmin, &
263  nbc_xmax => self%nbc_xmax, &
264  g => self%offset, &
265  bcoef => spline%bcoef)
266 
267  ! Special case: linear spline
268  if (degree == 1) then
269  bcoef(1:nbasis) = gtau(1:nbasis)
270  ! Periodic only: "wrap around" coefficients onto extended array
271  if (self%bspl%periodic) then
272  bcoef(nbasis + 1) = bcoef(1)
273  end if
274  return
275  end if
276 
277  ! Hermite boundary conditions at xmin, if any
278  ! NOTE: For consistency with the linear system, the i-th derivative
279  ! provided by the user must be multiplied by dx^i
280  if (self%bc_xmin == sll_p_hermite) then
281  if (present(derivs_xmin)) then
282  bcoef(1:nbc_xmin) = &
283  [(derivs_xmin(i)*self%dx**(i + self%odd - 1), i=nbc_xmin, 1, -1)]
284  else
285  sll_error(this_sub_name, "Hermite BC at xmin requires derivatives")
286  end if
287  end if
288 
289  ! Interpolation points
290  bcoef(nbc_xmin + 1 + g:nbasis - nbc_xmax + g) = gtau(:)
291 
292  ! Hermite boundary conditions at xmax, if any
293  ! NOTE: For consistency with the linear system, the i-th derivative
294  ! provided by the user must be multiplied by dx^i
295  if (self%bc_xmax == sll_p_hermite) then
296  if (present(derivs_xmax)) then
297  bcoef(nbasis - nbc_xmax + 1:nbasis) = &
298  [(derivs_xmax(i)*self%dx**(i + self%odd - 1), i=1, nbc_xmax)]
299  else
300  sll_error(this_sub_name, "Hermite BC at xmax requires derivatives")
301  end if
302  end if
303 
304  ! Solve linear system and compute coefficients
305  call self%matrix%solve_inplace(bcoef(1 + g:nbasis + g))
306 
307  ! Periodic only: "wrap around" coefficients onto extended array
308  if (self%bc_xmin == sll_p_periodic) then
309  bcoef(1:g) = bcoef(nbasis + 1:nbasis + g)
310  bcoef(nbasis + 1 + g:nbasis + degree) = bcoef(1 + g:degree)
311  end if
312 
313  end associate
314 
316 
317  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
318  !!
319  !! PRIVATE SUBROUTINES
320  !!
321  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
322 
323  ! TODO: move subroutine to init()
324  !-----------------------------------------------------------------------------
329  !-----------------------------------------------------------------------------
330  subroutine s_build_system(self, matrix)
331 
332  class(sll_t_spline_interpolator_1d), intent(in) :: self
333  class(sll_c_spline_matrix), intent(inout) :: matrix
334 
335  integer :: i, j, d, s
336  integer :: j0, d0
337  integer :: order
338  real(wp) :: x
339  real(wp) :: values(self%bspl%degree + 1)
340  real(wp), allocatable :: derivs(:, :)
341 
342  ! NEW
343  integer :: jmin
344 
345  associate(nbasis => self%bspl%nbasis, &
346  degree => self%bspl%degree, &
347  nbc_xmin => self%nbc_xmin, &
348  nbc_xmax => self%nbc_xmax)
349 
350  if (any([self%bc_xmin, self%bc_xmax] == sll_p_hermite)) then
351  allocate (derivs(0:degree/2, 1:degree + 1))
352  end if
353 
354  ! Hermite boundary conditions at xmin, if any
355  if (self%bc_xmin == sll_p_hermite) then
356  x = self%bspl%xmin
357  call self%bspl%eval_basis_and_n_derivs(x, nbc_xmin, derivs, jmin)
358 
359  ! In order to improve the condition number of the matrix, we normalize all
360  ! derivatives by multiplying the i-th derivative by dx^i
361 
362  associate(h => [(self%dx**i, i=1, ubound(derivs, 1))])
363  do j = lbound(derivs, 2), ubound(derivs, 2)
364  derivs(1:, j) = derivs(1:, j)*h(1:)
365  end do
366  end associate
367 
368  do i = 1, nbc_xmin
369  ! iterate only to deg as last bspline is 0
370  order = nbc_xmin - i + self%odd
371  do j = 1, degree
372  call matrix%set_element(i, j, derivs(order, j))
373  end do
374  end do
375 
376  end if
377 
378  ! Interpolation points
379  do i = nbc_xmin + 1, nbasis - nbc_xmax
380  x = self%tau(i - nbc_xmin)
381  call self%bspl%eval_basis(x, values, jmin)
382  do s = 1, degree + 1
383  j = modulo(jmin - self%offset + s - 2, nbasis) + 1
384  call matrix%set_element(i, j, values(s))
385  end do
386  end do
387 
388  ! Hermite boundary conditions at xmax, if any
389  if (self%bc_xmax == sll_p_hermite) then
390  x = self%bspl%xmax
391  call self%bspl%eval_basis_and_n_derivs(x, nbc_xmax, derivs, jmin)
392 
393  ! In order to improve the condition number of the matrix, we normalize all
394  ! derivatives by multiplying the i-th derivative by dx^i
395  associate(h => [(self%dx**i, i=1, ubound(derivs, 1))])
396  do j = lbound(derivs, 2), ubound(derivs, 2)
397  derivs(1:, j) = derivs(1:, j)*h(1:)
398  end do
399  end associate
400 
401  do i = nbasis - nbc_xmax + 1, nbasis
402  order = i - (nbasis - nbc_xmax + 1) + self%odd
403  j0 = nbasis - degree
404  d0 = 1
405  do s = 1, degree
406  j = j0 + s
407  d = d0 + s
408  call matrix%set_element(i, j, derivs(order, d))
409  end do
410  end do
411 
412  end if
413 
414  if (allocated(derivs)) deallocate (derivs)
415 
416  end associate ! nbasis, degree
417 
418  end subroutine s_build_system
419 
420  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
421  !!
422  !! PRIVATE SUBROUTINES, UNIFORM
423  !!
424  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
425 
426  !-----------------------------------------------------------------------------
428  class(sll_t_spline_interpolator_1d), intent(in) :: self
429  real(wp), allocatable, intent(out) :: tau(:)
430 
431  integer :: i, ntau, isum
432  integer, allocatable :: iknots(:)
433 
434  associate(nbasis => self%bspl%nbasis, &
435  ncells => self%bspl%ncells, &
436  degree => self%bspl%degree, &
437  xmin => self%bspl%xmin, &
438  xmax => self%bspl%xmax, &
439  dx => self%dx, &
440  bc_xmin => self%bc_xmin, &
441  bc_xmax => self%bc_xmax, &
442  nbc_xmin => self%nbc_xmin, &
443  nbc_xmax => self%nbc_xmax)
444 
445  ! Determine size of tau and allocate tau
446  ntau = nbasis - nbc_xmin - nbc_xmax
447  allocate (tau(1:ntau))
448 
449  if (bc_xmin == sll_p_periodic) then
450 
451  ! Periodic case:
452  ! . for odd degree, interpolation points are breakpoints (last excluded)
453  ! . for even degree, interpolation points are cell centers
454  associate(shift => merge(0.5_wp, 0.0_wp, self%odd == 0))
455  tau = [(xmin + (real(i - 1, wp) + shift)*dx, i=1, ntau)]
456  end associate
457 
458  else
459 
460  ! Non-periodic case: create array of temporary knots (integer shifts only)
461  ! in order to compute interpolation points using Greville-style averaging:
462  ! tau(i) = xmin + average(knots(i+1-degree:i)) * dx
463  allocate (iknots(2 - degree:ntau))
464 
465  ! Additional knots near x=xmin
466  associate(r => 2 - degree, s => -nbc_xmin)
467  select case (bc_xmin)
468  case (sll_p_greville); iknots(r:s) = 0
469  case (sll_p_hermite); iknots(r:s) = [(i, i=r - s - 1, -1)]
470  end select
471  end associate
472 
473  ! Knots inside the domain
474  associate(r => -nbc_xmin + 1, s => -nbc_xmin + 1 + ncells)
475  iknots(r:s) = [(i, i=0, ncells)]
476  end associate
477 
478  ! Additional knots near x=xmax
479  associate(r => -nbc_xmin + 1 + ncells + 1, s => ntau)
480  select case (bc_xmax)
481  case (sll_p_greville); iknots(r:s) = ncells
482  case (sll_p_hermite); iknots(r:s) = [(i, i=ncells + 1, ncells + 1 + s - r)]
483  end select
484  end associate
485 
486  ! Compute interpolation points using Greville-style averaging
487  associate(inv_deg => 1.0_wp/real(degree, wp))
488  do i = 1, ntau
489  isum = sum(iknots(i + 1 - degree:i))
490  if (modulo(isum, degree) == 0) then
491  tau(i) = xmin + real(isum/degree, wp)*dx
492  else
493  tau(i) = xmin + real(isum, wp)*inv_deg*dx
494  end if
495  end do
496  end associate
497 
498  ! Non-periodic case, odd degree: fix round-off issues
499  if (self%odd == 1) then
500  tau(1) = xmin
501  tau(ntau) = xmax
502  end if
503 
504  deallocate (iknots)
505 
506  end if ! (bc_xmin == sll_p_periodic)
507 
508  end associate
509 
511 
512  !-----------------------------------------------------------------------------
513  subroutine s_compute_num_diags_uniform(self, kl, ku)
514  class(sll_t_spline_interpolator_1d), intent(in) :: self
515  integer, intent(out) :: kl
516  integer, intent(out) :: ku
517 
518  associate(degree => self%bspl%degree)
519 
520  ! FIXME: In Hermite case ku and kl computed in general case when derivatives
521  ! of B-splines do not vanish at boundary
522  ! TODO: reduce kl and ku to take advantage of uniform grid
523  select case (self%bc_xmin)
524  case (sll_p_periodic); ku = (degree + 1)/2
525  case (sll_p_hermite); ku = max((degree + 1)/2, degree - 1)
526  case (sll_p_greville); ku = degree
527  end select
528 
529  select case (self%bc_xmax)
530  case (sll_p_periodic); kl = (degree + 1)/2
531  case (sll_p_hermite); kl = max((degree + 1)/2, degree - 1)
532  case (sll_p_greville); kl = degree
533  end select
534 
535  end associate
536 
537  end subroutine s_compute_num_diags_uniform
538 
539  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
540  !!
541  !! PRIVATE SUBROUTINES, NON-UNIFORM
542  !!
543  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
544 
545  !-----------------------------------------------------------------------------
547  class(sll_t_spline_interpolator_1d), intent(in) :: self
548  real(wp), allocatable, intent(out) :: tau(:)
549 
550  integer :: i, ntau
551  real(wp), allocatable :: temp_knots(:)
552 
553  associate(nbasis => self%bspl%nbasis, &
554  ncells => self%bspl%ncells, &
555  degree => self%bspl%degree, &
556  xmin => self%bspl%xmin, &
557  xmax => self%bspl%xmax, &
558  dx => self%dx, &
559  bc_xmin => self%bc_xmin, &
560  bc_xmax => self%bc_xmax, &
561  nbc_xmin => self%nbc_xmin, &
562  nbc_xmax => self%nbc_xmax)
563 
564  associate(breaks => self%bspl%knots(1:ncells + 1))
565 
566  ! Determine size of tau and allocate tau
567  ntau = nbasis - nbc_xmin - nbc_xmax
568  allocate (tau(1:ntau))
569 
570  ! Array of temporary knots needed to compute interpolation points
571  ! using Greville-style averaging: tau(i) = average(temp_knots(i+1-degree:i))
572  allocate (temp_knots(2 - degree:ntau))
573 
574  if (bc_xmin == sll_p_periodic) then
575 
576  associate(k => degree/2)
577  temp_knots(:) = self%bspl%knots(2 - degree + k:ntau + k)
578  end associate
579 
580  else
581 
582  associate(r => 2 - degree, s => -nbc_xmin)
583  select case (bc_xmin)
584  case (sll_p_greville); temp_knots(r:s) = breaks(1)
585  case (sll_p_hermite); temp_knots(r:s) = 2.0_wp*breaks(1) - breaks(2 + s - r:2:-1)
586  end select
587  end associate
588 
589  associate(r => -nbc_xmin + 1, s => -nbc_xmin + 1 + ncells)
590  temp_knots(r:s) = breaks(:)
591  end associate
592 
593  associate(r => -nbc_xmin + 1 + ncells + 1, s => ntau)
594  select case (bc_xmax)
595  case (sll_p_greville)
596  temp_knots(r:s) = breaks(ncells + 1)
597  case (sll_p_hermite)
598  temp_knots(r:s) = 2.0_wp*breaks(ncells + 1) - breaks(ncells:ncells + r - s:-1)
599  end select
600  end associate
601 
602  end if
603 
604  ! Compute interpolation points using Greville-style averaging
605  associate(inv_deg => 1.0_wp/real(degree, wp))
606  do i = 1, ntau
607  tau(i) = sum(temp_knots(i + 1 - degree:i))*inv_deg
608  end do
609  end associate
610 
611  ! Periodic case: apply periodic BCs to interpolation points
612  if (bc_xmin == sll_p_periodic) then
613  tau(:) = modulo(tau(:) - xmin, xmax - xmin) + xmin
614 
615  ! Non-periodic case, odd degree: fix round-off issues
616  else if (self%odd == 1) then
617  tau(1) = xmin
618  tau(ntau) = xmax
619  end if
620 
621  end associate ! breaks
622  end associate ! all other variables
623 
625 
626  !-----------------------------------------------------------------------------
627  subroutine s_compute_num_diags_non_uniform(self, kl, ku)
628  class(sll_t_spline_interpolator_1d), intent(in) :: self
629  integer, intent(out) :: kl
630  integer, intent(out) :: ku
631 
632  integer :: i, j, s, d, icell
633  real(wp) :: x
634 
635  ku = 0
636  kl = 0
637 
638  associate(nbasis => self%bspl%nbasis, &
639  degree => self%bspl%degree, &
640  offset => self%offset, &
641  nbc_xmin => self%nbc_xmin, &
642  nbc_xmax => self%nbc_xmax)
643 
644  if (self%bc_xmin == sll_p_periodic) then
645 
646  do i = 1, nbasis
647  x = self%tau(i)
648  icell = self%bspl%find_cell(x)
649  do s = 1, degree + 1
650  j = modulo(icell - offset - 2 + s, nbasis) + 1
651  d = j - i
652  if (d > nbasis/2) then; d = d - nbasis; else &
653  if (d < -nbasis/2) then; d = d + nbasis; end if
654  ku = max(ku, d)
655  kl = max(kl, -d)
656  end do
657  end do
658 
659  else
660 
661  do i = nbc_xmin + 1, nbasis - nbc_xmax
662  x = self%tau(i - nbc_xmin)
663  icell = self%bspl%find_cell(x)
664  do s = 1, degree + 1
665  j = icell - 1 + s
666  d = j - i
667  ku = max(ku, d)
668  kl = max(kl, -d)
669  end do
670  end do
671  ! FIXME: In Hermite case ku and kl computed in general case where
672  ! derivatives of B-splines do not vanish at boundary
673  ku = ku + nbc_xmin
674  kl = kl + nbc_xmax
675 
676  end if
677 
678  end associate
679 
680  end subroutine s_compute_num_diags_non_uniform
681 
Abstract class for B-splines of arbitrary degree.
Module for 1D splines, linear combination of B-spline functions.
Interpolator for 1D splines of arbitrary degree, on uniform and non-uniform grids.
subroutine s_build_system(self, matrix)
Private subroutine for assembling and factorizing linear system for any kind of boundary conditions a...
subroutine, public sll_s_spline_1d_compute_num_cells(degree, bc_xmin, bc_xmax, nipts, ncells)
Calculate number of cells from number of interpolation points.
integer, dimension(1:3), parameter allowed_bcs
Allowed boundary conditions.
subroutine s_spline_interpolator_1d__free(self)
Destroy local objects and free allocated memory.
integer, parameter wp
Working precision.
subroutine s_compute_num_diags_uniform(self, kl, ku)
subroutine s_spline_interpolator_1d__compute_interpolant(self, spline, gtau, derivs_xmin, derivs_xmax)
Compute interpolating 1D spline.
subroutine s_spline_interpolator_1d__get_interp_points(self, tau)
Get coordinates of interpolation points (1D grid)
subroutine s_compute_interpolation_points_non_uniform(self, tau)
subroutine s_spline_interpolator_1d__init(self, bspl, bc_xmin, bc_xmax)
Initialize a 1D spline interpolator object.
subroutine s_compute_num_diags_non_uniform(self, kl, ku)
subroutine s_compute_interpolation_points_uniform(self, tau)
Access point to matrix class providing factory function.
subroutine, public sll_s_spline_matrix_new(matrix, matrix_type, n, kl, ku)
Module to select the kind parameter.
integer, parameter, public f64
f64 is the kind type for 64-bit reals (double precision)
    Report Typos and Errors