Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_hermite_interpolation_2d.F90
Go to the documentation of this file.
2 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 #include "sll_assert.h"
4 #include "sll_memory.h"
5 #include "sll_working_precision.h"
6 
7  implicit none
8 
9  public :: &
20 
21  private
22 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 
24 !Hermite interpolation in 2d
25 !derivatives are given with finite stencil formulae of order p
26 !which can be arbitrary in each direction
27 !If p is odd, the reconstruction has discontinuous derivatives
28 !If p is even, the reconstruction has continuous derivatives
29 !p=6 should be quite similar to cubic splines
30 !do not hesitate to take large odd p, like the favourite p=17
31 !! WARNING
32 ! for the moment only in implementation for the case DIRICHLET x PERIODIC
33 
35  sll_real64 :: eta_min(2)
36  sll_real64 :: eta_max(2)
37  sll_int32 :: nc(2)
38  sll_int32 :: degree(2)
39  sll_int32 :: bc(2)
41  sll_real64, dimension(:, :, :), pointer :: deriv
42  sll_int32 :: continuity(2)
43  sll_int32 :: deriv_size(2)
47 
48  integer, parameter :: sll_p_hermite_periodic = 0, sll_p_hermite_dirichlet = 1
49  integer, parameter :: sll_p_hermite_c0 = 0, sll_hermite_c1 = 1
50 
51 ! interface delete
52 ! module procedure delete_hermite_interpolation_2d
53 ! end interface
54 
55 contains !*****************************************************************************
57  npts1, &
58  npts2, &
59  eta1_min, &
60  eta1_max, &
61  eta2_min, &
62  eta2_max, &
63  degree1, &
64  degree2, &
65  eta1_hermite_continuity, &
66  eta2_hermite_continuity, &
67  eta1_bc_type, &
68  eta2_bc_type, &
69  const_eta1_min_slope, &
70  const_eta1_max_slope, &
71  const_eta2_min_slope, &
72  const_eta2_max_slope, &
73  eta1_min_slopes, &
74  eta1_max_slopes, &
75  eta2_min_slopes, &
76  eta2_max_slopes) &
77  result(interp)
78 
79  type(sll_t_hermite_interpolation_2d), pointer :: interp
80  sll_int32, intent(in) :: npts1
81  sll_int32, intent(in) :: npts2
82  sll_real64, intent(in) :: eta1_min
83  sll_real64, intent(in) :: eta1_max
84  sll_real64, intent(in) :: eta2_min
85  sll_real64, intent(in) :: eta2_max
86  sll_int32, intent(in) :: degree1
87  sll_int32, intent(in) :: degree2
88  sll_int32, intent(in) :: eta1_hermite_continuity
89  sll_int32, intent(in) :: eta2_hermite_continuity
90  sll_int32, intent(in) :: eta1_bc_type
91  sll_int32, intent(in) :: eta2_bc_type
92  sll_real64, intent(in), optional :: const_eta1_min_slope
93  sll_real64, intent(in), optional :: const_eta1_max_slope
94  sll_real64, intent(in), optional :: const_eta2_min_slope
95  sll_real64, intent(in), optional :: const_eta2_max_slope
96  sll_real64, dimension(:), intent(in), optional :: eta1_min_slopes
97  sll_real64, dimension(:), intent(in), optional :: eta1_max_slopes
98  sll_real64, dimension(:), intent(in), optional :: eta2_min_slopes
99  sll_real64, dimension(:), intent(in), optional :: eta2_max_slopes
100  sll_int32 :: ierr
101 
102  sll_allocate(interp, ierr)
103 
105  interp, &
106  npts1, &
107  npts2, &
108  eta1_min, &
109  eta1_max, &
110  eta2_min, &
111  eta2_max, &
112  degree1, &
113  degree2, &
114  eta1_hermite_continuity, &
115  eta2_hermite_continuity, &
116  eta1_bc_type, &
117  eta2_bc_type, &
118  const_eta1_min_slope, &
119  const_eta1_max_slope, &
120  const_eta2_min_slope, &
121  const_eta2_max_slope, &
122  eta1_min_slopes, &
123  eta1_max_slopes, &
124  eta2_min_slopes, &
125  eta2_max_slopes)
126 
128 
130  interp, &
131  npts1, &
132  npts2, &
133  eta1_min, &
134  eta1_max, &
135  eta2_min, &
136  eta2_max, &
137  degree1, &
138  degree2, &
139  eta1_hermite_continuity, &
140  eta2_hermite_continuity, &
141  eta1_bc_type, &
142  eta2_bc_type, &
143  const_eta1_min_slope, &
144  const_eta1_max_slope, &
145  const_eta2_min_slope, &
146  const_eta2_max_slope, &
147  eta1_min_slopes, &
148  eta1_max_slopes, &
149  eta2_min_slopes, &
150  eta2_max_slopes)
151 
152  type(sll_t_hermite_interpolation_2d) :: interp
153 
154  sll_int32, intent(in) :: npts1
155  sll_int32, intent(in) :: npts2
156  sll_real64, intent(in) :: eta1_min
157  sll_real64, intent(in) :: eta1_max
158  sll_real64, intent(in) :: eta2_min
159  sll_real64, intent(in) :: eta2_max
160  sll_int32, intent(in) :: degree1
161  sll_int32, intent(in) :: degree2
162  sll_int32, intent(in) :: eta1_hermite_continuity
163  sll_int32, intent(in) :: eta2_hermite_continuity
164  sll_int32, intent(in) :: eta1_bc_type
165  sll_int32, intent(in) :: eta2_bc_type
166  sll_real64, intent(in), optional :: const_eta1_min_slope
167  sll_real64, intent(in), optional :: const_eta1_max_slope
168  sll_real64, intent(in), optional :: const_eta2_min_slope
169  sll_real64, intent(in), optional :: const_eta2_max_slope
170  sll_real64, dimension(:), intent(in), optional :: eta1_min_slopes
171  sll_real64, dimension(:), intent(in), optional :: eta1_max_slopes
172  sll_real64, dimension(:), intent(in), optional :: eta2_min_slopes
173  sll_real64, dimension(:), intent(in), optional :: eta2_max_slopes
174  sll_int32 :: ierr
175  sll_int32 :: deriv_size
176  sll_int32 :: i
177 
178  interp%Nc(1:2) = (/npts1 - 1, npts2 - 1/)
179  interp%degree(1:2) = (/degree1, degree2/)
180  interp%continuity = (/eta1_hermite_continuity, eta2_hermite_continuity/)
181  interp%bc(1:2) = (/eta1_bc_type, eta2_bc_type/)
182  interp%eta_min = (/eta1_min, eta2_min/)
183  interp%eta_max = (/eta1_max, eta2_max/)
184 
185  deriv_size = 1
186  do i = 1, 2
187  select case (interp%continuity(i))
188  case (sll_p_hermite_c0)
189  interp%deriv_size(i) = 3
190  case (sll_hermite_c1)
191  interp%deriv_size(i) = 2
192  case default
193  print *, '#bad value for hermite_continuity', interp%continuity
194  print *, '#in initialize_hermite_interpolation_2d'
195  stop
196  sll_assert(present(const_eta1_min_slope))
197  sll_assert(present(const_eta1_max_slope))
198  sll_assert(present(const_eta2_min_slope))
199  sll_assert(present(const_eta2_max_slope))
200  sll_assert(present(eta1_min_slopes))
201  sll_assert(present(eta1_max_slopes))
202  sll_assert(present(eta2_min_slopes))
203  sll_assert(present(eta2_max_slopes))
204 
205  end select
206  deriv_size = deriv_size*interp%deriv_size(i)
207  end do
208 
209  sll_allocate(interp%deriv(deriv_size, npts1, npts2), ierr)
210 
212 
214  interp, &
215  f)
216  type(sll_t_hermite_interpolation_2d) :: interp
217  sll_real64, dimension(:, :), intent(in) :: f
218  if ((interp%bc(1) == sll_p_hermite_dirichlet) .and. &
219  (interp%bc(2) == sll_p_hermite_periodic)) then
220  if ((interp%continuity(1) == sll_p_hermite_c0) .and. &
221  (interp%continuity(2) == sll_p_hermite_c0)) then
222  call hermite_coef_nat_per(f, interp%deriv, interp%Nc, interp%degree)
223  else
224  print *, '#interp%continuity=', interp%continuity
225  print *, '#possible_value=', sll_p_hermite_c0
226  print *, '#not implemented for the moment'
227  print *, '#in sll_s_compute_interpolants_hermite_2d'
228  stop
229  end if
230  else if ((interp%bc(1) == sll_p_hermite_periodic) .and. &
231  (interp%bc(2) == sll_p_hermite_periodic)) then
232  if ((interp%continuity(1) == sll_p_hermite_c0) .and. &
233  (interp%continuity(2) == sll_p_hermite_c0)) then
234  call hermite_coef_per_per(f, interp%deriv, interp%Nc, interp%degree)
235  else
236  print *, '#interp%continuity=', interp%continuity
237  print *, '#possible_value=', sll_p_hermite_c0
238  print *, '#not implemented for the moment'
239  print *, '#in sll_s_compute_interpolants_hermite_2d'
240  stop
241  end if
242 
243  else
244 
245  print *, '#interp%bc=', interp%bc
246  print *, '#possible_value=', sll_p_hermite_dirichlet, sll_p_hermite_periodic
247  print *, '#not implemented for the moment'
248  print *, '#in sll_s_compute_interpolants_hermite_2d'
249  stop
250  end if
251 
253 
254  subroutine sll_s_compute_w_hermite(w, r, s)
255  sll_int32, intent(in)::r, s
256  sll_real64, dimension(r:s), intent(out)::w
257  sll_int32 ::i, j
258  sll_real64::tmp
259 
260  !maple code for generation of w
261  !for k from r to -1 do
262  ! C[k]:=product((k-j),j=r..k-1)*product((k-j),j=k+1..s):
263  ! C[k]:=1/C[k]*product((-j),j=r..k-1)*product((-j),j=k+1..-1)*product((-j),j=1..s):
264  !od:
265  !for k from 1 to s do
266  ! C[k]:=product((k-j),j=r..k-1)*product((k-j),j=k+1..s):
267  ! C[k]:=1/C[k]*product((-j),j=r..-1)*product((-j),j=1..k-1)*product((-j),j=k+1..s):
268  !od:
269  !C[0]:=-add(C[k],k=r..-1)-add(C[k],k=1..s):
270 
271  do i = r, -1
272  tmp = 1._f64
273  do j = r, i - 1
274  tmp = tmp*real(i - j, f64)
275  end do
276  do j = i + 1, s
277  tmp = tmp*real(i - j, f64)
278  end do
279  tmp = 1._f64/tmp
280  do j = r, i - 1
281  tmp = tmp*real(-j, f64)
282  end do
283  do j = i + 1, -1
284  tmp = tmp*real(-j, f64)
285  end do
286  do j = 1, s
287  tmp = tmp*real(-j, f64)
288  end do
289  w(i) = tmp
290  end do
291 
292  do i = 1, s
293  tmp = 1._f64
294  do j = r, i - 1
295  tmp = tmp*real(i - j, f64)
296  end do
297  do j = i + 1, s
298  tmp = tmp*real(i - j, f64)
299  end do
300  tmp = 1._f64/tmp
301  do j = r, -1
302  tmp = tmp*real(-j, f64)
303  end do
304  do j = 1, i - 1
305  tmp = tmp*real(-j, f64)
306  end do
307  do j = i + 1, s
308  tmp = tmp*real(-j, f64)
309  end do
310  w(i) = tmp
311  end do
312  tmp = 0._f64
313  do i = r, -1
314  tmp = tmp + w(i)
315  end do
316  do i = 1, s
317  tmp = tmp + w(i)
318  end do
319  w(0) = -tmp
320 
321  !print *,'w',w
322  !do ii=r,s
323  ! print *,ii,w(r+s-ii)
324  !enddo
325  !
326 
327  end subroutine sll_s_compute_w_hermite
328 
329  subroutine sll_s_compute_hermite_derivatives_periodic1(f, num_points1, num_points2, p, buf)
330  sll_real64, dimension(:, :), intent(in) :: f
331  sll_int32, intent(in) :: num_points1
332  sll_int32, intent(in) :: num_points2
333  sll_int32, intent(in) :: p
334  sll_real64, dimension(:, :, :), intent(out) :: buf
335 
336  sll_real64 :: w_left(-p/2:(p + 1)/2)
337  sll_real64 :: w_right((-p + 1)/2:p/2 + 1)
338  sll_int32 :: r_left
339  sll_int32 :: s_left
340  sll_int32 :: r_right
341  sll_int32 :: s_right
342  sll_int32 :: i
343  sll_int32 :: j
344  sll_real64 :: tmp
345  sll_int32 :: ii
346  sll_int32 :: ind
347 
348  r_left = -p/2
349  s_left = (p + 1)/2
350  r_right = (-p + 1)/2
351  s_right = p/2 + 1
352  call sll_s_compute_w_hermite(w_left, r_left, s_left)
353  if (((2*p/2) - p) == 0) then
354  w_right(r_right:s_right) = w_left(r_left:s_left)
355  else
356  w_right(r_right:s_right) = -w_left(s_left:r_left:-1)
357  end if
358 
359  do j = 1, num_points2
360  do i = 1, num_points1
361  buf(1, i, j) = f(i, j) !f(0)
362  tmp = 0._f64
363  do ii = r_left, s_left
364  ind = modulo(i + ii - 2 + num_points1, num_points1 - 1) + 1
365  tmp = tmp + w_left(ii)*f(ind, j)
366  end do
367  buf(2, i, j) = tmp !df(0)
368  tmp = 0._f64
369  do ii = r_right, s_right
370  ind = modulo(i + ii - 2 + num_points1, num_points1 - 1) + 1
371  tmp = tmp + w_right(ii)*f(ind, j)
372  end do
373  buf(3, i, j) = tmp !df(1)
374  end do
375  end do
376 
378 
379 !function compute_hermite_r_left(p) result(res)
380 ! sll_int32, intent(in) :: p
381 ! sll_int32 :: res
382 ! res = -p/2
383 !end function compute_hermite_r_left
384 !
385 !
386 !function compute_hermite_s_left(p) result(res)
387 ! sll_int32, intent(in) :: p
388 ! sll_int32 :: res
389 ! res = (p+1)/2
390 !end function compute_hermite_s_left
391 !
392 !
393 !function compute_hermite_r_right(p) result(res)
394 ! sll_int32, intent(in) :: p
395 ! sll_int32 :: res
396 ! res = (-p+1)/2
397 !end function compute_hermite_r_right
398 !
399 !function compute_hermite_s_right(p) result(res)
400 ! sll_int32, intent(in) :: p
401 ! sll_int32 :: res
402 ! res = p/2/+1
403 !end function compute_hermite_s_right
404 
405  subroutine hermite_coef_nat_per(f, buf3d, N, d)
406  sll_int32, intent(in)::n(2), d(2)
407  sll_real64, dimension(N(1) + 1, N(2)), intent(in)::f
408  sll_real64, dimension(9, N(1) + 1, N(2) + 1), intent(out)::buf3d
409  sll_real64 ::w_left_1(-d(1)/2:(d(1) + 1)/2), w_right_1((-d(1) + 1)/2:d(1)/2 + 1)
410  sll_real64 ::w_left_2(-d(2)/2:(d(2) + 1)/2), w_right_2((-d(2) + 1)/2:d(2)/2 + 1)
411  sll_real64 ::tmp
412  sll_int32 ::i, j, ii, r_left(2), r_right(2), s_left(2), s_right(2), ind
413  r_left = -d/2
414  s_left = (d + 1)/2
415  r_right = (-d + 1)/2
416  s_right = d/2 + 1
417 
418  call sll_s_compute_w_hermite(w_left_1, r_left(1), s_left(1))
419  call sll_s_compute_w_hermite(w_left_2, r_left(2), s_left(2))
420  if ((2*(d(1)/2) - d(1)) == 0) then
421  w_right_1(r_right(1):s_right(1)) = w_left_1(r_left(1):s_left(1))
422  else
423  w_right_1(r_right(1):s_right(1)) = -w_left_1(s_left(1):r_left(1):-1)
424  end if
425 
426  if ((2*(d(2)/2) - d(2)) == 0) then
427  w_right_2(r_right(2):s_right(2)) = w_left_2(r_left(2):s_left(2))
428  else
429  w_right_2(r_right(2):s_right(2)) = -w_left_2(s_left(2):r_left(2):-1)
430  end if
431 
432  !print *,'w(',r_left(1),':',s_left(1),')=',w_left_1(r_left(1):s_left(1))
433  !print *,'w(',r_right(1),':',s_right(1),')=',w_right_1(r_right(1):s_right(1))
434 
435  do j = 1, n(2)
436  do i = 1, n(1) + 1
437  buf3d(1, i, j) = f(i, j) !f(0,0)
438  tmp = 0._f64
439  do ii = r_left(1), s_left(1)
440  ind = i + ii; if (ind > n(1) + 1) ind = 2*(n(1) + 1) - ind; if (ind < 1) ind = 2 - ind
441  tmp = tmp + w_left_1(ii)*f(ind, j)
442  end do
443  buf3d(2, i, j) = tmp !fx(0,0)
444  tmp = 0._f64
445  do ii = r_right(1), s_right(1)
446  ind = i + ii; if (ind > n(1) + 1) ind = 2*(n(1) + 1) - ind; if (ind < 1) ind = 2 - ind
447  tmp = tmp + w_right_1(ii)*f(ind, j)
448  end do
449  buf3d(3, i, j) = tmp !fx(1,0)
450  end do
451  end do
452  do i = 1, n(1) + 1
453  do j = 1, n(2)
454  tmp = 0._f64
455  do ii = r_left(2), s_left(2)
456  ind = modulo(j + ii - 1 + n(2), n(2)) + 1
457  tmp = tmp + w_left_2(ii)*f(i, ind)
458  end do
459  buf3d(4, i, j) = tmp !fy(0,0)
460  tmp = 0._f64
461  do ii = r_right(2), s_right(2)
462  ind = modulo(j + ii - 1 + n(2), n(2)) + 1
463  tmp = tmp + w_right_2(ii)*f(i, ind)
464  end do
465  buf3d(5, i, j) = tmp !fy(0,1)
466  end do
467  end do
468 
469  do j = 1, n(2)
470  do i = 1, n(1) + 1
471  tmp = 0._f64
472  do ii = r_left(1), s_left(1)
473  ind = i + ii; if (ind > n(1) + 1) ind = 2*(n(1) + 1) - ind; if (ind < 1) ind = 2 - ind
474  tmp = tmp + w_left_1(ii)*buf3d(4, ind, j)
475  end do
476  buf3d(6, i, j) = tmp !fxy(0,0)
477  tmp = 0._f64
478  do ii = r_right(1), s_right(1)
479  ind = i + ii; if (ind > n(1) + 1) ind = 2*(n(1) + 1) - ind; if (ind < 1) ind = 2 - ind
480  tmp = tmp + w_right_1(ii)*buf3d(4, ind, j)
481  end do
482  buf3d(7, i, j) = tmp !fxy(1,0)
483  tmp = 0._f64
484  do ii = r_left(1), s_left(1)
485  ind = i + ii; if (ind > n(1) + 1) ind = 2*(n(1) + 1) - ind; if (ind < 1) ind = 2 - ind
486  tmp = tmp + w_left_1(ii)*buf3d(5, ind, j)
487  end do
488  buf3d(8, i, j) = tmp !fxy(0,1)
489  tmp = 0._f64
490  do ii = r_right(1), s_right(1)
491  ind = i + ii; if (ind > n(1) + 1) ind = 2*(n(1) + 1) - ind; if (ind < 1) ind = 2 - ind
492  tmp = tmp + w_right_1(ii)*buf3d(5, ind, j)
493  end do
494  buf3d(9, i, j) = tmp !fxy(1,1)
495  end do
496  end do
497 
498  buf3d(:, :, n(2) + 1) = buf3d(:, :, 1)
499 
500  !print *,'d=',d,maxval(abs(buf3d))
501 
502  end subroutine hermite_coef_nat_per
503 
504  subroutine hermite_coef_per_per(f, buf3d, N, d)
505  sll_int32, intent(in)::n(2), d(2)
506  sll_real64, dimension(N(1) + 1, N(2)), intent(in)::f
507  sll_real64, dimension(9, N(1) + 1, N(2) + 1), intent(out)::buf3d
508  sll_real64 ::w_left_1(-d(1)/2:(d(1) + 1)/2), w_right_1((-d(1) + 1)/2:d(1)/2 + 1)
509  sll_real64 ::w_left_2(-d(2)/2:(d(2) + 1)/2), w_right_2((-d(2) + 1)/2:d(2)/2 + 1)
510  sll_real64 ::tmp
511  sll_int32 ::i, j, ii, r_left(2), r_right(2), s_left(2), s_right(2), ind
512  r_left = -d/2
513  s_left = (d + 1)/2
514  r_right = (-d + 1)/2
515  s_right = d/2 + 1
516 
517  call sll_s_compute_w_hermite(w_left_1, r_left(1), s_left(1))
518  call sll_s_compute_w_hermite(w_left_2, r_left(2), s_left(2))
519  if ((2*(d(1)/2) - d(1)) == 0) then
520  w_right_1(r_right(1):s_right(1)) = w_left_1(r_left(1):s_left(1))
521  else
522  w_right_1(r_right(1):s_right(1)) = -w_left_1(s_left(1):r_left(1):-1)
523  end if
524 
525  if ((2*(d(2)/2) - d(2)) == 0) then
526  w_right_2(r_right(2):s_right(2)) = w_left_2(r_left(2):s_left(2))
527  else
528  w_right_2(r_right(2):s_right(2)) = -w_left_2(s_left(2):r_left(2):-1)
529  end if
530 
531  !print *,'w(',r_left(1),':',s_left(1),')=',w_left_1(r_left(1):s_left(1))
532  !print *,'w(',r_right(1),':',s_right(1),')=',w_right_1(r_right(1):s_right(1))
533 
534  do j = 1, n(2)
535  do i = 1, n(1) + 1
536  buf3d(1, i, j) = f(i, j) !f(0,0)
537  tmp = 0._f64
538  do ii = r_left(1), s_left(1)
539  !ind=i+ii;if(ind>N(1)+1) ind=2*(N(1)+1)-ind;if(ind<1) ind=2-ind
540  ind = modulo(i + ii - 1 + n(1), n(1)) + 1
541  tmp = tmp + w_left_1(ii)*f(ind, j)
542  end do
543  buf3d(2, i, j) = tmp !fx(0,0)
544  tmp = 0._f64
545  do ii = r_right(1), s_right(1)
546  !ind=i+ii;if(ind>N(1)+1) ind=2*(N(1)+1)-ind;if(ind<1) ind=2-ind
547  ind = modulo(i + ii - 1 + n(1), n(1)) + 1
548  tmp = tmp + w_right_1(ii)*f(ind, j)
549  end do
550  buf3d(3, i, j) = tmp !fx(1,0)
551  end do
552  end do
553  do i = 1, n(1) + 1
554  do j = 1, n(2)
555  tmp = 0._f64
556  do ii = r_left(2), s_left(2)
557  ind = modulo(j + ii - 1 + n(2), n(2)) + 1
558  tmp = tmp + w_left_2(ii)*f(i, ind)
559  end do
560  buf3d(4, i, j) = tmp !fy(0,0)
561  tmp = 0._f64
562  do ii = r_right(2), s_right(2)
563  ind = modulo(j + ii - 1 + n(2), n(2)) + 1
564  tmp = tmp + w_right_2(ii)*f(i, ind)
565  end do
566  buf3d(5, i, j) = tmp !fy(0,1)
567  end do
568  end do
569 
570  do j = 1, n(2)
571  do i = 1, n(1) + 1
572  tmp = 0._f64
573  do ii = r_left(1), s_left(1)
574  !ind=i+ii;if(ind>N(1)+1) ind=2*(N(1)+1)-ind;if(ind<1) ind=2-ind
575  ind = modulo(i + ii - 1 + n(1), n(1)) + 1
576  tmp = tmp + w_left_1(ii)*buf3d(4, ind, j)
577  end do
578  buf3d(6, i, j) = tmp !fxy(0,0)
579  tmp = 0._f64
580  do ii = r_right(1), s_right(1)
581  !ind=i+ii;if(ind>N(1)+1) ind=2*(N(1)+1)-ind;if(ind<1) ind=2-ind
582  ind = modulo(i + ii - 1 + n(1), n(1)) + 1
583  tmp = tmp + w_right_1(ii)*buf3d(4, ind, j)
584  end do
585  buf3d(7, i, j) = tmp !fxy(1,0)
586  tmp = 0._f64
587  do ii = r_left(1), s_left(1)
588  !ind=i+ii;if(ind>N(1)+1) ind=2*(N(1)+1)-ind;if(ind<1) ind=2-ind
589  ind = modulo(i + ii - 1 + n(1), n(1)) + 1
590  tmp = tmp + w_left_1(ii)*buf3d(5, ind, j)
591  end do
592  buf3d(8, i, j) = tmp !fxy(0,1)
593  tmp = 0._f64
594  do ii = r_right(1), s_right(1)
595  !ind=i+ii;if(ind>N(1)+1) ind=2*(N(1)+1)-ind;if(ind<1) ind=2-ind
596  ind = modulo(i + ii - 1 + n(1), n(1)) + 1
597  tmp = tmp + w_right_1(ii)*buf3d(5, ind, j)
598  end do
599  buf3d(9, i, j) = tmp !fxy(1,1)
600  end do
601  end do
602 
603  buf3d(:, :, n(2) + 1) = buf3d(:, :, 1)
604 
605  !print *,'d=',d,maxval(abs(buf3d))
606 
607  end subroutine hermite_coef_per_per
608 
609  function sll_f_interpolate_value_hermite_2d(eta1, eta2, interp) result(res)
610  sll_real64, intent(in) :: eta1
611  sll_real64, intent(in) :: eta2
612  type(sll_t_hermite_interpolation_2d), pointer :: interp
613  sll_real64 :: res
614  sll_real64 :: eta_tmp(2)
615  sll_int32 :: ii(2)
616 
617  eta_tmp(1:2) = (/eta1, eta2/)
618 
619  !warning: to be changed for dealing with general boundary conditions
620 
621  call localize_nat(ii(1), eta_tmp(1), interp%eta_min(1), interp%eta_max(1), interp%Nc(1))
622  !print *,'#eta_min=',interp%eta_min
623  !print *,'#eta_max=',interp%eta_max
624  !print *,'#before',ii,eta_tmp(1:2),interp%Nc
625  call sll_s_localize_per(ii(2), eta_tmp(2), interp%eta_min(2), interp%eta_max(2), interp%Nc(2))
626  !print *,'#before',ii,eta_tmp(1:2),interp%Nc
627  call interpolate_hermite(interp%deriv, ii, eta_tmp, res, interp%Nc)
628  !print *,'#after'
629 
631 
632  subroutine interpolate_hermite(f, i, x, fval, N)
633  sll_int32, intent(in)::i(2), n(2)
634  !real(f64),intent(in)::xx(2),xmin(2),xmax(2)
635  sll_real64, intent(in)::x(2)
636  sll_real64, intent(out)::fval
637  sll_real64, dimension(0:8, 0:N(1), 0:N(2))::f
638  !integer::i(2),i1(2),s
639  sll_int32::i1(2), s
640  sll_real64::w(2, 0:3), tmp(0:3)
641  sll_real64::g(0:3, 0:3)
642 
643  !fval =f(0,i(1),i(2))!real(i(1),f64)
644 
645  !return
646 
647  do s = 1, 2
648  w(s, 0) = (2._f64*x(s) + 1)*(1._f64 - x(s))*(1._f64 - x(s));
649  w(s, 1) = x(s)*x(s)*(3._f64 - 2._f64*x(s))
650  w(s, 2) = x(s)*(1._f64 - x(s))*(1._f64 - x(s))
651  w(s, 3) = x(s)*x(s)*(x(s) - 1._f64)
652  i1(s) = i(s) + 1
653  end do
654 
655  g(0, 0) = f(0, i(1), i(2)) !f(0,0)
656  g(1, 0) = f(0, i1(1), i(2)) !f(1,0)
657  g(2, 0) = f(1, i(1), i(2)) !fx(0,0)
658  g(3, 0) = f(2, i(1), i(2)) !fx(1,0)
659  g(0, 1) = f(0, i(1), i1(2)) !f(0,1)
660  g(1, 1) = f(0, i1(1), i1(2)) !f(1,1)
661  g(2, 1) = f(1, i(1), i1(2)) !fx(0,1)
662  g(3, 1) = f(2, i(1), i1(2)) !fx(1,1)
663  g(0, 2) = f(3, i(1), i(2)) !fy(0,0)
664  g(1, 2) = f(3, i1(1), i(2)) !fy(1,0)
665  g(2, 2) = f(5, i(1), i(2)) !fxy(0,0)
666  g(3, 2) = f(6, i(1), i(2)) !fxy(1,0)
667  g(0, 3) = f(4, i(1), i(2)) !fy(0,1)
668  g(1, 3) = f(4, i1(1), i(2)) !fy(1,1)
669  g(2, 3) = f(7, i(1), i(2)) !fxy(0,1)
670  g(3, 3) = f(8, i(1), i(2)) !fxy(1,1)
671 
672  do s = 0, 3
673  tmp(s) = w(1, 0)*g(0, s) + w(1, 1)*g(1, s) + w(1, 2)*g(2, s) + w(1, 3)*g(3, s)
674  end do
675 
676  fval = w(2, 0)*tmp(0) + w(2, 1)*tmp(1) + w(2, 2)*tmp(2) + w(2, 3)*tmp(3)
677 
678  !print *,fval,' t',f
679  end subroutine interpolate_hermite
680 
681  subroutine sll_s_localize_per(i, x, xmin, xmax, N)
682  sll_int32, intent(out)::i
683  sll_real64, intent(inout)::x
684  sll_real64, intent(in)::xmin, xmax
685  sll_int32, intent(in)::n
686  x = (x - xmin)/(xmax - xmin)
687  x = x - real(floor(x), f64)
688  x = x*real(n, f64)
689  i = floor(x)
690  x = x - real(i, f64)
691  if (i == n) then
692  i = 0
693  x = 0._f64
694  end if
695  end subroutine sll_s_localize_per
696 
697  subroutine localize_nat(i, x, xmin, xmax, N)
698  sll_int32, intent(out)::i
699  sll_real64, intent(inout)::x
700  sll_real64, intent(in)::xmin, xmax
701  sll_int32, intent(in)::n
702  x = (x - xmin)/(xmax - xmin)
703  x = x*real(n, f64)
704  if (x >= real(n, f64)) then
705  x = real(n, f64)
706  end if
707  if (x <= 0._f64) then
708  x = 0._f64
709  end if
710  i = floor(x)
711  x = x - real(i, f64)
712  if (i == n) then
713  i = n - 1
714  x = 1._f64
715  end if
716  end subroutine localize_nat
717 
718 end module
subroutine, public sll_s_compute_interpolants_hermite_2d(interp, f)
subroutine, public sll_s_localize_per(i, x, xmin, xmax, N)
integer, parameter, public sll_p_hermite_dirichlet
subroutine, public sll_s_compute_hermite_derivatives_periodic1(f, num_points1, num_points2, p, buf)
integer, parameter, public sll_p_hermite_periodic
subroutine initialize_hermite_interpolation_2d(interp, npts1, npts2, eta1_min, eta1_max, eta2_min, eta2_max, degree1, degree2, eta1_hermite_continuity, eta2_hermite_continuity, eta1_bc_type, eta2_bc_type, const_eta1_min_slope, const_eta1_max_slope, const_eta2_min_slope, const_eta2_max_slope, eta1_min_slopes, eta1_max_slopes, eta2_min_slopes, eta2_max_slopes)
subroutine interpolate_hermite(f, i, x, fval, N)
subroutine localize_nat(i, x, xmin, xmax, N)
type(sll_t_hermite_interpolation_2d) function, pointer, public sll_f_new_hermite_interpolation_2d(npts1, npts2, eta1_min, eta1_max, eta2_min, eta2_max, degree1, degree2, eta1_hermite_continuity, eta2_hermite_continuity, eta1_bc_type, eta2_bc_type, const_eta1_min_slope, const_eta1_max_slope, const_eta2_min_slope, const_eta2_max_slope, eta1_min_slopes, eta1_max_slopes, eta2_min_slopes, eta2_max_slopes)
real(kind=f64) function, public sll_f_interpolate_value_hermite_2d(eta1, eta2, interp)
subroutine, public sll_s_compute_w_hermite(w, r, s)
    Report Typos and Errors