Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_pif_fieldsolver.F90
Go to the documentation of this file.
1 !**************************************************************
2 ! Author: Jakob Ameres, jakob.ameres@tum.de
3 !**************************************************************
4 
6 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 #include "sll_assert.h"
8 #include "sll_memory.h"
9 #include "sll_working_precision.h"
10 
11  use sll_m_constants, only: &
12  sll_p_i1, &
13  sll_p_pi
14 
15  implicit none
16 
17  public :: &
20 
21  private
22 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 
25 
26  sll_int32 :: dimx !spatial dimensions
27  sll_real64, allocatable, dimension(:) :: unitmode !normalized to domain fourier mode
28  sll_int32, allocatable, dimension(:, :) :: allmodes
29  sll_comp64, allocatable, dimension(:) :: rhs_one ! 1
30  contains
31  procedure, pass(this) :: init => sll_pif_fieldsolver_init
32  !sets the domain to be a d-dimensional cube with constant edge length
33  procedure, pass(this) :: set_box_len => sll_pif_fieldsolver_set_box_len
34  !sets user defined edge length in every direction
35  procedure, pass(this) :: set_box_lens => sll_pif_fieldsolver_set_box_lens
36  procedure, pass(this) :: problemsize => sll_pif_fieldsolver_get_problemsize
37 
38  procedure, pass(this) :: get_fourier_modes => get_fourier_modes
40  procedure, pass(this) :: calc_fourier_modes => calc_fourier_modes
41 
42  procedure, pass(this) :: get_fourier_modes2 => get_fourier_modes2
43  procedure, pass(this) :: calc_fourier_modes2 => calc_fourier_modes2
46 
47  procedure, pass(this) :: solve_poisson => sll_pif_fieldsolver_solve_poisson
48  procedure, pass(this) :: solve_mass => sll_pif_fieldsolver_solve_mass
49  procedure, pass(this) :: solve_quasineutral => sll_pif_fieldsolver_solve_quasineutral
50  procedure, pass(this) :: solve_qn_rho_wo_zonalflow => sll_pif_fieldsolver_solve_qn_rho_wo_zonalflow
51  procedure, pass(this) :: eval_gradient => sll_pif_fieldsolver_eval_gradient
52  procedure, pass(this) :: eval_solution => sll_pif_fieldsolver_eval_solution
53  procedure, pass(this) :: get_rhs_particle => get_fourier_modes
54  procedure, pass(this) :: visu_info => visu_info_sll_pif_fieldsolver
55 
56  procedure, pass(this) :: l2norm => l2norm_sll_pif_fieldsolver
57  end type sll_t_pif_fieldsolver
58 
59 contains
60  pure function sll_pif_fieldsolver_get_problemsize(this) result(sz)
61  class(sll_t_pif_fieldsolver), intent(in) :: this
62  sll_int32 :: sz
63  if (allocated(this%allmodes)) then
64  sz = size(this%allmodes, 2)
65  else
66  sz = 0
67  end if
69 
71  function l2norm_sll_pif_fieldsolver(this, solution) result(l2norm)
72  class(sll_t_pif_fieldsolver), intent(in) :: this
73  sll_comp64, dimension(:), intent(in) :: solution
74 ! sll_int32 :: idx
75  sll_real64 :: l2norm
76 
77  sll_assert(size(solution) == this%problemsize())
78 
79  l2norm = real(sqrt(dot_product(solution, solution)), f64)
80 
81  end function l2norm_sll_pif_fieldsolver
82 
83  subroutine sll_pif_fieldsolver_init(this, maxmode)
84  class(sll_t_pif_fieldsolver), intent(inout) :: this
85  sll_int32, intent(in) :: maxmode
86  sll_int32, allocatable, dimension(:) :: maxmodes, minmodes
87  sll_int32 :: ierr, idx
88 
89  sll_allocate(maxmodes(1:this%dimx), ierr)
90  sll_allocate(minmodes(1:this%dimx), ierr)
91 
92  maxmodes = maxmode
93  minmodes = -maxmode
94  minmodes(1) = 0
95  sll_allocate(this%allmodes(1:this%dimx, 1:product(maxmodes - minmodes + 1)), ierr)
96  this%allmodes = generate_exponents(minmodes, maxmodes)
97 
98  !Define the one
99  sll_allocate(this%rhs_one(1:this%problemsize()), ierr)
100  do idx = 1, size(this%allmodes, 2)
101  if (sum(abs(this%allmodes(:, idx))) == 0) then
102  this%rhs_one(idx) = cmplx(product((2*sll_p_pi/this%unitmode)), 0., f64)
103  end if
104  end do
105  end subroutine sll_pif_fieldsolver_init
106 
108  class(sll_t_pif_fieldsolver), intent(inout) :: this
109 
110  print *, "Spatial Dimensions (x)", this%dimx
111  print *, "Number of Fourier modes: ", this%problemsize()
112  print *, "Domain length", 1.0/this%unitmode*sll_p_pi*2.0
113 
114  end subroutine
115 
116  subroutine sll_pif_fieldsolver_set_box_len(this, length)
117  class(sll_t_pif_fieldsolver), intent(inout) :: this
118  sll_real64, intent(in) :: length
119  sll_int32 :: ierr
120 
121  if (.not. allocated(this%unitmode)) then
122  sll_allocate(this%unitmode(this%dimx), ierr)
123  end if
124 
125  this%unitmode = 2*sll_p_pi/length
126  end subroutine sll_pif_fieldsolver_set_box_len
127 
128  subroutine sll_pif_fieldsolver_set_box_lens(this, lengths)
129  class(sll_t_pif_fieldsolver), intent(inout) :: this
130  sll_real64, intent(in), dimension(:) :: lengths
131  sll_int32 :: ierr
132 
133  sll_assert(size(lengths) == this%dimx)
134 
135  if (.not. allocated(this%unitmode)) then
136  sll_allocate(this%unitmode(this%dimx), ierr)
137  end if
138 
139  this%unitmode(:) = 2*sll_p_pi/lengths(:)
140  end subroutine sll_pif_fieldsolver_set_box_lens
141 
142 ! sll_comp64 function get_fourier_mode( particle, mode)
143 ! sll_real64, dimension(:,:), intent(in) :: particle !particle vector (x,v,weight)
144 ! sll_real64, dimension(dimx), intent(in) :: mode !normalized to domain fourier mode
145 ! !warning the dot_product(x,y)=conjg(x)*y
146 ! get_fourier_mode=dot_product(particle(dimx+dimv+1,:),exp(-sll_p_i1*matmul(mode,particle(1:dimx,:))))
147 ! end function get_fourier_mode
148 
149 ! sll_pif_fieldsolver_get_rhs
150 
151  function get_fourier_modes2_chunk(this, particle, chunksize) result(fouriermodes)
152  class(sll_t_pif_fieldsolver), intent(in) :: this
153  sll_real64, dimension(:, :), intent(in) :: particle !particle vector (x,weight)
154  sll_int32, intent(in) :: chunksize
155  sll_comp64, dimension(:), allocatable :: fouriermodes
156  sll_int32 :: ierr
157 
158  sll_allocate(fouriermodes(1:this%problemsize()), ierr)
159  call this%calc_fourier_modes2_chunk(particle, fouriermodes, chunksize)
160  end function get_fourier_modes2_chunk
161 !
162 
163  subroutine calc_fourier_modes2_chunk(this, particle, fouriermodes, chunksize)
164  class(sll_t_pif_fieldsolver), intent(in) :: this
165  sll_real64, dimension(:, :), intent(in) :: particle !particle vector (x,weight)
166  sll_comp64, dimension(:), intent(out) :: fouriermodes
167  sll_int32, intent(in) :: chunksize
168  sll_int32 :: num, chunk
169  sll_comp64, dimension(size(fouriermodes)) :: fmodechunk
170 
171  num = size(particle, 2)
172  fouriermodes = (0.0_f64, 0.0_f64)
173  do chunk = 1, ceiling(real(num/chunksize, 8))
174  call this%calc_fourier_modes2 &
175  (particle(:, (chunk - 1)*chunksize + 1:min(chunk*chunksize, num)), fmodechunk)
176  fouriermodes = fouriermodes + fmodechunk;
177  end do
178  end subroutine calc_fourier_modes2_chunk
179 
180  !please apply this chunked
181  subroutine calc_fourier_modes2(this, particle, fouriermodes)
182  class(sll_t_pif_fieldsolver), intent(in) :: this
183  sll_real64, dimension(:, :), intent(in) :: particle !particle vector (x,weight)
184  !sll_real64, dimension(size(particle,2)) :: weight
185  sll_comp64, dimension(this%dimx, size(particle, 2)) :: unitmodes
186  sll_comp64, dimension(:), intent(out) :: fouriermodes
187  sll_int32 :: idx!,ierr
188  !Calculate unit fourier modes first
189  unitmodes = exp(cmplx(0.0, -sll_f_diag_dot_matrix_real64(this%unitmode, particle(1:this%dimx, :)), f64));
190  !Extract weights from particle array
191  !weight=particle(this%dimx+1,:)
192 
193  do idx = 1, this%problemsize()
194  fouriermodes(idx) = &
195  sum(product(array_exponent_comp64(unitmodes, this%allmodes(:, idx)), 1)*cmplx(particle(this%dimx + 1, :), 0.0, f64))
196  end do
197 
198  end subroutine calc_fourier_modes2
199 
200 !please apply this chuncked
201  function get_fourier_modes2(this, particle) result(fouriermodes)
202  class(sll_t_pif_fieldsolver), intent(in) :: this
203  sll_real64, dimension(:, :), intent(in) :: particle !particle vector (x,weight)
204 
205  sll_comp64, dimension(:), allocatable :: fouriermodes
206  sll_int32 :: ierr
207 
208  sll_allocate(fouriermodes(1:this%problemsize()), ierr)
209  call this%calc_fourier_modes2(particle, fouriermodes)
210  end function get_fourier_modes2
211 !
212 
215  function sll_pif_fieldsolver_solve_poisson(this, rhs) result(solution)
216  class(sll_t_pif_fieldsolver), intent(in) :: this
217  sll_comp64, dimension(:), intent(in) :: rhs
218  sll_comp64, dimension(size(rhs)) :: solution
219  sll_int32 :: idx
220 
221  sll_assert(size(rhs) == this%problemsize())
222  do idx = 1, size(rhs)
223  !intermit constant mode
224  if (sum(abs(this%allmodes(:, idx))) /= 0) then
225  solution(idx) = rhs(idx) &
226  /cmplx(sum((this%allmodes(:, idx)*this%unitmode(:))**2) &
227  *product(this%unitmode/sll_p_pi/2.0_f64), 0.0, f64)
228  else
229  solution(idx) = (0.0_f64, 0.0_f64)
230  end if
231  end do
232 
233  do idx = 1, this%problemsize()
234  if (.not. this%allmodes(1, idx) == 0) then
235  solution(idx) = solution(idx)*2
236  end if
237  end do
239 
240  function sll_pif_fieldsolver_solve_qn_rho_wo_zonalflow(this, rhs) result(solution)
241  class(sll_t_pif_fieldsolver), intent(in) :: this
242  sll_comp64, dimension(:), intent(in) :: rhs
243  sll_comp64, dimension(size(rhs)) :: solution
244  sll_int32 :: idx
245  sll_int32 :: zonaldim = 3
246 
247  sll_assert(size(rhs) == this%problemsize())
248  do idx = 1, size(rhs)
249  !intermit constant mode
250  if (sum(abs(this%allmodes(:, idx))) /= 0) then
251  solution(idx) = rhs(idx)*cmplx(product(this%unitmode/sll_p_pi/2), 0.0, f64)
252  else
253  solution(idx) = (0.0_f64, 0.0_f64)
254  end if
255 
256  if (this%dimx == 3) then
257  !remove Zonal flow in zonaldim
258  if (this%allmodes(zonaldim, idx) == 0) then
259  solution(idx) = (0.0_f64, 0.0_f64)
260  end if
261  end if
262 
263  end do
264 
265  do idx = 1, this%problemsize()
266  if (this%allmodes(1, idx) /= 0) then
267  solution(idx) = solution(idx)*2
268  end if
269  end do
270 
272 
273 !Get rho from the right hand side
274  function sll_pif_fieldsolver_solve_mass(this, rhs) result(solution)
275  class(sll_t_pif_fieldsolver), intent(in) :: this
276  sll_comp64, dimension(:), intent(in) :: rhs
277  sll_comp64, dimension(size(rhs)) :: solution
278  sll_int32 :: idx
279 
280  sll_assert(size(rhs) == this%problemsize())
281 
282  solution = rhs*cmplx(product(this%unitmode/sll_p_pi/2), 0.0_f64, f64)
283  do idx = 1, this%problemsize()
284  if (.not. this%allmodes(1, idx) == 0) then
285  solution(idx) = solution(idx)*2
286  end if
287  end do
288  end function sll_pif_fieldsolver_solve_mass
289 
290 !Get rho from the right hand side
291  function sll_pif_fieldsolver_solve_quasineutral(this, rhs) result(solution)
292  class(sll_t_pif_fieldsolver), intent(in) :: this
293  sll_comp64, dimension(:), intent(in) :: rhs
294  sll_comp64, dimension(size(rhs)) :: solution
295  sll_int32 :: idx
296 
297  sll_assert(size(rhs) == this%problemsize())
298 
299  solution = rhs*cmplx(product(this%unitmode/sll_p_pi/2), 0.0, f64)
300  do idx = 1, this%problemsize()
301  if (.not. this%allmodes(1, idx) == 0) then
302  solution(idx) = solution(idx)*2
303  end if
304 
305  !Remove constant mode, could also be a dimensional average
306  if (all(this%allmodes(:, idx) == 0)) then
307  solution(idx) = (0.0_f64, 0.0_f64)
308  end if
309  end do
311 
312  function sll_pif_fieldsolver_eval_gradient(this, pos, fouriermodes) result(gradient)
313  class(sll_t_pif_fieldsolver), intent(in) :: this
314  sll_real64, dimension(:, :), intent(in) :: pos !pos vector (x), no weights
315  sll_comp64, dimension(:), intent(in) :: fouriermodes
316  sll_real64, dimension(size(pos, 1), size(pos, 2)) :: gradient
317  !sll_comp64 :: partmode
318  sll_comp64, dimension(size(pos, 2)) :: partmode
319  sll_int32 :: idx, jdx
320  gradient = 0.0_f64
321 
322 ! do jdx=1,size(pos,2)
323 !
324 ! do idx=1,this%problemsize()
325 ! partmode=sll_p_i1*exp(sll_p_i1*(dot_product(this%allmodes(:,idx)*this%unitmode(:),pos(1:this%dimx,jdx)) ))
326 !
327 ! gradient(:,jdx)=gradient(:,jdx)+(real(partmode)*real(fouriermodes(idx))-aimag(partmode)*aimag(fouriermodes(idx)))*&
328 ! (this%allmodes(:,idx)*this%unitmode(:))
329 ! end do
330 ! end do
331 
332  do idx = 1, this%problemsize()
333  partmode = sll_p_i1*exp(cmplx(0.0_f64, matmul(this%allmodes(:, idx)*this%unitmode(:), pos(1:this%dimx, :)), f64))
334  do jdx = 1, size(partmode)
335  gradient(:,jdx)=gradient(:,jdx)+(real(partmode(jdx))*real(fouriermodes(idx))-aimag(partmode(jdx))*aimag(fouriermodes(idx)))*&
336  (this%allmodes(:, idx)*this%unitmode(:))
337  end do
338  end do
340 
341  function sll_pif_fieldsolver_eval_solution(this, pos, fouriermodes) result(fun)
342  class(sll_t_pif_fieldsolver), intent(in) :: this
343  sll_real64, dimension(:, :), intent(in) :: pos !pos vector (x), no weights
344  sll_comp64, dimension(:), intent(in) :: fouriermodes
345  sll_real64, dimension(size(pos, 2)) :: fun
346  sll_comp64, dimension(size(pos, 2)) :: partmode
347  sll_int32 :: idx!, jdx
348  fun = 0.0_f64
349  do idx = 1, this%problemsize()
350  partmode = exp(cmplx(0.0_f64, matmul(this%allmodes(:, idx)*this%unitmode(:), pos(1:this%dimx, :)), f64))
351  fun(:) = fun(:) + (real(partmode(:))*real(fouriermodes(idx)) - aimag(partmode(:))*aimag(fouriermodes(idx)))
352  end do
354 
355  function get_fourier_modes_chunk(this, particle, chunksize) result(fouriermodes)
356  class(sll_t_pif_fieldsolver), intent(in) :: this
357  sll_real64, dimension(:, :), intent(in) :: particle !particle vector (x,weight)
358  sll_comp64, dimension(:), allocatable :: fouriermodes
359  sll_int32, intent(in) :: chunksize
360  sll_int32 :: num, ierr, chunk
361  sll_comp64, dimension(this%problemsize()) :: fmodechunk
362 
363  sll_allocate(fouriermodes(1:this%problemsize()), ierr)
364 
365  num = size(particle, 2)
366  fouriermodes = (0.0_f64, 0.0_f64)
367  do chunk = 1, ceiling(real(num/chunksize, 8))
368  call this%calc_fourier_modes &
369  (particle(:, (chunk - 1)*chunksize + 1:min(chunk*chunksize, num)), fmodechunk)
370  fouriermodes = fouriermodes + fmodechunk;
371  end do
372  end function get_fourier_modes_chunk
373 
374  subroutine calc_fourier_modes(this, particle, fouriermodes)
375  class(sll_t_pif_fieldsolver), intent(in) :: this
376  sll_real64, dimension(:, :), intent(in) :: particle !particle vector (x,weight)
377  sll_comp64, dimension(:), intent(out) :: fouriermodes
378  sll_int32 :: idx
379 
380  do idx = 1, this%problemsize()
381  fouriermodes(idx)=sum(exp(-cmplx(0.0_f64,matmul(this%allmodes(:,idx)*this%unitmode,particle(1:this%dimx,:)),f64))*cmplx(particle(this%dimx+1,:),0.0,f64))
382  end do
383 
384  end subroutine calc_fourier_modes
385 
386  function kahan_sum_comp64(summands) result(sum)
387  sll_comp64, dimension(:), intent(in) :: summands
388  sll_comp64 :: sum, c, t, y
389  sll_int32 :: idx
390  sum = (0.0_f64, 0.0_f64)
391  c = (0.0_f64, 0.0_f64)
392  t = (0.0_f64, 0.0_f64)
393  do idx = 1, size(summands)
394  y = summands(idx) - c
395  t = sum + y
396  c = (t - sum) - y
397  sum = t
398  end do
399  end function
400 
401  function kahan_sum_real64(summands) result(sum)
402  sll_real64, dimension(:), intent(in) :: summands
403  sll_real64 :: sum, c, t, y
404  sll_int32 :: idx
405  sum = 0.0_f64
406  c = 0.0_f64
407  t = 0.0_f64
408  do idx = 1, size(summands)
409  y = summands(idx) - c
410  t = sum + y
411  c = (t - sum) - y
412  sum = t
413  end do
414  end function
415 
416  function get_fourier_modes(this, particle) result(fouriermodes)
417  class(sll_t_pif_fieldsolver), intent(in) :: this
418  sll_real64, dimension(:, :), intent(in) :: particle !particle vector (x,weight)
419  sll_comp64, dimension(:), allocatable :: fouriermodes
420  sll_int32 :: ierr
421 
422  sll_allocate(fouriermodes(1:this%problemsize()), ierr)
423  call this%calc_fourier_modes(particle, fouriermodes)
424  end function get_fourier_modes
425 
426  recursive function generate_exponents(min_exponents, max_exponents) result(list)
427  sll_int32, dimension(:), intent(in) :: min_exponents, max_exponents
428  sll_int32, dimension(:, :), allocatable :: list
429  sll_int32, dimension(:, :), allocatable :: sublist
430  sll_int32 :: dim, idx, sz, dz, num, subsz
431  sll_int32 :: ierr
432  dim = size(min_exponents);
433  !determine problemsize
434  sz = product(max_exponents - min_exponents + 1)
435  dz = max_exponents(1) - min_exponents(1) + 1
436  subsz = sz/dz
437 
438  !allocate memory
439  sll_allocate(list(dim, 1:sz), ierr)
440  sll_allocate(sublist(dim - 1, subsz), ierr)
441 
442  if (dim > 1) then
443  sublist = generate_exponents(min_exponents(2:dim), max_exponents(2:dim))
444 
445  num = min_exponents(1);
446  do idx = 1, dz
447  list(1, (1 + (idx - 1)*subsz):idx*subsz) = num
448  list(2:dim, (1 + (idx - 1)*subsz):idx*subsz) = sublist
449  num = num + 1
450  end do
451  else
452  num = min_exponents(1);
453  do idx = 1, dz
454  list(1, idx) = num
455  num = num + 1
456  end do
457  end if
458  end function generate_exponents
459 
460 ! function powers_comp64( basis, min_exponent, max_exponent)
461 ! sll_comp64, dimension(:
462 !
463 ! fouriermode(idx)=fouriermode(idx-1)
464 !
465 ! end
466 
467  function array_exponent_comp64(basis, exponent)
468  sll_comp64, dimension(:, :), intent(in) :: basis
469  sll_int32, dimension(:), intent(in) :: exponent
470  sll_comp64, dimension(size(basis, 1), size(basis, 2)) :: array_exponent_comp64
471  sll_int32 :: idx
472 
473  do idx = 1, size(basis, 2)
474  !If exponent is negative take complex conjugate, compiler should know...
475  array_exponent_comp64(:, idx) = basis(:, idx)**exponent(:)
476  end do
477  end function array_exponent_comp64
478 
479 ! function weighted_array_power(array, weight, powers)
480 ! sll_real64, dimension(:) :: array
481 !
482 ! end function
483 
484  function sll_f_diag_dot_matrix_real64(diagonal, matrix)
485  sll_real64, dimension(:, :), intent(in) :: matrix !full matrix
486  sll_real64, dimension(:), intent(in) :: diagonal !Entries of a diagonal matrix
487  sll_real64, dimension(size(matrix, 1), size(matrix, 2)) :: sll_f_diag_dot_matrix_real64
488  sll_int32 :: idx, sz
489 
490  sll_assert(size(matrix, 1) == size(diagonal))
491  sz = size(matrix, 2)
492  do idx = 1, sz
493  sll_f_diag_dot_matrix_real64(:, idx) = diagonal(:)*matrix(:, idx)
494  end do
495  end function sll_f_diag_dot_matrix_real64
496 
497 end module sll_m_pif_fieldsolver
Fortran module where set some physical and mathematical constants.
real(kind=f64), parameter, public sll_p_pi
complex(kind=f64), parameter, public sll_p_i1
subroutine calc_fourier_modes2_chunk(this, particle, fouriermodes, chunksize)
complex(kind=f64) function, dimension(size(rhs)) sll_pif_fieldsolver_solve_qn_rho_wo_zonalflow(this, rhs)
real(kind=f64) function l2norm_sll_pif_fieldsolver(this, solution)
Returns the l2norm for a coefficient vector of a solution.
complex(kind=f64) function kahan_sum_comp64(summands)
real(kind=f64) function kahan_sum_real64(summands)
complex(kind=f64) function, dimension(:), allocatable get_fourier_modes2_chunk(this, particle, chunksize)
real(kind=f64) function, dimension(size(pos, 2)) sll_pif_fieldsolver_eval_solution(this, pos, fouriermodes)
subroutine sll_pif_fieldsolver_set_box_lens(this, lengths)
complex(kind=f64) function, dimension(size(basis, 1), size(basis, 2)) array_exponent_comp64(basis, exponent)
pure integer(kind=i32) function sll_pif_fieldsolver_get_problemsize(this)
subroutine calc_fourier_modes2(this, particle, fouriermodes)
complex(kind=f64) function, dimension(:), allocatable get_fourier_modes2(this, particle)
subroutine sll_pif_fieldsolver_set_box_len(this, length)
subroutine calc_fourier_modes(this, particle, fouriermodes)
real(kind=f64) function, dimension(size(pos, 1), size(pos, 2)) sll_pif_fieldsolver_eval_gradient(this, pos, fouriermodes)
complex(kind=f64) function, dimension(:), allocatable get_fourier_modes(this, particle)
complex(kind=f64) function, dimension(size(rhs)) sll_pif_fieldsolver_solve_mass(this, rhs)
complex(kind=f64) function, dimension(size(rhs)) sll_pif_fieldsolver_solve_quasineutral(this, rhs)
complex(kind=f64) function, dimension(size(rhs)) sll_pif_fieldsolver_solve_poisson(this, rhs)
Get phi from the right hand side.
recursive integer(kind=i32) function, dimension(:, :), allocatable generate_exponents(min_exponents, max_exponents)
subroutine visu_info_sll_pif_fieldsolver(this)
complex(kind=f64) function, dimension(:), allocatable get_fourier_modes_chunk(this, particle, chunksize)
subroutine sll_pif_fieldsolver_init(this, maxmode)
real(kind=f64) function, dimension(size(matrix, 1), size(matrix, 2)), public sll_f_diag_dot_matrix_real64(diagonal, matrix)
    Report Typos and Errors