(git:42db5d2)
Loading...
Searching...
No Matches
hirshfeld_methods.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Calculate Hirshfeld charges and related functions
10!> \par History
11!> 11.2014 created [JGH]
12!> \author JGH
13! **************************************************************************************************
19 USE cell_types, ONLY: cell_type,&
20 pbc
25 USE cp_units, ONLY: cp_unit_to_cp2k
26 USE grid_api, ONLY: grid_func_ab,&
39 USE kinds, ONLY: default_string_length,&
40 dp
41 USE mathconstants, ONLY: pi
45 USE pw_env_types, ONLY: pw_env_get,&
49 USE pw_types, ONLY: pw_r3d_rs_type
52 USE qs_kind_types, ONLY: get_qs_kind,&
54 USE qs_rho_types, ONLY: qs_rho_get,&
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
74CONTAINS
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) THEN
224 rco = cp_unit_to_cp2k(rco, "angstrom")
225 END IF
226 END IF
227 CASE (radius_covalent)
228 CALL get_ptable_info(symbol=esym, covalent_radius=rco, found=found)
229 IF (.NOT. found) THEN
230 rco = max(rco, 1.0_dp)
231 ELSE
232 IF (hirshfeld_env%use_bohr) THEN
233 rco = cp_unit_to_cp2k(rco, "angstrom")
234 END IF
235 END IF
236 CASE (radius_single)
237 cpassert(PRESENT(radius))
238 rco = radius
239 END SELECT
240 al = 0.5_dp/rco**2
241 hirshfeld_env%kind_shape_fn(ikind)%zet(1) = al
242 hirshfeld_env%kind_shape_fn(ikind)%coef(1) = (al/pi)**1.5_dp
243 END DO
245 ! calculate atomic density
246 DO ikind = 1, nkind
247 atomic_kind => atomic_kind_set(ikind)
248 qs_kind => qs_kind_set(ikind)
249 CALL calculate_atomic_density(ppdens(:, :), atomic_kind, qs_kind, ngto, &
250 confine=.false.)
251 hirshfeld_env%kind_shape_fn(ikind)%numexp = ngto
252 ALLOCATE (hirshfeld_env%kind_shape_fn(ikind)%zet(ngto))
253 ALLOCATE (hirshfeld_env%kind_shape_fn(ikind)%coef(ngto))
254 hirshfeld_env%kind_shape_fn(ikind)%zet(:) = ppdens(:, 1)
255 CALL get_qs_kind(qs_kind, zeff=zeff)
256 hirshfeld_env%kind_shape_fn(ikind)%coef(:) = ppdens(:, 2)/zeff
257 END DO
258
259 CASE DEFAULT
260 cpabort("Unknown shape function")
261 END SELECT
262
263 END SUBROUTINE create_shape_function
264
265! **************************************************************************************************
266!> \brief ...
267!> \param qs_env ...
268!> \param hirshfeld_env ...
269!> \param charges ...
270! **************************************************************************************************
271 SUBROUTINE comp_hirshfeld_charges(qs_env, hirshfeld_env, charges)
272 TYPE(qs_environment_type), POINTER :: qs_env
273 TYPE(hirshfeld_type), POINTER :: hirshfeld_env
274 REAL(kind=dp), DIMENSION(:, :), INTENT(inout) :: charges
275
276 INTEGER :: is
277 LOGICAL :: rho_r_valid
278 REAL(kind=dp) :: tnfun
279 TYPE(pw_env_type), POINTER :: pw_env
280 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
281 TYPE(pw_r3d_rs_type) :: rhonorm
282 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
283 TYPE(qs_rho_type), POINTER :: rho
284
285 NULLIFY (rho_r)
286 ! normalization function on grid
287 CALL calculate_hirshfeld_normalization(qs_env, hirshfeld_env)
288 ! check normalization
289 tnfun = pw_integrate_function(hirshfeld_env%fnorm)
290 tnfun = abs(tnfun - sum(hirshfeld_env%charges))
291 !
292 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, rho=rho)
293 CALL qs_rho_get(rho, rho_r=rho_r, rho_r_valid=rho_r_valid)
294 CALL pw_env_get(pw_env=pw_env, auxbas_pw_pool=auxbas_pw_pool)
295 CALL auxbas_pw_pool%create_pw(rhonorm)
296 ! loop over spins
297 DO is = 1, SIZE(rho_r)
298 IF (rho_r_valid) THEN
299 CALL hfun_scale(rhonorm%array, rho_r(is)%array, &
300 hirshfeld_env%fnorm%array)
301 ELSE
302 cpabort("We need rho in real space")
303 END IF
304 CALL hirshfeld_integration(qs_env, hirshfeld_env, rhonorm, charges(:, is))
305 charges(:, is) = charges(:, is)*hirshfeld_env%charges(:)
306 END DO
307 CALL auxbas_pw_pool%give_back_pw(rhonorm)
308
309 END SUBROUTINE comp_hirshfeld_charges
310! **************************************************************************************************
311!> \brief Calculate fout = fun1/fun2
312!> \param fout ...
313!> \param fun1 ...
314!> \param fun2 ...
315! **************************************************************************************************
316 SUBROUTINE hfun_scale(fout, fun1, fun2)
317 REAL(kind=dp), DIMENSION(:, :, :), INTENT(OUT) :: fout
318 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: fun1, fun2
319
320 REAL(kind=dp), PARAMETER :: small = 1.0e-12_dp
321
322 INTEGER :: i1, i2, i3, n1, n2, n3
323
324 n1 = SIZE(fout, 1)
325 n2 = SIZE(fout, 2)
326 n3 = SIZE(fout, 3)
327 cpassert(n1 == SIZE(fun1, 1))
328 cpassert(n2 == SIZE(fun1, 2))
329 cpassert(n3 == SIZE(fun1, 3))
330 cpassert(n1 == SIZE(fun2, 1))
331 cpassert(n2 == SIZE(fun2, 2))
332 cpassert(n3 == SIZE(fun2, 3))
333
334 DO i3 = 1, n3
335 DO i2 = 1, n2
336 DO i1 = 1, n1
337 IF (fun2(i1, i2, i3) > small) THEN
338 fout(i1, i2, i3) = fun1(i1, i2, i3)/fun2(i1, i2, i3)
339 ELSE
340 fout(i1, i2, i3) = 0.0_dp
341 END IF
342 END DO
343 END DO
344 END DO
345
346 END SUBROUTINE hfun_scale
347
348! **************************************************************************************************
349!> \brief ...
350!> \param qs_env ...
351!> \param hirshfeld_env ...
352!> \param charges ...
353!> \param ounit ...
354! **************************************************************************************************
355 SUBROUTINE comp_hirshfeld_i_charges(qs_env, hirshfeld_env, charges, ounit)
356 TYPE(qs_environment_type), POINTER :: qs_env
357 TYPE(hirshfeld_type), POINTER :: hirshfeld_env
358 REAL(kind=dp), DIMENSION(:, :), INTENT(inout) :: charges
359 INTEGER, INTENT(IN) :: ounit
360
361 INTEGER, PARAMETER :: maxloop = 100
362 REAL(kind=dp), PARAMETER :: maxres = 1.0e-2_dp
363
364 CHARACTER(len=3) :: yesno
365 INTEGER :: iat, iloop, is, natom
366 LOGICAL :: rho_r_valid
367 REAL(kind=dp) :: res, tnfun
368 TYPE(pw_env_type), POINTER :: pw_env
369 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
370 TYPE(pw_r3d_rs_type) :: rhonorm
371 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
372 TYPE(qs_rho_type), POINTER :: rho
373
374 NULLIFY (rho_r)
375
376 natom = SIZE(charges, 1)
377
378 IF (ounit > 0) WRITE (ounit, "(/,T2,A)") "Hirshfeld charge iterations: Residuals ..."
379 !
380 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env, rho=rho)
381 CALL qs_rho_get(rho, rho_r=rho_r, rho_r_valid=rho_r_valid)
382 CALL pw_env_get(pw_env=pw_env, auxbas_pw_pool=auxbas_pw_pool)
383 CALL auxbas_pw_pool%create_pw(rhonorm)
384 !
385 DO iloop = 1, maxloop
386
387 ! normalization function on grid
388 CALL calculate_hirshfeld_normalization(qs_env, hirshfeld_env)
389 ! check normalization
390 tnfun = pw_integrate_function(hirshfeld_env%fnorm)
391 tnfun = abs(tnfun - sum(hirshfeld_env%charges))
392 ! loop over spins
393 DO is = 1, SIZE(rho_r)
394 IF (rho_r_valid) THEN
395 CALL hfun_scale(rhonorm%array, rho_r(is)%array, &
396 hirshfeld_env%fnorm%array)
397 ELSE
398 cpabort("We need rho in real space")
399 END IF
400 CALL hirshfeld_integration(qs_env, hirshfeld_env, rhonorm, charges(:, is))
401 charges(:, is) = charges(:, is)*hirshfeld_env%charges(:)
402 END DO
403 ! residual
404 res = 0.0_dp
405 DO iat = 1, natom
406 res = res + (sum(charges(iat, :)) - hirshfeld_env%charges(iat))**2
407 END DO
408 res = sqrt(res/real(natom, kind=dp))
409 IF (ounit > 0) THEN
410 yesno = "NO "
411 IF (mod(iloop, 10) == 0) yesno = "YES"
412 WRITE (ounit, fmt="(F8.3)", advance=yesno) res
413 END IF
414 ! update
415 DO iat = 1, natom
416 hirshfeld_env%charges(iat) = sum(charges(iat, :))
417 END DO
418 IF (res < maxres) EXIT
419
420 END DO
421 !
422 CALL auxbas_pw_pool%give_back_pw(rhonorm)
423
424 END SUBROUTINE comp_hirshfeld_i_charges
425
426! **************************************************************************************************
427!> \brief ...
428!> \param qs_env ...
429!> \param hirshfeld_env ...
430! **************************************************************************************************
431 SUBROUTINE calculate_hirshfeld_normalization(qs_env, hirshfeld_env)
432
433 TYPE(qs_environment_type), POINTER :: qs_env
434 TYPE(hirshfeld_type), POINTER :: hirshfeld_env
435
436 CHARACTER(len=*), PARAMETER :: routinen = 'calculate_hirshfeld_normalization'
437
438 INTEGER :: atom_a, handle, iatom, iex, ikind, &
439 ithread, j, natom, npme, nthread, &
440 numexp, subpatch_pattern
441 INTEGER, DIMENSION(:), POINTER :: atom_list, cores
442 REAL(kind=dp) :: alpha, coef, eps_rho_rspace, radius
443 REAL(kind=dp), DIMENSION(3) :: ra
444 REAL(kind=dp), DIMENSION(:, :), POINTER :: pab
445 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
446 TYPE(cell_type), POINTER :: cell
447 TYPE(dft_control_type), POINTER :: dft_control
448 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
449 TYPE(pw_env_type), POINTER :: pw_env
450 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
451 TYPE(pw_r3d_rs_type), POINTER :: fnorm
452 TYPE(realspace_grid_desc_type), POINTER :: auxbas_rs_desc
453 TYPE(realspace_grid_type), POINTER :: rs_rho
454
455 CALL timeset(routinen, handle)
456
457 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, cell=cell, &
458 dft_control=dft_control, particle_set=particle_set, pw_env=pw_env)
459 CALL pw_env_get(pw_env, auxbas_rs_desc=auxbas_rs_desc, auxbas_rs_grid=rs_rho, &
460 auxbas_pw_pool=auxbas_pw_pool)
461 ! be careful in parallel nsmax is chosen with multigrid in mind!
462 CALL rs_grid_zero(rs_rho)
463
464 eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
465 ALLOCATE (pab(1, 1))
466 nthread = 1
467 ithread = 0
468
469 DO ikind = 1, SIZE(atomic_kind_set)
470 numexp = hirshfeld_env%kind_shape_fn(ikind)%numexp
471 IF (numexp <= 0) cycle
472 CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
473 ALLOCATE (cores(natom))
474
475 DO iex = 1, numexp
476 alpha = hirshfeld_env%kind_shape_fn(ikind)%zet(iex)
477 coef = hirshfeld_env%kind_shape_fn(ikind)%coef(iex)
478 npme = 0
479 cores = 0
480 DO iatom = 1, natom
481 atom_a = atom_list(iatom)
482 ra(:) = pbc(particle_set(atom_a)%r, cell)
483 IF (rs_rho%desc%parallel .AND. .NOT. rs_rho%desc%distributed) THEN
484 ! replicated realspace grid, split the atoms up between procs
485 IF (modulo(iatom, rs_rho%desc%group_size) == rs_rho%desc%my_pos) THEN
486 npme = npme + 1
487 cores(npme) = iatom
488 END IF
489 ELSE
490 npme = npme + 1
491 cores(npme) = iatom
492 END IF
493 END DO
494 DO j = 1, npme
495 iatom = cores(j)
496 atom_a = atom_list(iatom)
497 pab(1, 1) = hirshfeld_env%charges(atom_a)*coef
498 ra(:) = pbc(particle_set(atom_a)%r, cell)
499 subpatch_pattern = 0
500 radius = exp_radius_very_extended(la_min=0, la_max=0, lb_min=0, lb_max=0, &
501 ra=ra, rb=ra, rp=ra, zetp=alpha, eps=eps_rho_rspace, &
502 pab=pab, o1=0, o2=0, & ! without map_consistent
503 prefactor=1.0_dp, cutoff=0.0_dp)
504
505 ! la_max==0 so set lmax_global to 0
506 CALL collocate_pgf_product(0, alpha, 0, 0, 0.0_dp, 0, ra, &
507 [0.0_dp, 0.0_dp, 0.0_dp], 1.0_dp, pab, 0, 0, rs_rho, &
508 radius=radius, ga_gb_function=grid_func_ab, &
509 use_subpatch=.true., subpatch_pattern=subpatch_pattern)
510 END DO
511 END DO
512
513 DEALLOCATE (cores)
514 END DO
515 DEALLOCATE (pab)
516
517 NULLIFY (fnorm)
518 CALL get_hirshfeld_info(hirshfeld_env, fnorm=fnorm)
519 IF (ASSOCIATED(fnorm)) THEN
520 CALL fnorm%release()
521 DEALLOCATE (fnorm)
522 END IF
523 ALLOCATE (fnorm)
524 CALL auxbas_pw_pool%create_pw(fnorm)
525 CALL set_hirshfeld_info(hirshfeld_env, fnorm=fnorm)
526
527 CALL transfer_rs2pw(rs_rho, fnorm)
528
529 CALL timestop(handle)
530
531 END SUBROUTINE calculate_hirshfeld_normalization
532
533! **************************************************************************************************
534!> \brief ...
535!> \param qs_env ...
536!> \param hirshfeld_env ...
537!> \param rfun ...
538!> \param fval ...
539!> \param fderiv ...
540! **************************************************************************************************
541 SUBROUTINE hirshfeld_integration(qs_env, hirshfeld_env, rfun, fval, fderiv)
542
543 TYPE(qs_environment_type), POINTER :: qs_env
544 TYPE(hirshfeld_type), POINTER :: hirshfeld_env
545 TYPE(pw_r3d_rs_type) :: rfun
546 REAL(kind=dp), DIMENSION(:), INTENT(inout) :: fval
547 REAL(kind=dp), DIMENSION(:, :), INTENT(inout), &
548 OPTIONAL :: fderiv
549
550 CHARACTER(len=*), PARAMETER :: routinen = 'hirshfeld_integration'
551
552 INTEGER :: atom_a, handle, iatom, iex, ikind, &
553 ithread, j, natom, npme, nthread, &
554 numexp
555 INTEGER, ALLOCATABLE, DIMENSION(:) :: cores
556 INTEGER, DIMENSION(:), POINTER :: atom_list
557 LOGICAL :: do_force
558 REAL(kind=dp) :: alpha, coef, dvol, eps_rho_rspace, radius
559 REAL(kind=dp), DIMENSION(3) :: force_a, force_b, ra
560 REAL(kind=dp), DIMENSION(:, :), POINTER :: hab, pab
561 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
562 TYPE(cell_type), POINTER :: cell
563 TYPE(dft_control_type), POINTER :: dft_control
564 TYPE(mp_para_env_type), POINTER :: para_env
565 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
566 TYPE(pw_env_type), POINTER :: pw_env
567 TYPE(realspace_grid_desc_type), POINTER :: auxbas_rs_desc
568 TYPE(realspace_grid_type), POINTER :: rs_v
569
570 CALL timeset(routinen, handle)
571
572 do_force = PRESENT(fderiv)
573 fval = 0.0_dp
574 dvol = rfun%pw_grid%dvol
575
576 NULLIFY (pw_env, auxbas_rs_desc)
577 CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
578 CALL pw_env_get(pw_env=pw_env, auxbas_rs_desc=auxbas_rs_desc, &
579 auxbas_rs_grid=rs_v)
580 CALL transfer_pw2rs(rs_v, rfun)
581
582 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, cell=cell, &
583 dft_control=dft_control, particle_set=particle_set)
584 eps_rho_rspace = dft_control%qs_control%eps_rho_rspace
585
586 nthread = 1
587 ithread = 0
588 ALLOCATE (hab(1, 1), pab(1, 1))
589
590 DO ikind = 1, SIZE(atomic_kind_set)
591 numexp = hirshfeld_env%kind_shape_fn(ikind)%numexp
592 IF (numexp <= 0) cycle
593 CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom, atom_list=atom_list)
594 ALLOCATE (cores(natom))
595
596 DO iex = 1, numexp
597 alpha = hirshfeld_env%kind_shape_fn(ikind)%zet(iex)
598 coef = hirshfeld_env%kind_shape_fn(ikind)%coef(iex)
599 npme = 0
600 cores = 0
601 DO iatom = 1, natom
602 atom_a = atom_list(iatom)
603 ra(:) = pbc(particle_set(atom_a)%r, cell)
604 IF (rs_v%desc%parallel .AND. .NOT. rs_v%desc%distributed) THEN
605 ! replicated realspace grid, split the atoms up between procs
606 IF (modulo(iatom, rs_v%desc%group_size) == rs_v%desc%my_pos) THEN
607 npme = npme + 1
608 cores(npme) = iatom
609 END IF
610 ELSE
611 npme = npme + 1
612 cores(npme) = iatom
613 END IF
614 END DO
615
616 DO j = 1, npme
617 iatom = cores(j)
618 atom_a = atom_list(iatom)
619 ra(:) = pbc(particle_set(atom_a)%r, cell)
620 pab(1, 1) = coef
621 hab(1, 1) = 0.0_dp
622 force_a(:) = 0.0_dp
623 force_b(:) = 0.0_dp
624
625 radius = exp_radius_very_extended(la_min=0, la_max=0, lb_min=0, lb_max=0, &
626 ra=ra, rb=ra, rp=ra, &
627 zetp=alpha, eps=eps_rho_rspace, &
628 pab=pab, o1=0, o2=0, & ! without map_consistent
629 prefactor=1.0_dp, cutoff=1.0_dp)
630
631 CALL integrate_pgf_product(0, alpha, 0, &
632 0, 0.0_dp, 0, ra, [0.0_dp, 0.0_dp, 0.0_dp], &
633 rs_v, hab, pab=pab, o1=0, o2=0, &
634 radius=radius, calculate_forces=do_force, &
635 force_a=force_a, force_b=force_b, use_virial=.false., &
636 use_subpatch=.true., subpatch_pattern=0)
637 fval(atom_a) = fval(atom_a) + hab(1, 1)*dvol*coef
638 IF (do_force) THEN
639 fderiv(:, atom_a) = fderiv(:, atom_a) + force_a(:)*dvol
640 END IF
641 END DO
642
643 END DO
644 DEALLOCATE (cores)
645
646 END DO
647
648 DEALLOCATE (hab, pab)
649
650 CALL get_qs_env(qs_env=qs_env, para_env=para_env)
651 CALL para_env%sum(fval)
652
653 CALL timestop(handle)
654
655 END SUBROUTINE hirshfeld_integration
656
657END MODULE hirshfeld_methods
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
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, optbasis, 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:1222
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:27
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:276
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:116
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.
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
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
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
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, mimic, 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_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, 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, matrix_vhxc, 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, xcint_weights, 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, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_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, harris_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, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, 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_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, hund_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, proj_shell_charge, lr_atom, do_mtlr, u_j_loop, ao_coef, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, 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...
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...
subroutine, public transfer_pw2rs(rs, pw)
...
subroutine, public transfer_rs2pw(rs, pw)
...
subroutine, public rs_grid_zero(rs)
Initialize grid to zero.
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
contains arbitrary information which need to be stored
quantities needed for a Hirshfeld based partitioning of real space
stores all the informations relevant to an mpi environment
contained for different pw related things
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Provides all information about a quickstep kind.
keeps the density in various representations, keeping track of which ones are valid.