Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_maxwell_2d_periodic_cartesian_par.F90
Go to the documentation of this file.
1 !**************************************************************
2 ! Copyright INRIA, CNRS
3 !
4 ! This code SeLaLib (for Semi-Lagrangian-Library)
5 ! is a parallel library for simulating the plasma turbulence
6 ! in a tokamak.
7 !
8 ! This software is governed by the CeCILL-B license
9 ! under French law and abiding by the rules of distribution
10 ! of free software. You can use, modify and redistribute
11 ! the software under the terms of the CeCILL-B license as
12 ! circulated by CEA, CNRS and INRIA at the following URL
13 ! "http://www.cecill.info".
14 !**************************************************************
15 
16 #define D_DX(field) \
17 plan%d_dx = field; \
18 call sll_s_fft_exec_r2c_1d(plan%fwx, plan%d_dx, plan%fft_x_array); \
19 plan%fft_x_array(2:ncx/2 + 1) = -cmplx(0.0_f64, plan%kx(2:ncx/2 + 1), kind=f64)*plan%fft_x_array(2:ncx/2 + 1); \
20 call sll_s_fft_exec_c2r_1d(plan%bwx, plan%fft_x_array, plan%d_dx); \
21 plan%d_dx = plan%d_dx/plan%ncx
22 
23 #define D_DY(field) \
24 plan%d_dy = field; \
25 call sll_s_fft_exec_r2c_1d(plan%fwy, plan%d_dy, plan%fft_y_array); \
26 plan%fft_y_array(2:ncy/2 + 1) = -cmplx(0.0_f64, plan%ky(2:ncy/2 + 1), kind=f64)*plan%fft_y_array(2:ncy/2 + 1); \
27 call sll_s_fft_exec_c2r_1d(plan%bwy, plan%fft_y_array, plan%d_dy); \
28 plan%d_dy = plan%d_dy/plan%ncy
29 
30 #define MPI_MASTER 0
31 
36 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
37 #include "sll_memory.h"
38 #include "sll_working_precision.h"
39 #include "sll_maxwell_solvers_macros.h"
40 
41  use sll_m_collective, only: &
45 
46  use sll_m_constants, only: &
47  sll_p_pi
48 
49  use sll_m_fft, only: &
50  sll_t_fft, &
57 
58  use sll_m_remapper, only: &
59  sll_o_apply_remap_2d, &
60  sll_o_compute_local_sizes, &
61  sll_t_layout_2d, &
62  sll_o_new_remap_plan, &
63  sll_t_remap_plan_2d_real64, &
64  sll_o_delete
65 
66  use sll_m_utilities, only: &
68 
69  implicit none
70 
71  public :: &
77 
78  private
79 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
80 
83  sll_int32 :: ncx
84  sll_int32 :: ncy
85  type(sll_t_fft) :: fwx
86  type(sll_t_fft) :: fwy
87  type(sll_t_fft) :: bwx
88  type(sll_t_fft) :: bwy
89  sll_real64, dimension(:), pointer :: d_dx
90  sll_real64, dimension(:), pointer :: d_dy
91  sll_comp64, dimension(:), pointer :: fft_x_array
92  sll_comp64, dimension(:), pointer :: fft_y_array
93  sll_real64 :: e_0
94  sll_real64 :: mu_0
95  type(sll_t_layout_2d), pointer :: layout_x
96  type(sll_t_layout_2d), pointer :: layout_y
97  type(sll_t_remap_plan_2d_real64), pointer :: rmp_xy
98  type(sll_t_remap_plan_2d_real64), pointer :: rmp_yx
99  sll_real64, dimension(:, :), pointer :: fz_x
100  sll_real64, dimension(:, :), pointer :: fz_y
101  sll_real64, dimension(:), pointer :: kx
102  sll_real64, dimension(:), pointer :: ky
104 
105 contains
106 
112  layout_x, layout_y, ncx, ncy, Lx, Ly) result(plan)
113 
115  type(sll_t_maxwell_2d_periodic_plan_cartesian_par), pointer :: plan
116  type(sll_t_layout_2d), pointer :: layout_x
117  type(sll_t_layout_2d), pointer :: layout_y
118  sll_int32 :: ncx
119  sll_int32 :: ncy
120  sll_real64 :: lx
121  sll_real64 :: ly
122  sll_int32 :: prank
123  sll_int32 :: psize
124  sll_int32 :: error
125  sll_int32 :: nx_loc
126  sll_int32 :: ny_loc
127  sll_real64 :: kx0
128  sll_real64 :: ky0
129  sll_int32 :: i, j
130 
133 
134  if ((.not. sll_f_is_power_of_two(int(ncx, i64))) .and. &
135  (.not. sll_f_is_power_of_two(int(ncy, i64)))) then
136  print *, 'This test needs to run with numbers of cells which are', &
137  'powers of 2.'
138  print *, 'Exiting...'
139  stop
140  end if
141 
142  sll_allocate(plan, error)
143  sll_clear_allocate(plan%d_dx(1:ncx), error)
144  sll_clear_allocate(plan%d_dy(1:ncy), error)
145 
146  plan%ncx = ncx
147  plan%ncy = ncy
148 
149  sll_allocate(plan%fft_x_array(ncx/2 + 1), error)
150  sll_allocate(plan%fft_y_array(ncy/2 + 1), error)
151 
152  call sll_s_fft_init_r2c_1d(plan%fwx, ncx, plan%d_dx, plan%fft_x_array)
153  call sll_s_fft_init_c2r_1d(plan%bwx, ncx, plan%fft_x_array, plan%d_dx)
154  call sll_s_fft_init_r2c_1d(plan%fwy, ncy, plan%d_dy, plan%fft_y_array)
155  call sll_s_fft_init_c2r_1d(plan%bwy, ncy, plan%fft_y_array, plan%d_dy)
156 
157  ! Layout and local sizes for FFTs in x-direction
158  plan%layout_x => layout_x
159  call sll_o_compute_local_sizes(plan%layout_x, nx_loc, ny_loc)
160  sll_clear_allocate(plan%fz_x(1:nx_loc, 1:ny_loc), error)
161 
162  ! Layout and local sizes for FFTs in y-direction
163  plan%layout_y => layout_y
164  call sll_o_compute_local_sizes(plan%layout_y, nx_loc, ny_loc)
165  sll_clear_allocate(plan%fz_y(1:nx_loc, 1:ny_loc), error)
166 
167  plan%rmp_xy => sll_o_new_remap_plan(plan%layout_x, plan%layout_y, plan%fz_x)
168  plan%rmp_yx => sll_o_new_remap_plan(plan%layout_y, plan%layout_x, plan%fz_y)
169 
170  sll_allocate(plan%kx(ncx/2 + 1), error)
171  sll_allocate(plan%ky(ncy/2 + 1), error)
172 
173  kx0 = 2._f64*sll_p_pi/lx
174  ky0 = 2._f64*sll_p_pi/ly
175 
176  do i = 2, ncx/2 + 1
177  plan%kx(i) = (i - 1)*kx0
178  end do
179  plan%kx(1) = 1.0_f64
180  do j = 2, ncy/2 + 1
181  plan%ky(j) = (j - 1)*ky0
182  end do
183  plan%ky(1) = 1.0_f64
184 
186 
187 !********************************************************************************
188 
190  subroutine sll_s_faraday_te(plan, dt, ex, ey)
191 
192  type(sll_t_maxwell_2d_periodic_plan_cartesian_par), pointer :: plan
193 
194  sll_real64, dimension(:, :) :: ex
195  sll_real64, dimension(:, :) :: ey
196  sll_int32 :: ncx
197  sll_int32 :: ncy
198  sll_int32 :: nx_loc
199  sll_int32 :: ny_loc
200  sll_int32 :: prank
201  sll_int32 :: psize
202  sll_real64, intent(in) :: dt
203 
204  sll_real64 :: dt_mu
205  sll_int32 :: i, j
206 
209 
210  ncx = plan%ncx
211  ncy = plan%ncy
212 
213 #ifdef DEBUG
214  call verify_argument_sizes_par(plan%layout_x, ey)
215  call verify_argument_sizes_par(plan%layout_y, ex)
216 #endif
217 
218  dt_mu = dt/plan%mu_0
219 
220  call sll_o_compute_local_sizes(plan%layout_x, nx_loc, ny_loc)
221  do j = 1, ny_loc
222  d_dx(ey(1:ncx, j))
223  plan%fz_x(:, j) = plan%fz_x(:, j) - dt_mu*plan%d_dx
224  end do
225 
226  call sll_o_apply_remap_2d(plan%rmp_xy, plan%fz_x, plan%fz_y)
227 
228  call sll_o_compute_local_sizes(plan%layout_y, nx_loc, ny_loc)
229  do i = 1, nx_loc
230  d_dy(ex(i, 1:ncy))
231  plan%fz_y(i, :) = plan%fz_y(i, :) + dt_mu*plan%d_dy
232  end do
233 
234  end subroutine sll_s_faraday_te
235 
237  subroutine sll_s_ampere_te(plan, dt, ex, ey, jx, jy)
238 
239  type(sll_t_maxwell_2d_periodic_plan_cartesian_par), pointer :: plan
240 
241  sll_real64, dimension(:, :), intent(inout) :: ex
242  sll_real64, dimension(:, :), intent(inout) :: ey
243  sll_real64, dimension(:, :), optional :: jx
244  sll_real64, dimension(:, :), optional :: jy
245  sll_real64, intent(in) :: dt
246  sll_int32 :: nx_loc
247  sll_int32 :: ny_loc
248  sll_int32 :: prank
249  sll_int32 :: psize
250 
251  sll_real64 :: dt_e
252  sll_int32 :: i, j
253  sll_int32 :: ncx, ncy
254 
257 
258 #ifdef DEBUG
259  call verify_argument_sizes_par(plan%layout_x, ey)
260  call verify_argument_sizes_par(plan%layout_y, ex)
261 #endif
262 
263  dt_e = dt/plan%e_0
264  ncx = plan%ncx
265  ncy = plan%ncy
266 
267  call sll_o_compute_local_sizes(plan%layout_y, nx_loc, ny_loc)
268  do i = 1, nx_loc
269  d_dy(plan%fz_y(i, 1:ncy))
270  ex(i, :) = ex(i, :) + dt_e*plan%d_dy
271  end do
272 
273  if (present(jx)) then
274 #ifdef DEBUG
275  call verify_argument_sizes_par(plan%layout_y, jx)
276 #endif
277  ex(:, :) = ex(:, :) - dt_e*jx(:, :)
278  end if
279 
280  call sll_o_apply_remap_2d(plan%rmp_xy, plan%fz_x, plan%fz_y)
281 
282  call sll_o_compute_local_sizes(plan%layout_x, nx_loc, ny_loc)
283  do j = 1, ny_loc
284  d_dx(plan%fz_x(1:ncx, j))
285  ey(:, j) = ey(:, j) - dt_e*plan%d_dx
286  end do
287 
288  if (present(jy)) then
289 #ifdef DEBUG
290  call verify_argument_sizes_par(plan%layout_x, jy)
291 #endif
292  ey(:, :) = ey(:, :) - dt*jy(:, :)/plan%e_0
293  end if
294 
295  end subroutine sll_s_ampere_te
296 
298  subroutine ampere_tm(plan, dt, bx, by, jz)
299 
300  type(sll_t_maxwell_2d_periodic_plan_cartesian_par), pointer :: plan
301 
302  sll_real64, dimension(:, :) :: bx
303  sll_real64, dimension(:, :) :: by
304  sll_real64, dimension(:, :), optional :: jz
305  sll_int32 :: ncx
306  sll_int32 :: ncy
307  sll_int32 :: nx_loc
308  sll_int32 :: ny_loc
309  sll_int32 :: prank
310  sll_int32 :: psize
311  sll_real64, intent(in) :: dt
312 
313  sll_real64 :: dt_e
314  sll_int32 :: i, j
315 
318 
319  ncx = plan%ncx
320  ncy = plan%ncy
321 
322 #ifdef DEBUG
323  call verify_argument_sizes_par(plan%layout_x, by)
324  call verify_argument_sizes_par(plan%layout_y, bx)
325 #endif
326 
327  dt_e = dt/plan%e_0
328 
329  call sll_o_compute_local_sizes(plan%layout_x, nx_loc, ny_loc)
330  do j = 1, ny_loc
331  d_dx(by(1:ncx, j))
332  plan%fz_x(:, j) = plan%fz_x(:, j) + dt_e*plan%d_dx
333  end do
334 
335  call sll_o_apply_remap_2d(plan%rmp_xy, plan%fz_x, plan%fz_y)
336 
337  call sll_o_compute_local_sizes(plan%layout_y, nx_loc, ny_loc)
338  do i = 1, nx_loc
339  d_dy(bx(i, 1:ncy))
340  plan%fz_y(i, :) = plan%fz_y(i, :) - dt_e*plan%d_dy
341  end do
342 
343  if (present(jz)) then
344 #ifdef DEBUG
345  call verify_argument_sizes_par(plan%layout_y, jz)
346 #endif
347  plan%fz_y = plan%fz_y - dt_e*jz
348  end if
349 
350  end subroutine ampere_tm
351 
353  subroutine faraday_tm(plan, dt, bx, by)
354 
355  type(sll_t_maxwell_2d_periodic_plan_cartesian_par), pointer :: plan
356 
357  sll_real64, dimension(:, :), intent(inout) :: bx
358  sll_real64, dimension(:, :), intent(inout) :: by
359  sll_real64, intent(in) :: dt
360  sll_int32 :: nx_loc
361  sll_int32 :: ny_loc
362  sll_int32 :: prank
363  sll_int32 :: psize
364 
365  sll_real64 :: dt_mu
366  sll_int32 :: i, j
367  sll_int32 :: ncx, ncy
368 
371 
372 #ifdef DEBUG
373  call verify_argument_sizes_par(plan%layout_x, by)
374  call verify_argument_sizes_par(plan%layout_y, bx)
375 #endif
376 
377  dt_mu = dt/plan%mu_0
378 
379  ncx = plan%ncx
380  ncy = plan%ncy
381 
382  call sll_o_compute_local_sizes(plan%layout_y, nx_loc, ny_loc)
383  do i = 1, nx_loc
384  d_dy(plan%fz_y(i, 1:ncy))
385  bx(i, :) = bx(i, :) - dt_mu*plan%d_dy
386  end do
387 
388  call sll_o_apply_remap_2d(plan%rmp_xy, plan%fz_x, plan%fz_y)
389 
390  call sll_o_compute_local_sizes(plan%layout_x, nx_loc, ny_loc)
391  do j = 1, ny_loc
392  d_dx(plan%fz_x(1:ncx, j))
393  by(:, j) = by(:, j) + dt_mu*plan%d_dx
394  end do
395 
396  end subroutine faraday_tm
397 
399 
402  type(sll_t_maxwell_2d_periodic_plan_cartesian_par), pointer :: plan
403 
404  if (.not. associated(plan)) then
405  print *, 'ERROR, delete_maxwell_3d_periodic_plan_par(): ', &
406  'passed plan is not associated.'
407  stop
408  end if
409 
410  call sll_s_fft_free(plan%fwx)
411  call sll_s_fft_free(plan%fwy)
412  call sll_s_fft_free(plan%bwx)
413  call sll_s_fft_free(plan%bwy)
414 
415  call sll_o_delete(plan%rmp_xy)
416  call sll_o_delete(plan%rmp_yx)
417  call sll_o_delete(plan%layout_x)
418  call sll_o_delete(plan%layout_y)
419 
421 
423  subroutine verify_argument_sizes_par(layout, array)
424  type(sll_t_layout_2d), pointer :: layout
425  sll_real64, dimension(:, :) :: array
426  sll_int32, dimension(2) :: n
427  sll_int32 :: i
428 
429  call sll_o_compute_local_sizes(layout, n(1), n(2))
430 
431  do i = 1, 2
432  if (n(i) /= size(array, i)) then
433  print *, 'ERROR: solve_maxwell_2d_periodic_cartesian_par()', &
434  'size of either ex,ey or bz does not match expected size. '
435  if (i == 1) then
436  print *, 'solve_maxwell_2d_periodic_cartesian_par(): ', &
437  'mismatch in direction x'
438  elseif (i == 2) then
439  print *, 'solve_maxwell_2d_periodic_cartesian_par(): ', &
440  'mismatch in direction y'
441  end if
442  print *, 'Exiting...'
443  stop
444  end if
445  end do
446 
447  end subroutine verify_argument_sizes_par
448 
Parallelizing facility.
integer(kind=i32) function, public sll_f_get_collective_rank(col)
Determines the rank of the calling process in the communicator.
type(sll_t_collective_t), pointer, public sll_v_world_collective
Control of subset assignment. Processes with the same color are in the same new communicator.
integer(kind=i32) function, public sll_f_get_collective_size(col)
Determines the size of the group associated with a communicator.
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.
Selalib periodic 2D maxwell solver for cartesian coordinates.
subroutine, public sll_s_delete_maxwell_2d_periodic_plan_cartesian_par(plan)
Delete maxwell solver object.
type(sll_t_maxwell_2d_periodic_plan_cartesian_par) function, pointer, public sll_f_new_maxwell_2d_periodic_plan_cartesian_par(layout_x, layout_y, ncx, ncy, Lx, Ly)
Presently, this function receives the geometric information as individual arguments....
subroutine, public sll_s_ampere_te(plan, dt, ex, ey, jx, jy)
Solve Ampere-Maxwell equation (TE mode)
subroutine faraday_tm(plan, dt, bx, by)
Solve Ampere-Maxwell equation (TE mode)
subroutine verify_argument_sizes_par(layout, array)
Check array size.
subroutine ampere_tm(plan, dt, bx, by, jz)
Solve Ampere-Maxwell equation (TE mode)
subroutine, public sll_s_faraday_te(plan, dt, ex, ey)
Solve faraday equation (TE mode)
Some common numerical utilities.
logical function, public sll_f_is_power_of_two(n)
Check if an integer is equal to.
Type for FFT plan in SeLaLib.
    Report Typos and Errors