LCOV - code coverage report
Current view: top level - src/pw - ps_wavelet_methods.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:2fce0f8) Lines: 213 224 95.1 %
Date: 2024-12-21 06:28:57 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         840 :    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         840 :       CALL timeset(routineN, handle)
      67             : 
      68         840 :       CALL cite_reference(Genovese2006)
      69         840 :       CALL cite_reference(Genovese2007)
      70             : 
      71         840 :       IF (ASSOCIATED(wavelet)) THEN
      72           0 :          CALL ps_wavelet_release(wavelet)
      73             :          NULLIFY (wavelet)
      74             :       END IF
      75             : 
      76        4200 :       ALLOCATE (wavelet)
      77             : 
      78         840 :       nx = pw_grid%npts(1)
      79         840 :       ny = pw_grid%npts(2)
      80         840 :       nz = pw_grid%npts(3)
      81             : 
      82         840 :       hx = pw_grid%dr(1)
      83         840 :       hy = pw_grid%dr(2)
      84         840 :       hz = pw_grid%dr(3)
      85             : 
      86        2520 :       nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
      87             : 
      88         840 :       iproc = pw_grid%para%group%mepos
      89             : 
      90             :       NULLIFY (wavelet%karray, wavelet%rho_z_sliced)
      91             : 
      92         840 :       wavelet%geocode = poisson_params%wavelet_geocode
      93         840 :       wavelet%method = poisson_params%wavelet_method
      94         840 :       wavelet%special_dimension = poisson_params%wavelet_special_dimension
      95         840 :       wavelet%itype_scf = poisson_params%wavelet_scf_type
      96         840 :       wavelet%datacode = "D"
      97             : 
      98         840 :       IF (poisson_params%wavelet_method == WAVELET0D) THEN
      99         526 :          IF (hx .NE. hy) &
     100           0 :             CPABORT("Poisson solver for non cubic cells not yet implemented")
     101         526 :          IF (hz .NE. hy) &
     102           0 :             CPABORT("Poisson solver for non cubic cells not yet implemented")
     103             :       END IF
     104             : 
     105         840 :       CALL RS_z_slice_distribution(wavelet, pw_grid)
     106             : 
     107         840 :       CALL timestop(handle)
     108         840 :    END SUBROUTINE ps_wavelet_create
     109             : 
     110             : ! **************************************************************************************************
     111             : !> \brief ...
     112             : !> \param wavelet ...
     113             : !> \param pw_grid ...
     114             : ! **************************************************************************************************
     115         840 :    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         840 :       CALL timeset(routineN, handle)
     129        2520 :       nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
     130         840 :       iproc = pw_grid%para%group%mepos
     131         840 :       geocode = wavelet%geocode
     132         840 :       nx = pw_grid%npts(1)
     133         840 :       ny = pw_grid%npts(2)
     134         840 :       nz = pw_grid%npts(3)
     135         840 :       hx = pw_grid%dr(1)
     136         840 :       hy = pw_grid%dr(2)
     137         840 :       hz = pw_grid%dr(3)
     138             : 
     139             :       !calculate Dimensions for the z-distributed density and for the kernel
     140             : 
     141         840 :       IF (geocode == 'P') THEN
     142         312 :          CALL P_FFT_dimensions(nx, ny, nz, m1, m2, m3, n1, n2, n3, md1, md2, md3, nd1, nd2, nd3, nproc)
     143         528 :       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         526 :       ELSE IF (geocode == 'F') THEN
     146         526 :          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         840 :       wavelet%PS_grid(1) = md1
     150         840 :       wavelet%PS_grid(2) = md3
     151         840 :       wavelet%PS_grid(3) = md2
     152         840 :       z_dim = md2/nproc
     153             :       !!!!!!!!!      indices y and z are interchanged    !!!!!!!
     154        4200 :       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         840 :                         pw_grid%para%group)
     158             : 
     159         840 :       CALL timestop(handle)
     160         840 :    END SUBROUTINE RS_z_slice_distribution
     161             : 
     162             : ! **************************************************************************************************
     163             : !> \brief ...
     164             : !> \param density ...
     165             : !> \param wavelet ...
     166             : !> \param pw_grid ...
     167             : ! **************************************************************************************************
     168       31915 :    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       31915 :       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       31915 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rbuf, sbuf
     184             : 
     185       31915 :       CALL timeset(routineN, handle)
     186             : 
     187       31915 :       CPASSERT(ASSOCIATED(wavelet))
     188             : 
     189       95745 :       nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
     190       31915 :       iproc = pw_grid%para%group%mepos
     191       31915 :       md2 = wavelet%PS_grid(3)
     192       31915 :       m2 = pw_grid%npts(3)
     193      127660 :       lb(:) = pw_grid%bounds_local(1, :)
     194      127660 :       ub(:) = pw_grid%bounds_local(2, :)
     195       31915 :       local_z_dim = MAX((md2/nproc), 1)
     196             : 
     197      191490 :       ALLOCATE (sbuf(PRODUCT(pw_grid%npts_local)))
     198      191490 :       ALLOCATE (rbuf(PRODUCT(wavelet%PS_grid)/nproc))
     199      223405 :       ALLOCATE (scount(nproc), sdispl(nproc), rcount(nproc), rdispl(nproc), tmp(nproc))
     200             : 
     201   891389598 :       rbuf = 0.0_dp
     202       31915 :       ii = 1
     203      940070 :       DO k = lb(3), ub(3)
     204    32708669 :          DO j = lb(2), ub(2)
     205   904342950 :             DO i = lb(1), ub(1)
     206   871666196 :                sbuf(ii) = density%array(i, j, k)
     207   903434795 :                ii = ii + 1
     208             :             END DO
     209             :          END DO
     210             :       END DO
     211             : 
     212       31915 :       should_warn = 0
     213       31915 :       IF (wavelet%geocode == 'S' .OR. wavelet%geocode == 'F') THEN
     214       15354 :          max_val_low = 0._dp
     215       15354 :          max_val_up = 0._dp
     216    16251965 :          IF (lb(2) == pw_grid%bounds(1, 2)) max_val_low = MAXVAL(ABS(density%array(:, lb(2), :)))
     217    16251965 :          IF (ub(2) == pw_grid%bounds(2, 2)) max_val_up = MAXVAL(ABS(density%array(:, ub(2), :)))
     218       15354 :          IF (max_val_low .GE. 0.0001_dp) should_warn = 1
     219       15354 :          IF (max_val_up .GE. 0.0001_dp) should_warn = 1
     220       15354 :          IF (wavelet%geocode == 'F') THEN
     221       15336 :             max_val_low = 0._dp
     222       15336 :             max_val_up = 0._dp
     223    16053638 :             IF (lb(1) == pw_grid%bounds(1, 1)) max_val_low = MAXVAL(ABS(density%array(lb(1), :, :)))
     224    16053638 :             IF (ub(1) == pw_grid%bounds(2, 1)) max_val_up = MAXVAL(ABS(density%array(ub(1), :, :)))
     225       15336 :             IF (max_val_low .GE. 0.0001_dp) should_warn = 1
     226       15336 :             IF (max_val_up .GE. 0.0001_dp) should_warn = 1
     227       15336 :             max_val_low = 0._dp
     228       15336 :             max_val_up = 0._dp
     229    16224731 :             IF (lb(3) == pw_grid%bounds(1, 3)) max_val_low = MAXVAL(ABS(density%array(:, :, lb(3))))
     230    16224731 :             IF (ub(3) == pw_grid%bounds(2, 3)) max_val_up = MAXVAL(ABS(density%array(:, :, ub(3))))
     231       15336 :             IF (max_val_low .GE. 0.0001_dp) should_warn = 1
     232       15336 :             IF (max_val_up .GE. 0.0001_dp) should_warn = 1
     233             :          END IF
     234             :       END IF
     235             : 
     236       31915 :       CALL pw_grid%para%group%max(should_warn)
     237       31915 :       IF (should_warn > 0 .AND. iproc == 0) THEN
     238        4291 :          CPWARN("Density non-zero on the edges of the unit cell: wrong results in WAVELET solver")
     239             :       END IF
     240       76382 :       DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
     241      120849 :          DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
     242      133401 :             cart_pos = (/i, j/)
     243       44467 :             CALL pw_grid%para%group%rank_cart(cart_pos, dest)
     244       44467 :             IF ((ub(1) .GE. lb(1)) .AND. (ub(2) .GE. lb(2))) THEN
     245       44467 :                IF (dest*local_z_dim .LE. m2) THEN
     246       44467 :                   IF ((dest + 1)*local_z_dim .LE. m2) THEN
     247       40074 :                      scount(dest + 1) = ABS((ub(1) - lb(1) + 1)*(ub(2) - lb(2) + 1)*local_z_dim)
     248             :                   ELSE
     249        4393 :                      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       44467 :             lox = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), i)
     258       44467 :             loy = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), j)
     259       88934 :             IF ((lox(2) .GE. lox(1)) .AND. (loy(2) .GE. loy(1))) THEN
     260       44467 :                IF (iproc*local_z_dim .LE. m2) THEN
     261       44467 :                   IF ((iproc + 1)*local_z_dim .LE. m2) THEN
     262       40074 :                      rcount(dest + 1) = ABS((lox(2) - lox(1) + 1)*(loy(2) - loy(1) + 1)*local_z_dim)
     263             :                   ELSE
     264        4393 :                      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       31915 :       sdispl(1) = 0
     276       31915 :       rdispl(1) = 0
     277       44467 :       DO i = 2, nproc
     278       12552 :          sdispl(i) = sdispl(i - 1) + scount(i - 1)
     279       44467 :          rdispl(i) = rdispl(i - 1) + rcount(i - 1)
     280             :       END DO
     281  2654413477 :       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   914747986 :       wavelet%rho_z_sliced = 0.0_dp
     285             : 
     286       76382 :       DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
     287      120849 :          DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
     288      133401 :             cart_pos = (/i, j/)
     289       44467 :             CALL pw_grid%para%group%rank_cart(cart_pos, dest)
     290             : 
     291       44467 :             lox = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), i)
     292       44467 :             loy = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), j)
     293       88934 :             IF (iproc*local_z_dim .LE. m2) THEN
     294       44467 :                IF ((iproc + 1)*local_z_dim .LE. m2) THEN
     295             :                   loz = local_z_dim
     296             :                ELSE
     297        4393 :                   loz = MOD(m2, local_z_dim)
     298             :                END IF
     299       44467 :                ii = 1
     300      952622 :                DO k = 1, loz
     301    32721221 :                   DO l = loy(1), loy(2)
     302   904342950 :                      DO m = lox(1), lox(2)
     303   871666196 :                         wavelet%rho_z_sliced(m, l, k) = rbuf(ii + rdispl(dest + 1))
     304   903434795 :                         ii = ii + 1
     305             :                      END DO
     306             :                   END DO
     307             :                END DO
     308             :             END IF
     309             :          END DO
     310             :       END DO
     311             : 
     312       31915 :       DEALLOCATE (sbuf, rbuf, scount, sdispl, rcount, rdispl, tmp)
     313             : 
     314       31915 :       CALL timestop(handle)
     315             : 
     316       31915 :    END SUBROUTINE cp2k_distribution_to_z_slices
     317             : 
     318             : ! **************************************************************************************************
     319             : !> \brief ...
     320             : !> \param density ...
     321             : !> \param wavelet ...
     322             : !> \param pw_grid ...
     323             : ! **************************************************************************************************
     324       31915 :    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       31915 :       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       31915 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rbuf, sbuf
     336             : 
     337           0 :       CPASSERT(ASSOCIATED(wavelet))
     338             : 
     339       95745 :       nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
     340       31915 :       iproc = pw_grid%para%group%mepos
     341       31915 :       md2 = wavelet%PS_grid(3)
     342       31915 :       m2 = pw_grid%npts(3)
     343             : 
     344      127660 :       lb(:) = pw_grid%bounds_local(1, :)
     345      127660 :       ub(:) = pw_grid%bounds_local(2, :)
     346             : 
     347       31915 :       local_z_dim = MAX((md2/nproc), 1)
     348             : 
     349      191490 :       ALLOCATE (rbuf(PRODUCT(pw_grid%npts_local)))
     350      191490 :       ALLOCATE (sbuf(PRODUCT(wavelet%PS_grid)/nproc))
     351      223405 :       ALLOCATE (scount(nproc), sdispl(nproc), rcount(nproc), rdispl(nproc), tmp(nproc))
     352       76382 :       scount = 0
     353       76382 :       rcount = 0
     354   871698111 :       rbuf = 0.0_dp
     355       31915 :       ii = 1
     356       31915 :       IF (iproc*local_z_dim .LE. m2) THEN
     357       31915 :          IF ((iproc + 1)*local_z_dim .LE. m2) THEN
     358             :             loz = local_z_dim
     359             :          ELSE
     360        2706 :             loz = MOD(m2, local_z_dim)
     361             :          END IF
     362             :       ELSE
     363             :          loz = 0
     364             :       END IF
     365             : 
     366       31915 :       min_x = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), 0)
     367       31915 :       min_y = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), 0)
     368       76382 :       DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
     369      120849 :          DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
     370      133401 :             cart_pos = (/i, j/)
     371       44467 :             CALL pw_grid%para%group%rank_cart(cart_pos, dest)
     372       44467 :             IF ((ub(1) .GE. lb(1)) .AND. (ub(2) .GE. lb(2))) THEN
     373       44467 :                IF (dest*local_z_dim .LE. m2) THEN
     374       44467 :                   IF ((dest + 1)*local_z_dim .LE. m2) THEN
     375       40074 :                      rcount(dest + 1) = ABS((ub(1) - lb(1) + 1)*(ub(2) - lb(2) + 1)*local_z_dim)
     376             :                   ELSE
     377        4393 :                      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       44467 :             lox = get_limit(pw_grid%npts(1), pw_grid%para%group%num_pe_cart(1), i)
     386       44467 :             loy = get_limit(pw_grid%npts(2), pw_grid%para%group%num_pe_cart(2), j)
     387       88934 :             IF ((lox(2) .GE. lox(1)) .AND. (loy(2) .GE. loy(1))) THEN
     388       44467 :                scount(dest + 1) = ABS((lox(2) - lox(1) + 1)*(loy(2) - loy(1) + 1)*loz)
     389      952622 :                DO k = lox(1) - min_x(1) + 1, lox(2) - min_x(1) + 1
     390    32721221 :                   DO l = loy(1) - min_y(1) + 1, loy(2) - min_y(1) + 1
     391   904342950 :                      DO m = 1, loz
     392   871666196 :                         sbuf(ii) = wavelet%rho_z_sliced(k, l, m)
     393   903434795 :                         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       31915 :       sdispl(1) = 0
     403       31915 :       rdispl(1) = 0
     404       44467 :       DO i = 2, nproc
     405       12552 :          sdispl(i) = sdispl(i - 1) + scount(i - 1)
     406       44467 :          rdispl(i) = rdispl(i - 1) + rcount(i - 1)
     407             :       END DO
     408  2634721990 :       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       76382 :       DO i = 0, pw_grid%para%group%num_pe_cart(1) - 1
     413      120849 :          DO j = 0, pw_grid%para%group%num_pe_cart(2) - 1
     414      133401 :             cart_pos = (/i, j/)
     415       44467 :             CALL pw_grid%para%group%rank_cart(cart_pos, dest)
     416       88934 :             IF (dest*local_z_dim .LE. m2) THEN
     417       44467 :                IF ((dest + 1)*local_z_dim .LE. m2) THEN
     418             :                   loz = local_z_dim
     419             :                ELSE
     420        4393 :                   loz = MOD(m2, local_z_dim)
     421             :                END IF
     422       44467 :                ii = 1
     423       44467 :                IF (lb(3) + (dest*local_z_dim) .LE. ub(3)) THEN
     424      952622 :                   DO m = lb(1), ub(1)
     425    32721221 :                      DO l = lb(2), ub(2)
     426   904342950 :                         DO k = lb(3) + (dest*local_z_dim), lb(3) + (dest*local_z_dim) + loz - 1
     427   871666196 :                            density%array(m, l, k) = rbuf(ii + rdispl(dest + 1))
     428   903434795 :                            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       31915 :       DEALLOCATE (sbuf, rbuf, scount, sdispl, rcount, rdispl, tmp)
     437             : 
     438       31915 :    END SUBROUTINE z_slices_to_cp2k_distribution
     439             : 
     440             : ! **************************************************************************************************
     441             : !> \brief ...
     442             : !> \param wavelet ...
     443             : !> \param pw_grid ...
     444             : ! **************************************************************************************************
     445       31915 :    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       31915 :       CALL timeset(routineN, handle)
     457       95745 :       nproc = PRODUCT(pw_grid%para%group%num_pe_cart)
     458       31915 :       iproc = pw_grid%para%group%mepos
     459       31915 :       geocode = wavelet%geocode
     460       31915 :       nx = pw_grid%npts(1)
     461       31915 :       ny = pw_grid%npts(2)
     462       31915 :       nz = pw_grid%npts(3)
     463       31915 :       hx = pw_grid%dr(1)
     464       31915 :       hy = pw_grid%dr(2)
     465       31915 :       hz = pw_grid%dr(3)
     466             : 
     467             :       CALL PSolver(geocode, iproc, nproc, nx, ny, nz, hx, hy, hz, &
     468       31915 :                    wavelet%rho_z_sliced, wavelet%karray, pw_grid)
     469       31915 :       CALL timestop(handle)
     470       31915 :    END SUBROUTINE ps_wavelet_solve
     471             : 
     472             : END MODULE ps_wavelet_methods

Generated by: LCOV version 1.15