LCOV - code coverage report
Current view: top level - src - hfx_admm_utils.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:9ccafda) Lines: 85.5 % 1056 903
Test Date: 2026-10-15 00:55:44 Functions: 100.0 % 11 11

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Utilities for hfx and admm methods
      10              : !>
      11              : !>
      12              : !> \par History
      13              : !>     refactoring 03-2011 [MI]
      14              : !>     Made GAPW compatible 12.2019 (A. Bussy)
      15              : !> \author MI
      16              : ! **************************************************************************************************
      17              : MODULE hfx_admm_utils
      18              :    USE admm_dm_types,                   ONLY: admm_dm_create
      19              :    USE admm_methods,                    ONLY: kpoint_calc_admm_matrices,&
      20              :                                               scale_dm
      21              :    USE admm_types,                      ONLY: admm_env_create,&
      22              :                                               admm_gapw_r3d_rs_type,&
      23              :                                               admm_type,&
      24              :                                               get_admm_env,&
      25              :                                               set_admm_env
      26              :    USE atomic_kind_types,               ONLY: atomic_kind_type
      27              :    USE basis_set_container_types,       ONLY: add_basis_set_to_container
      28              :    USE basis_set_types,                 ONLY: copy_gto_basis_set,&
      29              :                                               get_gto_basis_set,&
      30              :                                               gto_basis_set_type
      31              :    USE cell_types,                      ONLY: cell_type,&
      32              :                                               plane_distance
      33              :    USE cp_blacs_env,                    ONLY: cp_blacs_env_type
      34              :    USE cp_control_types,                ONLY: admm_control_type,&
      35              :                                               dft_control_type
      36              :    USE cp_dbcsr_api,                    ONLY: dbcsr_add,&
      37              :                                               dbcsr_copy,&
      38              :                                               dbcsr_create,&
      39              :                                               dbcsr_init_p,&
      40              :                                               dbcsr_p_type,&
      41              :                                               dbcsr_set,&
      42              :                                               dbcsr_type,&
      43              :                                               dbcsr_type_no_symmetry
      44              :    USE cp_dbcsr_cp2k_link,              ONLY: cp_dbcsr_alloc_block_from_nbl
      45              :    USE cp_dbcsr_operations,             ONLY: cp_dbcsr_m_by_n_from_row_template,&
      46              :                                               dbcsr_allocate_matrix_set
      47              :    USE cp_fm_pool_types,                ONLY: cp_fm_pool_p_type
      48              :    USE cp_fm_struct,                    ONLY: cp_fm_struct_create,&
      49              :                                               cp_fm_struct_release,&
      50              :                                               cp_fm_struct_type
      51              :    USE cp_fm_types,                     ONLY: cp_fm_create,&
      52              :                                               cp_fm_get_info,&
      53              :                                               cp_fm_type
      54              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      55              :                                               cp_logger_get_default_io_unit,&
      56              :                                               cp_logger_type,&
      57              :                                               cp_to_string
      58              :    USE distribution_1d_types,           ONLY: distribution_1d_type
      59              :    USE distribution_2d_types,           ONLY: distribution_2d_type
      60              :    USE external_potential_types,        ONLY: copy_potential
      61              :    USE hfx_derivatives,                 ONLY: derivatives_four_center
      62              :    USE hfx_energy_potential,            ONLY: integrate_four_center
      63              :    USE hfx_pw_methods,                  ONLY: pw_hfx
      64              :    USE hfx_ri,                          ONLY: hfx_ri_update_forces,&
      65              :                                               hfx_ri_update_ks
      66              :    USE hfx_ri_kp,                       ONLY: hfx_ri_update_forces_kp,&
      67              :                                               hfx_ri_update_ks_kp
      68              :    USE hfx_types,                       ONLY: hfx_type
      69              :    USE input_constants,                 ONLY: &
      70              :         do_admm_aux_exch_func_bee, do_admm_aux_exch_func_bee_libxc, do_admm_aux_exch_func_default, &
      71              :         do_admm_aux_exch_func_default_libxc, do_admm_aux_exch_func_none, &
      72              :         do_admm_aux_exch_func_opt, do_admm_aux_exch_func_opt_libxc, do_admm_aux_exch_func_pbex, &
      73              :         do_admm_aux_exch_func_pbex_libxc, do_admm_aux_exch_func_sx_libxc, &
      74              :         do_admm_basis_projection, do_admm_charge_constrained_projection, do_admm_purify_none, &
      75              :         do_potential_coulomb, do_potential_id, do_potential_long, do_potential_mix_cl, &
      76              :         do_potential_mix_cl_trunc, do_potential_short, do_potential_truncated, &
      77              :         xc_funct_no_shortcut, xc_none
      78              :    USE input_section_types,             ONLY: section_vals_duplicate,&
      79              :                                               section_vals_get,&
      80              :                                               section_vals_get_subs_vals,&
      81              :                                               section_vals_get_subs_vals2,&
      82              :                                               section_vals_remove_values,&
      83              :                                               section_vals_type,&
      84              :                                               section_vals_val_get,&
      85              :                                               section_vals_val_set
      86              :    USE kinds,                           ONLY: dp
      87              :    USE kpoint_methods,                  ONLY: kpoint_initialize_mos
      88              :    USE kpoint_transitional,             ONLY: kpoint_transitional_release,&
      89              :                                               set_2d_pointer
      90              :    USE kpoint_types,                    ONLY: get_kpoint_info,&
      91              :                                               kpoint_type
      92              :    USE libint_2c_3c,                    ONLY: cutoff_screen_factor
      93              :    USE mathlib,                         ONLY: erfc_cutoff
      94              :    USE message_passing,                 ONLY: mp_para_env_type
      95              :    USE molecule_types,                  ONLY: molecule_type
      96              :    USE particle_types,                  ONLY: particle_type
      97              :    USE paw_proj_set_types,              ONLY: get_paw_proj_set,&
      98              :                                               paw_proj_set_type
      99              :    USE pw_env_types,                    ONLY: pw_env_get,&
     100              :                                               pw_env_type
     101              :    USE pw_poisson_types,                ONLY: pw_poisson_type
     102              :    USE pw_pool_types,                   ONLY: pw_pool_type
     103              :    USE pw_types,                        ONLY: pw_r3d_rs_type
     104              :    USE qs_energy_types,                 ONLY: qs_energy_type
     105              :    USE qs_environment_types,            ONLY: get_qs_env,&
     106              :                                               qs_environment_type,&
     107              :                                               set_qs_env
     108              :    USE qs_interactions,                 ONLY: init_interaction_radii
     109              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
     110              :                                               get_qs_kind_set,&
     111              :                                               init_gapw_basis_set,&
     112              :                                               init_gapw_nlcc,&
     113              :                                               qs_kind_type
     114              :    USE qs_ks_types,                     ONLY: qs_ks_env_type
     115              :    USE qs_local_rho_types,              ONLY: local_rho_set_create
     116              :    USE qs_matrix_pools,                 ONLY: mpools_get
     117              :    USE qs_mo_types,                     ONLY: allocate_mo_set,&
     118              :                                               get_mo_set,&
     119              :                                               init_mo_set,&
     120              :                                               mo_set_type
     121              :    USE qs_neighbor_list_types,          ONLY: neighbor_list_set_p_type,&
     122              :                                               release_neighbor_list_sets
     123              :    USE qs_neighbor_lists,               ONLY: atom2d_build,&
     124              :                                               atom2d_cleanup,&
     125              :                                               build_neighbor_lists,&
     126              :                                               local_atoms_type,&
     127              :                                               pair_radius_setup,&
     128              :                                               write_neighbor_lists
     129              :    USE qs_oce_methods,                  ONLY: build_oce_matrices
     130              :    USE qs_oce_types,                    ONLY: allocate_oce_set,&
     131              :                                               create_oce_set
     132              :    USE qs_overlap,                      ONLY: build_overlap_matrix
     133              :    USE qs_rho_atom_methods,             ONLY: init_rho_atom
     134              :    USE qs_rho_methods,                  ONLY: qs_rho_rebuild
     135              :    USE qs_rho_types,                    ONLY: qs_rho_create,&
     136              :                                               qs_rho_get,&
     137              :                                               qs_rho_type
     138              :    USE rt_propagation_types,            ONLY: rt_prop_type
     139              :    USE task_list_methods,               ONLY: generate_qs_task_list
     140              :    USE task_list_types,                 ONLY: allocate_task_list,&
     141              :                                               deallocate_task_list
     142              :    USE virial_types,                    ONLY: virial_type
     143              :    USE xc_adiabatic_utils,              ONLY: rescale_xc_potential
     144              : #include "./base/base_uses.f90"
     145              : 
     146              :    IMPLICIT NONE
     147              : 
     148              :    PRIVATE
     149              : 
     150              :    ! *** Public subroutines ***
     151              :    PUBLIC :: hfx_ks_matrix, hfx_admm_init, aux_admm_init, create_admm_xc_section, &
     152              :              tddft_hfx_matrix, hfx_ks_matrix_kp
     153              : 
     154              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'hfx_admm_utils'
     155              : 
     156              : CONTAINS
     157              : 
     158              : ! **************************************************************************************************
     159              : !> \brief ...
     160              : !> \param qs_env ...
     161              : !> \param calculate_forces ...
     162              : !> \param ext_xc_section ...
     163              : ! **************************************************************************************************
     164        27276 :    SUBROUTINE hfx_admm_init(qs_env, calculate_forces, ext_xc_section)
     165              : 
     166              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     167              :       LOGICAL, INTENT(IN), OPTIONAL                      :: calculate_forces
     168              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: ext_xc_section
     169              : 
     170              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'hfx_admm_init'
     171              : 
     172              :       INTEGER                                            :: handle, ispin, n_rep_hf, nao_aux_fit, &
     173              :                                                             natoms, nelectron, nmo
     174              :       LOGICAL                                            :: calc_forces, do_kpoints, &
     175              :                                                             s_mstruct_changed, use_virial
     176              :       REAL(dp)                                           :: maxocc
     177              :       TYPE(admm_type), POINTER                           :: admm_env
     178              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     179              :       TYPE(cp_fm_struct_type), POINTER                   :: aux_fit_fm_struct
     180              :       TYPE(cp_fm_type), POINTER                          :: mo_coeff_aux_fit
     181        13638 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_s_aux_fit_kp
     182              :       TYPE(dbcsr_type), POINTER                          :: mo_coeff_b
     183              :       TYPE(dft_control_type), POINTER                    :: dft_control
     184        13638 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos, mos_aux_fit
     185              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     186        13638 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     187              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     188              :       TYPE(section_vals_type), POINTER                   :: hfx_sections, input, xc_section
     189              :       TYPE(virial_type), POINTER                         :: virial
     190              : 
     191        13638 :       CALL timeset(routineN, handle)
     192              : 
     193        13638 :       NULLIFY (admm_env, hfx_sections, mos, mos_aux_fit, para_env, virial, &
     194        13638 :                mo_coeff_aux_fit, xc_section, ks_env, dft_control, input, &
     195        13638 :                qs_kind_set, mo_coeff_b, aux_fit_fm_struct, blacs_env)
     196              : 
     197              :       CALL get_qs_env(qs_env, &
     198              :                       mos=mos, &
     199              :                       admm_env=admm_env, &
     200              :                       para_env=para_env, &
     201              :                       blacs_env=blacs_env, &
     202              :                       s_mstruct_changed=s_mstruct_changed, &
     203              :                       ks_env=ks_env, &
     204              :                       dft_control=dft_control, &
     205              :                       input=input, &
     206              :                       virial=virial, &
     207        13638 :                       do_kpoints=do_kpoints)
     208              : 
     209        13638 :       calc_forces = .FALSE.
     210        13638 :       IF (PRESENT(calculate_forces)) calc_forces = .TRUE.
     211              : 
     212        13638 :       hfx_sections => section_vals_get_subs_vals(input, "DFT%XC%HF")
     213        13638 :       IF (PRESENT(ext_xc_section)) hfx_sections => section_vals_get_subs_vals(ext_xc_section, "HF")
     214              : 
     215        13638 :       CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
     216        13638 :       IF (n_rep_hf > 1) THEN
     217            0 :          CPABORT("ADMM can handle only one HF section.")
     218              :       END IF
     219              : 
     220        13638 :       IF (.NOT. ASSOCIATED(admm_env)) THEN
     221              :          ! setup admm environment
     222          528 :          CALL get_qs_env(qs_env, input=input, natom=natoms, qs_kind_set=qs_kind_set)
     223          528 :          CALL get_qs_kind_set(qs_kind_set, nsgf=nao_aux_fit, basis_type="AUX_FIT")
     224          528 :          CALL admm_env_create(admm_env, dft_control%admm_control, mos, para_env, natoms, nao_aux_fit)
     225          528 :          CALL set_qs_env(qs_env, admm_env=admm_env)
     226          528 :          xc_section => section_vals_get_subs_vals(input, "DFT%XC")
     227          528 :          IF (PRESENT(ext_xc_section)) xc_section => ext_xc_section
     228              :          CALL create_admm_xc_section(x_data=qs_env%x_data, xc_section=xc_section, &
     229          528 :                                      admm_env=admm_env)
     230              : 
     231              :          ! Initialize the GAPW data types
     232          528 :          IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
     233          152 :             CALL init_admm_gapw(qs_env)
     234              :          END IF
     235              : 
     236              :          ! ADMM neighbor lists and overlap matrices
     237          528 :          CALL admm_init_hamiltonians(admm_env, qs_env, "AUX_FIT")
     238              : 
     239              :          !The aux_fit task list and densities
     240          528 :          ALLOCATE (admm_env%rho_aux_fit)
     241          528 :          CALL qs_rho_create(admm_env%rho_aux_fit)
     242          528 :          ALLOCATE (admm_env%rho_aux_fit_buffer)
     243          528 :          CALL qs_rho_create(admm_env%rho_aux_fit_buffer)
     244          528 :          CALL admm_update_s_mstruct(admm_env, qs_env, "AUX_FIT")
     245          528 :          IF (admm_env%do_gapw) CALL update_admm_gapw(qs_env)
     246              : 
     247              :          !The ADMM KS matrices
     248          528 :          CALL admm_alloc_ks_matrices(admm_env, qs_env)
     249              : 
     250              :          !The aux_fit MOs and derivatives
     251         2238 :          ALLOCATE (mos_aux_fit(dft_control%nspins))
     252         1182 :          DO ispin = 1, dft_control%nspins
     253          654 :             CALL get_mo_set(mo_set=mos(ispin), nmo=nmo, nelectron=nelectron, maxocc=maxocc)
     254              :             CALL allocate_mo_set(mo_set=mos_aux_fit(ispin), &
     255              :                                  nao=nao_aux_fit, &
     256              :                                  nmo=nmo, &
     257              :                                  nelectron=nelectron, &
     258              :                                  n_el_f=REAL(nelectron, dp), &
     259              :                                  maxocc=maxocc, &
     260         1182 :                                  flexible_electron_count=dft_control%relax_multiplicity)
     261              :          END DO
     262          528 :          admm_env%mos_aux_fit => mos_aux_fit
     263              : 
     264         1182 :          DO ispin = 1, dft_control%nspins
     265          654 :             CALL get_mo_set(mo_set=mos(ispin), nmo=nmo)
     266              :             CALL cp_fm_struct_create(aux_fit_fm_struct, context=blacs_env, para_env=para_env, &
     267          654 :                                      nrow_global=nao_aux_fit, ncol_global=nmo)
     268          654 :             CALL get_mo_set(mos_aux_fit(ispin), mo_coeff=mo_coeff_aux_fit, mo_coeff_b=mo_coeff_b)
     269          654 :             IF (.NOT. ASSOCIATED(mo_coeff_aux_fit)) THEN
     270              :                CALL init_mo_set(mos_aux_fit(ispin), fm_struct=aux_fit_fm_struct, &
     271          654 :                                 name="qs_env%mo_aux_fit"//TRIM(ADJUSTL(cp_to_string(ispin))))
     272              :             END IF
     273          654 :             CALL cp_fm_struct_release(aux_fit_fm_struct)
     274              : 
     275         1836 :             IF (.NOT. ASSOCIATED(mo_coeff_b)) THEN
     276          654 :                CALL cp_fm_get_info(mos_aux_fit(ispin)%mo_coeff, ncol_global=nmo)
     277          654 :                CALL dbcsr_init_p(mos_aux_fit(ispin)%mo_coeff_b)
     278          654 :                CALL get_admm_env(admm_env, matrix_s_aux_fit_kp=matrix_s_aux_fit_kp)
     279              :                CALL cp_dbcsr_m_by_n_from_row_template(mos_aux_fit(ispin)%mo_coeff_b, &
     280              :                                                       template=matrix_s_aux_fit_kp(1, 1)%matrix, &
     281          654 :                                                       n=nmo, sym=dbcsr_type_no_symmetry)
     282              :             END IF
     283              :          END DO
     284              : 
     285          528 :          IF (qs_env%requires_mo_derivs) THEN
     286         1184 :             ALLOCATE (admm_env%mo_derivs_aux_fit(dft_control%nspins))
     287          624 :             DO ispin = 1, dft_control%nspins
     288          344 :                CALL get_mo_set(admm_env%mos_aux_fit(ispin), mo_coeff=mo_coeff_aux_fit)
     289          624 :                CALL cp_fm_create(admm_env%mo_derivs_aux_fit(ispin), mo_coeff_aux_fit%matrix_struct)
     290              :             END DO
     291              :          END IF
     292              : 
     293         1056 :          IF (do_kpoints) THEN
     294              :             BLOCK
     295              :                TYPE(kpoint_type), POINTER :: kpoints
     296           32 :                TYPE(mo_set_type), DIMENSION(:), POINTER              :: mos_aux_fit_kp
     297           32 :                TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER        :: ao_mo_fm_pools_aux_fit
     298              :                TYPE(cp_fm_struct_type), POINTER                      :: ao_ao_fm_struct
     299              :                INTEGER                                               :: ik, ikk, is
     300              :                INTEGER, PARAMETER                                    :: nwork1 = 4
     301              :                LOGICAL                                               :: use_real_wfn
     302              : 
     303           32 :                NULLIFY (ao_mo_fm_pools_aux_fit, mos_aux_fit_kp)
     304              : 
     305           32 :                CALL get_qs_env(qs_env=qs_env, kpoints=kpoints)
     306           32 :                CALL get_kpoint_info(kpoints, use_real_wfn=use_real_wfn)
     307              : 
     308              :                !Test combinations of input values. So far, only ADMM2 is availavle
     309           32 :                IF (.NOT. admm_env%purification_method == do_admm_purify_none) THEN
     310            0 :                   CPABORT("Only ADMM_PURIFICATION_METHOD NONE implemeted for ADMM K-points")
     311              :                END IF
     312           32 :                IF (.NOT. (dft_control%admm_control%method == do_admm_basis_projection &
     313              :                           .OR. dft_control%admm_control%method == do_admm_charge_constrained_projection)) THEN
     314            0 :                   CPABORT("Only BASIS_PROJECTION and CHARGE_CONSTRAINED_PROJECTION implemented for KP")
     315              :                END IF
     316           32 :                IF (admm_env%do_admms .OR. admm_env%do_admmp .OR. admm_env%do_admmq) THEN
     317           14 :                   IF (use_real_wfn) CPABORT("Only KP-HFX ADMM2 is implemented with REAL wavefunctions")
     318              :                END IF
     319              : 
     320           32 :                CALL kpoint_initialize_mos(kpoints, admm_env%mos_aux_fit, for_aux_fit=.TRUE.)
     321              : 
     322           32 :                CALL mpools_get(kpoints%mpools_aux_fit, ao_mo_fm_pools=ao_mo_fm_pools_aux_fit)
     323          203 :                DO ik = 1, SIZE(kpoints%kp_aux_env)
     324          171 :                   mos_aux_fit_kp => kpoints%kp_aux_env(ik)%kpoint_env%mos
     325          171 :                   ikk = kpoints%kp_range(1) + ik - 1
     326          412 :                   DO ispin = 1, SIZE(mos_aux_fit_kp)
     327              :                      ! No sparse matrix representation of k-point MO vectors.
     328          209 :                      CPASSERT(.NOT. ASSOCIATED(mos_aux_fit_kp(ispin)%mo_coeff_b))
     329          209 :                      IF (ASSOCIATED(mos_aux_fit_kp(ispin)%mo_coeff) .OR. &
     330              :                          ASSOCIATED(mos_aux_fit_kp(ispin)%cmo_coeff)) CYCLE
     331              :                      CALL init_mo_set(mos_aux_fit_kp(ispin), &
     332              :                                       fm_pool=ao_mo_fm_pools_aux_fit(ispin)%pool, &
     333              :                                       name="kpoints_"//TRIM(ADJUSTL(cp_to_string(ikk)))// &
     334              :                                       "%mo_aux_fit"//TRIM(ADJUSTL(cp_to_string(ispin))), &
     335          380 :                                       complex_coeff=.NOT. use_real_wfn)
     336              :                   END DO
     337              :                END DO
     338              : 
     339          160 :                ALLOCATE (admm_env%scf_work_aux_fit(nwork1))
     340              : 
     341              :                ! create an ao_ao parallel matrix structure
     342              :                CALL cp_fm_struct_create(ao_ao_fm_struct, context=blacs_env, para_env=para_env, &
     343              :                                         nrow_global=nao_aux_fit, &
     344           32 :                                         ncol_global=nao_aux_fit)
     345              : 
     346          160 :                DO is = 1, nwork1
     347              :                   CALL cp_fm_create(admm_env%scf_work_aux_fit(is), &
     348              :                                     matrix_struct=ao_ao_fm_struct, &
     349          160 :                                     name="SCF-WORK_MATRIX-AUX-"//TRIM(ADJUSTL(cp_to_string(is))))
     350              :                END DO
     351           32 :                CALL cp_fm_struct_release(ao_ao_fm_struct)
     352              : 
     353              :                ! Create and populate the internal ADMM overlap matrices at each KP
     354           64 :                CALL kpoint_calc_admm_matrices(qs_env, calc_forces)
     355              : 
     356              :             END BLOCK
     357              :          END IF
     358              : 
     359        13110 :       ELSE IF (s_mstruct_changed) THEN
     360          470 :          CALL admm_init_hamiltonians(admm_env, qs_env, "AUX_FIT")
     361          470 :          CALL admm_update_s_mstruct(admm_env, qs_env, "AUX_FIT")
     362          470 :          CALL admm_alloc_ks_matrices(admm_env, qs_env)
     363          470 :          IF (admm_env%do_gapw) CALL update_admm_gapw(qs_env)
     364          470 :          IF (do_kpoints) CALL kpoint_calc_admm_matrices(qs_env, calc_forces)
     365              :       END IF
     366              : 
     367        13638 :       IF (admm_env%do_gapw .AND. dft_control%do_admm_dm) THEN
     368            0 :          CPABORT("GAPW ADMM not implemented for MCWEENY or NONE_DM purification.")
     369              :       END IF
     370              : 
     371              :       !ADMMS and ADMMP stress tensors only available for close-shell systesms, because virial cannot
     372              :       !be scaled by gsi spin component wise
     373        13638 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
     374         1342 :       IF (use_virial .AND. admm_env%do_admms .AND. dft_control%nspins == 2) THEN
     375            0 :          CPABORT("ADMMS stress tensor is only available for closed-shell systems")
     376              :       END IF
     377         1342 :       IF (use_virial .AND. admm_env%do_admmp .AND. dft_control%nspins == 2) THEN
     378            0 :          CPABORT("ADMMP stress tensor is only available for closed-shell systems")
     379              :       END IF
     380              : 
     381        13638 :       IF (dft_control%do_admm_dm .AND. .NOT. ASSOCIATED(admm_env%admm_dm)) THEN
     382           14 :          CALL admm_dm_create(admm_env%admm_dm, dft_control%admm_control, nspins=dft_control%nspins, natoms=natoms)
     383              :       END IF
     384              : 
     385        13638 :       CALL timestop(handle)
     386              : 
     387        13638 :    END SUBROUTINE hfx_admm_init
     388              : 
     389              : ! **************************************************************************************************
     390              : !> \brief Minimal setup routine for admm_env
     391              : !>        No forces
     392              : !>        No k-points
     393              : !>        No DFT correction terms
     394              : !> \param qs_env ...
     395              : !> \param mos ...
     396              : !> \param admm_env ...
     397              : !> \param admm_control ...
     398              : !> \param basis_type ...
     399              : ! **************************************************************************************************
     400            4 :    SUBROUTINE aux_admm_init(qs_env, mos, admm_env, admm_control, basis_type)
     401              : 
     402              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     403              :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos
     404              :       TYPE(admm_type), POINTER                           :: admm_env
     405              :       TYPE(admm_control_type), POINTER                   :: admm_control
     406              :       CHARACTER(LEN=*)                                   :: basis_type
     407              : 
     408              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'aux_admm_init'
     409              : 
     410              :       INTEGER                                            :: handle, ispin, nao_aux_fit, natoms, &
     411              :                                                             nelectron, nmo
     412              :       LOGICAL                                            :: do_kpoints
     413              :       REAL(dp)                                           :: maxocc
     414              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     415              :       TYPE(cp_fm_struct_type), POINTER                   :: aux_fit_fm_struct
     416              :       TYPE(cp_fm_type), POINTER                          :: mo_coeff_aux_fit
     417            4 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_s_aux_fit_kp
     418              :       TYPE(dbcsr_type), POINTER                          :: mo_coeff_b
     419              :       TYPE(dft_control_type), POINTER                    :: dft_control
     420            4 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mos_aux_fit
     421              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     422            4 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     423              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     424              : 
     425            4 :       CALL timeset(routineN, handle)
     426              : 
     427            4 :       CPASSERT(.NOT. ASSOCIATED(admm_env))
     428              : 
     429              :       CALL get_qs_env(qs_env, &
     430              :                       para_env=para_env, &
     431              :                       blacs_env=blacs_env, &
     432              :                       ks_env=ks_env, &
     433              :                       dft_control=dft_control, &
     434            4 :                       do_kpoints=do_kpoints)
     435              : 
     436            4 :       CPASSERT(.NOT. do_kpoints)
     437            4 :       IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
     438            0 :          CPABORT("AUX ADMM not possible with GAPW")
     439              :       END IF
     440              : 
     441              :       ! setup admm environment
     442            4 :       CALL get_qs_env(qs_env, natom=natoms, qs_kind_set=qs_kind_set)
     443            4 :       CALL get_qs_kind_set(qs_kind_set, nsgf=nao_aux_fit, basis_type=basis_type)
     444              :       !
     445            4 :       CALL admm_env_create(admm_env, admm_control, mos, para_env, natoms, nao_aux_fit)
     446              :       ! no XC correction used
     447            4 :       NULLIFY (admm_env%xc_section_aux, admm_env%xc_section_primary)
     448              :       ! ADMM neighbor lists and overlap matrices
     449            4 :       CALL admm_init_hamiltonians(admm_env, qs_env, basis_type)
     450            4 :       NULLIFY (admm_env%rho_aux_fit, admm_env%rho_aux_fit_buffer)
     451              :       !The ADMM KS matrices
     452            4 :       CALL admm_alloc_ks_matrices(admm_env, qs_env)
     453              :       !The aux_fit MOs and derivatives
     454           16 :       ALLOCATE (mos_aux_fit(dft_control%nspins))
     455            8 :       DO ispin = 1, dft_control%nspins
     456            4 :          CALL get_mo_set(mo_set=mos(ispin), nmo=nmo, nelectron=nelectron, maxocc=maxocc)
     457              :          CALL allocate_mo_set(mo_set=mos_aux_fit(ispin), nao=nao_aux_fit, nmo=nmo, &
     458              :                               nelectron=nelectron, n_el_f=REAL(nelectron, dp), &
     459            8 :                               maxocc=maxocc, flexible_electron_count=0.0_dp)
     460              :       END DO
     461            4 :       admm_env%mos_aux_fit => mos_aux_fit
     462              : 
     463            8 :       DO ispin = 1, dft_control%nspins
     464            4 :          CALL get_mo_set(mo_set=mos(ispin), nmo=nmo)
     465              :          CALL cp_fm_struct_create(aux_fit_fm_struct, context=blacs_env, para_env=para_env, &
     466            4 :                                   nrow_global=nao_aux_fit, ncol_global=nmo)
     467            4 :          CALL get_mo_set(mos_aux_fit(ispin), mo_coeff=mo_coeff_aux_fit, mo_coeff_b=mo_coeff_b)
     468            4 :          IF (.NOT. ASSOCIATED(mo_coeff_aux_fit)) THEN
     469              :             CALL init_mo_set(mos_aux_fit(ispin), fm_struct=aux_fit_fm_struct, &
     470            4 :                              name="mo_aux_fit"//TRIM(ADJUSTL(cp_to_string(ispin))))
     471              :          END IF
     472            4 :          CALL cp_fm_struct_release(aux_fit_fm_struct)
     473              : 
     474           12 :          IF (.NOT. ASSOCIATED(mo_coeff_b)) THEN
     475            4 :             CALL cp_fm_get_info(mos_aux_fit(ispin)%mo_coeff, ncol_global=nmo)
     476            4 :             CALL dbcsr_init_p(mos_aux_fit(ispin)%mo_coeff_b)
     477            4 :             CALL get_admm_env(admm_env, matrix_s_aux_fit_kp=matrix_s_aux_fit_kp)
     478              :             CALL cp_dbcsr_m_by_n_from_row_template(mos_aux_fit(ispin)%mo_coeff_b, &
     479              :                                                    template=matrix_s_aux_fit_kp(1, 1)%matrix, &
     480            4 :                                                    n=nmo, sym=dbcsr_type_no_symmetry)
     481              :          END IF
     482              :       END DO
     483              : 
     484            4 :       CALL timestop(handle)
     485              : 
     486            8 :    END SUBROUTINE aux_admm_init
     487              : 
     488              : ! **************************************************************************************************
     489              : !> \brief Sets up the admm_gapw env
     490              : !> \param qs_env ...
     491              : ! **************************************************************************************************
     492          152 :    SUBROUTINE init_admm_gapw(qs_env)
     493              : 
     494              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     495              : 
     496              :       INTEGER                                            :: ikind, nkind
     497              :       TYPE(admm_gapw_r3d_rs_type), POINTER               :: admm_gapw_env
     498              :       TYPE(admm_type), POINTER                           :: admm_env
     499          152 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     500              :       TYPE(dft_control_type), POINTER                    :: dft_control
     501              :       TYPE(gto_basis_set_type), POINTER                  :: aux_fit_basis, aux_fit_soft_basis, &
     502              :                                                             orb_basis, soft_basis
     503              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     504          152 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: admm_kind_set, qs_kind_set
     505              :       TYPE(section_vals_type), POINTER                   :: input
     506              : 
     507          152 :       NULLIFY (admm_kind_set, aux_fit_basis, atomic_kind_set, aux_fit_soft_basis, &
     508          152 :                dft_control, input, orb_basis, para_env, qs_kind_set, soft_basis)
     509              : 
     510              :       CALL get_qs_env(qs_env, admm_env=admm_env, &
     511              :                       atomic_kind_set=atomic_kind_set, &
     512              :                       dft_control=dft_control, &
     513              :                       input=input, &
     514              :                       para_env=para_env, &
     515          152 :                       qs_kind_set=qs_kind_set)
     516              : 
     517          152 :       admm_env%do_gapw = .TRUE.
     518          152 :       ALLOCATE (admm_env%admm_gapw_env)
     519          152 :       admm_gapw_env => admm_env%admm_gapw_env
     520          152 :       NULLIFY (admm_gapw_env%local_rho_set)
     521          152 :       NULLIFY (admm_gapw_env%admm_kind_set)
     522          152 :       NULLIFY (admm_gapw_env%task_list)
     523              : 
     524              :       !Create a new kind set for the ADMM stuff (paw_proj soft AUX_FIT basis, etc)
     525          152 :       nkind = SIZE(qs_kind_set)
     526         3788 :       ALLOCATE (admm_gapw_env%admm_kind_set(nkind))
     527          152 :       admm_kind_set => admm_gapw_env%admm_kind_set
     528              : 
     529              :       !In this new kind set, we want the AUX_FIT basis to be known as ORB, such that GAPW routines work
     530          444 :       DO ikind = 1, nkind
     531              :          !copying over simple data  of interest from qs_kind_set
     532          292 :          admm_kind_set(ikind)%name = qs_kind_set(ikind)%name
     533          292 :          admm_kind_set(ikind)%element_symbol = qs_kind_set(ikind)%element_symbol
     534          292 :          admm_kind_set(ikind)%natom = qs_kind_set(ikind)%natom
     535          292 :          admm_kind_set(ikind)%hard_radius = qs_kind_set(ikind)%hard_radius
     536          292 :          admm_kind_set(ikind)%max_rad_local = qs_kind_set(ikind)%max_rad_local
     537          292 :          admm_kind_set(ikind)%gpw_type_forced = qs_kind_set(ikind)%gpw_type_forced
     538          292 :          admm_kind_set(ikind)%ngrid_rad = qs_kind_set(ikind)%ngrid_rad
     539          292 :          admm_kind_set(ikind)%ngrid_ang = qs_kind_set(ikind)%ngrid_ang
     540              : 
     541              :          !copying potentials of interest from qs_kind_set
     542          292 :          IF (ASSOCIATED(qs_kind_set(ikind)%all_potential)) THEN
     543           76 :             CALL copy_potential(qs_kind_set(ikind)%all_potential, admm_kind_set(ikind)%all_potential)
     544              :          END IF
     545          292 :          IF (ASSOCIATED(qs_kind_set(ikind)%gth_potential)) THEN
     546          216 :             CALL copy_potential(qs_kind_set(ikind)%gth_potential, admm_kind_set(ikind)%gth_potential)
     547              :          END IF
     548          292 :          IF (ASSOCIATED(qs_kind_set(ikind)%sgp_potential)) THEN
     549            0 :             CALL copy_potential(qs_kind_set(ikind)%sgp_potential, admm_kind_set(ikind)%sgp_potential)
     550              :          END IF
     551              : 
     552          292 :          NULLIFY (orb_basis)
     553          292 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=aux_fit_basis, basis_type="AUX_FIT")
     554          292 :          CALL copy_gto_basis_set(aux_fit_basis, orb_basis)
     555          444 :          CALL add_basis_set_to_container(admm_kind_set(ikind)%basis_sets, orb_basis, "ORB")
     556              :       END DO
     557              : 
     558              :       !Create the corresponding soft basis set (and projectors)
     559              :       CALL init_gapw_basis_set(admm_kind_set, dft_control%qs_control, input, &
     560          152 :                                modify_qs_control=.FALSE.)
     561              : 
     562              :       !Make sure the basis and the projectors are well initialized
     563          152 :       CALL init_interaction_radii(dft_control%qs_control, admm_kind_set)
     564              : 
     565              :       !We also init the atomic grids and harmonics
     566          152 :       CALL local_rho_set_create(admm_gapw_env%local_rho_set)
     567              :       CALL init_rho_atom(admm_gapw_env%local_rho_set%rho_atom_set, &
     568          152 :                          atomic_kind_set, admm_kind_set, dft_control, para_env)
     569              : 
     570              :       !Make sure that any NLCC potential is well initialized
     571          152 :       CALL init_gapw_nlcc(admm_kind_set)
     572              : 
     573              :       !Need to have access to the soft AUX_FIT basis from the qs_env => add it to the qs_kinds
     574          444 :       DO ikind = 1, nkind
     575          292 :          NULLIFY (aux_fit_soft_basis)
     576          292 :          CALL get_qs_kind(admm_kind_set(ikind), basis_set=soft_basis, basis_type="ORB_SOFT")
     577          292 :          CALL copy_gto_basis_set(soft_basis, aux_fit_soft_basis)
     578          444 :          CALL add_basis_set_to_container(qs_kind_set(ikind)%basis_sets, aux_fit_soft_basis, "AUX_FIT_SOFT")
     579              :       END DO
     580              : 
     581          152 :    END SUBROUTINE init_admm_gapw
     582              : 
     583              : ! **************************************************************************************************
     584              : !> \brief Builds the ADMM nmeighbor lists and overlap matrix on the model of qs_energies_init_hamiltonians()
     585              : !> \param admm_env ...
     586              : !> \param qs_env ...
     587              : !> \param aux_basis_type ...
     588              : ! **************************************************************************************************
     589         1002 :    SUBROUTINE admm_init_hamiltonians(admm_env, qs_env, aux_basis_type)
     590              : 
     591              :       TYPE(admm_type), POINTER                           :: admm_env
     592              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     593              :       CHARACTER(len=*)                                   :: aux_basis_type
     594              : 
     595              :       CHARACTER(len=*), PARAMETER :: routineN = 'admm_init_hamiltonians'
     596              : 
     597              :       INTEGER                                            :: handle, hfx_pot, ikind, nkind
     598              :       LOGICAL                                            :: do_kpoints, mic, molecule_only
     599              :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: aux_fit_present, orb_present
     600              :       REAL(dp)                                           :: eps_schwarz, omega, pdist, roperator, &
     601              :                                                             subcells
     602              :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: aux_fit_radius, orb_radius
     603              :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: pair_radius
     604         1002 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     605              :       TYPE(cell_type), POINTER                           :: cell
     606         1002 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_s_aux_fit_kp, &
     607         1002 :                                                             matrix_s_aux_fit_vs_orb_kp
     608              :       TYPE(dft_control_type), POINTER                    :: dft_control
     609              :       TYPE(distribution_1d_type), POINTER                :: distribution_1d
     610              :       TYPE(distribution_2d_type), POINTER                :: distribution_2d
     611              :       TYPE(gto_basis_set_type), POINTER                  :: aux_fit_basis_set, orb_basis_set
     612              :       TYPE(kpoint_type), POINTER                         :: kpoints
     613         1002 :       TYPE(local_atoms_type), ALLOCATABLE, DIMENSION(:)  :: atom2d
     614         1002 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     615              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     616         1002 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     617         1002 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     618              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     619              :       TYPE(section_vals_type), POINTER                   :: hfx_sections, neighbor_list_section
     620              : 
     621         1002 :       NULLIFY (particle_set, cell, kpoints, distribution_1d, distribution_2d, molecule_set, &
     622         1002 :                atomic_kind_set, dft_control, neighbor_list_section, aux_fit_basis_set, orb_basis_set, &
     623         1002 :                ks_env, para_env, qs_kind_set, matrix_s_aux_fit_kp, matrix_s_aux_fit_vs_orb_kp)
     624              : 
     625         1002 :       CALL timeset(routineN, handle)
     626              : 
     627              :       CALL get_qs_env(qs_env, nkind=nkind, particle_set=particle_set, cell=cell, kpoints=kpoints, &
     628              :                       local_particles=distribution_1d, distribution_2d=distribution_2d, &
     629              :                       molecule_set=molecule_set, atomic_kind_set=atomic_kind_set, do_kpoints=do_kpoints, &
     630         1002 :                       dft_control=dft_control, para_env=para_env, qs_kind_set=qs_kind_set)
     631         4008 :       ALLOCATE (orb_present(nkind), aux_fit_present(nkind))
     632         7014 :       ALLOCATE (orb_radius(nkind), aux_fit_radius(nkind), pair_radius(nkind, nkind))
     633         1002 :       aux_fit_radius(:) = 0.0_dp
     634              : 
     635         1002 :       molecule_only = .FALSE.
     636         1002 :       IF (dft_control%qs_control%do_kg) molecule_only = .TRUE.
     637         1002 :       mic = molecule_only
     638         1002 :       IF (kpoints%nkp > 0) THEN
     639           48 :          mic = .FALSE.
     640          954 :       ELSE IF (dft_control%qs_control%semi_empirical) THEN
     641            0 :          mic = .TRUE.
     642              :       END IF
     643              : 
     644         1002 :       pdist = dft_control%qs_control%pairlist_radius
     645              : 
     646         1002 :       CALL section_vals_val_get(qs_env%input, "DFT%SUBCELLS", r_val=subcells)
     647         1002 :       neighbor_list_section => section_vals_get_subs_vals(qs_env%input, "DFT%PRINT%NEIGHBOR_LISTS")
     648              : 
     649         4876 :       ALLOCATE (atom2d(nkind))
     650              :       CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
     651         1002 :                         molecule_set, molecule_only, particle_set=particle_set)
     652              : 
     653         2872 :       DO ikind = 1, nkind
     654         1870 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, basis_type="ORB")
     655         1870 :          IF (ASSOCIATED(orb_basis_set)) THEN
     656         1870 :             orb_present(ikind) = .TRUE.
     657         1870 :             CALL get_gto_basis_set(gto_basis_set=orb_basis_set, kind_radius=orb_radius(ikind))
     658              :          ELSE
     659            0 :             orb_present(ikind) = .FALSE.
     660              :          END IF
     661              : 
     662         1870 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=aux_fit_basis_set, basis_type=aux_basis_type)
     663         2872 :          IF (ASSOCIATED(aux_fit_basis_set)) THEN
     664         1870 :             aux_fit_present(ikind) = .TRUE.
     665         1870 :             CALL get_gto_basis_set(gto_basis_set=aux_fit_basis_set, kind_radius=aux_fit_radius(ikind))
     666              :          ELSE
     667            0 :             aux_fit_present(ikind) = .FALSE.
     668              :          END IF
     669              :       END DO
     670              : 
     671         1002 :       IF (pdist < 0.0_dp) THEN
     672              :          pdist = MAX(plane_distance(1, 0, 0, cell), &
     673              :                      plane_distance(0, 1, 0, cell), &
     674            2 :                      plane_distance(0, 0, 1, cell))
     675              :       END IF
     676              : 
     677              :       !In case of K-points, we need to add the HFX potential range to sab_aux_fit, because it is used
     678              :       !to populate AUX density and KS matrices
     679         1002 :       roperator = 0.0_dp
     680         1002 :       IF (do_kpoints) THEN
     681           48 :          hfx_sections => section_vals_get_subs_vals(qs_env%input, "DFT%XC%HF")
     682           48 :          CALL section_vals_val_get(hfx_sections, "INTERACTION_POTENTIAL%POTENTIAL_TYPE", i_val=hfx_pot)
     683              : 
     684              :          SELECT CASE (hfx_pot)
     685              :          CASE (do_potential_id)
     686           26 :             roperator = 0.0_dp
     687              :          CASE (do_potential_truncated)
     688           32 :             CALL section_vals_val_get(hfx_sections, "INTERACTION_POTENTIAL%CUTOFF_RADIUS", r_val=roperator)
     689              :          CASE (do_potential_mix_cl_trunc)
     690            6 :             CALL section_vals_val_get(hfx_sections, "INTERACTION_POTENTIAL%CUTOFF_RADIUS", r_val=roperator)
     691              :          CASE (do_potential_short)
     692            0 :             CALL section_vals_val_get(hfx_sections, "INTERACTION_POTENTIAL%OMEGA", r_val=omega)
     693            0 :             CALL section_vals_val_get(hfx_sections, "SCREENING%EPS_SCHWARZ", r_val=eps_schwarz)
     694            0 :             CALL erfc_cutoff(eps_schwarz, omega, roperator)
     695              :          CASE DEFAULT
     696           48 :             CPABORT("HFX potential not available for K-points (NYI)")
     697              :          END SELECT
     698              :       END IF
     699              : 
     700         1002 :       CALL pair_radius_setup(aux_fit_present, aux_fit_present, aux_fit_radius, aux_fit_radius, pair_radius, pdist)
     701         6654 :       pair_radius = pair_radius + cutoff_screen_factor*roperator
     702              :       CALL build_neighbor_lists(admm_env%sab_aux_fit, particle_set, atom2d, cell, pair_radius, &
     703              :                                 mic=mic, molecular=molecule_only, subcells=subcells, nlname="sab_aux_fit", &
     704         1002 :                                 stable_images=kpoints%symmetry)
     705              :       CALL build_neighbor_lists(admm_env%sab_aux_fit_asymm, particle_set, atom2d, cell, pair_radius, &
     706              :                                 mic=mic, symmetric=.FALSE., molecular=molecule_only, subcells=subcells, &
     707         1002 :                                 nlname="sab_aux_fit_asymm", stable_images=kpoints%symmetry)
     708         1002 :       CALL pair_radius_setup(aux_fit_present, orb_present, aux_fit_radius, orb_radius, pair_radius)
     709              :       CALL build_neighbor_lists(admm_env%sab_aux_fit_vs_orb, particle_set, atom2d, cell, pair_radius, &
     710              :                                 mic=mic, symmetric=.FALSE., molecular=molecule_only, subcells=subcells, &
     711         1002 :                                 nlname="sab_aux_fit_vs_orb", stable_images=kpoints%symmetry)
     712              : 
     713              :       CALL write_neighbor_lists(admm_env%sab_aux_fit, particle_set, cell, para_env, neighbor_list_section, &
     714         1002 :                                 "/SAB_AUX_FIT", "sab_aux_fit", "AUX_FIT_ORBITAL AUX_FIT_ORBITAL")
     715              :       CALL write_neighbor_lists(admm_env%sab_aux_fit_vs_orb, particle_set, cell, para_env, neighbor_list_section, &
     716         1002 :                                 "/SAB_AUX_FIT_VS_ORB", "sab_aux_fit_vs_orb", "ORBITAL AUX_FIT_ORBITAL")
     717              : 
     718         1002 :       CALL atom2d_cleanup(atom2d)
     719              : 
     720              :       !The ADMM overlap matrices (initially in qs_core_hamiltonian.F)
     721         1002 :       CALL get_qs_env(qs_env, ks_env=ks_env)
     722              : 
     723         1002 :       CALL kpoint_transitional_release(admm_env%matrix_s_aux_fit)
     724              :       CALL build_overlap_matrix(ks_env, matrixkp_s=matrix_s_aux_fit_kp, &
     725              :                                 matrix_name="AUX_FIT_OVERLAP", &
     726              :                                 basis_type_a=aux_basis_type, &
     727              :                                 basis_type_b=aux_basis_type, &
     728         1002 :                                 sab_nl=admm_env%sab_aux_fit)
     729         1002 :       CALL set_2d_pointer(admm_env%matrix_s_aux_fit, matrix_s_aux_fit_kp)
     730         1002 :       CALL kpoint_transitional_release(admm_env%matrix_s_aux_fit_vs_orb)
     731              :       CALL build_overlap_matrix(ks_env, matrixkp_s=matrix_s_aux_fit_vs_orb_kp, &
     732              :                                 matrix_name="MIXED_OVERLAP", &
     733              :                                 basis_type_a=aux_basis_type, &
     734              :                                 basis_type_b="ORB", &
     735         1002 :                                 sab_nl=admm_env%sab_aux_fit_vs_orb)
     736         1002 :       CALL set_2d_pointer(admm_env%matrix_s_aux_fit_vs_orb, matrix_s_aux_fit_vs_orb_kp)
     737              : 
     738         1002 :       CALL timestop(handle)
     739              : 
     740         3006 :    END SUBROUTINE admm_init_hamiltonians
     741              : 
     742              : ! **************************************************************************************************
     743              : !> \brief Updates the ADMM task_list and density based on the model of qs_env_update_s_mstruct()
     744              : !> \param admm_env ...
     745              : !> \param qs_env ...
     746              : !> \param aux_basis_type ...
     747              : ! **************************************************************************************************
     748          998 :    SUBROUTINE admm_update_s_mstruct(admm_env, qs_env, aux_basis_type)
     749              : 
     750              :       TYPE(admm_type), POINTER                           :: admm_env
     751              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     752              :       CHARACTER(len=*)                                   :: aux_basis_type
     753              : 
     754              :       CHARACTER(len=*), PARAMETER :: routineN = 'admm_update_s_mstruct'
     755              : 
     756              :       INTEGER                                            :: handle
     757              :       LOGICAL                                            :: skip_load_balance_distributed
     758              :       TYPE(dft_control_type), POINTER                    :: dft_control
     759              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     760              : 
     761          998 :       NULLIFY (ks_env, dft_control)
     762              : 
     763          998 :       CALL timeset(routineN, handle)
     764              : 
     765          998 :       CALL get_qs_env(qs_env, ks_env=ks_env, dft_control=dft_control)
     766              : 
     767              :       !The aux_fit task_list
     768          998 :       skip_load_balance_distributed = dft_control%qs_control%skip_load_balance_distributed
     769          998 :       IF (ASSOCIATED(admm_env%task_list_aux_fit)) CALL deallocate_task_list(admm_env%task_list_aux_fit)
     770          998 :       CALL allocate_task_list(admm_env%task_list_aux_fit)
     771              :       CALL generate_qs_task_list(ks_env, admm_env%task_list_aux_fit, basis_type=aux_basis_type, &
     772              :                                  reorder_rs_grid_ranks=.FALSE., &
     773              :                                  skip_load_balance_distributed=skip_load_balance_distributed, &
     774          998 :                                  sab_orb_external=admm_env%sab_aux_fit)
     775              : 
     776              :       !The aux_fit densities
     777          998 :       CALL qs_rho_rebuild(admm_env%rho_aux_fit, qs_env=qs_env, admm=.TRUE.)
     778          998 :       CALL qs_rho_rebuild(admm_env%rho_aux_fit_buffer, qs_env=qs_env, admm=.TRUE.)
     779              : 
     780          998 :       CALL timestop(handle)
     781              : 
     782          998 :    END SUBROUTINE admm_update_s_mstruct
     783              : 
     784              : ! **************************************************************************************************
     785              : !> \brief Update the admm_gapw_env internals to the current qs_env (i.e. atomic positions)
     786              : !> \param qs_env ...
     787              : ! **************************************************************************************************
     788          416 :    SUBROUTINE update_admm_gapw(qs_env)
     789              : 
     790              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     791              : 
     792              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'update_admm_gapw'
     793              : 
     794              :       INTEGER                                            :: handle, ikind, nkind
     795              :       LOGICAL                                            :: paw_atom
     796              :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: aux_present, oce_present
     797              :       REAL(dp)                                           :: subcells
     798              :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: aux_radius, oce_radius
     799          416 :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)             :: pair_radius
     800              :       TYPE(admm_gapw_r3d_rs_type), POINTER               :: admm_gapw_env
     801              :       TYPE(admm_type), POINTER                           :: admm_env
     802          416 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     803              :       TYPE(cell_type), POINTER                           :: cell
     804              :       TYPE(dft_control_type), POINTER                    :: dft_control
     805              :       TYPE(distribution_1d_type), POINTER                :: distribution_1d
     806              :       TYPE(distribution_2d_type), POINTER                :: distribution_2d
     807              :       TYPE(gto_basis_set_type), POINTER                  :: aux_fit_basis
     808          416 :       TYPE(local_atoms_type), ALLOCATABLE, DIMENSION(:)  :: atom2d
     809          416 :       TYPE(molecule_type), DIMENSION(:), POINTER         :: molecule_set
     810              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     811          416 :          POINTER                                         :: sap_oce
     812          416 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     813              :       TYPE(paw_proj_set_type), POINTER                   :: paw_proj
     814          416 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: admm_kind_set, qs_kind_set
     815              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
     816              : 
     817          416 :       NULLIFY (ks_env, qs_kind_set, admm_kind_set, aux_fit_basis, cell, distribution_1d)
     818          416 :       NULLIFY (distribution_2d, paw_proj, particle_set, molecule_set, admm_env, admm_gapw_env)
     819          416 :       NULLIFY (dft_control, atomic_kind_set, sap_oce)
     820              : 
     821          416 :       CALL timeset(routineN, handle)
     822              : 
     823              :       CALL get_qs_env(qs_env, ks_env=ks_env, qs_kind_set=qs_kind_set, admm_env=admm_env, &
     824          416 :                       dft_control=dft_control)
     825          416 :       admm_gapw_env => admm_env%admm_gapw_env
     826          416 :       admm_kind_set => admm_gapw_env%admm_kind_set
     827          416 :       nkind = SIZE(qs_kind_set)
     828              : 
     829              :       !Update the task lisft for the AUX_FIT_SOFT basis
     830          416 :       IF (ASSOCIATED(admm_gapw_env%task_list)) CALL deallocate_task_list(admm_gapw_env%task_list)
     831          416 :       CALL allocate_task_list(admm_gapw_env%task_list)
     832              : 
     833              :       !note: we set soft_valid to .FALSE. want to use AUX_FIT_SOFT and not the normal ORB SOFT basis
     834              :       CALL generate_qs_task_list(ks_env, admm_gapw_env%task_list, basis_type="AUX_FIT_SOFT", &
     835              :                                  reorder_rs_grid_ranks=.FALSE., &
     836              :                                  skip_load_balance_distributed=dft_control%qs_control%skip_load_balance_distributed, &
     837          416 :                                  sab_orb_external=admm_env%sab_aux_fit)
     838              : 
     839              :       !Update the precomputed oce integrals
     840              :       !a sap_oce neighbor list is required => build it here
     841         1664 :       ALLOCATE (aux_present(nkind), oce_present(nkind))
     842          416 :       aux_present = .FALSE.; oce_present = .FALSE.
     843         1664 :       ALLOCATE (aux_radius(nkind), oce_radius(nkind))
     844          416 :       aux_radius = 0.0_dp; oce_radius = 0.0_dp
     845              : 
     846         1254 :       DO ikind = 1, nkind
     847          838 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=aux_fit_basis, basis_type="AUX_FIT")
     848          838 :          IF (ASSOCIATED(aux_fit_basis)) THEN
     849          838 :             aux_present(ikind) = .TRUE.
     850          838 :             CALL get_gto_basis_set(aux_fit_basis, kind_radius=aux_radius(ikind))
     851              :          END IF
     852              : 
     853              :          !note: get oce info from admm_kind_set
     854          838 :          CALL get_qs_kind(admm_kind_set(ikind), paw_atom=paw_atom, paw_proj_set=paw_proj)
     855         1254 :          IF (paw_atom) THEN
     856          510 :             oce_present(ikind) = .TRUE.
     857          510 :             CALL get_paw_proj_set(paw_proj, rcprj=oce_radius(ikind))
     858              :          END IF
     859              :       END DO
     860              : 
     861         1664 :       ALLOCATE (pair_radius(nkind, nkind))
     862          416 :       pair_radius = 0.0_dp
     863          416 :       CALL pair_radius_setup(aux_present, oce_present, aux_radius, oce_radius, pair_radius)
     864              : 
     865              :       CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, cell=cell, &
     866              :                       distribution_2d=distribution_2d, local_particles=distribution_1d, &
     867          416 :                       particle_set=particle_set, molecule_set=molecule_set)
     868          416 :       CALL section_vals_val_get(qs_env%input, "DFT%SUBCELLS", r_val=subcells)
     869              : 
     870         2086 :       ALLOCATE (atom2d(nkind))
     871              :       CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
     872          416 :                         molecule_set, .FALSE., particle_set)
     873              :       CALL build_neighbor_lists(sap_oce, particle_set, atom2d, cell, pair_radius, &
     874          416 :                                 subcells=subcells, operator_type="ABBA", nlname="AUX_PAW-PRJ")
     875          416 :       CALL atom2d_cleanup(atom2d)
     876              : 
     877              :       !actually compute the oce matrices
     878          416 :       CALL create_oce_set(admm_gapw_env%oce)
     879          416 :       CALL allocate_oce_set(admm_gapw_env%oce, nkind)
     880              : 
     881              :       !always compute the derivative, cheap anyways
     882              :       CALL build_oce_matrices(admm_gapw_env%oce%intac, calculate_forces=.TRUE., nder=1, &
     883              :                               qs_kind_set=admm_kind_set, particle_set=particle_set, &
     884          416 :                               sap_oce=sap_oce, eps_fit=dft_control%qs_control%gapw_control%eps_fit)
     885              : 
     886          416 :       CALL release_neighbor_list_sets(sap_oce)
     887              : 
     888          416 :       CALL timestop(handle)
     889              : 
     890         1248 :    END SUBROUTINE update_admm_gapw
     891              : 
     892              : ! **************************************************************************************************
     893              : !> \brief Allocates the various ADMM KS matrices
     894              : !> \param admm_env ...
     895              : !> \param qs_env ...
     896              : ! **************************************************************************************************
     897         1002 :    SUBROUTINE admm_alloc_ks_matrices(admm_env, qs_env)
     898              : 
     899              :       TYPE(admm_type), POINTER                           :: admm_env
     900              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     901              : 
     902              :       CHARACTER(len=*), PARAMETER :: routineN = 'admm_alloc_ks_matrices'
     903              : 
     904              :       INTEGER                                            :: handle, ic, ispin
     905         1002 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_ks_aux_fit_dft_kp, &
     906         1002 :                                                             matrix_ks_aux_fit_hfx_kp, &
     907         1002 :                                                             matrix_ks_aux_fit_kp, &
     908         1002 :                                                             matrix_s_aux_fit_kp
     909              :       TYPE(dft_control_type), POINTER                    :: dft_control
     910              : 
     911         1002 :       NULLIFY (dft_control, matrix_s_aux_fit_kp, matrix_ks_aux_fit_kp, matrix_ks_aux_fit_dft_kp, matrix_ks_aux_fit_hfx_kp)
     912              : 
     913         1002 :       CALL timeset(routineN, handle)
     914              : 
     915         1002 :       CALL get_qs_env(qs_env, dft_control=dft_control)
     916         1002 :       CALL get_admm_env(admm_env, matrix_s_aux_fit_kp=matrix_s_aux_fit_kp)
     917              : 
     918         1002 :       CALL kpoint_transitional_release(admm_env%matrix_ks_aux_fit)
     919         1002 :       CALL kpoint_transitional_release(admm_env%matrix_ks_aux_fit_dft)
     920         1002 :       CALL kpoint_transitional_release(admm_env%matrix_ks_aux_fit_hfx)
     921              : 
     922         1002 :       CALL dbcsr_allocate_matrix_set(matrix_ks_aux_fit_kp, dft_control%nspins, dft_control%nimages)
     923         1002 :       CALL dbcsr_allocate_matrix_set(matrix_ks_aux_fit_dft_kp, dft_control%nspins, dft_control%nimages)
     924         1002 :       CALL dbcsr_allocate_matrix_set(matrix_ks_aux_fit_hfx_kp, dft_control%nspins, dft_control%nimages)
     925              : 
     926         2186 :       DO ispin = 1, dft_control%nspins
     927         6948 :          DO ic = 1, dft_control%nimages
     928         4762 :             ALLOCATE (matrix_ks_aux_fit_kp(ispin, ic)%matrix)
     929              :             CALL dbcsr_create(matrix_ks_aux_fit_kp(ispin, ic)%matrix, template=matrix_s_aux_fit_kp(1, ic)%matrix, &
     930         4762 :                               name="KOHN-SHAM_MATRIX for ADMM")
     931         4762 :             CALL cp_dbcsr_alloc_block_from_nbl(matrix_ks_aux_fit_kp(ispin, ic)%matrix, admm_env%sab_aux_fit)
     932         4762 :             CALL dbcsr_set(matrix_ks_aux_fit_kp(ispin, ic)%matrix, 0.0_dp)
     933              : 
     934         4762 :             ALLOCATE (matrix_ks_aux_fit_dft_kp(ispin, ic)%matrix)
     935              :             CALL dbcsr_create(matrix_ks_aux_fit_dft_kp(ispin, ic)%matrix, template=matrix_s_aux_fit_kp(1, 1)%matrix, &
     936         4762 :                               name="KOHN-SHAM_MATRIX for ADMM")
     937         4762 :             CALL cp_dbcsr_alloc_block_from_nbl(matrix_ks_aux_fit_dft_kp(ispin, ic)%matrix, admm_env%sab_aux_fit)
     938         4762 :             CALL dbcsr_set(matrix_ks_aux_fit_dft_kp(ispin, ic)%matrix, 0.0_dp)
     939              : 
     940         4762 :             ALLOCATE (matrix_ks_aux_fit_hfx_kp(ispin, ic)%matrix)
     941              :             CALL dbcsr_create(matrix_ks_aux_fit_hfx_kp(ispin, ic)%matrix, template=matrix_s_aux_fit_kp(1, 1)%matrix, &
     942         4762 :                               name="KOHN-SHAM_MATRIX for ADMM")
     943         4762 :             CALL cp_dbcsr_alloc_block_from_nbl(matrix_ks_aux_fit_hfx_kp(ispin, ic)%matrix, admm_env%sab_aux_fit)
     944         5946 :             CALL dbcsr_set(matrix_ks_aux_fit_hfx_kp(ispin, ic)%matrix, 0.0_dp)
     945              :          END DO
     946              :       END DO
     947              : 
     948              :       CALL set_admm_env(admm_env, &
     949              :                         matrix_ks_aux_fit_kp=matrix_ks_aux_fit_kp, &
     950              :                         matrix_ks_aux_fit_dft_kp=matrix_ks_aux_fit_dft_kp, &
     951         1002 :                         matrix_ks_aux_fit_hfx_kp=matrix_ks_aux_fit_hfx_kp)
     952              : 
     953         1002 :       CALL timestop(handle)
     954              : 
     955         1002 :    END SUBROUTINE admm_alloc_ks_matrices
     956              : 
     957              : ! **************************************************************************************************
     958              : !> \brief Add the HFX K-point contribution to the real-space Hamiltonians
     959              : !> \param qs_env ...
     960              : !> \param matrix_ks ...
     961              : !> \param energy ...
     962              : !> \param calculate_forces ...
     963              : ! **************************************************************************************************
     964          276 :    SUBROUTINE hfx_ks_matrix_kp(qs_env, matrix_ks, energy, calculate_forces)
     965              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     966              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_ks
     967              :       TYPE(qs_energy_type), POINTER                      :: energy
     968              :       LOGICAL, INTENT(in)                                :: calculate_forces
     969              : 
     970              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'hfx_ks_matrix_kp'
     971              : 
     972              :       INTEGER                                            :: handle, img, irep, ispin, n_rep_hf, &
     973              :                                                             nimages, nspins
     974              :       LOGICAL                                            :: do_adiabatic_rescaling, &
     975              :                                                             s_mstruct_changed, use_virial
     976              :       REAL(dp)                                           :: eh1, ehfx, eold
     977          276 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: hf_energy
     978          276 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER          :: matrix_ks_aux_fit_im, matrix_ks_im
     979          276 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_h, matrix_ks_aux_fit_hfx_kp, &
     980          276 :                                                             matrix_ks_aux_fit_kp, matrix_ks_orb, &
     981          276 :                                                             rho_ao_orb
     982              :       TYPE(dft_control_type), POINTER                    :: dft_control
     983          276 :       TYPE(hfx_type), DIMENSION(:, :), POINTER           :: x_data
     984              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     985              :       TYPE(pw_env_type), POINTER                         :: pw_env
     986              :       TYPE(pw_poisson_type), POINTER                     :: poisson_env
     987              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     988              :       TYPE(qs_rho_type), POINTER                         :: rho_orb
     989              :       TYPE(section_vals_type), POINTER                   :: adiabatic_rescaling_section, &
     990              :                                                             hfx_sections, input
     991              :       TYPE(virial_type), POINTER                         :: virial
     992              : 
     993          276 :       CALL timeset(routineN, handle)
     994              : 
     995          276 :       NULLIFY (auxbas_pw_pool, dft_control, hfx_sections, input, &
     996          276 :                para_env, poisson_env, pw_env, virial, matrix_ks_im, &
     997          276 :                matrix_ks_orb, rho_ao_orb, matrix_h, matrix_ks_aux_fit_kp, &
     998          276 :                matrix_ks_aux_fit_im, matrix_ks_aux_fit_hfx_kp)
     999              : 
    1000              :       CALL get_qs_env(qs_env=qs_env, &
    1001              :                       dft_control=dft_control, &
    1002              :                       input=input, &
    1003              :                       matrix_h_kp=matrix_h, &
    1004              :                       para_env=para_env, &
    1005              :                       pw_env=pw_env, &
    1006              :                       virial=virial, &
    1007              :                       matrix_ks_im=matrix_ks_im, &
    1008              :                       s_mstruct_changed=s_mstruct_changed, &
    1009          276 :                       x_data=x_data)
    1010              : 
    1011              :       ! No RTP
    1012          276 :       IF (qs_env%run_rtp) CPABORT("No RTP implementation with K-points HFX")
    1013              : 
    1014              :       ! No adiabatic rescaling
    1015          276 :       adiabatic_rescaling_section => section_vals_get_subs_vals(input, "DFT%XC%ADIABATIC_RESCALING")
    1016          276 :       CALL section_vals_get(adiabatic_rescaling_section, explicit=do_adiabatic_rescaling)
    1017          276 :       IF (do_adiabatic_rescaling) CPABORT("No adiabatic rescaling implementation with K-points HFX")
    1018              : 
    1019          276 :       IF (dft_control%do_admm) THEN
    1020              :          CALL get_admm_env(qs_env%admm_env, matrix_ks_aux_fit_kp=matrix_ks_aux_fit_kp, &
    1021              :                            matrix_ks_aux_fit_im=matrix_ks_aux_fit_im, &
    1022          154 :                            matrix_ks_aux_fit_hfx_kp=matrix_ks_aux_fit_hfx_kp)
    1023              :       END IF
    1024              : 
    1025          276 :       nspins = dft_control%nspins
    1026          276 :       nimages = dft_control%nimages
    1027              : 
    1028          276 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
    1029          406 :       IF (use_virial .AND. calculate_forces) virial%pv_fock_4c = 0.0_dp
    1030              : 
    1031          276 :       hfx_sections => section_vals_get_subs_vals(input, "DFT%XC%HF")
    1032          276 :       CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
    1033              : 
    1034              :       ! *** Initialize the auxiliary ks matrix to zero if required
    1035          276 :       IF (dft_control%do_admm) THEN
    1036          332 :          DO ispin = 1, nspins
    1037        10396 :             DO img = 1, nimages
    1038        10242 :                CALL dbcsr_set(matrix_ks_aux_fit_kp(ispin, img)%matrix, 0.0_dp)
    1039              :             END DO
    1040              :          END DO
    1041              :       END IF
    1042          640 :       DO ispin = 1, nspins
    1043        15334 :          DO img = 1, nimages
    1044        15058 :             CALL dbcsr_set(matrix_ks(ispin, img)%matrix, 0.0_dp)
    1045              :          END DO
    1046              :       END DO
    1047              : 
    1048          828 :       ALLOCATE (hf_energy(n_rep_hf))
    1049              : 
    1050          276 :       eold = 0.0_dp
    1051              : 
    1052          552 :       DO irep = 1, n_rep_hf
    1053              : 
    1054              :          ! fetch the correct matrices for normal HFX or ADMM
    1055          276 :          IF (dft_control%do_admm) THEN
    1056          154 :             CALL get_admm_env(qs_env%admm_env, matrix_ks_aux_fit_kp=matrix_ks_orb, rho_aux_fit=rho_orb)
    1057              :          ELSE
    1058          122 :             CALL get_qs_env(qs_env=qs_env, matrix_ks_kp=matrix_ks_orb, rho=rho_orb)
    1059              :          END IF
    1060          276 :          CALL qs_rho_get(rho_struct=rho_orb, rho_ao_kp=rho_ao_orb)
    1061              : 
    1062              :          ! Finally the real hfx calulation
    1063              :          ehfx = 0.0_dp
    1064              : 
    1065          276 :          IF (.NOT. x_data(irep, 1)%do_hfx_ri) THEN
    1066            0 :             CPABORT("Only RI-HFX is implemented for K-points")
    1067              :          END IF
    1068              : 
    1069              :          CALL hfx_ri_update_ks_kp(qs_env, x_data(irep, 1)%ri_data, matrix_ks_orb, ehfx, &
    1070              :                                   rho_ao_orb, s_mstruct_changed, nspins, &
    1071          276 :                                   x_data(irep, 1)%general_parameter%fraction)
    1072              : 
    1073          276 :          IF (calculate_forces) THEN
    1074              :             !Scale auxiliary density matrix for ADMMP (see Merlot2014) with gsi(ispin) to scale force
    1075           50 :             IF (dft_control%do_admm) THEN
    1076           30 :                CALL scale_dm(qs_env, rho_ao_orb, scale_back=.FALSE.)
    1077              :             END IF
    1078              : 
    1079              :             CALL hfx_ri_update_forces_kp(qs_env, x_data(irep, 1)%ri_data, nspins, &
    1080              :                                          x_data(irep, 1)%general_parameter%fraction, &
    1081           50 :                                          rho_ao_orb, use_virial=use_virial)
    1082              : 
    1083           50 :             IF (dft_control%do_admm) THEN
    1084           30 :                CALL scale_dm(qs_env, rho_ao_orb, scale_back=.TRUE.)
    1085              :             END IF
    1086              :          END IF
    1087              : 
    1088          276 :          CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, poisson_env=poisson_env)
    1089          276 :          eh1 = ehfx - eold
    1090          276 :          CALL pw_hfx(qs_env, eh1, hfx_sections, poisson_env, auxbas_pw_pool, irep)
    1091          828 :          eold = ehfx
    1092              : 
    1093              :       END DO
    1094              : 
    1095              :       ! *** Set the total HFX energy
    1096          276 :       energy%ex = ehfx
    1097              : 
    1098              :       ! *** Add Core-Hamiltonian-Matrix ***
    1099          640 :       DO ispin = 1, nspins
    1100        15334 :          DO img = 1, nimages
    1101              :             CALL dbcsr_add(matrix_ks(ispin, img)%matrix, matrix_h(1, img)%matrix, &
    1102        15058 :                            1.0_dp, 1.0_dp)
    1103              :          END DO
    1104              :       END DO
    1105          276 :       IF (use_virial .AND. calculate_forces) THEN
    1106          130 :          virial%pv_exx = virial%pv_exx - virial%pv_fock_4c
    1107          130 :          virial%pv_virial = virial%pv_virial - virial%pv_fock_4c
    1108           10 :          virial%pv_calculate = .FALSE.
    1109              :       END IF
    1110              : 
    1111              :       !update the hfx aux_fit matrix
    1112          276 :       IF (dft_control%do_admm) THEN
    1113          332 :          DO ispin = 1, nspins
    1114        10396 :             DO img = 1, nimages
    1115              :                CALL dbcsr_add(matrix_ks_aux_fit_hfx_kp(ispin, img)%matrix, matrix_ks_aux_fit_kp(ispin, img)%matrix, &
    1116        10242 :                               0.0_dp, 1.0_dp)
    1117              :             END DO
    1118              :          END DO
    1119              :       END IF
    1120              : 
    1121          276 :       CALL timestop(handle)
    1122              : 
    1123         1104 :    END SUBROUTINE hfx_ks_matrix_kp
    1124              : 
    1125              : ! **************************************************************************************************
    1126              : !> \brief Add the hfx contributions to the Hamiltonian
    1127              : !>
    1128              : !> \param qs_env ...
    1129              : !> \param matrix_ks ...
    1130              : !> \param rho ...
    1131              : !> \param energy ...
    1132              : !> \param calculate_forces ...
    1133              : !> \param just_energy ...
    1134              : !> \param v_rspace_new ...
    1135              : !> \param v_tau_rspace ...
    1136              : !> \param ext_xc_section ...
    1137              : !> \par History
    1138              : !>     refactoring 03-2011 [MI]
    1139              : ! **************************************************************************************************
    1140              : 
    1141        30734 :    SUBROUTINE hfx_ks_matrix(qs_env, matrix_ks, rho, energy, calculate_forces, &
    1142              :                             just_energy, v_rspace_new, v_tau_rspace, ext_xc_section)
    1143              : 
    1144              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1145              :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_ks
    1146              :       TYPE(qs_rho_type), POINTER                         :: rho
    1147              :       TYPE(qs_energy_type), POINTER                      :: energy
    1148              :       LOGICAL, INTENT(in)                                :: calculate_forces, just_energy
    1149              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: v_rspace_new, v_tau_rspace
    1150              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: ext_xc_section
    1151              : 
    1152              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'hfx_ks_matrix'
    1153              : 
    1154              :       INTEGER                                            :: handle, img, irep, ispin, mspin, &
    1155              :                                                             n_rep_hf, nimages, ns, nspins
    1156              :       LOGICAL                                            :: distribute_fock_matrix, &
    1157              :                                                             do_adiabatic_rescaling, &
    1158              :                                                             hfx_treat_lsd_in_core, &
    1159              :                                                             s_mstruct_changed, use_virial
    1160              :       REAL(dp)                                           :: eh1, ehfx, ehfxrt, eold
    1161        30734 :       REAL(dp), ALLOCATABLE, DIMENSION(:)                :: hf_energy
    1162        30734 :       TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks_1d, matrix_ks_aux_fit, &
    1163        30734 :          matrix_ks_aux_fit_hfx, matrix_ks_aux_fit_im, matrix_ks_im, rho_ao_1d, rho_ao_resp
    1164        30734 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_h, matrix_h_im, matrix_ks_orb, &
    1165        30734 :                                                             rho_ao_orb
    1166              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1167        30734 :       TYPE(hfx_type), DIMENSION(:, :), POINTER           :: x_data
    1168        30734 :       TYPE(mo_set_type), DIMENSION(:), POINTER           :: mo_array
    1169              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1170              :       TYPE(pw_env_type), POINTER                         :: pw_env
    1171              :       TYPE(pw_poisson_type), POINTER                     :: poisson_env
    1172              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    1173              :       TYPE(qs_rho_type), POINTER                         :: rho_orb
    1174              :       TYPE(rt_prop_type), POINTER                        :: rtp
    1175              :       TYPE(section_vals_type), POINTER                   :: adiabatic_rescaling_section, &
    1176              :                                                             hfx_sections, input
    1177              :       TYPE(virial_type), POINTER                         :: virial
    1178              : 
    1179        30734 :       CALL timeset(routineN, handle)
    1180              : 
    1181        30734 :       NULLIFY (auxbas_pw_pool, dft_control, hfx_sections, input, &
    1182        30734 :                para_env, poisson_env, pw_env, virial, matrix_ks_im, &
    1183        30734 :                matrix_ks_orb, rho_ao_orb, matrix_h, matrix_h_im, matrix_ks_aux_fit, &
    1184        30734 :                matrix_ks_aux_fit_im, matrix_ks_aux_fit_hfx)
    1185              : 
    1186              :       CALL get_qs_env(qs_env=qs_env, &
    1187              :                       dft_control=dft_control, &
    1188              :                       input=input, &
    1189              :                       matrix_h_kp=matrix_h, &
    1190              :                       matrix_h_im_kp=matrix_h_im, &
    1191              :                       para_env=para_env, &
    1192              :                       pw_env=pw_env, &
    1193              :                       virial=virial, &
    1194              :                       matrix_ks_im=matrix_ks_im, &
    1195              :                       s_mstruct_changed=s_mstruct_changed, &
    1196        30734 :                       x_data=x_data)
    1197              : 
    1198        30734 :       IF (dft_control%do_admm) THEN
    1199              :          CALL get_admm_env(qs_env%admm_env, mos_aux_fit=mo_array, matrix_ks_aux_fit=matrix_ks_aux_fit, &
    1200        13228 :                            matrix_ks_aux_fit_im=matrix_ks_aux_fit_im, matrix_ks_aux_fit_hfx=matrix_ks_aux_fit_hfx)
    1201              :       ELSE
    1202        17506 :          CALL get_qs_env(qs_env=qs_env, mos=mo_array)
    1203              :       END IF
    1204              : 
    1205        30734 :       nspins = dft_control%nspins
    1206        30734 :       nimages = dft_control%nimages
    1207              : 
    1208        30734 :       use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
    1209              : 
    1210        31046 :       IF (use_virial .AND. calculate_forces) virial%pv_fock_4c = 0.0_dp
    1211              : 
    1212        30734 :       hfx_sections => section_vals_get_subs_vals(input, "DFT%XC%HF")
    1213        30734 :       IF (PRESENT(ext_xc_section)) hfx_sections => section_vals_get_subs_vals(ext_xc_section, "HF")
    1214              : 
    1215        30734 :       CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
    1216              :       CALL section_vals_val_get(hfx_sections, "TREAT_LSD_IN_CORE", l_val=hfx_treat_lsd_in_core, &
    1217        30734 :                                 i_rep_section=1)
    1218        30734 :       adiabatic_rescaling_section => section_vals_get_subs_vals(input, "DFT%XC%ADIABATIC_RESCALING")
    1219        30734 :       CALL section_vals_get(adiabatic_rescaling_section, explicit=do_adiabatic_rescaling)
    1220              : 
    1221              :       ! *** Initialize the auxiliary ks matrix to zero if required
    1222        30734 :       IF (dft_control%do_admm) THEN
    1223        28966 :          DO ispin = 1, nspins
    1224        28966 :             CALL dbcsr_set(matrix_ks_aux_fit(ispin)%matrix, 0.0_dp)
    1225              :          END DO
    1226              :       END IF
    1227        67470 :       DO ispin = 1, nspins
    1228       104206 :          DO img = 1, nimages
    1229        73472 :             CALL dbcsr_set(matrix_ks(ispin, img)%matrix, 0.0_dp)
    1230              :          END DO
    1231              :       END DO
    1232              : 
    1233        30734 :       CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
    1234              : 
    1235        92202 :       ALLOCATE (hf_energy(n_rep_hf))
    1236              : 
    1237        30734 :       eold = 0.0_dp
    1238              : 
    1239        61524 :       DO irep = 1, n_rep_hf
    1240              :          ! Remember: Vhfx is added, energy is calclulated from total Vhfx,
    1241              :          ! so energy of last iteration is correct
    1242              : 
    1243        30790 :          IF (do_adiabatic_rescaling .AND. hfx_treat_lsd_in_core) THEN
    1244            0 :             CPABORT("HFX_TREAT_LSD_IN_CORE not implemented for adiabatically rescaled hybrids")
    1245              :          END IF
    1246              :          ! everything is calculated with adiabatic rescaling but the potential is not added in a first step
    1247        30790 :          distribute_fock_matrix = .NOT. do_adiabatic_rescaling
    1248              : 
    1249        30790 :          mspin = 1
    1250        30790 :          IF (hfx_treat_lsd_in_core) mspin = nspins
    1251              : 
    1252              :          ! fetch the correct matrices for normal HFX or ADMM
    1253        30790 :          IF (dft_control%do_admm) THEN
    1254        13228 :             CALL get_admm_env(qs_env%admm_env, matrix_ks_aux_fit=matrix_ks_1d, rho_aux_fit=rho_orb)
    1255        13228 :             ns = SIZE(matrix_ks_1d)
    1256        13228 :             matrix_ks_orb(1:ns, 1:1) => matrix_ks_1d(1:ns)
    1257              :          ELSE
    1258        17562 :             CALL get_qs_env(qs_env=qs_env, matrix_ks_kp=matrix_ks_orb, rho=rho_orb)
    1259              :          END IF
    1260        30790 :          CALL qs_rho_get(rho_struct=rho_orb, rho_ao_kp=rho_ao_orb)
    1261              :          ! Finally the real hfx calulation
    1262        30790 :          ehfx = 0.0_dp
    1263              : 
    1264        30790 :          IF (x_data(irep, 1)%do_hfx_ri) THEN
    1265              : 
    1266              :             CALL hfx_ri_update_ks(qs_env, x_data(irep, 1)%ri_data, matrix_ks_orb, ehfx, &
    1267              :                                   mo_array, rho_ao_orb, &
    1268              :                                   s_mstruct_changed, nspins, &
    1269         1372 :                                   x_data(irep, 1)%general_parameter%fraction)
    1270         1372 :             IF (dft_control%do_admm) THEN
    1271              :                !for ADMMS, we need the exchange matrix k(d) for both spins
    1272          382 :                DO ispin = 1, nspins
    1273              :                   CALL dbcsr_copy(matrix_ks_aux_fit_hfx(ispin)%matrix, matrix_ks_orb(ispin, 1)%matrix, &
    1274          382 :                                   name="HF exch. part of matrix_ks_aux_fit for ADMMS")
    1275              :                END DO
    1276              :             END IF
    1277              : 
    1278              :          ELSE
    1279              : 
    1280        58848 :             DO ispin = 1, mspin
    1281              :                CALL integrate_four_center(qs_env, x_data, matrix_ks_orb, eh1, rho_ao_orb, hfx_sections, &
    1282              :                                           para_env, s_mstruct_changed, irep, distribute_fock_matrix, &
    1283        29430 :                                           ispin=ispin)
    1284        58848 :                ehfx = ehfx + eh1
    1285              :             END DO
    1286              :          END IF
    1287              : 
    1288        30790 :          IF (calculate_forces .AND. .NOT. do_adiabatic_rescaling) THEN
    1289              :             !Scale auxiliary density matrix for ADMMP (see Merlot2014) with gsi(ispin) to scale force
    1290          810 :             IF (dft_control%do_admm) THEN
    1291          288 :                CALL scale_dm(qs_env, rho_ao_orb, scale_back=.FALSE.)
    1292              :             END IF
    1293          810 :             NULLIFY (rho_ao_resp)
    1294              : 
    1295          810 :             IF (x_data(irep, 1)%do_hfx_ri) THEN
    1296              : 
    1297              :                CALL hfx_ri_update_forces(qs_env, x_data(irep, 1)%ri_data, nspins, &
    1298              :                                          x_data(irep, 1)%general_parameter%fraction, &
    1299              :                                          rho_ao=rho_ao_orb, mos=mo_array, &
    1300              :                                          rho_ao_resp=rho_ao_resp, &
    1301           50 :                                          use_virial=use_virial)
    1302              : 
    1303              :             ELSE
    1304              : 
    1305              :                CALL derivatives_four_center(qs_env, rho_ao_orb, rho_ao_resp, hfx_sections, &
    1306          760 :                                             para_env, irep, use_virial)
    1307              : 
    1308              :             END IF
    1309              : 
    1310              :             !Scale auxiliary density matrix for ADMMP back with 1/gsi(ispin)
    1311          810 :             IF (dft_control%do_admm) THEN
    1312          288 :                CALL scale_dm(qs_env, rho_ao_orb, scale_back=.TRUE.)
    1313              :             END IF
    1314              :          END IF
    1315              : 
    1316              :          !! If required, the calculation of the forces will be done later with adiabatic rescaling
    1317        30790 :          IF (do_adiabatic_rescaling) hf_energy(irep) = ehfx
    1318              : 
    1319              :          ! special case RTP/EMD we have a full complex density and HFX has a contribution from the imaginary part
    1320        30790 :          ehfxrt = 0.0_dp
    1321        30790 :          IF (qs_env%run_rtp) THEN
    1322              : 
    1323          508 :             CALL get_qs_env(qs_env=qs_env, rtp=rtp)
    1324         1086 :             DO ispin = 1, nspins
    1325         1086 :                CALL dbcsr_set(matrix_ks_im(ispin)%matrix, 0.0_dp)
    1326              :             END DO
    1327          508 :             IF (dft_control%do_admm) THEN
    1328              :                ! matrix_ks_orb => matrix_ks_aux_fit_im
    1329          114 :                ns = SIZE(matrix_ks_aux_fit_im)
    1330          114 :                matrix_ks_orb(1:ns, 1:1) => matrix_ks_aux_fit_im(1:ns)
    1331          266 :                DO ispin = 1, nspins
    1332          266 :                   CALL dbcsr_set(matrix_ks_aux_fit_im(ispin)%matrix, 0.0_dp)
    1333              :                END DO
    1334              :             ELSE
    1335              :                ! matrix_ks_orb => matrix_ks_im
    1336          394 :                ns = SIZE(matrix_ks_im)
    1337          394 :                matrix_ks_orb(1:ns, 1:1) => matrix_ks_im(1:ns)
    1338              :             END IF
    1339              : 
    1340          508 :             CALL qs_rho_get(rho_orb, rho_ao_im=rho_ao_1d)
    1341          508 :             ns = SIZE(rho_ao_1d)
    1342          508 :             rho_ao_orb(1:ns, 1:1) => rho_ao_1d(1:ns)
    1343              : 
    1344          508 :             ehfxrt = 0.0_dp
    1345              : 
    1346          508 :             IF (x_data(irep, 1)%do_hfx_ri) THEN
    1347              :                CALL hfx_ri_update_ks(qs_env, x_data(irep, 1)%ri_data, matrix_ks_orb, ehfx, &
    1348              :                                      mo_array, rho_ao_orb, &
    1349              :                                      .FALSE., nspins, &
    1350            0 :                                      x_data(irep, 1)%general_parameter%fraction)
    1351            0 :                IF (dft_control%do_admm) THEN
    1352              :                   !for ADMMS, we need the exchange matrix k(d) for both spins
    1353            0 :                   DO ispin = 1, nspins
    1354              :                      CALL dbcsr_copy(matrix_ks_aux_fit_hfx(ispin)%matrix, matrix_ks_orb(ispin, 1)%matrix, &
    1355            0 :                                      name="HF exch. part of matrix_ks_aux_fit for ADMMS")
    1356              :                   END DO
    1357              :                END IF
    1358              : 
    1359              :             ELSE
    1360         1016 :                DO ispin = 1, mspin
    1361              :                   CALL integrate_four_center(qs_env, x_data, matrix_ks_orb, eh1, rho_ao_orb, hfx_sections, &
    1362              :                                              para_env, .FALSE., irep, distribute_fock_matrix, &
    1363          508 :                                              ispin=ispin)
    1364         1016 :                   ehfxrt = ehfxrt + eh1
    1365              :                END DO
    1366              :             END IF
    1367              : 
    1368          508 :             IF (calculate_forces .AND. .NOT. do_adiabatic_rescaling) THEN
    1369          242 :                NULLIFY (rho_ao_resp)
    1370              : 
    1371          242 :                IF (x_data(irep, 1)%do_hfx_ri) THEN
    1372              : 
    1373              :                   CALL hfx_ri_update_forces(qs_env, x_data(irep, 1)%ri_data, nspins, &
    1374              :                                             x_data(irep, 1)%general_parameter%fraction, &
    1375              :                                             rho_ao=rho_ao_orb, mos=mo_array, &
    1376            0 :                                             use_virial=use_virial)
    1377              : 
    1378              :                ELSE
    1379              :                   CALL derivatives_four_center(qs_env, rho_ao_orb, rho_ao_resp, hfx_sections, &
    1380          242 :                                                para_env, irep, use_virial)
    1381              :                END IF
    1382              :             END IF
    1383              : 
    1384              :             !! If required, the calculation of the forces will be done later with adiabatic rescaling
    1385          508 :             IF (do_adiabatic_rescaling) hf_energy(irep) = ehfx + ehfxrt
    1386              : 
    1387          508 :             IF (dft_control%rtp_control%velocity_gauge) THEN
    1388            0 :                CPASSERT(ASSOCIATED(matrix_h_im))
    1389            0 :                DO ispin = 1, nspins
    1390              :                   CALL dbcsr_add(matrix_ks_im(ispin)%matrix, matrix_h_im(1, 1)%matrix, &
    1391            0 :                                  1.0_dp, 1.0_dp)
    1392              :                END DO
    1393              :             END IF
    1394              : 
    1395              :          END IF
    1396              : 
    1397        61524 :          IF (.NOT. qs_env%run_rtp) THEN
    1398              :             CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
    1399        30282 :                             poisson_env=poisson_env)
    1400        30282 :             eh1 = ehfx - eold
    1401        30282 :             CALL pw_hfx(qs_env, eh1, hfx_sections, poisson_env, auxbas_pw_pool, irep)
    1402        30282 :             eold = ehfx
    1403              :          END IF
    1404              : 
    1405              :       END DO
    1406              : 
    1407              :       ! *** Set the total HFX energy
    1408        30734 :       energy%ex = ehfx + ehfxrt
    1409              : 
    1410              :       ! *** Add Core-Hamiltonian-Matrix ***
    1411        67470 :       DO ispin = 1, nspins
    1412       104206 :          DO img = 1, nimages
    1413              :             CALL dbcsr_add(matrix_ks(ispin, img)%matrix, matrix_h(1, img)%matrix, &
    1414        73472 :                            1.0_dp, 1.0_dp)
    1415              :          END DO
    1416              :       END DO
    1417        30734 :       IF (use_virial .AND. calculate_forces) THEN
    1418          312 :          virial%pv_exx = virial%pv_exx - virial%pv_fock_4c
    1419          312 :          virial%pv_virial = virial%pv_virial - virial%pv_fock_4c
    1420           24 :          virial%pv_calculate = .FALSE.
    1421              :       END IF
    1422              : 
    1423              :       !! If we perform adiabatic rescaling we are now able to rescale the xc-potential
    1424        30734 :       IF (do_adiabatic_rescaling) THEN
    1425              :          CALL rescale_xc_potential(qs_env, matrix_ks, rho, energy, v_rspace_new, v_tau_rspace, &
    1426           44 :                                    hf_energy, just_energy, calculate_forces, use_virial)
    1427              :       END IF ! do_adiabatic_rescaling
    1428              : 
    1429              :       !update the hfx aux_fit matrixIF (dft_control%do_admm) THEN
    1430        30734 :       IF (dft_control%do_admm) THEN
    1431        28966 :          DO ispin = 1, nspins
    1432              :             CALL dbcsr_add(matrix_ks_aux_fit_hfx(ispin)%matrix, matrix_ks_aux_fit(ispin)%matrix, &
    1433        28966 :                            0.0_dp, 1.0_dp)
    1434              :          END DO
    1435              :       END IF
    1436              : 
    1437        30734 :       CALL timestop(handle)
    1438              : 
    1439       153670 :    END SUBROUTINE hfx_ks_matrix
    1440              : 
    1441              : ! **************************************************************************************************
    1442              : !> \brief This routine modifies the xc section depending on the potential type
    1443              : !>        used for the HF exchange and the resulting correction term. Currently
    1444              : !>        three types of corrections are implemented:
    1445              : !>
    1446              : !>        coulomb:     Ex,hf = Ex,hf' + (PBEx-PBEx')
    1447              : !>        shortrange:  Ex,hf = Ex,hf' + (XWPBEX-XWPBEX')
    1448              : !>        truncated:   Ex,hf = Ex,hf' + ( (XWPBEX0-PBE_HOLE_TC_LR) -(XWPBEX0-PBE_HOLE_TC_LR)' )
    1449              : !>
    1450              : !>        with ' denoting the auxiliary basis set and
    1451              : !>
    1452              : !>          PBEx:           PBE exchange functional
    1453              : !>          XWPBEX:         PBE exchange hole for short-range potential (erfc(omega*r)/r)
    1454              : !>          XWPBEX0:        PBE exchange hole for standard coulomb potential
    1455              : !>          PBE_HOLE_TC_LR: PBE exchange hole for longrange truncated coulomb potential
    1456              : !>
    1457              : !>        Above explanation is correct for the deafult case. If a specific functional is requested
    1458              : !>        for the correction term (cfun), we get
    1459              : !>        Ex,hf = Ex,hf' + (cfun-cfun')
    1460              : !>        for all cases of operators.
    1461              : !>
    1462              : !> \param x_data ...
    1463              : !> \param xc_section the original xc_section
    1464              : !> \param admm_env the ADMM environment
    1465              : !> \par History
    1466              : !>      12.2009 created [Manuel Guidon]
    1467              : !>      05.2021 simplify for case of no correction [JGH]
    1468              : !> \author Manuel Guidon
    1469              : ! **************************************************************************************************
    1470          554 :    SUBROUTINE create_admm_xc_section(x_data, xc_section, admm_env)
    1471              :       TYPE(hfx_type), DIMENSION(:, :), POINTER           :: x_data
    1472              :       TYPE(section_vals_type), POINTER                   :: xc_section
    1473              :       TYPE(admm_type), POINTER                           :: admm_env
    1474              : 
    1475              :       LOGICAL, PARAMETER                                 :: debug_functional = .FALSE.
    1476              : #if defined (__LIBXC)
    1477              :       REAL(KIND=dp), PARAMETER :: x_factor_c = 0.930525736349100025_dp
    1478              : #endif
    1479              : 
    1480              :       CHARACTER(LEN=20)                                  :: name_x_func
    1481              :       INTEGER                                            :: hfx_potential_type, ifun, iounit, nfun
    1482              :       LOGICAL                                            :: funct_found
    1483              :       REAL(dp)                                           :: cutoff_radius, hfx_fraction, omega, &
    1484              :                                                             scale_coulomb, scale_longrange, scale_x
    1485              :       TYPE(cp_logger_type), POINTER                      :: logger
    1486              :       TYPE(section_vals_type), POINTER                   :: xc_fun, xc_fun_section
    1487              : 
    1488          554 :       logger => cp_get_default_logger()
    1489          554 :       NULLIFY (admm_env%xc_section_aux, admm_env%xc_section_primary)
    1490              : 
    1491              :       !! ** Duplicate existing xc-section
    1492          554 :       CALL section_vals_duplicate(xc_section, admm_env%xc_section_aux)
    1493          554 :       CALL section_vals_duplicate(xc_section, admm_env%xc_section_primary)
    1494              :       !** Now modify the auxiliary basis
    1495              :       !** First remove all functionals
    1496          554 :       xc_fun_section => section_vals_get_subs_vals(admm_env%xc_section_aux, "XC_FUNCTIONAL")
    1497              : 
    1498              :       !* Overwrite possible shortcut
    1499              :       CALL section_vals_val_set(xc_fun_section, "_SECTION_PARAMETERS_", &
    1500          554 :                                 i_val=xc_funct_no_shortcut)
    1501              : 
    1502              :       !** Get number of Functionals in the list
    1503          554 :       ifun = 0
    1504          554 :       nfun = 0
    1505          444 :       DO
    1506          998 :          ifun = ifun + 1
    1507          998 :          xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    1508          998 :          IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    1509          444 :          nfun = nfun + 1
    1510              :       END DO
    1511              : 
    1512              :       ifun = 0
    1513          998 :       DO ifun = 1, nfun
    1514          444 :          xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=1)
    1515          444 :          IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    1516          998 :          CALL section_vals_remove_values(xc_fun)
    1517              :       END DO
    1518              : 
    1519          554 :       IF (ASSOCIATED(x_data)) THEN
    1520          544 :          hfx_potential_type = x_data(1, 1)%potential_parameter%potential_type
    1521          544 :          hfx_fraction = x_data(1, 1)%general_parameter%fraction
    1522              :       ELSE
    1523           10 :          CPWARN("ADMM requested without a DFT%XC%HF section. It will be ignored for the SCF.")
    1524           10 :          admm_env%aux_exch_func = do_admm_aux_exch_func_none
    1525              :       END IF
    1526              : 
    1527              :       !in case of no admm exchange corr., no auxiliary exchange functional needed
    1528          554 :       IF (admm_env%aux_exch_func == do_admm_aux_exch_func_none) THEN
    1529              :          CALL section_vals_val_set(xc_fun_section, "_SECTION_PARAMETERS_", &
    1530          124 :                                    i_val=xc_none)
    1531              :          hfx_fraction = 0.0_dp
    1532              :       ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_default) THEN
    1533              :          ! default PBE Functional
    1534              :          !! ** Add functionals evaluated with auxiliary basis
    1535          194 :          SELECT CASE (hfx_potential_type)
    1536              :          CASE (do_potential_coulomb)
    1537              :             CALL section_vals_val_set(xc_fun_section, "PBE%_SECTION_PARAMETERS_", &
    1538          194 :                                       l_val=.TRUE.)
    1539              :             CALL section_vals_val_set(xc_fun_section, "PBE%SCALE_X", &
    1540          194 :                                       r_val=-hfx_fraction)
    1541              :             CALL section_vals_val_set(xc_fun_section, "PBE%SCALE_C", &
    1542          194 :                                       r_val=0.0_dp)
    1543              :          CASE (do_potential_short)
    1544            6 :             omega = x_data(1, 1)%potential_parameter%omega
    1545              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
    1546            6 :                                       l_val=.TRUE.)
    1547              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
    1548            6 :                                       r_val=-hfx_fraction)
    1549              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
    1550            6 :                                       r_val=0.0_dp)
    1551              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
    1552            6 :                                       r_val=omega)
    1553              :          CASE (do_potential_truncated)
    1554           50 :             cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
    1555              :             CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
    1556           50 :                                       l_val=.TRUE.)
    1557              :             CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    1558           50 :                                       r_val=hfx_fraction)
    1559              :             CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
    1560           50 :                                       r_val=cutoff_radius)
    1561              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
    1562           50 :                                       l_val=.TRUE.)
    1563              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
    1564           50 :                                       r_val=0.0_dp)
    1565              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
    1566           50 :                                       r_val=-hfx_fraction)
    1567              :          CASE (do_potential_long)
    1568            2 :             omega = x_data(1, 1)%potential_parameter%omega
    1569              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
    1570            2 :                                       l_val=.TRUE.)
    1571              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
    1572            2 :                                       r_val=hfx_fraction)
    1573              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
    1574            2 :                                       r_val=-hfx_fraction)
    1575              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
    1576            2 :                                       r_val=omega)
    1577              :          CASE (do_potential_mix_cl)
    1578            2 :             omega = x_data(1, 1)%potential_parameter%omega
    1579            2 :             scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
    1580            2 :             scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
    1581              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
    1582            2 :                                       l_val=.TRUE.)
    1583              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
    1584            2 :                                       r_val=hfx_fraction*scale_longrange)
    1585              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
    1586            2 :                                       r_val=-hfx_fraction*(scale_longrange + scale_coulomb))
    1587              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
    1588            2 :                                       r_val=omega)
    1589              :          CASE (do_potential_mix_cl_trunc)
    1590            2 :             omega = x_data(1, 1)%potential_parameter%omega
    1591            2 :             cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
    1592            2 :             scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
    1593            2 :             scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
    1594              :             CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
    1595            2 :                                       l_val=.TRUE.)
    1596              :             CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    1597            2 :                                       r_val=hfx_fraction*(scale_longrange + scale_coulomb))
    1598              :             CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
    1599            2 :                                       r_val=cutoff_radius)
    1600              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
    1601            2 :                                       l_val=.TRUE.)
    1602              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
    1603            2 :                                       r_val=hfx_fraction*scale_longrange)
    1604              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
    1605            2 :                                       r_val=-hfx_fraction*(scale_longrange + scale_coulomb))
    1606              :             CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
    1607            2 :                                       r_val=omega)
    1608              :          CASE DEFAULT
    1609          256 :             CPABORT("Unknown potential operator!")
    1610              :          END SELECT
    1611              : 
    1612              :          !** Now modify the functionals for the primary basis
    1613          256 :          xc_fun_section => section_vals_get_subs_vals(admm_env%xc_section_primary, "XC_FUNCTIONAL")
    1614              :          !* Overwrite possible shortcut
    1615              :          CALL section_vals_val_set(xc_fun_section, "_SECTION_PARAMETERS_", &
    1616          256 :                                    i_val=xc_funct_no_shortcut)
    1617              : 
    1618          194 :          SELECT CASE (hfx_potential_type)
    1619              :          CASE (do_potential_coulomb)
    1620          194 :             ifun = 0
    1621          194 :             funct_found = .FALSE.
    1622              :             DO
    1623          356 :                ifun = ifun + 1
    1624          356 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    1625          356 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    1626          356 :                IF (xc_fun%section%name == "PBE") THEN
    1627          156 :                   funct_found = .TRUE.
    1628              :                END IF
    1629              :             END DO
    1630          194 :             IF (.NOT. funct_found) THEN
    1631              :                CALL section_vals_val_set(xc_fun_section, "PBE%_SECTION_PARAMETERS_", &
    1632           38 :                                          l_val=.TRUE.)
    1633              :                CALL section_vals_val_set(xc_fun_section, "PBE%SCALE_X", &
    1634           38 :                                          r_val=hfx_fraction)
    1635              :                CALL section_vals_val_set(xc_fun_section, "PBE%SCALE_C", &
    1636           38 :                                          r_val=0.0_dp)
    1637              :             ELSE
    1638              :                CALL section_vals_val_get(xc_fun_section, "PBE%SCALE_X", &
    1639          156 :                                          r_val=scale_x)
    1640          156 :                scale_x = scale_x + hfx_fraction
    1641              :                CALL section_vals_val_set(xc_fun_section, "PBE%SCALE_X", &
    1642          156 :                                          r_val=scale_x)
    1643              :             END IF
    1644              :          CASE (do_potential_short)
    1645            6 :             omega = x_data(1, 1)%potential_parameter%omega
    1646            6 :             ifun = 0
    1647            6 :             funct_found = .FALSE.
    1648              :             DO
    1649           18 :                ifun = ifun + 1
    1650           18 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    1651           18 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    1652           18 :                IF (xc_fun%section%name == "XWPBE") THEN
    1653            6 :                   funct_found = .TRUE.
    1654              :                END IF
    1655              :             END DO
    1656            6 :             IF (.NOT. funct_found) THEN
    1657              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
    1658            0 :                                          l_val=.TRUE.)
    1659              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
    1660            0 :                                          r_val=hfx_fraction)
    1661              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
    1662            0 :                                          r_val=0.0_dp)
    1663              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
    1664            0 :                                          r_val=omega)
    1665              :             ELSE
    1666              :                CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X", &
    1667            6 :                                          r_val=scale_x)
    1668            6 :                scale_x = scale_x + hfx_fraction
    1669              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
    1670            6 :                                          r_val=scale_x)
    1671              :             END IF
    1672              :          CASE (do_potential_long)
    1673            2 :             omega = x_data(1, 1)%potential_parameter%omega
    1674            2 :             ifun = 0
    1675            2 :             funct_found = .FALSE.
    1676              :             DO
    1677           10 :                ifun = ifun + 1
    1678           10 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    1679           10 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    1680           10 :                IF (xc_fun%section%name == "XWPBE") THEN
    1681            0 :                   funct_found = .TRUE.
    1682              :                END IF
    1683              :             END DO
    1684            2 :             IF (.NOT. funct_found) THEN
    1685              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
    1686            2 :                                          l_val=.TRUE.)
    1687              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
    1688            2 :                                          r_val=-hfx_fraction)
    1689              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
    1690            2 :                                          r_val=hfx_fraction)
    1691              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
    1692            2 :                                          r_val=omega)
    1693              :             ELSE
    1694              :                CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X", &
    1695            0 :                                          r_val=scale_x)
    1696            0 :                scale_x = scale_x - hfx_fraction
    1697              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
    1698            0 :                                          r_val=scale_x)
    1699              :                CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X0", &
    1700            0 :                                          r_val=scale_x)
    1701            0 :                scale_x = scale_x + hfx_fraction
    1702              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
    1703            0 :                                          r_val=scale_x)
    1704              : 
    1705              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
    1706            0 :                                          r_val=omega)
    1707              :             END IF
    1708              :          CASE (do_potential_truncated)
    1709           50 :             cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
    1710           50 :             ifun = 0
    1711           50 :             funct_found = .FALSE.
    1712              :             DO
    1713           74 :                ifun = ifun + 1
    1714           74 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    1715           74 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    1716           74 :                IF (xc_fun%section%name == "PBE_HOLE_T_C_LR") THEN
    1717            0 :                   funct_found = .TRUE.
    1718              :                END IF
    1719              :             END DO
    1720           50 :             IF (.NOT. funct_found) THEN
    1721              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
    1722           50 :                                          l_val=.TRUE.)
    1723              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    1724           50 :                                          r_val=-hfx_fraction)
    1725              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
    1726           50 :                                          r_val=cutoff_radius)
    1727              :             ELSE
    1728              :                CALL section_vals_val_get(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    1729            0 :                                          r_val=scale_x)
    1730            0 :                scale_x = scale_x - hfx_fraction
    1731              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    1732            0 :                                          r_val=scale_x)
    1733              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
    1734            0 :                                          r_val=cutoff_radius)
    1735              :             END IF
    1736           50 :             ifun = 0
    1737           50 :             funct_found = .FALSE.
    1738              :             DO
    1739          124 :                ifun = ifun + 1
    1740          124 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    1741          124 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    1742          124 :                IF (xc_fun%section%name == "XWPBE") THEN
    1743            0 :                   funct_found = .TRUE.
    1744              :                END IF
    1745              :             END DO
    1746           50 :             IF (.NOT. funct_found) THEN
    1747              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
    1748           50 :                                          l_val=.TRUE.)
    1749              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
    1750           50 :                                          r_val=hfx_fraction)
    1751              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
    1752           50 :                                          r_val=0.0_dp)
    1753              : 
    1754              :             ELSE
    1755              :                CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X0", &
    1756            0 :                                          r_val=scale_x)
    1757            0 :                scale_x = scale_x + hfx_fraction
    1758              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
    1759            0 :                                          r_val=scale_x)
    1760              :             END IF
    1761              :          CASE (do_potential_mix_cl_trunc)
    1762            2 :             cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
    1763            2 :             omega = x_data(1, 1)%potential_parameter%omega
    1764            2 :             scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
    1765            2 :             scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
    1766            2 :             ifun = 0
    1767            2 :             funct_found = .FALSE.
    1768              :             DO
    1769            6 :                ifun = ifun + 1
    1770            6 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    1771            6 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    1772            6 :                IF (xc_fun%section%name == "PBE_HOLE_T_C_LR") THEN
    1773            0 :                   funct_found = .TRUE.
    1774              :                END IF
    1775              :             END DO
    1776            2 :             IF (.NOT. funct_found) THEN
    1777              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
    1778            2 :                                          l_val=.TRUE.)
    1779              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    1780            2 :                                          r_val=-hfx_fraction*(scale_coulomb + scale_longrange))
    1781              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
    1782            2 :                                          r_val=cutoff_radius)
    1783              : 
    1784              :             ELSE
    1785              :                CALL section_vals_val_get(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    1786            0 :                                          r_val=scale_x)
    1787            0 :                scale_x = scale_x - hfx_fraction*(scale_coulomb + scale_longrange)
    1788              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    1789            0 :                                          r_val=scale_x)
    1790              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
    1791            0 :                                          r_val=cutoff_radius)
    1792              :             END IF
    1793            2 :             ifun = 0
    1794            2 :             funct_found = .FALSE.
    1795              :             DO
    1796            8 :                ifun = ifun + 1
    1797            8 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    1798            8 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    1799            8 :                IF (xc_fun%section%name == "XWPBE") THEN
    1800            2 :                   funct_found = .TRUE.
    1801              :                END IF
    1802              :             END DO
    1803            2 :             IF (.NOT. funct_found) THEN
    1804              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
    1805            0 :                                          l_val=.TRUE.)
    1806              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
    1807            0 :                                          r_val=hfx_fraction*(scale_coulomb + scale_longrange))
    1808              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
    1809            0 :                                          r_val=-hfx_fraction*scale_longrange)
    1810              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
    1811            0 :                                          r_val=omega)
    1812              : 
    1813              :             ELSE
    1814              :                CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X0", &
    1815            2 :                                          r_val=scale_x)
    1816            2 :                scale_x = scale_x + hfx_fraction*(scale_coulomb + scale_longrange)
    1817              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
    1818            2 :                                          r_val=scale_x)
    1819              :                CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X", &
    1820            2 :                                          r_val=scale_x)
    1821            2 :                scale_x = scale_x - hfx_fraction*scale_longrange
    1822              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
    1823            2 :                                          r_val=scale_x)
    1824              : 
    1825              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
    1826            2 :                                          r_val=omega)
    1827              :             END IF
    1828              :          CASE (do_potential_mix_cl)
    1829            2 :             omega = x_data(1, 1)%potential_parameter%omega
    1830            2 :             scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
    1831            2 :             scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
    1832            2 :             ifun = 0
    1833            2 :             funct_found = .FALSE.
    1834              :             DO
    1835            6 :                ifun = ifun + 1
    1836            6 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    1837            6 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    1838            6 :                IF (xc_fun%section%name == "XWPBE") THEN
    1839            2 :                   funct_found = .TRUE.
    1840              :                END IF
    1841              :             END DO
    1842          258 :             IF (.NOT. funct_found) THEN
    1843              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
    1844            0 :                                          l_val=.TRUE.)
    1845              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
    1846            0 :                                          r_val=hfx_fraction*(scale_coulomb + scale_longrange))
    1847              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
    1848            0 :                                          r_val=-hfx_fraction*scale_longrange)
    1849              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
    1850            0 :                                          r_val=omega)
    1851              : 
    1852              :             ELSE
    1853              :                CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X0", &
    1854            2 :                                          r_val=scale_x)
    1855            2 :                scale_x = scale_x + hfx_fraction*(scale_coulomb + scale_longrange)
    1856              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
    1857            2 :                                          r_val=scale_x)
    1858              : 
    1859              :                CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X", &
    1860            2 :                                          r_val=scale_x)
    1861            2 :                scale_x = scale_x - hfx_fraction*scale_longrange
    1862              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
    1863            2 :                                          r_val=scale_x)
    1864              : 
    1865              :                CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
    1866            2 :                                          r_val=omega)
    1867              :             END IF
    1868              :          END SELECT
    1869              :       ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_default_libxc) THEN
    1870              :          ! default PBE Functional
    1871              :          !! ** Add functionals evaluated with auxiliary basis
    1872              : #if defined (__LIBXC)
    1873            4 :          SELECT CASE (hfx_potential_type)
    1874              :          CASE (do_potential_coulomb)
    1875              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
    1876            4 :                                       l_val=.TRUE.)
    1877              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
    1878            4 :                                       r_val=-hfx_fraction)
    1879              :          CASE (do_potential_short)
    1880            2 :             omega = x_data(1, 1)%potential_parameter%omega
    1881              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
    1882            2 :                                       l_val=.TRUE.)
    1883              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    1884            2 :                                       r_val=-hfx_fraction)
    1885              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
    1886            2 :                                       r_val=omega)
    1887              :          CASE (do_potential_truncated)
    1888            0 :             cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
    1889              :             CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
    1890            0 :                                       l_val=.TRUE.)
    1891              :             CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    1892            0 :                                       r_val=hfx_fraction)
    1893              :             CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
    1894            0 :                                       r_val=cutoff_radius)
    1895              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
    1896            0 :                                       l_val=.TRUE.)
    1897              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    1898            0 :                                       r_val=-hfx_fraction)
    1899              :          CASE (do_potential_long)
    1900            2 :             omega = x_data(1, 1)%potential_parameter%omega
    1901              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
    1902            2 :                                       l_val=.TRUE.)
    1903              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    1904            2 :                                       r_val=hfx_fraction)
    1905              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
    1906            2 :                                       r_val=omega)
    1907              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
    1908            2 :                                       l_val=.TRUE.)
    1909              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
    1910            2 :                                       r_val=-hfx_fraction)
    1911              :          CASE (do_potential_mix_cl)
    1912            2 :             omega = x_data(1, 1)%potential_parameter%omega
    1913            2 :             scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
    1914            2 :             scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
    1915              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
    1916            2 :                                       l_val=.TRUE.)
    1917              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    1918            2 :                                       r_val=hfx_fraction*scale_longrange)
    1919              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
    1920            2 :                                       r_val=omega)
    1921              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
    1922            2 :                                       l_val=.TRUE.)
    1923              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
    1924            2 :                                       r_val=-hfx_fraction*(scale_longrange + scale_coulomb))
    1925              :          CASE (do_potential_mix_cl_trunc)
    1926            2 :             omega = x_data(1, 1)%potential_parameter%omega
    1927            2 :             cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
    1928            2 :             scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
    1929            2 :             scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
    1930              :             CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
    1931            2 :                                       l_val=.TRUE.)
    1932              :             CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    1933            2 :                                       r_val=hfx_fraction*(scale_longrange + scale_coulomb))
    1934              :             CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
    1935            2 :                                       r_val=cutoff_radius)
    1936              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
    1937            2 :                                       l_val=.TRUE.)
    1938              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    1939            2 :                                       r_val=hfx_fraction*scale_longrange)
    1940              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
    1941            2 :                                       r_val=omega)
    1942              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
    1943            2 :                                       l_val=.TRUE.)
    1944              :             CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
    1945            2 :                                       r_val=-hfx_fraction*(scale_longrange + scale_coulomb))
    1946              :          CASE DEFAULT
    1947           12 :             CPABORT("Unknown potential operator!")
    1948              :          END SELECT
    1949              : 
    1950              :          !** Now modify the functionals for the primary basis
    1951           12 :          xc_fun_section => section_vals_get_subs_vals(admm_env%xc_section_primary, "XC_FUNCTIONAL")
    1952              :          !* Overwrite possible shortcut
    1953              :          CALL section_vals_val_set(xc_fun_section, "_SECTION_PARAMETERS_", &
    1954           12 :                                    i_val=xc_funct_no_shortcut)
    1955              : 
    1956            4 :          SELECT CASE (hfx_potential_type)
    1957              :          CASE (do_potential_coulomb)
    1958            4 :             ifun = 0
    1959            4 :             funct_found = .FALSE.
    1960              :             DO
    1961            8 :                ifun = ifun + 1
    1962            8 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    1963            8 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    1964            8 :                IF (xc_fun%section%name == "GGA_X_PBE") THEN
    1965            0 :                   funct_found = .TRUE.
    1966              :                END IF
    1967              :             END DO
    1968            4 :             IF (.NOT. funct_found) THEN
    1969              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
    1970            4 :                                          l_val=.TRUE.)
    1971              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
    1972            4 :                                          r_val=hfx_fraction)
    1973              :             ELSE
    1974              :                CALL section_vals_val_get(xc_fun_section, "GGA_X_PBE%SCALE", &
    1975            0 :                                          r_val=scale_x)
    1976            0 :                scale_x = scale_x + hfx_fraction
    1977              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
    1978            0 :                                          r_val=scale_x)
    1979              :             END IF
    1980              :          CASE (do_potential_short)
    1981            2 :             omega = x_data(1, 1)%potential_parameter%omega
    1982            2 :             ifun = 0
    1983            2 :             funct_found = .FALSE.
    1984              :             DO
    1985            4 :                ifun = ifun + 1
    1986            4 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    1987            4 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    1988            4 :                IF (xc_fun%section%name == "GGA_X_WPBEH") THEN
    1989            0 :                   funct_found = .TRUE.
    1990              :                END IF
    1991              :             END DO
    1992            2 :             IF (.NOT. funct_found) THEN
    1993              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
    1994            2 :                                          l_val=.TRUE.)
    1995              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    1996            2 :                                          r_val=hfx_fraction)
    1997              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
    1998            2 :                                          r_val=omega)
    1999              :             ELSE
    2000              :                CALL section_vals_val_get(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    2001            0 :                                          r_val=scale_x)
    2002            0 :                scale_x = scale_x + hfx_fraction
    2003              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    2004            0 :                                          r_val=scale_x)
    2005              :             END IF
    2006              :          CASE (do_potential_long)
    2007            2 :             omega = x_data(1, 1)%potential_parameter%omega
    2008            2 :             ifun = 0
    2009            2 :             funct_found = .FALSE.
    2010              :             DO
    2011            4 :                ifun = ifun + 1
    2012            4 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    2013            4 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    2014            4 :                IF (xc_fun%section%name == "GGA_X_WPBEH") THEN
    2015            0 :                   funct_found = .TRUE.
    2016              :                END IF
    2017              :             END DO
    2018            2 :             IF (.NOT. funct_found) THEN
    2019              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
    2020            2 :                                          l_val=.TRUE.)
    2021              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    2022            2 :                                          r_val=-hfx_fraction)
    2023              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
    2024            2 :                                          r_val=omega)
    2025              :             ELSE
    2026              :                CALL section_vals_val_get(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    2027            0 :                                          r_val=scale_x)
    2028            0 :                scale_x = scale_x - hfx_fraction
    2029              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    2030            0 :                                          r_val=scale_x)
    2031              : 
    2032              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
    2033            0 :                                          r_val=omega)
    2034              :             END IF
    2035            2 :             ifun = 0
    2036            2 :             funct_found = .FALSE.
    2037              :             DO
    2038            6 :                ifun = ifun + 1
    2039            6 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    2040            6 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    2041            6 :                IF (xc_fun%section%name == "GGA_X_PBE") THEN
    2042            0 :                   funct_found = .TRUE.
    2043              :                END IF
    2044              :             END DO
    2045            2 :             IF (.NOT. funct_found) THEN
    2046              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
    2047            2 :                                          l_val=.TRUE.)
    2048              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
    2049            2 :                                          r_val=hfx_fraction)
    2050              :             ELSE
    2051              :                CALL section_vals_val_get(xc_fun_section, "GGA_X_PBE%SCALE", &
    2052            0 :                                          r_val=scale_x)
    2053            0 :                scale_x = scale_x + hfx_fraction
    2054              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
    2055            0 :                                          r_val=scale_x)
    2056              :             END IF
    2057              :          CASE (do_potential_truncated)
    2058            0 :             cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
    2059            0 :             ifun = 0
    2060            0 :             funct_found = .FALSE.
    2061              :             DO
    2062            0 :                ifun = ifun + 1
    2063            0 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    2064            0 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    2065            0 :                IF (xc_fun%section%name == "PBE_HOLE_T_C_LR") THEN
    2066            0 :                   funct_found = .TRUE.
    2067              :                END IF
    2068              :             END DO
    2069            0 :             IF (.NOT. funct_found) THEN
    2070              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
    2071            0 :                                          l_val=.TRUE.)
    2072              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    2073            0 :                                          r_val=-hfx_fraction)
    2074              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
    2075            0 :                                          r_val=cutoff_radius)
    2076              : 
    2077              :             ELSE
    2078              :                CALL section_vals_val_get(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    2079            0 :                                          r_val=scale_x)
    2080            0 :                scale_x = scale_x - hfx_fraction
    2081              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    2082            0 :                                          r_val=scale_x)
    2083              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
    2084            0 :                                          r_val=cutoff_radius)
    2085              :             END IF
    2086            0 :             ifun = 0
    2087            0 :             funct_found = .FALSE.
    2088              :             DO
    2089            0 :                ifun = ifun + 1
    2090            0 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    2091            0 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    2092            0 :                IF (xc_fun%section%name == "GGA_X_PBE") THEN
    2093            0 :                   funct_found = .TRUE.
    2094              :                END IF
    2095              :             END DO
    2096            0 :             IF (.NOT. funct_found) THEN
    2097              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
    2098            0 :                                          l_val=.TRUE.)
    2099              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
    2100            0 :                                          r_val=hfx_fraction)
    2101              : 
    2102              :             ELSE
    2103              :                CALL section_vals_val_get(xc_fun_section, "GGA_X_PBE%SCALE", &
    2104            0 :                                          r_val=scale_x)
    2105            0 :                scale_x = scale_x + hfx_fraction
    2106              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
    2107            0 :                                          r_val=scale_x)
    2108              :             END IF
    2109              :          CASE (do_potential_mix_cl_trunc)
    2110            2 :             cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
    2111            2 :             omega = x_data(1, 1)%potential_parameter%omega
    2112            2 :             scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
    2113            2 :             scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
    2114            2 :             ifun = 0
    2115            2 :             funct_found = .FALSE.
    2116              :             DO
    2117            4 :                ifun = ifun + 1
    2118            4 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    2119            4 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    2120            4 :                IF (xc_fun%section%name == "PBE_HOLE_T_C_LR") THEN
    2121            0 :                   funct_found = .TRUE.
    2122              :                END IF
    2123              :             END DO
    2124            2 :             IF (.NOT. funct_found) THEN
    2125              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
    2126            2 :                                          l_val=.TRUE.)
    2127              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    2128            2 :                                          r_val=-hfx_fraction*(scale_coulomb + scale_longrange))
    2129              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
    2130            2 :                                          r_val=cutoff_radius)
    2131              : 
    2132              :             ELSE
    2133              :                CALL section_vals_val_get(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    2134            0 :                                          r_val=scale_x)
    2135            0 :                scale_x = scale_x - hfx_fraction*(scale_coulomb + scale_longrange)
    2136              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
    2137            0 :                                          r_val=scale_x)
    2138              :                CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
    2139            0 :                                          r_val=cutoff_radius)
    2140              :             END IF
    2141            2 :             ifun = 0
    2142            2 :             funct_found = .FALSE.
    2143              :             DO
    2144            6 :                ifun = ifun + 1
    2145            6 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    2146            6 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    2147            6 :                IF (xc_fun%section%name == "GGA_X_WPBEH") THEN
    2148            0 :                   funct_found = .TRUE.
    2149              :                END IF
    2150              :             END DO
    2151            2 :             IF (.NOT. funct_found) THEN
    2152              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
    2153            2 :                                          l_val=.TRUE.)
    2154              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    2155            2 :                                          r_val=-hfx_fraction*scale_longrange)
    2156              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
    2157            2 :                                          r_val=omega)
    2158              : 
    2159              :             ELSE
    2160              :                CALL section_vals_val_get(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    2161            0 :                                          r_val=scale_x)
    2162            0 :                scale_x = scale_x - hfx_fraction*scale_longrange
    2163              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    2164            0 :                                          r_val=scale_x)
    2165              : 
    2166              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
    2167            0 :                                          r_val=omega)
    2168              :             END IF
    2169            2 :             ifun = 0
    2170            2 :             funct_found = .FALSE.
    2171              :             DO
    2172            8 :                ifun = ifun + 1
    2173            8 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    2174            8 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    2175            8 :                IF (xc_fun%section%name == "GGA_X_PBE") THEN
    2176            0 :                   funct_found = .TRUE.
    2177              :                END IF
    2178              :             END DO
    2179            2 :             IF (.NOT. funct_found) THEN
    2180              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
    2181            2 :                                          l_val=.TRUE.)
    2182              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
    2183            2 :                                          r_val=hfx_fraction*(scale_coulomb + scale_longrange))
    2184              :             ELSE
    2185              :                CALL section_vals_val_get(xc_fun_section, "GGA_X_PBE%SCALE", &
    2186            0 :                                          r_val=scale_x)
    2187            0 :                scale_x = scale_x + hfx_fraction*(scale_coulomb + scale_longrange)
    2188              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
    2189            0 :                                          r_val=scale_x)
    2190              :             END IF
    2191              :          CASE (do_potential_mix_cl)
    2192            2 :             omega = x_data(1, 1)%potential_parameter%omega
    2193            2 :             scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
    2194            2 :             scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
    2195            2 :             ifun = 0
    2196            2 :             funct_found = .FALSE.
    2197              :             DO
    2198            4 :                ifun = ifun + 1
    2199            4 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    2200            4 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    2201            4 :                IF (xc_fun%section%name == "GGA_X_WPBEH") THEN
    2202            0 :                   funct_found = .TRUE.
    2203              :                END IF
    2204              :             END DO
    2205            2 :             IF (.NOT. funct_found) THEN
    2206              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
    2207            2 :                                          l_val=.TRUE.)
    2208              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    2209            2 :                                          r_val=-hfx_fraction*scale_longrange)
    2210              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
    2211            2 :                                          r_val=omega)
    2212              : 
    2213              :             ELSE
    2214              :                CALL section_vals_val_get(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    2215            0 :                                          r_val=scale_x)
    2216            0 :                scale_x = scale_x - hfx_fraction*scale_longrange
    2217              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
    2218            0 :                                          r_val=scale_x)
    2219              : 
    2220              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
    2221            0 :                                          r_val=omega)
    2222              :             END IF
    2223            2 :             ifun = 0
    2224            2 :             funct_found = .FALSE.
    2225              :             DO
    2226            6 :                ifun = ifun + 1
    2227            6 :                xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    2228            6 :                IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    2229            6 :                IF (xc_fun%section%name == "GGA_X_PBE") THEN
    2230            0 :                   funct_found = .TRUE.
    2231              :                END IF
    2232              :             END DO
    2233           14 :             IF (.NOT. funct_found) THEN
    2234              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
    2235            2 :                                          l_val=.TRUE.)
    2236              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
    2237            2 :                                          r_val=hfx_fraction*(scale_coulomb + scale_longrange))
    2238              :             ELSE
    2239              :                CALL section_vals_val_get(xc_fun_section, "GGA_X_PBE%SCALE", &
    2240            0 :                                          r_val=scale_x)
    2241            0 :                scale_x = scale_x + hfx_fraction*(scale_coulomb + scale_longrange)
    2242              :                CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
    2243            0 :                                          r_val=scale_x)
    2244              :             END IF
    2245              :          END SELECT
    2246              : #else
    2247              :          CALL cp_abort(__LOCATION__, "In order use a LibXC-based ADMM "// &
    2248              :                        "exchange correction functionals, you have to compile and link against LibXC!")
    2249              : #endif
    2250              : 
    2251              :          ! PBEX (always bare form), OPTX and Becke88 functional
    2252              :       ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_pbex .OR. &
    2253              :                admm_env%aux_exch_func == do_admm_aux_exch_func_opt .OR. &
    2254              :                admm_env%aux_exch_func == do_admm_aux_exch_func_bee) THEN
    2255          144 :          IF (admm_env%aux_exch_func == do_admm_aux_exch_func_pbex) THEN
    2256          114 :             name_x_func = 'PBE'
    2257           30 :          ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt) THEN
    2258           14 :             name_x_func = 'OPTX'
    2259           16 :          ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_bee) THEN
    2260           16 :             name_x_func = 'BECKE88'
    2261              :          END IF
    2262              :          !primary basis
    2263              :          CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%_SECTION_PARAMETERS_", &
    2264          144 :                                    l_val=.TRUE.)
    2265              :          CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%SCALE_X", &
    2266          144 :                                    r_val=-hfx_fraction)
    2267              : 
    2268          144 :          IF (admm_env%aux_exch_func == do_admm_aux_exch_func_pbex) THEN
    2269          114 :             CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%SCALE_C", r_val=0.0_dp)
    2270              :          END IF
    2271              : 
    2272          144 :          IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt) THEN
    2273           14 :             IF (admm_env%aux_exch_func_param) THEN
    2274              :                CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%A1", &
    2275            0 :                                          r_val=admm_env%aux_x_param(1))
    2276              :                CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%A2", &
    2277            0 :                                          r_val=admm_env%aux_x_param(2))
    2278              :                CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%GAMMA", &
    2279            0 :                                          r_val=admm_env%aux_x_param(3))
    2280              :             END IF
    2281              :          END IF
    2282              : 
    2283              :          !** Now modify the functionals for the primary basis
    2284          144 :          xc_fun_section => section_vals_get_subs_vals(admm_env%xc_section_primary, "XC_FUNCTIONAL")
    2285              :          !* Overwrite possible L")
    2286              :          !* Overwrite possible shortcut
    2287              :          CALL section_vals_val_set(xc_fun_section, "_SECTION_PARAMETERS_", &
    2288          144 :                                    i_val=xc_funct_no_shortcut)
    2289              : 
    2290          144 :          ifun = 0
    2291          144 :          funct_found = .FALSE.
    2292              :          DO
    2293          256 :             ifun = ifun + 1
    2294          256 :             xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    2295          256 :             IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    2296          256 :             IF (xc_fun%section%name == TRIM(name_x_func)) THEN
    2297           66 :                funct_found = .TRUE.
    2298              :             END IF
    2299              :          END DO
    2300          144 :          IF (.NOT. funct_found) THEN
    2301              :             CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%_SECTION_PARAMETERS_", &
    2302           78 :                                       l_val=.TRUE.)
    2303              :             CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%SCALE_X", &
    2304           78 :                                       r_val=hfx_fraction)
    2305           78 :             IF (admm_env%aux_exch_func == do_admm_aux_exch_func_pbex) THEN
    2306              :                CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%SCALE_C", &
    2307           50 :                                          r_val=0.0_dp)
    2308           28 :             ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt) THEN
    2309           14 :                IF (admm_env%aux_exch_func_param) THEN
    2310              :                   CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%A1", &
    2311            0 :                                             r_val=admm_env%aux_x_param(1))
    2312              :                   CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%A2", &
    2313            0 :                                             r_val=admm_env%aux_x_param(2))
    2314              :                   CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%GAMMA", &
    2315            0 :                                             r_val=admm_env%aux_x_param(3))
    2316              :                END IF
    2317              :             END IF
    2318              : 
    2319              :          ELSE
    2320              :             CALL section_vals_val_get(xc_fun_section, TRIM(name_x_func)//"%SCALE_X", &
    2321           66 :                                       r_val=scale_x)
    2322           66 :             scale_x = scale_x + hfx_fraction
    2323              :             CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%SCALE_X", &
    2324           66 :                                       r_val=scale_x)
    2325           66 :             IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt) THEN
    2326            0 :                CPASSERT(.NOT. admm_env%aux_exch_func_param)
    2327              :             END IF
    2328              :          END IF
    2329              : 
    2330              :       ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_pbex_libxc .OR. &
    2331              :                admm_env%aux_exch_func == do_admm_aux_exch_func_opt_libxc .OR. &
    2332              :                admm_env%aux_exch_func == do_admm_aux_exch_func_sx_libxc .OR. &
    2333              :                admm_env%aux_exch_func == do_admm_aux_exch_func_bee_libxc) THEN
    2334              : #if defined(__LIBXC)
    2335           18 :          IF (admm_env%aux_exch_func == do_admm_aux_exch_func_pbex_libxc) THEN
    2336            2 :             name_x_func = 'GGA_X_PBE'
    2337           16 :          ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt_libxc) THEN
    2338            2 :             name_x_func = 'GGA_X_OPTX'
    2339           14 :          ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_bee_libxc) THEN
    2340            2 :             name_x_func = 'GGA_X_B88'
    2341           12 :          ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_sx_libxc) THEN
    2342           12 :             name_x_func = 'LDA_X'
    2343              :          END IF
    2344              :          !primary basis
    2345              :          CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%_SECTION_PARAMETERS_", &
    2346           18 :                                    l_val=.TRUE.)
    2347              :          CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%SCALE", &
    2348           18 :                                    r_val=-hfx_fraction)
    2349              : 
    2350           18 :          IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt_libxc) THEN
    2351            2 :             IF (admm_env%aux_exch_func_param) THEN
    2352              :                CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%_A", &
    2353            0 :                                          r_val=admm_env%aux_x_param(1))
    2354              :                ! LibXC rescales the second parameter of the OPTX functional (see documentation there)
    2355              :                CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%_B", &
    2356            0 :                                          r_val=admm_env%aux_x_param(2)/x_factor_c)
    2357              :                CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%_GAMMA", &
    2358            0 :                                          r_val=admm_env%aux_x_param(3))
    2359              :             END IF
    2360              :          END IF
    2361              : 
    2362              :          !** Now modify the functionals for the primary basis
    2363           18 :          xc_fun_section => section_vals_get_subs_vals(admm_env%xc_section_primary, "XC_FUNCTIONAL")
    2364              :          !* Overwrite possible L")
    2365              :          !* Overwrite possible shortcut
    2366              :          CALL section_vals_val_set(xc_fun_section, "_SECTION_PARAMETERS_", &
    2367           18 :                                    i_val=xc_funct_no_shortcut)
    2368              : 
    2369           18 :          ifun = 0
    2370           18 :          funct_found = .FALSE.
    2371              :          DO
    2372           36 :             ifun = ifun + 1
    2373           36 :             xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    2374           36 :             IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    2375           36 :             IF (xc_fun%section%name == TRIM(name_x_func)) THEN
    2376            0 :                funct_found = .TRUE.
    2377              :             END IF
    2378              :          END DO
    2379           18 :          IF (.NOT. funct_found) THEN
    2380              :             CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%_SECTION_PARAMETERS_", &
    2381           18 :                                       l_val=.TRUE.)
    2382              :             CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%SCALE", &
    2383           18 :                                       r_val=hfx_fraction)
    2384           18 :             IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt_libxc) THEN
    2385            2 :                IF (admm_env%aux_exch_func_param) THEN
    2386              :                   CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%_A", &
    2387            0 :                                             r_val=admm_env%aux_x_param(1))
    2388              :                   ! LibXC rescales the second parameter of the OPTX functional (see documentation there)
    2389              :                   CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%_B", &
    2390            0 :                                             r_val=admm_env%aux_x_param(2)/x_factor_c)
    2391              :                   CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%_GAMMA", &
    2392            0 :                                             r_val=admm_env%aux_x_param(3))
    2393              :                END IF
    2394              :             END IF
    2395              : 
    2396              :          ELSE
    2397              :             CALL section_vals_val_get(xc_fun_section, TRIM(name_x_func)//"%SCALE", &
    2398            0 :                                       r_val=scale_x)
    2399            0 :             scale_x = scale_x + hfx_fraction
    2400              :             CALL section_vals_val_set(xc_fun_section, TRIM(name_x_func)//"%SCALE", &
    2401            0 :                                       r_val=scale_x)
    2402            0 :             IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt_libxc) THEN
    2403            0 :                CPASSERT(.NOT. admm_env%aux_exch_func_param)
    2404              :             END IF
    2405              :          END IF
    2406              : #else
    2407              :          CALL cp_abort(__LOCATION__, "In order use a LibXC-based ADMM "// &
    2408              :                        "exchange correction functionals, you have to compile and link against LibXC!")
    2409              : #endif
    2410              : 
    2411              :       ELSE
    2412            0 :          CPABORT("Unknown exchange correction functional!")
    2413              :       END IF
    2414              : 
    2415              :       IF (debug_functional) THEN
    2416              :          iounit = cp_logger_get_default_io_unit(logger)
    2417              :          IF (iounit > 0) THEN
    2418              :             WRITE (iounit, "(A)") " ADMM Primary Basis Set Functional"
    2419              :          END IF
    2420              :          xc_fun_section => section_vals_get_subs_vals(admm_env%xc_section_primary, "XC_FUNCTIONAL")
    2421              :          ifun = 0
    2422              :          funct_found = .FALSE.
    2423              :          DO
    2424              :             ifun = ifun + 1
    2425              :             xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    2426              :             IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    2427              : 
    2428              :             scale_x = -1000.0_dp
    2429              :             IF (xc_fun%section%name /= "LYP" .AND. xc_fun%section%name /= "VWN") THEN
    2430              :                CALL section_vals_val_get(xc_fun, "SCALE_X", r_val=scale_x)
    2431              :             END IF
    2432              :             IF (xc_fun%section%name == "XWPBE") THEN
    2433              :                CALL section_vals_val_get(xc_fun, "SCALE_X0", r_val=hfx_fraction)
    2434              :                IF (iounit > 0) THEN
    2435              :                   WRITE (iounit, "(T5,A,T25,2F10.3)") TRIM(xc_fun%section%name), scale_x, hfx_fraction
    2436              :                END IF
    2437              :             ELSE
    2438              :                IF (iounit > 0) THEN
    2439              :                   WRITE (iounit, "(T5,A,T25,F10.3)") TRIM(xc_fun%section%name), scale_x
    2440              :                END IF
    2441              :             END IF
    2442              :          END DO
    2443              : 
    2444              :          IF (iounit > 0) THEN
    2445              :             WRITE (iounit, "(A)") " Auxiliary Basis Set Functional"
    2446              :          END IF
    2447              :          xc_fun_section => section_vals_get_subs_vals(admm_env%xc_section_aux, "XC_FUNCTIONAL")
    2448              :          ifun = 0
    2449              :          funct_found = .FALSE.
    2450              :          DO
    2451              :             ifun = ifun + 1
    2452              :             xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
    2453              :             IF (.NOT. ASSOCIATED(xc_fun)) EXIT
    2454              :             scale_x = -1000.0_dp
    2455              :             IF (xc_fun%section%name /= "LYP" .AND. xc_fun%section%name /= "VWN") THEN
    2456              :                CALL section_vals_val_get(xc_fun, "SCALE_X", r_val=scale_x)
    2457              :             END IF
    2458              :             IF (xc_fun%section%name == "XWPBE") THEN
    2459              :                CALL section_vals_val_get(xc_fun, "SCALE_X0", r_val=hfx_fraction)
    2460              :                IF (iounit > 0) THEN
    2461              :                   WRITE (iounit, "(T5,A,T25,2F10.3)") TRIM(xc_fun%section%name), scale_x, hfx_fraction
    2462              :                END IF
    2463              :             ELSE
    2464              :                IF (iounit > 0) THEN
    2465              :                   WRITE (iounit, "(T5,A,T25,F10.3)") TRIM(xc_fun%section%name), scale_x
    2466              :                END IF
    2467              :             END IF
    2468              :          END DO
    2469              :       END IF
    2470              : 
    2471          554 :    END SUBROUTINE create_admm_xc_section
    2472              : 
    2473              : ! **************************************************************************************************
    2474              : !> \brief Add the hfx contributions to the Hamiltonian
    2475              : !>
    2476              : !> \param matrix_ks Kohn-Sham matrix (updated on exit)
    2477              : !> \param rho_ao    electron density expressed in terms of atomic orbitals
    2478              : !> \param qs_env    Quickstep environment
    2479              : !> \param update_energy whether to update energy (default: yes)
    2480              : !> \param recalc_integrals whether to recalculate integrals (default: value of HF%TREAT_LSD_IN_CORE)
    2481              : !> \param external_hfx_sections ...
    2482              : !> \param external_x_data ...
    2483              : !> \param external_para_env ...
    2484              : !> \note
    2485              : !>     Simplified version of subroutine hfx_ks_matrix()
    2486              : ! **************************************************************************************************
    2487         8317 :    SUBROUTINE tddft_hfx_matrix(matrix_ks, rho_ao, qs_env, update_energy, recalc_integrals, &
    2488         8317 :                                external_hfx_sections, external_x_data, external_para_env)
    2489              :       TYPE(dbcsr_p_type), DIMENSION(:), INTENT(INOUT), &
    2490              :          TARGET                                          :: matrix_ks, rho_ao
    2491              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    2492              :       LOGICAL, INTENT(IN), OPTIONAL                      :: update_energy, recalc_integrals
    2493              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: external_hfx_sections
    2494              :       TYPE(hfx_type), DIMENSION(:, :), OPTIONAL, TARGET  :: external_x_data
    2495              :       TYPE(mp_para_env_type), OPTIONAL, POINTER          :: external_para_env
    2496              : 
    2497              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'tddft_hfx_matrix'
    2498              : 
    2499              :       INTEGER                                            :: handle, irep, ispin, mspin, n_rep_hf, &
    2500              :                                                             nspins
    2501              :       LOGICAL                                            :: distribute_fock_matrix, &
    2502              :                                                             hfx_treat_lsd_in_core, &
    2503              :                                                             my_update_energy, s_mstruct_changed
    2504              :       REAL(KIND=dp)                                      :: eh1, ehfx
    2505         8317 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_ks_kp, rho_ao_kp
    2506              :       TYPE(dft_control_type), POINTER                    :: dft_control
    2507         8317 :       TYPE(hfx_type), DIMENSION(:, :), POINTER           :: x_data
    2508              :       TYPE(mp_para_env_type), POINTER                    :: para_env
    2509              :       TYPE(qs_energy_type), POINTER                      :: energy
    2510              :       TYPE(section_vals_type), POINTER                   :: hfx_sections, input
    2511              : 
    2512         8317 :       CALL timeset(routineN, handle)
    2513              : 
    2514         8317 :       NULLIFY (dft_control, hfx_sections, input, para_env, matrix_ks_kp, rho_ao_kp)
    2515              : 
    2516              :       CALL get_qs_env(qs_env=qs_env, &
    2517              :                       dft_control=dft_control, &
    2518              :                       energy=energy, &
    2519              :                       input=input, &
    2520              :                       para_env=para_env, &
    2521              :                       s_mstruct_changed=s_mstruct_changed, &
    2522         8317 :                       x_data=x_data)
    2523              : 
    2524              :       ! This should probably be the HF section from the TDDFPT XC section!
    2525         8317 :       hfx_sections => section_vals_get_subs_vals(input, "DFT%XC%HF")
    2526              : 
    2527         8317 :       IF (PRESENT(external_hfx_sections)) hfx_sections => external_hfx_sections
    2528         8317 :       IF (PRESENT(external_x_data)) x_data => external_x_data
    2529         8317 :       IF (PRESENT(external_para_env)) para_env => external_para_env
    2530              : 
    2531         8317 :       my_update_energy = .TRUE.
    2532         8317 :       IF (PRESENT(update_energy)) my_update_energy = update_energy
    2533              : 
    2534         8317 :       IF (PRESENT(recalc_integrals)) s_mstruct_changed = recalc_integrals
    2535              : 
    2536         8317 :       CPASSERT(dft_control%nimages == 1)
    2537         8317 :       nspins = dft_control%nspins
    2538              : 
    2539         8317 :       CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
    2540              :       CALL section_vals_val_get(hfx_sections, "TREAT_LSD_IN_CORE", l_val=hfx_treat_lsd_in_core, &
    2541         8317 :                                 i_rep_section=1)
    2542              : 
    2543         8317 :       CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
    2544         8317 :       distribute_fock_matrix = .TRUE.
    2545              : 
    2546         8317 :       mspin = 1
    2547         8317 :       IF (hfx_treat_lsd_in_core) mspin = nspins
    2548              : 
    2549         8317 :       matrix_ks_kp(1:nspins, 1:1) => matrix_ks(1:nspins)
    2550         8317 :       rho_ao_kp(1:nspins, 1:1) => rho_ao(1:nspins)
    2551              : 
    2552        16466 :       DO irep = 1, n_rep_hf
    2553              :          ! the real hfx calulation
    2554         8149 :          ehfx = 0.0_dp
    2555              : 
    2556        16466 :          IF (x_data(irep, 1)%do_hfx_ri) THEN
    2557              :             CALL hfx_ri_update_ks(qs_env, x_data(irep, 1)%ri_data, matrix_ks_kp, ehfx, &
    2558              :                                   rho_ao=rho_ao_kp, geometry_did_change=s_mstruct_changed, &
    2559          308 :                                   nspins=nspins, hf_fraction=x_data(irep, 1)%general_parameter%fraction)
    2560              : 
    2561              :          ELSE
    2562        15682 :             DO ispin = 1, mspin
    2563              :                CALL integrate_four_center(qs_env, x_data, matrix_ks_kp, eh1, rho_ao_kp, hfx_sections, para_env, &
    2564         7841 :                                           s_mstruct_changed, irep, distribute_fock_matrix, ispin=ispin)
    2565        15682 :                ehfx = ehfx + eh1
    2566              :             END DO
    2567              :          END IF
    2568              :       END DO
    2569         8317 :       IF (my_update_energy) energy%ex = ehfx
    2570              : 
    2571         8317 :       CALL timestop(handle)
    2572         8317 :    END SUBROUTINE tddft_hfx_matrix
    2573              : 
    2574              : END MODULE hfx_admm_utils
        

Generated by: LCOV version 2.0-1