7 #include "sll_assert.h"
8 #include "sll_memory.h"
9 #include "sll_working_precision.h"
27 sll_real64,
allocatable,
dimension(:) :: unitmode
28 sll_int32,
allocatable,
dimension(:, :) :: allmodes
29 sll_comp64,
allocatable,
dimension(:) :: rhs_one
63 if (
allocated(this%allmodes))
then
64 sz =
size(this%allmodes, 2)
73 sll_comp64,
dimension(:),
intent(in) :: solution
77 sll_assert(
size(solution) == this%problemsize())
79 l2norm = real(sqrt(dot_product(solution, solution)), f64)
85 sll_int32,
intent(in) :: maxmode
86 sll_int32,
allocatable,
dimension(:) :: maxmodes, minmodes
87 sll_int32 :: ierr, idx
89 sll_allocate(maxmodes(1:this%dimx), ierr)
90 sll_allocate(minmodes(1:this%dimx), ierr)
95 sll_allocate(this%allmodes(1:this%dimx, 1:product(maxmodes - minmodes + 1)), ierr)
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)
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
118 sll_real64,
intent(in) :: length
121 if (.not.
allocated(this%unitmode))
then
122 sll_allocate(this%unitmode(this%dimx), ierr)
130 sll_real64,
intent(in),
dimension(:) :: lengths
133 sll_assert(
size(lengths) == this%dimx)
135 if (.not.
allocated(this%unitmode))
then
136 sll_allocate(this%unitmode(this%dimx), ierr)
139 this%unitmode(:) = 2*
sll_p_pi/lengths(:)
153 sll_real64,
dimension(:, :),
intent(in) :: particle
154 sll_int32,
intent(in) :: chunksize
155 sll_comp64,
dimension(:),
allocatable :: fouriermodes
158 sll_allocate(fouriermodes(1:this%problemsize()), ierr)
159 call this%calc_fourier_modes2_chunk(particle, fouriermodes, chunksize)
165 sll_real64,
dimension(:, :),
intent(in) :: particle
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
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;
183 sll_real64,
dimension(:, :),
intent(in) :: particle
185 sll_comp64,
dimension(this%dimx, size(particle, 2)) :: unitmodes
186 sll_comp64,
dimension(:),
intent(out) :: fouriermodes
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))
203 sll_real64,
dimension(:, :),
intent(in) :: particle
205 sll_comp64,
dimension(:),
allocatable :: fouriermodes
208 sll_allocate(fouriermodes(1:this%problemsize()), ierr)
209 call this%calc_fourier_modes2(particle, fouriermodes)
217 sll_comp64,
dimension(:),
intent(in) :: rhs
218 sll_comp64,
dimension(size(rhs)) :: solution
221 sll_assert(
size(rhs) == this%problemsize())
222 do idx = 1,
size(rhs)
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)
229 solution(idx) = (0.0_f64, 0.0_f64)
233 do idx = 1, this%problemsize()
234 if (.not. this%allmodes(1, idx) == 0)
then
235 solution(idx) = solution(idx)*2
242 sll_comp64,
dimension(:),
intent(in) :: rhs
243 sll_comp64,
dimension(size(rhs)) :: solution
245 sll_int32 :: zonaldim = 3
247 sll_assert(
size(rhs) == this%problemsize())
248 do idx = 1,
size(rhs)
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)
253 solution(idx) = (0.0_f64, 0.0_f64)
256 if (this%dimx == 3)
then
258 if (this%allmodes(zonaldim, idx) == 0)
then
259 solution(idx) = (0.0_f64, 0.0_f64)
265 do idx = 1, this%problemsize()
266 if (this%allmodes(1, idx) /= 0)
then
267 solution(idx) = solution(idx)*2
276 sll_comp64,
dimension(:),
intent(in) :: rhs
277 sll_comp64,
dimension(size(rhs)) :: solution
280 sll_assert(
size(rhs) == this%problemsize())
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
293 sll_comp64,
dimension(:),
intent(in) :: rhs
294 sll_comp64,
dimension(size(rhs)) :: solution
297 sll_assert(
size(rhs) == this%problemsize())
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
306 if (all(this%allmodes(:, idx) == 0))
then
307 solution(idx) = (0.0_f64, 0.0_f64)
314 sll_real64,
dimension(:, :),
intent(in) :: pos
315 sll_comp64,
dimension(:),
intent(in) :: fouriermodes
316 sll_real64,
dimension(size(pos, 1), size(pos, 2)) :: gradient
318 sll_comp64,
dimension(size(pos, 2)) :: partmode
319 sll_int32 :: idx, jdx
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(:))
343 sll_real64,
dimension(:, :),
intent(in) :: pos
344 sll_comp64,
dimension(:),
intent(in) :: fouriermodes
345 sll_real64,
dimension(size(pos, 2)) :: fun
346 sll_comp64,
dimension(size(pos, 2)) :: partmode
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)))
357 sll_real64,
dimension(:, :),
intent(in) :: particle
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
363 sll_allocate(fouriermodes(1:this%problemsize()), ierr)
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;
376 sll_real64,
dimension(:, :),
intent(in) :: particle
377 sll_comp64,
dimension(:),
intent(out) :: fouriermodes
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))
387 sll_comp64,
dimension(:),
intent(in) :: summands
388 sll_comp64 :: sum, c, t, y
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
402 sll_real64,
dimension(:),
intent(in) :: summands
403 sll_real64 :: sum, c, t, y
408 do idx = 1,
size(summands)
409 y = summands(idx) - c
418 sll_real64,
dimension(:, :),
intent(in) :: particle
419 sll_comp64,
dimension(:),
allocatable :: fouriermodes
422 sll_allocate(fouriermodes(1:this%problemsize()), ierr)
423 call this%calc_fourier_modes(particle, fouriermodes)
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
432 dim =
size(min_exponents);
434 sz = product(max_exponents - min_exponents + 1)
435 dz = max_exponents(1) - min_exponents(1) + 1
439 sll_allocate(list(dim, 1:sz), ierr)
440 sll_allocate(sublist(dim - 1, subsz), ierr)
445 num = min_exponents(1);
447 list(1, (1 + (idx - 1)*subsz):idx*subsz) = num
448 list(2:dim, (1 + (idx - 1)*subsz):idx*subsz) = sublist
452 num = min_exponents(1);
468 sll_comp64,
dimension(:, :),
intent(in) :: basis
469 sll_int32,
dimension(:),
intent(in) :: exponent
473 do idx = 1,
size(basis, 2)
485 sll_real64,
dimension(:, :),
intent(in) :: matrix
486 sll_real64,
dimension(:),
intent(in) :: diagonal
490 sll_assert(
size(matrix, 1) ==
size(diagonal))
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)