Line data Source code
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 : MODULE qs_rho0_methods
10 :
11 : USE ao_util, ONLY: exp_radius,&
12 : gaussint_sph,&
13 : trace_r_AxB
14 : USE atomic_kind_types, ONLY: atomic_kind_type,&
15 : get_atomic_kind,&
16 : get_atomic_kind_set
17 : USE basis_set_types, ONLY: get_gto_basis_set,&
18 : gto_basis_set_type
19 : USE cp_control_types, ONLY: gapw_control_type
20 : USE cp_log_handling, ONLY: cp_get_default_logger,&
21 : cp_logger_type
22 : USE cp_output_handling, ONLY: cp_print_key_finished_output,&
23 : cp_print_key_unit_nr
24 : USE input_section_types, ONLY: section_vals_get_subs_vals,&
25 : section_vals_type,&
26 : section_vals_val_get
27 : USE kinds, ONLY: default_string_length,&
28 : dp
29 : USE mathconstants, ONLY: fourpi
30 : USE memory_utilities, ONLY: reallocate
31 : USE orbital_pointers, ONLY: indco,&
32 : indso,&
33 : nco,&
34 : ncoset,&
35 : nso,&
36 : nsoset
37 : USE orbital_transformation_matrices, ONLY: orbtramat
38 : USE qs_environment_types, ONLY: get_qs_env,&
39 : qs_environment_type
40 : USE qs_grid_atom, ONLY: grid_atom_type
41 : USE qs_harmonics_atom, ONLY: get_none0_cg_list,&
42 : harmonics_atom_type
43 : USE qs_kind_types, ONLY: get_qs_kind,&
44 : qs_kind_type,&
45 : set_qs_kind
46 : USE qs_local_rho_types, ONLY: allocate_rhoz,&
47 : calculate_rhoz,&
48 : local_rho_type,&
49 : rhoz_type,&
50 : set_local_rho
51 : USE qs_oce_methods, ONLY: prj_scatter
52 : USE qs_rho0_types, ONLY: &
53 : allocate_multipoles, allocate_rho0_atom, allocate_rho0_atom_rad, allocate_rho0_mpole, &
54 : calculate_g0, get_rho0_mpole, initialize_mpole_rho, mpole_gau_overlap, mpole_rho_atom, &
55 : rho0_atom_type, rho0_mpole_type, write_rho0_info
56 : USE qs_rho_atom_types, ONLY: get_rho_atom,&
57 : rho_atom_coeff,&
58 : rho_atom_type
59 : #include "./base/base_uses.f90"
60 :
61 : IMPLICIT NONE
62 :
63 : PRIVATE
64 :
65 : ! Global parameters (only in this module)
66 :
67 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_rho0_methods'
68 :
69 : ! Public subroutines
70 :
71 : PUBLIC :: calculate_rho0_atom, init_rho0
72 :
73 : CONTAINS
74 :
75 : ! **************************************************************************************************
76 : !> \brief ...
77 : !> \param mp_gau ...
78 : !> \param basis_1c ...
79 : !> \param harmonics ...
80 : !> \param nchannels ...
81 : !> \param nsotot ...
82 : ! **************************************************************************************************
83 3400 : SUBROUTINE calculate_mpole_gau(mp_gau, basis_1c, harmonics, nchannels, nsotot)
84 :
85 : TYPE(mpole_gau_overlap) :: mp_gau
86 : TYPE(gto_basis_set_type), POINTER :: basis_1c
87 : TYPE(harmonics_atom_type), POINTER :: harmonics
88 : INTEGER, INTENT(IN) :: nchannels, nsotot
89 :
90 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_mpole_gau'
91 :
92 : INTEGER :: handle, icg, ig1, ig2, ipgf1, ipgf2, iset1, iset2, iso, iso1, iso2, l, l1, l2, &
93 : llmax, m1, m2, max_iso_not0_local, max_s_harm, maxl, maxso, n1, n2, nset
94 : INTEGER, ALLOCATABLE, DIMENSION(:) :: cg_n_list
95 : INTEGER, ALLOCATABLE, DIMENSION(:, :, :) :: cg_list
96 3400 : INTEGER, DIMENSION(:), POINTER :: lmax, lmin, npgf
97 : REAL(KIND=dp) :: zet1, zet2
98 3400 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: zet
99 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: my_CG
100 :
101 3400 : CALL timeset(routineN, handle)
102 :
103 3400 : NULLIFY (lmax, lmin, npgf, my_CG, zet)
104 :
105 3400 : CALL reallocate(mp_gau%Qlm_gg, 1, nsotot, 1, nsotot, 1, nchannels)
106 :
107 : CALL get_gto_basis_set(gto_basis_set=basis_1c, &
108 : lmax=lmax, lmin=lmin, maxso=maxso, &
109 3400 : npgf=npgf, nset=nset, zet=zet, maxl=maxl)
110 :
111 3400 : max_s_harm = harmonics%max_s_harm
112 3400 : llmax = harmonics%llmax
113 :
114 20400 : ALLOCATE (cg_list(2, nsoset(maxl)**2, max_s_harm), cg_n_list(max_s_harm))
115 :
116 3400 : my_CG => harmonics%my_CG
117 :
118 3400 : m1 = 0
119 12782 : DO iset1 = 1, nset
120 : m2 = 0
121 43016 : DO iset2 = 1, nset
122 :
123 : CALL get_none0_cg_list(my_CG, lmin(iset1), lmax(iset1), lmin(iset2), lmax(iset2), &
124 33634 : max_s_harm, llmax, cg_list, cg_n_list, max_iso_not0_local)
125 :
126 33634 : n1 = nsoset(lmax(iset1))
127 114914 : DO ipgf1 = 1, npgf(iset1)
128 81280 : zet1 = zet(ipgf1, iset1)
129 :
130 81280 : n2 = nsoset(lmax(iset2))
131 334186 : DO ipgf2 = 1, npgf(iset2)
132 219272 : zet2 = zet(ipgf2, iset2)
133 :
134 1588244 : DO iso = 1, MIN(nchannels, max_iso_not0_local)
135 1287692 : l = indso(1, iso)
136 3709522 : DO icg = 1, cg_n_list(iso)
137 2202558 : iso1 = cg_list(1, icg, iso)
138 2202558 : iso2 = cg_list(2, icg, iso)
139 :
140 2202558 : l1 = indso(1, iso1)
141 2202558 : l2 = indso(1, iso2)
142 2202558 : ig1 = iso1 + n1*(ipgf1 - 1) + m1
143 2202558 : ig2 = iso2 + n2*(ipgf2 - 1) + m2
144 :
145 : mp_gau%Qlm_gg(ig1, ig2, iso) = fourpi/(2._dp*l + 1._dp)* &
146 3490250 : my_CG(iso1, iso2, iso)*gaussint_sph(zet1 + zet2, l + l1 + l2)
147 : END DO ! icg
148 : END DO ! iso
149 :
150 : END DO ! ipgf2
151 : END DO ! ipgf1
152 76650 : m2 = m2 + maxso
153 : END DO ! iset2
154 12782 : m1 = m1 + maxso
155 : END DO ! iset1
156 :
157 3400 : DEALLOCATE (cg_list, cg_n_list)
158 :
159 3400 : CALL timestop(handle)
160 6800 : END SUBROUTINE calculate_mpole_gau
161 :
162 : ! **************************************************************************************************
163 : !> \brief ...
164 : !> \param gapw_control ...
165 : !> \param rho_atom_set ...
166 : !> \param rho0_atom_set ...
167 : !> \param rho0_mp ...
168 : !> \param a_list ...
169 : !> \param natom ...
170 : !> \param ikind ...
171 : !> \param qs_kind ...
172 : !> \param rho0_h_tot ...
173 : ! **************************************************************************************************
174 32878 : SUBROUTINE calculate_rho0_atom(gapw_control, rho_atom_set, rho0_atom_set, &
175 32878 : rho0_mp, a_list, natom, ikind, qs_kind, rho0_h_tot)
176 :
177 : TYPE(gapw_control_type), POINTER :: gapw_control
178 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho_atom_set
179 : TYPE(rho0_atom_type), DIMENSION(:), POINTER :: rho0_atom_set
180 : TYPE(rho0_mpole_type), POINTER :: rho0_mp
181 : INTEGER, DIMENSION(:), INTENT(IN) :: a_list
182 : INTEGER, INTENT(IN) :: natom, ikind
183 : TYPE(qs_kind_type), INTENT(IN) :: qs_kind
184 : REAL(KIND=dp), INTENT(INOUT) :: rho0_h_tot
185 :
186 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_rho0_atom'
187 :
188 : INTEGER :: handle, iat, iatom, ic, ico, ir, is, &
189 : iso, ispin, l, lmax0, lshell, lx, ly, &
190 : lz, nr, nsotot, nspins
191 : LOGICAL :: paw_atom
192 : REAL(KIND=dp) :: sum1
193 32878 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: cpc_ah, cpc_as
194 32878 : REAL(KIND=dp), DIMENSION(:), POINTER :: norm_g0l_h
195 32878 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: g0_h, vg0_h
196 : TYPE(grid_atom_type), POINTER :: g_atom
197 : TYPE(harmonics_atom_type), POINTER :: harmonics
198 : TYPE(mpole_gau_overlap), POINTER :: mpole_gau
199 : TYPE(mpole_rho_atom), POINTER :: mpole_rho
200 32878 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: cpc_h, cpc_s
201 : TYPE(rho_atom_type), POINTER :: rho_atom
202 :
203 32878 : CALL timeset(routineN, handle)
204 :
205 32878 : NULLIFY (mpole_gau)
206 32878 : NULLIFY (mpole_rho)
207 32878 : NULLIFY (g0_h, vg0_h, g_atom)
208 32878 : NULLIFY (norm_g0l_h, harmonics)
209 :
210 : CALL get_rho0_mpole(rho0_mpole=rho0_mp, ikind=ikind, &
211 : l0_ikind=lmax0, mp_gau_ikind=mpole_gau, &
212 : g0_h=g0_h, &
213 : vg0_h=vg0_h, &
214 32878 : norm_g0l_h=norm_g0l_h)
215 :
216 32878 : CALL get_qs_kind(qs_kind, harmonics=harmonics, paw_atom=paw_atom, grid_atom=g_atom)
217 :
218 32878 : nr = g_atom%nr
219 :
220 : ! Set density coefficient to zero before the calculation
221 87278 : DO iat = 1, natom
222 54400 : iatom = a_list(iat)
223 21212168 : rho0_atom_set(iatom)%rho0_rad_h%r_coef = 0.0_dp
224 437888 : rho0_mp%mp_rho(iatom)%Qlm_tot = 0.0_dp
225 54400 : rho0_mp%mp_rho(iatom)%Qlm_tot(1) = rho0_mp%mp_rho(iatom)%Qlm_z
226 163200 : rho0_mp%mp_rho(iatom)%Q0 = 0.0_dp
227 515878 : rho0_mp%mp_rho(iatom)%Qlm_car = 0.0_dp
228 : END DO
229 :
230 32878 : IF (.NOT. (.NOT. paw_atom .AND. gapw_control%nopaw_as_gpw)) THEN
231 81168 : DO iat = 1, natom
232 49836 : iatom = a_list(iat)
233 49836 : mpole_rho => rho0_mp%mp_rho(iatom)
234 49836 : rho_atom => rho_atom_set(iatom)
235 :
236 49836 : IF (paw_atom) THEN
237 49836 : NULLIFY (cpc_h, cpc_s)
238 49836 : CALL get_rho_atom(rho_atom=rho_atom, cpc_h=cpc_h, cpc_s=cpc_s)
239 49836 : nspins = SIZE(cpc_h)
240 49836 : nsotot = SIZE(mpole_gau%Qlm_gg, 1)
241 249180 : ALLOCATE (cpc_ah(nsotot, nsotot, nspins))
242 161759706 : cpc_ah = 0._dp
243 199344 : ALLOCATE (cpc_as(nsotot, nsotot, nspins))
244 161759706 : cpc_as = 0._dp
245 107806 : DO ispin = 1, nspins
246 57970 : CALL prj_scatter(cpc_h(ispin)%r_coef, cpc_ah(:, :, ispin), qs_kind)
247 107806 : CALL prj_scatter(cpc_s(ispin)%r_coef, cpc_as(:, :, ispin), qs_kind)
248 : END DO
249 : END IF
250 :
251 : ! Total charge (hard-soft) at atom
252 49836 : IF (paw_atom) THEN
253 107806 : DO ispin = 1, nspins
254 : mpole_rho%Q0(ispin) = (trace_r_AxB(mpole_gau%Qlm_gg(:, :, 1), nsotot, &
255 : cpc_ah(:, :, ispin), nsotot, nsotot, nsotot) &
256 : - trace_r_AxB(mpole_gau%Qlm_gg(:, :, 1), nsotot, &
257 107806 : cpc_as(:, :, ispin), nsotot, nsotot, nsotot))/SQRT(fourpi)
258 : END DO
259 : END IF
260 : ! Multipoles of local charge distribution
261 428760 : DO iso = 1, nsoset(lmax0)
262 378924 : l = indso(1, iso)
263 378924 : IF (paw_atom) THEN
264 378924 : mpole_rho%Qlm_h(iso) = 0.0_dp
265 378924 : mpole_rho%Qlm_s(iso) = 0.0_dp
266 :
267 817278 : DO ispin = 1, nspins
268 : mpole_rho%Qlm_h(iso) = mpole_rho%Qlm_h(iso) + &
269 : trace_r_AxB(mpole_gau%Qlm_gg(:, :, iso), nsotot, &
270 438354 : cpc_ah(:, :, ispin), nsotot, nsotot, nsotot)
271 : mpole_rho%Qlm_s(iso) = mpole_rho%Qlm_s(iso) + &
272 : trace_r_AxB(mpole_gau%Qlm_gg(:, :, iso), nsotot, &
273 817278 : cpc_as(:, :, ispin), nsotot, nsotot, nsotot)
274 : END DO ! ispin
275 :
276 : mpole_rho%Qlm_tot(iso) = mpole_rho%Qlm_tot(iso) + &
277 378924 : mpole_rho%Qlm_h(iso) - mpole_rho%Qlm_s(iso)
278 : END IF
279 :
280 : rho0_atom_set(iatom)%rho0_rad_h%r_coef(1:nr, iso) = &
281 41471564 : g0_h(1:nr, l)*mpole_rho%Qlm_tot(iso)
282 : rho0_atom_set(iatom)%vrho0_rad_h%r_coef(1:nr, iso) = &
283 41471564 : vg0_h(1:nr, l)*mpole_rho%Qlm_tot(iso)
284 :
285 378924 : sum1 = 0.0_dp
286 20925244 : DO ir = 1, nr
287 : sum1 = sum1 + g_atom%wr(ir)* &
288 20925244 : rho0_atom_set(iatom)%rho0_rad_h%r_coef(ir, iso)
289 : END DO
290 428760 : rho0_h_tot = rho0_h_tot + sum1*harmonics%slm_int(iso)
291 : END DO ! iso
292 82714 : IF (paw_atom) THEN
293 49836 : DEALLOCATE (cpc_ah, cpc_as)
294 : END IF
295 : END DO ! iat
296 : END IF
297 :
298 : ! Transform the coefficinets from spherical to Cartesian
299 32878 : IF (.NOT. paw_atom .AND. gapw_control%nopaw_as_gpw) THEN
300 6110 : DO iat = 1, natom
301 4564 : iatom = a_list(iat)
302 4564 : mpole_rho => rho0_mp%mp_rho(iatom)
303 :
304 10674 : DO lshell = 0, lmax0
305 13692 : DO ic = 1, nco(lshell)
306 4564 : ico = ic + ncoset(lshell - 1)
307 9128 : mpole_rho%Qlm_car(ico) = 0.0_dp
308 : END DO
309 : END DO
310 : END DO
311 : ELSE
312 81168 : DO iat = 1, natom
313 49836 : iatom = a_list(iat)
314 49836 : mpole_rho => rho0_mp%mp_rho(iatom)
315 212140 : DO lshell = 0, lmax0
316 604844 : DO ic = 1, nco(lshell)
317 424036 : ico = ic + ncoset(lshell - 1)
318 424036 : mpole_rho%Qlm_car(ico) = 0.0_dp
319 424036 : lx = indco(1, ico)
320 424036 : ly = indco(2, ico)
321 424036 : lz = indco(3, ico)
322 2281284 : DO is = 1, nso(lshell)
323 1726276 : iso = is + nsoset(lshell - 1)
324 : mpole_rho%Qlm_car(ico) = mpole_rho%Qlm_car(ico) + &
325 : norm_g0l_h(lshell)* &
326 : orbtramat(lshell)%slm(is, ic)* &
327 2150312 : mpole_rho%Qlm_tot(iso)
328 :
329 : END DO
330 : END DO
331 : END DO ! lshell
332 : END DO ! iat
333 : END IF
334 : !MI Get rid of full gapw
335 :
336 32878 : CALL timestop(handle)
337 :
338 65756 : END SUBROUTINE calculate_rho0_atom
339 :
340 : ! **************************************************************************************************
341 : !> \brief ...
342 : !> \param local_rho_set ...
343 : !> \param qs_env ...
344 : !> \param gapw_control ...
345 : !> \param zcore ...
346 : ! **************************************************************************************************
347 3568 : SUBROUTINE init_rho0(local_rho_set, qs_env, gapw_control, zcore)
348 :
349 : TYPE(local_rho_type), POINTER :: local_rho_set
350 : TYPE(qs_environment_type), POINTER :: qs_env
351 : TYPE(gapw_control_type), POINTER :: gapw_control
352 : REAL(KIND=dp), INTENT(IN), OPTIONAL :: zcore
353 :
354 : CHARACTER(len=*), PARAMETER :: routineN = 'init_rho0'
355 :
356 : CHARACTER(LEN=default_string_length) :: unit_str
357 : INTEGER :: handle, iat, iatom, ikind, l, l_rho1_max, laddg, lmaxg, maxl, maxnset, maxso, &
358 : nat, natom, nchan_c, nchan_s, nkind, nr, nset, nsotot, output_unit
359 1784 : INTEGER, DIMENSION(:), POINTER :: atom_list
360 : LOGICAL :: paw_atom
361 : REAL(KIND=dp) :: alpha_core, eps_Vrho0, max_rpgf0_s, &
362 : radius, rc_min, rc_orb, &
363 : total_rho_core_rspace, zeff
364 1784 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
365 : TYPE(cp_logger_type), POINTER :: logger
366 : TYPE(grid_atom_type), POINTER :: grid_atom
367 : TYPE(gto_basis_set_type), POINTER :: basis_1c
368 : TYPE(harmonics_atom_type), POINTER :: harmonics
369 1784 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
370 1784 : TYPE(rho0_atom_type), DIMENSION(:), POINTER :: rho0_atom_set
371 : TYPE(rho0_mpole_type), POINTER :: rho0_mpole
372 1784 : TYPE(rhoz_type), DIMENSION(:), POINTER :: rhoz_set
373 : TYPE(section_vals_type), POINTER :: dft_section
374 :
375 1784 : CALL timeset(routineN, handle)
376 :
377 1784 : NULLIFY (logger)
378 1784 : logger => cp_get_default_logger()
379 :
380 1784 : NULLIFY (qs_kind_set)
381 1784 : NULLIFY (atomic_kind_set)
382 1784 : NULLIFY (harmonics)
383 1784 : NULLIFY (basis_1c)
384 1784 : NULLIFY (rho0_mpole)
385 1784 : NULLIFY (rho0_atom_set)
386 1784 : NULLIFY (rhoz_set)
387 :
388 : CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, &
389 1784 : atomic_kind_set=atomic_kind_set)
390 :
391 1784 : nkind = SIZE(atomic_kind_set)
392 1784 : eps_Vrho0 = gapw_control%eps_Vrho0
393 :
394 : ! Initialize rhoz total to zero
395 : ! in gapw rhoz is calculated on local the lebedev grids
396 1784 : total_rho_core_rspace = 0.0_dp
397 :
398 1784 : CALL get_atomic_kind_set(atomic_kind_set, natom=natom)
399 :
400 : ! Initialize the multipole and the compensation charge type
401 1784 : CALL allocate_rho0_mpole(rho0_mpole)
402 1784 : CALL allocate_rho0_atom(rho0_atom_set, natom)
403 :
404 : ! Allocate the multipole set
405 1784 : CALL allocate_multipoles(rho0_mpole%mp_rho, natom, rho0_mpole%mp_gau, nkind)
406 :
407 : ! Allocate the core density on the radial grid for each kind: rhoz_set
408 1784 : CALL allocate_rhoz(rhoz_set, nkind)
409 :
410 : ! For each kind, determine the max l for the compensation charge density
411 1784 : lmaxg = gapw_control%lmax_rho0
412 1784 : laddg = gapw_control%ladd_rho0
413 :
414 1784 : CALL reallocate(rho0_mpole%lmax0_kind, 1, nkind)
415 :
416 1784 : rho0_mpole%lmax_0 = 0
417 1784 : rc_min = 100.0_dp
418 1784 : maxnset = 0
419 5526 : DO ikind = 1, nkind
420 3742 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=nat)
421 : CALL get_qs_kind(qs_kind_set(ikind), &
422 : ngrid_rad=nr, &
423 : grid_atom=grid_atom, &
424 : harmonics=harmonics, &
425 : paw_atom=paw_atom, &
426 : hard0_radius=rc_orb, &
427 : zeff=zeff, &
428 3742 : alpha_core_charge=alpha_core)
429 : CALL get_qs_kind(qs_kind_set(ikind), &
430 3742 : basis_set=basis_1c, basis_type="GAPW_1C")
431 :
432 : ! Set charge distribution of ionic cores to zero when computing the response-density
433 3742 : IF (PRESENT(zcore)) zeff = zcore
434 :
435 : CALL get_gto_basis_set(gto_basis_set=basis_1c, &
436 : maxl=maxl, &
437 3742 : maxso=maxso, nset=nset)
438 :
439 3742 : maxnset = MAX(maxnset, nset)
440 :
441 3742 : l_rho1_max = indso(1, harmonics%max_iso_not0)
442 3742 : IF (paw_atom) THEN
443 3400 : rho0_mpole%lmax0_kind(ikind) = MIN(2*maxl, l_rho1_max, maxl + laddg, lmaxg)
444 : ELSE
445 342 : rho0_mpole%lmax0_kind(ikind) = 0
446 : END IF
447 :
448 3742 : CALL set_qs_kind(qs_kind_set(ikind), lmax_rho0=rho0_mpole%lmax0_kind(ikind))
449 :
450 3742 : IF (gapw_control%lrho1_eq_lrho0) harmonics%max_iso_not0 = &
451 0 : nsoset(rho0_mpole%lmax0_kind(ikind))
452 :
453 3742 : rho0_mpole%lmax_0 = MAX(rho0_mpole%lmax_0, rho0_mpole%lmax0_kind(ikind))
454 3742 : rc_min = MIN(rc_min, rc_orb)
455 :
456 3742 : nchan_s = nsoset(rho0_mpole%lmax0_kind(ikind))
457 3742 : nchan_c = ncoset(rho0_mpole%lmax0_kind(ikind))
458 3742 : nsotot = maxso*nset
459 :
460 9880 : DO iat = 1, nat
461 6138 : iatom = atom_list(iat)
462 : ! Allocate the multipole for rho1_h rho1_s and rho_z
463 6138 : CALL initialize_mpole_rho(rho0_mpole%mp_rho(iatom), nchan_s, nchan_c, zeff)
464 : ! Allocate the radial part of rho0_h and rho0_s
465 : ! This is calculated on the radial grid centered at the atomic position
466 9880 : CALL allocate_rho0_atom_rad(rho0_atom_set(iatom), nr, nchan_s)
467 : END DO
468 :
469 3742 : IF (paw_atom) THEN
470 : ! Calculate multipoles given by the product of 2 primitives Qlm_gg
471 : CALL calculate_mpole_gau(rho0_mpole%mp_gau(ikind), &
472 3400 : basis_1c, harmonics, nchan_s, nsotot)
473 : END IF
474 :
475 : ! Calculate the core density rhoz
476 : ! exp(-alpha_c**2 r**2)Z(alpha_c**2/pi)**(3/2)
477 : ! on the logarithmic radial grid
478 : ! WARNING: alpha_core_charge = alpha_c**2
479 : CALL calculate_rhoz(rhoz_set(ikind), grid_atom, alpha_core, zeff, &
480 13010 : nat, total_rho_core_rspace, harmonics)
481 : END DO ! ikind
482 1784 : total_rho_core_rspace = -total_rho_core_rspace
483 :
484 1784 : IF (gapw_control%alpha0_hard_from_input) THEN
485 : ! The exponent for the compensation charge rho0_hard is read from input
486 104 : rho0_mpole%zet0_h = gapw_control%alpha0_hard
487 : ELSE
488 : ! Calculate the exponent for the compensation charge rho0_hard
489 1680 : rho0_mpole%zet0_h = 0.1_dp
490 155030 : DO
491 156710 : radius = exp_radius(rho0_mpole%lmax_0, rho0_mpole%zet0_h, eps_Vrho0, 1.0_dp)
492 156710 : IF (radius <= rc_min) EXIT
493 155030 : rho0_mpole%zet0_h = rho0_mpole%zet0_h + 0.1_dp
494 : END DO
495 :
496 : END IF
497 :
498 : ! Allocate and calculate the normalization factors for g0_lm_h and g0_lm_s
499 1784 : CALL reallocate(rho0_mpole%norm_g0l_h, 0, rho0_mpole%lmax_0)
500 7148 : DO l = 0, rho0_mpole%lmax_0
501 : rho0_mpole%norm_g0l_h(l) = (2._dp*l + 1._dp)/ &
502 7148 : (fourpi*gaussint_sph(rho0_mpole%zet0_h, 2*l))
503 : END DO
504 :
505 : ! Allocate and Initialize the g0 gaussians used to build the compensation density
506 : ! and calculate the interaction radii
507 1784 : max_rpgf0_s = 0.0_dp
508 5526 : DO ikind = 1, nkind
509 3742 : CALL get_qs_kind(qs_kind_set(ikind), grid_atom=grid_atom)
510 3742 : CALL calculate_g0(rho0_mpole, grid_atom, ikind)
511 5526 : CALL interaction_radii_g0(rho0_mpole, ikind, eps_Vrho0, max_rpgf0_s)
512 : END DO
513 1784 : rho0_mpole%max_rpgf0_s = max_rpgf0_s
514 :
515 1784 : CALL set_local_rho(local_rho_set, rho0_atom_set=rho0_atom_set, rho0_mpole=rho0_mpole, rhoz_set=rhoz_set)
516 1784 : local_rho_set%rhoz_tot = total_rho_core_rspace
517 :
518 1784 : dft_section => section_vals_get_subs_vals(qs_env%input, "DFT")
519 : output_unit = cp_print_key_unit_nr(logger, dft_section, "PRINT%GAPW%RHO0_INFORMATION", &
520 1784 : extension=".Log")
521 1784 : CALL section_vals_val_get(dft_section, "PRINT%GAPW%RHO0_INFORMATION%UNIT", c_val=unit_str)
522 1784 : IF (output_unit > 0) THEN
523 1 : CALL write_rho0_info(rho0_mpole, unit_str, output_unit)
524 : END IF
525 : CALL cp_print_key_finished_output(output_unit, logger, dft_section, &
526 1784 : "PRINT%GAPW%RHO0_INFORMATION")
527 :
528 1784 : CALL timestop(handle)
529 :
530 1784 : END SUBROUTINE init_rho0
531 :
532 : ! **************************************************************************************************
533 : !> \brief ...
534 : !> \param rho0_mpole ...
535 : !> \param ik ...
536 : !> \param eps_Vrho0 ...
537 : !> \param max_rpgf0_s ...
538 : ! **************************************************************************************************
539 3742 : SUBROUTINE interaction_radii_g0(rho0_mpole, ik, eps_Vrho0, max_rpgf0_s)
540 :
541 : TYPE(rho0_mpole_type), POINTER :: rho0_mpole
542 : INTEGER, INTENT(IN) :: ik
543 : REAL(KIND=dp), INTENT(IN) :: eps_Vrho0
544 : REAL(KIND=dp), INTENT(INOUT) :: max_rpgf0_s
545 :
546 : INTEGER :: l, lmax
547 : REAL(KIND=dp) :: r_h, z0_h
548 3742 : REAL(KIND=dp), DIMENSION(:), POINTER :: ng0_h
549 :
550 : CALL get_rho0_mpole(rho0_mpole, ikind=ik, l0_ikind=lmax, &
551 3742 : zet0_h=z0_h, norm_g0l_h=ng0_h)
552 3742 : r_h = 0.0_dp
553 13992 : DO l = 0, lmax
554 13992 : r_h = MAX(r_h, exp_radius(l, z0_h, eps_Vrho0, ng0_h(l), rlow=r_h))
555 : END DO
556 :
557 3742 : rho0_mpole%mp_gau(ik)%rpgf0_h = r_h
558 3742 : rho0_mpole%mp_gau(ik)%rpgf0_s = r_h
559 3742 : max_rpgf0_s = MAX(max_rpgf0_s, r_h)
560 :
561 3742 : END SUBROUTINE interaction_radii_g0
562 :
563 : END MODULE qs_rho0_methods
|