Line data Source code
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 : MODULE hartree_local_methods
9 : USE atomic_kind_types, ONLY: atomic_kind_type,&
10 : get_atomic_kind
11 : USE basis_set_types, ONLY: get_gto_basis_set,&
12 : gto_basis_set_type
13 : USE cell_types, ONLY: cell_type
14 : USE cp_control_types, ONLY: dft_control_type
15 : USE hartree_local_types, ONLY: allocate_ecoul_1center,&
16 : ecoul_1center_type,&
17 : hartree_local_type,&
18 : set_ecoul_1c
19 : USE kinds, ONLY: dp
20 : USE mathconstants, ONLY: fourpi,&
21 : pi
22 : USE message_passing, ONLY: mp_para_env_type
23 : USE orbital_pointers, ONLY: indso,&
24 : nsoset
25 : USE pw_env_types, ONLY: pw_env_get,&
26 : pw_env_type
27 : USE pw_poisson_types, ONLY: pw_poisson_periodic,&
28 : pw_poisson_type
29 : USE qs_charges_types, ONLY: qs_charges_type
30 : USE qs_cneo_methods, ONLY: Vh_1c_nuc_integrals,&
31 : calculate_rhoz_cneo
32 : USE qs_cneo_types, ONLY: cneo_potential_type,&
33 : rhoz_cneo_type
34 : USE qs_environment_types, ONLY: get_qs_env,&
35 : qs_environment_type
36 : USE qs_grid_atom, ONLY: grid_atom_type
37 : USE qs_harmonics_atom, ONLY: get_none0_cg_list,&
38 : harmonics_atom_type
39 : USE qs_kind_types, ONLY: get_qs_kind,&
40 : get_qs_kind_set,&
41 : qs_kind_type
42 : USE qs_local_rho_types, ONLY: get_local_rho,&
43 : local_rho_type,&
44 : rhoz_type
45 : USE qs_rho0_types, ONLY: get_rho0_mpole,&
46 : rho0_atom_type,&
47 : rho0_mpole_type
48 : USE qs_rho_atom_types, ONLY: get_rho_atom,&
49 : rho_atom_coeff,&
50 : rho_atom_type
51 : USE util, ONLY: get_limit
52 : USE virial_types, ONLY: virial_type
53 : #include "./base/base_uses.f90"
54 :
55 : IMPLICIT NONE
56 :
57 : PRIVATE
58 :
59 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'hartree_local_methods'
60 :
61 : ! Public Subroutine
62 :
63 : PUBLIC :: init_coulomb_local, calculate_Vh_1center, Vh_1c_gg_integrals
64 : PUBLIC :: gapw_background_potential
65 :
66 : CONTAINS
67 :
68 : ! **************************************************************************************************
69 : !> \brief ...
70 : !> \param hartree_local ...
71 : !> \param natom ...
72 : ! **************************************************************************************************
73 3300 : SUBROUTINE init_coulomb_local(hartree_local, natom)
74 :
75 : TYPE(hartree_local_type), POINTER :: hartree_local
76 : INTEGER, INTENT(IN) :: natom
77 :
78 : CHARACTER(len=*), PARAMETER :: routineN = 'init_coulomb_local'
79 :
80 : INTEGER :: handle
81 3300 : TYPE(ecoul_1center_type), DIMENSION(:), POINTER :: ecoul_1c
82 :
83 3300 : CALL timeset(routineN, handle)
84 :
85 3300 : NULLIFY (ecoul_1c)
86 : ! Allocate and Initialize 1-center Potentials and Integrals
87 3300 : CALL allocate_ecoul_1center(ecoul_1c, natom)
88 3300 : hartree_local%ecoul_1c => ecoul_1c
89 :
90 3300 : CALL timestop(handle)
91 :
92 3300 : END SUBROUTINE init_coulomb_local
93 :
94 : ! **************************************************************************************************
95 : !> \brief Calculates Hartree potential for hard and soft densities (including
96 : !> nuclear charge and compensation charges) using numerical integration
97 : !> \param vrad_h ...
98 : !> \param vrad_s ...
99 : !> \param rrad_h ...
100 : !> \param rrad_s ...
101 : !> \param rrad_0 ...
102 : !> \param rrad_z ...
103 : !> \param grid_atom ...
104 : !> \par History
105 : !> 05.2012 JGH refactoring
106 : !> \author ??
107 : ! **************************************************************************************************
108 15 : SUBROUTINE calculate_Vh_1center(vrad_h, vrad_s, rrad_h, rrad_s, rrad_0, rrad_z, grid_atom)
109 :
110 : REAL(dp), DIMENSION(:, :), INTENT(INOUT) :: vrad_h, vrad_s
111 : TYPE(rho_atom_coeff), DIMENSION(:), INTENT(IN) :: rrad_h, rrad_s
112 : REAL(dp), DIMENSION(:, :), INTENT(IN) :: rrad_0
113 : REAL(dp), DIMENSION(:), INTENT(IN) :: rrad_z
114 : TYPE(grid_atom_type), POINTER :: grid_atom
115 :
116 : CHARACTER(len=*), PARAMETER :: routineN = 'calculate_Vh_1center'
117 :
118 : INTEGER :: handle, ir, iso, ispin, l_ang, &
119 : max_s_harm, nchannels, nr, nspins
120 : REAL(dp) :: I1_down, I1_up, I2_down, I2_up, prefactor
121 15 : REAL(dp), ALLOCATABLE, DIMENSION(:) :: rho_1, rho_2
122 15 : REAL(dp), DIMENSION(:), POINTER :: wr
123 15 : REAL(dp), DIMENSION(:, :), POINTER :: oor2l, r2l
124 :
125 15 : CALL timeset(routineN, handle)
126 :
127 15 : nr = grid_atom%nr
128 15 : max_s_harm = SIZE(vrad_h, 2)
129 15 : nspins = SIZE(rrad_h, 1)
130 15 : nchannels = SIZE(rrad_0, 2)
131 :
132 15 : r2l => grid_atom%rad2l
133 15 : oor2l => grid_atom%oorad2l
134 15 : wr => grid_atom%wr
135 :
136 60 : ALLOCATE (rho_1(nr), rho_2(nr))
137 :
138 198 : DO iso = 1, max_s_harm
139 183 : rho_1(:) = 0.0_dp
140 183 : rho_2(:) = 0.0_dp
141 948 : IF (iso == 1) rho_1(:) = rrad_z(:)
142 6933 : IF (iso <= nchannels) rho_2(:) = rrad_0(:, iso)
143 549 : DO ispin = 1, nspins
144 18666 : rho_1(:) = rho_1(:) + rrad_h(ispin)%r_coef(:, iso)
145 18849 : rho_2(:) = rho_2(:) + rrad_s(ispin)%r_coef(:, iso)
146 : END DO
147 :
148 183 : l_ang = indso(1, iso)
149 183 : prefactor = fourpi/(2._dp*l_ang + 1._dp)
150 :
151 9333 : rho_1(:) = rho_1(:)*wr(:)
152 9333 : rho_2(:) = rho_2(:)*wr(:)
153 :
154 183 : I1_up = 0.0_dp
155 183 : I1_down = 0.0_dp
156 183 : I2_up = 0.0_dp
157 183 : I2_down = 0.0_dp
158 :
159 183 : I1_up = r2l(nr, l_ang)*rho_1(nr)
160 183 : I2_up = r2l(nr, l_ang)*rho_2(nr)
161 :
162 9150 : DO ir = nr - 1, 1, -1
163 8967 : I1_down = I1_down + oor2l(ir, l_ang + 1)*rho_1(ir)
164 9150 : I2_down = I2_down + oor2l(ir, l_ang + 1)*rho_2(ir)
165 : END DO
166 :
167 : vrad_h(nr, iso) = vrad_h(nr, iso) + prefactor* &
168 183 : (oor2l(nr, l_ang + 1)*I1_up + r2l(nr, l_ang)*I1_down)
169 : vrad_s(nr, iso) = vrad_s(nr, iso) + prefactor* &
170 183 : (oor2l(nr, l_ang + 1)*I2_up + r2l(nr, l_ang)*I2_down)
171 :
172 9165 : DO ir = nr - 1, 1, -1
173 8967 : I1_up = I1_up + r2l(ir, l_ang)*rho_1(ir)
174 8967 : I1_down = I1_down - oor2l(ir, l_ang + 1)*rho_1(ir)
175 8967 : I2_up = I2_up + r2l(ir, l_ang)*rho_2(ir)
176 8967 : I2_down = I2_down - oor2l(ir, l_ang + 1)*rho_2(ir)
177 :
178 : vrad_h(ir, iso) = vrad_h(ir, iso) + prefactor* &
179 8967 : (oor2l(ir, l_ang + 1)*I1_up + r2l(ir, l_ang)*I1_down)
180 : vrad_s(ir, iso) = vrad_s(ir, iso) + prefactor* &
181 9150 : (oor2l(ir, l_ang + 1)*I2_up + r2l(ir, l_ang)*I2_down)
182 :
183 : END DO
184 :
185 : END DO
186 :
187 15 : DEALLOCATE (rho_1, rho_2)
188 :
189 15 : CALL timestop(handle)
190 :
191 15 : END SUBROUTINE calculate_Vh_1center
192 :
193 : ! **************************************************************************************************
194 : !> \brief Calculates one center GAPW Hartree energies and matrix elements
195 : !> Hartree potentials are input
196 : !> Takes possible background charge into account
197 : !> Special case for densities without core charge
198 : !> \param qs_env ...
199 : !> \param energy_hartree_1c ...
200 : !> \param ecoul_1c ...
201 : !> \param local_rho_set ...
202 : !> \param para_env ...
203 : !> \param tddft ...
204 : !> \param local_rho_set_2nd ...
205 : !> \param core_2nd ...
206 : !> \par History
207 : !> 05.2012 JGH refactoring
208 : !> \author ??
209 : ! **************************************************************************************************
210 28722 : SUBROUTINE Vh_1c_gg_integrals(qs_env, energy_hartree_1c, ecoul_1c, local_rho_set, para_env, tddft, local_rho_set_2nd, &
211 : core_2nd)
212 :
213 : TYPE(qs_environment_type), POINTER :: qs_env
214 : REAL(kind=dp), INTENT(out) :: energy_hartree_1c
215 : TYPE(ecoul_1center_type), DIMENSION(:), POINTER :: ecoul_1c
216 : TYPE(local_rho_type), POINTER :: local_rho_set
217 : TYPE(mp_para_env_type), POINTER :: para_env
218 : LOGICAL, INTENT(IN) :: tddft
219 : TYPE(local_rho_type), OPTIONAL, POINTER :: local_rho_set_2nd
220 : LOGICAL, INTENT(IN), OPTIONAL :: core_2nd
221 :
222 : CHARACTER(LEN=*), PARAMETER :: routineN = 'Vh_1c_gg_integrals'
223 :
224 : INTEGER :: bo(2), handle, iat, iatom, ikind, ipgf1, is1, iset1, iso, l_ang, llmax, &
225 : llmax_nuc, lmax0, lmax0_2nd, lmax_0, m1, max_iso, max_iso_not0, max_iso_not0_nuc, &
226 : max_s_harm, max_s_harm_nuc, maxl, maxl_nuc, maxso, maxso_nuc, mepos, n1, nat, nchan_0, &
227 : nkind, nr, nset, nset_nuc, nsotot, nsotot_nuc, nspins, num_pe
228 28722 : INTEGER, ALLOCATABLE, DIMENSION(:) :: cg_n_list
229 28722 : INTEGER, ALLOCATABLE, DIMENSION(:, :, :) :: cg_list
230 28722 : INTEGER, DIMENSION(:), POINTER :: atom_list, lmax, lmax_nuc, lmin, &
231 28722 : lmin_nuc, npgf, npgf_nuc
232 : LOGICAL :: cneo, core_charge, l_2nd_local_rho, &
233 : my_core_2nd, my_periodic, paw_atom
234 : REAL(dp) :: back_ch, background_energy, &
235 : background_nuc, ecoul_1_z_cneo
236 28722 : REAL(dp), ALLOCATABLE, DIMENSION(:) :: background_potential, gexp, sqrtwr
237 28722 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: aVh1b_00, aVh1b_00_nuc, aVh1b_hh, &
238 28722 : aVh1b_hh_nuc, aVh1b_ss, aVh1b_ss_nuc, &
239 28722 : g0_h_w
240 28722 : REAL(dp), DIMENSION(:), POINTER :: rrad_z, vrrad_z
241 28722 : REAL(dp), DIMENSION(:, :), POINTER :: g0_h, g0_h_2nd, gsph, gsph_nuc, rrad_0, &
242 28722 : Vh1_h, Vh1_s, vrrad_0, zet, zet_nuc
243 28722 : REAL(dp), DIMENSION(:, :, :), POINTER :: my_CG, Qlm_gg, Qlm_gg_2nd
244 28722 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
245 : TYPE(cell_type), POINTER :: cell
246 : TYPE(cneo_potential_type), POINTER :: cneo_potential
247 : TYPE(dft_control_type), POINTER :: dft_control
248 : TYPE(grid_atom_type), POINTER :: grid_atom
249 : TYPE(gto_basis_set_type), POINTER :: basis_1c, nuc_basis
250 : TYPE(harmonics_atom_type), POINTER :: harmonics
251 : TYPE(pw_env_type), POINTER :: pw_env
252 : TYPE(pw_poisson_type), POINTER :: poisson_env
253 : TYPE(qs_charges_type), POINTER :: qs_charges
254 28722 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
255 28722 : TYPE(rho0_atom_type), DIMENSION(:), POINTER :: rho0_atom_set, rho0_atom_set_2nd
256 : TYPE(rho0_mpole_type), POINTER :: rho0_mpole, rho0_mpole_2nd
257 28722 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho_atom_set, rho_atom_set_2nd
258 : TYPE(rho_atom_type), POINTER :: rho_atom
259 28722 : TYPE(rhoz_cneo_type), DIMENSION(:), POINTER :: rhoz_cneo_set
260 : TYPE(rhoz_cneo_type), POINTER :: rhoz_cneo
261 28722 : TYPE(rhoz_type), DIMENSION(:), POINTER :: rhoz_set, rhoz_set_2nd
262 : TYPE(virial_type), POINTER :: virial
263 :
264 28722 : CALL timeset(routineN, handle)
265 :
266 28722 : NULLIFY (cell, dft_control, poisson_env, pw_env, qs_charges)
267 28722 : NULLIFY (atomic_kind_set, qs_kind_set, rho_atom_set, rho0_atom_set)
268 28722 : NULLIFY (rho0_mpole, rhoz_set)
269 28722 : NULLIFY (atom_list, grid_atom, harmonics)
270 28722 : NULLIFY (basis_1c, lmin, lmax, npgf, zet)
271 : NULLIFY (gsph)
272 28722 : NULLIFY (rhoz_cneo, rhoz_cneo_set)
273 :
274 : CALL get_qs_env(qs_env=qs_env, &
275 : cell=cell, dft_control=dft_control, &
276 : atomic_kind_set=atomic_kind_set, &
277 : qs_kind_set=qs_kind_set, &
278 28722 : pw_env=pw_env, qs_charges=qs_charges, virial=virial)
279 :
280 28722 : CALL pw_env_get(pw_env, poisson_env=poisson_env)
281 28722 : my_periodic = (poisson_env%method == pw_poisson_periodic)
282 :
283 : ! The compensating uniform charge is fixed by the electron number, not
284 : ! by the approximate hard/soft quadrature. A planar countercharge makes
285 : ! the full Poisson problem neutral. At fixed charge the correction is
286 : ! linear in the density, so it contributes no TDDFT Hartree kernel.
287 28722 : back_ch = 0.0_dp
288 28722 : IF (my_periodic .AND. .NOT. dft_control%do_pcc .AND. .NOT. tddft) back_ch = dft_control%charge
289 :
290 : ! rhoz_set is not accessed in TDDFT
291 : CALL get_local_rho(local_rho_set, rho_atom_set, rho0_atom_set, rho0_mpole, rhoz_set, &
292 28722 : rhoz_cneo_set) ! for integral space
293 :
294 : ! for forces we need a second local_rho_set
295 28722 : l_2nd_local_rho = .FALSE.
296 28722 : IF (PRESENT(local_rho_set_2nd)) THEN ! for potential
297 348 : l_2nd_local_rho = .TRUE.
298 348 : NULLIFY (rho_atom_set_2nd, rho0_atom_set_2nd, rhoz_set_2nd) ! for potential
299 348 : CALL get_local_rho(local_rho_set_2nd, rho_atom_set_2nd, rho0_atom_set_2nd, rho0_mpole_2nd, rhoz_set=rhoz_set_2nd)
300 : END IF
301 :
302 28722 : nkind = SIZE(atomic_kind_set, 1)
303 28722 : nspins = dft_control%nspins
304 :
305 28722 : core_charge = .NOT. tddft ! for forces mixed version
306 28722 : my_core_2nd = .TRUE.
307 28722 : IF (PRESENT(core_2nd)) my_core_2nd = .NOT. core_2nd ! if my_core_2nd true, include core charge
308 :
309 : ! The aim of the following code was to return immediately if the subroutine
310 : ! was called for triplet excited states in spin-restricted case. This check
311 : ! is also performed before invocation of this subroutine. It should be save
312 : ! to remove the optional argument 'do_triplet' from the subroutine interface.
313 : !IF (tddft) THEN
314 : ! CPASSERT(PRESENT(do_triplet))
315 : ! IF (nspins == 1 .AND. do_triplet) RETURN
316 : !END IF
317 :
318 28722 : CALL get_qs_kind_set(qs_kind_set, maxg_iso_not0=max_iso)
319 28722 : CALL get_rho0_mpole(rho0_mpole=rho0_mpole, lmax_0=lmax_0)
320 :
321 : ! Put to 0 the local hartree energy contribution from 1 center integrals
322 28722 : energy_hartree_1c = 0.0_dp
323 : ! Restore total quantum nuclear density to zero
324 28722 : qs_charges%total_rho1_hard_nuc = 0.0_dp
325 28722 : rho0_mpole%tot_rhoz_cneo_s = 0.0_dp
326 :
327 : ! Here starts the loop over all the atoms
328 83340 : DO ikind = 1, nkind
329 :
330 54618 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=nat)
331 54618 : NULLIFY (cneo_potential)
332 : CALL get_qs_kind(qs_kind_set(ikind), &
333 : grid_atom=grid_atom, &
334 : harmonics=harmonics, ngrid_rad=nr, &
335 : max_iso_not0=max_iso_not0, paw_atom=paw_atom, &
336 54618 : cneo_potential=cneo_potential)
337 : CALL get_qs_kind(qs_kind_set(ikind), &
338 54618 : basis_set=basis_1c, basis_type="GAPW_1C")
339 :
340 54618 : cneo = ASSOCIATED(cneo_potential)
341 54618 : IF (cneo .AND. tddft) THEN
342 0 : CPABORT("Electronic TDDFT with CNEO quantum nuclei is not implemented.")
343 : END IF
344 :
345 54618 : NULLIFY (nuc_basis)
346 54618 : max_iso_not0_nuc = 0
347 54618 : IF (cneo) THEN
348 48 : CPASSERT(paw_atom)
349 : CALL get_qs_kind(qs_kind_set(ikind), &
350 48 : basis_set=nuc_basis, basis_type="NUC")
351 48 : max_iso_not0_nuc = cneo_potential%harmonics%max_iso_not0
352 : END IF
353 :
354 137958 : IF (paw_atom) THEN
355 : !=========== PAW ===============
356 : CALL get_gto_basis_set(gto_basis_set=basis_1c, lmax=lmax, lmin=lmin, &
357 : maxso=maxso, npgf=npgf, maxl=maxl, &
358 51264 : nset=nset, zet=zet)
359 :
360 51264 : max_s_harm = harmonics%max_s_harm
361 51264 : llmax = harmonics%llmax
362 :
363 51264 : nsotot = maxso*nset
364 205056 : ALLOCATE (gsph(nr, nsotot))
365 153792 : ALLOCATE (gexp(nr))
366 307584 : ALLOCATE (sqrtwr(nr), g0_h_w(nr, 0:lmax_0), background_potential(nr))
367 51264 : background_potential(:) = gapw_background_potential(back_ch, cell%deth, grid_atom%rad2(:))
368 :
369 205056 : ALLOCATE (aVh1b_hh(nsotot, nsotot))
370 153792 : ALLOCATE (aVh1b_ss(nsotot, nsotot))
371 153792 : ALLOCATE (aVh1b_00(nsotot, nsotot))
372 :
373 51264 : NULLIFY (Qlm_gg, g0_h)
374 : CALL get_rho0_mpole(rho0_mpole=rho0_mpole, ikind=ikind, &
375 : l0_ikind=lmax0, &
376 51264 : Qlm_gg=Qlm_gg, g0_h=g0_h) ! Qlm_gg of density
377 :
378 51264 : IF (PRESENT(local_rho_set_2nd)) THEN ! for potential
379 708 : NULLIFY (Qlm_gg_2nd, g0_h_2nd)
380 : CALL get_rho0_mpole(rho0_mpole=rho0_mpole_2nd, ikind=ikind, &
381 : l0_ikind=lmax0_2nd, &
382 708 : Qlm_gg=Qlm_gg_2nd, g0_h=g0_h_2nd) ! Qlm_gg of density
383 : END IF
384 51264 : nchan_0 = nsoset(lmax0)
385 :
386 51264 : IF (nchan_0 > MAX(max_iso_not0, max_iso_not0_nuc)) THEN
387 0 : CPABORT("channels for rho0 > # max of spherical harmonics")
388 : END IF
389 :
390 51264 : NULLIFY (Vh1_h, Vh1_s)
391 205056 : ALLOCATE (Vh1_h(nr, max_iso_not0))
392 205056 : ALLOCATE (Vh1_s(nr, MAX(max_iso_not0, max_iso_not0_nuc, nchan_0)))
393 :
394 51264 : NULLIFY (lmax_nuc, lmin_nuc, npgf_nuc, zet_nuc, gsph_nuc)
395 51264 : maxso_nuc = 0
396 51264 : maxl_nuc = -1
397 51264 : nset_nuc = 0
398 51264 : max_s_harm_nuc = 0
399 51264 : llmax_nuc = -1
400 51264 : nsotot_nuc = 0
401 51264 : IF (cneo) THEN
402 : CALL get_gto_basis_set(gto_basis_set=nuc_basis, lmax=lmax_nuc, &
403 : lmin=lmin_nuc, maxso=maxso_nuc, npgf=npgf_nuc, &
404 48 : maxl=maxl_nuc, nset=nset_nuc, zet=zet_nuc)
405 :
406 48 : max_s_harm_nuc = cneo_potential%harmonics%max_s_harm
407 48 : llmax_nuc = cneo_potential%harmonics%llmax
408 48 : nsotot_nuc = maxso_nuc*nset_nuc
409 192 : ALLOCATE (gsph_nuc(nr, nsotot_nuc))
410 198336 : gsph_nuc = 0.0_dp
411 192 : ALLOCATE (aVh1b_hh_nuc(nsotot_nuc, nsotot_nuc))
412 144 : ALLOCATE (aVh1b_ss_nuc(nsotot_nuc, nsotot_nuc))
413 192 : ALLOCATE (aVh1b_00_nuc(nsotot_nuc, nsotot_nuc))
414 : END IF
415 :
416 0 : ALLOCATE (cg_list(2, nsoset(MAX(maxl, maxl_nuc))**2, &
417 : MAX(max_s_harm, max_s_harm_nuc)), &
418 307584 : cg_n_list(MAX(max_s_harm, max_s_harm_nuc)))
419 :
420 51264 : NULLIFY (rrad_z, my_CG)
421 51264 : my_CG => harmonics%my_CG
422 :
423 : ! set to zero temporary arrays
424 51264 : sqrtwr = 0.0_dp
425 51264 : g0_h_w = 0.0_dp
426 51264 : gexp = 0.0_dp
427 105675970 : gsph = 0.0_dp
428 :
429 2841988 : sqrtwr(1:nr) = SQRT(grid_atom%wr(1:nr))
430 193596 : DO l_ang = 0, lmax0
431 7851840 : g0_h_w(1:nr, l_ang) = g0_h(1:nr, l_ang)*grid_atom%wr(1:nr)
432 : END DO
433 :
434 : m1 = 0
435 182808 : DO iset1 = 1, nset
436 131544 : n1 = nsoset(lmax(iset1))
437 495642 : DO ipgf1 = 1, npgf(iset1)
438 20096714 : gexp(1:nr) = EXP(-zet(ipgf1, iset1)*grid_atom%rad2(1:nr))*sqrtwr(1:nr)
439 1518524 : DO is1 = nsoset(lmin(iset1) - 1) + 1, nsoset(lmax(iset1))
440 1022882 : iso = is1 + (ipgf1 - 1)*n1 + m1
441 1022882 : l_ang = indso(1, is1)
442 111233212 : gsph(1:nr, iso) = grid_atom%rad2l(1:nr, l_ang)*gexp(1:nr)
443 : END DO ! is1
444 : END DO ! ipgf1
445 182808 : m1 = m1 + maxso
446 : END DO ! iset1
447 :
448 51264 : IF (cneo) THEN
449 : ! initialize nuclear pmat, cpc and e_core to zero
450 140 : DO iat = 1, nat
451 92 : iatom = atom_list(iat)
452 50876 : rhoz_cneo_set(iatom)%pmat = 0.0_dp
453 50876 : rhoz_cneo_set(iatom)%cpc_h = 0.0_dp
454 50876 : rhoz_cneo_set(iatom)%cpc_s = 0.0_dp
455 92 : rhoz_cneo_set(iatom)%e_core = 0.0_dp
456 140 : rhoz_cneo_set(iatom)%ready = .FALSE.
457 : END DO
458 :
459 : ! calculate nuclear gsph
460 48 : m1 = 0
461 480 : DO iset1 = 1, nset_nuc
462 432 : n1 = nsoset(lmax_nuc(iset1))
463 864 : DO ipgf1 = 1, npgf_nuc(iset1)
464 22032 : gexp(1:nr) = EXP(-zet_nuc(ipgf1, iset1)*grid_atom%rad2(1:nr))*sqrtwr(1:nr)
465 1968 : DO is1 = nsoset(lmin_nuc(iset1) - 1) + 1, nsoset(lmax_nuc(iset1))
466 1104 : iso = is1 + (ipgf1 - 1)*n1 + m1
467 1104 : l_ang = indso(1, is1)
468 111936 : gsph_nuc(1:nr, iso) = cneo_potential%rad2l(1:nr, l_ang)*gexp(1:nr)
469 : END DO ! is1
470 : END DO ! ipgf1
471 480 : m1 = m1 + maxso_nuc
472 : END DO ! iset1
473 : END IF
474 :
475 : ! Distribute the atoms of this kind
476 51264 : num_pe = para_env%num_pe
477 51264 : mepos = para_env%mepos
478 51264 : bo = get_limit(nat, num_pe, mepos)
479 :
480 91510 : DO iat = bo(1), bo(2) !1,nat
481 40246 : iatom = atom_list(iat)
482 40246 : rho_atom => rho_atom_set(iatom)
483 :
484 40246 : NULLIFY (rrad_z, vrrad_z, rrad_0, vrrad_0)
485 40246 : IF (core_charge .AND. .NOT. cneo) THEN
486 33608 : rrad_z => rhoz_set(ikind)%r_coef ! for density
487 : END IF
488 40246 : IF (my_core_2nd .AND. .NOT. cneo) THEN
489 33813 : IF (l_2nd_local_rho) THEN
490 260 : vrrad_z => rhoz_set_2nd(ikind)%vr_coef ! for potential
491 : ELSE
492 33553 : vrrad_z => rhoz_set(ikind)%vr_coef ! for potential
493 : END IF
494 : END IF
495 40246 : rrad_0 => rho0_atom_set(iatom)%rho0_rad_h%r_coef ! for density
496 40246 : vrrad_0 => rho0_atom_set(iatom)%vrho0_rad_h%r_coef
497 40246 : IF (l_2nd_local_rho) THEN
498 520 : rho_atom => rho_atom_set_2nd(iatom)
499 520 : vrrad_0 => rho0_atom_set_2nd(iatom)%vrho0_rad_h%r_coef ! for potential
500 : END IF
501 : CALL Vh_1c_atom_potential(rho_atom, vrrad_0, &
502 : grid_atom, my_core_2nd .AND. .NOT. cneo, & ! core charge for potential (2nd)
503 : vrrad_z, Vh1_h, Vh1_s, &
504 40246 : nchan_0, nspins, max_iso_not0, background_potential)
505 :
506 40246 : IF (l_2nd_local_rho) rho_atom => rho_atom_set(iatom) ! rho_atom for density
507 :
508 40246 : ecoul_1_z_cneo = 0.0_dp
509 40246 : background_nuc = 0.0_dp
510 40246 : IF (cneo) THEN
511 46 : rhoz_cneo => rhoz_cneo_set(iatom)
512 : ! Add the soft tail of nuclear Hartree potential to total Vh1_s first.
513 : ! vrho already contains the -zeff factor.
514 1196 : DO iso = 1, max_iso_not0_nuc
515 116196 : Vh1_s(:, iso) = Vh1_s(:, iso) + rhoz_cneo%vrho_rad_s(:, iso)
516 : END DO
517 :
518 : ! Build nuclear 1c integrals according to Vh1_h from electronic density only
519 : ! and Vh1_s from electron density and last step (or initial guess) nuclear density
520 : ! Vh1_h_nuc = -Z*Vh1_h, Vh1_s_nuc = -Z*Vh1_s
521 : CALL Vh_1c_nuc_integrals(rhoz_cneo, cneo_potential%zeff, &
522 : aVh1b_hh_nuc, aVh1b_ss_nuc, aVh1b_00_nuc, Vh1_h, Vh1_s, &
523 : max_iso_not0, max_iso_not0_nuc, &
524 : max_s_harm_nuc, llmax_nuc, cg_list, cg_n_list, &
525 : nset_nuc, npgf_nuc, lmin_nuc, lmax_nuc, nsotot_nuc, maxso_nuc, &
526 : nchan_0, gsph_nuc, g0_h_w, cneo_potential%harmonics%my_CG, &
527 46 : cneo_potential%Qlm_gg)
528 :
529 : ! Solve the nuclear 1c problem
530 : CALL calculate_rhoz_cneo(rhoz_cneo, cneo_potential, cg_list, cg_n_list, nset_nuc, &
531 46 : npgf_nuc, lmin_nuc, lmax_nuc, maxl_nuc, maxso_nuc)
532 : ! slm_int(iso=1) = sqrt(4*Pi), slm_int(iso>1) = 0, without using Lebedev grid
533 : ! when printing, nuclear density is positive, thus needing the minus sign
534 : qs_charges%total_rho1_hard_nuc = qs_charges%total_rho1_hard_nuc - SQRT(fourpi) &
535 2346 : *SUM(rhoz_cneo%rho_rad_h(:, 1)*grid_atom%wr(:))
536 : rho0_mpole%tot_rhoz_cneo_s = rho0_mpole%tot_rhoz_cneo_s - SQRT(fourpi) &
537 2346 : *SUM(rhoz_cneo%rho_rad_s(:, 1)*grid_atom%wr(:))
538 :
539 : ! Calculate the contributions to Ecoul coming from Vh1_h*rhoz_cneo_h and Vh1_s*rhoz_cneo_s.
540 : ! Self-interaction of the quantum nucleus is already removed in ecoul_1_z_cneo.
541 : ! rho already contains the -zeff factor.
542 460 : DO iso = 1, MIN(max_iso_not0, max_iso_not0_nuc)
543 : ecoul_1_z_cneo = ecoul_1_z_cneo + 0.5_dp* &
544 : (SUM(Vh1_h(:, iso)*rhoz_cneo%rho_rad_h(:, iso)*grid_atom%wr(:)) &
545 41860 : - SUM(Vh1_s(:, iso)*rhoz_cneo%rho_rad_s(:, iso)*grid_atom%wr(:)))
546 : END DO
547 782 : DO iso = max_iso_not0 + 1, max_iso_not0_nuc
548 : ecoul_1_z_cneo = ecoul_1_z_cneo - 0.5_dp* &
549 37582 : SUM(Vh1_s(:, iso)*rhoz_cneo%rho_rad_s(:, iso)*grid_atom%wr(:))
550 : END DO
551 :
552 : background_nuc = SUM(background_potential*(rhoz_cneo%rho_rad_h(:, 1) - &
553 2346 : rhoz_cneo%rho_rad_s(:, 1))*grid_atom%wr(:))
554 : ! The background interaction is linear, whereas the generic
555 : ! Coulomb contraction above includes only one half of it.
556 46 : ecoul_1_z_cneo = ecoul_1_z_cneo + 0.5_dp*background_nuc
557 :
558 : ! Add nuclear Hartree potential to total Vh1_h after solving the nuclear 1c problem
559 : ! to avoid nuclear self-interaction.
560 : ! vrho already contains the -zeff factor.
561 : ! Here the min of two max_iso_not0's is chosen, because even when the nuclear one
562 : ! is larger, it is meaningless to let Vh1_h have higher angular momentum components
563 : ! as Vh1_h now is only used for the electronic part.
564 460 : DO iso = 1, MIN(max_iso_not0, max_iso_not0_nuc)
565 41860 : Vh1_h(:, iso) = Vh1_h(:, iso) + rhoz_cneo%vrho_rad_h(:, iso)
566 : END DO
567 : END IF
568 :
569 : CALL Vh_1c_atom_energy(energy_hartree_1c, ecoul_1c, rho_atom, rrad_0, &
570 : grid_atom, iatom, core_charge .AND. .NOT. cneo, & ! core charge for density
571 : rrad_z, Vh1_h, Vh1_s, nchan_0, nspins, max_iso_not0, &
572 40246 : background_potential, background_energy)
573 :
574 40246 : IF (l_2nd_local_rho) rho_atom => rho_atom_set_2nd(iatom) ! rho_atom for potential (2nd)
575 :
576 40246 : IF (cneo) THEN
577 46 : CALL set_ecoul_1c(ecoul_1c, iatom, ecoul_1_z=ecoul_1c(iatom)%ecoul_1_z + ecoul_1_z_cneo)
578 46 : energy_hartree_1c = energy_hartree_1c + ecoul_1_z_cneo
579 : END IF
580 :
581 : ! Besides the OCE coefficient derivatives, E_background has an
582 : ! explicit 1/volume dependence. At fixed local radial functions
583 : ! its contribution to -dE/d(strain) is E_background times I.
584 40246 : IF (virial%pv_calculate .AND. .NOT. tddft) THEN
585 2664 : DO iso = 1, 3
586 1998 : virial%pv_virial(iso, iso) = virial%pv_virial(iso, iso) + background_energy + background_nuc
587 2664 : virial%pv_ehartree(iso, iso) = virial%pv_ehartree(iso, iso) + background_energy + background_nuc
588 : END DO
589 : END IF
590 :
591 : CALL Vh_1c_atom_integrals(rho_atom, & ! results (int_local_h and int_local_s) written on rho_atom_2nd
592 : ! int_local_h and int_local_s are used in update_ks_atom
593 : ! on int_local_h mixed core / non-core
594 : aVh1b_hh, aVh1b_ss, aVh1b_00, Vh1_h, Vh1_s, max_iso_not0, &
595 : max_s_harm, llmax, cg_list, cg_n_list, &
596 : nset, npgf, lmin, lmax, nsotot, maxso, nspins, nchan_0, gsph, &
597 91510 : g0_h_w, my_CG, Qlm_gg) ! Qlm_gg for density from local_rho_set
598 :
599 : END DO ! iat
600 :
601 51264 : DEALLOCATE (aVh1b_hh)
602 51264 : DEALLOCATE (aVh1b_ss)
603 51264 : DEALLOCATE (aVh1b_00)
604 51264 : IF (ALLOCATED(aVh1b_hh_nuc)) DEALLOCATE (aVh1b_hh_nuc)
605 51264 : IF (ALLOCATED(aVh1b_ss_nuc)) DEALLOCATE (aVh1b_ss_nuc)
606 51264 : IF (ALLOCATED(aVh1b_00_nuc)) DEALLOCATE (aVh1b_00_nuc)
607 51264 : DEALLOCATE (Vh1_h, Vh1_s)
608 51264 : DEALLOCATE (cg_list, cg_n_list)
609 51264 : DEALLOCATE (gsph)
610 51264 : IF (ASSOCIATED(gsph_nuc)) DEALLOCATE (gsph_nuc)
611 51264 : DEALLOCATE (gexp)
612 51264 : DEALLOCATE (sqrtwr, g0_h_w, background_potential)
613 :
614 153792 : IF (cneo) THEN
615 : ! broadcast nuclear pmat, cpc and e_core
616 140 : DO iat = 1, nat
617 92 : iatom = atom_list(iat)
618 101660 : CALL para_env%sum(rhoz_cneo_set(iatom)%pmat)
619 101660 : CALL para_env%sum(rhoz_cneo_set(iatom)%cpc_h)
620 101660 : CALL para_env%sum(rhoz_cneo_set(iatom)%cpc_s)
621 92 : CALL para_env%sum(rhoz_cneo_set(iatom)%e_core)
622 140 : rhoz_cneo_set(iatom)%ready = .TRUE.
623 : END DO
624 : END IF
625 : ELSE
626 : !=========== NO PAW ===============
627 : ! This term is taken care of using the core density as in GPW
628 : CYCLE
629 : END IF ! paw
630 : END DO ! ikind
631 :
632 28722 : CALL para_env%sum(energy_hartree_1c)
633 28722 : CALL para_env%sum(qs_charges%total_rho1_hard_nuc)
634 28722 : CALL para_env%sum(rho0_mpole%tot_rhoz_cneo_s)
635 :
636 28722 : CALL timestop(handle)
637 :
638 57444 : END SUBROUTINE Vh_1c_gg_integrals
639 :
640 : ! **************************************************************************************************
641 :
642 : ! **************************************************************************************************
643 : !> \brief ...
644 : !> \param rho_atom ...
645 : !> \param vrrad_0 ...
646 : !> \param grid_atom ...
647 : !> \param core_charge ...
648 : !> \param vrrad_z ...
649 : !> \param Vh1_h ...
650 : !> \param Vh1_s ...
651 : !> \param nchan_0 ...
652 : !> \param nspins ...
653 : !> \param max_iso_not0 ...
654 : !> \param background_potential Unweighted l=0 potential of the uniform background.
655 : ! **************************************************************************************************
656 40246 : SUBROUTINE Vh_1c_atom_potential(rho_atom, vrrad_0, &
657 : grid_atom, core_charge, vrrad_z, Vh1_h, Vh1_s, &
658 40246 : nchan_0, nspins, max_iso_not0, background_potential)
659 :
660 : TYPE(rho_atom_type), POINTER :: rho_atom
661 : REAL(dp), DIMENSION(:, :), POINTER :: vrrad_0
662 : TYPE(grid_atom_type), POINTER :: grid_atom
663 : LOGICAL, INTENT(IN) :: core_charge
664 : REAL(dp), DIMENSION(:), POINTER :: vrrad_z
665 : REAL(dp), DIMENSION(:, :), POINTER :: Vh1_h, Vh1_s
666 : INTEGER, INTENT(IN) :: nchan_0, nspins, max_iso_not0
667 : REAL(dp), INTENT(IN) :: background_potential(:)
668 :
669 : INTEGER :: iso, ispin, nr
670 40246 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: vr_h, vr_s
671 :
672 40246 : nr = grid_atom%nr
673 :
674 40246 : NULLIFY (vr_h, vr_s)
675 40246 : CALL get_rho_atom(rho_atom=rho_atom, vrho_rad_h=vr_h, vrho_rad_s=vr_s)
676 :
677 29202180 : Vh1_h = 0.0_dp
678 29239716 : Vh1_s = 0.0_dp
679 :
680 3772167 : IF (core_charge) Vh1_h(:, 1) = vrrad_z(:)
681 :
682 355236 : DO iso = 1, nchan_0
683 33817714 : Vh1_s(:, iso) = vrrad_0(:, iso)
684 : END DO
685 :
686 86096 : DO ispin = 1, nspins
687 713058 : DO iso = 1, max_iso_not0
688 34570096 : Vh1_h(:, iso) = Vh1_h(:, iso) + vr_h(ispin)%r_coef(:, iso)
689 34615946 : Vh1_s(:, iso) = Vh1_s(:, iso) + vr_s(ispin)%r_coef(:, iso)
690 : END DO
691 : END DO
692 :
693 2210950 : Vh1_h(:, 1) = Vh1_h(:, 1) + background_potential
694 2210950 : Vh1_s(:, 1) = Vh1_s(:, 1) + background_potential
695 :
696 40246 : END SUBROUTINE Vh_1c_atom_potential
697 :
698 : ! **************************************************************************************************
699 :
700 : ! **************************************************************************************************
701 : !> \brief ...
702 : !> \param energy_hartree_1c ...
703 : !> \param ecoul_1c ...
704 : !> \param rho_atom ...
705 : !> \param rrad_0 ...
706 : !> \param grid_atom ...
707 : !> \param iatom ...
708 : !> \param core_charge ...
709 : !> \param rrad_z ...
710 : !> \param Vh1_h ...
711 : !> \param Vh1_s ...
712 : !> \param nchan_0 ...
713 : !> \param nspins ...
714 : !> \param max_iso_not0 ...
715 : !> \param background_potential Unweighted l=0 potential of the uniform background.
716 : !> \param background_energy Full linear background interaction for the volume derivative.
717 : ! **************************************************************************************************
718 40246 : SUBROUTINE Vh_1c_atom_energy(energy_hartree_1c, ecoul_1c, rho_atom, rrad_0, &
719 : grid_atom, iatom, core_charge, rrad_z, Vh1_h, Vh1_s, &
720 40246 : nchan_0, nspins, max_iso_not0, background_potential, background_energy)
721 :
722 : REAL(dp), INTENT(INOUT) :: energy_hartree_1c
723 : TYPE(ecoul_1center_type), DIMENSION(:), POINTER :: ecoul_1c
724 : TYPE(rho_atom_type), POINTER :: rho_atom
725 : REAL(dp), DIMENSION(:, :), POINTER :: rrad_0
726 : TYPE(grid_atom_type), POINTER :: grid_atom
727 : INTEGER, INTENT(IN) :: iatom
728 : LOGICAL, INTENT(IN) :: core_charge
729 : REAL(dp), DIMENSION(:), POINTER :: rrad_z
730 : REAL(dp), DIMENSION(:, :), POINTER :: Vh1_h, Vh1_s
731 : INTEGER, INTENT(IN) :: nchan_0, nspins, max_iso_not0
732 : REAL(dp), INTENT(IN) :: background_potential(:)
733 : REAL(dp), INTENT(OUT) :: background_energy
734 :
735 : INTEGER :: iso, ispin, nr
736 : REAL(dp) :: bg_0, bg_h, bg_s, bg_z, ecoul_1_0, &
737 : ecoul_1_h, ecoul_1_s, ecoul_1_z
738 40246 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: r_h, r_s
739 :
740 40246 : nr = grid_atom%nr
741 :
742 40246 : NULLIFY (r_h, r_s)
743 40246 : CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
744 :
745 : ! Calculate the contributions to Ecoul coming from Vh1_h*rhoz
746 40246 : ecoul_1_z = 0.0_dp
747 40246 : bg_z = 0.0_dp
748 40246 : IF (core_charge) THEN
749 1872412 : ecoul_1_z = 0.5_dp*SUM(Vh1_h(:, 1)*rrad_z(:)*grid_atom%wr(:))
750 1872412 : bg_z = SUM(background_potential*rrad_z(:)*grid_atom%wr(:))
751 : END IF
752 :
753 : ! Calculate the contributions to Ecoul coming from Vh1_s*rho0
754 40246 : ecoul_1_0 = 0.0_dp
755 355236 : DO iso = 1, nchan_0
756 16928980 : ecoul_1_0 = ecoul_1_0 + 0.5_dp*SUM(Vh1_s(:, iso)*rrad_0(:, iso)*grid_atom%wr(:))
757 : END DO
758 2210950 : bg_0 = SUM(background_potential*rrad_0(:, 1)*grid_atom%wr(:))
759 :
760 : ! Calculate the contributions to Ecoul coming from Vh1_h*rho1_h and Vh1_s*rho1_s
761 40246 : ecoul_1_s = 0.0_dp
762 40246 : ecoul_1_h = 0.0_dp
763 40246 : bg_h = 0.0_dp
764 40246 : bg_s = 0.0_dp
765 86096 : DO ispin = 1, nspins
766 2556904 : bg_h = bg_h + SUM(background_potential*r_h(ispin)%r_coef(:, 1)*grid_atom%wr(:))
767 2556904 : bg_s = bg_s + SUM(background_potential*r_s(ispin)%r_coef(:, 1)*grid_atom%wr(:))
768 713058 : DO iso = 1, max_iso_not0
769 34570096 : ecoul_1_s = ecoul_1_s + 0.5_dp*SUM(Vh1_s(:, iso)*r_s(ispin)%r_coef(:, iso)*grid_atom%wr(:))
770 34615946 : ecoul_1_h = ecoul_1_h + 0.5_dp*SUM(Vh1_h(:, iso)*r_h(ispin)%r_coef(:, iso)*grid_atom%wr(:))
771 : END DO
772 : END DO
773 :
774 : ! Unlike the quadratic Hartree self-energy, the interaction with a fixed
775 : ! uniform background has no factor 1/2. Its potential is already in Vh1.
776 40246 : ecoul_1_z = ecoul_1_z + 0.5_dp*bg_z
777 40246 : ecoul_1_0 = ecoul_1_0 + 0.5_dp*bg_0
778 40246 : ecoul_1_h = ecoul_1_h + 0.5_dp*bg_h
779 40246 : ecoul_1_s = ecoul_1_s + 0.5_dp*bg_s
780 40246 : background_energy = bg_z - bg_0 + bg_h - bg_s
781 :
782 40246 : CALL set_ecoul_1c(ecoul_1c, iatom, ecoul_1_z=ecoul_1_z, ecoul_1_0=ecoul_1_0)
783 40246 : CALL set_ecoul_1c(ecoul_1c=ecoul_1c, iatom=iatom, ecoul_1_h=ecoul_1_h, ecoul_1_s=ecoul_1_s)
784 :
785 40246 : energy_hartree_1c = energy_hartree_1c + ecoul_1_z - ecoul_1_0
786 40246 : energy_hartree_1c = energy_hartree_1c + ecoul_1_h - ecoul_1_s
787 :
788 40246 : END SUBROUTINE Vh_1c_atom_energy
789 :
790 : ! **************************************************************************************************
791 : !> \brief l=0 potential for the periodic mean-potential correction.
792 : !> For a neutral localized difference delta_rho between hard and soft
793 : !> total charges, integral V(delta_rho) = -2*pi/3 integral r^2 delta_rho.
794 : !> CP2K stores electron-minus-nuclear densities, opposite to net_charge.
795 : !> Radial quadrature weights belong in the contraction, not in this potential.
796 : !> \param net_charge Physical cell charge, positive for missing electrons.
797 : !> \param volume Cell volume in bohr^3.
798 : !> \param rad2 Squared atom-centered radial coordinates.
799 : !> \return Real spherical-harmonic l=0 coefficient of the potential.
800 : ! **************************************************************************************************
801 51278 : PURE FUNCTION gapw_background_potential(net_charge, volume, rad2) RESULT(potential)
802 : REAL(dp), INTENT(IN) :: net_charge, volume, rad2(:)
803 : REAL(dp) :: potential(SIZE(rad2))
804 :
805 2864416 : potential = -(2.0_dp*pi/3.0_dp)*SQRT(fourpi)*net_charge/volume*rad2
806 51278 : END FUNCTION gapw_background_potential
807 :
808 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
809 :
810 : ! **************************************************************************************************
811 : !> \brief ...
812 : !> \param rho_atom ...
813 : !> \param aVh1b_hh ...
814 : !> \param aVh1b_ss ...
815 : !> \param aVh1b_00 ...
816 : !> \param Vh1_h ...
817 : !> \param Vh1_s ...
818 : !> \param max_iso_not0 ...
819 : !> \param max_s_harm ...
820 : !> \param llmax ...
821 : !> \param cg_list ...
822 : !> \param cg_n_list ...
823 : !> \param nset ...
824 : !> \param npgf ...
825 : !> \param lmin ...
826 : !> \param lmax ...
827 : !> \param nsotot ...
828 : !> \param maxso ...
829 : !> \param nspins ...
830 : !> \param nchan_0 ...
831 : !> \param gsph ...
832 : !> \param g0_h_w ...
833 : !> \param my_CG ...
834 : !> \param Qlm_gg ...
835 : ! **************************************************************************************************
836 40246 : SUBROUTINE Vh_1c_atom_integrals(rho_atom, &
837 40246 : aVh1b_hh, aVh1b_ss, aVh1b_00, Vh1_h, Vh1_s, max_iso_not0, &
838 40246 : max_s_harm, llmax, cg_list, cg_n_list, &
839 : nset, npgf, lmin, lmax, nsotot, maxso, nspins, nchan_0, gsph, &
840 40246 : g0_h_w, my_CG, Qlm_gg)
841 :
842 : TYPE(rho_atom_type), POINTER :: rho_atom
843 : REAL(dp), DIMENSION(:, :) :: aVh1b_hh, aVh1b_ss, aVh1b_00
844 : REAL(dp), DIMENSION(:, :), POINTER :: Vh1_h, Vh1_s
845 : INTEGER, INTENT(IN) :: max_iso_not0, max_s_harm, llmax
846 : INTEGER, DIMENSION(:, :, :) :: cg_list
847 : INTEGER, DIMENSION(:) :: cg_n_list
848 : INTEGER, INTENT(IN) :: nset
849 : INTEGER, DIMENSION(:), POINTER :: npgf, lmin, lmax
850 : INTEGER, INTENT(IN) :: nsotot, maxso, nspins, nchan_0
851 : REAL(dp), DIMENSION(:, :), POINTER :: gsph
852 : REAL(dp), DIMENSION(:, 0:) :: g0_h_w
853 : REAL(dp), DIMENSION(:, :, :), POINTER :: my_CG, Qlm_gg
854 :
855 : INTEGER :: icg, ipgf1, ipgf2, ir, is1, is2, iset1, &
856 : iset2, iso, iso1, iso2, ispin, l_ang, &
857 : m1, m2, max_iso_not0_local, n1, n2, nr
858 : REAL(dp) :: gVg_0, gVg_h, gVg_s
859 40246 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: int_local_h, int_local_s
860 :
861 40246 : NULLIFY (int_local_h, int_local_s)
862 : CALL get_rho_atom(rho_atom=rho_atom, &
863 : ga_Vlocal_gb_h=int_local_h, &
864 40246 : ga_Vlocal_gb_s=int_local_s)
865 :
866 : ! Calculate the integrals of the potential with 2 primitives
867 137657068 : aVh1b_hh = 0.0_dp
868 137657068 : aVh1b_ss = 0.0_dp
869 137657068 : aVh1b_00 = 0.0_dp
870 :
871 40246 : nr = SIZE(gsph, 1)
872 :
873 40246 : m1 = 0
874 140431 : DO iset1 = 1, nset
875 : m2 = 0
876 432532 : DO iset2 = 1, nset
877 : CALL get_none0_cg_list(my_CG, lmin(iset1), lmax(iset1), lmin(iset2), lmax(iset2), &
878 332347 : max_s_harm, llmax, cg_list, cg_n_list, max_iso_not0_local)
879 :
880 332347 : n1 = nsoset(lmax(iset1))
881 1171643 : DO ipgf1 = 1, npgf(iset1)
882 839296 : n2 = nsoset(lmax(iset2))
883 3624868 : DO ipgf2 = 1, npgf(iset2)
884 : ! with contributions to V1_s*rho0
885 25620386 : DO iso = 1, MIN(nchan_0, max_iso_not0)
886 23167161 : l_ang = indso(1, iso)
887 1239345105 : gVg_0 = SUM(Vh1_s(:, iso)*g0_h_w(:, l_ang))
888 49835456 : DO icg = 1, cg_n_list(iso)
889 24215070 : is1 = cg_list(1, icg, iso)
890 24215070 : is2 = cg_list(2, icg, iso)
891 :
892 24215070 : iso1 = is1 + n1*(ipgf1 - 1) + m1
893 24215070 : iso2 = is2 + n2*(ipgf2 - 1) + m2
894 24215070 : gVg_h = 0.0_dp
895 24215070 : gVg_s = 0.0_dp
896 :
897 1286791864 : DO ir = 1, nr
898 1262576794 : gVg_h = gVg_h + gsph(ir, iso1)*gsph(ir, iso2)*Vh1_h(ir, iso)
899 1286791864 : gVg_s = gVg_s + gsph(ir, iso1)*gsph(ir, iso2)*Vh1_s(ir, iso)
900 : END DO ! ir
901 :
902 24215070 : aVh1b_hh(iso1, iso2) = aVh1b_hh(iso1, iso2) + gVg_h*my_CG(is1, is2, iso)
903 24215070 : aVh1b_ss(iso1, iso2) = aVh1b_ss(iso1, iso2) + gVg_s*my_CG(is1, is2, iso)
904 47382231 : aVh1b_00(iso1, iso2) = aVh1b_00(iso1, iso2) + gVg_0*Qlm_gg(iso1, iso2, iso)
905 :
906 : END DO !icg
907 : END DO ! iso
908 : ! without contributions to V1_s*rho0
909 32099873 : DO iso = nchan_0 + 1, max_iso_not0
910 42461174 : DO icg = 1, cg_n_list(iso)
911 11200597 : is1 = cg_list(1, icg, iso)
912 11200597 : is2 = cg_list(2, icg, iso)
913 :
914 11200597 : iso1 = is1 + n1*(ipgf1 - 1) + m1
915 11200597 : iso2 = is2 + n2*(ipgf2 - 1) + m2
916 11200597 : gVg_h = 0.0_dp
917 11200597 : gVg_s = 0.0_dp
918 :
919 581173787 : DO ir = 1, nr
920 569973190 : gVg_h = gVg_h + gsph(ir, iso1)*gsph(ir, iso2)*Vh1_h(ir, iso)
921 581173787 : gVg_s = gVg_s + gsph(ir, iso1)*gsph(ir, iso2)*Vh1_s(ir, iso)
922 : END DO ! ir
923 :
924 11200597 : aVh1b_hh(iso1, iso2) = aVh1b_hh(iso1, iso2) + gVg_h*my_CG(is1, is2, iso)
925 40007949 : aVh1b_ss(iso1, iso2) = aVh1b_ss(iso1, iso2) + gVg_s*my_CG(is1, is2, iso)
926 :
927 : END DO !icg
928 : END DO ! iso
929 : END DO ! ipgf2
930 : END DO ! ipgf1
931 432532 : m2 = m2 + maxso
932 : END DO ! iset2
933 140431 : m1 = m1 + maxso
934 : END DO !iset1
935 86096 : DO ispin = 1, nspins
936 45850 : CALL daxpy(nsotot*nsotot, 1.0_dp, aVh1b_hh, 1, int_local_h(ispin)%r_coef, 1)
937 45850 : CALL daxpy(nsotot*nsotot, 1.0_dp, aVh1b_ss, 1, int_local_s(ispin)%r_coef, 1)
938 45850 : CALL daxpy(nsotot*nsotot, -1.0_dp, aVh1b_00, 1, int_local_h(ispin)%r_coef, 1)
939 86096 : CALL daxpy(nsotot*nsotot, -1.0_dp, aVh1b_00, 1, int_local_s(ispin)%r_coef, 1)
940 : END DO ! ispin
941 :
942 40246 : END SUBROUTINE Vh_1c_atom_integrals
943 :
944 : !%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
945 :
946 : END MODULE hartree_local_methods
|