Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_periodic_interpolator_1d.F90
Go to the documentation of this file.
1 
10 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
11 #include "sll_memory.h"
12 #include "sll_errors.h"
13 #include "sll_working_precision.h"
14 
15  use sll_m_interpolators_1d_base, only: &
17 
18  use sll_m_periodic_interp, only: &
23 
24  implicit none
25 
26  public :: &
27  sll_o_delete, &
29 
30  private
31 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
32 
35  ! Be careful here. For consistency with the other interpolators
36  ! num_points is the number of nodes (including both boundaries)
37  ! and not the number of cells as used in the periodic interpolator module.
38  sll_int32 :: num_points
39  sll_real64 :: cell_size
40  sll_real64 :: domain_size
41  type(sll_t_periodic_interp_work) :: per_interp
42  contains
44  procedure, pass(interpolator) :: init => initialize_per1d_interpolator
46  procedure :: compute_interpolants => compute_interpolants_per1d
48  procedure :: interpolate_from_interpolant_value => interpolate_value_per1d
50  procedure :: interpolate_from_interpolant_derivative_eta1 => interpolate_deriv1_per1d
52  procedure :: interpolate_from_interpolant_array => interpolate_values_per1d
54  procedure, pass:: interpolate_array => per_interpolate1d
56  procedure, pass:: interpolate_array_disp => per_interpolate1d_disp
58  procedure, pass:: interpolate_array_disp_inplace => per_interpolate1d_disp_inplace
60  procedure, pass :: set_coefficients => set_coefficients_per1d
62  procedure, pass :: get_coefficients => get_coefficients_per1d
63 
65 
67  interface sll_o_delete
68  module procedure delete_per1d
69  end interface sll_o_delete
70 
71 contains ! ****************************************************************
72 
75  num_points, &
76  xmin, &
77  xmax, &
78  type, &
79  order) result(res)
80 
81  type(sll_t_periodic_interpolator_1d), pointer :: res
82  sll_int32, intent(in) :: num_points
83  sll_real64, intent(in) :: xmin
84  sll_real64, intent(in) :: xmax
85  sll_int32, intent(in) :: type
86  sll_int32, intent(in) :: order
87  sll_int32 :: ierr
88  sll_allocate(res, ierr)
90  res, &
91  num_points, &
92  xmin, &
93  xmax, &
94  type, &
95  order)
96  end function new_periodic_1d_interpolator
97 
98  subroutine per_interpolate1d(this, num_pts, data, coordinates, output_array)
99  class(sll_t_periodic_interpolator_1d), intent(inout) :: this
100  !class(sll_spline_1D), intent(in) :: this
101  sll_int32, intent(in) :: num_pts
102  sll_real64, dimension(num_pts), intent(in) :: coordinates
103  sll_real64, dimension(:), intent(in) :: data
104  sll_real64, dimension(num_pts), intent(out) :: output_array
105  ! local variables
106  !sll_int32 :: ierr
107  ! periodic interpolation only implemented for constant displacement
108  print *, 'periodic_interpolate1d: periodic interpolation not implemented', &
109  ' for array of displacements'
110  output_array = -1000000._f64
111  print *, num_pts
112  print *, maxval(coordinates)
113  print *, maxval(data)
114  print *, maxval(output_array)
115  print *, this%num_points
116  stop
117  end subroutine per_interpolate1d
118 
119  subroutine per_interpolate1d_disp(this, num_pts, data, alpha, output_array)
120  class(sll_t_periodic_interpolator_1d), intent(inout) :: this
121  sll_int32, intent(in) :: num_pts
122  sll_real64, intent(in) :: alpha
123  sll_real64, dimension(:), intent(in) :: data
124  sll_real64, dimension(num_pts), intent(out) :: output_array
125  ! Be careful here. For consistency with the other interpolators
126  ! num_points is the number of nodes (including both boundaries)
127  ! and not the number of cells as used in the periodic interpolator module.
128  call sll_s_periodic_interp(this%per_interp, output_array, data, &
129  -alpha/this%cell_size)
130  ! complete by periodicity
131  output_array(num_pts) = output_array(1)
132  end subroutine per_interpolate1d_disp
133 
134  subroutine per_interpolate1d_disp_inplace(this, num_pts, data, alpha)
135  class(sll_t_periodic_interpolator_1d), intent(inout) :: this
136  sll_int32, intent(in) :: num_pts
137  sll_real64, intent(in) :: alpha
138  sll_real64, dimension(num_pts), intent(inout) :: data
139 
140  ! local variable
141  sll_real64 :: tmp(num_pts)
142  ! Be careful here. For consistency with the other interpolators
143  ! num_points is the number of nodes (including both boundaries)
144  ! and not the number of cells as used in the periodic interpolator module.
145  call sll_s_periodic_interp(this%per_interp, tmp, data, &
146  -alpha/this%cell_size)
147  ! complete by periodicity
148  data = tmp
149  data(num_pts) = tmp(1)
150  end subroutine per_interpolate1d_disp_inplace
151 
152  ! Both versions F03 and F95 of compute_interpolants_per1d should have the
153  ! same name. In the F95 we should add a generic interface around this
154  ! subroutine, selecting on the type of interpolator. In the F03 case the
155  ! interface is the compute_interpolants routine which gets assigned to
156  ! the per1d at initialization time.
157  subroutine compute_interpolants_per1d(interpolator, data_array, &
158  eta_coords, &
159  size_eta_coords)
160  class(sll_t_periodic_interpolator_1d), intent(inout) :: interpolator
161  sll_real64, dimension(:), intent(in) :: data_array
162  sll_real64, dimension(:), intent(in), optional :: eta_coords
163  sll_int32, intent(in), optional :: size_eta_coords
164 
165  print *, 'compute_interpolants_per1d:', &
166  ' not implemented for periodic interpolation'
167 
168  if (present(eta_coords) .or. present(size_eta_coords)) then
169  sll_error('compute_interpolants_per1d', 'This case is not yet implemented')
170  end if
171 
172  print *, maxval(data_array)
173  print *, interpolator%num_points
174  stop
175  end subroutine compute_interpolants_per1d
176 
177  ! Alternative implementation for the function meant to interpolate a
178  ! whole array. This implementation fixes some problems in the previous
179  ! function. Furthermore, it separates the operation into the more
180  ! elementary steps: one is supposed to first compute the interpolants,
181  ! then request to interpolate array values.
183  interpolator, &
184  num_pts, &
185  vals_to_interpolate, &
186  output_array)
187  class(sll_t_periodic_interpolator_1d), intent(inout) :: interpolator
188  sll_int32, intent(in) :: num_pts
189  sll_real64, dimension(num_pts), intent(in) :: vals_to_interpolate
190  sll_real64, dimension(num_pts), intent(out) :: output_array
191  !sll_int32 :: ierr
192  output_array = -1000000._f64
193  print *, 'interpolate_values_per1d:', &
194  ' not implemented for periodic interpolation'
195  print *, interpolator%num_points
196  print *, num_pts
197  print *, maxval(vals_to_interpolate)
198  stop
199  end subroutine interpolate_values_per1d
200 
201 !PN DEFINED BUT NOT USED
202 ! subroutine interpolate_derivatives_per1d( &
203 ! interpolator, &
204 ! num_pts, &
205 ! vals_to_interpolate, &
206 ! output_array )
207 
208 ! class(sll_t_periodic_interpolator_1d), intent(in) :: interpolator
209 ! sll_int32, intent(in) :: num_pts
210 ! sll_real64, dimension(:), intent(in) :: vals_to_interpolate
211 ! sll_real64, dimension(:), intent(out) :: output_array
212 ! !sll_int32 :: ierr
213 
214 ! print*, 'interpolate_from_interpolant_derivatives_eta1: ', &
215 ! 'not implemented for periodic interpolation'
216 ! output_array = -1000000._f64
217 ! print *,interpolator%num_points
218 ! print *,num_pts
219 ! print *,maxval(vals_to_interpolate)
220 ! stop
221 ! end subroutine interpolate_derivatives_per1d
222 
223  function interpolate_value_per1d(interpolator, eta1) result(val)
224  class(sll_t_periodic_interpolator_1d), intent(in) :: interpolator
225  sll_real64 :: val
226  sll_real64, intent(in) :: eta1
227  print *, 'interpolate_value_per1d: ', &
228  'not implemented for periodic interpolation'
229  val = -1000000._f64
230  print *, eta1
231  print *, interpolator%num_points
232  stop
233  end function
234 
235  function interpolate_deriv1_per1d(interpolator, eta1) result(val)
236  class(sll_t_periodic_interpolator_1d), intent(in) :: interpolator
237  sll_real64 :: val
238  sll_real64, intent(in) :: eta1
239  print *, 'interpolate_deriv1_per1d: ', &
240  'not implemented for periodic interpolation'
241  val = -1000000._f64
242  print *, eta1
243  print *, interpolator%num_points
244  stop
245  end function interpolate_deriv1_per1d
246 
247 !PN DEFINED BUT NOT USED
248 ! function interpolate_derivative_f95( interpolator, eta1 ) result(val)
249 ! class(sll_t_periodic_interpolator_1d), intent(in) :: interpolator
250 ! sll_real64 :: val
251 ! sll_real64, intent(in) :: eta1
252 ! print*, 'interpolate_derivative_f95: ', &
253 ! 'not implemented for periodic interpolation'
254 ! val = -1000000._f64
255 ! print *,eta1
256 ! print *,interpolator%num_points
257 ! stop
258 ! end function interpolate_derivative_f95
259 
260  ! Why is the name of this function changing depending on the standard?
261  ! only one will be compiled anyway!!
262 
265  interpolator, &
266  num_points, &
267  xmin, &
268  xmax, &
269  type, &
270  order)
271 
272  class(sll_t_periodic_interpolator_1d), intent(inout) :: interpolator
273  sll_int32, intent(in) :: num_points
274  sll_real64, intent(in) :: xmin
275  sll_real64, intent(in) :: xmax
276  sll_int32, intent(in) :: type
277  sll_int32, intent(in) :: order
278  !sll_int32 :: ierr
279  !sll_int32 :: i
280  !sll_real64 :: delta
281 
282  ! Be careful here. For consistency with the other interpolators
283  ! num_points is the number of nodes (including both boundaries)
284  ! and not the number of cells as used in the periodic interpolator module.
285  interpolator%num_points = num_points - 1
286  interpolator%cell_size = (xmax - xmin)/real(num_points - 1, f64)
287  interpolator%domain_size = xmax - xmin
288 
289  call sll_s_periodic_interp_init(interpolator%per_interp, num_points - 1, &
290  type, order)
291  end subroutine
292 
293  subroutine delete_per1d(obj)
294  class(sll_t_periodic_interpolator_1d) :: obj
295  call sll_s_periodic_interp_free(obj%per_interp)
296  end subroutine delete_per1d
297 
298  subroutine set_coefficients_per1d(interpolator, coeffs)
299  class(sll_t_periodic_interpolator_1d), intent(inout) :: interpolator
300  sll_real64, dimension(:), intent(in), optional :: coeffs
301  print *, 'set_coefficients_per1d(): ERROR: This function has not been ', &
302  'implemented yet.'
303  if (present(coeffs)) then
304  print *, '#coeffs present but not used'
305  end if
306  print *, interpolator%num_points
307  stop
308  end subroutine set_coefficients_per1d
309 
310  function get_coefficients_per1d(interpolator)
311  class(sll_t_periodic_interpolator_1d), intent(in) :: interpolator
312  sll_real64, dimension(:), pointer :: get_coefficients_per1d
313 
314  print *, 'get_coefficients_per1d(): ERROR: This function has not been ', &
315  'implemented yet.'
316  print *, interpolator%num_points
317  get_coefficients_per1d => null()
318  stop
319  end function get_coefficients_per1d
320 
Module for 1D interpolation and reconstruction.
subroutine, public sll_s_periodic_interp_free(this)
subroutine, public sll_s_periodic_interp_init(this, N, interpolator, order)
subroutine, public sll_s_periodic_interp(this, u_out, u, alpha)
Interpolator with periodic boundary conditions.
subroutine initialize_per1d_interpolator(interpolator, num_points, xmin, xmax, type, order)
initialize periodic interpolator
real(kind=f64) function, dimension(:), pointer get_coefficients_per1d(interpolator)
real(kind=f64) function interpolate_deriv1_per1d(interpolator, eta1)
subroutine per_interpolate1d(this, num_pts, data, coordinates, output_array)
subroutine interpolate_values_per1d(interpolator, num_pts, vals_to_interpolate, output_array)
real(kind=f64) function interpolate_value_per1d(interpolator, eta1)
subroutine set_coefficients_per1d(interpolator, coeffs)
type(sll_t_periodic_interpolator_1d) function, pointer new_periodic_1d_interpolator(num_points, xmin, xmax, type, order)
Create a new interpolator.
subroutine compute_interpolants_per1d(interpolator, data_array, eta_coords, size_eta_coords)
subroutine per_interpolate1d_disp(this, num_pts, data, alpha, output_array)
subroutine per_interpolate1d_disp_inplace(this, num_pts, data, alpha)
Abstract class for 1D interpolation and reconstruction.
    Report Typos and Errors