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 : MODULE qs_tddfpt2_operators
9 : USE admm_types, ONLY: admm_type
10 : USE cell_types, ONLY: cell_type,&
11 : pbc
12 : USE cp_dbcsr_api, ONLY: &
13 : dbcsr_create, dbcsr_filter, dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, &
14 : dbcsr_iterator_start, dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_p_type, &
15 : dbcsr_release, dbcsr_set, dbcsr_type, dbcsr_type_no_symmetry
16 : USE cp_dbcsr_operations, ONLY: copy_fm_to_dbcsr,&
17 : cp_dbcsr_plus_fm_fm_t,&
18 : cp_dbcsr_sm_fm_multiply
19 : USE cp_fm_basic_linalg, ONLY: cp_fm_column_scale,&
20 : cp_fm_scale_and_add
21 : USE cp_fm_struct, ONLY: cp_fm_struct_type
22 : USE cp_fm_types, ONLY: cp_fm_create,&
23 : cp_fm_get_info,&
24 : cp_fm_release,&
25 : cp_fm_to_fm,&
26 : cp_fm_type
27 : USE hartree_local_methods, ONLY: Vh_1c_gg_integrals
28 : USE hartree_local_types, ONLY: hartree_local_type
29 : USE hfx_admm_utils, ONLY: tddft_hfx_matrix
30 : USE hfx_types, ONLY: hfx_type
31 : USE input_section_types, ONLY: section_vals_get,&
32 : section_vals_get_subs_vals,&
33 : section_vals_type
34 : USE kinds, ONLY: dp
35 : USE message_passing, ONLY: mp_para_env_type
36 : USE parallel_gemm_api, ONLY: parallel_gemm
37 : USE particle_types, ONLY: particle_type
38 : USE pw_env_types, ONLY: pw_env_get,&
39 : pw_env_type
40 : USE pw_methods, ONLY: pw_axpy,&
41 : pw_multiply,&
42 : pw_scale,&
43 : pw_transfer,&
44 : pw_zero
45 : USE pw_poisson_methods, ONLY: pw_poisson_solve
46 : USE pw_poisson_types, ONLY: pw_poisson_type
47 : USE pw_pool_types, ONLY: pw_pool_type
48 : USE pw_types, ONLY: pw_c1d_gs_type,&
49 : pw_r3d_rs_type
50 : USE qs_environment_types, ONLY: get_qs_env,&
51 : qs_environment_type
52 : USE qs_kernel_types, ONLY: full_kernel_env_type
53 : USE qs_local_rho_types, ONLY: local_rho_type
54 : USE qs_rho0_ggrid, ONLY: integrate_vhg0_rspace
55 : USE qs_rho_types, ONLY: qs_rho_get,&
56 : qs_rho_type
57 : USE qs_tddfpt2_stda_utils, ONLY: get_lowdin_x
58 : USE qs_tddfpt2_subgroups, ONLY: tddfpt_subgroup_env_type
59 : USE qs_tddfpt2_types, ONLY: tddfpt_ground_state_mos,&
60 : tddfpt_work_matrices
61 : USE xc, ONLY: xc_calc_2nd_deriv_analytical,&
62 : xc_calc_2nd_deriv_numerical
63 : USE xc_rho_set_types, ONLY: xc_rho_set_type,&
64 : xc_rho_set_update
65 : #include "./base/base_uses.f90"
66 :
67 : IMPLICIT NONE
68 :
69 : PRIVATE
70 :
71 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_tddfpt2_operators'
72 :
73 : LOGICAL, PARAMETER, PRIVATE :: debug_this_module = .FALSE.
74 : ! number of first derivative components (3: d/dx, d/dy, d/dz)
75 : INTEGER, PARAMETER, PRIVATE :: nderivs = 3
76 : INTEGER, PARAMETER, PRIVATE :: maxspins = 2
77 :
78 : PUBLIC :: tddfpt_apply_energy_diff, tddfpt_apply_coulomb, tddfpt_apply_xc, tddfpt_apply_hfx, &
79 : tddfpt_apply_xc_potential, tddfpt_apply_hfxlr_kernel, tddfpt_apply_hfxsr_kernel
80 :
81 : ! **************************************************************************************************
82 :
83 : CONTAINS
84 :
85 : ! **************************************************************************************************
86 : !> \brief Apply orbital energy difference term:
87 : !> Aop_evects(spin,state) += KS(spin) * evects(spin,state) -
88 : !> S * evects(spin,state) * diag(evals_occ(spin))
89 : !> \param Aop_evects action of TDDFPT operator on trial vectors (modified on exit)
90 : !> \param evects trial vectors C_{1,i}
91 : !> \param S_evects S * C_{1,i}
92 : !> \param gs_mos molecular orbitals optimised for the ground state (only occupied orbital
93 : !> energies [component %evals_occ] are needed)
94 : !> \param matrix_ks Kohn-Sham matrix
95 : !> \par History
96 : !> * 05.2016 initialise all matrix elements in one go [Sergey Chulkov]
97 : !> * 03.2017 renamed from tddfpt_init_energy_diff(), altered prototype [Sergey Chulkov]
98 : !> \note Based on the subroutine p_op_l1() which was originally created by
99 : !> Thomas Chassaing on 08.2002.
100 : ! **************************************************************************************************
101 5164 : SUBROUTINE tddfpt_apply_energy_diff(Aop_evects, evects, S_evects, gs_mos, matrix_ks)
102 : TYPE(cp_fm_type), DIMENSION(:, :), INTENT(in) :: Aop_evects, evects, S_evects
103 : TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
104 : INTENT(in) :: gs_mos
105 : TYPE(dbcsr_p_type), DIMENSION(:), INTENT(in) :: matrix_ks
106 :
107 : CHARACTER(LEN=*), PARAMETER :: routineN = 'tddfpt_apply_energy_diff'
108 :
109 : INTEGER :: handle, ispin, ivect, nactive, nao, &
110 : nspins, nvects
111 : TYPE(cp_fm_struct_type), POINTER :: matrix_struct
112 : TYPE(cp_fm_type) :: hevec
113 :
114 5164 : CALL timeset(routineN, handle)
115 :
116 5164 : nspins = SIZE(evects, 1)
117 5164 : nvects = SIZE(evects, 2)
118 :
119 11006 : DO ispin = 1, nspins
120 : CALL cp_fm_get_info(matrix=evects(ispin, 1), matrix_struct=matrix_struct, &
121 5842 : nrow_global=nao, ncol_global=nactive)
122 5842 : CALL cp_fm_create(hevec, matrix_struct)
123 :
124 21074 : DO ivect = 1, nvects
125 : CALL cp_dbcsr_sm_fm_multiply(matrix_ks(ispin)%matrix, evects(ispin, ivect), &
126 : Aop_evects(ispin, ivect), ncol=nactive, &
127 15232 : alpha=1.0_dp, beta=1.0_dp)
128 :
129 15232 : IF (ASSOCIATED(gs_mos(ispin)%evals_occ_matrix)) THEN
130 : ! orbital energy correction: evals_occ_matrix is not a diagonal matrix
131 : CALL parallel_gemm('N', 'N', nao, nactive, nactive, 1.0_dp, &
132 : S_evects(ispin, ivect), gs_mos(ispin)%evals_occ_matrix, &
133 756 : 0.0_dp, hevec)
134 : ELSE
135 14476 : CALL cp_fm_to_fm(S_evects(ispin, ivect), hevec)
136 14476 : CALL cp_fm_column_scale(hevec, gs_mos(ispin)%evals_occ)
137 : END IF
138 :
139 : ! KS * C1 - S * C1 * occupied_orbital_energies
140 21074 : CALL cp_fm_scale_and_add(1.0_dp, Aop_evects(ispin, ivect), -1.0_dp, hevec)
141 : END DO
142 16848 : CALL cp_fm_release(hevec)
143 : END DO
144 :
145 5164 : CALL timestop(handle)
146 :
147 5164 : END SUBROUTINE tddfpt_apply_energy_diff
148 :
149 : ! **************************************************************************************************
150 : !> \brief Update v_rspace by adding coulomb term.
151 : !> \param A_ia_rspace action of TDDFPT operator on the trial vector expressed in a plane wave
152 : !> representation (modified on exit)
153 : !> \param rho_ia_g response density in reciprocal space for the given trial vector
154 : !> \param local_rho_set ...
155 : !> \param hartree_local ...
156 : !> \param qs_env ...
157 : !> \param sub_env the full sub_environment needed for calculation
158 : !> \param gapw Flag indicating GAPW cacluation
159 : !> \param work_v_gspace work reciprocal-space grid to store Coulomb potential (modified on exit)
160 : !> \param work_v_rspace work real-space grid to store Coulomb potential (modified on exit)
161 : !> \par History
162 : !> * 05.2016 compute all coulomb terms in one go [Sergey Chulkov]
163 : !> * 03.2017 proceed excited states sequentially; minimise the number of conversions between
164 : !> DBCSR and FM matrices [Sergey Chulkov]
165 : !> * 06.2018 return the action expressed in the plane wave representation instead of the one
166 : !> in the atomic basis set representation
167 : !> \note Based on the subroutine kpp1_calc_k_p_p1() which was originally created by
168 : !> Mohamed Fawzi on 10.2002.
169 : ! **************************************************************************************************
170 5944 : SUBROUTINE tddfpt_apply_coulomb(A_ia_rspace, rho_ia_g, local_rho_set, hartree_local, &
171 : qs_env, sub_env, gapw, work_v_gspace, work_v_rspace)
172 : TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(INOUT) :: A_ia_rspace
173 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: rho_ia_g
174 : TYPE(local_rho_type), POINTER :: local_rho_set
175 : TYPE(hartree_local_type), POINTER :: hartree_local
176 : TYPE(qs_environment_type), POINTER :: qs_env
177 : TYPE(tddfpt_subgroup_env_type), INTENT(in) :: sub_env
178 : LOGICAL, INTENT(IN) :: gapw
179 : TYPE(pw_c1d_gs_type), INTENT(INOUT) :: work_v_gspace
180 : TYPE(pw_r3d_rs_type), INTENT(INOUT) :: work_v_rspace
181 :
182 : CHARACTER(LEN=*), PARAMETER :: routineN = 'tddfpt_apply_coulomb'
183 :
184 : INTEGER :: handle, ispin, nspins
185 : REAL(kind=dp) :: alpha, pair_energy
186 : TYPE(pw_env_type), POINTER :: pw_env
187 : TYPE(pw_poisson_type), POINTER :: poisson_env
188 :
189 5944 : CALL timeset(routineN, handle)
190 :
191 5944 : nspins = SIZE(A_ia_rspace)
192 5944 : pw_env => sub_env%pw_env
193 5944 : CALL pw_env_get(pw_env, poisson_env=poisson_env)
194 :
195 5944 : IF (nspins > 1) THEN
196 1358 : alpha = 1.0_dp
197 : ELSE
198 : ! spin-restricted case: alpha == 2 due to singlet state.
199 : ! In case of triplet states alpha == 0, so we should not call this subroutine at all.
200 4586 : alpha = 2.0_dp
201 : END IF
202 :
203 5944 : IF (gapw) THEN
204 784 : CPASSERT(ASSOCIATED(local_rho_set))
205 784 : CALL pw_axpy(local_rho_set%rho0_mpole%rho0_s_gs, rho_ia_g)
206 : END IF
207 :
208 5944 : CALL pw_poisson_solve(poisson_env, rho_ia_g, pair_energy, work_v_gspace)
209 5944 : CALL pw_transfer(work_v_gspace, work_v_rspace)
210 :
211 : ! (i a || j b) = ( i_alpha a_alpha + i_beta a_beta || j_alpha b_alpha + j_beta b_beta) =
212 : ! tr (Cj_alpha^T * [J_i{alpha}a{alpha}_munu + J_i{beta}a{beta}_munu] * Cb_alpha) +
213 : ! tr (Cj_beta^T * [J_i{alpha}a{alpha}_munu + J_i{beta}a{beta}_munu] * Cb_beta)
214 13246 : DO ispin = 1, nspins
215 13246 : CALL pw_axpy(work_v_rspace, A_ia_rspace(ispin), alpha)
216 : END DO
217 :
218 5944 : IF (gapw) THEN
219 : CALL Vh_1c_gg_integrals(qs_env, pair_energy, &
220 : hartree_local%ecoul_1c, &
221 : local_rho_set, &
222 784 : sub_env%para_env, tddft=.TRUE., core_2nd=.TRUE.)
223 784 : CALL pw_scale(work_v_rspace, work_v_rspace%pw_grid%dvol)
224 : CALL integrate_vhg0_rspace(qs_env, work_v_rspace, sub_env%para_env, &
225 : calculate_forces=.FALSE., &
226 784 : local_rho_set=local_rho_set)
227 : END IF
228 :
229 5944 : CALL timestop(handle)
230 :
231 5944 : END SUBROUTINE tddfpt_apply_coulomb
232 :
233 : ! **************************************************************************************************
234 : !> \brief Driver routine for applying fxc (analyic vs. finite difference for testing
235 : !> \param A_ia_rspace action of TDDFPT operator on trial vectors expressed in a plane wave
236 : !> representation (modified on exit)
237 : !> \param kernel_env kernel environment
238 : !> \param rho_ia_struct response density for the given trial vector
239 : !> \param is_rks_triplets indicates that the triplet excited states calculation using
240 : !> spin-unpolarised molecular orbitals has been requested
241 : !> \param pw_env plain wave environment
242 : !> \param work_v_xc work real-space grid to store the gradient of the exchange-correlation
243 : !> potential with respect to the response density (modified on exit)
244 : !> \param work_v_xc_tau ...
245 : ! **************************************************************************************************
246 7098 : SUBROUTINE tddfpt_apply_xc(A_ia_rspace, kernel_env, rho_ia_struct, is_rks_triplets, &
247 : pw_env, work_v_xc, work_v_xc_tau)
248 :
249 : TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(INOUT) :: A_ia_rspace
250 : TYPE(full_kernel_env_type), INTENT(IN) :: kernel_env
251 : TYPE(qs_rho_type), POINTER :: rho_ia_struct
252 : LOGICAL, INTENT(in) :: is_rks_triplets
253 : TYPE(pw_env_type), POINTER :: pw_env
254 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: work_v_xc, work_v_xc_tau
255 :
256 : INTEGER :: ispin, nspins
257 :
258 7098 : nspins = SIZE(A_ia_rspace)
259 :
260 7098 : IF (kernel_env%deriv2_analytic) THEN
261 : CALL tddfpt_apply_xc_analytic(kernel_env, rho_ia_struct, is_rks_triplets, nspins, &
262 7058 : pw_env, work_v_xc, work_v_xc_tau)
263 : ELSE
264 : CALL tddfpt_apply_xc_fd(kernel_env, rho_ia_struct, is_rks_triplets, nspins, &
265 40 : pw_env, work_v_xc, work_v_xc_tau)
266 : END IF
267 :
268 15554 : DO ispin = 1, nspins
269 : ! pw2 = pw2 + alpha * pw1
270 15554 : CALL pw_axpy(work_v_xc(ispin), A_ia_rspace(ispin), kernel_env%alpha)
271 : END DO
272 :
273 7098 : END SUBROUTINE tddfpt_apply_xc
274 :
275 : ! **************************************************************************************************
276 : !> \brief Routine for applying fxc potential
277 : !> \param A_ia_rspace action of TDDFPT operator on trial vectors expressed in a plane wave
278 : !> representation (modified on exit)
279 : !> \param fxc_rspace ...
280 : !> \param rho_ia_struct response density for the given trial vector
281 : !> \param is_rks_triplets ...
282 : ! **************************************************************************************************
283 156 : SUBROUTINE tddfpt_apply_xc_potential(A_ia_rspace, fxc_rspace, rho_ia_struct, is_rks_triplets)
284 :
285 : TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(INOUT) :: A_ia_rspace
286 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rspace
287 : TYPE(qs_rho_type), POINTER :: rho_ia_struct
288 : LOGICAL, INTENT(in) :: is_rks_triplets
289 :
290 : INTEGER :: nspins
291 : REAL(KIND=dp) :: alpha
292 156 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho1_r
293 :
294 156 : nspins = SIZE(A_ia_rspace)
295 :
296 156 : alpha = 1.0_dp
297 :
298 156 : CALL qs_rho_get(rho_ia_struct, rho_r=rho1_r)
299 :
300 156 : IF (nspins == 2) THEN
301 0 : CALL pw_multiply(A_ia_rspace(1), fxc_rspace(1), rho1_r(1), alpha)
302 0 : CALL pw_multiply(A_ia_rspace(1), fxc_rspace(2), rho1_r(2), alpha)
303 0 : CALL pw_multiply(A_ia_rspace(2), fxc_rspace(3), rho1_r(2), alpha)
304 0 : CALL pw_multiply(A_ia_rspace(2), fxc_rspace(2), rho1_r(1), alpha)
305 156 : ELSE IF (is_rks_triplets) THEN
306 0 : CALL pw_multiply(A_ia_rspace(1), fxc_rspace(1), rho1_r(1), alpha)
307 0 : CALL pw_multiply(A_ia_rspace(1), fxc_rspace(2), rho1_r(1), -alpha)
308 : ELSE
309 156 : CALL pw_multiply(A_ia_rspace(1), fxc_rspace(1), rho1_r(1), alpha)
310 156 : CALL pw_multiply(A_ia_rspace(1), fxc_rspace(2), rho1_r(1), alpha)
311 : END IF
312 :
313 156 : END SUBROUTINE tddfpt_apply_xc_potential
314 :
315 : ! **************************************************************************************************
316 : !> \brief Update A_ia_munu by adding exchange-correlation term.
317 : !> \param kernel_env kernel environment
318 : !> \param rho_ia_struct response density for the given trial vector
319 : !> \param is_rks_triplets indicates that the triplet excited states calculation using
320 : !> spin-unpolarised molecular orbitals has been requested
321 : !> \param nspins ...
322 : !> \param pw_env plain wave environment
323 : !> \param work_v_xc work real-space grid to store the gradient of the exchange-correlation
324 : !> potential with respect to the response density (modified on exit)
325 : !> \param work_v_xc_tau ...
326 : !> \par History
327 : !> * 05.2016 compute all kernel terms in one go [Sergey Chulkov]
328 : !> * 03.2017 proceed excited states sequentially; minimise the number of conversions between
329 : !> DBCSR and FM matrices [Sergey Chulkov]
330 : !> * 06.2018 return the action expressed in the plane wave representation instead of the one
331 : !> in the atomic basis set representation
332 : !> \note Based on the subroutine kpp1_calc_k_p_p1() which was originally created by
333 : !> Mohamed Fawzi on 10.2002.
334 : ! **************************************************************************************************
335 7058 : SUBROUTINE tddfpt_apply_xc_analytic(kernel_env, rho_ia_struct, is_rks_triplets, nspins, &
336 : pw_env, work_v_xc, work_v_xc_tau)
337 : TYPE(full_kernel_env_type), INTENT(in) :: kernel_env
338 : TYPE(qs_rho_type), POINTER :: rho_ia_struct
339 : LOGICAL, INTENT(in) :: is_rks_triplets
340 : INTEGER, INTENT(in) :: nspins
341 : TYPE(pw_env_type), POINTER :: pw_env
342 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: work_v_xc, work_v_xc_tau
343 :
344 : CHARACTER(LEN=*), PARAMETER :: routineN = 'tddfpt_apply_xc_analytic'
345 :
346 : INTEGER :: handle, ispin
347 7058 : TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_ia_g, rho_ia_g2
348 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
349 7058 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_ia_r, rho_ia_r2, tau_ia_r, tau_ia_r2
350 :
351 7058 : CALL timeset(routineN, handle)
352 :
353 7058 : CALL qs_rho_get(rho_ia_struct, rho_g=rho_ia_g, rho_r=rho_ia_r, tau_r=tau_ia_r)
354 7058 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
355 :
356 : IF (debug_this_module) THEN
357 : CPASSERT(SIZE(rho_ia_g) == nspins)
358 : CPASSERT(SIZE(rho_ia_r) == nspins)
359 : CPASSERT((.NOT. ASSOCIATED(tau_ia_r)) .OR. SIZE(tau_ia_r) == nspins)
360 : CPASSERT((.NOT. is_rks_triplets) .OR. nspins == 1)
361 : END IF
362 :
363 7058 : NULLIFY (tau_ia_r2)
364 7058 : IF (is_rks_triplets) THEN
365 1512 : ALLOCATE (rho_ia_r2(2))
366 1512 : ALLOCATE (rho_ia_g2(2))
367 504 : rho_ia_r2(1) = rho_ia_r(1)
368 504 : rho_ia_r2(2) = rho_ia_r(1)
369 504 : rho_ia_g2(1) = rho_ia_g(1)
370 504 : rho_ia_g2(2) = rho_ia_g(1)
371 :
372 504 : IF (ASSOCIATED(tau_ia_r)) THEN
373 0 : ALLOCATE (tau_ia_r2(2))
374 0 : tau_ia_r2(1) = tau_ia_r(1)
375 0 : tau_ia_r2(2) = tau_ia_r(1)
376 : END IF
377 : ELSE
378 6554 : rho_ia_r2 => rho_ia_r
379 6554 : rho_ia_g2 => rho_ia_g
380 :
381 6554 : tau_ia_r2 => tau_ia_r
382 : END IF
383 :
384 15454 : DO ispin = 1, nspins
385 8396 : CALL pw_zero(work_v_xc(ispin))
386 15454 : IF (ASSOCIATED(work_v_xc_tau)) CALL pw_zero(work_v_xc_tau(ispin))
387 : END DO
388 :
389 : CALL xc_rho_set_update(rho_set=kernel_env%xc_rho1_set, rho_r=rho_ia_r2, rho_g=rho_ia_g2, tau=tau_ia_r2, &
390 : needs=kernel_env%xc_rho1_cflags, xc_deriv_method_id=kernel_env%deriv_method_id, &
391 7058 : xc_rho_smooth_id=kernel_env%rho_smooth_id, pw_pool=auxbas_pw_pool)
392 :
393 : CALL xc_calc_2nd_deriv_analytical(v_xc=work_v_xc, v_xc_tau=work_v_xc_tau, deriv_set=kernel_env%xc_deriv_set, &
394 : rho_set=kernel_env%xc_rho_set, &
395 : rho1_set=kernel_env%xc_rho1_set, pw_pool=auxbas_pw_pool, &
396 7058 : xc_section=kernel_env%xc_section, gapw=.FALSE., tddfpt_fac=kernel_env%beta)
397 :
398 7058 : IF (is_rks_triplets) THEN
399 504 : DEALLOCATE (rho_ia_r2)
400 504 : DEALLOCATE (rho_ia_g2)
401 504 : IF (ASSOCIATED(tau_ia_r2)) DEALLOCATE (tau_ia_r2)
402 : END IF
403 :
404 7058 : CALL timestop(handle)
405 :
406 7058 : END SUBROUTINE tddfpt_apply_xc_analytic
407 :
408 : ! **************************************************************************************************
409 : !> \brief Update A_ia_munu by adding exchange-correlation term using finite difference methods.
410 : !> \param kernel_env kernel environment
411 : !> \param rho_ia_struct response density for the given trial vector
412 : !> \param is_rks_triplets indicates that the triplet excited states calculation using
413 : !> spin-unpolarised molecular orbitals has been requested
414 : !> \param nspins ...
415 : !> \param pw_env plain wave environment
416 : !> \param work_v_xc work real-space grid to store the gradient of the exchange-correlation
417 : !> potential with respect to the response density (modified on exit)
418 : !> \param work_v_xc_tau ...
419 : ! **************************************************************************************************
420 40 : SUBROUTINE tddfpt_apply_xc_fd(kernel_env, rho_ia_struct, is_rks_triplets, nspins, &
421 : pw_env, work_v_xc, work_v_xc_tau)
422 : TYPE(full_kernel_env_type), INTENT(in) :: kernel_env
423 : TYPE(qs_rho_type), POINTER :: rho_ia_struct
424 : LOGICAL, INTENT(in) :: is_rks_triplets
425 : INTEGER, INTENT(in) :: nspins
426 : TYPE(pw_env_type), POINTER :: pw_env
427 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: work_v_xc, work_v_xc_tau
428 :
429 : CHARACTER(LEN=*), PARAMETER :: routineN = 'tddfpt_apply_xc_fd'
430 :
431 : INTEGER :: handle, ispin
432 : LOGICAL :: lsd, singlet, triplet
433 40 : TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho1_g
434 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
435 40 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho1_r, tau1_r
436 : TYPE(xc_rho_set_type), POINTER :: rho_set
437 :
438 40 : CALL timeset(routineN, handle)
439 :
440 40 : CALL qs_rho_get(rho_ia_struct, rho_r=rho1_r, rho_g=rho1_g, tau_r=tau1_r)
441 40 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
442 100 : DO ispin = 1, nspins
443 100 : CALL pw_zero(work_v_xc(ispin))
444 : END DO
445 40 : rho_set => kernel_env%xc_rho_set
446 :
447 40 : singlet = .FALSE.
448 40 : triplet = .FALSE.
449 40 : lsd = .FALSE.
450 40 : IF (nspins == 1 .AND. .NOT. is_rks_triplets) THEN
451 40 : singlet = .TRUE.
452 40 : ELSE IF (nspins == 1 .AND. is_rks_triplets) THEN
453 40 : triplet = .TRUE.
454 20 : ELSE IF (nspins == 2) THEN
455 40 : lsd = .TRUE.
456 : ELSE
457 0 : CPABORT("illegal options")
458 : END IF
459 :
460 40 : IF (ASSOCIATED(tau1_r)) THEN
461 0 : DO ispin = 1, nspins
462 0 : CALL pw_zero(work_v_xc_tau(ispin))
463 : END DO
464 : END IF
465 :
466 : CALL xc_calc_2nd_deriv_numerical(work_v_xc, work_v_xc_tau, rho_set, rho1_r, rho1_g, tau1_r, &
467 : auxbas_pw_pool, kernel_env%xc_section, &
468 40 : is_rks_triplets)
469 :
470 40 : CALL timestop(handle)
471 :
472 40 : END SUBROUTINE tddfpt_apply_xc_fd
473 :
474 : ! **************************************************************************************************
475 : !> \brief Update action of TDDFPT operator on trial vectors by adding exact-exchange term.
476 : !> \param Aop_evects action of TDDFPT operator on trial vectors (modified on exit)
477 : !> \param evects trial vectors
478 : !> \param gs_mos molecular orbitals optimised for the ground state (only occupied
479 : !> molecular orbitals [component %mos_occ] are needed)
480 : !> \param do_admm perform auxiliary density matrix method calculations
481 : !> \param qs_env Quickstep environment
482 : !> \param work_rho_ia_ao_symm ...
483 : !> \param work_hmat_symm ...
484 : !> \param work_rho_ia_ao_asymm ...
485 : !> \param work_hmat_asymm ...
486 : !> \param wfm_rho_orb ...
487 : !> \par History
488 : !> * 05.2016 compute all exact-exchange terms in one go [Sergey Chulkov]
489 : !> * 03.2017 code related to ADMM correction is now moved to tddfpt_apply_admm_correction()
490 : !> in order to compute this correction within parallel groups [Sergey Chulkov]
491 : !> \note Based on the subroutine kpp1_calc_k_p_p1() which was originally created by
492 : !> Mohamed Fawzi on 10.2002.
493 : ! **************************************************************************************************
494 1110 : SUBROUTINE tddfpt_apply_hfx(Aop_evects, evects, gs_mos, do_admm, qs_env, &
495 1110 : work_rho_ia_ao_symm, work_hmat_symm, work_rho_ia_ao_asymm, &
496 1110 : work_hmat_asymm, wfm_rho_orb)
497 : TYPE(cp_fm_type), DIMENSION(:, :), INTENT(in) :: Aop_evects, evects
498 : TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
499 : INTENT(in) :: gs_mos
500 : LOGICAL, INTENT(in) :: do_admm
501 : TYPE(qs_environment_type), POINTER :: qs_env
502 : TYPE(dbcsr_p_type), DIMENSION(:), INTENT(INOUT) :: work_rho_ia_ao_symm
503 : TYPE(dbcsr_p_type), DIMENSION(:), INTENT(INOUT), &
504 : TARGET :: work_hmat_symm
505 : TYPE(dbcsr_p_type), DIMENSION(:), INTENT(INOUT) :: work_rho_ia_ao_asymm
506 : TYPE(dbcsr_p_type), DIMENSION(:), INTENT(INOUT), &
507 : TARGET :: work_hmat_asymm
508 : TYPE(cp_fm_type), INTENT(IN) :: wfm_rho_orb
509 :
510 : CHARACTER(LEN=*), PARAMETER :: routineN = 'tddfpt_apply_hfx'
511 :
512 : INTEGER :: handle, ispin, ivect, nao, nao_aux, &
513 : nspins, nvects
514 : INTEGER, DIMENSION(maxspins) :: nactive
515 : LOGICAL :: do_hfx
516 : REAL(kind=dp) :: alpha
517 : TYPE(admm_type), POINTER :: admm_env
518 : TYPE(section_vals_type), POINTER :: hfx_section, input
519 :
520 1110 : CALL timeset(routineN, handle)
521 :
522 : ! Check for hfx section
523 1110 : CALL get_qs_env(qs_env, input=input)
524 1110 : hfx_section => section_vals_get_subs_vals(input, "DFT%XC%HF")
525 1110 : CALL section_vals_get(hfx_section, explicit=do_hfx)
526 :
527 1110 : IF (do_hfx) THEN
528 1110 : nspins = SIZE(evects, 1)
529 1110 : nvects = SIZE(evects, 2)
530 :
531 1110 : IF (nspins > 1) THEN
532 78 : alpha = 1.0_dp
533 : ELSE
534 1032 : alpha = 2.0_dp
535 : END IF
536 :
537 1110 : CALL cp_fm_get_info(gs_mos(1)%mos_occ, nrow_global=nao)
538 2298 : DO ispin = 1, nspins
539 2298 : CALL cp_fm_get_info(evects(ispin, 1), ncol_global=nactive(ispin))
540 : END DO
541 :
542 1110 : IF (do_admm) THEN
543 604 : CALL get_qs_env(qs_env, admm_env=admm_env)
544 604 : CALL cp_fm_get_info(admm_env%A, nrow_global=nao_aux)
545 : END IF
546 :
547 : !Note: the symmetrized transition density matrix is P = 0.5*(C*evect^T + evect*C^T)
548 : ! in the end, we only want evect*C^T for consistency with the MO formulation of TDDFT
549 : ! therefore, we go in 2 steps: with the symmetric 0.5*(C*evect^T + evect*C^T) and
550 : ! the antisymemtric 0.5*(C*evect^T - evect*C^T)
551 :
552 : ! some stuff from qs_ks_build_kohn_sham_matrix
553 : ! TO DO: add SIC support
554 3398 : DO ivect = 1, nvects
555 4704 : DO ispin = 1, nspins
556 :
557 : !The symmetric density matrix
558 : CALL parallel_gemm('N', 'T', nao, nao, nactive(ispin), 0.5_dp, evects(ispin, ivect), &
559 2416 : gs_mos(ispin)%mos_occ, 0.0_dp, wfm_rho_orb)
560 : CALL parallel_gemm('N', 'T', nao, nao, nactive(ispin), 0.5_dp, gs_mos(ispin)%mos_occ, &
561 2416 : evects(ispin, ivect), 1.0_dp, wfm_rho_orb)
562 :
563 2416 : CALL dbcsr_set(work_hmat_symm(ispin)%matrix, 0.0_dp)
564 4704 : IF (do_admm) THEN
565 : CALL parallel_gemm('N', 'N', nao_aux, nao, nao, 1.0_dp, admm_env%A, &
566 1280 : wfm_rho_orb, 0.0_dp, admm_env%work_aux_orb)
567 : CALL parallel_gemm('N', 'T', nao_aux, nao_aux, nao, 1.0_dp, admm_env%work_aux_orb, admm_env%A, &
568 1280 : 0.0_dp, admm_env%work_aux_aux)
569 1280 : CALL copy_fm_to_dbcsr(admm_env%work_aux_aux, work_rho_ia_ao_symm(ispin)%matrix, keep_sparsity=.TRUE.)
570 : ELSE
571 1136 : CALL copy_fm_to_dbcsr(wfm_rho_orb, work_rho_ia_ao_symm(ispin)%matrix, keep_sparsity=.TRUE.)
572 : END IF
573 : END DO
574 :
575 2288 : CALL tddft_hfx_matrix(work_hmat_symm, work_rho_ia_ao_symm, qs_env)
576 :
577 2288 : IF (do_admm) THEN
578 2532 : DO ispin = 1, nspins
579 : CALL cp_dbcsr_sm_fm_multiply(work_hmat_symm(ispin)%matrix, admm_env%A, admm_env%work_aux_orb, &
580 1280 : ncol=nao, alpha=1.0_dp, beta=0.0_dp)
581 :
582 : CALL parallel_gemm('T', 'N', nao, nao, nao_aux, 1.0_dp, admm_env%A, &
583 1280 : admm_env%work_aux_orb, 0.0_dp, wfm_rho_orb)
584 :
585 : CALL parallel_gemm('N', 'N', nao, nactive(ispin), nao, alpha, wfm_rho_orb, &
586 2532 : gs_mos(ispin)%mos_occ, 1.0_dp, Aop_evects(ispin, ivect))
587 : END DO
588 : ELSE
589 2172 : DO ispin = 1, nspins
590 : CALL cp_dbcsr_sm_fm_multiply(work_hmat_symm(ispin)%matrix, gs_mos(ispin)%mos_occ, &
591 : Aop_evects(ispin, ivect), ncol=nactive(ispin), &
592 2172 : alpha=alpha, beta=1.0_dp)
593 : END DO
594 : END IF
595 :
596 : !The anti-symmetric density matrix
597 4704 : DO ispin = 1, nspins
598 :
599 : !The symmetric density matrix
600 : CALL parallel_gemm('N', 'T', nao, nao, nactive(ispin), 0.5_dp, evects(ispin, ivect), &
601 2416 : gs_mos(ispin)%mos_occ, 0.0_dp, wfm_rho_orb)
602 : CALL parallel_gemm('N', 'T', nao, nao, nactive(ispin), -0.5_dp, gs_mos(ispin)%mos_occ, &
603 2416 : evects(ispin, ivect), 1.0_dp, wfm_rho_orb)
604 :
605 2416 : CALL dbcsr_set(work_hmat_asymm(ispin)%matrix, 0.0_dp)
606 4704 : IF (do_admm) THEN
607 : CALL parallel_gemm('N', 'N', nao_aux, nao, nao, 1.0_dp, admm_env%A, &
608 1280 : wfm_rho_orb, 0.0_dp, admm_env%work_aux_orb)
609 : CALL parallel_gemm('N', 'T', nao_aux, nao_aux, nao, 1.0_dp, admm_env%work_aux_orb, admm_env%A, &
610 1280 : 0.0_dp, admm_env%work_aux_aux)
611 1280 : CALL copy_fm_to_dbcsr(admm_env%work_aux_aux, work_rho_ia_ao_asymm(ispin)%matrix, keep_sparsity=.TRUE.)
612 : ELSE
613 1136 : CALL copy_fm_to_dbcsr(wfm_rho_orb, work_rho_ia_ao_asymm(ispin)%matrix, keep_sparsity=.TRUE.)
614 : END IF
615 : END DO
616 :
617 2288 : CALL tddft_hfx_matrix(work_hmat_asymm, work_rho_ia_ao_asymm, qs_env)
618 :
619 3398 : IF (do_admm) THEN
620 2532 : DO ispin = 1, nspins
621 : CALL cp_dbcsr_sm_fm_multiply(work_hmat_asymm(ispin)%matrix, admm_env%A, admm_env%work_aux_orb, &
622 1280 : ncol=nao, alpha=1.0_dp, beta=0.0_dp)
623 :
624 : CALL parallel_gemm('T', 'N', nao, nao, nao_aux, 1.0_dp, admm_env%A, &
625 1280 : admm_env%work_aux_orb, 0.0_dp, wfm_rho_orb)
626 :
627 : CALL parallel_gemm('N', 'N', nao, nactive(ispin), nao, alpha, wfm_rho_orb, &
628 2532 : gs_mos(ispin)%mos_occ, 1.0_dp, Aop_evects(ispin, ivect))
629 : END DO
630 : ELSE
631 2172 : DO ispin = 1, nspins
632 : CALL cp_dbcsr_sm_fm_multiply(work_hmat_asymm(ispin)%matrix, gs_mos(ispin)%mos_occ, &
633 : Aop_evects(ispin, ivect), ncol=nactive(ispin), &
634 2172 : alpha=alpha, beta=1.0_dp)
635 : END DO
636 : END IF
637 : END DO
638 : END IF
639 :
640 1110 : CALL timestop(handle)
641 :
642 1110 : END SUBROUTINE tddfpt_apply_hfx
643 :
644 : ! **************************************************************************************************
645 : !> \brief Update action of TDDFPT operator on trial vectors by adding exact-exchange term.
646 : !> \param Aop_evects action of TDDFPT operator on trial vectors (modified on exit)
647 : !> \param evects trial vectors
648 : !> \param gs_mos molecular orbitals optimised for the ground state (only occupied
649 : !> molecular orbitals [component %mos_occ] are needed)
650 : !> \param qs_env Quickstep environment
651 : !> \param admm_env ...
652 : !> \param hfx_section ...
653 : !> \param x_data ...
654 : !> \param symmetry ...
655 : !> \param recalc_integrals ...
656 : !> \param work_rho_ia_ao ...
657 : !> \param work_hmat ...
658 : !> \param wfm_rho_orb ...
659 : ! **************************************************************************************************
660 44 : SUBROUTINE tddfpt_apply_hfxsr_kernel(Aop_evects, evects, gs_mos, qs_env, admm_env, &
661 : hfx_section, x_data, symmetry, recalc_integrals, &
662 44 : work_rho_ia_ao, work_hmat, wfm_rho_orb)
663 : TYPE(cp_fm_type), DIMENSION(:, :), INTENT(in) :: Aop_evects, evects
664 : TYPE(tddfpt_ground_state_mos), DIMENSION(:), &
665 : INTENT(in) :: gs_mos
666 : TYPE(qs_environment_type), POINTER :: qs_env
667 : TYPE(admm_type), POINTER :: admm_env
668 : TYPE(section_vals_type), POINTER :: hfx_section
669 : TYPE(hfx_type), DIMENSION(:, :), POINTER :: x_data
670 : INTEGER, INTENT(IN) :: symmetry
671 : LOGICAL, INTENT(IN) :: recalc_integrals
672 : TYPE(dbcsr_p_type), DIMENSION(:), INTENT(INOUT) :: work_rho_ia_ao
673 : TYPE(dbcsr_p_type), DIMENSION(:), INTENT(INOUT), &
674 : TARGET :: work_hmat
675 : TYPE(cp_fm_type), INTENT(IN) :: wfm_rho_orb
676 :
677 : CHARACTER(LEN=*), PARAMETER :: routineN = 'tddfpt_apply_hfxsr_kernel'
678 :
679 : INTEGER :: handle, ispin, ivect, nao, nao_aux, &
680 : nspins, nvects
681 : INTEGER, DIMENSION(maxspins) :: nactive
682 : LOGICAL :: reint
683 : REAL(kind=dp) :: alpha
684 :
685 44 : CALL timeset(routineN, handle)
686 :
687 44 : nspins = SIZE(evects, 1)
688 44 : nvects = SIZE(evects, 2)
689 :
690 44 : alpha = 2.0_dp
691 44 : IF (nspins > 1) alpha = 1.0_dp
692 :
693 44 : CALL cp_fm_get_info(gs_mos(1)%mos_occ, nrow_global=nao)
694 44 : CALL cp_fm_get_info(admm_env%A, nrow_global=nao_aux)
695 88 : DO ispin = 1, nspins
696 88 : CALL cp_fm_get_info(evects(ispin, 1), ncol_global=nactive(ispin))
697 : END DO
698 :
699 44 : reint = recalc_integrals
700 :
701 132 : DO ivect = 1, nvects
702 176 : DO ispin = 1, nspins
703 : CALL parallel_gemm('N', 'T', nao, nao, nactive(ispin), 0.5_dp, evects(ispin, ivect), &
704 88 : gs_mos(ispin)%mos_occ, 0.0_dp, wfm_rho_orb)
705 : CALL parallel_gemm('N', 'T', nao, nao, nactive(ispin), 0.5_dp*symmetry, gs_mos(ispin)%mos_occ, &
706 88 : evects(ispin, ivect), 1.0_dp, wfm_rho_orb)
707 88 : CALL dbcsr_set(work_hmat(ispin)%matrix, 0.0_dp)
708 : CALL parallel_gemm('N', 'N', nao_aux, nao, nao, 1.0_dp, admm_env%A, &
709 88 : wfm_rho_orb, 0.0_dp, admm_env%work_aux_orb)
710 : CALL parallel_gemm('N', 'T', nao_aux, nao_aux, nao, 1.0_dp, admm_env%work_aux_orb, admm_env%A, &
711 88 : 0.0_dp, admm_env%work_aux_aux)
712 176 : CALL copy_fm_to_dbcsr(admm_env%work_aux_aux, work_rho_ia_ao(ispin)%matrix, keep_sparsity=.TRUE.)
713 : END DO
714 :
715 88 : CALL tddft_hfx_matrix(work_hmat, work_rho_ia_ao, qs_env, .FALSE., reint, hfx_section, x_data)
716 88 : reint = .FALSE.
717 :
718 220 : DO ispin = 1, nspins
719 : CALL cp_dbcsr_sm_fm_multiply(work_hmat(ispin)%matrix, admm_env%A, admm_env%work_aux_orb, &
720 88 : ncol=nao, alpha=1.0_dp, beta=0.0_dp)
721 : CALL parallel_gemm('T', 'N', nao, nao, nao_aux, 1.0_dp, admm_env%A, &
722 88 : admm_env%work_aux_orb, 0.0_dp, wfm_rho_orb)
723 : CALL parallel_gemm('N', 'N', nao, nactive(ispin), nao, alpha, wfm_rho_orb, &
724 176 : gs_mos(ispin)%mos_occ, 1.0_dp, Aop_evects(ispin, ivect))
725 : END DO
726 : END DO
727 :
728 44 : CALL timestop(handle)
729 :
730 44 : END SUBROUTINE tddfpt_apply_hfxsr_kernel
731 :
732 : ! **************************************************************************************************
733 : !> \brief ...Calculate the HFXLR kernel contribution by contracting the Lowdin MO coefficients --
734 : !> transition charges with the exchange-type integrals using the sTDA approximation
735 : !> \param qs_env ...
736 : !> \param sub_env ...
737 : !> \param rcut ...
738 : !> \param hfx_scale ...
739 : !> \param work ...
740 : !> \param X ...
741 : !> \param res ... vector AX with A being the sTDA matrix and X the Davidson trial vector of the
742 : !> eigenvalue problem A*X = omega*X
743 : ! **************************************************************************************************
744 72 : SUBROUTINE tddfpt_apply_hfxlr_kernel(qs_env, sub_env, rcut, hfx_scale, work, X, res)
745 :
746 : TYPE(qs_environment_type), POINTER :: qs_env
747 : TYPE(tddfpt_subgroup_env_type) :: sub_env
748 : REAL(KIND=dp), INTENT(IN) :: rcut, hfx_scale
749 : TYPE(tddfpt_work_matrices) :: work
750 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: X, res
751 :
752 : CHARACTER(len=*), PARAMETER :: routineN = 'tddfpt_apply_hfxlr_kernel'
753 :
754 : INTEGER :: blk, handle, iatom, ispin, jatom, natom, &
755 : nsgf, nspins
756 : INTEGER, DIMENSION(2) :: nactive
757 : REAL(KIND=dp) :: dr, eps_filter, fcut, gabr
758 : REAL(KIND=dp), DIMENSION(3) :: rij
759 72 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: pblock
760 : TYPE(cell_type), POINTER :: cell
761 : TYPE(cp_fm_struct_type), POINTER :: fmstruct
762 : TYPE(cp_fm_type) :: cvec
763 72 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: xtransformed
764 : TYPE(cp_fm_type), POINTER :: ct
765 : TYPE(dbcsr_iterator_type) :: iter
766 : TYPE(dbcsr_type) :: pdens
767 : TYPE(dbcsr_type), POINTER :: tempmat
768 : TYPE(mp_para_env_type), POINTER :: para_env
769 72 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
770 :
771 72 : CALL timeset(routineN, handle)
772 :
773 : ! parameters
774 72 : eps_filter = 1.E-08_dp
775 :
776 72 : nspins = SIZE(X)
777 144 : DO ispin = 1, nspins
778 144 : CALL cp_fm_get_info(X(ispin), ncol_global=nactive(ispin))
779 : END DO
780 :
781 72 : para_env => sub_env%para_env
782 :
783 72 : CALL get_qs_env(qs_env, natom=natom, cell=cell, particle_set=particle_set)
784 :
785 : ! calculate Loewdin transformed Davidson trial vector tilde(X)=S^1/2*X
786 : ! and tilde(tilde(X))=S^1/2_A*tilde(X)_A
787 288 : ALLOCATE (xtransformed(nspins))
788 144 : DO ispin = 1, nspins
789 72 : NULLIFY (fmstruct)
790 72 : ct => work%ctransformed(ispin)
791 72 : CALL cp_fm_get_info(ct, matrix_struct=fmstruct)
792 144 : CALL cp_fm_create(matrix=xtransformed(ispin), matrix_struct=fmstruct, name="XTRANSFORMED")
793 : END DO
794 72 : CALL get_lowdin_x(work%shalf, X, xtransformed)
795 :
796 144 : DO ispin = 1, nspins
797 72 : ct => work%ctransformed(ispin)
798 72 : CALL cp_fm_get_info(ct, matrix_struct=fmstruct, nrow_global=nsgf)
799 72 : CALL cp_fm_create(cvec, fmstruct)
800 : !
801 72 : tempmat => work%shalf
802 72 : CALL dbcsr_create(pdens, template=tempmat, matrix_type=dbcsr_type_no_symmetry)
803 : ! P(nu,mu) = SUM_j XT(nu,j)*CT(mu,j)
804 72 : ct => work%ctransformed(ispin)
805 72 : CALL dbcsr_set(pdens, 0.0_dp)
806 : CALL cp_dbcsr_plus_fm_fm_t(pdens, xtransformed(ispin), ct, nactive(ispin), &
807 72 : 1.0_dp, keep_sparsity=.FALSE.)
808 72 : CALL dbcsr_filter(pdens, eps_filter)
809 : ! Apply PP*gab -> PP; gab = gamma_coulomb
810 : ! P(nu,mu) = P(nu,mu)*g(a of nu,b of mu)
811 72 : CALL dbcsr_iterator_start(iter, pdens)
812 396 : DO WHILE (dbcsr_iterator_blocks_left(iter))
813 324 : CALL dbcsr_iterator_next_block(iter, iatom, jatom, pblock, blk)
814 1296 : rij = particle_set(iatom)%r - particle_set(jatom)%r
815 1296 : rij = pbc(rij, cell)
816 1296 : dr = SQRT(SUM(rij(:)**2))
817 324 : gabr = 1._dp/rcut
818 324 : IF (dr < 1.e-6) THEN
819 108 : gabr = 2._dp*gabr/SQRT(3.1415926_dp)
820 : ELSE
821 216 : gabr = ERF(gabr*dr)/dr
822 : fcut = EXP(dr - 4._dp*rcut)
823 216 : fcut = fcut/(fcut + 1._dp)
824 : END IF
825 21924 : pblock = hfx_scale*gabr*pblock
826 : END DO
827 72 : CALL dbcsr_iterator_stop(iter)
828 : ! CV(mu,i) = P(nu,mu)*CT(mu,i)
829 72 : CALL cp_dbcsr_sm_fm_multiply(pdens, ct, cvec, nactive(ispin), 1.0_dp, 0.0_dp)
830 : ! rho(nu,i) = rho(nu,i) + ShalfP(nu,mu)*CV(mu,i)
831 : CALL cp_dbcsr_sm_fm_multiply(work%shalf, cvec, res(ispin), nactive(ispin), &
832 72 : -1.0_dp, 1.0_dp)
833 : !
834 72 : CALL dbcsr_release(pdens)
835 : !
836 288 : CALL cp_fm_release(cvec)
837 : END DO
838 :
839 72 : CALL cp_fm_release(xtransformed)
840 :
841 72 : CALL timestop(handle)
842 :
843 144 : END SUBROUTINE tddfpt_apply_hfxlr_kernel
844 :
845 : ! **************************************************************************************************
846 :
847 : END MODULE qs_tddfpt2_operators
|