LCOV - code coverage report
Current view: top level - src/pw - ps_wavelet_methods.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:b279b6b) Lines: 213 224 95.1 %
Date: 2024-04-24 07:13:09 Functions: 5 5 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 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         752 :    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         752 :       CALL timeset(routineN, handle)
      67             : 
      68         752 :       CALL cite_reference(Genovese2006)
      69         752 :       CALL cite_reference(Genovese2007)
      70             : 
      71         752 :       IF (ASSOCIATED(wavelet)) THEN
      72           0 :          CALL ps_wavelet_release(wavelet)
      73             :          NULLIFY (wavelet)
      74             :       END IF
      75             : 
      76        3760 :       ALLOCATE (wavelet)
      77             : 
      78         752 :       nx = pw_grid%npts(1)
      79         752 :       ny = pw_grid%npts(2)
      80         752 :       nz = pw_grid%npts(3)
      81             : 
      82         752 :       hx = pw_grid%dr(1)
      83         752 :       hy = pw_grid%dr(2)
      84         752 :       hz = pw_grid%dr(3)
      85             : 
      86        2256 :       nproc = PRODUCT(pw_grid%para%rs_dims)
      87             : 
      88         752 :       iproc = pw_grid%para%rs_mpo
      89             : 
      90             :       NULLIFY (wavelet%karray, wavelet%rho_z_sliced)
      91             : 
      92         752 :       wavelet%geocode = poisson_params%wavelet_geocode
      93         752 :       wavelet%method = poisson_params%wavelet_method
      94         752 :       wavelet%special_dimension = poisson_params%wavelet_special_dimension
      95         752 :       wavelet%itype_scf = poisson_params%wavelet_scf_type
      96         752 :       wavelet%datacode = "D"
      97             : 
      98         752 :       IF (poisson_params%wavelet_method == WAVELET0D) THEN
      99         456 :          IF (hx .NE. hy) &
     100           0 :             CPABORT("Poisson solver for non cubic cells not yet implemented")
     101         456 :          IF (hz .NE. hy) &
     102           0 :             CPABORT("Poisson solver for non cubic cells not yet implemented")
     103             :       END IF
     104             : 
     105         752 :       CALL RS_z_slice_distribution(wavelet, pw_grid)
     106             : 
     107         752 :       CALL timestop(handle)
     108         752 :    END SUBROUTINE ps_wavelet_create
     109             : 
     110             : ! **************************************************************************************************
     111             : !> \brief ...
     112             : !> \param wavelet ...
     113             : !> \param pw_grid ...
     114             : ! **************************************************************************************************
     115         752 :    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         752 :       CALL timeset(routineN, handle)
     129        2256 :       nproc = PRODUCT(pw_grid%para%rs_dims)
     130         752 :       iproc = pw_grid%para%rs_mpo
     131         752 :       geocode = wavelet%geocode
     132         752 :       nx = pw_grid%npts(1)
     133         752 :       ny = pw_grid%npts(2)
     134         752 :       nz = pw_grid%npts(3)
     135         752 :       hx = pw_grid%dr(1)
     136         752 :       hy = pw_grid%dr(2)
     137         752 :       hz = pw_grid%dr(3)
     138             : 
     139             :       !calculate Dimensions for the z-distributed density and for the kernel
     140             : 
     141         752 :       IF (geocode == 'P') THEN
     142         294 :          CALL P_FFT_dimensions(nx, ny, nz, m1, m2, m3, n1, n2, n3, md1, md2, md3, nd1, nd2, nd3, nproc)
     143         458 :       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         456 :       ELSE IF (geocode == 'F') THEN
     146         456 :          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         752 :       wavelet%PS_grid(1) = md1
     150         752 :       wavelet%PS_grid(2) = md3
     151         752 :       wavelet%PS_grid(3) = md2
     152         752 :       z_dim = md2/nproc
     153             :       !!!!!!!!!      indices y and z are interchanged    !!!!!!!
     154        3760 :       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         752 :                         pw_grid%para%rs_group)
     158             : 
     159         752 :       CALL timestop(handle)
     160         752 :    END SUBROUTINE RS_z_slice_distribution
     161             : 
     162             : ! **************************************************************************************************
     163             : !> \brief ...
     164             : !> \param density ...
     165             : !> \param wavelet ...
     166             : !> \param pw_grid ...
     167             : ! **************************************************************************************************
     168       30089 :    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       30089 :       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       30089 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rbuf, sbuf
     184             : 
     185       30089 :       CALL timeset(routineN, handle)
     186             : 
     187       30089 :       CPASSERT(ASSOCIATED(wavelet))
     188             : 
     189       90267 :       nproc = PRODUCT(pw_grid%para%rs_dims)
     190       30089 :       iproc = pw_grid%para%rs_mpo
     191       30089 :       md2 = wavelet%PS_grid(3)
     192       30089 :       m2 = pw_grid%npts(3)
     193      120356 :       lb(:) = pw_grid%bounds_local(1, :)
     194      120356 :       ub(:) = pw_grid%bounds_local(2, :)
     195       30089 :       local_z_dim = MAX((md2/nproc), 1)
     196             : 
     197      180534 :       ALLOCATE (sbuf(PRODUCT(pw_grid%npts_local)))
     198      180534 :       ALLOCATE (rbuf(PRODUCT(wavelet%PS_grid)/nproc))
     199      330979 :       ALLOCATE (scount(nproc), sdispl(nproc), rcount(nproc), rdispl(nproc), tmp(nproc))
     200             : 
     201   839736760 :       rbuf = 0.0_dp
     202       30089 :       ii = 1
     203      876182 :       DO k = lb(3), ub(3)
     204    30457939 :          DO j = lb(2), ub(2)
     205   849682504 :             DO i = lb(1), ub(1)
     206   819254654 :                sbuf(ii) = density%array(i, j, k)
     207   848836411 :                ii = ii + 1
     208             :             END DO
     209             :          END DO
     210             :       END DO
     211             : 
     212       30089 :       should_warn = 0
     213       30089 :       IF (wavelet%geocode == 'S' .OR. wavelet%geocode == 'F') THEN
     214       14128 :          max_val_low = 0._dp
     215       14128 :          max_val_up = 0._dp
     216    14849982 :          IF (lb(2) == pw_grid%bounds(1, 2)) max_val_low = MAXVAL(ABS(density%array(:, lb(2), :)))
     217    14849982 :          IF (ub(2) == pw_grid%bounds(2, 2)) max_val_up = MAXVAL(ABS(density%array(:, ub(2), :)))
     218       14128 :          IF (max_val_low .GE. 0.0001_dp) should_warn = 1
     219       14128 :          IF (max_val_up .GE. 0.0001_dp) should_warn = 1
     220       14128 :          IF (wavelet%geocode == 'F') THEN
     221       14110 :             max_val_low = 0._dp
     222       14110 :             max_val_up = 0._dp
     223    14666442 :             IF (lb(1) == pw_grid%bounds(1, 1)) max_val_low = MAXVAL(ABS(density%array(lb(1), :, :)))
     224    14666442 :             IF (ub(1) == pw_grid%bounds(2, 1)) max_val_up = MAXVAL(ABS(density%array(ub(1), :, :)))
     225       14110 :             IF (max_val_low .GE. 0.0001_dp) should_warn = 1
     226       14110 :             IF (max_val_up .GE. 0.0001_dp) should_warn = 1
     227       14110 :             max_val_low = 0._dp
     228       14110 :             max_val_up = 0._dp
     229    14822748 :             IF (lb(3) == pw_grid%bounds(1, 3)) max_val_low = MAXVAL(ABS(density%array(:, :, lb(3))))
     230    14822748 :             IF (ub(3) == pw_grid%bounds(2, 3)) max_val_up = MAXVAL(ABS(density%array(:, :, ub(3))))
     231       14110 :             IF (max_val_low .GE. 0.0001_dp) should_warn = 1
     232       14110 :             IF (max_val_up .GE. 0.0001_dp) should_warn = 1
     233             :          END IF
     234             :       END IF
     235             : 
     236       30089 :       CALL pw_grid%para%group%max(should_warn)
     237       30089 :       IF (should_warn > 0 .AND. iproc == 0) &
     238        4184 :          CPWARN("Density non-zero on the edges of the unit cell: wrong results in WAVELET solver")
     239             : 
     240       71926 :       DO i = 0, pw_grid%para%rs_dims(1) - 1
     241      113763 :          DO j = 0, pw_grid%para%rs_dims(2) - 1
     242      125511 :             cart_pos = (/i, j/)
     243       41837 :             CALL pw_grid%para%rs_group%rank_cart(cart_pos, dest)
     244       41837 :             IF ((ub(1) .GE. lb(1)) .AND. (ub(2) .GE. lb(2))) THEN
     245       41837 :                IF (dest*local_z_dim .LE. m2) THEN
     246       41837 :                   IF ((dest + 1)*local_z_dim .LE. m2) THEN
     247       37492 :                      scount(dest + 1) = ABS((ub(1) - lb(1) + 1)*(ub(2) - lb(2) + 1)*local_z_dim)
     248             :                   ELSE
     249        4345 :                      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       41837 :             lox = get_limit(pw_grid%npts(1), pw_grid%para%rs_dims(1), i)
     258       41837 :             loy = get_limit(pw_grid%npts(2), pw_grid%para%rs_dims(2), j)
     259       83674 :             IF ((lox(2) .GE. lox(1)) .AND. (loy(2) .GE. loy(1))) THEN
     260       41837 :                IF (iproc*local_z_dim .LE. m2) THEN
     261       41837 :                   IF ((iproc + 1)*local_z_dim .LE. m2) THEN
     262       37492 :                      rcount(dest + 1) = ABS((lox(2) - lox(1) + 1)*(loy(2) - loy(1) + 1)*local_z_dim)
     263             :                   ELSE
     264        4345 :                      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       30089 :       sdispl(1) = 0
     276       30089 :       rdispl(1) = 0
     277       41837 :       DO i = 2, nproc
     278       11748 :          sdispl(i) = sdispl(i - 1) + scount(i - 1)
     279       41837 :          rdispl(i) = rdispl(i - 1) + rcount(i - 1)
     280             :       END DO
     281  2498698085 :       CALL pw_grid%para%rs_group%alltoall(sbuf, scount, sdispl, rbuf, rcount, rdispl)
     282             :       !!!! and now, how to put the right cubes to the right position!!!!!!
     283             : 
     284   861449872 :       wavelet%rho_z_sliced = 0.0_dp
     285             : 
     286       71926 :       DO i = 0, pw_grid%para%rs_dims(1) - 1
     287      113763 :          DO j = 0, pw_grid%para%rs_dims(2) - 1
     288      125511 :             cart_pos = (/i, j/)
     289       41837 :             CALL pw_grid%para%rs_group%rank_cart(cart_pos, dest)
     290             : 
     291       41837 :             lox = get_limit(pw_grid%npts(1), pw_grid%para%rs_dims(1), i)
     292       41837 :             loy = get_limit(pw_grid%npts(2), pw_grid%para%rs_dims(2), j)
     293       83674 :             IF (iproc*local_z_dim .LE. m2) THEN
     294       41837 :                IF ((iproc + 1)*local_z_dim .LE. m2) THEN
     295             :                   loz = local_z_dim
     296             :                ELSE
     297        4345 :                   loz = MOD(m2, local_z_dim)
     298             :                END IF
     299       41837 :                ii = 1
     300      887930 :                DO k = 1, loz
     301    30469687 :                   DO l = loy(1), loy(2)
     302   849682504 :                      DO m = lox(1), lox(2)
     303   819254654 :                         wavelet%rho_z_sliced(m, l, k) = rbuf(ii + rdispl(dest + 1))
     304   848836411 :                         ii = ii + 1
     305             :                      END DO
     306             :                   END DO
     307             :                END DO
     308             :             END IF
     309             :          END DO
     310             :       END DO
     311             : 
     312       30089 :       DEALLOCATE (sbuf, rbuf, scount, sdispl, rcount, rdispl, tmp)
     313             : 
     314       30089 :       CALL timestop(handle)
     315             : 
     316       30089 :    END SUBROUTINE cp2k_distribution_to_z_slices
     317             : 
     318             : ! **************************************************************************************************
     319             : !> \brief ...
     320             : !> \param density ...
     321             : !> \param wavelet ...
     322             : !> \param pw_grid ...
     323             : ! **************************************************************************************************
     324       30089 :    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       30089 :       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       30089 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rbuf, sbuf
     336             : 
     337           0 :       CPASSERT(ASSOCIATED(wavelet))
     338             : 
     339       90267 :       nproc = PRODUCT(pw_grid%para%rs_dims)
     340       30089 :       iproc = pw_grid%para%rs_mpo
     341       30089 :       md2 = wavelet%PS_grid(3)
     342       30089 :       m2 = pw_grid%npts(3)
     343             : 
     344      120356 :       lb(:) = pw_grid%bounds_local(1, :)
     345      120356 :       ub(:) = pw_grid%bounds_local(2, :)
     346             : 
     347       30089 :       local_z_dim = MAX((md2/nproc), 1)
     348             : 
     349      180534 :       ALLOCATE (rbuf(PRODUCT(pw_grid%npts_local)))
     350      180534 :       ALLOCATE (sbuf(PRODUCT(wavelet%PS_grid)/nproc))
     351      330979 :       ALLOCATE (scount(nproc), sdispl(nproc), rcount(nproc), rdispl(nproc), tmp(nproc))
     352       71926 :       scount = 0
     353       71926 :       rcount = 0
     354   819284743 :       rbuf = 0.0_dp
     355       30089 :       ii = 1
     356       30089 :       IF (iproc*local_z_dim .LE. m2) THEN
     357       30089 :          IF ((iproc + 1)*local_z_dim .LE. m2) THEN
     358             :             loz = local_z_dim
     359             :          ELSE
     360        2682 :             loz = MOD(m2, local_z_dim)
     361             :          END IF
     362             :       ELSE
     363             :          loz = 0
     364             :       END IF
     365             : 
     366       30089 :       min_x = get_limit(pw_grid%npts(1), pw_grid%para%rs_dims(1), 0)
     367       30089 :       min_y = get_limit(pw_grid%npts(2), pw_grid%para%rs_dims(2), 0)
     368       71926 :       DO i = 0, pw_grid%para%rs_dims(1) - 1
     369      113763 :          DO j = 0, pw_grid%para%rs_dims(2) - 1
     370      125511 :             cart_pos = (/i, j/)
     371       41837 :             CALL pw_grid%para%rs_group%rank_cart(cart_pos, dest)
     372       41837 :             IF ((ub(1) .GE. lb(1)) .AND. (ub(2) .GE. lb(2))) THEN
     373       41837 :                IF (dest*local_z_dim .LE. m2) THEN
     374       41837 :                   IF ((dest + 1)*local_z_dim .LE. m2) THEN
     375       37492 :                      rcount(dest + 1) = ABS((ub(1) - lb(1) + 1)*(ub(2) - lb(2) + 1)*local_z_dim)
     376             :                   ELSE
     377        4345 :                      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       41837 :             lox = get_limit(pw_grid%npts(1), pw_grid%para%rs_dims(1), i)
     386       41837 :             loy = get_limit(pw_grid%npts(2), pw_grid%para%rs_dims(2), j)
     387       83674 :             IF ((lox(2) .GE. lox(1)) .AND. (loy(2) .GE. loy(1))) THEN
     388       41837 :                scount(dest + 1) = ABS((lox(2) - lox(1) + 1)*(loy(2) - loy(1) + 1)*loz)
     389      887930 :                DO k = lox(1) - min_x(1) + 1, lox(2) - min_x(1) + 1
     390    30469687 :                   DO l = loy(1) - min_y(1) + 1, loy(2) - min_y(1) + 1
     391   849682504 :                      DO m = 1, loz
     392   819254654 :                         sbuf(ii) = wavelet%rho_z_sliced(k, l, m)
     393   848836411 :                         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       30089 :       sdispl(1) = 0
     403       30089 :       rdispl(1) = 0
     404       41837 :       DO i = 2, nproc
     405       11748 :          sdispl(i) = sdispl(i - 1) + scount(i - 1)
     406       41837 :          rdispl(i) = rdispl(i - 1) + rcount(i - 1)
     407             :       END DO
     408  2478246068 :       CALL pw_grid%para%rs_group%alltoall(sbuf, scount, sdispl, rbuf, rcount, rdispl)
     409             : 
     410             :       !!!! and now, how to put the right cubes to the right position!!!!!!
     411             : 
     412       71926 :       DO i = 0, pw_grid%para%rs_dims(1) - 1
     413      113763 :          DO j = 0, pw_grid%para%rs_dims(2) - 1
     414      125511 :             cart_pos = (/i, j/)
     415       41837 :             CALL pw_grid%para%rs_group%rank_cart(cart_pos, dest)
     416       83674 :             IF (dest*local_z_dim .LE. m2) THEN
     417       41837 :                IF ((dest + 1)*local_z_dim .LE. m2) THEN
     418             :                   loz = local_z_dim
     419             :                ELSE
     420        4345 :                   loz = MOD(m2, local_z_dim)
     421             :                END IF
     422       41837 :                ii = 1
     423       41837 :                IF (lb(3) + (dest*local_z_dim) .LE. ub(3)) THEN
     424      887930 :                   DO m = lb(1), ub(1)
     425    30469687 :                      DO l = lb(2), ub(2)
     426   849682504 :                         DO k = lb(3) + (dest*local_z_dim), lb(3) + (dest*local_z_dim) + loz - 1
     427   819254654 :                            density%array(m, l, k) = rbuf(ii + rdispl(dest + 1))
     428   848836411 :                            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       30089 :       DEALLOCATE (sbuf, rbuf, scount, sdispl, rcount, rdispl, tmp)
     437             : 
     438       30089 :    END SUBROUTINE z_slices_to_cp2k_distribution
     439             : 
     440             : ! **************************************************************************************************
     441             : !> \brief ...
     442             : !> \param wavelet ...
     443             : !> \param pw_grid ...
     444             : ! **************************************************************************************************
     445       30089 :    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       30089 :       CALL timeset(routineN, handle)
     457       90267 :       nproc = PRODUCT(pw_grid%para%rs_dims)
     458       30089 :       iproc = pw_grid%para%rs_mpo
     459       30089 :       geocode = wavelet%geocode
     460       30089 :       nx = pw_grid%npts(1)
     461       30089 :       ny = pw_grid%npts(2)
     462       30089 :       nz = pw_grid%npts(3)
     463       30089 :       hx = pw_grid%dr(1)
     464       30089 :       hy = pw_grid%dr(2)
     465       30089 :       hz = pw_grid%dr(3)
     466             : 
     467             :       CALL PSolver(geocode, iproc, nproc, nx, ny, nz, hx, hy, hz, &
     468       30089 :                    wavelet%rho_z_sliced, wavelet%karray, pw_grid)
     469       30089 :       CALL timestop(handle)
     470       30089 :    END SUBROUTINE ps_wavelet_solve
     471             : 
     472             : END MODULE ps_wavelet_methods

Generated by: LCOV version 1.15