24 use,
intrinsic :: iso_c_binding
39 use,
intrinsic :: iso_fortran_env
74 integer(C_INTPTR_T) :: N_local(3)
75 integer(C_INTPTR_T) :: N(3)
76 integer(C_INTPTR_T) :: Nos(3)
77 integer(C_INTPTR_T),
public :: M(3)
78 integer :: M_istart(3)
79 integer(C_INTPTR_T) :: local_M
81 real(real64),
public :: sigma
83 logical,
public :: set_defaults = .false.
85 real(real64),
public :: norm
88 type(MPI_Comm) :: comm
92 complex(C_DOUBLE_COMPLEX),
pointer :: f_lin(:) => null()
93 complex(C_DOUBLE_COMPLEX),
pointer :: f(:,:,:) => null()
94 complex(C_DOUBLE_COMPLEX),
pointer :: f_hat(:,:,:) => null()
95 real(C_DOUBLE),
pointer :: x_lin(:,:) => null()
96 real(C_DOUBLE),
pointer :: x(:,:,:,:) => null()
98 real(C_DOUBLE) :: lower_border(3)
99 real(C_DOUBLE) :: upper_border(3)
100 real(real64) :: lo_global(3)
101 real(real64) :: up_global(3)
109 type(pnfft_t),
intent(inout) :: pnfft
110 type(namespace_t),
intent(in) :: namespace
138 type(pnfft_t),
intent(inout) :: pnfft
139 type(pnfft_t),
intent(in) :: pnfft_options
140 integer,
intent(in) :: nn(3)
141 logical,
optional,
intent(in) :: optimize
143 integer :: ii, my_nn(3)
150 if (.not. pnfft%set_defaults)
then
152 pnfft%mm = pnfft_options%mm
153 pnfft%sigma = pnfft_options%sigma
158 my_nn(ii) = nn(ii)*int(pnfft%sigma)
162 pnfft%Nos(1:3) = my_nn(1:3)
165 pnfft%flags = pnfft_malloc_x + pnfft_malloc_f_hat + pnfft_malloc_f + &
166 pnfft_window_kaiser_bessel
177 type(mpi_comm),
intent(out):: comm
192 ierror = pnfft_create_procmesh(2, mpi_grp%comm%MPI_VAL, pnfft%np, comm%MPI_VAL)
198 if (ierror /= 0)
then
199 message(1) =
"The number of rows and columns in PNFFT processor grid is not equal to "
200 message(2) =
"the number of processor in the MPI communicator."
211 type(
pnfft_t),
intent(in) :: in
212 type(
pnfft_t),
intent(out) :: out
219 out%set_defaults = in%set_defaults
226 type(
pnfft_t),
intent(in) :: pnfft
268 subroutine pnfft_init_plan(pnfft, pnfft_options, comm, fs_n_global, fs_n, fs_istart, rs_n, rs_istart)
269 type(
pnfft_t),
intent(inout) :: pnfft
270 type(
pnfft_t),
intent(inout) :: pnfft_options
271 type(mpi_comm),
intent(in) :: comm
272 integer,
intent(in) :: fs_n_global(1:3)
273 integer,
intent(out) :: fs_n(1:3)
274 integer,
intent(out) :: fs_istart(1:3)
275 integer,
intent(out) :: rs_n(1:3)
276 integer,
intent(out) :: rs_istart(1:3)
278 real(c_double) :: lower_border(3), upper_border(3)
279 real(c_double) :: x_max(3)
280 integer(C_INTPTR_T) :: local_n(3), local_n_start(3), d=3, local_m
281 type(c_ptr) :: cf_hat, cf, cx
286 pnfft%N(1:3) = fs_n_global(1:3)
290 x_max(:) = 0.4_real64
293 call pnfft_local_size_guru(3, pnfft%N, pnfft%Nos, x_max, pnfft%mm, comm%MPI_VAL, &
294 pnfft_transposed_f_hat, local_n, local_n_start, lower_border, upper_border)
304 pnfft%lower_border = lower_border
305 pnfft%upper_border = upper_border
306 pnfft%N_local(1:3) = local_n(1:3)
308 pnfft%M(1) = pnfft%N_local(2)
309 pnfft%M(2) = pnfft%N_local(3)
310 pnfft%M(3) = pnfft%N_local(1)
312 local_m = pnfft%M(1) * pnfft%M(2) * pnfft%M(3)
314 fs_n(1) = int(local_n(1))
315 fs_n(2) = int(local_n(3))
316 fs_n(3) = int(local_n(2))
317 fs_istart(1) = int(pnfft%N(1)/2 + local_n_start(1) + 1)
318 fs_istart(2) = int(pnfft%N(3)/2 + local_n_start(3) + 1)
319 fs_istart(3) = int(pnfft%N(2)/2 + local_n_start(2) + 1)
322 rs_n(1:3) = int(pnfft%M(1:3))
324 rs_istart(1) = fs_istart(3)
325 rs_istart(2) = fs_istart(2)
326 rs_istart(3) = fs_istart(1)
328 pnfft%M_istart(:) = rs_istart(:)
331 pnfft%plan = pnfft_init_guru(3, pnfft%N, pnfft%Nos, x_max, local_m, pnfft%mm, &
332 pnfft%flags, pfft_estimate, comm%MPI_VAL)
335 pnfft%local_M=local_m
339 cf_hat = pnfft_get_f_hat(pnfft%plan)
340 cf = pnfft_get_f(pnfft%plan)
341 cx = pnfft_get_x(pnfft%plan)
349 call c_f_pointer(cf_hat, pnfft%f_hat, [local_n(1),local_n(3),local_n(2)])
350 call c_f_pointer(cf, pnfft%f_lin, [pnfft%local_M])
351 call c_f_pointer(cf, pnfft%f, [pnfft%M(1),pnfft%M(2),pnfft%M(3)])
352 call c_f_pointer(cx, pnfft%x_lin, [d, pnfft%local_M])
353 call c_f_pointer(cx, pnfft%x, [d, pnfft%M(1),pnfft%M(2),pnfft%M(3)])
357 write(6,*)
mpi_world%rank,
"local_N(3) ", local_n
358 write(6,*)
mpi_world%rank,
"local_N_start(3) ", local_n_start
359 write(6,*)
mpi_world%rank,
"fs_istart(1:3) ", fs_istart
360 write(6,*)
mpi_world%rank,
"fs_n(1:3) ", fs_n
362 write(6,*)
mpi_world%rank,
"rs_n(1:3) ", rs_n
363 write(6,*)
mpi_world%rank,
"lower_border ", lower_border
364 write(6,*)
mpi_world%rank,
"upper_border ", upper_border
365 write(6,*)
mpi_world%rank,
"rs_range ", upper_border(:) - lower_border(:)
366 write(6,*)
mpi_world%rank,
"local_M ", local_m
367 write(6,*)
mpi_world%rank,
"pnfft%N_local ", pnfft%N_local
368 write(6,*)
mpi_world%rank,
"pnfft%M ", pnfft%M
369 write(6,*)
mpi_world%rank,
"pnfft%M_istart ", pnfft%M_istart
370 write(6,*)
mpi_world%rank,
"size(pnfft%f_hat)",
size(pnfft%f_hat,1),
size(pnfft%f_hat,2),
size(pnfft%f_hat, 3)
371 write(6,*)
mpi_world%rank,
"size(pnfft%f) ",
size(pnfft%f,1),
size(pnfft%f,2),
size(pnfft%f,3)
378 type(
pnfft_t),
intent(inout) :: pnfft
383 call pnfft_finalize(pnfft%plan, pnfft_free_x + pnfft_free_f_hat + pnfft_free_f)
402 type(
pnfft_t),
intent(inout) :: pnfft
404 real(real64),
intent(in) :: x(:,:)
406 real(real64) :: len(3), cc(3), eps,temp, lo(3), up(3)
407 integer :: ii, idir, i1, i2, i3
408 real(real64),
allocatable :: dx(:,:)
415 lo = pnfft%lower_border
416 up = pnfft%upper_border
421 len(:) = (maxval(x(:,idir))-minval(x(:,idir)))*eps
422 cc(:) = (minval(x(:,idir))+maxval(x(:,idir)))/
m_two
428 do i1 = 1, int(pnfft%M(1))
429 do i2 = 1, int(pnfft%M(2))
430 do i3 = 1, int(pnfft%M(3))
431 pnfft%x(1, i1,i2,i3) = (x(pnfft%M_istart(1)+i1-1, 1) - cc(1))/len(1)
432 pnfft%x(2, i1,i2,i3) = (x(pnfft%M_istart(2)+i2-1, 2) - cc(2))/len(2)
433 pnfft%x(3, i1,i2,i3) = (x(pnfft%M_istart(3)+i3-1, 3) - cc(3))/len(3)
450 temp = (x(pnfft%M_istart(3)+i3-1, 3) - cc(3))/len(3)
451 if (temp > pnfft%upper_border(3) .or. temp < pnfft%lower_border(3))
then
452 write(6,*)
mpi_world%rank,
"out of bounds x3 = ", temp,
"-- ", pnfft%lower_border(3), pnfft%upper_border(3)
458 temp = (x(pnfft%M_istart(2)+i2-1, 2) - cc(2))/len(2)
459 if (temp > pnfft%upper_border(2) .or. temp < pnfft%lower_border(2))
then
460 write(6,*)
mpi_world%rank,
"out of bounds x2 = ", temp,
"-- ", pnfft%lower_border(2), pnfft%upper_border(2)
465 temp = (x(pnfft%M_istart(1)+i1-1, 1) - cc(1))/len(1)
466 if (temp > pnfft%upper_border(1) .or. temp < pnfft%lower_border(1))
then
467 write(6,*)
mpi_world%rank,
"out of bounds x1 = ", temp,
"-- ", pnfft%lower_border(1), pnfft%upper_border(1)
483 safe_allocate( dx(1:maxval(pnfft%M(:))-1, 1:3))
488 do ii = 1,
size(x(:,idir))-1
489 dx(ii,idir)= abs(x(ii+1, idir)-x(ii, idir))
496 pnfft%norm =
m_one/(pnfft%N(1)*pnfft%N(2)*pnfft%N(3))
498 write(6,*)
mpi_world%rank,
"pnfft%norm", pnfft%norm
505 type(
pnfft_t),
intent(in) :: pnfft
508 integer :: nn, i1, i2, i3
510 character(len=3) :: filenum
520 call io_mkdir(
'debug/PNFFT', namespace)
523 call mpi_barrier(pnfft%comm, ierr)
527 write(filenum,
'(i3.3)') nn
529 iunit =
io_open(
'debug/PNFFT/rs_partition.'//filenum, &
530 namespace, action=
'write')
532 do i1 = 1, int(pnfft%M(1))
533 do i2 = 1, int(pnfft%M(2))
534 do i3 = 1, int(pnfft%M(3))
535 write(iunit,
'(3f18.8)') pnfft%x(1, i1,i2,i3), pnfft%x(2, i1,i2,i3), pnfft%x(3, i1,i2,i3)
560#include "pnfft_inc.F90"
563#include "complex.F90"
564#include "pnfft_inc.F90"
type(debug_t), save, public debug
real(real64), parameter, public m_two
real(real64), parameter, public m_zero
real(real64), parameter, public m_one
subroutine, public io_close(iunit, grp)
subroutine, public io_mkdir(fname, namespace, parents)
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
This module is intended to contain "only mathematical" functions and procedures.
subroutine, public messages_info(no_lines, iunit, verbose_limit, stress, all_nodes, namespace)
subroutine, public messages_new_line()
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
logical function mpi_grp_is_root(grp)
Is the current MPI process of grpcomm, root.
type(mpi_grp_t), public mpi_world
The low level module to work with the PFFT library. http:
subroutine, public pfft_decompose(n_proc, dim1, dim2)
Decompose all available processors in 2D processor grid, most equally possible.
The includes for the PFFT.
The low level module to work with the PNFFT library. http:
subroutine, public zpnfft_backward(pnfft, in, out)
subroutine, public pnfft_copy_params(in, out)
subroutine, public pnfft_set_sp_nodes(pnfft, namespace, X)
subroutine, public pnfft_init_plan(pnfft, pnfft_options, comm, fs_n_global, fs_n, fs_istart, rs_n, rs_istart)
subroutine pnfft_init_params(pnfft, pnfft_options, nn, optimize)
subroutine, public pnfft_write_info(pnfft)
subroutine, public pnfft_guru_options(pnfft, namespace)
subroutine, public pnfft_end(pnfft)
subroutine, public dpnfft_forward(pnfft, in, out)
subroutine, public zpnfft_forward(pnfft, in, out)
subroutine pnfft_messages_debug(pnfft, namespace)
subroutine, public dpnfft_backward(pnfft, in, out)
subroutine, public pnfft_init_procmesh(pnfft, mpi_grp, comm)
The includes for the PNFFT.
This is defined even when running serial.