LCOV - code coverage report
Current view: top level - src - qs_cdft_utils.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:71c3ab0) Lines: 86.8 % 675 586
Test Date: 2026-07-25 06:35:44 Functions: 90.9 % 11 10

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

Generated by: LCOV version 2.0-1