(git:ed6f26b)
Loading...
Searching...
No Matches
xc_atom.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! **************************************************************************************************
9MODULE xc_atom
10
15 USE kinds, ONLY: dp
17 USE pw_types, ONLY: pw_r3d_rs_type
18 USE xc, ONLY: divide_by_norm_drho,&
20 USE xc_derivative_desc, ONLY: &
31#include "../base/base_uses.f90"
32
33 IMPLICIT NONE
34
35 PRIVATE
36
37 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xc_atom'
38
40
41CONTAINS
42
43! **************************************************************************************************
44!> \brief ...
45!> \param xc_fun_section ...
46!> \param rho_set ...
47!> \param deriv_set ...
48!> \param deriv_order ...
49!> \param needs ...
50!> \param w ...
51!> \param lsd ...
52!> \param na ...
53!> \param nr ...
54!> \param exc ...
55!> \param vxc ...
56!> \param vxg ...
57!> \param vtau ...
58!> \param energy_only ...
59!> \param epr_xc ...
60!> \param adiabatic_rescale_factor ...
61! **************************************************************************************************
62 SUBROUTINE vxc_of_r_new(xc_fun_section, rho_set, deriv_set, deriv_order, needs, w, &
63 lsd, na, nr, exc, vxc, vxg, vtau, &
64 energy_only, epr_xc, adiabatic_rescale_factor)
65
66! This routine updates rho_set by giving to it the rho and drho that are needed.
67! Since for the local densities rho1_h and rho1_s local grids are used it is not possible
68! to call xc_rho_set_update.
69! As input of this routine one gets rho and drho on a one dimensional grid.
70! The grid is the angular grid corresponding to a given point ir_pnt on the radial grid.
71! The derivatives are calculated on this one dimensional grid, the results are stored in
72! exc, vxc(1:na,ir_pnt,ispin), vxg(1:na,ir_pnt,ispin), vxg_cross(1:na,ir_pnt,ispin)
73! Afterwords the arrays containing the derivatives are put to zero so that the routine
74! can safely be called for the next radial point ir_pnt
75
76 TYPE(section_vals_type), POINTER :: xc_fun_section
77 TYPE(xc_rho_set_type), INTENT(IN) :: rho_set
78 TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set
79 INTEGER, INTENT(in) :: deriv_order
80 TYPE(xc_rho_cflags_type), INTENT(in) :: needs
81 REAL(dp), DIMENSION(:, :), POINTER :: w
82 LOGICAL, INTENT(IN) :: lsd
83 INTEGER, INTENT(in) :: na, nr
84 REAL(dp) :: exc
85 REAL(dp), DIMENSION(:, :, :), POINTER :: vxc
86 REAL(dp), DIMENSION(:, :, :, :), POINTER :: vxg
87 REAL(dp), DIMENSION(:, :, :), POINTER :: vtau
88 LOGICAL, INTENT(IN), OPTIONAL :: energy_only, epr_xc
89 REAL(dp), INTENT(IN), OPTIONAL :: adiabatic_rescale_factor
90
91 CHARACTER(LEN=*), PARAMETER :: routinen = 'vxc_of_r_new'
92
93 INTEGER :: handle, ia, idir, ir, my_deriv_order
94 LOGICAL :: gradient_f, my_epr_xc, my_only_energy
95 REAL(dp) :: my_adiabatic_rescale_factor
96 REAL(dp), DIMENSION(:, :, :), POINTER :: deriv_data
97 REAL(kind=dp) :: drho_cutoff
98 TYPE(xc_derivative_type), POINTER :: deriv_att
99
100 CALL timeset(routinen, handle)
101 my_only_energy = .false.
102 IF (PRESENT(energy_only)) my_only_energy = energy_only
103
104 IF (PRESENT(adiabatic_rescale_factor)) THEN
105 my_adiabatic_rescale_factor = adiabatic_rescale_factor
106 ELSE
107 my_adiabatic_rescale_factor = 1.0_dp
108 END IF
109
110 ! needed for the epr routines
111 my_epr_xc = .false.
112 IF (PRESENT(epr_xc)) my_epr_xc = epr_xc
113 my_deriv_order = deriv_order
114 IF (my_epr_xc) my_deriv_order = 2
115
116 gradient_f = (needs%drho_spin .OR. needs%norm_drho_spin .OR. &
117 needs%drho .OR. needs%norm_drho)
118
119! Calculate the derivatives
120 CALL xc_functionals_eval(xc_fun_section, &
121 lsd=lsd, &
122 rho_set=rho_set, &
123 deriv_set=deriv_set, &
124 deriv_order=my_deriv_order)
125
126 CALL xc_rho_set_get(rho_set, drho_cutoff=drho_cutoff)
127
128 NULLIFY (deriv_data)
129
130 IF (my_epr_xc) THEN
131 ! nabla v_xc (using the vxg arrays)
132 ! there's no point doing this when lsd = false
133 IF (lsd) THEN
134 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa])
135 IF (ASSOCIATED(deriv_att)) THEN
136 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
137 DO ir = 1, nr
138 DO ia = 1, na
139 DO idir = 1, 3
140 vxg(idir, ia, ir, 1) = rho_set%drhoa(idir)%array(ia, ir, 1)* &
141 deriv_data(ia, ir, 1)
142 END DO !idir
143 END DO !ia
144 END DO !ir
145 NULLIFY (deriv_data)
146 END IF
147 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob])
148 IF (ASSOCIATED(deriv_att)) THEN
149 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
150 DO ir = 1, nr
151 DO ia = 1, na
152 DO idir = 1, 3
153 vxg(idir, ia, ir, 2) = rho_set%drhob(idir)%array(ia, ir, 1)* &
154 deriv_data(ia, ir, 1)
155 END DO !idir
156 END DO !ia
157 END DO !ir
158 NULLIFY (deriv_data)
159 END IF
160 END IF
161 ! EXC energy ! is that needed for epr?
162 deriv_att => xc_dset_get_derivative(deriv_set, [INTEGER::])
163 exc = 0.0_dp
164 IF (ASSOCIATED(deriv_att)) THEN
165 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
166 DO ir = 1, nr
167 DO ia = 1, na
168 exc = exc + deriv_data(ia, ir, 1)*w(ia, ir)
169 END DO
170 END DO
171 NULLIFY (deriv_data)
172 END IF
173 ELSE
174! EXC energy
175 deriv_att => xc_dset_get_derivative(deriv_set, [INTEGER::])
176 exc = 0.0_dp
177 IF (ASSOCIATED(deriv_att)) THEN
178 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
179 DO ir = 1, nr
180 DO ia = 1, na
181 exc = exc + deriv_data(ia, ir, 1)*w(ia, ir)
182 END DO
183 END DO
184 NULLIFY (deriv_data)
185 END IF
186 ! Calculate the potential only if needed
187 IF (.NOT. my_only_energy) THEN
188! Derivative with respect to the density
189 IF (lsd) THEN
190 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa])
191 IF (ASSOCIATED(deriv_att)) THEN
192 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
193 vxc(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
194 NULLIFY (deriv_data)
195 END IF
196 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob])
197 IF (ASSOCIATED(deriv_att)) THEN
198 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
199 vxc(:, :, 2) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
200 NULLIFY (deriv_data)
201 END IF
202 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho])
203 IF (ASSOCIATED(deriv_att)) THEN
204 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
205 vxc(:, :, 1) = vxc(:, :, 1) + deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
206 vxc(:, :, 2) = vxc(:, :, 2) + deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
207 NULLIFY (deriv_data)
208 END IF
209 ELSE
210 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho])
211 IF (ASSOCIATED(deriv_att)) THEN
212 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
213 vxc(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
214 NULLIFY (deriv_data)
215 END IF
216 END IF ! lsd
217
218! Derivatives with respect to the gradient
219 IF (lsd) THEN
220 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa])
221 IF (ASSOCIATED(deriv_att)) THEN
222 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
223 DO ir = 1, nr
224 DO ia = 1, na
225 DO idir = 1, 3
226 IF (rho_set%norm_drhoa(ia, ir, 1) > drho_cutoff) THEN
227 vxg(idir, ia, ir, 1) = rho_set%drhoa(idir)%array(ia, ir, 1)* &
228 deriv_data(ia, ir, 1)*w(ia, ir)/ &
229 rho_set%norm_drhoa(ia, ir, 1)*my_adiabatic_rescale_factor
230 ELSE
231 vxg(idir, ia, ir, 1) = 0.0_dp
232 END IF
233 END DO
234 END DO
235 END DO
236 NULLIFY (deriv_data)
237 END IF
238 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob])
239 IF (ASSOCIATED(deriv_att)) THEN
240 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
241 DO ir = 1, nr
242 DO ia = 1, na
243 DO idir = 1, 3
244 IF (rho_set%norm_drhob(ia, ir, 1) > drho_cutoff) THEN
245 vxg(idir, ia, ir, 2) = rho_set%drhob(idir)%array(ia, ir, 1)* &
246 deriv_data(ia, ir, 1)*w(ia, ir)/ &
247 rho_set%norm_drhob(ia, ir, 1)*my_adiabatic_rescale_factor
248 ELSE
249 vxg(idir, ia, ir, 2) = 0.0_dp
250 END IF
251 END DO
252 END DO
253 END DO
254 NULLIFY (deriv_data)
255 END IF
256 ! Cross Terms
257 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
258 IF (ASSOCIATED(deriv_att)) THEN
259 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
260 DO ir = 1, nr
261 DO ia = 1, na
262 DO idir = 1, 3
263 IF (rho_set%norm_drho(ia, ir, 1) > drho_cutoff) THEN
264 vxg(idir, ia, ir, 1:2) = &
265 vxg(idir, ia, ir, 1:2) + ( &
266 rho_set%drhoa(idir)%array(ia, ir, 1) + &
267 rho_set%drhob(idir)%array(ia, ir, 1))* &
268 deriv_data(ia, ir, 1)*w(ia, ir)/rho_set%norm_drho(ia, ir, 1)* &
269 my_adiabatic_rescale_factor
270 END IF
271 END DO
272 END DO
273 END DO
274 NULLIFY (deriv_data)
275 END IF
276 ELSE
277 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
278 IF (ASSOCIATED(deriv_att)) THEN
279 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
280 DO ir = 1, nr
281 DO ia = 1, na
282 IF (rho_set%norm_drho(ia, ir, 1) > drho_cutoff) THEN
283 DO idir = 1, 3
284 vxg(idir, ia, ir, 1) = rho_set%drho(idir)%array(ia, ir, 1)* &
285 deriv_data(ia, ir, 1)*w(ia, ir)/ &
286 rho_set%norm_drho(ia, ir, 1)*my_adiabatic_rescale_factor
287 END DO
288 ELSE
289 vxg(1:3, ia, ir, 1) = 0.0_dp
290 END IF
291 END DO
292 END DO
293 NULLIFY (deriv_data)
294 END IF
295 END IF ! lsd
296! Derivative with respect to tau
297 IF (lsd) THEN
298 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a])
299 IF (ASSOCIATED(deriv_att)) THEN
300 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
301 vtau(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
302 NULLIFY (deriv_data)
303 END IF
304 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b])
305 IF (ASSOCIATED(deriv_att)) THEN
306 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
307 vtau(:, :, 2) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
308 NULLIFY (deriv_data)
309 END IF
310 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau])
311 IF (ASSOCIATED(deriv_att)) THEN
312 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
313 vtau(:, :, 1) = vtau(:, :, 1) + deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
314 vtau(:, :, 2) = vtau(:, :, 2) + deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
315 NULLIFY (deriv_data)
316 END IF
317 ELSE
318 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau])
319 IF (ASSOCIATED(deriv_att)) THEN
320 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
321 vtau(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
322 NULLIFY (deriv_data)
323 END IF
324 END IF ! lsd
325 END IF ! only_energy
326 END IF ! epr_xc
327
328 CALL timestop(handle)
329
330 END SUBROUTINE vxc_of_r_new
331
332! **************************************************************************************************
333!> \brief ...
334!> \param rho_set ...
335!> \param rho1_set ...
336!> \param xc_section ...
337!> \param deriv_set ...
338!> \param w ...
339!> \param vxc ...
340!> \param vxg ...
341!> \param do_triplet ...
342! **************************************************************************************************
343 SUBROUTINE xc_2nd_deriv_of_r(rho_set, rho1_set, xc_section, &
344 deriv_set, w, vxc, vxg, do_triplet)
345
346! As input of this routine one gets rho and drho on a one dimensional grid.
347! The grid is the angular grid corresponding to a given point ir on the radial grid.
348! The derivatives are calculated on this one dimensional grid, the results are stored in
349! vxc(1:na,ir,ispin), vxg(1:na,ir,ispin), vxg_cross(1:na,ir,ispin)
350! Afterwords the arrays containing the derivatives are put to zero so that the routine
351! can safely be called for the next radial point ir
352
353 TYPE(xc_rho_set_type), INTENT(IN) :: rho_set, rho1_set
354 TYPE(section_vals_type), POINTER :: xc_section
355 TYPE(xc_derivative_set_type), INTENT(INOUT) :: deriv_set
356 REAL(dp), DIMENSION(:, :), POINTER :: w
357 REAL(dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER :: vxc
358 REAL(dp), DIMENSION(:, :, :, :), POINTER :: vxg
359 LOGICAL, INTENT(IN), OPTIONAL :: do_triplet
360
361 CHARACTER(LEN=*), PARAMETER :: routinen = 'xc_2nd_deriv_of_r'
362
363 INTEGER :: handle, ispin, nspins
364 LOGICAL :: lsd
365 REAL(dp) :: drho_cutoff, my_fac_triplet
366 TYPE(cp_sll_xc_deriv_type), POINTER :: pos
367 TYPE(pw_pool_type), POINTER :: pw_pool
368 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: vxc_pw, vxc_tau_pw
369 TYPE(section_vals_type), POINTER :: xc_fun_section
370 TYPE(xc_derivative_type), POINTER :: deriv_att
371
372 CALL timeset(routinen, handle)
373
374 nspins = SIZE(vxc, 3)
375 lsd = (nspins == 2)
376 IF (ASSOCIATED(rho_set%rhoa)) THEN
377 lsd = .true.
378 END IF
379 my_fac_triplet = 1.0_dp
380 IF (PRESENT(do_triplet)) THEN
381 IF (do_triplet) my_fac_triplet = -1.0_dp
382 END IF
383
384 CALL xc_rho_set_get(rho_set, drho_cutoff=drho_cutoff)
385 xc_fun_section => section_vals_get_subs_vals(xc_section, &
386 "XC_FUNCTIONAL")
387
388 ! Calculate the derivatives
389 CALL xc_functionals_eval(xc_fun_section, &
390 lsd=lsd, &
391 rho_set=rho_set, &
392 deriv_set=deriv_set, &
393 deriv_order=2)
394
395 CALL divide_by_norm_drho(deriv_set, rho_set, lsd)
396
397 ! multiply by w
398 pos => deriv_set%derivs
399 DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
400 deriv_att%deriv_data(:, :, 1) = w(:, :)*deriv_att%deriv_data(:, :, 1)
401 END DO
402
403 NULLIFY (pw_pool)
404 ALLOCATE (vxc_pw(nspins))
405 DO ispin = 1, nspins
406 vxc_pw(ispin)%array => vxc(:, :, ispin:ispin)
407 END DO
408
409 NULLIFY (vxc_tau_pw)
410
411 CALL xc_calc_2nd_deriv_analytical(vxc_pw, vxc_tau_pw, deriv_set, rho_set, rho1_set, pw_pool, &
412 xc_section, gapw=.true., vxg=vxg, tddfpt_fac=my_fac_triplet)
413
414 DEALLOCATE (vxc_pw)
415
416 ! zero the derivative data for the next call
417 pos => deriv_set%derivs
418 DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
419 deriv_att%deriv_data = 0.0_dp
420 END DO
421
422 CALL timestop(handle)
423
424 END SUBROUTINE xc_2nd_deriv_of_r
425
426! **************************************************************************************************
427!> \brief ...
428!> \param rho_set ...
429!> \param needs ...
430!> \param nspins ...
431!> \param bo ...
432! **************************************************************************************************
433 SUBROUTINE xc_rho_set_atom_update(rho_set, needs, nspins, bo)
434
435! This routine allocates the storage arrays for rho and drho
436! In calculate_vxc_atom this is called once for each atomic_kind,
437! After the loop over all the atoms of the kind and over all the points
438! of the radial grid for each atom, rho_set is deallocated.
439! Within the same kind, at each new point on the radial grid, the rho_set
440! arrays rho and drho are overwritten.
441
442 TYPE(xc_rho_set_type), INTENT(INOUT) :: rho_set
443 TYPE(xc_rho_cflags_type), INTENT(IN) :: needs
444 INTEGER, INTENT(IN) :: nspins
445 INTEGER, DIMENSION(2, 3), INTENT(IN) :: bo
446
447 INTEGER :: idir
448
449 SELECT CASE (nspins)
450 CASE (1)
451! What is this for?
452 IF (needs%rho_1_3) THEN
453 NULLIFY (rho_set%rho_1_3)
454 ALLOCATE (rho_set%rho_1_3(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
455 rho_set%owns%rho_1_3 = .true.
456 rho_set%has%rho_1_3 = .false.
457 END IF
458! Allocate the storage space for the density
459 IF (needs%rho) THEN
460 NULLIFY (rho_set%rho)
461 ALLOCATE (rho_set%rho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
462 rho_set%owns%rho = .true.
463 rho_set%has%rho = .false.
464 END IF
465! Allocate the storage space for the norm of the gradient of the density
466 IF (needs%norm_drho) THEN
467 NULLIFY (rho_set%norm_drho)
468 ALLOCATE (rho_set%norm_drho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
469 rho_set%owns%norm_drho = .true.
470 rho_set%has%norm_drho = .false.
471 END IF
472! Allocate the storage space for the three components of the gradient of the density
473 IF (needs%drho) THEN
474 DO idir = 1, 3
475 NULLIFY (rho_set%drho(idir)%array)
476 ALLOCATE (rho_set%drho(idir)%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
477 END DO
478 rho_set%owns%drho = .true.
479 rho_set%has%drho = .false.
480 END IF
481 CASE (2)
482! Allocate the storage space for the total density
483 IF (needs%rho) THEN
484 ! this should never be the case unless you use LDA functionals with LSD
485 NULLIFY (rho_set%rho)
486 ALLOCATE (rho_set%rho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
487 rho_set%owns%rho = .true.
488 rho_set%has%rho = .false.
489 END IF
490! What is this for?
491 IF (needs%rho_1_3) THEN
492 NULLIFY (rho_set%rho_1_3)
493 ALLOCATE (rho_set%rho_1_3(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
494 rho_set%owns%rho_1_3 = .true.
495 rho_set%has%rho_1_3 = .false.
496 END IF
497! What is this for?
498 IF (needs%rho_spin_1_3) THEN
499 NULLIFY (rho_set%rhoa_1_3, rho_set%rhob_1_3)
500 ALLOCATE (rho_set%rhoa_1_3(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
501 ALLOCATE (rho_set%rhob_1_3(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
502 rho_set%owns%rho_spin_1_3 = .true.
503 rho_set%has%rho_spin_1_3 = .false.
504 END IF
505! Allocate the storage space for the spin densities rhoa and rhob
506 IF (needs%rho_spin) THEN
507 NULLIFY (rho_set%rhoa, rho_set%rhob)
508 ALLOCATE (rho_set%rhoa(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
509 ALLOCATE (rho_set%rhob(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
510 rho_set%owns%rho_spin = .true.
511 rho_set%has%rho_spin = .false.
512 END IF
513! Allocate the storage space for the norm of the gradient of the total density
514 IF (needs%norm_drho) THEN
515 NULLIFY (rho_set%norm_drho)
516 ALLOCATE (rho_set%norm_drho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
517 rho_set%owns%norm_drho = .true.
518 rho_set%has%norm_drho = .false.
519 END IF
520! Allocate the storage space for the norm of the gradient of rhoa and of rhob separatedly
521 IF (needs%norm_drho_spin) THEN
522 NULLIFY (rho_set%norm_drhoa, rho_set%norm_drhob)
523 ALLOCATE (rho_set%norm_drhoa(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
524 ALLOCATE (rho_set%norm_drhob(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
525 rho_set%owns%norm_drho_spin = .true.
526 rho_set%has%norm_drho_spin = .false.
527 END IF
528! Allocate the storage space for the components of the gradient for the total rho
529 IF (needs%drho) THEN
530 DO idir = 1, 3
531 NULLIFY (rho_set%drho(idir)%array)
532 ALLOCATE (rho_set%drho(idir)%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
533 END DO
534 rho_set%owns%drho = .true.
535 rho_set%has%drho = .false.
536 END IF
537! Allocate the storage space for the components of the gradient for rhoa and rhob
538 IF (needs%drho_spin) THEN
539 DO idir = 1, 3
540 NULLIFY (rho_set%drhoa(idir)%array, rho_set%drhob(idir)%array)
541 ALLOCATE (rho_set%drhoa(idir)%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
542 ALLOCATE (rho_set%drhob(idir)%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
543 END DO
544 rho_set%owns%drho_spin = .true.
545 rho_set%has%drho_spin = .false.
546 END IF
547!
548 END SELECT
549
550 ! tau part
551 IF (needs%tau) THEN
552 NULLIFY (rho_set%tau)
553 ALLOCATE (rho_set%tau(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
554 rho_set%owns%tau = .true.
555 END IF
556 IF (needs%tau_spin) THEN
557 NULLIFY (rho_set%tau_a, rho_set%tau_b)
558 ALLOCATE (rho_set%tau_a(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
559 ALLOCATE (rho_set%tau_b(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
560 rho_set%owns%tau_spin = .true.
561 rho_set%has%tau_spin = .false.
562 END IF
563
564 ! Laplace part
565 IF (needs%laplace_rho) THEN
566 NULLIFY (rho_set%laplace_rho)
567 ALLOCATE (rho_set%laplace_rho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
568 rho_set%owns%laplace_rho = .true.
569 END IF
570 IF (needs%laplace_rho_spin) THEN
571 NULLIFY (rho_set%laplace_rhoa)
572 NULLIFY (rho_set%laplace_rhob)
573 ALLOCATE (rho_set%laplace_rhoa(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
574 ALLOCATE (rho_set%laplace_rhob(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
575 rho_set%owns%laplace_rho_spin = .true.
576 rho_set%has%laplace_rho_spin = .true.
577 END IF
578
579 END SUBROUTINE xc_rho_set_atom_update
580
581! **************************************************************************************************
582!> \brief ...
583!> \param rho_set ...
584!> \param lsd ...
585!> \param nspins ...
586!> \param needs ...
587!> \param rho ...
588!> \param drho ...
589!> \param tau ...
590!> \param na ...
591!> \param ir ...
592! **************************************************************************************************
593 SUBROUTINE fill_rho_set(rho_set, lsd, nspins, needs, rho, drho, tau, na, ir)
594
595 TYPE(xc_rho_set_type), INTENT(INOUT) :: rho_set
596 LOGICAL, INTENT(IN) :: lsd
597 INTEGER, INTENT(IN) :: nspins
598 TYPE(xc_rho_cflags_type), INTENT(IN) :: needs
599 REAL(dp), DIMENSION(:, :, :), INTENT(IN) :: rho
600 REAL(dp), DIMENSION(:, :, :, :), INTENT(IN) :: drho
601 REAL(dp), DIMENSION(:, :, :), INTENT(IN) :: tau
602 INTEGER, INTENT(IN) :: na, ir
603
604 REAL(kind=dp), PARAMETER :: f13 = (1.0_dp/3.0_dp)
605
606 INTEGER :: ia, idir, my_nspins
607 LOGICAL :: gradient_f, tddft_split
608
609 my_nspins = nspins
610 tddft_split = .false.
611 IF (lsd .AND. nspins == 1) THEN
612 my_nspins = 2
613 tddft_split = .true.
614 END IF
615
616 ! some checks
617 IF (lsd) THEN
618 ELSE
619 cpassert(SIZE(rho, 3) == 1)
620 END IF
621 SELECT CASE (my_nspins)
622 CASE (1)
623 cpassert(.NOT. needs%rho_spin)
624 cpassert(.NOT. needs%drho_spin)
625 cpassert(.NOT. needs%norm_drho_spin)
626 cpassert(.NOT. needs%rho_spin_1_3)
627 CASE (2)
628 CASE default
629 cpabort("Unsupported number of spins")
630 END SELECT
631
632 gradient_f = (needs%drho_spin .OR. needs%norm_drho_spin .OR. &
633 needs%drho .OR. needs%norm_drho)
634
635 SELECT CASE (my_nspins)
636 CASE (1)
637 ! Give rho to 1/3
638 IF (needs%rho_1_3) THEN
639 DO ia = 1, na
640 rho_set%rho_1_3(ia, ir, 1) = max(rho(ia, ir, 1), 0.0_dp)**f13
641 END DO
642 rho_set%owns%rho_1_3 = .true.
643 rho_set%has%rho_1_3 = .true.
644 END IF
645 ! Give the density
646 IF (needs%rho) THEN
647 DO ia = 1, na
648 rho_set%rho(ia, ir, 1) = rho(ia, ir, 1)
649 END DO
650 rho_set%owns%rho = .true.
651 rho_set%has%rho = .true.
652 END IF
653 ! Give the norm of the gradient of the density
654 IF (needs%norm_drho) THEN
655 DO ia = 1, na
656 rho_set%norm_drho(ia, ir, 1) = drho(4, ia, ir, 1)
657 END DO
658 rho_set%owns%norm_drho = .true.
659 rho_set%has%norm_drho = .true.
660 END IF
661 ! Give the three components of the gradient of the density
662 IF (needs%drho) THEN
663 DO idir = 1, 3
664 DO ia = 1, na
665 rho_set%drho(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1)
666 END DO
667 END DO
668 rho_set%owns%drho = .true.
669 rho_set%has%drho = .true.
670 END IF
671 CASE (2)
672 ! Give the total density
673 IF (needs%rho) THEN
674 ! this should never be the case unless you use LDA functionals with LSD
675 IF (.NOT. tddft_split) THEN
676 DO ia = 1, na
677 rho_set%rho(ia, ir, 1) = rho(ia, ir, 1) + rho(ia, ir, 2)
678 END DO
679 ELSE
680 DO ia = 1, na
681 rho_set%rho(ia, ir, 1) = rho(ia, ir, 1)
682 END DO
683 END IF
684 rho_set%owns%rho = .true.
685 rho_set%has%rho = .true.
686 END IF
687 ! Give the total density to 1/3
688 IF (needs%rho_1_3) THEN
689 IF (.NOT. tddft_split) THEN
690 DO ia = 1, na
691 rho_set%rho_1_3(ia, ir, 1) = max(rho(ia, ir, 1) + rho(ia, ir, 2), 0.0_dp)**f13
692 END DO
693 ELSE
694 DO ia = 1, na
695 rho_set%rho_1_3(ia, ir, 1) = max(rho(ia, ir, 1), 0.0_dp)**f13
696 END DO
697 END IF
698 rho_set%owns%rho_1_3 = .true.
699 rho_set%has%rho_1_3 = .true.
700 END IF
701 ! Give the spin densities to 1/3
702 IF (needs%rho_spin_1_3) THEN
703 IF (.NOT. tddft_split) THEN
704 DO ia = 1, na
705 rho_set%rhoa_1_3(ia, ir, 1) = max(rho(ia, ir, 1), 0.0_dp)**f13
706 rho_set%rhob_1_3(ia, ir, 1) = max(rho(ia, ir, 2), 0.0_dp)**f13
707 END DO
708 ELSE
709 DO ia = 1, na
710 rho_set%rhoa_1_3(ia, ir, 1) = max(0.5_dp*rho(ia, ir, 1), 0.0_dp)**f13
711 rho_set%rhob_1_3(ia, ir, 1) = rho_set%rhoa_1_3(ia, ir, 1)
712 END DO
713 END IF
714 rho_set%owns%rho_spin_1_3 = .true.
715 rho_set%has%rho_spin_1_3 = .true.
716 END IF
717 ! Give the spin densities rhoa and rhob
718 IF (needs%rho_spin) THEN
719 IF (.NOT. tddft_split) THEN
720 DO ia = 1, na
721 rho_set%rhoa(ia, ir, 1) = rho(ia, ir, 1)
722 rho_set%rhob(ia, ir, 1) = rho(ia, ir, 2)
723 END DO
724 ELSE
725 DO ia = 1, na
726 rho_set%rhoa(ia, ir, 1) = 0.5_dp*rho(ia, ir, 1)
727 rho_set%rhob(ia, ir, 1) = rho_set%rhoa(ia, ir, 1)
728 END DO
729 END IF
730 rho_set%owns%rho_spin = .true.
731 rho_set%has%rho_spin = .true.
732 END IF
733 ! Give the norm of the gradient of the total density
734 IF (needs%norm_drho) THEN
735 IF (.NOT. tddft_split) THEN
736 DO ia = 1, na
737 rho_set%norm_drho(ia, ir, 1) = sqrt( &
738 (drho(1, ia, ir, 1) + drho(1, ia, ir, 2))**2 + &
739 (drho(2, ia, ir, 1) + drho(2, ia, ir, 2))**2 + &
740 (drho(3, ia, ir, 1) + drho(3, ia, ir, 2))**2)
741 END DO
742 ELSE
743 DO ia = 1, na
744 rho_set%norm_drho(ia, ir, 1) = drho(4, ia, ir, 1)
745 END DO
746 END IF
747 rho_set%owns%norm_drho = .true.
748 rho_set%has%norm_drho = .true.
749 END IF
750 ! Give the norm of the gradient of rhoa and of rhob separatedly
751 IF (needs%norm_drho_spin) THEN
752 IF (.NOT. tddft_split) THEN
753 DO ia = 1, na
754 rho_set%norm_drhoa(ia, ir, 1) = drho(4, ia, ir, 1)
755 rho_set%norm_drhob(ia, ir, 1) = drho(4, ia, ir, 2)
756 END DO
757 ELSE
758 DO ia = 1, na
759 rho_set%norm_drhoa(ia, ir, 1) = 0.5_dp*drho(4, ia, ir, 1)
760 rho_set%norm_drhob(ia, ir, 1) = rho_set%norm_drhoa(ia, ir, 1)
761 END DO
762 END IF
763 rho_set%owns%norm_drho_spin = .true.
764 rho_set%has%norm_drho_spin = .true.
765 END IF
766 ! Give the components of the gradient for the total rho
767 IF (needs%drho) THEN
768 IF (.NOT. tddft_split) THEN
769 DO idir = 1, 3
770 DO ia = 1, na
771 rho_set%drho(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1) + drho(idir, ia, ir, 2)
772 END DO
773 END DO
774 ELSE
775 DO idir = 1, 3
776 DO ia = 1, na
777 rho_set%drho(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1)
778 END DO
779 END DO
780 END IF
781 rho_set%owns%drho = .true.
782 rho_set%has%drho = .true.
783 END IF
784 ! Give the components of the gradient for rhoa and rhob
785 IF (needs%drho_spin) THEN
786 IF (.NOT. tddft_split) THEN
787 DO idir = 1, 3
788 DO ia = 1, na
789 rho_set%drhoa(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1)
790 rho_set%drhob(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 2)
791 END DO
792 END DO
793 ELSE
794 DO idir = 1, 3
795 DO ia = 1, na
796 rho_set%drhoa(idir)%array(ia, ir, 1) = 0.5_dp*drho(idir, ia, ir, 1)
797 rho_set%drhob(idir)%array(ia, ir, 1) = rho_set%drhoa(idir)%array(ia, ir, 1)
798 END DO
799 END DO
800 END IF
801 rho_set%owns%drho_spin = .true.
802 rho_set%has%drho_spin = .true.
803 END IF
804 !
805 END SELECT
806
807 ! tau part
808 IF (needs%tau .OR. needs%tau_spin) THEN
809 cpassert(SIZE(tau, 3) == my_nspins)
810 END IF
811 IF (needs%tau) THEN
812 IF (my_nspins == 2) THEN
813 DO ia = 1, na
814 rho_set%tau(ia, ir, 1) = tau(ia, ir, 1) + tau(ia, ir, 2)
815 END DO
816 rho_set%owns%tau = .true.
817 rho_set%has%tau = .true.
818 ELSE
819 DO ia = 1, na
820 rho_set%tau(ia, ir, 1) = tau(ia, ir, 1)
821 END DO
822 rho_set%owns%tau = .true.
823 rho_set%has%tau = .true.
824 END IF
825 END IF
826 IF (needs%tau_spin) THEN
827 DO ia = 1, na
828 rho_set%tau_a(ia, ir, 1) = tau(ia, ir, 1)
829 rho_set%tau_b(ia, ir, 1) = tau(ia, ir, 2)
830 END DO
831 rho_set%owns%tau_spin = .true.
832 rho_set%has%tau_spin = .true.
833 END IF
834
835 END SUBROUTINE fill_rho_set
836
837END MODULE xc_atom
logical function, public cp_sll_xc_deriv_next(iterator, el_att)
returns true if the actual element is valid (i.e. iterator ont at end) moves the iterator to the next...
objects that represent the structure of input sections and the data contained in an input section
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
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
subroutine, public xc_rho_set_atom_update(rho_set, needs, nspins, bo)
...
Definition xc_atom.F:434
subroutine, public fill_rho_set(rho_set, lsd, nspins, needs, rho, drho, tau, na, ir)
...
Definition xc_atom.F:594
subroutine, public xc_2nd_deriv_of_r(rho_set, rho1_set, xc_section, deriv_set, w, vxc, vxg, do_triplet)
...
Definition xc_atom.F:345
subroutine, public vxc_of_r_new(xc_fun_section, rho_set, deriv_set, deriv_order, needs, w, lsd, na, nr, exc, vxc, vxg, vtau, energy_only, epr_xc, adiabatic_rescale_factor)
...
Definition xc_atom.F:65
Module with functions to handle derivative descriptors. derivative description are strings have the f...
integer, parameter, public deriv_norm_drho
integer, parameter, public deriv_norm_drhoa
integer, parameter, public deriv_rhob
integer, parameter, public deriv_rhoa
integer, parameter, public deriv_tau
integer, parameter, public deriv_tau_b
integer, parameter, public deriv_tau_a
integer, parameter, public deriv_rho
integer, parameter, public deriv_norm_drhob
represent a group ofunctional derivatives
type(xc_derivative_type) function, pointer, public xc_dset_get_derivative(derivative_set, description, allocate_deriv)
returns the requested xc_derivative
Provides types for the management of the xc-functionals and their derivatives.
subroutine, public xc_derivative_get(deriv, split_desc, order, deriv_data, accept_null_data)
returns various information on the given derivative
subroutine, public xc_functionals_eval(functionals, lsd, rho_set, deriv_set, deriv_order)
...
contains the structure
contains the structure
subroutine, public xc_rho_set_get(rho_set, can_return_null, rho, drho, norm_drho, rhoa, rhob, norm_drhoa, norm_drhob, rho_1_3, rhoa_1_3, rhob_1_3, laplace_rho, laplace_rhoa, laplace_rhob, drhoa, drhob, rho_cutoff, drho_cutoff, tau_cutoff, tau, tau_a, tau_b, local_bounds)
returns the various attributes of rho_set
Exchange and Correlation functional calculations.
Definition xc.F:17
subroutine, public divide_by_norm_drho(deriv_set, rho_set, lsd)
divides derivatives from deriv_set by norm_drho
Definition xc.F:5421
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)
Calculates the second derivative of E_xc at rho in the direction rho1 (if you see the second derivati...
Definition xc.F:2640
represent a single linked list that stores pointers to the elements
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
A derivative set contains the different derivatives of a xc-functional in form of a linked list.
represent a derivative of a functional
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