(git:d597271)
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(nspins))
234 DO ispin = 1, nspins
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(nspins))
252 DO ispin = 1, nspins
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 END IF
267 END IF
268
269 ELSE
270 CALL qs_fxc_calculate(rho0_struct, rho1_struct, xc_section, weights, auxbas_pw_pool, &
271 fxc_rho_lo, fxc_tau_lo, &
272 is_triplet=is_triplet, spinflip=spinflip, &
273 compute_virial=do_virial, virial_xc=virial_xc)
274 END IF
275
276 ! nonlocal vdW functionals
277 vdw_nl = .false.
278 IF (PRESENT(dispersion_env)) THEN
279 CALL section_vals_val_get(xc_section, "VDW_POTENTIAL%POTENTIAL_TYPE", i_val=vdw)
280 vdw_nl = (vdw == xc_vdw_fun_nonloc)
281 IF (vdw_nl) THEN
282 nsteps = section_get_ival(xc_section, "NSTEPS")
283 order = 2*nsteps
284 eps_delta = section_get_rval(xc_section, "STEP_SIZE")
285 CALL qs_rho_get(rho1_struct, rho_r=rho1_r)
286 ALLOCATE (fxc_vdw(nspins))
287 DO ispin = 1, nspins
288 CALL auxbas_pw_pool%create_pw(fxc_vdw(ispin))
289 END DO
290 CALL qs_fxc_nlvdw_fdiff(qs_env, dispersion_env, rho_r, rho1_r, &
291 order, eps_delta, fxc_vdw)
292 END IF
293 END IF
294
295 ! de-apply NLCC density
296 IF (ASSOCIATED(rho_nlcc)) THEN
297 factor = -1.0_dp
298 DO ispin = 1, nspins
299 CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
300 CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
301 END DO
302 END IF
303
304 ! return potentials
305 IF (ASSOCIATED(fxc_rho)) THEN
306 DO ispin = 1, min(SIZE(fxc_rho_lo), SIZE(fxc_rho))
307 CALL pw_transfer(fxc_rho_lo(ispin), fxc_rho(ispin))
308 END DO
309 DO ispin = 1, SIZE(fxc_rho_lo)
310 CALL auxbas_pw_pool%give_back_pw(fxc_rho_lo(ispin))
311 END DO
312 DEALLOCATE (fxc_rho_lo)
313 ELSE
314 fxc_rho => fxc_rho_lo
315 END IF
316 IF (ASSOCIATED(fxc_tau)) THEN
317 IF (ASSOCIATED(fxc_tau_lo)) THEN
318 DO ispin = 1, min(SIZE(fxc_tau_lo), SIZE(fxc_tau))
319 CALL pw_transfer(fxc_tau_lo(ispin), fxc_tau(ispin))
320 END DO
321 DO ispin = 1, SIZE(fxc_tau_lo)
322 CALL auxbas_pw_pool%give_back_pw(fxc_tau_lo(ispin))
323 END DO
324 DEALLOCATE (fxc_tau_lo)
325 ELSE
326 DO ispin = 1, nspins
327 CALL pw_zero(fxc_tau(ispin))
328 END DO
329 END IF
330 ELSE
331 fxc_tau => fxc_tau_lo
332 END IF
333
334 ! Add possible nl-vdW pootential
335 IF (vdw_nl) THEN
336 DO ispin = 1, nspins
337 CALL pw_axpy(fxc_vdw(ispin), fxc_rho(ispin), 1.0_dp)
338 CALL auxbas_pw_pool%give_back_pw(fxc_vdw(ispin))
339 END DO
340 DEALLOCATE (fxc_vdw)
341 END IF
342
343 IF (do_onecenter) THEN
344 CALL fxc_atom_calc(qs_env, rho0_atom_set, rho1_atom_set, xc_section, &
345 do_scale=do_scale, do_triplet=is_triplet, do_sf=spinflip, &
346 para_env_ext=para_env_external, &
347 kind_set_external=kind_set_external)
348 END IF
349
350 CALL timestop(handle)
351
352 END SUBROUTINE qs_fxc_create
353
354! **************************************************************************************************
355!> \brief ...
356!> \param rho0 ...
357!> \param rho1 ...
358!> \param xc_section ...
359!> \param weights ...
360!> \param auxbas_pw_pool ...
361!> \param fxc_rho ...
362!> \param fxc_tau ...
363!> \param is_triplet ...
364!> \param spinflip ...
365!> \param compute_virial ...
366!> \param virial_xc ...
367! **************************************************************************************************
368 SUBROUTINE qs_fxc_calculate(rho0, rho1, xc_section, weights, auxbas_pw_pool, &
369 fxc_rho, fxc_tau, is_triplet, spinflip, &
370 compute_virial, virial_xc)
371
372 TYPE(qs_rho_type), POINTER :: rho0, rho1
373 TYPE(section_vals_type), POINTER :: xc_section
374 TYPE(pw_r3d_rs_type), POINTER :: weights
375 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
376 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho, fxc_tau
377 LOGICAL, INTENT(IN), OPTIONAL :: is_triplet, spinflip, compute_virial
378 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT), &
379 OPTIONAL :: virial_xc
380
381 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_calculate'
382
383 INTEGER :: handle, ispin, mspins, nspins
384 INTEGER, DIMENSION(2, 3) :: bo
385 LOGICAL :: do_analytic, do_sf, do_triplet, &
386 do_virial, lsd
387 REAL(kind=dp), DIMENSION(:, :, :, :), POINTER :: vxg
388 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho0_g, rho1_g
389 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho0_r, rho1_r, tau0_r, tau1_r
390 TYPE(qs_rho_type), POINTER :: rhot0, rhot1
391 TYPE(section_vals_type), POINTER :: xc_fun_section
392 TYPE(xc_derivative_set_type) :: xc_deriv_set
393 TYPE(xc_rho_cflags_type) :: needs
394 TYPE(xc_rho_set_type) :: rho0_set, rho1_set
395
396 CALL timeset(routinen, handle)
397
398 do_triplet = .false.
399 IF (PRESENT(is_triplet)) do_triplet = is_triplet
400
401 do_sf = .false.
402 IF (PRESENT(spinflip)) do_sf = spinflip
403
404 do_virial = .false.
405 IF (PRESENT(compute_virial)) do_virial = compute_virial
406
407 do_analytic = section_get_lval(xc_section, "2ND_DERIV_ANALYTICAL")
408
409 CALL qs_rho_get(rho0, rho_r=rho0_r, rho_g=rho0_g, tau_r=tau0_r)
410 CALL qs_rho_get(rho1, rho_r=rho1_r, tau_r=tau1_r)
411 NULLIFY (rho1_g)
412
413 mspins = SIZE(rho0_r)
414 nspins = SIZE(rho0_r)
415 lsd = (nspins == 2)
416 IF (nspins == 1 .AND. do_triplet) THEN
417 nspins = 2
418 lsd = .true.
419 ELSE IF (do_sf) THEN
420 nspins = 1
421 mspins = 1
422 lsd = .true.
423 END IF
424
425 cpassert(.NOT. ASSOCIATED(fxc_rho))
426 cpassert(.NOT. ASSOCIATED(fxc_tau))
427 xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
428 needs = xc_functionals_get_needs(xc_fun_section, lsd, .true.)
429 ALLOCATE (fxc_rho(mspins))
430 DO ispin = 1, mspins
431 CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
432 CALL pw_zero(fxc_rho(ispin))
433 END DO
434 IF (needs%tau .OR. needs%tau_spin) THEN
435 IF (.NOT. ASSOCIATED(tau1_r)) THEN
436 cpabort("Tau-dependent functionals requires allocated kinetic energy density grid")
437 END IF
438 ALLOCATE (fxc_tau(mspins))
439 DO ispin = 1, mspins
440 CALL auxbas_pw_pool%create_pw(fxc_tau(ispin))
441 CALL pw_zero(fxc_tau(ispin))
442 END DO
443 END IF
444
445 IF (mspins == 1 .AND. do_triplet) THEN
446 ! split the density and response density arrays for triplet calculation
447 ALLOCATE (rhot0)
448 CALL qs_rho_create(rhot0)
449 CALL qs_rho_copy(rho0, rhot0, auxbas_pw_pool, 2, factor=2.0_dp)
450 !
451 ALLOCATE (rhot1)
452 CALL qs_rho_create(rhot1)
453 CALL qs_rho_copy(rho1, rhot1, auxbas_pw_pool, 2, factor=2.0_dp)
454 !
455 CALL qs_rho_get(rhot0, rho_r=rho0_r, rho_g=rho0_g, tau_r=tau0_r)
456 CALL qs_rho_get(rhot1, rho_r=rho1_r, tau_r=tau1_r)
457
458 CALL xc_prep_2nd_deriv(xc_deriv_set, rho0_set, rho0_r, auxbas_pw_pool, weights, &
459 xc_section=xc_section, tau_r=tau0_r)
460 bo = rho1_r(1)%pw_grid%bounds_local
461 ! create the place where to store the argument for the functionals
462 CALL xc_rho_set_create(rho1_set, bo, &
463 rho_cutoff=section_get_rval(xc_section, "DENSITY_CUTOFF"), &
464 drho_cutoff=section_get_rval(xc_section, "GRADIENT_CUTOFF"), &
465 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
466
467 ! calculate the arguments needed by the functionals
468 CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
469 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
470 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
471 auxbas_pw_pool, spinflip=do_sf)
472 ELSE
473 CALL xc_prep_2nd_deriv(xc_deriv_set, rho0_set, rho0_r, auxbas_pw_pool, weights, &
474 xc_section=xc_section, tau_r=tau0_r)
475 bo = rho1_r(1)%pw_grid%bounds_local
476 ! create the place where to store the argument for the functionals
477 CALL xc_rho_set_create(rho1_set, bo, &
478 rho_cutoff=section_get_rval(xc_section, "DENSITY_CUTOFF"), &
479 drho_cutoff=section_get_rval(xc_section, "GRADIENT_CUTOFF"), &
480 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
481
482 ! calculate the arguments needed by the functionals
483 CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
484 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
485 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
486 auxbas_pw_pool, spinflip=do_sf)
487 END IF
488
489 IF (mspins == 1 .AND. do_triplet .AND. do_analytic) THEN
490
491 CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, rho0_set, &
492 rho1_set, auxbas_pw_pool, xc_section, &
493 gapw=.false., vxg=vxg, tddfpt_fac=-1.0_dp, spinflip=do_sf, &
494 compute_virial=compute_virial, virial_xc=virial_xc)
495
496 ELSE IF (do_analytic) THEN
497
498 CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, rho0_set, &
499 rho1_set, auxbas_pw_pool, xc_section, &
500 gapw=.false., vxg=vxg, spinflip=do_sf, &
501 compute_virial=compute_virial, virial_xc=virial_xc)
502
503 ELSE
504
505 CALL xc_calc_2nd_deriv_numerical(fxc_rho, fxc_tau, rho0_set, rho1_r, rho1_g, tau1_r, &
506 auxbas_pw_pool, weights, xc_section, &
507 do_triplet, compute_virial, virial_xc, xc_deriv_set)
508
509 END IF
510
511 IF (mspins == 1 .AND. do_triplet) THEN
512 CALL qs_rho_release(rhot0)
513 DEALLOCATE (rhot0)
514 CALL qs_rho_release(rhot1)
515 DEALLOCATE (rhot1)
516 END IF
517
518 CALL xc_dset_release(xc_deriv_set)
519 CALL xc_rho_set_release(rho0_set)
520 CALL xc_rho_set_release(rho1_set)
521
522 CALL timestop(handle)
523
524 END SUBROUTINE qs_fxc_calculate
525
526! **************************************************************************************************
527!> \brief ...
528!> \param qs_env ...
529!> \param rho0_struct ...
530!> \param xc_rho_set ...
531!> \param xc_deriv_set ...
532!> \param xc_section ...
533!> \param pw_env_ext ...
534!> \param is_triplet ...
535! **************************************************************************************************
536 SUBROUTINE qs_fxc_prep(qs_env, rho0_struct, xc_rho_set, xc_deriv_set, &
537 xc_section, pw_env_ext, is_triplet)
538
539 TYPE(qs_environment_type), POINTER :: qs_env
540 TYPE(qs_rho_type), POINTER :: rho0_struct
541 TYPE(xc_rho_set_type) :: xc_rho_set
542 TYPE(xc_derivative_set_type) :: xc_deriv_set
543 TYPE(section_vals_type), POINTER :: xc_section
544 TYPE(pw_env_type), OPTIONAL, POINTER :: pw_env_ext
545 LOGICAL, INTENT(IN), OPTIONAL :: is_triplet
546
547 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_prep'
548
549 INTEGER :: handle, ispin, nspins
550 LOGICAL :: uf_grid
551 REAL(kind=dp) :: factor
552 TYPE(dft_control_type), POINTER :: dft_control
553 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
554 TYPE(pw_c1d_gs_type), POINTER :: rho_nlcc_g
555 TYPE(pw_env_type), POINTER :: pw_env
556 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool, xc_pw_pool
557 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
558 TYPE(pw_r3d_rs_type), POINTER :: rho_nlcc, weights, weights_uf
559 TYPE(qs_rho_type), POINTER :: rho0_uf
560
561 CALL timeset(routinen, handle)
562
563 CALL get_qs_env(qs_env, dft_control=dft_control)
564
565 IF (PRESENT(pw_env_ext)) THEN
566 pw_env => pw_env_ext
567 ELSE
568 CALL get_qs_env(qs_env, pw_env=pw_env)
569 END IF
570 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, xc_pw_pool=xc_pw_pool)
571 uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
572
573 nspins = dft_control%nspins
574
575 NULLIFY (rho_nlcc, rho_nlcc_g)
576 CALL get_qs_env(qs_env, rho_nlcc=rho_nlcc, rho_nlcc_g=rho_nlcc_g)
577 IF (ASSOCIATED(rho_nlcc)) THEN
578 NULLIFY (rho_r, rho_g)
579 CALL qs_rho_get(rho0_struct, rho_r=rho_r, rho_g=rho_g)
580 factor = 1.0_dp
581 DO ispin = 1, nspins
582 CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
583 CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
584 END DO
585 END IF
586
587 NULLIFY (weights)
588 CALL get_qs_env(qs_env, xcint_weights=weights)
589
590 IF (uf_grid) THEN
591 NULLIFY (weights_uf)
592 IF (ASSOCIATED(weights)) THEN
593 ALLOCATE (weights_uf)
594 CALL xc_pw_pool%create_pw(weights_uf)
595 block
596 TYPE(pw_c1d_gs_type) :: weights_g, weights_g_uf
597 CALL auxbas_pw_pool%create_pw(weights_g)
598 CALL xc_pw_pool%create_pw(weights_g_uf)
599 CALL pw_transfer(weights, weights_g)
600 CALL pw_transfer(weights_g, weights_g_uf)
601 CALL pw_transfer(weights_g_uf, weights_uf)
602 CALL xc_pw_pool%give_back_pw(weights_g_uf)
603 CALL auxbas_pw_pool%give_back_pw(weights_g)
604 END block
605 END IF
606 !
607 ALLOCATE (rho0_uf)
608 CALL qs_rho_create(rho0_uf)
609 CALL qs_rho_transfer(rho0_struct, rho0_uf, auxbas_pw_pool, xc_pw_pool)
610 !
611 CALL qs_fxc_deriv(rho0_uf, xc_rho_set, xc_deriv_set, &
612 xc_section, weights_uf, xc_pw_pool, is_triplet)
613 !
614 CALL qs_rho_release(rho0_uf)
615 DEALLOCATE (rho0_uf)
616 IF (ASSOCIATED(weights_uf)) THEN
617 CALL xc_pw_pool%give_back_pw(weights_uf)
618 DEALLOCATE (weights_uf)
619 END IF
620 ELSE
621 CALL qs_fxc_deriv(rho0_struct, xc_rho_set, xc_deriv_set, &
622 xc_section, weights, auxbas_pw_pool, is_triplet)
623 END IF
624
625 ! de-apply NLCC density
626 IF (ASSOCIATED(rho_nlcc)) THEN
627 factor = -1.0_dp
628 DO ispin = 1, nspins
629 CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
630 CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
631 END DO
632 END IF
633
634 CALL timestop(handle)
635
636 END SUBROUTINE qs_fxc_prep
637
638! **************************************************************************************************
639!> \brief ...
640!> \param rho0 ...
641!> \param xc_rho_set ...
642!> \param xc_deriv_set ...
643!> \param xc_section ...
644!> \param weights ...
645!> \param auxbas_pw_pool ...
646!> \param is_triplet ...
647! **************************************************************************************************
648 SUBROUTINE qs_fxc_deriv(rho0, xc_rho_set, xc_deriv_set, xc_section, weights, auxbas_pw_pool, &
649 is_triplet)
650
651 TYPE(qs_rho_type), POINTER :: rho0
652 TYPE(xc_rho_set_type) :: xc_rho_set
653 TYPE(xc_derivative_set_type) :: xc_deriv_set
654 TYPE(section_vals_type), POINTER :: xc_section
655 TYPE(pw_r3d_rs_type), POINTER :: weights
656 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
657 LOGICAL, INTENT(IN) :: is_triplet
658
659 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_deriv'
660
661 INTEGER :: handle
662 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho0_r, tau0_r
663 TYPE(qs_rho_type), POINTER :: rhot0
664
665 CALL timeset(routinen, handle)
666
667 NULLIFY (rho0_r, tau0_r)
668 IF (is_triplet) THEN
669 ! split the density and response density arrays for triplet calculation
670 ALLOCATE (rhot0)
671 CALL qs_rho_create(rhot0)
672 CALL qs_rho_copy(rho0, rhot0, auxbas_pw_pool, 2, factor=2.0_dp)
673 CALL qs_rho_get(rhot0, rho_r=rho0_r, tau_r=tau0_r)
674 CALL xc_prep_2nd_deriv(xc_deriv_set, xc_rho_set, rho0_r, auxbas_pw_pool, weights, &
675 xc_section=xc_section, tau_r=tau0_r)
676 CALL qs_rho_release(rhot0)
677 DEALLOCATE (rhot0)
678 ELSE
679 CALL qs_rho_get(rho0, rho_r=rho0_r, tau_r=tau0_r)
680 CALL xc_prep_2nd_deriv(xc_deriv_set, xc_rho_set, rho0_r, auxbas_pw_pool, weights, &
681 xc_section=xc_section, tau_r=tau0_r)
682 END IF
683
684 CALL timestop(handle)
685
686 END SUBROUTINE qs_fxc_deriv
687
688! **************************************************************************************************
689!> \brief ...
690!> \param qs_env ...
691!> \param xc_deriv_set ...
692!> \param xc_rho_set ...
693!> \param rho1_struct ...
694!> \param rho0_atom_set ...
695!> \param xc_section ...
696!> \param do_onecenter ...
697!> \param fxc_rho ...
698!> \param fxc_tau ...
699!> \param rho1_atom_set ...
700!> \param do_scale ...
701!> \param is_triplet ...
702!> \param spinflip ...
703!> \param pw_env_ext ...
704!> \param kind_set_external ...
705!> \param para_env_external ...
706!> \param compute_virial ...
707!> \param virial_xc ...
708! **************************************************************************************************
709 SUBROUTINE qs_fxc_apply(qs_env, xc_deriv_set, xc_rho_set, rho1_struct, rho0_atom_set, &
710 xc_section, do_onecenter, fxc_rho, fxc_tau, rho1_atom_set, &
711 do_scale, is_triplet, spinflip, pw_env_ext, &
712 kind_set_external, para_env_external, compute_virial, virial_xc)
713
714 TYPE(qs_environment_type), POINTER :: qs_env
715 TYPE(xc_derivative_set_type) :: xc_deriv_set
716 TYPE(xc_rho_set_type) :: xc_rho_set
717 TYPE(qs_rho_type), POINTER :: rho1_struct
718 TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho0_atom_set
719 TYPE(section_vals_type), POINTER :: xc_section
720 LOGICAL, INTENT(IN) :: do_onecenter
721 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho, fxc_tau
722 TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho1_atom_set
723 LOGICAL, INTENT(IN), OPTIONAL :: do_scale, is_triplet, spinflip
724 TYPE(pw_env_type), OPTIONAL, POINTER :: pw_env_ext
725 TYPE(qs_kind_type), DIMENSION(:), OPTIONAL, &
726 POINTER :: kind_set_external
727 TYPE(mp_para_env_type), INTENT(IN), OPTIONAL :: para_env_external
728 LOGICAL, INTENT(IN), OPTIONAL :: compute_virial
729 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT), &
730 OPTIONAL :: virial_xc
731
732 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_apply'
733
734 INTEGER :: handle, ispin, nspins
735 LOGICAL :: do_virial, uf_grid
736 TYPE(dft_control_type), POINTER :: dft_control
737 TYPE(pw_env_type), POINTER :: pw_env
738 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool, xc_pw_pool
739 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho_lo, fxc_rho_uf, fxc_tau_lo, &
740 fxc_tau_uf
741 TYPE(pw_r3d_rs_type), POINTER :: weights, weights_uf
742 TYPE(qs_rho_type), POINTER :: rho1_uf
743
744 CALL timeset(routinen, handle)
745
746 do_virial = .false.
747 IF (PRESENT(compute_virial)) do_virial = compute_virial
748
749 CALL get_qs_env(qs_env, dft_control=dft_control)
750
751 IF (PRESENT(pw_env_ext)) THEN
752 pw_env => pw_env_ext
753 ELSE
754 CALL get_qs_env(qs_env, pw_env=pw_env)
755 END IF
756 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, xc_pw_pool=xc_pw_pool)
757 uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
758
759 nspins = dft_control%nspins
760 IF (ASSOCIATED(fxc_rho)) THEN
761 cpassert(nspins == SIZE(fxc_rho))
762 END IF
763 IF (ASSOCIATED(fxc_tau)) THEN
764 cpassert(nspins == SIZE(fxc_tau))
765 END IF
766
767 CALL get_qs_env(qs_env, xcint_weights=weights)
768
769 NULLIFY (fxc_rho_lo, fxc_tau_lo)
770 IF (uf_grid) THEN
771 NULLIFY (weights_uf)
772 IF (ASSOCIATED(weights)) THEN
773 ALLOCATE (weights_uf)
774 CALL xc_pw_pool%create_pw(weights_uf)
775 block
776 TYPE(pw_c1d_gs_type) :: weights_g, weights_g_uf
777 CALL auxbas_pw_pool%create_pw(weights_g)
778 CALL xc_pw_pool%create_pw(weights_g_uf)
779 CALL pw_transfer(weights, weights_g)
780 CALL pw_transfer(weights_g, weights_g_uf)
781 CALL pw_transfer(weights_g_uf, weights_uf)
782 CALL xc_pw_pool%give_back_pw(weights_g_uf)
783 CALL auxbas_pw_pool%give_back_pw(weights_g)
784 END block
785 END IF
786 !
787 ALLOCATE (rho1_uf)
788 CALL qs_rho_create(rho1_uf)
789 CALL qs_rho_transfer(rho1_struct, rho1_uf, auxbas_pw_pool, xc_pw_pool)
790 !
791 NULLIFY (fxc_rho_uf, fxc_tau_uf)
792 CALL qs_fxc_eval(xc_deriv_set, xc_rho_set, rho1_uf, xc_section, &
793 weights_uf, xc_pw_pool, fxc_rho_uf, fxc_tau_uf, &
794 is_triplet=is_triplet, spinflip=spinflip, &
795 compute_virial=do_virial, virial_xc=virial_xc)
796 !
797 CALL qs_rho_release(rho1_uf)
798 DEALLOCATE (rho1_uf)
799 IF (ASSOCIATED(weights_uf)) THEN
800 CALL xc_pw_pool%give_back_pw(weights_uf)
801 DEALLOCATE (weights_uf)
802 END IF
803 IF (ASSOCIATED(fxc_rho_uf)) THEN
804 ALLOCATE (fxc_rho_lo(nspins))
805 DO ispin = 1, nspins
806 CALL auxbas_pw_pool%create_pw(fxc_rho_lo(ispin))
807 block
808 TYPE(pw_c1d_gs_type) :: fxc_g, fxc_g_uf
809 CALL auxbas_pw_pool%create_pw(fxc_g)
810 CALL xc_pw_pool%create_pw(fxc_g_uf)
811 CALL pw_transfer(fxc_rho_uf(ispin), fxc_g_uf)
812 CALL pw_transfer(fxc_g_uf, fxc_g)
813 CALL pw_transfer(fxc_g, fxc_rho_lo(ispin))
814 CALL xc_pw_pool%give_back_pw(fxc_g_uf)
815 CALL auxbas_pw_pool%give_back_pw(fxc_g)
816 END block
817 CALL xc_pw_pool%give_back_pw(fxc_rho_uf(ispin))
818 END DO
819 DEALLOCATE (fxc_rho_uf)
820 END IF
821 IF (ASSOCIATED(fxc_tau_uf)) THEN
822 ALLOCATE (fxc_tau_lo(nspins))
823 DO ispin = 1, nspins
824 CALL auxbas_pw_pool%create_pw(fxc_tau_lo(ispin))
825 block
826 TYPE(pw_c1d_gs_type) :: fxc_g, fxc_g_uf
827 CALL auxbas_pw_pool%create_pw(fxc_g)
828 CALL xc_pw_pool%create_pw(fxc_g_uf)
829 CALL pw_transfer(fxc_tau_uf(ispin), fxc_g_uf)
830 CALL pw_transfer(fxc_g_uf, fxc_g)
831 CALL pw_transfer(fxc_g, fxc_tau_lo(ispin))
832 CALL xc_pw_pool%give_back_pw(fxc_g_uf)
833 CALL auxbas_pw_pool%give_back_pw(fxc_g)
834 END block
835 CALL xc_pw_pool%give_back_pw(fxc_tau_uf(ispin))
836 END DO
837 END IF
838
839 ELSE
840 CALL qs_fxc_eval(xc_deriv_set, xc_rho_set, rho1_struct, xc_section, &
841 weights, auxbas_pw_pool, fxc_rho_lo, fxc_tau_lo, &
842 is_triplet=is_triplet, spinflip=spinflip, &
843 compute_virial=do_virial, virial_xc=virial_xc)
844 END IF
845
846 ! return potentials
847 IF (ASSOCIATED(fxc_rho)) THEN
848 DO ispin = 1, min(SIZE(fxc_rho_lo), SIZE(fxc_rho))
849 CALL pw_transfer(fxc_rho_lo(ispin), fxc_rho(ispin))
850 END DO
851 DO ispin = 1, SIZE(fxc_rho_lo)
852 CALL auxbas_pw_pool%give_back_pw(fxc_rho_lo(ispin))
853 END DO
854 DEALLOCATE (fxc_rho_lo)
855 ELSE
856 fxc_rho => fxc_rho_lo
857 END IF
858 IF (ASSOCIATED(fxc_tau)) THEN
859 IF (ASSOCIATED(fxc_tau_lo)) THEN
860 DO ispin = 1, min(SIZE(fxc_tau_lo), SIZE(fxc_tau))
861 CALL pw_transfer(fxc_tau_lo(ispin), fxc_tau(ispin))
862 END DO
863 DO ispin = 1, SIZE(fxc_tau_lo)
864 CALL auxbas_pw_pool%give_back_pw(fxc_tau_lo(ispin))
865 END DO
866 DEALLOCATE (fxc_tau_lo)
867 ELSE
868 DO ispin = 1, nspins
869 CALL pw_zero(fxc_tau(ispin))
870 END DO
871 END IF
872 ELSE
873 fxc_tau => fxc_tau_lo
874 END IF
875
876 IF (do_onecenter) THEN
877 CALL fxc_atom_calc(qs_env, rho0_atom_set, rho1_atom_set, xc_section, &
878 do_scale=do_scale, do_triplet=is_triplet, do_sf=spinflip, &
879 para_env_ext=para_env_external, &
880 kind_set_external=kind_set_external)
881 END IF
882
883 CALL timestop(handle)
884
885 END SUBROUTINE qs_fxc_apply
886
887! **************************************************************************************************
888!> \brief ...
889!> \param xc_deriv_set ...
890!> \param xc_rho_set ...
891!> \param rho1 ...
892!> \param xc_section ...
893!> \param weights ...
894!> \param auxbas_pw_pool ...
895!> \param fxc_rho ...
896!> \param fxc_tau ...
897!> \param is_triplet ...
898!> \param spinflip ...
899!> \param compute_virial ...
900!> \param virial_xc ...
901! **************************************************************************************************
902 SUBROUTINE qs_fxc_eval(xc_deriv_set, xc_rho_set, rho1, xc_section, weights, auxbas_pw_pool, &
903 fxc_rho, fxc_tau, is_triplet, spinflip, &
904 compute_virial, virial_xc)
905
906 TYPE(xc_derivative_set_type) :: xc_deriv_set
907 TYPE(xc_rho_set_type) :: xc_rho_set
908 TYPE(qs_rho_type), POINTER :: rho1
909 TYPE(section_vals_type), POINTER :: xc_section
910 TYPE(pw_r3d_rs_type), POINTER :: weights
911 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
912 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho, fxc_tau
913 LOGICAL, INTENT(IN), OPTIONAL :: is_triplet, spinflip, compute_virial
914 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT), &
915 OPTIONAL :: virial_xc
916
917 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_eval'
918
919 INTEGER :: handle, ispin, mspins, nspins
920 INTEGER, DIMENSION(2, 3) :: bo
921 LOGICAL :: do_analytic, do_sf, do_triplet, &
922 do_virial, lsd
923 REAL(kind=dp), DIMENSION(:, :, :, :), POINTER :: vxg
924 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho1_g
925 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho1_r, tau1_r
926 TYPE(qs_rho_type), POINTER :: rhot1
927 TYPE(section_vals_type), POINTER :: xc_fun_section
928 TYPE(xc_rho_cflags_type) :: needs
929 TYPE(xc_rho_set_type) :: rho1_set
930
931 CALL timeset(routinen, handle)
932
933 do_triplet = .false.
934 IF (PRESENT(is_triplet)) do_triplet = is_triplet
935
936 do_sf = .false.
937 IF (PRESENT(spinflip)) do_sf = spinflip
938
939 do_virial = .false.
940 IF (PRESENT(compute_virial)) do_virial = compute_virial
941
942 do_analytic = section_get_lval(xc_section, "2ND_DERIV_ANALYTICAL")
943
944 CALL qs_rho_get(rho1, rho_r=rho1_r, tau_r=tau1_r)
945 NULLIFY (rho1_g)
946
947 mspins = SIZE(rho1_r)
948 nspins = SIZE(rho1_r)
949 lsd = (nspins == 2)
950 IF (nspins == 1 .AND. do_triplet) THEN
951 nspins = 2
952 lsd = .true.
953 ELSE IF (do_sf) THEN
954 nspins = 1
955 mspins = 1
956 lsd = .true.
957 END IF
958
959 cpassert(.NOT. ASSOCIATED(fxc_rho))
960 cpassert(.NOT. ASSOCIATED(fxc_tau))
961 xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
962 needs = xc_functionals_get_needs(xc_fun_section, lsd, .true.)
963 ALLOCATE (fxc_rho(mspins))
964 DO ispin = 1, mspins
965 CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
966 CALL pw_zero(fxc_rho(ispin))
967 END DO
968 IF (needs%tau .OR. needs%tau_spin) THEN
969 IF (.NOT. ASSOCIATED(tau1_r)) THEN
970 cpabort("Tau-dependent functionals requires allocated kinetic energy density grid")
971 END IF
972 ALLOCATE (fxc_tau(mspins))
973 DO ispin = 1, mspins
974 CALL auxbas_pw_pool%create_pw(fxc_tau(ispin))
975 CALL pw_zero(fxc_tau(ispin))
976 END DO
977 END IF
978
979 IF (mspins == 1 .AND. do_triplet) THEN
980 ! split the density and response density arrays for triplet calculation
981 ALLOCATE (rhot1)
982 CALL qs_rho_create(rhot1)
983 CALL qs_rho_copy(rho1, rhot1, auxbas_pw_pool, 2, factor=2.0_dp)
984 !
985 CALL qs_rho_get(rhot1, rho_r=rho1_r, tau_r=tau1_r)
986 END IF
987
988 bo = rho1_r(1)%pw_grid%bounds_local
989 ! create the place where to store the argument for the functionals
990 CALL xc_rho_set_create(rho1_set, bo, &
991 rho_cutoff=section_get_rval(xc_section, "DENSITY_CUTOFF"), &
992 drho_cutoff=section_get_rval(xc_section, "GRADIENT_CUTOFF"), &
993 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
994
995 ! calculate the arguments needed by the functionals
996 CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
997 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
998 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
999 auxbas_pw_pool, spinflip=do_sf)
1000
1001 IF (mspins == 1 .AND. do_triplet .AND. do_analytic) THEN
1002
1003 CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, xc_rho_set, &
1004 rho1_set, auxbas_pw_pool, xc_section, &
1005 gapw=.false., vxg=vxg, tddfpt_fac=-1.0_dp, spinflip=do_sf, &
1006 compute_virial=compute_virial, virial_xc=virial_xc)
1007
1008 ELSE IF (do_analytic) THEN
1009
1010 CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, xc_rho_set, &
1011 rho1_set, auxbas_pw_pool, xc_section, &
1012 gapw=.false., vxg=vxg, spinflip=do_sf, &
1013 compute_virial=compute_virial, virial_xc=virial_xc)
1014
1015 ELSE
1016
1017 CALL xc_calc_2nd_deriv_numerical(fxc_rho, fxc_tau, xc_rho_set, rho1_r, rho1_g, tau1_r, &
1018 auxbas_pw_pool, weights, xc_section, &
1019 do_triplet, compute_virial, virial_xc, xc_deriv_set)
1020
1021 END IF
1022
1023 IF (mspins == 1 .AND. do_triplet) THEN
1024 CALL qs_rho_release(rhot1)
1025 DEALLOCATE (rhot1)
1026 END IF
1027 CALL xc_rho_set_release(rho1_set)
1028
1029 CALL timestop(handle)
1030
1031 END SUBROUTINE qs_fxc_eval
1032
1033! **************************************************************************************************
1034!> \brief ...
1035!> \param qs_env ...
1036!> \param rho0_struct ...
1037!> \param rho1_struct ...
1038!> \param xc_section ...
1039!> \param accuracy ...
1040!> \param fxc_rho ...
1041!> \param fxc_tau ...
1042!> \param is_triplet ...
1043!> \param spinflip ...
1044!>
1045!>
1046!> https://en.wikipedia.org/wiki/Finite_difference_coefficient
1047!> ---------------------------------------------------------------------------------------------------
1048!> Derivative Accuracy 4 3 2 1 0 1 2 3 4
1049!> ---------------------------------------------------------------------------------------------------
1050!> 1 2 -1/2 0 1/2
1051!> 4 1/12 -2/3 0 2/3 -1/12
1052!> 6 -1/60 3/20 -3/4 0 3/4 -3/20 1/60
1053!> 8 1/280 -4/105 1/5 -4/5 0 4/5 -1/5 4/105 -1/280
1054!> ---------------------------------------------------------------------------------------------------
1055!> 2 2 1 -2 1
1056!> 4 -1/12 4/3 -5/2 4/3 -1/12
1057!> 6 1/90 -3/20 3/2 -49/18 3/2 -3/20 1/90
1058!> 8 -1/560 8/315 -1/5 8/5 -205/72 8/5 -1/5 8/315 -1/560
1059!> ---------------------------------------------------------------------------------------------------
1060! **************************************************************************************************
1061 SUBROUTINE qs_fxc_fdiff(qs_env, rho0_struct, rho1_struct, xc_section, accuracy, &
1062 fxc_rho, fxc_tau, is_triplet, spinflip)
1063
1064 TYPE(qs_environment_type), POINTER :: qs_env
1065 TYPE(qs_rho_type), POINTER :: rho0_struct, rho1_struct
1066 TYPE(section_vals_type), POINTER :: xc_section
1067 INTEGER, INTENT(IN) :: accuracy
1068 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho, fxc_tau
1069 LOGICAL, INTENT(IN), OPTIONAL :: is_triplet, spinflip
1070
1071 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_fdiff'
1072 REAL(kind=dp), PARAMETER :: epsrho = 5.e-4_dp
1073
1074 INTEGER :: handle, ispin, istep, nspins, nstep
1075 LOGICAL :: do_sf, do_triplet
1076 REAL(kind=dp) :: alpha, beta, exc, oeps1
1077 REAL(kind=dp), DIMENSION(-4:4) :: ak
1078 TYPE(dft_control_type), POINTER :: dft_control
1079 TYPE(pw_env_type), POINTER :: pw_env
1080 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1081 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_tau_rspace, vxc00
1082 TYPE(qs_ks_env_type), POINTER :: ks_env
1083 TYPE(qs_rho_type), POINTER :: rhoin
1084
1085 CALL timeset(routinen, handle)
1086
1087 cpassert(.NOT. ASSOCIATED(fxc_rho))
1088 cpassert(.NOT. ASSOCIATED(fxc_tau))
1089 cpassert(ASSOCIATED(rho0_struct))
1090 cpassert(ASSOCIATED(rho1_struct))
1091
1092 do_triplet = .false.
1093 IF (PRESENT(is_triplet)) do_triplet = is_triplet
1094
1095 do_sf = .false.
1096 IF (PRESENT(spinflip)) do_sf = spinflip
1097 IF (do_sf) THEN
1098 cpabort("Spin Flip TDDFT only available with analytic 2nd xc derivatives")
1099 END IF
1100
1101 ak = 0.0_dp
1102 SELECT CASE (accuracy)
1103 CASE (:4)
1104 nstep = 2
1105 ak(-2:2) = [1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp]/12.0_dp
1106 CASE (5:7)
1107 nstep = 3
1108 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
1109 CASE (8:)
1110 nstep = 4
1111 ak(-4:4) = [1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
1112 224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp]/280.0_dp
1113 END SELECT
1114
1115 CALL get_qs_env(qs_env, ks_env=ks_env, dft_control=dft_control, pw_env=pw_env)
1116 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
1117
1118 nspins = dft_control%nspins
1119 exc = 0.0_dp
1120
1121 DO istep = -nstep, nstep
1122
1123 IF (ak(istep) /= 0.0_dp) THEN
1124 alpha = 1.0_dp
1125 beta = real(istep, kind=dp)*epsrho
1126 NULLIFY (rhoin)
1127 ALLOCATE (rhoin)
1128 CALL qs_rho_create(rhoin)
1129 NULLIFY (vxc00, v_tau_rspace)
1130 IF (do_triplet) THEN
1131 cpassert(nspins == 1)
1132 ! rhoin = (0.5 rho0, 0.5 rho0)
1133 CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, 2)
1134 ! rhoin = (0.5 rho0 + 0.5 rho1, 0.5 rho0)
1135 CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, 0.5_dp*beta)
1136 CALL qs_vxc_create(ks_env, rhoin, xc_section, vxc00, v_tau_rspace, exc)
1137 CALL pw_axpy(vxc00(2), vxc00(1), -1.0_dp)
1138 IF (ASSOCIATED(v_tau_rspace)) CALL pw_axpy(v_tau_rspace(2), v_tau_rspace(1), -1.0_dp)
1139 ELSE
1140 CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, nspins)
1141 CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, beta)
1142 CALL qs_vxc_create(ks_env, rhoin, xc_section, vxc00, v_tau_rspace, exc)
1143 END IF
1144 CALL qs_rho_release(rhoin)
1145 DEALLOCATE (rhoin)
1146 IF (.NOT. ASSOCIATED(fxc_rho)) THEN
1147 ALLOCATE (fxc_rho(nspins))
1148 DO ispin = 1, nspins
1149 CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
1150 CALL pw_zero(fxc_rho(ispin))
1151 END DO
1152 END IF
1153 DO ispin = 1, nspins
1154 CALL pw_axpy(vxc00(ispin), fxc_rho(ispin), ak(istep))
1155 END DO
1156 DO ispin = 1, SIZE(vxc00)
1157 CALL auxbas_pw_pool%give_back_pw(vxc00(ispin))
1158 END DO
1159 DEALLOCATE (vxc00)
1160 IF (ASSOCIATED(v_tau_rspace)) THEN
1161 IF (.NOT. ASSOCIATED(fxc_tau)) THEN
1162 ALLOCATE (fxc_tau(nspins))
1163 DO ispin = 1, nspins
1164 CALL auxbas_pw_pool%create_pw(fxc_tau(ispin))
1165 CALL pw_zero(fxc_tau(ispin))
1166 END DO
1167 END IF
1168 DO ispin = 1, nspins
1169 CALL pw_axpy(v_tau_rspace(ispin), fxc_tau(ispin), ak(istep))
1170 END DO
1171 DO ispin = 1, SIZE(v_tau_rspace)
1172 CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
1173 END DO
1174 DEALLOCATE (v_tau_rspace)
1175 END IF
1176 END IF
1177
1178 END DO
1179
1180 oeps1 = 1.0_dp/epsrho
1181 DO ispin = 1, nspins
1182 CALL pw_scale(fxc_rho(ispin), oeps1)
1183 END DO
1184 IF (ASSOCIATED(fxc_tau)) THEN
1185 DO ispin = 1, nspins
1186 CALL pw_scale(fxc_tau(ispin), oeps1)
1187 END DO
1188 END IF
1189
1190 CALL timestop(handle)
1191
1192 END SUBROUTINE qs_fxc_fdiff
1193
1194END 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:713
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:538
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:1063
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