LCOV - code coverage report
Current view: top level - src/pw - ps_wavelet_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 95.1 % 224 213
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 Definition and initialisation of the ps_wavelet data type.
      10              : !> \history 01.2014 Renamed from ps_wavelet_types to disentangle dependencies (Ole Schuett)
      11              : !> \author Florian Schiffmann (09.2007,fschiff)
      12              : ! **************************************************************************************************
      13              : MODULE ps_wavelet_methods
      14              : 
      15              :    USE bibliography,                    ONLY: Genovese2006,&
      16              :                                               Genovese2007,&
      17              :                                               cite_reference
      18              :    USE kinds,                           ONLY: dp
      19              :    USE ps_wavelet_kernel,               ONLY: createKernel
      20              :    USE ps_wavelet_types,                ONLY: WAVELET0D,&
      21              :                                               ps_wavelet_release,&
      22              :                                               ps_wavelet_type
      23              :    USE ps_wavelet_util,                 ONLY: F_FFT_dimensions,&
      24              :                                               PSolver,&
      25              :                                               P_FFT_dimensions,&
      26              :                                               S_FFT_dimensions
      27              :    USE pw_grid_types,                   ONLY: pw_grid_type
      28              :    USE pw_poisson_types,                ONLY: pw_poisson_parameter_type
      29              :    USE pw_types,                        ONLY: pw_r3d_rs_type
      30              :    USE util,                            ONLY: get_limit
      31              : #include "../base/base_uses.f90"
      32              : 
      33              :    IMPLICIT NONE
      34              : 
      35              :    PRIVATE
      36              : 
      37              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ps_wavelet_methods'
      38              : 
      39              : ! *** Public data types ***
      40              : 
      41              :    PUBLIC :: ps_wavelet_create, &
      42              :              cp2k_distribution_to_z_slices, &
      43              :              z_slices_to_cp2k_distribution, &
      44              :              ps_wavelet_solve
      45              : 
      46              : CONTAINS
      47              : 
      48              : ! **************************************************************************************************
      49              : !> \brief creates the ps_wavelet_type which is needed for the link to
      50              : !>      the Poisson Solver of Luigi Genovese
      51              : !> \param poisson_params ...
      52              : !> \param wavelet wavelet to create
      53              : !> \param pw_grid the grid that is used to create the wavelet kernel
      54              : !> \author Flroian Schiffmann
      55              : ! **************************************************************************************************
      56          836 :    SUBROUTINE ps_wavelet_create(poisson_params, wavelet, pw_grid)
      57              :       TYPE(pw_poisson_parameter_type), INTENT(IN)        :: poisson_params
      58              :       TYPE(ps_wavelet_type), POINTER                     :: wavelet
      59              :       TYPE(pw_grid_type), POINTER                        :: pw_grid
      60              : 
      61              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'ps_wavelet_create'
      62              : 
      63              :       INTEGER                                            :: handle, iproc, nproc, nx, ny, nz
      64              :       REAL(KIND=dp)                                      :: hx, hy, hz
      65              : 
      66          836 :       CALL timeset(routineN, handle)
      67              : 
      68          836 :       CALL cite_reference(Genovese2006)
      69          836 :       CALL cite_reference(Genovese2007)
      70              : 
      71          836 :       IF (ASSOCIATED(wavelet)) THEN
      72            0 :          CALL ps_wavelet_release(wavelet)
      73              :          NULLIFY (wavelet)
      74              :       END IF
      75              : 
      76         4180 :       ALLOCATE (wavelet)
      77              : 
      78          836 :       nx = pw_grid%npts(1)
      79          836 :       ny = pw_grid%npts(2)
      80          836 :       nz = pw_grid%npts(3)
      81              : 
      82          836 :       hx = pw_grid%dr(1)
      83          836 :       hy = pw_grid%dr(2)
      84          836 :       hz = pw_grid%dr(3)
      85              : 
      86         2508 :       nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
      87              : 
      88          836 :       iproc = pw_grid%para%group%mepos
      89              : 
      90              :       NULLIFY (wavelet%karray, wavelet%rho_z_sliced)
      91              : 
      92          836 :       wavelet%geocode = poisson_params%wavelet_geocode
      93          836 :       wavelet%method = poisson_params%wavelet_method
      94          836 :       wavelet%special_dimension = poisson_params%wavelet_special_dimension
      95          836 :       wavelet%itype_scf = poisson_params%wavelet_scf_type
      96          836 :       wavelet%datacode = "D"
      97              : 
      98          836 :       IF (poisson_params%wavelet_method == WAVELET0D) THEN
      99          508 :          IF (hx /= hy) &
     100            0 :             CPABORT("Poisson solver for non cubic cells not yet implemented")
     101          508 :          IF (hz /= hy) &
     102            0 :             CPABORT("Poisson solver for non cubic cells not yet implemented")
     103              :       END IF
     104              : 
     105          836 :       CALL RS_z_slice_distribution(wavelet, pw_grid)
     106              : 
     107          836 :       CALL timestop(handle)
     108          836 :    END SUBROUTINE ps_wavelet_create
     109              : 
     110              : ! **************************************************************************************************
     111              : !> \brief ...
     112              : !> \param wavelet ...
     113              : !> \param pw_grid ...
     114              : ! **************************************************************************************************
     115          836 :    SUBROUTINE RS_z_slice_distribution(wavelet, pw_grid)
     116              : 
     117              :       TYPE(ps_wavelet_type), POINTER                     :: wavelet
     118              :       TYPE(pw_grid_type), POINTER                        :: pw_grid
     119              : 
     120              :       CHARACTER(len=*), PARAMETER :: routineN = 'RS_z_slice_distribution'
     121              : 
     122              :       CHARACTER(LEN=1)                                   :: geocode
     123              :       INTEGER                                            :: handle, iproc, m1, m2, m3, md1, md2, &
     124              :                                                             md3, n1, n2, n3, nd1, nd2, nd3, nproc, &
     125              :                                                             nx, ny, nz, z_dim
     126              :       REAL(KIND=dp)                                      :: hx, hy, hz
     127              : 
     128          836 :       CALL timeset(routineN, handle)
     129         2508 :       nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
     130          836 :       iproc = pw_grid%para%group%mepos
     131          836 :       geocode = wavelet%geocode
     132          836 :       nx = pw_grid%npts(1)
     133          836 :       ny = pw_grid%npts(2)
     134          836 :       nz = pw_grid%npts(3)
     135          836 :       hx = pw_grid%dr(1)
     136          836 :       hy = pw_grid%dr(2)
     137          836 :       hz = pw_grid%dr(3)
     138              : 
     139              :       !calculate Dimensions for the z-distributed density and for the kernel
     140              : 
     141          836 :       IF (geocode == 'P') THEN
     142          326 :          CALL P_FFT_dimensions(nx, ny, nz, m1, m2, m3, n1, n2, n3, md1, md2, md3, nd1, nd2, nd3, nproc)
     143          510 :       ELSE IF (geocode == 'S') THEN
     144            2 :          CALL S_FFT_dimensions(nx, ny, nz, m1, m2, m3, n1, n2, n3, md1, md2, md3, nd1, nd2, nd3, nproc)
     145          508 :       ELSE IF (geocode == 'F') THEN
     146          508 :          CALL F_FFT_dimensions(nx, ny, nz, m1, m2, m3, n1, n2, n3, md1, md2, md3, nd1, nd2, nd3, nproc)
     147              :       END IF
     148              : 
     149          836 :       wavelet%PS_grid(1) = md1
     150          836 :       wavelet%PS_grid(2) = md3
     151          836 :       wavelet%PS_grid(3) = md2
     152          836 :       z_dim = md2/nproc
     153              :       !!!!!!!!!      indices y and z are interchanged    !!!!!!!
     154         4180 :       ALLOCATE (wavelet%rho_z_sliced(md1, md3, z_dim))
     155              : 
     156              :       CALL createKernel(geocode, nx, ny, nz, hx, hy, hz, wavelet%itype_scf, iproc, nproc, wavelet%karray, &
     157          836 :                         pw_grid%para%group)
     158              : 
     159          836 :       CALL timestop(handle)
     160          836 :    END SUBROUTINE RS_z_slice_distribution
     161              : 
     162              : ! **************************************************************************************************
     163              : !> \brief ...
     164              : !> \param density ...
     165              : !> \param wavelet ...
     166              : !> \param pw_grid ...
     167              : ! **************************************************************************************************
     168        32597 :    SUBROUTINE cp2k_distribution_to_z_slices(density, wavelet, pw_grid)
     169              : 
     170              :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: density
     171              :       TYPE(ps_wavelet_type), POINTER                     :: wavelet
     172              :       TYPE(pw_grid_type), POINTER                        :: pw_grid
     173              : 
     174              :       CHARACTER(len=*), PARAMETER :: routineN = 'cp2k_distribution_to_z_slices'
     175              : 
     176              :       INTEGER                                            :: dest, handle, i, ii, iproc, j, k, l, &
     177              :                                                             local_z_dim, loz, m, m2, md2, nproc, &
     178              :                                                             should_warn
     179        32597 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: rcount, rdispl, scount, sdispl, tmp
     180              :       INTEGER, DIMENSION(2)                              :: cart_pos, lox, loy
     181              :       INTEGER, DIMENSION(3)                              :: lb, ub
     182              :       REAL(KIND=dp)                                      :: max_val_low, max_val_up
     183        32597 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rbuf, sbuf
     184              : 
     185        32597 :       CALL timeset(routineN, handle)
     186              : 
     187        32597 :       CPASSERT(ASSOCIATED(wavelet))
     188              : 
     189        97791 :       nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
     190        32597 :       iproc = pw_grid%para%group%mepos
     191        32597 :       md2 = wavelet%PS_grid(3)
     192        32597 :       m2 = pw_grid%npts(3)
     193       130388 :       lb(:) = pw_grid%bounds_local(1, :)
     194       130388 :       ub(:) = pw_grid%bounds_local(2, :)
     195        32597 :       local_z_dim = MAX((md2/nproc), 1)
     196              : 
     197       195582 :       ALLOCATE (sbuf(PRODUCT(pw_grid%npts_local)))
     198       195582 :       ALLOCATE (rbuf(PRODUCT(wavelet%PS_grid)/nproc))
     199       228179 :       ALLOCATE (scount(nproc), sdispl(nproc), rcount(nproc), rdispl(nproc), tmp(nproc))
     200              : 
     201    931727658 :       rbuf = 0.0_dp
     202        32597 :       ii = 1
     203       952598 :       DO k = lb(3), ub(3)
     204     33182575 :          DO j = lb(2), ub(2)
     205    945585923 :             DO i = lb(1), ub(1)
     206    912435945 :                sbuf(ii) = density%array(i, j, k)
     207    944665922 :                ii = ii + 1
     208              :             END DO
     209              :          END DO
     210              :       END DO
     211              : 
     212        32597 :       should_warn = 0
     213        32597 :       IF (wavelet%geocode == 'S' .OR. wavelet%geocode == 'F') THEN
     214        15274 :          max_val_low = 0._dp
     215        15274 :          max_val_up = 0._dp
     216     16423473 :          IF (lb(2) == pw_grid%bounds(1, 2)) max_val_low = MAXVAL(ABS(density%array(:, lb(2), :)))
     217     16423473 :          IF (ub(2) == pw_grid%bounds(2, 2)) max_val_up = MAXVAL(ABS(density%array(:, ub(2), :)))
     218        15274 :          IF (max_val_low >= 0.0001_dp) should_warn = 1
     219        15274 :          IF (max_val_up >= 0.0001_dp) should_warn = 1
     220        15274 :          IF (wavelet%geocode == 'F') THEN
     221        15256 :             max_val_low = 0._dp
     222        15256 :             max_val_up = 0._dp
     223     16017012 :             IF (lb(1) == pw_grid%bounds(1, 1)) max_val_low = MAXVAL(ABS(density%array(lb(1), :, :)))
     224     16017012 :             IF (ub(1) == pw_grid%bounds(2, 1)) max_val_up = MAXVAL(ABS(density%array(ub(1), :, :)))
     225        15256 :             IF (max_val_low >= 0.0001_dp) should_warn = 1
     226        15256 :             IF (max_val_up >= 0.0001_dp) should_warn = 1
     227        15256 :             max_val_low = 0._dp
     228        15256 :             max_val_up = 0._dp
     229     16184343 :             IF (lb(3) == pw_grid%bounds(1, 3)) max_val_low = MAXVAL(ABS(density%array(:, :, lb(3))))
     230     16184343 :             IF (ub(3) == pw_grid%bounds(2, 3)) max_val_up = MAXVAL(ABS(density%array(:, :, ub(3))))
     231        15256 :             IF (max_val_low >= 0.0001_dp) should_warn = 1
     232        15256 :             IF (max_val_up >= 0.0001_dp) should_warn = 1
     233              :          END IF
     234              :       END IF
     235              : 
     236        32597 :       CALL pw_grid%para%group%max(should_warn)
     237        32597 :       IF (should_warn > 0 .AND. iproc == 0) THEN
     238         4400 :          CPWARN("Density non-zero on the edges of the unit cell: wrong results in WAVELET solver")
     239              :       END IF
     240        77708 :       DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
     241       122819 :          DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
     242       135333 :             cart_pos = [i, j]
     243        45111 :             CALL pw_grid%para%group%rank_cart(cart_pos, dest)
     244        45111 :             IF ((ub(1) >= lb(1)) .AND. (ub(2) >= lb(2))) THEN
     245        45111 :                IF (dest*local_z_dim <= m2) THEN
     246        45111 :                   IF ((dest + 1)*local_z_dim <= m2) THEN
     247        40676 :                      scount(dest + 1) = ABS((ub(1) - lb(1) + 1)*(ub(2) - lb(2) + 1)*local_z_dim)
     248              :                   ELSE
     249         4435 :                      scount(dest + 1) = ABS((ub(1) - lb(1) + 1)*(ub(2) - lb(2) + 1)*MOD(m2, local_z_dim))
     250              :                   END IF
     251              :                ELSE
     252            0 :                   scount(dest + 1) = 0
     253              :                END IF
     254              :             ELSE
     255            0 :                scount(dest + 1) = 0
     256              :             END IF
     257        45111 :             lox = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), i)
     258        45111 :             loy = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), j)
     259        90222 :             IF ((lox(2) >= lox(1)) .AND. (loy(2) >= loy(1))) THEN
     260        45111 :                IF (iproc*local_z_dim <= m2) THEN
     261        45111 :                   IF ((iproc + 1)*local_z_dim <= m2) THEN
     262        40676 :                      rcount(dest + 1) = ABS((lox(2) - lox(1) + 1)*(loy(2) - loy(1) + 1)*local_z_dim)
     263              :                   ELSE
     264         4435 :                      rcount(dest + 1) = ABS((lox(2) - lox(1) + 1)*(loy(2) - loy(1) + 1)*MOD(m2, local_z_dim))
     265              :                   END IF
     266              :                ELSE
     267            0 :                   rcount(dest + 1) = 0
     268              :                END IF
     269              :             ELSE
     270            0 :                rcount(dest + 1) = 0
     271              :             END IF
     272              : 
     273              :          END DO
     274              :       END DO
     275        32597 :       sdispl(1) = 0
     276        32597 :       rdispl(1) = 0
     277        45111 :       DO i = 2, nproc
     278        12514 :          sdispl(i) = sdispl(i - 1) + scount(i - 1)
     279        45111 :          rdispl(i) = rdispl(i - 1) + rcount(i - 1)
     280              :       END DO
     281   2775858664 :       CALL pw_grid%para%group%alltoall(sbuf, scount, sdispl, rbuf, rcount, rdispl)
     282              :       !!!! and now, how to put the right cubes to the right position!!!!!!
     283              : 
     284    955512940 :       wavelet%rho_z_sliced = 0.0_dp
     285              : 
     286        77708 :       DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
     287       122819 :          DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
     288       135333 :             cart_pos = [i, j]
     289        45111 :             CALL pw_grid%para%group%rank_cart(cart_pos, dest)
     290              : 
     291        45111 :             lox = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), i)
     292        45111 :             loy = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), j)
     293        90222 :             IF (iproc*local_z_dim <= m2) THEN
     294        45111 :                IF ((iproc + 1)*local_z_dim <= m2) THEN
     295              :                   loz = local_z_dim
     296              :                ELSE
     297         4435 :                   loz = MOD(m2, local_z_dim)
     298              :                END IF
     299        45111 :                ii = 1
     300       965112 :                DO k = 1, loz
     301     33195089 :                   DO l = loy(1), loy(2)
     302    945585923 :                      DO m = lox(1), lox(2)
     303    912435945 :                         wavelet%rho_z_sliced(m, l, k) = rbuf(ii + rdispl(dest + 1))
     304    944665922 :                         ii = ii + 1
     305              :                      END DO
     306              :                   END DO
     307              :                END DO
     308              :             END IF
     309              :          END DO
     310              :       END DO
     311              : 
     312        32597 :       DEALLOCATE (sbuf, rbuf, scount, sdispl, rcount, rdispl, tmp)
     313              : 
     314        32597 :       CALL timestop(handle)
     315              : 
     316        32597 :    END SUBROUTINE cp2k_distribution_to_z_slices
     317              : 
     318              : ! **************************************************************************************************
     319              : !> \brief ...
     320              : !> \param density ...
     321              : !> \param wavelet ...
     322              : !> \param pw_grid ...
     323              : ! **************************************************************************************************
     324        32597 :    SUBROUTINE z_slices_to_cp2k_distribution(density, wavelet, pw_grid)
     325              : 
     326              :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: density
     327              :       TYPE(ps_wavelet_type), POINTER                     :: wavelet
     328              :       TYPE(pw_grid_type), POINTER                        :: pw_grid
     329              : 
     330              :       INTEGER                                            :: dest, i, ii, iproc, j, k, l, &
     331              :                                                             local_z_dim, loz, m, m2, md2, nproc
     332        32597 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: rcount, rdispl, scount, sdispl, tmp
     333              :       INTEGER, DIMENSION(2)                              :: cart_pos, lox, loy, min_x, min_y
     334              :       INTEGER, DIMENSION(3)                              :: lb, ub
     335        32597 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rbuf, sbuf
     336              : 
     337            0 :       CPASSERT(ASSOCIATED(wavelet))
     338              : 
     339        97791 :       nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
     340        32597 :       iproc = pw_grid%para%group%mepos
     341        32597 :       md2 = wavelet%PS_grid(3)
     342        32597 :       m2 = pw_grid%npts(3)
     343              : 
     344       130388 :       lb(:) = pw_grid%bounds_local(1, :)
     345       130388 :       ub(:) = pw_grid%bounds_local(2, :)
     346              : 
     347        32597 :       local_z_dim = MAX((md2/nproc), 1)
     348              : 
     349       195582 :       ALLOCATE (rbuf(PRODUCT(pw_grid%npts_local)))
     350       195582 :       ALLOCATE (sbuf(PRODUCT(wavelet%PS_grid)/nproc))
     351       228179 :       ALLOCATE (scount(nproc), sdispl(nproc), rcount(nproc), rdispl(nproc), tmp(nproc))
     352        77708 :       scount = 0
     353        77708 :       rcount = 0
     354    912468542 :       rbuf = 0.0_dp
     355        32597 :       ii = 1
     356        32597 :       IF (iproc*local_z_dim <= m2) THEN
     357        32597 :          IF ((iproc + 1)*local_z_dim <= m2) THEN
     358              :             loz = local_z_dim
     359              :          ELSE
     360         2727 :             loz = MOD(m2, local_z_dim)
     361              :          END IF
     362              :       ELSE
     363              :          loz = 0
     364              :       END IF
     365              : 
     366        32597 :       min_x = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), 0)
     367        32597 :       min_y = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), 0)
     368        77708 :       DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
     369       122819 :          DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
     370       135333 :             cart_pos = [i, j]
     371        45111 :             CALL pw_grid%para%group%rank_cart(cart_pos, dest)
     372        45111 :             IF ((ub(1) >= lb(1)) .AND. (ub(2) >= lb(2))) THEN
     373        45111 :                IF (dest*local_z_dim <= m2) THEN
     374        45111 :                   IF ((dest + 1)*local_z_dim <= m2) THEN
     375        40676 :                      rcount(dest + 1) = ABS((ub(1) - lb(1) + 1)*(ub(2) - lb(2) + 1)*local_z_dim)
     376              :                   ELSE
     377         4435 :                      rcount(dest + 1) = ABS((ub(1) - lb(1) + 1)*(ub(2) - lb(2) + 1)*MOD(m2, local_z_dim))
     378              :                   END IF
     379              :                ELSE
     380            0 :                   rcount(dest + 1) = 0
     381              :                END IF
     382              :             ELSE
     383            0 :                rcount(dest + 1) = 0
     384              :             END IF
     385        45111 :             lox = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), i)
     386        45111 :             loy = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), j)
     387        90222 :             IF ((lox(2) >= lox(1)) .AND. (loy(2) >= loy(1))) THEN
     388        45111 :                scount(dest + 1) = ABS((lox(2) - lox(1) + 1)*(loy(2) - loy(1) + 1)*loz)
     389       965112 :                DO k = lox(1) - min_x(1) + 1, lox(2) - min_x(1) + 1
     390     33195089 :                   DO l = loy(1) - min_y(1) + 1, loy(2) - min_y(1) + 1
     391    945585923 :                      DO m = 1, loz
     392    912435945 :                         sbuf(ii) = wavelet%rho_z_sliced(k, l, m)
     393    944665922 :                         ii = ii + 1
     394              :                      END DO
     395              :                   END DO
     396              :                END DO
     397              :             ELSE
     398            0 :                scount(dest + 1) = 0
     399              :             END IF
     400              :          END DO
     401              :       END DO
     402        32597 :       sdispl(1) = 0
     403        32597 :       rdispl(1) = 0
     404        45111 :       DO i = 2, nproc
     405        12514 :          sdispl(i) = sdispl(i - 1) + scount(i - 1)
     406        45111 :          rdispl(i) = rdispl(i - 1) + rcount(i - 1)
     407              :       END DO
     408   2756599548 :       CALL pw_grid%para%group%alltoall(sbuf, scount, sdispl, rbuf, rcount, rdispl)
     409              : 
     410              :       !!!! and now, how to put the right cubes to the right position!!!!!!
     411              : 
     412        77708 :       DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
     413       122819 :          DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
     414       135333 :             cart_pos = [i, j]
     415        45111 :             CALL pw_grid%para%group%rank_cart(cart_pos, dest)
     416        90222 :             IF (dest*local_z_dim <= m2) THEN
     417        45111 :                IF ((dest + 1)*local_z_dim <= m2) THEN
     418              :                   loz = local_z_dim
     419              :                ELSE
     420         4435 :                   loz = MOD(m2, local_z_dim)
     421              :                END IF
     422        45111 :                ii = 1
     423        45111 :                IF (lb(3) + (dest*local_z_dim) <= ub(3)) THEN
     424       965112 :                   DO m = lb(1), ub(1)
     425     33195089 :                      DO l = lb(2), ub(2)
     426    945585923 :                         DO k = lb(3) + (dest*local_z_dim), lb(3) + (dest*local_z_dim) + loz - 1
     427    912435945 :                            density%array(m, l, k) = rbuf(ii + rdispl(dest + 1))
     428    944665922 :                            ii = ii + 1
     429              :                         END DO
     430              :                      END DO
     431              :                   END DO
     432              :                END IF
     433              :             END IF
     434              :          END DO
     435              :       END DO
     436        32597 :       DEALLOCATE (sbuf, rbuf, scount, sdispl, rcount, rdispl, tmp)
     437              : 
     438        32597 :    END SUBROUTINE z_slices_to_cp2k_distribution
     439              : 
     440              : ! **************************************************************************************************
     441              : !> \brief ...
     442              : !> \param wavelet ...
     443              : !> \param pw_grid ...
     444              : ! **************************************************************************************************
     445        32597 :    SUBROUTINE ps_wavelet_solve(wavelet, pw_grid)
     446              : 
     447              :       TYPE(ps_wavelet_type), POINTER                     :: wavelet
     448              :       TYPE(pw_grid_type), POINTER                        :: pw_grid
     449              : 
     450              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'ps_wavelet_solve'
     451              : 
     452              :       CHARACTER(LEN=1)                                   :: geocode
     453              :       INTEGER                                            :: handle, iproc, nproc, nx, ny, nz
     454              :       REAL(KIND=dp)                                      :: hx, hy, hz
     455              : 
     456        32597 :       CALL timeset(routineN, handle)
     457        97791 :       nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
     458        32597 :       iproc = pw_grid%para%group%mepos
     459        32597 :       geocode = wavelet%geocode
     460        32597 :       nx = pw_grid%npts(1)
     461        32597 :       ny = pw_grid%npts(2)
     462        32597 :       nz = pw_grid%npts(3)
     463        32597 :       hx = pw_grid%dr(1)
     464        32597 :       hy = pw_grid%dr(2)
     465        32597 :       hz = pw_grid%dr(3)
     466              : 
     467              :       CALL PSolver(geocode, iproc, nproc, nx, ny, nz, hx, hy, hz, &
     468        32597 :                    wavelet%rho_z_sliced, wavelet%karray, pw_grid)
     469        32597 :       CALL timestop(handle)
     470        32597 :    END SUBROUTINE ps_wavelet_solve
     471              : 
     472              : END MODULE ps_wavelet_methods
        

Generated by: LCOV version 2.0-1