LCOV - code coverage report
Current view: top level - src/pw - ps_wavelet_util.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:c24029e) Lines: 87.9 % 165 145
Test Date: 2026-07-04 06:36:57 Functions: 100.0 % 5 5

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Performs a wavelet based solution of the Poisson equation.
      10              : !> \author Florian Schiffmann (09.2007,fschiff)
      11              : ! **************************************************************************************************
      12              : MODULE ps_wavelet_util
      13              : 
      14              :    USE kinds,                           ONLY: dp
      15              :    USE mathconstants,                   ONLY: fourpi
      16              :    USE ps_wavelet_base,                 ONLY: f_poissonsolver,&
      17              :                                               p_poissonsolver,&
      18              :                                               s_poissonsolver
      19              :    USE ps_wavelet_fft3d,                ONLY: fourier_dim
      20              :    USE pw_grid_types,                   ONLY: pw_grid_type
      21              : #include "../base/base_uses.f90"
      22              : 
      23              :    IMPLICIT NONE
      24              : 
      25              :    PRIVATE
      26              : 
      27              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ps_wavelet_util'
      28              : 
      29              :    ! *** Public data types ***
      30              : 
      31              :    PUBLIC :: PSolver, &
      32              :              P_FFT_dimensions, &
      33              :              S_FFT_dimensions, &
      34              :              F_FFT_dimensions
      35              : 
      36              : CONTAINS
      37              : 
      38              : ! **************************************************************************************************
      39              : !> \brief Calculate the Poisson equation $\nabla^2 V(x,y,z)=-4 \pi \rho(x,y,z)$
      40              : !>     from a given $\rho$, for different boundary conditions an for different data distributions.
      41              : !>     Following the boundary conditions, it applies the Poisson Kernel previously calculated.
      42              : !> \param geocode Indicates the boundary conditions (BC) of the problem:
      43              : !>             'F' free BC, isolated systems.
      44              : !>                 The program calculates the solution as if the given density is
      45              : !>                 "alone" in R^3 space.
      46              : !>             'S' surface BC, isolated in y direction, periodic in xz plane
      47              : !>                 The given density is supposed to be periodic in the xz plane,
      48              : !>                 so the dimensions in these direction mus be compatible with the FFT
      49              : !>                 Beware of the fact that the isolated direction is y!
      50              : !>             'P' periodic BC.
      51              : !>                 The density is supposed to be periodic in all the three directions,
      52              : !>                 then all the dimensions must be compatible with the FFT.
      53              : !>                 No need for setting up the kernel.
      54              : !> \param iproc label of the process,from 0 to nproc-1
      55              : !> \param nproc number of processors
      56              : !> \param n01 global dimension in the three directions.
      57              : !> \param n02 global dimension in the three directions.
      58              : !> \param n03 global dimension in the three directions.
      59              : !> \param hx    grid spacings. For the isolated BC case for the moment they are supposed to
      60              : !>                 be equal in the three directions
      61              : !> \param hy grid spacings. For the isolated BC case for the moment they are supposed to
      62              : !>                 be equal in the three directions
      63              : !> \param hz grid spacings. For the isolated BC case for the moment they are supposed to
      64              : !>                 be equal in the three directions
      65              : !> \param rhopot main input/output array.
      66              : !>                 On input, it represents the density values on the grid points
      67              : !>                 On output, it is the Hartree potential, namely the solution of the Poisson
      68              : !>                 equation PLUS (when ixc/=0) the XC potential PLUS (again for ixc/=0) the
      69              : !>                 pot_ion array. The output is non overlapping, in the sense that it does not
      70              : !>                 consider the points that are related to gradient and WB calculation
      71              : !> \param karray kernel of the poisson equation. It is provided in distributed case, with
      72              : !>                 dimensions that are related to the output of the PS_dim4allocation routine
      73              : !>                 it MUST be created by following the same geocode as the Poisson Solver.
      74              : !> \param pw_grid ...
      75              : !> \date February 2007
      76              : !> \author Luigi Genovese
      77              : !> \note The dimensions of the arrays must be compatible with geocode, nproc,
      78              : !>     ixc and iproc. Since the arguments of these routines are indicated with the *, it
      79              : !>     is IMPERATIVE to use the PS_dim4allocation routine for calculation arrays sizes.
      80              : ! **************************************************************************************************
      81        33295 :    SUBROUTINE PSolver(geocode, iproc, nproc, n01, n02, n03, hx, hy, hz, &
      82              :                       rhopot, karray, pw_grid)
      83              :       CHARACTER(len=1), INTENT(in)                       :: geocode
      84              :       INTEGER, INTENT(in)                                :: iproc, nproc, n01, n02, n03
      85              :       REAL(KIND=dp), INTENT(in)                          :: hx, hy, hz
      86              :       REAL(KIND=dp), DIMENSION(*), INTENT(inout)         :: rhopot
      87              :       REAL(KIND=dp), DIMENSION(*), INTENT(in)            :: karray
      88              :       TYPE(pw_grid_type), POINTER                        :: pw_grid
      89              : 
      90              :       INTEGER                                            :: i1, i2, i3, iend, istart, j2, m1, m2, &
      91              :                                                             m3, md1, md2, md3, n1, n2, n3, nd1, &
      92              :                                                             nd2, nd3, nlim, nwb, nwbl, nwbr, nxc, &
      93              :                                                             nxcl, nxcr, nxt
      94              :       REAL(KIND=dp)                                      :: factor, hgrid, red_fact, scal
      95        33295 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: zf
      96              : 
      97              : !the order of the finite-difference gradient (fixed)
      98              : !calculate the dimensions wrt the geocode
      99              : 
     100        33295 :       IF (geocode == 'P') THEN
     101        17323 :          CALL P_FFT_dimensions(n01, n02, n03, m1, m2, m3, n1, n2, n3, md1, md2, md3, nd1, nd2, nd3, nproc)
     102        15972 :       ELSE IF (geocode == 'S') THEN
     103           54 :          CALL S_FFT_dimensions(n01, n02, n03, m1, m2, m3, n1, n2, n3, md1, md2, md3, nd1, nd2, nd3, nproc)
     104        15918 :       ELSE IF (geocode == 'F') THEN
     105        15918 :          CALL F_FFT_dimensions(n01, n02, n03, m1, m2, m3, n1, n2, n3, md1, md2, md3, nd1, nd2, nd3, nproc)
     106              :       ELSE
     107            0 :          CPABORT("PSolver: geometry code not admitted")
     108              :       END IF
     109              :       !array allocations
     110       166475 :       ALLOCATE (zf(md1, md3, md2/nproc))
     111              : 
     112              :       !  CALL timing(iproc,'Exchangecorr  ','ON')
     113              :       !dimension for exchange-correlation (different in the global or distributed case)
     114              :       !let us calculate the dimension of the portion of the rhopot array to be passed
     115              :       !to the xc routine
     116              :       !this portion will depend on the need of calculating the gradient or not,
     117              :       !and whether the White-Bird correction must be inserted or not
     118              :       !(absent only in the LB ixc=13 case)
     119              : 
     120              :       !nxc is the effective part of the third dimension that is being processed
     121              :       !nxt is the dimension of the part of rhopot that must be passed to the gradient routine
     122              :       !nwb is the dimension of the part of rhopot in the wb-postprocessing routine
     123              :       !note: nxc <= nwb <= nxt
     124              :       !the dimension are related by the values of nwbl and nwbr
     125              :       !      nxc+nxcl+nxcr-2 = nwb
     126              :       !      nwb+nwbl+nwbr = nxt
     127        33295 :       istart = iproc*(md2/nproc)
     128        33295 :       iend = MIN((iproc + 1)*md2/nproc, m2)
     129              : 
     130        33295 :       nxc = iend - istart
     131        33295 :       nwbl = 0
     132        33295 :       nwbr = 0
     133        33295 :       nxcl = 1
     134        33295 :       nxcr = 1
     135              : 
     136        33295 :       nwb = nxcl + nxc + nxcr - 2
     137        33295 :       nxt = nwbr + nwb + nwbl
     138              : 
     139              :       !calculate the actual limit of the array for the zero padded FFT
     140        33295 :       IF (geocode == 'P') THEN
     141        17323 :          nlim = n2
     142        15972 :       ELSE IF (geocode == 'S') THEN
     143           54 :          nlim = n2
     144        15918 :       ELSE IF (geocode == 'F') THEN
     145        15918 :          nlim = n2/2
     146              :       END IF
     147              : 
     148              :       !!$  print *,'density must go from',min(istart+1,m2),'to',iend,'with n2/2=',n2/2
     149              :       !!$  print *,'        it goes from',i3start+nwbl+nxcl-1,'to',i3start+nxc-1
     150              : 
     151        33295 :       IF (istart + 1 <= m2) THEN
     152        33295 :          red_fact = 1._dp
     153        33295 :          CALL scale_and_distribute(m1, m3, md1, md2, md3, nxc, rhopot, zf, nproc, red_fact)
     154            0 :       ELSE IF (istart + 1 <= nlim) THEN !this condition assures that we have perform good zero padding
     155            0 :          DO i2 = istart + 1, MIN(nlim, istart + md2/nproc)
     156            0 :             j2 = i2 - istart
     157            0 :             DO i3 = 1, md3
     158            0 :                DO i1 = 1, md1
     159            0 :                   zf(i1, i3, j2) = 0._dp
     160              :                END DO
     161              :             END DO
     162              :          END DO
     163              :       END IF
     164              : 
     165              :       !this routine builds the values for each process of the potential (zf), multiplying by scal
     166        33295 :       IF (geocode == 'P') THEN
     167              :          !no powers of hgrid because they are incorporated in the plane wave treatment
     168        17323 :          scal = 1._dp/REAL(n1*n2*n3, KIND=dp)
     169              :          CALL P_PoissonSolver(n1, n2, n3, nd1, nd2, nd3, md1, md2, md3, nproc, iproc, zf, &
     170        17323 :                               scal, hx, hy, hz, pw_grid%para%group)
     171        15972 :       ELSE IF (geocode == 'S') THEN
     172              :          !only one power of hgrid
     173           54 :          scal = hy/REAL(n1*n2*n3, KIND=dp)
     174              :          CALL S_PoissonSolver(n1, n2, n3, nd1, nd2, nd3, md1, md2, md3, nproc, iproc, karray, zf, &
     175           54 :                               scal, pw_grid%para%group)
     176        15918 :       ELSE IF (geocode == 'F') THEN
     177        15918 :          hgrid = MAX(hx, hy, hz)
     178        15918 :          scal = hgrid**3/REAL(n1*n2*n3, KIND=dp)
     179              :          CALL F_PoissonSolver(n1, n2, n3, nd1, nd2, nd3, md1, md2, md3, nproc, iproc, karray, zf, &
     180        15918 :                               scal, pw_grid%para%group)
     181        15918 :          factor = 0.5_dp*hgrid**3
     182              :       END IF
     183              : 
     184              :       !  call timing(iproc,'PSolv_comput  ','ON')
     185              : 
     186              :       !the value of the shift depends on the distributed i/o or not
     187        33295 :       IF (geocode == 'F') THEN
     188        15918 :          red_fact = 1._dp
     189              :       ELSE
     190        17377 :          red_fact = -fourpi
     191              :       END IF
     192              : 
     193        33295 :       CALL scale_and_distribute(m1, m3, md1, md2, md3, nxc, zf, rhopot, nproc, red_fact)
     194              : 
     195        33295 :       DEALLOCATE (zf)
     196              : 
     197        33295 :    END SUBROUTINE PSolver
     198              : 
     199              : ! **************************************************************************************************
     200              : !> \brief Calculate four sets of dimension needed for the calculation of the
     201              : !>     convolution for the periodic system
     202              : !> \param n01 original real dimensions (input)
     203              : !> \param n02 original real dimensions (input)
     204              : !> \param n03 original real dimensions (input)
     205              : !> \param m1 original real dimension, with m2 and m3 exchanged
     206              : !> \param m2 original real dimension, with m2 and m3 exchanged
     207              : !> \param m3 original real dimension, with m2 and m3 exchanged
     208              : !> \param n1 the first FFT dimensions, for the moment supposed to be even
     209              : !> \param n2 the first FFT dimensions, for the moment supposed to be even
     210              : !> \param n3 the first FFT dimensions, for the moment supposed to be even
     211              : !> \param md1 the n1,n2,n3 dimensions. They contain the real unpadded space,
     212              : !>                 properly enlarged to be compatible with the FFT dimensions n_i.
     213              : !>                 md2 is further enlarged to be a multiple of nproc
     214              : !> \param md2 the n1,n2,n3 dimensions. They contain the real unpadded space,
     215              : !>                 properly enlarged to be compatible with the FFT dimensions n_i.
     216              : !>                 md2 is further enlarged to be a multiple of nproc
     217              : !> \param md3 the n1,n2,n3 dimensions. They contain the real unpadded space,
     218              : !>                 properly enlarged to be compatible with the FFT dimensions n_i.
     219              : !>                 md2 is further enlarged to be a multiple of nproc
     220              : !> \param nd1 fourier dimensions for which the kernel is injective,
     221              : !>                 formally 1/8 of the fourier grid. Here the dimension nd3 is
     222              : !>                 enlarged to be a multiple of nproc
     223              : !> \param nd2 fourier dimensions for which the kernel is injective,
     224              : !>                 formally 1/8 of the fourier grid. Here the dimension nd3 is
     225              : !>                 enlarged to be a multiple of nproc
     226              : !> \param nd3 fourier dimensions for which the kernel is injective,
     227              : !>                 formally 1/8 of the fourier grid. Here the dimension nd3 is
     228              : !>                 enlarged to be a multiple of nproc
     229              : !> \param nproc ...
     230              : !> \date October 2006
     231              : !> \author Luigi Genovese
     232              : !> \note This four sets of dimensions are actually redundant (mi=n0i),
     233              : !>     due to the backward-compatibility
     234              : !>     with the other geometries of the Poisson Solver.
     235              : !>     The dimensions 2 and 3 are exchanged.
     236              : ! **************************************************************************************************
     237        52947 :    SUBROUTINE P_FFT_dimensions(n01, n02, n03, m1, m2, m3, n1, n2, n3, md1, md2, md3, nd1, nd2, nd3, nproc)
     238              :       INTEGER, INTENT(in)                                :: n01, n02, n03
     239              :       INTEGER, INTENT(out)                               :: m1, m2, m3, n1, n2, n3, md1, md2, md3, &
     240              :                                                             nd1, nd2, nd3
     241              :       INTEGER, INTENT(in)                                :: nproc
     242              : 
     243              :       CHARACTER(len=80)                                  :: err
     244              :       INTEGER                                            :: l1, l2, l3
     245              : 
     246              : !dimensions of the density in the real space
     247              : 
     248        17649 :       m1 = n01
     249        17649 :       m2 = n03
     250        17649 :       m3 = n02
     251              : 
     252              :       ! real space grid dimension (suitable for number of processors)
     253        17649 :       l1 = m1
     254        17649 :       l2 = m2
     255        17649 :       l3 = m3 !beware of the half dimension
     256        17649 :       CALL fourier_dim(l1, n1)
     257        17649 :       IF (n1 == m1) THEN
     258              :       ELSE
     259            0 :          WRITE (err, *) 'the FFT in the x direction is not allowed; n01 dimension ', n01
     260            0 :          CPABORT(TRIM(err))
     261              :       END IF
     262              :       l1 = l1 + 1
     263        17649 :       CALL fourier_dim(l2, n2)
     264        17649 :       IF (n2 == m2) THEN
     265              :       ELSE
     266            0 :          WRITE (err, *) 'the FFT in the z direction is not allowed; n03 dimension ', n03
     267            0 :          CPABORT(TRIM(err))
     268              :       END IF
     269        17649 :       CALL fourier_dim(l3, n3)
     270        17649 :       IF (n3 == m3) THEN
     271              :       ELSE
     272            0 :          WRITE (err, *) 'the FFT in the y direction is not allowed; n02 dimension ', n02
     273            0 :          CPABORT(TRIM(err))
     274              :       END IF
     275              : 
     276              :       !dimensions that contain the unpadded real space,
     277              :       ! compatible with the number of processes
     278        17649 :       md1 = n1
     279        17649 :       md2 = n2
     280        17649 :       md3 = n3
     281        19029 :       DO WHILE (nproc*(md2/nproc) < n2)
     282         1380 :          md2 = md2 + 1
     283              :       END DO
     284              : 
     285              :       !dimensions of the kernel, 1/8 of the total volume,
     286              :       !compatible with nproc
     287        17649 :       nd1 = n1/2 + 1
     288        17649 :       nd2 = n2/2 + 1
     289        17649 :       nd3 = n3/2 + 1
     290        19579 :       DO WHILE (MODULO(nd3, nproc) /= 0)
     291         1930 :          nd3 = nd3 + 1
     292              :       END DO
     293              : 
     294        17649 :    END SUBROUTINE P_FFT_dimensions
     295              : 
     296              : ! **************************************************************************************************
     297              : !> \brief Calculate four sets of dimension needed for the calculation of the
     298              : !>     convolution for the surface system
     299              : !> \param n01 original real dimensions (input)
     300              : !> \param n02 original real dimensions (input)
     301              : !> \param n03 original real dimensions (input)
     302              : !> \param m1 original real dimension, with 2 and 3 exchanged
     303              : !> \param m2 original real dimension, with 2 and 3 exchanged
     304              : !> \param m3 original real dimension, with 2 and 3 exchanged
     305              : !> \param n1 the first FFT dimensions, for the moment supposed to be even
     306              : !> \param n2 the first FFT dimensions, for the moment supposed to be even
     307              : !> \param n3 the double of the first FFT even dimension greater than m3
     308              : !>           (improved for the HalFFT procedure)
     309              : !> \param md1 the n1,n2 dimensions.
     310              : !> \param md2 the n1,n2,n3 dimensions.
     311              : !> \param md3 the half of n3 dimension. They contain the real unpadded space,
     312              : !>                 properly enlarged to be compatible with the FFT dimensions n_i.
     313              : !>                 md2 is further enlarged to be a multiple of nproc
     314              : !> \param nd1 fourier dimensions for which the kernel is injective,
     315              : !>                 formally 1/8 of the fourier grid. Here the dimension nd3 is
     316              : !>                 enlarged to be a multiple of nproc
     317              : !> \param nd2 fourier dimensions for which the kernel is injective,
     318              : !>                 formally 1/8 of the fourier grid. Here the dimension nd3 is
     319              : !>                 enlarged to be a multiple of nproc
     320              : !> \param nd3 fourier dimensions for which the kernel is injective,
     321              : !>                 formally 1/8 of the fourier grid. Here the dimension nd3 is
     322              : !>                 enlarged to be a multiple of nproc
     323              : !> \param nproc ...
     324              : !> \date October 2006
     325              : !> \author Luigi Genovese
     326              : !> \note This four sets of dimensions are actually redundant (mi=n0i),
     327              : !>     due to the backward-compatibility
     328              : !>     with the Poisson Solver with other geometries.
     329              : !>     Dimensions n02 and n03 were exchanged
     330              : ! **************************************************************************************************
     331          198 :    SUBROUTINE S_FFT_dimensions(n01, n02, n03, m1, m2, m3, n1, n2, n3, md1, md2, md3, nd1, nd2, nd3, nproc)
     332              :       INTEGER, INTENT(in)                                :: n01, n02, n03
     333              :       INTEGER, INTENT(out)                               :: m1, m2, m3, n1, n2, n3, md1, md2, md3, &
     334              :                                                             nd1, nd2, nd3
     335              :       INTEGER, INTENT(in)                                :: nproc
     336              : 
     337              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'S_FFT_dimensions'
     338              : 
     339              :       CHARACTER(len=80)                                  :: err
     340              :       INTEGER                                            :: handle, l1, l2, l3
     341              : 
     342              : !dimensions of the density in the real space
     343              : 
     344           66 :       CALL timeset(routineN, handle)
     345           66 :       m1 = n01
     346           66 :       m2 = n03
     347           66 :       m3 = n02
     348              : 
     349              :       ! real space grid dimension (suitable for number of processors)
     350           66 :       l1 = m1
     351           66 :       l2 = m2
     352           66 :       l3 = m3 !beware of the half dimension
     353           66 :       CALL fourier_dim(l1, n1)
     354           66 :       IF (n1 == m1) THEN
     355              :       ELSE
     356            0 :          WRITE (err, *) 'the FFT in the x direction is not allowed; n01 dimension', n01
     357            0 :          CPABORT(TRIM(err))
     358              :       END IF
     359              :       l1 = l1 + 1
     360           66 :       CALL fourier_dim(l2, n2)
     361           66 :       IF (n2 == m2) THEN
     362              :       ELSE
     363            0 :          WRITE (err, *) 'the FFT in the z direction is not allowed; n03 dimension', n03
     364            0 :          CPABORT(TRIM(err))
     365              :       END IF
     366           66 :       DO
     367           66 :          CALL fourier_dim(l3, n3)
     368           66 :          IF (MODULO(n3, 2) == 0) THEN
     369              :             EXIT
     370              :          END IF
     371            0 :          l3 = l3 + 1
     372              :       END DO
     373           66 :       n3 = 2*n3
     374              : 
     375              :       !dimensions that contain the unpadded real space,
     376              :       ! compatible with the number of processes
     377           66 :       md1 = n1
     378           66 :       md2 = n2
     379           66 :       md3 = n3/2
     380           66 :       DO WHILE (nproc*(md2/nproc) < n2)
     381            0 :          md2 = md2 + 1
     382              :       END DO
     383              : 
     384              :       !dimensions of the kernel, 1/8 of the total volume,
     385              :       !compatible with nproc
     386              : 
     387              :       !these two dimensions are like that since they are even
     388           66 :       nd1 = n1/2 + 1
     389           66 :       nd2 = n2/2 + 1
     390              : 
     391           66 :       nd3 = n3/2 + 1
     392          132 :       DO WHILE (MODULO(nd3, nproc) /= 0)
     393           66 :          nd3 = nd3 + 1
     394              :       END DO
     395           66 :       CALL timestop(handle)
     396              : 
     397           66 :    END SUBROUTINE S_FFT_dimensions
     398              : 
     399              : ! **************************************************************************************************
     400              : !> \brief Calculate four sets of dimension needed for the calculation of the
     401              : !>     zero-padded convolution
     402              : !> \param n01 original real dimensions (input)
     403              : !> \param n02 original real dimensions (input)
     404              : !> \param n03 original real dimensions (input)
     405              : !> \param m1 original real dimension with the dimension 2 and 3 exchanged
     406              : !> \param m2 original real dimension with the dimension 2 and 3 exchanged
     407              : !> \param m3 original real dimension with the dimension 2 and 3 exchanged
     408              : !> \param n1 ...
     409              : !> \param n2 ...
     410              : !> \param n3 the double of the first FFT even dimension greater than m3
     411              : !>           (improved for the HalFFT procedure)
     412              : !> \param md1 half of n1,n2,n3 dimension. They contain the real unpadded space,
     413              : !>                 properly enlarged to be compatible with the FFT dimensions n_i.
     414              : !>                 md2 is further enlarged to be a multiple of nproc
     415              : !> \param md2 half of n1,n2,n3 dimension. They contain the real unpadded space,
     416              : !>                 properly enlarged to be compatible with the FFT dimensions n_i.
     417              : !>                 md2 is further enlarged to be a multiple of nproc
     418              : !> \param md3 half of n1,n2,n3 dimension. They contain the real unpadded space,
     419              : !>                 properly enlarged to be compatible with the FFT dimensions n_i.
     420              : !>                 md2 is further enlarged to be a multiple of nproc
     421              : !> \param nd1 fourier dimensions for which the kernel FFT is injective,
     422              : !>                 formally 1/8 of the fourier grid. Here the dimension nd3 is
     423              : !>                 enlarged to be a multiple of nproc
     424              : !> \param nd2 fourier dimensions for which the kernel FFT is injective,
     425              : !>                 formally 1/8 of the fourier grid. Here the dimension nd3 is
     426              : !>                 enlarged to be a multiple of nproc
     427              : !> \param nd3 fourier dimensions for which the kernel FFT is injective,
     428              : !>                 formally 1/8 of the fourier grid. Here the dimension nd3 is
     429              : !>                 enlarged to be a multiple of nproc
     430              : !> \param nproc ...
     431              : !> \date February 2006
     432              : !> \author Luigi Genovese
     433              : !> \note The dimension m2 and m3 correspond to n03 and n02 respectively
     434              : !>     this is needed since the convolution routine manage arrays of dimension
     435              : !>     (md1,md3,md2/nproc)
     436              : ! **************************************************************************************************
     437        17292 :    SUBROUTINE F_FFT_dimensions(n01, n02, n03, m1, m2, m3, n1, n2, n3, md1, md2, md3, nd1, nd2, nd3, nproc)
     438              :       INTEGER, INTENT(in)                                :: n01, n02, n03
     439              :       INTEGER, INTENT(out)                               :: m1, m2, m3, n1, n2, n3, md1, md2, md3, &
     440              :                                                             nd1, nd2, nd3
     441              :       INTEGER, INTENT(in)                                :: nproc
     442              : 
     443              :       INTEGER                                            :: l1, l2, l3
     444              : 
     445              : !dimensions of the density in the real space, inverted for convenience
     446              : 
     447        17292 :       m1 = n01
     448        17292 :       m2 = n03
     449        17292 :       m3 = n02
     450              :       ! real space grid dimension (suitable for number of processors)
     451        17292 :       l1 = 2*m1
     452        17292 :       l2 = 2*m2
     453        17292 :       l3 = m3 !beware of the half dimension
     454        17292 :       DO
     455        17292 :          CALL fourier_dim(l1, n1)
     456        17292 :          IF (MODULO(n1, 2) == 0) THEN
     457              :             EXIT
     458              :          END IF
     459        17292 :          l1 = l1 + 1
     460              :       END DO
     461        17292 :       DO
     462        17292 :          CALL fourier_dim(l2, n2)
     463        17292 :          IF (MODULO(n2, 2) == 0) THEN
     464              :             EXIT
     465              :          END IF
     466        17292 :          l2 = l2 + 1
     467              :       END DO
     468        27082 :       DO
     469        27082 :          CALL fourier_dim(l3, n3)
     470        27082 :          IF (MODULO(n3, 2) == 0) THEN
     471              :             EXIT
     472              :          END IF
     473         9790 :          l3 = l3 + 1
     474              :       END DO
     475        17292 :       n3 = 2*n3
     476              : 
     477              :       !dimensions that contain the unpadded real space,
     478              :       ! compatible with the number of processes
     479        17292 :       md1 = n1/2
     480        17292 :       md2 = n2/2
     481        17292 :       md3 = n3/2
     482        19640 :       DO WHILE (nproc*(md2/nproc) < n2/2)
     483         2348 :          md2 = md2 + 1
     484              :       END DO
     485              : 
     486              :       !dimensions of the kernel, 1/8 of the total volume,
     487              :       !compatible with nproc
     488        17292 :       nd1 = n1/2 + 1
     489        17292 :       nd2 = n2/2 + 1
     490        17292 :       nd3 = n3/2 + 1
     491              : 
     492        26456 :       DO WHILE (MODULO(nd3, nproc) /= 0)
     493         9164 :          nd3 = nd3 + 1
     494              :       END DO
     495              : 
     496        17292 :    END SUBROUTINE F_FFT_dimensions
     497              : 
     498              : ! **************************************************************************************************
     499              : !> \brief ...
     500              : !> \param m1 ...
     501              : !> \param m3 ...
     502              : !> \param md1 ...
     503              : !> \param md2 ...
     504              : !> \param md3 ...
     505              : !> \param nxc ...
     506              : !> \param rhopot ...
     507              : !> \param zf ...
     508              : !> \param nproc ...
     509              : !> \param factor ...
     510              : ! **************************************************************************************************
     511        66590 :    SUBROUTINE scale_and_distribute(m1, m3, md1, md2, md3, nxc, &
     512        66590 :                                    rhopot, zf, nproc, factor)
     513              : 
     514              :       !Arguments----------------------
     515              :       INTEGER, INTENT(in)                                :: m1, m3, md1, md2, md3, nxc, nproc
     516              :       REAL(KIND=dp), DIMENSION(md1, md3, md2/nproc), &
     517              :          INTENT(inout)                                   :: zf, rhopot
     518              :       REAL(KIND=dp), INTENT(in)                          :: factor
     519              : 
     520              :       CHARACTER(len=*), PARAMETER :: routineN = 'scale_and_distribute'
     521              : 
     522              :       INTEGER                                            :: handle, j1, j3, jp2
     523              : 
     524        66590 :       CALL timeset(routineN, handle)
     525              : 
     526        66590 :       IF (nxc >= 1) THEN
     527      1489542 :          DO jp2 = 1, nxc
     528     48002796 :             DO j3 = 1, m3
     529   1919562780 :                DO j1 = 1, m1
     530   1919562780 :                   zf(j1, j3, jp2) = factor*rhopot(j1, j3, jp2)
     531              :                END DO
     532     54001546 :                DO j1 = m1 + 1, md1
     533     52578594 :                   zf(j1, j3, jp2) = 0._dp
     534              :                END DO
     535              :             END DO
     536      2220754 :             DO j3 = m3 + 1, md3
     537     29985686 :                DO j1 = 1, md1
     538     28562734 :                   zf(j1, j3, jp2) = 0._dp
     539              :                END DO
     540              :             END DO
     541              :          END DO
     542        77300 :          DO jp2 = nxc + 1, md2/nproc
     543       419162 :             DO j3 = 1, md3
     544     11845654 :                DO j1 = 1, md1
     545     11834944 :                   zf(j1, j3, jp2) = 0._dp
     546              :                END DO
     547              :             END DO
     548              :          END DO
     549              :       ELSE
     550            0 :          zf = 0._dp
     551              :       END IF
     552        66590 :       CALL timestop(handle)
     553              : 
     554        66590 :    END SUBROUTINE scale_and_distribute
     555              : END MODULE ps_wavelet_util
        

Generated by: LCOV version 2.0-1