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 : !> \brief Calculate the KS reference potentials
10 : !> \par History
11 : !> 07.2022 created
12 : !> \author JGH
13 : ! **************************************************************************************************
14 : MODULE qs_ks_reference
15 : USE admm_types, ONLY: admm_type,&
16 : get_admm_env
17 : USE atomic_kind_types, ONLY: atomic_kind_type
18 : USE cp_control_types, ONLY: dft_control_type
19 : USE cp_dbcsr_api, ONLY: dbcsr_p_type
20 : USE hartree_local_methods, ONLY: Vh_1c_gg_integrals,&
21 : init_coulomb_local
22 : USE hartree_local_types, ONLY: hartree_local_create,&
23 : hartree_local_release,&
24 : hartree_local_type
25 : USE input_constants, ONLY: do_admm_aux_exch_func_none
26 : USE input_section_types, ONLY: section_vals_get_subs_vals,&
27 : section_vals_type
28 : USE kinds, ONLY: dp
29 : USE message_passing, ONLY: mp_para_env_type
30 : USE pw_env_types, ONLY: pw_env_get,&
31 : pw_env_type
32 : USE pw_grid_types, ONLY: pw_grid_type
33 : USE pw_methods, ONLY: pw_scale,&
34 : pw_transfer,&
35 : pw_zero
36 : USE pw_poisson_methods, ONLY: pw_poisson_solve
37 : USE pw_poisson_types, ONLY: pw_poisson_type
38 : USE pw_pool_types, ONLY: pw_pool_type
39 : USE pw_types, ONLY: pw_c1d_gs_type,&
40 : pw_r3d_rs_type
41 : USE qs_core_energies, ONLY: calculate_ecore_overlap,&
42 : calculate_ecore_self
43 : USE qs_environment_types, ONLY: get_qs_env,&
44 : qs_environment_type
45 : USE qs_gapw_densities, ONLY: prepare_gapw_den
46 : USE qs_kind_types, ONLY: qs_kind_type
47 : USE qs_ks_methods, ONLY: calc_rho_tot_gspace
48 : USE qs_ks_types, ONLY: qs_ks_env_type
49 : USE qs_local_rho_types, ONLY: local_rho_set_create,&
50 : local_rho_type
51 : USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
52 : USE qs_oce_types, ONLY: oce_matrix_type
53 : USE qs_rho0_ggrid, ONLY: integrate_vhg0_rspace,&
54 : rho0_s_grid_create
55 : USE qs_rho0_methods, ONLY: init_rho0
56 : USE qs_rho_atom_methods, ONLY: allocate_rho_atom_internals,&
57 : calculate_rho_atom_coeff
58 : USE qs_rho_types, ONLY: qs_rho_get,&
59 : qs_rho_type
60 : USE qs_vxc, ONLY: qs_vxc_create
61 : USE qs_vxc_atom, ONLY: calculate_vxc_atom
62 : USE virial_types, ONLY: virial_type
63 : #include "./base/base_uses.f90"
64 :
65 : IMPLICIT NONE
66 :
67 : PRIVATE
68 :
69 : ! *** Global parameters ***
70 :
71 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_ks_reference'
72 :
73 : PUBLIC :: ks_ref_potential, ks_ref_potential_atom
74 :
75 : ! **************************************************************************************************
76 :
77 : CONTAINS
78 :
79 : ! **************************************************************************************************
80 : !> \brief calculate the Kohn-Sham reference potential
81 : !> \param qs_env ...
82 : !> \param vh_rspace ...
83 : !> \param vxc_rspace ...
84 : !> \param vtau_rspace ...
85 : !> \param vadmm_rspace ...
86 : !> \param ehartree ...
87 : !> \param exc ...
88 : !> \param h_stress container for the stress tensor of the Hartree term
89 : !> \par History
90 : !> 10.2019 created [JGH]
91 : !> \author JGH
92 : ! **************************************************************************************************
93 4872 : SUBROUTINE ks_ref_potential(qs_env, vh_rspace, vxc_rspace, vtau_rspace, vadmm_rspace, &
94 : ehartree, exc, h_stress)
95 : TYPE(qs_environment_type), POINTER :: qs_env
96 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: vh_rspace
97 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: vxc_rspace, vtau_rspace, vadmm_rspace
98 : REAL(KIND=dp), INTENT(OUT) :: ehartree, exc
99 : REAL(KIND=dp), DIMENSION(3, 3), INTENT(INOUT), &
100 : OPTIONAL :: h_stress
101 :
102 : CHARACTER(LEN=*), PARAMETER :: routineN = 'ks_ref_potential'
103 :
104 : INTEGER :: handle, iab, ispin, nspins
105 : REAL(dp) :: eadmm, eovrl, eself
106 : REAL(KIND=dp), DIMENSION(3, 3) :: virial_xc
107 : TYPE(admm_type), POINTER :: admm_env
108 : TYPE(dft_control_type), POINTER :: dft_control
109 : TYPE(mp_para_env_type), POINTER :: para_env
110 : TYPE(pw_c1d_gs_type) :: rho_tot_gspace, v_hartree_gspace
111 : TYPE(pw_c1d_gs_type), POINTER :: rho_core
112 : TYPE(pw_env_type), POINTER :: pw_env
113 : TYPE(pw_grid_type), POINTER :: pw_grid
114 : TYPE(pw_poisson_type), POINTER :: poisson_env
115 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
116 : TYPE(pw_r3d_rs_type) :: v_hartree_rspace
117 1624 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_admm_rspace, v_admm_tau_rspace, &
118 1624 : v_rspace, v_tau_rspace
119 : TYPE(qs_ks_env_type), POINTER :: ks_env
120 : TYPE(qs_rho_type), POINTER :: rho, rho_xc
121 : TYPE(section_vals_type), POINTER :: xc_section
122 : TYPE(virial_type), POINTER :: virial
123 :
124 1624 : CALL timeset(routineN, handle)
125 :
126 : ! get all information on the electronic density
127 1624 : NULLIFY (rho, ks_env)
128 : CALL get_qs_env(qs_env=qs_env, rho=rho, dft_control=dft_control, &
129 1624 : para_env=para_env, ks_env=ks_env, rho_core=rho_core)
130 :
131 1624 : nspins = dft_control%nspins
132 :
133 1624 : NULLIFY (pw_env)
134 1624 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
135 1624 : CPASSERT(ASSOCIATED(pw_env))
136 :
137 1624 : NULLIFY (auxbas_pw_pool, poisson_env)
138 : ! gets the tmp grids
139 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
140 1624 : poisson_env=poisson_env)
141 :
142 : ! Calculate the Hartree potential
143 1624 : CALL auxbas_pw_pool%create_pw(v_hartree_gspace)
144 1624 : CALL auxbas_pw_pool%create_pw(v_hartree_rspace)
145 1624 : CALL auxbas_pw_pool%create_pw(rho_tot_gspace)
146 :
147 : ! Get the total density in g-space [ions + electrons]
148 1624 : CALL calc_rho_tot_gspace(rho_tot_gspace, qs_env, rho)
149 :
150 : CALL pw_poisson_solve(poisson_env, rho_tot_gspace, ehartree, &
151 1624 : v_hartree_gspace, h_stress=h_stress, rho_core=rho_core)
152 1624 : CALL pw_transfer(v_hartree_gspace, v_hartree_rspace)
153 1624 : CALL pw_scale(v_hartree_rspace, v_hartree_rspace%pw_grid%dvol)
154 :
155 1624 : CALL auxbas_pw_pool%give_back_pw(v_hartree_gspace)
156 1624 : CALL auxbas_pw_pool%give_back_pw(rho_tot_gspace)
157 : !
158 1624 : CALL calculate_ecore_self(qs_env, E_self_core=eself)
159 1624 : CALL calculate_ecore_overlap(qs_env, para_env, PRESENT(h_stress), E_overlap_core=eovrl)
160 1624 : ehartree = ehartree + eovrl + eself
161 :
162 : ! v_rspace and v_tau_rspace are generated from the auxbas pool
163 1624 : IF (dft_control%do_admm) THEN
164 368 : CALL get_qs_env(qs_env, admm_env=admm_env)
165 368 : xc_section => admm_env%xc_section_primary
166 : ELSE
167 1256 : xc_section => section_vals_get_subs_vals(qs_env%input, "DFT%XC")
168 : END IF
169 1624 : NULLIFY (v_rspace, v_tau_rspace)
170 1624 : IF (dft_control%qs_control%gapw_xc) THEN
171 14 : CALL get_qs_env(qs_env=qs_env, rho_xc=rho_xc)
172 : CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho_xc, xc_section=xc_section, &
173 14 : vxc_rho=v_rspace, vxc_tau=v_tau_rspace, exc=exc, just_energy=.FALSE.)
174 : ELSE
175 : CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho, xc_section=xc_section, &
176 1610 : vxc_rho=v_rspace, vxc_tau=v_tau_rspace, exc=exc, just_energy=.FALSE.)
177 : END IF
178 :
179 1624 : NULLIFY (v_admm_rspace, v_admm_tau_rspace)
180 1624 : IF (dft_control%do_admm) THEN
181 368 : IF (dft_control%admm_control%aux_exch_func /= do_admm_aux_exch_func_none) THEN
182 : ! For the virial, we have to save the pv_xc component because it will be reset in qs_vxc_create
183 234 : IF (PRESENT(h_stress)) THEN
184 12 : CALL get_qs_env(qs_env, virial=virial)
185 156 : virial_xc = virial%pv_xc
186 : END IF
187 234 : CALL get_admm_env(admm_env, rho_aux_fit=rho)
188 234 : xc_section => admm_env%xc_section_aux
189 : CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho, xc_section=xc_section, &
190 234 : vxc_rho=v_admm_rspace, vxc_tau=v_admm_tau_rspace, exc=eadmm, just_energy=.FALSE.)
191 378 : IF (PRESENT(h_stress)) virial%pv_xc = virial%pv_xc + virial_xc
192 : END IF
193 : END IF
194 :
195 : ! allocate potentials
196 1624 : IF (ASSOCIATED(vh_rspace%pw_grid)) THEN
197 294 : CALL vh_rspace%release()
198 : END IF
199 1624 : IF (ASSOCIATED(vxc_rspace)) THEN
200 588 : DO iab = 1, SIZE(vxc_rspace)
201 588 : CALL vxc_rspace(iab)%release()
202 : END DO
203 : ELSE
204 5522 : ALLOCATE (vxc_rspace(nspins))
205 : END IF
206 1624 : IF (ASSOCIATED(v_tau_rspace)) THEN
207 96 : IF (ASSOCIATED(vtau_rspace)) THEN
208 32 : DO iab = 1, SIZE(vtau_rspace)
209 32 : CALL vtau_rspace(iab)%release()
210 : END DO
211 : ELSE
212 340 : ALLOCATE (vtau_rspace(nspins))
213 : END IF
214 : ELSE
215 1528 : NULLIFY (vtau_rspace)
216 : END IF
217 1624 : IF (ASSOCIATED(v_admm_rspace)) THEN
218 226 : IF (ASSOCIATED(vadmm_rspace)) THEN
219 64 : DO iab = 1, SIZE(vadmm_rspace)
220 64 : CALL vadmm_rspace(iab)%release()
221 : END DO
222 : ELSE
223 804 : ALLOCATE (vadmm_rspace(nspins))
224 : END IF
225 : ELSE
226 1398 : NULLIFY (vadmm_rspace)
227 : END IF
228 :
229 1624 : pw_grid => v_hartree_rspace%pw_grid
230 1624 : CALL vh_rspace%create(pw_grid)
231 3450 : DO ispin = 1, nspins
232 1826 : CALL vxc_rspace(ispin)%create(pw_grid)
233 1826 : IF (ASSOCIATED(vtau_rspace)) THEN
234 116 : CALL vtau_rspace(ispin)%create(pw_grid)
235 : END IF
236 3450 : IF (ASSOCIATED(vadmm_rspace)) THEN
237 254 : CALL vadmm_rspace(ispin)%create(pw_grid)
238 : END IF
239 : END DO
240 : !
241 1624 : CALL pw_transfer(v_hartree_rspace, vh_rspace)
242 1624 : IF (ASSOCIATED(v_rspace)) THEN
243 2764 : DO ispin = 1, nspins
244 1458 : CALL pw_transfer(v_rspace(ispin), vxc_rspace(ispin))
245 1458 : CALL pw_scale(vxc_rspace(ispin), v_rspace(ispin)%pw_grid%dvol)
246 2764 : IF (ASSOCIATED(v_tau_rspace)) THEN
247 116 : CALL pw_transfer(v_tau_rspace(ispin), vtau_rspace(ispin))
248 116 : CALL pw_scale(vtau_rspace(ispin), v_tau_rspace(ispin)%pw_grid%dvol)
249 : END IF
250 : END DO
251 : ELSE
252 686 : DO ispin = 1, nspins
253 686 : CALL pw_zero(vxc_rspace(ispin))
254 : END DO
255 : END IF
256 1624 : IF (ASSOCIATED(v_admm_rspace)) THEN
257 480 : DO ispin = 1, nspins
258 254 : CALL pw_transfer(v_admm_rspace(ispin), vadmm_rspace(ispin))
259 480 : CALL pw_scale(vadmm_rspace(ispin), vadmm_rspace(ispin)%pw_grid%dvol)
260 : END DO
261 : END IF
262 :
263 : ! return pw grids
264 1624 : CALL auxbas_pw_pool%give_back_pw(v_hartree_rspace)
265 1624 : IF (ASSOCIATED(v_rspace)) THEN
266 2764 : DO ispin = 1, nspins
267 1458 : CALL auxbas_pw_pool%give_back_pw(v_rspace(ispin))
268 2764 : IF (ASSOCIATED(v_tau_rspace)) THEN
269 116 : CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
270 : END IF
271 : END DO
272 1306 : DEALLOCATE (v_rspace)
273 : END IF
274 1624 : IF (ASSOCIATED(v_tau_rspace)) DEALLOCATE (v_tau_rspace)
275 1624 : IF (ASSOCIATED(v_admm_rspace)) THEN
276 480 : DO ispin = 1, nspins
277 480 : CALL auxbas_pw_pool%give_back_pw(v_admm_rspace(ispin))
278 : END DO
279 226 : DEALLOCATE (v_admm_rspace)
280 : END IF
281 :
282 1624 : CALL timestop(handle)
283 :
284 1624 : END SUBROUTINE ks_ref_potential
285 :
286 : ! **************************************************************************************************
287 : !> \brief calculate the Kohn-Sham GAPW reference potentials
288 : !> \param qs_env ...
289 : !> \param local_rho_set ...
290 : !> \param local_rho_set_admm ...
291 : !> \param v_hartree_rspace ...
292 : !> \par History
293 : !> 07.2022 created [JGH]
294 : !> \author JGH
295 : ! **************************************************************************************************
296 550 : SUBROUTINE ks_ref_potential_atom(qs_env, local_rho_set, local_rho_set_admm, v_hartree_rspace)
297 : TYPE(qs_environment_type), POINTER :: qs_env
298 : TYPE(local_rho_type), POINTER :: local_rho_set, local_rho_set_admm
299 : TYPE(pw_r3d_rs_type), INTENT(IN) :: v_hartree_rspace
300 :
301 : CHARACTER(LEN=*), PARAMETER :: routineN = 'ks_ref_potential_atom'
302 :
303 : INTEGER :: handle, natom, nspins
304 : LOGICAL :: gapw, gapw_xc
305 : REAL(KIND=dp) :: eh1c, exc1, exc1_admm
306 : TYPE(admm_type), POINTER :: admm_env
307 550 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
308 550 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_aux, rho_ao_kp
309 : TYPE(dft_control_type), POINTER :: dft_control
310 : TYPE(hartree_local_type), POINTER :: hartree_local
311 : TYPE(mp_para_env_type), POINTER :: para_env
312 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
313 550 : POINTER :: sab
314 : TYPE(oce_matrix_type), POINTER :: oce
315 : TYPE(pw_env_type), POINTER :: pw_env
316 550 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
317 : TYPE(qs_rho_type), POINTER :: rho, rho_aux_fit
318 : TYPE(section_vals_type), POINTER :: xc_section
319 :
320 550 : CALL timeset(routineN, handle)
321 :
322 : ! get all information on the electronic density
323 : CALL get_qs_env(qs_env=qs_env, rho=rho, pw_env=pw_env, &
324 550 : dft_control=dft_control, para_env=para_env)
325 :
326 550 : nspins = dft_control%nspins
327 550 : gapw = dft_control%qs_control%gapw
328 550 : gapw_xc = dft_control%qs_control%gapw_xc
329 :
330 550 : IF (gapw .OR. gapw_xc) THEN
331 76 : NULLIFY (hartree_local, local_rho_set, local_rho_set_admm)
332 : CALL get_qs_env(qs_env, &
333 : atomic_kind_set=atomic_kind_set, &
334 76 : qs_kind_set=qs_kind_set)
335 76 : CALL local_rho_set_create(local_rho_set)
336 : CALL allocate_rho_atom_internals(local_rho_set%rho_atom_set, atomic_kind_set, &
337 76 : qs_kind_set, dft_control, para_env)
338 76 : IF (gapw) THEN
339 62 : CALL get_qs_env(qs_env, natom=natom)
340 62 : CALL init_rho0(local_rho_set, qs_env, dft_control%qs_control%gapw_control)
341 62 : CALL rho0_s_grid_create(pw_env, local_rho_set%rho0_mpole)
342 62 : CALL hartree_local_create(hartree_local)
343 62 : CALL init_coulomb_local(hartree_local, natom)
344 : END IF
345 :
346 76 : CALL get_qs_env(qs_env=qs_env, oce=oce, sab_orb=sab)
347 76 : CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
348 : CALL calculate_rho_atom_coeff(qs_env, rho_ao_kp, local_rho_set%rho_atom_set, &
349 76 : qs_kind_set, oce, sab, para_env)
350 76 : CALL prepare_gapw_den(qs_env, local_rho_set, do_rho0=gapw)
351 :
352 76 : IF (gapw) THEN
353 62 : CALL Vh_1c_gg_integrals(qs_env, eh1c, hartree_local%ecoul_1c, local_rho_set, para_env, .FALSE.)
354 : CALL integrate_vhg0_rspace(qs_env, v_hartree_rspace, para_env, calculate_forces=.FALSE., &
355 62 : local_rho_set=local_rho_set)
356 : END IF
357 76 : IF (dft_control%do_admm) THEN
358 10 : CALL get_qs_env(qs_env, admm_env=admm_env)
359 10 : xc_section => admm_env%xc_section_primary
360 : ELSE
361 66 : xc_section => section_vals_get_subs_vals(qs_env%input, "DFT%XC")
362 : END IF
363 : CALL calculate_vxc_atom(qs_env, .FALSE., exc1=exc1, xc_section_external=xc_section, &
364 76 : rho_atom_set_external=local_rho_set%rho_atom_set)
365 :
366 76 : IF (dft_control%do_admm) THEN
367 10 : IF (admm_env%do_gapw) THEN
368 10 : CALL local_rho_set_create(local_rho_set_admm)
369 : CALL allocate_rho_atom_internals(local_rho_set_admm%rho_atom_set, atomic_kind_set, &
370 10 : admm_env%admm_gapw_env%admm_kind_set, dft_control, para_env)
371 10 : oce => admm_env%admm_gapw_env%oce
372 10 : sab => admm_env%sab_aux_fit
373 10 : CALL get_admm_env(admm_env, rho_aux_fit=rho_aux_fit)
374 10 : CALL qs_rho_get(rho, rho_ao_kp=rho_ao_aux)
375 : CALL calculate_rho_atom_coeff(qs_env, rho_ao_aux, local_rho_set_admm%rho_atom_set, &
376 10 : admm_env%admm_gapw_env%admm_kind_set, oce, sab, para_env)
377 : CALL prepare_gapw_den(qs_env, local_rho_set=local_rho_set_admm, &
378 10 : do_rho0=.FALSE., kind_set_external=admm_env%admm_gapw_env%admm_kind_set)
379 : !compute the potential due to atomic densities
380 10 : xc_section => admm_env%xc_section_aux
381 : CALL calculate_vxc_atom(qs_env, energy_only=.FALSE., exc1=exc1_admm, &
382 : kind_set_external=admm_env%admm_gapw_env%admm_kind_set, &
383 : xc_section_external=xc_section, &
384 10 : rho_atom_set_external=local_rho_set_admm%rho_atom_set)
385 : END IF
386 : END IF
387 :
388 : ! clean up
389 76 : CALL hartree_local_release(hartree_local)
390 :
391 : ELSE
392 :
393 474 : NULLIFY (local_rho_set, local_rho_set_admm)
394 :
395 : END IF
396 :
397 550 : CALL timestop(handle)
398 :
399 550 : END SUBROUTINE ks_ref_potential_atom
400 :
401 : ! **************************************************************************************************
402 :
403 : END MODULE qs_ks_reference
|