(git:b279b6b)
hirshfeld_methods.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 Calculate Hirshfeld charges and related functions
10 !> \par History
11 !> 11.2014 created [JGH]
12 !> \author JGH
13 ! **************************************************************************************************
17  USE atomic_kind_types, ONLY: atomic_kind_type,&
19  USE cell_types, ONLY: cell_type,&
20  pbc
21  USE cp_control_types, ONLY: dft_control_type
23  put_results
24  USE cp_result_types, ONLY: cp_result_type
25  USE cp_units, ONLY: cp_unit_to_cp2k
26  USE grid_api, ONLY: grid_func_ab,&
30  hirshfeld_type,&
32  USE input_constants, ONLY: radius_covalent,&
35  radius_user,&
36  radius_vdw,&
39  USE kinds, ONLY: default_string_length,&
40  dp
41  USE mathconstants, ONLY: pi
42  USE message_passing, ONLY: mp_para_env_type
43  USE particle_types, ONLY: particle_type
45  USE pw_env_types, ONLY: pw_env_get,&
46  pw_env_type
47  USE pw_methods, ONLY: pw_integrate_function
48  USE pw_pool_types, ONLY: pw_pool_type
49  USE pw_types, ONLY: pw_r3d_rs_type
50  USE qs_environment_types, ONLY: get_qs_env,&
51  qs_environment_type
52  USE qs_kind_types, ONLY: get_qs_kind,&
53  qs_kind_type
54  USE qs_rho_types, ONLY: qs_rho_get,&
55  qs_rho_type
56  USE realspace_grid_types, ONLY: realspace_grid_desc_type,&
57  realspace_grid_type,&
58  rs_grid_zero,&
61 #include "./base/base_uses.f90"
62 
63  IMPLICIT NONE
64  PRIVATE
65 
66  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'hirshfeld_methods'
67 
71 
72 ! **************************************************************************************************
73 
74 CONTAINS
75 
76 ! **************************************************************************************************
77 !> \brief ...
78 !> \param charges ...
79 !> \param hirshfeld_env ...
80 !> \param particle_set ...
81 !> \param qs_kind_set ...
82 !> \param unit_nr ...
83 ! **************************************************************************************************
84  SUBROUTINE write_hirshfeld_charges(charges, hirshfeld_env, particle_set, &
85  qs_kind_set, unit_nr)
86  REAL(kind=dp), DIMENSION(:, :), INTENT(inout) :: charges
87  TYPE(hirshfeld_type), POINTER :: hirshfeld_env
88  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
89  TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
90  INTEGER, INTENT(IN) :: unit_nr
91 
92  CHARACTER(len=2) :: element_symbol
93  INTEGER :: iatom, ikind, natom, nspin
94  REAL(kind=dp) :: refc, tc1, zeff
95 
96  natom = SIZE(charges, 1)
97  nspin = SIZE(charges, 2)
98  WRITE (unit_nr, '(/,T2,A)') '!-----------------------------------------------------------------------------!'
99  WRITE (unit=unit_nr, fmt="(T28,A)") "Hirshfeld Charges"
100  IF (nspin == 1) THEN
101  WRITE (unit=unit_nr, fmt="(/,T3,A,A)") &
102  "#Atom Element Kind ", " Ref Charge Population Net charge"
103  ELSE
104  WRITE (unit=unit_nr, fmt="(/,T3,A,A)") &
105  "#Atom Element Kind ", " Ref Charge Population Spin moment Net charge"
106  END IF
107  tc1 = 0.0_dp
108  DO iatom = 1, natom
109  CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, &
110  element_symbol=element_symbol, kind_number=ikind)
111  refc = hirshfeld_env%charges(iatom)
112  CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
113  IF (nspin == 1) THEN
114  WRITE (unit=unit_nr, fmt="(i7,T15,A2,T20,i3,T27,F8.3,T42,F8.3,T72,F8.3)") &
115  iatom, element_symbol, ikind, refc, charges(iatom, 1), zeff - charges(iatom, 1)
116  ELSE
117  WRITE (unit=unit_nr, fmt="(i7,T15,A2,T20,i3,T27,F8.3,T36,2F8.3,T61,F8.3,T72,F8.3)") &
118  iatom, element_symbol, ikind, refc, charges(iatom, 1), charges(iatom, 2), &
119  charges(iatom, 1) - charges(iatom, 2), zeff - sum(charges(iatom, :))
120  END IF
121  tc1 = tc1 + (zeff - sum(charges(iatom, :)))
122  END DO
123  WRITE (unit=unit_nr, fmt="(/,T3,A,T72,F8.3)") "Total Charge ", tc1
124  WRITE (unit_nr, '(T2,A)') '!-----------------------------------------------------------------------------!'
125 
126  END SUBROUTINE write_hirshfeld_charges
127 
128 ! **************************************************************************************************
129 !> \brief saves the Hirshfeld charges to the results structure
130 !> \param charges the calculated Hirshfeld charges
131 !> \param particle_set the particle set
132 !> \param qs_kind_set the kind set
133 !> \param qs_env the environment
134 ! **************************************************************************************************
135  SUBROUTINE save_hirshfeld_charges(charges, particle_set, qs_kind_set, qs_env)
136  REAL(kind=dp), DIMENSION(:, :), INTENT(inout) :: charges
137  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
138  TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
139  TYPE(qs_environment_type), POINTER :: qs_env
140 
141  CHARACTER(LEN=default_string_length) :: description
142  INTEGER :: iatom, ikind, natom
143  REAL(kind=dp) :: zeff
144  REAL(kind=dp), DIMENSION(:), POINTER :: charges_save
145  TYPE(cp_result_type), POINTER :: results
146 
147  NULLIFY (results)
148  CALL get_qs_env(qs_env, results=results)
149 
150  natom = SIZE(charges, 1)
151  ALLOCATE (charges_save(natom))
152 
153  DO iatom = 1, natom
154  CALL get_atomic_kind(atomic_kind=particle_set(iatom)%atomic_kind, &
155  kind_number=ikind)
156  CALL get_qs_kind(qs_kind_set(ikind), zeff=zeff)
157  charges_save(iatom) = zeff - sum(charges(iatom, :))
158  END DO
159 
160  ! Store charges in results
161  description = "[HIRSHFELD-CHARGES]"
162  CALL cp_results_erase(results=results, description=description)
163  CALL put_results(results=results, description=description, &
164  values=charges_save)
165 
166  DEALLOCATE (charges_save)
167 
168  END SUBROUTINE save_hirshfeld_charges
169 
170 ! **************************************************************************************************
171 !> \brief creates kind specific shape functions for Hirshfeld charges
172 !> \param hirshfeld_env the env that holds information about Hirshfeld
173 !> \param qs_kind_set the qs_kind_set
174 !> \param atomic_kind_set the atomic_kind_set
175 !> \param radius optional radius parameter to use for all atomic kinds
176 !> \param radii_list optional list of radii to use for different atomic kinds
177 ! **************************************************************************************************
178  SUBROUTINE create_shape_function(hirshfeld_env, qs_kind_set, atomic_kind_set, radius, radii_list)
179  TYPE(hirshfeld_type), POINTER :: hirshfeld_env
180  TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
181  TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
182  REAL(kind=dp), OPTIONAL :: radius
183  REAL(kind=dp), DIMENSION(:), OPTIONAL, POINTER :: radii_list
184 
185  INTEGER, PARAMETER :: ngto = 8
186 
187  CHARACTER(len=2) :: esym
188  INTEGER :: ikind, nkind
189  LOGICAL :: found
190  REAL(kind=dp) :: al, rco, zeff
191  REAL(kind=dp), DIMENSION(ngto, 2) :: ppdens
192  TYPE(atomic_kind_type), POINTER :: atomic_kind
193  TYPE(qs_kind_type), POINTER :: qs_kind
194 
195  cpassert(ASSOCIATED(hirshfeld_env))
196 
197  nkind = SIZE(qs_kind_set)
198  ALLOCATE (hirshfeld_env%kind_shape_fn(nkind))
199 
200  SELECT CASE (hirshfeld_env%shape_function_type)
202  DO ikind = 1, nkind
203  hirshfeld_env%kind_shape_fn(ikind)%numexp = 1
204  ALLOCATE (hirshfeld_env%kind_shape_fn(ikind)%zet(1))
205  ALLOCATE (hirshfeld_env%kind_shape_fn(ikind)%coef(1))
206  CALL get_qs_kind(qs_kind_set(ikind), element_symbol=esym)
207  rco = 2.0_dp
208  SELECT CASE (hirshfeld_env%radius_type)
209  CASE (radius_default)
210  CALL get_ptable_info(symbol=esym, covalent_radius=rco, found=found)
211  rco = max(rco, 1.0_dp)
212  CASE (radius_user)
213  cpassert(PRESENT(radii_list))
214  cpassert(ASSOCIATED(radii_list))
215  cpassert(SIZE(radii_list) == nkind)
216  ! Note we assume that radii_list is correctly ordered
217  rco = radii_list(ikind)
218  CASE (radius_vdw)
219  CALL get_ptable_info(symbol=esym, vdw_radius=rco, found=found)
220  IF (.NOT. found) THEN
221  rco = max(rco, 1.0_dp)
222  ELSE
223  IF (hirshfeld_env%use_bohr) &
224  rco = cp_unit_to_cp2k(rco, "angstrom")
225  END IF
226  CASE (radius_covalent)
227  CALL get_ptable_info(symbol=esym, covalent_radius=rco, found=found)
228  IF (.NOT. found) THEN
229  rco = max(rco, 1.0_dp)
230  ELSE
231  IF (hirshfeld_env%use_bohr) &
232  rco = cp_unit_to_cp2k(rco, "angstrom")
233  END IF
234  CASE (radius_single)
235  cpassert(PRESENT(radius))
236  rco = radius
237  END SELECT
238  al = 0.5_dp/rco**2
239  hirshfeld_env%kind_shape_fn(ikind)%zet(1) = al
240  hirshfeld_env%kind_shape_fn(ikind)%coef(1) = (al/pi)**1.5_dp
241  END DO
243  ! calculate atomic density
244  DO ikind = 1, nkind
245  atomic_kind => atomic_kind_set(ikind)
246  qs_kind => qs_kind_set(ikind)
247  CALL calculate_atomic_density(ppdens(:, :), atomic_kind, qs_kind, ngto, &
248  confine=.false.)
249  hirshfeld_env%kind_shape_fn(ikind)%numexp = ngto
250  ALLOCATE (hirshfeld_env%kind_shape_fn(ikind)%zet(ngto))
251  ALLOCATE (hirshfeld_env%kind_shape_fn(ikind)%coef(ngto))
252  hirshfeld_env%kind_shape_fn(ikind)%zet(:) = ppdens(:, 1)
253  CALL get_qs_kind(qs_kind, zeff=zeff)
254  hirshfeld_env%kind_shape_fn(ikind)%coef(:) = ppdens(:, 2)/zeff
255  END DO
256 
257  CASE DEFAULT
258  cpabort("Unknown shape function")
259  END SELECT
260 
261  END SUBROUTINE create_shape_function
262 
263 ! **************************************************************************************************
264 !> \brief ...
265 !> \param qs_env ...
266 !> \param hirshfeld_env ...
267 !> \param charges ...
268 ! **************************************************************************************************
269  SUBROUTINE comp_hirshfeld_charges(qs_env, hirshfeld_env, charges)
270  TYPE(qs_environment_type), POINTER :: qs_env
271  TYPE(hirshfeld_type), POINTER :: hirshfeld_env
272  REAL(kind=dp), DIMENSION(:, :), INTENT(inout) :: charges
273 
274  INTEGER :: is
275  LOGICAL :: rho_r_valid
276  REAL(kind=dp) :: tnfun
277  TYPE(pw_env_type), POINTER :: pw_env
278  TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
279  TYPE(pw_r3d_rs_type) :: rhonorm
280  TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
281  TYPE(qs_rho_type), POINTER :: rho
282 
283  NULLIFY (rho_r)
284  ! normalization function on grid
285  CALL calculate_hirshfeld_normalization(qs_env, hirshfeld_env)
286  ! check normalization
287  tnfun = pw_integrate_function(hirshfeld_env%fnorm)
288  tnfun = abs(tnfun - sum(hirshfeld_env%charges))
289  !
290  CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, rho=rho)
291  CALL qs_rho_get(rho, rho_r=rho_r, rho_r_valid=rho_r_valid)
292  CALL pw_env_get(pw_env=pw_env, auxbas_pw_pool=auxbas_pw_pool)
293  CALL auxbas_pw_pool%create_pw(rhonorm)
294  ! loop over spins
295  DO is = 1, SIZE(rho_r)
296  IF (rho_r_valid) THEN
297  CALL hfun_scale(rhonorm%array, rho_r(is)%array, &
298  hirshfeld_env%fnorm%array)
299  ELSE
300  cpabort("We need rho in real space")
301  END IF
302  CALL hirshfeld_integration(qs_env, hirshfeld_env, rhonorm, charges(:, is))
303  charges(:, is) = charges(:, is)*hirshfeld_env%charges(:)
304  END DO
305  CALL auxbas_pw_pool%give_back_pw(rhonorm)
306 
307  END SUBROUTINE comp_hirshfeld_charges
308 ! **************************************************************************************************
309 !> \brief Calculate fout = fun1/fun2
310 !> \param fout ...
311 !> \param fun1 ...
312 !> \param fun2 ...
313 ! **************************************************************************************************
314  SUBROUTINE hfun_scale(fout, fun1, fun2)
315  REAL(kind=dp), DIMENSION(:, :, :), INTENT(OUT) :: fout
316  REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: fun1, fun2
317 
318  REAL(kind=dp), PARAMETER :: small = 1.0e-12_dp
319 
320  INTEGER :: i1, i2, i3, n1, n2, n3
321 
322  n1 = SIZE(fout, 1)
323  n2 = SIZE(fout, 2)
324  n3 = SIZE(fout, 3)
325  cpassert(n1 == SIZE(fun1, 1))
326  cpassert(n2 == SIZE(fun1, 2))
327  cpassert(n3 == SIZE(fun1, 3))
328  cpassert(n1 == SIZE(fun2, 1))
329  cpassert(n2 == SIZE(fun2, 2))
330  cpassert(n3 == SIZE(fun2, 3))
331 
332  DO i3 = 1, n3
333  DO i2 = 1, n2
334  DO i1 = 1, n1
335  IF (fun2(i1, i2, i3) > small) THEN
336  fout(i1, i2, i3) = fun1(i1, i2, i3)/fun2(i1, i2, i3)
337  ELSE
338  fout(i1, i2, i3) = 0.0_dp
339  END IF
340  END DO
341  END DO
342  END DO
343 
344  END SUBROUTINE hfun_scale
345 
346 ! **************************************************************************************************
347 !> \brief ...
348 !> \param qs_env ...
349 !> \param hirshfeld_env ...
350 !> \param charges ...
351 !> \param ounit ...
352 ! **************************************************************************************************
353  SUBROUTINE comp_hirshfeld_i_charges(qs_env, hirshfeld_env, charges, ounit)
354  TYPE(qs_environment_type), POINTER :: qs_env
355  TYPE(hirshfeld_type), POINTER :: hirshfeld_env
356  REAL(kind=dp), DIMENSION(:, :), INTENT(inout) :: charges
357  INTEGER, INTENT(IN) :: ounit
358 
359  INTEGER, PARAMETER :: maxloop = 100
360  REAL(kind=dp), PARAMETER :: maxres = 1.0e-2_dp
361 
362  CHARACTER(len=3) :: yesno
363  INTEGER :: iat, iloop, is, natom
364  LOGICAL :: rho_r_valid
365  REAL(kind=dp) :: res, tnfun
366  TYPE(pw_env_type), POINTER :: pw_env
367  TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
368  TYPE(pw_r3d_rs_type) :: rhonorm
369  TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
370  TYPE(qs_rho_type), POINTER :: rho
371 
372  NULLIFY (rho_r)
373 
374  natom = SIZE(charges, 1)
375 
376  IF (ounit > 0) WRITE (ounit, "(/,T2,A)") "Hirshfeld charge iterations: Residuals ..."
377  !
378  CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, rho=rho)
379  CALL qs_rho_get(rho, rho_r=rho_r, rho_r_valid=rho_r_valid)
380  CALL pw_env_get(pw_env=pw_env, auxbas_pw_pool=auxbas_pw_pool)
381  CALL auxbas_pw_pool%create_pw(rhonorm)
382  !
383  DO iloop = 1, maxloop
384 
385  ! normalization function on grid
386  CALL calculate_hirshfeld_normalization(qs_env, hirshfeld_env)
387  ! check normalization
388  tnfun = pw_integrate_function(hirshfeld_env%fnorm)
389  tnfun = abs(tnfun - sum(hirshfeld_env%charges))
390  ! loop over spins
391  DO is = 1, SIZE(rho_r)
392  IF (rho_r_valid) THEN
393  CALL hfun_scale(rhonorm%array, rho_r(is)%array, &
394  hirshfeld_env%fnorm%array)
395  ELSE
396  cpabort("We need rho in real space")
397  END IF
398  CALL hirshfeld_integration(qs_env, hirshfeld_env, rhonorm, charges(:, is))
399  charges(:, is) = charges(:, is)*hirshfeld_env%charges(:)
400  END DO
401  ! residual
402  res = 0.0_dp
403  DO iat = 1, natom
404  res = res + (sum(charges(iat, :)) - hirshfeld_env%charges(iat))**2
405  END DO
406  res = sqrt(res/real(natom, kind=dp))
407  IF (ounit > 0) THEN
408  yesno = "NO "
409  IF (mod(iloop, 10) == 0) yesno = "YES"
410  WRITE (ounit, fmt="(F8.3)", advance=yesno) res
411  END IF
412  ! update
413  DO iat = 1, natom
414  hirshfeld_env%charges(iat) = sum(charges(iat, :))
415  END DO
416  IF (res < maxres) EXIT
417 
418  END DO
419  !
420  CALL auxbas_pw_pool%give_back_pw(rhonorm)
421 
422  END SUBROUTINE comp_hirshfeld_i_charges
423 
424 ! **************************************************************************************************
425 !> \brief ...
426 !> \param qs_env ...
427 !> \param hirshfeld_env ...
428 ! **************************************************************************************************
429  SUBROUTINE calculate_hirshfeld_normalization(qs_env, hirshfeld_env)
430 
431  TYPE(qs_environment_type), POINTER :: qs_env
432  TYPE(hirshfeld_type), POINTER :: hirshfeld_env
433 
434  CHARACTER(len=*), PARAMETER :: routinen = 'calculate_hirshfeld_normalization'
435 
436  INTEGER :: atom_a, handle, iatom, iex, ikind, &
437  ithread, j, natom, npme, nthread, &
438  numexp, subpatch_pattern
439  INTEGER, DIMENSION(:), POINTER :: atom_list, cores
440  REAL(kind=dp) :: alpha, coef, eps_rho_rspace, radius
441  REAL(kind=dp), DIMENSION(3) :: ra
442  REAL(kind=dp), DIMENSION(:, :), POINTER :: pab
443  TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
444  TYPE(cell_type), POINTER :: cell
445  TYPE(dft_control_type), POINTER :: dft_control
446  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
447  TYPE(pw_env_type), POINTER :: pw_env
448  TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
449  TYPE(pw_r3d_rs_type), POINTER :: fnorm
450  TYPE(realspace_grid_desc_type), POINTER :: auxbas_rs_desc
451  TYPE(realspace_grid_type), POINTER :: rs_rho
452 
453  CALL timeset(routinen, handle)
454 
455  CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, cell=cell, &
456  dft_control=dft_control, particle_set=particle_set, pw_env=pw_env)
457  CALL pw_env_get(pw_env, auxbas_rs_desc=auxbas_rs_desc, auxbas_rs_grid=rs_rho, &
458  auxbas_pw_pool=auxbas_pw_pool)
459  ! be careful in parallel nsmax is chosen with multigrid in mind!
460  CALL rs_grid_zero(rs_rho)
461 
462  eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
463  ALLOCATE (pab(1, 1))
464  nthread = 1
465  ithread = 0
466 
467  DO ikind = 1, SIZE(atomic_kind_set)
468  numexp = hirshfeld_env%kind_shape_fn(ikind)%numexp
469  IF (numexp <= 0) cycle
470  CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
471  ALLOCATE (cores(natom))
472 
473  DO iex = 1, numexp
474  alpha = hirshfeld_env%kind_shape_fn(ikind)%zet(iex)
475  coef = hirshfeld_env%kind_shape_fn(ikind)%coef(iex)
476  npme = 0
477  cores = 0
478  DO iatom = 1, natom
479  atom_a = atom_list(iatom)
480  ra(:) = pbc(particle_set(atom_a)%r, cell)
481  IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
482  ! replicated realspace grid, split the atoms up between procs
483  IF (modulo(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
484  npme = npme + 1
485  cores(npme) = iatom
486  END IF
487  ELSE
488  npme = npme + 1
489  cores(npme) = iatom
490  END IF
491  END DO
492  DO j = 1, npme
493  iatom = cores(j)
494  atom_a = atom_list(iatom)
495  pab(1, 1) = hirshfeld_env%charges(atom_a)*coef
496  ra(:) = pbc(particle_set(atom_a)%r, cell)
497  subpatch_pattern = 0
498  radius = exp_radius_very_extended(la_min=0, la_max=0, lb_min=0, lb_max=0, &
499  ra=ra, rb=ra, rp=ra, zetp=alpha, eps=eps_rho_rspace, &
500  pab=pab, o1=0, o2=0, & ! without map_consistent
501  prefactor=1.0_dp, cutoff=0.0_dp)
502 
503  ! la_max==0 so set lmax_global to 0
504  CALL collocate_pgf_product(0, alpha, 0, 0, 0.0_dp, 0, ra, &
505  (/0.0_dp, 0.0_dp, 0.0_dp/), 1.0_dp, pab, 0, 0, rs_rho, &
506  radius=radius, ga_gb_function=grid_func_ab, &
507  use_subpatch=.true., subpatch_pattern=subpatch_pattern)
508  END DO
509  END DO
510 
511  DEALLOCATE (cores)
512  END DO
513  DEALLOCATE (pab)
514 
515  NULLIFY (fnorm)
516  CALL get_hirshfeld_info(hirshfeld_env, fnorm=fnorm)
517  IF (ASSOCIATED(fnorm)) THEN
518  CALL fnorm%release()
519  DEALLOCATE (fnorm)
520  END IF
521  ALLOCATE (fnorm)
522  CALL auxbas_pw_pool%create_pw(fnorm)
523  CALL set_hirshfeld_info(hirshfeld_env, fnorm=fnorm)
524 
525  CALL transfer_rs2pw(rs_rho, fnorm)
526 
527  CALL timestop(handle)
528 
529  END SUBROUTINE calculate_hirshfeld_normalization
530 
531 ! **************************************************************************************************
532 !> \brief ...
533 !> \param qs_env ...
534 !> \param hirshfeld_env ...
535 !> \param rfun ...
536 !> \param fval ...
537 !> \param fderiv ...
538 ! **************************************************************************************************
539  SUBROUTINE hirshfeld_integration(qs_env, hirshfeld_env, rfun, fval, fderiv)
540 
541  TYPE(qs_environment_type), POINTER :: qs_env
542  TYPE(hirshfeld_type), POINTER :: hirshfeld_env
543  TYPE(pw_r3d_rs_type) :: rfun
544  REAL(kind=dp), DIMENSION(:), INTENT(inout) :: fval
545  REAL(kind=dp), DIMENSION(:, :), INTENT(inout), &
546  OPTIONAL :: fderiv
547 
548  CHARACTER(len=*), PARAMETER :: routinen = 'hirshfeld_integration'
549 
550  INTEGER :: atom_a, handle, iatom, iex, ikind, &
551  ithread, j, natom, npme, nthread, &
552  numexp
553  INTEGER, ALLOCATABLE, DIMENSION(:) :: cores
554  INTEGER, DIMENSION(:), POINTER :: atom_list
555  LOGICAL :: do_force
556  REAL(kind=dp) :: alpha, coef, dvol, eps_rho_rspace, radius
557  REAL(kind=dp), DIMENSION(3) :: force_a, force_b, ra
558  REAL(kind=dp), DIMENSION(:, :), POINTER :: hab, pab
559  TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
560  TYPE(cell_type), POINTER :: cell
561  TYPE(dft_control_type), POINTER :: dft_control
562  TYPE(mp_para_env_type), POINTER :: para_env
563  TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
564  TYPE(pw_env_type), POINTER :: pw_env
565  TYPE(realspace_grid_desc_type), POINTER :: auxbas_rs_desc
566  TYPE(realspace_grid_type), POINTER :: rs_v
567 
568  CALL timeset(routinen, handle)
569 
570  do_force = PRESENT(fderiv)
571  fval = 0.0_dp
572  dvol = rfun%pw_grid%dvol
573 
574  NULLIFY (pw_env, auxbas_rs_desc)
575  CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
576  CALL pw_env_get(pw_env=pw_env, auxbas_rs_desc=auxbas_rs_desc, &
577  auxbas_rs_grid=rs_v)
578  CALL transfer_pw2rs(rs_v, rfun)
579 
580  CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, cell=cell, &
581  dft_control=dft_control, particle_set=particle_set)
582  eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
583 
584  nthread = 1
585  ithread = 0
586  ALLOCATE (hab(1, 1), pab(1, 1))
587 
588  DO ikind = 1, SIZE(atomic_kind_set)
589  numexp = hirshfeld_env%kind_shape_fn(ikind)%numexp
590  IF (numexp <= 0) cycle
591  CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
592  ALLOCATE (cores(natom))
593 
594  DO iex = 1, numexp
595  alpha = hirshfeld_env%kind_shape_fn(ikind)%zet(iex)
596  coef = hirshfeld_env%kind_shape_fn(ikind)%coef(iex)
597  npme = 0
598  cores = 0
599  DO iatom = 1, natom
600  atom_a = atom_list(iatom)
601  ra(:) = pbc(particle_set(atom_a)%r, cell)
602  IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed) THEN
603  ! replicated realspace grid, split the atoms up between procs
604  IF (modulo(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos) THEN
605  npme = npme + 1
606  cores(npme) = iatom
607  END IF
608  ELSE
609  npme = npme + 1
610  cores(npme) = iatom
611  END IF
612  END DO
613 
614  DO j = 1, npme
615  iatom = cores(j)
616  atom_a = atom_list(iatom)
617  ra(:) = pbc(particle_set(atom_a)%r, cell)
618  pab(1, 1) = coef
619  hab(1, 1) = 0.0_dp
620  force_a(:) = 0.0_dp
621  force_b(:) = 0.0_dp
622 
623  radius = exp_radius_very_extended(la_min=0, la_max=0, lb_min=0, lb_max=0, &
624  ra=ra, rb=ra, rp=ra, &
625  zetp=alpha, eps=eps_rho_rspace, &
626  pab=pab, o1=0, o2=0, & ! without map_consistent
627  prefactor=1.0_dp, cutoff=1.0_dp)
628 
629  CALL integrate_pgf_product(0, alpha, 0, &
630  0, 0.0_dp, 0, ra, (/0.0_dp, 0.0_dp, 0.0_dp/), &
631  rs_v, hab, pab=pab, o1=0, o2=0, &
632  radius=radius, calculate_forces=do_force, &
633  force_a=force_a, force_b=force_b, use_virial=.false., &
634  use_subpatch=.true., subpatch_pattern=0)
635  fval(atom_a) = fval(atom_a) + hab(1, 1)*dvol*coef
636  IF (do_force) THEN
637  fderiv(:, atom_a) = fderiv(:, atom_a) + force_a(:)*dvol
638  END IF
639  END DO
640 
641  END DO
642  DEALLOCATE (cores)
643 
644  END DO
645 
646  DEALLOCATE (hab, pab)
647 
648  CALL get_qs_env(qs_env=qs_env, para_env=para_env)
649  CALL para_env%sum(fval)
650 
651  CALL timestop(handle)
652 
653  END SUBROUTINE hirshfeld_integration
654 
655 END MODULE hirshfeld_methods
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
calculate the orbitals for a given atomic kind type
subroutine, public calculate_atomic_density(density, atomic_kind, qs_kind, ngto, iunit, allelectron, confine)
...
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.
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...
set of type/routines to handle the storage of results in force_envs
subroutine, public cp_results_erase(results, description, nval)
erase a part of result_list
set of type/routines to handle the storage of results in force_envs
unit conversion facility
Definition: cp_units.F:30
real(kind=dp) function, public cp_unit_to_cp2k(value, unit_str, defaults, power)
converts to the internal cp2k units to the given unit
Definition: cp_units.F:1150
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 integrate_pgf_product(la_max, zeta, la_min, lb_max, zetb, lb_min, ra, rab, rsgrid, hab, pab, o1, o2, radius, calculate_forces, force_a, force_b, compute_tau, use_virial, my_virial_a, my_virial_b, hdab, hadb, a_hdab, use_subpatch, subpatch_pattern)
low level function to compute matrix elements of primitive gaussian functions
Definition: grid_api.F:279
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 comp_hirshfeld_charges(qs_env, hirshfeld_env, charges)
...
subroutine, public create_shape_function(hirshfeld_env, qs_kind_set, atomic_kind_set, radius, radii_list)
creates kind specific shape functions for Hirshfeld charges
subroutine, public write_hirshfeld_charges(charges, hirshfeld_env, particle_set, qs_kind_set, unit_nr)
...
subroutine, public comp_hirshfeld_i_charges(qs_env, hirshfeld_env, charges, ounit)
...
subroutine, public save_hirshfeld_charges(charges, particle_set, qs_kind_set, qs_env)
saves the Hirshfeld charges to the results structure
The types needed for the calculation of Hirshfeld charges and related functions.
subroutine, public get_hirshfeld_info(hirshfeld_env, shape_function_type, iterative, ref_charge, fnorm, radius_type, use_bohr)
Get information from a 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 radius_vdw
integer, parameter, public radius_default
integer, parameter, public radius_user
integer, parameter, public shape_function_density
integer, parameter, public radius_covalent
integer, parameter, public shape_function_gaussian
integer, parameter, public radius_single
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
integer, parameter, public default_string_length
Definition: kinds.F:57
Definition of mathematical constants and functions.
Definition: mathconstants.F:16
real(kind=dp), parameter, public pi
Interface to the message passing library MPI.
Define the data structure for the particle information.
Periodic Table related data definitions.
subroutine, public get_ptable_info(symbol, number, amass, ielement, covalent_radius, metallic_radius, vdw_radius, found)
Pass information about the kind given the element symbol.
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
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.
superstucture that hold various representations of the density and keeps track of which ones are vali...
Definition: qs_rho_types.F:18
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
Definition: qs_rho_types.F:229
subroutine, public transfer_pw2rs(rs, pw)
...
subroutine, public transfer_rs2pw(rs, pw)
...
subroutine, public rs_grid_zero(rs)
Initialize grid to zero.