Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_characteristics_2d_verlet.F90
Go to the documentation of this file.
1 !**************************************************************
2 ! Copyright INRIA
3 ! Authors :
4 ! CALVI project team
5 !
6 ! This code SeLaLib (for Semi-Lagrangian-Library)
7 ! is a parallel library for simulating the plasma turbulence
8 ! in a tokamak.
9 !
10 ! This software is governed by the CeCILL-B license
11 ! under French law and abiding by the rules of distribution
12 ! of free software. You can use, modify and redistribute
13 ! the software under the terms of the CeCILL-B license as
14 ! circulated by CEA, CNRS and INRIA at the following URL
15 ! "http://www.cecill.info".
16 !**************************************************************
17 
21 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 #include "sll_assert.h"
23 #include "sll_memory.h"
24 #include "sll_working_precision.h"
25 
27  sll_p_periodic, &
28  sll_p_set_to_limit
29 
35 
36  use sll_m_interpolators_1d_base, only: &
38 
39  use sll_m_interpolators_2d_base, only: &
41 
42  implicit none
43 
44  public :: &
47 
48  private
49 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
50 
52  sll_int32 :: npts1
53  sll_int32 :: npts2
54  sll_real64 :: eta1_min
55  sll_real64 :: eta1_max
56  sll_real64 :: eta2_min
57  sll_real64 :: eta2_max
58  procedure(sll_i_signature_process_outside_point), pointer, nopass :: &
59  process_outside_point1
60  procedure(sll_i_signature_process_outside_point), pointer, nopass :: &
61  process_outside_point2
62  class(sll_c_interpolator_2d), pointer :: a1_interp_x1x2
63  class(sll_c_interpolator_2d), pointer :: a2_interp_x1x2
64  class(sll_c_interpolator_1d), pointer :: a1_interp_x1
65  class(sll_c_interpolator_1d), pointer :: a2_interp_x1
66  sll_int32 :: x1_maxiter
67  sll_int32 :: x2_maxiter
68  sll_real64 :: x1_tol
69  sll_real64 :: x2_tol
70 
71  contains
72  procedure, pass(charac) :: init => initialize_verlet_2d_charac
73  procedure, pass(charac) :: compute_characteristics => compute_verlet_2d_charac
74  end type sll_t_charac_2d_verlet
75 
76 contains
78  Npts1, &
79  Npts2, &
80  A1_interp_x1x2, &
81  A2_interp_x1x2, &
82  A1_interp_x1, &
83  A2_interp_x1, &
84  bc_type_1, &
85  bc_type_2, &
86  eta1_min, &
87  eta1_max, &
88  eta2_min, &
89  eta2_max, &
90  process_outside_point1, &
91  process_outside_point2, &
92  x1_maxiter, &
93  x2_maxiter, &
94  x1_tol, &
95  x2_tol) &
96  result(charac)
97 
98  type(sll_t_charac_2d_verlet), pointer :: charac
99  sll_int32, intent(in) :: npts1
100  sll_int32, intent(in) :: npts2
101  sll_int32, intent(in), optional :: bc_type_1
102  sll_int32, intent(in), optional :: bc_type_2
103  sll_real64, intent(in), optional :: eta1_min
104  sll_real64, intent(in), optional :: eta1_max
105  sll_real64, intent(in), optional :: eta2_min
106  sll_real64, intent(in), optional :: eta2_max
107  procedure(sll_i_signature_process_outside_point), optional :: &
108  process_outside_point1
109  procedure(sll_i_signature_process_outside_point), optional :: &
110  process_outside_point2
111  class(sll_c_interpolator_2d), target :: a1_interp_x1x2
112  class(sll_c_interpolator_2d), target :: a2_interp_x1x2
113  class(sll_c_interpolator_1d), target :: a1_interp_x1
114  class(sll_c_interpolator_1d), target :: a2_interp_x1
115  sll_int32, intent(in), optional :: x1_maxiter
116  sll_int32, intent(in), optional :: x2_maxiter
117  sll_real64, intent(in), optional :: x1_tol
118  sll_real64, intent(in), optional :: x2_tol
119  sll_int32 :: ierr
120 
121  sll_allocate(charac, ierr)
123  charac, &
124  npts1, &
125  npts2, &
126  a1_interp_x1x2, &
127  a2_interp_x1x2, &
128  a1_interp_x1, &
129  a2_interp_x1, &
130  bc_type_1, &
131  bc_type_2, &
132  eta1_min, &
133  eta1_max, &
134  eta2_min, &
135  eta2_max, &
136  process_outside_point1, &
137  process_outside_point2, &
138  x1_maxiter, &
139  x2_maxiter, &
140  x1_tol, &
141  x2_tol)
142 
143  end function sll_f_new_verlet_2d_charac
145  charac, &
146  Npts1, &
147  Npts2, &
148  A1_interp_x1x2, &
149  A2_interp_x1x2, &
150  A1_interp_x1, &
151  A2_interp_x1, &
152  bc_type_1, &
153  bc_type_2, &
154  eta1_min, &
155  eta1_max, &
156  eta2_min, &
157  eta2_max, &
158  process_outside_point1, &
159  process_outside_point2, &
160  x1_maxiter, &
161  x2_maxiter, &
162  x1_tol, &
163  x2_tol)
164 
165  class(sll_t_charac_2d_verlet) :: charac
166  sll_int32, intent(in) :: npts1
167  sll_int32, intent(in) :: npts2
168  sll_int32, intent(in), optional :: bc_type_1
169  sll_int32, intent(in), optional :: bc_type_2
170  sll_real64, intent(in), optional :: eta1_min
171  sll_real64, intent(in), optional :: eta1_max
172  sll_real64, intent(in), optional :: eta2_min
173  sll_real64, intent(in), optional :: eta2_max
174  procedure(sll_i_signature_process_outside_point), optional :: &
175  process_outside_point1
176  procedure(sll_i_signature_process_outside_point), optional :: &
177  process_outside_point2
178  class(sll_c_interpolator_2d), target :: A1_interp_x1x2
179  class(sll_c_interpolator_2d), target :: A2_interp_x1x2
180  class(sll_c_interpolator_1d), target :: A1_interp_x1
181  class(sll_c_interpolator_1d), target :: A2_interp_x1
182  sll_int32, intent(in), optional :: x1_maxiter
183  sll_int32, intent(in), optional :: x2_maxiter
184  sll_real64, intent(in), optional :: x1_tol
185  sll_real64, intent(in), optional :: x2_tol
186 
187  charac%Npts1 = npts1
188  charac%Npts2 = npts2
189 
190  if (present(eta1_min)) then
191  charac%eta1_min = eta1_min
192  else
193  charac%eta1_min = 0._f64
194  end if
195  if (present(eta1_max)) then
196  charac%eta1_max = eta1_max
197  else
198  charac%eta1_max = 1._f64
199  end if
200  if (present(eta2_min)) then
201  charac%eta2_min = eta2_min
202  else
203  charac%eta2_min = 0._f64
204  end if
205 
206  if (present(eta2_max)) then
207  charac%eta2_max = eta2_max
208  else
209  charac%eta2_max = 1._f64
210  end if
211 
212  !charac%process_outside_point1 => process_outside_point1
213  !charac%process_outside_point2 => process_outside_point2
214 
215  if (present(process_outside_point1)) then
216  charac%process_outside_point1 => process_outside_point1
217  else if (.not. (present(bc_type_1))) then
218  print *, '#provide boundary condition'
219  print *, '#bc_type_1 or process_outside_point1 function'
220  print *, '#in initialize_sll_t_charac_2d_verlet'
221  stop
222  else
223  select case (bc_type_1)
224  case (sll_p_periodic)
225  charac%process_outside_point1 => sll_f_process_outside_point_periodic
226  case (sll_p_set_to_limit)
227  charac%process_outside_point1 => sll_f_process_outside_point_set_to_limit
228  case default
229  print *, '#bad value of boundary condition'
230  print *, '#in initialize_sll_t_charac_2d_verlet'
231  stop
232  end select
233  end if
234 
235  if ((present(process_outside_point1)) .and. (present(bc_type_1))) then
236  print *, '#provide either process_outside_point1 or bc_type_1'
237  print *, '#and not both'
238  print *, '#in initialize_sll_t_charac_2d_verlet'
239  stop
240  end if
241 
242  if (present(process_outside_point2)) then
243  charac%process_outside_point2 => process_outside_point2
244  else if (.not. (present(bc_type_2))) then
245  print *, '#provide boundary condition'
246  print *, '#bc_type_2 or process_outside_point1 function'
247  print *, '#in initialize_sll_t_charac_2d_verlet'
248  stop
249  else
250  select case (bc_type_2)
251  case (sll_p_periodic)
252  charac%process_outside_point2 => sll_f_process_outside_point_periodic
253  case (sll_p_set_to_limit)
254  charac%process_outside_point2 => sll_f_process_outside_point_set_to_limit
255  case default
256  print *, '#bad value of boundary condition'
257  print *, '#in initialize_sll_t_charac_2d_verlet'
258  stop
259  end select
260  end if
261 
262  if ((present(process_outside_point2)) .and. (present(bc_type_2))) then
263  print *, '#provide either process_outside_point2 or bc_type_2'
264  print *, '#and not both'
265  print *, '#in initialize_sll_t_charac_2d_verlet'
266  stop
267  end if
268 
269  charac%A1_interp_x1x2 => a1_interp_x1x2
270  charac%A2_interp_x1x2 => a2_interp_x1x2
271  charac%A1_interp_x1 => a1_interp_x1
272  charac%A2_interp_x1 => a2_interp_x1
273 
274  if (present(x1_maxiter)) then
275  charac%x1_maxiter = x1_maxiter
276  else
277  charac%x1_maxiter = 1000
278  end if
279  if (present(x2_maxiter)) then
280  charac%x2_maxiter = x2_maxiter
281  else
282  charac%x2_maxiter = charac%x1_maxiter
283  end if
284 
285  if (present(x1_tol)) then
286  charac%x1_tol = x1_tol
287  else
288  charac%x1_tol = 1.e-12_f64
289  end if
290  if (present(x2_tol)) then
291  charac%x2_tol = x2_tol
292  else
293  charac%x2_tol = charac%x1_tol
294  end if
295 
296  end subroutine initialize_verlet_2d_charac
297 
299  charac, &
300  A1, &
301  A2, &
302  dt, &
303  input1, &
304  input2, &
305  output1, &
306  output2)
307 
308  class(sll_t_charac_2d_verlet) :: charac
309  sll_real64, dimension(:, :), intent(in) :: a1
310  sll_real64, dimension(:, :), intent(in) :: a2
311  sll_real64, intent(in) :: dt
312  sll_real64, dimension(:), intent(in) :: input1
313  sll_real64, dimension(:), intent(in) :: input2
314  sll_real64, dimension(:, :), intent(out) :: output1
315  sll_real64, dimension(:, :), intent(out) :: output2
316  sll_int32 :: i
317  sll_int32 :: j
318  sll_real64 :: x1
319  sll_real64 :: x2
320  sll_real64 :: x1_old
321  sll_real64 :: x2_old
322  sll_real64 :: x1_i !i for inside, so that interpolation is possible
323  sll_real64 :: x2_i
324  sll_int32 :: iter
325  sll_int32 :: npts1
326  sll_int32 :: npts2
327  sll_real64 :: eta1_min
328  sll_real64 :: eta1_max
329  sll_real64 :: eta2_min
330  sll_real64 :: eta2_max
331 
332  npts1 = charac%Npts1
333  npts2 = charac%Npts2
334  eta1_min = charac%eta1_min
335  eta1_max = charac%eta1_max
336  eta2_min = charac%eta2_min
337  eta2_max = charac%eta2_max
338 
339  sll_assert(size(a1, 1) >= npts1)
340  sll_assert(size(a1, 2) >= npts2)
341  sll_assert(size(a2, 1) >= npts1)
342  sll_assert(size(a2, 2) >= npts2)
343  sll_assert(size(input1) >= npts1)
344  sll_assert(size(input2) >= npts2)
345  sll_assert(size(output1, 1) >= npts1)
346  sll_assert(size(output1, 2) >= npts2)
347  sll_assert(size(output2, 1) >= npts1)
348  sll_assert(size(output2, 2) >= npts2)
349 
350  ! [YG: 8 Aug 2016]
351  ! Optional arguments 'eta_coords[1|2]=input[1|2]' and
352  ! 'size_eta_coords[1|2]=Npts[1|2]' not passed because:
353  ! 1. most interpolators do not implement such an option
354  ! 2. 'input[1|2]' is (usually) the same mesh used to initialize the interpolator
355  call charac%A1_interp_x1x2%compute_interpolants(a1)
356  call charac%A2_interp_x1x2%compute_interpolants(a2)
357 ! call charac%A1_interp_x1x2%compute_interpolants( &
358 ! A1, &
359 ! input1, &
360 ! Npts1, &
361 ! input2, &
362 ! Npts2)
363 ! call charac%A2_interp_x1x2%compute_interpolants( &
364 ! A2, &
365 ! input1, &
366 ! Npts1, &
367 ! input2, &
368 ! Npts2)
369 
370  do j = 1, charac%Npts2
371 
372  ! [YG: 8 Aug 2016]
373  ! Optional arguments 'eta_coords=input' and 'size_eta_coords=Npts'
374  ! not passed because:
375  ! 1. most interpolators do not implement such an option
376  ! 2. 'input' is (usually) the same mesh used to initialize the interpolator
377  call charac%A1_interp_x1%compute_interpolants(a1(:, j))
378  call charac%A2_interp_x1%compute_interpolants(a2(:, j))
379 ! call charac%A1_interp_x1%compute_interpolants( A1(:,j), input1, charac%Npts1 )
380 ! call charac%A2_interp_x1%compute_interpolants( A2(:,j), input1, charac%Npts1 )
381 
382  do i = 1, charac%Npts1
383  !We start from X(t_{n+1}) = x_i, Y(t_{n+1})=y_j
384  !and look for X(t_n) = Xn, Y(t_n) = Yn
385 
386  !X* = x_i-A1(X*,y_j)*dt/2
387  x1 = input1(i) - 0.5_f64*dt*a1(i, j)
388  if ((x1 <= charac%eta1_min) .or. (x1 >= charac%eta1_max)) then
389  x1 = charac%process_outside_point1(x1, charac%eta1_min, charac%eta1_max)
390  end if
391  x1_old = 0._f64
392  iter = 0
393  do while (iter < charac%x1_maxiter .and. abs(x1_old - x1) > charac%x1_tol)
394  x1_old = x1
395  if ((x1 <= charac%eta1_min) .or. (x1 >= charac%eta1_max)) then
396  x1_i = charac%process_outside_point1(x1, charac%eta1_min, charac%eta1_max)
397  else
398  x1_i = x1
399  end if
400  x1 = input1(i) - 0.5_f64*dt*charac%A1_interp_x1%interpolate_from_interpolant_value(x1_i)
401  iter = iter + 1
402  end do
403  if (iter == charac%x1_maxiter .and. abs(x1_old - x1) > charac%x1_tol) then
404  !print*,'#not enough iterations for compute_characteristics2D_verlet x1',&
405  ! iter,abs(x1_old-x1)
406  ! stop
407  end if
408  if ((x1 <= charac%eta1_min) .or. (x1 >= charac%eta1_max)) then
409  x1 = charac%process_outside_point1(x1, charac%eta1_min, charac%eta1_max)
410  end if
411 
412  !Yn = y_j-(A2(X*,y_j)+A2(X*,Yn))*dt/2
413  x2 = input2(j) - dt*a2(i, j)
414  x2_old = 0._f64
415  iter = 0
416  do while (iter < charac%x2_maxiter .and. abs(x2_old - x2) > charac%x2_tol)
417  x2_old = x2
418  x2_i = x2
419  if ((x2 <= charac%eta2_min) .or. (x2 >= charac%eta2_max)) then
420  x2_i = charac%process_outside_point2(x2, charac%eta2_min, charac%eta2_max)
421  else
422  x2_i = x2
423  end if
424  x2 = input2(j) - 0.5_f64*dt*(charac%A2_interp_x1x2%interpolate_from_interpolant_value(x1, x2_i) &
425  + charac%A2_interp_x1%interpolate_from_interpolant_value(x1))
426  iter = iter + 1
427  end do
428  if (iter == charac%x2_maxiter .and. abs(x2_old - x2) > charac%x2_tol) then
429  !print*,'#not enough iterations for compute_characteristics2D_verlet x2',&
430  ! iter,abs(x2_old-x2)
431  ! stop
432  end if
433  if ((x2 <= charac%eta2_min) .or. (x2 >= charac%eta2_max)) then
434  x2 = charac%process_outside_point2(x2, charac%eta2_min, charac%eta2_max)
435  end if
436 
437  !Xn = y_j-A1(X*,Yn)*dt/2
438  x1 = x1 - 0.5_f64*dt*charac%A1_interp_x1x2%interpolate_from_interpolant_value(x1, x2)
439  if ((x1 <= charac%eta1_min) .or. (x1 >= charac%eta1_max)) then
440  x1 = charac%process_outside_point1(x1, charac%eta1_min, charac%eta1_max)
441  end if
442 
443  output1(i, j) = x1
444  output2(i, j) = x2
445  end do
446  end do
447 
448  end subroutine compute_verlet_2d_charac
449 
Abstract class to compute the characteristic in two dimensions.
real(kind=f64) function, public sll_f_process_outside_point_periodic(eta, eta_min, eta_max)
real(kind=f64) function, public sll_f_process_outside_point_set_to_limit(eta, eta_min, eta_max)
computes the characteristic with verlet method
subroutine initialize_verlet_2d_charac(charac, Npts1, Npts2, A1_interp_x1x2, A2_interp_x1x2, A1_interp_x1, A2_interp_x1, bc_type_1, bc_type_2, eta1_min, eta1_max, eta2_min, eta2_max, process_outside_point1, process_outside_point2, x1_maxiter, x2_maxiter, x1_tol, x2_tol)
subroutine compute_verlet_2d_charac(charac, A1, A2, dt, input1, input2, output1, output2)
type(sll_t_charac_2d_verlet) function, pointer, public sll_f_new_verlet_2d_charac(Npts1, Npts2, A1_interp_x1x2, A2_interp_x1x2, A1_interp_x1, A2_interp_x1, bc_type_1, bc_type_2, eta1_min, eta1_max, eta2_min, eta2_max, process_outside_point1, process_outside_point2, x1_maxiter, x2_maxiter, x1_tol, x2_tol)
Module for 1D interpolation and reconstruction.
abstract data type for 2d interpolation
Abstract class for 1D interpolation and reconstruction.
Base class/basic interface for 2D interpolators.
    Report Typos and Errors