8 #include "sll_assert.h"
9 #include "sll_errors.h"
53 class(sll_c_bsplines),
pointer :: bspl1 => null()
54 class(sll_c_bsplines),
pointer :: bspl2 => null()
60 real(
wp),
allocatable :: ext_gtau(:, :)
63 class(sll_c_bsplines),
allocatable :: ext_bspl1
96 integer,
intent(in) :: degree(2)
97 integer,
intent(in) :: bc_rmax
98 integer,
intent(in) :: nipts(2)
99 integer,
intent(out) :: ncells(2)
113 degree(1), bc_rmax, bc_rmax, 2*nipts(1), ncells(1))
114 ncells(1) = (ncells(1) + 1)/2
118 degree(2), sll_p_periodic, sll_p_periodic, nipts(2), ncells(2))
137 class(sll_c_bsplines),
target,
intent(in) :: bspl1
138 class(sll_c_bsplines),
target,
intent(in) :: bspl2
139 integer,
intent(in) :: bc_rmax
142 sll_assert(bspl1%radial)
143 sll_assert(.not. bspl1%periodic)
146 sll_assert(bspl2%periodic)
147 sll_assert(modulo(bspl2%ncells, 2) == 0)
150 sll_assert(any(bc_rmax == [sll_p_greville, sll_p_hermite]))
160 call self%ext_spline%init(self%ext_bspl1, self%bspl2)
163 call self%ext_interp%init( &
166 bc_xmin=[bc_rmax, sll_p_periodic], &
167 bc_xmax=[bc_rmax, sll_p_periodic])
170 self%nbc_rmax = merge(self%bspl1%degree/2, 0, bc_rmax == sll_p_hermite)
173 associate(n1 => self%ext_bspl1%nbasis, &
174 n2 => self%bspl2%nbasis, &
177 allocate (self%ext_gtau(n1 - 2*a1, n2))
182 self%nipts(1) = (
size(self%ext_gtau, 1) + 1)/2
183 self%nipts(2) =
size(self%ext_gtau, 2)
186 self%i1_start =
size(self%ext_gtau, 1) - self%nipts(1) + 1
189 self%even_deg1 = 1 - modulo(self%bspl1%degree, 2)
202 call self%ext_interp%free()
203 call self%ext_bspl1%free()
206 deallocate (self%ext_gtau)
219 real(wp),
allocatable,
intent(out) :: tau1(:)
220 real(wp),
allocatable,
intent(out) :: tau2(:)
222 real(wp),
allocatable :: ext_tau1(:)
223 real(wp),
allocatable :: ext_tau2(:)
226 call self%ext_interp%get_interp_points(ext_tau1, ext_tau2)
229 associate(n1 => self%nipts(1), &
230 n2 => self%nipts(2), &
231 first => self%i1_start)
233 allocate (tau1(n1), source=ext_tau1(first:))
234 allocate (tau2(n2), source=ext_tau2(:))
252 spline, gtau, derivs_rmax)
255 type(sll_t_spline_2d),
intent(inout) :: spline
256 real(wp),
intent(in) :: gtau(:, :)
257 real(wp),
intent(in),
optional :: derivs_rmax(:, :)
259 character(len=*),
parameter :: &
260 this_sub_name =
"sll_t_polar_spline_interpolator_2d % compute_interpolant"
262 class(sll_t_spline_2d_boundary_data),
allocatable :: boundary_data
263 integer :: i1, i2, j1, j2, k, shift
265 sll_assert(spline%belongs_to_space(self%bspl1, self%bspl2))
266 sll_assert(
size(gtau, 1) == self%nipts(1))
267 sll_assert(
size(gtau, 2) == self%nipts(2))
270 self%ext_gtau(self%i1_start:, :) = gtau(:, :)
272 shift = self%nipts(2)/2
275 do i2 = 1, self%nipts(2)
276 j2 = 1 + modulo(i2 - 1 + shift, self%nipts(2))
277 do j1 = 1, self%i1_start - 1
278 i1 = self%i1_start - j1
279 self%ext_gtau(j1, j2) = gtau(i1, i2)
285 if (
present(derivs_rmax))
then
286 sll_assert(
size(derivs_rmax, 1) == self%nbc_rmax)
287 sll_assert(
size(derivs_rmax, 2) == self%nipts(2))
289 allocate (boundary_data)
290 allocate (boundary_data%derivs_x1_min(self%nbc_rmax, self%nipts(2)))
291 allocate (boundary_data%derivs_x1_max(self%nbc_rmax, self%nipts(2)))
294 boundary_data%derivs_x1_max(:, :) = derivs_rmax(:, :)
297 do i2 = 1, self%nipts(2)
298 j2 = 1 + modulo(i2 - 1 + shift, self%nipts(2))
299 do k = 1, self%nbc_rmax
300 boundary_data%derivs_x1_min(k, j2) = (-1)**(k - self%even_deg1)*derivs_rmax(k, i2)
306 call self%ext_interp%compute_interpolant(self%ext_spline, self%ext_gtau, boundary_data)
309 associate(start => 1 +
size(self%ext_spline%bcoef, 1) -
size(spline%bcoef, 1))
311 spline%bcoef(:, :) = self%ext_spline%bcoef(start:, :)
Describe different boundary conditions.
Access point to B-splines of arbitrary degree providing factory function.
subroutine, public sll_s_bsplines_new_mirror_copy(radial_basis, extended_basis)
Create B-splines by mirroring radial basis onto extended domain [-R,R].
Interpolator for 2D polar splines of arbitrary degree, on uniform and non-uniform grids (directions a...
integer, parameter wp
Working precision.
subroutine s_polar_spline_interpolator_2d__init(self, bspl1, bspl2, bc_rmax)
Initialize a 2D tensor-product spline interpolator object.
subroutine s_polar_spline_interpolator_2d__get_interp_points(self, tau1, tau2)
Get coordinates of interpolation points (2D tensor grid)
subroutine, public sll_s_polar_spline_2d_compute_num_cells(degree, bc_rmax, nipts, ncells)
Calculate number of cells from number of interpolation points.
subroutine s_polar_spline_interpolator_2d__compute_interpolant(self, spline, gtau, derivs_rmax)
Compute interpolating 2D spline.
subroutine s_polar_spline_interpolator_2d__free(self)
Destroy local objects and free allocated memory.
Module for 1D splines, linear combination of B-spline functions.
Module for tensor-product 2D splines.
Interpolator for 1D splines of arbitrary degree, on uniform and non-uniform grids.
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.
Interpolator for 2D tensor-product splines of arbitrary degree, on uniform and non-uniform grids (dir...
subroutine, public sll_s_spline_2d_compute_num_cells(degree, bc_xmin, bc_xmax, nipts, ncells)
Calculate number of cells from number of interpolation points.
Module to select the kind parameter.
integer, parameter, public f64
f64 is the kind type for 64-bit reals (double precision)
2D tensor-product spline interpolator
Container for 2D boundary condition data: . x1-derivatives at x1_min and x1_max, for all values of x2...
2D tensor-product spline interpolator