LCOV - code coverage report
Current view: top level - src - fde_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:9ccafda) Lines: 96.3 % 214 206
Test Date: 2026-10-15 00:55:44 Functions: 100.0 % 8 8

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : MODULE fde_methods
       8              :    USE cp_control_types,                ONLY: dft_control_type,&
       9              :                                               fde_control_type
      10              :    USE cp_files,                        ONLY: close_file,&
      11              :                                               open_file
      12              :    USE cp_log_handling,                 ONLY: cp_to_string
      13              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      14              :                                               section_vals_type
      15              :    USE kinds,                           ONLY: dp
      16              :    USE message_passing,                 ONLY: mp_comm_type,&
      17              :                                               mp_para_env_type
      18              :    USE pw_env_types,                    ONLY: pw_env_get,&
      19              :                                               pw_env_type
      20              :    USE pw_grid_types,                   ONLY: PW_MODE_LOCAL
      21              :    USE pw_methods,                      ONLY: pw_axpy,&
      22              :                                               pw_copy,&
      23              :                                               pw_transfer,&
      24              :                                               pw_zero
      25              :    USE pw_poisson_methods,              ONLY: pw_poisson_solve
      26              :    USE pw_poisson_types,                ONLY: pw_poisson_type
      27              :    USE pw_pool_types,                   ONLY: pw_pool_type
      28              :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      29              :                                               pw_r3d_rs_type
      30              :    USE qs_environment_types,            ONLY: get_qs_env,&
      31              :                                               qs_environment_type
      32              :    USE qs_ks_methods,                   ONLY: calc_rho_tot_gspace
      33              :    USE qs_ks_types,                     ONLY: get_ks_env,&
      34              :                                               qs_ks_env_type
      35              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      36              :                                               qs_rho_type
      37              :    USE xc,                              ONLY: xc_vxc_pw_create
      38              : #include "./base/base_uses.f90"
      39              : 
      40              :    IMPLICIT NONE
      41              :    PRIVATE
      42              : 
      43              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'fde_methods'
      44              : 
      45              :    PUBLIC :: &
      46              :       fde_build_v_emb, &
      47              :       fde_get_env_density, &
      48              :       fde_spawn, &
      49              :       fde_v_es, &
      50              :       fde_write_pw, &
      51              :       fde_read_pw, &
      52              :       fde_read_results
      53              : 
      54              : CONTAINS
      55              : 
      56              : ! **************************************************************************************************
      57              : !> \brief Build the electrostatic potential of a QS calculation
      58              : !> \param qs_env ...
      59              : !> \param v_es ...
      60              : ! **************************************************************************************************
      61           16 :    SUBROUTINE fde_v_es(qs_env, v_es)
      62              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      63              :       TYPE(pw_r3d_rs_type), INTENT(OUT)                  :: v_es
      64              : 
      65              :       REAL(KIND=dp)                                      :: e_es
      66              :       TYPE(pw_c1d_gs_type)                               :: rho_tot_g, v_es_g
      67              :       TYPE(pw_env_type), POINTER                         :: pw_env
      68              :       TYPE(pw_poisson_type), POINTER                     :: poisson_env
      69              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
      70              :       TYPE(qs_rho_type), POINTER                         :: rho
      71              : 
      72            8 :       NULLIFY (pw_env, poisson_env, auxbas_pw_pool, rho)
      73            8 :       CALL get_qs_env(qs_env, pw_env=pw_env, rho=rho)
      74            8 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, poisson_env=poisson_env)
      75              : 
      76            8 :       CALL auxbas_pw_pool%create_pw(rho_tot_g)
      77            8 :       CALL pw_zero(rho_tot_g)
      78            8 :       CALL calc_rho_tot_gspace(rho_tot_g, qs_env, rho)
      79              : 
      80            8 :       CALL auxbas_pw_pool%create_pw(v_es_g)
      81            8 :       CALL pw_poisson_solve(poisson_env, rho_tot_g, e_es, v_es_g)
      82              : 
      83            8 :       CALL auxbas_pw_pool%create_pw(v_es)
      84            8 :       CALL pw_transfer(v_es_g, v_es)
      85              : 
      86            8 :       CALL auxbas_pw_pool%give_back_pw(rho_tot_g)
      87            8 :       CALL auxbas_pw_pool%give_back_pw(v_es_g)
      88              : 
      89            8 :    END SUBROUTINE fde_v_es
      90              : 
      91              : ! **************************************************************************************************
      92              : !> \brief Copy the electron density from a QS calculation into a new grid
      93              : !> \param qs_env ...
      94              : !> \param rho ...
      95              : ! **************************************************************************************************
      96            4 :    SUBROUTINE fde_get_env_density(qs_env, rho)
      97              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      98              :       TYPE(pw_r3d_rs_type), INTENT(OUT)                  :: rho
      99              : 
     100              :       INTEGER                                            :: ispin, nspins
     101              :       TYPE(dft_control_type), POINTER                    :: dft_control
     102              :       TYPE(pw_env_type), POINTER                         :: pw_env
     103              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     104            4 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r
     105              :       TYPE(qs_rho_type), POINTER                         :: rho_qs
     106              : 
     107            4 :       NULLIFY (dft_control, pw_env, auxbas_pw_pool, rho_r, rho_qs)
     108            4 :       CALL get_qs_env(qs_env, dft_control=dft_control, pw_env=pw_env, rho=rho_qs)
     109            4 :       nspins = dft_control%nspins
     110              : 
     111            4 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     112            4 :       CALL auxbas_pw_pool%create_pw(rho)
     113            4 :       CALL pw_zero(rho)
     114              : 
     115            4 :       CALL qs_rho_get(rho_qs, rho_r=rho_r)
     116            8 :       DO ispin = 1, nspins
     117            8 :          CALL pw_axpy(rho_r(ispin), rho, 1.0_dp)
     118              :       END DO
     119              : 
     120            4 :    END SUBROUTINE fde_get_env_density
     121              : 
     122              : ! **************************************************************************************************
     123              : !> \brief Evaluate an XC+KEDF potential and energy for a density
     124              : !> \param ks_env ...
     125              : !> \param pw_env ...
     126              : !> \param xc_section ...
     127              : !> \param rho ...
     128              : !> \param v_xc ...
     129              : !> \param e_xc ...
     130              : ! **************************************************************************************************
     131           24 :    SUBROUTINE fde_vxc_on_grid(ks_env, pw_env, xc_section, rho, v_xc, e_xc)
     132              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     133              :       TYPE(pw_env_type), POINTER                         :: pw_env
     134              :       TYPE(section_vals_type), POINTER                   :: xc_section
     135              :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: rho
     136              :       TYPE(pw_r3d_rs_type), INTENT(OUT)                  :: v_xc
     137              :       REAL(KIND=dp), INTENT(OUT)                         :: e_xc
     138              : 
     139              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: virial_xc
     140              :       TYPE(pw_c1d_gs_type)                               :: rho_g_single
     141           24 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g
     142              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool, xc_pw_pool
     143           24 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r, tau, vxc_rho, vxc_tau
     144              :       TYPE(pw_r3d_rs_type), POINTER                      :: weights
     145              : 
     146           24 :       NULLIFY (auxbas_pw_pool, xc_pw_pool, rho_r, rho_g, tau, vxc_rho, vxc_tau, weights)
     147           24 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, xc_pw_pool=xc_pw_pool)
     148           24 :       CALL get_ks_env(ks_env, xcint_weights=weights)
     149              : 
     150           72 :       ALLOCATE (rho_r(1), rho_g(1))
     151           24 :       rho_r(1) = rho
     152           24 :       CALL auxbas_pw_pool%create_pw(rho_g_single)
     153           24 :       CALL pw_transfer(rho, rho_g_single)
     154           24 :       rho_g(1) = rho_g_single
     155              : 
     156              :       CALL xc_vxc_pw_create(vxc_rho=vxc_rho, &
     157              :                             vxc_tau=vxc_tau, &
     158              :                             exc=e_xc, &
     159              :                             rho_r=rho_r, &
     160              :                             rho_g=rho_g, &
     161              :                             tau=tau, &
     162              :                             xc_section=xc_section, &
     163              :                             weights=weights, &
     164              :                             pw_pool=xc_pw_pool, &
     165              :                             compute_virial=.FALSE., &
     166           24 :                             virial_xc=virial_xc)
     167              : 
     168           24 :       CALL auxbas_pw_pool%create_pw(v_xc)
     169           24 :       CALL pw_copy(vxc_rho(1), v_xc)
     170              : 
     171           24 :       CALL xc_pw_pool%give_back_pw(vxc_rho(1))
     172           24 :       DEALLOCATE (vxc_rho)
     173           24 :       IF (ASSOCIATED(vxc_tau)) THEN
     174            0 :          CALL xc_pw_pool%give_back_pw(vxc_tau(1))
     175            0 :          DEALLOCATE (vxc_tau)
     176              :       END IF
     177           24 :       CALL auxbas_pw_pool%give_back_pw(rho_g_single)
     178           24 :       DEALLOCATE (rho_r, rho_g)
     179              : 
     180           24 :    END SUBROUTINE fde_vxc_on_grid
     181              : 
     182              : ! **************************************************************************************************
     183              : !> \brief Build the embedding potential and evaluate nonadditive terms of a QS calculation.
     184              : !> \param qs_env ...
     185              : !> \param rho ...
     186              : !> \param v_emb ...
     187              : !> \param e_xc_na ...
     188              : !> \param e_kin_na ...
     189              : ! **************************************************************************************************
     190           36 :    SUBROUTINE fde_build_v_emb(qs_env, rho, v_emb, e_xc_na, e_kin_na)
     191              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     192              :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: rho
     193              :       TYPE(pw_r3d_rs_type), INTENT(OUT)                  :: v_emb
     194              :       REAL(KIND=dp), INTENT(OUT)                         :: e_xc_na, e_kin_na
     195              : 
     196              :       REAL(KIND=dp)                                      :: exc_a, exc_ab, exc_b
     197              :       TYPE(dft_control_type), POINTER                    :: dft_control
     198              :       TYPE(pw_env_type), POINTER                         :: pw_env
     199              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     200              :       TYPE(pw_r3d_rs_type)                               :: rho_ab, rho_b_r, v_a, v_ab, v_tmp
     201              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     202              :       TYPE(section_vals_type), POINTER                   :: input, kg_xc_section, xc_section
     203              : 
     204            4 :       NULLIFY (dft_control, pw_env, auxbas_pw_pool, ks_env, input, xc_section, kg_xc_section)
     205            4 :       CALL get_qs_env(qs_env, dft_control=dft_control, pw_env=pw_env, ks_env=ks_env, input=input)
     206            4 :       CPASSERT(dft_control%nspins == 1)
     207            4 :       CPASSERT(.NOT. dft_control%qs_control%gapw)
     208              : 
     209            4 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     210              : 
     211            4 :       CALL fde_get_env_density(qs_env, rho_b_r)
     212            4 :       CALL auxbas_pw_pool%create_pw(rho_ab)
     213            4 :       CALL pw_copy(rho_b_r, rho_ab)
     214            4 :       CALL pw_axpy(rho, rho_ab, 1.0_dp)
     215              : 
     216            4 :       xc_section => section_vals_get_subs_vals(input, "DFT%XC")
     217            4 :       kg_xc_section => section_vals_get_subs_vals(input, "DFT%KG_METHOD%XC")
     218              : 
     219            4 :       CALL fde_v_es(qs_env, v_emb)
     220              : 
     221            4 :       CALL fde_vxc_on_grid(ks_env, pw_env, xc_section, rho_ab, v_ab, exc_ab)
     222            4 :       CALL fde_vxc_on_grid(ks_env, pw_env, xc_section, rho, v_a, exc_a)
     223            4 :       CALL fde_vxc_on_grid(ks_env, pw_env, xc_section, rho_b_r, v_tmp, exc_b) ! energy only
     224            4 :       CALL auxbas_pw_pool%give_back_pw(v_tmp)
     225            4 :       CALL pw_axpy(v_ab, v_emb, 1.0_dp)
     226            4 :       CALL pw_axpy(v_a, v_emb, -1.0_dp)
     227            4 :       CALL auxbas_pw_pool%give_back_pw(v_ab)
     228            4 :       CALL auxbas_pw_pool%give_back_pw(v_a)
     229            4 :       e_xc_na = exc_ab - exc_a - exc_b
     230              : 
     231            4 :       CALL fde_vxc_on_grid(ks_env, pw_env, kg_xc_section, rho_ab, v_ab, exc_ab)
     232            4 :       CALL fde_vxc_on_grid(ks_env, pw_env, kg_xc_section, rho, v_a, exc_a)
     233            4 :       CALL fde_vxc_on_grid(ks_env, pw_env, kg_xc_section, rho_b_r, v_tmp, exc_b) ! energy only
     234            4 :       CALL auxbas_pw_pool%give_back_pw(v_tmp)
     235            4 :       CALL pw_axpy(v_ab, v_emb, 1.0_dp)
     236            4 :       CALL pw_axpy(v_a, v_emb, -1.0_dp)
     237            4 :       CALL auxbas_pw_pool%give_back_pw(v_ab)
     238            4 :       CALL auxbas_pw_pool%give_back_pw(v_a)
     239            4 :       e_kin_na = exc_ab - exc_a - exc_b
     240              : 
     241            4 :       CALL auxbas_pw_pool%give_back_pw(rho_ab)
     242            4 :       CALL auxbas_pw_pool%give_back_pw(rho_b_r)
     243              : 
     244            4 :    END SUBROUTINE fde_build_v_emb
     245              : 
     246              : ! **************************************************************************************************
     247              : !> \brief Spawns the subsystem solver. Only the source rank launches the process; the other ranks
     248              : !>        wait for it on the broadcasts below
     249              : !> \param fde_control ...
     250              : !> \param input_file ...
     251              : !> \param para_env ...
     252              : ! **************************************************************************************************
     253            4 :    SUBROUTINE fde_spawn(fde_control, input_file, para_env)
     254              :       TYPE(fde_control_type), POINTER                    :: fde_control
     255              :       CHARACTER(len=*), INTENT(IN)                       :: input_file
     256              :       TYPE(mp_para_env_type), INTENT(IN)                 :: para_env
     257              : 
     258            4 :       CHARACTER(len=:), ALLOCATABLE                      :: command
     259              :       INTEGER                                            :: cmdstat, exitstat
     260              : 
     261            4 :       IF (LEN_TRIM(fde_control%workdir) > 0) THEN
     262              :          command = "cd "//TRIM(fde_control%workdir)//" && "// &
     263            0 :                    TRIM(fde_control%command)//" "//TRIM(input_file)
     264              :       ELSE
     265            4 :          command = TRIM(fde_control%command)//" "//TRIM(input_file)
     266              :       END IF
     267              : 
     268            4 :       exitstat = 0
     269            4 :       cmdstat = 0
     270            4 :       IF (para_env%is_source()) THEN
     271            2 :          CALL EXECUTE_COMMAND_LINE(command, wait=.TRUE., exitstat=exitstat, cmdstat=cmdstat)
     272              :       END IF
     273              : 
     274            4 :       CALL para_env%bcast(cmdstat)
     275            4 :       CALL para_env%bcast(exitstat)
     276              : 
     277            4 :       IF (cmdstat /= 0) THEN
     278            0 :          CPABORT("FDE: failed to launch command: "//command)
     279              :       END IF
     280            4 :       IF (exitstat /= 0) THEN
     281            0 :          CPABORT("FDE: command returned a non-zero exit status: "//TRIM(cp_to_string(exitstat)))
     282              :       END IF
     283              : 
     284            4 :    END SUBROUTINE fde_spawn
     285              : 
     286              : ! **************************************************************************************************
     287              : !> \brief Write grid points to disk in the Molcas format, optionally with weights and values.
     288              : !>        write_value=.TRUE.: x y z weight value
     289              : !>        write_value=.FALSE.: x y z
     290              : !> \param pw ...
     291              : !> \param filename ...
     292              : !> \param write_value ...
     293              : ! **************************************************************************************************
     294            8 :    SUBROUTINE fde_write_pw(pw, filename, write_value)
     295              :       TYPE(pw_r3d_rs_type), INTENT(IN)                   :: pw
     296              :       CHARACTER(len=*), INTENT(IN)                       :: filename
     297              :       LOGICAL, INTENT(IN)                                :: write_value
     298              : 
     299              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'fde_write_pw'
     300              : 
     301              :       INTEGER                                            :: dest, handle, I1, I2, I3, ip, L1, L2, &
     302              :                                                             L3, mepos, num_pe, source, tag, U1, &
     303              :                                                             U2, U3, unit_nr
     304              :       REAL(KIND=dp)                                      :: dvol, x, y, z
     305            8 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: buf
     306              :       TYPE(mp_comm_type)                                 :: group
     307              : 
     308            8 :       CALL timeset(routineN, handle)
     309              : 
     310            8 :       L1 = pw%pw_grid%bounds(1, 1)
     311            8 :       U1 = pw%pw_grid%bounds(2, 1)
     312            8 :       L2 = pw%pw_grid%bounds(1, 2)
     313            8 :       U2 = pw%pw_grid%bounds(2, 2)
     314            8 :       L3 = pw%pw_grid%bounds(1, 3)
     315            8 :       U3 = pw%pw_grid%bounds(2, 3)
     316            8 :       dvol = pw%pw_grid%dvol
     317              : 
     318            8 :       group = pw%pw_grid%para%group
     319            8 :       mepos = pw%pw_grid%para%group%mepos
     320            8 :       num_pe = pw%pw_grid%para%group%num_pe
     321            8 :       tag = 1
     322            8 :       dest = 0
     323              : 
     324            8 :       unit_nr = -1
     325            8 :       IF (mepos == dest) THEN
     326              :          CALL open_file(file_name=TRIM(filename), file_status="REPLACE", file_form="FORMATTED", &
     327            4 :                         file_action="WRITE", unit_number=unit_nr)
     328            4 :          WRITE (unit_nr, '(I10)') pw%pw_grid%ngpts
     329              :       END IF
     330              : 
     331           24 :       ALLOCATE (buf(L3:U3))
     332              : 
     333          152 :       DO I1 = L1, U1
     334         2744 :          DO I2 = L2, U2
     335         2592 :             IF (pw%pw_grid%para%mode /= PW_MODE_LOCAL) THEN
     336         2592 :                source = dest
     337         7776 :                DO ip = 0, num_pe - 1
     338              :                   IF (pw%pw_grid%para%bo(1, 1, ip, 1) <= I1 - L1 + 1 &
     339              :                       .AND. pw%pw_grid%para%bo(2, 1, ip, 1) >= I1 - L1 + 1 &
     340              :                       .AND. pw%pw_grid%para%bo(1, 2, ip, 1) <= I2 - L2 + 1 &
     341         7776 :                       .AND. pw%pw_grid%para%bo(2, 2, ip, 1) >= I2 - L2 + 1) THEN
     342         2592 :                      source = ip
     343              :                   END IF
     344              :                END DO
     345              :             ELSE
     346            0 :                source = dest
     347              :             END IF
     348              : 
     349         2592 :             IF (source == dest) THEN
     350        12960 :                IF (mepos == source) buf(:) = pw%array(I1, I2, :)
     351              :             ELSE
     352         1296 :                IF (mepos == source) THEN
     353        12312 :                   buf(:) = pw%array(I1, I2, :)
     354          648 :                   CALL group%send(buf, dest, tag)
     355              :                END IF
     356         1296 :                IF (mepos == dest) CALL group%recv(buf, source, tag)
     357              :             END IF
     358              : 
     359         2592 :             IF (mepos == dest) THEN
     360        24624 :                DO I3 = L3, U3
     361              :                   x = pw%pw_grid%dh(1, 1)*(I1 - L1) &
     362              :                       + pw%pw_grid%dh(2, 1)*(I2 - L2) &
     363        23328 :                       + pw%pw_grid%dh(3, 1)*(I3 - L3)
     364              :                   y = pw%pw_grid%dh(1, 2)*(I1 - L1) &
     365              :                       + pw%pw_grid%dh(2, 2)*(I2 - L2) &
     366        23328 :                       + pw%pw_grid%dh(3, 2)*(I3 - L3)
     367              :                   z = pw%pw_grid%dh(1, 3)*(I1 - L1) &
     368              :                       + pw%pw_grid%dh(2, 3)*(I2 - L2) &
     369        23328 :                       + pw%pw_grid%dh(3, 3)*(I3 - L3)
     370        24624 :                   IF (write_value) THEN
     371        11664 :                      WRITE (unit_nr, '(3F16.8,2ES20.10E3)') x, y, z, dvol, buf(I3)
     372              :                   ELSE
     373        11664 :                      WRITE (unit_nr, '(3F16.8)') x, y, z
     374              :                   END IF
     375              :                END DO
     376              :             END IF
     377              : 
     378         2736 :             CALL group%sync()
     379              :          END DO
     380              :       END DO
     381              : 
     382            8 :       DEALLOCATE (buf)
     383              : 
     384            8 :       IF (mepos == dest) CALL close_file(unit_number=unit_nr)
     385              : 
     386            8 :       CALL timestop(handle)
     387              : 
     388            8 :    END SUBROUTINE fde_write_pw
     389              : 
     390              : ! **************************************************************************************************
     391              : !> \brief Read the density in x y z weight value format
     392              : !> \param pw ...
     393              : !> \param filename ...
     394              : ! **************************************************************************************************
     395            4 :    SUBROUTINE fde_read_pw(pw, filename)
     396              :       TYPE(pw_r3d_rs_type), INTENT(INOUT)                :: pw
     397              :       CHARACTER(len=*), INTENT(IN)                       :: filename
     398              : 
     399              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'fde_read_pw'
     400              : 
     401              :       INTEGER                                            :: dest, handle, I1, I2, I3, ip, L1, L2, &
     402              :                                                             L3, mepos, npoints, num_pe, source, &
     403              :                                                             tag, U1, U2, U3, unit_nr
     404            4 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: buf
     405              :       TYPE(mp_comm_type)                                 :: group
     406              : 
     407            4 :       CALL timeset(routineN, handle)
     408              : 
     409            4 :       L1 = pw%pw_grid%bounds(1, 1)
     410            4 :       U1 = pw%pw_grid%bounds(2, 1)
     411            4 :       L2 = pw%pw_grid%bounds(1, 2)
     412            4 :       U2 = pw%pw_grid%bounds(2, 2)
     413            4 :       L3 = pw%pw_grid%bounds(1, 3)
     414            4 :       U3 = pw%pw_grid%bounds(2, 3)
     415              : 
     416            4 :       group = pw%pw_grid%para%group
     417            4 :       mepos = pw%pw_grid%para%group%mepos
     418            4 :       num_pe = pw%pw_grid%para%group%num_pe
     419            4 :       tag = 1
     420            4 :       dest = 0
     421              : 
     422            4 :       unit_nr = -1
     423            4 :       IF (mepos == dest) THEN
     424              :          CALL open_file(file_name=TRIM(filename), file_status="OLD", file_form="FORMATTED", &
     425            2 :                         file_action="READ", unit_number=unit_nr)
     426            2 :          READ (unit_nr, *) npoints
     427            2 :          IF (npoints /= pw%pw_grid%ngpts) THEN
     428            0 :             CPABORT("Number of grid points in file does not match the pw grid")
     429              :          END IF
     430              :       END IF
     431              : 
     432           12 :       ALLOCATE (buf(L3:U3))
     433              : 
     434           76 :       DO I1 = L1, U1
     435         1372 :          DO I2 = L2, U2
     436         1296 :             IF (pw%pw_grid%para%mode /= PW_MODE_LOCAL) THEN
     437         1296 :                source = dest
     438         3888 :                DO ip = 0, num_pe - 1
     439              :                   IF (pw%pw_grid%para%bo(1, 1, ip, 1) <= I1 - L1 + 1 &
     440              :                       .AND. pw%pw_grid%para%bo(2, 1, ip, 1) >= I1 - L1 + 1 &
     441              :                       .AND. pw%pw_grid%para%bo(1, 2, ip, 1) <= I2 - L2 + 1 &
     442         3888 :                       .AND. pw%pw_grid%para%bo(2, 2, ip, 1) >= I2 - L2 + 1) THEN
     443         1296 :                      source = ip
     444              :                   END IF
     445              :                END DO
     446              :             ELSE
     447            0 :                source = dest
     448              :             END IF
     449              : 
     450         1296 :             IF (mepos == dest) THEN
     451        12312 :                DO I3 = L3, U3
     452        12312 :                   READ (unit_nr, *) buf(I3)
     453              :                END DO
     454              :             END IF
     455              : 
     456         1296 :             IF (source == dest) THEN
     457         6480 :                IF (mepos == source) pw%array(I1, I2, :) = buf(:)
     458              :             ELSE
     459          648 :                IF (mepos == dest) CALL group%send(buf, source, tag)
     460          648 :                IF (mepos == source) THEN
     461          324 :                   CALL group%recv(buf, dest, tag)
     462         6156 :                   pw%array(I1, I2, :) = buf(:)
     463              :                END IF
     464              :             END IF
     465              : 
     466         1368 :             CALL group%sync()
     467              :          END DO
     468              :       END DO
     469              : 
     470            4 :       DEALLOCATE (buf)
     471              : 
     472            4 :       IF (mepos == dest) CALL close_file(unit_number=unit_nr)
     473              : 
     474            4 :       CALL timestop(handle)
     475              : 
     476            4 :    END SUBROUTINE fde_read_pw
     477              : 
     478              : ! **************************************************************************************************
     479              : !> \brief Read scalar results returned by the subsystem solver, one value per line, in this order:
     480              : !>        E_sub : embedded subsystem total energy
     481              : !>        E_emb : embedding energy
     482              : !>        E_nuc : nuclear repulsion energy
     483              : !>        n_e   : number of active-subsystem electrons
     484              : !>        n_a   : number of nuclei of subsystem A
     485              : !>        Followed by n_a lines of
     486              : !>        Z_I x_I y_I z_I (charge and coordinates in the CP2K frame)
     487              : !> \param filename ...
     488              : !> \param para_env ...
     489              : !> \param e_sub ...
     490              : !> \param e_emb ...
     491              : !> \param e_nuc ...
     492              : !> \param n_e ...
     493              : !> \param n_a ...
     494              : !> \param z_a ...
     495              : !> \param r_a ...
     496              : ! **************************************************************************************************
     497            4 :    SUBROUTINE fde_read_results(filename, para_env, e_sub, e_emb, e_nuc, n_e, n_a, z_a, r_a)
     498              :       CHARACTER(len=*), INTENT(IN)                       :: filename
     499              :       TYPE(mp_para_env_type), INTENT(IN)                 :: para_env
     500              :       REAL(KIND=dp), INTENT(OUT)                         :: e_sub, e_emb, e_nuc, n_e
     501              :       INTEGER, INTENT(OUT)                               :: n_a
     502              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
     503              :          INTENT(OUT)                                     :: z_a
     504              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
     505              :          INTENT(OUT)                                     :: r_a
     506              : 
     507              :       INTEGER                                            :: iatom, unit_nr
     508              :       REAL(KIND=dp), DIMENSION(4)                        :: vals
     509              : 
     510            4 :       vals = 0.0_dp
     511            4 :       n_a = 0
     512            4 :       IF (para_env%is_source()) THEN
     513              :          CALL open_file(file_name=TRIM(filename), file_status="OLD", file_form="FORMATTED", &
     514            2 :                         file_action="READ", unit_number=unit_nr)
     515            2 :          READ (unit_nr, *) vals(1)
     516            2 :          READ (unit_nr, *) vals(2)
     517            2 :          READ (unit_nr, *) vals(3)
     518            2 :          READ (unit_nr, *) vals(4)
     519            2 :          READ (unit_nr, *) n_a
     520              :       END IF
     521            4 :       CALL para_env%bcast(vals)
     522            4 :       CALL para_env%bcast(n_a)
     523              : 
     524           20 :       ALLOCATE (z_a(n_a), r_a(3, n_a))
     525            4 :       z_a = 0.0_dp
     526            4 :       r_a = 0.0_dp
     527            4 :       IF (para_env%is_source()) THEN
     528            4 :          DO iatom = 1, n_a
     529            4 :             READ (unit_nr, *) z_a(iatom), r_a(1, iatom), r_a(2, iatom), r_a(3, iatom)
     530              :          END DO
     531            2 :          CALL close_file(unit_number=unit_nr)
     532              :       END IF
     533            4 :       CALL para_env%bcast(z_a)
     534            4 :       CALL para_env%bcast(r_a)
     535              : 
     536            4 :       e_sub = vals(1)
     537            4 :       e_emb = vals(2)
     538            4 :       e_nuc = vals(3)
     539            4 :       n_e = vals(4)
     540              : 
     541            4 :    END SUBROUTINE fde_read_results
     542              : 
     543              : END MODULE fde_methods
        

Generated by: LCOV version 2.0-1