70#include "./base/base_uses.f90"
80 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_fxc'
102 SUBROUTINE qs_fxc_create(qs_env, rho0_struct, rho1_struct, xc_section, fxc_rho, fxc_tau, &
103 is_triplet, spinflip, no_weights, uf_grid_results, &
104 pw_env_ext, compute_virial, virial_xc)
107 TYPE(
qs_rho_type),
POINTER :: rho0_struct, rho1_struct
110 LOGICAL,
INTENT(IN),
OPTIONAL :: is_triplet, spinflip, no_weights, &
113 LOGICAL,
INTENT(IN),
OPTIONAL :: compute_virial
114 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(INOUT), &
115 OPTIONAL :: virial_xc
117 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_fxc_create'
119 INTEGER :: handle, ispin, nspins
120 LOGICAL :: do_virial, do_w, ret_uf, uf_grid
121 REAL(kind=
dp) :: factor
126 TYPE(
pw_pool_type),
POINTER :: auxbas_pw_pool, xc_pw_pool
127 TYPE(
pw_r3d_rs_type),
DIMENSION(:),
POINTER :: fxc_rho_lo, fxc_rho_uf, fxc_tau_lo, &
132 CALL timeset(routinen, handle)
135 IF (
PRESENT(compute_virial)) do_virial = compute_virial
137 CALL get_qs_env(qs_env, dft_control=dft_control)
139 IF (
PRESENT(pw_env_ext))
THEN
144 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, xc_pw_pool=xc_pw_pool)
145 uf_grid = .NOT.
pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
147 nspins = dft_control%nspins
148 IF (
ASSOCIATED(fxc_rho))
THEN
149 cpassert(nspins ==
SIZE(fxc_rho))
151 IF (
ASSOCIATED(fxc_tau))
THEN
152 cpassert(nspins ==
SIZE(fxc_tau))
155 NULLIFY (rho_nlcc, rho_nlcc_g)
156 CALL get_qs_env(qs_env, rho_nlcc=rho_nlcc, rho_nlcc_g=rho_nlcc_g)
157 IF (
ASSOCIATED(rho_nlcc))
THEN
158 NULLIFY (rho_r, rho_g)
159 CALL qs_rho_get(rho0_struct, rho_r=rho_r, rho_g=rho_g)
162 CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
163 CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
168 IF (
PRESENT(no_weights)) do_w = .NOT. no_weights
170 CALL get_qs_env(qs_env, xcint_weights=weights)
175 NULLIFY (fxc_rho_lo, fxc_tau_lo)
177 IF (
PRESENT(uf_grid_results))
THEN
178 ret_uf = uf_grid_results
183 IF (
ASSOCIATED(weights))
THEN
184 ALLOCATE (weights_uf)
185 CALL xc_pw_pool%create_pw(weights_uf)
188 CALL auxbas_pw_pool%create_pw(weights_g)
189 CALL xc_pw_pool%create_pw(weights_g_uf)
193 CALL xc_pw_pool%give_back_pw(weights_g_uf)
194 CALL auxbas_pw_pool%give_back_pw(weights_g)
198 ALLOCATE (rho0_uf, rho1_uf)
204 NULLIFY (fxc_rho_uf, fxc_tau_uf)
205 CALL qs_fxc_calculate(rho0_uf, rho1_uf, xc_section, weights_uf, xc_pw_pool, &
206 fxc_rho_uf, fxc_tau_uf, &
207 is_triplet=is_triplet, spinflip=spinflip, &
208 compute_virial=do_virial, virial_xc=virial_xc)
212 DEALLOCATE (rho0_uf, rho1_uf)
213 IF (
ASSOCIATED(weights_uf))
THEN
214 CALL xc_pw_pool%give_back_pw(weights_uf)
215 DEALLOCATE (weights_uf)
218 fxc_rho_lo => fxc_rho_uf
219 fxc_tau_lo => fxc_tau_uf
221 IF (
ASSOCIATED(fxc_rho_uf))
THEN
222 ALLOCATE (fxc_rho_lo(nspins))
224 CALL auxbas_pw_pool%create_pw(fxc_rho_lo(ispin))
227 CALL auxbas_pw_pool%create_pw(fxc_g)
228 CALL xc_pw_pool%create_pw(fxc_g_uf)
232 CALL xc_pw_pool%give_back_pw(fxc_g_uf)
233 CALL auxbas_pw_pool%give_back_pw(fxc_g)
235 CALL xc_pw_pool%give_back_pw(fxc_rho_uf(ispin))
237 DEALLOCATE (fxc_rho_uf)
239 IF (
ASSOCIATED(fxc_tau_uf))
THEN
240 ALLOCATE (fxc_tau_lo(nspins))
242 CALL auxbas_pw_pool%create_pw(fxc_tau_lo(ispin))
244 TYPE(pw_c1d_gs_type) :: fxc_g, fxc_g_uf
245 CALL auxbas_pw_pool%create_pw(fxc_g)
246 CALL xc_pw_pool%create_pw(fxc_g_uf)
247 CALL pw_transfer(fxc_tau_uf(ispin), fxc_g_uf)
248 CALL pw_transfer(fxc_g_uf, fxc_g)
249 CALL pw_transfer(fxc_g, fxc_tau_lo(ispin))
250 CALL xc_pw_pool%give_back_pw(fxc_g_uf)
251 CALL auxbas_pw_pool%give_back_pw(fxc_g)
253 CALL xc_pw_pool%give_back_pw(fxc_tau_uf(ispin))
259 CALL qs_fxc_calculate(rho0_struct, rho1_struct, xc_section, weights, auxbas_pw_pool, &
260 fxc_rho_lo, fxc_tau_lo, &
261 is_triplet=is_triplet, spinflip=spinflip, &
262 compute_virial=do_virial, virial_xc=virial_xc)
266 IF (
ASSOCIATED(rho_nlcc))
THEN
269 CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
270 CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
275 IF (
ASSOCIATED(fxc_rho))
THEN
276 DO ispin = 1, min(
SIZE(fxc_rho_lo),
SIZE(fxc_rho))
277 CALL pw_transfer(fxc_rho_lo(ispin), fxc_rho(ispin))
279 DO ispin = 1,
SIZE(fxc_rho_lo)
280 CALL auxbas_pw_pool%give_back_pw(fxc_rho_lo(ispin))
282 DEALLOCATE (fxc_rho_lo)
284 fxc_rho => fxc_rho_lo
286 IF (
ASSOCIATED(fxc_tau))
THEN
287 IF (
ASSOCIATED(fxc_tau_lo))
THEN
288 DO ispin = 1, min(
SIZE(fxc_tau_lo),
SIZE(fxc_tau))
289 CALL pw_transfer(fxc_tau_lo(ispin), fxc_tau(ispin))
291 DO ispin = 1,
SIZE(fxc_tau_lo)
292 CALL auxbas_pw_pool%give_back_pw(fxc_tau_lo(ispin))
294 DEALLOCATE (fxc_tau_lo)
297 CALL pw_zero(fxc_tau(ispin))
301 fxc_tau => fxc_tau_lo
304 CALL timestop(handle)
322 SUBROUTINE qs_fxc_calculate(rho0, rho1, xc_section, weights, auxbas_pw_pool, &
323 fxc_rho, fxc_tau, is_triplet, spinflip, &
324 compute_virial, virial_xc)
326 TYPE(qs_rho_type),
POINTER :: rho0, rho1
327 TYPE(section_vals_type),
POINTER :: xc_section
328 TYPE(pw_r3d_rs_type),
POINTER :: weights
329 TYPE(pw_pool_type),
POINTER :: auxbas_pw_pool
330 TYPE(pw_r3d_rs_type),
DIMENSION(:),
POINTER :: fxc_rho, fxc_tau
331 LOGICAL,
INTENT(IN),
OPTIONAL :: is_triplet, spinflip, compute_virial
332 REAL(kind=dp),
DIMENSION(3, 3),
INTENT(INOUT), &
333 OPTIONAL :: virial_xc
335 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_fxc_calculate'
337 INTEGER :: handle, ispin, mspins, nspins
338 INTEGER,
DIMENSION(2, 3) :: bo
339 LOGICAL :: do_analytic, do_sf, do_triplet, &
341 REAL(kind=dp),
DIMENSION(:, :, :, :),
POINTER :: vxg
342 TYPE(pw_c1d_gs_type),
DIMENSION(:),
POINTER :: rho0_g, rho1_g
343 TYPE(pw_r3d_rs_type),
DIMENSION(:),
POINTER :: rho0_r, rho1_r, tau0_r, tau1_r
344 TYPE(qs_rho_type),
POINTER :: rhot0, rhot1
345 TYPE(section_vals_type),
POINTER :: xc_fun_section
346 TYPE(xc_derivative_set_type) :: xc_deriv_set
347 TYPE(xc_rho_cflags_type) :: needs
348 TYPE(xc_rho_set_type) :: rho0_set, rho1_set
350 CALL timeset(routinen, handle)
353 IF (
PRESENT(is_triplet)) do_triplet = is_triplet
356 IF (
PRESENT(spinflip)) do_sf = spinflip
359 IF (
PRESENT(compute_virial)) do_virial = compute_virial
361 do_analytic = section_get_lval(xc_section,
"2ND_DERIV_ANALYTICAL")
363 CALL qs_rho_get(rho0, rho_r=rho0_r, rho_g=rho0_g, tau_r=tau0_r)
364 CALL qs_rho_get(rho1, rho_r=rho1_r, tau_r=tau1_r)
367 mspins =
SIZE(rho0_r)
368 nspins =
SIZE(rho0_r)
370 IF (nspins == 1 .AND. do_triplet)
THEN
379 cpassert(.NOT.
ASSOCIATED(fxc_rho))
380 cpassert(.NOT.
ASSOCIATED(fxc_tau))
381 xc_fun_section => section_vals_get_subs_vals(xc_section,
"XC_FUNCTIONAL")
382 needs = xc_functionals_get_needs(xc_fun_section, lsd, .true.)
383 ALLOCATE (fxc_rho(mspins))
385 CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
386 CALL pw_zero(fxc_rho(ispin))
388 IF (needs%tau .OR. needs%tau_spin)
THEN
389 IF (.NOT.
ASSOCIATED(tau1_r))
THEN
390 cpabort(
"Tau-dependent functionals requires allocated kinetic energy density grid")
392 ALLOCATE (fxc_tau(mspins))
394 CALL auxbas_pw_pool%create_pw(fxc_tau(ispin))
395 CALL pw_zero(fxc_tau(ispin))
399 IF (mspins == 1 .AND. do_triplet)
THEN
402 CALL qs_rho_create(rhot0)
403 CALL qs_rho_copy(rho0, rhot0, auxbas_pw_pool, 2, factor=2.0_dp)
406 CALL qs_rho_create(rhot1)
407 CALL qs_rho_copy(rho1, rhot1, auxbas_pw_pool, 2, factor=2.0_dp)
409 CALL qs_rho_get(rhot0, rho_r=rho0_r, rho_g=rho0_g, tau_r=tau0_r)
410 CALL qs_rho_get(rhot1, rho_r=rho1_r, tau_r=tau1_r)
412 CALL xc_prep_2nd_deriv(xc_deriv_set, rho0_set, rho0_r, auxbas_pw_pool, weights, &
413 xc_section=xc_section, tau_r=tau0_r)
414 bo = rho1_r(1)%pw_grid%bounds_local
416 CALL xc_rho_set_create(rho1_set, bo, &
417 rho_cutoff=section_get_rval(xc_section,
"DENSITY_CUTOFF"), &
418 drho_cutoff=section_get_rval(xc_section,
"GRADIENT_CUTOFF"), &
419 tau_cutoff=section_get_rval(xc_section,
"TAU_CUTOFF"))
422 CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
423 section_get_ival(xc_section,
"XC_GRID%XC_DERIV"), &
424 section_get_ival(xc_section,
"XC_GRID%XC_SMOOTH_RHO"), &
425 auxbas_pw_pool, spinflip=do_sf)
427 CALL xc_prep_2nd_deriv(xc_deriv_set, rho0_set, rho0_r, auxbas_pw_pool, weights, &
428 xc_section=xc_section, tau_r=tau0_r)
429 bo = rho1_r(1)%pw_grid%bounds_local
431 CALL xc_rho_set_create(rho1_set, bo, &
432 rho_cutoff=section_get_rval(xc_section,
"DENSITY_CUTOFF"), &
433 drho_cutoff=section_get_rval(xc_section,
"GRADIENT_CUTOFF"), &
434 tau_cutoff=section_get_rval(xc_section,
"TAU_CUTOFF"))
437 CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
438 section_get_ival(xc_section,
"XC_GRID%XC_DERIV"), &
439 section_get_ival(xc_section,
"XC_GRID%XC_SMOOTH_RHO"), &
440 auxbas_pw_pool, spinflip=do_sf)
443 IF (mspins == 1 .AND. do_triplet .AND. do_analytic)
THEN
445 CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, rho0_set, &
446 rho1_set, auxbas_pw_pool, xc_section, &
447 gapw=.false., vxg=vxg, tddfpt_fac=-1.0_dp, spinflip=do_sf, &
448 compute_virial=compute_virial, virial_xc=virial_xc)
450 ELSE IF (do_analytic)
THEN
452 CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, rho0_set, &
453 rho1_set, auxbas_pw_pool, xc_section, &
454 gapw=.false., vxg=vxg, spinflip=do_sf, &
455 compute_virial=compute_virial, virial_xc=virial_xc)
459 CALL xc_calc_2nd_deriv_numerical(fxc_rho, fxc_tau, rho0_set, rho1_r, rho1_g, tau1_r, &
460 auxbas_pw_pool, weights, xc_section, &
461 do_triplet, compute_virial, virial_xc, xc_deriv_set)
465 IF (mspins == 1 .AND. do_triplet)
THEN
466 CALL qs_rho_release(rhot0)
468 CALL qs_rho_release(rhot1)
472 CALL xc_dset_release(xc_deriv_set)
473 CALL xc_rho_set_release(rho0_set)
474 CALL xc_rho_set_release(rho1_set)
476 CALL timestop(handle)
478 END SUBROUTINE qs_fxc_calculate
490 SUBROUTINE qs_fxc_prep(qs_env, rho0_struct, xc_rho_set, xc_deriv_set, &
491 xc_section, pw_env_ext, is_triplet)
493 TYPE(qs_environment_type),
POINTER :: qs_env
494 TYPE(qs_rho_type),
POINTER :: rho0_struct
495 TYPE(xc_rho_set_type) :: xc_rho_set
496 TYPE(xc_derivative_set_type) :: xc_deriv_set
497 TYPE(section_vals_type),
POINTER :: xc_section
498 TYPE(pw_env_type),
OPTIONAL,
POINTER :: pw_env_ext
499 LOGICAL,
INTENT(IN),
OPTIONAL :: is_triplet
501 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_fxc_prep'
503 INTEGER :: handle, ispin, nspins
505 REAL(kind=dp) :: factor
506 TYPE(dft_control_type),
POINTER :: dft_control
507 TYPE(pw_c1d_gs_type),
DIMENSION(:),
POINTER :: rho_g
508 TYPE(pw_c1d_gs_type),
POINTER :: rho_nlcc_g
509 TYPE(pw_env_type),
POINTER :: pw_env
510 TYPE(pw_pool_type),
POINTER :: auxbas_pw_pool, xc_pw_pool
511 TYPE(pw_r3d_rs_type),
DIMENSION(:),
POINTER :: rho_r
512 TYPE(pw_r3d_rs_type),
POINTER :: rho_nlcc, weights, weights_uf
513 TYPE(qs_rho_type),
POINTER :: rho0_uf
515 CALL timeset(routinen, handle)
517 CALL get_qs_env(qs_env, dft_control=dft_control)
519 IF (
PRESENT(pw_env_ext))
THEN
522 CALL get_qs_env(qs_env, pw_env=pw_env)
524 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, xc_pw_pool=xc_pw_pool)
525 uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
527 nspins = dft_control%nspins
529 NULLIFY (rho_nlcc, rho_nlcc_g)
530 CALL get_qs_env(qs_env, rho_nlcc=rho_nlcc, rho_nlcc_g=rho_nlcc_g)
531 IF (
ASSOCIATED(rho_nlcc))
THEN
532 NULLIFY (rho_r, rho_g)
533 CALL qs_rho_get(rho0_struct, rho_r=rho_r, rho_g=rho_g)
536 CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
537 CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
542 CALL get_qs_env(qs_env, xcint_weights=weights)
546 IF (
ASSOCIATED(weights))
THEN
547 ALLOCATE (weights_uf)
548 CALL xc_pw_pool%create_pw(weights_uf)
550 TYPE(pw_c1d_gs_type) :: weights_g, weights_g_uf
551 CALL auxbas_pw_pool%create_pw(weights_g)
552 CALL xc_pw_pool%create_pw(weights_g_uf)
553 CALL pw_transfer(weights, weights_g)
554 CALL pw_transfer(weights_g, weights_g_uf)
555 CALL pw_transfer(weights_g_uf, weights_uf)
556 CALL xc_pw_pool%give_back_pw(weights_g_uf)
557 CALL auxbas_pw_pool%give_back_pw(weights_g)
562 CALL qs_rho_create(rho0_uf)
563 CALL qs_rho_transfer(rho0_struct, rho0_uf, auxbas_pw_pool, xc_pw_pool)
565 CALL qs_fxc_deriv(rho0_uf, xc_rho_set, xc_deriv_set, &
566 xc_section, weights_uf, xc_pw_pool, is_triplet)
568 CALL qs_rho_release(rho0_uf)
570 IF (
ASSOCIATED(weights_uf))
THEN
571 CALL xc_pw_pool%give_back_pw(weights_uf)
572 DEALLOCATE (weights_uf)
575 CALL qs_fxc_deriv(rho0_struct, xc_rho_set, xc_deriv_set, &
576 xc_section, weights, auxbas_pw_pool, is_triplet)
580 IF (
ASSOCIATED(rho_nlcc))
THEN
583 CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
584 CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
588 CALL timestop(handle)
602 SUBROUTINE qs_fxc_deriv(rho0, xc_rho_set, xc_deriv_set, xc_section, weights, auxbas_pw_pool, &
605 TYPE(qs_rho_type),
POINTER :: rho0
606 TYPE(xc_rho_set_type) :: xc_rho_set
607 TYPE(xc_derivative_set_type) :: xc_deriv_set
608 TYPE(section_vals_type),
POINTER :: xc_section
609 TYPE(pw_r3d_rs_type),
POINTER :: weights
610 TYPE(pw_pool_type),
POINTER :: auxbas_pw_pool
611 LOGICAL,
INTENT(IN) :: is_triplet
613 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_fxc_deriv'
616 TYPE(pw_r3d_rs_type),
DIMENSION(:),
POINTER :: rho0_r, tau0_r
617 TYPE(qs_rho_type),
POINTER :: rhot0
619 CALL timeset(routinen, handle)
621 NULLIFY (rho0_r, tau0_r)
625 CALL qs_rho_create(rhot0)
626 CALL qs_rho_copy(rho0, rhot0, auxbas_pw_pool, 2, factor=2.0_dp)
627 CALL qs_rho_get(rhot0, rho_r=rho0_r, tau_r=tau0_r)
628 CALL xc_prep_2nd_deriv(xc_deriv_set, xc_rho_set, rho0_r, auxbas_pw_pool, weights, &
629 xc_section=xc_section, tau_r=tau0_r)
630 CALL qs_rho_release(rhot0)
633 CALL qs_rho_get(rho0, rho_r=rho0_r, tau_r=tau0_r)
634 CALL xc_prep_2nd_deriv(xc_deriv_set, xc_rho_set, rho0_r, auxbas_pw_pool, weights, &
635 xc_section=xc_section, tau_r=tau0_r)
638 CALL timestop(handle)
640 END SUBROUTINE qs_fxc_deriv
657 SUBROUTINE qs_fxc_apply(qs_env, xc_deriv_set, xc_rho_set, rho1_struct, xc_section, fxc_rho, fxc_tau, &
658 is_triplet, spinflip, pw_env_ext, compute_virial, virial_xc)
660 TYPE(qs_environment_type),
POINTER :: qs_env
661 TYPE(xc_derivative_set_type) :: xc_deriv_set
662 TYPE(xc_rho_set_type) :: xc_rho_set
663 TYPE(qs_rho_type),
POINTER :: rho1_struct
664 TYPE(section_vals_type),
POINTER :: xc_section
665 TYPE(pw_r3d_rs_type),
DIMENSION(:),
POINTER :: fxc_rho, fxc_tau
666 LOGICAL,
INTENT(IN),
OPTIONAL :: is_triplet, spinflip
667 TYPE(pw_env_type),
OPTIONAL,
POINTER :: pw_env_ext
668 LOGICAL,
INTENT(IN),
OPTIONAL :: compute_virial
669 REAL(kind=dp),
DIMENSION(3, 3),
INTENT(INOUT), &
670 OPTIONAL :: virial_xc
672 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_fxc_apply'
674 INTEGER :: handle, ispin, nspins
675 LOGICAL :: do_virial, uf_grid
676 TYPE(dft_control_type),
POINTER :: dft_control
677 TYPE(pw_env_type),
POINTER :: pw_env
678 TYPE(pw_pool_type),
POINTER :: auxbas_pw_pool, xc_pw_pool
679 TYPE(pw_r3d_rs_type),
DIMENSION(:),
POINTER :: fxc_rho_lo, fxc_rho_uf, fxc_tau_lo, &
681 TYPE(pw_r3d_rs_type),
POINTER :: weights, weights_uf
682 TYPE(qs_rho_type),
POINTER :: rho1_uf
684 CALL timeset(routinen, handle)
687 IF (
PRESENT(compute_virial)) do_virial = compute_virial
689 CALL get_qs_env(qs_env, dft_control=dft_control)
691 IF (
PRESENT(pw_env_ext))
THEN
694 CALL get_qs_env(qs_env, pw_env=pw_env)
696 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, xc_pw_pool=xc_pw_pool)
697 uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
699 nspins = dft_control%nspins
700 IF (
ASSOCIATED(fxc_rho))
THEN
701 cpassert(nspins ==
SIZE(fxc_rho))
703 IF (
ASSOCIATED(fxc_tau))
THEN
704 cpassert(nspins ==
SIZE(fxc_tau))
707 CALL get_qs_env(qs_env, xcint_weights=weights)
709 NULLIFY (fxc_rho_lo, fxc_tau_lo)
712 IF (
ASSOCIATED(weights))
THEN
713 ALLOCATE (weights_uf)
714 CALL xc_pw_pool%create_pw(weights_uf)
716 TYPE(pw_c1d_gs_type) :: weights_g, weights_g_uf
717 CALL auxbas_pw_pool%create_pw(weights_g)
718 CALL xc_pw_pool%create_pw(weights_g_uf)
719 CALL pw_transfer(weights, weights_g)
720 CALL pw_transfer(weights_g, weights_g_uf)
721 CALL pw_transfer(weights_g_uf, weights_uf)
722 CALL xc_pw_pool%give_back_pw(weights_g_uf)
723 CALL auxbas_pw_pool%give_back_pw(weights_g)
728 CALL qs_rho_create(rho1_uf)
729 CALL qs_rho_transfer(rho1_struct, rho1_uf, auxbas_pw_pool, xc_pw_pool)
731 NULLIFY (fxc_rho_uf, fxc_tau_uf)
732 CALL qs_fxc_eval(xc_deriv_set, xc_rho_set, rho1_uf, xc_section, &
733 weights_uf, xc_pw_pool, fxc_rho_uf, fxc_tau_uf, &
734 is_triplet=is_triplet, spinflip=spinflip, &
735 compute_virial=do_virial, virial_xc=virial_xc)
737 CALL qs_rho_release(rho1_uf)
739 IF (
ASSOCIATED(weights_uf))
THEN
740 CALL xc_pw_pool%give_back_pw(weights_uf)
741 DEALLOCATE (weights_uf)
743 IF (
ASSOCIATED(fxc_rho_uf))
THEN
744 ALLOCATE (fxc_rho_lo(nspins))
746 CALL auxbas_pw_pool%create_pw(fxc_rho_lo(ispin))
748 TYPE(pw_c1d_gs_type) :: fxc_g, fxc_g_uf
749 CALL auxbas_pw_pool%create_pw(fxc_g)
750 CALL xc_pw_pool%create_pw(fxc_g_uf)
751 CALL pw_transfer(fxc_rho_uf(ispin), fxc_g_uf)
752 CALL pw_transfer(fxc_g_uf, fxc_g)
753 CALL pw_transfer(fxc_g, fxc_rho_lo(ispin))
754 CALL xc_pw_pool%give_back_pw(fxc_g_uf)
755 CALL auxbas_pw_pool%give_back_pw(fxc_g)
757 CALL xc_pw_pool%give_back_pw(fxc_rho_uf(ispin))
759 DEALLOCATE (fxc_rho_uf)
761 IF (
ASSOCIATED(fxc_tau_uf))
THEN
762 ALLOCATE (fxc_tau_lo(nspins))
764 CALL auxbas_pw_pool%create_pw(fxc_tau_lo(ispin))
766 TYPE(pw_c1d_gs_type) :: fxc_g, fxc_g_uf
767 CALL auxbas_pw_pool%create_pw(fxc_g)
768 CALL xc_pw_pool%create_pw(fxc_g_uf)
769 CALL pw_transfer(fxc_tau_uf(ispin), fxc_g_uf)
770 CALL pw_transfer(fxc_g_uf, fxc_g)
771 CALL pw_transfer(fxc_g, fxc_tau_lo(ispin))
772 CALL xc_pw_pool%give_back_pw(fxc_g_uf)
773 CALL auxbas_pw_pool%give_back_pw(fxc_g)
775 CALL xc_pw_pool%give_back_pw(fxc_tau_uf(ispin))
780 CALL qs_fxc_eval(xc_deriv_set, xc_rho_set, rho1_struct, xc_section, &
781 weights, auxbas_pw_pool, fxc_rho_lo, fxc_tau_lo, &
782 is_triplet=is_triplet, spinflip=spinflip, &
783 compute_virial=do_virial, virial_xc=virial_xc)
787 IF (
ASSOCIATED(fxc_rho))
THEN
788 DO ispin = 1, min(
SIZE(fxc_rho_lo),
SIZE(fxc_rho))
789 CALL pw_transfer(fxc_rho_lo(ispin), fxc_rho(ispin))
791 DO ispin = 1,
SIZE(fxc_rho_lo)
792 CALL auxbas_pw_pool%give_back_pw(fxc_rho_lo(ispin))
794 DEALLOCATE (fxc_rho_lo)
796 fxc_rho => fxc_rho_lo
798 IF (
ASSOCIATED(fxc_tau))
THEN
799 IF (
ASSOCIATED(fxc_tau_lo))
THEN
800 DO ispin = 1, min(
SIZE(fxc_tau_lo),
SIZE(fxc_tau))
801 CALL pw_transfer(fxc_tau_lo(ispin), fxc_tau(ispin))
803 DO ispin = 1,
SIZE(fxc_tau_lo)
804 CALL auxbas_pw_pool%give_back_pw(fxc_tau_lo(ispin))
806 DEALLOCATE (fxc_tau_lo)
809 CALL pw_zero(fxc_tau(ispin))
813 fxc_tau => fxc_tau_lo
816 CALL timestop(handle)
835 SUBROUTINE qs_fxc_eval(xc_deriv_set, xc_rho_set, rho1, xc_section, weights, auxbas_pw_pool, &
836 fxc_rho, fxc_tau, is_triplet, spinflip, &
837 compute_virial, virial_xc)
839 TYPE(xc_derivative_set_type) :: xc_deriv_set
840 TYPE(xc_rho_set_type) :: xc_rho_set
841 TYPE(qs_rho_type),
POINTER :: rho1
842 TYPE(section_vals_type),
POINTER :: xc_section
843 TYPE(pw_r3d_rs_type),
POINTER :: weights
844 TYPE(pw_pool_type),
POINTER :: auxbas_pw_pool
845 TYPE(pw_r3d_rs_type),
DIMENSION(:),
POINTER :: fxc_rho, fxc_tau
846 LOGICAL,
INTENT(IN),
OPTIONAL :: is_triplet, spinflip, compute_virial
847 REAL(kind=dp),
DIMENSION(3, 3),
INTENT(INOUT), &
848 OPTIONAL :: virial_xc
850 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_fxc_eval'
852 INTEGER :: handle, ispin, mspins, nspins
853 INTEGER,
DIMENSION(2, 3) :: bo
854 LOGICAL :: do_analytic, do_sf, do_triplet, &
856 REAL(kind=dp),
DIMENSION(:, :, :, :),
POINTER :: vxg
857 TYPE(pw_c1d_gs_type),
DIMENSION(:),
POINTER :: rho1_g
858 TYPE(pw_r3d_rs_type),
DIMENSION(:),
POINTER :: rho1_r, tau1_r
859 TYPE(qs_rho_type),
POINTER :: rhot1
860 TYPE(section_vals_type),
POINTER :: xc_fun_section
861 TYPE(xc_rho_cflags_type) :: needs
862 TYPE(xc_rho_set_type) :: rho1_set
864 CALL timeset(routinen, handle)
867 IF (
PRESENT(is_triplet)) do_triplet = is_triplet
870 IF (
PRESENT(spinflip)) do_sf = spinflip
873 IF (
PRESENT(compute_virial)) do_virial = compute_virial
875 do_analytic = section_get_lval(xc_section,
"2ND_DERIV_ANALYTICAL")
877 CALL qs_rho_get(rho1, rho_r=rho1_r, tau_r=tau1_r)
880 mspins =
SIZE(rho1_r)
881 nspins =
SIZE(rho1_r)
883 IF (nspins == 1 .AND. do_triplet)
THEN
892 cpassert(.NOT.
ASSOCIATED(fxc_rho))
893 cpassert(.NOT.
ASSOCIATED(fxc_tau))
894 xc_fun_section => section_vals_get_subs_vals(xc_section,
"XC_FUNCTIONAL")
895 needs = xc_functionals_get_needs(xc_fun_section, lsd, .true.)
896 ALLOCATE (fxc_rho(mspins))
898 CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
899 CALL pw_zero(fxc_rho(ispin))
901 IF (needs%tau .OR. needs%tau_spin)
THEN
902 IF (.NOT.
ASSOCIATED(tau1_r))
THEN
903 cpabort(
"Tau-dependent functionals requires allocated kinetic energy density grid")
905 ALLOCATE (fxc_tau(mspins))
907 CALL auxbas_pw_pool%create_pw(fxc_tau(ispin))
908 CALL pw_zero(fxc_tau(ispin))
912 IF (mspins == 1 .AND. do_triplet)
THEN
915 CALL qs_rho_create(rhot1)
916 CALL qs_rho_copy(rho1, rhot1, auxbas_pw_pool, 2, factor=2.0_dp)
918 CALL qs_rho_get(rhot1, rho_r=rho1_r, tau_r=tau1_r)
921 bo = rho1_r(1)%pw_grid%bounds_local
923 CALL xc_rho_set_create(rho1_set, bo, &
924 rho_cutoff=section_get_rval(xc_section,
"DENSITY_CUTOFF"), &
925 drho_cutoff=section_get_rval(xc_section,
"GRADIENT_CUTOFF"), &
926 tau_cutoff=section_get_rval(xc_section,
"TAU_CUTOFF"))
929 CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
930 section_get_ival(xc_section,
"XC_GRID%XC_DERIV"), &
931 section_get_ival(xc_section,
"XC_GRID%XC_SMOOTH_RHO"), &
932 auxbas_pw_pool, spinflip=do_sf)
934 IF (mspins == 1 .AND. do_triplet .AND. do_analytic)
THEN
936 CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, xc_rho_set, &
937 rho1_set, auxbas_pw_pool, xc_section, &
938 gapw=.false., vxg=vxg, tddfpt_fac=-1.0_dp, spinflip=do_sf, &
939 compute_virial=compute_virial, virial_xc=virial_xc)
941 ELSE IF (do_analytic)
THEN
943 CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, xc_rho_set, &
944 rho1_set, auxbas_pw_pool, xc_section, &
945 gapw=.false., vxg=vxg, spinflip=do_sf, &
946 compute_virial=compute_virial, virial_xc=virial_xc)
950 CALL xc_calc_2nd_deriv_numerical(fxc_rho, fxc_tau, xc_rho_set, rho1_r, rho1_g, tau1_r, &
951 auxbas_pw_pool, weights, xc_section, &
952 do_triplet, compute_virial, virial_xc, xc_deriv_set)
956 IF (mspins == 1 .AND. do_triplet)
THEN
957 CALL qs_rho_release(rhot1)
960 CALL xc_rho_set_release(rho1_set)
962 CALL timestop(handle)
964 END SUBROUTINE qs_fxc_eval
978 SUBROUTINE qs_fxc_fdiff(qs_env, rho0_struct, rho1_struct, xc_section, accuracy, &
979 fxc_rho, fxc_tau, is_triplet, spinflip)
981 TYPE(qs_environment_type),
POINTER :: qs_env
982 TYPE(qs_rho_type),
POINTER :: rho0_struct, rho1_struct
983 TYPE(section_vals_type),
POINTER :: xc_section
984 INTEGER,
INTENT(IN) :: accuracy
985 TYPE(pw_r3d_rs_type),
DIMENSION(:),
POINTER :: fxc_rho, fxc_tau
986 LOGICAL,
INTENT(IN),
OPTIONAL :: is_triplet, spinflip
988 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_fxc_fdiff'
989 REAL(kind=dp),
PARAMETER :: epsrho = 5.e-4_dp
991 INTEGER :: handle, ispin, istep, nspins, nstep
992 LOGICAL :: do_sf, do_triplet
993 REAL(kind=dp) :: alpha, beta, exc, oeps1
994 REAL(kind=dp),
DIMENSION(-4:4) :: ak
995 TYPE(dft_control_type),
POINTER :: dft_control
996 TYPE(pw_env_type),
POINTER :: pw_env
997 TYPE(pw_pool_type),
POINTER :: auxbas_pw_pool
998 TYPE(pw_r3d_rs_type),
DIMENSION(:),
POINTER :: v_tau_rspace, vxc00
999 TYPE(qs_ks_env_type),
POINTER :: ks_env
1000 TYPE(qs_rho_type),
POINTER :: rhoin
1002 CALL timeset(routinen, handle)
1004 cpassert(.NOT.
ASSOCIATED(fxc_rho))
1005 cpassert(.NOT.
ASSOCIATED(fxc_tau))
1006 cpassert(
ASSOCIATED(rho0_struct))
1007 cpassert(
ASSOCIATED(rho1_struct))
1009 do_triplet = .false.
1010 IF (
PRESENT(is_triplet)) do_triplet = is_triplet
1013 IF (
PRESENT(spinflip)) do_sf = spinflip
1015 cpabort(
"Spin Flip TDDFT only available with analytic 2nd xc derivatives")
1019 SELECT CASE (accuracy)
1022 ak(-2:2) = [1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp]/12.0_dp
1025 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
1028 ak(-4:4) = [1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
1029 224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp]/280.0_dp
1032 CALL get_qs_env(qs_env, ks_env=ks_env, dft_control=dft_control, pw_env=pw_env)
1033 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
1035 nspins = dft_control%nspins
1038 DO istep = -nstep, nstep
1040 IF (ak(istep) /= 0.0_dp)
THEN
1042 beta = real(istep, kind=dp)*epsrho
1045 CALL qs_rho_create(rhoin)
1046 NULLIFY (vxc00, v_tau_rspace)
1047 IF (do_triplet)
THEN
1048 cpassert(nspins == 1)
1050 CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, 2)
1052 CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, 0.5_dp*beta)
1053 CALL qs_vxc_create(ks_env, rhoin, xc_section, vxc00, v_tau_rspace, exc)
1054 CALL pw_axpy(vxc00(2), vxc00(1), -1.0_dp)
1055 IF (
ASSOCIATED(v_tau_rspace))
CALL pw_axpy(v_tau_rspace(2), v_tau_rspace(1), -1.0_dp)
1057 CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, nspins)
1058 CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, beta)
1059 CALL qs_vxc_create(ks_env, rhoin, xc_section, vxc00, v_tau_rspace, exc)
1061 CALL qs_rho_release(rhoin)
1063 IF (.NOT.
ASSOCIATED(fxc_rho))
THEN
1064 ALLOCATE (fxc_rho(nspins))
1065 DO ispin = 1, nspins
1066 CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
1067 CALL pw_zero(fxc_rho(ispin))
1070 DO ispin = 1, nspins
1071 CALL pw_axpy(vxc00(ispin), fxc_rho(ispin), ak(istep))
1073 DO ispin = 1,
SIZE(vxc00)
1074 CALL auxbas_pw_pool%give_back_pw(vxc00(ispin))
1077 IF (
ASSOCIATED(v_tau_rspace))
THEN
1078 IF (.NOT.
ASSOCIATED(fxc_tau))
THEN
1079 ALLOCATE (fxc_tau(nspins))
1080 DO ispin = 1, nspins
1081 CALL auxbas_pw_pool%create_pw(fxc_tau(ispin))
1082 CALL pw_zero(fxc_tau(ispin))
1085 DO ispin = 1, nspins
1086 CALL pw_axpy(v_tau_rspace(ispin), fxc_tau(ispin), ak(istep))
1088 DO ispin = 1,
SIZE(v_tau_rspace)
1089 CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
1091 DEALLOCATE (v_tau_rspace)
1097 oeps1 = 1.0_dp/epsrho
1098 DO ispin = 1, nspins
1099 CALL pw_scale(fxc_rho(ispin), oeps1)
1101 IF (
ASSOCIATED(fxc_tau))
THEN
1102 DO ispin = 1, nspins
1103 CALL pw_scale(fxc_tau(ispin), oeps1)
1107 CALL timestop(handle)
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
Defines the basic variable types.
integer, parameter, public dp
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.
logical function, public pw_grid_compare(grida, gridb)
Check if two pw_grids are equal.
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
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.
Setup Routine for Fxc Potentials.
subroutine, public qs_fxc_create(qs_env, rho0_struct, rho1_struct, xc_section, fxc_rho, fxc_tau, is_triplet, spinflip, no_weights, uf_grid_results, pw_env_ext, compute_virial, virial_xc)
...
subroutine, public qs_fxc_prep(qs_env, rho0_struct, xc_rho_set, xc_deriv_set, xc_section, pw_env_ext, is_triplet)
...
subroutine, public qs_fxc_fdiff(qs_env, rho0_struct, rho1_struct, xc_section, accuracy, fxc_rho, fxc_tau, is_triplet, spinflip)
...
subroutine, public qs_fxc_apply(qs_env, xc_deriv_set, xc_rho_set, rho1_struct, xc_section, fxc_rho, fxc_tau, is_triplet, spinflip, pw_env_ext, compute_virial, virial_xc)
...
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...
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)
...
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.
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....
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...
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
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 ...
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