(git:b195825)
qs_cdft_utils.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief Utility subroutines for CDFT calculations
10 !> \par History
11 !> separated from et_coupling [03.2017]
12 !> \author Nico Holmberg [03.2017]
13 ! **************************************************************************************************
16  USE atomic_kind_types, ONLY: atomic_kind_type,&
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
27  cp_logger_type,&
28  cp_to_string
32  USE cp_units, ONLY: cp_unit_from_cp2k
33  USE grid_api, ONLY: grid_func_ab,&
37  hirshfeld_type,&
39  USE input_constants, ONLY: &
46  section_vals_type,&
48  USE kinds, ONLY: default_path_length,&
49  dp
50  USE memory_utilities, ONLY: reallocate
51  USE message_passing, ONLY: mp_para_env_type
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
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,&
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 ***
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  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  INTEGER, DIMENSION(:), POINTER :: atom_list, cores, stride
106  LOGICAL :: build, in_memory, mpi_io
107  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  REAL(kind=dp), DIMENSION(:), POINTER :: radii_list
112  REAL(kind=dp), DIMENSION(:, :), POINTER :: pab
113  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  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  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  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  NULLIFY (cores, stride, atom_list, cell, para_env, dft_control, &
132  particle_set, logger, cdft_constraint_section, qs_kind_set, &
133  particles, subsys, pab, pw_env, rs_cavity, cavity_env, &
134  auxbas_pw_pool, atomic_kind_set, group, radii_list, cdft_control)
135  logger => cp_get_default_logger()
136  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  para_env=para_env)
143  cdft_constraint_section => section_vals_get_subs_vals(qs_env%input, "DFT%QS%CDFT")
144  iw = cp_print_key_unit_nr(logger, cdft_constraint_section, "PROGRAM_RUN_INFO", extension=".cdftLog")
145  cdft_control => dft_control%qs_control%cdft_control
146  becke_control => cdft_control%becke_control
147  group => cdft_control%group
148  in_memory = .false.
149  IF (cdft_control%save_pot) THEN
150  in_memory = becke_control%in_memory
151  END IF
152  IF (becke_control%cavity_confine) THEN
153  ALLOCATE (is_constraint(natom))
154  is_constraint = .false.
155  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  is_constraint(cdft_control%atoms(i)) = .true.
159  END DO
160  END IF
161  eps_cavity = becke_control%eps_cavity
162  ! Setup atomic radii for adjusting cell boundaries
163  IF (becke_control%adjust) THEN
164  IF (.NOT. ASSOCIATED(becke_control%radii)) THEN
165  CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
166  IF (.NOT. SIZE(atomic_kind_set) == SIZE(becke_control%radii_tmp)) &
167  CALL cp_abort(__location__, &
168  "Length of keyword BECKE_CONSTRAINT\ATOMIC_RADII does not "// &
169  "match number of atomic kinds in the input coordinate file.")
170  ALLOCATE (becke_control%radii(SIZE(atomic_kind_set)))
171  becke_control%radii(:) = becke_control%radii_tmp(:)
172  DEALLOCATE (becke_control%radii_tmp)
173  END IF
174  END IF
175  ! Setup cutoff scheme
176  IF (.NOT. ASSOCIATED(becke_control%cutoffs)) THEN
177  CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
178  ALLOCATE (becke_control%cutoffs(natom))
179  SELECT CASE (becke_control%cutoff_type)
180  CASE (becke_cutoff_global)
181  becke_control%cutoffs(:) = becke_control%rglobal
182  CASE (becke_cutoff_element)
183  IF (.NOT. SIZE(atomic_kind_set) == SIZE(becke_control%cutoffs_tmp)) &
184  CALL cp_abort(__location__, &
185  "Length of keyword BECKE_CONSTRAINT\ELEMENT_CUTOFFS does not "// &
186  "match number of atomic kinds in the input coordinate file.")
187  DO ikind = 1, SIZE(atomic_kind_set)
188  CALL get_atomic_kind(atomic_kind_set(ikind), natom=katom, atom_list=atom_list)
189  DO iatom = 1, katom
190  atom_a = atom_list(iatom)
191  becke_control%cutoffs(atom_a) = becke_control%cutoffs_tmp(ikind)
192  END DO
193  END DO
194  DEALLOCATE (becke_control%cutoffs_tmp)
195  END SELECT
196  END IF
197  ! Zero weight functions
198  DO igroup = 1, SIZE(group)
199  CALL pw_zero(group(igroup)%weight)
200  END DO
201  IF (cdft_control%atomic_charges) THEN
202  DO iatom = 1, cdft_control%natoms
203  CALL pw_zero(cdft_control%charge(iatom))
204  END DO
205  END IF
206  ! Allocate storage for cell adjustment coefficients and needed distance vectors
207  build = .false.
208  IF (becke_control%adjust .AND. .NOT. ASSOCIATED(becke_control%aij)) THEN
209  ALLOCATE (becke_control%aij(natom, natom))
210  build = .true.
211  END IF
212  IF (becke_control%vector_buffer%store_vectors) THEN
213  ALLOCATE (becke_control%vector_buffer%distances(natom))
214  ALLOCATE (becke_control%vector_buffer%distance_vecs(3, natom))
215  IF (in_memory) ALLOCATE (becke_control%vector_buffer%pair_dist_vecs(3, natom, natom))
216  ALLOCATE (becke_control%vector_buffer%position_vecs(3, natom))
217  END IF
218  ALLOCATE (becke_control%vector_buffer%R12(natom, natom))
219  ! Calculate pairwise distances between each atom pair
220  DO i = 1, 3
221  cell_v(i) = cell%hmat(i, i)
222  END DO
223  DO iatom = 1, natom - 1
224  DO jatom = iatom + 1, natom
225  r = particle_set(iatom)%r
226  r1 = particle_set(jatom)%r
227  DO i = 1, 3
228  r(i) = modulo(r(i), cell%hmat(i, i)) - cell%hmat(i, i)/2._dp
229  r1(i) = modulo(r1(i), cell%hmat(i, i)) - cell%hmat(i, i)/2._dp
230  END DO
231  dist_vec = (r - r1) - anint((r - r1)/cell_v)*cell_v
232  ! Store pbc corrected position and pairwise distance vectors for later reuse
233  IF (becke_control%vector_buffer%store_vectors) THEN
234  becke_control%vector_buffer%position_vecs(:, iatom) = r(:)
235  IF (iatom == 1 .AND. jatom == natom) becke_control%vector_buffer%position_vecs(:, jatom) = r1(:)
236  IF (in_memory) THEN
237  becke_control%vector_buffer%pair_dist_vecs(:, iatom, jatom) = dist_vec(:)
238  becke_control%vector_buffer%pair_dist_vecs(:, jatom, iatom) = -dist_vec(:)
239  END IF
240  END IF
241  becke_control%vector_buffer%R12(iatom, jatom) = sqrt(dot_product(dist_vec, dist_vec))
242  becke_control%vector_buffer%R12(jatom, iatom) = becke_control%vector_buffer%R12(iatom, jatom)
243  ! Set up heteronuclear cell partitioning using user defined radii
244  IF (build) THEN
245  CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, kind_number=ikind)
246  ircov = becke_control%radii(ikind)
247  CALL get_atomic_kind(atomic_kind=particle_set(jatom)%atomic_kind, kind_number=ikind)
248  jrcov = becke_control%radii(ikind)
249  IF (ircov .NE. jrcov) THEN
250  chi = ircov/jrcov
251  uij = (chi - 1.0_dp)/(chi + 1.0_dp)
252  becke_control%aij(iatom, jatom) = uij/(uij**2 - 1.0_dp)
253  IF (becke_control%aij(iatom, jatom) .GT. 0.5_dp) THEN
254  becke_control%aij(iatom, jatom) = 0.5_dp
255  ELSE IF (becke_control%aij(iatom, jatom) .LT. -0.5_dp) THEN
256  becke_control%aij(iatom, jatom) = -0.5_dp
257  END IF
258  ELSE
259  becke_control%aij(iatom, jatom) = 0.0_dp
260  END IF
261  ! Note change of sign
262  becke_control%aij(jatom, iatom) = -becke_control%aij(iatom, jatom)
263  END IF
264  END DO
265  END DO
266  ! Dump some additional information about the calculation
267  IF (cdft_control%first_iteration) THEN
268  IF (iw > 0) THEN
269  WRITE (iw, '(/,T3,A)') &
270  '----------------------- Becke atomic parameters ------------------------'
271  IF (becke_control%adjust) THEN
272  WRITE (iw, '(T3,A)') &
273  'Atom Element Cutoff (angstrom) CDFT Radius (angstrom)'
274  DO iatom = 1, natom
275  CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, element_symbol=element_symbol, &
276  kind_number=ikind)
277  ircov = cp_unit_from_cp2k(becke_control%radii(ikind), "angstrom")
278  WRITE (iw, "(i6,T15,A2,T37,F8.3,T67,F8.3)") &
279  iatom, adjustr(element_symbol), cp_unit_from_cp2k(becke_control%cutoffs(iatom), "angstrom"), &
280  ircov
281  END DO
282  ELSE
283  WRITE (iw, '(T3,A)') &
284  'Atom Element Cutoff (angstrom)'
285  DO iatom = 1, natom
286  CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, element_symbol=element_symbol)
287  WRITE (iw, "(i7,T15,A2,T37,F8.3)") &
288  iatom, adjustr(element_symbol), cp_unit_from_cp2k(becke_control%cutoffs(iatom), "angstrom")
289  END DO
290  END IF
291  WRITE (iw, '(T3,A)') &
292  '------------------------------------------------------------------------'
293  WRITE (iw, '(/,T3,A,T60)') &
294  '----------------------- Becke group definitions ------------------------'
295  DO igroup = 1, SIZE(group)
296  IF (igroup > 1) WRITE (iw, '(T3,A)') ' '
297  WRITE (iw, '(T5,A,I5,A,I5)') &
298  'Atomic group', igroup, ' of ', SIZE(group)
299  WRITE (iw, '(T5,A)') 'Atom Element Coefficient'
300  DO ip = 1, SIZE(group(igroup)%atoms)
301  iatom = group(igroup)%atoms(ip)
302  CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, element_symbol=element_symbol)
303  WRITE (iw, '(i8,T16,A2,T23,F8.3)') iatom, adjustr(element_symbol), group(igroup)%coeff(ip)
304  END DO
305  END DO
306  WRITE (iw, '(T3,A)') &
307  '------------------------------------------------------------------------'
308  END IF
309  cdft_control%first_iteration = .false.
310  END IF
311  ! Setup cavity confinement using spherical Gaussians
312  IF (becke_control%cavity_confine) THEN
313  cavity_env => becke_control%cavity_env
314  CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, pw_env=pw_env, qs_kind_set=qs_kind_set)
315  cpassert(ASSOCIATED(qs_kind_set))
316  nkind = SIZE(qs_kind_set)
317  ! Setup the Gaussian shape function
318  IF (.NOT. ASSOCIATED(cavity_env%kind_shape_fn)) THEN
319  IF (ASSOCIATED(becke_control%radii)) THEN
320  ALLOCATE (radii_list(SIZE(becke_control%radii)))
321  DO ikind = 1, SIZE(becke_control%radii)
322  IF (cavity_env%use_bohr) THEN
323  radii_list(ikind) = becke_control%radii(ikind)
324  ELSE
325  radii_list(ikind) = cp_unit_from_cp2k(becke_control%radii(ikind), "angstrom")
326  END IF
327  END DO
328  END IF
329  CALL create_shape_function(cavity_env, qs_kind_set, atomic_kind_set, &
330  radius=becke_control%rcavity, &
331  radii_list=radii_list)
332  IF (ASSOCIATED(radii_list)) &
333  DEALLOCATE (radii_list)
334  END IF
335  ! Form cavity by summing isolated Gaussian densities over constraint atoms
336  NULLIFY (rs_cavity)
337  CALL pw_env_get(pw_env, auxbas_rs_grid=rs_cavity, auxbas_pw_pool=auxbas_pw_pool)
338  CALL rs_grid_zero(rs_cavity)
339  ALLOCATE (pab(1, 1))
340  nthread = 1
341  ithread = 0
342  DO ikind = 1, SIZE(atomic_kind_set)
343  numexp = cavity_env%kind_shape_fn(ikind)%numexp
344  IF (numexp <= 0) cycle
345  CALL get_atomic_kind(atomic_kind_set(ikind), natom=katom, atom_list=atom_list)
346  ALLOCATE (cores(katom))
347  DO iex = 1, numexp
348  alpha = cavity_env%kind_shape_fn(ikind)%zet(iex)
349  coef = cavity_env%kind_shape_fn(ikind)%coef(iex)
350  npme = 0
351  cores = 0
352  DO iatom = 1, katom
353  IF (rs_cavity%desc%parallel .AND. .NOT. rs_cavity%desc%distributed) THEN
354  ! replicated realspace grid, split the atoms up between procs
355  IF (modulo(iatom, rs_cavity%desc%group_size) == rs_cavity%desc%my_pos) THEN
356  npme = npme + 1
357  cores(npme) = iatom
358  END IF
359  ELSE
360  npme = npme + 1
361  cores(npme) = iatom
362  END IF
363  END DO
364  DO j = 1, npme
365  iatom = cores(j)
366  atom_a = atom_list(iatom)
367  pab(1, 1) = coef
368  IF (becke_control%vector_buffer%store_vectors) THEN
369  ra(:) = becke_control%vector_buffer%position_vecs(:, atom_a) + cell_v(:)/2._dp
370  ELSE
371  ra(:) = pbc(particle_set(atom_a)%r, cell)
372  END IF
373  IF (is_constraint(atom_a)) THEN
374  radius = exp_radius_very_extended(la_min=0, la_max=0, lb_min=0, lb_max=0, &
375  ra=ra, rb=ra, rp=ra, zetp=alpha, &
376  eps=dft_control%qs_control%eps_rho_rspace, &
377  pab=pab, o1=0, o2=0, & ! without map_consistent
378  prefactor=1.0_dp, cutoff=0.0_dp)
379 
380  CALL collocate_pgf_product(0, alpha, 0, 0, 0.0_dp, 0, ra, &
381  (/0.0_dp, 0.0_dp, 0.0_dp/), 1.0_dp, &
382  pab, 0, 0, rs_cavity, &
383  radius=radius, ga_gb_function=grid_func_ab, &
384  use_subpatch=.true., subpatch_pattern=0)
385  END IF
386  END DO
387  END DO
388  DEALLOCATE (cores)
389  END DO
390  DEALLOCATE (pab)
391  CALL auxbas_pw_pool%create_pw(becke_control%cavity)
392  CALL transfer_rs2pw(rs_cavity, becke_control%cavity)
393  ! Grid points where the Gaussian density falls below eps_cavity are ignored
394  ! We can calculate the smallest/largest values along z-direction outside
395  ! which the cavity is zero at every point (x, y)
396  ! If gradients are needed storage needs to be allocated only for grid points within
397  ! these bounds
398  IF (in_memory .OR. cdft_control%save_pot) THEN
399  CALL hfun_zero(becke_control%cavity%array, eps_cavity, just_bounds=.true., bounds=bounds)
400  ! Save bounds (first nonzero grid point indices)
401  bo = group(1)%weight%pw_grid%bounds_local
402  IF (bounds(2) .LT. bo(2, 3)) THEN
403  bounds(2) = bounds(2) - 1
404  ELSE
405  bounds(2) = bo(2, 3)
406  END IF
407  IF (bounds(1) .GT. bo(1, 3)) THEN
408  ! In the special case bounds(1) == bounds(2) == bo(2, 3), after this check
409  ! bounds(1) > bounds(2) and the subsequent gradient allocation (:, :, :, bounds(1):bounds(2))
410  ! will correctly allocate a 0-sized array
411  bounds(1) = bounds(1) + 1
412  ELSE
413  bounds(1) = bo(1, 3)
414  END IF
415  becke_control%confine_bounds = bounds
416  END IF
417  ! Optional printing of cavity (meant for testing, so options currently hardcoded...)
418  IF (becke_control%print_cavity) THEN
419  CALL hfun_zero(becke_control%cavity%array, eps_cavity, just_bounds=.false.)
420  ALLOCATE (stride(3))
421  stride = (/2, 2, 2/)
422  mpi_io = .true.
423  ! Note PROGRAM_RUN_INFO section neeeds to be active!
424  unit_nr = cp_print_key_unit_nr(logger, cdft_constraint_section, "PROGRAM_RUN_INFO", &
425  middle_name="BECKE_CAVITY", &
426  extension=".cube", file_position="REWIND", &
427  log_filename=.false., mpi_io=mpi_io)
428  IF (para_env%is_source() .AND. unit_nr .LT. 1) &
429  CALL cp_abort(__location__, &
430  "Please turn on PROGRAM_RUN_INFO to print cavity")
431  CALL get_qs_env(qs_env, subsys=subsys)
432  CALL qs_subsys_get(subsys, particles=particles)
433  CALL cp_pw_to_cube(becke_control%cavity, unit_nr, "CAVITY", particles=particles, stride=stride, mpi_io=mpi_io)
434  CALL cp_print_key_finished_output(unit_nr, logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io)
435  DEALLOCATE (stride)
436  END IF
437  END IF
438  IF (ALLOCATED(is_constraint)) &
439  DEALLOCATE (is_constraint)
440  CALL timestop(handle)
441 
442  END SUBROUTINE becke_constraint_init
443 
444 ! **************************************************************************************************
445 !> \brief reads the input parameters specific to Becke-based CDFT constraints
446 !> \param cdft_control the cdft_control which holds the Becke control type
447 !> \param becke_section the input section containing Becke constraint information
448 !> \par History
449 !> Created 01.2007 [fschiff]
450 !> Merged Becke into CDFT 09.2018 [Nico Holmberg]
451 !> \author Nico Holmberg [09.2018]
452 ! **************************************************************************************************
453  SUBROUTINE read_becke_section(cdft_control, becke_section)
454 
455  TYPE(cdft_control_type), INTENT(INOUT) :: cdft_control
456  TYPE(section_vals_type), POINTER :: becke_section
457 
458  INTEGER :: j
459  LOGICAL :: exists
460  REAL(kind=dp), DIMENSION(:), POINTER :: rtmplist
461  TYPE(becke_constraint_type), POINTER :: becke_control
462 
463  NULLIFY (rtmplist)
464  becke_control => cdft_control%becke_control
465  cpassert(ASSOCIATED(becke_control))
466 
467  ! Atomic size corrections
468  CALL section_vals_val_get(becke_section, "ADJUST_SIZE", l_val=becke_control%adjust)
469  IF (becke_control%adjust) THEN
470  CALL section_vals_val_get(becke_section, "ATOMIC_RADII", explicit=exists)
471  IF (.NOT. exists) cpabort("Keyword ATOMIC_RADII is missing.")
472  CALL section_vals_val_get(becke_section, "ATOMIC_RADII", r_vals=rtmplist)
473  cpassert(SIZE(rtmplist) > 0)
474  ALLOCATE (becke_control%radii_tmp(SIZE(rtmplist)))
475  DO j = 1, SIZE(rtmplist)
476  becke_control%radii_tmp(j) = rtmplist(j)
477  END DO
478  END IF
479 
480  ! Cutoff scheme
481  CALL section_vals_val_get(becke_section, "CUTOFF_TYPE", i_val=becke_control%cutoff_type)
482  SELECT CASE (becke_control%cutoff_type)
483  CASE (becke_cutoff_global)
484  CALL section_vals_val_get(becke_section, "GLOBAL_CUTOFF", r_val=becke_control%rglobal)
485  CASE (becke_cutoff_element)
486  CALL section_vals_val_get(becke_section, "ELEMENT_CUTOFF", r_vals=rtmplist)
487  cpassert(SIZE(rtmplist) > 0)
488  ALLOCATE (becke_control%cutoffs_tmp(SIZE(rtmplist)))
489  DO j = 1, SIZE(rtmplist)
490  becke_control%cutoffs_tmp(j) = rtmplist(j)
491  END DO
492  END SELECT
493 
494  ! Gaussian cavity confinement
495  CALL section_vals_val_get(becke_section, "CAVITY_CONFINE", l_val=becke_control%cavity_confine)
496  CALL section_vals_val_get(becke_section, "SHOULD_SKIP", l_val=becke_control%should_skip)
497  CALL section_vals_val_get(becke_section, "IN_MEMORY", l_val=becke_control%in_memory)
498  IF (cdft_control%becke_control%cavity_confine) THEN
499  CALL section_vals_val_get(becke_section, "CAVITY_SHAPE", i_val=becke_control%cavity_shape)
500  IF (becke_control%cavity_shape == radius_user .AND. .NOT. becke_control%adjust) &
501  CALL cp_abort(__location__, &
502  "Activate keyword ADJUST_SIZE to use cavity shape USER.")
503  CALL section_vals_val_get(becke_section, "CAVITY_RADIUS", r_val=becke_control%rcavity)
504  CALL section_vals_val_get(becke_section, "EPS_CAVITY", r_val=becke_control%eps_cavity)
505  CALL section_vals_val_get(becke_section, "CAVITY_PRINT", l_val=becke_control%print_cavity)
506  CALL section_vals_val_get(becke_section, "CAVITY_USE_BOHR", l_val=becke_control%use_bohr)
507  IF (.NOT. cdft_control%becke_control%use_bohr) THEN
508  becke_control%rcavity = cp_unit_from_cp2k(becke_control%rcavity, "angstrom")
509  END IF
510  CALL create_hirshfeld_type(becke_control%cavity_env)
511  CALL set_hirshfeld_info(becke_control%cavity_env, &
512  shape_function_type=shape_function_gaussian, iterative=.false., &
513  radius_type=becke_control%cavity_shape, &
514  use_bohr=becke_control%use_bohr)
515  END IF
516 
517  CALL cite_reference(becke1988b)
518 
519  END SUBROUTINE read_becke_section
520 
521 ! **************************************************************************************************
522 !> \brief reads the input parameters needed to define CDFT constraints
523 !> \param cdft_control the object which holds the CDFT control type
524 !> \param cdft_control_section the input section containing CDFT constraint information
525 !> \author Nico Holmberg [09.2018]
526 ! **************************************************************************************************
527  SUBROUTINE read_constraint_definitions(cdft_control, cdft_control_section)
528 
529  TYPE(cdft_control_type), INTENT(INOUT) :: cdft_control
530  TYPE(section_vals_type), INTENT(INOUT), POINTER :: cdft_control_section
531 
532  INTEGER :: i, j, jj, k, n_rep, natoms, nvar, &
533  tot_natoms
534  INTEGER, DIMENSION(:), POINTER :: atomlist, dummylist, tmplist
535  LOGICAL :: exists, is_duplicate
536  REAL(kind=dp), DIMENSION(:), POINTER :: rtmplist
537  TYPE(section_vals_type), POINTER :: group_section
538 
539  NULLIFY (tmplist, rtmplist, atomlist, dummylist, group_section)
540 
541  group_section => section_vals_get_subs_vals(cdft_control_section, "ATOM_GROUP")
542  CALL section_vals_get(group_section, n_repetition=nvar, explicit=exists)
543  IF (.NOT. exists) cpabort("Section ATOM_GROUP is missing.")
544  ALLOCATE (cdft_control%group(nvar))
545  tot_natoms = 0
546  ! Parse all ATOM_GROUP sections
547  DO k = 1, nvar
548  ! First determine how much storage is needed
549  natoms = 0
550  CALL section_vals_val_get(group_section, "ATOMS", i_rep_section=k, n_rep_val=n_rep)
551  DO j = 1, n_rep
552  CALL section_vals_val_get(group_section, "ATOMS", i_rep_section=k, i_rep_val=j, i_vals=tmplist)
553  IF (SIZE(tmplist) < 1) &
554  cpabort("Each ATOM_GROUP must contain at least 1 atom.")
555  natoms = natoms + SIZE(tmplist)
556  END DO
557  ALLOCATE (cdft_control%group(k)%atoms(natoms))
558  ALLOCATE (cdft_control%group(k)%coeff(natoms))
559  NULLIFY (cdft_control%group(k)%weight)
560  NULLIFY (cdft_control%group(k)%integrated)
561  tot_natoms = tot_natoms + natoms
562  ! Now parse
563  jj = 0
564  DO j = 1, n_rep
565  CALL section_vals_val_get(group_section, "ATOMS", i_rep_section=k, i_rep_val=j, i_vals=tmplist)
566  DO i = 1, SIZE(tmplist)
567  jj = jj + 1
568  cdft_control%group(k)%atoms(jj) = tmplist(i)
569  END DO
570  END DO
571  CALL section_vals_val_get(group_section, "COEFF", i_rep_section=k, n_rep_val=n_rep)
572  jj = 0
573  DO j = 1, n_rep
574  CALL section_vals_val_get(group_section, "COEFF", i_rep_section=k, i_rep_val=j, r_vals=rtmplist)
575  DO i = 1, SIZE(rtmplist)
576  jj = jj + 1
577  IF (jj > natoms) cpabort("Length of keywords ATOMS and COEFF must match.")
578  IF (abs(rtmplist(i)) /= 1.0_dp) cpabort("Keyword COEFF accepts only values +/-1.0")
579  cdft_control%group(k)%coeff(jj) = rtmplist(i)
580  END DO
581  END DO
582  IF (jj < natoms) cpabort("Length of keywords ATOMS and COEFF must match.")
583  CALL section_vals_val_get(group_section, "CONSTRAINT_TYPE", i_rep_section=k, &
584  i_val=cdft_control%group(k)%constraint_type)
585  CALL section_vals_val_get(group_section, "FRAGMENT_CONSTRAINT", i_rep_section=k, &
586  l_val=cdft_control%group(k)%is_fragment_constraint)
587  IF (cdft_control%group(k)%is_fragment_constraint) cdft_control%fragment_density = .true.
588  END DO
589  ! Create a list containing all constraint atoms
590  ALLOCATE (atomlist(tot_natoms))
591  atomlist = -1
592  jj = 0
593  DO k = 1, nvar
594  DO j = 1, SIZE(cdft_control%group(k)%atoms)
595  is_duplicate = .false.
596  DO i = 1, jj + 1
597  IF (cdft_control%group(k)%atoms(j) == atomlist(i)) THEN
598  is_duplicate = .true.
599  EXIT
600  END IF
601  END DO
602  IF (.NOT. is_duplicate) THEN
603  jj = jj + 1
604  atomlist(jj) = cdft_control%group(k)%atoms(j)
605  END IF
606  END DO
607  END DO
608  CALL reallocate(atomlist, 1, jj)
609  CALL section_vals_val_get(cdft_control_section, "ATOMIC_CHARGES", &
610  l_val=cdft_control%atomic_charges)
611  ! Parse any dummy atoms (no constraint, just charges)
612  IF (cdft_control%atomic_charges) THEN
613  group_section => section_vals_get_subs_vals(cdft_control_section, "DUMMY_ATOMS")
614  CALL section_vals_get(group_section, explicit=exists)
615  IF (exists) THEN
616  ! First determine how many atoms there are
617  natoms = 0
618  CALL section_vals_val_get(group_section, "ATOMS", n_rep_val=n_rep)
619  DO j = 1, n_rep
620  CALL section_vals_val_get(group_section, "ATOMS", i_rep_val=j, i_vals=tmplist)
621  IF (SIZE(tmplist) < 1) &
622  cpabort("DUMMY_ATOMS must contain at least 1 atom.")
623  natoms = natoms + SIZE(tmplist)
624  END DO
625  ALLOCATE (dummylist(natoms))
626  ! Now parse
627  jj = 0
628  DO j = 1, n_rep
629  CALL section_vals_val_get(group_section, "ATOMS", i_rep_val=j, i_vals=tmplist)
630  DO i = 1, SIZE(tmplist)
631  jj = jj + 1
632  dummylist(jj) = tmplist(i)
633  END DO
634  END DO
635  ! Check for duplicates
636  DO j = 1, natoms
637  DO i = j + 1, natoms
638  IF (dummylist(i) == dummylist(j)) &
639  cpabort("Duplicate atoms defined in section DUMMY_ATOMS.")
640  END DO
641  END DO
642  ! Check that a dummy atom is not included in any ATOM_GROUP
643  DO j = 1, SIZE(atomlist)
644  DO i = 1, SIZE(dummylist)
645  IF (dummylist(i) == atomlist(j)) &
646  CALL cp_abort(__location__, &
647  "Duplicate atoms defined in sections ATOM_GROUP and DUMMY_ATOMS.")
648  END DO
649  END DO
650  END IF
651  END IF
652  ! Join dummy atoms and constraint atoms into one list
653  IF (ASSOCIATED(dummylist)) THEN
654  cdft_control%natoms = SIZE(atomlist) + SIZE(dummylist)
655  ELSE
656  cdft_control%natoms = SIZE(atomlist)
657  END IF
658  ALLOCATE (cdft_control%atoms(cdft_control%natoms))
659  ALLOCATE (cdft_control%is_constraint(cdft_control%natoms))
660  IF (cdft_control%atomic_charges) ALLOCATE (cdft_control%charge(cdft_control%natoms))
661  cdft_control%atoms(1:SIZE(atomlist)) = atomlist
662  IF (ASSOCIATED(dummylist)) THEN
663  cdft_control%atoms(1 + SIZE(atomlist):) = dummylist
664  DEALLOCATE (dummylist)
665  END IF
666  cdft_control%is_constraint = .false.
667  cdft_control%is_constraint(1:SIZE(atomlist)) = .true.
668  DEALLOCATE (atomlist)
669  ! Get constraint potential definitions from input
670  ALLOCATE (cdft_control%strength(nvar))
671  ALLOCATE (cdft_control%value(nvar))
672  ALLOCATE (cdft_control%target(nvar))
673  CALL section_vals_val_get(cdft_control_section, "STRENGTH", r_vals=rtmplist)
674  IF (SIZE(rtmplist) /= nvar) &
675  CALL cp_abort(__location__, &
676  "The length of keyword STRENGTH is incorrect. "// &
677  "Expected "//trim(adjustl(cp_to_string(nvar)))// &
678  " value(s), got "// &
679  trim(adjustl(cp_to_string(SIZE(rtmplist))))//" value(s).")
680  DO j = 1, nvar
681  cdft_control%strength(j) = rtmplist(j)
682  END DO
683  CALL section_vals_val_get(cdft_control_section, "TARGET", r_vals=rtmplist)
684  IF (SIZE(rtmplist) /= nvar) &
685  CALL cp_abort(__location__, &
686  "The length of keyword TARGET is incorrect. "// &
687  "Expected "//trim(adjustl(cp_to_string(nvar)))// &
688  " value(s), got "// &
689  trim(adjustl(cp_to_string(SIZE(rtmplist))))//" value(s).")
690  DO j = 1, nvar
691  cdft_control%target(j) = rtmplist(j)
692  END DO
693  ! Read fragment constraint definitions
694  IF (cdft_control%fragment_density) THEN
695  CALL section_vals_val_get(cdft_control_section, "FRAGMENT_A_FILE_NAME", &
696  c_val=cdft_control%fragment_a_fname)
697  CALL section_vals_val_get(cdft_control_section, "FRAGMENT_B_FILE_NAME", &
698  c_val=cdft_control%fragment_b_fname)
699  CALL section_vals_val_get(cdft_control_section, "FRAGMENT_A_SPIN_FILE", &
700  c_val=cdft_control%fragment_a_spin_fname)
701  CALL section_vals_val_get(cdft_control_section, "FRAGMENT_B_SPIN_FILE", &
702  c_val=cdft_control%fragment_b_spin_fname)
703  CALL section_vals_val_get(cdft_control_section, "FLIP_FRAGMENT_A", &
704  l_val=cdft_control%flip_fragment(1))
705  CALL section_vals_val_get(cdft_control_section, "FLIP_FRAGMENT_B", &
706  l_val=cdft_control%flip_fragment(2))
707  END IF
708 
709  END SUBROUTINE read_constraint_definitions
710 
711 ! **************************************************************************************************
712 !> \brief reads the input parameters needed for CDFT with OT
713 !> \param qs_control the qs_control which holds the CDFT control type
714 !> \param cdft_control_section the input section for CDFT
715 !> \author Nico Holmberg [12.2015]
716 ! **************************************************************************************************
717  SUBROUTINE read_cdft_control_section(qs_control, cdft_control_section)
718  TYPE(qs_control_type), INTENT(INOUT) :: qs_control
719  TYPE(section_vals_type), POINTER :: cdft_control_section
720 
721  INTEGER :: k, nvar
722  LOGICAL :: exists
723  TYPE(cdft_control_type), POINTER :: cdft_control
724  TYPE(section_vals_type), POINTER :: becke_constraint_section, group_section, &
725  hirshfeld_constraint_section, &
726  outer_scf_section, print_section
727 
728  NULLIFY (outer_scf_section, hirshfeld_constraint_section, becke_constraint_section, &
729  print_section, group_section)
730  cdft_control => qs_control%cdft_control
731  cpassert(ASSOCIATED(cdft_control))
732  group_section => section_vals_get_subs_vals(cdft_control_section, "ATOM_GROUP")
733  CALL section_vals_get(group_section, n_repetition=nvar, explicit=exists)
734 
735  CALL section_vals_val_get(cdft_control_section, "TYPE_OF_CONSTRAINT", &
736  i_val=qs_control%cdft_control%type)
737 
738  IF (cdft_control%type /= outer_scf_none) THEN
739  CALL section_vals_val_get(cdft_control_section, "REUSE_PRECOND", &
740  l_val=cdft_control%reuse_precond)
741  CALL section_vals_val_get(cdft_control_section, "PRECOND_FREQ", &
742  i_val=cdft_control%precond_freq)
743  CALL section_vals_val_get(cdft_control_section, "MAX_REUSE", &
744  i_val=cdft_control%max_reuse)
745  CALL section_vals_val_get(cdft_control_section, "PURGE_HISTORY", &
746  l_val=cdft_control%purge_history)
747  CALL section_vals_val_get(cdft_control_section, "PURGE_FREQ", &
748  i_val=cdft_control%purge_freq)
749  CALL section_vals_val_get(cdft_control_section, "PURGE_OFFSET", &
750  i_val=cdft_control%purge_offset)
751  CALL section_vals_val_get(cdft_control_section, "COUNTER", &
752  i_val=cdft_control%ienergy)
753  print_section => section_vals_get_subs_vals(cdft_control_section, "PROGRAM_RUN_INFO%WEIGHT_FUNCTION")
754  CALL section_vals_get(print_section, explicit=cdft_control%print_weight)
755 
756  outer_scf_section => section_vals_get_subs_vals(cdft_control_section, "OUTER_SCF")
757  CALL outer_scf_read_parameters(cdft_control%constraint_control, outer_scf_section)
758  IF (cdft_control%constraint_control%have_scf) THEN
759  IF (cdft_control%constraint_control%type /= outer_scf_cdft_constraint) &
760  cpabort("Unsupported CDFT constraint.")
761  ! Constraint definitions
762  CALL read_constraint_definitions(cdft_control, cdft_control_section)
763  ! Constraint-specific initializations
764  SELECT CASE (cdft_control%type)
766  becke_constraint_section => section_vals_get_subs_vals(cdft_control_section, "BECKE_CONSTRAINT")
767  CALL section_vals_get(becke_constraint_section, explicit=exists)
768  IF (.NOT. exists) cpabort("BECKE_CONSTRAINT section is missing.")
769  DO k = 1, nvar
770  NULLIFY (cdft_control%group(k)%gradients)
771  END DO
772  CALL read_becke_section(cdft_control, becke_constraint_section)
774  hirshfeld_constraint_section => section_vals_get_subs_vals(cdft_control_section, "HIRSHFELD_CONSTRAINT")
775  CALL section_vals_get(hirshfeld_constraint_section, explicit=exists)
776  IF (.NOT. exists) cpabort("HIRSHFELD_CONSTRAINT section is missing.")
777  DO k = 1, nvar
778  NULLIFY (cdft_control%group(k)%gradients_x)
779  NULLIFY (cdft_control%group(k)%gradients_y)
780  NULLIFY (cdft_control%group(k)%gradients_z)
781  END DO
782  CALL read_hirshfeld_constraint_section(cdft_control, hirshfeld_constraint_section)
783  CASE DEFAULT
784  cpabort("Unknown constraint type.")
785  END SELECT
786 
787  CALL cite_reference(holmberg2017)
788  CALL cite_reference(holmberg2018)
789  ELSE
790  qs_control%cdft = .false.
791  END IF
792  ELSE
793  qs_control%cdft = .false.
794  END IF
795 
796  END SUBROUTINE read_cdft_control_section
797 
798 ! **************************************************************************************************
799 !> \brief reads the input parameters needed for Hirshfeld constraint
800 !> \param cdft_control the cdft_control which holds the Hirshfeld constraint
801 !> \param hirshfeld_section the input section for a Hirshfeld constraint
802 ! **************************************************************************************************
803  SUBROUTINE read_hirshfeld_constraint_section(cdft_control, hirshfeld_section)
804  TYPE(cdft_control_type), INTENT(INOUT) :: cdft_control
805  TYPE(section_vals_type), POINTER :: hirshfeld_section
806 
807  LOGICAL :: exists
808  REAL(kind=dp), DIMENSION(:), POINTER :: rtmplist
809  TYPE(hirshfeld_constraint_type), POINTER :: hirshfeld_control
810 
811  NULLIFY (rtmplist)
812  hirshfeld_control => cdft_control%hirshfeld_control
813  cpassert(ASSOCIATED(hirshfeld_control))
814 
815  CALL section_vals_val_get(hirshfeld_section, "SHAPE_FUNCTION", i_val=hirshfeld_control%shape_function)
816  CALL section_vals_val_get(hirshfeld_section, "GAUSSIAN_SHAPE", i_val=hirshfeld_control%gaussian_shape)
817  CALL section_vals_val_get(hirshfeld_section, "GAUSSIAN_RADIUS", r_val=hirshfeld_control%radius)
818  CALL section_vals_val_get(hirshfeld_section, "USE_BOHR", l_val=hirshfeld_control%use_bohr)
819  CALL section_vals_val_get(hirshfeld_section, "USE_ATOMIC_CUTOFF", l_val=hirshfeld_control%use_atomic_cutoff)
820  CALL section_vals_val_get(hirshfeld_section, "PRINT_DENSITY", l_val=hirshfeld_control%print_density)
821  CALL section_vals_val_get(hirshfeld_section, "EPS_CUTOFF", r_val=hirshfeld_control%eps_cutoff)
822  CALL section_vals_val_get(hirshfeld_section, "ATOMIC_CUTOFF", r_val=hirshfeld_control%atomic_cutoff)
823 
824  IF (.NOT. hirshfeld_control%use_bohr) THEN
825  hirshfeld_control%radius = cp_unit_from_cp2k(hirshfeld_control%radius, "angstrom")
826  END IF
827 
828  IF (hirshfeld_control%shape_function == shape_function_gaussian .AND. &
829  hirshfeld_control%gaussian_shape == radius_user) THEN
830  CALL section_vals_val_get(hirshfeld_section, "ATOMIC_RADII", explicit=exists)
831  IF (.NOT. exists) cpabort("Keyword ATOMIC_RADII is missing.")
832  CALL section_vals_val_get(hirshfeld_section, "ATOMIC_RADII", r_vals=rtmplist)
833  cpassert(SIZE(rtmplist) > 0)
834  ALLOCATE (hirshfeld_control%radii(SIZE(rtmplist)))
835  hirshfeld_control%radii(:) = rtmplist
836  END IF
837 
838  CALL create_hirshfeld_type(hirshfeld_control%hirshfeld_env)
839  CALL set_hirshfeld_info(hirshfeld_control%hirshfeld_env, &
840  shape_function_type=hirshfeld_control%shape_function, &
841  iterative=.false., &
842  radius_type=hirshfeld_control%gaussian_shape, &
843  use_bohr=hirshfeld_control%use_bohr)
844 
845  END SUBROUTINE read_hirshfeld_constraint_section
846 
847 ! **************************************************************************************************
848 !> \brief Calculate fout = fun1/fun2 or fout = fun1*fun2
849 !> \param fout the output 3D potential
850 !> \param fun1 the first input 3D potential
851 !> \param fun2 the second input 3D potential
852 !> \param divide logical that decides whether to divide or multiply the input potentials
853 !> \param small customisable parameter to determine lower bound of division
854 ! **************************************************************************************************
855  SUBROUTINE hfun_scale(fout, fun1, fun2, divide, small)
856  REAL(kind=dp), DIMENSION(:, :, :), INTENT(OUT) :: fout
857  REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: fun1, fun2
858  LOGICAL, INTENT(IN) :: divide
859  REAL(kind=dp), INTENT(IN) :: small
860 
861  INTEGER :: i1, i2, i3, n1, n2, n3
862 
863  n1 = SIZE(fout, 1)
864  n2 = SIZE(fout, 2)
865  n3 = SIZE(fout, 3)
866  cpassert(n1 == SIZE(fun1, 1))
867  cpassert(n2 == SIZE(fun1, 2))
868  cpassert(n3 == SIZE(fun1, 3))
869  cpassert(n1 == SIZE(fun2, 1))
870  cpassert(n2 == SIZE(fun2, 2))
871  cpassert(n3 == SIZE(fun2, 3))
872 
873  IF (divide) THEN
874  DO i3 = 1, n3
875  DO i2 = 1, n2
876  DO i1 = 1, n1
877  IF (fun2(i1, i2, i3) > small) THEN
878  fout(i1, i2, i3) = fun1(i1, i2, i3)/fun2(i1, i2, i3)
879  ELSE
880  fout(i1, i2, i3) = 0.0_dp
881  END IF
882  END DO
883  END DO
884  END DO
885  ELSE
886  DO i3 = 1, n3
887  DO i2 = 1, n2
888  DO i1 = 1, n1
889  fout(i1, i2, i3) = fun1(i1, i2, i3)*fun2(i1, i2, i3)
890  END DO
891  END DO
892  END DO
893  END IF
894 
895  END SUBROUTINE hfun_scale
896 
897 ! **************************************************************************************************
898 !> \brief Determine confinement bounds along confinement dir (hardcoded to be z)
899 !> and optionally zero entries below a given threshold
900 !> \param fun input 3D potential (real space)
901 !> \param th threshold for screening values
902 !> \param just_bounds if the bounds should be computed without zeroing values
903 !> \param bounds the confinement bounds: fun is nonzero only between these values along 3rd dimension
904 ! **************************************************************************************************
905  SUBROUTINE hfun_zero(fun, th, just_bounds, bounds)
906  REAL(kind=dp), DIMENSION(:, :, :), INTENT(INOUT) :: fun
907  REAL(kind=dp), INTENT(IN) :: th
908  LOGICAL :: just_bounds
909  INTEGER, OPTIONAL :: bounds(2)
910 
911  INTEGER :: i1, i2, i3, lb, n1, n2, n3, nzeroed, &
912  nzeroed_inner, ub
913  LOGICAL :: lb_final, ub_final
914 
915  n1 = SIZE(fun, 1)
916  n2 = SIZE(fun, 2)
917  n3 = SIZE(fun, 3)
918  IF (just_bounds) THEN
919  cpassert(PRESENT(bounds))
920  lb = 1
921  lb_final = .false.
922  ub_final = .false.
923  END IF
924 
925  DO i3 = 1, n3
926  IF (just_bounds) nzeroed = 0
927  DO i2 = 1, n2
928  IF (just_bounds) nzeroed_inner = 0
929  DO i1 = 1, n1
930  IF (fun(i1, i2, i3) < th) THEN
931  IF (just_bounds) THEN
932  nzeroed_inner = nzeroed_inner + 1
933  ELSE
934  fun(i1, i2, i3) = 0.0_dp
935  END IF
936  ELSE
937  IF (just_bounds) EXIT
938  END IF
939  END DO
940  IF (just_bounds) THEN
941  IF (nzeroed_inner < n1) EXIT
942  nzeroed = nzeroed + nzeroed_inner
943  END IF
944  END DO
945  IF (just_bounds) THEN
946  IF (nzeroed == (n2*n1)) THEN
947  IF (.NOT. lb_final) THEN
948  lb = i3
949  ELSE IF (.NOT. ub_final) THEN
950  ub = i3
951  ub_final = .true.
952  END IF
953  ELSE
954  IF (.NOT. lb_final) lb_final = .true.
955  IF (ub_final) ub_final = .false. ! Safeguard against "holes"
956  END IF
957  END IF
958  END DO
959  IF (just_bounds) THEN
960  IF (.NOT. ub_final) ub = n3
961  bounds(1) = lb
962  bounds(2) = ub
963  bounds = bounds - (n3/2) - 1
964  END IF
965 
966  END SUBROUTINE hfun_zero
967 
968 ! **************************************************************************************************
969 !> \brief Initializes Gaussian Hirshfeld constraints
970 !> \param qs_env the qs_env where to build the constraint
971 !> \author Nico Holmberg (09.2018)
972 ! **************************************************************************************************
973  SUBROUTINE hirshfeld_constraint_init(qs_env)
974  TYPE(qs_environment_type), POINTER :: qs_env
975 
976  CHARACTER(len=*), PARAMETER :: routinen = 'hirshfeld_constraint_init'
977 
978  CHARACTER(len=2) :: element_symbol
979  INTEGER :: handle, iat, iatom, igroup, ikind, ip, &
980  iw, natom, nkind
981  INTEGER, DIMENSION(:), POINTER :: atom_list
982  REAL(kind=dp) :: zeff
983  REAL(kind=dp), DIMENSION(:), POINTER :: radii_list
984  TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
985  TYPE(atomic_kind_type), POINTER :: atomic_kind
986  TYPE(cdft_control_type), POINTER :: cdft_control
987  TYPE(cdft_group_type), DIMENSION(:), POINTER :: group
988  TYPE(cp_logger_type), POINTER :: logger
989  TYPE(dft_control_type), POINTER :: dft_control
990  TYPE(hirshfeld_constraint_type), POINTER :: hirshfeld_control
991  TYPE(hirshfeld_type), POINTER :: hirshfeld_env
992  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
993  TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
994  TYPE(section_vals_type), POINTER :: print_section
995 
996  NULLIFY (cdft_control, hirshfeld_control, hirshfeld_env, qs_kind_set, atomic_kind_set, &
997  radii_list, dft_control, group, atomic_kind, atom_list)
998  CALL timeset(routinen, handle)
999 
1000  logger => cp_get_default_logger()
1001  print_section => section_vals_get_subs_vals(qs_env%input, "DFT%QS%CDFT")
1002  iw = cp_print_key_unit_nr(logger, print_section, "PROGRAM_RUN_INFO", extension=".cdftLog")
1003 
1004  CALL get_qs_env(qs_env, dft_control=dft_control)
1005  cdft_control => dft_control%qs_control%cdft_control
1006  hirshfeld_control => cdft_control%hirshfeld_control
1007  hirshfeld_env => hirshfeld_control%hirshfeld_env
1008 
1009  ! Setup the Hirshfeld shape function
1010  IF (.NOT. ASSOCIATED(hirshfeld_env%kind_shape_fn)) THEN
1011  hirshfeld_env => hirshfeld_control%hirshfeld_env
1012  CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set)
1013  cpassert(ASSOCIATED(qs_kind_set))
1014  nkind = SIZE(qs_kind_set)
1015  ! Parse atomic radii for setting up Gaussian shape function
1016  IF (ASSOCIATED(hirshfeld_control%radii)) THEN
1017  IF (.NOT. SIZE(atomic_kind_set) == SIZE(hirshfeld_control%radii)) &
1018  CALL cp_abort(__location__, &
1019  "Length of keyword HIRSHFELD_CONSTRAINT\ATOMIC_RADII does not "// &
1020  "match number of atomic kinds in the input coordinate file.")
1021 
1022  ALLOCATE (radii_list(SIZE(hirshfeld_control%radii)))
1023  DO ikind = 1, SIZE(hirshfeld_control%radii)
1024  IF (hirshfeld_control%use_bohr) THEN
1025  radii_list(ikind) = hirshfeld_control%radii(ikind)
1026  ELSE
1027  radii_list(ikind) = cp_unit_from_cp2k(hirshfeld_control%radii(ikind), "angstrom")
1028  END IF
1029  END DO
1030  END IF
1031  ! radius/radii_list parameters are optional for shape_function_density
1032  CALL create_shape_function(hirshfeld_env, qs_kind_set, atomic_kind_set, &
1033  radius=hirshfeld_control%radius, &
1034  radii_list=radii_list)
1035  IF (ASSOCIATED(radii_list)) DEALLOCATE (radii_list)
1036  END IF
1037 
1038  ! Atomic reference charges (Mulliken not supported)
1039  IF (.NOT. ASSOCIATED(hirshfeld_env%charges)) THEN
1040  CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set, atomic_kind_set=atomic_kind_set, &
1041  nkind=nkind, natom=natom)
1042  ALLOCATE (hirshfeld_env%charges(natom))
1043  DO ikind = 1, nkind
1044  CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
1045  atomic_kind => atomic_kind_set(ikind)
1046  CALL get_atomic_kind(atomic_kind, atom_list=atom_list)
1047  DO iat = 1, SIZE(atom_list)
1048  iatom = atom_list(iat)
1049  hirshfeld_env%charges(iatom) = zeff
1050  END DO
1051  END DO
1052  END IF
1053 
1054  ! Print some additional information about the calculation on the first iteration
1055  IF (cdft_control%first_iteration) THEN
1056  IF (iw > 0) THEN
1057  group => cdft_control%group
1058  CALL get_qs_env(qs_env, particle_set=particle_set)
1059  IF (ASSOCIATED(hirshfeld_control%radii)) THEN
1060  WRITE (iw, '(T3,A)') &
1061  'Atom Element Gaussian radius (angstrom)'
1062  DO iatom = 1, natom
1063  CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, element_symbol=element_symbol)
1064  WRITE (iw, "(i7,T15,A2,T37,F8.3)") &
1065  iatom, adjustr(element_symbol), cp_unit_from_cp2k(hirshfeld_control%radii(iatom), "angstrom")
1066  END DO
1067  WRITE (iw, '(T3,A)') &
1068  '------------------------------------------------------------------------'
1069  END IF
1070  WRITE (iw, '(/,T3,A,T60)') &
1071  '----------------------- CDFT group definitions -------------------------'
1072  DO igroup = 1, SIZE(group)
1073  IF (igroup > 1) WRITE (iw, '(T3,A)') ' '
1074  WRITE (iw, '(T5,A,I5,A,I5)') &
1075  'Atomic group', igroup, ' of ', SIZE(group)
1076  WRITE (iw, '(T5,A)') 'Atom Element Coefficient'
1077  DO ip = 1, SIZE(group(igroup)%atoms)
1078  iatom = group(igroup)%atoms(ip)
1079  CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, element_symbol=element_symbol)
1080  WRITE (iw, '(i8,T16,A2,T23,F8.3)') iatom, adjustr(element_symbol), group(igroup)%coeff(ip)
1081  END DO
1082  END DO
1083  WRITE (iw, '(T3,A)') &
1084  '------------------------------------------------------------------------'
1085  END IF
1086  cdft_control%first_iteration = .false.
1087  END IF
1088 
1089  ! Radii no longer needed
1090  IF (ASSOCIATED(hirshfeld_control%radii)) DEALLOCATE (hirshfeld_control%radii)
1091  CALL timestop(handle)
1092 
1093  END SUBROUTINE hirshfeld_constraint_init
1094 
1095 ! **************************************************************************************************
1096 !> \brief Prints information about CDFT constraints
1097 !> \param qs_env the qs_env where to build the constraint
1098 !> \param electronic_charge the CDFT charges
1099 !> \par History
1100 !> Created 9.2018 [Nico Holmberg]
1101 ! **************************************************************************************************
1102  SUBROUTINE cdft_constraint_print(qs_env, electronic_charge)
1103  TYPE(qs_environment_type), POINTER :: qs_env
1104  REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: electronic_charge
1105 
1106  CHARACTER(len=2) :: element_symbol
1107  INTEGER :: iatom, ikind, iw, jatom
1108  REAL(kind=dp) :: tc(2), zeff
1109  TYPE(cdft_control_type), POINTER :: cdft_control
1110  TYPE(cp_logger_type), POINTER :: logger
1111  TYPE(dft_control_type), POINTER :: dft_control
1112  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1113  TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1114  TYPE(section_vals_type), POINTER :: cdft_constraint_section
1115 
1116  NULLIFY (cdft_constraint_section, logger, particle_set, dft_control, qs_kind_set)
1117  logger => cp_get_default_logger()
1118 
1119  CALL get_qs_env(qs_env, &
1120  particle_set=particle_set, &
1121  dft_control=dft_control, &
1122  qs_kind_set=qs_kind_set)
1123  cpassert(ASSOCIATED(qs_kind_set))
1124 
1125  cdft_constraint_section => section_vals_get_subs_vals(qs_env%input, "DFT%QS%CDFT")
1126  iw = cp_print_key_unit_nr(logger, cdft_constraint_section, "PROGRAM_RUN_INFO", extension=".cdftLog")
1127  cdft_control => dft_control%qs_control%cdft_control
1128 
1129  ! Print constraint information
1130  CALL qs_scf_cdft_constraint_info(iw, cdft_control)
1131 
1132  ! Print weight function(s) to cube file(s) whenever weight is (re)built
1133  IF (cdft_control%print_weight .AND. cdft_control%need_pot) &
1134  CALL cdft_print_weight_function(qs_env)
1135 
1136  ! Print atomic CDFT charges
1137  IF (iw > 0 .AND. cdft_control%atomic_charges) THEN
1138  IF (.NOT. cdft_control%fragment_density) THEN
1139  IF (dft_control%nspins == 1) THEN
1140  WRITE (iw, '(/,T3,A)') &
1141  '-------------------------------- CDFT atomic charges --------------------------------'
1142  WRITE (iw, '(T3,A,A)') &
1143  '#Atom Element Is_constraint', ' Core charge Population (total)'// &
1144  ' Net charge'
1145  tc = 0.0_dp
1146  DO iatom = 1, cdft_control%natoms
1147  jatom = cdft_control%atoms(iatom)
1148  CALL get_atomic_kind(atomic_kind=particle_set(jatom)%atomic_kind, &
1149  element_symbol=element_symbol, &
1150  kind_number=ikind)
1151  CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
1152  WRITE (iw, "(i7,T15,A2,T23,L10,T39,F8.3,T61,F8.3,T81,F8.3)") &
1153  jatom, adjustr(element_symbol), cdft_control%is_constraint(iatom), zeff, electronic_charge(iatom, 1), &
1154  (zeff - electronic_charge(iatom, 1))
1155  tc(1) = tc(1) + (zeff - electronic_charge(iatom, 1))
1156  END DO
1157  WRITE (iw, '(/,T3,A,T81,F8.3,/)') "Total Charge: ", tc(1)
1158  ELSE
1159  WRITE (iw, '(/,T3,A)') &
1160  '------------------------------------------ CDFT atomic charges -------------------------------------------'
1161  WRITE (iw, '(T3,A,A)') &
1162  '#Atom Element Is_constraint', ' Core charge Population (alpha, beta)'// &
1163  ' Net charge Spin population'
1164  tc = 0.0_dp
1165  DO iatom = 1, cdft_control%natoms
1166  jatom = cdft_control%atoms(iatom)
1167  CALL get_atomic_kind(atomic_kind=particle_set(jatom)%atomic_kind, &
1168  element_symbol=element_symbol, &
1169  kind_number=ikind)
1170  CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
1171  WRITE (iw, "(i7,T15,A2,T23,L10,T39,F8.3,T53,F8.3,T67,F8.3,T81,F8.3,T102,F8.3)") &
1172  jatom, adjustr(element_symbol), &
1173  cdft_control%is_constraint(iatom), &
1174  zeff, electronic_charge(iatom, 1), electronic_charge(iatom, 2), &
1175  (zeff - electronic_charge(iatom, 1) - electronic_charge(iatom, 2)), &
1176  electronic_charge(iatom, 1) - electronic_charge(iatom, 2)
1177  tc(1) = tc(1) + (zeff - electronic_charge(iatom, 1) - electronic_charge(iatom, 2))
1178  tc(2) = tc(2) + (electronic_charge(iatom, 1) - electronic_charge(iatom, 2))
1179  END DO
1180  WRITE (iw, '(/,T3,A,T81,F8.3,T102,F8.3/)') "Total Charge and Spin Moment: ", tc(1), tc(2)
1181  END IF
1182  ELSE
1183  IF (all(cdft_control%group(:)%constraint_type == cdft_charge_constraint)) THEN
1184  WRITE (iw, '(/,T3,A)') &
1185  '-------------------------------- CDFT atomic charges --------------------------------'
1186  IF (dft_control%nspins == 1) THEN
1187  WRITE (iw, '(T3,A,A)') &
1188  '#Atom Element Is_constraint', ' Fragment charge Population (total)'// &
1189  ' Net charge'
1190  ELSE
1191  WRITE (iw, '(T3,A,A)') &
1192  '#Atom Element Is_constraint', ' Fragment charge Population (alpha, beta)'// &
1193  ' Net charge'
1194  END IF
1195  tc = 0.0_dp
1196  DO iatom = 1, cdft_control%natoms
1197  jatom = cdft_control%atoms(iatom)
1198  CALL get_atomic_kind(atomic_kind=particle_set(jatom)%atomic_kind, &
1199  element_symbol=element_symbol, &
1200  kind_number=ikind)
1201  IF (dft_control%nspins == 1) THEN
1202  WRITE (iw, "(i7,T15,A2,T23,L10,T43,F8.3,T65,F8.3,T81,F8.3)") &
1203  jatom, adjustr(element_symbol), &
1204  cdft_control%is_constraint(iatom), &
1205  cdft_control%charges_fragment(iatom, 1), &
1206  electronic_charge(iatom, 1), &
1207  (electronic_charge(iatom, 1) - &
1208  cdft_control%charges_fragment(iatom, 1))
1209  tc(1) = tc(1) + (electronic_charge(iatom, 1) - &
1210  cdft_control%charges_fragment(iatom, 1))
1211  ELSE
1212  WRITE (iw, "(i7,T15,A2,T23,L10,T43,F8.3,T57,F8.3,T69,F8.3,T81,F8.3)") &
1213  jatom, adjustr(element_symbol), &
1214  cdft_control%is_constraint(iatom), &
1215  cdft_control%charges_fragment(iatom, 1), &
1216  electronic_charge(iatom, 1), electronic_charge(iatom, 2), &
1217  (electronic_charge(iatom, 1) + electronic_charge(iatom, 2) - &
1218  cdft_control%charges_fragment(iatom, 1))
1219  tc(1) = tc(1) + (electronic_charge(iatom, 1) + electronic_charge(iatom, 2) - &
1220  cdft_control%charges_fragment(iatom, 1))
1221  END IF
1222  END DO
1223  WRITE (iw, '(/,T3,A,T81,F8.3,/)') "Total Charge: ", tc(1)
1224  ELSE
1225  WRITE (iw, '(/,T3,A)') &
1226  '------------------------------------------ CDFT atomic charges -------------------------------------------'
1227  WRITE (iw, '(T3,A,A)') &
1228  '#Atom Element Is_constraint', ' Fragment charge/spin moment'// &
1229  ' Population (alpha, beta) Net charge/spin moment'
1230  tc = 0.0_dp
1231  DO iatom = 1, cdft_control%natoms
1232  jatom = cdft_control%atoms(iatom)
1233  CALL get_atomic_kind(atomic_kind=particle_set(jatom)%atomic_kind, &
1234  element_symbol=element_symbol, &
1235  kind_number=ikind)
1236  WRITE (iw, "(i7,T15,A2,T22,L10,T40,F8.3,T52,F8.3,T66,F8.3,T78,F8.3,T90,F8.3,T102,F8.3)") &
1237  jatom, adjustr(element_symbol), &
1238  cdft_control%is_constraint(iatom), &
1239  cdft_control%charges_fragment(iatom, 1), &
1240  cdft_control%charges_fragment(iatom, 2), &
1241  electronic_charge(iatom, 1), electronic_charge(iatom, 2), &
1242  (electronic_charge(iatom, 1) + electronic_charge(iatom, 2) - &
1243  cdft_control%charges_fragment(iatom, 1)), &
1244  (electronic_charge(iatom, 1) - electronic_charge(iatom, 2) - &
1245  cdft_control%charges_fragment(iatom, 2))
1246  tc(1) = tc(1) + (electronic_charge(iatom, 1) + electronic_charge(iatom, 2) - &
1247  cdft_control%charges_fragment(iatom, 1))
1248  tc(2) = tc(2) + (electronic_charge(iatom, 1) - electronic_charge(iatom, 2) - &
1249  cdft_control%charges_fragment(iatom, 2))
1250  END DO
1251  WRITE (iw, '(/,T3,A,T90,F8.3,T102,F8.3/)') "Total Charge and Spin Moment: ", tc(1), tc(2)
1252  END IF
1253  END IF
1254  END IF
1255 
1256  END SUBROUTINE cdft_constraint_print
1257 
1258 ! **************************************************************************************************
1259 !> \brief Prints CDFT weight functions to cube files
1260 !> \param qs_env ...
1261 ! **************************************************************************************************
1262  SUBROUTINE cdft_print_weight_function(qs_env)
1263  TYPE(qs_environment_type), POINTER :: qs_env
1264 
1265  CHARACTER(LEN=default_path_length) :: middle_name
1266  INTEGER :: igroup, unit_nr
1267  LOGICAL :: mpi_io
1268  TYPE(cdft_control_type), POINTER :: cdft_control
1269  TYPE(cp_logger_type), POINTER :: logger
1270  TYPE(dft_control_type), POINTER :: dft_control
1271  TYPE(mp_para_env_type), POINTER :: para_env
1272  TYPE(particle_list_type), POINTER :: particles
1273  TYPE(qs_subsys_type), POINTER :: subsys
1274  TYPE(section_vals_type), POINTER :: cdft_constraint_section
1275 
1276  NULLIFY (cdft_constraint_section, logger, particles, dft_control, &
1277  para_env, subsys, cdft_control)
1278  logger => cp_get_default_logger()
1279 
1280  CALL get_qs_env(qs_env, subsys=subsys, para_env=para_env, dft_control=dft_control)
1281  CALL qs_subsys_get(subsys, particles=particles)
1282  cdft_control => dft_control%qs_control%cdft_control
1283  cdft_constraint_section => section_vals_get_subs_vals(qs_env%input, "DFT%QS%CDFT")
1284 
1285  DO igroup = 1, SIZE(cdft_control%group)
1286  mpi_io = .true.
1287  middle_name = "cdft_weight_"//trim(adjustl(cp_to_string(igroup)))
1288  unit_nr = cp_print_key_unit_nr(logger, cdft_constraint_section, "PROGRAM_RUN_INFO", &
1289  middle_name=middle_name, &
1290  extension=".cube", file_position="REWIND", &
1291  log_filename=.false., mpi_io=mpi_io)
1292  ! Note PROGRAM_RUN_INFO section neeeds to be active!
1293  IF (para_env%is_source() .AND. unit_nr .LT. 1) &
1294  CALL cp_abort(__location__, &
1295  "Please turn on PROGRAM_RUN_INFO to print CDFT weight function.")
1296 
1297  CALL cp_pw_to_cube(cdft_control%group(igroup)%weight, &
1298  unit_nr, &
1299  "CDFT Weight Function", &
1300  particles=particles, &
1301  stride=section_get_ivals(cdft_constraint_section, "PROGRAM_RUN_INFO%WEIGHT_FUNCTION%STRIDE"), &
1302  mpi_io=mpi_io)
1303  CALL cp_print_key_finished_output(unit_nr, logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io)
1304  END DO
1305 
1306  END SUBROUTINE cdft_print_weight_function
1307 
1308 ! **************************************************************************************************
1309 !> \brief Prints Hirshfeld weight function and promolecule density
1310 !> \param qs_env ...
1311 ! **************************************************************************************************
1312  SUBROUTINE cdft_print_hirshfeld_density(qs_env)
1313  TYPE(qs_environment_type), POINTER :: qs_env
1314 
1315  CHARACTER(LEN=default_path_length) :: middle_name
1316  INTEGER :: iatom, igroup, unit_nr
1317  LOGICAL :: mpi_io
1318  TYPE(cdft_control_type), POINTER :: cdft_control
1319  TYPE(cp_logger_type), POINTER :: logger
1320  TYPE(dft_control_type), POINTER :: dft_control
1321  TYPE(mp_para_env_type), POINTER :: para_env
1322  TYPE(particle_list_type), POINTER :: particles
1323  TYPE(pw_env_type), POINTER :: pw_env
1324  TYPE(qs_subsys_type), POINTER :: subsys
1325  TYPE(section_vals_type), POINTER :: cdft_constraint_section
1326 
1327  NULLIFY (cdft_constraint_section, logger, particles, dft_control, &
1328  para_env, subsys, cdft_control, pw_env)
1329  logger => cp_get_default_logger()
1330 
1331  CALL get_qs_env(qs_env, subsys=subsys, para_env=para_env, dft_control=dft_control, pw_env=pw_env)
1332  CALL qs_subsys_get(subsys, particles=particles)
1333  cdft_control => dft_control%qs_control%cdft_control
1334  cdft_constraint_section => section_vals_get_subs_vals(qs_env%input, "DFT%QS%CDFT")
1335 
1336  mpi_io = .true.
1337 
1338  DO igroup = 1, SIZE(cdft_control%group)
1339 
1340  middle_name = "hw_rho_total"//trim(adjustl(cp_to_string(igroup)))
1341  unit_nr = cp_print_key_unit_nr(logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io, &
1342  file_position="REWIND", middle_name=middle_name, extension=".cube")
1343 
1344  CALL cp_pw_to_cube(cdft_control%group(igroup)%hw_rho_total, unit_nr, "CDFT Weight Function", mpi_io=mpi_io, &
1345  particles=particles, stride=section_get_ivals(cdft_constraint_section, "PROGRAM_RUN_INFO%WEIGHT_FUNCTION%STRIDE"))
1346 
1347  CALL cp_print_key_finished_output(unit_nr, logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io)
1348 
1349  END DO
1350 
1351  DO igroup = 1, SIZE(cdft_control%group)
1352 
1353  middle_name = "hw_rho_total_constraint_"//trim(adjustl(cp_to_string(igroup)))
1354  unit_nr = cp_print_key_unit_nr(logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io, &
1355  file_position="REWIND", middle_name=middle_name, extension=".cube")
1356 
1357  CALL cp_pw_to_cube(cdft_control%group(igroup)%hw_rho_total_constraint, unit_nr, &
1358  "CDFT Weight Function", mpi_io=mpi_io, particles=particles, &
1359  stride=section_get_ivals(cdft_constraint_section, "PROGRAM_RUN_INFO%WEIGHT_FUNCTION%STRIDE"))
1360 
1361  CALL cp_print_key_finished_output(unit_nr, logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io)
1362 
1363  END DO
1364 
1365  DO igroup = 1, SIZE(cdft_control%group)
1366  DO iatom = 1, (cdft_control%natoms)
1367 
1368  middle_name = "hw_rho_atomic_"//trim(adjustl(cp_to_string(iatom)))
1369  unit_nr = cp_print_key_unit_nr(logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io, &
1370  file_position="REWIND", middle_name=middle_name, extension=".cube")
1371 
1372  CALL cp_pw_to_cube(cdft_control%group(igroup)%hw_rho_atomic(iatom), unit_nr, &
1373  "CDFT Weight Function", mpi_io=mpi_io, particles=particles, &
1374  stride=section_get_ivals(cdft_constraint_section, "PROGRAM_RUN_INFO%WEIGHT_FUNCTION%STRIDE"))
1375 
1376  CALL cp_print_key_finished_output(unit_nr, logger, cdft_constraint_section, "PROGRAM_RUN_INFO", mpi_io=mpi_io)
1377 
1378  END DO
1379  END DO
1380 
1381  END SUBROUTINE cdft_print_hirshfeld_density
1382 
1383 END MODULE qs_cdft_utils
subroutine pbc(r, r_pbc, s, s_pbc, a, b, c, alpha, beta, gamma, debug, info, pbc0, h, hinv)
...
Definition: dumpdcd.F:1203
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Definition: grid_common.h:117
All kind of helpful little routines.
Definition: ao_util.F:14
real(kind=dp) function, public exp_radius_very_extended(la_min, la_max, lb_min, lb_max, pab, o1, o2, ra, rb, rp, zetp, eps, prefactor, cutoff, epsabs)
computes the radius of the Gaussian outside of which it is smaller than eps
Definition: ao_util.F:209
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
collects all references to literature in CP2K as new algorithms / method are included from literature...
Definition: bibliography.F:28
integer, save, public holmberg2017
Definition: bibliography.F:43
integer, save, public holmberg2018
Definition: bibliography.F:43
integer, save, public becke1988b
Definition: bibliography.F:43
Handles all functions related to the CELL.
Definition: cell_types.F:15
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
A wrapper around pw_to_cube() which accepts particle_list_type.
subroutine, public cp_pw_to_cube(pw, unit_nr, title, particles, stride, zero_tails, silent, mpi_io)
...
unit conversion facility
Definition: cp_units.F:30
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
Definition: cp_units.F:1179
Fortran API for the grid package, which is written in C.
Definition: grid_api.F:12
integer, parameter, public grid_func_ab
Definition: grid_api.F:29
subroutine, public collocate_pgf_product(la_max, zeta, la_min, lb_max, zetb, lb_min, ra, rab, scale, pab, o1, o2, rsgrid, ga_gb_function, radius, use_subpatch, subpatch_pattern)
low level collocation of primitive gaussian functions
Definition: grid_api.F:119
Calculate Hirshfeld charges and related functions.
subroutine, public create_shape_function(hirshfeld_env, qs_kind_set, atomic_kind_set, radius, radii_list)
creates kind specific shape functions for Hirshfeld charges
The types needed for the calculation of Hirshfeld charges and related functions.
subroutine, public create_hirshfeld_type(hirshfeld_env)
...
subroutine, public set_hirshfeld_info(hirshfeld_env, shape_function_type, iterative, ref_charge, fnorm, radius_type, use_bohr)
Set values of a Hirshfeld env.
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public becke_cutoff_element
integer, parameter, public outer_scf_cdft_constraint
integer, parameter, public cdft_charge_constraint
integer, parameter, public outer_scf_becke_constraint
integer, parameter, public radius_user
integer, parameter, public outer_scf_hirshfeld_constraint
integer, parameter, public shape_function_gaussian
integer, parameter, public outer_scf_none
integer, parameter, public becke_cutoff_global
objects that represent the structure of input sections and the data contained in an input section
integer function, dimension(:), pointer, public section_get_ivals(section_vals, keyword_name)
...
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
integer, parameter, public default_path_length
Definition: kinds.F:58
Utility routines for the memory handling.
Interface to the message passing library MPI.
parameters that control the outer loop of an SCF iteration
subroutine, public outer_scf_read_parameters(outer_scf, outer_scf_section)
reads the parameters of the outer_scf section into the given outer_scf
represent a simple array based list of the given type
Define the data structure for the particle information.
container for various plainwaves related things
Definition: pw_env_types.F:14
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
Definition: pw_env_types.F:113
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Definition: pw_pool_types.F:24
Defines CDFT control structures.
Definition: qs_cdft_types.F:14
Utility subroutines for CDFT calculations.
Definition: qs_cdft_utils.F:14
subroutine, public read_cdft_control_section(qs_control, cdft_control_section)
reads the input parameters needed for CDFT with OT
subroutine, public cdft_constraint_print(qs_env, electronic_charge)
Prints information about CDFT constraints.
subroutine, public hirshfeld_constraint_init(qs_env)
Initializes Gaussian Hirshfeld constraints.
subroutine, public cdft_print_weight_function(qs_env)
Prints CDFT weight functions to cube files.
subroutine, public becke_constraint_init(qs_env)
Initializes the Becke constraint environment.
Definition: qs_cdft_utils.F:97
subroutine, public hfun_scale(fout, fun1, fun2, divide, small)
Calculate fout = fun1/fun2 or fout = fun1*fun2.
subroutine, public read_becke_section(cdft_control, becke_section)
reads the input parameters specific to Becke-based CDFT constraints
subroutine, public cdft_print_hirshfeld_density(qs_env)
Prints Hirshfeld weight function and promolecule density.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_RI_aux_kp, matrix_s, matrix_s_RI_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, WannierCentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, rhs)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
Definition: qs_kind_types.F:23
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_r3d_rs_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, U_of_dft_plus_u, J_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, J0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, floating, name, element_symbol, pao_basis_size, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
subroutine, public qs_scf_cdft_constraint_info(output_unit, cdft_control)
writes CDFT constraint information
types that represent a quickstep subsys
subroutine, public qs_subsys_get(subsys, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell, energy, force, qs_kind_set, cp_subsys, nelectron_total, nelectron_spin)
...
subroutine, public transfer_rs2pw(rs, pw)
...
subroutine, public rs_grid_zero(rs)
Initialize grid to zero.