(git:50c68ef)
Loading...
Searching...
No Matches
qs_fxc.F
Go to the documentation of this file.
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 Setup Routine for Fxc Potentials
10!> \par History
11!> init 17.03.2020
12!> complete refactoring 08.2026
13!> \author JGH
14! **************************************************************************************************
15MODULE qs_fxc
16
25 USE kinds, ONLY: dp
27 USE pw_env_types, ONLY: pw_env_get,&
29 USE pw_grids, ONLY: pw_grid_compare
30 USE pw_methods, ONLY: pw_axpy,&
31 pw_scale,&
35 USE pw_types, ONLY: pw_c1d_gs_type,&
41 USE qs_fxc_atom, ONLY: fxc_atom_calc
45 USE qs_rho_methods, ONLY: qs_rho_copy,&
48 USE qs_rho_types, ONLY: qs_rho_create,&
52 USE qs_vxc, ONLY: qs_vxc_create
64#include "./base/base_uses.f90"
65
66 IMPLICIT NONE
67
68 PRIVATE
69
70 ! *** Public subroutines ***
72 PUBLIC :: qs_fxc_fdiff
73
74 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_fxc'
75
76! **************************************************************************************************
77
78CONTAINS
79
80! **************************************************************************************************
81!> \brief ...
82!> \param qs_env ...
83!> \param rho0_struct ...
84!> \param rho1_struct ...
85!> \param rho0_atom_set ...
86!> \param xc_section ...
87!> \param do_onecenter ...
88!> \param fxc_rho ...
89!> \param fxc_tau ...
90!> \param rho1_atom_set ...
91!> \param do_scale ...
92!> \param is_triplet ...
93!> \param spinflip ...
94!> \param no_weights ...
95!> \param uf_grid_results ...
96!> \param pw_env_ext ...
97!> \param kind_set_external ...
98!> \param para_env_external ...
99!> \param dispersion_env ...
100!> \param compute_virial ...
101!> \param virial_xc ...
102! **************************************************************************************************
103 SUBROUTINE qs_fxc_create(qs_env, rho0_struct, rho1_struct, rho0_atom_set, &
104 xc_section, do_onecenter, &
105 fxc_rho, fxc_tau, rho1_atom_set, &
106 do_scale, is_triplet, spinflip, no_weights, uf_grid_results, &
107 pw_env_ext, kind_set_external, para_env_external, &
108 dispersion_env, compute_virial, virial_xc)
109
110 TYPE(qs_environment_type), POINTER :: qs_env
111 TYPE(qs_rho_type), POINTER :: rho0_struct, rho1_struct
112 TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho0_atom_set
113 TYPE(section_vals_type), POINTER :: xc_section
114 LOGICAL, INTENT(IN) :: do_onecenter
115 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho, fxc_tau
116 TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho1_atom_set
117 LOGICAL, INTENT(IN), OPTIONAL :: do_scale, is_triplet, spinflip, &
118 no_weights, uf_grid_results
119 TYPE(pw_env_type), OPTIONAL, POINTER :: pw_env_ext
120 TYPE(qs_kind_type), DIMENSION(:), OPTIONAL, &
121 POINTER :: kind_set_external
122 TYPE(mp_para_env_type), INTENT(IN), OPTIONAL :: para_env_external
123 TYPE(qs_dispersion_type), OPTIONAL, POINTER :: dispersion_env
124 LOGICAL, INTENT(IN), OPTIONAL :: compute_virial
125 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT), &
126 OPTIONAL :: virial_xc
127
128 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_create'
129
130 INTEGER :: handle, ispin, nspins, nsteps, order, vdw
131 LOGICAL :: do_virial, do_w, ret_uf, uf_grid, vdw_nl
132 REAL(kind=dp) :: eps_delta, factor
133 TYPE(dft_control_type), POINTER :: dft_control
134 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
135 TYPE(pw_c1d_gs_type), POINTER :: rho_nlcc_g
136 TYPE(pw_env_type), POINTER :: pw_env
137 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool, xc_pw_pool
138 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho_lo, fxc_rho_uf, fxc_tau_lo, &
139 fxc_tau_uf, fxc_vdw, rho1_r, rho_r
140 TYPE(pw_r3d_rs_type), POINTER :: rho_nlcc, weights, weights_uf
141 TYPE(qs_rho_type), POINTER :: rho0_uf, rho1_uf
142
143 CALL timeset(routinen, handle)
144
145 do_virial = .false.
146 IF (PRESENT(compute_virial)) do_virial = compute_virial
147
148 CALL get_qs_env(qs_env, dft_control=dft_control)
149
150 IF (PRESENT(pw_env_ext)) THEN
151 pw_env => pw_env_ext
152 ELSE
153 CALL get_qs_env(qs_env, pw_env=pw_env)
154 END IF
155 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, xc_pw_pool=xc_pw_pool)
156 uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
157
158 nspins = dft_control%nspins
159 IF (ASSOCIATED(fxc_rho)) THEN
160 cpassert(nspins == SIZE(fxc_rho))
161 END IF
162 IF (ASSOCIATED(fxc_tau)) THEN
163 cpassert(nspins == SIZE(fxc_tau))
164 END IF
165
166 NULLIFY (rho_nlcc, rho_nlcc_g)
167 CALL get_qs_env(qs_env, rho_nlcc=rho_nlcc, rho_nlcc_g=rho_nlcc_g)
168 IF (ASSOCIATED(rho_nlcc)) THEN
169 NULLIFY (rho_r, rho_g)
170 CALL qs_rho_get(rho0_struct, rho_r=rho_r, rho_g=rho_g)
171 factor = 1.0_dp
172 DO ispin = 1, nspins
173 CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
174 CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
175 END DO
176 END IF
177
178 do_w = .true.
179 IF (PRESENT(no_weights)) do_w = .NOT. no_weights
180 IF (do_w) THEN
181 CALL get_qs_env(qs_env, xcint_weights=weights)
182 ELSE
183 NULLIFY (weights)
184 END IF
185
186 NULLIFY (fxc_rho_lo, fxc_tau_lo)
187 IF (uf_grid) THEN
188 IF (PRESENT(uf_grid_results)) THEN
189 ret_uf = uf_grid_results
190 ELSE
191 ret_uf = .false.
192 END IF
193 NULLIFY (weights_uf)
194 IF (ASSOCIATED(weights)) THEN
195 ALLOCATE (weights_uf)
196 CALL xc_pw_pool%create_pw(weights_uf)
197 block
198 TYPE(pw_c1d_gs_type) :: weights_g, weights_g_uf
199 CALL auxbas_pw_pool%create_pw(weights_g)
200 CALL xc_pw_pool%create_pw(weights_g_uf)
201 CALL pw_transfer(weights, weights_g)
202 CALL pw_transfer(weights_g, weights_g_uf)
203 CALL pw_transfer(weights_g_uf, weights_uf)
204 CALL xc_pw_pool%give_back_pw(weights_g_uf)
205 CALL auxbas_pw_pool%give_back_pw(weights_g)
206 END block
207 END IF
208 !
209 ALLOCATE (rho0_uf, rho1_uf)
210 CALL qs_rho_create(rho0_uf)
211 CALL qs_rho_create(rho1_uf)
212 CALL qs_rho_transfer(rho0_struct, rho0_uf, auxbas_pw_pool, xc_pw_pool)
213 CALL qs_rho_transfer(rho1_struct, rho1_uf, auxbas_pw_pool, xc_pw_pool)
214 !
215 NULLIFY (fxc_rho_uf, fxc_tau_uf)
216 CALL qs_fxc_calculate(rho0_uf, rho1_uf, xc_section, weights_uf, xc_pw_pool, &
217 fxc_rho_uf, fxc_tau_uf, &
218 is_triplet=is_triplet, spinflip=spinflip, &
219 compute_virial=do_virial, virial_xc=virial_xc)
220 !
221 CALL qs_rho_release(rho0_uf)
222 CALL qs_rho_release(rho1_uf)
223 DEALLOCATE (rho0_uf, rho1_uf)
224 IF (ASSOCIATED(weights_uf)) THEN
225 CALL xc_pw_pool%give_back_pw(weights_uf)
226 DEALLOCATE (weights_uf)
227 END IF
228 IF (ret_uf) THEN
229 fxc_rho_lo => fxc_rho_uf
230 fxc_tau_lo => fxc_tau_uf
231 ELSE
232 IF (ASSOCIATED(fxc_rho_uf)) THEN
233 ALLOCATE (fxc_rho_lo(SIZE(fxc_rho_uf)))
234 DO ispin = 1, SIZE(fxc_rho_uf)
235 CALL auxbas_pw_pool%create_pw(fxc_rho_lo(ispin))
236 block
237 TYPE(pw_c1d_gs_type) :: fxc_g, fxc_g_uf
238 CALL auxbas_pw_pool%create_pw(fxc_g)
239 CALL xc_pw_pool%create_pw(fxc_g_uf)
240 CALL pw_transfer(fxc_rho_uf(ispin), fxc_g_uf)
241 CALL pw_transfer(fxc_g_uf, fxc_g)
242 CALL pw_transfer(fxc_g, fxc_rho_lo(ispin))
243 CALL xc_pw_pool%give_back_pw(fxc_g_uf)
244 CALL auxbas_pw_pool%give_back_pw(fxc_g)
245 END block
246 CALL xc_pw_pool%give_back_pw(fxc_rho_uf(ispin))
247 END DO
248 DEALLOCATE (fxc_rho_uf)
249 END IF
250 IF (ASSOCIATED(fxc_tau_uf)) THEN
251 ALLOCATE (fxc_tau_lo(SIZE(fxc_tau_uf)))
252 DO ispin = 1, SIZE(fxc_tau_uf)
253 CALL auxbas_pw_pool%create_pw(fxc_tau_lo(ispin))
254 block
255 TYPE(pw_c1d_gs_type) :: fxc_g, fxc_g_uf
256 CALL auxbas_pw_pool%create_pw(fxc_g)
257 CALL xc_pw_pool%create_pw(fxc_g_uf)
258 CALL pw_transfer(fxc_tau_uf(ispin), fxc_g_uf)
259 CALL pw_transfer(fxc_g_uf, fxc_g)
260 CALL pw_transfer(fxc_g, fxc_tau_lo(ispin))
261 CALL xc_pw_pool%give_back_pw(fxc_g_uf)
262 CALL auxbas_pw_pool%give_back_pw(fxc_g)
263 END block
264 CALL xc_pw_pool%give_back_pw(fxc_tau_uf(ispin))
265 END DO
266 DEALLOCATE (fxc_tau_uf)
267 END IF
268 END IF
269
270 ELSE
271 CALL qs_fxc_calculate(rho0_struct, rho1_struct, xc_section, weights, auxbas_pw_pool, &
272 fxc_rho_lo, fxc_tau_lo, &
273 is_triplet=is_triplet, spinflip=spinflip, &
274 compute_virial=do_virial, virial_xc=virial_xc)
275 END IF
276
277 ! nonlocal vdW functionals
278 vdw_nl = .false.
279 IF (PRESENT(dispersion_env)) THEN
280 CALL section_vals_val_get(xc_section, "VDW_POTENTIAL%POTENTIAL_TYPE", i_val=vdw)
281 vdw_nl = (vdw == xc_vdw_fun_nonloc)
282 IF (vdw_nl) THEN
283 nsteps = section_get_ival(xc_section, "NSTEPS")
284 order = 2*nsteps
285 eps_delta = section_get_rval(xc_section, "STEP_SIZE")
286 CALL qs_rho_get(rho1_struct, rho_r=rho1_r)
287 ALLOCATE (fxc_vdw(nspins))
288 DO ispin = 1, nspins
289 CALL auxbas_pw_pool%create_pw(fxc_vdw(ispin))
290 END DO
291 CALL qs_fxc_nlvdw_fdiff(qs_env, dispersion_env, rho_r, rho1_r, &
292 order, eps_delta, fxc_vdw)
293 END IF
294 END IF
295
296 ! de-apply NLCC density
297 IF (ASSOCIATED(rho_nlcc)) THEN
298 factor = -1.0_dp
299 DO ispin = 1, nspins
300 CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
301 CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
302 END DO
303 END IF
304
305 ! return potentials
306 IF (ASSOCIATED(fxc_rho)) THEN
307 DO ispin = 1, min(SIZE(fxc_rho_lo), SIZE(fxc_rho))
308 CALL pw_transfer(fxc_rho_lo(ispin), fxc_rho(ispin))
309 END DO
310 DO ispin = 1, SIZE(fxc_rho_lo)
311 CALL auxbas_pw_pool%give_back_pw(fxc_rho_lo(ispin))
312 END DO
313 DEALLOCATE (fxc_rho_lo)
314 ELSE
315 fxc_rho => fxc_rho_lo
316 END IF
317 IF (ASSOCIATED(fxc_tau)) THEN
318 IF (ASSOCIATED(fxc_tau_lo)) THEN
319 DO ispin = 1, min(SIZE(fxc_tau_lo), SIZE(fxc_tau))
320 CALL pw_transfer(fxc_tau_lo(ispin), fxc_tau(ispin))
321 END DO
322 DO ispin = 1, SIZE(fxc_tau_lo)
323 CALL auxbas_pw_pool%give_back_pw(fxc_tau_lo(ispin))
324 END DO
325 DEALLOCATE (fxc_tau_lo)
326 ELSE
327 DO ispin = 1, nspins
328 CALL pw_zero(fxc_tau(ispin))
329 END DO
330 END IF
331 ELSE
332 fxc_tau => fxc_tau_lo
333 END IF
334
335 ! Add possible nl-vdW pootential
336 IF (vdw_nl) THEN
337 DO ispin = 1, nspins
338 CALL pw_axpy(fxc_vdw(ispin), fxc_rho(ispin), 1.0_dp)
339 CALL auxbas_pw_pool%give_back_pw(fxc_vdw(ispin))
340 END DO
341 DEALLOCATE (fxc_vdw)
342 END IF
343
344 IF (do_onecenter) THEN
345 CALL fxc_atom_calc(qs_env, rho0_atom_set, rho1_atom_set, xc_section, &
346 do_scale=do_scale, do_triplet=is_triplet, do_sf=spinflip, &
347 para_env_ext=para_env_external, &
348 kind_set_external=kind_set_external)
349 END IF
350
351 CALL timestop(handle)
352
353 END SUBROUTINE qs_fxc_create
354
355! **************************************************************************************************
356!> \brief ...
357!> \param rho0 ...
358!> \param rho1 ...
359!> \param xc_section ...
360!> \param weights ...
361!> \param auxbas_pw_pool ...
362!> \param fxc_rho ...
363!> \param fxc_tau ...
364!> \param is_triplet ...
365!> \param spinflip ...
366!> \param compute_virial ...
367!> \param virial_xc ...
368! **************************************************************************************************
369 SUBROUTINE qs_fxc_calculate(rho0, rho1, xc_section, weights, auxbas_pw_pool, &
370 fxc_rho, fxc_tau, is_triplet, spinflip, &
371 compute_virial, virial_xc)
372
373 TYPE(qs_rho_type), POINTER :: rho0, rho1
374 TYPE(section_vals_type), POINTER :: xc_section
375 TYPE(pw_r3d_rs_type), POINTER :: weights
376 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
377 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho, fxc_tau
378 LOGICAL, INTENT(IN), OPTIONAL :: is_triplet, spinflip, compute_virial
379 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT), &
380 OPTIONAL :: virial_xc
381
382 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_calculate'
383
384 INTEGER :: handle, ispin, mspins, nspins
385 INTEGER, DIMENSION(2, 3) :: bo
386 LOGICAL :: do_analytic, do_sf, do_triplet, &
387 do_virial, lsd
388 REAL(kind=dp), DIMENSION(:, :, :, :), POINTER :: vxg
389 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho0_g, rho1_g
390 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho0_r, rho1_r, tau0_r, tau1_r
391 TYPE(qs_rho_type), POINTER :: rhot0, rhot1
392 TYPE(section_vals_type), POINTER :: xc_fun_section
393 TYPE(xc_derivative_set_type) :: xc_deriv_set
394 TYPE(xc_rho_cflags_type) :: needs
395 TYPE(xc_rho_set_type) :: rho0_set, rho1_set
396
397 CALL timeset(routinen, handle)
398
399 do_triplet = .false.
400 IF (PRESENT(is_triplet)) do_triplet = is_triplet
401
402 do_sf = .false.
403 IF (PRESENT(spinflip)) do_sf = spinflip
404
405 do_virial = .false.
406 IF (PRESENT(compute_virial)) do_virial = compute_virial
407
408 do_analytic = section_get_lval(xc_section, "2ND_DERIV_ANALYTICAL")
409
410 CALL qs_rho_get(rho0, rho_r=rho0_r, rho_g=rho0_g, tau_r=tau0_r)
411 CALL qs_rho_get(rho1, rho_r=rho1_r, tau_r=tau1_r)
412 NULLIFY (rho1_g)
413
414 mspins = SIZE(rho0_r)
415 nspins = SIZE(rho0_r)
416 lsd = (nspins == 2)
417 IF (nspins == 1 .AND. do_triplet) THEN
418 nspins = 2
419 lsd = .true.
420 ELSE IF (do_sf) THEN
421 nspins = 1
422 mspins = 1
423 lsd = .true.
424 END IF
425
426 cpassert(.NOT. ASSOCIATED(fxc_rho))
427 cpassert(.NOT. ASSOCIATED(fxc_tau))
428 xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
429 needs = xc_functionals_get_needs(xc_fun_section, lsd, .true.)
430 ALLOCATE (fxc_rho(mspins))
431 DO ispin = 1, mspins
432 CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
433 CALL pw_zero(fxc_rho(ispin))
434 END DO
435 IF (needs%tau .OR. needs%tau_spin) THEN
436 IF (.NOT. ASSOCIATED(tau1_r)) THEN
437 cpabort("Tau-dependent functionals requires allocated kinetic energy density grid")
438 END IF
439 ALLOCATE (fxc_tau(mspins))
440 DO ispin = 1, mspins
441 CALL auxbas_pw_pool%create_pw(fxc_tau(ispin))
442 CALL pw_zero(fxc_tau(ispin))
443 END DO
444 END IF
445
446 IF (mspins == 1 .AND. do_triplet) THEN
447 ! split the density and response density arrays for triplet calculation
448 ALLOCATE (rhot0)
449 CALL qs_rho_create(rhot0)
450 CALL qs_rho_copy(rho0, rhot0, auxbas_pw_pool, 2, factor=2.0_dp)
451 !
452 ALLOCATE (rhot1)
453 CALL qs_rho_create(rhot1)
454 CALL qs_rho_copy(rho1, rhot1, auxbas_pw_pool, 2, factor=2.0_dp)
455 !
456 CALL qs_rho_get(rhot0, rho_r=rho0_r, rho_g=rho0_g, tau_r=tau0_r)
457 CALL qs_rho_get(rhot1, rho_r=rho1_r, tau_r=tau1_r)
458
459 CALL xc_prep_2nd_deriv(xc_deriv_set, rho0_set, rho0_r, auxbas_pw_pool, weights, &
460 xc_section=xc_section, tau_r=tau0_r)
461 bo = rho1_r(1)%pw_grid%bounds_local
462 ! create the place where to store the argument for the functionals
463 CALL xc_rho_set_create(rho1_set, bo, &
464 rho_cutoff=section_get_rval(xc_section, "DENSITY_CUTOFF"), &
465 drho_cutoff=section_get_rval(xc_section, "GRADIENT_CUTOFF"), &
466 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
467
468 ! calculate the arguments needed by the functionals
469 CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
470 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
471 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
472 auxbas_pw_pool, spinflip=do_sf)
473 ELSE
474 CALL xc_prep_2nd_deriv(xc_deriv_set, rho0_set, rho0_r, auxbas_pw_pool, weights, &
475 xc_section=xc_section, tau_r=tau0_r)
476 bo = rho1_r(1)%pw_grid%bounds_local
477 ! create the place where to store the argument for the functionals
478 CALL xc_rho_set_create(rho1_set, bo, &
479 rho_cutoff=section_get_rval(xc_section, "DENSITY_CUTOFF"), &
480 drho_cutoff=section_get_rval(xc_section, "GRADIENT_CUTOFF"), &
481 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
482
483 ! calculate the arguments needed by the functionals
484 CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
485 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
486 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
487 auxbas_pw_pool, spinflip=do_sf)
488 END IF
489
490 IF (mspins == 1 .AND. do_triplet .AND. do_analytic) THEN
491
492 CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, rho0_set, &
493 rho1_set, auxbas_pw_pool, xc_section, &
494 gapw=.false., vxg=vxg, tddfpt_fac=-1.0_dp, spinflip=do_sf, &
495 compute_virial=compute_virial, virial_xc=virial_xc)
496
497 ELSE IF (do_analytic) THEN
498
499 CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, rho0_set, &
500 rho1_set, auxbas_pw_pool, xc_section, &
501 gapw=.false., vxg=vxg, spinflip=do_sf, &
502 compute_virial=compute_virial, virial_xc=virial_xc)
503
504 ELSE
505
506 CALL xc_calc_2nd_deriv_numerical(fxc_rho, fxc_tau, rho0_set, rho1_r, rho1_g, tau1_r, &
507 auxbas_pw_pool, weights, xc_section, &
508 do_triplet, compute_virial, virial_xc, xc_deriv_set)
509
510 END IF
511
512 IF (mspins == 1 .AND. do_triplet) THEN
513 CALL qs_rho_release(rhot0)
514 DEALLOCATE (rhot0)
515 CALL qs_rho_release(rhot1)
516 DEALLOCATE (rhot1)
517 END IF
518
519 CALL xc_dset_release(xc_deriv_set)
520 CALL xc_rho_set_release(rho0_set)
521 CALL xc_rho_set_release(rho1_set)
522
523 CALL timestop(handle)
524
525 END SUBROUTINE qs_fxc_calculate
526
527! **************************************************************************************************
528!> \brief ...
529!> \param qs_env ...
530!> \param rho0_struct ...
531!> \param xc_rho_set ...
532!> \param xc_deriv_set ...
533!> \param xc_section ...
534!> \param pw_env_ext ...
535!> \param is_triplet ...
536! **************************************************************************************************
537 SUBROUTINE qs_fxc_prep(qs_env, rho0_struct, xc_rho_set, xc_deriv_set, &
538 xc_section, pw_env_ext, is_triplet)
539
540 TYPE(qs_environment_type), POINTER :: qs_env
541 TYPE(qs_rho_type), POINTER :: rho0_struct
542 TYPE(xc_rho_set_type) :: xc_rho_set
543 TYPE(xc_derivative_set_type) :: xc_deriv_set
544 TYPE(section_vals_type), POINTER :: xc_section
545 TYPE(pw_env_type), OPTIONAL, POINTER :: pw_env_ext
546 LOGICAL, INTENT(IN), OPTIONAL :: is_triplet
547
548 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_prep'
549
550 INTEGER :: handle, ispin, nspins
551 LOGICAL :: uf_grid
552 REAL(kind=dp) :: factor
553 TYPE(dft_control_type), POINTER :: dft_control
554 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
555 TYPE(pw_c1d_gs_type), POINTER :: rho_nlcc_g
556 TYPE(pw_env_type), POINTER :: pw_env
557 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool, xc_pw_pool
558 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
559 TYPE(pw_r3d_rs_type), POINTER :: rho_nlcc, weights, weights_uf
560 TYPE(qs_rho_type), POINTER :: rho0_uf
561
562 CALL timeset(routinen, handle)
563
564 CALL get_qs_env(qs_env, dft_control=dft_control)
565
566 IF (PRESENT(pw_env_ext)) THEN
567 pw_env => pw_env_ext
568 ELSE
569 CALL get_qs_env(qs_env, pw_env=pw_env)
570 END IF
571 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, xc_pw_pool=xc_pw_pool)
572 uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
573
574 nspins = dft_control%nspins
575
576 NULLIFY (rho_nlcc, rho_nlcc_g)
577 CALL get_qs_env(qs_env, rho_nlcc=rho_nlcc, rho_nlcc_g=rho_nlcc_g)
578 IF (ASSOCIATED(rho_nlcc)) THEN
579 NULLIFY (rho_r, rho_g)
580 CALL qs_rho_get(rho0_struct, rho_r=rho_r, rho_g=rho_g)
581 factor = 1.0_dp
582 DO ispin = 1, nspins
583 CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
584 CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
585 END DO
586 END IF
587
588 NULLIFY (weights)
589 CALL get_qs_env(qs_env, xcint_weights=weights)
590
591 IF (uf_grid) THEN
592 NULLIFY (weights_uf)
593 IF (ASSOCIATED(weights)) THEN
594 ALLOCATE (weights_uf)
595 CALL xc_pw_pool%create_pw(weights_uf)
596 block
597 TYPE(pw_c1d_gs_type) :: weights_g, weights_g_uf
598 CALL auxbas_pw_pool%create_pw(weights_g)
599 CALL xc_pw_pool%create_pw(weights_g_uf)
600 CALL pw_transfer(weights, weights_g)
601 CALL pw_transfer(weights_g, weights_g_uf)
602 CALL pw_transfer(weights_g_uf, weights_uf)
603 CALL xc_pw_pool%give_back_pw(weights_g_uf)
604 CALL auxbas_pw_pool%give_back_pw(weights_g)
605 END block
606 END IF
607 !
608 ALLOCATE (rho0_uf)
609 CALL qs_rho_create(rho0_uf)
610 CALL qs_rho_transfer(rho0_struct, rho0_uf, auxbas_pw_pool, xc_pw_pool)
611 !
612 CALL qs_fxc_deriv(rho0_uf, xc_rho_set, xc_deriv_set, &
613 xc_section, weights_uf, xc_pw_pool, is_triplet)
614 !
615 CALL qs_rho_release(rho0_uf)
616 DEALLOCATE (rho0_uf)
617 IF (ASSOCIATED(weights_uf)) THEN
618 CALL xc_pw_pool%give_back_pw(weights_uf)
619 DEALLOCATE (weights_uf)
620 END IF
621 ELSE
622 CALL qs_fxc_deriv(rho0_struct, xc_rho_set, xc_deriv_set, &
623 xc_section, weights, auxbas_pw_pool, is_triplet)
624 END IF
625
626 ! de-apply NLCC density
627 IF (ASSOCIATED(rho_nlcc)) THEN
628 factor = -1.0_dp
629 DO ispin = 1, nspins
630 CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
631 CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
632 END DO
633 END IF
634
635 CALL timestop(handle)
636
637 END SUBROUTINE qs_fxc_prep
638
639! **************************************************************************************************
640!> \brief ...
641!> \param rho0 ...
642!> \param xc_rho_set ...
643!> \param xc_deriv_set ...
644!> \param xc_section ...
645!> \param weights ...
646!> \param auxbas_pw_pool ...
647!> \param is_triplet ...
648! **************************************************************************************************
649 SUBROUTINE qs_fxc_deriv(rho0, xc_rho_set, xc_deriv_set, xc_section, weights, auxbas_pw_pool, &
650 is_triplet)
651
652 TYPE(qs_rho_type), POINTER :: rho0
653 TYPE(xc_rho_set_type) :: xc_rho_set
654 TYPE(xc_derivative_set_type) :: xc_deriv_set
655 TYPE(section_vals_type), POINTER :: xc_section
656 TYPE(pw_r3d_rs_type), POINTER :: weights
657 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
658 LOGICAL, INTENT(IN) :: is_triplet
659
660 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_deriv'
661
662 INTEGER :: handle
663 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho0_r, tau0_r
664 TYPE(qs_rho_type), POINTER :: rhot0
665
666 CALL timeset(routinen, handle)
667
668 NULLIFY (rho0_r, tau0_r)
669 IF (is_triplet) THEN
670 ! split the density and response density arrays for triplet calculation
671 ALLOCATE (rhot0)
672 CALL qs_rho_create(rhot0)
673 CALL qs_rho_copy(rho0, rhot0, auxbas_pw_pool, 2, factor=2.0_dp)
674 CALL qs_rho_get(rhot0, rho_r=rho0_r, tau_r=tau0_r)
675 CALL xc_prep_2nd_deriv(xc_deriv_set, xc_rho_set, rho0_r, auxbas_pw_pool, weights, &
676 xc_section=xc_section, tau_r=tau0_r)
677 CALL qs_rho_release(rhot0)
678 DEALLOCATE (rhot0)
679 ELSE
680 CALL qs_rho_get(rho0, rho_r=rho0_r, tau_r=tau0_r)
681 CALL xc_prep_2nd_deriv(xc_deriv_set, xc_rho_set, rho0_r, auxbas_pw_pool, weights, &
682 xc_section=xc_section, tau_r=tau0_r)
683 END IF
684
685 CALL timestop(handle)
686
687 END SUBROUTINE qs_fxc_deriv
688
689! **************************************************************************************************
690!> \brief ...
691!> \param qs_env ...
692!> \param xc_deriv_set ...
693!> \param xc_rho_set ...
694!> \param rho1_struct ...
695!> \param rho0_atom_set ...
696!> \param xc_section ...
697!> \param do_onecenter ...
698!> \param fxc_rho ...
699!> \param fxc_tau ...
700!> \param rho1_atom_set ...
701!> \param do_scale ...
702!> \param is_triplet ...
703!> \param spinflip ...
704!> \param pw_env_ext ...
705!> \param kind_set_external ...
706!> \param para_env_external ...
707!> \param compute_virial ...
708!> \param virial_xc ...
709! **************************************************************************************************
710 SUBROUTINE qs_fxc_apply(qs_env, xc_deriv_set, xc_rho_set, rho1_struct, rho0_atom_set, &
711 xc_section, do_onecenter, fxc_rho, fxc_tau, rho1_atom_set, &
712 do_scale, is_triplet, spinflip, pw_env_ext, &
713 kind_set_external, para_env_external, compute_virial, virial_xc)
714
715 TYPE(qs_environment_type), POINTER :: qs_env
716 TYPE(xc_derivative_set_type) :: xc_deriv_set
717 TYPE(xc_rho_set_type) :: xc_rho_set
718 TYPE(qs_rho_type), POINTER :: rho1_struct
719 TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho0_atom_set
720 TYPE(section_vals_type), POINTER :: xc_section
721 LOGICAL, INTENT(IN) :: do_onecenter
722 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho, fxc_tau
723 TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho1_atom_set
724 LOGICAL, INTENT(IN), OPTIONAL :: do_scale, is_triplet, spinflip
725 TYPE(pw_env_type), OPTIONAL, POINTER :: pw_env_ext
726 TYPE(qs_kind_type), DIMENSION(:), OPTIONAL, &
727 POINTER :: kind_set_external
728 TYPE(mp_para_env_type), INTENT(IN), OPTIONAL :: para_env_external
729 LOGICAL, INTENT(IN), OPTIONAL :: compute_virial
730 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT), &
731 OPTIONAL :: virial_xc
732
733 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_apply'
734
735 INTEGER :: handle, ispin, nspins
736 LOGICAL :: do_virial, uf_grid
737 TYPE(dft_control_type), POINTER :: dft_control
738 TYPE(pw_env_type), POINTER :: pw_env
739 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool, xc_pw_pool
740 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho_lo, fxc_rho_uf, fxc_tau_lo, &
741 fxc_tau_uf
742 TYPE(pw_r3d_rs_type), POINTER :: weights, weights_uf
743 TYPE(qs_rho_type), POINTER :: rho1_uf
744
745 CALL timeset(routinen, handle)
746
747 do_virial = .false.
748 IF (PRESENT(compute_virial)) do_virial = compute_virial
749
750 CALL get_qs_env(qs_env, dft_control=dft_control)
751
752 IF (PRESENT(pw_env_ext)) THEN
753 pw_env => pw_env_ext
754 ELSE
755 CALL get_qs_env(qs_env, pw_env=pw_env)
756 END IF
757 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, xc_pw_pool=xc_pw_pool)
758 uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
759
760 nspins = dft_control%nspins
761 IF (ASSOCIATED(fxc_rho)) THEN
762 cpassert(nspins == SIZE(fxc_rho))
763 END IF
764 IF (ASSOCIATED(fxc_tau)) THEN
765 cpassert(nspins == SIZE(fxc_tau))
766 END IF
767
768 CALL get_qs_env(qs_env, xcint_weights=weights)
769
770 NULLIFY (fxc_rho_lo, fxc_tau_lo)
771 IF (uf_grid) THEN
772 NULLIFY (weights_uf)
773 IF (ASSOCIATED(weights)) THEN
774 ALLOCATE (weights_uf)
775 CALL xc_pw_pool%create_pw(weights_uf)
776 block
777 TYPE(pw_c1d_gs_type) :: weights_g, weights_g_uf
778 CALL auxbas_pw_pool%create_pw(weights_g)
779 CALL xc_pw_pool%create_pw(weights_g_uf)
780 CALL pw_transfer(weights, weights_g)
781 CALL pw_transfer(weights_g, weights_g_uf)
782 CALL pw_transfer(weights_g_uf, weights_uf)
783 CALL xc_pw_pool%give_back_pw(weights_g_uf)
784 CALL auxbas_pw_pool%give_back_pw(weights_g)
785 END block
786 END IF
787 !
788 ALLOCATE (rho1_uf)
789 CALL qs_rho_create(rho1_uf)
790 CALL qs_rho_transfer(rho1_struct, rho1_uf, auxbas_pw_pool, xc_pw_pool)
791 !
792 NULLIFY (fxc_rho_uf, fxc_tau_uf)
793 CALL qs_fxc_eval(xc_deriv_set, xc_rho_set, rho1_uf, xc_section, &
794 weights_uf, xc_pw_pool, fxc_rho_uf, fxc_tau_uf, &
795 is_triplet=is_triplet, spinflip=spinflip, &
796 compute_virial=do_virial, virial_xc=virial_xc)
797 !
798 CALL qs_rho_release(rho1_uf)
799 DEALLOCATE (rho1_uf)
800 IF (ASSOCIATED(weights_uf)) THEN
801 CALL xc_pw_pool%give_back_pw(weights_uf)
802 DEALLOCATE (weights_uf)
803 END IF
804 IF (ASSOCIATED(fxc_rho_uf)) THEN
805 ALLOCATE (fxc_rho_lo(SIZE(fxc_rho_uf)))
806 DO ispin = 1, SIZE(fxc_rho_uf)
807 CALL auxbas_pw_pool%create_pw(fxc_rho_lo(ispin))
808 block
809 TYPE(pw_c1d_gs_type) :: fxc_g, fxc_g_uf
810 CALL auxbas_pw_pool%create_pw(fxc_g)
811 CALL xc_pw_pool%create_pw(fxc_g_uf)
812 CALL pw_transfer(fxc_rho_uf(ispin), fxc_g_uf)
813 CALL pw_transfer(fxc_g_uf, fxc_g)
814 CALL pw_transfer(fxc_g, fxc_rho_lo(ispin))
815 CALL xc_pw_pool%give_back_pw(fxc_g_uf)
816 CALL auxbas_pw_pool%give_back_pw(fxc_g)
817 END block
818 CALL xc_pw_pool%give_back_pw(fxc_rho_uf(ispin))
819 END DO
820 DEALLOCATE (fxc_rho_uf)
821 END IF
822 IF (ASSOCIATED(fxc_tau_uf)) THEN
823 ALLOCATE (fxc_tau_lo(SIZE(fxc_tau_uf)))
824 DO ispin = 1, SIZE(fxc_tau_uf)
825 CALL auxbas_pw_pool%create_pw(fxc_tau_lo(ispin))
826 block
827 TYPE(pw_c1d_gs_type) :: fxc_g, fxc_g_uf
828 CALL auxbas_pw_pool%create_pw(fxc_g)
829 CALL xc_pw_pool%create_pw(fxc_g_uf)
830 CALL pw_transfer(fxc_tau_uf(ispin), fxc_g_uf)
831 CALL pw_transfer(fxc_g_uf, fxc_g)
832 CALL pw_transfer(fxc_g, fxc_tau_lo(ispin))
833 CALL xc_pw_pool%give_back_pw(fxc_g_uf)
834 CALL auxbas_pw_pool%give_back_pw(fxc_g)
835 END block
836 CALL xc_pw_pool%give_back_pw(fxc_tau_uf(ispin))
837 END DO
838 DEALLOCATE (fxc_tau_uf)
839 END IF
840
841 ELSE
842 CALL qs_fxc_eval(xc_deriv_set, xc_rho_set, rho1_struct, xc_section, &
843 weights, auxbas_pw_pool, fxc_rho_lo, fxc_tau_lo, &
844 is_triplet=is_triplet, spinflip=spinflip, &
845 compute_virial=do_virial, virial_xc=virial_xc)
846 END IF
847
848 ! return potentials
849 IF (ASSOCIATED(fxc_rho)) THEN
850 DO ispin = 1, min(SIZE(fxc_rho_lo), SIZE(fxc_rho))
851 CALL pw_transfer(fxc_rho_lo(ispin), fxc_rho(ispin))
852 END DO
853 DO ispin = 1, SIZE(fxc_rho_lo)
854 CALL auxbas_pw_pool%give_back_pw(fxc_rho_lo(ispin))
855 END DO
856 DEALLOCATE (fxc_rho_lo)
857 ELSE
858 fxc_rho => fxc_rho_lo
859 END IF
860 IF (ASSOCIATED(fxc_tau)) THEN
861 IF (ASSOCIATED(fxc_tau_lo)) THEN
862 DO ispin = 1, min(SIZE(fxc_tau_lo), SIZE(fxc_tau))
863 CALL pw_transfer(fxc_tau_lo(ispin), fxc_tau(ispin))
864 END DO
865 DO ispin = 1, SIZE(fxc_tau_lo)
866 CALL auxbas_pw_pool%give_back_pw(fxc_tau_lo(ispin))
867 END DO
868 DEALLOCATE (fxc_tau_lo)
869 ELSE
870 DO ispin = 1, nspins
871 CALL pw_zero(fxc_tau(ispin))
872 END DO
873 END IF
874 ELSE
875 fxc_tau => fxc_tau_lo
876 END IF
877
878 IF (do_onecenter) THEN
879 CALL fxc_atom_calc(qs_env, rho0_atom_set, rho1_atom_set, xc_section, &
880 do_scale=do_scale, do_triplet=is_triplet, do_sf=spinflip, &
881 para_env_ext=para_env_external, &
882 kind_set_external=kind_set_external)
883 END IF
884
885 CALL timestop(handle)
886
887 END SUBROUTINE qs_fxc_apply
888
889! **************************************************************************************************
890!> \brief ...
891!> \param xc_deriv_set ...
892!> \param xc_rho_set ...
893!> \param rho1 ...
894!> \param xc_section ...
895!> \param weights ...
896!> \param auxbas_pw_pool ...
897!> \param fxc_rho ...
898!> \param fxc_tau ...
899!> \param is_triplet ...
900!> \param spinflip ...
901!> \param compute_virial ...
902!> \param virial_xc ...
903! **************************************************************************************************
904 SUBROUTINE qs_fxc_eval(xc_deriv_set, xc_rho_set, rho1, xc_section, weights, auxbas_pw_pool, &
905 fxc_rho, fxc_tau, is_triplet, spinflip, &
906 compute_virial, virial_xc)
907
908 TYPE(xc_derivative_set_type) :: xc_deriv_set
909 TYPE(xc_rho_set_type) :: xc_rho_set
910 TYPE(qs_rho_type), POINTER :: rho1
911 TYPE(section_vals_type), POINTER :: xc_section
912 TYPE(pw_r3d_rs_type), POINTER :: weights
913 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
914 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho, fxc_tau
915 LOGICAL, INTENT(IN), OPTIONAL :: is_triplet, spinflip, compute_virial
916 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT), &
917 OPTIONAL :: virial_xc
918
919 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_eval'
920
921 INTEGER :: handle, ispin, mspins, nspins
922 INTEGER, DIMENSION(2, 3) :: bo
923 LOGICAL :: do_analytic, do_sf, do_triplet, &
924 do_virial, lsd
925 REAL(kind=dp), DIMENSION(:, :, :, :), POINTER :: vxg
926 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho1_g
927 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho1_r, tau1_r
928 TYPE(qs_rho_type), POINTER :: rhot1
929 TYPE(section_vals_type), POINTER :: xc_fun_section
930 TYPE(xc_rho_cflags_type) :: needs
931 TYPE(xc_rho_set_type) :: rho1_set
932
933 CALL timeset(routinen, handle)
934
935 do_triplet = .false.
936 IF (PRESENT(is_triplet)) do_triplet = is_triplet
937
938 do_sf = .false.
939 IF (PRESENT(spinflip)) do_sf = spinflip
940
941 do_virial = .false.
942 IF (PRESENT(compute_virial)) do_virial = compute_virial
943
944 do_analytic = section_get_lval(xc_section, "2ND_DERIV_ANALYTICAL")
945
946 CALL qs_rho_get(rho1, rho_r=rho1_r, tau_r=tau1_r)
947 NULLIFY (rho1_g)
948
949 mspins = SIZE(rho1_r)
950 nspins = SIZE(rho1_r)
951 lsd = (nspins == 2)
952 IF (nspins == 1 .AND. do_triplet) THEN
953 nspins = 2
954 lsd = .true.
955 ELSE IF (do_sf) THEN
956 nspins = 1
957 mspins = 1
958 lsd = .true.
959 END IF
960
961 cpassert(.NOT. ASSOCIATED(fxc_rho))
962 cpassert(.NOT. ASSOCIATED(fxc_tau))
963 xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
964 needs = xc_functionals_get_needs(xc_fun_section, lsd, .true.)
965 ALLOCATE (fxc_rho(mspins))
966 DO ispin = 1, mspins
967 CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
968 CALL pw_zero(fxc_rho(ispin))
969 END DO
970 IF (needs%tau .OR. needs%tau_spin) THEN
971 IF (.NOT. ASSOCIATED(tau1_r)) THEN
972 cpabort("Tau-dependent functionals requires allocated kinetic energy density grid")
973 END IF
974 ALLOCATE (fxc_tau(mspins))
975 DO ispin = 1, mspins
976 CALL auxbas_pw_pool%create_pw(fxc_tau(ispin))
977 CALL pw_zero(fxc_tau(ispin))
978 END DO
979 END IF
980
981 IF (mspins == 1 .AND. do_triplet) THEN
982 ! split the density and response density arrays for triplet calculation
983 ALLOCATE (rhot1)
984 CALL qs_rho_create(rhot1)
985 CALL qs_rho_copy(rho1, rhot1, auxbas_pw_pool, 2, factor=2.0_dp)
986 !
987 CALL qs_rho_get(rhot1, rho_r=rho1_r, tau_r=tau1_r)
988 END IF
989
990 bo = rho1_r(1)%pw_grid%bounds_local
991 ! create the place where to store the argument for the functionals
992 CALL xc_rho_set_create(rho1_set, bo, &
993 rho_cutoff=section_get_rval(xc_section, "DENSITY_CUTOFF"), &
994 drho_cutoff=section_get_rval(xc_section, "GRADIENT_CUTOFF"), &
995 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
996
997 ! calculate the arguments needed by the functionals
998 CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
999 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
1000 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
1001 auxbas_pw_pool, spinflip=do_sf)
1002
1003 IF (mspins == 1 .AND. do_triplet .AND. do_analytic) THEN
1004
1005 CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, xc_rho_set, &
1006 rho1_set, auxbas_pw_pool, xc_section, &
1007 gapw=.false., vxg=vxg, tddfpt_fac=-1.0_dp, spinflip=do_sf, &
1008 compute_virial=compute_virial, virial_xc=virial_xc)
1009
1010 ELSE IF (do_analytic) THEN
1011
1012 CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, xc_rho_set, &
1013 rho1_set, auxbas_pw_pool, xc_section, &
1014 gapw=.false., vxg=vxg, spinflip=do_sf, &
1015 compute_virial=compute_virial, virial_xc=virial_xc)
1016
1017 ELSE
1018
1019 CALL xc_calc_2nd_deriv_numerical(fxc_rho, fxc_tau, xc_rho_set, rho1_r, rho1_g, tau1_r, &
1020 auxbas_pw_pool, weights, xc_section, &
1021 do_triplet, compute_virial, virial_xc, xc_deriv_set)
1022
1023 END IF
1024
1025 IF (mspins == 1 .AND. do_triplet) THEN
1026 CALL qs_rho_release(rhot1)
1027 DEALLOCATE (rhot1)
1028 END IF
1029 CALL xc_rho_set_release(rho1_set)
1030
1031 CALL timestop(handle)
1032
1033 END SUBROUTINE qs_fxc_eval
1034
1035! **************************************************************************************************
1036!> \brief ...
1037!> \param qs_env ...
1038!> \param rho0_struct ...
1039!> \param rho1_struct ...
1040!> \param xc_section ...
1041!> \param accuracy ...
1042!> \param fxc_rho ...
1043!> \param fxc_tau ...
1044!> \param is_triplet ...
1045!> \param spinflip ...
1046!>
1047!>
1048!> https://en.wikipedia.org/wiki/Finite_difference_coefficient
1049!> ---------------------------------------------------------------------------------------------------
1050!> Derivative Accuracy 4 3 2 1 0 1 2 3 4
1051!> ---------------------------------------------------------------------------------------------------
1052!> 1 2 -1/2 0 1/2
1053!> 4 1/12 -2/3 0 2/3 -1/12
1054!> 6 -1/60 3/20 -3/4 0 3/4 -3/20 1/60
1055!> 8 1/280 -4/105 1/5 -4/5 0 4/5 -1/5 4/105 -1/280
1056!> ---------------------------------------------------------------------------------------------------
1057!> 2 2 1 -2 1
1058!> 4 -1/12 4/3 -5/2 4/3 -1/12
1059!> 6 1/90 -3/20 3/2 -49/18 3/2 -3/20 1/90
1060!> 8 -1/560 8/315 -1/5 8/5 -205/72 8/5 -1/5 8/315 -1/560
1061!> ---------------------------------------------------------------------------------------------------
1062! **************************************************************************************************
1063 SUBROUTINE qs_fxc_fdiff(qs_env, rho0_struct, rho1_struct, xc_section, accuracy, &
1064 fxc_rho, fxc_tau, is_triplet, spinflip)
1065
1066 TYPE(qs_environment_type), POINTER :: qs_env
1067 TYPE(qs_rho_type), POINTER :: rho0_struct, rho1_struct
1068 TYPE(section_vals_type), POINTER :: xc_section
1069 INTEGER, INTENT(IN) :: accuracy
1070 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho, fxc_tau
1071 LOGICAL, INTENT(IN), OPTIONAL :: is_triplet, spinflip
1072
1073 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_fdiff'
1074 REAL(kind=dp), PARAMETER :: epsrho = 5.e-4_dp
1075
1076 INTEGER :: handle, ispin, istep, nspins, nstep
1077 LOGICAL :: do_sf, do_triplet
1078 REAL(kind=dp) :: alpha, beta, exc, oeps1
1079 REAL(kind=dp), DIMENSION(-4:4) :: ak
1080 TYPE(dft_control_type), POINTER :: dft_control
1081 TYPE(pw_env_type), POINTER :: pw_env
1082 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1083 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_tau_rspace, vxc00
1084 TYPE(qs_ks_env_type), POINTER :: ks_env
1085 TYPE(qs_rho_type), POINTER :: rhoin
1086
1087 CALL timeset(routinen, handle)
1088
1089 cpassert(.NOT. ASSOCIATED(fxc_rho))
1090 cpassert(.NOT. ASSOCIATED(fxc_tau))
1091 cpassert(ASSOCIATED(rho0_struct))
1092 cpassert(ASSOCIATED(rho1_struct))
1093
1094 do_triplet = .false.
1095 IF (PRESENT(is_triplet)) do_triplet = is_triplet
1096
1097 do_sf = .false.
1098 IF (PRESENT(spinflip)) do_sf = spinflip
1099 IF (do_sf) THEN
1100 cpabort("Spin Flip TDDFT only available with analytic 2nd xc derivatives")
1101 END IF
1102
1103 ak = 0.0_dp
1104 SELECT CASE (accuracy)
1105 CASE (:4)
1106 nstep = 2
1107 ak(-2:2) = [1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp]/12.0_dp
1108 CASE (5:7)
1109 nstep = 3
1110 ak(-3:3) = [-1.0_dp, 9.0_dp, -45.0_dp, 0.0_dp, 45.0_dp, -9.0_dp, 1.0_dp]/60.0_dp
1111 CASE (8:)
1112 nstep = 4
1113 ak(-4:4) = [1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
1114 224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp]/280.0_dp
1115 END SELECT
1116
1117 CALL get_qs_env(qs_env, ks_env=ks_env, dft_control=dft_control, pw_env=pw_env)
1118 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
1119
1120 nspins = dft_control%nspins
1121 exc = 0.0_dp
1122
1123 DO istep = -nstep, nstep
1124
1125 IF (ak(istep) /= 0.0_dp) THEN
1126 alpha = 1.0_dp
1127 beta = real(istep, kind=dp)*epsrho
1128 NULLIFY (rhoin)
1129 ALLOCATE (rhoin)
1130 CALL qs_rho_create(rhoin)
1131 NULLIFY (vxc00, v_tau_rspace)
1132 IF (do_triplet) THEN
1133 cpassert(nspins == 1)
1134 ! rhoin = (0.5 rho0, 0.5 rho0)
1135 CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, 2)
1136 ! rhoin = (0.5 rho0 + 0.5 rho1, 0.5 rho0)
1137 CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, 0.5_dp*beta)
1138 CALL qs_vxc_create(ks_env, rhoin, xc_section, vxc00, v_tau_rspace, exc)
1139 CALL pw_axpy(vxc00(2), vxc00(1), -1.0_dp)
1140 IF (ASSOCIATED(v_tau_rspace)) CALL pw_axpy(v_tau_rspace(2), v_tau_rspace(1), -1.0_dp)
1141 ELSE
1142 CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, nspins)
1143 CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, beta)
1144 CALL qs_vxc_create(ks_env, rhoin, xc_section, vxc00, v_tau_rspace, exc)
1145 END IF
1146 CALL qs_rho_release(rhoin)
1147 DEALLOCATE (rhoin)
1148 IF (.NOT. ASSOCIATED(fxc_rho)) THEN
1149 ALLOCATE (fxc_rho(nspins))
1150 DO ispin = 1, nspins
1151 CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
1152 CALL pw_zero(fxc_rho(ispin))
1153 END DO
1154 END IF
1155 DO ispin = 1, nspins
1156 CALL pw_axpy(vxc00(ispin), fxc_rho(ispin), ak(istep))
1157 END DO
1158 DO ispin = 1, SIZE(vxc00)
1159 CALL auxbas_pw_pool%give_back_pw(vxc00(ispin))
1160 END DO
1161 DEALLOCATE (vxc00)
1162 IF (ASSOCIATED(v_tau_rspace)) THEN
1163 IF (.NOT. ASSOCIATED(fxc_tau)) THEN
1164 ALLOCATE (fxc_tau(nspins))
1165 DO ispin = 1, nspins
1166 CALL auxbas_pw_pool%create_pw(fxc_tau(ispin))
1167 CALL pw_zero(fxc_tau(ispin))
1168 END DO
1169 END IF
1170 DO ispin = 1, nspins
1171 CALL pw_axpy(v_tau_rspace(ispin), fxc_tau(ispin), ak(istep))
1172 END DO
1173 DO ispin = 1, SIZE(v_tau_rspace)
1174 CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
1175 END DO
1176 DEALLOCATE (v_tau_rspace)
1177 END IF
1178 END IF
1179
1180 END DO
1181
1182 oeps1 = 1.0_dp/epsrho
1183 DO ispin = 1, nspins
1184 CALL pw_scale(fxc_rho(ispin), oeps1)
1185 END DO
1186 IF (ASSOCIATED(fxc_tau)) THEN
1187 DO ispin = 1, nspins
1188 CALL pw_scale(fxc_tau(ispin), oeps1)
1189 END DO
1190 END IF
1191
1192 CALL timestop(handle)
1193
1194 END SUBROUTINE qs_fxc_fdiff
1195
1196END MODULE qs_fxc
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public xc_vdw_fun_nonloc
objects that represent the structure of input sections and the data contained in an input section
real(kind=dp) function, public section_get_rval(section_vals, keyword_name)
...
integer function, public section_get_ival(section_vals, keyword_name)
...
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
logical function, public section_get_lval(section_vals, keyword_name)
...
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Interface to the message passing library MPI.
container for various plainwaves related things
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
This module defines the grid data type and some basic operations on it.
Definition pw_grids.F:36
logical function, public pw_grid_compare(grida, gridb)
Check if two pw_grids are equal.
Definition pw_grids.F:148
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Calculation of non local dispersion functionals Some routines adapted from: Copyright (C) 2001-2009 Q...
subroutine, public qs_fxc_nlvdw_fdiff(qs_env, dispersion_env, rho0_r, rho1_r, accuracy, epsrho, fxc_rho)
Second derivative of nl-vdW potential using finite differences.
Definition of disperson types for DFT calculations.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
routines that build the integrals of the Fxc kernel calculated for the atomic density in the basis se...
Definition qs_fxc_atom.F:12
subroutine, public fxc_atom_calc(qs_env, rho_atom_set, rho1_atom_set, xc_section, para_env_ext, do_scale, do_triplet, do_sf, kind_set_external)
...
Definition qs_fxc_atom.F:76
Setup Routine for Fxc Potentials.
Definition qs_fxc.F:15
subroutine, public qs_fxc_apply(qs_env, xc_deriv_set, xc_rho_set, rho1_struct, rho0_atom_set, xc_section, do_onecenter, fxc_rho, fxc_tau, rho1_atom_set, do_scale, is_triplet, spinflip, pw_env_ext, kind_set_external, para_env_external, compute_virial, virial_xc)
...
Definition qs_fxc.F:714
subroutine, public qs_fxc_prep(qs_env, rho0_struct, xc_rho_set, xc_deriv_set, xc_section, pw_env_ext, is_triplet)
...
Definition qs_fxc.F:539
subroutine, public qs_fxc_create(qs_env, rho0_struct, rho1_struct, rho0_atom_set, xc_section, do_onecenter, fxc_rho, fxc_tau, rho1_atom_set, do_scale, is_triplet, spinflip, no_weights, uf_grid_results, pw_env_ext, kind_set_external, para_env_external, dispersion_env, compute_virial, virial_xc)
...
Definition qs_fxc.F:109
subroutine, public qs_fxc_fdiff(qs_env, rho0_struct, rho1_struct, xc_section, accuracy, fxc_rho, fxc_tau, is_triplet, spinflip)
...
Definition qs_fxc.F:1065
Define the quickstep kind type and their sub types.
methods of the rho structure (defined in qs_rho_types)
subroutine, public qs_rho_copy(rho_input, rho_output, auxbas_pw_pool, mspin, factor)
Allocate a density structure and fill it with data from an input structure SIZE(rho_input) == mspin =...
subroutine, public qs_rho_scale_and_add(rhoa, rhob, alpha, beta)
rhoa = alpha*rhoa+beta*rhob
subroutine, public qs_rho_transfer(rho_input, rho_output, in_pw_pool, out_pw_pool)
Allocate a density structure and fill it with data from an input structure Transfer all data to input...
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
subroutine, public qs_rho_create(rho)
Allocates a new instance of rho.
subroutine, public qs_rho_release(rho_struct)
releases a rho_struct by decreasing the reference count by one and deallocating if it reaches 0 (to b...
subroutine, public qs_vxc_create(ks_env, rho_struct, xc_section, vxc_rho, vxc_tau, exc, just_energy, edisp, dispersion_env, adiabatic_rescale_factor, pw_env_external, native_skala_atom_force, qs_env_external, native_gapw_composite_override, native_skala_defer_to_atom_composite)
calculates and allocates the xc potential, already reducing it to the dependence on rho and the one o...
Definition qs_vxc.F:120
represent a group ofunctional derivatives
subroutine, public xc_dset_release(derivative_set)
releases a derivative set
type(xc_rho_cflags_type) function, public xc_functionals_get_needs(functionals, lsd, calc_potential)
...
contains the structure
contains the structure
subroutine, public xc_rho_set_create(rho_set, local_bounds, rho_cutoff, drho_cutoff, tau_cutoff)
allocates and does (minimal) initialization of a rho_set
subroutine, public xc_rho_set_release(rho_set, pw_pool)
releases the given rho_set
subroutine, public xc_rho_set_update(rho_set, rho_r, rho_g, tau, needs, xc_deriv_method_id, xc_rho_smooth_id, pw_pool, spinflip)
updates the given rho set with the density given by rho_r (and rho_g). The rho set will contain the c...
Exchange and Correlation functional calculations.
Definition xc.F:17
subroutine, public xc_prep_2nd_deriv(deriv_set, rho_set, rho_r, pw_pool, weights, xc_section, tau_r)
Prepare objects for the calculation of the 2nd derivatives of the density functional....
Definition xc.F:9863
subroutine, public xc_calc_2nd_deriv_analytical(v_xc, v_xc_tau, deriv_set, rho_set, rho1_set, pw_pool, xc_section, gapw, vxg, tddfpt_fac, compute_virial, virial_xc, spinflip)
Calculates the second derivative of E_xc at rho in the direction rho1 (if you see the second derivati...
Definition xc.F:2060
subroutine, public xc_calc_2nd_deriv_numerical(v_xc, v_tau, rho_set, rho1_r, rho1_g, tau1_r, pw_pool, weights, xc_section, do_triplet, calc_virial, virial_xc, deriv_set)
calculates 2nd derivative numerically
Definition xc.F:1066
stores all the informations relevant to an mpi environment
contained for different pw related things
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Provides all information about a quickstep kind.
calculation environment to calculate the ks matrix, holds all the needed vars. assumes that the core ...
keeps the density in various representations, keeping track of which ones are valid.
A derivative set contains the different derivatives of a xc-functional in form of a linked list.
contains a flag for each component of xc_rho_set, so that you can use it to tell which components you...
represent a density, with all the representation and data needed to perform a functional evaluation