LCOV - code coverage report
Current view: top level - src - qs_cdft_utils.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:ccc2433) Lines: 587 675 87.0 %
Date: 2024-04-25 07:09:54 Functions: 10 11 90.9 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Utility subroutines for CDFT calculations
      10             : !> \par   History
      11             : !>                 separated from et_coupling [03.2017]
      12             : !> \author Nico Holmberg [03.2017]
      13             : ! **************************************************************************************************
      14             : MODULE qs_cdft_utils
      15             :    USE ao_util,                         ONLY: exp_radius_very_extended
      16             :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      17             :                                               get_atomic_kind
      18             :    USE bibliography,                    ONLY: Becke1988b,&
      19             :                                               Holmberg2017,&
      20             :                                               Holmberg2018,&
      21             :                                               cite_reference
      22             :    USE cell_types,                      ONLY: cell_type,&
      23             :                                               pbc
      24             :    USE cp_control_types,                ONLY: dft_control_type,&
      25             :                                               qs_control_type
      26             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      27             :                                               cp_logger_type,&
      28             :                                               cp_to_string
      29             :    USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
      30             :                                               cp_print_key_unit_nr
      31             :    USE cp_realspace_grid_cube,          ONLY: cp_pw_to_cube
      32             :    USE cp_units,                        ONLY: cp_unit_from_cp2k
      33             :    USE grid_api,                        ONLY: GRID_FUNC_AB,&
      34             :                                               collocate_pgf_product
      35             :    USE hirshfeld_methods,               ONLY: create_shape_function
      36             :    USE hirshfeld_types,                 ONLY: create_hirshfeld_type,&
      37             :                                               hirshfeld_type,&
      38             :                                               set_hirshfeld_info
      39             :    USE input_constants,                 ONLY: &
      40             :         becke_cutoff_element, becke_cutoff_global, cdft_charge_constraint, &
      41             :         outer_scf_becke_constraint, outer_scf_cdft_constraint, outer_scf_hirshfeld_constraint, &
      42             :         outer_scf_none, radius_user, shape_function_gaussian
      43             :    USE input_section_types,             ONLY: section_get_ivals,&
      44             :                                               section_vals_get,&
      45             :                                               section_vals_get_subs_vals,&
      46             :                                               section_vals_type,&
      47             :                                               section_vals_val_get
      48             :    USE kinds,                           ONLY: default_path_length,&
      49             :                                               dp
      50             :    USE memory_utilities,                ONLY: reallocate
      51             :    USE message_passing,                 ONLY: mp_para_env_type
      52             :    USE outer_scf_control_types,         ONLY: outer_scf_read_parameters
      53             :    USE particle_list_types,             ONLY: particle_list_type
      54             :    USE particle_types,                  ONLY: particle_type
      55             :    USE pw_env_types,                    ONLY: pw_env_get,&
      56             :                                               pw_env_type
      57             :    USE pw_methods,                      ONLY: pw_zero
      58             :    USE pw_pool_types,                   ONLY: pw_pool_type
      59             :    USE qs_cdft_types,                   ONLY: becke_constraint_type,&
      60             :                                               cdft_control_type,&
      61             :                                               cdft_group_type,&
      62             :                                               hirshfeld_constraint_type
      63             :    USE qs_environment_types,            ONLY: get_qs_env,&
      64             :                                               qs_environment_type
      65             :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      66             :                                               qs_kind_type
      67             :    USE qs_scf_output,                   ONLY: qs_scf_cdft_constraint_info
      68             :    USE qs_subsys_types,                 ONLY: qs_subsys_get,&
      69             :                                               qs_subsys_type
      70             :    USE realspace_grid_types,            ONLY: realspace_grid_type,&
      71             :                                               rs_grid_zero,&
      72             :                                               transfer_rs2pw
      73             : #include "./base/base_uses.f90"
      74             : 
      75             :    IMPLICIT NONE
      76             : 
      77             :    PRIVATE
      78             : 
      79             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_cdft_utils'
      80             :    LOGICAL, PARAMETER, PRIVATE          :: debug_this_module = .FALSE.
      81             : 
      82             : ! *** Public subroutines ***
      83             :    PUBLIC :: becke_constraint_init, read_becke_section, read_cdft_control_section
      84             :    PUBLIC :: hfun_scale, hirshfeld_constraint_init, cdft_constraint_print, &
      85             :              cdft_print_hirshfeld_density, cdft_print_weight_function
      86             : 
      87             : CONTAINS
      88             : 
      89             : ! **************************************************************************************************
      90             : !> \brief Initializes the Becke constraint environment
      91             : !> \param qs_env the qs_env where to build the constraint
      92             : !> \par   History
      93             : !>        Created 01.2007 [fschiff]
      94             : !>        Extended functionality 12/15-12/16 [Nico Holmberg]
      95             : ! **************************************************************************************************
      96         190 :    SUBROUTINE becke_constraint_init(qs_env)
      97             :       TYPE(qs_environment_type), POINTER                 :: qs_env
      98             : 
      99             :       CHARACTER(len=*), PARAMETER :: routineN = 'becke_constraint_init'
     100             : 
     101             :       CHARACTER(len=2)                                   :: element_symbol
     102             :       INTEGER :: atom_a, bounds(2), handle, i, iatom, iex, igroup, ikind, ip, ithread, iw, j, &
     103             :          jatom, katom, natom, nkind, npme, nthread, numexp, unit_nr
     104             :       INTEGER, DIMENSION(2, 3)                           :: bo
     105         190 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list, cores, stride
     106             :       LOGICAL                                            :: build, in_memory, mpi_io
     107         190 :       LOGICAL, ALLOCATABLE, DIMENSION(:)                 :: is_constraint
     108             :       REAL(KIND=dp)                                      :: alpha, chi, coef, eps_cavity, ircov, &
     109             :                                                             jrcov, radius, uij
     110             :       REAL(KIND=dp), DIMENSION(3)                        :: cell_v, dist_vec, r, r1, ra
     111         190 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: radii_list
     112         190 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: pab
     113         190 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     114             :       TYPE(becke_constraint_type), POINTER               :: becke_control
     115             :       TYPE(cdft_control_type), POINTER                   :: cdft_control
     116         190 :       TYPE(cdft_group_type), DIMENSION(:), POINTER       :: group
     117             :       TYPE(cell_type), POINTER                           :: cell
     118             :       TYPE(cp_logger_type), POINTER                      :: logger
     119             :       TYPE(dft_control_type), POINTER                    :: dft_control
     120             :       TYPE(hirshfeld_type), POINTER                      :: cavity_env
     121             :       TYPE(mp_para_env_type), POINTER                    :: para_env
     122             :       TYPE(particle_list_type), POINTER                  :: particles
     123         190 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     124             :       TYPE(pw_env_type), POINTER                         :: pw_env
     125             :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     126         190 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     127             :       TYPE(qs_subsys_type), POINTER                      :: subsys
     128             :       TYPE(realspace_grid_type), POINTER                 :: rs_cavity
     129             :       TYPE(section_vals_type), POINTER                   :: cdft_constraint_section
     130             : 
     131         190 :       NULLIFY (cores, stride, atom_list, cell, para_env, dft_control, &
     132         190 :                particle_set, logger, cdft_constraint_section, qs_kind_set, &
     133         190 :                particles, subsys, pab, pw_env, rs_cavity, cavity_env, &
     134         190 :                auxbas_pw_pool, atomic_kind_set, group, radii_list, cdft_control)
     135         380 :       logger => cp_get_default_logger()
     136         190 :       CALL timeset(routineN, handle)
     137             :       CALL get_qs_env(qs_env, &
     138             :                       cell=cell, &
     139             :                       particle_set=particle_set, &
     140             :                       natom=natom, &
     141             :                       dft_control=dft_control, &
     142         190 :                       para_env=para_env)
     143         190 :       cdft_constraint_section => section_vals_get_subs_vals(qs_env%input, "DFT%QS%CDFT")
     144         190 :       iw = cp_print_key_unit_nr(logger, cdft_constraint_section, "PROGRAM_RUN_INFO", extension=".cdftLog")
     145         190 :       cdft_control => dft_control%qs_control%cdft_control
     146         190 :       becke_control => cdft_control%becke_control
     147         190 :       group => cdft_control%group
     148         190 :       in_memory = .FALSE.
     149         190 :       IF (cdft_control%save_pot) THEN
     150          72 :          in_memory = becke_control%in_memory
     151             :       END IF
     152         190 :       IF (becke_control%cavity_confine) THEN
     153         522 :          ALLOCATE (is_constraint(natom))
     154         554 :          is_constraint = .FALSE.
     155         516 :          DO i = 1, cdft_control%natoms
     156             :             ! Notice that here is_constraint=.TRUE. also for dummy atoms to properly compute their Becke charges
     157             :             ! A subsequent check (atom_in_group) ensures that the gradients of these dummy atoms are correct
     158         516 :             is_constraint(cdft_control%atoms(i)) = .TRUE.
     159             :          END DO
     160             :       END IF
     161         190 :       eps_cavity = becke_control%eps_cavity
     162             :       ! Setup atomic radii for adjusting cell boundaries
     163         190 :       IF (becke_control%adjust) THEN
     164         118 :          IF (.NOT. ASSOCIATED(becke_control%radii)) THEN
     165          94 :             CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
     166          94 :             IF (.NOT. SIZE(atomic_kind_set) == SIZE(becke_control%radii_tmp)) &
     167             :                CALL cp_abort(__LOCATION__, &
     168             :                              "Length of keyword BECKE_CONSTRAINT\ATOMIC_RADII does not "// &
     169           0 :                              "match number of atomic kinds in the input coordinate file.")
     170         282 :             ALLOCATE (becke_control%radii(SIZE(atomic_kind_set)))
     171         282 :             becke_control%radii(:) = becke_control%radii_tmp(:)
     172          94 :             DEALLOCATE (becke_control%radii_tmp)
     173             :          END IF
     174             :       END IF
     175             :       ! Setup cutoff scheme
     176         190 :       IF (.NOT. ASSOCIATED(becke_control%cutoffs)) THEN
     177         150 :          CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
     178         450 :          ALLOCATE (becke_control%cutoffs(natom))
     179         264 :          SELECT CASE (becke_control%cutoff_type)
     180             :          CASE (becke_cutoff_global)
     181         354 :             becke_control%cutoffs(:) = becke_control%rglobal
     182             :          CASE (becke_cutoff_element)
     183          36 :             IF (.NOT. SIZE(atomic_kind_set) == SIZE(becke_control%cutoffs_tmp)) &
     184             :                CALL cp_abort(__LOCATION__, &
     185             :                              "Length of keyword BECKE_CONSTRAINT\ELEMENT_CUTOFFS does not "// &
     186           0 :                              "match number of atomic kinds in the input coordinate file.")
     187         108 :             DO ikind = 1, SIZE(atomic_kind_set)
     188          72 :                CALL get_atomic_kind(atomic_kind_set(ikind), natom=katom, atom_list=atom_list)
     189         202 :                DO iatom = 1, katom
     190          94 :                   atom_a = atom_list(iatom)
     191         166 :                   becke_control%cutoffs(atom_a) = becke_control%cutoffs_tmp(ikind)
     192             :                END DO
     193             :             END DO
     194         186 :             DEALLOCATE (becke_control%cutoffs_tmp)
     195             :          END SELECT
     196             :       END IF
     197             :       ! Zero weight functions
     198         408 :       DO igroup = 1, SIZE(group)
     199         408 :          CALL pw_zero(group(igroup)%weight)
     200             :       END DO
     201         190 :       IF (cdft_control%atomic_charges) THEN
     202         310 :          DO iatom = 1, cdft_control%natoms
     203         310 :             CALL pw_zero(cdft_control%charge(iatom))
     204             :          END DO
     205             :       END IF
     206             :       ! Allocate storage for cell adjustment coefficients and needed distance vectors
     207         190 :       build = .FALSE.
     208         190 :       IF (becke_control%adjust .AND. .NOT. ASSOCIATED(becke_control%aij)) THEN
     209         376 :          ALLOCATE (becke_control%aij(natom, natom))
     210          94 :          build = .TRUE.
     211             :       END IF
     212         190 :       IF (becke_control%vector_buffer%store_vectors) THEN
     213         570 :          ALLOCATE (becke_control%vector_buffer%distances(natom))
     214         570 :          ALLOCATE (becke_control%vector_buffer%distance_vecs(3, natom))
     215         376 :          IF (in_memory) ALLOCATE (becke_control%vector_buffer%pair_dist_vecs(3, natom, natom))
     216         570 :          ALLOCATE (becke_control%vector_buffer%position_vecs(3, natom))
     217             :       END IF
     218         760 :       ALLOCATE (becke_control%vector_buffer%R12(natom, natom))
     219             :       ! Calculate pairwise distances between each atom pair
     220         760 :       DO i = 1, 3
     221         760 :          cell_v(i) = cell%hmat(i, i)
     222             :       END DO
     223         414 :       DO iatom = 1, natom - 1
     224         672 :          DO jatom = iatom + 1, natom
     225        1032 :             r = particle_set(iatom)%r
     226        1032 :             r1 = particle_set(jatom)%r
     227        1032 :             DO i = 1, 3
     228         774 :                r(i) = MODULO(r(i), cell%hmat(i, i)) - cell%hmat(i, i)/2._dp
     229        1032 :                r1(i) = MODULO(r1(i), cell%hmat(i, i)) - cell%hmat(i, i)/2._dp
     230             :             END DO
     231        1032 :             dist_vec = (r - r1) - ANINT((r - r1)/cell_v)*cell_v
     232             :             ! Store pbc corrected position and pairwise distance vectors for later reuse
     233         258 :             IF (becke_control%vector_buffer%store_vectors) THEN
     234        1032 :                becke_control%vector_buffer%position_vecs(:, iatom) = r(:)
     235         828 :                IF (iatom == 1 .AND. jatom == natom) becke_control%vector_buffer%position_vecs(:, jatom) = r1(:)
     236         258 :                IF (in_memory) THEN
     237         248 :                   becke_control%vector_buffer%pair_dist_vecs(:, iatom, jatom) = dist_vec(:)
     238         248 :                   becke_control%vector_buffer%pair_dist_vecs(:, jatom, iatom) = -dist_vec(:)
     239             :                END IF
     240             :             END IF
     241        1032 :             becke_control%vector_buffer%R12(iatom, jatom) = SQRT(DOT_PRODUCT(dist_vec, dist_vec))
     242         258 :             becke_control%vector_buffer%R12(jatom, iatom) = becke_control%vector_buffer%R12(iatom, jatom)
     243             :             ! Set up heteronuclear cell partitioning using user defined radii
     244         482 :             IF (build) THEN
     245         150 :                CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, kind_number=ikind)
     246         150 :                ircov = becke_control%radii(ikind)
     247         150 :                CALL get_atomic_kind(atomic_kind=particle_set(jatom)%atomic_kind, kind_number=ikind)
     248         150 :                jrcov = becke_control%radii(ikind)
     249         150 :                IF (ircov .NE. jrcov) THEN
     250         122 :                   chi = ircov/jrcov
     251         122 :                   uij = (chi - 1.0_dp)/(chi + 1.0_dp)
     252         122 :                   becke_control%aij(iatom, jatom) = uij/(uij**2 - 1.0_dp)
     253         122 :                   IF (becke_control%aij(iatom, jatom) .GT. 0.5_dp) THEN
     254           0 :                      becke_control%aij(iatom, jatom) = 0.5_dp
     255         122 :                   ELSE IF (becke_control%aij(iatom, jatom) .LT. -0.5_dp) THEN
     256           0 :                      becke_control%aij(iatom, jatom) = -0.5_dp
     257             :                   END IF
     258             :                ELSE
     259          28 :                   becke_control%aij(iatom, jatom) = 0.0_dp
     260             :                END IF
     261             :                ! Note change of sign
     262         150 :                becke_control%aij(jatom, iatom) = -becke_control%aij(iatom, jatom)
     263             :             END IF
     264             :          END DO
     265             :       END DO
     266             :       ! Dump some additional information about the calculation
     267         190 :       IF (cdft_control%first_iteration) THEN
     268         150 :          IF (iw > 0) THEN
     269             :             WRITE (iw, '(/,T3,A)') &
     270          75 :                '----------------------- Becke atomic parameters ------------------------'
     271          75 :             IF (becke_control%adjust) THEN
     272             :                WRITE (iw, '(T3,A)') &
     273          47 :                   'Atom   Element           Cutoff (angstrom)        CDFT Radius (angstrom)'
     274         155 :                DO iatom = 1, natom
     275             :                   CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, element_symbol=element_symbol, &
     276         108 :                                        kind_number=ikind)
     277         108 :                   ircov = cp_unit_from_cp2k(becke_control%radii(ikind), "angstrom")
     278             :                   WRITE (iw, "(i6,T15,A2,T37,F8.3,T67,F8.3)") &
     279         108 :                      iatom, ADJUSTR(element_symbol), cp_unit_from_cp2k(becke_control%cutoffs(iatom), "angstrom"), &
     280         371 :                      ircov
     281             :                END DO
     282             :             ELSE
     283             :                WRITE (iw, '(T3,A)') &
     284          28 :                   'Atom   Element           Cutoff (angstrom)'
     285          87 :                DO iatom = 1, natom
     286          59 :                   CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, element_symbol=element_symbol)
     287             :                   WRITE (iw, "(i7,T15,A2,T37,F8.3)") &
     288          87 :                      iatom, ADJUSTR(element_symbol), cp_unit_from_cp2k(becke_control%cutoffs(iatom), "angstrom")
     289             :                END DO
     290             :             END IF
     291             :             WRITE (iw, '(T3,A)') &
     292          75 :                '------------------------------------------------------------------------'
     293             :             WRITE (iw, '(/,T3,A,T60)') &
     294          75 :                '----------------------- Becke group definitions ------------------------'
     295         160 :             DO igroup = 1, SIZE(group)
     296          85 :                IF (igroup > 1) WRITE (iw, '(T3,A)') ' '
     297             :                WRITE (iw, '(T5,A,I5,A,I5)') &
     298          85 :                   'Atomic group', igroup, ' of ', SIZE(group)
     299          85 :                WRITE (iw, '(T5,A)') 'Atom  Element  Coefficient'
     300         325 :                DO ip = 1, SIZE(group(igroup)%atoms)
     301         165 :                   iatom = group(igroup)%atoms(ip)
     302         165 :                   CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, element_symbol=element_symbol)
     303         250 :                   WRITE (iw, '(i8,T16,A2,T23,F8.3)') iatom, ADJUSTR(element_symbol), group(igroup)%coeff(ip)
     304             :                END DO
     305             :             END DO
     306             :             WRITE (iw, '(T3,A)') &
     307          75 :                '------------------------------------------------------------------------'
     308             :          END IF
     309         150 :          cdft_control%first_iteration = .FALSE.
     310             :       END IF
     311             :       ! Setup cavity confinement using spherical Gaussians
     312         190 :       IF (becke_control%cavity_confine) THEN
     313         174 :          cavity_env => becke_control%cavity_env
     314         174 :          CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, pw_env=pw_env, qs_kind_set=qs_kind_set)
     315         174 :          CPASSERT(ASSOCIATED(qs_kind_set))
     316         174 :          nkind = SIZE(qs_kind_set)
     317             :          ! Setup the Gaussian shape function
     318         174 :          IF (.NOT. ASSOCIATED(cavity_env%kind_shape_fn)) THEN
     319         138 :             IF (ASSOCIATED(becke_control%radii)) THEN
     320         276 :                ALLOCATE (radii_list(SIZE(becke_control%radii)))
     321         276 :                DO ikind = 1, SIZE(becke_control%radii)
     322         276 :                   IF (cavity_env%use_bohr) THEN
     323           4 :                      radii_list(ikind) = becke_control%radii(ikind)
     324             :                   ELSE
     325         180 :                      radii_list(ikind) = cp_unit_from_cp2k(becke_control%radii(ikind), "angstrom")
     326             :                   END IF
     327             :                END DO
     328             :             END IF
     329             :             CALL create_shape_function(cavity_env, qs_kind_set, atomic_kind_set, &
     330             :                                        radius=becke_control%rcavity, &
     331         138 :                                        radii_list=radii_list)
     332         138 :             IF (ASSOCIATED(radii_list)) &
     333          92 :                DEALLOCATE (radii_list)
     334             :          END IF
     335             :          ! Form cavity by summing isolated Gaussian densities over constraint atoms
     336         174 :          NULLIFY (rs_cavity)
     337         174 :          CALL pw_env_get(pw_env, auxbas_rs_grid=rs_cavity, auxbas_pw_pool=auxbas_pw_pool)
     338         174 :          CALL rs_grid_zero(rs_cavity)
     339         174 :          ALLOCATE (pab(1, 1))
     340         174 :          nthread = 1
     341         174 :          ithread = 0
     342         482 :          DO ikind = 1, SIZE(atomic_kind_set)
     343         308 :             numexp = cavity_env%kind_shape_fn(ikind)%numexp
     344         308 :             IF (numexp <= 0) CYCLE
     345         308 :             CALL get_atomic_kind(atomic_kind_set(ikind), natom=katom, atom_list=atom_list)
     346         924 :             ALLOCATE (cores(katom))
     347         616 :             DO iex = 1, numexp
     348         308 :                alpha = cavity_env%kind_shape_fn(ikind)%zet(iex)
     349         308 :                coef = cavity_env%kind_shape_fn(ikind)%coef(iex)
     350         308 :                npme = 0
     351         688 :                cores = 0
     352         688 :                DO iatom = 1, katom
     353         688 :                   IF (rs_cavity%desc%parallel .AND. .NOT. rs_cavity%desc%distributed) THEN
     354             :                      ! replicated realspace grid, split the atoms up between procs
     355         380 :                      IF (MODULO(iatom, rs_cavity%desc%group_size) == rs_cavity%desc%my_pos) THEN
     356         190 :                         npme = npme + 1
     357         190 :                         cores(npme) = iatom
     358             :                      END IF
     359             :                   ELSE
     360           0 :                      npme = npme + 1
     361           0 :                      cores(npme) = iatom
     362             :                   END IF
     363             :                END DO
     364         806 :                DO j = 1, npme
     365         190 :                   iatom = cores(j)
     366         190 :                   atom_a = atom_list(iatom)
     367         190 :                   pab(1, 1) = coef
     368         190 :                   IF (becke_control%vector_buffer%store_vectors) THEN
     369         760 :                      ra(:) = becke_control%vector_buffer%position_vecs(:, atom_a) + cell_v(:)/2._dp
     370             :                   ELSE
     371           0 :                      ra(:) = pbc(particle_set(atom_a)%r, cell)
     372             :                   END IF
     373         498 :                   IF (is_constraint(atom_a)) THEN
     374             :                      radius = exp_radius_very_extended(la_min=0, la_max=0, lb_min=0, lb_max=0, &
     375             :                                                        ra=ra, rb=ra, rp=ra, zetp=alpha, &
     376             :                                                        eps=dft_control%qs_control%eps_rho_rspace, &
     377             :                                                        pab=pab, o1=0, o2=0, &  ! without map_consistent
     378         171 :                                                        prefactor=1.0_dp, cutoff=0.0_dp)
     379             : 
     380             :                      CALL collocate_pgf_product(0, alpha, 0, 0, 0.0_dp, 0, ra, &
     381             :                                                 (/0.0_dp, 0.0_dp, 0.0_dp/), 1.0_dp, &
     382             :                                                 pab, 0, 0, rs_cavity, &
     383             :                                                 radius=radius, ga_gb_function=GRID_FUNC_AB, &
     384         171 :                                                 use_subpatch=.TRUE., subpatch_pattern=0)
     385             :                   END IF
     386             :                END DO
     387             :             END DO
     388         790 :             DEALLOCATE (cores)
     389             :          END DO
     390         174 :          DEALLOCATE (pab)
     391         174 :          CALL auxbas_pw_pool%create_pw(becke_control%cavity)
     392         174 :          CALL transfer_rs2pw(rs_cavity, becke_control%cavity)
     393             :          ! Grid points where the Gaussian density falls below eps_cavity are ignored
     394             :          ! We can calculate the smallest/largest values along z-direction outside
     395             :          ! which the cavity is zero at every point (x, y)
     396             :          ! If gradients are needed storage needs to be allocated only for grid points within
     397             :          ! these bounds
     398         174 :          IF (in_memory .OR. cdft_control%save_pot) THEN
     399          64 :             CALL hfun_zero(becke_control%cavity%array, eps_cavity, just_bounds=.TRUE., bounds=bounds)
     400             :             ! Save bounds (first nonzero grid point indices)
     401         640 :             bo = group(1)%weight%pw_grid%bounds_local
     402          64 :             IF (bounds(2) .LT. bo(2, 3)) THEN
     403           8 :                bounds(2) = bounds(2) - 1
     404             :             ELSE
     405          56 :                bounds(2) = bo(2, 3)
     406             :             END IF
     407          64 :             IF (bounds(1) .GT. bo(1, 3)) THEN
     408             :                ! In the special case bounds(1) == bounds(2) == bo(2, 3), after this check
     409             :                ! bounds(1) > bounds(2) and the subsequent gradient allocation (:, :, :, bounds(1):bounds(2))
     410             :                ! will correctly allocate a 0-sized array
     411           8 :                bounds(1) = bounds(1) + 1
     412             :             ELSE
     413          56 :                bounds(1) = bo(1, 3)
     414             :             END IF
     415         192 :             becke_control%confine_bounds = bounds
     416             :          END IF
     417             :          ! Optional printing of cavity (meant for testing, so options currently hardcoded...)
     418         174 :          IF (becke_control%print_cavity) THEN
     419           2 :             CALL hfun_zero(becke_control%cavity%array, eps_cavity, just_bounds=.FALSE.)
     420           2 :             ALLOCATE (stride(3))
     421           8 :             stride = (/2, 2, 2/)
     422           2 :             mpi_io = .TRUE.
     423             :             ! Note PROGRAM_RUN_INFO section neeeds to be active!
     424             :             unit_nr = cp_print_key_unit_nr(logger, cdft_constraint_section, "PROGRAM_RUN_INFO", &
     425             :                                            middle_name="BECKE_CAVITY", &
     426             :                                            extension=".cube", file_position="REWIND", &
     427           2 :                                            log_filename=.FALSE., mpi_io=mpi_io)
     428           2 :             IF (para_env%is_source() .AND. unit_nr .LT. 1) &
     429             :                CALL cp_abort(__LOCATION__, &
     430           0 :                              "Please turn on PROGRAM_RUN_INFO to print cavity")
     431           2 :             CALL get_qs_env(qs_env, subsys=subsys)
     432           2 :             CALL qs_subsys_get(subsys, particles=particles)
     433           2 :             CALL cp_pw_to_cube(becke_control%cavity, unit_nr, "CAVITY", particles=particles, stride=stride, mpi_io=mpi_io)
     434           2 :             CALL cp_print_key_finished_output(unit_nr, logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io)
     435           2 :             DEALLOCATE (stride)
     436             :          END IF
     437             :       END IF
     438         190 :       IF (ALLOCATED(is_constraint)) &
     439         174 :          DEALLOCATE (is_constraint)
     440         190 :       CALL timestop(handle)
     441             : 
     442         380 :    END SUBROUTINE becke_constraint_init
     443             : 
     444             : ! **************************************************************************************************
     445             : !> \brief reads the input parameters specific to Becke-based CDFT constraints
     446             : !> \param cdft_control the cdft_control which holds the Becke control type
     447             : !> \param becke_section the input section containing Becke constraint information
     448             : !> \par   History
     449             : !>        Created 01.2007 [fschiff]
     450             : !>        Merged Becke into CDFT 09.2018 [Nico Holmberg]
     451             : !> \author Nico Holmberg [09.2018]
     452             : ! **************************************************************************************************
     453         236 :    SUBROUTINE read_becke_section(cdft_control, becke_section)
     454             : 
     455             :       TYPE(cdft_control_type), INTENT(INOUT)             :: cdft_control
     456             :       TYPE(section_vals_type), POINTER                   :: becke_section
     457             : 
     458             :       INTEGER                                            :: j
     459             :       LOGICAL                                            :: exists
     460         236 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rtmplist
     461             :       TYPE(becke_constraint_type), POINTER               :: becke_control
     462             : 
     463         236 :       NULLIFY (rtmplist)
     464         236 :       becke_control => cdft_control%becke_control
     465           0 :       CPASSERT(ASSOCIATED(becke_control))
     466             : 
     467             :       ! Atomic size corrections
     468         236 :       CALL section_vals_val_get(becke_section, "ADJUST_SIZE", l_val=becke_control%adjust)
     469         236 :       IF (becke_control%adjust) THEN
     470         156 :          CALL section_vals_val_get(becke_section, "ATOMIC_RADII", explicit=exists)
     471         156 :          IF (.NOT. exists) CPABORT("Keyword ATOMIC_RADII is missing.")
     472         156 :          CALL section_vals_val_get(becke_section, "ATOMIC_RADII", r_vals=rtmplist)
     473         156 :          CPASSERT(SIZE(rtmplist) > 0)
     474         468 :          ALLOCATE (becke_control%radii_tmp(SIZE(rtmplist)))
     475         624 :          DO j = 1, SIZE(rtmplist)
     476         468 :             becke_control%radii_tmp(j) = rtmplist(j)
     477             :          END DO
     478             :       END IF
     479             : 
     480             :       ! Cutoff scheme
     481         236 :       CALL section_vals_val_get(becke_section, "CUTOFF_TYPE", i_val=becke_control%cutoff_type)
     482         376 :       SELECT CASE (becke_control%cutoff_type)
     483             :       CASE (becke_cutoff_global)
     484         140 :          CALL section_vals_val_get(becke_section, "GLOBAL_CUTOFF", r_val=becke_control%rglobal)
     485             :       CASE (becke_cutoff_element)
     486          96 :          CALL section_vals_val_get(becke_section, "ELEMENT_CUTOFF", r_vals=rtmplist)
     487          96 :          CPASSERT(SIZE(rtmplist) > 0)
     488         288 :          ALLOCATE (becke_control%cutoffs_tmp(SIZE(rtmplist)))
     489         524 :          DO j = 1, SIZE(rtmplist)
     490         288 :             becke_control%cutoffs_tmp(j) = rtmplist(j)
     491             :          END DO
     492             :       END SELECT
     493             : 
     494             :       ! Gaussian cavity confinement
     495         236 :       CALL section_vals_val_get(becke_section, "CAVITY_CONFINE", l_val=becke_control%cavity_confine)
     496         236 :       CALL section_vals_val_get(becke_section, "SHOULD_SKIP", l_val=becke_control%should_skip)
     497         236 :       CALL section_vals_val_get(becke_section, "IN_MEMORY", l_val=becke_control%in_memory)
     498         236 :       IF (cdft_control%becke_control%cavity_confine) THEN
     499         222 :          CALL section_vals_val_get(becke_section, "CAVITY_SHAPE", i_val=becke_control%cavity_shape)
     500         222 :          IF (becke_control%cavity_shape == radius_user .AND. .NOT. becke_control%adjust) &
     501             :             CALL cp_abort(__LOCATION__, &
     502           0 :                           "Activate keyword ADJUST_SIZE to use cavity shape USER.")
     503         222 :          CALL section_vals_val_get(becke_section, "CAVITY_RADIUS", r_val=becke_control%rcavity)
     504         222 :          CALL section_vals_val_get(becke_section, "EPS_CAVITY", r_val=becke_control%eps_cavity)
     505         222 :          CALL section_vals_val_get(becke_section, "CAVITY_PRINT", l_val=becke_control%print_cavity)
     506         222 :          CALL section_vals_val_get(becke_section, "CAVITY_USE_BOHR", l_val=becke_control%use_bohr)
     507         222 :          IF (.NOT. cdft_control%becke_control%use_bohr) THEN
     508         220 :             becke_control%rcavity = cp_unit_from_cp2k(becke_control%rcavity, "angstrom")
     509             :          END IF
     510         222 :          CALL create_hirshfeld_type(becke_control%cavity_env)
     511             :          CALL set_hirshfeld_info(becke_control%cavity_env, &
     512             :                                  shape_function_type=shape_function_gaussian, iterative=.FALSE., &
     513             :                                  radius_type=becke_control%cavity_shape, &
     514         222 :                                  use_bohr=becke_control%use_bohr)
     515             :       END IF
     516             : 
     517         236 :       CALL cite_reference(Becke1988b)
     518             : 
     519         236 :    END SUBROUTINE read_becke_section
     520             : 
     521             : ! **************************************************************************************************
     522             : !> \brief reads the input parameters needed to define CDFT constraints
     523             : !> \param cdft_control the object which holds the CDFT control type
     524             : !> \param cdft_control_section the input section containing CDFT constraint information
     525             : !> \author Nico Holmberg [09.2018]
     526             : ! **************************************************************************************************
     527         264 :    SUBROUTINE read_constraint_definitions(cdft_control, cdft_control_section)
     528             : 
     529             :       TYPE(cdft_control_type), INTENT(INOUT)             :: cdft_control
     530             :       TYPE(section_vals_type), INTENT(INOUT), POINTER    :: cdft_control_section
     531             : 
     532             :       INTEGER                                            :: i, j, jj, k, n_rep, natoms, nvar, &
     533             :                                                             tot_natoms
     534         264 :       INTEGER, DIMENSION(:), POINTER                     :: atomlist, dummylist, tmplist
     535             :       LOGICAL                                            :: exists, is_duplicate
     536         264 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rtmplist
     537             :       TYPE(section_vals_type), POINTER                   :: group_section
     538             : 
     539         264 :       NULLIFY (tmplist, rtmplist, atomlist, dummylist, group_section)
     540             : 
     541         528 :       group_section => section_vals_get_subs_vals(cdft_control_section, "ATOM_GROUP")
     542         264 :       CALL section_vals_get(group_section, n_repetition=nvar, explicit=exists)
     543         264 :       IF (.NOT. exists) CPABORT("Section ATOM_GROUP is missing.")
     544        1078 :       ALLOCATE (cdft_control%group(nvar))
     545         264 :       tot_natoms = 0
     546             :       ! Parse all ATOM_GROUP sections
     547         550 :       DO k = 1, nvar
     548             :          ! First determine how much storage is needed
     549         286 :          natoms = 0
     550         286 :          CALL section_vals_val_get(group_section, "ATOMS", i_rep_section=k, n_rep_val=n_rep)
     551         572 :          DO j = 1, n_rep
     552         286 :             CALL section_vals_val_get(group_section, "ATOMS", i_rep_section=k, i_rep_val=j, i_vals=tmplist)
     553         286 :             IF (SIZE(tmplist) < 1) &
     554           0 :                CPABORT("Each ATOM_GROUP must contain at least 1 atom.")
     555         572 :             natoms = natoms + SIZE(tmplist)
     556             :          END DO
     557         858 :          ALLOCATE (cdft_control%group(k)%atoms(natoms))
     558         858 :          ALLOCATE (cdft_control%group(k)%coeff(natoms))
     559         286 :          NULLIFY (cdft_control%group(k)%weight)
     560         286 :          NULLIFY (cdft_control%group(k)%integrated)
     561         286 :          tot_natoms = tot_natoms + natoms
     562             :          ! Now parse
     563         286 :          jj = 0
     564         572 :          DO j = 1, n_rep
     565         286 :             CALL section_vals_val_get(group_section, "ATOMS", i_rep_section=k, i_rep_val=j, i_vals=tmplist)
     566        1102 :             DO i = 1, SIZE(tmplist)
     567         530 :                jj = jj + 1
     568         816 :                cdft_control%group(k)%atoms(jj) = tmplist(i)
     569             :             END DO
     570             :          END DO
     571         286 :          CALL section_vals_val_get(group_section, "COEFF", i_rep_section=k, n_rep_val=n_rep)
     572         286 :          jj = 0
     573         572 :          DO j = 1, n_rep
     574         286 :             CALL section_vals_val_get(group_section, "COEFF", i_rep_section=k, i_rep_val=j, r_vals=rtmplist)
     575        1102 :             DO i = 1, SIZE(rtmplist)
     576         530 :                jj = jj + 1
     577         530 :                IF (jj > natoms) CPABORT("Length of keywords ATOMS and COEFF must match.")
     578         530 :                IF (ABS(rtmplist(i)) /= 1.0_dp) CPABORT("Keyword COEFF accepts only values +/-1.0")
     579         816 :                cdft_control%group(k)%coeff(jj) = rtmplist(i)
     580             :             END DO
     581             :          END DO
     582         286 :          IF (jj < natoms) CPABORT("Length of keywords ATOMS and COEFF must match.")
     583             :          CALL section_vals_val_get(group_section, "CONSTRAINT_TYPE", i_rep_section=k, &
     584         286 :                                    i_val=cdft_control%group(k)%constraint_type)
     585             :          CALL section_vals_val_get(group_section, "FRAGMENT_CONSTRAINT", i_rep_section=k, &
     586         286 :                                    l_val=cdft_control%group(k)%is_fragment_constraint)
     587        1122 :          IF (cdft_control%group(k)%is_fragment_constraint) cdft_control%fragment_density = .TRUE.
     588             :       END DO
     589             :       ! Create a list containing all constraint atoms
     590         792 :       ALLOCATE (atomlist(tot_natoms))
     591         794 :       atomlist = -1
     592         264 :       jj = 0
     593         550 :       DO k = 1, nvar
     594        1080 :          DO j = 1, SIZE(cdft_control%group(k)%atoms)
     595         530 :             is_duplicate = .FALSE.
     596        1286 :             DO i = 1, jj + 1
     597        1286 :                IF (cdft_control%group(k)%atoms(j) == atomlist(i)) THEN
     598             :                   is_duplicate = .TRUE.
     599             :                   EXIT
     600             :                END IF
     601             :             END DO
     602         816 :             IF (.NOT. is_duplicate) THEN
     603         492 :                jj = jj + 1
     604         492 :                atomlist(jj) = cdft_control%group(k)%atoms(j)
     605             :             END IF
     606             :          END DO
     607             :       END DO
     608         264 :       CALL reallocate(atomlist, 1, jj)
     609             :       CALL section_vals_val_get(cdft_control_section, "ATOMIC_CHARGES", &
     610         264 :                                 l_val=cdft_control%atomic_charges)
     611             :       ! Parse any dummy atoms (no constraint, just charges)
     612         264 :       IF (cdft_control%atomic_charges) THEN
     613         116 :          group_section => section_vals_get_subs_vals(cdft_control_section, "DUMMY_ATOMS")
     614         116 :          CALL section_vals_get(group_section, explicit=exists)
     615         116 :          IF (exists) THEN
     616             :             ! First determine how many atoms there are
     617           2 :             natoms = 0
     618           2 :             CALL section_vals_val_get(group_section, "ATOMS", n_rep_val=n_rep)
     619           4 :             DO j = 1, n_rep
     620           2 :                CALL section_vals_val_get(group_section, "ATOMS", i_rep_val=j, i_vals=tmplist)
     621           2 :                IF (SIZE(tmplist) < 1) &
     622           0 :                   CPABORT("DUMMY_ATOMS must contain at least 1 atom.")
     623           4 :                natoms = natoms + SIZE(tmplist)
     624             :             END DO
     625           6 :             ALLOCATE (dummylist(natoms))
     626             :             ! Now parse
     627           2 :             jj = 0
     628           4 :             DO j = 1, n_rep
     629           2 :                CALL section_vals_val_get(group_section, "ATOMS", i_rep_val=j, i_vals=tmplist)
     630           6 :                DO i = 1, SIZE(tmplist)
     631           2 :                   jj = jj + 1
     632           4 :                   dummylist(jj) = tmplist(i)
     633             :                END DO
     634             :             END DO
     635             :             ! Check for duplicates
     636           4 :             DO j = 1, natoms
     637           4 :                DO i = j + 1, natoms
     638           0 :                   IF (dummylist(i) == dummylist(j)) &
     639           2 :                      CPABORT("Duplicate atoms defined in section DUMMY_ATOMS.")
     640             :                END DO
     641             :             END DO
     642             :             ! Check that a dummy atom is not included in any ATOM_GROUP
     643           6 :             DO j = 1, SIZE(atomlist)
     644           6 :                DO i = 1, SIZE(dummylist)
     645           2 :                   IF (dummylist(i) == atomlist(j)) &
     646             :                      CALL cp_abort(__LOCATION__, &
     647           2 :                                    "Duplicate atoms defined in sections ATOM_GROUP and DUMMY_ATOMS.")
     648             :                END DO
     649             :             END DO
     650             :          END IF
     651             :       END IF
     652             :       ! Join dummy atoms and constraint atoms into one list
     653         264 :       IF (ASSOCIATED(dummylist)) THEN
     654           2 :          cdft_control%natoms = SIZE(atomlist) + SIZE(dummylist)
     655             :       ELSE
     656         262 :          cdft_control%natoms = SIZE(atomlist)
     657             :       END IF
     658         792 :       ALLOCATE (cdft_control%atoms(cdft_control%natoms))
     659         792 :       ALLOCATE (cdft_control%is_constraint(cdft_control%natoms))
     660         732 :       IF (cdft_control%atomic_charges) ALLOCATE (cdft_control%charge(cdft_control%natoms))
     661         756 :       cdft_control%atoms(1:SIZE(atomlist)) = atomlist
     662         264 :       IF (ASSOCIATED(dummylist)) THEN
     663           4 :          cdft_control%atoms(1 + SIZE(atomlist):) = dummylist
     664           2 :          DEALLOCATE (dummylist)
     665             :       END IF
     666         758 :       cdft_control%is_constraint = .FALSE.
     667         756 :       cdft_control%is_constraint(1:SIZE(atomlist)) = .TRUE.
     668         264 :       DEALLOCATE (atomlist)
     669             :       ! Get constraint potential definitions from input
     670         792 :       ALLOCATE (cdft_control%strength(nvar))
     671         792 :       ALLOCATE (cdft_control%value(nvar))
     672         792 :       ALLOCATE (cdft_control%target(nvar))
     673         264 :       CALL section_vals_val_get(cdft_control_section, "STRENGTH", r_vals=rtmplist)
     674         264 :       IF (SIZE(rtmplist) /= nvar) &
     675             :          CALL cp_abort(__LOCATION__, &
     676             :                        "The length of keyword STRENGTH is incorrect. "// &
     677             :                        "Expected "//TRIM(ADJUSTL(cp_to_string(nvar)))// &
     678             :                        " value(s), got "// &
     679           0 :                        TRIM(ADJUSTL(cp_to_string(SIZE(rtmplist))))//" value(s).")
     680         550 :       DO j = 1, nvar
     681         550 :          cdft_control%strength(j) = rtmplist(j)
     682             :       END DO
     683         264 :       CALL section_vals_val_get(cdft_control_section, "TARGET", r_vals=rtmplist)
     684         264 :       IF (SIZE(rtmplist) /= nvar) &
     685             :          CALL cp_abort(__LOCATION__, &
     686             :                        "The length of keyword TARGET is incorrect. "// &
     687             :                        "Expected "//TRIM(ADJUSTL(cp_to_string(nvar)))// &
     688             :                        " value(s), got "// &
     689           0 :                        TRIM(ADJUSTL(cp_to_string(SIZE(rtmplist))))//" value(s).")
     690         550 :       DO j = 1, nvar
     691         550 :          cdft_control%target(j) = rtmplist(j)
     692             :       END DO
     693             :       ! Read fragment constraint definitions
     694         264 :       IF (cdft_control%fragment_density) THEN
     695             :          CALL section_vals_val_get(cdft_control_section, "FRAGMENT_A_FILE_NAME", &
     696          10 :                                    c_val=cdft_control%fragment_a_fname)
     697             :          CALL section_vals_val_get(cdft_control_section, "FRAGMENT_B_FILE_NAME", &
     698          10 :                                    c_val=cdft_control%fragment_b_fname)
     699             :          CALL section_vals_val_get(cdft_control_section, "FRAGMENT_A_SPIN_FILE", &
     700          10 :                                    c_val=cdft_control%fragment_a_spin_fname)
     701             :          CALL section_vals_val_get(cdft_control_section, "FRAGMENT_B_SPIN_FILE", &
     702          10 :                                    c_val=cdft_control%fragment_b_spin_fname)
     703             :          CALL section_vals_val_get(cdft_control_section, "FLIP_FRAGMENT_A", &
     704          10 :                                    l_val=cdft_control%flip_fragment(1))
     705             :          CALL section_vals_val_get(cdft_control_section, "FLIP_FRAGMENT_B", &
     706          10 :                                    l_val=cdft_control%flip_fragment(2))
     707             :       END IF
     708             : 
     709         264 :    END SUBROUTINE read_constraint_definitions
     710             : 
     711             : ! **************************************************************************************************
     712             : !> \brief reads the input parameters needed for CDFT with OT
     713             : !> \param qs_control the qs_control which holds the CDFT control type
     714             : !> \param cdft_control_section the input section for CDFT
     715             : !> \author Nico Holmberg [12.2015]
     716             : ! **************************************************************************************************
     717         528 :    SUBROUTINE read_cdft_control_section(qs_control, cdft_control_section)
     718             :       TYPE(qs_control_type), INTENT(INOUT)               :: qs_control
     719             :       TYPE(section_vals_type), POINTER                   :: cdft_control_section
     720             : 
     721             :       INTEGER                                            :: k, nvar
     722             :       LOGICAL                                            :: exists
     723             :       TYPE(cdft_control_type), POINTER                   :: cdft_control
     724             :       TYPE(section_vals_type), POINTER                   :: becke_constraint_section, group_section, &
     725             :                                                             hirshfeld_constraint_section, &
     726             :                                                             outer_scf_section, print_section
     727             : 
     728         264 :       NULLIFY (outer_scf_section, hirshfeld_constraint_section, becke_constraint_section, &
     729         264 :                print_section, group_section)
     730         264 :       cdft_control => qs_control%cdft_control
     731         264 :       CPASSERT(ASSOCIATED(cdft_control))
     732         264 :       group_section => section_vals_get_subs_vals(cdft_control_section, "ATOM_GROUP")
     733         264 :       CALL section_vals_get(group_section, n_repetition=nvar, explicit=exists)
     734             : 
     735             :       CALL section_vals_val_get(cdft_control_section, "TYPE_OF_CONSTRAINT", &
     736         264 :                                 i_val=qs_control%cdft_control%type)
     737             : 
     738         264 :       IF (cdft_control%type /= outer_scf_none) THEN
     739             :          CALL section_vals_val_get(cdft_control_section, "REUSE_PRECOND", &
     740         264 :                                    l_val=cdft_control%reuse_precond)
     741             :          CALL section_vals_val_get(cdft_control_section, "PRECOND_FREQ", &
     742         264 :                                    i_val=cdft_control%precond_freq)
     743             :          CALL section_vals_val_get(cdft_control_section, "MAX_REUSE", &
     744         264 :                                    i_val=cdft_control%max_reuse)
     745             :          CALL section_vals_val_get(cdft_control_section, "PURGE_HISTORY", &
     746         264 :                                    l_val=cdft_control%purge_history)
     747             :          CALL section_vals_val_get(cdft_control_section, "PURGE_FREQ", &
     748         264 :                                    i_val=cdft_control%purge_freq)
     749             :          CALL section_vals_val_get(cdft_control_section, "PURGE_OFFSET", &
     750         264 :                                    i_val=cdft_control%purge_offset)
     751             :          CALL section_vals_val_get(cdft_control_section, "COUNTER", &
     752         264 :                                    i_val=cdft_control%ienergy)
     753         264 :          print_section => section_vals_get_subs_vals(cdft_control_section, "PROGRAM_RUN_INFO%WEIGHT_FUNCTION")
     754         264 :          CALL section_vals_get(print_section, explicit=cdft_control%print_weight)
     755             : 
     756         264 :          outer_scf_section => section_vals_get_subs_vals(cdft_control_section, "OUTER_SCF")
     757         264 :          CALL outer_scf_read_parameters(cdft_control%constraint_control, outer_scf_section)
     758         264 :          IF (cdft_control%constraint_control%have_scf) THEN
     759         264 :             IF (cdft_control%constraint_control%type /= outer_scf_cdft_constraint) &
     760           0 :                CPABORT("Unsupported CDFT constraint.")
     761             :             ! Constraint definitions
     762         264 :             CALL read_constraint_definitions(cdft_control, cdft_control_section)
     763             :             ! Constraint-specific initializations
     764         500 :             SELECT CASE (cdft_control%type)
     765             :             CASE (outer_scf_becke_constraint)
     766         236 :                becke_constraint_section => section_vals_get_subs_vals(cdft_control_section, "BECKE_CONSTRAINT")
     767         236 :                CALL section_vals_get(becke_constraint_section, explicit=exists)
     768         236 :                IF (.NOT. exists) CPABORT("BECKE_CONSTRAINT section is missing.")
     769         494 :                DO k = 1, nvar
     770         494 :                   NULLIFY (cdft_control%group(k)%gradients)
     771             :                END DO
     772         236 :                CALL read_becke_section(cdft_control, becke_constraint_section)
     773             :             CASE (outer_scf_hirshfeld_constraint)
     774          28 :                hirshfeld_constraint_section => section_vals_get_subs_vals(cdft_control_section, "HIRSHFELD_CONSTRAINT")
     775          28 :                CALL section_vals_get(hirshfeld_constraint_section, explicit=exists)
     776          28 :                IF (.NOT. exists) CPABORT("HIRSHFELD_CONSTRAINT section is missing.")
     777          56 :                DO k = 1, nvar
     778          28 :                   NULLIFY (cdft_control%group(k)%gradients_x)
     779          28 :                   NULLIFY (cdft_control%group(k)%gradients_y)
     780          56 :                   NULLIFY (cdft_control%group(k)%gradients_z)
     781             :                END DO
     782          28 :                CALL read_hirshfeld_constraint_section(cdft_control, hirshfeld_constraint_section)
     783             :             CASE DEFAULT
     784         528 :                CPABORT("Unknown constraint type.")
     785             :             END SELECT
     786             : 
     787         264 :             CALL cite_reference(Holmberg2017)
     788         264 :             CALL cite_reference(Holmberg2018)
     789             :          ELSE
     790           0 :             qs_control%cdft = .FALSE.
     791             :          END IF
     792             :       ELSE
     793           0 :          qs_control%cdft = .FALSE.
     794             :       END IF
     795             : 
     796         264 :    END SUBROUTINE read_cdft_control_section
     797             : 
     798             : ! **************************************************************************************************
     799             : !> \brief reads the input parameters needed for Hirshfeld constraint
     800             : !> \param cdft_control the cdft_control which holds the Hirshfeld constraint
     801             : !> \param hirshfeld_section the input section for a Hirshfeld constraint
     802             : ! **************************************************************************************************
     803          28 :    SUBROUTINE read_hirshfeld_constraint_section(cdft_control, hirshfeld_section)
     804             :       TYPE(cdft_control_type), INTENT(INOUT)             :: cdft_control
     805             :       TYPE(section_vals_type), POINTER                   :: hirshfeld_section
     806             : 
     807             :       LOGICAL                                            :: exists
     808          28 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: rtmplist
     809             :       TYPE(hirshfeld_constraint_type), POINTER           :: hirshfeld_control
     810             : 
     811          28 :       NULLIFY (rtmplist)
     812          28 :       hirshfeld_control => cdft_control%hirshfeld_control
     813           0 :       CPASSERT(ASSOCIATED(hirshfeld_control))
     814             : 
     815          28 :       CALL section_vals_val_get(hirshfeld_section, "SHAPE_FUNCTION", i_val=hirshfeld_control%shape_function)
     816          28 :       CALL section_vals_val_get(hirshfeld_section, "GAUSSIAN_SHAPE", i_val=hirshfeld_control%gaussian_shape)
     817          28 :       CALL section_vals_val_get(hirshfeld_section, "GAUSSIAN_RADIUS", r_val=hirshfeld_control%radius)
     818          28 :       CALL section_vals_val_get(hirshfeld_section, "USE_BOHR", l_val=hirshfeld_control%use_bohr)
     819          28 :       CALL section_vals_val_get(hirshfeld_section, "USE_ATOMIC_CUTOFF", l_val=hirshfeld_control%use_atomic_cutoff)
     820          28 :       CALL section_vals_val_get(hirshfeld_section, "PRINT_DENSITY", l_val=hirshfeld_control%print_density)
     821          28 :       CALL section_vals_val_get(hirshfeld_section, "EPS_CUTOFF", r_val=hirshfeld_control%eps_cutoff)
     822          28 :       CALL section_vals_val_get(hirshfeld_section, "ATOMIC_CUTOFF", r_val=hirshfeld_control%atomic_cutoff)
     823             : 
     824          28 :       IF (.NOT. hirshfeld_control%use_bohr) THEN
     825          28 :          hirshfeld_control%radius = cp_unit_from_cp2k(hirshfeld_control%radius, "angstrom")
     826             :       END IF
     827             : 
     828          28 :       IF (hirshfeld_control%shape_function == shape_function_gaussian .AND. &
     829             :           hirshfeld_control%gaussian_shape == radius_user) THEN
     830           0 :          CALL section_vals_val_get(hirshfeld_section, "ATOMIC_RADII", explicit=exists)
     831           0 :          IF (.NOT. exists) CPABORT("Keyword ATOMIC_RADII is missing.")
     832           0 :          CALL section_vals_val_get(hirshfeld_section, "ATOMIC_RADII", r_vals=rtmplist)
     833           0 :          CPASSERT(SIZE(rtmplist) > 0)
     834           0 :          ALLOCATE (hirshfeld_control%radii(SIZE(rtmplist)))
     835           0 :          hirshfeld_control%radii(:) = rtmplist
     836             :       END IF
     837             : 
     838          28 :       CALL create_hirshfeld_type(hirshfeld_control%hirshfeld_env)
     839             :       CALL set_hirshfeld_info(hirshfeld_control%hirshfeld_env, &
     840             :                               shape_function_type=hirshfeld_control%shape_function, &
     841             :                               iterative=.FALSE., &
     842             :                               radius_type=hirshfeld_control%gaussian_shape, &
     843          28 :                               use_bohr=hirshfeld_control%use_bohr)
     844             : 
     845          28 :    END SUBROUTINE read_hirshfeld_constraint_section
     846             : 
     847             : ! **************************************************************************************************
     848             : !> \brief Calculate fout = fun1/fun2 or fout = fun1*fun2
     849             : !> \param fout the output 3D potential
     850             : !> \param fun1 the first input 3D potential
     851             : !> \param fun2 the second input 3D potential
     852             : !> \param divide logical that decides whether to divide or multiply the input potentials
     853             : !> \param small customisable parameter to determine lower bound of division
     854             : ! **************************************************************************************************
     855          40 :    SUBROUTINE hfun_scale(fout, fun1, fun2, divide, small)
     856             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(OUT)     :: fout
     857             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN)      :: fun1, fun2
     858             :       LOGICAL, INTENT(IN)                                :: divide
     859             :       REAL(KIND=dp), INTENT(IN)                          :: small
     860             : 
     861             :       INTEGER                                            :: i1, i2, i3, n1, n2, n3
     862             : 
     863          40 :       n1 = SIZE(fout, 1)
     864          40 :       n2 = SIZE(fout, 2)
     865          40 :       n3 = SIZE(fout, 3)
     866          40 :       CPASSERT(n1 == SIZE(fun1, 1))
     867          40 :       CPASSERT(n2 == SIZE(fun1, 2))
     868          40 :       CPASSERT(n3 == SIZE(fun1, 3))
     869          40 :       CPASSERT(n1 == SIZE(fun2, 1))
     870          40 :       CPASSERT(n2 == SIZE(fun2, 2))
     871          40 :       CPASSERT(n3 == SIZE(fun2, 3))
     872             : 
     873          40 :       IF (divide) THEN
     874        1640 :          DO i3 = 1, n3
     875       65640 :             DO i2 = 1, n2
     876     1409600 :                DO i1 = 1, n1
     877     1408000 :                   IF (fun2(i1, i2, i3) > small) THEN
     878     1163532 :                      fout(i1, i2, i3) = fun1(i1, i2, i3)/fun2(i1, i2, i3)
     879             :                   ELSE
     880      180468 :                      fout(i1, i2, i3) = 0.0_dp
     881             :                   END IF
     882             :                END DO
     883             :             END DO
     884             :          END DO
     885             :       ELSE
     886           0 :          DO i3 = 1, n3
     887           0 :             DO i2 = 1, n2
     888           0 :                DO i1 = 1, n1
     889           0 :                   fout(i1, i2, i3) = fun1(i1, i2, i3)*fun2(i1, i2, i3)
     890             :                END DO
     891             :             END DO
     892             :          END DO
     893             :       END IF
     894             : 
     895          40 :    END SUBROUTINE hfun_scale
     896             : 
     897             : ! **************************************************************************************************
     898             : !> \brief Determine confinement bounds along confinement dir (hardcoded to be z)
     899             : !>        and optionally zero entries below a given threshold
     900             : !> \param fun input 3D potential (real space)
     901             : !> \param th threshold for screening values
     902             : !> \param just_bounds if the bounds should be computed without zeroing values
     903             : !> \param bounds the confinement bounds: fun is nonzero only between these values along 3rd dimension
     904             : ! **************************************************************************************************
     905          66 :    SUBROUTINE hfun_zero(fun, th, just_bounds, bounds)
     906             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(INOUT)   :: fun
     907             :       REAL(KIND=dp), INTENT(IN)                          :: th
     908             :       LOGICAL                                            :: just_bounds
     909             :       INTEGER, OPTIONAL                                  :: bounds(2)
     910             : 
     911             :       INTEGER                                            :: i1, i2, i3, lb, n1, n2, n3, nzeroed, &
     912             :                                                             nzeroed_inner, ub
     913             :       LOGICAL                                            :: lb_final, ub_final
     914             : 
     915          66 :       n1 = SIZE(fun, 1)
     916          66 :       n2 = SIZE(fun, 2)
     917          66 :       n3 = SIZE(fun, 3)
     918          66 :       IF (just_bounds) THEN
     919          64 :          CPASSERT(PRESENT(bounds))
     920             :          lb = 1
     921             :          lb_final = .FALSE.
     922             :          ub_final = .FALSE.
     923             :       END IF
     924             : 
     925        2898 :       DO i3 = 1, n3
     926        2832 :          IF (just_bounds) nzeroed = 0
     927       20466 :          DO i2 = 1, n2
     928       20306 :             IF (just_bounds) nzeroed_inner = 0
     929      518013 :             DO i1 = 1, n1
     930      520685 :                IF (fun(i1, i2, i3) < th) THEN
     931      446635 :                   IF (just_bounds) THEN
     932      433707 :                      nzeroed_inner = nzeroed_inner + 1
     933             :                   ELSE
     934       12928 :                      fun(i1, i2, i3) = 0.0_dp
     935             :                   END IF
     936             :                ELSE
     937       53744 :                   IF (just_bounds) EXIT
     938             :                END IF
     939             :             END DO
     940       23138 :             IF (just_bounds) THEN
     941       17106 :                IF (nzeroed_inner < n1) EXIT
     942       14434 :                nzeroed = nzeroed + nzeroed_inner
     943             :             END IF
     944             :          END DO
     945        2898 :          IF (just_bounds) THEN
     946        2752 :             IF (nzeroed == (n2*n1)) THEN
     947          80 :                IF (.NOT. lb_final) THEN
     948             :                   lb = i3
     949          56 :                ELSE IF (.NOT. ub_final) THEN
     950           8 :                   ub = i3
     951           8 :                   ub_final = .TRUE.
     952             :                END IF
     953             :             ELSE
     954             :                IF (.NOT. lb_final) lb_final = .TRUE.
     955             :                IF (ub_final) ub_final = .FALSE. ! Safeguard against "holes"
     956             :             END IF
     957             :          END IF
     958             :       END DO
     959          66 :       IF (just_bounds) THEN
     960          64 :          IF (.NOT. ub_final) ub = n3
     961          64 :          bounds(1) = lb
     962          64 :          bounds(2) = ub
     963         192 :          bounds = bounds - (n3/2) - 1
     964             :       END IF
     965             : 
     966          66 :    END SUBROUTINE hfun_zero
     967             : 
     968             : ! **************************************************************************************************
     969             : !> \brief Initializes Gaussian Hirshfeld constraints
     970             : !> \param qs_env the qs_env where to build the constraint
     971             : !> \author  Nico Holmberg (09.2018)
     972             : ! **************************************************************************************************
     973          22 :    SUBROUTINE hirshfeld_constraint_init(qs_env)
     974             :       TYPE(qs_environment_type), POINTER                 :: qs_env
     975             : 
     976             :       CHARACTER(len=*), PARAMETER :: routineN = 'hirshfeld_constraint_init'
     977             : 
     978             :       CHARACTER(len=2)                                   :: element_symbol
     979             :       INTEGER                                            :: handle, iat, iatom, igroup, ikind, ip, &
     980             :                                                             iw, natom, nkind
     981          22 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
     982             :       REAL(KIND=dp)                                      :: zeff
     983          22 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: radii_list
     984          22 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     985             :       TYPE(atomic_kind_type), POINTER                    :: atomic_kind
     986             :       TYPE(cdft_control_type), POINTER                   :: cdft_control
     987          22 :       TYPE(cdft_group_type), DIMENSION(:), POINTER       :: group
     988             :       TYPE(cp_logger_type), POINTER                      :: logger
     989             :       TYPE(dft_control_type), POINTER                    :: dft_control
     990             :       TYPE(hirshfeld_constraint_type), POINTER           :: hirshfeld_control
     991             :       TYPE(hirshfeld_type), POINTER                      :: hirshfeld_env
     992          22 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     993          22 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     994             :       TYPE(section_vals_type), POINTER                   :: print_section
     995             : 
     996          22 :       NULLIFY (cdft_control, hirshfeld_control, hirshfeld_env, qs_kind_set, atomic_kind_set, &
     997          22 :                radii_list, dft_control, group, atomic_kind, atom_list)
     998          22 :       CALL timeset(routineN, handle)
     999             : 
    1000          22 :       logger => cp_get_default_logger()
    1001          22 :       print_section => section_vals_get_subs_vals(qs_env%input, "DFT%QS%CDFT")
    1002          22 :       iw = cp_print_key_unit_nr(logger, print_section, "PROGRAM_RUN_INFO", extension=".cdftLog")
    1003             : 
    1004          22 :       CALL get_qs_env(qs_env, dft_control=dft_control)
    1005          22 :       cdft_control => dft_control%qs_control%cdft_control
    1006          22 :       hirshfeld_control => cdft_control%hirshfeld_control
    1007          22 :       hirshfeld_env => hirshfeld_control%hirshfeld_env
    1008             : 
    1009             :       ! Setup the Hirshfeld shape function
    1010          22 :       IF (.NOT. ASSOCIATED(hirshfeld_env%kind_shape_fn)) THEN
    1011             :          hirshfeld_env => hirshfeld_control%hirshfeld_env
    1012          22 :          CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set)
    1013          22 :          CPASSERT(ASSOCIATED(qs_kind_set))
    1014          22 :          nkind = SIZE(qs_kind_set)
    1015             :          ! Parse atomic radii for setting up Gaussian shape function
    1016          22 :          IF (ASSOCIATED(hirshfeld_control%radii)) THEN
    1017           0 :             IF (.NOT. SIZE(atomic_kind_set) == SIZE(hirshfeld_control%radii)) &
    1018             :                CALL cp_abort(__LOCATION__, &
    1019             :                              "Length of keyword HIRSHFELD_CONSTRAINT\ATOMIC_RADII does not "// &
    1020           0 :                              "match number of atomic kinds in the input coordinate file.")
    1021             : 
    1022           0 :             ALLOCATE (radii_list(SIZE(hirshfeld_control%radii)))
    1023           0 :             DO ikind = 1, SIZE(hirshfeld_control%radii)
    1024           0 :                IF (hirshfeld_control%use_bohr) THEN
    1025           0 :                   radii_list(ikind) = hirshfeld_control%radii(ikind)
    1026             :                ELSE
    1027           0 :                   radii_list(ikind) = cp_unit_from_cp2k(hirshfeld_control%radii(ikind), "angstrom")
    1028             :                END IF
    1029             :             END DO
    1030             :          END IF
    1031             :          ! radius/radii_list parameters are optional for shape_function_density
    1032             :          CALL create_shape_function(hirshfeld_env, qs_kind_set, atomic_kind_set, &
    1033             :                                     radius=hirshfeld_control%radius, &
    1034          22 :                                     radii_list=radii_list)
    1035          22 :          IF (ASSOCIATED(radii_list)) DEALLOCATE (radii_list)
    1036             :       END IF
    1037             : 
    1038             :       ! Atomic reference charges (Mulliken not supported)
    1039          22 :       IF (.NOT. ASSOCIATED(hirshfeld_env%charges)) THEN
    1040             :          CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set, atomic_kind_set=atomic_kind_set, &
    1041          22 :                          nkind=nkind, natom=natom)
    1042          66 :          ALLOCATE (hirshfeld_env%charges(natom))
    1043          66 :          DO ikind = 1, nkind
    1044          44 :             CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
    1045          44 :             atomic_kind => atomic_kind_set(ikind)
    1046          44 :             CALL get_atomic_kind(atomic_kind, atom_list=atom_list)
    1047         154 :             DO iat = 1, SIZE(atom_list)
    1048          44 :                iatom = atom_list(iat)
    1049          88 :                hirshfeld_env%charges(iatom) = zeff
    1050             :             END DO
    1051             :          END DO
    1052             :       END IF
    1053             : 
    1054             :       ! Print some additional information about the calculation on the first iteration
    1055          22 :       IF (cdft_control%first_iteration) THEN
    1056          22 :          IF (iw > 0) THEN
    1057          12 :             group => cdft_control%group
    1058          12 :             CALL get_qs_env(qs_env, particle_set=particle_set)
    1059          12 :             IF (ASSOCIATED(hirshfeld_control%radii)) THEN
    1060             :                WRITE (iw, '(T3,A)') &
    1061           0 :                   'Atom   Element  Gaussian radius (angstrom)'
    1062           0 :                DO iatom = 1, natom
    1063           0 :                   CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, element_symbol=element_symbol)
    1064             :                   WRITE (iw, "(i7,T15,A2,T37,F8.3)") &
    1065           0 :                      iatom, ADJUSTR(element_symbol), cp_unit_from_cp2k(hirshfeld_control%radii(iatom), "angstrom")
    1066             :                END DO
    1067             :                WRITE (iw, '(T3,A)') &
    1068           0 :                   '------------------------------------------------------------------------'
    1069             :             END IF
    1070             :             WRITE (iw, '(/,T3,A,T60)') &
    1071          12 :                '----------------------- CDFT group definitions -------------------------'
    1072          24 :             DO igroup = 1, SIZE(group)
    1073          12 :                IF (igroup > 1) WRITE (iw, '(T3,A)') ' '
    1074             :                WRITE (iw, '(T5,A,I5,A,I5)') &
    1075          12 :                   'Atomic group', igroup, ' of ', SIZE(group)
    1076          12 :                WRITE (iw, '(T5,A)') 'Atom  Element  Coefficient'
    1077          47 :                DO ip = 1, SIZE(group(igroup)%atoms)
    1078          23 :                   iatom = group(igroup)%atoms(ip)
    1079          23 :                   CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, element_symbol=element_symbol)
    1080          35 :                   WRITE (iw, '(i8,T16,A2,T23,F8.3)') iatom, ADJUSTR(element_symbol), group(igroup)%coeff(ip)
    1081             :                END DO
    1082             :             END DO
    1083             :             WRITE (iw, '(T3,A)') &
    1084          12 :                '------------------------------------------------------------------------'
    1085             :          END IF
    1086          22 :          cdft_control%first_iteration = .FALSE.
    1087             :       END IF
    1088             : 
    1089             :       ! Radii no longer needed
    1090          22 :       IF (ASSOCIATED(hirshfeld_control%radii)) DEALLOCATE (hirshfeld_control%radii)
    1091          22 :       CALL timestop(handle)
    1092             : 
    1093          22 :    END SUBROUTINE hirshfeld_constraint_init
    1094             : 
    1095             : ! **************************************************************************************************
    1096             : !> \brief Prints information about CDFT constraints
    1097             : !> \param qs_env the qs_env where to build the constraint
    1098             : !> \param electronic_charge the CDFT charges
    1099             : !> \par   History
    1100             : !>        Created 9.2018 [Nico Holmberg]
    1101             : ! **************************************************************************************************
    1102        3034 :    SUBROUTINE cdft_constraint_print(qs_env, electronic_charge)
    1103             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1104             :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :)        :: electronic_charge
    1105             : 
    1106             :       CHARACTER(len=2)                                   :: element_symbol
    1107             :       INTEGER                                            :: iatom, ikind, iw, jatom
    1108             :       REAL(kind=dp)                                      :: tc(2), zeff
    1109             :       TYPE(cdft_control_type), POINTER                   :: cdft_control
    1110             :       TYPE(cp_logger_type), POINTER                      :: logger
    1111             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1112        3034 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1113        3034 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1114             :       TYPE(section_vals_type), POINTER                   :: cdft_constraint_section
    1115             : 
    1116        3034 :       NULLIFY (cdft_constraint_section, logger, particle_set, dft_control, qs_kind_set)
    1117        6068 :       logger => cp_get_default_logger()
    1118             : 
    1119             :       CALL get_qs_env(qs_env, &
    1120             :                       particle_set=particle_set, &
    1121             :                       dft_control=dft_control, &
    1122        3034 :                       qs_kind_set=qs_kind_set)
    1123        3034 :       CPASSERT(ASSOCIATED(qs_kind_set))
    1124             : 
    1125        3034 :       cdft_constraint_section => section_vals_get_subs_vals(qs_env%input, "DFT%QS%CDFT")
    1126        3034 :       iw = cp_print_key_unit_nr(logger, cdft_constraint_section, "PROGRAM_RUN_INFO", extension=".cdftLog")
    1127        3034 :       cdft_control => dft_control%qs_control%cdft_control
    1128             : 
    1129             :       ! Print constraint information
    1130        3034 :       CALL qs_scf_cdft_constraint_info(iw, cdft_control)
    1131             : 
    1132             :       ! Print weight function(s) to cube file(s) whenever weight is (re)built
    1133        3034 :       IF (cdft_control%print_weight .AND. cdft_control%need_pot) &
    1134           2 :          CALL cdft_print_weight_function(qs_env)
    1135             : 
    1136             :       ! Print atomic CDFT charges
    1137        3034 :       IF (iw > 0 .AND. cdft_control%atomic_charges) THEN
    1138         799 :          IF (.NOT. cdft_control%fragment_density) THEN
    1139         794 :             IF (dft_control%nspins == 1) THEN
    1140             :                WRITE (iw, '(/,T3,A)') &
    1141           0 :                   '-------------------------------- CDFT atomic charges --------------------------------'
    1142             :                WRITE (iw, '(T3,A,A)') &
    1143           0 :                   '#Atom  Element   Is_constraint', '   Core charge    Population (total)'// &
    1144           0 :                   '          Net charge'
    1145           0 :                tc = 0.0_dp
    1146           0 :                DO iatom = 1, cdft_control%natoms
    1147           0 :                   jatom = cdft_control%atoms(iatom)
    1148             :                   CALL get_atomic_kind(atomic_kind=particle_set(jatom)%atomic_kind, &
    1149             :                                        element_symbol=element_symbol, &
    1150           0 :                                        kind_number=ikind)
    1151           0 :                   CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
    1152             :                   WRITE (iw, "(i7,T15,A2,T23,L10,T39,F8.3,T61,F8.3,T81,F8.3)") &
    1153           0 :                      jatom, ADJUSTR(element_symbol), cdft_control%is_constraint(iatom), zeff, electronic_charge(iatom, 1), &
    1154           0 :                      (zeff - electronic_charge(iatom, 1))
    1155           0 :                   tc(1) = tc(1) + (zeff - electronic_charge(iatom, 1))
    1156             :                END DO
    1157           0 :                WRITE (iw, '(/,T3,A,T81,F8.3,/)') "Total Charge: ", tc(1)
    1158             :             ELSE
    1159             :                WRITE (iw, '(/,T3,A)') &
    1160         794 :                   '------------------------------------------ CDFT atomic charges -------------------------------------------'
    1161             :                WRITE (iw, '(T3,A,A)') &
    1162         794 :                   '#Atom  Element   Is_constraint', '   Core charge    Population (alpha, beta)'// &
    1163        1588 :                   '    Net charge      Spin population'
    1164         794 :                tc = 0.0_dp
    1165        2343 :                DO iatom = 1, cdft_control%natoms
    1166        1549 :                   jatom = cdft_control%atoms(iatom)
    1167             :                   CALL get_atomic_kind(atomic_kind=particle_set(jatom)%atomic_kind, &
    1168             :                                        element_symbol=element_symbol, &
    1169        1549 :                                        kind_number=ikind)
    1170        1549 :                   CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
    1171             :                   WRITE (iw, "(i7,T15,A2,T23,L10,T39,F8.3,T53,F8.3,T67,F8.3,T81,F8.3,T102,F8.3)") &
    1172        1549 :                      jatom, ADJUSTR(element_symbol), &
    1173        1549 :                      cdft_control%is_constraint(iatom), &
    1174        1549 :                      zeff, electronic_charge(iatom, 1), electronic_charge(iatom, 2), &
    1175        1549 :                      (zeff - electronic_charge(iatom, 1) - electronic_charge(iatom, 2)), &
    1176        3098 :                      electronic_charge(iatom, 1) - electronic_charge(iatom, 2)
    1177        1549 :                   tc(1) = tc(1) + (zeff - electronic_charge(iatom, 1) - electronic_charge(iatom, 2))
    1178        3892 :                   tc(2) = tc(2) + (electronic_charge(iatom, 1) - electronic_charge(iatom, 2))
    1179             :                END DO
    1180         794 :                WRITE (iw, '(/,T3,A,T81,F8.3,T102,F8.3/)') "Total Charge and Spin Moment: ", tc(1), tc(2)
    1181             :             END IF
    1182             :          ELSE
    1183           8 :             IF (ALL(cdft_control%group(:)%constraint_type == cdft_charge_constraint)) THEN
    1184             :                WRITE (iw, '(/,T3,A)') &
    1185           3 :                   '-------------------------------- CDFT atomic charges --------------------------------'
    1186           3 :                IF (dft_control%nspins == 1) THEN
    1187             :                   WRITE (iw, '(T3,A,A)') &
    1188           0 :                      '#Atom  Element   Is_constraint', '   Fragment charge    Population (total)'// &
    1189           0 :                      '      Net charge'
    1190             :                ELSE
    1191             :                   WRITE (iw, '(T3,A,A)') &
    1192           3 :                      '#Atom  Element   Is_constraint', '   Fragment charge  Population (alpha, beta)'// &
    1193           6 :                      '  Net charge'
    1194             :                END IF
    1195           3 :                tc = 0.0_dp
    1196           7 :                DO iatom = 1, cdft_control%natoms
    1197           4 :                   jatom = cdft_control%atoms(iatom)
    1198             :                   CALL get_atomic_kind(atomic_kind=particle_set(jatom)%atomic_kind, &
    1199             :                                        element_symbol=element_symbol, &
    1200           4 :                                        kind_number=ikind)
    1201           7 :                   IF (dft_control%nspins == 1) THEN
    1202             :                      WRITE (iw, "(i7,T15,A2,T23,L10,T43,F8.3,T65,F8.3,T81,F8.3)") &
    1203           0 :                         jatom, ADJUSTR(element_symbol), &
    1204           0 :                         cdft_control%is_constraint(iatom), &
    1205           0 :                         cdft_control%charges_fragment(iatom, 1), &
    1206           0 :                         electronic_charge(iatom, 1), &
    1207             :                         (electronic_charge(iatom, 1) - &
    1208           0 :                          cdft_control%charges_fragment(iatom, 1))
    1209             :                      tc(1) = tc(1) + (electronic_charge(iatom, 1) - &
    1210           0 :                                       cdft_control%charges_fragment(iatom, 1))
    1211             :                   ELSE
    1212             :                      WRITE (iw, "(i7,T15,A2,T23,L10,T43,F8.3,T57,F8.3,T69,F8.3,T81,F8.3)") &
    1213           4 :                         jatom, ADJUSTR(element_symbol), &
    1214           4 :                         cdft_control%is_constraint(iatom), &
    1215           4 :                         cdft_control%charges_fragment(iatom, 1), &
    1216           4 :                         electronic_charge(iatom, 1), electronic_charge(iatom, 2), &
    1217             :                         (electronic_charge(iatom, 1) + electronic_charge(iatom, 2) - &
    1218           8 :                          cdft_control%charges_fragment(iatom, 1))
    1219             :                      tc(1) = tc(1) + (electronic_charge(iatom, 1) + electronic_charge(iatom, 2) - &
    1220           4 :                                       cdft_control%charges_fragment(iatom, 1))
    1221             :                   END IF
    1222             :                END DO
    1223           3 :                WRITE (iw, '(/,T3,A,T81,F8.3,/)') "Total Charge: ", tc(1)
    1224             :             ELSE
    1225             :                WRITE (iw, '(/,T3,A)') &
    1226           2 :                   '------------------------------------------ CDFT atomic charges -------------------------------------------'
    1227             :                WRITE (iw, '(T3,A,A)') &
    1228           2 :                   '#Atom  Element  Is_constraint', ' Fragment charge/spin moment'// &
    1229           4 :                   '  Population (alpha, beta)  Net charge/spin moment'
    1230           2 :                tc = 0.0_dp
    1231           5 :                DO iatom = 1, cdft_control%natoms
    1232           3 :                   jatom = cdft_control%atoms(iatom)
    1233             :                   CALL get_atomic_kind(atomic_kind=particle_set(jatom)%atomic_kind, &
    1234             :                                        element_symbol=element_symbol, &
    1235           3 :                                        kind_number=ikind)
    1236             :                   WRITE (iw, "(i7,T15,A2,T22,L10,T40,F8.3,T52,F8.3,T66,F8.3,T78,F8.3,T90,F8.3,T102,F8.3)") &
    1237           3 :                      jatom, ADJUSTR(element_symbol), &
    1238           3 :                      cdft_control%is_constraint(iatom), &
    1239           3 :                      cdft_control%charges_fragment(iatom, 1), &
    1240           3 :                      cdft_control%charges_fragment(iatom, 2), &
    1241           3 :                      electronic_charge(iatom, 1), electronic_charge(iatom, 2), &
    1242             :                      (electronic_charge(iatom, 1) + electronic_charge(iatom, 2) - &
    1243           3 :                       cdft_control%charges_fragment(iatom, 1)), &
    1244             :                      (electronic_charge(iatom, 1) - electronic_charge(iatom, 2) - &
    1245           6 :                       cdft_control%charges_fragment(iatom, 2))
    1246             :                   tc(1) = tc(1) + (electronic_charge(iatom, 1) + electronic_charge(iatom, 2) - &
    1247           3 :                                    cdft_control%charges_fragment(iatom, 1))
    1248             :                   tc(2) = tc(2) + (electronic_charge(iatom, 1) - electronic_charge(iatom, 2) - &
    1249           8 :                                    cdft_control%charges_fragment(iatom, 2))
    1250             :                END DO
    1251           2 :                WRITE (iw, '(/,T3,A,T90,F8.3,T102,F8.3/)') "Total Charge and Spin Moment: ", tc(1), tc(2)
    1252             :             END IF
    1253             :          END IF
    1254             :       END IF
    1255             : 
    1256        3034 :    END SUBROUTINE cdft_constraint_print
    1257             : 
    1258             : ! **************************************************************************************************
    1259             : !> \brief Prints CDFT weight functions to cube files
    1260             : !> \param qs_env ...
    1261             : ! **************************************************************************************************
    1262           2 :    SUBROUTINE cdft_print_weight_function(qs_env)
    1263             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1264             : 
    1265             :       CHARACTER(LEN=default_path_length)                 :: middle_name
    1266             :       INTEGER                                            :: igroup, unit_nr
    1267             :       LOGICAL                                            :: mpi_io
    1268             :       TYPE(cdft_control_type), POINTER                   :: cdft_control
    1269             :       TYPE(cp_logger_type), POINTER                      :: logger
    1270             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1271             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1272             :       TYPE(particle_list_type), POINTER                  :: particles
    1273             :       TYPE(qs_subsys_type), POINTER                      :: subsys
    1274             :       TYPE(section_vals_type), POINTER                   :: cdft_constraint_section
    1275             : 
    1276           2 :       NULLIFY (cdft_constraint_section, logger, particles, dft_control, &
    1277           2 :                para_env, subsys, cdft_control)
    1278           2 :       logger => cp_get_default_logger()
    1279             : 
    1280           2 :       CALL get_qs_env(qs_env, subsys=subsys, para_env=para_env, dft_control=dft_control)
    1281           2 :       CALL qs_subsys_get(subsys, particles=particles)
    1282           2 :       cdft_control => dft_control%qs_control%cdft_control
    1283           2 :       cdft_constraint_section => section_vals_get_subs_vals(qs_env%input, "DFT%QS%CDFT")
    1284             : 
    1285           4 :       DO igroup = 1, SIZE(cdft_control%group)
    1286           2 :          mpi_io = .TRUE.
    1287           2 :          middle_name = "cdft_weight_"//TRIM(ADJUSTL(cp_to_string(igroup)))
    1288             :          unit_nr = cp_print_key_unit_nr(logger, cdft_constraint_section, "PROGRAM_RUN_INFO", &
    1289             :                                         middle_name=middle_name, &
    1290             :                                         extension=".cube", file_position="REWIND", &
    1291           2 :                                         log_filename=.FALSE., mpi_io=mpi_io)
    1292             :          ! Note PROGRAM_RUN_INFO section neeeds to be active!
    1293           2 :          IF (para_env%is_source() .AND. unit_nr .LT. 1) &
    1294             :             CALL cp_abort(__LOCATION__, &
    1295           0 :                           "Please turn on PROGRAM_RUN_INFO to print CDFT weight function.")
    1296             : 
    1297             :          CALL cp_pw_to_cube(cdft_control%group(igroup)%weight, &
    1298             :                             unit_nr, &
    1299             :                             "CDFT Weight Function", &
    1300             :                             particles=particles, &
    1301             :                             stride=section_get_ivals(cdft_constraint_section, "PROGRAM_RUN_INFO%WEIGHT_FUNCTION%STRIDE"), &
    1302           2 :                             mpi_io=mpi_io)
    1303           4 :          CALL cp_print_key_finished_output(unit_nr, logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io)
    1304             :       END DO
    1305             : 
    1306           2 :    END SUBROUTINE cdft_print_weight_function
    1307             : 
    1308             : ! **************************************************************************************************
    1309             : !> \brief Prints Hirshfeld weight function and promolecule density
    1310             : !> \param qs_env ...
    1311             : ! **************************************************************************************************
    1312           0 :    SUBROUTINE cdft_print_hirshfeld_density(qs_env)
    1313             :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1314             : 
    1315             :       CHARACTER(LEN=default_path_length)                 :: middle_name
    1316             :       INTEGER                                            :: iatom, igroup, unit_nr
    1317             :       LOGICAL                                            :: mpi_io
    1318             :       TYPE(cdft_control_type), POINTER                   :: cdft_control
    1319             :       TYPE(cp_logger_type), POINTER                      :: logger
    1320             :       TYPE(dft_control_type), POINTER                    :: dft_control
    1321             :       TYPE(mp_para_env_type), POINTER                    :: para_env
    1322             :       TYPE(particle_list_type), POINTER                  :: particles
    1323             :       TYPE(pw_env_type), POINTER                         :: pw_env
    1324             :       TYPE(qs_subsys_type), POINTER                      :: subsys
    1325             :       TYPE(section_vals_type), POINTER                   :: cdft_constraint_section
    1326             : 
    1327           0 :       NULLIFY (cdft_constraint_section, logger, particles, dft_control, &
    1328           0 :                para_env, subsys, cdft_control, pw_env)
    1329           0 :       logger => cp_get_default_logger()
    1330             : 
    1331           0 :       CALL get_qs_env(qs_env, subsys=subsys, para_env=para_env, dft_control=dft_control, pw_env=pw_env)
    1332           0 :       CALL qs_subsys_get(subsys, particles=particles)
    1333           0 :       cdft_control => dft_control%qs_control%cdft_control
    1334           0 :       cdft_constraint_section => section_vals_get_subs_vals(qs_env%input, "DFT%QS%CDFT")
    1335             : 
    1336           0 :       mpi_io = .TRUE.
    1337             : 
    1338           0 :       DO igroup = 1, SIZE(cdft_control%group)
    1339             : 
    1340           0 :          middle_name = "hw_rho_total"//TRIM(ADJUSTL(cp_to_string(igroup)))
    1341             :          unit_nr = cp_print_key_unit_nr(logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io, &
    1342           0 :                                         file_position="REWIND", middle_name=middle_name, extension=".cube")
    1343             : 
    1344             :          CALL cp_pw_to_cube(cdft_control%group(igroup)%hw_rho_total, unit_nr, "CDFT Weight Function", mpi_io=mpi_io, &
    1345           0 :                   particles=particles, stride=section_get_ivals(cdft_constraint_section, "PROGRAM_RUN_INFO%WEIGHT_FUNCTION%STRIDE"))
    1346             : 
    1347           0 :          CALL cp_print_key_finished_output(unit_nr, logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io)
    1348             : 
    1349             :       END DO
    1350             : 
    1351           0 :       DO igroup = 1, SIZE(cdft_control%group)
    1352             : 
    1353           0 :          middle_name = "hw_rho_total_constraint_"//TRIM(ADJUSTL(cp_to_string(igroup)))
    1354             :          unit_nr = cp_print_key_unit_nr(logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io, &
    1355           0 :                                         file_position="REWIND", middle_name=middle_name, extension=".cube")
    1356             : 
    1357             :          CALL cp_pw_to_cube(cdft_control%group(igroup)%hw_rho_total_constraint, unit_nr, &
    1358             :                             "CDFT Weight Function", mpi_io=mpi_io, particles=particles, &
    1359           0 :                             stride=section_get_ivals(cdft_constraint_section, "PROGRAM_RUN_INFO%WEIGHT_FUNCTION%STRIDE"))
    1360             : 
    1361           0 :          CALL cp_print_key_finished_output(unit_nr, logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io)
    1362             : 
    1363             :       END DO
    1364             : 
    1365           0 :       DO igroup = 1, SIZE(cdft_control%group)
    1366           0 :          DO iatom = 1, (cdft_control%natoms)
    1367             : 
    1368           0 :             middle_name = "hw_rho_atomic_"//TRIM(ADJUSTL(cp_to_string(iatom)))
    1369             :             unit_nr = cp_print_key_unit_nr(logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io, &
    1370           0 :                                            file_position="REWIND", middle_name=middle_name, extension=".cube")
    1371             : 
    1372             :             CALL cp_pw_to_cube(cdft_control%group(igroup)%hw_rho_atomic(iatom), unit_nr, &
    1373             :                                "CDFT Weight Function", mpi_io=mpi_io, particles=particles, &
    1374           0 :                                stride=section_get_ivals(cdft_constraint_section, "PROGRAM_RUN_INFO%WEIGHT_FUNCTION%STRIDE"))
    1375             : 
    1376           0 :             CALL cp_print_key_finished_output(unit_nr, logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io)
    1377             : 
    1378             :          END DO
    1379             :       END DO
    1380             : 
    1381           0 :    END SUBROUTINE cdft_print_hirshfeld_density
    1382             : 
    1383             : END MODULE qs_cdft_utils

Generated by: LCOV version 1.15