LCOV - code coverage report
Current view: top level - src - ec_external.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:262480d) Lines: 265 334 79.3 %
Date: 2024-11-22 07:00:40 Functions: 6 7 85.7 %

          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 Routines for an external energy correction on top of a Kohn-Sham calculation
      10             : !> \par History
      11             : !>       10.2024 created
      12             : !> \author JGH
      13             : ! **************************************************************************************************
      14             : MODULE ec_external
      15             :    USE atomic_kind_types,               ONLY: atomic_kind_type
      16             :    USE cell_types,                      ONLY: cell_type
      17             :    USE core_ppl,                        ONLY: build_core_ppl
      18             :    USE core_ppnl,                       ONLY: build_core_ppnl
      19             :    USE cp_control_types,                ONLY: dft_control_type
      20             :    USE cp_dbcsr_api,                    ONLY: dbcsr_add,&
      21             :                                               dbcsr_copy,&
      22             :                                               dbcsr_create,&
      23             :                                               dbcsr_p_type,&
      24             :                                               dbcsr_set,&
      25             :                                               dbcsr_type,&
      26             :                                               dbcsr_type_symmetric
      27             :    USE cp_dbcsr_cp2k_link,              ONLY: cp_dbcsr_alloc_block_from_nbl
      28             :    USE cp_dbcsr_operations,             ONLY: cp_dbcsr_plus_fm_fm_t,&
      29             :                                               cp_dbcsr_sm_fm_multiply,&
      30             :                                               dbcsr_allocate_matrix_set,&
      31             :                                               dbcsr_deallocate_matrix_set
      32             :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      33             :                                               cp_fm_struct_release,&
      34             :                                               cp_fm_struct_type
      35             :    USE cp_fm_types,                     ONLY: cp_fm_create,&
      36             :                                               cp_fm_get_diag,&
      37             :                                               cp_fm_get_info,&
      38             :                                               cp_fm_maxabsval,&
      39             :                                               cp_fm_release,&
      40             :                                               cp_fm_set_all,&
      41             :                                               cp_fm_to_fm,&
      42             :                                               cp_fm_type
      43             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      44             :                                               cp_logger_get_default_unit_nr,&
      45             :                                               cp_logger_type
      46             :    USE ec_env_types,                    ONLY: energy_correction_type
      47             :    USE kinds,                           ONLY: default_string_length,&
      48             :                                               dp
      49             :    USE mathlib,                         ONLY: det_3x3
      50             :    USE message_passing,                 ONLY: mp_para_env_type
      51             :    USE parallel_gemm_api,               ONLY: parallel_gemm
      52             :    USE particle_types,                  ONLY: particle_type
      53             :    USE physcon,                         ONLY: pascal
      54             :    USE qs_core_energies,                ONLY: calculate_ptrace
      55             :    USE qs_environment_types,            ONLY: get_qs_env,&
      56             :                                               qs_environment_type
      57             :    USE qs_force_types,                  ONLY: qs_force_type
      58             :    USE qs_kind_types,                   ONLY: qs_kind_type
      59             :    USE qs_kinetic,                      ONLY: build_kinetic_matrix
      60             :    USE qs_ks_types,                     ONLY: qs_ks_env_type
      61             :    USE qs_mo_types,                     ONLY: get_mo_set,&
      62             :                                               mo_set_type
      63             :    USE qs_neighbor_list_types,          ONLY: neighbor_list_set_p_type
      64             :    USE qs_overlap,                      ONLY: build_overlap_matrix
      65             :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      66             :                                               qs_rho_type
      67             :    USE virial_methods,                  ONLY: one_third_sum_diag
      68             :    USE virial_types,                    ONLY: virial_type
      69             : #include "./base/base_uses.f90"
      70             : 
      71             :    IMPLICIT NONE
      72             : 
      73             :    PRIVATE
      74             : 
      75             : ! *** Global parameters ***
      76             : 
      77             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ec_external'
      78             : 
      79             :    PUBLIC :: ec_ext_energy
      80             : 
      81             : CONTAINS
      82             : 
      83             : ! **************************************************************************************************
      84             : !> \brief External energy method
      85             : !> \param qs_env ...
      86             : !> \param ec_env ...
      87             : !> \param calculate_forces ...
      88             : !> \par History
      89             : !>       10.2024 created
      90             : !> \author JGH
      91             : ! **************************************************************************************************
      92          12 :    SUBROUTINE ec_ext_energy(qs_env, ec_env, calculate_forces)
      93             :       TYPE(qs_environment_type), POINTER                 :: qs_env
      94             :       TYPE(energy_correction_type), POINTER              :: ec_env
      95             :       LOGICAL, INTENT(IN)                                :: calculate_forces
      96             : 
      97             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'ec_ext_energy'
      98             : 
      99             :       INTEGER                                            :: handle, ispin, nocc, nspins, unit_nr
     100             :       REAL(KIND=dp)                                      :: focc
     101             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct
     102          12 :       TYPE(cp_fm_type), DIMENSION(:), POINTER            :: cpmos, mo_occ, mo_ref
     103             :       TYPE(cp_fm_type), POINTER                          :: mo_coeff
     104             :       TYPE(cp_logger_type), POINTER                      :: logger
     105          12 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_s
     106             :       TYPE(dft_control_type), POINTER                    :: dft_control
     107          12 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos
     108             : 
     109          12 :       CALL timeset(routineN, handle)
     110             : 
     111          12 :       CALL get_qs_env(qs_env, dft_control=dft_control)
     112          12 :       nspins = dft_control%nspins
     113             : 
     114          12 :       logger => cp_get_default_logger()
     115          12 :       IF (logger%para_env%is_source()) THEN
     116           6 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     117             :       ELSE
     118           6 :          unit_nr = -1
     119             :       END IF
     120             : 
     121          12 :       CALL get_qs_env(qs_env, mos=mos)
     122          96 :       ALLOCATE (cpmos(nspins), mo_ref(nspins), mo_occ(nspins))
     123          24 :       DO ispin = 1, nspins
     124          12 :          CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, homo=nocc)
     125          12 :          NULLIFY (fm_struct)
     126             :          CALL cp_fm_struct_create(fm_struct, ncol_global=nocc, &
     127          12 :                                   template_fmstruct=mo_coeff%matrix_struct)
     128          12 :          CALL cp_fm_create(cpmos(ispin), fm_struct)
     129          12 :          CALL cp_fm_set_all(cpmos(ispin), 0.0_dp)
     130          12 :          CALL cp_fm_create(mo_ref(ispin), fm_struct)
     131          12 :          CALL cp_fm_set_all(mo_ref(ispin), 0.0_dp)
     132          12 :          CALL cp_fm_create(mo_occ(ispin), fm_struct)
     133          12 :          CALL cp_fm_to_fm(mo_coeff, mo_occ(ispin), nocc)
     134          36 :          CALL cp_fm_struct_release(fm_struct)
     135             :       END DO
     136             : 
     137          12 :       CALL cp_fm_release(ec_env%mo_occ)
     138          12 :       CALL cp_fm_release(ec_env%cpmos)
     139          12 :       IF (ec_env%debug_external) THEN
     140             :          !
     141          12 :          ec_env%mo_occ => mo_ref
     142          12 :          CALL ec_ext_debug(qs_env, ec_env, calculate_forces, unit_nr)
     143             :          !
     144          12 :          IF (calculate_forces) THEN
     145           4 :             focc = 2.0_dp
     146           4 :             IF (nspins == 1) focc = 4.0_dp
     147           8 :             DO ispin = 1, nspins
     148           4 :                CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, homo=nocc)
     149             :                CALL cp_dbcsr_sm_fm_multiply(ec_env%matrix_h(1, 1)%matrix, ec_env%mo_occ(ispin), &
     150             :                                             cpmos(ispin), nocc, &
     151           8 :                                             alpha=focc, beta=0.0_dp)
     152             :             END DO
     153             :          END IF
     154          12 :          ec_env%cpmos => cpmos
     155             :       ELSE
     156             :          ! get external information
     157             : !deb     CALL ec_ext_interface(qs_env, ec_env%ex, mo_ref, cpmos, calculate_forces, unit_nr)
     158           0 :          ec_env%mo_occ => mo_ref
     159           0 :          ec_env%cpmos => cpmos
     160           0 :          CPABORT("EC EXT NYA")
     161             :       END IF
     162             : 
     163          12 :       IF (calculate_forces) THEN
     164             :          ! check for orbital rotations
     165           4 :          CALL get_qs_env(qs_env, matrix_s=matrix_s)
     166           8 :          DO ispin = 1, nspins
     167             :             CALL align_vectors(ec_env%cpmos(ispin), ec_env%mo_occ(ispin), mo_occ(ispin), &
     168           8 :                                matrix_s(1)%matrix, unit_nr)
     169             :          END DO
     170             :          ! set up matrices for response
     171           4 :          CALL ec_ext_setup(qs_env, ec_env, .TRUE., unit_nr)
     172             :          ! orthogonality force
     173             :          CALL matrix_r_forces(qs_env, ec_env%cpmos, ec_env%mo_occ, &
     174           4 :                               ec_env%matrix_w(1, 1)%matrix, unit_nr)
     175             :       ELSE
     176           8 :          CALL ec_ext_setup(qs_env, ec_env, .FALSE., unit_nr)
     177             :       END IF
     178             : 
     179          12 :       CALL cp_fm_release(mo_occ)
     180             : 
     181          12 :       CALL timestop(handle)
     182             : 
     183          12 :    END SUBROUTINE ec_ext_energy
     184             : 
     185             : ! **************************************************************************************************
     186             : 
     187             : ! **************************************************************************************************
     188             : !> \brief ...
     189             : !> \param qs_env ...
     190             : !> \param ec_env ...
     191             : !> \param calculate_forces ...
     192             : !> \param unit_nr ...
     193             : ! **************************************************************************************************
     194          12 :    SUBROUTINE ec_ext_debug(qs_env, ec_env, calculate_forces, unit_nr)
     195             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     196             :       TYPE(energy_correction_type), POINTER              :: ec_env
     197             :       LOGICAL, INTENT(IN)                                :: calculate_forces
     198             :       INTEGER, INTENT(IN)                                :: unit_nr
     199             : 
     200             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'ec_ext_debug'
     201             : 
     202             :       CHARACTER(LEN=default_string_length)               :: headline
     203             :       INTEGER                                            :: handle, ispin, nocc, nspins
     204             :       TYPE(cp_fm_type), POINTER                          :: mo_coeff
     205          12 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_h, matrix_p, matrix_s
     206             :       TYPE(dft_control_type), POINTER                    :: dft_control
     207          12 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos
     208             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     209          12 :          POINTER                                         :: sab_orb
     210             :       TYPE(qs_rho_type), POINTER                         :: rho
     211             : 
     212          12 :       CALL timeset(routineN, handle)
     213             : 
     214             :       CALL get_qs_env(qs_env=qs_env, &
     215             :                       dft_control=dft_control, &
     216             :                       sab_orb=sab_orb, &
     217             :                       rho=rho, &
     218             :                       matrix_s_kp=matrix_s, &
     219          12 :                       matrix_h_kp=matrix_h)
     220             : 
     221          12 :       nspins = dft_control%nspins
     222          12 :       CALL get_qs_env(qs_env, mos=mos)
     223          24 :       DO ispin = 1, nspins
     224          12 :          CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, homo=nocc)
     225          24 :          CALL cp_fm_to_fm(mo_coeff, ec_env%mo_occ(ispin), nocc)
     226             :       END DO
     227             : 
     228             :       ! Core Hamiltonian matrix
     229          12 :       IF (ASSOCIATED(ec_env%matrix_h)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_h)
     230          12 :       CALL dbcsr_allocate_matrix_set(ec_env%matrix_h, 1, 1)
     231          12 :       headline = "CORE HAMILTONIAN MATRIX"
     232          12 :       ALLOCATE (ec_env%matrix_h(1, 1)%matrix)
     233             :       CALL dbcsr_create(ec_env%matrix_h(1, 1)%matrix, name=TRIM(headline), &
     234          12 :                         template=matrix_h(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
     235          12 :       CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_h(1, 1)%matrix, sab_orb)
     236          12 :       CALL dbcsr_copy(ec_env%matrix_h(1, 1)%matrix, matrix_h(1, 1)%matrix)
     237             : 
     238             :       ! Get density matrix of reference calculation
     239          12 :       CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
     240             :       ! Use Core energy as model energy
     241          12 :       CALL calculate_ptrace(ec_env%matrix_h, matrix_p, ec_env%ex, nspins)
     242             : 
     243          12 :       IF (calculate_forces) THEN
     244             :          ! force of model energy
     245           4 :          CALL ec_debug_force(qs_env, matrix_p, unit_nr)
     246             :       END IF
     247             : 
     248          12 :       CALL timestop(handle)
     249             : 
     250          12 :    END SUBROUTINE ec_ext_debug
     251             : 
     252             : ! **************************************************************************************************
     253             : !> \brief ...
     254             : !> \param qs_env ...
     255             : !> \param matrix_p ...
     256             : !> \param unit_nr ...
     257             : ! **************************************************************************************************
     258           4 :    SUBROUTINE ec_debug_force(qs_env, matrix_p, unit_nr)
     259             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     260             :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_p
     261             :       INTEGER, INTENT(IN)                                :: unit_nr
     262             : 
     263             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'ec_debug_force'
     264             : 
     265             :       INTEGER                                            :: handle, iounit, nder, nimages
     266           4 :       INTEGER, DIMENSION(:, :, :), POINTER               :: cell_to_index
     267             :       LOGICAL                                            :: calculate_forces, debug_forces, &
     268             :                                                             debug_stress, use_virial
     269             :       REAL(KIND=dp)                                      :: eps_ppnl, fconv
     270             :       REAL(KIND=dp), DIMENSION(3)                        :: fodeb
     271             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: stdeb, sttot
     272           4 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     273             :       TYPE(cell_type), POINTER                           :: cell
     274           4 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: scrm
     275             :       TYPE(dft_control_type), POINTER                    :: dft_control
     276             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     277             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     278           4 :          POINTER                                         :: sab_orb, sac_ppl, sap_ppnl
     279           4 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     280           4 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     281           4 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     282             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     283             :       TYPE(virial_type), POINTER                         :: virial
     284             : 
     285           4 :       CALL timeset(routineN, handle)
     286             : 
     287           4 :       debug_forces = .TRUE.
     288           4 :       debug_stress = .TRUE.
     289           4 :       iounit = unit_nr
     290             : 
     291           4 :       calculate_forces = .TRUE.
     292             : 
     293             :       ! no k-points possible
     294           4 :       NULLIFY (cell, dft_control, force, ks_env, para_env, virial)
     295             :       CALL get_qs_env(qs_env=qs_env, &
     296             :                       cell=cell, &
     297             :                       dft_control=dft_control, &
     298             :                       force=force, &
     299             :                       ks_env=ks_env, &
     300             :                       para_env=para_env, &
     301           4 :                       virial=virial)
     302           4 :       nimages = dft_control%nimages
     303           4 :       IF (nimages /= 1) THEN
     304           0 :          CPABORT("K-points not implemented")
     305             :       END IF
     306             : 
     307             :       ! check for virial
     308           4 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     309             : 
     310           4 :       fconv = 1.0E-9_dp*pascal/cell%deth
     311           4 :       IF (debug_stress .AND. use_virial) THEN
     312           0 :          sttot = virial%pv_virial
     313             :       END IF
     314             : 
     315             :       ! check for GAPW/GAPW_XC
     316           4 :       IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
     317           0 :          CPABORT("GAPW not implemented")
     318             :       END IF
     319             : 
     320             :       ! get neighbor lists
     321           4 :       NULLIFY (sab_orb, sac_ppl, sap_ppnl)
     322             :       CALL get_qs_env(qs_env=qs_env, &
     323           4 :                       sab_orb=sab_orb, sac_ppl=sac_ppl, sap_ppnl=sap_ppnl)
     324             : 
     325             :       ! initialize src matrix
     326           4 :       NULLIFY (scrm)
     327           4 :       CALL dbcsr_allocate_matrix_set(scrm, 1, 1)
     328           4 :       ALLOCATE (scrm(1, 1)%matrix)
     329           4 :       CALL dbcsr_create(scrm(1, 1)%matrix, template=matrix_p(1, 1)%matrix)
     330           4 :       CALL cp_dbcsr_alloc_block_from_nbl(scrm(1, 1)%matrix, sab_orb)
     331             : 
     332           4 :       nder = 1
     333           4 :       IF (SIZE(matrix_p, 1) == 2) THEN
     334             :          CALL dbcsr_add(matrix_p(1, 1)%matrix, matrix_p(2, 1)%matrix, &
     335           0 :                         alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
     336             :       END IF
     337             : 
     338             :       ! kinetic energy
     339          16 :       IF (debug_forces) fodeb(1:3) = force(1)%kinetic(1:3, 1)
     340           4 :       IF (debug_stress .AND. use_virial) stdeb = virial%pv_ekinetic
     341             :       CALL build_kinetic_matrix(ks_env, matrixkp_t=scrm, &
     342             :                                 matrix_name="KINETIC ENERGY MATRIX", &
     343             :                                 basis_type="ORB", &
     344             :                                 sab_nl=sab_orb, calculate_forces=.TRUE., &
     345           4 :                                 matrixkp_p=matrix_p)
     346             :       IF (debug_forces) THEN
     347          16 :          fodeb(1:3) = force(1)%kinetic(1:3, 1) - fodeb(1:3)
     348           4 :          CALL para_env%sum(fodeb)
     349           4 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dT    ", fodeb
     350             :       END IF
     351           4 :       IF (debug_stress .AND. use_virial) THEN
     352           0 :          stdeb = fconv*(virial%pv_ekinetic - stdeb)
     353           0 :          CALL para_env%sum(stdeb)
     354           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
     355           0 :             'STRESS| Pout*dT', one_third_sum_diag(stdeb), det_3x3(stdeb)
     356             :       END IF
     357           4 :       IF (SIZE(matrix_p, 1) == 2) THEN
     358             :          CALL dbcsr_add(matrix_p(1, 1)%matrix, matrix_p(2, 1)%matrix, &
     359           0 :                         alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
     360             :       END IF
     361             : 
     362             :       ! compute the ppl contribution to the core hamiltonian
     363           4 :       NULLIFY (atomic_kind_set, particle_set, qs_kind_set)
     364             :       CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, particle_set=particle_set, &
     365           4 :                       atomic_kind_set=atomic_kind_set)
     366             : 
     367           4 :       IF (ASSOCIATED(sac_ppl)) THEN
     368          16 :          IF (calculate_forces .AND. debug_forces) fodeb(1:3) = force(1)%gth_ppl(1:3, 1)
     369           4 :          IF (debug_stress .AND. use_virial) stdeb = virial%pv_ppl
     370             :          CALL build_core_ppl(scrm, matrix_p, force, &
     371             :                              virial, calculate_forces, use_virial, nder, &
     372             :                              qs_kind_set, atomic_kind_set, particle_set, sab_orb, sac_ppl, &
     373           4 :                              nimages, cell_to_index, "ORB")
     374             :          IF (calculate_forces .AND. debug_forces) THEN
     375          16 :             fodeb(1:3) = force(1)%gth_ppl(1:3, 1) - fodeb(1:3)
     376           4 :             CALL para_env%sum(fodeb)
     377           4 :             IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dH_PPL ", fodeb
     378             :          END IF
     379           4 :          IF (debug_stress .AND. use_virial) THEN
     380           0 :             stdeb = fconv*(virial%pv_ppl - stdeb)
     381           0 :             CALL para_env%sum(stdeb)
     382           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
     383           0 :                'STRESS| Pout*dH_PPL', one_third_sum_diag(stdeb), det_3x3(stdeb)
     384             :          END IF
     385             :       END IF
     386             : 
     387             :       ! compute the ppnl contribution to the core hamiltonian ***
     388           4 :       eps_ppnl = dft_control%qs_control%eps_ppnl
     389           4 :       IF (ASSOCIATED(sap_ppnl)) THEN
     390           8 :          IF (calculate_forces .AND. debug_forces) fodeb(1:3) = force(1)%gth_ppnl(1:3, 1)
     391           2 :          IF (debug_stress .AND. use_virial) stdeb = virial%pv_ppnl
     392             :          CALL build_core_ppnl(scrm, matrix_p, force, &
     393             :                               virial, calculate_forces, use_virial, nder, &
     394             :                               qs_kind_set, atomic_kind_set, particle_set, &
     395             :                               sab_orb, sap_ppnl, eps_ppnl, &
     396           2 :                               nimages, cell_to_index, "ORB")
     397             :          IF (calculate_forces .AND. debug_forces) THEN
     398           8 :             fodeb(1:3) = force(1)%gth_ppnl(1:3, 1) - fodeb(1:3)
     399           2 :             CALL para_env%sum(fodeb)
     400           2 :             IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dH_PPNL", fodeb
     401             :          END IF
     402           2 :          IF (debug_stress .AND. use_virial) THEN
     403           0 :             stdeb = fconv*(virial%pv_ppnl - stdeb)
     404           0 :             CALL para_env%sum(stdeb)
     405           0 :             IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
     406           0 :                'STRESS| Pout*dH_PPNL', one_third_sum_diag(stdeb), det_3x3(stdeb)
     407             :          END IF
     408             :       END IF
     409             : 
     410           4 :       IF (debug_stress .AND. use_virial) THEN
     411           0 :          stdeb = fconv*(virial%pv_virial - sttot)
     412           0 :          CALL para_env%sum(stdeb)
     413           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
     414           0 :             'STRESS| Stress Pout*dHcore   ', one_third_sum_diag(stdeb), det_3x3(stdeb)
     415           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") ' '
     416             :       END IF
     417             : 
     418             :       ! delete scr matrix
     419           4 :       CALL dbcsr_deallocate_matrix_set(scrm)
     420             : 
     421           4 :       CALL timestop(handle)
     422             : 
     423           4 :    END SUBROUTINE ec_debug_force
     424             : 
     425             : ! **************************************************************************************************
     426             : 
     427             : ! **************************************************************************************************
     428             : !> \brief ...
     429             : !> \param qs_env ...
     430             : !> \param ec_env ...
     431             : !> \param calc_forces ...
     432             : !> \param unit_nr ...
     433             : ! **************************************************************************************************
     434          12 :    SUBROUTINE ec_ext_setup(qs_env, ec_env, calc_forces, unit_nr)
     435             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     436             :       TYPE(energy_correction_type), POINTER              :: ec_env
     437             :       LOGICAL, INTENT(IN)                                :: calc_forces
     438             :       INTEGER, INTENT(IN)                                :: unit_nr
     439             : 
     440             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'ec_ext_setup'
     441             : 
     442             :       CHARACTER(LEN=default_string_length)               :: headline
     443             :       INTEGER                                            :: handle, ispin, nao, nocc, nspins
     444             :       REAL(KIND=dp)                                      :: a_max, c_max
     445             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct, mat_struct
     446             :       TYPE(cp_fm_type)                                   :: emat, ksmo, smo
     447          12 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_h, matrix_ks, matrix_p, matrix_s
     448             :       TYPE(dft_control_type), POINTER                    :: dft_control
     449             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     450          12 :          POINTER                                         :: sab_orb
     451             :       TYPE(qs_rho_type), POINTER                         :: rho
     452             : 
     453          12 :       CALL timeset(routineN, handle)
     454             : 
     455             :       CALL get_qs_env(qs_env=qs_env, &
     456             :                       dft_control=dft_control, &
     457             :                       sab_orb=sab_orb, &
     458             :                       rho=rho, &
     459             :                       matrix_s_kp=matrix_s, &
     460             :                       matrix_ks_kp=matrix_ks, &
     461          12 :                       matrix_h_kp=matrix_h)
     462             : 
     463          12 :       nspins = dft_control%nspins
     464             : 
     465             :       ! KS Hamiltonian matrix
     466          12 :       IF (ASSOCIATED(ec_env%matrix_ks)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_ks)
     467          12 :       CALL dbcsr_allocate_matrix_set(ec_env%matrix_ks, nspins, 1)
     468          12 :       headline = "HAMILTONIAN MATRIX"
     469          24 :       DO ispin = 1, nspins
     470          12 :          ALLOCATE (ec_env%matrix_ks(ispin, 1)%matrix)
     471             :          CALL dbcsr_create(ec_env%matrix_ks(ispin, 1)%matrix, name=TRIM(headline), &
     472          12 :                            template=matrix_ks(ispin, 1)%matrix, matrix_type=dbcsr_type_symmetric)
     473          12 :          CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_ks(ispin, 1)%matrix, sab_orb)
     474          24 :          CALL dbcsr_copy(ec_env%matrix_ks(ispin, 1)%matrix, matrix_ks(ispin, 1)%matrix)
     475             :       END DO
     476             : 
     477             :       ! Overlap matrix
     478          12 :       IF (ASSOCIATED(ec_env%matrix_s)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_s)
     479          12 :       CALL dbcsr_allocate_matrix_set(ec_env%matrix_s, 1, 1)
     480          12 :       headline = "OVERLAP MATRIX"
     481          12 :       ALLOCATE (ec_env%matrix_s(1, 1)%matrix)
     482             :       CALL dbcsr_create(ec_env%matrix_s(1, 1)%matrix, name=TRIM(headline), &
     483          12 :                         template=matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
     484          12 :       CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_s(1, 1)%matrix, sab_orb)
     485          12 :       CALL dbcsr_copy(ec_env%matrix_s(1, 1)%matrix, matrix_s(1, 1)%matrix)
     486             : 
     487             :       ! density matrix
     488             :       ! Get density matrix of reference calculation
     489          12 :       CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
     490          12 :       IF (ASSOCIATED(ec_env%matrix_p)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_p)
     491          12 :       CALL dbcsr_allocate_matrix_set(ec_env%matrix_p, nspins, 1)
     492          12 :       headline = "DENSITY MATRIX"
     493          24 :       DO ispin = 1, nspins
     494          12 :          ALLOCATE (ec_env%matrix_p(ispin, 1)%matrix)
     495             :          CALL dbcsr_create(ec_env%matrix_p(ispin, 1)%matrix, name=TRIM(headline), &
     496          12 :                            template=matrix_p(ispin, 1)%matrix, matrix_type=dbcsr_type_symmetric)
     497          12 :          CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_p(ispin, 1)%matrix, sab_orb)
     498          24 :          CALL dbcsr_copy(ec_env%matrix_p(ispin, 1)%matrix, matrix_p(ispin, 1)%matrix)
     499             :       END DO
     500             : 
     501          12 :       IF (calc_forces) THEN
     502             :          ! energy weighted density matrix
     503             :          ! for security, we recalculate W here (stored in qs_env)
     504           4 :          IF (ASSOCIATED(ec_env%matrix_w)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_w)
     505           4 :          CALL dbcsr_allocate_matrix_set(ec_env%matrix_w, nspins, 1)
     506           4 :          headline = "ENERGY WEIGHTED DENSITY MATRIX"
     507           8 :          DO ispin = 1, nspins
     508           4 :             ALLOCATE (ec_env%matrix_w(ispin, 1)%matrix)
     509             :             CALL dbcsr_create(ec_env%matrix_w(ispin, 1)%matrix, name=TRIM(headline), &
     510           4 :                               template=matrix_p(ispin, 1)%matrix, matrix_type=dbcsr_type_symmetric)
     511           4 :             CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_w(ispin, 1)%matrix, sab_orb)
     512           8 :             CALL dbcsr_set(ec_env%matrix_w(ispin, 1)%matrix, 0.0_dp)
     513             :          END DO
     514             : 
     515             :          ! hz matrix
     516           4 :          IF (ASSOCIATED(ec_env%matrix_hz)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_hz)
     517           4 :          CALL dbcsr_allocate_matrix_set(ec_env%matrix_hz, nspins)
     518           4 :          headline = "Hz MATRIX"
     519           8 :          DO ispin = 1, nspins
     520           4 :             ALLOCATE (ec_env%matrix_hz(ispin)%matrix)
     521             :             CALL dbcsr_create(ec_env%matrix_hz(ispin)%matrix, name=TRIM(headline), &
     522           4 :                               template=matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
     523           4 :             CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_hz(ispin)%matrix, sab_orb)
     524           8 :             CALL dbcsr_set(ec_env%matrix_hz(ispin)%matrix, 0.0_dp)
     525             :          END DO
     526             : 
     527             :          ! Test for consistency of orbitals and KS matrix
     528           8 :          DO ispin = 1, nspins
     529           4 :             mat_struct => ec_env%mo_occ(ispin)%matrix_struct
     530           4 :             CALL cp_fm_create(ksmo, mat_struct)
     531           4 :             CALL cp_fm_get_info(ksmo, nrow_global=nao, ncol_global=nocc)
     532             :             CALL cp_dbcsr_sm_fm_multiply(ec_env%matrix_ks(ispin, 1)%matrix, ec_env%mo_occ(ispin), &
     533           4 :                                          ksmo, nocc, alpha=1.0_dp, beta=0.0_dp)
     534           4 :             CALL cp_fm_create(smo, mat_struct)
     535             :             CALL cp_dbcsr_sm_fm_multiply(ec_env%matrix_s(1, 1)%matrix, ec_env%mo_occ(ispin), &
     536           4 :                                          smo, nocc, alpha=1.0_dp, beta=0.0_dp)
     537             :             CALL cp_fm_struct_create(fm_struct, ncol_global=nocc, nrow_global=nocc, &
     538           4 :                                      template_fmstruct=mat_struct)
     539           4 :             CALL cp_fm_create(emat, fm_struct)
     540           4 :             CALL parallel_gemm('T', 'N', nocc, nocc, nao, 1.0_dp, ec_env%mo_occ(ispin), ksmo, 0.0_dp, emat)
     541           4 :             CALL parallel_gemm('N', 'N', nao, nocc, nocc, -1.0_dp, smo, emat, 1.0_dp, ksmo)
     542           4 :             CALL cp_fm_maxabsval(ksmo, a_max)
     543           4 :             CALL cp_fm_struct_release(fm_struct)
     544           4 :             CALL cp_fm_release(smo)
     545           4 :             CALL cp_fm_release(ksmo)
     546           4 :             CALL cp_fm_release(emat)
     547           4 :             CALL cp_fm_maxabsval(ec_env%mo_occ(ispin), c_max)
     548          24 :             IF (unit_nr > 0) THEN
     549           2 :                WRITE (unit_nr, "(T3,A,T50,I2,T61,F20.12)") "External:: Max value of MO coeficients", ispin, c_max
     550           2 :                WRITE (unit_nr, "(T3,A,T50,I2,T61,F20.12)") "External:: Max value of MO gradients", ispin, a_max
     551             :             END IF
     552             :          END DO
     553             :       END IF
     554             : 
     555          12 :       CALL timestop(handle)
     556             : 
     557          12 :    END SUBROUTINE ec_ext_setup
     558             : 
     559             : ! **************************************************************************************************
     560             : !> \brief ...
     561             : !> \param cpmos ...
     562             : !> \param mo_ref ...
     563             : !> \param mo_occ ...
     564             : !> \param matrix_s ...
     565             : !> \param unit_nr ...
     566             : ! **************************************************************************************************
     567           4 :    SUBROUTINE align_vectors(cpmos, mo_ref, mo_occ, matrix_s, unit_nr)
     568             :       TYPE(cp_fm_type), INTENT(IN)                       :: cpmos, mo_ref, mo_occ
     569             :       TYPE(dbcsr_type), POINTER                          :: matrix_s
     570             :       INTEGER, INTENT(IN)                                :: unit_nr
     571             : 
     572             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'align_vectors'
     573             : 
     574             :       INTEGER                                            :: handle, i, nao, nocc, scg
     575             :       REAL(KIND=dp)                                      :: a_max
     576             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: diag
     577             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct, mat_struct
     578             :       TYPE(cp_fm_type)                                   :: emat, smo
     579             : 
     580           4 :       CALL timeset(routineN, handle)
     581             : 
     582           4 :       mat_struct => cpmos%matrix_struct
     583           4 :       CALL cp_fm_create(smo, mat_struct)
     584           4 :       CALL cp_fm_get_info(smo, nrow_global=nao, ncol_global=nocc)
     585           4 :       CALL cp_dbcsr_sm_fm_multiply(matrix_s, mo_occ, smo, nocc, alpha=1.0_dp, beta=0.0_dp)
     586             :       CALL cp_fm_struct_create(fm_struct, ncol_global=nocc, nrow_global=nocc, &
     587           4 :                                template_fmstruct=mat_struct)
     588           4 :       CALL cp_fm_create(emat, fm_struct)
     589           4 :       CALL parallel_gemm('T', 'N', nocc, nocc, nao, 1.0_dp, mo_ref, smo, 0.0_dp, emat)
     590           4 :       CALL parallel_gemm('N', 'N', nao, nocc, nocc, 1.0_dp, cpmos, emat, 0.0_dp, smo)
     591           4 :       CALL cp_fm_to_fm(smo, cpmos)
     592           4 :       CALL cp_fm_to_fm(mo_occ, mo_ref)
     593             :       !
     594          12 :       ALLOCATE (diag(nocc))
     595           4 :       CALL cp_fm_get_diag(emat, diag)
     596          14 :       a_max = nocc - SUM(diag)
     597           4 :       scg = 0
     598          14 :       DO i = 1, nocc
     599          14 :          IF (ABS(diag(i) + 1.0_dp) < 0.001) scg = scg + 1
     600             :       END DO
     601           4 :       IF (unit_nr > 0) THEN
     602           2 :          WRITE (unit_nr, "(T3,A,T61,F20.8)") "External:: Orbital rotation index", a_max
     603           2 :          WRITE (unit_nr, "(T3,A,T71,I10)") "External:: Number of orbital phase changes", scg
     604             :       END IF
     605             : 
     606           4 :       DEALLOCATE (diag)
     607           4 :       CALL cp_fm_struct_release(fm_struct)
     608           4 :       CALL cp_fm_release(smo)
     609           4 :       CALL cp_fm_release(emat)
     610             : 
     611           4 :       CALL timestop(handle)
     612             : 
     613           8 :    END SUBROUTINE align_vectors
     614             : 
     615             : ! **************************************************************************************************
     616             : !> \brief ...
     617             : !> \param qs_env ...
     618             : !> \param matrix_w ...
     619             : !> \param unit_nr ...
     620             : ! **************************************************************************************************
     621           0 :    SUBROUTINE matrix_w_forces(qs_env, matrix_w, unit_nr)
     622             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     623             :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_w
     624             :       INTEGER, INTENT(IN)                                :: unit_nr
     625             : 
     626             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'matrix_w_forces'
     627             : 
     628             :       INTEGER                                            :: handle, iounit, nder, nimages
     629             :       LOGICAL                                            :: debug_forces, debug_stress, use_virial
     630             :       REAL(KIND=dp)                                      :: fconv
     631             :       REAL(KIND=dp), DIMENSION(3)                        :: fodeb
     632             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: stdeb, sttot
     633             :       TYPE(cell_type), POINTER                           :: cell
     634           0 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: scrm
     635             :       TYPE(dft_control_type), POINTER                    :: dft_control
     636             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     637             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     638           0 :          POINTER                                         :: sab_orb
     639           0 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     640             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     641             :       TYPE(virial_type), POINTER                         :: virial
     642             : 
     643           0 :       CALL timeset(routineN, handle)
     644             : 
     645           0 :       debug_forces = .TRUE.
     646           0 :       debug_stress = .TRUE.
     647             : 
     648           0 :       iounit = unit_nr
     649             : 
     650             :       ! no k-points possible
     651             :       CALL get_qs_env(qs_env=qs_env, &
     652             :                       cell=cell, &
     653             :                       dft_control=dft_control, &
     654             :                       force=force, &
     655             :                       ks_env=ks_env, &
     656             :                       sab_orb=sab_orb, &
     657             :                       para_env=para_env, &
     658           0 :                       virial=virial)
     659           0 :       nimages = dft_control%nimages
     660           0 :       IF (nimages /= 1) THEN
     661           0 :          CPABORT("K-points not implemented")
     662             :       END IF
     663             : 
     664             :       ! check for virial
     665           0 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     666             : 
     667           0 :       fconv = 1.0E-9_dp*pascal/cell%deth
     668           0 :       IF (debug_stress .AND. use_virial) THEN
     669           0 :          sttot = virial%pv_virial
     670             :       END IF
     671             : 
     672             :       ! initialize src matrix
     673           0 :       NULLIFY (scrm)
     674           0 :       CALL dbcsr_allocate_matrix_set(scrm, 1, 1)
     675           0 :       ALLOCATE (scrm(1, 1)%matrix)
     676           0 :       CALL dbcsr_create(scrm(1, 1)%matrix, template=matrix_w(1, 1)%matrix)
     677           0 :       CALL cp_dbcsr_alloc_block_from_nbl(scrm(1, 1)%matrix, sab_orb)
     678             : 
     679           0 :       nder = 1
     680           0 :       IF (SIZE(matrix_w, 1) == 2) THEN
     681             :          CALL dbcsr_add(matrix_w(1, 1)%matrix, matrix_w(2, 1)%matrix, &
     682           0 :                         alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
     683             :       END IF
     684             : 
     685             :       ! Overlap and kinetic energy matrices
     686           0 :       IF (debug_forces) fodeb(1:3) = force(1)%overlap(1:3, 1)
     687           0 :       IF (debug_stress .AND. use_virial) stdeb = virial%pv_overlap
     688             :       CALL build_overlap_matrix(ks_env, matrixkp_s=scrm, &
     689             :                                 matrix_name="OVERLAP MATRIX", &
     690             :                                 basis_type_a="ORB", &
     691             :                                 basis_type_b="ORB", &
     692             :                                 sab_nl=sab_orb, calculate_forces=.TRUE., &
     693           0 :                                 matrixkp_p=matrix_w)
     694             : 
     695             :       IF (debug_forces) THEN
     696           0 :          fodeb(1:3) = force(1)%overlap(1:3, 1) - fodeb(1:3)
     697           0 :          CALL para_env%sum(fodeb)
     698           0 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Wout*dS    ", fodeb
     699             :       END IF
     700           0 :       IF (debug_stress .AND. use_virial) THEN
     701           0 :          stdeb = fconv*(virial%pv_overlap - stdeb)
     702           0 :          CALL para_env%sum(stdeb)
     703           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
     704           0 :             'STRESS| Wout*dS', one_third_sum_diag(stdeb), det_3x3(stdeb)
     705             :       END IF
     706           0 :       IF (SIZE(matrix_w, 1) == 2) THEN
     707             :          CALL dbcsr_add(matrix_w(1, 1)%matrix, matrix_w(2, 1)%matrix, &
     708           0 :                         alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
     709             :       END IF
     710             : 
     711             :       ! delete scrm matrix
     712           0 :       CALL dbcsr_deallocate_matrix_set(scrm)
     713             : 
     714           0 :       CALL timestop(handle)
     715             : 
     716           0 :    END SUBROUTINE matrix_w_forces
     717             : 
     718             : ! **************************************************************************************************
     719             : !> \brief ...
     720             : !> \param qs_env ...
     721             : !> \param cpmos ...
     722             : !> \param mo_occ ...
     723             : !> \param matrix_r ...
     724             : !> \param unit_nr ...
     725             : ! **************************************************************************************************
     726           4 :    SUBROUTINE matrix_r_forces(qs_env, cpmos, mo_occ, matrix_r, unit_nr)
     727             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     728             :       TYPE(cp_fm_type), DIMENSION(:), POINTER            :: cpmos, mo_occ
     729             :       TYPE(dbcsr_type), POINTER                          :: matrix_r
     730             :       INTEGER, INTENT(IN)                                :: unit_nr
     731             : 
     732             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'matrix_r_forces'
     733             : 
     734             :       INTEGER                                            :: handle, iounit, ispin, nao, nocc, nspins
     735             :       LOGICAL                                            :: debug_forces, debug_stress, use_virial
     736             :       REAL(KIND=dp)                                      :: fconv, focc
     737             :       REAL(KIND=dp), DIMENSION(3)                        :: fodeb
     738             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: stdeb
     739             :       TYPE(cell_type), POINTER                           :: cell
     740             :       TYPE(cp_fm_struct_type), POINTER                   :: fm_struct, mat_struct
     741             :       TYPE(cp_fm_type)                                   :: chcmat, rcvec
     742           4 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: scrm
     743             :       TYPE(dft_control_type), POINTER                    :: dft_control
     744             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     745             :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     746           4 :          POINTER                                         :: sab_orb
     747           4 :       TYPE(qs_force_type), DIMENSION(:), POINTER         :: force
     748             :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     749             :       TYPE(virial_type), POINTER                         :: virial
     750             : 
     751           4 :       CALL timeset(routineN, handle)
     752             : 
     753           4 :       debug_forces = .TRUE.
     754           4 :       debug_stress = .TRUE.
     755           4 :       iounit = unit_nr
     756             : 
     757           4 :       nspins = SIZE(mo_occ)
     758           4 :       focc = 1.0_dp
     759           4 :       IF (nspins == 1) focc = 2.0_dp
     760           4 :       focc = 0.25_dp*focc
     761             : 
     762           4 :       CALL dbcsr_set(matrix_r, 0.0_dp)
     763           8 :       DO ispin = 1, nspins
     764           4 :          CALL cp_fm_get_info(cpmos(ispin), matrix_struct=fm_struct, nrow_global=nao, ncol_global=nocc)
     765           4 :          CALL cp_fm_create(rcvec, fm_struct)
     766           4 :          CALL cp_fm_struct_create(mat_struct, nrow_global=nocc, ncol_global=nocc, template_fmstruct=fm_struct)
     767           4 :          CALL cp_fm_create(chcmat, mat_struct)
     768           4 :          CALL parallel_gemm("T", "N", nocc, nocc, nao, 1.0_dp, mo_occ(ispin), cpmos(ispin), 0.0_dp, chcmat)
     769           4 :          CALL parallel_gemm("N", "N", nao, nocc, nocc, 1.0_dp, mo_occ(ispin), chcmat, 0.0_dp, rcvec)
     770           4 :          CALL cp_dbcsr_plus_fm_fm_t(matrix_r, matrix_v=rcvec, matrix_g=mo_occ(ispin), ncol=nocc, alpha=focc)
     771           4 :          CALL cp_fm_struct_release(mat_struct)
     772           4 :          CALL cp_fm_release(rcvec)
     773          16 :          CALL cp_fm_release(chcmat)
     774             :       END DO
     775             : 
     776             :       CALL get_qs_env(qs_env=qs_env, &
     777             :                       cell=cell, &
     778             :                       dft_control=dft_control, &
     779             :                       force=force, &
     780             :                       ks_env=ks_env, &
     781             :                       sab_orb=sab_orb, &
     782             :                       para_env=para_env, &
     783           4 :                       virial=virial)
     784             :       ! check for virial
     785           4 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     786           4 :       fconv = 1.0E-9_dp*pascal/cell%deth
     787             : 
     788          16 :       IF (debug_forces) fodeb(1:3) = force(1)%overlap(1:3, 1)
     789           4 :       IF (debug_stress .AND. use_virial) stdeb = virial%pv_overlap
     790           4 :       NULLIFY (scrm)
     791             :       CALL build_overlap_matrix(ks_env, matrix_s=scrm, &
     792             :                                 matrix_name="OVERLAP MATRIX", &
     793             :                                 basis_type_a="ORB", basis_type_b="ORB", &
     794             :                                 sab_nl=sab_orb, calculate_forces=.TRUE., &
     795           4 :                                 matrix_p=matrix_r)
     796             :       IF (debug_forces) THEN
     797          16 :          fodeb(1:3) = force(1)%overlap(1:3, 1) - fodeb(1:3)
     798           4 :          CALL para_env%sum(fodeb)
     799           4 :          IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Wz*dS ", fodeb
     800             :       END IF
     801           4 :       IF (debug_stress .AND. use_virial) THEN
     802           0 :          stdeb = fconv*(virial%pv_overlap - stdeb)
     803           0 :          CALL para_env%sum(stdeb)
     804           0 :          IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
     805           0 :             'STRESS| Wz   ', one_third_sum_diag(stdeb), det_3x3(stdeb)
     806             :       END IF
     807           4 :       CALL dbcsr_deallocate_matrix_set(scrm)
     808             : 
     809           4 :       CALL timestop(handle)
     810             : 
     811           4 :    END SUBROUTINE matrix_r_forces
     812             : 
     813             : END MODULE ec_external

Generated by: LCOV version 1.15