9 #include "sll_assert.h"
10 #include "sll_memory.h"
11 #include "sll_working_precision.h"
29 use sll_m_remapper,
only: &
30 sll_o_apply_remap_3d, &
31 sll_o_compute_local_sizes, &
32 sll_o_get_layout_collective, &
33 sll_o_initialize_layout_with_distributed_array, &
35 sll_o_local_to_global, &
36 sll_f_new_layout_3d, &
37 sll_o_new_remap_plan, &
38 sll_t_remap_plan_3d_comp64, &
39 sll_t_remap_plan_3d_real64, &
41 sll_s_factorize_in_two_powers_of_two
49 #define OMP_COLLAPSE collapse(2)
50 #define OMP_SCHEDULE schedule(static)
86 type(sll_t_layout_3d),
pointer :: layout_split
87 type(sll_t_layout_3d),
pointer :: layout_x
88 type(sll_t_layout_3d),
pointer :: layout_y
89 type(sll_t_layout_3d),
pointer :: layout_z
91 sll_int32,
dimension(3, 3) :: loc_sizes
92 sll_comp64,
dimension(:, :, :),
pointer :: array_x
93 sll_comp64,
dimension(:, :, :),
pointer :: array_y
94 sll_comp64,
dimension(:, :, :),
pointer :: array_z
95 sll_comp64,
dimension(:, :, :),
pointer :: array_z1
96 sll_comp64,
dimension(:, :, :),
pointer :: array_z2
97 sll_comp64,
allocatable :: array1d_x(:)
98 sll_comp64,
allocatable :: array1d_y(:)
99 sll_comp64,
allocatable :: array1d_z(:)
100 sll_real64,
allocatable :: phi_x1(:, :, :)
101 sll_real64,
allocatable :: phi_x2(:, :, :)
102 sll_real64,
allocatable :: phi_x3(:, :, :)
103 sll_real64,
allocatable :: ex_x1(:, :, :)
104 sll_real64,
allocatable :: ey_x2(:, :, :)
105 sll_real64,
allocatable :: ez_x3(:, :, :)
107 type(sll_t_remap_plan_3d_comp64),
pointer :: rmp3_xy
108 type(sll_t_remap_plan_3d_comp64),
pointer :: rmp3_yz
109 type(sll_t_remap_plan_3d_comp64),
pointer :: rmp3_zy
110 type(sll_t_remap_plan_3d_comp64),
pointer :: rmp3_yx
111 type(sll_t_remap_plan_3d_real64),
pointer :: rmp_x1_to_split
112 type(sll_t_remap_plan_3d_real64),
pointer :: rmp_split_to_x1
113 type(sll_t_remap_plan_3d_real64),
pointer :: rmp_x2_to_split
114 type(sll_t_remap_plan_3d_real64),
pointer :: rmp_x3_to_split
115 type(sll_t_remap_plan_3d_real64),
pointer :: rmp_x1_to_x2
116 type(sll_t_remap_plan_3d_real64),
pointer :: rmp_x2_to_x3
117 type(sll_t_remap_plan_3d_real64),
pointer :: rmp_x3_to_x1
140 type(sll_t_layout_3d),
pointer,
intent(in) :: start_layout
141 sll_int32,
intent(in) :: ncx
142 sll_int32,
intent(in) :: ncy
143 sll_int32,
intent(in) :: ncz
144 sll_real64,
intent(in) :: lx
145 sll_real64,
intent(in) :: ly
146 sll_real64,
intent(in) :: lz
155 sll_int32 :: npx, npy, npz
157 sll_int32,
dimension(3, 3) :: loc_sizes
158 sll_real64,
allocatable :: tmp(:, :, :)
160 collective => sll_o_get_layout_collective(start_layout)
163 if (int(colsz, i32) > min(ncx*ncy, ncy*ncz, ncz*ncx))
then
164 print *,
'This test needs to run in a number of processes which', &
165 ' is less than or equal', min(ncx*ncy, ncy*ncz, ncz*ncx),
' in order to ', &
166 'be able properly split the arrays.'
167 print *,
'Exiting...'
178 plan%dx = lx/real(ncx, f64)
179 plan%dy = ly/real(ncy, f64)
180 plan%dz = lz/real(ncz, f64)
193 plan%layout_split => start_layout
196 plan%layout_x => sll_f_new_layout_3d(collective)
198 call sll_s_factorize_in_two_powers_of_two(int(colsz, i32), npy, npz)
200 call sll_o_initialize_layout_with_distributed_array( &
208 call sll_o_compute_local_sizes( &
215 plan%layout_y => sll_f_new_layout_3d(collective)
218 call sll_o_initialize_layout_with_distributed_array( &
227 call sll_o_compute_local_sizes( &
234 plan%layout_z => sll_f_new_layout_3d(collective)
238 call sll_o_initialize_layout_with_distributed_array( &
247 call sll_o_compute_local_sizes( &
253 plan%loc_sizes = loc_sizes
255 sll_allocate(plan%array_x(loc_sizes(1, 1), loc_sizes(1, 2), loc_sizes(1, 3)), ierr)
256 sll_allocate(plan%array_y(loc_sizes(2, 1), loc_sizes(2, 2), loc_sizes(2, 3)), ierr)
257 sll_allocate(plan%array_z(loc_sizes(3, 1), loc_sizes(3, 2), loc_sizes(3, 3)), ierr)
258 sll_allocate(plan%array_z1(loc_sizes(3, 1), loc_sizes(3, 2), loc_sizes(3, 3)), ierr)
259 sll_allocate(plan%array_z2(loc_sizes(3, 1), loc_sizes(3, 2), loc_sizes(3, 3)), ierr)
261 allocate (plan%array1d_x(loc_sizes(1, 1)))
262 allocate (plan%array1d_y(loc_sizes(2, 2)))
263 allocate (plan%array1d_z(loc_sizes(3, 3)))
265 plan%rmp3_xy => sll_o_new_remap_plan(plan%layout_x, plan%layout_y, plan%array_x)
266 plan%rmp3_yz => sll_o_new_remap_plan(plan%layout_y, plan%layout_z, plan%array_y)
267 plan%rmp3_zy => sll_o_new_remap_plan(plan%layout_z, plan%layout_y, plan%array_z)
268 plan%rmp3_yx => sll_o_new_remap_plan(plan%layout_y, plan%layout_x, plan%array_y)
270 sll_allocate(plan%phi_x1(loc_sizes(1, 1), loc_sizes(1, 2), loc_sizes(1, 3)), ierr)
271 sll_allocate(plan%phi_x2(loc_sizes(2, 1), loc_sizes(2, 2), loc_sizes(2, 3)), ierr)
272 sll_allocate(plan%phi_x3(loc_sizes(3, 1), loc_sizes(3, 2), loc_sizes(3, 3)), ierr)
273 sll_allocate(plan%ex_x1(loc_sizes(1, 1), loc_sizes(1, 2), loc_sizes(1, 3)), ierr)
274 sll_allocate(plan%ey_x2(loc_sizes(2, 1), loc_sizes(2, 2), loc_sizes(2, 3)), ierr)
275 sll_allocate(plan%ez_x3(loc_sizes(3, 1), loc_sizes(3, 2), loc_sizes(3, 3)), ierr)
277 plan%rmp_x1_to_split => sll_o_new_remap_plan(plan%layout_x, plan%layout_split, plan%ex_x1)
278 plan%rmp_x2_to_split => sll_o_new_remap_plan(plan%layout_y, plan%layout_split, plan%ey_x2)
279 plan%rmp_x3_to_split => sll_o_new_remap_plan(plan%layout_z, plan%layout_split, plan%ez_x3)
280 plan%rmp_x1_to_x2 => sll_o_new_remap_plan(plan%layout_x, plan%layout_y, plan%ex_x1)
281 plan%rmp_x2_to_x3 => sll_o_new_remap_plan(plan%layout_y, plan%layout_z, plan%ey_x2)
282 plan%rmp_x3_to_x1 => sll_o_new_remap_plan(plan%layout_z, plan%layout_x, plan%ez_x3)
284 call sll_o_compute_local_sizes( &
290 sll_allocate(tmp(loc_sizes(1, 1), loc_sizes(1, 2), loc_sizes(1, 3)), ierr)
291 plan%rmp_split_to_x1 => sll_o_new_remap_plan(plan%layout_split, plan%layout_x, tmp)
299 sll_real64,
dimension(:, :, :) :: rho
300 sll_real64,
dimension(:, :, :) :: phi
301 sll_int32 :: nx, ny, nz
303 sll_int32 :: nx_loc, ny_loc, nz_loc
304 sll_int32 :: i, j, k, ijk(3)
305 sll_real64 :: lx, ly, lz
306 sll_real64 :: kx0, ky0, kz0
307 sll_real64 :: kx, ky, kz
308 sll_real64 :: ind_x, ind_y, ind_z
309 sll_real64 :: nxyz_inv
310 type(sll_t_layout_3d),
pointer :: layout_x, layout_y, layout_z
311 sll_int32,
dimension(1:3) :: global
312 sll_int32 :: gi, gj, gk
313 sll_comp64,
allocatable :: stripe(:)
326 nxyz_inv = 1.0_f64/real(nx*ny*nz, f64)
329 layout_x => plan%layout_x
330 layout_y => plan%layout_y
331 layout_z => plan%layout_z
337 nx_loc = plan%loc_sizes(1, 1)
338 ny_loc = plan%loc_sizes(1, 2)
339 nz_loc = plan%loc_sizes(1, 3)
340 call sll_o_apply_remap_3d(plan%rmp_split_to_x1, rho, plan%ex_x1)
343 allocate (stripe(nx_loc))
347 stripe = cmplx(plan%ex_x1(:, j, k), 0_f64, kind=f64)
349 plan%array_x(:, j, k) = stripe
357 nx_loc = plan%loc_sizes(2, 1)
358 ny_loc = plan%loc_sizes(2, 2)
359 nz_loc = plan%loc_sizes(2, 3)
360 call sll_o_apply_remap_3d(plan%rmp3_xy, plan%array_x, plan%array_y)
363 allocate (stripe(ny_loc))
367 stripe = plan%array_y(i, :, k)
369 plan%array_y(i, :, k) = stripe
377 nx_loc = plan%loc_sizes(3, 1)
378 ny_loc = plan%loc_sizes(3, 2)
379 nz_loc = plan%loc_sizes(3, 3)
380 call sll_o_apply_remap_3d(plan%rmp3_yz, plan%array_y, plan%array_z)
383 allocate (stripe(nz_loc))
387 stripe = plan%array_z(i, j, :)
389 plan%array_z(i, j, :) = stripe*cmplx(nxyz_inv, 0.0_f64, kind=f64)
411 global = sll_o_local_to_global(layout_z, ijk)
415 if ((gi == 1) .and. (gj == 1) .and. (gk == 1))
then
416 plan%array_z(1, 1, 1) = (0.0_f64, 0.0_f64)
419 ind_x = real(gi - 1, f64)
421 ind_x = real(nx - (gi - 1), f64)
424 ind_y = real(gj - 1, f64)
426 ind_y = real(ny - (gj - 1), f64)
429 ind_z = real(gk - 1, f64)
431 ind_z = real(nz - (gk - 1), f64)
436 plan%array_z(i, j, k) = plan%array_z(i, j, k)/ &
437 cmplx(kx**2 + ky**2 + kz**2, 0.0_f64, kind=f64)
447 allocate (stripe(nz_loc))
451 stripe = plan%array_z(i, j, :)
453 plan%array_z(i, j, :) = stripe
461 nx_loc = plan%loc_sizes(2, 1)
462 ny_loc = plan%loc_sizes(2, 2)
463 nz_loc = plan%loc_sizes(2, 3)
464 call sll_o_apply_remap_3d(plan%rmp3_zy, plan%array_z, plan%array_y)
467 allocate (stripe(ny_loc))
471 stripe = plan%array_y(i, :, k)
473 plan%array_y(i, :, k) = stripe
481 nx_loc = plan%loc_sizes(1, 1)
482 ny_loc = plan%loc_sizes(1, 2)
483 nz_loc = plan%loc_sizes(1, 3)
484 call sll_o_apply_remap_3d(plan%rmp3_yx, plan%array_y, plan%array_x)
487 allocate (stripe(nx_loc))
491 stripe = plan%array_x(:, j, k)
493 phi(:, j, k) = real(stripe, f64)
679 nx_loc = plan%loc_sizes(1, 1)
680 ny_loc = plan%loc_sizes(1, 2)
681 nz_loc = plan%loc_sizes(1, 3)
682 call sll_o_apply_remap_3d(plan%rmp_split_to_x1, rho, plan%ex_x1)
685 plan%array1d_x = cmplx(plan%ex_x1(:, j, k), 0_f64, kind=f64)
687 plan%array_x(:, j, k) = plan%array1d_x
692 nx_loc = plan%loc_sizes(2, 1)
693 ny_loc = plan%loc_sizes(2, 2)
694 nz_loc = plan%loc_sizes(2, 3)
695 call sll_o_apply_remap_3d(plan%rmp3_xy, plan%array_x, plan%array_y)
698 plan%array1d_y = plan%array_y(i, :, k)
700 plan%array_y(i, :, k) = plan%array1d_y
705 nx_loc = plan%loc_sizes(3, 1)
706 ny_loc = plan%loc_sizes(3, 2)
707 nz_loc = plan%loc_sizes(3, 3)
708 call sll_o_apply_remap_3d(plan%rmp3_yz, plan%array_y, plan%array_z)
711 plan%array1d_z = plan%array_z(i, j, :)
713 plan%array_z(i, j, :) = plan%array1d_z
718 plan%array_z = plan%array_z/cmplx(nx*ny*nz, 0.0_f64, f64)
727 global = sll_o_local_to_global(layout_z, ijk)
728 global = sll_o_local_to_global(layout_z, (/i, j, k/))
732 if ((gi == 1) .and. (gj == 1) .and. (gk == 1))
then
733 plan%array_z(1, 1, 1) = (0.0_f64, 0.0_f64)
736 ind_x = real(gi - 1, f64)
738 ind_x = real(nx - (gi - 1), f64)
741 ind_y = real(gj - 1, f64)
743 ind_y = real(ny - (gj - 1), f64)
746 ind_z = real(gk - 1, f64)
748 ind_z = real(nz - (gk - 1), f64)
753 plan%array_z(i, j, k) = plan%array_z(i, j, k)/ &
754 cmplx(kx**2 + ky**2 + kz**2, 0.0_f64, kind=f64)
763 plan%array1d_z = plan%array_z(i, j, :)
765 plan%array_z(i, j, :) = plan%array1d_z
770 nx_loc = plan%loc_sizes(2, 1)
771 ny_loc = plan%loc_sizes(2, 2)
772 nz_loc = plan%loc_sizes(2, 3)
773 call sll_o_apply_remap_3d(plan%rmp3_zy, plan%array_z, plan%array_y)
776 plan%array1d_y = plan%array_y(i, :, k)
778 plan%array_y(i, :, k) = plan%array1d_y
783 nx_loc = plan%loc_sizes(1, 1)
784 ny_loc = plan%loc_sizes(1, 2)
785 nz_loc = plan%loc_sizes(1, 3)
786 call sll_o_apply_remap_3d(plan%rmp3_yx, plan%array_y, plan%array_x)
789 plan%array1d_x = plan%array_x(:, j, k)
791 plan%array_x(:, j, k) = plan%array1d_x
794 phi = real(plan%array_x, f64)
803 sll_real64,
dimension(:, :, :) :: rho
804 sll_real64,
dimension(:, :, :) :: ex
805 sll_real64,
dimension(:, :, :) :: ey
806 sll_real64,
dimension(:, :, :) :: ez
807 sll_int32 :: nx, ny, nz
809 sll_int32 :: nx_loc, ny_loc, nz_loc
811 sll_real64 :: lx, ly, lz
812 sll_real64 :: kx0, ky0, kz0
813 sll_real64 :: kx, ky, kz
814 sll_real64 :: ind_x, ind_y, ind_z
815 type(sll_t_layout_3d),
pointer :: layout_x
816 type(sll_t_layout_3d),
pointer :: layout_y
817 type(sll_t_layout_3d),
pointer :: layout_z
818 sll_int32,
dimension(1:3) :: global
819 sll_int32 :: gi, gj, gk
834 layout_x => plan%layout_x
835 layout_y => plan%layout_y
836 layout_z => plan%layout_z
838 call sll_o_apply_remap_3d(plan%rmp_split_to_x1, rho, plan%ex_x1)
843 nx_loc = plan%loc_sizes(1, 1)
844 ny_loc = plan%loc_sizes(1, 2)
845 nz_loc = plan%loc_sizes(1, 3)
849 plan%array1d_x = cmplx(plan%ex_x1(:, j, k), 0_f64, kind=f64)
852 plan%array_x(:, j, k) = plan%array1d_x
857 nx_loc = plan%loc_sizes(2, 1)
858 ny_loc = plan%loc_sizes(2, 2)
859 nz_loc = plan%loc_sizes(2, 3)
860 call sll_o_apply_remap_3d(plan%rmp3_xy, plan%array_x, plan%array_y)
863 plan%array1d_y = plan%array_y(i, :, k)
865 plan%array_y(i, :, k) = plan%array1d_y
870 nx_loc = plan%loc_sizes(3, 1)
871 ny_loc = plan%loc_sizes(3, 2)
872 nz_loc = plan%loc_sizes(3, 3)
873 call sll_o_apply_remap_3d(plan%rmp3_yz, plan%array_y, plan%array_z)
876 plan%array1d_z = plan%array_z(i, j, :)
878 plan%array_z(i, j, :) = plan%array1d_z
883 plan%array_z = plan%array_z/cmplx(nx*ny*nz, 0.0_f64, f64)
889 global = sll_o_local_to_global(layout_z, (/i, j, k/))
893 if ((gi == 1) .and. (gj == 1) .and. (gk == 1))
then
894 plan%array_z(1, 1, 1) = (0.0_f64, 0.0_f64)
895 plan%array_z1(1, 1, 1) = (0.0_f64, 0.0_f64)
896 plan%array_z2(1, 1, 1) = (0.0_f64, 0.0_f64)
899 ind_x = real(gi - 1, f64)
901 ind_x = real(nx - (gi - 1), f64)
904 ind_y = real(gj - 1, f64)
906 ind_y = real(ny - (gj - 1), f64)
909 ind_z = real(gk - 1, f64)
911 ind_z = real(nz - (gk - 1), f64)
916 plan%array_z(i, j, k) = plan%array_z(i, j, k)/cmplx(kx**2 + ky**2 + kz**2, 0.0_f64, kind=f64)
921 kxi = cmplx(0.0_f64, -kz0*real(i - 1, f64), kind=f64)
922 plan%array_z(i, j, k) = kxi*plan%array_z(i, j, k)/ &
923 cmplx(nz*(nz/2 - 1), 0.0_f64, kind=f64)
934 plan%array1d_z = plan%array_z(i, j, :)
939 plan%array_z(i, j, :) = plan%array1d_z
944 nx_loc = plan%loc_sizes(2, 1)
945 ny_loc = plan%loc_sizes(2, 2)
946 nz_loc = plan%loc_sizes(2, 3)
947 call sll_o_apply_remap_3d(plan%rmp3_zy, plan%array_z, plan%array_y)
950 plan%array1d_y = plan%array_y(i, :, k)
955 plan%array_y(i, :, k) = plan%array1d_y
960 nx_loc = plan%loc_sizes(1, 1)
961 ny_loc = plan%loc_sizes(1, 2)
962 nz_loc = plan%loc_sizes(1, 3)
963 call sll_o_apply_remap_3d(plan%rmp3_yx, plan%array_y, plan%array_x)
966 plan%array1d_x = plan%array_x(:, j, k)
971 plan%array_x(:, j, k) = plan%array1d_x
977 call sll_o_apply_remap_3d(plan%rmp_x1_to_split, real(plan%array_x, f64), ez)
983 sll_real64,
intent(in) :: phi(:, :, :)
984 sll_real64,
intent(out) :: ex(:, :, :)
985 sll_real64,
intent(out) :: ey(:, :, :)
986 sll_real64,
intent(out) :: ez(:, :, :)
992 call sll_o_apply_remap_3d(plan%rmp_x1_to_split, plan%ex_x1, ex)
994 call sll_o_apply_remap_3d(plan%rmp_x1_to_x2, phi, plan%phi_x2)
996 call sll_o_apply_remap_3d(plan%rmp_x2_to_split, plan%ey_x2, ey)
998 call sll_o_apply_remap_3d(plan%rmp_x2_to_x3, plan%phi_x2, plan%phi_x3)
1000 call sll_o_apply_remap_3d(plan%rmp_x3_to_split, plan%ez_x3, ez)
1006 sll_real64,
intent(in) :: phi(:, :, :)
1007 sll_real64,
intent(out) :: ex(:, :, :)
1008 sll_real64,
intent(out) :: ey(:, :, :)
1009 sll_real64,
intent(out) :: ez(:, :, :)
1015 call sll_o_apply_remap_3d(plan%rmp_x3_to_split, plan%ez_x3, ez)
1017 call sll_o_apply_remap_3d(plan%rmp_x3_to_x1, phi, plan%phi_x1)
1019 call sll_o_apply_remap_3d(plan%rmp_x1_to_split, plan%ex_x1, ex)
1021 call sll_o_apply_remap_3d(plan%rmp_x1_to_x2, plan%phi_x1, plan%phi_x2)
1023 call sll_o_apply_remap_3d(plan%rmp_x2_to_split, plan%ey_x2, ey)
1039 call sll_o_delete(plan%layout_x)
1040 call sll_o_delete(plan%layout_y)
1041 call sll_o_delete(plan%layout_z)
1043 sll_deallocate_array(plan%array_x, ierr)
1044 sll_deallocate_array(plan%array_y, ierr)
1045 sll_deallocate_array(plan%array_z, ierr)
1050 type(sll_t_layout_3d),
pointer :: layout
1051 sll_real64,
dimension(:, :, :) :: rho
1052 sll_real64,
dimension(:, :, :) :: phi
1053 sll_int32,
dimension(3) :: n
1056 call sll_o_compute_local_sizes(layout, n(1), n(2), n(3))
1059 if ((n(i) /=
size(rho, i)) .or. (n(i) /=
size(phi, i)))
then
1060 print *,
'Input sizes passed to sll_s_poisson_3d_periodic_par_solve do not match'
1062 print *,
'Input sizes passed to "sll_s_poisson_3d_periodic_par_solve" ', &
1063 'do not match in direction x'
1064 elseif (i == 2)
then
1065 print *,
'Input sizes passed to "sll_s_poisson_3d_periodic_par_solve" ', &
1066 'do not match in direction y'
1068 print *,
'Input sizes passed to "sll_s_poisson_3d_periodic_par_solve" ', &
1069 'do not match in direction z'
1071 print *,
'Exiting...'
1081 sll_real64,
dimension(:, :, :),
intent(in) :: phi
1082 sll_real64,
dimension(:, :, :),
intent(out) :: ex
1085 sll_int32 :: nx_loc, ny_loc, nz_loc
1086 sll_int32 :: i, j, k
1088 sll_comp64 :: norm_fac
1089 sll_comp64,
allocatable :: stripe(:)
1094 norm_fac = cmplx(1.0_f64/real(nx, f64), 0.0_f64, f64)
1096 nx_loc = plan%loc_sizes(1, 1)
1097 ny_loc = plan%loc_sizes(1, 2)
1098 nz_loc = plan%loc_sizes(1, 3)
1105 allocate (stripe(nx_loc))
1109 stripe = cmplx(phi(:, j, k), 0_f64, kind=f64)
1112 stripe(i) = stripe(i)*cmplx(0_f64, -kx0*real(i - 1, f64), kind=f64) &
1115 do i = nx_loc/2 + 1, nx_loc
1116 stripe(i) = stripe(i)*cmplx(0_f64, kx0*real(nx - i + 1, f64), kind=f64) &
1120 ex(:, j, k) = real(stripe, f64)
1130 plan%array1d_x = cmplx(phi(:, j, k), 0_f64, kind=f64)
1133 plan%array_x(i, j, k) = plan%array1d_x(i)* &
1134 cmplx(0_f64, -kx0*real(i - 1, f64), kind=f64) &
1137 do i = nx_loc/2 + 1, nx_loc
1138 plan%array_x(i, j, k) = plan%array1d_x(i)* &
1139 cmplx(0_f64, kx0*real(nx - i + 1, f64), kind=f64) &
1146 plan%array1d_x = plan%array_x(:, j, k)
1151 plan%array_x(:, j, k) = plan%array1d_x
1154 ex = real(plan%array_x, f64)
1162 sll_real64,
dimension(:, :, :),
intent(in) :: phi
1163 sll_real64,
dimension(:, :, :),
intent(out) :: ey
1166 sll_int32 :: nx_loc, ny_loc, nz_loc
1167 sll_int32 :: i, j, k
1169 sll_comp64 :: norm_fac
1170 sll_comp64,
allocatable :: stripe(:)
1175 norm_fac = cmplx(1.0_f64/real(ny, f64), 0.0_f64, f64)
1177 nx_loc = plan%loc_sizes(2, 1)
1178 ny_loc = plan%loc_sizes(2, 2)
1179 nz_loc = plan%loc_sizes(2, 3)
1187 allocate (stripe(ny_loc))
1191 stripe = cmplx(phi(i, :, k), 0_f64, kind=f64)
1194 stripe(j) = stripe(j)*cmplx(0_f64, -ky0*real(j - 1, f64), kind=f64) &
1197 do j = ny_loc/2 + 1, ny_loc
1198 stripe(j) = stripe(j)*cmplx(0_f64, ky0*real(ny - j + 1, f64), kind=f64) &
1202 ey(i, :, k) = real(stripe, f64)
1212 plan%array1d_y = cmplx(phi(i, :, k), 0_f64, kind=f64)
1215 plan%array_y(i, j, k) = plan%array1d_y(j) &
1216 *cmplx(0_f64, -ky0*real(j - 1, f64), kind=f64) &
1219 do j = ny_loc/2 + 1, ny_loc
1220 plan%array_y(i, j, k) = plan%array1d_y(j) &
1221 *cmplx(0_f64, ky0*real(ny - j + 1, f64), kind=f64) &
1228 plan%array1d_y = plan%array_y(i, :, k)
1233 plan%array_y(i, :, k) = plan%array1d_y
1236 ey = real(plan%array_y, f64)
1244 sll_real64,
dimension(:, :, :),
intent(in) :: phi
1245 sll_real64,
dimension(:, :, :),
intent(out) :: ez
1248 sll_int32 :: nx_loc, ny_loc, nz_loc
1249 sll_int32 :: i, j, k
1251 sll_comp64 :: norm_fac
1252 sll_comp64,
allocatable :: stripe(:)
1257 norm_fac = cmplx(1.0_f64/real(nz, f64), 0.0_f64, f64)
1259 nx_loc = plan%loc_sizes(3, 1)
1260 ny_loc = plan%loc_sizes(3, 2)
1261 nz_loc = plan%loc_sizes(3, 3)
1269 allocate (stripe(nz_loc))
1273 stripe = cmplx(phi(i, j, :), 0_f64, kind=f64)
1276 stripe(k) = stripe(k) &
1277 *cmplx(0_f64, -kz0*real(k - 1, f64), kind=f64)*norm_fac
1279 do k = nz_loc/2 + 1, nz_loc
1280 stripe(k) = stripe(k) &
1281 *cmplx(0_f64, kz0*real(nz - k + 1, f64), kind=f64)*norm_fac
1284 ez(i, j, :) = real(stripe, f64)
1294 plan%array1d_z = cmplx(phi(i, j, :), 0_f64, kind=f64)
1297 plan%array_z(i, j, k) = plan%array1d_z(k) &
1298 *cmplx(0_f64, -kz0*real(k - 1, f64), kind=f64) &
1301 do k = nz_loc/2 + 1, nz_loc
1302 plan%array_z(i, j, k) = plan%array1d_z(k) &
1303 *cmplx(0_f64, kz0*real(nz - k + 1, f64), kind=f64) &
1310 plan%array1d_z = plan%array_z(i, j, :)
1315 plan%array_z(i, j, :) = plan%array1d_z
1318 ez = real(plan%array_z, f64)
1330 sll_real64,
intent(in) :: phi_x1(:, :, :)
1331 sll_real64,
intent(out) :: efield_x1(:, :, :)
1334 sll_int32 :: num_pts_x1
1338 sll_real64 :: r_delta
1342 num_pts_x1 = plan%loc_sizes(1, 1)
1344 r_delta = 1.0_f64/plan%dx
1347 do k = 1, plan%loc_sizes(1, 3)
1348 do j = 1, plan%loc_sizes(1, 2)
1350 ex = r_delta*(-1.5_f64*phi_x1(1, j, k) + &
1351 2.0_f64*phi_x1(2, j, k) - &
1352 0.5_f64*phi_x1(3, j, k))
1353 efield_x1(1, j, k) = -ex
1355 ex = r_delta*(0.5_f64*phi_x1(num_pts_x1 - 2, j, k) - &
1356 2.0_f64*phi_x1(num_pts_x1 - 1, j, k) + &
1357 1.5_f64*phi_x1(num_pts_x1, j, k))
1358 efield_x1(num_pts_x1, j, k) = -ex
1363 do k = 1, plan%loc_sizes(1, 3)
1364 do j = 1, plan%loc_sizes(1, 2)
1365 do i = 2, num_pts_x1 - 1
1366 ex = r_delta*0.5_f64*(phi_x1(i + 1, j, k) - phi_x1(i - 1, j, k))
1367 efield_x1(i, j, k) = -ex
1380 sll_real64,
intent(in) :: phi_x2(:, :, :)
1381 sll_real64,
intent(out) :: efield_x2(:, :, :)
1384 sll_int32 :: num_pts_x2
1388 sll_real64 :: r_delta
1392 num_pts_x2 = plan%loc_sizes(2, 2)
1393 r_delta = 1.0_f64/plan%dy
1396 do k = 1, plan%loc_sizes(2, 3)
1397 do i = 1, plan%loc_sizes(2, 1)
1399 ey = r_delta*(-1.5_f64*phi_x2(i, 1, k) + 2.0_f64*phi_x2(i, 2, k) - &
1400 0.5_f64*phi_x2(i, 3, k))
1401 efield_x2(i, 1, k) = -ey
1403 ey = r_delta*(0.5_f64*phi_x2(i, num_pts_x2 - 2, k) - &
1404 2.0_f64*phi_x2(i, num_pts_x2 - 1, k) + &
1405 1.5_f64*phi_x2(i, num_pts_x2, k))
1406 efield_x2(i, num_pts_x2, k) = -ey
1411 do k = 1, plan%loc_sizes(2, 3)
1412 do j = 2, num_pts_x2 - 1
1413 do i = 1, plan%loc_sizes(2, 1)
1414 ey = r_delta*0.5_f64*(phi_x2(i, j + 1, k) - phi_x2(i, j - 1, k))
1415 efield_x2(i, j, k) = -ey
1428 sll_real64,
intent(in) :: phi_x3(:, :, :)
1429 sll_real64,
intent(out) :: efield_x3(:, :, :)
1432 sll_int32 :: num_pts_x1
1433 sll_int32 :: num_pts_x2
1434 sll_int32 :: num_pts_x3
1438 sll_real64 :: r_delta
1442 num_pts_x1 = plan%loc_sizes(3, 1)
1443 num_pts_x2 = plan%loc_sizes(3, 2)
1444 num_pts_x3 = plan%loc_sizes(3, 3)
1446 r_delta = 1.0_f64/plan%dz
1449 do j = 1, num_pts_x2
1450 do i = 1, num_pts_x1
1451 ez = r_delta*(-1.5_f64*phi_x3(i, j, 1) + 2.0_f64*phi_x3(i, j, 2) - &
1452 0.5_f64*phi_x3(i, j, 3))
1453 efield_x3(i, j, 1) = -ez
1455 ez = r_delta*(0.5_f64*phi_x3(i, j, num_pts_x3 - 2) - &
1456 2.0_f64*phi_x3(i, j, num_pts_x3 - 1) + &
1457 1.5_f64*phi_x3(i, j, num_pts_x3))
1458 efield_x3(i, j, num_pts_x3) = -ez
1463 do k = 2, num_pts_x3 - 1
1464 do j = 1, num_pts_x2
1465 do i = 1, num_pts_x1
1466 ez = r_delta*0.5_f64*(phi_x3(i, j, k + 1) - phi_x3(i, j, k - 1))
1467 efield_x3(i, j, k) = -ez
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
real(kind=f64), parameter, public sll_p_twopi
subroutine, public sll_s_fft_free(plan)
Delete a plan.
integer, parameter, public sll_p_fft_forward
Flag to specify forward FFT (negative sign) [value -1].
subroutine, public sll_s_fft_exec_c2c_1d(plan, array_in, array_out)
Compute fast Fourier transform in complex to complex mode.
subroutine, public sll_s_fft_init_c2c_1d(plan, nx, array_in, array_out, direction, normalized, aligned, optimization)
Create new 1d complex to complex plan.
integer, parameter, public sll_p_fft_backward
Flag to specify backward FFT (positive sign) [value 1].
Periodic 3D poisson solver (parallel version)
subroutine, public sll_s_poisson_3d_periodic_par_solve(plan, rho, phi)
Compute the 3d potential from the Poisson equation with periodic boundary conditions.
subroutine sll_s_compute_ez_from_phi(plan, phi, ez)
Compute the 3d potential from the Poisson equation with periodic boundary conditions.
subroutine, public sll_s_poisson_3d_periodic_par_free(plan)
Delete the solver structure.
subroutine, public sll_s_poisson_3d_periodic_par_compute_e_from_phi_layoutseq3(plan, phi, ex, ey, ez)
Compute the electric fields from the potential (phi sequential along x3)
subroutine sll_s_compute_ey_from_phi(plan, phi, ey)
Compute the 3d potential from the Poisson equation with periodic boundary conditions.
subroutine sll_s_compute_ex_from_phi(plan, phi, ex)
Compute the 3d potential from the Poisson equation with periodic boundary conditions.
subroutine, public sll_s_poisson_3d_periodic_par_init(start_layout, ncx, ncy, ncz, Lx, Ly, Lz, plan)
Allocate the structure for the 3d parallel Poisson solver.
subroutine compute_electric_field_x3_3d(plan, phi_x3, efield_x3)
logical, parameter use_openmp_threading
subroutine sll_s_poisson_3d_periodic_par_solve_e(plan, rho, ex, ey, ez)
Compute the electric fields from the potential (phi sequential along x1) Compute the 3d potential fro...
subroutine compute_electric_field_x1_3d(plan, phi_x1, efield_x1)
subroutine, public sll_s_poisson_3d_periodic_par_compute_e_from_phi(plan, phi, ex, ey, ez)
subroutine verify_argument_sizes_par(layout, rho, phi)
Check sizes of arrays in input.
subroutine compute_electric_field_x2_3d(plan, phi_x2, efield_x2)
Some common numerical utilities.
logical function, public sll_f_is_even(n)
Check if an integer is even.
logical function, public sll_f_is_power_of_two(n)
Check if an integer is equal to.
Wrapper around the communicator.
Type for FFT plan in SeLaLib.
Structure to solve Poisson equation on 3d mesh with periodic boundary conditions. Solver is parallel ...