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 : ! **************************************************************************************************
9 : !> \brief Routines for a Kim-Gordon-like partitioning into molecular subunits
10 : !> \par History
11 : !> 2012.06 created [Martin Haeufel]
12 : !> \author Martin Haeufel and Florian Schiffmann
13 : ! **************************************************************************************************
14 : MODULE kg_correction
15 : USE atomic_kind_types, ONLY: atomic_kind_type
16 : USE cp_control_types, ONLY: dft_control_type
17 : USE cp_dbcsr_api, ONLY: dbcsr_add,&
18 : dbcsr_p_type
19 : USE cp_dbcsr_contrib, ONLY: dbcsr_dot
20 : USE cp_log_handling, ONLY: cp_get_default_logger,&
21 : cp_logger_get_default_unit_nr,&
22 : cp_logger_type
23 : USE ec_methods, ONLY: create_kernel
24 : USE input_constants, ONLY: kg_tnadd_atomic,&
25 : kg_tnadd_embed,&
26 : kg_tnadd_embed_ri,&
27 : kg_tnadd_none
28 : USE input_section_types, ONLY: section_vals_get,&
29 : section_vals_get_subs_vals,&
30 : section_vals_type
31 : USE kg_environment_types, ONLY: kg_environment_type
32 : USE kinds, ONLY: dp
33 : USE lri_environment_methods, ONLY: calculate_lri_densities,&
34 : lri_kg_rho_update
35 : USE lri_environment_types, ONLY: lri_density_type,&
36 : lri_environment_type,&
37 : lri_kind_type
38 : USE lri_forces, ONLY: calculate_lri_forces
39 : USE lri_ks_methods, ONLY: calculate_lri_ks_matrix
40 : USE message_passing, ONLY: mp_para_env_type
41 : USE pw_env_types, ONLY: pw_env_get,&
42 : pw_env_type
43 : USE pw_methods, ONLY: pw_integral_ab,&
44 : pw_scale
45 : USE pw_pool_types, ONLY: pw_pool_type
46 : USE pw_types, ONLY: pw_c1d_gs_type,&
47 : pw_r3d_rs_type
48 : USE qs_environment_types, ONLY: get_qs_env,&
49 : qs_environment_type
50 : USE qs_integrate_potential, ONLY: integrate_v_rspace,&
51 : integrate_v_rspace_one_center
52 : USE qs_ks_types, ONLY: qs_ks_env_type
53 : USE qs_rho_methods, ONLY: qs_rho_rebuild,&
54 : qs_rho_update_rho
55 : USE qs_rho_types, ONLY: qs_rho_create,&
56 : qs_rho_get,&
57 : qs_rho_release,&
58 : qs_rho_set,&
59 : qs_rho_type,&
60 : qs_rho_unset_rho_ao
61 : USE qs_vxc, ONLY: qs_vxc_create
62 : USE virial_types, ONLY: virial_type
63 : USE xc, ONLY: xc_uses_kinetic_energy_density
64 : #include "./base/base_uses.f90"
65 :
66 : IMPLICIT NONE
67 :
68 : PRIVATE
69 :
70 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'kg_correction'
71 :
72 : PUBLIC :: kg_ekin_subset
73 :
74 : CONTAINS
75 :
76 : ! **************************************************************************************************
77 : !> \brief Calculates the subsystem Hohenberg-Kohn kinetic energy and the forces
78 : !> \param qs_env ...
79 : !> \param ks_matrix ...
80 : !> \param ekin_mol ...
81 : !> \param calc_force ...
82 : !> \param do_kernel Contribution of kinetic energy functional to kernel in response calculation
83 : !> \param pmat_ext Response density used to fold 2nd deriv or to integrate kinetic energy functional
84 : !> \par History
85 : !> 2012.06 created [Martin Haeufel]
86 : !> 2014.01 added atomic potential option [JGH]
87 : !> 2020.01 Added KG contribution to linear response [fbelle]
88 : !> \author Martin Haeufel and Florian Schiffmann
89 : ! **************************************************************************************************
90 1048 : SUBROUTINE kg_ekin_subset(qs_env, ks_matrix, ekin_mol, calc_force, do_kernel, pmat_ext)
91 : TYPE(qs_environment_type), POINTER :: qs_env
92 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_matrix
93 : REAL(KIND=dp), INTENT(out) :: ekin_mol
94 : LOGICAL, INTENT(IN) :: calc_force, do_kernel
95 : TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
96 : POINTER :: pmat_ext
97 :
98 : LOGICAL :: lrigpw
99 : TYPE(dft_control_type), POINTER :: dft_control
100 : TYPE(kg_environment_type), POINTER :: kg_env
101 :
102 1048 : CALL get_qs_env(qs_env, kg_env=kg_env, dft_control=dft_control)
103 1048 : lrigpw = dft_control%qs_control%lrigpw
104 : IF ((kg_env%tnadd_method == kg_tnadd_embed_ri .OR. &
105 1048 : (kg_env%tnadd_method == kg_tnadd_embed .AND. lrigpw)) .AND. &
106 : kg_uses_kinetic_energy_density(kg_env, dft_control%lsd)) THEN
107 0 : CPABORT("KG LRI/RI embedding with meta-kinetic energy functionals not implemented")
108 : END IF
109 1048 : IF (kg_env%tnadd_method == kg_tnadd_embed) THEN
110 742 : IF (lrigpw) THEN
111 20 : CALL kg_ekin_embed_lri(qs_env, kg_env, ks_matrix, ekin_mol, calc_force)
112 : ELSE
113 : CALL kg_ekin_embed(qs_env, kg_env, ks_matrix, ekin_mol, calc_force, &
114 722 : do_kernel, pmat_ext)
115 : END IF
116 306 : ELSE IF (kg_env%tnadd_method == kg_tnadd_embed_ri) THEN
117 : CALL kg_ekin_ri_embed(qs_env, kg_env, ks_matrix, ekin_mol, calc_force, &
118 96 : do_kernel, pmat_ext)
119 210 : ELSE IF (kg_env%tnadd_method == kg_tnadd_atomic) THEN
120 172 : CALL kg_ekin_atomic(qs_env, ks_matrix, ekin_mol)
121 38 : ELSE IF (kg_env%tnadd_method == kg_tnadd_none) THEN
122 38 : ekin_mol = 0.0_dp
123 : ELSE
124 0 : CPABORT("Unknown KG embedding method")
125 : END IF
126 :
127 1048 : END SUBROUTINE kg_ekin_subset
128 :
129 : ! **************************************************************************************************
130 : !> \brief Returns whether the KG XC section needs the kinetic energy density.
131 : !> \param kg_env Kim-Gordon environment
132 : !> \param lsd spin-polarized calculation flag
133 : !> \return ...
134 : ! **************************************************************************************************
135 232 : FUNCTION kg_uses_kinetic_energy_density(kg_env, lsd) RESULT(res)
136 : TYPE(kg_environment_type), POINTER :: kg_env
137 : LOGICAL, INTENT(IN) :: lsd
138 : LOGICAL :: res
139 :
140 : LOGICAL :: explicit
141 : TYPE(section_vals_type), POINTER :: xc_fun_section
142 :
143 116 : res = .FALSE.
144 116 : IF (.NOT. ASSOCIATED(kg_env%xc_section_kg)) RETURN
145 :
146 116 : xc_fun_section => section_vals_get_subs_vals(kg_env%xc_section_kg, "XC_FUNCTIONAL")
147 116 : CALL section_vals_get(xc_fun_section, explicit=explicit)
148 116 : IF (explicit) res = xc_uses_kinetic_energy_density(xc_fun_section, lsd)
149 :
150 : END FUNCTION kg_uses_kinetic_energy_density
151 :
152 : ! **************************************************************************************************
153 : !> \brief ...
154 : !> \param qs_env ...
155 : !> \param kg_env ...
156 : !> \param ks_matrix ...
157 : !> \param ekin_mol ...
158 : !> \param calc_force ...
159 : !> \param do_kernel Contribution of kinetic energy functional to kernel in response calculation
160 : !> \param pmat_ext Response density used to fold 2nd deriv or to integrate kinetic energy functional
161 : ! **************************************************************************************************
162 1444 : SUBROUTINE kg_ekin_embed(qs_env, kg_env, ks_matrix, ekin_mol, calc_force, do_kernel, pmat_ext)
163 : TYPE(qs_environment_type), POINTER :: qs_env
164 : TYPE(kg_environment_type), POINTER :: kg_env
165 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_matrix
166 : REAL(KIND=dp), INTENT(out) :: ekin_mol
167 : LOGICAL, INTENT(IN) :: calc_force, do_kernel
168 : TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
169 : POINTER :: pmat_ext
170 :
171 : CHARACTER(LEN=*), PARAMETER :: routineN = 'kg_ekin_embed'
172 :
173 : CHARACTER(LEN=10) :: basis_type
174 : INTEGER :: handle, iounit, ispin, isub, nspins
175 : LOGICAL :: gapw, gapw_xc, use_gapw_soft, use_virial
176 : REAL(KIND=dp) :: alpha, ekin_imol
177 : REAL(KIND=dp), DIMENSION(3, 3) :: xcvirial
178 : TYPE(cp_logger_type), POINTER :: logger
179 722 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: density_matrix
180 : TYPE(dft_control_type), POINTER :: dft_control
181 722 : TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho1_g
182 : TYPE(pw_env_type), POINTER :: pw_env
183 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
184 722 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho1_r, rho_r, tau1_r, vxc_rho, vxc_tau
185 : TYPE(qs_ks_env_type), POINTER :: ks_env
186 : TYPE(qs_rho_type), POINTER :: old_rho, rho1, rho1_use, rho1_xc, &
187 : rho_struct, rho_use, rho_xc
188 : TYPE(section_vals_type), POINTER :: xc_section
189 : TYPE(virial_type), POINTER :: virial
190 :
191 722 : CALL timeset(routineN, handle)
192 :
193 722 : logger => cp_get_default_logger()
194 722 : iounit = cp_logger_get_default_unit_nr(logger)
195 :
196 722 : NULLIFY (ks_env, dft_control, old_rho, pw_env, rho1_use, rho1_xc, rho_struct, &
197 722 : rho_use, rho_xc, virial, vxc_rho, vxc_tau)
198 :
199 : CALL get_qs_env(qs_env, &
200 : ks_env=ks_env, &
201 : rho=old_rho, &
202 : dft_control=dft_control, &
203 : virial=virial, &
204 722 : pw_env=pw_env)
205 722 : nspins = dft_control%nspins
206 722 : gapw = dft_control%qs_control%gapw
207 722 : gapw_xc = dft_control%qs_control%gapw_xc
208 722 : use_gapw_soft = gapw .OR. gapw_xc
209 722 : IF (use_gapw_soft) THEN
210 98 : basis_type = "ORB_SOFT"
211 : ELSE
212 624 : basis_type = "ORB"
213 : END IF
214 722 : use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
215 722 : use_virial = use_virial .AND. calc_force
216 :
217 : ! Kernel potential in response calculation (no forces calculated at this point)
218 : ! requires spin-factor
219 : ! alpha = 2 closed-shell
220 : ! alpha = 1 open-shell
221 722 : alpha = 1.0_dp
222 722 : IF (do_kernel .AND. .NOT. calc_force .AND. nspins == 1) alpha = 2.0_dp
223 :
224 722 : NULLIFY (auxbas_pw_pool)
225 722 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
226 :
227 : ! get the density matrix
228 722 : CALL qs_rho_get(old_rho, rho_ao=density_matrix)
229 : ! allocate and initialize the density
230 722 : ALLOCATE (rho_struct)
231 722 : CALL qs_rho_create(rho_struct)
232 : ! set the density matrix to the blocked matrix
233 722 : CALL qs_rho_set(rho_struct, rho_ao=density_matrix) ! blocked_matrix
234 722 : CALL qs_rho_rebuild(rho_struct, qs_env, rebuild_ao=.FALSE., rebuild_grids=.TRUE.)
235 722 : IF (gapw_xc) THEN
236 22 : ALLOCATE (rho_xc)
237 22 : CALL qs_rho_create(rho_xc)
238 22 : CALL qs_rho_rebuild(rho_xc, qs_env, rebuild_ao=.TRUE., rebuild_grids=.TRUE.)
239 : END IF
240 : ! full density kinetic energy term
241 : IF (gapw_xc) THEN
242 22 : CALL qs_rho_update_rho(rho_struct, qs_env, rho_xc_external=rho_xc)
243 22 : rho_use => rho_xc
244 : ELSE
245 700 : CALL qs_rho_update_rho(rho_struct, qs_env)
246 700 : rho_use => rho_struct
247 : END IF
248 : ! get blocked density that has been put on grid
249 722 : CALL qs_rho_get(rho_use, rho_r=rho_r)
250 :
251 : ! If external density associated then it is needed either for
252 : ! 1) folding of second derivative while partially integrating, or
253 : ! 2) integration of response forces
254 722 : NULLIFY (rho1)
255 722 : IF (PRESENT(pmat_ext)) THEN
256 58 : ALLOCATE (rho1)
257 58 : CALL qs_rho_create(rho1)
258 58 : CALL qs_rho_set(rho1, rho_ao=pmat_ext)
259 58 : CALL qs_rho_rebuild(rho1, qs_env, rebuild_ao=.FALSE., rebuild_grids=.TRUE.)
260 58 : IF (gapw_xc) THEN
261 0 : ALLOCATE (rho1_xc)
262 0 : CALL qs_rho_create(rho1_xc)
263 0 : CALL qs_rho_rebuild(rho1_xc, qs_env, rebuild_ao=.TRUE., rebuild_grids=.TRUE.)
264 0 : CALL qs_rho_update_rho(rho1, qs_env, rho_xc_external=rho1_xc)
265 0 : rho1_use => rho1_xc
266 : ELSE
267 58 : CALL qs_rho_update_rho(rho1, qs_env)
268 58 : rho1_use => rho1
269 : END IF
270 : END IF
271 :
272 : ! XC-section pointing to kinetic energy functional in KG environment
273 : NULLIFY (xc_section)
274 722 : xc_section => kg_env%xc_section_kg
275 :
276 722 : ekin_imol = 0.0_dp
277 :
278 : ! calculate xc potential or kernel
279 722 : IF (do_kernel) THEN
280 : ! derivation wrt to rho_struct and evaluation at rho_struct
281 142 : IF (use_virial) virial%pv_xc = 0.0_dp
282 46 : CALL qs_rho_get(rho1_use, rho_r=rho1_r, rho_g=rho1_g, tau_r=tau1_r)
283 : CALL create_kernel(qs_env, &
284 : vxc=vxc_rho, &
285 : vxc_tau=vxc_tau, &
286 : rho=rho_use, &
287 : rho1_r=rho1_r, &
288 : rho1_g=rho1_g, &
289 : tau1_r=tau1_r, &
290 : xc_section=xc_section, &
291 : compute_virial=use_virial, &
292 46 : virial_xc=virial%pv_xc)
293 : ELSE
294 : CALL qs_vxc_create(ks_env=ks_env, &
295 : rho_struct=rho_use, &
296 : xc_section=xc_section, &
297 : vxc_rho=vxc_rho, &
298 : vxc_tau=vxc_tau, &
299 676 : exc=ekin_imol)
300 : END IF
301 :
302 : ! Integrate xc-potential with external density for outer response forces
303 722 : IF (PRESENT(pmat_ext) .AND. .NOT. do_kernel) THEN
304 12 : CALL qs_rho_get(rho1, rho_ao=density_matrix)
305 12 : CALL qs_rho_get(rho1_use, rho_r=rho1_r, tau_r=tau1_r)
306 : ! Direct volume term of virial
307 : ! xc-potential is unscaled
308 12 : IF (use_virial) THEN
309 8 : ekin_imol = 0.0_dp
310 16 : DO ispin = 1, nspins
311 8 : ekin_imol = ekin_imol + pw_integral_ab(rho1_r(ispin), vxc_rho(ispin))
312 16 : IF (ASSOCIATED(vxc_tau)) THEN
313 0 : ekin_imol = ekin_imol + pw_integral_ab(tau1_r(ispin), vxc_tau(ispin))
314 : END IF
315 : END DO
316 : END IF
317 : END IF
318 :
319 1444 : DO ispin = 1, nspins
320 1444 : CALL pw_scale(vxc_rho(ispin), alpha*vxc_rho(ispin)%pw_grid%dvol)
321 : END DO
322 :
323 1444 : DO ispin = 1, nspins
324 : CALL integrate_v_rspace(v_rspace=vxc_rho(ispin), &
325 : pmat=density_matrix(ispin), hmat=ks_matrix(ispin), &
326 722 : qs_env=qs_env, calculate_forces=calc_force, gapw=use_gapw_soft)
327 722 : CALL auxbas_pw_pool%give_back_pw(vxc_rho(ispin))
328 1444 : IF (ASSOCIATED(vxc_tau)) THEN
329 34 : CALL pw_scale(vxc_tau(ispin), alpha*vxc_tau(ispin)%pw_grid%dvol)
330 : CALL integrate_v_rspace(v_rspace=vxc_tau(ispin), &
331 : pmat=density_matrix(ispin), hmat=ks_matrix(ispin), &
332 : qs_env=qs_env, compute_tau=.TRUE., &
333 34 : calculate_forces=calc_force, gapw=use_gapw_soft)
334 34 : CALL auxbas_pw_pool%give_back_pw(vxc_tau(ispin))
335 : END IF
336 : END DO
337 722 : DEALLOCATE (vxc_rho)
338 722 : IF (ASSOCIATED(vxc_tau)) DEALLOCATE (vxc_tau)
339 722 : ekin_mol = -ekin_imol
340 722 : xcvirial(1:3, 1:3) = 0.0_dp
341 722 : IF (use_virial) THEN
342 312 : xcvirial(1:3, 1:3) = xcvirial(1:3, 1:3) - virial%pv_xc(1:3, 1:3)
343 : END IF
344 :
345 : ! loop over all subsets
346 2320 : DO isub = 1, kg_env%nsubsets
347 : ! calculate the densities for the given blocked density matrix
348 : ! pass the subset task_list
349 1598 : IF (gapw_xc) THEN
350 : CALL qs_rho_update_rho(rho_struct, qs_env, rho_xc_external=rho_xc, &
351 : task_list_external=kg_env%subset(isub)%task_list, &
352 66 : task_list_external_soft=kg_env%subset(isub)%task_list)
353 66 : rho_use => rho_xc
354 : ELSE
355 : CALL qs_rho_update_rho(rho_struct, qs_env, &
356 1532 : task_list_external=kg_env%subset(isub)%task_list)
357 1532 : rho_use => rho_struct
358 : END IF
359 : ! Same for external (response) density if present
360 1598 : IF (PRESENT(pmat_ext)) THEN
361 116 : IF (gapw_xc) THEN
362 : CALL qs_rho_update_rho(rho1, qs_env, rho_xc_external=rho1_xc, &
363 : task_list_external=kg_env%subset(isub)%task_list, &
364 0 : task_list_external_soft=kg_env%subset(isub)%task_list)
365 0 : rho1_use => rho1_xc
366 : ELSE
367 : CALL qs_rho_update_rho(rho1, qs_env, &
368 116 : task_list_external=kg_env%subset(isub)%task_list)
369 116 : rho1_use => rho1
370 : END IF
371 : END IF
372 :
373 1598 : ekin_imol = 0.0_dp
374 1598 : NULLIFY (vxc_rho, vxc_tau)
375 :
376 : ! calculate Hohenberg-Kohn kinetic energy of the density
377 : ! corresponding to the remaining molecular block(s)
378 : ! info per block in rho_struct now
379 :
380 : ! calculate xc-potential or kernel
381 1598 : IF (do_kernel) THEN
382 284 : IF (use_virial) virial%pv_xc = 0.0_dp
383 92 : CALL qs_rho_get(rho1_use, rho_r=rho1_r, rho_g=rho1_g, tau_r=tau1_r)
384 : CALL create_kernel(qs_env, &
385 : vxc=vxc_rho, &
386 : vxc_tau=vxc_tau, &
387 : rho=rho_use, &
388 : rho1_r=rho1_r, &
389 : rho1_g=rho1_g, &
390 : tau1_r=tau1_r, &
391 : xc_section=xc_section, &
392 : compute_virial=use_virial, &
393 92 : virial_xc=virial%pv_xc)
394 : ELSE
395 : CALL qs_vxc_create(ks_env=ks_env, &
396 : rho_struct=rho_use, &
397 : xc_section=xc_section, &
398 : vxc_rho=vxc_rho, &
399 : vxc_tau=vxc_tau, &
400 1506 : exc=ekin_imol)
401 : END IF
402 :
403 : ! Integrate with response density for outer response forces
404 1598 : IF (PRESENT(pmat_ext) .AND. .NOT. do_kernel) THEN
405 24 : CALL qs_rho_get(rho1, rho_ao=density_matrix)
406 24 : CALL qs_rho_get(rho1_use, rho_r=rho1_r, tau_r=tau1_r)
407 : ! Direct volume term of virial
408 : ! xc-potential is unscaled
409 24 : IF (use_virial) THEN
410 16 : ekin_imol = 0.0_dp
411 32 : DO ispin = 1, nspins
412 16 : ekin_imol = ekin_imol + pw_integral_ab(rho1_r(ispin), vxc_rho(ispin))
413 32 : IF (ASSOCIATED(vxc_tau)) THEN
414 0 : ekin_imol = ekin_imol + pw_integral_ab(tau1_r(ispin), vxc_tau(ispin))
415 : END IF
416 : END DO
417 : END IF
418 : END IF
419 :
420 3196 : DO ispin = 1, nspins
421 1598 : CALL pw_scale(vxc_rho(ispin), -alpha*vxc_rho(ispin)%pw_grid%dvol)
422 :
423 : CALL integrate_v_rspace(v_rspace=vxc_rho(ispin), &
424 : pmat=density_matrix(ispin), &
425 : hmat=ks_matrix(ispin), &
426 : qs_env=qs_env, &
427 : calculate_forces=calc_force, &
428 : basis_type=basis_type, &
429 1598 : task_list_external=kg_env%subset(isub)%task_list)
430 : ! clean up vxc_rho
431 1598 : CALL auxbas_pw_pool%give_back_pw(vxc_rho(ispin))
432 3196 : IF (ASSOCIATED(vxc_tau)) THEN
433 102 : CALL pw_scale(vxc_tau(ispin), -alpha*vxc_tau(ispin)%pw_grid%dvol)
434 : CALL integrate_v_rspace(v_rspace=vxc_tau(ispin), &
435 : pmat=density_matrix(ispin), &
436 : hmat=ks_matrix(ispin), &
437 : qs_env=qs_env, &
438 : compute_tau=.TRUE., &
439 : calculate_forces=calc_force, &
440 : basis_type=basis_type, &
441 102 : task_list_external=kg_env%subset(isub)%task_list)
442 : ! clean up vxc_rho
443 102 : CALL auxbas_pw_pool%give_back_pw(vxc_tau(ispin))
444 : END IF
445 : END DO
446 1598 : DEALLOCATE (vxc_rho)
447 1598 : IF (ASSOCIATED(vxc_tau)) DEALLOCATE (vxc_tau)
448 :
449 1598 : ekin_mol = ekin_mol + ekin_imol
450 :
451 2320 : IF (use_virial) THEN
452 728 : xcvirial(1:3, 1:3) = xcvirial(1:3, 1:3) + virial%pv_xc(1:3, 1:3)
453 : END IF
454 :
455 : END DO
456 :
457 722 : IF (use_virial) THEN
458 312 : virial%pv_xc(1:3, 1:3) = xcvirial(1:3, 1:3)
459 : END IF
460 :
461 : ! clean up rho_struct
462 722 : CALL qs_rho_unset_rho_ao(rho_struct)
463 722 : CALL qs_rho_release(rho_struct)
464 722 : DEALLOCATE (rho_struct)
465 722 : IF (ASSOCIATED(rho_xc)) THEN
466 22 : CALL qs_rho_release(rho_xc)
467 22 : DEALLOCATE (rho_xc)
468 : END IF
469 722 : IF (PRESENT(pmat_ext)) THEN
470 58 : CALL qs_rho_unset_rho_ao(rho1)
471 58 : CALL qs_rho_release(rho1)
472 58 : DEALLOCATE (rho1)
473 58 : IF (ASSOCIATED(rho1_xc)) THEN
474 0 : CALL qs_rho_release(rho1_xc)
475 0 : DEALLOCATE (rho1_xc)
476 : END IF
477 : END IF
478 :
479 722 : CALL timestop(handle)
480 :
481 722 : END SUBROUTINE kg_ekin_embed
482 :
483 : ! **************************************************************************************************
484 : !> \brief ...
485 : !> \param qs_env ...
486 : !> \param kg_env ...
487 : !> \param ks_matrix ...
488 : !> \param ekin_mol ...
489 : !> \param calc_force ...
490 : ! **************************************************************************************************
491 20 : SUBROUTINE kg_ekin_embed_lri(qs_env, kg_env, ks_matrix, ekin_mol, calc_force)
492 : TYPE(qs_environment_type), POINTER :: qs_env
493 : TYPE(kg_environment_type), POINTER :: kg_env
494 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_matrix
495 : REAL(KIND=dp), INTENT(out) :: ekin_mol
496 : LOGICAL :: calc_force
497 :
498 : CHARACTER(LEN=*), PARAMETER :: routineN = 'kg_ekin_embed_lri'
499 :
500 : INTEGER :: color, handle, iatom, ikind, imol, &
501 : ispin, isub, natom, nkind, nspins
502 : INTEGER, ALLOCATABLE, DIMENSION(:) :: atomlist
503 : LOGICAL :: use_virial
504 : REAL(KIND=dp) :: ekin_imol
505 : REAL(KIND=dp), DIMENSION(3, 3) :: xcvirial
506 20 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
507 20 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: density_matrix, ksmat
508 20 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: pmat
509 : TYPE(dft_control_type), POINTER :: dft_control
510 : TYPE(lri_density_type), POINTER :: lri_density
511 : TYPE(lri_environment_type), POINTER :: lri_env
512 20 : TYPE(lri_kind_type), DIMENSION(:), POINTER :: lri_v_int
513 : TYPE(mp_para_env_type), POINTER :: para_env
514 : TYPE(pw_env_type), POINTER :: pw_env
515 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
516 20 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: vxc_rho, vxc_tau
517 : TYPE(qs_ks_env_type), POINTER :: ks_env
518 : TYPE(qs_rho_type), POINTER :: old_rho, rho_struct
519 : TYPE(virial_type), POINTER :: virial
520 :
521 20 : CALL timeset(routineN, handle)
522 :
523 20 : NULLIFY (vxc_rho, vxc_tau, old_rho, rho_struct, ks_env)
524 :
525 20 : CALL get_qs_env(qs_env, dft_control=dft_control)
526 :
527 : ! get set of molecules, natom, dft_control, pw_env
528 : CALL get_qs_env(qs_env, &
529 : ks_env=ks_env, &
530 : rho=old_rho, &
531 : natom=natom, &
532 : dft_control=dft_control, &
533 : virial=virial, &
534 : para_env=para_env, &
535 20 : pw_env=pw_env)
536 :
537 20 : nspins = dft_control%nspins
538 20 : use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
539 0 : use_virial = use_virial .AND. calc_force
540 :
541 20 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
542 :
543 : ! get the density matrix
544 20 : CALL qs_rho_get(old_rho, rho_ao=density_matrix)
545 : ! allocate and initialize the density
546 20 : ALLOCATE (rho_struct)
547 20 : CALL qs_rho_create(rho_struct)
548 : ! set the density matrix to the blocked matrix
549 20 : CALL qs_rho_set(rho_struct, rho_ao=density_matrix) ! blocked_matrix
550 20 : CALL qs_rho_rebuild(rho_struct, qs_env, rebuild_ao=.FALSE., rebuild_grids=.TRUE.)
551 :
552 20 : CALL get_qs_env(qs_env, lri_env=lri_env, lri_density=lri_density, nkind=nkind)
553 20 : IF (lri_env%exact_1c_terms) THEN
554 0 : CPABORT(" KG with LRI and exact one-center terms not implemented")
555 : END IF
556 60 : ALLOCATE (atomlist(natom))
557 40 : DO ispin = 1, nspins
558 20 : lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
559 80 : DO ikind = 1, nkind
560 14660 : lri_v_int(ikind)%v_int = 0.0_dp
561 60 : IF (calc_force) THEN
562 46 : lri_v_int(ikind)%v_dadr = 0.0_dp
563 46 : lri_v_int(ikind)%v_dfdr = 0.0_dp
564 : END IF
565 : END DO
566 : END DO
567 :
568 : ! full density kinetic energy term
569 120 : atomlist = 1
570 20 : CALL lri_kg_rho_update(rho_struct, qs_env, lri_env, lri_density, atomlist)
571 : ekin_imol = 0.0_dp
572 : CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho_struct, xc_section=kg_env%xc_section_kg, &
573 20 : vxc_rho=vxc_rho, vxc_tau=vxc_tau, exc=ekin_imol)
574 20 : IF (ASSOCIATED(vxc_tau)) THEN
575 0 : CPABORT(" KG with meta-kinetic energy functionals not implemented")
576 : END IF
577 40 : DO ispin = 1, nspins
578 20 : CALL pw_scale(vxc_rho(ispin), vxc_rho(ispin)%pw_grid%dvol)
579 20 : lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
580 20 : CALL integrate_v_rspace_one_center(vxc_rho(ispin), qs_env, lri_v_int, calc_force, "LRI_AUX")
581 40 : CALL auxbas_pw_pool%give_back_pw(vxc_rho(ispin))
582 : END DO
583 20 : DEALLOCATE (vxc_rho)
584 20 : ekin_mol = -ekin_imol
585 20 : xcvirial(1:3, 1:3) = 0.0_dp
586 20 : IF (use_virial) xcvirial(1:3, 1:3) = xcvirial(1:3, 1:3) - virial%pv_xc(1:3, 1:3)
587 :
588 : ! loop over all subsets
589 60 : DO isub = 1, kg_env%nsubsets
590 40 : atomlist = 0
591 240 : DO iatom = 1, natom
592 200 : imol = kg_env%atom_to_molecule(iatom)
593 200 : color = kg_env%subset_of_mol(imol)
594 240 : IF (color == isub) atomlist(iatom) = 1
595 : END DO
596 40 : CALL lri_kg_rho_update(rho_struct, qs_env, lri_env, lri_density, atomlist)
597 :
598 : ekin_imol = 0.0_dp
599 : ! calc Hohenberg-Kohn kin. energy of the density corresp. to the remaining molecular block(s)
600 : CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho_struct, xc_section=kg_env%xc_section_kg, &
601 40 : vxc_rho=vxc_rho, vxc_tau=vxc_tau, exc=ekin_imol)
602 40 : ekin_mol = ekin_mol + ekin_imol
603 :
604 80 : DO ispin = 1, nspins
605 40 : CALL pw_scale(vxc_rho(ispin), -vxc_rho(ispin)%pw_grid%dvol)
606 40 : lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
607 : CALL integrate_v_rspace_one_center(vxc_rho(ispin), qs_env, &
608 : lri_v_int, calc_force, &
609 40 : "LRI_AUX", atomlist=atomlist)
610 : ! clean up vxc_rho
611 80 : CALL auxbas_pw_pool%give_back_pw(vxc_rho(ispin))
612 : END DO
613 40 : DEALLOCATE (vxc_rho)
614 :
615 100 : IF (use_virial) THEN
616 0 : xcvirial(1:3, 1:3) = xcvirial(1:3, 1:3) + virial%pv_xc(1:3, 1:3)
617 : END IF
618 :
619 : END DO
620 :
621 20 : IF (use_virial) THEN
622 0 : virial%pv_xc(1:3, 1:3) = xcvirial(1:3, 1:3)
623 : END IF
624 :
625 20 : CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
626 40 : ALLOCATE (ksmat(1))
627 40 : DO ispin = 1, nspins
628 20 : lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
629 60 : DO ikind = 1, nkind
630 29300 : CALL para_env%sum(lri_v_int(ikind)%v_int)
631 : END DO
632 20 : ksmat(1)%matrix => ks_matrix(ispin)%matrix
633 40 : CALL calculate_lri_ks_matrix(lri_env, lri_v_int, ksmat, atomic_kind_set)
634 : END DO
635 20 : IF (calc_force) THEN
636 2 : pmat(1:nspins, 1:1) => density_matrix(1:nspins)
637 2 : CALL calculate_lri_forces(lri_env, lri_density, qs_env, pmat, atomic_kind_set)
638 : END IF
639 20 : DEALLOCATE (atomlist, ksmat)
640 :
641 : ! clean up rho_struct
642 20 : CALL qs_rho_unset_rho_ao(rho_struct)
643 20 : CALL qs_rho_release(rho_struct)
644 20 : DEALLOCATE (rho_struct)
645 :
646 20 : CALL timestop(handle)
647 :
648 60 : END SUBROUTINE kg_ekin_embed_lri
649 :
650 : ! **************************************************************************************************
651 : !> \brief ...
652 : !> \param qs_env ...
653 : !> \param kg_env ...
654 : !> \param ks_matrix ...
655 : !> \param ekin_mol ...
656 : !> \param calc_force ...
657 : !> \param do_kernel Contribution of kinetic energy functional to kernel in response calculation
658 : !> \param pmat_ext Response density used to fold 2nd deriv or to integrate kinetic energy functional
659 : ! **************************************************************************************************
660 96 : SUBROUTINE kg_ekin_ri_embed(qs_env, kg_env, ks_matrix, ekin_mol, calc_force, &
661 : do_kernel, pmat_ext)
662 : TYPE(qs_environment_type), POINTER :: qs_env
663 : TYPE(kg_environment_type), POINTER :: kg_env
664 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_matrix
665 : REAL(KIND=dp), INTENT(out) :: ekin_mol
666 : LOGICAL :: calc_force, do_kernel
667 : TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
668 : POINTER :: pmat_ext
669 :
670 : CHARACTER(LEN=*), PARAMETER :: routineN = 'kg_ekin_ri_embed'
671 :
672 : INTEGER :: color, handle, iatom, ikind, imol, &
673 : iounit, ispin, isub, natom, nkind, &
674 : nspins
675 96 : INTEGER, ALLOCATABLE, DIMENSION(:) :: atomlist
676 96 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
677 : LOGICAL :: use_virial
678 : REAL(KIND=dp) :: alpha, ekin_imol
679 : REAL(KIND=dp), DIMENSION(3, 3) :: xcvirial
680 96 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
681 : TYPE(cp_logger_type), POINTER :: logger
682 96 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: density_matrix, ksmat
683 96 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: pmat
684 : TYPE(dft_control_type), POINTER :: dft_control
685 : TYPE(lri_density_type), POINTER :: lri_density, lri_rho1
686 : TYPE(lri_environment_type), POINTER :: lri_env, lri_env1
687 96 : TYPE(lri_kind_type), DIMENSION(:), POINTER :: lri_v_int
688 : TYPE(mp_para_env_type), POINTER :: para_env
689 96 : TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho1_g
690 : TYPE(pw_env_type), POINTER :: pw_env
691 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
692 96 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho1_r, tau1_r, vxc_rho, vxc_tau
693 : TYPE(qs_ks_env_type), POINTER :: ks_env
694 : TYPE(qs_rho_type), POINTER :: rho, rho1, rho_struct
695 : TYPE(section_vals_type), POINTER :: xc_section
696 : TYPE(virial_type), POINTER :: virial
697 :
698 96 : CALL timeset(routineN, handle)
699 :
700 96 : logger => cp_get_default_logger()
701 96 : iounit = cp_logger_get_default_unit_nr(logger)
702 :
703 : CALL get_qs_env(qs_env, &
704 : ks_env=ks_env, &
705 : rho=rho, &
706 : natom=natom, &
707 : nkind=nkind, &
708 : dft_control=dft_control, &
709 : virial=virial, &
710 : para_env=para_env, &
711 96 : pw_env=pw_env)
712 :
713 96 : nspins = dft_control%nspins
714 130 : use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
715 38 : use_virial = use_virial .AND. calc_force
716 :
717 : ! Kernel potential in response calculation (no forces calculated at this point)
718 : ! requires spin-factor
719 : ! alpha = 2 closed-shell
720 : ! alpha = 1 open-shell
721 96 : alpha = 1.0_dp
722 96 : IF (do_kernel .AND. .NOT. calc_force .AND. nspins == 1) alpha = 2.0_dp
723 :
724 96 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
725 :
726 : ! get the density matrix
727 96 : CALL qs_rho_get(rho, rho_ao=density_matrix)
728 : ! allocate and initialize the density
729 : NULLIFY (rho_struct)
730 96 : ALLOCATE (rho_struct)
731 96 : CALL qs_rho_create(rho_struct)
732 : ! set the density matrix to the blocked matrix
733 96 : CALL qs_rho_set(rho_struct, rho_ao=density_matrix)
734 96 : CALL qs_rho_rebuild(rho_struct, qs_env, rebuild_ao=.FALSE., rebuild_grids=.TRUE.)
735 :
736 96 : CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
737 96 : ALLOCATE (cell_to_index(1, 1, 1))
738 96 : cell_to_index(1, 1, 1) = 1
739 96 : lri_env => kg_env%lri_env
740 96 : lri_density => kg_env%lri_density
741 :
742 96 : NULLIFY (pmat)
743 480 : ALLOCATE (pmat(nspins, 1))
744 192 : DO ispin = 1, nspins
745 192 : pmat(ispin, 1)%matrix => density_matrix(ispin)%matrix
746 : END DO
747 : CALL calculate_lri_densities(lri_env, lri_density, qs_env, pmat, cell_to_index, &
748 96 : rho_struct, atomic_kind_set, para_env, response_density=.FALSE.)
749 96 : kg_env%lri_density => lri_density
750 :
751 96 : DEALLOCATE (pmat)
752 :
753 96 : IF (PRESENT(pmat_ext)) THEN
754 : ! If external density associated then it is needed either for
755 : ! 1) folding of second derivative while partially integrating, or
756 : ! 2) integration of response forces
757 : NULLIFY (rho1)
758 0 : ALLOCATE (rho1)
759 0 : CALL qs_rho_create(rho1)
760 0 : CALL qs_rho_set(rho1, rho_ao=pmat_ext)
761 0 : CALL qs_rho_rebuild(rho1, qs_env, rebuild_ao=.FALSE., rebuild_grids=.TRUE.)
762 :
763 0 : lri_env1 => kg_env%lri_env1
764 0 : lri_rho1 => kg_env%lri_rho1
765 : ! calculate external density as LRI-densities
766 0 : NULLIFY (pmat)
767 0 : ALLOCATE (pmat(nspins, 1))
768 0 : DO ispin = 1, nspins
769 0 : pmat(ispin, 1)%matrix => pmat_ext(ispin)%matrix
770 : END DO
771 : CALL calculate_lri_densities(lri_env1, lri_rho1, qs_env, pmat, cell_to_index, &
772 0 : rho1, atomic_kind_set, para_env, response_density=.FALSE.)
773 0 : kg_env%lri_rho1 => lri_rho1
774 0 : DEALLOCATE (pmat)
775 :
776 : END IF
777 :
778 : ! XC-section pointing to kinetic energy functional in KG environment
779 : NULLIFY (xc_section)
780 96 : xc_section => kg_env%xc_section_kg
781 :
782 : ! full density kinetic energy term
783 96 : ekin_imol = 0.0_dp
784 96 : NULLIFY (vxc_rho, vxc_tau)
785 :
786 : ! calculate xc potential or kernel
787 96 : IF (do_kernel) THEN
788 : ! kernel total
789 : ! derivation wrt to rho_struct and evaluation at rho_struct
790 0 : CALL qs_rho_get(rho1, rho_r=rho1_r, rho_g=rho1_g, tau_r=tau1_r)
791 : CALL create_kernel(qs_env, &
792 : vxc=vxc_rho, &
793 : vxc_tau=vxc_tau, &
794 : rho=rho_struct, &
795 : rho1_r=rho1_r, &
796 : rho1_g=rho1_g, &
797 : tau1_r=tau1_r, &
798 0 : xc_section=xc_section)
799 : ELSE
800 : ! vxc total
801 : CALL qs_vxc_create(ks_env=ks_env, &
802 : rho_struct=rho_struct, &
803 : xc_section=xc_section, &
804 : vxc_rho=vxc_rho, &
805 : vxc_tau=vxc_tau, &
806 96 : exc=ekin_imol)
807 :
808 : END IF
809 :
810 96 : IF (ASSOCIATED(vxc_tau)) THEN
811 0 : CPABORT(" KG with meta-kinetic energy functionals not implemented")
812 : END IF
813 :
814 192 : DO ispin = 1, nspins
815 96 : CALL pw_scale(vxc_rho(ispin), alpha*vxc_rho(ispin)%pw_grid%dvol)
816 :
817 96 : IF (PRESENT(pmat_ext) .AND. .NOT. do_kernel) THEN
818 : ! int w/ pmat_ext
819 0 : lri_v_int => lri_rho1%lri_coefs(ispin)%lri_kinds
820 : ELSE
821 : ! int w/ rho_ao
822 96 : lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
823 : END IF
824 96 : CALL integrate_v_rspace_one_center(vxc_rho(ispin), qs_env, lri_v_int, calc_force, "LRI_AUX")
825 192 : CALL auxbas_pw_pool%give_back_pw(vxc_rho(ispin))
826 : END DO
827 :
828 96 : DEALLOCATE (vxc_rho)
829 96 : ekin_mol = -ekin_imol
830 96 : xcvirial(1:3, 1:3) = 0.0_dp
831 144 : IF (use_virial) xcvirial(1:3, 1:3) = xcvirial(1:3, 1:3) - virial%pv_xc(1:3, 1:3)
832 :
833 : ! loop over all subsets
834 288 : ALLOCATE (atomlist(natom))
835 288 : DO isub = 1, kg_env%nsubsets
836 192 : atomlist = 0
837 1152 : DO iatom = 1, natom
838 960 : imol = kg_env%atom_to_molecule(iatom)
839 960 : color = kg_env%subset_of_mol(imol)
840 1152 : IF (color == isub) atomlist(iatom) = 1
841 : END DO
842 : ! update ground-state density
843 192 : CALL lri_kg_rho_update(rho_struct, qs_env, lri_env, lri_density, atomlist)
844 :
845 : ! Same for external (response) density if present
846 192 : IF (PRESENT(pmat_ext)) THEN
847 : ! update response density
848 0 : CALL lri_kg_rho_update(rho1, qs_env, lri_env1, lri_rho1, atomlist)
849 : END IF
850 :
851 192 : ekin_imol = 0.0_dp
852 : ! calc Hohenberg-Kohn kin. energy of the density corresp. to the remaining molecular block(s)
853 192 : NULLIFY (vxc_rho, vxc_tau)
854 :
855 : ! calculate xc potential or kernel
856 192 : IF (do_kernel) THEN
857 : ! subsys kernel
858 0 : CALL qs_rho_get(rho1, rho_r=rho1_r, rho_g=rho1_g, tau_r=tau1_r)
859 : CALL create_kernel(qs_env, &
860 : vxc=vxc_rho, &
861 : vxc_tau=vxc_tau, &
862 : rho=rho_struct, &
863 : rho1_r=rho1_r, &
864 : rho1_g=rho1_g, &
865 : tau1_r=tau1_r, &
866 0 : xc_section=xc_section)
867 : ELSE
868 :
869 : ! subsys xc-potential
870 : CALL qs_vxc_create(ks_env=ks_env, &
871 : rho_struct=rho_struct, &
872 : xc_section=xc_section, &
873 : vxc_rho=vxc_rho, &
874 : vxc_tau=vxc_tau, &
875 192 : exc=ekin_imol)
876 : END IF
877 192 : ekin_mol = ekin_mol + ekin_imol
878 :
879 384 : DO ispin = 1, nspins
880 192 : CALL pw_scale(vxc_rho(ispin), -alpha*vxc_rho(ispin)%pw_grid%dvol)
881 :
882 192 : IF (PRESENT(pmat_ext) .AND. .NOT. do_kernel) THEN
883 : ! int w/ pmat_ext
884 0 : lri_v_int => lri_rho1%lri_coefs(ispin)%lri_kinds
885 : ELSE
886 : ! int w/ rho_ao
887 192 : lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
888 : END IF
889 :
890 : CALL integrate_v_rspace_one_center(vxc_rho(ispin), qs_env, &
891 : lri_v_int, calc_force, &
892 192 : "LRI_AUX", atomlist=atomlist)
893 : ! clean up vxc_rho
894 384 : CALL auxbas_pw_pool%give_back_pw(vxc_rho(ispin))
895 : END DO
896 192 : DEALLOCATE (vxc_rho)
897 :
898 288 : IF (use_virial) THEN
899 104 : xcvirial(1:3, 1:3) = xcvirial(1:3, 1:3) + virial%pv_xc(1:3, 1:3)
900 : END IF
901 :
902 : END DO
903 :
904 96 : IF (use_virial) THEN
905 52 : virial%pv_xc(1:3, 1:3) = xcvirial(1:3, 1:3)
906 : END IF
907 :
908 192 : ALLOCATE (ksmat(1))
909 192 : DO ispin = 1, nspins
910 96 : ksmat(1)%matrix => ks_matrix(ispin)%matrix
911 192 : IF (PRESENT(pmat_ext) .AND. .NOT. do_kernel) THEN
912 : ! KS int with rho_ext"
913 0 : lri_v_int => lri_rho1%lri_coefs(ispin)%lri_kinds
914 0 : DO ikind = 1, nkind
915 0 : CALL para_env%sum(lri_v_int(ikind)%v_int)
916 : END DO
917 0 : CALL calculate_lri_ks_matrix(lri_env1, lri_v_int, ksmat, atomic_kind_set)
918 : ELSE
919 : ! KS int with rho_ao"
920 96 : lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
921 288 : DO ikind = 1, nkind
922 140640 : CALL para_env%sum(lri_v_int(ikind)%v_int)
923 : END DO
924 96 : CALL calculate_lri_ks_matrix(lri_env, lri_v_int, ksmat, atomic_kind_set)
925 : END IF
926 :
927 : END DO
928 96 : IF (calc_force) THEN
929 :
930 10 : NULLIFY (pmat)
931 40 : ALLOCATE (pmat(nspins, 1))
932 :
933 10 : IF (PRESENT(pmat_ext) .AND. .NOT. do_kernel) THEN
934 : ! Forces with rho_ext
935 0 : DO ispin = 1, nspins
936 0 : pmat(ispin, 1)%matrix => pmat_ext(ispin)%matrix
937 : END DO
938 0 : CALL calculate_lri_forces(lri_env1, lri_rho1, qs_env, pmat, atomic_kind_set)
939 : ELSE
940 : ! Forces with rho_ao
941 20 : DO ispin = 1, nspins
942 20 : pmat(ispin, 1)%matrix => density_matrix(ispin)%matrix
943 : END DO
944 10 : CALL calculate_lri_forces(lri_env, lri_density, qs_env, pmat, atomic_kind_set)
945 : END IF
946 :
947 10 : DEALLOCATE (pmat)
948 :
949 : END IF
950 96 : DEALLOCATE (atomlist, ksmat)
951 :
952 : ! clean up rho_struct
953 96 : CALL qs_rho_unset_rho_ao(rho_struct)
954 96 : CALL qs_rho_release(rho_struct)
955 96 : DEALLOCATE (rho_struct)
956 96 : IF (PRESENT(pmat_ext)) THEN
957 0 : CALL qs_rho_unset_rho_ao(rho1)
958 0 : CALL qs_rho_release(rho1)
959 0 : DEALLOCATE (rho1)
960 : END IF
961 96 : DEALLOCATE (cell_to_index)
962 :
963 96 : CALL timestop(handle)
964 :
965 192 : END SUBROUTINE kg_ekin_ri_embed
966 :
967 : ! **************************************************************************************************
968 : !> \brief ...
969 : !> \param qs_env ...
970 : !> \param ks_matrix ...
971 : !> \param ekin_mol ...
972 : ! **************************************************************************************************
973 172 : SUBROUTINE kg_ekin_atomic(qs_env, ks_matrix, ekin_mol)
974 : TYPE(qs_environment_type), POINTER :: qs_env
975 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_matrix
976 : REAL(KIND=dp), INTENT(out) :: ekin_mol
977 :
978 : CHARACTER(LEN=*), PARAMETER :: routineN = 'kg_ekin_atomic'
979 :
980 : INTEGER :: handle, ispin, nspins
981 172 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: density_matrix, tnadd_matrix
982 : TYPE(kg_environment_type), POINTER :: kg_env
983 : TYPE(qs_rho_type), POINTER :: rho
984 :
985 172 : NULLIFY (rho, kg_env, density_matrix, tnadd_matrix)
986 :
987 172 : CALL timeset(routineN, handle)
988 172 : CALL get_qs_env(qs_env, kg_env=kg_env, rho=rho)
989 :
990 172 : nspins = SIZE(ks_matrix)
991 : ! get the density matrix
992 172 : CALL qs_rho_get(rho, rho_ao=density_matrix)
993 : ! get the tnadd matrix
994 172 : tnadd_matrix => kg_env%tnadd_mat
995 :
996 172 : ekin_mol = 0.0_dp
997 344 : DO ispin = 1, nspins
998 172 : CALL dbcsr_dot(tnadd_matrix(1)%matrix, density_matrix(ispin)%matrix, ekin_mol)
999 : CALL dbcsr_add(ks_matrix(ispin)%matrix, tnadd_matrix(1)%matrix, &
1000 344 : alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
1001 : END DO
1002 : ! definition is inverted (see qs_ks_methods)
1003 172 : ekin_mol = -ekin_mol
1004 :
1005 172 : CALL timestop(handle)
1006 :
1007 172 : END SUBROUTINE kg_ekin_atomic
1008 :
1009 : END MODULE kg_correction
|