Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_cubic_spline_interpolator_1d_nonuniform.F90
Go to the documentation of this file.
1 
8 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 #include "sll_assert.h"
10 #include "sll_errors.h"
11 #include "sll_memory.h"
12 #include "sll_working_precision.h"
13 
15  sll_p_periodic
16 
19 
20  use sll_m_cubic_splines, only: &
29 
30  use sll_m_interpolators_1d_base, only: &
32 
33  implicit none
34 
35  public :: &
38 
39  private
40 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
41 
44  sll_real64, dimension(:), pointer :: interpolation_points
45  sll_int32 :: num_points
46  sll_int32 :: bc_type
47  type(sll_t_cubic_spline_1d) :: spline
48  type(sll_t_cubic_nonunif_spline_1d), pointer :: nonunif_spline
49  contains
51  procedure, pass(interpolator) :: init => initialize_cs1d_interpolator2
53  procedure :: compute_interpolants => compute_interpolants_cs1d
55  procedure :: interpolate_from_interpolant_value => interpolate_value_cs1d
57  procedure :: interpolate_from_interpolant_derivative_eta1 => interpolate_deriv1_cs1d
59  procedure :: interpolate_from_interpolant_array => interpolate_values_cs1d
61  !procedure :: interpolate_pointer_values => interpolate_pointer_values_cs1d
63  procedure :: interpolate_from_interpolant_derivatives_eta1 => interpolate_derivatives_cs1d
65  procedure, pass:: interpolate_array => spline_interpolate1d
67  procedure, pass:: interpolate_array_disp => spline_interpolate1d_disp
69  procedure, pass:: interpolate_array_disp_inplace => spline_interpolate1d_disp_inplace
70  !generic :: initialize => initialize_cs1d_interpolator
72  procedure, pass :: set_coefficients => set_coefficients_cs1d
74  procedure, pass :: get_coefficients => get_coefficients_cs1d
76 
78  interface sll_o_delete
79  module procedure delete_cs1d
80  end interface sll_o_delete
81 
82 contains ! ****************************************************************
83 
84  subroutine spline_interpolate1d(this, num_pts, data, coordinates, output_array)
85  class(sll_t_cubic_spline_interpolator_1d_nonuniform), intent(inout) :: this
86  !class(sll_t_cubic_spline_1d), intent(in) :: this
87  sll_int32, intent(in) :: num_pts
88  sll_real64, dimension(num_pts), intent(in) :: coordinates
89  sll_real64, dimension(:), intent(in) :: data
90  sll_real64, dimension(num_pts), intent(out) :: output_array
91  ! compute the interpolating spline coefficients
92  call sll_s_cubic_spline_1d_compute_interpolant(data, this%spline)
93  call sll_s_cubic_spline_1d_eval_array(coordinates, output_array, num_pts, &
94  this%spline)
95  end subroutine spline_interpolate1d
96 
97  subroutine spline_interpolate1d_disp(this, num_pts, data, alpha, output_array)
98  class(sll_t_cubic_spline_interpolator_1d_nonuniform), intent(inout) :: this
99  !class(sll_t_cubic_spline_1d), intent(in) :: this
100  sll_int32, intent(in) :: num_pts
101  sll_real64, intent(in) :: alpha
102  sll_real64, dimension(:), intent(in) :: data
103  sll_real64, dimension(num_pts), intent(out) :: output_array
104 
105  sll_real64, dimension(num_pts) :: coordinates
106  sll_real64 :: length, delta
107  sll_real64 :: xmin, xmax
108  sll_int32 :: i
109  ! compute the interpolating spline coefficients
110  call sll_s_cubic_spline_1d_compute_interpolant(data, this%spline)
111  ! compute array of coordinates where interpolation is performed from displacement
112  length = this%interpolation_points(num_pts) - &
113  this%interpolation_points(1)
114  delta = this%interpolation_points(2) - this%interpolation_points(1)
115  xmin = this%interpolation_points(1)
116  xmax = this%interpolation_points(num_pts)
117  if (this%bc_type == sll_p_periodic) then
118  do i = 1, num_pts
119  coordinates(i) = xmin + modulo(this%interpolation_points(i) - xmin - alpha, length)
120  sll_assert(coordinates(i) >= xmin)
121  sll_assert(coordinates(i) <= xmax)
122  end do
123  else
124  if (alpha < 0) then
125  do i = 1, num_pts
126  coordinates(i) = max(this%interpolation_points(i) + alpha, xmin)
127  sll_assert((xmin <= coordinates(i)) .and. (coordinates(i) <= xmax))
128  end do
129  else
130  do i = 1, num_pts
131  coordinates(i) = min(this%interpolation_points(i) + alpha, xmax)
132  sll_assert((xmin <= coordinates(i)) .and. (coordinates(i) <= xmax))
133  end do
134  end if
135  end if
136  call sll_s_cubic_spline_1d_eval_array(coordinates, output_array, num_pts, &
137  this%spline)
138  end subroutine spline_interpolate1d_disp
139 
140  subroutine spline_interpolate1d_disp_inplace(this, num_pts, data, alpha)
141  class(sll_t_cubic_spline_interpolator_1d_nonuniform), intent(inout) :: this
142  !class(sll_t_cubic_spline_1d), intent(in) :: this
143  sll_int32, intent(in) :: num_pts
144  sll_real64, intent(in) :: alpha
145  sll_real64, dimension(num_pts), intent(inout) :: data
146 
147  sll_real64, dimension(num_pts) :: coordinates
148  sll_real64 :: length, delta
149  sll_real64 :: xmin, xmax
150  sll_int32 :: i
151  ! compute the interpolating spline coefficients
152  call sll_s_cubic_spline_1d_compute_interpolant(data, this%spline)
153  ! compute array of coordinates where interpolation is performed from displacement
154  length = this%interpolation_points(num_pts) - &
155  this%interpolation_points(1)
156  delta = this%interpolation_points(2) - this%interpolation_points(1)
157  xmin = this%interpolation_points(1)
158  xmax = this%interpolation_points(num_pts)
159  if (this%bc_type == sll_p_periodic) then
160  do i = 1, num_pts
161  coordinates(i) = xmin + modulo(this%interpolation_points(i) - xmin - alpha, length)
162  sll_assert(coordinates(i) >= xmin)
163  sll_assert(coordinates(i) <= xmax)
164  end do
165  else
166  if (alpha < 0) then
167  do i = 1, num_pts
168  coordinates(i) = max(this%interpolation_points(i) + alpha, xmin)
169  sll_assert((xmin <= coordinates(i)) .and. (coordinates(i) <= xmax))
170  end do
171  else
172  do i = 1, num_pts
173  coordinates(i) = min(this%interpolation_points(i) + alpha, xmax)
174  sll_assert((xmin <= coordinates(i)) .and. (coordinates(i) <= xmax))
175  end do
176  end if
177  end if
178  call sll_s_cubic_spline_1d_eval_array(coordinates, data, num_pts, &
179  this%spline)
180  end subroutine spline_interpolate1d_disp_inplace
181 
182  ! Both versions F03 and F95 of compute_interpolants_cs1d should have the
183  ! same name. In the F95 we should add a generic interface around this
184  ! subroutine, selecting on the type of interpolator. In the F03 case the
185  ! interface is the compute_interpolants routine which gets assigned to
186  ! the cs1d at initialization time.
187 
188  subroutine compute_interpolants_cs1d(interpolator, data_array, &
189  eta_coords, &
190  size_eta_coords)
191  class(sll_t_cubic_spline_interpolator_1d_nonuniform), intent(inout) :: interpolator
192  sll_real64, dimension(:), intent(in) :: data_array
193  sll_real64, dimension(:), intent(in), optional :: eta_coords
194  sll_int32, intent(in), optional :: size_eta_coords
195 
196  if (present(eta_coords) .or. present(size_eta_coords)) then
197  sll_error('compute_interpolants_cs1d', 'This case is not yet implemented')
198  end if
199 
200  call sll_s_cubic_spline_1d_compute_interpolant(data_array, interpolator%spline)
201 
202  end subroutine
203 
204  ! Alternative implementation for the function meant to interpolate a
205  ! whole array. This implementation fixes some problems in the previous
206  ! function. Furthermore, it separates the operation into the more
207  ! elementary steps: one is supposed to first compute the interpolants,
208  ! then request to interpolate array values.
210  interpolator, &
211  num_pts, &
212  vals_to_interpolate, &
213  output_array)
214  class(sll_t_cubic_spline_interpolator_1d_nonuniform), intent(inout) :: interpolator
215  sll_int32, intent(in) :: num_pts
216  sll_real64, dimension(num_pts), intent(in) :: vals_to_interpolate
217  sll_real64, dimension(num_pts), intent(out) :: output_array
218  call sll_s_cubic_spline_1d_eval_array(vals_to_interpolate, output_array, &
219  num_pts, interpolator%spline)
220  end subroutine interpolate_values_cs1d
221 
223  interpolator, &
224  num_pts, &
225  vals_to_interpolate, &
226  output_array)
227  class(sll_t_cubic_spline_interpolator_1d_nonuniform), intent(inout) :: interpolator
228  sll_int32, intent(in) :: num_pts
229  sll_real64, dimension(:), intent(in) :: vals_to_interpolate
230  sll_real64, dimension(:), intent(out) :: output_array
231  call sll_s_cubic_spline_1d_eval_array_deriv(vals_to_interpolate, output_array, &
232  num_pts, interpolator%spline)
233  end subroutine interpolate_derivatives_cs1d
234 
235  function interpolate_value_cs1d(interpolator, eta1) result(val)
236  class(sll_t_cubic_spline_interpolator_1d_nonuniform), intent(in) :: interpolator
237  sll_real64 :: val
238  sll_real64, intent(in) :: eta1
239  val = sll_f_cubic_spline_1d_eval(eta1, interpolator%spline)
240  end function
241 
242  function interpolate_deriv1_cs1d(interpolator, eta1) result(val)
243  class(sll_t_cubic_spline_interpolator_1d_nonuniform), intent(in) :: interpolator
244  sll_real64 :: val
245  sll_real64, intent(in) :: eta1
246  val = sll_f_cubic_spline_1d_eval_deriv(eta1, interpolator%spline)
247  end function
248 
249 !PN DEFINED BUT NOT USED
250 ! function interpolate_derivative_f95( interpolator, eta1 ) result(val)
251 ! class(sll_t_cubic_spline_interpolator_1d_nonuniform), intent(in) :: interpolator
252 ! sll_real64 :: val
253 ! sll_real64, intent(in) :: eta1
254 ! val = sll_f_cubic_spline_1d_eval_deriv(eta1,interpolator%spline)
255 ! end function
256 
257  ! Why is the name of this function changing depending on the standard?
258  ! only one will be compiled anyway!!
259 
262  interpolator, &
263  num_points, &
264  xmin, &
265  xmax, &
266  bc_type, &
267  slope_left, &
268  slope_right)
269 
270  class(sll_t_cubic_spline_interpolator_1d_nonuniform), intent(inout) :: interpolator
271  sll_int32, intent(in) :: num_points
272  sll_real64, intent(in) :: xmin
273  sll_real64, intent(in) :: xmax
274  sll_int32, intent(in) :: bc_type
275  sll_real64, intent(in), optional :: slope_left
276  sll_real64, intent(in), optional :: slope_right
277  sll_int32 :: ierr
278  sll_int32 :: i
279  sll_real64 :: delta
280 
281  interpolator%num_points = num_points
282  sll_allocate(interpolator%interpolation_points(num_points), ierr)
283  interpolator%interpolation_points(1) = xmin
284  delta = (xmax - xmin)/(num_points - 1)
285  do i = 2, num_points
286  interpolator%interpolation_points(i) = &
287  interpolator%interpolation_points(i - 1) + delta
288  end do
289  interpolator%bc_type = bc_type
290  if (present(slope_left) .and. present(slope_right)) then
292  interpolator%spline, &
293  num_points, &
294  xmin, xmax, &
295  bc_type, &
296  slope_left, &
297  slope_right)
298  else
300  interpolator%spline, &
301  num_points, xmin, xmax, bc_type)
302  end if
303  end subroutine
304 
305  subroutine delete_cs1d(obj)
307  call sll_s_cubic_spline_1d_free(obj%spline)
308  end subroutine delete_cs1d
309 
310  subroutine set_coefficients_cs1d(interpolator, coeffs)
311  class(sll_t_cubic_spline_interpolator_1d_nonuniform), intent(inout) :: interpolator
312  sll_real64, dimension(:), intent(in), optional :: coeffs
313  print *, 'set_coefficients_cs1d(): ERROR: This function has not been ', &
314  'implemented yet.'
315  print *, interpolator%num_points
316  if (present(coeffs)) then
317  print *, 'coeffs are present'
318  end if
319  stop
320  end subroutine set_coefficients_cs1d
321 
322  function get_coefficients_cs1d(interpolator)
323  class(sll_t_cubic_spline_interpolator_1d_nonuniform), intent(in) :: interpolator
324  sll_real64, dimension(:), pointer :: get_coefficients_cs1d
325 
326  print *, 'get_coefficients_cs1d(): ERROR: This function has not been ', &
327  'implemented yet.'
328  print *, interpolator%num_points
329  get_coefficients_cs1d => null()
330  stop
331  end function get_coefficients_cs1d
332 
Provides capabilities for data interpolation with cubic B-splines on non-uniform meshes.
Implements sll_c_interpolator_1d with cubic splines on non uniform mesh.
real(kind=f64) function, dimension(:), pointer get_coefficients_cs1d(interpolator)
subroutine initialize_cs1d_interpolator2(interpolator, num_points, xmin, xmax, bc_type, slope_left, slope_right)
initialize cubic spline interpolator
subroutine compute_interpolants_cs1d(interpolator, data_array, eta_coords, size_eta_coords)
subroutine interpolate_derivatives_cs1d(interpolator, num_pts, vals_to_interpolate, output_array)
subroutine spline_interpolate1d(this, num_pts, data, coordinates, output_array)
subroutine interpolate_values_cs1d(interpolator, num_pts, vals_to_interpolate, output_array)
subroutine spline_interpolate1d_disp(this, num_pts, data, alpha, output_array)
Provides capabilities for data and derivative interpolation with cubic B-splines and different bounda...
real(kind=f64) function, public sll_f_cubic_spline_1d_eval_deriv(x, spline)
returns the value of the derivative at the image of the abscissa 'x', using the spline coefficients s...
subroutine, public sll_s_cubic_spline_1d_compute_interpolant(f, spline)
Computes the cubic spline coefficients corresponding to the 1D data array 'f'.
subroutine, public sll_s_cubic_spline_1d_init(self, num_points, xmin, xmax, bc_type, sl, sr, fast_algorithm)
Returns a pointer to a heap-allocated cubic spline object.
subroutine, public sll_s_cubic_spline_1d_eval_array(a_in, a_out, n, spline)
returns the values of the images of a collection of abscissae, represented by a 1D array in another o...
subroutine, public sll_s_cubic_spline_1d_eval_array_deriv(array_in, array_out, num_pts, spline)
returns the values of the derivatives evaluated at a collection of abscissae stored in the input 1D a...
real(kind=f64) function, public sll_f_cubic_spline_1d_eval(x, spline)
returns the value of the interpolated image of the abscissa x, using the spline coefficients stored i...
subroutine, public sll_s_cubic_spline_1d_free(spline)
deallocate the sll_t_cubic_spline_1d object
Module for 1D interpolation and reconstruction.
basic type for one-dimensional cubic spline data.
Abstract class for 1D interpolation and reconstruction.
    Report Typos and Errors