Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_qn_2d_polar.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 
19 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20 #include "sll_memory.h"
21 #include "sll_working_precision.h"
22 
23  use sll_m_constants, only: sll_p_pi
24 
26 
27  use sll_m_fft, only: sll_t_fft, &
33 
34  use sll_m_gyroaverage_utilities, only: &
37 
38  implicit none
39 
40  public :: &
58 
59  private
60 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
61 
63 
64  sll_real64 :: eta_min(2)
65  sll_real64 :: eta_max(2)
66  sll_int32 :: nc(2)
67  sll_int32 :: n_points
68 
69  sll_real64, dimension(:, :), pointer :: points
70  sll_int32, dimension(:, :), pointer :: pre_compute_n
71  sll_real64, dimension(:, :, :), pointer :: pre_compute_coeff
72  sll_int32, dimension(:, :, :), pointer :: pre_compute_index
73  sll_real64, dimension(:, :), pointer :: pre_compute_coeff_spl
74  sll_int32 :: size_pre_compute
75 
76  sll_real64, dimension(:, :, :), pointer :: mat_gyro
77  sll_real64, dimension(:, :, :), pointer :: mat_double_gyro
78  sll_real64, dimension(:, :, :, :), pointer :: mat_gyro_circ
79  sll_real64, dimension(:, :, :, :), pointer :: mat_double_gyro_circ
80 
81  sll_comp64, dimension(:, :, :), pointer :: mat_qn_inverse
82 
83  sll_real64, dimension(:), allocatable :: lambda
84  sll_real64, dimension(:), allocatable :: t_i
85  ! solve \lambda(r)\phi-\tilde{\phi} = second member
86 
87  sll_real64, dimension(:), pointer :: mu_points_for_phi
88  sll_real64, dimension(:), pointer :: mu_weights_for_phi
89  sll_int32 :: n_mu_for_phi
90 
91  end type sll_t_qn_2d_polar
92 
93 contains
94 
95  subroutine sll_s_qn_2d_polar_init(this, eta_min, eta_max, Nc, N_points, lambda, T_i)
96 
97  sll_real64, intent(in) :: eta_min(2)
98  sll_real64, intent(in) :: eta_max(2)
99  sll_int32, intent(in) :: nc(2)
100  sll_int32, intent(in) :: n_points
101  sll_real64, dimension(:), intent(in) :: lambda
102  sll_real64, dimension(:), intent(in) :: t_i
103  type(sll_t_qn_2d_polar) :: this
104 
105  sll_int32 :: err
106 
107  sll_allocate(this%points(3, n_points), err)
108  sll_allocate(this%lambda(1:nc(1) + 1), err)
109  sll_allocate(this%T_i(1:nc(1) + 1), err)
110 
111  call sll_s_compute_shape_circle(this%points, n_points)
112 
113  this%eta_min = eta_min
114  this%eta_max = eta_max
115  this%Nc = nc
116  this%N_points = n_points
117 
118  this%lambda = lambda
119  this%T_i = t_i
120 
121  end subroutine sll_s_qn_2d_polar_init
122 
123  subroutine sll_s_compute_splines_coefs_matrix_nat_1d(mat, dnat, lnat, N)
124  sll_int32, intent(in)::n
125  sll_real64, dimension(0:N + 2, 1:N + 1), intent(inout) :: mat
126  sll_real64, dimension(0:N + 2), intent(in)::dnat, lnat
127  sll_real64, dimension(:, :), allocatable :: matb
128  sll_int32 :: err, i, j
129 
130  ! Conditions aux bords nulles
131 
132  sll_allocate(matb(0:n + 2, 0:n + 2), err)
133 
134  matb = 0._f64
135 
136  do j = 0, n + 2
137  matb(j, j) = 6._f64
138  end do
139 
140  do i = 1, n + 1
141  do j = 0, n + 2
142  matb(i, j) = matb(i, j) - lnat(i - 1)*matb(i - 1, j)
143  end do
144  end do
145 
146  do j = 0, n + 2
147  matb(n + 2, j) = (matb(n + 2, j) - lnat(n + 1)*matb(n + 1, j) - lnat(n + 2)*matb(n, j))/dnat(n + 2)
148  end do
149 
150  do i = n + 1, 2, -1
151  do j = 0, n + 2
152  matb(i, j) = (matb(i, j) - matb(i + 1, j))/dnat(i)
153  end do
154  end do
155 
156  do j = 0, n + 2
157  matb(1, j) = (matb(1, j) - 2._f64*matb(2, j))/dnat(1)
158  end do
159 
160  do j = 0, n + 2
161  matb(0, j) = (matb(0, j) - 3._f64*matb(2, j))/dnat(0)
162  end do
163 
164  mat(0:n + 2, 1:n + 1) = matb(0:n + 2, 1:n + 1)
165 
167 
168  subroutine sll_s_compute_splines_coefs_matrix_per_1d(mat, dper, lper, mper, N)
169  sll_int32, intent(in)::n
170  sll_real64, dimension(0:N - 1, 0:N - 1), intent(inout) :: mat
171  sll_real64, dimension(0:N + 2), intent(in)::dper, lper, mper
172  sll_int32 :: i, j
173 
174  mat = 0._f64
175 
176  do j = 0, n - 1
177  mat(j, j) = 6._f64
178  end do
179 
180  do i = 1, n - 1
181  do j = 0, n - 1
182  mat(i, j) = mat(i, j) - lper(i - 1)*mat(i - 1, j)
183  end do
184  end do
185 
186  do i = 0, n - 2
187  do j = 0, n - 1
188  mat(n - 1, j) = mat(n - 1, j) - mper(i)*mat(i, j)
189  end do
190  end do
191 
192  do j = 0, n - 1
193  mat(n - 1, j) = mat(n - 1, j)*dper(n - 1)
194  end do
195 
196  do j = 0, n - 1
197  mat(n - 2, j) = dper(n - 2)*(mat(n - 2, j) - (1._f64 - mper(n - 3))*mat(n - 1, j))
198  end do
199 
200  do i = n - 3, 1, -1
201  do j = 0, n - 1
202  mat(i, j) = dper(i)*(mat(i, j) - mat(i + 1, j) + mper(i - 1)*mat(n - 1, j))
203  end do
204  end do
205 
206  do j = 0, n - 1
207  mat(0, j) = dper(0)*(mat(0, j) - mat(1, j) - mat(n - 1, j))
208  end do
209 
211 
212  subroutine kronecker_product(A, NxA, NyA, B, NxB, NyB, kronecker)
213  sll_int32, intent(in)::nxa, nya, nxb, nyb
214  sll_real64, dimension(0:NxA - 1, 0:NyA - 1), intent(in)::a
215  sll_real64, dimension(0:NxB - 1, 0:NyB - 1), intent(in)::b
216  sll_real64, dimension(0:NxA*NxB - 1, 0:NyA*NyB - 1), intent(inout) :: kronecker
217  sll_int32 :: ia, ib, ja, jb
218 
219  do ia = 0, nxa - 1
220  do ib = 0, nxb - 1
221  do ja = 0, nya - 1
222  do jb = 0, nyb - 1
223  kronecker(ib + nxb*ia, jb + nyb*ja) = a(ia, ja)*b(ib, jb)
224  end do
225  end do
226  end do
227  end do
228 
229  end subroutine kronecker_product
230 
231  subroutine matrix_product(A, NxA, NyA, B, NxB, NyB, prod)
232  sll_int32, intent(in)::nxa, nya, nxb, nyb
233  sll_real64, dimension(0:NxA - 1, 0:NyA - 1), intent(in)::a
234  sll_real64, dimension(0:NxB - 1, 0:NyB - 1), intent(in)::b
235  sll_real64, dimension(0:NxA - 1, 0:NyB - 1), intent(inout) :: prod
236  sll_int32 :: i, j, k
237  sll_real64 :: result
238 
239  if (nya /= nxb) then
240  print *, '#incompatible sizes in matrix_product'
241  stop
242  else
243  do i = 0, nxa - 1
244  do j = 0, nyb - 1
245  result = 0._f64
246  do k = 0, nya - 1
247  result = result + a(i, k)*b(k, j)
248  end do
249  prod(i, j) = result
250  end do
251  end do
252  end if
253 
254  end subroutine matrix_product
255 
256  subroutine sll_s_matrix_product_compf(A, NxA, NyA, B, NxB, NyB, prod)
257  sll_int32, intent(in)::nxa, nya, nxb, nyb
258  sll_comp64, dimension(:, :), intent(in)::a
259  sll_comp64, dimension(:, :), intent(in)::b
260  sll_comp64, dimension(:, :), intent(inout) :: prod
261  sll_int32 :: i, j, k
262  sll_comp64 :: result
263 
264  if (nya /= nxb) then
265  print *, '#incompatible sizes in matrix_product'
266  stop
267  else
268  do i = 1, nxa
269  do j = 1, nyb
270  result = (0.0_f64, 0.0_f64)
271  do k = 1, nya
272  result = result + a(i, k)*b(k, j)
273  end do
274  prod(i, j) = result
275  end do
276  end do
277  end if
278 
279  end subroutine sll_s_matrix_product_compf
280 
281  subroutine matrix_product_comp(A, NxA, NyA, B, NxB, NyB, prod)
282  sll_int32, intent(in)::nxa, nya, nxb, nyb
283  sll_comp64, dimension(0:NxA - 1, 0:NyA - 1), intent(in)::a
284  sll_comp64, dimension(0:NxB - 1, 0:NyB - 1), intent(in)::b
285  sll_comp64, dimension(0:NxA - 1, 0:NyB - 1), intent(inout) :: prod
286  sll_int32 :: i, j, k
287  sll_comp64 :: result
288 
289  if (nya /= nxb) then
290  print *, '#incompatible sizes in matrix_product'
291  stop
292  else
293  do i = 0, nxa - 1
294  do j = 0, nyb - 1
295  result = (0._f64, 0.0_f64)
296  do k = 0, nya - 1
297  result = result + a(i, k)*b(k, j)
298  end do
299  prod(i, j) = result
300  end do
301  end do
302  end if
303 
304  end subroutine matrix_product_comp
305 
306  subroutine matrix_product_circ(A, NxA, NyA, B, NxB, NyB, prod, Ntheta)
307  sll_int32, intent(in)::ntheta, nxa, nya, nxb, nyb
308  sll_real64, dimension(0:Ntheta - 1, 0:NxA - 1, 0:NyA - 1), intent(in)::a
309  sll_real64, dimension(0:Ntheta - 1, 0:NxB - 1, 0:NyB - 1), intent(in)::b
310  sll_real64, dimension(0:Ntheta - 1, 0:NxA - 1, 0:NyB - 1), intent(inout) :: prod
311  sll_real64, dimension(:, :), allocatable :: mat_stock, mat_stock_sum
312  sll_int32 :: i, j, error
313  !sll_real64 :: result
314 
315  sll_allocate(mat_stock(0:nxa - 1, 0:nyb - 1), error)
316  sll_allocate(mat_stock_sum(0:nxa - 1, 0:nyb - 1), error)
317 
318  if (nya /= nxb) then
319  print *, '#incompatible sizes in matrix_product_circ'
320  stop
321  else
322  do i = 0, ntheta - 1
323  mat_stock_sum = 0._f64
324  do j = 0, ntheta - 1
325  call matrix_product(a(modulo(i + j, ntheta), :, :), nxa, nya, b(j, :, :), nxb, nyb, mat_stock)
326  mat_stock_sum = mat_stock_sum + mat_stock
327  end do
328  prod(i, :, :) = mat_stock_sum
329  end do
330  end if
331 
332  end subroutine matrix_product_circ
333 
334  subroutine sll_s_precompute_gyroaverage_index(quasineutral, rho, N_rho)
335  type(sll_t_qn_2d_polar) :: quasineutral
336  sll_int32 :: n_rho
337  sll_real64, dimension(1:N_rho), intent(in) :: rho
338  sll_int32, dimension(:, :), allocatable :: buf
339  sll_int32 ::i, j, k, p, ell_1, ell_2, ii(2), s, nb, ind(2)
340  sll_real64::val(-1:2, -1:2), eta_star(2), eta(2), delta_eta(2), x(2)
341  sll_int32 ::error, max_nb
342 
343  delta_eta(1) = (quasineutral%eta_max(1) - quasineutral%eta_min(1))/real(quasineutral%Nc(1), f64)
344  delta_eta(2) = (quasineutral%eta_max(2) - quasineutral%eta_min(2))/real(quasineutral%Nc(2), f64)
345 
346  sll_allocate(buf(0:quasineutral%Nc(1) + 2, 0:quasineutral%Nc(2) - 1), error)
347  sll_allocate(quasineutral%pre_compute_N(1:n_rho, quasineutral%Nc(1) + 1), error)
348 
349  eta(2) = quasineutral%eta_min(2)
350 
351  max_nb = 0
352 
353  do p = 1, n_rho
354 
355  buf = 0
356  nb = 0
357  do i = 1, quasineutral%Nc(1) + 1
358  eta(1) = quasineutral%eta_min(1) + real(i - 1, f64)*delta_eta(1)
359  s = 0
360  do k = 1, quasineutral%N_points
361  x(1) = eta(1)*cos(eta(2)) + rho(p)*quasineutral%points(1, k)
362  x(2) = eta(1)*sin(eta(2)) + rho(p)*quasineutral%points(2, k)
363  call sll_s_localize_polar(x, quasineutral%eta_min, quasineutral%eta_max, ii, eta_star, quasineutral%Nc)
364  do ell_2 = -1, 2
365  ind(2) = modulo(ii(2) + ell_2, quasineutral%Nc(2))
366  do ell_1 = -1, 2
367  ind(1) = ii(1) + 1 + ell_1
368  if (buf(ind(1), ind(2)) .ne. i) then
369  s = s + 1
370  buf(ind(1), ind(2)) = i
371  end if
372  end do
373  end do
374  end do
375  quasineutral%pre_compute_N(p, i) = s
376  nb = nb + s
377  end do
378  max_nb = max(max_nb, nb)
379 
380  quasineutral%size_pre_compute = max_nb
381  ! print*,'#N_points pre_compute=',nb,quasineutral%Nc(1),nb/quasineutral%Nc(1)
382 
383  end do ! p=1,N_rho
384 
385  sll_allocate(quasineutral%pre_compute_index(1:n_rho, 1:2, 1:max_nb), error)
386  sll_allocate(quasineutral%pre_compute_coeff_spl(1:n_rho, 1:max_nb), error)
387 
388  do p = 1, n_rho
389 
390  buf = 0
391  nb = 0
392  s = 0
393  val = 0._f64
394  eta(2) = quasineutral%eta_min(2)
395  do i = 1, quasineutral%Nc(1) + 1
396  eta(1) = quasineutral%eta_min(1) + real(i - 1, f64)*delta_eta(1)
397  do k = 1, quasineutral%N_points
398  x(1) = eta(1)*cos(eta(2)) + rho(p)*quasineutral%points(1, k)
399  x(2) = eta(1)*sin(eta(2)) + rho(p)*quasineutral%points(2, k)
400  call sll_s_localize_polar(x, quasineutral%eta_min, quasineutral%eta_max, ii, eta_star, quasineutral%Nc)
401 
402  call sll_s_contribution_spl(eta_star, val)
403 
404  val = val*quasineutral%points(3, k)
405 
406  do ell_2 = -1, 2
407  ind(2) = modulo(ii(2) + ell_2, quasineutral%Nc(2))
408  do ell_1 = -1, 2
409  ind(1) = ii(1) + 1 + ell_1
410  j = buf(ind(1), ind(2))
411  if (j <= nb) then
412  s = s + 1
413  buf(ind(1), ind(2)) = s
414  quasineutral%pre_compute_coeff_spl(p, s) = val(ell_1, ell_2)
415  quasineutral%pre_compute_index(p, 1, s) = ind(1)
416  quasineutral%pre_compute_index(p, 2, s) = ind(2)
417  else
418  quasineutral%pre_compute_coeff_spl(p, j) = quasineutral%pre_compute_coeff_spl(p, j) + val(ell_1, ell_2)
419  end if
420  end do
421  end do
422  end do
423  nb = s
424  end do
425 
426  end do ! p=1,N_rho
427 
428  ! print *,'#min/max=',minval(quasineutral%pre_compute_coeff_spl(:)),maxval(quasineutral%pre_compute_coeff_spl(:))
429 
430  sll_deallocate_array(buf, error)
431 
433 
434  subroutine sll_s_precompute_inverse_qn_matrix_polar_splines(quasineutral, mu_points, mu_weights, N_mu)
435  type(sll_t_qn_2d_polar) :: quasineutral
436  sll_int32, intent(in) :: n_mu
437  sll_real64, dimension(1:N_mu), intent(in) :: mu_points
438  sll_real64, dimension(1:N_mu), intent(in) :: mu_weights
439  sll_comp64, dimension(:, :), allocatable :: mat_stock1, mat_stock2
440  sll_real64, dimension(:), allocatable, target::dnat, lnat, dper, lper, mper
441  sll_real64, dimension(:), pointer::pointer_dnat, pointer_lnat
442  sll_real64, dimension(:), pointer::pointer_dper, pointer_lper, pointer_mper
443  sll_real64, dimension(:, :), allocatable, target::mat_nat, mat_per
444  sll_real64, dimension(:, :), pointer::pointer_mat_nat, pointer_mat_per
445  sll_real64, dimension(:, :, :), allocatable, target::mat_spl2d_circ
446  sll_real64, dimension(:, :, :), pointer::pointer_mat_spl2d_circ
447  sll_real64, dimension(:, :, :, :), allocatable, target::mat_contribution_circ
448  sll_real64, dimension(:, :, :, :), pointer::pointer_mat_contribution_circ
449  sll_comp64, dimension(:, :, :), allocatable::d_spl2d
450  sll_comp64, dimension(:, :, :, :), allocatable::d_contr
451  sll_int32, dimension(:), allocatable :: ipiv
452  sll_comp64, dimension(:), allocatable :: work
453  sll_real64 :: mode
454  sll_comp64 :: exp_comp
455  sll_int32 :: info
456  sll_int32 :: nr, ntheta
457  sll_int32 :: error
458  sll_int32 :: i, j, k, m, p, s
459  sll_int32 :: ii(2)
460 
461  ! Taille du maillage
462  nr = quasineutral%Nc(1)
463  ntheta = quasineutral%Nc(2)
464 
465  ! Allocate
466  sll_allocate(mat_stock1(0:nr, 0:nr), error)
467  sll_allocate(mat_stock2(0:nr, 0:nr), error)
468  sll_allocate(quasineutral%mat_qn_inverse(0:ntheta - 1, 0:nr, 0:nr), error)
469  sll_allocate(dnat(0:nr + 2), error)
470  sll_allocate(lnat(0:nr + 2), error)
471  sll_allocate(dper(0:ntheta - 1), error)
472  sll_allocate(lper(0:ntheta - 1), error)
473  sll_allocate(mper(0:ntheta - 1), error)
474  sll_allocate(mat_nat(0:nr + 2, 0:nr), error)
475  sll_allocate(mat_per(0:ntheta - 1, 0:ntheta - 1), error)
476  sll_allocate(mat_spl2d_circ(0:ntheta - 1, 0:nr + 2, 0:nr), error)
477  sll_allocate(d_spl2d(0:ntheta - 1, 0:nr + 2, 0:nr), error)
478  sll_allocate(mat_contribution_circ(0:n_mu, 0:ntheta - 1, 0:nr, 0:nr + 2), error)
479  sll_allocate(d_contr(0:n_mu, 0:ntheta - 1, 0:nr, 0:nr + 2), error)
480  sll_allocate(ipiv(nr + 1), error)
481  sll_allocate(work((nr + 1)**2), error)
482 
483  sll_allocate(quasineutral%mat_double_gyro_circ(1:n_mu, 0:ntheta - 1, 0:nr, 0:nr), error)
484  sll_allocate(quasineutral%mat_gyro_circ(1:n_mu, 0:ntheta - 1, 0:nr, 0:nr), error)
485 
486  ! Initialise les coefficients de splines
487  call sll_s_splcoefnat1d0old(dnat, lnat, nr)
488  call sll_s_splcoefper1d0old(dper, lper, mper, ntheta)
489 
490  ! Pointeurs
491  pointer_dnat => dnat
492  pointer_lnat => lnat
493  pointer_dper => dper
494  pointer_lper => lper
495  pointer_mper => mper
496  pointer_mat_nat => mat_nat
497  pointer_mat_per => mat_per
498  pointer_mat_spl2d_circ => mat_spl2d_circ
499  pointer_mat_contribution_circ => mat_contribution_circ
500 
501  ! Construction de la matrice des coefficients de splines
502  call sll_s_compute_splines_coefs_matrix_nat_1d(pointer_mat_nat, pointer_dnat, pointer_lnat, nr)
503  call sll_s_compute_splines_coefs_matrix_per_1d(pointer_mat_per, pointer_dper, pointer_lper, pointer_mper, ntheta)
504  do j = 0, ntheta - 1
505  pointer_mat_spl2d_circ(j, :, :) = pointer_mat_per(0, j)*pointer_mat_nat
506  end do
507 
508  ! Construction de la matrice de contribution
509  pointer_mat_contribution_circ = 0._f64
510  do p = 1, n_mu
511  s = 0
512  do i = 1, nr + 1
513  do k = 1, quasineutral%pre_compute_N(p, i)
514  s = s + 1
515  ii(1) = quasineutral%pre_compute_index(p, 1, s)
516  ii(2) = modulo(quasineutral%pre_compute_index(p, 2, s), ntheta)
517  pointer_mat_contribution_circ(p,ii(2),i-1,ii(1))=pointer_mat_contribution_circ(p,ii(2),i-1,ii(1))+quasineutral%pre_compute_coeff_spl(p,s)
518  end do
519  end do
520  end do
521 
522  ! Matrices D^{spl} et D^{contr}
523  d_spl2d = (0.0_f64, 0.0_f64)
524  d_contr = (0.0_f64, 0.0_f64)
525  do m = 0, ntheta - 1
526  do j = 0, ntheta - 1
527  mode = real(-2._f64*sll_p_pi*real(j, f64)*real(m, f64)/real(ntheta, f64), f64)
528  exp_comp = cmplx(cos(mode), sin(mode), kind=f64)
529  d_spl2d(m, :, :) = d_spl2d(m, :, :) + pointer_mat_spl2d_circ(j, :, :)*exp_comp
530  do p = 1, n_mu
531  d_contr(p, m, :, :) = d_contr(p, m, :, :) + pointer_mat_contribution_circ(p, j, :, :)*exp_comp
532  end do
533  end do
534  end do
535 
536  ! Construction de la matrice à inverser
537  quasineutral%mat_qn_inverse = (0._f64, 0._f64)
538  do m = 0, ntheta - 1
539  do p = 1, n_mu
540  mat_stock1 = (0._f64, 0._f64)
541  mat_stock2 = (0._f64, 0._f64)
542  call matrix_product_comp(d_contr(p, m, :, :), nr + 1, nr + 3, d_spl2d(m, :, :), nr + 3, nr + 1, mat_stock1)
543  call matrix_product_comp(mat_stock1(:, :), nr + 1, nr + 1, mat_stock1(:, :), nr + 1, nr + 1, mat_stock2)
544 
545  !call matrix_product_comp(transpose(mat_stock1(:,:)),Nr+1,Nr+1,mat_stock1(:,:),Nr+1,Nr+1,mat_stock2)
546 
547  do i = 0, nr
548  mat_stock2(i, i) = mat_stock2(i, i) - quasineutral%lambda(i + 1)*(1._f64, 0._f64)
549  end do
550  do i = 0, nr
551  quasineutral%mat_qn_inverse(m, i, :) = &
552  quasineutral%mat_qn_inverse(m, i, :) &
553  - mu_weights(p)*mat_stock2(i, :)* &
554  cmplx(exp(-mu_points(p)/quasineutral%T_i(i + 1)), 0._f64, f64)
555  end do
556  end do
557  end do
558  ! Inversion des blocs
559  do m = 0, ntheta - 1
560  call zgetrf(nr + 1, nr + 1, quasineutral%mat_qn_inverse(m, :, :), nr + 1, ipiv, info)
561  call zgetri(nr + 1, quasineutral%mat_qn_inverse(m, :, :), nr + 1, ipiv, work, (nr + 1)**2, info)
562  end do
563 
564  ! Deallocate
565  sll_deallocate_array(mat_stock1, error)
566  sll_deallocate_array(mat_stock2, error)
567  sll_deallocate_array(dnat, error)
568  sll_deallocate_array(lnat, error)
569  sll_deallocate_array(dper, error)
570  sll_deallocate_array(lper, error)
571  sll_deallocate_array(mper, error)
572  sll_deallocate_array(mat_nat, error)
573  sll_deallocate_array(mat_per, error)
574  sll_deallocate_array(mat_spl2d_circ, error)
575  sll_deallocate_array(d_spl2d, error)
576  sll_deallocate_array(mat_contribution_circ, error)
577  sll_deallocate_array(d_contr, error)
578  sll_deallocate_array(ipiv, error)
579  sll_deallocate_array(work, error)
580 
582 
583  subroutine sll_s_qn_2d_polar_solve(quasineutral, phi)
584  type(sll_t_qn_2d_polar) :: quasineutral
585  sll_real64, dimension(1:quasineutral%Nc(1) + 1, 1:quasineutral%Nc(2)), intent(inout) :: phi
586  sll_comp64, dimension(:, :), allocatable :: phi_comp, phi_old
587  sll_real64, dimension(:), allocatable::buf_fft
588  !type(sll_t_fft) :: fw, bw
589  sll_comp64 :: result
590  sll_int32 :: nr, ntheta
591  sll_int32 :: error
592  sll_int32 :: i, j, m
593 
594  ! Taille du maillage
595  nr = quasineutral%Nc(1)
596  ntheta = quasineutral%Nc(2)
597 
598  ! Allocate
599  sll_allocate(phi_comp(1:nr + 1, 1:ntheta), error)
600  sll_allocate(phi_old(1:nr + 1, 1:ntheta), error)
601  sll_clear_allocate(buf_fft(1:4*ntheta + 15), error)
602 
603  ! FFT(PHI)
604  phi_comp = phi*(1._f64, 0._f64)
605  call zffti(ntheta, buf_fft)
606  !call sll_s_fft_init_c2r_1d(fw, 2*ntheta-2,phi_comp(1,:),buf_fft)
607  !call sll_s_fft_init_r2c_1d(bw, 2*ntheta-2,buf_fft,phi_comp(1,:))
608  do i = 1, nr + 1
609  call zfftf(ntheta, phi_comp(i, :), buf_fft)
610  !call sll_s_fft_exec_c2r_1d(fw, phi_comp(i,:),buf_fft)
611  end do
612 
613  ! Produit matrice/vecteur
614  phi_old = phi_comp
615  do m = 1, ntheta
616  do i = 1, nr + 1
617  result = (0._f64, 0.0_f64)
618  do j = 1, nr + 1
619  result = result + quasineutral%mat_qn_inverse(m - 1, i - 1, j - 1)*phi_old(j, m)
620  end do
621  phi_comp(i, m) = result
622  end do
623  end do
624 
625  ! FFT^-1
626  do i = 1, nr + 1
627  call zfftb(ntheta, phi_comp(i, :), buf_fft)
628  !call sll_s_fft_exec_r2c_1d(bw, buf_fft, phi_comp(i,:))
629  end do
630  phi = real(phi_comp, f64)/real(ntheta, f64)
631 
632  ! Sorties
633  ! print *,"phi_min : ",minval(phi)
634  ! print *,"phi_max : ",maxval(phi)
635 
636  !call sll_s_fft_free(fw)
637  !call sll_s_fft_free(bw)
638  ! Deallocate
639  sll_deallocate_array(phi_comp, error)
640  sll_deallocate_array(phi_old, error)
641  sll_deallocate_array(buf_fft, error)
642 
643  end subroutine sll_s_qn_2d_polar_solve
644 
645  subroutine sll_s_qn_2d_polar_test_solve(Nc, eta_min, eta_max, mu_points, mu_weights, N_mu, mode, lambda, T_i, phi_init, phi_qn)
646  sll_int32, intent(in) :: nc(2)
647  sll_real64, intent(in) :: eta_min(2)
648  sll_real64, intent(in) :: eta_max(2)
649  sll_int32, intent(in) :: n_mu
650  sll_int32, intent(in) :: mode(2)
651  sll_real64, dimension(1:N_mu), intent(in) :: mu_points
652  sll_real64, dimension(1:N_mu), intent(in) :: mu_weights
653  sll_real64, dimension(1:Nc(1) + 1, 1:Nc(2) + 1), intent(in) :: phi_init
654  sll_real64, dimension(1:Nc(1) + 1, 1:Nc(2) + 1), intent(in) :: phi_qn
655  sll_real64, dimension(1:Nc(1) + 1), intent(in) :: lambda, t_i
656  sll_int32 :: n_min(2), n_max(2)
657  sll_real64, dimension(:), allocatable :: gamma0
658  sll_real64 :: tmp1
659  sll_real64 :: eps, rho2d(2), mu2dmax(2), error(3)
660  sll_int32 :: i, ierr, p
661 
662  sll_allocate(gamma0(1:nc(1) + 1), ierr)
663 
664  n_min = 1
665  n_max(1) = nc(1)
666  n_max(2) = nc(2)
667 
668  mu2dmax(1) = maxval(mu_points)
669  mu2dmax(2) = maxval(mu_points)
670 
671  eps = 1.d-10
672  gamma0 = 0._f64
673 
674  call compute_n_bounds_polar_circle(n_min(1), n_max(1), nc(1), 2._f64*sqrt(2._f64*mu2dmax), eta_min(1), eta_max(1))
675 
676  do p = 1, n_mu
677  rho2d(1) = sqrt(2._f64*mu_points(p))
678  rho2d(2) = sqrt(2._f64*mu_points(p))
679  call solution_polar_circle(rho2d, mode, eta_min, eta_max, tmp1)
680  do i = 1, nc(1) + 1
681  gamma0(i) = gamma0(i) + mu_weights(p)*exp(-mu_points(p)/t_i(i))*(lambda(i) - tmp1**2)
682  end do
683  end do
684  do i = 1, nc(1) + 1
685  gamma0(i) = 1._f64/gamma0(i)
686  end do
687 
688  ! print *,'#gamma0val=',gamma0
689 
690  print *, '#N_min(1:2) / N_max(1:2) = ', n_min, ' / ', n_max
691  call compute_error_1d(phi_qn, phi_init, gamma0, error, n_min, n_max)
692  print *, '#error subdomain=', error
693  call compute_error_1d(phi_qn, phi_init, gamma0, error, (/1, 1/), nc)
694  print *, '#error whole domain=', error
695 
696  call sll_o_gnuplot_2d( &
697  eta_min(1), &
698  eta_max(1), &
699  nc(1) + 1, &
700  eta_min(2), &
701  eta_max(2), &
702  nc(2) + 1, &
703  phi_qn, &
704  'fdiff', &
705  1, &
706  ierr)
707 
708  end subroutine sll_s_qn_2d_polar_test_solve
709 
711  Nc, &
712  eta_min, &
713  eta_max, &
714  mu_points, &
715  mu_weights, &
716  N_mu, &
717  mode) &
718  result(gamma0)
719  sll_int32, intent(in) :: nc(2)
720  sll_real64, intent(in) :: eta_min(2)
721  sll_real64, intent(in) :: eta_max(2)
722  sll_int32, intent(in) :: n_mu
723  sll_int32, intent(in) :: mode(2)
724  sll_real64, dimension(1:N_mu), intent(in) :: mu_points
725  sll_real64, dimension(1:N_mu), intent(in) :: mu_weights
726  sll_real64 :: gamma0
727  sll_real64 :: tmp1
728  sll_real64 :: rho2d(2)
729  sll_int32 :: p
730 
731  gamma0 = 0._f64
732  do p = 1, n_mu
733  rho2d(1) = sqrt(2._f64*mu_points(p))
734  rho2d(2) = sqrt(2._f64*mu_points(p))
735  call solution_polar_circle(rho2d, mode, eta_min, eta_max, tmp1)
736  !gamma0 = gamma0 + mu_weights(p)*exp(-mu_points(p))*(1._f64-tmp1**2)
737  gamma0 = gamma0 + mu_weights(p)*(1._f64 - tmp1**2)
738  !gamma0 = gamma0 + mu_weights(p)*(tmp1**2)
739  end do
740 
741  !gamma0 = 1._f64-gamma0
742 
743  return
744  print *, nc
745 
747 
748  subroutine solve_circulant_system(Ntheta, Nr, mat_circ, sol)
749  ! Solve mat_circ*X=sol where mat_circ(0:Ntheta-1,0:Nr,0:Nr)
750  ! is a circulent matrix of size Ntheta*(Nr+1) Ntheta*(Nr+1)
751  ! and sol(1:Nr+1,1:Ntheta)
752  sll_int32 :: ntheta
753  sll_int32 :: nr
754  sll_int32 :: i
755  sll_int32 :: j
756  sll_int32 :: m
757  sll_int32 :: error
758  sll_comp64, dimension(:, :, :), allocatable :: dm
759  sll_comp64, dimension(:, :), allocatable :: sol_comp
760  sll_comp64, dimension(:, :), allocatable :: sol_old
761  sll_real64, dimension(:), allocatable :: buf_fft
762  sll_real64 :: mode
763  sll_comp64 :: exp_comp, result
764  sll_int32, dimension(:), allocatable :: ipiv
765  sll_comp64, dimension(:), allocatable :: work
766  sll_int32 :: info
767  sll_real64, dimension(0:Ntheta - 1, 0:Nr, 0:Nr), intent(in) :: mat_circ
768  sll_real64, dimension(1:Nr + 1, 1:Ntheta), intent(inout) :: sol
769  !type(sll_t_fft) :: fw, bw
770 
771  sll_allocate(dm(0:ntheta - 1, 0:nr, 0:nr), error)
772  sll_allocate(sol_comp(1:nr + 1, 1:ntheta), error)
773  sll_allocate(sol_old(1:nr + 1, 1:ntheta), error)
774  sll_allocate(buf_fft(1:4*ntheta + 15), error)
775  sll_allocate(ipiv(nr + 1), error)
776  sll_allocate(work((nr + 1)**2), error)
777 
778  sol_comp = sol*(1._f64, 0._f64)
779 
780  ! FFT(PHI)
781  call zffti(ntheta, buf_fft)
782  !call sll_s_fft_init_c2r_1d(fw,2*ntheta-2,sol_comp(1,:),buf_fft)
783  !call sll_s_fft_init_r2c_1d(bw,2*ntheta-2,buf_fft,sol_comp(1,:))
784  do i = 1, nr + 1
785  call zfftf(ntheta, sol_comp(i, :), buf_fft)
786  !call sll_s_fft_exec_c2r_1d(fw,sol_comp(i,:),buf_fft)
787  end do
788 
789  ! Matrices Dm
790  dm = (0._f64, 0.0_f64)
791  do m = 0, ntheta - 1
792  do j = 0, ntheta - 1
793  mode = real(-2._f64*sll_p_pi*real(j, f64)*real(m, f64)/real(ntheta, f64), f64)
794  exp_comp = cmplx(cos(mode), sin(mode), kind=f64)
795  dm(m, :, :) = dm(m, :, :) + mat_circ(j, :, :)*exp_comp
796  end do
797 
798  call zgetrf(nr + 1, nr + 1, dm(m, :, :), nr + 1, ipiv, info)
799  call zgetri(nr + 1, dm(m, :, :), nr + 1, ipiv, work, (nr + 1)**2, info)
800 
801  end do
802 
803  ! Produit Dm
804  sol_old = sol_comp
805  do m = 1, ntheta
806  do i = 1, nr + 1
807  result = (0._f64, 0.0_f64)
808  do j = 1, nr + 1
809  result = result + dm(m - 1, i - 1, j - 1)*sol_old(j, m)
810  end do
811  sol_comp(i, m) = result
812  end do
813  end do
814 
815  ! FFT^-1
816  do i = 1, nr + 1
817  call zfftb(ntheta, sol_comp(i, :), buf_fft)
818  !call sll_s_fft_exec_r2c_1d(bw,buf_fft,sol_comp(i,:))
819  end do
820 
821  sol = real(sol_comp/cmplx(ntheta, 0._f64, f64), f64)
822 
823  !call sll_s_fft_free(fw)
824  !call sll_s_fft_free(bw)
825 
826  end subroutine solve_circulant_system
827 
828  subroutine test_solve_circulant_system(mat, Nr, Ntheta)
829  sll_int32, intent(in) :: nr, ntheta
830  sll_real64, dimension(0:Ntheta - 1, 0:Nr, 0:Nr), intent(in) :: mat
831  sll_real64, dimension(:, :, :), allocatable :: inv, test_id
832  sll_real64, dimension(:, :), allocatable :: phi
833  sll_int32 :: i, j, m, error
834 
835  sll_allocate(inv(0:ntheta - 1, 0:nr, 0:nr), error)
836  sll_allocate(test_id(0:ntheta - 1, 0:nr, 0:nr), error)
837  sll_allocate(phi(1:nr + 1, 1:ntheta), error)
838 
839  do m = 1, nr + 1
840  phi = 0._f64
841  phi(m, 1) = 1._f64
842 
843  call solve_circulant_system(ntheta, nr, mat, phi)
844 
845  do i = 0, nr
846  do j = 0, ntheta - 1
847  inv(modulo(ntheta - j, ntheta), i, m - 1) = phi(i + 1, j + 1)
848  end do
849  end do
850  end do
851 
852  call matrix_product_circ(mat, nr + 1, nr + 1, inv, nr + 1, nr + 1, test_id, ntheta)
853 
854  do i = 0, nr
855  test_id(0, i, i) = test_id(0, i, i) - 1._f64
856  end do
857 
858  print *, "Inversion error = ", maxval(test_id)
859 
860  end subroutine test_solve_circulant_system
861 
862  !----------------------------------------
863 
864  subroutine hermite_coef_nat_per(f, buf3d, N, d)
865  sll_int32, intent(in)::n(2), d(2)
866  sll_real64, dimension(N(1) + 1, N(2)), intent(in)::f
867  sll_real64, dimension(9, N(1) + 1, N(2) + 1), intent(out)::buf3d
868  sll_real64 ::w_left_1(-d(1)/2:(d(1) + 1)/2), w_right_1((-d(1) + 1)/2:d(1)/2 + 1)
869  sll_real64 ::w_left_2(-d(2)/2:(d(2) + 1)/2), w_right_2((-d(2) + 1)/2:d(2)/2 + 1)
870  sll_real64 ::tmp
871  sll_int32 ::i, j, ii, r_left(2), r_right(2), s_left(2), s_right(2), ind
872  r_left = -d/2
873  s_left = (d + 1)/2
874  r_right = (-d + 1)/2
875  s_right = d/2 + 1
876 
877  call compute_w_hermite(w_left_1, r_left(1), s_left(1))
878  call compute_w_hermite(w_left_2, r_left(2), s_left(2))
879  if ((2*(d(1)/2) - d(1)) == 0) then
880  w_right_1(r_right(1):s_right(1)) = w_left_1(r_left(1):s_left(1))
881  else
882  w_right_1(r_right(1):s_right(1)) = -w_left_1(s_left(1):r_left(1):-1)
883  end if
884 
885  if ((2*(d(2)/2) - d(2)) == 0) then
886  w_right_2(r_right(2):s_right(2)) = w_left_2(r_left(2):s_left(2))
887  else
888  w_right_2(r_right(2):s_right(2)) = -w_left_2(s_left(2):r_left(2):-1)
889  end if
890 
891  !print *,'w(',r_left(1),':',s_left(1),')=',w_left_1(r_left(1):s_left(1))
892  !print *,'w(',r_right(1),':',s_right(1),')=',w_right_1(r_right(1):s_right(1))
893 
894  do j = 1, n(2)
895  do i = 1, n(1) + 1
896  buf3d(1, i, j) = f(i, j) !f(0,0)
897  tmp = 0._f64
898  do ii = r_left(1), s_left(1)
899  ind = i + ii; if (ind > n(1) + 1) ind = 2*(n(1) + 1) - ind; if (ind < 1) ind = 2 - ind
900  tmp = tmp + w_left_1(ii)*f(ind, j)
901  end do
902  buf3d(2, i, j) = tmp !fx(0,0)
903  tmp = 0._f64
904  do ii = r_right(1), s_right(1)
905  ind = i + ii; if (ind > n(1) + 1) ind = 2*(n(1) + 1) - ind; if (ind < 1) ind = 2 - ind
906  tmp = tmp + w_right_1(ii)*f(ind, j)
907  end do
908  buf3d(3, i, j) = tmp !fx(1,0)
909  end do
910  end do
911  do i = 1, n(1) + 1
912  do j = 1, n(2)
913  tmp = 0._f64
914  do ii = r_left(2), s_left(2)
915  ind = modulo(j + ii - 1 + n(2), n(2)) + 1
916  tmp = tmp + w_left_2(ii)*f(i, ind)
917  end do
918  buf3d(4, i, j) = tmp !fy(0,0)
919  tmp = 0._f64
920  do ii = r_right(2), s_right(2)
921  ind = modulo(j + ii - 1 + n(2), n(2)) + 1
922  tmp = tmp + w_right_2(ii)*f(i, ind)
923  end do
924  buf3d(5, i, j) = tmp !fy(0,1)
925  end do
926  end do
927 
928  do j = 1, n(2)
929  do i = 1, n(1) + 1
930  tmp = 0._f64
931  do ii = r_left(1), s_left(1)
932  ind = i + ii; if (ind > n(1) + 1) ind = 2*(n(1) + 1) - ind; if (ind < 1) ind = 2 - ind
933  tmp = tmp + w_left_1(ii)*buf3d(4, ind, j)
934  end do
935  buf3d(6, i, j) = tmp !fxy(0,0)
936  tmp = 0._f64
937  do ii = r_right(1), s_right(1)
938  ind = i + ii; if (ind > n(1) + 1) ind = 2*(n(1) + 1) - ind; if (ind < 1) ind = 2 - ind
939  tmp = tmp + w_right_1(ii)*buf3d(4, ind, j)
940  end do
941  buf3d(7, i, j) = tmp !fxy(1,0)
942  tmp = 0._f64
943  do ii = r_left(1), s_left(1)
944  ind = i + ii; if (ind > n(1) + 1) ind = 2*(n(1) + 1) - ind; if (ind < 1) ind = 2 - ind
945  tmp = tmp + w_left_1(ii)*buf3d(5, ind, j)
946  end do
947  buf3d(8, i, j) = tmp !fxy(0,1)
948  tmp = 0._f64
949  do ii = r_right(1), s_right(1)
950  ind = i + ii; if (ind > n(1) + 1) ind = 2*(n(1) + 1) - ind; if (ind < 1) ind = 2 - ind
951  tmp = tmp + w_right_1(ii)*buf3d(5, ind, j)
952  end do
953  buf3d(9, i, j) = tmp !fxy(1,1)
954  end do
955  end do
956 
957  buf3d(:, :, n(2) + 1) = buf3d(:, :, 1)
958 
959  end subroutine hermite_coef_nat_per
960 
961  subroutine hermite_c1_coef_nat_per(f, buf3d, N, d)
962  integer, intent(in)::N(2), d(2)
963  sll_real64, dimension(N(1) + 1, N(2)), intent(in)::f
964  sll_real64, dimension(4, N(1) + 1, N(2) + 1), intent(out)::buf3d
965  sll_real64, dimension(:), allocatable ::w_left_1, w_left_2
966  sll_real64 ::tmp
967  sll_int32::i, j, ii, r_left(2), s_left(2), ind, dd(2)
968  sll_int32::error
969  dd(1) = 2*((d(1) + 1)/2)
970  dd(2) = 2*((d(2) + 1)/2)
971 
972  r_left = -dd/2
973  s_left = (dd + 1)/2
974 
975  sll_allocate(w_left_1(-dd(1)/2:dd(1)/2), error)
976  sll_allocate(w_left_2(-dd(2)/2:dd(2)/2), error)
977 
978  call compute_w_hermite(w_left_1, r_left(1), s_left(1))
979  call compute_w_hermite(w_left_2, r_left(2), s_left(2))
980 
981  !print *,'w(',r_left(1),':',s_left(1),')=',w_left_1(r_left(1):s_left(1))
982  !print *,'w(',r_right(1),':',s_right(1),')=',w_right_1(r_right(1):s_right(1))
983 
984  do j = 1, n(2)
985  do i = 1, n(1) + 1
986  buf3d(1, i, j) = f(i, j) !f(0,0)
987  tmp = 0._f64
988  do ii = r_left(1), s_left(1)
989  ind = i + ii; if (ind > n(1) + 1) ind = 2*(n(1) + 1) - ind; if (ind < 1) ind = 2 - ind
990  tmp = tmp + w_left_1(ii)*f(ind, j)
991  end do
992  buf3d(2, i, j) = tmp !fx(0,0)
993  end do
994  end do
995  do i = 1, n(1) + 1
996  do j = 1, n(2)
997  tmp = 0._f64
998  do ii = r_left(2), s_left(2)
999  ind = modulo(j + ii - 1 + n(2), n(2)) + 1
1000  tmp = tmp + w_left_2(ii)*f(i, ind)
1001  end do
1002  buf3d(3, i, j) = tmp !fy(0,0)
1003  end do
1004  end do
1005 
1006  do j = 1, n(2)
1007  do i = 1, n(1) + 1
1008  tmp = 0._f64
1009  do ii = r_left(1), s_left(1)
1010  ind = i + ii; if (ind > n(1) + 1) ind = 2*(n(1) + 1) - ind; if (ind < 1) ind = 2 - ind
1011  tmp = tmp + w_left_1(ii)*buf3d(3, ind, j)
1012  end do
1013  buf3d(4, i, j) = tmp !fxy(0,0)
1014  end do
1015  end do
1016 
1017  buf3d(:, :, n(2) + 1) = buf3d(:, :, 1)
1018 
1019  sll_deallocate_array(w_left_1, error)
1020  sll_deallocate_array(w_left_2, error)
1021 
1022  end subroutine hermite_c1_coef_nat_per
1023 
1024  subroutine compute_w_hermite(w, r, s)
1025  sll_int32, intent(in)::r, s
1026  sll_real64, dimension(r:s), intent(out)::w
1027  sll_int32 ::i, j
1028  sll_real64::tmp
1029 
1030  !maple code for generation of w
1031  !for k from r to -1 do
1032  ! C[k]:=product((k-j),j=r..k-1)*product((k-j),j=k+1..s):
1033  ! C[k]:=1/C[k]*product((-j),j=r..k-1)*product((-j),j=k+1..-1)*product((-j),j=1..s):
1034  !od:
1035  !for k from 1 to s do
1036  ! C[k]:=product((k-j),j=r..k-1)*product((k-j),j=k+1..s):
1037  ! C[k]:=1/C[k]*product((-j),j=r..-1)*product((-j),j=1..k-1)*product((-j),j=k+1..s):
1038  !od:
1039  !C[0]:=-add(C[k],k=r..-1)-add(C[k],k=1..s):
1040 
1041  do i = r, -1
1042  tmp = 1._f64
1043  do j = r, i - 1
1044  tmp = tmp*real(i - j, f64)
1045  end do
1046  do j = i + 1, s
1047  tmp = tmp*real(i - j, f64)
1048  end do
1049  tmp = 1._f64/tmp
1050  do j = r, i - 1
1051  tmp = tmp*real(-j, f64)
1052  end do
1053  do j = i + 1, -1
1054  tmp = tmp*real(-j, f64)
1055  end do
1056  do j = 1, s
1057  tmp = tmp*real(-j, f64)
1058  end do
1059  w(i) = tmp
1060  end do
1061 
1062  do i = 1, s
1063  tmp = 1._f64
1064  do j = r, i - 1
1065  tmp = tmp*real(i - j, f64)
1066  end do
1067  do j = i + 1, s
1068  tmp = tmp*real(i - j, f64)
1069  end do
1070  tmp = 1._f64/tmp
1071  do j = r, -1
1072  tmp = tmp*real(-j, f64)
1073  end do
1074  do j = 1, i - 1
1075  tmp = tmp*real(-j, f64)
1076  end do
1077  do j = i + 1, s
1078  tmp = tmp*real(-j, f64)
1079  end do
1080  w(i) = tmp
1081  end do
1082  tmp = 0._f64
1083  do i = r, -1
1084  tmp = tmp + w(i)
1085  end do
1086  do i = 1, s
1087  tmp = tmp + w(i)
1088  end do
1089  w(0) = -tmp
1090 
1091  !print *,'w',w
1092  !do ii=r,s
1093  ! print *,ii,w(r+s-ii)
1094  !enddo
1095  !
1096 
1097  end subroutine compute_w_hermite
1098 
1099  subroutine sll_s_localize_polar(x, eta_min, eta_max, ii, eta, N)
1100  sll_real64, intent(in)::x(2), eta_min(2), eta_max(2)
1101  sll_int32, intent(out)::ii(2)
1102  sll_int32, intent(in)::n(2)
1103  sll_real64, intent(out)::eta(2)
1104 
1105  eta(1) = sqrt(x(1)**2 + x(2)**2)
1106  call localize_nat(ii(1), eta(1), eta_min(1), eta_max(1), n(1))
1107  eta(2) = atan2(x(2), x(1))
1108  call localize_per(ii(2), eta(2), eta_min(2), eta_max(2), n(2))
1109  end subroutine sll_s_localize_polar
1110 
1111  subroutine localize_per(i, x, xmin, xmax, N)
1112  sll_int32, intent(out)::i
1113  sll_real64, intent(inout)::x
1114  sll_real64, intent(in)::xmin, xmax
1115  sll_int32, intent(in)::n
1116  x = (x - xmin)/(xmax - xmin)
1117  x = x - real(floor(x), f64)
1118  x = x*real(n, f64)
1119  i = floor(x)
1120  x = x - real(i, f64)
1121  if (i == n) then
1122  i = 0
1123  x = 0._f64
1124  end if
1125  end subroutine localize_per
1126 
1127  subroutine localize_nat(i, x, xmin, xmax, N)
1128  sll_int32, intent(out)::i
1129  sll_real64, intent(inout)::x
1130  sll_real64, intent(in)::xmin, xmax
1131  sll_int32, intent(in)::n
1132  x = (x - xmin)/(xmax - xmin)
1133  x = x*real(n, f64)
1134  if (x >= real(n, f64)) then
1135  x = real(n, f64)
1136  end if
1137  if (x <= 0._f64) then
1138  x = 0._f64
1139  end if
1140  i = floor(x)
1141  x = x - real(i, f64)
1142  if (i == n) then
1143  i = n - 1
1144  x = 1._f64
1145  end if
1146  end subroutine localize_nat
1147 
1148  subroutine interpolate_hermite(f, i, x, fval, N)
1149  sll_int32, intent(in)::i(2), n(2)
1150  !real(f64),intent(in)::xx(2),xmin(2),xmax(2)
1151  sll_real64, intent(in)::x(2)
1152  sll_real64, intent(out)::fval
1153  sll_real64, dimension(0:8, 0:N(1), 0:N(2))::f
1154  !integer::i(2),i1(2),s
1155  sll_int32::i1(2), s
1156  sll_real64::w(2, 0:3), tmp(0:3)
1157  sll_real64::g(0:3, 0:3)
1158 
1159  !fval =f(0,i(1),i(2))!real(i(1),f64)
1160 
1161  !return
1162 
1163  do s = 1, 2
1164  w(s, 0) = (2._f64*x(s) + 1)*(1._f64 - x(s))*(1._f64 - x(s));
1165  w(s, 1) = x(s)*x(s)*(3._f64 - 2._f64*x(s))
1166  w(s, 2) = x(s)*(1._f64 - x(s))*(1._f64 - x(s))
1167  w(s, 3) = x(s)*x(s)*(x(s) - 1._f64)
1168  i1(s) = i(s) + 1
1169  end do
1170 
1171  g(0, 0) = f(0, i(1), i(2)) !f(0,0)
1172  g(1, 0) = f(0, i1(1), i(2)) !f(1,0)
1173  g(2, 0) = f(1, i(1), i(2)) !fx(0,0)
1174  g(3, 0) = f(2, i(1), i(2)) !fx(1,0)
1175  g(0, 1) = f(0, i(1), i1(2)) !f(0,1)
1176  g(1, 1) = f(0, i1(1), i1(2)) !f(1,1)
1177  g(2, 1) = f(1, i(1), i1(2)) !fx(0,1)
1178  g(3, 1) = f(2, i(1), i1(2)) !fx(1,1)
1179  g(0, 2) = f(3, i(1), i(2)) !fy(0,0)
1180  g(1, 2) = f(3, i1(1), i(2)) !fy(1,0)
1181  g(2, 2) = f(5, i(1), i(2)) !fxy(0,0)
1182  g(3, 2) = f(6, i(1), i(2)) !fxy(1,0)
1183  g(0, 3) = f(4, i(1), i(2)) !fy(0,1)
1184  g(1, 3) = f(4, i1(1), i(2)) !fy(1,1)
1185  g(2, 3) = f(7, i(1), i(2)) !fxy(0,1)
1186  g(3, 3) = f(8, i(1), i(2)) !fxy(1,1)
1187 
1188  do s = 0, 3
1189  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)
1190  end do
1191 
1192  fval = w(2, 0)*tmp(0) + w(2, 1)*tmp(1) + w(2, 2)*tmp(2) + w(2, 3)*tmp(3)
1193 
1194  !print *,fval,' t',f
1195  end subroutine interpolate_hermite
1196 
1197  subroutine interpolate_hermite_c1(f, i, x, fval, N)
1198  sll_int32, intent(in)::i(2), n(2)
1199  !real(f64),intent(in)::xx(2),xmin(2),xmax(2)
1200  sll_real64, intent(in)::x(2)
1201  sll_real64, intent(out)::fval
1202  sll_real64, dimension(0:3, 0:N(1), 0:N(2))::f
1203  !integer::i(2),i1(2),s
1204  sll_int32::i1(2), s
1205  sll_real64::w(2, 0:3), tmp(0:3)
1206  sll_real64::g(0:3, 0:3)
1207 
1208  !fval =f(0,i(1),i(2))!real(i(1),f64)
1209 
1210  !return
1211 
1212  do s = 1, 2
1213  w(s, 0) = (2._f64*x(s) + 1)*(1._f64 - x(s))*(1._f64 - x(s));
1214  w(s, 1) = x(s)*x(s)*(3._f64 - 2._f64*x(s))
1215  w(s, 2) = x(s)*(1._f64 - x(s))*(1._f64 - x(s))
1216  w(s, 3) = x(s)*x(s)*(x(s) - 1._f64)
1217  i1(s) = i(s) + 1
1218  end do
1219 
1220  g(0, 0) = f(0, i(1), i(2)) !f(0,0)
1221  g(1, 0) = f(0, i1(1), i(2)) !f(1,0)
1222  g(2, 0) = f(1, i(1), i(2)) !fx(0,0)
1223  g(3, 0) = f(1, i1(1), i(2)) !fx(1,0)
1224  g(0, 1) = f(0, i(1), i1(2)) !f(0,1)
1225  g(1, 1) = f(0, i1(1), i1(2)) !f(1,1)
1226  g(2, 1) = f(1, i(1), i1(2)) !fx(0,1)
1227  g(3, 1) = f(1, i1(1), i1(2)) !fx(1,1)
1228  g(0, 2) = f(2, i(1), i(2)) !fy(0,0)
1229  g(1, 2) = f(2, i1(1), i(2)) !fy(1,0)
1230  g(2, 2) = f(3, i(1), i(2)) !fxy(0,0)
1231  g(3, 2) = f(3, i1(1), i(2)) !fxy(1,0)
1232  g(0, 3) = f(2, i(1), i1(2)) !fy(0,1)
1233  g(1, 3) = f(2, i1(1), i1(2)) !fy(1,1)
1234  g(2, 3) = f(3, i(1), i1(2)) !fxy(0,1)
1235  g(3, 3) = f(3, i1(1), i1(2)) !fxy(1,1)
1236 
1237  do s = 0, 3
1238  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)
1239  end do
1240 
1241  fval = w(2, 0)*tmp(0) + w(2, 1)*tmp(1) + w(2, 2)*tmp(2) + w(2, 3)*tmp(3)
1242  !print *,fval,' t',f
1243  end subroutine interpolate_hermite_c1
1244 
1245  subroutine contribution_hermite_c1(x, val)
1246  sll_real64, intent(in)::x(0:1)
1247  sll_real64, intent(out)::val(4, 0:1, 0:1)
1248  sll_int32::s
1249  sll_real64::w(0:3, 0:1)!,tmp(0:3)
1250  do s = 0, 1
1251  w(0, s) = (2._f64*x(s) + 1)*(1._f64 - x(s))*(1._f64 - x(s));
1252  w(1, s) = x(s)*x(s)*(3._f64 - 2._f64*x(s))
1253  w(2, s) = x(s)*(1._f64 - x(s))*(1._f64 - x(s))
1254  w(3, s) = x(s)*x(s)*(x(s) - 1._f64)
1255  end do
1256 
1257  val(1, 0, 0) = w(0, 0)*w(0, 1)
1258  val(2, 0, 0) = w(2, 0)*w(0, 1)
1259  val(3, 0, 0) = w(0, 0)*w(2, 1)
1260  val(4, 0, 0) = w(2, 0)*w(2, 1)
1261 
1262  val(1, 1, 0) = w(1, 0)*w(0, 1)
1263  val(2, 1, 0) = w(3, 0)*w(0, 1)
1264  val(3, 1, 0) = w(1, 0)*w(2, 1)
1265  val(4, 1, 0) = w(3, 0)*w(2, 1)
1266 
1267  val(1, 0, 1) = w(0, 0)*w(1, 1)
1268  val(2, 0, 1) = w(2, 0)*w(1, 1)
1269  val(3, 0, 1) = w(0, 0)*w(3, 1)
1270  val(4, 0, 1) = w(2, 0)*w(3, 1)
1271 
1272  val(1, 1, 1) = w(1, 0)*w(1, 1)
1273  val(2, 1, 1) = w(3, 0)*w(1, 1)
1274  val(3, 1, 1) = w(1, 0)*w(3, 1)
1275  val(4, 1, 1) = w(3, 0)*w(3, 1)
1276 
1277  !print *,val
1278  !stop
1279 
1280  end subroutine contribution_hermite_c1
1281 
1282  subroutine sll_s_contribution_spl(x, val)
1283  sll_real64, intent(in)::x(0:1)
1284  sll_real64, intent(out)::val(-1:2, -1:2)
1285  sll_int32::s
1286  sll_real64::w(-1:2, 0:1)
1287  do s = 0, 1
1288  w(-1, s) = (1._f64/6._f64)*(1._f64 - x(s))*(1._f64 - x(s))*(1._f64 - x(s));
1289  w(0, s) = 1._f64/6._f64 + 0.5_f64*(1._f64 - x(s))*(-(1._f64 - x(s))* &
1290  (1._f64 - x(s)) + (1._f64 - x(s)) + 1._f64);
1291  w(1, s) = 1._f64/6._f64 + 0.5_f64*x(s)*(-x(s)*x(s) + x(s) + 1._f64);
1292  w(2, s) = (1._f64/6._f64)*x(s)*x(s)*x(s);
1293  end do
1294 
1295  val(-1, -1) = w(-1, 0)*w(-1, 1)
1296  val(-1, 0) = w(-1, 0)*w(0, 1)
1297  val(-1, 1) = w(-1, 0)*w(1, 1)
1298  val(-1, 2) = w(-1, 0)*w(2, 1)
1299 
1300  val(0, -1) = w(0, 0)*w(-1, 1)
1301  val(0, 0) = w(0, 0)*w(0, 1)
1302  val(0, 1) = w(0, 0)*w(1, 1)
1303  val(0, 2) = w(0, 0)*w(2, 1)
1304 
1305  val(1, -1) = w(1, 0)*w(-1, 1)
1306  val(1, 0) = w(1, 0)*w(0, 1)
1307  val(1, 1) = w(1, 0)*w(1, 1)
1308  val(1, 2) = w(1, 0)*w(2, 1)
1309 
1310  val(2, -1) = w(2, 0)*w(-1, 1)
1311  val(2, 0) = w(2, 0)*w(0, 1)
1312  val(2, 1) = w(2, 0)*w(1, 1)
1313  val(2, 2) = w(2, 0)*w(2, 1)
1314 
1315  end subroutine sll_s_contribution_spl
1316 
1317  subroutine splcoefnat1d0(lunat, N)
1318  sll_int32, intent(in)::n
1319  sll_real64, dimension(0:1, 0:N + 2), intent(out)::lunat
1320  sll_int32::i
1321  sll_real64::a(0:2)
1322  a(0) = -3._f64; a(1) = 0._f64; a(2) = 3._f64;
1323  lunat(0, 0) = a(0);
1324  lunat(1, 0) = 1._f64/lunat(0, 0);
1325  lunat(0, 1) = 4._f64 - a(1)*lunat(1, 0);
1326  lunat(1, 1) = 1._f64/lunat(0, 1);
1327  lunat(0, 2) = 4._f64 - lunat(1, 1)*(1._f64 - a(2)/a(0));
1328  do i = 2, n
1329  lunat(1, i) = 1._f64/lunat(0, i);
1330  lunat(0, i + 1) = 4._f64 - lunat(1, i);
1331  end do
1332  lunat(1, n + 2) = a(0)/lunat(0, n);
1333  lunat(1, n + 1) = (a(1) - lunat(1, n + 2))/lunat(0, n + 1);
1334  lunat(0, n + 2) = a(2) - lunat(1, n + 1);
1335  end subroutine splcoefnat1d0
1336 
1337  subroutine splcoefnat1d(p, lunat, N)
1338  sll_int32, intent(in)::n
1339  sll_real64, dimension(0:1, 0:N + 2), intent(in)::lunat
1340  sll_real64, dimension(0:N + 2), intent(inout)::p
1341  sll_int32::i
1342  sll_real64::a(0:2)
1343  a(0) = -3._f64; a(1) = 0._f64; a(2) = 3._f64;
1344  !p(0)=0._f64;
1345  !p(N+2)=0._f64;
1346  do i = 0, n + 2;
1347  p(i) = 6._f64*p(i);
1348  end do;
1349  do i = 1, n + 1; p(i) = p(i) - lunat(1, i - 1)*p(i - 1); end do
1350  p(n + 2) = p(n + 2) - (lunat(1, n + 1)*p(n + 1) + lunat(1, n + 2)*p(n));
1351  p(n + 2) = p(n + 2)/lunat(0, n + 2);
1352  do i = n + 1, 2, -1; p(i) = (p(i) - p(i + 1))/lunat(0, i); end do
1353  p(1) = (p(1) - (1._f64 - a(2)/a(0))*p(2))/lunat(0, 1);
1354  p(0) = (p(0) - a(1)*p(1) - a(2)*p(2))/lunat(0, 0);
1355  !p(i-1)+4*p(i)+p(i+1)=6ftab(i-1,j), i=1..N+1
1356  !a(0)*p(0)+a(1)*p(1)+a(2)*p(2)=f'(rmin)=0);
1357  !a(0)*p(Na)+a(1)*p(Na+1)+a(2)*p(Na+2)=f'(rmax)=0);
1358  end subroutine splcoefnat1d
1359 
1360  subroutine sll_s_splcoefnat1d0old(dnat, lnat, N)
1361  sll_int32, intent(in)::n
1362  sll_real64, dimension(0:N + 2), intent(inout)::dnat, lnat
1363  sll_int32::i
1364  sll_real64::a(0:2)
1365  a(0) = -3._f64; a(1) = 0._f64; a(2) = 3._f64;
1366  dnat(0) = a(0);
1367  lnat(0) = 1._f64/dnat(0);
1368  dnat(1) = 4._f64 - a(1)*lnat(0);
1369  lnat(1) = 1._f64/dnat(1);
1370  dnat(2) = 4._f64 - lnat(1)*(1._f64 - a(2)/a(0));
1371  do i = 2, n
1372  lnat(i) = 1._f64/dnat(i);
1373  dnat(i + 1) = 4._f64 - lnat(i);
1374  end do
1375  lnat(n + 2) = a(0)/dnat(n);
1376  lnat(n + 1) = (a(1) - lnat(n + 2))/dnat(n + 1);
1377  dnat(n + 2) = a(2) - lnat(n + 1);
1378  end subroutine sll_s_splcoefnat1d0old
1379 
1380  subroutine splcoefnatper2d(f, buf, dnatx, lnatx, dpery, lpery, mpery, Nx, Ny)
1381  sll_int32, intent(in)::nx, ny
1382  sll_real64, dimension(:, :), pointer::f
1383  sll_real64, dimension(:), pointer::buf, dpery, lpery, mpery, dnatx, lnatx
1384  sll_int32::i, j
1385  !natural spline coefficients in x
1386  do j = 0, ny - 1
1387  do i = 0, nx + 2; buf(i) = f(i, j); end do
1388  call splcoefnat1dold(buf, dnatx, lnatx, nx)
1389  do i = 0, nx + 2; f(i, j) = buf(i); end do
1390  end do
1391  !periodic spline coefficients in y
1392  do i = 0, nx + 2
1393  do j = 0, ny - 1; buf(j) = f(i, j); end do
1394  call splcoefper1dold(buf, dpery, lpery, mpery, ny)
1395  do j = 0, ny - 1; f(i, j) = buf(j); end do
1396  end do
1397 
1398  end subroutine splcoefnatper2d
1399 
1400  subroutine splnatper2d(f, xx, xmin, xmax, yy, ymin, ymax, fval, Nx, Ny)
1401  sll_int32, intent(in)::nx, ny
1402  sll_real64, intent(in)::xx, xmin, xmax, yy, ymin, ymax
1403  sll_real64, intent(out)::fval
1404  sll_real64, dimension(:, :), pointer::f
1405  sll_int32::i, j
1406  sll_int32::ix(0:3), iy(0:3)
1407  sll_real64::x, y
1408  sll_real64::wx(0:3), wy(0:3), tmp(0:3)
1409 
1410  x = (xx - xmin)/(xmax - xmin)
1411  !x=x-real(floor(x),f64)
1412  if (x < 0._f64) x = 0._f64;
1413  if (x >= 1._f64) x = 1._f64 - 1.e-12_f64;
1414  x = x*real(nx, f64)
1415  i = floor(x)
1416  x = x - real(i, f64)
1417 
1418  y = (yy - ymin)/(ymax - ymin)
1419  y = y - real(floor(y), f64)
1420  y = y*real(ny, f64)
1421  j = floor(y)
1422  y = y - real(j, f64)
1423 
1424  wx(0) = (1._f64/6._f64)*(1._f64 - x)*(1._f64 - x)*(1._f64 - x);
1425  wx(1) = 1._f64/6._f64 + 0.5_f64*(1._f64 - x)*(-(1._f64 - x)* &
1426  (1._f64 - x) + (1._f64 - x) + 1._f64);
1427  wx(2) = 1._f64/6._f64 + 0.5_f64*x*(-x*x + x + 1._f64);
1428  wx(3) = (1._f64/6._f64)*x*x*x;
1429  wy(0) = (1._f64/6._f64)*(1._f64 - y)*(1._f64 - y)*(1._f64 - y);
1430  wy(1) = 1._f64/6._f64 + 0.5_f64*(1._f64 - y)*(-(1._f64 - y)* &
1431  (1._f64 - y) + (1._f64 - y) + 1._f64);
1432  wy(2) = 1._f64/6._f64 + 0.5_f64*y*(-y*y + y + 1._f64);
1433  wy(3) = (1._f64/6._f64)*y*y*y;
1434  iy(0) = mod(j + ny - 1, ny)
1435  iy(1) = j
1436  iy(2) = mod(j + 1, ny)
1437  iy(3) = mod(j + 2, ny)
1438 
1439  ix(0) = i
1440  ix(1) = i + 1
1441  ix(2) = i + 2
1442  ix(3) = i + 3
1443 
1444  tmp(0) = wx(0)*f(ix(0), iy(0)) + wx(1)*f(ix(1), iy(0)) &
1445  + wx(2)*f(ix(2), iy(0)) + wx(3)*f(ix(3), iy(0))
1446  tmp(1) = wx(0)*f(ix(0), iy(1)) + wx(1)*f(ix(1), iy(1)) &
1447  + wx(2)*f(ix(2), iy(1)) + wx(3)*f(ix(3), iy(1))
1448  tmp(2) = wx(0)*f(ix(0), iy(2)) + wx(1)*f(ix(1), iy(2)) &
1449  + wx(2)*f(ix(2), iy(2)) + wx(3)*f(ix(3), iy(2))
1450  tmp(3) = wx(0)*f(ix(0), iy(3)) + wx(1)*f(ix(1), iy(3)) &
1451  + wx(2)*f(ix(2), iy(3)) + wx(3)*f(ix(3), iy(3))
1452 
1453  fval = wy(0)*tmp(0) + wy(1)*tmp(1) + wy(2)*tmp(2) + wy(3)*tmp(3)
1454 
1455  end subroutine splnatper2d
1456 
1457  subroutine splper1d(f, xx, xmin, xmax, fval, N)
1458  sll_int32, intent(in)::n
1459  sll_real64, intent(in)::xx, xmin, xmax
1460  sll_real64, intent(out)::fval
1461  sll_real64, dimension(0:N - 1), intent(inout)::f
1462  sll_int32::i
1463  real(f64)::x
1464  real(f64)::w(0:3)
1465  x = (xx - xmin)/(xmax - xmin)
1466  x = x - real(floor(x), f64)
1467  x = x*real(n, f64)
1468  i = floor(x)
1469  x = x - real(i, f64)
1470  w(0) = (1._f64/6._f64)*(1._f64 - x)*(1._f64 - x)*(1._f64 - x);
1471  w(1) = 1._f64/6._f64 + 0.5_f64*(1._f64 - x)*(-(1._f64 - x)* &
1472  (1._f64 - x) + (1._f64 - x) + 1._f64);
1473  w(2) = 1._f64/6._f64 + 0.5_f64*x*(-x*x + x + 1._f64);
1474  w(3) = (1._f64/6._f64)*x*x*x;
1475  fval = w(0)*f(mod(i + n - 1, n)) + w(1)*f(i) + w(2)*f(mod(i + 1, n)) + w(3)*f(mod(i + 2, n))
1476  end subroutine splper1d
1477 
1478  subroutine splnat1d(f, xx, xmin, xmax, fval, N)
1479  sll_int32, intent(in)::n
1480  sll_real64, intent(in)::xx, xmin, xmax
1481  sll_real64, intent(out)::fval
1482  sll_real64, dimension(0:N + 2), intent(inout)::f
1483  sll_int32::i
1484  sll_real64::x
1485  sll_real64::w(0:3)
1486  x = (xx - xmin)/(xmax - xmin)
1487  !x=x-real(floor(x),f64)
1488  if (x < 0._f64) x = 0._f64;
1489  if (x > 1._f64) x = 1._f64 - 1.e-12_f64;
1490  x = x*real(n, f64)
1491  i = floor(x)
1492  x = x - real(i, f64)
1493 
1494  w(0) = (1._f64/6._f64)*(1._f64 - x)*(1._f64 - x)*(1._f64 - x);
1495  w(1) = 1._f64/6._f64 + 0.5_f64*(1._f64 - x)*(-(1._f64 - x)* &
1496  (1._f64 - x) + (1._f64 - x) + 1._f64);
1497  w(2) = 1._f64/6._f64 + 0.5_f64*x*(-x*x + x + 1._f64);
1498  w(3) = (1._f64/6._f64)*x*x*x;
1499  fval = w(0)*f(i) + w(1)*f(i + 1) + w(2)*f(i + 2) + w(3)*f(i + 3)
1500  end subroutine splnat1d
1501 
1502  subroutine sll_s_splcoefper1d0old(dper, lper, mper, N)
1503  sll_int32, intent(in)::n
1504  sll_real64, dimension(0:N - 1), intent(out)::dper, lper, mper
1505  sll_int32::i
1506 
1507  dper(0) = 4._f64
1508  mper(0) = 0.25_f64
1509  do i = 0, n - 2
1510  lper(i) = 1._f64/dper(i)
1511  dper(i + 1) = 4._f64 - lper(i)
1512  mper(i + 1) = -mper(i)/dper(i + 1)
1513  end do
1514  dper(n - 1) = dper(n - 1) - (lper(n - 2) + 2._f64*mper(n - 2))
1515  do i = 0, n - 1
1516  dper(i) = 1._f64/dper(i)
1517  end do
1518  end subroutine sll_s_splcoefper1d0old
1519 
1520  subroutine splcoefper1d0(luper, N)
1521  sll_int32, intent(in)::n
1522  sll_real64, dimension(0:3*N - 1), intent(out)::luper
1523  sll_int32::i
1524 
1525  luper(0 + 3*0) = 4._f64
1526  luper(2 + 3*0) = 0.25_f64
1527  do i = 0, n - 2
1528  luper(1 + 3*i) = 1._f64/luper(0 + 3*i)
1529  luper(0 + 3*(i + 1)) = 4._f64 - luper(1 + 3*i)
1530  luper(2 + 3*(i + 1)) = -luper(2 + 3*i)/luper(0 + 3*(i + 1))
1531  end do
1532  luper(0 + 3*(n - 1)) = luper(0 + 3*(n - 1)) - (luper(1 + 3*(n - 2)) + 2._f64*luper(2 + 3*(n - 2)))
1533  do i = 0, n - 1
1534  luper(0 + 3*i) = 1._f64/luper(0 + 3*i)
1535  end do
1536  end subroutine splcoefper1d0
1537 
1538  subroutine splcoefper1d(f, luper, N)
1539  sll_int32, intent(in)::n
1540  sll_real64, dimension(0:3*N - 1), intent(in)::luper
1541  sll_real64, dimension(0:N - 1), intent(inout)::f
1542  sll_int32::i
1543  do i = 0, n - 1; f(i) = 6._f64*f(i); end do;
1544  do i = 1, n - 1
1545  f(i) = f(i) - f(i - 1)*luper(1 + 3*(i - 1))
1546  end do
1547  do i = 0, n - 2
1548  f(n - 1) = f(n - 1) - luper(2 + 3*i)*f(i)
1549  end do
1550  f(n - 1) = f(n - 1)*luper(0 + 3*(n - 1)); f(n - 2) = luper(0 + 3*(n - 2))*(f(n - 2) - (1._f64 - luper(2 + 3*(n - 3)))*f(n - 1))
1551  do i = n - 3, 1, -1
1552  f(i) = luper(0 + 3*i)*(f(i) - f(i + 1) + luper(2 + 3*(i - 1))*f(n - 1))
1553  end do
1554  f(0) = luper(0 + 3*0)*(f(0) - f(1) - f(n - 1));
1555  end subroutine splcoefper1d
1556 
1557  subroutine splcoefnat1dold(p, dnat, lnat, N)
1558  sll_int32, intent(in)::n
1559  sll_real64, dimension(0:N + 2), intent(in)::dnat, lnat
1560  sll_real64, dimension(0:N + 2), intent(inout)::p
1561  sll_int32::i
1562  sll_real64::a(0:2)
1563  a(0) = -3._f64; a(1) = 0._f64; a(2) = 3._f64;
1564  !p(0)=0._f64;
1565  !p(N+2)=0._f64;
1566  do i = 0, n + 2;
1567  p(i) = 6._f64*p(i);
1568  end do;
1569  do i = 1, n + 1; p(i) = p(i) - lnat(i - 1)*p(i - 1); end do
1570  p(n + 2) = p(n + 2) - (lnat(n + 1)*p(n + 1) + lnat(n + 2)*p(n));
1571  p(n + 2) = p(n + 2)/dnat(n + 2);
1572  do i = n + 1, 2, -1; p(i) = (p(i) - p(i + 1))/dnat(i); end do
1573  p(1) = (p(1) - (1._f64 - a(2)/a(0))*p(2))/dnat(1);
1574  p(0) = (p(0) - a(1)*p(1) - a(2)*p(2))/dnat(0);
1575  !p(i-1)+4*p(i)+p(i+1)=6ftab(i-1,j), i=1..N+1
1576  !a(0)*p(0)+a(1)*p(1)+a(2)*p(2)=f'(rmin)=0);
1577  !a(0)*p(Na)+a(1)*p(Na+1)+a(2)*p(Na+2)=f'(rmax)=0);
1578  end subroutine splcoefnat1dold
1579 
1580  subroutine splcoefper1dold(f, dper, lper, mper, N)
1581  sll_int32, intent(in)::n
1582  sll_real64, dimension(0:N - 1), intent(in)::dper, lper, mper
1583  sll_real64, dimension(0:N - 1), intent(inout)::f
1584  sll_int32::i
1585  do i = 0, n - 1; f(i) = 6._f64*f(i); end do;
1586  do i = 1, n - 1
1587  f(i) = f(i) - f(i - 1)*lper(i - 1)
1588  end do
1589  do i = 0, n - 2
1590  f(n - 1) = f(n - 1) - mper(i)*f(i)
1591  end do
1592  f(n - 1) = f(n - 1)*dper(n - 1); f(n - 2) = dper(n - 2)*(f(n - 2) - (1._f64 - mper(n - 3))*f(n - 1))
1593  do i = n - 3, 1, -1
1594  f(i) = dper(i)*(f(i) - f(i + 1) + mper(i - 1)*f(n - 1))
1595  end do
1596  f(0) = dper(0)*(f(0) - f(1) - f(n - 1));
1597  end subroutine splcoefper1dold
1598 
1599  subroutine solve_tridiag(a, b, c, v, x, n)
1600 ! Using Thomas' Algorithm
1601  implicit none
1602 ! a - sub-diagonal (means it is the diagonal below the main diagonal)
1603 ! b - the main diagonal
1604 ! c - sup-diagonal (means it is the diagonal above the main diagonal)
1605 ! v - right part
1606 ! x - the answer
1607 ! n - number of equations
1608 
1609  sll_int32, intent(in) :: n
1610  sll_real64, dimension(n), intent(in) :: a, b, c, v
1611  sll_real64, dimension(n), intent(out) :: x
1612  sll_real64, dimension(n) :: bp, vp
1613  sll_real64 :: m
1614  sll_int32 i
1615 
1616  ! Make copies of the b and v variables so that they are unaltered by this sub
1617  bp(1) = b(1)
1618  vp(1) = v(1)
1619 
1620  !The first pass (setting coefficients):
1621  firstpass: do i = 2, n
1622  m = a(i)/bp(i - 1)
1623  bp(i) = b(i) - m*c(i - 1)
1624  vp(i) = v(i) - m*vp(i - 1)
1625  end do firstpass
1626 
1627  x(n) = vp(n)/bp(n)
1628  !The second pass (back-substition)
1629  backsub: do i = n - 1, 1, -1
1630  x(i) = (vp(i) - c(i)*x(i + 1))/bp(i)
1631  end do backsub
1632 
1633  end subroutine solve_tridiag
1634 
1635  subroutine compute_n_bounds_polar_circle(N_min, N_max, N, rho, eta_min, eta_max)
1636  ! version modifiée : N -> N+1
1637  sll_int32, intent(out)::n_min, n_max
1638  sll_int32, intent(in)::n
1639  sll_real64, intent(in)::rho(2), eta_min, eta_max
1640  sll_real64::delta_eta
1641  sll_int32::n_rho
1642  delta_eta = (eta_max - eta_min)/real(n, f64)
1643  n_rho = floor(max(rho(1), rho(2))/delta_eta) + 1
1644  n_min = 1 + n_rho
1645  n_max = n + 1 - n_rho
1646  if ((n_min > n + 1) .or. (n_max < 1) .or. (n_min > n_max)) then
1647  print *, '#Warning: rho is too big'
1648  print *, '#Bad computation of N_min and N_max'
1649  n_min = 1
1650  n_max = n + 1
1651  end if
1652  end subroutine compute_n_bounds_polar_circle
1653 
1654  subroutine compute_factor_bounds(f, f_init, eps, bounds, N_min, N_max)
1655  sll_real64, dimension(:, :), intent(in)::f, f_init
1656  sll_int32, intent(in)::n_min(2), n_max(2)
1657  sll_real64, intent(in)::eps
1658  sll_real64, intent(out)::bounds(2)
1659  sll_int32::i, j
1660  sll_real64::tmp
1661 
1662  bounds(1) = 1.e10_f64
1663  bounds(2) = -bounds(1)
1664  do j = n_min(2), n_max(2) + 1
1665  do i = n_min(1), n_max(1) + 1
1666  if (abs(f_init(i, j)) > eps) then
1667  tmp = f(i, j)/f_init(i, j)
1668  if (tmp > bounds(2)) bounds(2) = tmp;
1669  if (tmp < bounds(1)) bounds(1) = tmp;
1670  end if
1671  end do
1672  end do
1673  end subroutine compute_factor_bounds
1674 
1675  subroutine sll_s_compute_error(f, f_init, J_factor, err, N_min, N_max)
1676  sll_real64, dimension(:, :), intent(in)::f, f_init
1677  sll_int32, intent(in)::n_min(2), n_max(2)
1678  sll_real64, intent(in)::j_factor
1679  sll_real64, intent(out)::err(3)
1680  sll_int32::i, j
1681  sll_real64::tmp, delta
1682 
1683  err = 0._f64
1684 
1685  do j = n_min(2), n_max(2) + 1
1686  do i = n_min(1), n_max(1) + 1
1687  tmp = f(i, j) - j_factor*f_init(i, j)
1688  err(1) = err(1) + abs(tmp)
1689  err(2) = err(2) + abs(tmp)**2
1690  err(3) = max(err(3), abs(tmp))
1691  end do
1692  end do
1693  delta = 1._f64/(real((n_max(2) - n_min(2)), f64)*real((n_max(1) - n_min(1)), f64))
1694  err(1) = err(1)*delta
1695  err(2) = sqrt(err(2)*delta)
1696 
1697  end subroutine sll_s_compute_error
1698 
1699  subroutine compute_error_1d(f, f_init, J_factor, err, N_min, N_max)
1700  sll_real64, dimension(:, :), intent(in)::f, f_init
1701  sll_int32, intent(in)::n_min(2), n_max(2)
1702  sll_real64, dimension(:), intent(in) :: j_factor
1703  sll_real64, intent(out)::err(3)
1704  sll_int32::i, j
1705  sll_real64::tmp, delta
1706 
1707  err = 0._f64
1708 
1709  do j = n_min(2), n_max(2) + 1
1710  do i = n_min(1), n_max(1) + 1
1711  tmp = f(i, j) - j_factor(i)*f_init(i, j)
1712  err(1) = err(1) + abs(tmp)
1713  err(2) = err(2) + abs(tmp)**2
1714  err(3) = max(err(3), abs(tmp))
1715  end do
1716  end do
1717  delta = 1._f64/(real((n_max(2) - n_min(2)), f64)*real((n_max(1) - n_min(1)), f64))
1718  err(1) = err(1)*delta
1719  err(2) = sqrt(err(2)*delta)
1720 
1721  end subroutine compute_error_1d
1722 
1723  subroutine solution_polar_circle(rho, mode, eta_min, eta_max, val)
1724  sll_real64, intent(in)::rho(2), eta_min(2), eta_max(2)
1725  sll_int32, intent(in)::mode(2)
1726  sll_real64, intent(out)::val
1727  sll_real64::tmp
1728  !integer::i
1729  !logical::is_file
1730  val = 0._f64
1731  if (abs(rho(1) - rho(2)) > 1.e-12) then
1732  print *, '#for the moment rho(1)=rho(2) is needed'
1733  return
1734  end if
1735  call sll_s_zero_bessel_dir_dir(mode, eta_min(1), eta_max(1), tmp)
1736  val = 0._f64 !temporary because DBESJ not recognized on helios and curie
1737  !val = DBESJN(0,tmp*rho(1)/eta_max(1))
1738  !print *,i,j,mode_max,alpha,tmp
1739  end subroutine solution_polar_circle
1740 
1741  subroutine sll_s_compute_gamma0(mode, eta_min, eta_max, val)
1742  sll_real64, intent(in)::eta_min(2), eta_max(2)
1743  sll_int32, intent(in)::mode(2)
1744  sll_real64, intent(out)::val
1745  sll_real64::tmp!,mu,mu_max
1746  !integer::N_approx
1747  !logical::is_file
1748 ! N_approx = 2**15
1749 ! mu_max = 50._f64
1750 ! sum1=0._f64
1751 ! sum2=0._f64
1752  call sll_s_zero_bessel_dir_dir(mode, eta_min(1), eta_max(1), tmp)
1753  !print *,"tmp=",tmp
1754  !print *,"eta_max(1)=",eta_max(1)
1755  if (abs(tmp - 3.9651944700162098_f64) > 1.e-12) then
1756  print *, '#error : gamma0 not computed for this mode : ', mode
1757  return
1758  end if
1759  if (abs(eta_max(1) - 18._f64) > 1.e-12) then
1760  print *, '#error : gamma0 not computed for this eta_max : ', eta_max(1)
1761  return
1762  end if
1763  val = 0.95319247622058476357_f64
1764 ! delta_x=real(real(mu_max,f64)/real(N_approx,f64),f64)
1765 ! do i=1,N_approx/2-1
1766 ! mu = real(2._f64*real(i,f64)*delta_x,f64)
1767 ! sum1 = sum1 + DBESJN(0,tmp*sqrt(2._f64*mu)/eta_max(1))**2*exp(-mu)
1768 ! enddo
1769 ! do i=1,N_approx/2
1770 ! mu = real((2._f64*real(i,f64)-1._f64)*delta_x,f64)
1771 ! sum2 = sum2 + DBESJN(0,tmp*sqrt(2._f64*mu)/eta_max(1))**2*exp(-mu)
1772 ! enddo
1773 ! val = 2._f64*sum1 + 4._f64*sum2 + DBESJN(0,0._f64)**2 + DBESJN(0,tmp*sqrt(2._f64*mu_max)/eta_max(1))**2*exp(-mu_max)
1774 ! val = val*real(delta_x/3._f64,f64)
1775  end subroutine sll_s_compute_gamma0
1776 
1778  quasineutral, &
1779  mu_quadr_for_phi_case, &
1780  N_mu_for_phi, &
1781  mu_max_for_phi, &
1782  mu_points_user_defined, &
1783  mu_weights_user_defined, &
1784  N_mu_user_defined)
1785 
1786  type(sll_t_qn_2d_polar) :: quasineutral
1787  character(len=256), intent(in) :: mu_quadr_for_phi_case
1788  sll_int32, intent(in) :: n_mu_for_phi
1789  sll_real64, intent(in) :: mu_max_for_phi
1790  sll_real64, dimension(:), intent(in), optional :: mu_points_user_defined
1791  sll_real64, dimension(:), intent(in), optional :: mu_weights_user_defined
1792  sll_int32, intent(in) :: n_mu_user_defined
1793  sll_real64 :: h
1794  sll_int32 :: ierr, i
1795 
1796  if (mu_quadr_for_phi_case == "SLL_USER_DEFINED") then
1797  quasineutral%N_mu_for_phi = n_mu_user_defined
1798  sll_allocate(quasineutral%mu_points_for_phi(1:n_mu_user_defined), ierr)
1799  sll_allocate(quasineutral%mu_weights_for_phi(1:n_mu_user_defined), ierr)
1800  if (.not. ((present(mu_points_user_defined)) &
1801  .and. (present(mu_weights_user_defined)))) then
1802  print *, '#provide mu_points_user_defined, mu_weights_user_defined'
1803  print *, '#in sll_s_mu_quadr_for_phi_init'
1804  stop
1805  end if
1806 ! else
1807 ! if(&
1808 ! (present(mu_points_user_defined)) &
1809 ! .or.(present(mu_weights_user_defined)) &
1810 ! )then
1811 ! print *,'# do not provide mu_points_user_defined, mu_weights_user_defined'
1812 ! print *,'#in sll_s_mu_quadr_for_phi_init'
1813 ! stop
1814 ! endif
1815  end if
1816 
1817  select case (mu_quadr_for_phi_case)
1818  case ("SLL_USER_DEFINED")
1819  if (size(mu_points_user_defined) /= n_mu_user_defined) then
1820  print *, '#incompatible sizes for mu_points_user_defined :', size(mu_points_user_defined)
1821  print *, '#and N_mu_user_defined :', n_mu_user_defined
1822  print *, '#in sll_s_mu_quadr_for_phi_init'
1823  stop
1824  elseif (size(mu_weights_user_defined) /= n_mu_user_defined) then
1825  print *, '#incompatible sizes for mu_weights_user_defined :', size(mu_weights_user_defined)
1826  print *, '#and N_mu_user_defined :', n_mu_user_defined
1827  print *, '#in sll_s_mu_quadr_for_phi_init'
1828  stop
1829  else
1830  quasineutral%mu_points_for_phi(1:n_mu_user_defined) = mu_points_user_defined
1831  quasineutral%mu_weights_for_phi(1:n_mu_user_defined) = mu_weights_user_defined
1832  end if
1833  case ("SLL_LIN_LEE")
1834  quasineutral%N_mu_for_phi = n_mu_for_phi
1835  sll_allocate(quasineutral%mu_points_for_phi(1:n_mu_for_phi), ierr)
1836  sll_allocate(quasineutral%mu_weights_for_phi(1:n_mu_for_phi), ierr)
1837  select case (n_mu_for_phi)
1838  case (1)
1839  quasineutral%mu_points_for_phi(1) = 1._f64
1840  quasineutral%mu_weights_for_phi(1) = 1._f64
1841  case (2)
1842  quasineutral%mu_points_for_phi(1) = 0.4167845_f64
1843  quasineutral%mu_points_for_phi(2) = 2.495154605_f64
1844  quasineutral%mu_weights_for_phi(1) = 0.7194_f64
1845  quasineutral%mu_weights_for_phi(2) = 0.2806_f64
1846  case (3)
1847  quasineutral%mu_points_for_phi(1) = 0.148131245_f64
1848  quasineutral%mu_points_for_phi(2) = 1._f64
1849  quasineutral%mu_points_for_phi(3) = 3.15959522_f64
1850  quasineutral%mu_weights_for_phi(1) = 0.3583_f64
1851  quasineutral%mu_weights_for_phi(2) = 0.5004_f64
1852  quasineutral%mu_weights_for_phi(3) = 0.1413_f64
1853  case default
1854  print *, '# bad N_mu_user_defined in SLL_LIN_LEE (must be 1, 2 or 3) : ', n_mu_for_phi
1855  print *, '#in sll_s_mu_quadr_for_phi_init'
1856  stop
1857  end select
1858  case ("SLL_RECTANGLES")
1859  quasineutral%N_mu_for_phi = n_mu_for_phi
1860  sll_allocate(quasineutral%mu_points_for_phi(1:n_mu_for_phi), ierr)
1861  sll_allocate(quasineutral%mu_weights_for_phi(1:n_mu_for_phi), ierr)
1862  do i = 1, n_mu_for_phi
1863  quasineutral%mu_points_for_phi(i) = mu_max_for_phi*real(i - 1, f64)/real(n_mu_for_phi, f64)
1864  quasineutral%mu_weights_for_phi(i) = mu_max_for_phi/real(n_mu_for_phi, f64)
1865  end do
1866  case ("SLL_SIMPSON")
1867  quasineutral%N_mu_for_phi = n_mu_for_phi
1868  sll_allocate(quasineutral%mu_points_for_phi(1:n_mu_for_phi), ierr)
1869  sll_allocate(quasineutral%mu_weights_for_phi(1:n_mu_for_phi), ierr)
1870  do i = 1, n_mu_for_phi
1871  quasineutral%mu_points_for_phi(i) = mu_max_for_phi*real(i - 1, f64)/real(n_mu_for_phi - 1, f64)
1872  end do
1873  h = mu_max_for_phi/(3._f64*real(n_mu_for_phi, f64))
1874  quasineutral%mu_weights_for_phi(1) = h
1875  do i = 1, (n_mu_for_phi - 1)/2 - 1
1876  quasineutral%mu_weights_for_phi(2*i) = 4._f64*h
1877  quasineutral%mu_weights_for_phi(2*i + 1) = 2._f64*h
1878  end do
1879  quasineutral%mu_weights_for_phi(n_mu_for_phi - 1) = 4._f64*h
1880  quasineutral%mu_weights_for_phi(n_mu_for_phi) = h
1881  case default
1882  print *, '#mu_quadr_for_phi_case not defined'
1883  print *, '#in sll_s_mu_quadr_for_phi_init'
1884  stop
1885  end select
1886  end subroutine sll_s_mu_quadr_for_phi_init
1887 
1888 end module sll_m_qn_2d_polar
Write file for gnuplot to display 2d field.
Fortran module where set some physical and mathematical constants.
real(kind=f64), parameter, public sll_p_pi
FFT interface for FFTW.
subroutine, public sll_s_fft_exec_r2c_1d(plan, array_in, array_out)
Compute fast Fourier transform in real to complex mode.
subroutine, public sll_s_fft_free(plan)
Delete a plan.
subroutine, public sll_s_fft_init_r2c_1d(plan, nx, array_in, array_out, normalized, aligned, optimization)
Create new 1d real to complex plan for forward FFT.
subroutine, public sll_s_fft_exec_c2r_1d(plan, array_in, array_out)
Compute fast Fourier transform in complex to real mode.
subroutine, public sll_s_fft_init_c2r_1d(plan, nx, array_in, array_out, normalized, aligned, optimization)
Create new 1d complex to real plan for backward FFT.
Implements the functions to write data file plotable by GNUplot.
subroutine, public sll_s_compute_shape_circle(points, N_points)
subroutine, public sll_s_zero_bessel_dir_dir(mode, eta_min, eta_max, val)
subroutine matrix_product_circ(A, NxA, NyA, B, NxB, NyB, prod, Ntheta)
subroutine solve_tridiag(a, b, c, v, x, n)
subroutine splnat1d(f, xx, xmin, xmax, fval, N)
subroutine, public sll_s_precompute_inverse_qn_matrix_polar_splines(quasineutral, mu_points, mu_weights, N_mu)
subroutine compute_error_1d(f, f_init, J_factor, err, N_min, N_max)
subroutine splcoefnat1dold(p, dnat, lnat, N)
subroutine compute_w_hermite(w, r, s)
subroutine, public sll_s_compute_splines_coefs_matrix_per_1d(mat, dper, lper, mper, N)
subroutine, public sll_s_contribution_spl(x, val)
subroutine kronecker_product(A, NxA, NyA, B, NxB, NyB, kronecker)
subroutine splnatper2d(f, xx, xmin, xmax, yy, ymin, ymax, fval, Nx, Ny)
subroutine splcoefper1d(f, luper, N)
subroutine interpolate_hermite(f, i, x, fval, N)
subroutine splcoefnat1d(p, lunat, N)
subroutine, public sll_s_mu_quadr_for_phi_init(quasineutral, mu_quadr_for_phi_case, N_mu_for_phi, mu_max_for_phi, mu_points_user_defined, mu_weights_user_defined, N_mu_user_defined)
subroutine splper1d(f, xx, xmin, xmax, fval, N)
subroutine matrix_product_comp(A, NxA, NyA, B, NxB, NyB, prod)
subroutine solution_polar_circle(rho, mode, eta_min, eta_max, val)
subroutine, public sll_s_matrix_product_compf(A, NxA, NyA, B, NxB, NyB, prod)
subroutine interpolate_hermite_c1(f, i, x, fval, N)
subroutine, public sll_s_localize_polar(x, eta_min, eta_max, ii, eta, N)
subroutine splcoefnat1d0(lunat, N)
subroutine contribution_hermite_c1(x, val)
subroutine matrix_product(A, NxA, NyA, B, NxB, NyB, prod)
subroutine solve_circulant_system(Ntheta, Nr, mat_circ, sol)
subroutine, public sll_s_compute_gamma0(mode, eta_min, eta_max, val)
subroutine hermite_coef_nat_per(f, buf3d, N, d)
subroutine, public sll_s_qn_2d_polar_init(this, eta_min, eta_max, Nc, N_points, lambda, T_i)
subroutine, public sll_s_precompute_gyroaverage_index(quasineutral, rho, N_rho)
subroutine, public sll_s_compute_error(f, f_init, J_factor, err, N_min, N_max)
subroutine, public sll_s_qn_2d_polar_solve(quasineutral, phi)
subroutine, public sll_s_splcoefper1d0old(dper, lper, mper, N)
subroutine compute_n_bounds_polar_circle(N_min, N_max, N, rho, eta_min, eta_max)
subroutine localize_per(i, x, xmin, xmax, N)
subroutine localize_nat(i, x, xmin, xmax, N)
subroutine, public sll_s_compute_splines_coefs_matrix_nat_1d(mat, dnat, lnat, N)
subroutine, public sll_s_qn_2d_polar_test_solve(Nc, eta_min, eta_max, mu_points, mu_weights, N_mu, mode, lambda, T_i, phi_init, phi_qn)
subroutine compute_factor_bounds(f, f_init, eps, bounds, N_min, N_max)
subroutine, public sll_s_splcoefnat1d0old(dnat, lnat, N)
subroutine hermite_c1_coef_nat_per(f, buf3d, N, d)
subroutine splcoefper1d0(luper, N)
subroutine test_solve_circulant_system(mat, Nr, Ntheta)
subroutine splcoefnatper2d(f, buf, dnatx, lnatx, dpery, lpery, mpery, Nx, Ny)
real(kind=f64) function, public sll_f_compute_gamma0_quadrature(Nc, eta_min, eta_max, mu_points, mu_weights, N_mu, mode)
subroutine splcoefper1dold(f, dper, lper, mper, N)
subroutine sol(vkgs, vkgd, vkgi, vfg, kld, vu, neq, mp, ifac, isol, nsym, energ, ier, nsky)
Definition: sol.f:3
Type for FFT plan in SeLaLib.
    Report Typos and Errors