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)
 
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.