(git:4a2d255)
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-2025 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief https://en.wikipedia.org/wiki/Finite_difference_coefficient
10!---------------------------------------------------------------------------------------------------
11!Derivative Accuracy 4 3 2 1 0 1 2 3 4
12!---------------------------------------------------------------------------------------------------
13! 1 2 -1/2 0 1/2
14! 4 1/12 -2/3 0 2/3 -1/12
15! 6 -1/60 3/20 -3/4 0 3/4 -3/20 1/60
16! 8 1/280 -4/105 1/5 -4/5 0 4/5 -1/5 4/105 -1/280
17!---------------------------------------------------------------------------------------------------
18! 2 2 1 -2 1
19! 4 -1/12 4/3 -5/2 4/3 -1/12
20! 6 1/90 -3/20 3/2 -49/18 3/2 -3/20 1/90
21! 8 -1/560 8/315 -1/5 8/5 -205/72 8/5 -1/5 8/315 -1/560
22!---------------------------------------------------------------------------------------------------
23!> \par History
24!> init 17.03.2020
25!> \author JGH
26! **************************************************************************************************
27MODULE qs_fxc
28
34 USE kinds, ONLY: dp
35 USE pw_env_types, ONLY: pw_env_get,&
37 USE pw_methods, ONLY: pw_axpy,&
38 pw_scale,&
41 USE pw_types, ONLY: pw_c1d_gs_type,&
43 USE qs_ks_types, ONLY: get_ks_env,&
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
53 USE xc, ONLY: xc_calc_2nd_deriv,&
66#include "./base/base_uses.f90"
67
68 IMPLICIT NONE
69
70 PRIVATE
71
72 ! *** Public subroutines ***
74
75 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_fxc'
76
77! **************************************************************************************************
78
79CONTAINS
80
81! **************************************************************************************************
82!> \brief ...
83!> \param rho0 ...
84!> \param rho1_r ...
85!> \param tau1_r ...
86!> \param xc_section ...
87!> \param auxbas_pw_pool ...
88!> \param is_triplet ...
89!> \param v_xc ...
90!> \param v_xc_tau ...
91!> \param spinflip ...
92! **************************************************************************************************
93 SUBROUTINE qs_fxc_analytic(rho0, rho1_r, tau1_r, xc_section, auxbas_pw_pool, is_triplet, v_xc, v_xc_tau, spinflip)
94
95 TYPE(qs_rho_type), POINTER :: rho0
96 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho1_r, tau1_r
97 TYPE(section_vals_type), POINTER :: xc_section
98 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
99 LOGICAL, INTENT(IN) :: is_triplet
100 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_xc, v_xc_tau
101 LOGICAL, OPTIONAL :: spinflip
102
103 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_analytic'
104
105 INTEGER :: handle, nspins
106 INTEGER, DIMENSION(2, 3) :: bo
107 LOGICAL :: do_sf, lsd
108 REAL(kind=dp) :: fac
109 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho0_g, rho1_g
110 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho0_r, tau0_r
111 TYPE(section_vals_type), POINTER :: xc_fun_section
112 TYPE(xc_derivative_set_type) :: deriv_set
113 TYPE(xc_rho_cflags_type) :: needs
114 TYPE(xc_rho_set_type) :: rho0_set
115
116 CALL timeset(routinen, handle)
117
118 cpassert(.NOT. ASSOCIATED(v_xc))
119 cpassert(.NOT. ASSOCIATED(v_xc_tau))
120
121 do_sf = .false.
122 IF (PRESENT(spinflip)) do_sf = spinflip
123
124 CALL qs_rho_get(rho0, rho_r=rho0_r, rho_g=rho0_g, tau_r=tau0_r)
125 nspins = SIZE(rho0_r)
126
127 lsd = (nspins == 2)
128 fac = 0._dp
129 IF (is_triplet .AND. nspins == 1) fac = -1.0_dp
130
131 NULLIFY (rho1_g)
132 bo = rho1_r(1)%pw_grid%bounds_local
133 xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
134 needs = xc_functionals_get_needs(xc_fun_section, lsd, .true.)
135 ! calculate the arguments needed by the functionals and the values of the functional on the grid
136 CALL xc_prep_2nd_deriv(deriv_set, rho0_set, rho0_r, auxbas_pw_pool, xc_section=xc_section, tau_r=tau0_r)
137 ! Folds the density rho1 with the functional
138 CALL xc_calc_2nd_deriv(v_xc, v_xc_tau, deriv_set, rho0_set, rho1_r, rho1_g, tau1_r, &
139 auxbas_pw_pool, xc_section=xc_section, gapw=.false., do_triplet=is_triplet, &
140 do_sf=do_sf)
141 CALL xc_dset_release(deriv_set)
142 CALL xc_rho_set_release(rho0_set)
143
144 CALL timestop(handle)
145
146 END SUBROUTINE qs_fxc_analytic
147
148! **************************************************************************************************
149!> \brief ...
150!> \param ks_env ...
151!> \param rho0_struct ...
152!> \param rho1_struct ...
153!> \param xc_section ...
154!> \param accuracy ...
155!> \param is_triplet ...
156!> \param fxc_rho ...
157!> \param fxc_tau ...
158! **************************************************************************************************
159 SUBROUTINE qs_fxc_fdiff(ks_env, rho0_struct, rho1_struct, xc_section, accuracy, is_triplet, &
160 fxc_rho, fxc_tau)
161
162 TYPE(qs_ks_env_type), POINTER :: ks_env
163 TYPE(qs_rho_type), POINTER :: rho0_struct, rho1_struct
164 TYPE(section_vals_type), POINTER :: xc_section
165 INTEGER, INTENT(IN) :: accuracy
166 LOGICAL, INTENT(IN) :: is_triplet
167 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho, fxc_tau
168
169 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fxc_fdiff'
170 REAL(kind=dp), PARAMETER :: epsrho = 5.e-4_dp
171
172 INTEGER :: handle, ispin, istep, nspins, nstep
173 REAL(kind=dp) :: alpha, beta, exc, oeps1
174 REAL(kind=dp), DIMENSION(-4:4) :: ak
175 TYPE(dft_control_type), POINTER :: dft_control
176 TYPE(pw_env_type), POINTER :: pw_env
177 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
178 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_tau_rspace, vxc00
179 TYPE(qs_rho_type), POINTER :: rhoin
180
181 CALL timeset(routinen, handle)
182
183 cpassert(.NOT. ASSOCIATED(fxc_rho))
184 cpassert(.NOT. ASSOCIATED(fxc_tau))
185 cpassert(ASSOCIATED(rho0_struct))
186 cpassert(ASSOCIATED(rho1_struct))
187
188 ak = 0.0_dp
189 SELECT CASE (accuracy)
190 CASE (:4)
191 nstep = 2
192 ak(-2:2) = (/1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp/)/12.0_dp
193 CASE (5:7)
194 nstep = 3
195 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
196 CASE (8:)
197 nstep = 4
198 ak(-4:4) = (/1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
199 224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp/)/280.0_dp
200 END SELECT
201
202 CALL get_ks_env(ks_env, dft_control=dft_control, pw_env=pw_env)
203 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
204
205 nspins = dft_control%nspins
206 exc = 0.0_dp
207
208 DO istep = -nstep, nstep
209
210 IF (ak(istep) /= 0.0_dp) THEN
211 alpha = 1.0_dp
212 beta = real(istep, kind=dp)*epsrho
213 NULLIFY (rhoin)
214 ALLOCATE (rhoin)
215 CALL qs_rho_create(rhoin)
216 NULLIFY (vxc00, v_tau_rspace)
217 IF (is_triplet) THEN
218 cpassert(nspins == 1)
219 ! rhoin = (0.5 rho0, 0.5 rho0)
220 CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, 2)
221 ! rhoin = (0.5 rho0 + 0.5 rho1, 0.5 rho0)
222 CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, 0.5_dp*beta)
223 CALL qs_vxc_create(ks_env=ks_env, rho_struct=rhoin, xc_section=xc_section, &
224 vxc_rho=vxc00, vxc_tau=v_tau_rspace, exc=exc, just_energy=.false.)
225 CALL pw_axpy(vxc00(2), vxc00(1), -1.0_dp)
226 IF (ASSOCIATED(v_tau_rspace)) CALL pw_axpy(v_tau_rspace(2), v_tau_rspace(1), -1.0_dp)
227 ELSE
228 CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, nspins)
229 CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, beta)
230 CALL qs_vxc_create(ks_env=ks_env, rho_struct=rhoin, xc_section=xc_section, &
231 vxc_rho=vxc00, vxc_tau=v_tau_rspace, exc=exc, just_energy=.false.)
232 END IF
233 CALL qs_rho_release(rhoin)
234 DEALLOCATE (rhoin)
235 IF (.NOT. ASSOCIATED(fxc_rho)) THEN
236 ALLOCATE (fxc_rho(nspins))
237 DO ispin = 1, nspins
238 CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
239 CALL pw_zero(fxc_rho(ispin))
240 END DO
241 END IF
242 DO ispin = 1, nspins
243 CALL pw_axpy(vxc00(ispin), fxc_rho(ispin), ak(istep))
244 END DO
245 DO ispin = 1, SIZE(vxc00)
246 CALL auxbas_pw_pool%give_back_pw(vxc00(ispin))
247 END DO
248 DEALLOCATE (vxc00)
249 IF (ASSOCIATED(v_tau_rspace)) THEN
250 IF (.NOT. ASSOCIATED(fxc_tau)) THEN
251 ALLOCATE (fxc_tau(nspins))
252 DO ispin = 1, nspins
253 CALL auxbas_pw_pool%create_pw(fxc_tau(ispin))
254 CALL pw_zero(fxc_tau(ispin))
255 END DO
256 END IF
257 DO ispin = 1, nspins
258 CALL pw_axpy(v_tau_rspace(ispin), fxc_tau(ispin), ak(istep))
259 END DO
260 DO ispin = 1, SIZE(v_tau_rspace)
261 CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
262 END DO
263 DEALLOCATE (v_tau_rspace)
264 END IF
265 END IF
266
267 END DO
268
269 oeps1 = 1.0_dp/epsrho
270 DO ispin = 1, nspins
271 CALL pw_scale(fxc_rho(ispin), oeps1)
272 END DO
273 IF (ASSOCIATED(fxc_tau)) THEN
274 DO ispin = 1, nspins
275 CALL pw_scale(fxc_tau(ispin), oeps1)
276 END DO
277 END IF
278
279 CALL timestop(handle)
280
281 END SUBROUTINE qs_fxc_fdiff
282
283! **************************************************************************************************
284!> \brief Calculates the values at the grid points in real space (r_i), of the second and third
285!> functional derivatives of the exchange-correlation energy functional.
286!> fxc_rho(r_i) = fxc[n](r_i)*n^(1)(r_i) ! Second functional derivative
287!> gxc_rho(r_i) = n^(1)(r_i)*gxc[n](r_i)*n^(1)(r_i) ! Third functional derivative
288!> \param rho0_struct Ground state density, n(r).
289!> \param rho1_struct Density used to fold the functional derivatives, n^(1)(r).
290!> \param xc_section ...
291!> \param pw_pool ...
292!> \param fxc_rho Second functional derivative with respect to the density, n(r).
293!> \param fxc_tau mGGA contribution to the second functional derivative with respect to the density.
294!> \param gxc_rho Third functional derivative with respect to the density, n(r).
295!> \param gxc_tau mGGA contribution to the third functional derivative with respect to the density.
296!> \param spinflip Flag used to activate the spin-flip noncollinear kernel and kernel derivatives.
297!> \par History
298!> * 07.2024 Created [LHS]
299! **************************************************************************************************
300 SUBROUTINE qs_fgxc_analytic(rho0_struct, rho1_struct, xc_section, pw_pool, &
301 fxc_rho, fxc_tau, gxc_rho, gxc_tau, spinflip)
302
303 TYPE(qs_rho_type), POINTER :: rho0_struct, rho1_struct
304 TYPE(section_vals_type), POINTER :: xc_section
305 TYPE(pw_pool_type), POINTER :: pw_pool
306 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho, fxc_tau, gxc_rho, gxc_tau
307 LOGICAL, INTENT(IN), OPTIONAL :: spinflip
308
309 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fgxc_analytic'
310
311 INTEGER :: handle, ispin, nspins, spindim
312 INTEGER, DIMENSION(2, 3) :: bo
313 LOGICAL :: do_sf, lsd
314 REAL(kind=dp) :: fac
315 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho0_g, rho1_g
316 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho0_r, rho1_r, tau0_r, tau1_r
317 TYPE(section_vals_type), POINTER :: xc_fun_section
318 TYPE(xc_derivative_set_type) :: deriv_set
319 TYPE(xc_rho_cflags_type) :: needs
320 TYPE(xc_rho_set_type) :: rho0_set, rho1_set
321
322 CALL timeset(routinen, handle)
323
324 ! Only rho0 and rho1 should be associated
325 cpassert(.NOT. ASSOCIATED(fxc_rho))
326 cpassert(.NOT. ASSOCIATED(fxc_tau))
327 cpassert(.NOT. ASSOCIATED(gxc_rho))
328 cpassert(.NOT. ASSOCIATED(gxc_tau))
329 cpassert(ASSOCIATED(rho0_struct))
330 cpassert(ASSOCIATED(rho1_struct))
331
332 ! Initialize parameters
333 do_sf = .false.
334 IF (PRESENT(spinflip)) do_sf = spinflip
335 !
336 ! Get the values on the gridpoints of the rho0 density
337 CALL qs_rho_get(rho0_struct, rho_r=rho0_r, rho_g=rho0_g, tau_r=tau0_r)
338 nspins = SIZE(rho0_r)
339 lsd = (nspins == 2)
340 !
341 IF (do_sf) THEN
342 spindim = 1
343 ELSE
344 spindim = nspins
345 END IF
346 !
347 fac = 0._dp
348 IF (nspins == 1) THEN
349 fac = 1.0_dp
350 END IF
351
352 ! Read xc functional section and find out what the functional actually needs
353 xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
354 needs = xc_functionals_get_needs(xc_fun_section, lsd, .true.)
355
356 ! Create fields for the kernel and kernel derivative
357 ALLOCATE (fxc_rho(spindim), gxc_rho(nspins))
358 DO ispin = 1, spindim
359 CALL pw_pool%create_pw(fxc_rho(ispin))
360 CALL pw_zero(fxc_rho(ispin))
361 END DO
362 DO ispin = 1, nspins
363 CALL pw_pool%create_pw(gxc_rho(ispin))
364 CALL pw_zero(gxc_rho(ispin))
365 END DO
366 ! Create fields for mGGA functionals. This implementation is not ready yet!
367 IF (needs%tau .OR. needs%tau_spin) THEN
368 IF (.NOT. ASSOCIATED(tau1_r)) &
369 cpabort("Tau-dependent functionals requires allocated kinetic energy density grid")
370 ALLOCATE (fxc_tau(spindim), gxc_tau(nspins))
371 DO ispin = 1, spindim
372 CALL pw_pool%create_pw(fxc_tau(ispin))
373 CALL pw_zero(fxc_tau(ispin))
374 END DO
375 DO ispin = 1, nspins
376 CALL pw_pool%create_pw(gxc_tau(ispin))
377 CALL pw_zero(gxc_tau(ispin))
378 END DO
379 END IF
380
381 ! Build rho0_set
382 ! calculate the arguments needed by the functionals
383 ! Needs
384 ! deriv_set xc_derivative_set_type just declared
385 ! rho0_set xc_rho_set_type just declared
386 ! rho0_r pw_type calculated by qs_rho_get
387 ! pw_pool given by the calling subroutine
388 ! xc_section given by the calling subroutine
389 ! tau0_r pw_type calculated by qs_rho_get
390 CALL xc_prep_3rd_deriv(deriv_set, rho0_set, rho0_r, pw_pool, xc_section, tau_r=tau0_r, &
391 do_sf=do_sf)
392
393 ! Build rho1_set
394 ! Get the values on the gridpoints of the rho1 density
395 CALL qs_rho_get(rho1_struct, rho_r=rho1_r, rho_g=rho1_g, tau_r=tau1_r)
396 bo = rho1_r(1)%pw_grid%bounds_local
397 ! create the place where to store the argument for the functionals
398 ! Needs
399 ! rho1_set xc_rho_set_type just declared
400 ! bo 2x3 integer matrix should have bounds_local or rho1_r
401 CALL xc_rho_set_create(rho1_set, bo, &
402 rho_cutoff=section_get_rval(xc_section, "DENSITY_CUTOFF"), &
403 drho_cutoff=section_get_rval(xc_section, "GRADIENT_CUTOFF"), &
404 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
405 ! calculate the arguments needed by the functionals
406 ! Needs
407 ! rho1_set object created by xc_rho_set_create
408 ! rho1_r,rho1_g,tau1_r pw_type values of rho1 in real space grid
409 ! needs xc_rho_cflags_type defined through xc_functionals_get_needs
410 ! pw_pool Given by the calling subroutine
411 CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
412 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
413 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
414 pw_pool, spinflip=do_sf)
415
416 ! Calculate exchange correlation kernel
417 ! Needs
418 ! fxc_rho, fxc_tau pw_type not associated
419 ! deriv_set created and defined by xc_prep_3rd_deriv
420 ! rho0_set xc_rho_set_type build by xc_prep_3rd_deriv
421 ! rho1_set xc_rho_set_type build by xc_rho_set_create/update
422 ! pw_pool needs to be given by the calling subroutine
423 ! xc_section needs to be given by the calling subroutine
424 CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, deriv_set, rho0_set, rho1_set, pw_pool, &
425 xc_section, .false., spinflip=do_sf, tddfpt_fac=fac)
426 ! Calculate exchange correlation kernel derivative
427 CALL xc_calc_3rd_deriv_analytical(gxc_rho, gxc_tau, deriv_set, rho0_set, rho1_set, pw_pool, &
428 xc_section, spinflip=do_sf)
429
430 CALL xc_dset_release(deriv_set)
431 CALL xc_rho_set_release(rho0_set)
432 CALL xc_rho_set_release(rho1_set)
433
434 CALL timestop(handle)
435
436 END SUBROUTINE qs_fgxc_analytic
437
438! **************************************************************************************************
439!> \brief ...
440!> \param ks_env ...
441!> \param rho0_struct ...
442!> \param rho1_struct ...
443!> \param xc_section ...
444!> \param accuracy ...
445!> \param epsrho ...
446!> \param is_triplet ...
447!> \param fxc_rho ...
448!> \param fxc_tau ...
449!> \param gxc_rho ...
450!> \param gxc_tau ...
451!> \param spinflip ...
452! **************************************************************************************************
453 SUBROUTINE qs_fgxc_gdiff(ks_env, rho0_struct, rho1_struct, xc_section, accuracy, epsrho, &
454 is_triplet, fxc_rho, fxc_tau, gxc_rho, gxc_tau, spinflip)
455
456 TYPE(qs_ks_env_type), POINTER :: ks_env
457 TYPE(qs_rho_type), POINTER :: rho0_struct, rho1_struct
458 TYPE(section_vals_type), POINTER :: xc_section
459 INTEGER, INTENT(IN) :: accuracy
460 REAL(kind=dp), INTENT(IN) :: epsrho
461 LOGICAL, INTENT(IN) :: is_triplet
462 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho, fxc_tau, gxc_rho, gxc_tau
463 LOGICAL, OPTIONAL :: spinflip
464
465 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fgxc_gdiff'
466
467 INTEGER :: handle, ispin, istep, nspins, nstep
468 LOGICAL :: do_sf
469 REAL(kind=dp) :: alpha, beta, exc, oeps1
470 REAL(kind=dp), DIMENSION(-4:4) :: ak
471 TYPE(dft_control_type), POINTER :: dft_control
472 TYPE(pw_env_type), POINTER :: pw_env
473 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
474 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho1_r, tau1_r, v_tau_rspace, vxc00, &
475 vxc00b
476 TYPE(qs_rho_type), POINTER :: rhoin
477
478 CALL timeset(routinen, handle)
479
480 cpassert(.NOT. ASSOCIATED(fxc_rho))
481 cpassert(.NOT. ASSOCIATED(fxc_tau))
482 cpassert(.NOT. ASSOCIATED(gxc_rho))
483 cpassert(.NOT. ASSOCIATED(gxc_tau))
484 cpassert(ASSOCIATED(rho0_struct))
485 cpassert(ASSOCIATED(rho1_struct))
486
487 do_sf = .false.
488 IF (PRESENT(spinflip)) do_sf = spinflip
489
490 ak = 0.0_dp
491 SELECT CASE (accuracy)
492 CASE (:4)
493 nstep = 2
494 ak(-2:2) = (/1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp/)/12.0_dp
495 CASE (5:7)
496 nstep = 3
497 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
498 CASE (8:)
499 nstep = 4
500 ak(-4:4) = (/1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
501 224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp/)/280.0_dp
502 END SELECT
503
504 CALL get_ks_env(ks_env, dft_control=dft_control, pw_env=pw_env)
505 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
506
507 nspins = dft_control%nspins
508 exc = 0.0_dp
509
510 IF (do_sf) THEN
511 CALL qs_rho_get(rho1_struct, rho_r=rho1_r, tau_r=tau1_r)
512 CALL qs_fxc_analytic(rho0_struct, rho1_r, tau1_r, xc_section, &
513 auxbas_pw_pool, is_triplet, fxc_rho, fxc_tau, spinflip=do_sf)
514 ELSE
515 CALL qs_fxc_fdiff(ks_env, rho0_struct, rho1_struct, xc_section, accuracy, is_triplet, &
516 fxc_rho, fxc_tau)
517 END IF
518
519 DO istep = -nstep, nstep
520
521 IF (ak(istep) /= 0.0_dp) THEN
522 alpha = 1.0_dp
523 beta = real(istep, kind=dp)*epsrho
524 NULLIFY (rhoin)
525 ALLOCATE (rhoin)
526 CALL qs_rho_create(rhoin)
527 NULLIFY (vxc00, vxc00b, v_tau_rspace)
528 CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, nspins)
529 CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, beta)
530 IF (do_sf) THEN
531 ! variation in alpha density
532 CALL qs_fxc_analytic(rhoin, rho1_r, tau1_r, &
533 xc_section, auxbas_pw_pool, is_triplet, &
534 vxc00, v_tau_rspace, spinflip=do_sf)
535 ! variation in beta density
536 CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, nspins)
537 CALL qs_rho_scale_and_add_b(rhoin, rho1_struct, alpha, beta)
538 CALL qs_fxc_analytic(rhoin, rho1_r, tau1_r, &
539 xc_section, auxbas_pw_pool, is_triplet, &
540 vxc00b, v_tau_rspace, spinflip=do_sf)
541 ELSE
542 CALL qs_fxc_fdiff(ks_env=ks_env, rho0_struct=rhoin, rho1_struct=rho1_struct, &
543 xc_section=xc_section, accuracy=accuracy, is_triplet=is_triplet, &
544 fxc_rho=vxc00, fxc_tau=v_tau_rspace)
545 END IF
546 CALL qs_rho_release(rhoin)
547 DEALLOCATE (rhoin)
548 IF (.NOT. ASSOCIATED(gxc_rho)) THEN
549 ALLOCATE (gxc_rho(nspins))
550 DO ispin = 1, nspins
551 CALL auxbas_pw_pool%create_pw(gxc_rho(ispin))
552 CALL pw_zero(gxc_rho(ispin))
553 END DO
554 END IF
555 IF (do_sf) THEN
556 CALL pw_axpy(vxc00(1), gxc_rho(1), ak(istep))
557 CALL pw_axpy(vxc00b(1), gxc_rho(2), ak(istep))
558 ELSE
559 DO ispin = 1, nspins
560 CALL pw_axpy(vxc00(ispin), gxc_rho(ispin), ak(istep))
561 END DO
562 END IF
563 DO ispin = 1, SIZE(vxc00)
564 CALL auxbas_pw_pool%give_back_pw(vxc00(ispin))
565 END DO
566 DEALLOCATE (vxc00)
567 IF (ASSOCIATED(vxc00b)) THEN
568 CALL auxbas_pw_pool%give_back_pw(vxc00b(1))
569 DEALLOCATE (vxc00b)
570 END IF
571 IF (ASSOCIATED(v_tau_rspace)) THEN
572 IF (.NOT. ASSOCIATED(gxc_tau)) THEN
573 ALLOCATE (gxc_tau(nspins))
574 DO ispin = 1, nspins
575 CALL auxbas_pw_pool%create_pw(gxc_tau(ispin))
576 CALL pw_zero(gxc_tau(ispin))
577 END DO
578 END IF
579 DO ispin = 1, nspins
580 CALL pw_axpy(v_tau_rspace(ispin), gxc_tau(ispin), ak(istep))
581 END DO
582 DO ispin = 1, SIZE(v_tau_rspace)
583 CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
584 END DO
585 DEALLOCATE (v_tau_rspace)
586 END IF
587 END IF
588
589 END DO
590
591 oeps1 = 1.0_dp/epsrho
592 DO ispin = 1, nspins
593 CALL pw_scale(gxc_rho(ispin), oeps1)
594 END DO
595 IF (ASSOCIATED(gxc_tau)) THEN
596 DO ispin = 1, nspins
597 CALL pw_scale(gxc_tau(ispin), oeps1)
598 END DO
599 END IF
600
601 CALL timestop(handle)
602
603 END SUBROUTINE qs_fgxc_gdiff
604
605! **************************************************************************************************
606!> \brief ...
607!> \param ks_env ...
608!> \param rho0_struct ...
609!> \param rho1_struct ...
610!> \param xc_section ...
611!> \param accuracy ...
612!> \param is_triplet ...
613!> \param fxc_rho ...
614!> \param fxc_tau ...
615!> \param gxc_rho ...
616!> \param gxc_tau ...
617! **************************************************************************************************
618 SUBROUTINE qs_fgxc_create(ks_env, rho0_struct, rho1_struct, xc_section, accuracy, is_triplet, &
619 fxc_rho, fxc_tau, gxc_rho, gxc_tau)
620
621 TYPE(qs_ks_env_type), POINTER :: ks_env
622 TYPE(qs_rho_type), POINTER :: rho0_struct, rho1_struct
623 TYPE(section_vals_type), POINTER :: xc_section
624 INTEGER, INTENT(IN) :: accuracy
625 LOGICAL, INTENT(IN) :: is_triplet
626 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho, fxc_tau, gxc_rho, gxc_tau
627
628 CHARACTER(len=*), PARAMETER :: routinen = 'qs_fgxc_create'
629 REAL(kind=dp), PARAMETER :: epsrho = 5.e-4_dp
630
631 INTEGER :: handle, ispin, istep, nspins, nstep
632 REAL(kind=dp) :: alpha, beta, exc, oeps1, oeps2
633 REAL(kind=dp), DIMENSION(-4:4) :: ak, bl
634 TYPE(dft_control_type), POINTER :: dft_control
635 TYPE(pw_env_type), POINTER :: pw_env
636 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
637 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_tau_rspace, vxc00
638 TYPE(qs_rho_type), POINTER :: rhoin
639
640 CALL timeset(routinen, handle)
641
642 cpassert(.NOT. ASSOCIATED(fxc_rho))
643 cpassert(.NOT. ASSOCIATED(fxc_tau))
644 cpassert(.NOT. ASSOCIATED(gxc_rho))
645 cpassert(.NOT. ASSOCIATED(gxc_tau))
646 cpassert(ASSOCIATED(rho0_struct))
647 cpassert(ASSOCIATED(rho1_struct))
648
649 ak = 0.0_dp
650 bl = 0.0_dp
651 SELECT CASE (accuracy)
652 CASE (:4)
653 nstep = 2
654 ak(-2:2) = (/1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp/)/12.0_dp
655 bl(-2:2) = (/-1.0_dp, 16.0_dp, -30.0_dp, 16.0_dp, -1.0_dp/)/12.0_dp
656 CASE (5:7)
657 nstep = 3
658 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
659 bl(-3:3) = (/2.0_dp, -27.0_dp, 270.0_dp, -490.0_dp, 270.0_dp, -27.0_dp, 2.0_dp/)/180.0_dp
660 CASE (8:)
661 nstep = 4
662 ak(-4:4) = (/1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
663 224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp/)/280.0_dp
664 bl(-4:4) = (/-1.0_dp, 128.0_dp/9.0_dp, -112.0_dp, 896.0_dp, -14350.0_dp/9.0_dp, &
665 896.0_dp, -112.0_dp, 128.0_dp/9.0_dp, -1.0_dp/)/560.0_dp
666 END SELECT
667
668 CALL get_ks_env(ks_env, dft_control=dft_control, pw_env=pw_env)
669 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
670
671 nspins = dft_control%nspins
672 exc = 0.0_dp
673
674 DO istep = -nstep, nstep
675
676 alpha = 1.0_dp
677 beta = real(istep, kind=dp)*epsrho
678 NULLIFY (rhoin)
679 ALLOCATE (rhoin)
680 CALL qs_rho_create(rhoin)
681 NULLIFY (vxc00, v_tau_rspace)
682 IF (is_triplet) THEN
683 cpassert(nspins == 1)
684 ! rhoin = (0.5 rho0, 0.5 rho0)
685 CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, 2)
686 ! rhoin = (0.5 rho0 + 0.5 rho1, 0.5 rho0)
687 CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, 0.5_dp*beta)
688 CALL qs_vxc_create(ks_env=ks_env, rho_struct=rhoin, xc_section=xc_section, &
689 vxc_rho=vxc00, vxc_tau=v_tau_rspace, exc=exc, just_energy=.false.)
690 CALL pw_axpy(vxc00(2), vxc00(1), -1.0_dp)
691 ELSE
692 CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, nspins)
693 CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, beta)
694 CALL qs_vxc_create(ks_env=ks_env, rho_struct=rhoin, xc_section=xc_section, &
695 vxc_rho=vxc00, vxc_tau=v_tau_rspace, exc=exc, just_energy=.false.)
696 END IF
697 CALL qs_rho_release(rhoin)
698 DEALLOCATE (rhoin)
699 IF (.NOT. ASSOCIATED(fxc_rho)) THEN
700 ALLOCATE (fxc_rho(nspins))
701 DO ispin = 1, nspins
702 CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
703 CALL pw_zero(fxc_rho(ispin))
704 END DO
705 END IF
706 IF (.NOT. ASSOCIATED(gxc_rho)) THEN
707 ALLOCATE (gxc_rho(nspins))
708 DO ispin = 1, nspins
709 CALL auxbas_pw_pool%create_pw(gxc_rho(ispin))
710 CALL pw_zero(gxc_rho(ispin))
711 END DO
712 END IF
713 cpassert(.NOT. ASSOCIATED(v_tau_rspace))
714 DO ispin = 1, nspins
715 IF (ak(istep) /= 0.0_dp) THEN
716 CALL pw_axpy(vxc00(ispin), fxc_rho(ispin), ak(istep))
717 END IF
718 IF (bl(istep) /= 0.0_dp) THEN
719 CALL pw_axpy(vxc00(ispin), gxc_rho(ispin), bl(istep))
720 END IF
721 END DO
722 DO ispin = 1, SIZE(vxc00)
723 CALL auxbas_pw_pool%give_back_pw(vxc00(ispin))
724 END DO
725 DEALLOCATE (vxc00)
726
727 END DO
728
729 oeps1 = 1.0_dp/epsrho
730 oeps2 = 1.0_dp/(epsrho**2)
731 DO ispin = 1, nspins
732 CALL pw_scale(fxc_rho(ispin), oeps1)
733 CALL pw_scale(gxc_rho(ispin), oeps2)
734 END DO
735
736 CALL timestop(handle)
737
738 END SUBROUTINE qs_fgxc_create
739
740! **************************************************************************************************
741!> \brief ...
742!> \param ks_env ...
743!> \param fxc_rho ...
744!> \param fxc_tau ...
745!> \param gxc_rho ...
746!> \param gxc_tau ...
747! **************************************************************************************************
748 SUBROUTINE qs_fgxc_release(ks_env, fxc_rho, fxc_tau, gxc_rho, gxc_tau)
749
750 TYPE(qs_ks_env_type), POINTER :: ks_env
751 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: fxc_rho, fxc_tau, gxc_rho, gxc_tau
752
753 INTEGER :: ispin
754 TYPE(pw_env_type), POINTER :: pw_env
755 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
756
757 CALL get_ks_env(ks_env, pw_env=pw_env)
758 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
759
760 IF (ASSOCIATED(fxc_rho)) THEN
761 DO ispin = 1, SIZE(fxc_rho)
762 CALL auxbas_pw_pool%give_back_pw(fxc_rho(ispin))
763 END DO
764 DEALLOCATE (fxc_rho)
765 END IF
766 IF (ASSOCIATED(fxc_tau)) THEN
767 DO ispin = 1, SIZE(fxc_tau)
768 CALL auxbas_pw_pool%give_back_pw(fxc_tau(ispin))
769 END DO
770 DEALLOCATE (fxc_tau)
771 END IF
772 IF (ASSOCIATED(gxc_rho)) THEN
773 DO ispin = 1, SIZE(gxc_rho)
774 CALL auxbas_pw_pool%give_back_pw(gxc_rho(ispin))
775 END DO
776 DEALLOCATE (gxc_rho)
777 END IF
778 IF (ASSOCIATED(gxc_tau)) THEN
779 DO ispin = 1, SIZE(gxc_tau)
780 CALL auxbas_pw_pool%give_back_pw(gxc_tau(ispin))
781 END DO
782 DEALLOCATE (gxc_tau)
783 END IF
784
785 END SUBROUTINE qs_fgxc_release
786
787END MODULE qs_fxc
static GRID_HOST_DEVICE double fac(const int i)
Factorial function, e.g. fac(5) = 5! = 120.
Definition grid_common.h:51
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
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
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
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
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
https://en.wikipedia.org/wiki/Finite_difference_coefficient
Definition qs_fxc.F:27
subroutine, public qs_fgxc_create(ks_env, rho0_struct, rho1_struct, xc_section, accuracy, is_triplet, fxc_rho, fxc_tau, gxc_rho, gxc_tau)
...
Definition qs_fxc.F:620
subroutine, public qs_fgxc_gdiff(ks_env, rho0_struct, rho1_struct, xc_section, accuracy, epsrho, is_triplet, fxc_rho, fxc_tau, gxc_rho, gxc_tau, spinflip)
...
Definition qs_fxc.F:455
subroutine, public qs_fgxc_release(ks_env, fxc_rho, fxc_tau, gxc_rho, gxc_tau)
...
Definition qs_fxc.F:749
subroutine, public qs_fxc_fdiff(ks_env, rho0_struct, rho1_struct, xc_section, accuracy, is_triplet, fxc_rho, fxc_tau)
...
Definition qs_fxc.F:161
subroutine, public qs_fgxc_analytic(rho0_struct, rho1_struct, xc_section, pw_pool, fxc_rho, fxc_tau, gxc_rho, gxc_tau, spinflip)
Calculates the values at the grid points in real space (r_i), of the second and third functional deri...
Definition qs_fxc.F:302
subroutine, public qs_fxc_analytic(rho0, rho1_r, tau1_r, xc_section, auxbas_pw_pool, is_triplet, v_xc, v_xc_tau, spinflip)
...
Definition qs_fxc.F:94
subroutine, public get_ks_env(ks_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, complex_ks, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, kinetic, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_ks_im_kp, rho, rho_xc, vppl, rho_core, rho_nlcc, rho_nlcc_g, vee, neighbor_list_id, sab_orb, sab_all, sac_ae, sac_ppl, sac_lri, sap_ppnl, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_vdw, sab_scp, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, task_list, task_list_soft, kpoints, do_kpoints, atomic_kind_set, qs_kind_set, cell, cell_ref, use_ref_cell, particle_set, energy, force, local_particles, local_molecules, molecule_kind_set, molecule_set, subsys, cp_subsys, virial, results, atprop, nkind, natom, dft_control, dbcsr_dist, distribution_2d, pw_env, para_env, blacs_env, nelectron_total, nelectron_spin)
...
methods of the rho structure (defined in qs_rho_types)
subroutine, public qs_rho_scale_and_add_b(rhoa, rhob, alpha, beta)
rhoa(2) = alpha*rhoa(2)+beta*rhob(1)
subroutine, public qs_rho_copy(rho_input, rho_output, auxbas_pw_pool, mspin)
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
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)
calculates and allocates the xc potential, already reducing it to the dependence on rho and the one o...
Definition qs_vxc.F:98
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_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:2650
subroutine, public xc_prep_3rd_deriv(deriv_set, rho_set, rho_r, pw_pool, xc_section, tau_r, do_sf)
Prepare deriv_set for the calculation of the 3rd derivatives of the density functional....
Definition xc.F:6187
subroutine, public xc_calc_2nd_deriv(v_xc, v_xc_tau, deriv_set, rho_set, rho1_r, rho1_g, tau1_r, pw_pool, xc_section, gapw, vxg, do_excitations, do_sf, do_triplet, compute_virial, virial_xc)
Caller routine to calculate the second order potential in the direction of rho1_r.
Definition xc.F:1532
subroutine, public xc_calc_3rd_deriv_analytical(v_xc, v_xc_tau, deriv_set, rho_set, rho1_set, pw_pool, xc_section, spinflip)
Calculates the third functional derivative of the exchange-correlation functional,...
Definition xc.F:5328
subroutine, public xc_prep_2nd_deriv(deriv_set, rho_set, rho_r, pw_pool, xc_section, tau_r)
Prepare objects for the calculation of the 2nd derivatives of the density functional....
Definition xc.F:6131
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