(git:374b731)
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-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! **************************************************************************************************
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) &
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
655END 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, 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.
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, 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.
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...
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:55
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.