LCOV - code coverage report
Current view: top level - src - ed_analysis.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:4dc10b3) Lines: 576 598 96.3 %
Date: 2024-11-21 06:45:46 Functions: 6 6 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 Calculate Energy Decomposition analysis
      10             : !> \par History
      11             : !>      07.2023 created [JGH]
      12             : !> \author JGH
      13             : ! **************************************************************************************************
      14             : MODULE ed_analysis
      15             :    USE admm_types,                      ONLY: admm_type
      16             :    USE atomic_kind_types,               ONLY: atomic_kind_type
      17             :    USE basis_set_types,                 ONLY: gto_basis_set_p_type,&
      18             :                                               gto_basis_set_type
      19             :    USE bibliography,                    ONLY: Eriksen2020,&
      20             :                                               cite_reference
      21             :    USE cell_types,                      ONLY: cell_type
      22             :    USE core_ae,                         ONLY: build_erfc
      23             :    USE cp_control_types,                ONLY: dft_control_type
      24             :    USE cp_dbcsr_api,                    ONLY: &
      25             :         dbcsr_add, dbcsr_copy, dbcsr_create, dbcsr_distribution_type, dbcsr_dot, dbcsr_get_info, &
      26             :         dbcsr_p_type, dbcsr_release, dbcsr_reserve_diag_blocks, dbcsr_scale, dbcsr_set, &
      27             :         dbcsr_type, dbcsr_type_symmetric
      28             :    USE cp_dbcsr_operations,             ONLY: cp_dbcsr_plus_fm_fm_t,&
      29             :                                               cp_dbcsr_sm_fm_multiply
      30             :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      31             :                                               cp_fm_struct_release,&
      32             :                                               cp_fm_struct_type
      33             :    USE cp_fm_types,                     ONLY: &
      34             :         cp_fm_create, cp_fm_get_diag, cp_fm_get_element, cp_fm_get_info, cp_fm_get_submatrix, &
      35             :         cp_fm_release, cp_fm_set_all, cp_fm_set_element, cp_fm_set_submatrix, cp_fm_to_fm, &
      36             :         cp_fm_type
      37             :    USE hartree_local_methods,           ONLY: Vh_1c_gg_integrals
      38             :    USE hartree_local_types,             ONLY: ecoul_1center_type
      39             :    USE hfx_admm_utils,                  ONLY: tddft_hfx_matrix
      40             :    USE iao_analysis,                    ONLY: iao_calculate_dmat,&
      41             :                                               iao_charges,&
      42             :                                               iao_wfn_analysis,&
      43             :                                               print_center_spread
      44             :    USE iao_types,                       ONLY: iao_env_type,&
      45             :                                               iao_set_default
      46             :    USE input_constants,                 ONLY: do_admm_aux_exch_func_none
      47             :    USE input_section_types,             ONLY: section_vals_get,&
      48             :                                               section_vals_get_subs_vals,&
      49             :                                               section_vals_type,&
      50             :                                               section_vals_val_get
      51             :    USE kinds,                           ONLY: dp
      52             :    USE mathconstants,                   ONLY: pi
      53             :    USE message_passing,                 ONLY: mp_comm_type,&
      54             :                                               mp_para_env_type
      55             :    USE mulliken,                        ONLY: mulliken_charges
      56             :    USE parallel_gemm_api,               ONLY: parallel_gemm
      57             :    USE particle_methods,                ONLY: get_particle_set
      58             :    USE particle_types,                  ONLY: particle_type
      59             :    USE physcon,                         ONLY: angstrom
      60             :    USE pw_env_types,                    ONLY: pw_env_get,&
      61             :                                               pw_env_type
      62             :    USE pw_methods,                      ONLY: pw_axpy,&
      63             :                                               pw_scale,&
      64             :                                               pw_transfer
      65             :    USE pw_poisson_methods,              ONLY: pw_poisson_solve
      66             :    USE pw_poisson_types,                ONLY: pw_poisson_type
      67             :    USE pw_pool_types,                   ONLY: pw_pool_type
      68             :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      69             :                                               pw_r3d_rs_type
      70             :    USE qs_collocate_density,            ONLY: calculate_rho_core
      71             :    USE qs_core_energies,                ONLY: calculate_ecore_alpha,&
      72             :                                               calculate_ecore_overlap,&
      73             :                                               calculate_ecore_self
      74             :    USE qs_core_hamiltonian,             ONLY: core_matrices
      75             :    USE qs_dispersion_pairpot,           ONLY: calculate_dispersion_pairpot
      76             :    USE qs_dispersion_types,             ONLY: qs_dispersion_type
      77             :    USE qs_energy_types,                 ONLY: qs_energy_type
      78             :    USE qs_environment_types,            ONLY: get_qs_env,&
      79             :                                               qs_environment_type
      80             :    USE qs_gcp_method,                   ONLY: calculate_gcp_pairpot
      81             :    USE qs_gcp_types,                    ONLY: qs_gcp_type
      82             :    USE qs_integrate_potential,          ONLY: integrate_v_core_rspace,&
      83             :                                               integrate_v_gaussian_rspace,&
      84             :                                               integrate_v_rspace
      85             :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      86             :                                               qs_kind_type
      87             :    USE qs_ks_atom,                      ONLY: update_ks_atom
      88             :    USE qs_ks_types,                     ONLY: qs_ks_env_type
      89             :    USE qs_local_rho_types,              ONLY: local_rho_type
      90             :    USE qs_mo_methods,                   ONLY: calculate_subspace_eigenvalues
      91             :    USE qs_mo_types,                     ONLY: deallocate_mo_set,&
      92             :                                               duplicate_mo_set,&
      93             :                                               get_mo_set,&
      94             :                                               mo_set_type
      95             :    USE qs_neighbor_list_types,          ONLY: neighbor_list_set_p_type
      96             :    USE qs_rho0_ggrid,                   ONLY: integrate_vhg0_rspace
      97             :    USE qs_rho_atom_types,               ONLY: rho_atom_type,&
      98             :                                               zero_rho_atom_integrals
      99             :    USE qs_rho_types,                    ONLY: qs_rho_get,&
     100             :                                               qs_rho_type
     101             :    USE qs_vxc,                          ONLY: qs_xc_density
     102             :    USE qs_vxc_atom,                     ONLY: calculate_vxc_atom
     103             :    USE xc_derivatives,                  ONLY: xc_functionals_get_needs
     104             :    USE xc_rho_cflags_types,             ONLY: xc_rho_cflags_type
     105             : #include "./base/base_uses.f90"
     106             : 
     107             :    IMPLICIT NONE
     108             :    PRIVATE
     109             : 
     110             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ed_analysis'
     111             : 
     112             :    PUBLIC ::  edmf_analysis
     113             : 
     114             : ! **************************************************************************************************
     115             : 
     116             : CONTAINS
     117             : 
     118             : ! **************************************************************************************************
     119             : !> \brief ...
     120             : !> \param qs_env ...
     121             : !> \param input_section ...
     122             : !> \param unit_nr ...
     123             : ! **************************************************************************************************
     124          58 :    SUBROUTINE edmf_analysis(qs_env, input_section, unit_nr)
     125             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     126             :       TYPE(section_vals_type), POINTER                   :: input_section
     127             :       INTEGER, INTENT(IN)                                :: unit_nr
     128             : 
     129             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'edmf_analysis'
     130             : 
     131             :       INTEGER                                            :: handle, iatom, ikind, iorb, ispin, jorb, &
     132             :                                                             nao, natom, nimages, nkind, no, norb, &
     133             :                                                             nref, nspin
     134             :       INTEGER, DIMENSION(2)                              :: nocc
     135          58 :       INTEGER, DIMENSION(:), POINTER                     :: refbas_blk_sizes
     136             :       LOGICAL :: detailed_ener, do_hfx, ewald_correction, explicit, gapw, gapw_xc, &
     137             :          ref_orb_canonical, skip_localize, uniform_occupation, uocc
     138             :       REAL(KIND=dp)                                      :: ateps, checksum, e1, e2, e_pot, ealpha, &
     139             :                                                             ecc, egcp, ehfx, ekts, evdw, focc, &
     140             :                                                             sum_energy
     141          58 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: amval, atcore, ate1h, ate1xc, atecc, &
     142          58 :                                                             ateks, atener, atewald, odiag
     143          58 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: atdet, atmul, mcharge, mweight
     144          58 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: bcenter
     145          58 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: occupation_numbers
     146             :       TYPE(cell_type), POINTER                           :: cell
     147             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct
     148             :       TYPE(cp_fm_type)                                   :: cvec, cvec2, smo
     149          58 :       TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:)        :: c_iao_coef, ciao, fij_mat, orb_weight, &
     150          58 :                                                             rotmat
     151             :       TYPE(cp_fm_type), POINTER                          :: cloc, moref
     152             :       TYPE(dbcsr_distribution_type)                      :: dbcsr_dist
     153             :       TYPE(dbcsr_p_type)                                 :: dve_mat
     154          58 :       TYPE(dbcsr_p_type), ALLOCATABLE, DIMENSION(:)      :: exc_mat, ks_mat, vhxc_mat
     155          58 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: core_mat, matrix_h, matrix_hfx, &
     156          58 :                                                             matrix_ks, matrix_p, matrix_s, matrix_t
     157          58 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: math, matp
     158             :       TYPE(dbcsr_type)                                   :: dkmat, dmat
     159             :       TYPE(dbcsr_type), POINTER                          :: smat
     160             :       TYPE(dft_control_type), POINTER                    :: dft_control
     161          58 :       TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER  :: ref_basis_set_list
     162             :       TYPE(gto_basis_set_type), POINTER                  :: refbasis
     163             :       TYPE(iao_env_type)                                 :: iao_env
     164          58 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos, mos_loc
     165             :       TYPE(mp_comm_type)                                 :: group
     166             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     167          58 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     168             :       TYPE(qs_dispersion_type), POINTER                  :: dispersion_env
     169             :       TYPE(qs_energy_type), POINTER                      :: energy
     170             :       TYPE(qs_gcp_type), POINTER                         :: gcp_env
     171          58 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     172             :       TYPE(qs_kind_type), POINTER                        :: qs_kind
     173             :       TYPE(qs_rho_type), POINTER                         :: rho
     174             :       TYPE(section_vals_type), POINTER                   :: hfx_sections, input
     175             : 
     176          58 :       CALL section_vals_get(input_section, explicit=explicit)
     177          58 :       IF (.NOT. explicit) RETURN
     178             : 
     179          30 :       CALL timeset(routineN, handle)
     180             : 
     181          30 :       IF (unit_nr > 0) THEN
     182             :          WRITE (UNIT=unit_nr, FMT="(/,4(T2,A))") &
     183          15 :             "!-----------------------------------------------------------------------------!", &
     184          15 :             "!                        ENERGY DECOMPOSITION ANALYSIS                        !", &
     185          15 :             "!                    Janus J Eriksen, JCP 153 214109 (2020)                   !", &
     186          30 :             "!-----------------------------------------------------------------------------!"
     187             :       END IF
     188          30 :       CALL cite_reference(Eriksen2020)
     189             : 
     190             :       ! input options
     191          30 :       CALL section_vals_val_get(input_section, "REFERENCE_ORB_CANONICAL", l_val=ref_orb_canonical)
     192          30 :       CALL section_vals_val_get(input_section, "DETAILED_ENERGY", l_val=detailed_ener)
     193          30 :       CALL section_vals_val_get(input_section, "SKIP_LOCALIZATION", l_val=skip_localize)
     194          30 :       CALL section_vals_val_get(input_section, "EWALD_ALPHA_PARAMETER", r_val=ealpha)
     195          30 :       ewald_correction = (ealpha /= 0.0_dp)
     196             :       ! k-points?
     197          30 :       CALL get_qs_env(qs_env, dft_control=dft_control)
     198          30 :       nimages = dft_control%nimages
     199          30 :       IF (nimages > 1) THEN
     200           0 :          IF (unit_nr > 0) THEN
     201             :             WRITE (UNIT=unit_nr, FMT="(T2,A)") &
     202           0 :                "K-Points: MAO's determined and analyzed using Gamma-Point only."
     203             :          END IF
     204             :       END IF
     205          30 :       gapw = dft_control%qs_control%gapw
     206          30 :       gapw_xc = dft_control%qs_control%gapw_xc
     207          30 :       IF (ewald_correction) THEN
     208           2 :          IF (gapw .OR. gapw_xc) THEN
     209           0 :             CALL cp_warn(__LOCATION__, "Ewald Correction for GAPW and GAPW_XC not available.")
     210           0 :             CPABORT("Ewald Correction")
     211             :          END IF
     212             :       END IF
     213          30 :       CALL get_qs_env(qs_env, input=input)
     214          30 :       hfx_sections => section_vals_get_subs_vals(input, "DFT%XC%HF")
     215          30 :       CALL section_vals_get(hfx_sections, explicit=do_hfx)
     216             : 
     217          30 :       CALL get_qs_env(qs_env, mos=mos)
     218          30 :       nspin = dft_control%nspins
     219         122 :       ALLOCATE (mos_loc(nspin))
     220             : 
     221             :       ! do we have a uniform occupation
     222          30 :       uocc = .TRUE.
     223          62 :       DO ispin = 1, nspin
     224          32 :          CALL get_mo_set(mos(ispin), uniform_occupation=uniform_occupation)
     225          62 :          IF (.NOT. uniform_occupation) uocc = .FALSE.
     226             :       END DO
     227          30 :       IF (unit_nr > 0) THEN
     228          15 :          IF (uocc) THEN
     229             :             WRITE (UNIT=unit_nr, FMT="(T2,A)") &
     230          14 :                "MO's have a uniform occupation pattern"
     231             :          ELSE
     232             :             WRITE (UNIT=unit_nr, FMT="(T2,A)") &
     233           1 :                "MO's have varying occupations"
     234             :          END IF
     235             :       END IF
     236             : 
     237             :       ! perform IAO analysis
     238          30 :       CALL iao_set_default(iao_env)
     239          30 :       iao_env%do_iao = .TRUE.
     240          30 :       iao_env%do_charges = .TRUE.
     241          30 :       IF (skip_localize) THEN
     242           2 :          iao_env%do_bondorbitals = .FALSE.
     243           2 :          iao_env%do_center = .FALSE.
     244             :       ELSE
     245          28 :          iao_env%do_bondorbitals = .TRUE.
     246          28 :          iao_env%do_center = .TRUE.
     247             :       END IF
     248          30 :       iao_env%eps_occ = 1.0E-4_dp
     249          30 :       CALL get_qs_env(qs_env, cell=cell)
     250          36 :       iao_env%pos_periodic = .NOT. ALL(cell%perd == 0)
     251          30 :       no = 0
     252          30 :       nocc = 0
     253          62 :       DO ispin = 1, nspin
     254          32 :          CALL duplicate_mo_set(mos_loc(ispin), mos(ispin))
     255          32 :          CALL get_mo_set(mos_loc(ispin), nmo=norb)
     256          32 :          no = MAX(no, norb)
     257          32 :          nocc(ispin) = norb
     258          62 :          IF (ref_orb_canonical) THEN
     259          32 :             CALL get_mo_set(mos_loc(ispin), mo_coeff=moref)
     260          32 :             CALL get_qs_env(qs_env, matrix_ks=matrix_ks)
     261             :             CALL calculate_subspace_eigenvalues(moref, matrix_ks(ispin)%matrix, &
     262          32 :                                                 do_rotation=.TRUE.)
     263             :          END IF
     264             :       END DO
     265         120 :       ALLOCATE (bcenter(5, no, nspin))
     266        1154 :       bcenter = 0.0_dp
     267             :       CALL iao_wfn_analysis(qs_env, iao_env, unit_nr, &
     268          30 :                             c_iao_coef=c_iao_coef, mos=mos_loc, bond_centers=bcenter)
     269             : 
     270             :       ! output bond centers
     271          30 :       IF (iao_env%do_bondorbitals .AND. iao_env%do_center) THEN
     272          28 :          CALL print_center_spread(bcenter, nocc, iounit=unit_nr)
     273             :       END IF
     274             : 
     275             :       ! Calculate orbital rotation matrix
     276          30 :       CALL get_qs_env(qs_env, matrix_s=matrix_s)
     277          30 :       smat => matrix_s(1)%matrix
     278         122 :       ALLOCATE (rotmat(nspin))
     279          62 :       DO ispin = 1, nspin
     280          32 :          CALL get_mo_set(mos_loc(ispin), mo_coeff=cloc)
     281          32 :          CALL get_mo_set(mos(ispin), mo_coeff=moref)
     282          32 :          CALL cp_fm_get_info(cloc, nrow_global=nao, ncol_global=norb)
     283          32 :          CALL cp_fm_create(smo, cloc%matrix_struct)
     284          32 :          NULLIFY (fm_struct)
     285             :          CALL cp_fm_struct_create(fm_struct, nrow_global=norb, ncol_global=norb, &
     286          32 :                                   template_fmstruct=cloc%matrix_struct)
     287          32 :          CALL cp_fm_create(rotmat(ispin), fm_struct)
     288          32 :          CALL cp_fm_struct_release(fm_struct)
     289             :          ! ROTMAT = Cref(T)*S*Cloc
     290          32 :          CALL cp_dbcsr_sm_fm_multiply(smat, cloc, smo, ncol=norb)
     291             :          CALL parallel_gemm('T', 'N', norb, norb, nao, 1.0_dp, moref, &
     292          32 :                             smo, 0.0_dp, rotmat(ispin))
     293          94 :          CALL cp_fm_release(smo)
     294             :       END DO
     295             : 
     296             :       ! calculate occupation matrix
     297          30 :       IF (.NOT. uocc) THEN
     298           6 :          ALLOCATE (fij_mat(nspin))
     299           4 :          DO ispin = 1, nspin
     300           2 :             CALL cp_fm_create(fij_mat(ispin), rotmat(ispin)%matrix_struct)
     301           2 :             CALL cp_fm_set_all(fij_mat(ispin), 0.0_dp)
     302           2 :             CALL cp_fm_create(smo, rotmat(ispin)%matrix_struct)
     303             :             ! fii = f
     304           2 :             CALL get_mo_set(mos(ispin), nmo=norb, occupation_numbers=occupation_numbers)
     305          54 :             DO iorb = 1, norb
     306          54 :                CALL cp_fm_set_element(fij_mat(ispin), iorb, iorb, occupation_numbers(iorb))
     307             :             END DO
     308             :             ! fij = U(T)*f*U
     309             :             CALL parallel_gemm('N', 'N', norb, norb, norb, 1.0_dp, fij_mat(ispin), &
     310           2 :                                rotmat(ispin), 0.0_dp, smo)
     311             :             CALL parallel_gemm('T', 'N', norb, norb, norb, 1.0_dp, rotmat(ispin), &
     312           2 :                                smo, 0.0_dp, fij_mat(ispin))
     313           6 :             CALL cp_fm_release(smo)
     314             :          END DO
     315             :       END IF
     316             : 
     317             :       ! localized orbitals in IAO basis => CIAO
     318          92 :       ALLOCATE (ciao(nspin))
     319          62 :       DO ispin = 1, nspin
     320          32 :          CALL get_mo_set(mos_loc(ispin), mo_coeff=cloc)
     321          32 :          CALL cp_fm_get_info(cloc, nrow_global=nao, ncol_global=norb)
     322          32 :          CALL cp_fm_get_info(c_iao_coef(ispin), ncol_global=nref)
     323          32 :          CALL cp_fm_create(smo, cloc%matrix_struct)
     324          32 :          NULLIFY (fm_struct)
     325             :          CALL cp_fm_struct_create(fm_struct, nrow_global=nref, &
     326          32 :                                   template_fmstruct=cloc%matrix_struct)
     327          32 :          CALL cp_fm_create(ciao(ispin), fm_struct)
     328          32 :          CALL cp_fm_struct_release(fm_struct)
     329             :          ! CIAO = A(T)*S*C
     330          32 :          CALL cp_dbcsr_sm_fm_multiply(smat, cloc, smo, ncol=norb)
     331             :          CALL parallel_gemm('T', 'N', nref, norb, nao, 1.0_dp, c_iao_coef(ispin), &
     332          32 :                             smo, 0.0_dp, ciao(ispin))
     333          94 :          CALL cp_fm_release(smo)
     334             :       END DO
     335             : 
     336             :       ! Reference basis set
     337          30 :       CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set)
     338          30 :       nkind = SIZE(qs_kind_set)
     339         148 :       ALLOCATE (ref_basis_set_list(nkind))
     340          88 :       DO ikind = 1, nkind
     341          58 :          qs_kind => qs_kind_set(ikind)
     342          58 :          NULLIFY (ref_basis_set_list(ikind)%gto_basis_set)
     343          58 :          NULLIFY (refbasis)
     344          58 :          CALL get_qs_kind(qs_kind=qs_kind, basis_set=refbasis, basis_type="MIN")
     345          88 :          IF (ASSOCIATED(refbasis)) ref_basis_set_list(ikind)%gto_basis_set => refbasis
     346             :       END DO
     347          30 :       CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, natom=natom)
     348          90 :       ALLOCATE (refbas_blk_sizes(natom))
     349             :       CALL get_particle_set(particle_set, qs_kind_set, nsgf=refbas_blk_sizes, &
     350          30 :                             basis=ref_basis_set_list)
     351             : 
     352             :       ! Atomic orbital weights
     353          92 :       ALLOCATE (orb_weight(nspin))
     354          90 :       ALLOCATE (mcharge(natom, 1))
     355          62 :       DO ispin = 1, nspin
     356          32 :          CALL get_mo_set(mos_loc(ispin), mo_coeff=cloc)
     357          32 :          NULLIFY (fm_struct)
     358             :          CALL cp_fm_struct_create(fm_struct, nrow_global=natom, &
     359          32 :                                   template_fmstruct=cloc%matrix_struct)
     360          32 :          CALL cp_fm_create(orb_weight(ispin), fm_struct)
     361          32 :          CALL cp_fm_struct_release(fm_struct)
     362          62 :          CALL cp_fm_set_all(orb_weight(ispin), 0.0_dp)
     363             :       END DO
     364             :       !
     365          30 :       CALL dbcsr_get_info(smat, distribution=dbcsr_dist)
     366             :       CALL dbcsr_create(matrix=dmat, name="DMAT", &
     367             :                         dist=dbcsr_dist, matrix_type=dbcsr_type_symmetric, &
     368             :                         row_blk_size=refbas_blk_sizes, col_blk_size=refbas_blk_sizes, &
     369          30 :                         nze=0)
     370          30 :       CALL dbcsr_reserve_diag_blocks(dmat)
     371             :       !
     372          30 :       NULLIFY (fm_struct)
     373             :       CALL cp_fm_struct_create(fm_struct, ncol_global=1, &
     374          30 :                                template_fmstruct=ciao(1)%matrix_struct)
     375          30 :       CALL cp_fm_create(cvec, fm_struct)
     376          30 :       CALL cp_fm_create(cvec2, fm_struct)
     377          30 :       CALL cp_fm_struct_release(fm_struct)
     378             :       !
     379          62 :       DO ispin = 1, nspin
     380             :          CALL get_mo_set(mos_loc(ispin), &
     381             :                          mo_coeff=cloc, nmo=norb, &
     382          32 :                          occupation_numbers=occupation_numbers)
     383          62 :          IF (uocc) THEN
     384             :             ! uniform occupation
     385         158 :             DO iorb = 1, norb
     386         128 :                CALL cp_fm_to_fm(ciao(ispin), cvec, ncol=1, source_start=iorb, target_start=1)
     387         128 :                focc = occupation_numbers(iorb)
     388         128 :                CALL dbcsr_set(dmat, 0.0_dp)
     389         128 :                CALL cp_dbcsr_plus_fm_fm_t(dmat, cvec, ncol=1, alpha=focc)
     390         128 :                CALL iao_charges(dmat, mcharge(:, 1))
     391             :                CALL cp_fm_set_submatrix(orb_weight(ispin), mcharge, start_row=1, &
     392         128 :                                         start_col=iorb, n_rows=natom, n_cols=1)
     393         560 :                checksum = SUM(mcharge(:, 1))
     394         158 :                IF (ABS(focc - checksum) > 1.E-6_dp) THEN
     395           0 :                   CALL cp_warn(__LOCATION__, "Sum of atomic orbital weights is incorrect")
     396           0 :                   IF (unit_nr > 0) THEN
     397             :                      WRITE (UNIT=unit_nr, FMT="(T2,A,F10.6,T40,A,F10.6)") &
     398           0 :                         "Orbital occupation:", focc, &
     399           0 :                         "Sum of atomic orbital weights:", checksum
     400             :                   END IF
     401             :                END IF
     402             :             END DO
     403             :          ELSE
     404             :             ! non-diagonal occupation matrix
     405           6 :             ALLOCATE (odiag(norb))
     406           2 :             CALL cp_fm_get_diag(fij_mat(ispin), odiag)
     407          54 :             DO iorb = 1, norb
     408          52 :                IF (odiag(iorb) < 1.E-8_dp) CYCLE
     409          44 :                CALL dbcsr_set(dmat, 0.0_dp)
     410          44 :                CALL cp_fm_to_fm(ciao(ispin), cvec, ncol=1, source_start=iorb, target_start=1)
     411        1188 :                DO jorb = 1, norb
     412        1144 :                   CALL cp_fm_get_element(fij_mat(ispin), iorb, jorb, focc)
     413        1144 :                   IF (focc < 1.E-12_dp) CYCLE
     414         570 :                   CALL cp_fm_to_fm(ciao(ispin), cvec2, ncol=1, source_start=jorb, target_start=1)
     415        1758 :                   CALL cp_dbcsr_plus_fm_fm_t(dmat, cvec, cvec2, 1, alpha=focc, symmetry_mode=1)
     416             :                END DO
     417          44 :                CALL iao_charges(dmat, mcharge(:, 1))
     418         396 :                checksum = SUM(mcharge(:, 1))
     419          44 :                focc = odiag(iorb)
     420          44 :                IF (ABS(focc - checksum) > 1.E-6_dp) THEN
     421           0 :                   CALL cp_warn(__LOCATION__, "Sum of atomic orbital weights is incorrect")
     422           0 :                   IF (unit_nr > 0) THEN
     423             :                      WRITE (UNIT=unit_nr, FMT="(T2,A,F10.6,T40,A,F10.6)") &
     424           0 :                         "Orbital occupation:", focc, &
     425           0 :                         "Sum of atomic orbital weights:", checksum
     426             :                   END IF
     427             :                END IF
     428         396 :                mcharge(:, 1) = mcharge(:, 1)/focc
     429             :                CALL cp_fm_set_submatrix(orb_weight(ispin), mcharge, start_row=1, &
     430          54 :                                         start_col=iorb, n_rows=natom, n_cols=1)
     431             :             END DO
     432           2 :             DEALLOCATE (odiag)
     433             :          END IF
     434             :       END DO
     435          30 :       DEALLOCATE (mcharge)
     436          30 :       CALL dbcsr_release(dmat)
     437          30 :       CALL cp_fm_release(cvec)
     438          30 :       CALL cp_fm_release(cvec2)
     439             : 
     440          30 :       CALL get_qs_env(qs_env, para_env=para_env)
     441          30 :       group = para_env
     442             :       ! energy arrays
     443         180 :       ALLOCATE (atener(natom), ateks(natom), atecc(natom), atcore(natom))
     444         120 :       ALLOCATE (ate1xc(natom), ate1h(natom), atewald(natom))
     445         136 :       atener = 0.0_dp
     446         136 :       ateks = 0.0_dp
     447         136 :       atecc = 0.0_dp
     448         136 :       atcore = 0.0_dp
     449         136 :       ate1xc = 0.0_dp
     450         136 :       ate1h = 0.0_dp
     451         136 :       atewald = 0.0_dp
     452          30 :       IF (detailed_ener) THEN
     453          30 :          ALLOCATE (atdet(natom, 10), atmul(natom, 10), amval(natom))
     454         246 :          atdet = 0.0_dp
     455         246 :          atmul = 0.0_dp
     456             :       END IF
     457             :       ! atom dependent density matrix
     458          30 :       CALL dbcsr_create(dkmat, template=smat)
     459          30 :       CALL dbcsr_copy(dkmat, smat)
     460          30 :       CALL dbcsr_set(dkmat, 0.0_dp)
     461             :       ! KS matrix + correction
     462          30 :       CALL get_qs_env(qs_env, matrix_h=matrix_h, matrix_ks=matrix_ks, kinetic=matrix_t)
     463         244 :       ALLOCATE (ks_mat(nspin), core_mat(1), vhxc_mat(nspin), exc_mat(1))
     464          62 :       DO ispin = 1, nspin
     465          32 :          ALLOCATE (ks_mat(ispin)%matrix)
     466          32 :          CALL dbcsr_create(ks_mat(ispin)%matrix, template=matrix_h(1)%matrix)
     467          32 :          CALL dbcsr_copy(ks_mat(ispin)%matrix, matrix_h(1)%matrix)
     468          32 :          CALL dbcsr_add(ks_mat(ispin)%matrix, matrix_ks(ispin)%matrix, 1.0_dp, 1.0_dp)
     469          32 :          CALL dbcsr_scale(ks_mat(ispin)%matrix, 0.5_dp)
     470             :          !
     471          32 :          ALLOCATE (vhxc_mat(ispin)%matrix)
     472          32 :          CALL dbcsr_create(vhxc_mat(ispin)%matrix, template=smat)
     473          32 :          CALL dbcsr_copy(vhxc_mat(ispin)%matrix, smat)
     474          62 :          CALL dbcsr_set(vhxc_mat(ispin)%matrix, 0.0_dp)
     475             :       END DO
     476             :       !
     477          30 :       ALLOCATE (core_mat(1)%matrix)
     478          30 :       CALL dbcsr_create(core_mat(1)%matrix, template=matrix_h(1)%matrix)
     479          30 :       CALL dbcsr_copy(core_mat(1)%matrix, matrix_h(1)%matrix)
     480          30 :       CALL dbcsr_set(core_mat(1)%matrix, 0.0_dp)
     481             :       !
     482          30 :       ALLOCATE (exc_mat(1)%matrix)
     483          30 :       CALL dbcsr_create(exc_mat(1)%matrix, template=smat)
     484          30 :       CALL dbcsr_copy(exc_mat(1)%matrix, smat)
     485          30 :       CALL dbcsr_set(exc_mat(1)%matrix, 0.0_dp)
     486             :       !
     487          30 :       CALL vhxc_correction(qs_env, vhxc_mat, exc_mat, atecc, ate1xc, ate1h)
     488             :       !
     489          30 :       CALL get_qs_env(qs_env, rho=rho)
     490          30 :       CALL qs_rho_get(rho, rho_ao=matrix_p)
     491          30 :       math(1:1, 1:1) => core_mat(1:1)
     492          30 :       matp(1:nspin, 1:1) => matrix_p(1:nspin)
     493          30 :       CALL core_matrices(qs_env, math, matp, .FALSE., 0, atcore=atcore)
     494          30 :       CALL group%sum(atcore)
     495             :       !
     496          30 :       IF (ewald_correction) THEN
     497           2 :          ALLOCATE (dve_mat%matrix)
     498           2 :          CALL dbcsr_create(dve_mat%matrix, template=matrix_h(1)%matrix)
     499           2 :          CALL dbcsr_copy(dve_mat%matrix, matrix_h(1)%matrix)
     500           2 :          CALL dbcsr_set(dve_mat%matrix, 0.0_dp)
     501           2 :          CALL vh_ewald_correction(qs_env, ealpha, dve_mat, atewald)
     502           2 :          CALL group%sum(atewald)
     503             :       END IF
     504             :       !
     505          62 :       DO ispin = 1, nspin
     506          32 :          CALL dbcsr_add(ks_mat(ispin)%matrix, vhxc_mat(ispin)%matrix, 1.0_dp, 1.0_dp)
     507          62 :          CALL dbcsr_add(ks_mat(ispin)%matrix, core_mat(1)%matrix, 1.0_dp, -0.5_dp)
     508             :       END DO
     509             :       !
     510          30 :       IF (detailed_ener .AND. do_hfx) THEN
     511           6 :          ALLOCATE (matrix_hfx(nspin))
     512           4 :          DO ispin = 1, nspin
     513           2 :             ALLOCATE (matrix_hfx(nspin)%matrix)
     514           2 :             CALL dbcsr_create(matrix_hfx(ispin)%matrix, template=smat)
     515           2 :             CALL dbcsr_copy(matrix_hfx(ispin)%matrix, smat)
     516           4 :             CALL dbcsr_set(matrix_hfx(ispin)%matrix, 0.0_dp)
     517             :          END DO
     518           2 :          CALL get_hfx_ks_matrix(qs_env, matrix_hfx)
     519             :       END IF
     520             :       ! Loop over spins and atoms
     521          62 :       DO ispin = 1, nspin
     522          32 :          CALL get_mo_set(mos_loc(ispin), mo_coeff=cloc, nmo=norb)
     523          96 :          ALLOCATE (mweight(1, norb))
     524         144 :          DO iatom = 1, natom
     525             :             CALL cp_fm_get_submatrix(orb_weight(ispin), mweight, start_row=iatom, &
     526         112 :                                      start_col=1, n_rows=1, n_cols=norb)
     527         112 :             IF (uocc) THEN
     528          96 :                CALL iao_calculate_dmat(cloc, dkmat, mweight(1, :), .FALSE.)
     529             :             ELSE
     530          16 :                CALL iao_calculate_dmat(cloc, dkmat, mweight(1, :), fij_mat(ispin))
     531             :             END IF
     532         112 :             CALL dbcsr_dot(dkmat, ks_mat(ispin)%matrix, ecc)
     533         112 :             ateks(iatom) = ateks(iatom) + ecc
     534             :             !
     535         112 :             IF (detailed_ener) THEN
     536          18 :                CALL dbcsr_dot(dkmat, matrix_t(1)%matrix, e1)
     537          18 :                atdet(iatom, 1) = atdet(iatom, 1) + e1
     538          18 :                CALL dbcsr_dot(dkmat, matrix_h(1)%matrix, e2)
     539          18 :                atdet(iatom, 2) = atdet(iatom, 2) + (e2 - e1)
     540          18 :                IF (do_hfx) THEN
     541           6 :                   CALL dbcsr_scale(matrix_hfx(ispin)%matrix, 0.5_dp)
     542           6 :                   CALL dbcsr_dot(dkmat, matrix_hfx(ispin)%matrix, ehfx)
     543           6 :                   atdet(iatom, 5) = atdet(iatom, 5) + ehfx
     544           6 :                   CALL dbcsr_scale(matrix_hfx(ispin)%matrix, 2.0_dp)
     545             :                ELSE
     546          12 :                   ehfx = 0.0_dp
     547             :                END IF
     548          18 :                CALL dbcsr_dot(dkmat, exc_mat(1)%matrix, e1)
     549          18 :                atdet(iatom, 3) = atdet(iatom, 3) + ecc - e2 - e1 - ehfx
     550          18 :                atdet(iatom, 4) = atdet(iatom, 4) + e1
     551             :             END IF
     552         144 :             IF (ewald_correction) THEN
     553           6 :                CALL dbcsr_dot(dkmat, dve_mat%matrix, ecc)
     554           6 :                atewald(iatom) = atewald(iatom) + ecc
     555             :             END IF
     556             :             !
     557             :          END DO
     558          94 :          DEALLOCATE (mweight)
     559             :       END DO
     560             :       !
     561          30 :       IF (detailed_ener) THEN
     562             :          ! Mulliken
     563           6 :          CALL get_qs_env(qs_env, rho=rho, para_env=para_env)
     564           6 :          CALL qs_rho_get(rho, rho_ao=matrix_p)
     565             :          ! kinetic energy
     566          12 :          DO ispin = 1, nspin
     567             :             CALL mulliken_charges(matrix_p(ispin)%matrix, matrix_t(1)%matrix, &
     568           6 :                                   para_env, amval)
     569          24 :             atmul(1:natom, 1) = atmul(1:natom, 1) + amval(1:natom)
     570             :             CALL mulliken_charges(matrix_p(ispin)%matrix, matrix_h(1)%matrix, &
     571           6 :                                   para_env, amval)
     572          24 :             atmul(1:natom, 2) = atmul(1:natom, 2) + amval(1:natom)
     573          24 :             atmul(1:natom, 3) = atmul(1:natom, 3) - amval(1:natom)
     574             :             CALL mulliken_charges(matrix_p(ispin)%matrix, ks_mat(ispin)%matrix, &
     575           6 :                                   para_env, amval)
     576          24 :             atmul(1:natom, 3) = atmul(1:natom, 3) + amval(1:natom)
     577           6 :             IF (do_hfx) THEN
     578             :                CALL mulliken_charges(matrix_p(ispin)%matrix, matrix_hfx(ispin)%matrix, &
     579           2 :                                      para_env, amval)
     580           8 :                atmul(1:natom, 5) = atmul(1:natom, 5) + 0.5_dp*amval(1:natom)
     581           8 :                atmul(1:natom, 3) = atmul(1:natom, 3) - 0.5_dp*amval(1:natom)
     582             :             END IF
     583             :             CALL mulliken_charges(matrix_p(ispin)%matrix, exc_mat(1)%matrix, &
     584           6 :                                   para_env, amval)
     585          24 :             atmul(1:natom, 4) = atmul(1:natom, 4) + amval(1:natom)
     586          30 :             atmul(1:natom, 3) = atmul(1:natom, 3) - amval(1:natom)
     587             :          END DO
     588          24 :          atmul(1:natom, 2) = atmul(1:natom, 2) - atmul(1:natom, 1)
     589          24 :          atmul(1:natom, 3) = atmul(1:natom, 3) + 0.5_dp*atmul(1:natom, 2)
     590          24 :          atmul(1:natom, 2) = 0.5_dp*atmul(1:natom, 2) + 0.5_dp*atcore(1:natom)
     591             :       END IF
     592             :       !
     593          30 :       CALL dbcsr_release(dkmat)
     594          62 :       DO ispin = 1, nspin
     595          32 :          CALL dbcsr_release(ks_mat(ispin)%matrix)
     596          32 :          CALL dbcsr_release(vhxc_mat(ispin)%matrix)
     597          32 :          DEALLOCATE (ks_mat(ispin)%matrix, vhxc_mat(ispin)%matrix)
     598          62 :          CALL deallocate_mo_set(mos_loc(ispin))
     599             :       END DO
     600          30 :       CALL dbcsr_release(core_mat(1)%matrix)
     601          30 :       DEALLOCATE (core_mat(1)%matrix)
     602          30 :       CALL dbcsr_release(exc_mat(1)%matrix)
     603          30 :       DEALLOCATE (exc_mat(1)%matrix)
     604          30 :       DEALLOCATE (ks_mat, core_mat, vhxc_mat, exc_mat)
     605          30 :       DEALLOCATE (mos_loc)
     606          30 :       DEALLOCATE (refbas_blk_sizes)
     607          30 :       DEALLOCATE (ref_basis_set_list)
     608          30 :       IF (detailed_ener .AND. do_hfx) THEN
     609           4 :          DO ispin = 1, nspin
     610           2 :             CALL dbcsr_release(matrix_hfx(ispin)%matrix)
     611           4 :             DEALLOCATE (matrix_hfx(ispin)%matrix)
     612             :          END DO
     613           2 :          DEALLOCATE (matrix_hfx)
     614             :       END IF
     615          30 :       IF (ewald_correction) THEN
     616           2 :          CALL dbcsr_release(dve_mat%matrix)
     617           2 :          DEALLOCATE (dve_mat%matrix)
     618             :       END IF
     619          30 :       CALL cp_fm_release(orb_weight)
     620          30 :       CALL cp_fm_release(ciao)
     621          30 :       CALL cp_fm_release(rotmat)
     622          30 :       CALL cp_fm_release(c_iao_coef)
     623          30 :       IF (.NOT. uocc) THEN
     624           2 :          CALL cp_fm_release(fij_mat)
     625             :       END IF
     626             : 
     627             :       ! KS energy
     628         136 :       atener(1:natom) = ateks(1:natom)
     629             :       ! 1/2 of VPP contribution Tr[VPP(K)*P]
     630         136 :       atener(1:natom) = atener(1:natom) + 0.5_dp*atcore(1:natom)
     631             :       ! core energy corrections
     632          30 :       CALL group%sum(atecc)
     633         136 :       atener(1:natom) = atener(1:natom) + atecc(1:natom)
     634          48 :       IF (detailed_ener) atdet(1:natom, 6) = atdet(1:natom, 6) + atecc(1:natom)
     635             :       ! one center terms (GAPW)
     636          30 :       CALL group%sum(ate1xc)
     637          30 :       CALL group%sum(ate1h)
     638         136 :       atener(1:natom) = atener(1:natom) + ate1xc(1:natom) + ate1h(1:natom)
     639          30 :       IF (detailed_ener) THEN
     640           6 :          IF (gapw .OR. gapw_xc) atdet(1:natom, 8) = atdet(1:natom, 8) + ate1xc(1:natom)
     641           0 :          IF (gapw) atdet(1:natom, 9) = atdet(1:natom, 9) + ate1h(1:natom)
     642             :       END IF
     643             :       ! core correction
     644         136 :       atecc(1:natom) = 0.0_dp
     645          30 :       CALL calculate_ecore_overlap(qs_env, para_env, .FALSE., atecc=atecc)
     646          30 :       CALL group%sum(atecc)
     647         136 :       atener(1:natom) = atener(1:natom) + atecc(1:natom)
     648          48 :       IF (detailed_ener) atdet(1:natom, 7) = atdet(1:natom, 7) + atecc(1:natom)
     649          30 :       IF (ewald_correction) THEN
     650           8 :          atewald(1:natom) = atewald(1:natom) - atecc(1:natom)
     651             :       END IF
     652             :       ! e self
     653         136 :       atecc(1:natom) = 0.0_dp
     654          30 :       CALL calculate_ecore_self(qs_env, atecc=atecc)
     655          30 :       CALL group%sum(atecc)
     656         136 :       atener(1:natom) = atener(1:natom) + atecc(1:natom)
     657          48 :       IF (detailed_ener) atdet(1:natom, 7) = atdet(1:natom, 7) + atecc(1:natom)
     658          30 :       IF (ewald_correction) THEN
     659           8 :          atewald(1:natom) = atewald(1:natom) - atecc(1:natom)
     660           2 :          CALL calculate_ecore_alpha(qs_env, ealpha, atewald)
     661             :       END IF
     662             :       ! vdW pair-potentials
     663         136 :       atecc(1:natom) = 0.0_dp
     664          30 :       CALL get_qs_env(qs_env=qs_env, dispersion_env=dispersion_env)
     665          30 :       CALL calculate_dispersion_pairpot(qs_env, dispersion_env, evdw, .FALSE., atevdw=atecc)
     666             :       ! Pair potential gCP energy
     667          30 :       CALL get_qs_env(qs_env=qs_env, gcp_env=gcp_env)
     668          30 :       IF (ASSOCIATED(gcp_env)) THEN
     669          30 :          CALL calculate_gcp_pairpot(qs_env, gcp_env, egcp, .FALSE., ategcp=atecc)
     670             :       END IF
     671          30 :       CALL group%sum(atecc)
     672         136 :       atener(1:natom) = atener(1:natom) + atecc(1:natom)
     673          48 :       IF (detailed_ener) atdet(1:natom, 10) = atdet(1:natom, 10) + atecc(1:natom)
     674             :       ! distribute the entropic energy
     675          30 :       CALL get_qs_env(qs_env, energy=energy)
     676          30 :       ekts = energy%kts/REAL(natom, KIND=dp)
     677         136 :       atener(1:natom) = atener(1:natom) + ekts
     678             :       ! 0.5 Vpp(at)*D + 0.5 * Vpp*D(at)
     679          30 :       IF (detailed_ener) THEN
     680          24 :          atdet(1:natom, 3) = atdet(1:natom, 3) + 0.5_dp*atdet(1:natom, 2)
     681          24 :          atdet(1:natom, 2) = 0.5_dp*atdet(1:natom, 2) + 0.5_dp*atcore(1:natom)
     682             :       END IF
     683             :       !
     684          30 :       IF (detailed_ener) THEN
     685           6 :          IF (unit_nr > 0) THEN
     686           3 :             WRITE (unit_nr, FMT="(/,T2,A)") "Detailed IAO Atomic Energy Components "
     687           3 :             CALL write_atdet(unit_nr, atdet(:, 1), "Kinetic Energy")
     688           3 :             CALL write_atdet(unit_nr, atdet(:, 2), "Short-Range Core and/or PP Energy")
     689           3 :             CALL write_atdet(unit_nr, atdet(:, 3), "Hartree Energy (long-ranged part)")
     690           3 :             CALL write_atdet(unit_nr, atdet(:, 5), "Exact Exchange Energy")
     691           3 :             CALL write_atdet(unit_nr, atdet(:, 4), "Exchange-Correlation Energy")
     692           3 :             CALL write_atdet(unit_nr, atdet(:, 6), "Atomic Core Hartree: Int(nc V(n+nc) dx")
     693           3 :             CALL write_atdet(unit_nr, atdet(:, 7), "Core Self Energy Corrections")
     694           3 :             IF (gapw) THEN
     695           0 :                CALL write_atdet(unit_nr, atdet(:, 9), "GAPW: 1-center Hartree Energy")
     696             :             END IF
     697           3 :             IF (gapw .OR. gapw_xc) THEN
     698           0 :                CALL write_atdet(unit_nr, atdet(:, 8), "GAPW: 1-center XC Energy")
     699             :             END IF
     700           3 :             IF (ABS(evdw) > 1.E-14_dp) THEN
     701           0 :                CALL write_atdet(unit_nr, atdet(:, 10), "vdW Pairpotential Energy")
     702             :             END IF
     703          12 :             DO iatom = 1, natom
     704         102 :                atecc(iatom) = SUM(atdet(iatom, 1:10)) - atener(iatom)
     705             :             END DO
     706           3 :             CALL write_atdet(unit_nr, atecc(:), "Missing Energy")
     707             :             !
     708           3 :             WRITE (unit_nr, FMT="(/,T2,A)") "Detailed Mulliken Atomic Energy Components "
     709           3 :             CALL write_atdet(unit_nr, atmul(:, 1), "Kinetic Energy")
     710           3 :             CALL write_atdet(unit_nr, atmul(:, 2), "Short-Range Core and/or PP Energy")
     711           3 :             CALL write_atdet(unit_nr, atmul(:, 3), "Hartree Energy (long-ranged part)")
     712           3 :             CALL write_atdet(unit_nr, atmul(:, 5), "Exact Exchange Energy")
     713           3 :             CALL write_atdet(unit_nr, atmul(:, 4), "Exchange-Correlation Energy")
     714           3 :             CALL write_atdet(unit_nr, atdet(:, 6), "Atomic Core Hartree: Int(nc V(n+nc) dx")
     715           3 :             CALL write_atdet(unit_nr, atdet(:, 7), "Core Self Energy Corrections")
     716           3 :             IF (gapw) THEN
     717           0 :                CALL write_atdet(unit_nr, atdet(:, 9), "GAPW: 1-center Hartree Energy")
     718             :             END IF
     719           3 :             IF (gapw .OR. gapw_xc) THEN
     720           0 :                CALL write_atdet(unit_nr, atdet(:, 8), "GAPW: 1-center XC Energy")
     721             :             END IF
     722           3 :             IF (ABS(evdw) > 1.E-14_dp) THEN
     723           0 :                CALL write_atdet(unit_nr, atdet(:, 10), "vdW Pairpotential Energy")
     724             :             END IF
     725             :          END IF
     726             :       END IF
     727             : 
     728          30 :       IF (unit_nr > 0) THEN
     729          15 :          e_pot = energy%total
     730          15 :          ateps = 1.E-6_dp
     731          15 :          CALL write_atener(unit_nr, particle_set, atener, "Atomic Energy Decomposition")
     732          68 :          sum_energy = SUM(atener(:))
     733          15 :          checksum = ABS(e_pot - sum_energy)
     734             :          WRITE (UNIT=unit_nr, FMT="((T2,A,T56,F25.13))") &
     735          15 :             "Potential energy (Atomic):", sum_energy, &
     736          15 :             "Potential energy (Total) :", e_pot, &
     737          30 :             "Difference               :", checksum
     738          15 :          CPASSERT((checksum < ateps*ABS(e_pot)))
     739             :          !
     740          15 :          IF (ewald_correction) THEN
     741           1 :             WRITE (UNIT=unit_nr, FMT="(/,(T2,A,F10.3,A))") "Universal Ewald Parameter: ", ealpha, " [Angstrom]"
     742           1 :             CALL write_atener(unit_nr, particle_set, atewald, "Change in Atomic Energy Decomposition")
     743           4 :             sum_energy = SUM(atewald(:))
     744             :             WRITE (UNIT=unit_nr, FMT="((T2,A,T56,F25.13))") &
     745           1 :                "Total Change in Potential energy:", sum_energy
     746             :          END IF
     747             :       END IF
     748             : 
     749          30 :       IF (detailed_ener) THEN
     750           6 :          DEALLOCATE (atdet, atmul, amval)
     751             :       END IF
     752             : 
     753          30 :       IF (unit_nr > 0) THEN
     754             :          WRITE (UNIT=unit_nr, FMT="(/,T2,A)") &
     755          15 :             "!--------------------------- END OF ED ANALYSIS ------------------------------!"
     756             :       END IF
     757          30 :       DEALLOCATE (bcenter)
     758          30 :       DEALLOCATE (atener, ateks, atecc, atcore, ate1xc, ate1h, atewald)
     759             : 
     760          30 :       CALL timestop(handle)
     761             : 
     762         266 :    END SUBROUTINE edmf_analysis
     763             : 
     764             : ! **************************************************************************************************
     765             : !> \brief ...
     766             : !> \param qs_env ...
     767             : !> \param vhxc_mat ...
     768             : !> \param exc_mat ...
     769             : !> \param atecc ...
     770             : !> \param ate1xc ...
     771             : !> \param ate1h ...
     772             : ! **************************************************************************************************
     773          30 :    SUBROUTINE vhxc_correction(qs_env, vhxc_mat, exc_mat, atecc, ate1xc, ate1h)
     774             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     775             :       TYPE(dbcsr_p_type), DIMENSION(:)                   :: vhxc_mat, exc_mat
     776             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: atecc, ate1xc, ate1h
     777             : 
     778             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'vhxc_correction'
     779             : 
     780             :       INTEGER                                            :: handle, iatom, ispin, natom, nspins
     781             :       LOGICAL                                            :: do_admm_corr, gapw, gapw_xc
     782             :       REAL(KIND=dp)                                      :: eh1, exc1
     783             :       TYPE(admm_type), POINTER                           :: admm_env
     784          30 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     785          30 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p
     786             :       TYPE(dft_control_type), POINTER                    :: dft_control
     787          30 :       TYPE(ecoul_1center_type), DIMENSION(:), POINTER    :: ecoul_1c
     788             :       TYPE(local_rho_type), POINTER                      :: local_rho_set
     789             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     790             :       TYPE(pw_env_type), POINTER                         :: pw_env
     791             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     792             :       TYPE(pw_r3d_rs_type)                               :: xc_den
     793          30 :       TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:)    :: vtau, vxc
     794             :       TYPE(pw_r3d_rs_type), POINTER                      :: v_hartree_rspace
     795             :       TYPE(qs_dispersion_type), POINTER                  :: dispersion_env
     796          30 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     797             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     798             :       TYPE(qs_rho_type), POINTER                         :: rho_struct
     799          30 :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho_atom_set
     800             :       TYPE(section_vals_type), POINTER                   :: xc_fun_section, xc_section
     801             :       TYPE(xc_rho_cflags_type)                           :: needs
     802             : 
     803          30 :       CALL timeset(routineN, handle)
     804             : 
     805          30 :       CALL get_qs_env(qs_env, ks_env=ks_env, dft_control=dft_control, pw_env=pw_env)
     806             : 
     807          30 :       nspins = dft_control%nspins
     808          30 :       gapw = dft_control%qs_control%gapw
     809          30 :       gapw_xc = dft_control%qs_control%gapw_xc
     810          30 :       do_admm_corr = .FALSE.
     811          30 :       IF (dft_control%do_admm) THEN
     812           0 :          IF (qs_env%admm_env%aux_exch_func /= do_admm_aux_exch_func_none) do_admm_corr = .TRUE.
     813             :       END IF
     814             :       IF (do_admm_corr) THEN
     815           0 :          CALL get_qs_env(qs_env, admm_env=admm_env)
     816           0 :          xc_section => admm_env%xc_section_aux
     817             :       ELSE
     818          30 :          xc_section => section_vals_get_subs_vals(qs_env%input, "DFT%XC")
     819             :       END IF
     820          30 :       xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
     821          30 :       needs = xc_functionals_get_needs(xc_fun_section, (nspins == 2), .TRUE.)
     822             : 
     823          30 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
     824          30 :       CALL auxbas_pw_pool%create_pw(xc_den)
     825         122 :       ALLOCATE (vxc(nspins))
     826          62 :       DO ispin = 1, nspins
     827          62 :          CALL auxbas_pw_pool%create_pw(vxc(ispin))
     828             :       END DO
     829          30 :       IF (needs%tau .OR. needs%tau_spin) THEN
     830          24 :          ALLOCATE (vtau(nspins))
     831          16 :          DO ispin = 1, nspins
     832          38 :             CALL auxbas_pw_pool%create_pw(vtau(ispin))
     833             :          END DO
     834             :       END IF
     835             : 
     836             :       ! Nuclear charge correction
     837          30 :       CALL get_qs_env(qs_env, v_hartree_rspace=v_hartree_rspace)
     838          30 :       CALL integrate_v_core_rspace(v_hartree_rspace, qs_env, atecc=atecc)
     839          30 :       IF (gapw .OR. gapw_xc) THEN
     840             :          CALL get_qs_env(qs_env=qs_env, local_rho_set=local_rho_set, &
     841             :                          rho_atom_set=rho_atom_set, ecoul_1c=ecoul_1c, &
     842           8 :                          natom=natom, para_env=para_env)
     843           8 :          CALL zero_rho_atom_integrals(rho_atom_set)
     844           8 :          CALL calculate_vxc_atom(qs_env, .FALSE., exc1)
     845           8 :          IF (gapw) THEN
     846           6 :             CALL Vh_1c_gg_integrals(qs_env, eh1, ecoul_1c, local_rho_set, para_env, tddft=.FALSE.)
     847           6 :             CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set)
     848             :             CALL integrate_vhg0_rspace(qs_env, v_hartree_rspace, para_env, calculate_forces=.FALSE., &
     849           6 :                                        local_rho_set=local_rho_set, atener=atecc)
     850             :          END IF
     851             :       END IF
     852             : 
     853           8 :       IF (gapw_xc) THEN
     854           2 :          CALL get_qs_env(qs_env, rho_xc=rho_struct, dispersion_env=dispersion_env)
     855             :       ELSE
     856          28 :          CALL get_qs_env(qs_env, rho=rho_struct, dispersion_env=dispersion_env)
     857             :       END IF
     858             :       !
     859          30 :       CPASSERT(.NOT. do_admm_corr)
     860             :       !
     861          30 :       IF (needs%tau .OR. needs%tau_spin) THEN
     862             :          CALL qs_xc_density(ks_env, rho_struct, xc_section, dispersion_env=dispersion_env, &
     863           8 :                             xc_den=xc_den, vxc=vxc, vtau=vtau)
     864             :       ELSE
     865             :          CALL qs_xc_density(ks_env, rho_struct, xc_section, dispersion_env=dispersion_env, &
     866          22 :                             xc_den=xc_den, vxc=vxc)
     867             :       END IF
     868          62 :       DO ispin = 1, nspins
     869          32 :          CALL pw_scale(vxc(ispin), -0.5_dp)
     870          32 :          CALL pw_axpy(xc_den, vxc(ispin))
     871          32 :          CALL pw_scale(vxc(ispin), vxc(ispin)%pw_grid%dvol)
     872             :          CALL integrate_v_rspace(qs_env=qs_env, v_rspace=vxc(ispin), &
     873             :                                  hmat=vhxc_mat(ispin), calculate_forces=.FALSE., &
     874          32 :                                  gapw=(gapw .OR. gapw_xc))
     875          62 :          IF (needs%tau .OR. needs%tau_spin) THEN
     876           8 :             CALL pw_scale(vtau(ispin), -0.5_dp*vtau(ispin)%pw_grid%dvol)
     877             :             CALL integrate_v_rspace(qs_env=qs_env, v_rspace=vtau(ispin), &
     878             :                                     hmat=vhxc_mat(ispin), calculate_forces=.FALSE., &
     879           8 :                                     compute_tau=.TRUE., gapw=(gapw .OR. gapw_xc))
     880             :          END IF
     881             :       END DO
     882          30 :       CALL pw_scale(xc_den, xc_den%pw_grid%dvol)
     883             :       CALL integrate_v_rspace(qs_env=qs_env, v_rspace=xc_den, &
     884             :                               hmat=exc_mat(1), calculate_forces=.FALSE., &
     885          30 :                               gapw=(gapw .OR. gapw_xc))
     886             : 
     887          30 :       IF (gapw .OR. gapw_xc) THEN
     888             :          ! remove one-center potential matrix part
     889           8 :          CALL qs_rho_get(rho_struct, rho_ao_kp=matrix_p)
     890           8 :          CALL update_ks_atom(qs_env, vhxc_mat, matrix_p, forces=.FALSE., kscale=-0.5_dp)
     891             :          !
     892          32 :          DO iatom = 1, natom
     893             :             ate1xc(iatom) = ate1xc(iatom) + &
     894          32 :                             rho_atom_set(iatom)%exc_h - rho_atom_set(iatom)%exc_s
     895             :          END DO
     896           8 :          IF (gapw) THEN
     897          24 :             DO iatom = 1, natom
     898             :                ate1h(iatom) = ate1h(iatom) + &
     899             :                               ecoul_1c(iatom)%ecoul_1_h - ecoul_1c(iatom)%ecoul_1_s + &
     900          24 :                               ecoul_1c(iatom)%ecoul_1_z - ecoul_1c(iatom)%ecoul_1_0
     901             :             END DO
     902             :          END IF
     903             :       END IF
     904             : 
     905          30 :       CALL auxbas_pw_pool%give_back_pw(xc_den)
     906          62 :       DO ispin = 1, nspins
     907          62 :          CALL auxbas_pw_pool%give_back_pw(vxc(ispin))
     908             :       END DO
     909          30 :       IF (needs%tau .OR. needs%tau_spin) THEN
     910          16 :          DO ispin = 1, nspins
     911          38 :             CALL auxbas_pw_pool%give_back_pw(vtau(ispin))
     912             :          END DO
     913             :       END IF
     914             : 
     915          30 :       CALL timestop(handle)
     916             : 
     917          60 :    END SUBROUTINE vhxc_correction
     918             : 
     919             : ! **************************************************************************************************
     920             : !> \brief ...
     921             : !> \param qs_env ...
     922             : !> \param ealpha ...
     923             : !> \param vh_mat ...
     924             : !> \param atewd ...
     925             : ! **************************************************************************************************
     926           2 :    SUBROUTINE vh_ewald_correction(qs_env, ealpha, vh_mat, atewd)
     927             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     928             :       REAL(KIND=dp), INTENT(IN)                          :: ealpha
     929             :       TYPE(dbcsr_p_type)                                 :: vh_mat
     930             :       REAL(KIND=dp), DIMENSION(:), INTENT(INOUT)         :: atewd
     931             : 
     932             :       CHARACTER(len=*), PARAMETER :: routineN = 'vh_ewald_correction'
     933             : 
     934             :       INTEGER                                            :: handle, ikind, ispin, natom, nkind
     935             :       REAL(KIND=dp)                                      :: eps_core_charge, rhotot, zeff
     936             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: alpha, atcore, atecc, ccore
     937           2 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     938             :       TYPE(dbcsr_p_type)                                 :: e_mat
     939           2 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_p
     940             :       TYPE(dft_control_type), POINTER                    :: dft_control
     941             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     942           2 :          POINTER                                         :: sab_orb, sac_ae
     943           2 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     944             :       TYPE(pw_c1d_gs_type)                               :: rho_tot_ewd_g, v_hewd_gspace
     945             :       TYPE(pw_env_type), POINTER                         :: pw_env
     946             :       TYPE(pw_poisson_type), POINTER                     :: poisson_env
     947             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     948             :       TYPE(pw_r3d_rs_type)                               :: rho_tot_ewd_r, v_hewd_rspace
     949           2 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r
     950             :       TYPE(pw_r3d_rs_type), POINTER                      :: v_hartree_rspace
     951           2 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     952             :       TYPE(qs_rho_type), POINTER                         :: rho
     953             : 
     954           2 :       CALL timeset(routineN, handle)
     955             : 
     956           2 :       natom = SIZE(atewd)
     957           8 :       ALLOCATE (atecc(natom), atcore(natom))
     958             :       CALL get_qs_env(qs_env=qs_env, nkind=nkind, qs_kind_set=qs_kind_set, &
     959           2 :                       dft_control=dft_control)
     960           8 :       ALLOCATE (alpha(nkind), ccore(nkind))
     961           6 :       DO ikind = 1, nkind
     962           4 :          CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
     963           4 :          alpha(ikind) = ealpha
     964           6 :          ccore(ikind) = zeff*(ealpha/pi)**1.5_dp
     965             :       END DO
     966             :       !
     967           2 :       CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
     968             :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
     969           2 :                       poisson_env=poisson_env)
     970             :       !
     971           2 :       CALL auxbas_pw_pool%create_pw(v_hewd_gspace)
     972           2 :       CALL auxbas_pw_pool%create_pw(v_hewd_rspace)
     973           2 :       CALL auxbas_pw_pool%create_pw(rho_tot_ewd_g)
     974           2 :       CALL auxbas_pw_pool%create_pw(rho_tot_ewd_r)
     975             :       rhotot = 0.0_dp
     976           2 :       CALL calculate_rho_core(rho_tot_ewd_r, rhotot, qs_env, calpha=alpha, ccore=ccore)
     977             :       ! Get the total density in g-space [ions + electrons]
     978           2 :       CALL get_qs_env(qs_env=qs_env, rho=rho)
     979           2 :       CALL qs_rho_get(rho, rho_r=rho_r)
     980           4 :       DO ispin = 1, dft_control%nspins
     981           4 :          CALL pw_axpy(rho_r(ispin), rho_tot_ewd_r)
     982             :       END DO
     983           2 :       CALL pw_transfer(rho_tot_ewd_r, rho_tot_ewd_g)
     984             :       !
     985           2 :       CALL pw_poisson_solve(poisson_env, density=rho_tot_ewd_g, vhartree=v_hewd_gspace)
     986           2 :       CALL pw_transfer(v_hewd_gspace, v_hewd_rspace)
     987           2 :       CALL pw_scale(v_hewd_rspace, v_hewd_rspace%pw_grid%dvol)
     988           8 :       atecc = 0.0_dp
     989           2 :       CALL integrate_v_gaussian_rspace(v_hewd_rspace, qs_env, alpha, ccore, atecc)
     990           8 :       atewd(1:natom) = atewd(1:natom) + atecc(1:natom)
     991             :       !
     992           8 :       atecc = 0.0_dp
     993           2 :       CALL get_qs_env(qs_env, v_hartree_rspace=v_hartree_rspace)
     994           2 :       CALL integrate_v_core_rspace(v_hartree_rspace, qs_env, atecc=atecc)
     995           8 :       atewd(1:natom) = atewd(1:natom) - atecc(1:natom)
     996             :       !
     997           2 :       CALL pw_axpy(v_hartree_rspace, v_hewd_rspace, -1.0_dp)
     998           2 :       CALL dbcsr_set(vh_mat%matrix, 0.0_dp)
     999             :       CALL integrate_v_rspace(qs_env=qs_env, v_rspace=v_hewd_rspace, hmat=vh_mat, &
    1000           2 :                               calculate_forces=.FALSE.)
    1001             :       !
    1002           2 :       CALL dbcsr_scale(vh_mat%matrix, 0.5_dp)
    1003             :       !
    1004             :       ! delta erfc
    1005           2 :       CALL qs_rho_get(rho, rho_ao=matrix_p)
    1006           2 :       eps_core_charge = dft_control%qs_control%eps_core_charge
    1007           2 :       ALLOCATE (e_mat%matrix)
    1008           2 :       CALL dbcsr_create(e_mat%matrix, template=vh_mat%matrix)
    1009           2 :       CALL dbcsr_copy(e_mat%matrix, vh_mat%matrix)
    1010             :       !
    1011             :       CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, &
    1012           2 :                       particle_set=particle_set, sab_orb=sab_orb, sac_ppl=sac_ae)
    1013           2 :       CALL dbcsr_set(e_mat%matrix, 0.0_dp)
    1014           8 :       atcore = 0.0_dp
    1015             :       CALL build_erfc(e_mat, matrix_p, qs_kind_set, atomic_kind_set, particle_set, &
    1016           2 :                       alpha, ccore, eps_core_charge, sab_orb, sac_ae, atcore)
    1017           8 :       atewd(1:natom) = atewd(1:natom) + 0.5_dp*atcore(1:natom)
    1018           2 :       CALL dbcsr_add(vh_mat%matrix, e_mat%matrix, 1.0_dp, 0.5_dp)
    1019           6 :       DO ikind = 1, nkind
    1020             :          CALL get_qs_kind(qs_kind_set(ikind), alpha_core_charge=alpha(ikind), &
    1021           6 :                           ccore_charge=ccore(ikind))
    1022             :       END DO
    1023           2 :       CALL dbcsr_set(e_mat%matrix, 0.0_dp)
    1024           8 :       atcore = 0.0_dp
    1025             :       CALL build_erfc(e_mat, matrix_p, qs_kind_set, atomic_kind_set, particle_set, &
    1026           2 :                       alpha, ccore, eps_core_charge, sab_orb, sac_ae, atcore)
    1027           8 :       atewd(1:natom) = atewd(1:natom) - 0.5_dp*atcore(1:natom)
    1028           2 :       CALL dbcsr_add(vh_mat%matrix, e_mat%matrix, 1.0_dp, -0.5_dp)
    1029             :       !
    1030           2 :       CALL dbcsr_release(e_mat%matrix)
    1031           2 :       DEALLOCATE (e_mat%matrix)
    1032           2 :       CALL auxbas_pw_pool%give_back_pw(v_hewd_gspace)
    1033           2 :       CALL auxbas_pw_pool%give_back_pw(v_hewd_rspace)
    1034           2 :       CALL auxbas_pw_pool%give_back_pw(rho_tot_ewd_g)
    1035           2 :       CALL auxbas_pw_pool%give_back_pw(rho_tot_ewd_r)
    1036           2 :       DEALLOCATE (atecc, atcore)
    1037           2 :       DEALLOCATE (alpha, ccore)
    1038             : 
    1039           2 :       CALL timestop(handle)
    1040             : 
    1041           4 :    END SUBROUTINE vh_ewald_correction
    1042             : 
    1043             : ! **************************************************************************************************
    1044             : !> \brief ...
    1045             : !> \param qs_env ...
    1046             : !> \param matrix_hfx ...
    1047             : ! **************************************************************************************************
    1048           2 :    SUBROUTINE get_hfx_ks_matrix(qs_env, matrix_hfx)
    1049             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1050             :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_hfx
    1051             : 
    1052             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'get_hfx_ks_matrix'
    1053             : 
    1054             :       INTEGER                                            :: handle
    1055           2 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_p
    1056             :       TYPE(qs_rho_type), POINTER                         :: rho
    1057             : 
    1058           2 :       CALL timeset(routineN, handle)
    1059             : 
    1060           2 :       CALL get_qs_env(qs_env, rho=rho)
    1061           2 :       CALL qs_rho_get(rho, rho_ao=matrix_p)
    1062             :       CALL tddft_hfx_matrix(matrix_hfx, matrix_p, qs_env, update_energy=.FALSE., &
    1063           2 :                             recalc_integrals=.FALSE.)
    1064             : 
    1065           2 :       CALL timestop(handle)
    1066             : 
    1067           2 :    END SUBROUTINE get_hfx_ks_matrix
    1068             : ! **************************************************************************************************
    1069             : !> \brief Write the atomic coordinates, types, and energies
    1070             : !> \param iounit ...
    1071             : !> \param particle_set ...
    1072             : !> \param atener ...
    1073             : !> \param label ...
    1074             : !> \date    05.06.2023
    1075             : !> \author  JGH
    1076             : !> \version 1.0
    1077             : ! **************************************************************************************************
    1078          16 :    SUBROUTINE write_atener(iounit, particle_set, atener, label)
    1079             : 
    1080             :       INTEGER, INTENT(IN)                                :: iounit
    1081             :       TYPE(particle_type), DIMENSION(:)                  :: particle_set
    1082             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: atener
    1083             :       CHARACTER(LEN=*), INTENT(IN)                       :: label
    1084             : 
    1085             :       INTEGER                                            :: i, natom
    1086             : 
    1087          16 :       IF (iounit > 0) THEN
    1088          16 :          WRITE (UNIT=iounit, FMT="(/,T2,A)") TRIM(label)
    1089             :          WRITE (UNIT=iounit, FMT="(T4,A,T30,A,T42,A,T54,A,T69,A)") &
    1090          16 :             "Atom  Element", "X", "Y", "Z", "Energy[a.u.]"
    1091          16 :          natom = SIZE(atener)
    1092          72 :          DO i = 1, natom
    1093          56 :             WRITE (UNIT=iounit, FMT="(I6,T12,A2,T24,3F12.6,F21.10)") i, &
    1094          56 :                TRIM(ADJUSTL(particle_set(i)%atomic_kind%element_symbol)), &
    1095         296 :                particle_set(i)%r(1:3)*angstrom, atener(i)
    1096             :          END DO
    1097          16 :          WRITE (UNIT=iounit, FMT="(A)") ""
    1098             :       END IF
    1099             : 
    1100          16 :    END SUBROUTINE write_atener
    1101             : 
    1102             : ! **************************************************************************************************
    1103             : !> \brief Write the one component of atomic energies
    1104             : !> \param iounit ...
    1105             : !> \param atener ...
    1106             : !> \param label ...
    1107             : !> \date    18.08.2023
    1108             : !> \author  JGH
    1109             : !> \version 1.0
    1110             : ! **************************************************************************************************
    1111          45 :    SUBROUTINE write_atdet(iounit, atener, label)
    1112             :       INTEGER, INTENT(IN)                                :: iounit
    1113             :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: atener
    1114             :       CHARACTER(LEN=*), INTENT(IN)                       :: label
    1115             : 
    1116             :       INTEGER                                            :: natom
    1117             : 
    1118          45 :       IF (iounit > 0) THEN
    1119          45 :          natom = SIZE(atener)
    1120          45 :          WRITE (UNIT=iounit, FMT="(T2,A)") TRIM(label)
    1121          45 :          WRITE (UNIT=iounit, FMT="(5G16.8)") atener(1:natom)
    1122             :       END IF
    1123             : 
    1124          45 :    END SUBROUTINE write_atdet
    1125             : 
    1126             : END MODULE ed_analysis

Generated by: LCOV version 1.15