LCOV - code coverage report
Current view: top level - src/pw - rs_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 98.2 % 163 160
Test Date: 2025-12-04 06:27:48 Functions: 100.0 % 5 5

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief  numerical operations on real-space grid
      10              : !> \par History
      11              : !>       12.2014 created [Hossein Bani-Hashemian]
      12              : !> \author Mohammad Hossein Bani-Hashemian
      13              : ! **************************************************************************************************
      14              : MODULE rs_methods
      15              : 
      16              :    USE kinds,                           ONLY: dp
      17              :    USE pw_grid_types,                   ONLY: pw_grid_type
      18              :    USE pw_methods,                      ONLY: pw_integrate_function,&
      19              :                                               pw_scale,&
      20              :                                               pw_transfer,&
      21              :                                               pw_zero
      22              :    USE pw_pool_types,                   ONLY: pw_pool_type
      23              :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      24              :                                               pw_r3d_rs_type
      25              :    USE realspace_grid_types,            ONLY: realspace_grid_desc_type,&
      26              :                                               realspace_grid_type,&
      27              :                                               rs_grid_create,&
      28              :                                               rs_grid_release,&
      29              :                                               rs_grid_zero,&
      30              :                                               transfer_pw2rs,&
      31              :                                               transfer_rs2pw
      32              : #include "../base/base_uses.f90"
      33              : 
      34              :    IMPLICIT NONE
      35              :    PRIVATE
      36              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'rs_methods'
      37              : 
      38              :    PUBLIC derive_fdm_cd3, &
      39              :       derive_fdm_cd5, &
      40              :       derive_fdm_cd7, &
      41              :       setup_grid_axes, &
      42              :       pw_mollifier
      43              : 
      44              :    REAL(dp), PARAMETER, PRIVATE         :: small_value = 1.0E-8_dp
      45              : 
      46              : CONTAINS
      47              : 
      48              : ! **************************************************************************************************
      49              : !> \brief    2nd order finite difference derivative of a function on realspace grid
      50              : !> \param f  input function
      51              : !> \param df derivative of f
      52              : !> \param rs_grid real-space grid
      53              : !> \par History:
      54              : !>      - Creation (15.11.2013,MK)
      55              : !>      - Refactored and moved here from qs_sccs.F (12.2014, Hossein Bani-Hashemian)
      56              : !> \author     Matthias Krack (MK)
      57              : !> \version    1.0
      58              : ! **************************************************************************************************
      59          196 :    SUBROUTINE derive_fdm_cd3(f, df, rs_grid)
      60              : 
      61              :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: f
      62              :       TYPE(pw_r3d_rs_type), DIMENSION(3), INTENT(INOUT)  :: df
      63              :       TYPE(realspace_grid_type), INTENT(IN)              :: rs_grid
      64              : 
      65              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'derive_fdm_cd3'
      66              : 
      67              :       INTEGER                                            :: handle, i, j, k
      68              :       INTEGER, DIMENSION(3)                              :: lb, ub
      69              :       REAL(KIND=dp), DIMENSION(3)                        :: h
      70          392 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: drdx, drdy, drdz, r
      71              :       TYPE(realspace_grid_desc_type), POINTER            :: rs_desc
      72         7056 :       TYPE(realspace_grid_type), DIMENSION(3)            :: drs_grid
      73              : 
      74          196 :       CALL timeset(routineN, handle)
      75              : 
      76              :       ! Setup
      77          196 :       rs_desc => rs_grid%desc
      78          196 :       CALL transfer_pw2rs(rs_grid, f)
      79          784 :       DO i = 1, 3
      80          588 :          CALL rs_grid_create(drs_grid(i), rs_desc)
      81          784 :          CALL rs_grid_zero(drs_grid(i))
      82              :       END DO
      83              : 
      84          784 :       lb(1:3) = rs_grid%lb_real(1:3)
      85          784 :       ub(1:3) = rs_grid%ub_real(1:3)
      86          196 :       r => rs_grid%r
      87          196 :       drdx => drs_grid(1)%r
      88          196 :       drdy => drs_grid(2)%r
      89          196 :       drdz => drs_grid(3)%r
      90              : 
      91              :       ! 3-point stencil central differences
      92          784 :       h(1:3) = 2.0_dp*f%pw_grid%dr(1:3)
      93              : !$OMP     PARALLEL DO DEFAULT(NONE) &
      94              : !$OMP                 PRIVATE(i,j,k) &
      95          196 : !$OMP                 SHARED(drdx,drdy,drdz,h,lb,r,ub)
      96              :       DO k = lb(3), ub(3)
      97              :          DO j = lb(2), ub(2)
      98              :             DO i = lb(1), ub(1)
      99              :                drdx(i, j, k) = (r(i + 1, j, k) - r(i - 1, j, k))/h(1)
     100              :                drdy(i, j, k) = (r(i, j + 1, k) - r(i, j - 1, k))/h(2)
     101              :                drdz(i, j, k) = (r(i, j, k + 1) - r(i, j, k - 1))/h(3)
     102              :             END DO
     103              :          END DO
     104              :       END DO
     105              : !$OMP     END PARALLEL DO
     106              : 
     107              :       ! Cleanup
     108          784 :       DO i = 1, 3
     109          588 :          CALL transfer_rs2pw(drs_grid(i), df(i))
     110          784 :          CALL rs_grid_release(drs_grid(i))
     111              :       END DO
     112              : 
     113          196 :       CALL timestop(handle)
     114              : 
     115          392 :    END SUBROUTINE derive_fdm_cd3
     116              : 
     117              : ! **************************************************************************************************
     118              : !> \brief    4th order finite difference derivative of a function on realspace grid
     119              : !> \param f  input function
     120              : !> \param df derivative of f
     121              : !> \param rs_grid real-space grid
     122              : !> \par History:
     123              : !>      - Creation (15.11.2013,MK)
     124              : !>      - Refactored and moved here from qs_sccs.F (12.2014, Hossein Bani-Hashemian)
     125              : !> \author     Matthias Krack (MK)
     126              : !> \version    1.0
     127              : ! **************************************************************************************************
     128          192 :    SUBROUTINE derive_fdm_cd5(f, df, rs_grid)
     129              : 
     130              :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: f
     131              :       TYPE(pw_r3d_rs_type), DIMENSION(3), INTENT(INOUT)  :: df
     132              :       TYPE(realspace_grid_type), INTENT(IN)              :: rs_grid
     133              : 
     134              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'derive_fdm_cd5'
     135              : 
     136              :       INTEGER                                            :: handle, i, j, k
     137              :       INTEGER, DIMENSION(3)                              :: lb, ub
     138              :       REAL(KIND=dp), DIMENSION(3)                        :: h
     139          384 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: drdx, drdy, drdz, r
     140              :       TYPE(realspace_grid_desc_type), POINTER            :: rs_desc
     141         6912 :       TYPE(realspace_grid_type), DIMENSION(3)            :: drs_grid
     142              : 
     143          192 :       CALL timeset(routineN, handle)
     144              : 
     145              :       ! Setup
     146          192 :       rs_desc => rs_grid%desc
     147          192 :       CALL transfer_pw2rs(rs_grid, f)
     148          768 :       DO i = 1, 3
     149          576 :          CALL rs_grid_create(drs_grid(i), rs_desc)
     150          768 :          CALL rs_grid_zero(drs_grid(i))
     151              :       END DO
     152              : 
     153          768 :       lb(1:3) = rs_grid%lb_real(1:3)
     154          768 :       ub(1:3) = rs_grid%ub_real(1:3)
     155          192 :       r => rs_grid%r
     156          192 :       drdx => drs_grid(1)%r
     157          192 :       drdy => drs_grid(2)%r
     158          192 :       drdz => drs_grid(3)%r
     159              : 
     160              :       ! 5-point stencil central differences
     161          768 :       h(1:3) = 12.0_dp*f%pw_grid%dr(1:3)
     162              : !$OMP     PARALLEL DO DEFAULT(NONE) &
     163              : !$OMP                 PRIVATE(i,j,k) &
     164          192 : !$OMP                 SHARED(drdx,drdy,drdz,h,lb,r,ub)
     165              :       DO k = lb(3), ub(3)
     166              :          DO j = lb(2), ub(2)
     167              :             DO i = lb(1), ub(1)
     168              :                drdx(i, j, k) = (r(i - 2, j, k) - r(i + 2, j, k) + 8.0_dp*(r(i + 1, j, k) - r(i - 1, j, k)))/h(1)
     169              :                drdy(i, j, k) = (r(i, j - 2, k) - r(i, j + 2, k) + 8.0_dp*(r(i, j + 1, k) - r(i, j - 1, k)))/h(2)
     170              :                drdz(i, j, k) = (r(i, j, k - 2) - r(i, j, k + 2) + 8.0_dp*(r(i, j, k + 1) - r(i, j, k - 1)))/h(3)
     171              :             END DO
     172              :          END DO
     173              :       END DO
     174              : !$OMP     END PARALLEL DO
     175              : 
     176              :       ! Cleanup
     177          768 :       DO i = 1, 3
     178          576 :          CALL transfer_rs2pw(drs_grid(i), df(i))
     179          768 :          CALL rs_grid_release(drs_grid(i))
     180              :       END DO
     181              : 
     182          192 :       CALL timestop(handle)
     183              : 
     184          384 :    END SUBROUTINE derive_fdm_cd5
     185              : 
     186              : ! **************************************************************************************************
     187              : !> \brief    6th order finite difference derivative of a function on realspace grid
     188              : !> \param f  input function
     189              : !> \param df derivative of f
     190              : !> \param rs_grid real-space grid
     191              : !> \par History:
     192              : !>      - Creation (15.11.2013,MK)
     193              : !>      - Refactored and moved here from qs_sccs.F (12.2014, Hossein Bani-Hashemian)
     194              : !> \author     Matthias Krack (MK)
     195              : !> \version    1.0
     196              : ! **************************************************************************************************
     197          104 :    SUBROUTINE derive_fdm_cd7(f, df, rs_grid)
     198              : 
     199              :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: f
     200              :       TYPE(pw_r3d_rs_type), DIMENSION(3), INTENT(INOUT)  :: df
     201              :       TYPE(realspace_grid_type), INTENT(IN)              :: rs_grid
     202              : 
     203              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'derive_fdm_cd7'
     204              : 
     205              :       INTEGER                                            :: handle, i, j, k
     206              :       INTEGER, DIMENSION(3)                              :: lb, ub
     207              :       REAL(KIND=dp), DIMENSION(3)                        :: h
     208          208 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: drdx, drdy, drdz, r
     209              :       TYPE(realspace_grid_desc_type), POINTER            :: rs_desc
     210         3744 :       TYPE(realspace_grid_type), DIMENSION(3)            :: drs_grid
     211              : 
     212          104 :       CALL timeset(routineN, handle)
     213              : 
     214              :       ! Setup
     215          104 :       rs_desc => rs_grid%desc
     216          104 :       CALL transfer_pw2rs(rs_grid, f)
     217          416 :       DO i = 1, 3
     218          312 :          CALL rs_grid_create(drs_grid(i), rs_desc)
     219          416 :          CALL rs_grid_zero(drs_grid(i))
     220              :       END DO
     221              : 
     222          416 :       lb(1:3) = rs_grid%lb_real(1:3)
     223          416 :       ub(1:3) = rs_grid%ub_real(1:3)
     224          104 :       r => rs_grid%r
     225          104 :       drdx => drs_grid(1)%r
     226          104 :       drdy => drs_grid(2)%r
     227          104 :       drdz => drs_grid(3)%r
     228              : 
     229              :       ! 7-point stencil central differences
     230          416 :       h(1:3) = 60.0_dp*f%pw_grid%dr(1:3)
     231              : !$OMP     PARALLEL DO DEFAULT(NONE) &
     232              : !$OMP                 PRIVATE(i,j,k) &
     233          104 : !$OMP                 SHARED(drdx,drdy,drdz,h,lb,r,ub)
     234              :       DO k = lb(3), ub(3)
     235              :          DO j = lb(2), ub(2)
     236              :             DO i = lb(1), ub(1)
     237              :                drdx(i, j, k) = (r(i + 3, j, k) - r(i - 3, j, k) + 9.0_dp*(r(i - 2, j, k) - r(i + 2, j, k)) + &
     238              :                                 45.0_dp*(r(i + 1, j, k) - r(i - 1, j, k)))/h(1)
     239              :                drdy(i, j, k) = (r(i, j + 3, k) - r(i, j - 3, k) + 9.0_dp*(r(i, j - 2, k) - r(i, j + 2, k)) + &
     240              :                                 45.0_dp*(r(i, j + 1, k) - r(i, j - 1, k)))/h(2)
     241              :                drdz(i, j, k) = (r(i, j, k + 3) - r(i, j, k - 3) + 9.0_dp*(r(i, j, k - 2) - r(i, j, k + 2)) + &
     242              :                                 45.0_dp*(r(i, j, k + 1) - r(i, j, k - 1)))/h(3)
     243              :             END DO
     244              :          END DO
     245              :       END DO
     246              : !$OMP     END PARALLEL DO
     247              : 
     248              :       ! Cleanup
     249          416 :       DO i = 1, 3
     250          312 :          CALL transfer_rs2pw(drs_grid(i), df(i))
     251          416 :          CALL rs_grid_release(drs_grid(i))
     252              :       END DO
     253              : 
     254          104 :       CALL timestop(handle)
     255              : 
     256          208 :    END SUBROUTINE derive_fdm_cd7
     257              : 
     258              : ! **************************************************************************************************
     259              : !> \brief returns the global axes and the portion of the axes that are local to
     260              : !>        the current mpi rank
     261              : !> \param pw_grid plane wave grid
     262              : !> \param x_glbl x grid vector of the simulation box
     263              : !> \param y_glbl y grid vector of the simulation box
     264              : !> \param z_glbl z grid vector of the simulation box
     265              : !> \param x_locl x grid vector of the simulation box local to this process
     266              : !> \param y_locl y grid vector of the simulation box local to this process
     267              : !> \param z_locl z grid vector of the simulation box local to this process
     268              : !> \par History
     269              : !>       07.2014 created [Hossein Bani-Hashemian]
     270              : !>       07.2015 moved here from dirichlet_bc_utils.F [Hossein Bani-Hashemian]
     271              : !> \author Mohammad Hossein Bani-Hashemian
     272              : ! **************************************************************************************************
     273           80 :    SUBROUTINE setup_grid_axes(pw_grid, x_glbl, y_glbl, z_glbl, x_locl, y_locl, z_locl)
     274              : 
     275              :       TYPE(pw_grid_type), INTENT(IN)                     :: pw_grid
     276              :       REAL(dp), ALLOCATABLE, DIMENSION(:), INTENT(OUT)   :: x_glbl, y_glbl, z_glbl, x_locl, y_locl, &
     277              :                                                             z_locl
     278              : 
     279              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'setup_grid_axes'
     280              : 
     281              :       INTEGER                                            :: glb1, glb2, glb3, gub1, gub2, gub3, &
     282              :                                                             handle, i, lb1, lb2, lb3, ub1, ub2, ub3
     283           80 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: gindx, gindy, gindz, lindx, lindy, lindz
     284              :       INTEGER, DIMENSION(2, 3)                           :: bounds, bounds_local
     285              :       INTEGER, DIMENSION(3)                              :: npts, npts_local
     286              :       REAL(dp), DIMENSION(3)                             :: dr
     287              : 
     288           80 :       CALL timeset(routineN, handle)
     289              : 
     290          320 :       dr = pw_grid%dr
     291          800 :       bounds = pw_grid%bounds
     292          800 :       bounds_local = pw_grid%bounds_local
     293          320 :       npts = pw_grid%npts
     294          320 :       npts_local = pw_grid%npts_local
     295              : 
     296              : ! local and global lower and upper bounds
     297           80 :       glb1 = bounds(1, 1); gub1 = bounds(2, 1)
     298           80 :       glb2 = bounds(1, 2); gub2 = bounds(2, 2)
     299           80 :       glb3 = bounds(1, 3); gub3 = bounds(2, 3)
     300           80 :       lb1 = bounds_local(1, 1); ub1 = bounds_local(2, 1)
     301           80 :       lb2 = bounds_local(1, 2); ub2 = bounds_local(2, 2)
     302           80 :       lb3 = bounds_local(1, 3); ub3 = bounds_local(2, 3)
     303              : 
     304          560 :       ALLOCATE (lindx(lb1:ub1), lindy(lb2:ub2), lindz(lb3:ub3))
     305          560 :       ALLOCATE (gindx(glb1:gub1), gindy(glb2:gub2), gindz(glb3:gub3))
     306          560 :       ALLOCATE (x_locl(lb1:ub1), y_locl(lb2:ub2), z_locl(lb3:ub3))
     307          560 :       ALLOCATE (x_glbl(glb1:gub1), y_glbl(glb2:gub2), z_glbl(glb3:gub3))
     308              : 
     309        10396 :       gindx(:) = [(i, i=0, npts(1) - 1)]
     310        10564 :       gindy(:) = [(i, i=0, npts(2) - 1)]
     311        10340 :       gindz(:) = [(i, i=0, npts(3) - 1)]
     312         5278 :       lindx(:) = [(i, i=0, npts_local(1) - 1)]
     313        10564 :       lindy(:) = [(i, i=0, npts_local(2) - 1)]
     314        10340 :       lindz(:) = [(i, i=0, npts_local(3) - 1)]
     315              : 
     316         5198 :       x_glbl(:) = gindx*dr(1)
     317         5282 :       y_glbl(:) = gindy*dr(2)
     318         5170 :       z_glbl(:) = gindz*dr(3)
     319              : 
     320              : ! map [0 .. (npts_local-1)] --> [lb .. ub]
     321           80 :       IF (lb1 == ub1) THEN
     322            0 :          lindx(:) = lb1
     323              :       ELSE
     324         2639 :          lindx(:) = lindx(:)*((ub1 - lb1)/(npts_local(1) - 1)) + lb1
     325              :       END IF
     326           80 :       IF (lb2 == ub2) THEN
     327            0 :          lindy(:) = lb2
     328              :       ELSE
     329         5282 :          lindy(:) = lindy(:)*((ub2 - lb2)/(npts_local(2) - 1)) + lb2
     330              :       END IF
     331           80 :       IF (lb3 == ub3) THEN
     332            0 :          lindz(:) = lb3
     333              :       ELSE
     334         5170 :          lindz(:) = lindz(:)*((ub3 - lb3)/(npts_local(3) - 1)) + lb3
     335              :       END IF
     336              : 
     337         2639 :       x_locl(:) = x_glbl(lindx)
     338         5282 :       y_locl(:) = y_glbl(lindy)
     339         5170 :       z_locl(:) = z_glbl(lindz)
     340              : 
     341           80 :       CALL timestop(handle)
     342              : 
     343          160 :    END SUBROUTINE setup_grid_axes
     344              : 
     345              : ! **************************************************************************************************
     346              : !> \brief convolutes a function with a smoothing kernel K_\zeta
     347              : !>                         v * K_\zeta
     348              : !> K_\zeta is the standard mollifier defined as:
     349              : !>        K_\zeta(x) = \frac{1}{\zeta^3} K(\frac{x}{\zeta})
     350              : !> where
     351              : !>        K(x) = \kappa \exp (\frac{1}{|x|^2 - 1}),  if |x| <= 1
     352              : !>             = 0,                                  otherwise
     353              : !> \param pw_pool pool of pw grid
     354              : !> \param zeta parameter \zeta defining the width of the mollifier
     355              : !> \param x_glbl x grid vector of the simulation box
     356              : !> \param y_glbl y grid vector of the simulation box
     357              : !> \param z_glbl z grid vector of the simulation box
     358              : !> \param pw_in the input function
     359              : !> \param pw_out the convoluted function
     360              : !> \par History
     361              : !>       10.2014 created [Hossein Bani-Hashemian]
     362              : !>       07.2015 moved here from ps_implicit_methods.F [Hossein Bani-Hashemian]
     363              : !> \author Mohammad Hossein Bani-Hashemian
     364              : ! **************************************************************************************************
     365           28 :    SUBROUTINE pw_mollifier(pw_pool, zeta, x_glbl, y_glbl, z_glbl, pw_in, pw_out)
     366              : 
     367              :       TYPE(pw_pool_type), INTENT(IN), POINTER            :: pw_pool
     368              :       REAL(dp), INTENT(IN)                               :: zeta
     369              :       REAL(dp), ALLOCATABLE, DIMENSION(:), INTENT(IN)    :: x_glbl, y_glbl, z_glbl
     370              :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: pw_in
     371              :       TYPE(pw_r3d_rs_type), INTENT(INOUT)                :: pw_out
     372              : 
     373              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'pw_mollifier'
     374              : 
     375              :       INTEGER                                            :: handle, i, j, k, lb1, lb2, lb3, ub1, &
     376              :                                                             ub2, ub3
     377              :       INTEGER, DIMENSION(2, 3)                           :: bounds, bounds_local
     378              :       REAL(dp)                                           :: normfact, xi, xmax, xmin, yj, ymax, &
     379              :                                                             ymin, zk, zmax, zmin
     380              :       REAL(dp), DIMENSION(3, 3)                          :: dh
     381              :       TYPE(pw_c1d_gs_type)                               :: G_gs, pw_in_gs, pw_out_gs
     382              :       TYPE(pw_grid_type), POINTER                        :: pw_grid
     383              :       TYPE(pw_r3d_rs_type)                               :: G
     384              : 
     385           28 :       CALL timeset(routineN, handle)
     386              : 
     387           28 :       pw_grid => pw_in%pw_grid
     388          364 :       dh = pw_grid%dh
     389          280 :       bounds_local = pw_grid%bounds_local
     390          280 :       bounds = pw_grid%bounds
     391              : 
     392           28 :       lb1 = bounds_local(1, 1); ub1 = bounds_local(2, 1)
     393           28 :       lb2 = bounds_local(1, 2); ub2 = bounds_local(2, 2)
     394           28 :       lb3 = bounds_local(1, 3); ub3 = bounds_local(2, 3)
     395              : 
     396           28 :       CALL pw_pool%create_pw(G)
     397           28 :       CALL pw_pool%create_pw(G_gs)
     398           28 :       CALL pw_pool%create_pw(pw_in_gs)
     399           28 :       CALL pw_pool%create_pw(pw_out_gs)
     400              : 
     401           28 :       CALL pw_zero(G)
     402           28 :       xmin = x_glbl(bounds(1, 1)); xmax = x_glbl(bounds(2, 1))
     403           28 :       ymin = y_glbl(bounds(1, 2)); ymax = y_glbl(bounds(2, 2))
     404           28 :       zmin = z_glbl(bounds(1, 3)); zmax = z_glbl(bounds(2, 3))
     405              : 
     406         2044 :       DO k = lb3, ub3
     407       147196 :          DO j = lb2, ub2
     408      5372640 :             DO i = lb1, ub1
     409      5225472 :                xi = x_glbl(i); yj = y_glbl(j); zk = z_glbl(k)
     410     21047040 :                IF (norm2([(xi - xmin), (yj - ymin), (zk - zmin)]) < zeta - small_value) THEN
     411         5940 :                   G%array(i, j, k) = EXP(1.0_dp/(norm2([(xi - xmin), (yj - ymin), (zk - zmin)]/zeta)**2 - 1))
     412     20895948 :                ELSE IF (norm2([(xi - xmax), (yj - ymax), (zk - zmax)]) < zeta - small_value) THEN
     413         5940 :                   G%array(i, j, k) = EXP(1.0_dp/(norm2([(xi - xmax), (yj - ymax), (zk - zmax)]/zeta)**2 - 1))
     414     20890008 :                ELSE IF (norm2([(xi - xmin), (yj - ymax), (zk - zmax)]) < zeta - small_value) THEN
     415         5940 :                   G%array(i, j, k) = EXP(1.0_dp/(norm2([(xi - xmin), (yj - ymax), (zk - zmax)]/zeta)**2 - 1))
     416     20884068 :                ELSE IF (norm2([(xi - xmax), (yj - ymin), (zk - zmax)]) < zeta - small_value) THEN
     417         5940 :                   G%array(i, j, k) = EXP(1.0_dp/(norm2([(xi - xmax), (yj - ymin), (zk - zmax)]/zeta)**2 - 1))
     418     20878128 :                ELSE IF (norm2([(xi - xmax), (yj - ymax), (zk - zmin)]) < zeta - small_value) THEN
     419         5940 :                   G%array(i, j, k) = EXP(1.0_dp/(norm2([(xi - xmax), (yj - ymax), (zk - zmin)]/zeta)**2 - 1))
     420     20872188 :                ELSE IF (norm2([(xi - xmin), (yj - ymin), (zk - zmax)]) < zeta - small_value) THEN
     421         5940 :                   G%array(i, j, k) = EXP(1.0_dp/(norm2([(xi - xmin), (yj - ymin), (zk - zmax)]/zeta)**2 - 1))
     422     20866248 :                ELSE IF (norm2([(xi - xmin), (yj - ymax), (zk - zmin)]) < zeta - small_value) THEN
     423         5940 :                   G%array(i, j, k) = EXP(1.0_dp/(norm2([(xi - xmin), (yj - ymax), (zk - zmin)]/zeta)**2 - 1))
     424     20860308 :                ELSE IF (norm2([(xi - xmax), (yj - ymin), (zk - zmin)]) < zeta - small_value) THEN
     425         5940 :                   G%array(i, j, k) = EXP(1.0_dp/(norm2([(xi - xmax), (yj - ymin), (zk - zmin)]/zeta)**2 - 1))
     426              :                END IF
     427              :             END DO
     428              :          END DO
     429              :       END DO
     430           28 :       CALL pw_scale(G, (1.0_dp/zeta)**3)
     431           28 :       normfact = pw_integrate_function(G)
     432           28 :       CALL pw_scale(G, 1.0_dp/normfact)
     433              : 
     434           28 :       CALL pw_transfer(G, G_gs)
     435           28 :       CALL pw_transfer(pw_in, pw_in_gs)
     436      5225500 :       pw_out_gs%array = G_gs%array*pw_in_gs%array
     437           28 :       CALL pw_transfer(pw_out_gs, pw_out)
     438              : 
     439              :       ! multiply by the reciprocal of the forward Fourier transform normalization prefactor (here 1/N, by convention)
     440           28 :       CALL pw_scale(pw_out, REAL(pw_grid%ngpts, KIND=dp))
     441              :       ! from discrete convolution to continuous convolution
     442           28 :       CALL pw_scale(pw_out, pw_grid%dvol)
     443              : 
     444         2044 :       DO k = lb3, ub3
     445       147196 :          DO j = lb2, ub2
     446      5372640 :             DO i = lb1, ub1
     447      5370624 :                IF (ABS(pw_out%array(i, j, k)) <= 1.0E-10_dp) pw_out%array(i, j, k) = 0.0_dp
     448              :             END DO
     449              :          END DO
     450              :       END DO
     451              : 
     452           28 :       CALL pw_pool%give_back_pw(G)
     453           28 :       CALL pw_pool%give_back_pw(G_gs)
     454           28 :       CALL pw_pool%give_back_pw(pw_in_gs)
     455           28 :       CALL pw_pool%give_back_pw(pw_out_gs)
     456           28 :       CALL timestop(handle)
     457              : 
     458           28 :    END SUBROUTINE pw_mollifier
     459              : 
     460              : END MODULE rs_methods
        

Generated by: LCOV version 2.0-1