(git:50ddb19)
Loading...
Searching...
No Matches
xc.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Exchange and Correlation functional calculations
10!> \par History
11!> (13-Feb-2001) JGH, based on earlier version of apsi
12!> 02.2003 Many many changes [fawzi]
13!> 03.2004 new xc interface [fawzi]
14!> 04.2004 kinetic functionals [fawzi]
15!> \author fawzi
16! **************************************************************************************************
17MODULE xc
33 USE kinds, ONLY: default_path_length, &
34 dp
37 USE pw_methods, ONLY: pw_axpy, &
38 pw_copy, &
40 pw_derive, &
42 pw_scale, &
45 USE pw_pool_types, ONLY: &
47 USE pw_types, ONLY: &
49 USE xc_derivative_desc, ONLY: &
70#include "../base/base_uses.f90"
71
72 IMPLICIT NONE
73 PRIVATE
78 PUBLIC :: calc_xc_density
79
80 LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .true.
81 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xc'
82 CHARACTER(len=*), PARAMETER, PRIVATE :: gauxc_high_deriv_message = &
83 "Response and kernel properties with GauXC/Skala require higher XC derivatives, "// &
84 "which are not implemented. Use a native CP2K XC functional or disable the coupled XC kernel."
85
86CONTAINS
87
88! **************************************************************************************************
89!> \brief ...
90!> \param xc_fun_section ...
91!> \param lsd ...
92!> \return ...
93! **************************************************************************************************
94 FUNCTION xc_uses_kinetic_energy_density(xc_fun_section, lsd) RESULT(res)
95 TYPE(section_vals_type), POINTER, INTENT(IN) :: xc_fun_section
96 LOGICAL, INTENT(IN) :: lsd
97 LOGICAL :: res
98
99 TYPE(xc_rho_cflags_type) :: needs
100
101 needs = xc_functionals_get_needs(xc_fun_section, &
102 lsd=lsd, &
103 calc_potential=.false.)
104 res = (needs%tau_spin .OR. needs%tau)
105
107
108! **************************************************************************************************
109!> \brief ...
110!> \param xc_fun_section ...
111!> \param lsd ...
112!> \return ...
113! **************************************************************************************************
114 FUNCTION xc_uses_norm_drho(xc_fun_section, lsd) RESULT(res)
115 TYPE(section_vals_type), POINTER, INTENT(IN) :: xc_fun_section
116 LOGICAL, INTENT(IN) :: lsd
117 LOGICAL :: res
118
119 TYPE(xc_rho_cflags_type) :: needs
120
121 needs = xc_functionals_get_needs(xc_fun_section, &
122 lsd=lsd, &
123 calc_potential=.false.)
124 res = (needs%norm_drho .OR. needs%norm_drho_spin)
125
126 END FUNCTION xc_uses_norm_drho
127
128! **************************************************************************************************
129!> \brief creates a xc_rho_set and a derivative set containing the derivatives
130!> of the functionals with the given deriv_order.
131!> \param rho_set will contain the rho set
132!> \param deriv_set will contain the derivatives
133!> \param deriv_order the order of the requested derivatives. If positive
134!> 0:deriv_order are calculated, if negative only -deriv_order is
135!> guaranteed to be valid. Orders not requested might be present,
136!> but might contain garbage.
137!> \param rho_r the value of the density in the real space
138!> \param rho_g value of the density in the g space (can be null, used only
139!> without smoothing of rho or deriv)
140!> \param tau value of the kinetic density tau on the grid (can be null,
141!> used only with meta functionals)
142!> \param xc_section the section describing the functional to use
143!> \param pw_pool the pool for the grids
144!> \param weights integration weights
145!> \param calc_potential if the basic components of the arguments
146!> should be kept in rho set (a basic component is for example drho
147!> when with lda a functional needs norm_drho)
148!> \author fawzi
149!> \note
150!> if any of the functionals is gradient corrected the full gradient is
151!> added to the rho set
152! **************************************************************************************************
153 SUBROUTINE xc_rho_set_and_dset_create(rho_set, deriv_set, deriv_order, &
154 rho_r, rho_g, tau, xc_section, pw_pool, &
155 weights, calc_potential)
156
157 TYPE(xc_rho_set_type) :: rho_set
158 TYPE(xc_derivative_set_type) :: deriv_set
159 INTEGER, INTENT(in) :: deriv_order
160 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r, tau
161 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
162 TYPE(section_vals_type), POINTER :: xc_section
163 TYPE(pw_pool_type), POINTER :: pw_pool
164 TYPE(pw_r3d_rs_type), POINTER :: weights
165 LOGICAL, INTENT(in) :: calc_potential
166
167 CHARACTER(len=*), PARAMETER :: routinen = 'xc_rho_set_and_dset_create'
168
169 INTEGER :: handle, nspins
170 LOGICAL :: lsd
171 TYPE(xc_derivative_type), POINTER :: deriv_att
172 TYPE(cp_sll_xc_deriv_type), POINTER :: pos
173 TYPE(section_vals_type), POINTER :: xc_fun_sections
174
175 CALL timeset(routinen, handle)
176
177 mark_used(weights)
178
179 cpassert(ASSOCIATED(pw_pool))
180
181 nspins = SIZE(rho_r)
182 lsd = (nspins /= 1)
183
184 xc_fun_sections => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
185
186 ! Create deriv_set object
187 CALL xc_dset_create(deriv_set, pw_pool)
188
189 ! Create objects for density related stuff
190 CALL xc_rho_set_create(rho_set, &
191 rho_r(1)%pw_grid%bounds_local, &
192 rho_cutoff=section_get_rval(xc_section, "density_cutoff"), &
193 drho_cutoff=section_get_rval(xc_section, "gradient_cutoff"), &
194 tau_cutoff=section_get_rval(xc_section, "tau_cutoff"))
195
196 ! Calculate density stuff, for example the gradient of rho, according to the functional needs
197 CALL xc_rho_set_update(rho_set, rho_r, rho_g, tau, &
198 xc_functionals_get_needs(xc_fun_sections, lsd, calc_potential), &
199 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
200 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
201 pw_pool)
202
203 ! Calculate values of the functional on the grid
204 CALL xc_functionals_eval(xc_fun_sections, &
205 lsd=lsd, &
206 rho_set=rho_set, &
207 deriv_set=deriv_set, &
208 deriv_order=deriv_order)
209
210 ! apply weights
211 IF (ASSOCIATED(weights)) THEN
212 pos => deriv_set%derivs
213 DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
214 deriv_att%deriv_data(:, :, :) = weights%array(:, :, :)*deriv_att%deriv_data(:, :, :)
215 END DO
216 END IF
217
218 CALL divide_by_norm_drho(deriv_set, rho_set, lsd)
219
220 CALL timestop(handle)
221
222 END SUBROUTINE xc_rho_set_and_dset_create
223
224! **************************************************************************************************
225!> \brief smooths the cutoff on rho with a function smoothderiv_rho that is 0
226!> for rho<rho_cutoff and 1 for rho>rho_cutoff*rho_smooth_cutoff_range:
227!> E= integral e_0*smoothderiv_rho => dE/d...= de/d... * smooth,
228!> dE/drho = de/drho * smooth + e_0 * dsmooth/drho
229!> \param pot the potential to smooth
230!> \param rho , rhoa,rhob: the value of the density (used to apply the cutoff)
231!> \param rhoa ...
232!> \param rhob ...
233!> \param rho_cutoff the value at whch the cutoff function must go to 0
234!> \param rho_smooth_cutoff_range range of the smoothing
235!> \param e_0 value of e_0, if given it is assumed that pot is the derivative
236!> wrt. to rho, and needs the dsmooth*e_0 contribution
237!> \param e_0_scale_factor ...
238!> \author Fawzi Mohamed
239! **************************************************************************************************
240 SUBROUTINE smooth_cutoff(pot, rho, rhoa, rhob, rho_cutoff, &
241 rho_smooth_cutoff_range, e_0, e_0_scale_factor)
242 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN), &
243 POINTER :: pot, rho, rhoa, rhob
244 REAL(kind=dp), INTENT(in) :: rho_cutoff, rho_smooth_cutoff_range
245 REAL(kind=dp), DIMENSION(:, :, :), OPTIONAL, &
246 POINTER :: e_0
247 REAL(kind=dp), INTENT(in), OPTIONAL :: e_0_scale_factor
248
249 INTEGER :: i, j, k
250 INTEGER, DIMENSION(2, 3) :: bo
251 REAL(kind=dp) :: my_e_0_scale_factor, my_rho, my_rho_n, my_rho_n2, rho_smooth_cutoff, &
252 rho_smooth_cutoff_2, rho_smooth_cutoff_range_2
253
254 cpassert(ASSOCIATED(pot))
255 bo(1, :) = lbound(pot)
256 bo(2, :) = ubound(pot)
257 my_e_0_scale_factor = 1.0_dp
258 IF (PRESENT(e_0_scale_factor)) my_e_0_scale_factor = e_0_scale_factor
259 rho_smooth_cutoff = rho_cutoff*rho_smooth_cutoff_range
260 rho_smooth_cutoff_2 = (rho_cutoff + rho_smooth_cutoff)/2
261 rho_smooth_cutoff_range_2 = rho_smooth_cutoff_2 - rho_cutoff
262
263 IF (rho_smooth_cutoff_range > 0.0_dp) THEN
264 IF (PRESENT(e_0)) THEN
265 cpassert(ASSOCIATED(e_0))
266 IF (ASSOCIATED(rho)) THEN
267!$OMP PARALLEL DO DEFAULT(NONE) &
268!$OMP SHARED(bo,e_0,pot,rho,rho_cutoff,rho_smooth_cutoff,rho_smooth_cutoff_2, &
269!$OMP rho_smooth_cutoff_range_2,my_e_0_scale_factor) &
270!$OMP PRIVATE(k,j,i,my_rho,my_rho_n,my_rho_n2) &
271!$OMP COLLAPSE(3)
272 DO k = bo(1, 3), bo(2, 3)
273 DO j = bo(1, 2), bo(2, 2)
274 DO i = bo(1, 1), bo(2, 1)
275 my_rho = rho(i, j, k)
276 IF (my_rho < rho_smooth_cutoff) THEN
277 IF (my_rho < rho_cutoff) THEN
278 pot(i, j, k) = 0.0_dp
279 ELSE IF (my_rho < rho_smooth_cutoff_2) THEN
280 my_rho_n = (my_rho - rho_cutoff)/rho_smooth_cutoff_range_2
281 my_rho_n2 = my_rho_n*my_rho_n
282 pot(i, j, k) = pot(i, j, k)* &
283 my_rho_n2*(my_rho_n - 0.5_dp*my_rho_n2) + &
284 my_e_0_scale_factor*e_0(i, j, k)* &
285 my_rho_n2*(3.0_dp - 2.0_dp*my_rho_n) &
286 /rho_smooth_cutoff_range_2
287 ELSE
288 my_rho_n = 2.0_dp - (my_rho - rho_cutoff)/rho_smooth_cutoff_range_2
289 my_rho_n2 = my_rho_n*my_rho_n
290 pot(i, j, k) = pot(i, j, k)* &
291 (1.0_dp - my_rho_n2*(my_rho_n - 0.5_dp*my_rho_n2)) &
292 + my_e_0_scale_factor*e_0(i, j, k)* &
293 my_rho_n2*(3.0_dp - 2.0_dp*my_rho_n) &
294 /rho_smooth_cutoff_range_2
295 END IF
296 END IF
297 END DO
298 END DO
299 END DO
300!$OMP END PARALLEL DO
301 ELSE
302!$OMP PARALLEL DO DEFAULT(NONE) &
303!$OMP SHARED(bo,pot,e_0,rhoa,rhob,rho_cutoff,rho_smooth_cutoff,rho_smooth_cutoff_2, &
304!$OMP rho_smooth_cutoff_range_2,my_e_0_scale_factor) &
305!$OMP PRIVATE(k,j,i,my_rho,my_rho_n,my_rho_n2) &
306!$OMP COLLAPSE(3)
307 DO k = bo(1, 3), bo(2, 3)
308 DO j = bo(1, 2), bo(2, 2)
309 DO i = bo(1, 1), bo(2, 1)
310 my_rho = rhoa(i, j, k) + rhob(i, j, k)
311 IF (my_rho < rho_smooth_cutoff) THEN
312 IF (my_rho < rho_cutoff) THEN
313 pot(i, j, k) = 0.0_dp
314 ELSE IF (my_rho < rho_smooth_cutoff_2) THEN
315 my_rho_n = (my_rho - rho_cutoff)/rho_smooth_cutoff_range_2
316 my_rho_n2 = my_rho_n*my_rho_n
317 pot(i, j, k) = pot(i, j, k)* &
318 my_rho_n2*(my_rho_n - 0.5_dp*my_rho_n2) + &
319 my_e_0_scale_factor*e_0(i, j, k)* &
320 my_rho_n2*(3.0_dp - 2.0_dp*my_rho_n) &
321 /rho_smooth_cutoff_range_2
322 ELSE
323 my_rho_n = 2.0_dp - (my_rho - rho_cutoff)/rho_smooth_cutoff_range_2
324 my_rho_n2 = my_rho_n*my_rho_n
325 pot(i, j, k) = pot(i, j, k)* &
326 (1.0_dp - my_rho_n2*(my_rho_n - 0.5_dp*my_rho_n2)) &
327 + my_e_0_scale_factor*e_0(i, j, k)* &
328 my_rho_n2*(3.0_dp - 2.0_dp*my_rho_n) &
329 /rho_smooth_cutoff_range_2
330 END IF
331 END IF
332 END DO
333 END DO
334 END DO
335!$OMP END PARALLEL DO
336 END IF
337 ELSE
338 IF (ASSOCIATED(rho)) THEN
339!$OMP PARALLEL DO DEFAULT(NONE) &
340!$OMP SHARED(bo,pot,rho_cutoff,rho_smooth_cutoff,rho_smooth_cutoff_2, &
341!$OMP rho_smooth_cutoff_range_2,rho) &
342!$OMP PRIVATE(k,j,i,my_rho,my_rho_n,my_rho_n2) &
343!$OMP COLLAPSE(3)
344 DO k = bo(1, 3), bo(2, 3)
345 DO j = bo(1, 2), bo(2, 2)
346 DO i = bo(1, 1), bo(2, 1)
347 my_rho = rho(i, j, k)
348 IF (my_rho < rho_smooth_cutoff) THEN
349 IF (my_rho < rho_cutoff) THEN
350 pot(i, j, k) = 0.0_dp
351 ELSE IF (my_rho < rho_smooth_cutoff_2) THEN
352 my_rho_n = (my_rho - rho_cutoff)/rho_smooth_cutoff_range_2
353 my_rho_n2 = my_rho_n*my_rho_n
354 pot(i, j, k) = pot(i, j, k)* &
355 my_rho_n2*(my_rho_n - 0.5_dp*my_rho_n2)
356 ELSE
357 my_rho_n = 2.0_dp - (my_rho - rho_cutoff)/rho_smooth_cutoff_range_2
358 my_rho_n2 = my_rho_n*my_rho_n
359 pot(i, j, k) = pot(i, j, k)* &
360 (1.0_dp - my_rho_n2*(my_rho_n - 0.5_dp*my_rho_n2))
361 END IF
362 END IF
363 END DO
364 END DO
365 END DO
366!$OMP END PARALLEL DO
367 ELSE
368!$OMP PARALLEL DO DEFAULT(NONE) &
369!$OMP SHARED(bo,pot,rho_cutoff,rho_smooth_cutoff,rho_smooth_cutoff_2, &
370!$OMP rho_smooth_cutoff_range_2,rhoa,rhob) &
371!$OMP PRIVATE(k,j,i,my_rho,my_rho_n,my_rho_n2) &
372!$OMP COLLAPSE(3)
373 DO k = bo(1, 3), bo(2, 3)
374 DO j = bo(1, 2), bo(2, 2)
375 DO i = bo(1, 1), bo(2, 1)
376 my_rho = rhoa(i, j, k) + rhob(i, j, k)
377 IF (my_rho < rho_smooth_cutoff) THEN
378 IF (my_rho < rho_cutoff) THEN
379 pot(i, j, k) = 0.0_dp
380 ELSE IF (my_rho < rho_smooth_cutoff_2) THEN
381 my_rho_n = (my_rho - rho_cutoff)/rho_smooth_cutoff_range_2
382 my_rho_n2 = my_rho_n*my_rho_n
383 pot(i, j, k) = pot(i, j, k)* &
384 my_rho_n2*(my_rho_n - 0.5_dp*my_rho_n2)
385 ELSE
386 my_rho_n = 2.0_dp - (my_rho - rho_cutoff)/rho_smooth_cutoff_range_2
387 my_rho_n2 = my_rho_n*my_rho_n
388 pot(i, j, k) = pot(i, j, k)* &
389 (1.0_dp - my_rho_n2*(my_rho_n - 0.5_dp*my_rho_n2))
390 END IF
391 END IF
392 END DO
393 END DO
394 END DO
395!$OMP END PARALLEL DO
396 END IF
397 END IF
398 END IF
399 END SUBROUTINE smooth_cutoff
400
401 SUBROUTINE calc_xc_density(pot, rho, rho_cutoff)
402 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: pot
403 TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(INOUT) :: rho
404 REAL(kind=dp), INTENT(in) :: rho_cutoff
405
406 INTEGER :: i, j, k, nspins
407 INTEGER, DIMENSION(2, 3) :: bo
408 REAL(kind=dp) :: eps1, eps2, my_rho, my_pot
409
410 bo(1, :) = lbound(pot%array)
411 bo(2, :) = ubound(pot%array)
412 nspins = SIZE(rho)
413
414 eps1 = rho_cutoff*1.e-4_dp
415 eps2 = rho_cutoff
416
417 DO k = bo(1, 3), bo(2, 3)
418 DO j = bo(1, 2), bo(2, 2)
419 DO i = bo(1, 1), bo(2, 1)
420 my_pot = pot%array(i, j, k)
421 IF (nspins == 2) THEN
422 my_rho = rho(1)%array(i, j, k) + rho(2)%array(i, j, k)
423 ELSE
424 my_rho = rho(1)%array(i, j, k)
425 END IF
426 IF (my_rho > eps1) THEN
427 pot%array(i, j, k) = my_pot/my_rho
428 ELSE IF (my_rho < eps2) THEN
429 pot%array(i, j, k) = 0.0_dp
430 ELSE
431 pot%array(i, j, k) = min(my_pot/my_rho, my_rho**(1._dp/3._dp))
432 END IF
433 END DO
434 END DO
435 END DO
436
437 END SUBROUTINE calc_xc_density
438
439! **************************************************************************************************
440!> \brief Exchange and Correlation functional calculations
441!> \param vxc_rho will contain the v_xc part that depend on rho
442!> (if one of the chosen xc functionals has it it is allocated and you
443!> are responsible for it)
444!> \param vxc_tau will contain the kinetic tau part of v_xc
445!> (if one of the chosen xc functionals has it it is allocated and you
446!> are responsible for it)
447!> \param exc the xc energy
448!> \param rho_r the value of the density in the real space
449!> \param rho_g value of the density in the g space (needs to be associated
450!> only for gradient corrections)
451!> \param tau value of the kinetic density tau on the grid (can be null,
452!> used only with meta functionals)
453!> \param xc_section which functional to calculate, and how to do it
454!> \param weights integration weights
455!> \param pw_pool the pool for the grids
456!> \param compute_virial ...
457!> \param virial_xc ...
458!> \param exc_r the value of the xc functional in the real space
459!> \par History
460!> JGH (13-Jun-2002): adaptation to new functionals
461!> Fawzi (11.2002): drho_g(1:3)->drho_g
462!> Fawzi (1.2003). lsd version
463!> Fawzi (11.2003): version using the new xc interface
464!> Fawzi (03.2004): fft free for smoothed density and derivs, gga lsd
465!> Fawzi (04.2004): metafunctionals
466!> mguidon (12.2008) : laplace functionals
467!> \author fawzi; based LDA version of JGH, based on earlier version of apsi
468!> \note
469!> Beware: some really dirty pointer handling!
470!> energy should be kept consistent with xc_exc_calc
471! **************************************************************************************************
472 SUBROUTINE xc_vxc_pw_create(vxc_rho, vxc_tau, exc, rho_r, rho_g, tau, xc_section, weights, &
473 pw_pool, compute_virial, virial_xc, exc_r)
474 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: vxc_rho, vxc_tau
475 REAL(kind=dp), INTENT(out) :: exc
476 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r, tau
477 TYPE(pw_r3d_rs_type), POINTER :: weights
478 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
479 TYPE(section_vals_type), POINTER :: xc_section
480 TYPE(pw_pool_type), POINTER :: pw_pool
481 LOGICAL :: compute_virial
482 REAL(kind=dp), DIMENSION(3, 3), INTENT(OUT) :: virial_xc
483 TYPE(pw_r3d_rs_type), INTENT(INOUT), OPTIONAL :: exc_r
484
485 CHARACTER(len=*), PARAMETER :: routinen = 'xc_vxc_pw_create'
486 INTEGER, DIMENSION(2), PARAMETER :: norm_drho_spin_name = [deriv_norm_drhoa, deriv_norm_drhob]
487
488 INTEGER :: handle, idir, ispin, jdir, &
489 npoints, nspins, &
490 xc_deriv_method_id, xc_rho_smooth_id, deriv_id
491 INTEGER, DIMENSION(2, 3) :: bo
492 LOGICAL :: dealloc_pw_to_deriv, has_laplace, &
493 has_tau, lsd, use_virial, has_gradient, &
494 has_derivs, has_rho, dealloc_pw_to_deriv_rho
495 REAL(kind=dp) :: density_smooth_cut_range, drho_cutoff, &
496 rho_cutoff
497 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: deriv_data, norm_drho, norm_drho_spin, &
498 rho, rhoa, rhob
499 TYPE(cp_sll_xc_deriv_type), POINTER :: pos
500 TYPE(pw_grid_type), POINTER :: pw_grid
501 TYPE(pw_r3d_rs_type), DIMENSION(3) :: pw_to_deriv, pw_to_deriv_rho
502 TYPE(pw_c1d_gs_type) :: tmp_g, vxc_g
503 TYPE(pw_r3d_rs_type) :: v_drho_r, virial_pw
504 TYPE(xc_derivative_set_type) :: deriv_set
505 TYPE(xc_derivative_type), POINTER :: deriv_att
506 TYPE(xc_rho_set_type) :: rho_set
507
508 CALL timeset(routinen, handle)
509 NULLIFY (norm_drho_spin, norm_drho, pos)
510
511 pw_grid => rho_r(1)%pw_grid
512
513 cpassert(ASSOCIATED(xc_section))
514 cpassert(ASSOCIATED(pw_pool))
515 cpassert(.NOT. ASSOCIATED(vxc_rho))
516 cpassert(.NOT. ASSOCIATED(vxc_tau))
517 nspins = SIZE(rho_r)
518 lsd = (nspins /= 1)
519 IF (lsd) THEN
520 cpassert(nspins == 2)
521 END IF
522
523 use_virial = compute_virial
524 virial_xc = 0.0_dp
525
526 bo = rho_r(1)%pw_grid%bounds_local
527 npoints = (bo(2, 1) - bo(1, 1) + 1)*(bo(2, 2) - bo(1, 2) + 1)*(bo(2, 3) - bo(1, 3) + 1)
528
529 ! calculate the potential derivatives
530 CALL xc_rho_set_and_dset_create(rho_set=rho_set, deriv_set=deriv_set, &
531 deriv_order=1, rho_r=rho_r, rho_g=rho_g, tau=tau, &
532 xc_section=xc_section, &
533 pw_pool=pw_pool, weights=weights, &
534 calc_potential=.true.)
535
536 CALL section_vals_val_get(xc_section, "XC_GRID%XC_DERIV", &
537 i_val=xc_deriv_method_id)
538 CALL section_vals_val_get(xc_section, "XC_GRID%XC_SMOOTH_RHO", &
539 i_val=xc_rho_smooth_id)
540 CALL section_vals_val_get(xc_section, "DENSITY_SMOOTH_CUTOFF_RANGE", &
541 r_val=density_smooth_cut_range)
542
543 CALL xc_rho_set_get(rho_set, rho_cutoff=rho_cutoff, &
544 drho_cutoff=drho_cutoff)
545
546 CALL check_for_derivatives(deriv_set, lsd, has_rho, has_gradient, has_tau, has_laplace)
547 ! check for unknown derivatives
548 has_derivs = has_rho .OR. has_gradient .OR. has_tau .OR. has_laplace
549
550 ALLOCATE (vxc_rho(nspins))
551
552 CALL xc_rho_set_get(rho_set, rho=rho, rhoa=rhoa, rhob=rhob, &
553 can_return_null=.true.)
554
555 ! recover the vxc arrays
556 IF (lsd) THEN
557 CALL xc_dset_recover_pw(deriv_set, [deriv_rhoa], vxc_rho(1), pw_grid, pw_pool)
558 CALL xc_dset_recover_pw(deriv_set, [deriv_rhob], vxc_rho(2), pw_grid, pw_pool)
559 ELSE
560 CALL xc_dset_recover_pw(deriv_set, [deriv_rho], vxc_rho(1), pw_grid, pw_pool)
561 END IF
562
563 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
564 IF (ASSOCIATED(deriv_att)) THEN
565 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
566
567 CALL xc_rho_set_get(rho_set, norm_drho=norm_drho, &
568 rho_cutoff=rho_cutoff, &
569 drho_cutoff=drho_cutoff, &
570 can_return_null=.true.)
571 CALL xc_rho_set_recover_pw(rho_set, pw_grid, pw_pool, dealloc_pw_to_deriv_rho, drho=pw_to_deriv_rho)
572
573 cpassert(ASSOCIATED(deriv_data))
574 IF (use_virial) THEN
575 CALL pw_pool%create_pw(virial_pw)
576 CALL pw_zero(virial_pw)
577 DO idir = 1, 3
578!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(virial_pw,pw_to_deriv_rho,deriv_data,idir)
579 virial_pw%array(:, :, :) = pw_to_deriv_rho(idir)%array(:, :, :)*deriv_data(:, :, :)
580!$OMP END PARALLEL WORKSHARE
581 DO jdir = 1, idir
582 virial_xc(idir, jdir) = -pw_grid%dvol* &
583 accurate_dot_product(virial_pw%array(:, :, :), &
584 pw_to_deriv_rho(jdir)%array(:, :, :))
585 virial_xc(jdir, idir) = virial_xc(idir, jdir)
586 END DO
587 END DO
588 CALL pw_pool%give_back_pw(virial_pw)
589 END IF ! use_virial
590 DO idir = 1, 3
591 cpassert(ASSOCIATED(pw_to_deriv_rho(idir)%array))
592!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(deriv_data,pw_to_deriv_rho,idir)
593 pw_to_deriv_rho(idir)%array(:, :, :) = pw_to_deriv_rho(idir)%array(:, :, :)*deriv_data(:, :, :)
594!$OMP END PARALLEL WORKSHARE
595 END DO
596
597 ! Deallocate pw to save memory
598 CALL pw_pool%give_back_cr3d(deriv_att%deriv_data)
599
600 END IF
601
602 IF ((has_gradient .AND. xc_requires_tmp_g(xc_deriv_method_id)) .OR. pw_grid%spherical) THEN
603 CALL pw_pool%create_pw(vxc_g)
604 IF (.NOT. pw_grid%spherical) THEN
605 CALL pw_pool%create_pw(tmp_g)
606 END IF
607 END IF
608
609 DO ispin = 1, nspins
610
611 IF (lsd) THEN
612 IF (ispin == 1) THEN
613 CALL xc_rho_set_get(rho_set, norm_drhoa=norm_drho_spin, &
614 can_return_null=.true.)
615 IF (ASSOCIATED(norm_drho_spin)) CALL xc_rho_set_recover_pw( &
616 rho_set, pw_grid, pw_pool, dealloc_pw_to_deriv, drhoa=pw_to_deriv)
617 ELSE
618 CALL xc_rho_set_get(rho_set, norm_drhob=norm_drho_spin, &
619 can_return_null=.true.)
620 IF (ASSOCIATED(norm_drho_spin)) CALL xc_rho_set_recover_pw( &
621 rho_set, pw_grid, pw_pool, dealloc_pw_to_deriv, drhob=pw_to_deriv)
622 END IF
623
624 deriv_att => xc_dset_get_derivative(deriv_set, [norm_drho_spin_name(ispin)])
625 IF (ASSOCIATED(deriv_att)) THEN
626 cpassert(lsd)
627 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
628
629 IF (use_virial) THEN
630 CALL pw_pool%create_pw(virial_pw)
631 CALL pw_zero(virial_pw)
632 DO idir = 1, 3
633!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(deriv_data,pw_to_deriv,virial_pw,idir)
634 virial_pw%array(:, :, :) = pw_to_deriv(idir)%array(:, :, :)*deriv_data(:, :, :)
635!$OMP END PARALLEL WORKSHARE
636 DO jdir = 1, idir
637 virial_xc(idir, jdir) = virial_xc(idir, jdir) - pw_grid%dvol* &
638 accurate_dot_product(virial_pw%array(:, :, :), &
639 pw_to_deriv(jdir)%array(:, :, :))
640 virial_xc(jdir, idir) = virial_xc(idir, jdir)
641 END DO
642 END DO
643 CALL pw_pool%give_back_pw(virial_pw)
644 END IF ! use_virial
645
646 DO idir = 1, 3
647!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(deriv_data,idir,pw_to_deriv)
648 pw_to_deriv(idir)%array(:, :, :) = deriv_data(:, :, :)*pw_to_deriv(idir)%array(:, :, :)
649!$OMP END PARALLEL WORKSHARE
650 END DO
651 END IF ! deriv_att
652
653 END IF ! LSD
654
655 IF (ASSOCIATED(pw_to_deriv_rho(1)%array)) THEN
656 IF (.NOT. ASSOCIATED(pw_to_deriv(1)%array)) THEN
657 pw_to_deriv = pw_to_deriv_rho
658 dealloc_pw_to_deriv = ((.NOT. lsd) .OR. (ispin == 2))
659 dealloc_pw_to_deriv = dealloc_pw_to_deriv .AND. dealloc_pw_to_deriv_rho
660 ELSE
661 ! This branch is called in case of open-shell systems
662 ! Add the contributions from norm_drho and norm_drho_spin
663 DO idir = 1, 3
664 CALL pw_axpy(pw_to_deriv_rho(idir), pw_to_deriv(idir))
665 IF (ispin == 2) THEN
666 IF (dealloc_pw_to_deriv_rho) THEN
667 CALL pw_pool%give_back_pw(pw_to_deriv_rho(idir))
668 END IF
669 END IF
670 END DO
671 END IF
672 END IF
673
674 IF (ASSOCIATED(pw_to_deriv(1)%array)) THEN
675 DO idir = 1, 3
676 CALL pw_scale(pw_to_deriv(idir), -1.0_dp)
677 END DO
678
679 CALL xc_pw_divergence(xc_deriv_method_id, pw_to_deriv, tmp_g, vxc_g, vxc_rho(ispin))
680
681 IF (dealloc_pw_to_deriv) THEN
682 DO idir = 1, 3
683 CALL pw_pool%give_back_pw(pw_to_deriv(idir))
684 END DO
685 END IF
686 END IF
687
688 ! Add laplace part to vxc_rho
689 IF (has_laplace) THEN
690 IF (lsd) THEN
691 IF (ispin == 1) THEN
692 deriv_id = deriv_laplace_rhoa
693 ELSE
694 deriv_id = deriv_laplace_rhob
695 END IF
696 ELSE
697 deriv_id = deriv_laplace_rho
698 END IF
699
700 CALL xc_dset_recover_pw(deriv_set, [deriv_id], pw_to_deriv(1), pw_grid)
701
702 IF (use_virial) CALL virial_laplace(rho_r(ispin), pw_pool, virial_xc, &
703 pw_to_deriv(1)%array)
704
705 CALL xc_pw_laplace(pw_to_deriv(1), pw_pool, xc_deriv_method_id)
706
707 CALL pw_axpy(pw_to_deriv(1), vxc_rho(ispin))
708
709 CALL pw_pool%give_back_pw(pw_to_deriv(1))
710 END IF
711
712 IF (pw_grid%spherical) THEN
713 ! filter vxc
714 CALL pw_transfer(vxc_rho(ispin), vxc_g)
715 CALL pw_transfer(vxc_g, vxc_rho(ispin))
716 END IF
717 CALL smooth_cutoff(pot=vxc_rho(ispin)%array, rho=rho, rhoa=rhoa, rhob=rhob, &
718 rho_cutoff=rho_cutoff*density_smooth_cut_range, &
719 rho_smooth_cutoff_range=density_smooth_cut_range)
720
721 v_drho_r = vxc_rho(ispin)
722 CALL pw_pool%create_pw(vxc_rho(ispin))
723 CALL xc_pw_smooth(v_drho_r, vxc_rho(ispin), xc_rho_smooth_id)
724 CALL pw_pool%give_back_pw(v_drho_r)
725 END DO
726
727 CALL pw_pool%give_back_pw(vxc_g)
728 CALL pw_pool%give_back_pw(tmp_g)
729
730 ! 0-deriv -> value of exc
731 ! this has to be kept consistent with xc_exc_calc
732 IF (has_derivs) THEN
733 CALL xc_dset_recover_pw(deriv_set, [INTEGER::], v_drho_r, pw_grid)
734
735 CALL smooth_cutoff(pot=v_drho_r%array, rho=rho, rhoa=rhoa, rhob=rhob, &
736 rho_cutoff=rho_cutoff, &
737 rho_smooth_cutoff_range=density_smooth_cut_range)
738
739 exc = pw_integrate_function(v_drho_r)
740 !
741 ! return the xc functional value at the grid points
742 !
743 IF (PRESENT(exc_r)) THEN
744 exc_r = v_drho_r
745 ELSE
746 CALL v_drho_r%release()
747 END IF
748 ELSE
749 exc = 0.0_dp
750 END IF
751
752 CALL xc_rho_set_release(rho_set, pw_pool=pw_pool)
753
754 ! tau part
755 IF (has_tau) THEN
756 ALLOCATE (vxc_tau(nspins))
757 IF (lsd) THEN
758 CALL xc_dset_recover_pw(deriv_set, [deriv_tau_a], vxc_tau(1), pw_grid)
759 CALL xc_dset_recover_pw(deriv_set, [deriv_tau_b], vxc_tau(2), pw_grid)
760 ELSE
761 CALL xc_dset_recover_pw(deriv_set, [deriv_tau], vxc_tau(1), pw_grid)
762 END IF
763 DO ispin = 1, nspins
764 cpassert(ASSOCIATED(vxc_tau(ispin)%array))
765 END DO
766 END IF
767 CALL xc_dset_release(deriv_set)
768
769 CALL timestop(handle)
770
771 END SUBROUTINE xc_vxc_pw_create
772
773! **************************************************************************************************
774!> \brief calculates just the exchange and correlation energy
775!> (no vxc)
776!> \param rho_r realspace density on the grid
777!> \param rho_g g-space density on the grid
778!> \param tau kinetic energy density on the grid
779!> \param xc_section XC parameters
780!> \param weights Integration weights
781!> \param pw_pool pool of plain-wave grids
782!> \return the XC energy
783!> \par History
784!> 11.2003 created [fawzi]
785!> \author fawzi
786!> \note
787!> has to be kept consistent with xc_vxc_pw_create
788! **************************************************************************************************
789 FUNCTION xc_exc_calc(rho_r, rho_g, tau, xc_section, weights, pw_pool) &
790 result(exc)
791 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r, tau
792 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
793 TYPE(section_vals_type), POINTER :: xc_section
794 TYPE(pw_r3d_rs_type), POINTER :: weights
795 TYPE(pw_pool_type), POINTER :: pw_pool
796 REAL(kind=dp) :: exc
797
798 CHARACTER(len=*), PARAMETER :: routinen = 'xc_exc_calc'
799
800 INTEGER :: handle
801 REAL(dp) :: density_smooth_cut_range, rho_cutoff
802 REAL(dp), DIMENSION(:, :, :), POINTER :: e_0
803 TYPE(xc_derivative_set_type) :: deriv_set
804 TYPE(xc_derivative_type), POINTER :: deriv
805 TYPE(xc_rho_set_type) :: rho_set
806
807 CALL timeset(routinen, handle)
808
809 NULLIFY (deriv, e_0)
810 exc = 0.0_dp
811
812 ! this has to be consistent with what is done in xc_vxc_pw_create
813 CALL xc_rho_set_and_dset_create(rho_set=rho_set, &
814 deriv_set=deriv_set, deriv_order=0, &
815 rho_r=rho_r, rho_g=rho_g, tau=tau, xc_section=xc_section, &
816 pw_pool=pw_pool, weights=weights, &
817 calc_potential=.false.)
818 deriv => xc_dset_get_derivative(deriv_set, [INTEGER::])
819
820 IF (ASSOCIATED(deriv)) THEN
821 CALL xc_derivative_get(deriv, deriv_data=e_0)
822
823 CALL section_vals_val_get(xc_section, "DENSITY_CUTOFF", &
824 r_val=rho_cutoff)
825 CALL section_vals_val_get(xc_section, "DENSITY_SMOOTH_CUTOFF_RANGE", &
826 r_val=density_smooth_cut_range)
827 CALL smooth_cutoff(pot=e_0, rho=rho_set%rho, &
828 rhoa=rho_set%rhoa, rhob=rho_set%rhob, &
829 rho_cutoff=rho_cutoff, &
830 rho_smooth_cutoff_range=density_smooth_cut_range)
831
832 exc = accurate_sum(e_0)*rho_r(1)%pw_grid%dvol
833 IF (rho_r(1)%pw_grid%para%mode == pw_mode_distributed) THEN
834 CALL rho_r(1)%pw_grid%para%group%sum(exc)
835 END IF
836
837 CALL xc_rho_set_release(rho_set, pw_pool=pw_pool)
838 CALL xc_dset_release(deriv_set)
839 END IF
840
841 CALL timestop(handle)
842
843 END FUNCTION xc_exc_calc
844
845! **************************************************************************************************
846!> \brief calculates just the exchange and correlation energy density
847!> \param rho_r realspace density on the grid
848!> \param rho_g g-space density on the grid
849!> \param tau kinetic energy density on the grid
850!> \param xc_section XC parameters
851!> \param weights Integration weights
852!> \param pw_pool pool of plain-wave grids
853!> \param exc xc energy density
854!> \author JGH
855! **************************************************************************************************
856 SUBROUTINE xc_exc_pw_create(rho_r, rho_g, tau, xc_section, weights, pw_pool, exc)
857 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r, tau
858 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
859 TYPE(section_vals_type), POINTER :: xc_section
860 TYPE(pw_r3d_rs_type), POINTER :: weights
861 TYPE(pw_pool_type), POINTER :: pw_pool
862 TYPE(pw_r3d_rs_type) :: exc
863
864 CHARACTER(len=*), PARAMETER :: routinen = 'xc_exc_pw_create'
865
866 INTEGER :: handle
867 REAL(dp) :: density_smooth_cut_range, rho_cutoff
868 REAL(dp), DIMENSION(:, :, :), POINTER :: e_0
869 TYPE(xc_derivative_set_type) :: deriv_set
870 TYPE(xc_derivative_type), POINTER :: deriv
871 TYPE(xc_rho_set_type) :: rho_set
872
873 CALL timeset(routinen, handle)
874
875 NULLIFY (deriv, e_0)
876
877 CALL xc_rho_set_and_dset_create(rho_set=rho_set, &
878 deriv_set=deriv_set, deriv_order=0, &
879 rho_r=rho_r, rho_g=rho_g, tau=tau, xc_section=xc_section, &
880 pw_pool=pw_pool, weights=weights, &
881 calc_potential=.false.)
882 deriv => xc_dset_get_derivative(deriv_set, [INTEGER::])
883
884 IF (ASSOCIATED(deriv)) THEN
885 CALL xc_derivative_get(deriv, deriv_data=e_0)
886
887 CALL section_vals_val_get(xc_section, "DENSITY_CUTOFF", &
888 r_val=rho_cutoff)
889 CALL section_vals_val_get(xc_section, "DENSITY_SMOOTH_CUTOFF_RANGE", &
890 r_val=density_smooth_cut_range)
891 CALL smooth_cutoff(pot=e_0, rho=rho_set%rho, &
892 rhoa=rho_set%rhoa, rhob=rho_set%rhob, &
893 rho_cutoff=rho_cutoff, &
894 rho_smooth_cutoff_range=density_smooth_cut_range)
895
896 exc%array = e_0
897
898 CALL xc_rho_set_release(rho_set, pw_pool=pw_pool)
899 CALL xc_dset_release(deriv_set)
900 END IF
901
902 CALL timestop(handle)
903
904 END SUBROUTINE xc_exc_pw_create
905
906! **************************************************************************************************
907!> \brief Caller routine to calculate the second order potential in the direction of rho1_r
908!> \param v_xc XC potential, will be allocated, to be integrated with the KS density
909!> \param v_xc_tau ...
910!> \param deriv_set XC derivatives from xc_prep_2nd_deriv
911!> \param rho_set XC rho set from KS rho from xc_prep_2nd_deriv
912!> \param rho1_r first-order density in r space
913!> \param rho1_g first-order density in g space
914!> \param tau1_r ...
915!> \param pw_pool pw pool to create new grids
916!> \param xc_section XC section to calculate the derivatives from
917!> \param gapw whether to carry out GAPW (not possible with numerical derivatives)
918!> \param vxg GAPW potential
919!> \param do_excitations ...
920!> \param do_triplet ...
921!> \param compute_virial ...
922!> \param virial_xc virial terms will be collected here
923! **************************************************************************************************
924 SUBROUTINE xc_calc_2nd_deriv(v_xc, v_xc_tau, deriv_set, rho_set, rho1_r, rho1_g, tau1_r, &
925 pw_pool, weights, xc_section, gapw, vxg, &
926 do_excitations, do_sf, do_triplet, &
927 compute_virial, virial_xc)
928
929 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_xc, v_xc_tau
930 TYPE(xc_derivative_set_type) :: deriv_set
931 TYPE(xc_rho_set_type) :: rho_set
932 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho1_r, tau1_r
933 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho1_g
934 TYPE(pw_pool_type), INTENT(IN), POINTER :: pw_pool
935 TYPE(pw_r3d_rs_type), POINTER :: weights
936 TYPE(section_vals_type), INTENT(IN), POINTER :: xc_section
937 LOGICAL, INTENT(IN) :: gapw
938 REAL(kind=dp), DIMENSION(:, :, :, :), OPTIONAL, &
939 POINTER :: vxg
940 LOGICAL, INTENT(IN), OPTIONAL :: do_excitations, do_sf, &
941 do_triplet, compute_virial
942 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT), &
943 OPTIONAL :: virial_xc
944
945 CHARACTER(len=*), PARAMETER :: routinen = 'xc_calc_2nd_deriv'
946
947 INTEGER :: handle, ispin, nspins
948 INTEGER, DIMENSION(2, 3) :: bo
949 LOGICAL :: lsd, my_compute_virial, &
950 my_do_excitations, my_do_sf, &
951 my_do_triplet
952 REAL(kind=dp) :: fac
953 TYPE(section_vals_type), POINTER :: xc_fun_section
954 TYPE(xc_rho_cflags_type) :: needs
955 TYPE(xc_rho_set_type) :: rho1_set
956
957 CALL timeset(routinen, handle)
958
959 my_compute_virial = .false.
960 IF (PRESENT(compute_virial)) my_compute_virial = compute_virial
961
962 my_do_sf = .false.
963 IF (PRESENT(do_sf)) my_do_sf = do_sf
964
965 my_do_excitations = .false.
966 IF (PRESENT(do_excitations)) my_do_excitations = do_excitations
967
968 my_do_triplet = .false.
969 IF (PRESENT(do_triplet)) my_do_triplet = do_triplet
970
971 nspins = SIZE(rho1_r)
972 lsd = (nspins == 2)
973 IF (nspins == 1 .AND. my_do_excitations .AND. my_do_triplet) THEN
974 nspins = 2
975 lsd = .true.
976 ELSE IF (my_do_sf) THEN
977 nspins = 1
978 lsd = .true.
979 END IF
980
981 NULLIFY (v_xc, v_xc_tau)
982 ALLOCATE (v_xc(nspins))
983 DO ispin = 1, nspins
984 CALL pw_pool%create_pw(v_xc(ispin))
985 CALL pw_zero(v_xc(ispin))
986 END DO
987
988 xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
989 needs = xc_functionals_get_needs(xc_fun_section, lsd, .true.)
990
991 IF (needs%tau .OR. needs%tau_spin) THEN
992 IF (.NOT. ASSOCIATED(tau1_r)) THEN
993 cpabort("Tau-dependent functionals requires allocated kinetic energy density grid")
994 END IF
995 ALLOCATE (v_xc_tau(nspins))
996 DO ispin = 1, nspins
997 CALL pw_pool%create_pw(v_xc_tau(ispin))
998 CALL pw_zero(v_xc_tau(ispin))
999 END DO
1000 END IF
1001
1002 IF (section_get_lval(xc_section, "2ND_DERIV_ANALYTICAL")) THEN
1003 !------!
1004 ! rho1 !
1005 !------!
1006 bo = rho1_r(1)%pw_grid%bounds_local
1007 ! create the place where to store the argument for the functionals
1008 CALL xc_rho_set_create(rho1_set, bo, &
1009 rho_cutoff=section_get_rval(xc_section, "DENSITY_CUTOFF"), &
1010 drho_cutoff=section_get_rval(xc_section, "GRADIENT_CUTOFF"), &
1011 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
1012
1013 ! calculate the arguments needed by the functionals
1014 CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
1015 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
1016 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
1017 pw_pool, spinflip=my_do_sf)
1018
1019 fac = 0._dp
1020 IF (nspins == 1 .AND. my_do_excitations) THEN
1021 IF (my_do_triplet) fac = -1.0_dp
1022 END IF
1023
1024 CALL xc_calc_2nd_deriv_analytical(v_xc, v_xc_tau, deriv_set, rho_set, &
1025 rho1_set, pw_pool, xc_section, &
1026 gapw, vxg=vxg, spinflip=my_do_sf, tddfpt_fac=fac, &
1027 compute_virial=compute_virial, virial_xc=virial_xc)
1028
1029 CALL xc_rho_set_release(rho1_set)
1030
1031 ELSE
1032 IF (gapw) cpabort("Numerical 2nd derivatives not implemented with GAPW")
1033
1034 CALL xc_calc_2nd_deriv_numerical(v_xc, v_xc_tau, rho_set, rho1_r, rho1_g, tau1_r, &
1035 pw_pool, weights, xc_section, &
1036 my_do_excitations .AND. my_do_triplet, &
1037 compute_virial, virial_xc, deriv_set)
1038 END IF
1039
1040 CALL timestop(handle)
1041
1042 END SUBROUTINE xc_calc_2nd_deriv
1043
1044! **************************************************************************************************
1045!> \brief calculates 2nd derivative numerically
1046!> \param v_xc potential to be calculated (has to be allocated already)
1047!> \param v_tau tau-part of the potential to be calculated (has to be allocated already)
1048!> \param rho_set KS density from xc_prep_2nd_deriv
1049!> \param rho1_r first-order density in r-space
1050!> \param rho1_g first-order density in g-space
1051!> \param tau1_r first-order kinetic-energy density in r-space
1052!> \param pw_pool pw pool for new grids
1053!> \param xc_section XC section to calculate the derivatives from
1054!> \param do_triplet ...
1055!> \param calc_virial whether to calculate virial terms
1056!> \param virial_xc collects stress tensor components (no metaGGAs!)
1057!> \param deriv_set deriv set from xc_prep_2nd_deriv (only for virials)
1058! **************************************************************************************************
1059 SUBROUTINE xc_calc_2nd_deriv_numerical(v_xc, v_tau, rho_set, rho1_r, rho1_g, tau1_r, &
1060 pw_pool, weights, xc_section, &
1061 do_triplet, calc_virial, virial_xc, deriv_set)
1062
1063 TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(IN), POINTER :: v_xc, v_tau
1064 TYPE(xc_rho_set_type), INTENT(IN) :: rho_set
1065 TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(IN), POINTER :: rho1_r, tau1_r
1066 TYPE(pw_c1d_gs_type), DIMENSION(:), INTENT(IN), POINTER :: rho1_g
1067 TYPE(pw_pool_type), INTENT(IN), POINTER :: pw_pool
1068 TYPE(pw_r3d_rs_type), INTENT(IN), POINTER :: weights
1069 TYPE(section_vals_type), INTENT(IN), POINTER :: xc_section
1070 LOGICAL, INTENT(IN) :: do_triplet
1071 LOGICAL, INTENT(IN), OPTIONAL :: calc_virial
1072 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT), &
1073 OPTIONAL :: virial_xc
1074 TYPE(xc_derivative_set_type), OPTIONAL :: deriv_set
1075
1076 CHARACTER(len=*), PARAMETER :: routinen = 'xc_calc_2nd_deriv_numerical'
1077 REAL(kind=dp), DIMENSION(-4:4, 4), PARAMETER :: &
1078 rweights = reshape([0.0_dp, 0.0_dp, 0.0_dp, -0.5_dp, 0.0_dp, 0.5_dp, 0.0_dp, 0.0_dp, 0.0_dp, &
1079 0.0_dp, 0.0_dp, 1.0_dp/12.0_dp, -2.0_dp/3.0_dp, 0.0_dp, 2.0_dp/3.0_dp, -1.0_dp/12.0_dp, 0.0_dp, 0.0_dp, &
1080 0.0_dp, -1.0_dp/60.0_dp, 0.15_dp, -0.75_dp, 0.0_dp, 0.75_dp, -0.15_dp, 1.0_dp/60.0_dp, 0.0_dp, &
1081 1.0_dp/280.0_dp, -4.0_dp/105.0_dp, 0.2_dp, -0.8_dp, 0.0_dp, 0.8_dp, -0.2_dp, 4.0_dp/105.0_dp, -1.0_dp/280.0_dp], [9, 4])
1082
1083 INTEGER :: handle, idir, ispin, nspins, istep, nsteps
1084 INTEGER, DIMENSION(2, 3) :: bo
1085 LOGICAL :: gradient_f, lsd, my_calc_virial, tau_f, laplace_f, rho_f
1086 REAL(kind=dp) :: exc, gradient_cut, h, rweight, step, rho_cutoff
1087 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: dr1dr, dra1dra, drb1drb
1088 REAL(kind=dp), DIMENSION(3, 3) :: virial_dummy
1089 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: norm_drho, norm_drho2, norm_drho2a, &
1090 norm_drho2b, norm_drhoa, norm_drhob, &
1091 rho, rho1, rho1a, rho1b, rhoa, rhob, &
1092 tau_a, tau_b, tau, tau1, tau1a, tau1b, laplace, laplace1, &
1093 laplacea, laplaceb, laplace1a, laplace1b, &
1094 laplace2, laplace2a, laplace2b, deriv_data
1095 TYPE(cp_3d_r_cp_type), DIMENSION(3) :: drho, drho1, drho1a, drho1b, drhoa, drhob
1096 TYPE(pw_r3d_rs_type) :: v_drho, v_drhoa, v_drhob
1097 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: vxc_rho, vxc_tau
1098 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
1099 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r, tau_r
1100 TYPE(pw_r3d_rs_type) :: virial_pw, v_laplace, v_laplacea, v_laplaceb
1101 TYPE(section_vals_type), POINTER :: xc_fun_section
1102 TYPE(xc_derivative_set_type) :: deriv_set1
1103 TYPE(xc_rho_cflags_type) :: needs
1104 TYPE(xc_rho_set_type) :: rho1_set, rho2_set
1105
1106 CALL timeset(routinen, handle)
1107
1108 my_calc_virial = .false.
1109 IF (PRESENT(calc_virial) .AND. PRESENT(virial_xc)) my_calc_virial = calc_virial
1110
1111 nspins = SIZE(v_xc)
1112
1113 NULLIFY (tau, tau_r, tau_a, tau_b)
1114
1115 h = section_get_rval(xc_section, "STEP_SIZE")
1116 nsteps = section_get_ival(xc_section, "NSTEPS")
1117 IF (nsteps < lbound(rweights, 2) .OR. nspins > ubound(rweights, 2)) THEN
1118 cpabort("The number of steps must be a value from 1 to 4.")
1119 END IF
1120
1121 IF (nspins == 2) THEN
1122 NULLIFY (vxc_rho, rho_g, vxc_tau)
1123 ALLOCATE (rho_r(2))
1124 DO ispin = 1, nspins
1125 CALL pw_pool%create_pw(rho_r(ispin))
1126 END DO
1127 IF (ASSOCIATED(tau1_r) .AND. ASSOCIATED(v_tau)) THEN
1128 ALLOCATE (tau_r(2))
1129 DO ispin = 1, nspins
1130 CALL pw_pool%create_pw(tau_r(ispin))
1131 END DO
1132 END IF
1133 CALL xc_rho_set_get(rho_set, can_return_null=.true., rhoa=rhoa, rhob=rhob, tau_a=tau_a, tau_b=tau_b)
1134 DO istep = -nsteps, nsteps
1135 IF (istep == 0) cycle
1136 rweight = rweights(istep, nsteps)/h
1137 step = real(istep, dp)*h
1138 CALL calc_resp_potential_numer_ab(rho_r, rho_g, rho1_r, rhoa, rhob, vxc_rho, &
1139 tau_r, tau1_r, tau_a, tau_b, vxc_tau, xc_section, &
1140 weights, pw_pool, step)
1141 DO ispin = 1, nspins
1142 CALL pw_axpy(vxc_rho(ispin), v_xc(ispin), rweight)
1143 IF (ASSOCIATED(vxc_tau) .AND. ASSOCIATED(v_tau)) THEN
1144 CALL pw_axpy(vxc_tau(ispin), v_tau(ispin), rweight)
1145 END IF
1146 END DO
1147 DO ispin = 1, nspins
1148 CALL vxc_rho(ispin)%release()
1149 END DO
1150 DEALLOCATE (vxc_rho)
1151 IF (ASSOCIATED(vxc_tau)) THEN
1152 DO ispin = 1, nspins
1153 CALL vxc_tau(ispin)%release()
1154 END DO
1155 DEALLOCATE (vxc_tau)
1156 END IF
1157 END DO
1158 ELSE IF (nspins == 1 .AND. do_triplet) THEN
1159 NULLIFY (vxc_rho, vxc_tau, rho_g)
1160 ALLOCATE (rho_r(2))
1161 DO ispin = 1, 2
1162 CALL pw_pool%create_pw(rho_r(ispin))
1163 END DO
1164 IF (ASSOCIATED(tau1_r) .AND. ASSOCIATED(v_tau)) THEN
1165 ALLOCATE (tau_r(2))
1166 DO ispin = 1, nspins
1167 CALL pw_pool%create_pw(tau_r(ispin))
1168 END DO
1169 END IF
1170 CALL xc_rho_set_get(rho_set, can_return_null=.true., rhoa=rhoa, rhob=rhob, tau_a=tau_a, tau_b=tau_b)
1171 DO istep = -nsteps, nsteps
1172 IF (istep == 0) cycle
1173 rweight = rweights(istep, nsteps)/h
1174 step = real(istep, dp)*h
1175 ! K(alpha,alpha)
1176!$OMP PARALLEL DEFAULT(NONE) SHARED(rho_r,rhoa,rhob,step,rho1_r,tau_r,tau_a,tau_b,tau1_r)
1177!$OMP WORKSHARE
1178 rho_r(1)%array(:, :, :) = rhoa(:, :, :) + step*rho1_r(1)%array(:, :, :)
1179!$OMP END WORKSHARE NOWAIT
1180!$OMP WORKSHARE
1181 rho_r(2)%array(:, :, :) = rhob(:, :, :)
1182!$OMP END WORKSHARE NOWAIT
1183 IF (ASSOCIATED(tau1_r)) THEN
1184!$OMP WORKSHARE
1185 tau_r(1)%array(:, :, :) = tau_a(:, :, :) + step*tau1_r(1)%array(:, :, :)
1186!$OMP END WORKSHARE NOWAIT
1187!$OMP WORKSHARE
1188 tau_r(2)%array(:, :, :) = tau_b(:, :, :)
1189!$OMP END WORKSHARE NOWAIT
1190 END IF
1191!$OMP END PARALLEL
1192 CALL xc_vxc_pw_create(vxc_rho, vxc_tau, exc, rho_r, rho_g, tau_r, xc_section, &
1193 weights, pw_pool, .false., virial_dummy)
1194 CALL pw_axpy(vxc_rho(1), v_xc(1), rweight)
1195 IF (ASSOCIATED(vxc_tau) .AND. ASSOCIATED(v_tau)) THEN
1196 CALL pw_axpy(vxc_tau(1), v_tau(1), rweight)
1197 END IF
1198 DO ispin = 1, 2
1199 CALL vxc_rho(ispin)%release()
1200 END DO
1201 DEALLOCATE (vxc_rho)
1202 IF (ASSOCIATED(vxc_tau)) THEN
1203 DO ispin = 1, 2
1204 CALL vxc_tau(ispin)%release()
1205 END DO
1206 DEALLOCATE (vxc_tau)
1207 END IF
1208!$OMP PARALLEL DEFAULT(NONE) SHARED(rho_r,rhoa,rhob,step,rho1_r,tau_r,tau_a,tau_b,tau1_r)
1209!$OMP WORKSHARE
1210 ! K(alpha,beta)
1211 rho_r(1)%array(:, :, :) = rhoa(:, :, :)
1212!$OMP END WORKSHARE NOWAIT
1213!$OMP WORKSHARE
1214 rho_r(2)%array(:, :, :) = rhob(:, :, :) + step*rho1_r(1)%array(:, :, :)
1215!$OMP END WORKSHARE NOWAIT
1216 IF (ASSOCIATED(tau1_r)) THEN
1217!$OMP WORKSHARE
1218 tau_r(1)%array(:, :, :) = tau_a(:, :, :)
1219!$OMP END WORKSHARE NOWAIT
1220!$OMP WORKSHARE
1221 tau_r(2)%array(:, :, :) = tau_b(:, :, :) + step*tau1_r(1)%array(:, :, :)
1222!$OMP END WORKSHARE NOWAIT
1223 END IF
1224!$OMP END PARALLEL
1225 CALL xc_vxc_pw_create(vxc_rho, vxc_tau, exc, rho_r, rho_g, tau_r, xc_section, &
1226 weights, pw_pool, .false., virial_dummy)
1227 CALL pw_axpy(vxc_rho(1), v_xc(1), rweight)
1228 IF (ASSOCIATED(vxc_tau) .AND. ASSOCIATED(v_tau)) THEN
1229 CALL pw_axpy(vxc_tau(1), v_tau(1), rweight)
1230 END IF
1231 DO ispin = 1, 2
1232 CALL vxc_rho(ispin)%release()
1233 END DO
1234 DEALLOCATE (vxc_rho)
1235 IF (ASSOCIATED(vxc_tau)) THEN
1236 DO ispin = 1, 2
1237 CALL vxc_tau(ispin)%release()
1238 END DO
1239 DEALLOCATE (vxc_tau)
1240 END IF
1241 END DO
1242 ELSE
1243 NULLIFY (vxc_rho, rho_r, rho_g, vxc_tau, tau_r, tau)
1244 ALLOCATE (rho_r(1))
1245 CALL pw_pool%create_pw(rho_r(1))
1246 IF (ASSOCIATED(tau1_r) .AND. ASSOCIATED(v_tau)) THEN
1247 ALLOCATE (tau_r(1))
1248 CALL pw_pool%create_pw(tau_r(1))
1249 END IF
1250 CALL xc_rho_set_get(rho_set, can_return_null=.true., rho=rho, tau=tau)
1251 DO istep = -nsteps, nsteps
1252 IF (istep == 0) cycle
1253 rweight = rweights(istep, nsteps)/h
1254 step = real(istep, dp)*h
1255!$OMP PARALLEL DEFAULT(NONE) SHARED(rho_r,rho,step,rho1_r,tau1_r,tau,tau_r)
1256!$OMP WORKSHARE
1257 rho_r(1)%array(:, :, :) = rho(:, :, :) + step*rho1_r(1)%array(:, :, :)
1258!$OMP END WORKSHARE NOWAIT
1259 IF (ASSOCIATED(tau1_r) .AND. ASSOCIATED(tau) .AND. ASSOCIATED(tau1_r)) THEN
1260!$OMP WORKSHARE
1261 tau_r(1)%array(:, :, :) = tau(:, :, :) + step*tau1_r(1)%array(:, :, :)
1262!$OMP END WORKSHARE NOWAIT
1263 END IF
1264!$OMP END PARALLEL
1265 CALL xc_vxc_pw_create(vxc_rho, vxc_tau, exc, rho_r, rho_g, tau_r, xc_section, &
1266 weights, pw_pool, .false., virial_dummy)
1267 CALL pw_axpy(vxc_rho(1), v_xc(1), rweight)
1268 IF (ASSOCIATED(vxc_tau) .AND. ASSOCIATED(v_tau)) THEN
1269 CALL pw_axpy(vxc_tau(1), v_tau(1), rweight)
1270 END IF
1271 CALL vxc_rho(1)%release()
1272 DEALLOCATE (vxc_rho)
1273 IF (ASSOCIATED(vxc_tau)) THEN
1274 CALL vxc_tau(1)%release()
1275 DEALLOCATE (vxc_tau)
1276 END IF
1277 END DO
1278 END IF
1279
1280 IF (my_calc_virial) THEN
1281 lsd = (nspins == 2)
1282 IF (nspins == 1 .AND. do_triplet) THEN
1283 lsd = .true.
1284 END IF
1285
1286 CALL check_for_derivatives(deriv_set, (nspins == 2), rho_f, gradient_f, tau_f, laplace_f)
1287
1288 ! Calculate the virial terms
1289 ! Those arising from the first derivatives are treated like in xc_calc_2nd_deriv_analytical
1290 ! Those arising from the second derivatives are calculated numerically
1291 ! We assume that all metaGGA functionals require the gradient
1292 IF (gradient_f) THEN
1293 bo = rho_set%local_bounds
1294
1295 ! Create the work grid for the virial terms
1296 CALL allocate_pw(virial_pw, pw_pool, bo)
1297
1298 gradient_cut = section_get_rval(xc_section, "GRADIENT_CUTOFF")
1299
1300 ! create the container to store the argument of the functionals
1301 CALL xc_rho_set_create(rho1_set, bo, &
1302 rho_cutoff=section_get_rval(xc_section, "DENSITY_CUTOFF"), &
1303 drho_cutoff=gradient_cut, &
1304 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
1305
1306 xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
1307 needs = xc_functionals_get_needs(xc_fun_section, lsd, .true.)
1308
1309 ! calculate the arguments needed by the functionals
1310 CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
1311 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
1312 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
1313 pw_pool)
1314
1315 IF (lsd) THEN
1316 CALL xc_rho_set_get(rho_set, drhoa=drhoa, drhob=drhob, norm_drho=norm_drho, &
1317 norm_drhoa=norm_drhoa, norm_drhob=norm_drhob, tau_a=tau_a, tau_b=tau_b, &
1318 laplace_rhoa=laplacea, laplace_rhob=laplaceb, can_return_null=.true.)
1319 CALL xc_rho_set_get(rho1_set, rhoa=rho1a, rhob=rho1b, drhoa=drho1a, drhob=drho1b, laplace_rhoa=laplace1a, &
1320 laplace_rhob=laplace1b, can_return_null=.true.)
1321
1322 CALL calc_drho_from_ab(drho, drhoa, drhob)
1323 CALL calc_drho_from_ab(drho1, drho1a, drho1b)
1324 ELSE
1325 CALL xc_rho_set_get(rho_set, drho=drho, norm_drho=norm_drho, tau=tau, laplace_rho=laplace, can_return_null=.true.)
1326 CALL xc_rho_set_get(rho1_set, rho=rho1, drho=drho1, laplace_rho=laplace1, can_return_null=.true.)
1327 END IF
1328
1329 CALL prepare_dr1dr(dr1dr, drho, drho1)
1330
1331 IF (lsd) THEN
1332 CALL prepare_dr1dr(dra1dra, drhoa, drho1a)
1333 CALL prepare_dr1dr(drb1drb, drhob, drho1b)
1334
1335 CALL allocate_pw(v_drho, pw_pool, bo)
1336 CALL allocate_pw(v_drhoa, pw_pool, bo)
1337 CALL allocate_pw(v_drhob, pw_pool, bo)
1338
1339 IF (ASSOCIATED(norm_drhoa)) CALL apply_drho(deriv_set, [deriv_norm_drhoa], virial_pw, &
1340 drhoa, drho1a, virial_xc, &
1341 norm_drhoa, gradient_cut, dra1dra, v_drhoa%array)
1342 IF (ASSOCIATED(norm_drhob)) CALL apply_drho(deriv_set, [deriv_norm_drhob], virial_pw, &
1343 drhob, drho1b, virial_xc, &
1344 norm_drhob, gradient_cut, drb1drb, v_drhob%array)
1345 IF (ASSOCIATED(norm_drho)) CALL apply_drho(deriv_set, [deriv_norm_drho], virial_pw, &
1346 drho, drho1, virial_xc, &
1347 norm_drho, gradient_cut, dr1dr, v_drho%array)
1348 IF (laplace_f) THEN
1349 CALL xc_derivative_get(xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa]), deriv_data=deriv_data)
1350 cpassert(ASSOCIATED(deriv_data))
1351 virial_pw%array(:, :, :) = -rho1a(:, :, :)
1352 CALL virial_laplace(virial_pw, pw_pool, virial_xc, deriv_data)
1353
1354 CALL allocate_pw(v_laplacea, pw_pool, bo)
1355
1356 CALL xc_derivative_get(xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob]), deriv_data=deriv_data)
1357 cpassert(ASSOCIATED(deriv_data))
1358 virial_pw%array(:, :, :) = -rho1b(:, :, :)
1359 CALL virial_laplace(virial_pw, pw_pool, virial_xc, deriv_data)
1360
1361 CALL allocate_pw(v_laplaceb, pw_pool, bo)
1362 END IF
1363
1364 ELSE
1365
1366 ! Create the work grid for the potential of the gradient part
1367 CALL allocate_pw(v_drho, pw_pool, bo)
1368
1369 CALL apply_drho(deriv_set, [deriv_norm_drho], virial_pw, drho, drho1, virial_xc, &
1370 norm_drho, gradient_cut, dr1dr, v_drho%array)
1371 IF (laplace_f) THEN
1372 CALL xc_derivative_get(xc_dset_get_derivative(deriv_set, [deriv_laplace_rho]), deriv_data=deriv_data)
1373 cpassert(ASSOCIATED(deriv_data))
1374 virial_pw%array(:, :, :) = -rho1(:, :, :)
1375 CALL virial_laplace(virial_pw, pw_pool, virial_xc, deriv_data)
1376
1377 CALL allocate_pw(v_laplace, pw_pool, bo)
1378 END IF
1379
1380 END IF
1381
1382 IF (lsd) THEN
1383 rho_r(1)%array = rhoa
1384 rho_r(2)%array = rhob
1385 ELSE
1386 rho_r(1)%array = rho
1387 END IF
1388 IF (ASSOCIATED(tau1_r)) THEN
1389 IF (lsd) THEN
1390 tau_r(1)%array = tau_a
1391 tau_r(2)%array = tau_b
1392 ELSE
1393 tau_r(1)%array = tau
1394 END IF
1395 END IF
1396
1397 ! Create deriv sets with same densities but different gradients
1398 CALL xc_dset_create(deriv_set1, pw_pool)
1399
1400 rho_cutoff = section_get_rval(xc_section, "DENSITY_CUTOFF")
1401
1402 ! create the place where to store the argument for the functionals
1403 CALL xc_rho_set_create(rho2_set, bo, &
1404 rho_cutoff=rho_cutoff, &
1405 drho_cutoff=section_get_rval(xc_section, "GRADIENT_CUTOFF"), &
1406 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
1407
1408 ! calculate the arguments needed by the functionals
1409 CALL xc_rho_set_update(rho2_set, rho_r, rho_g, tau_r, needs, &
1410 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
1411 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
1412 pw_pool)
1413
1414 IF (lsd) THEN
1415 CALL xc_rho_set_get(rho1_set, rhoa=rho1a, rhob=rho1b, tau_a=tau1a, tau_b=tau1b, &
1416 laplace_rhoa=laplace1a, laplace_rhob=laplace1b, can_return_null=.true.)
1417 CALL xc_rho_set_get(rho2_set, norm_drhoa=norm_drho2a, norm_drhob=norm_drho2b, &
1418 norm_drho=norm_drho2, laplace_rhoa=laplace2a, laplace_rhob=laplace2b, can_return_null=.true.)
1419
1420 DO istep = -nsteps, nsteps
1421 IF (istep == 0) cycle
1422 rweight = rweights(istep, nsteps)/h
1423 step = real(istep, dp)*h
1424 IF (ASSOCIATED(norm_drhoa)) THEN
1425 CALL get_derivs_rho(norm_drho2a, norm_drhoa, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1426 CALL update_deriv_rho(deriv_set1, [deriv_rhoa], bo, &
1427 norm_drhoa, gradient_cut, rweight, rho1a, v_drhoa%array)
1428 CALL update_deriv_rho(deriv_set1, [deriv_rhob], bo, &
1429 norm_drhoa, gradient_cut, rweight, rho1b, v_drhoa%array)
1430 CALL update_deriv_rho(deriv_set1, [deriv_norm_drhoa], bo, &
1431 norm_drhoa, gradient_cut, rweight, dra1dra, v_drhoa%array)
1432 CALL update_deriv_drho_ab(deriv_set1, [deriv_norm_drhob], bo, &
1433 norm_drhoa, gradient_cut, rweight, dra1dra, drb1drb, v_drhoa%array, v_drhob%array)
1434 CALL update_deriv_drho_ab(deriv_set1, [deriv_norm_drho], bo, &
1435 norm_drhoa, gradient_cut, rweight, dra1dra, dr1dr, v_drhoa%array, v_drho%array)
1436 IF (tau_f) THEN
1437 CALL update_deriv_rho(deriv_set1, [deriv_tau_a], bo, &
1438 norm_drhoa, gradient_cut, rweight, tau1a, v_drhoa%array)
1439 CALL update_deriv_rho(deriv_set1, [deriv_tau_b], bo, &
1440 norm_drhoa, gradient_cut, rweight, tau1b, v_drhoa%array)
1441 END IF
1442 IF (laplace_f) THEN
1443 CALL update_deriv_rho(deriv_set1, [deriv_laplace_rhoa], bo, &
1444 norm_drhoa, gradient_cut, rweight, laplace1a, v_drhoa%array)
1445 CALL update_deriv_rho(deriv_set1, [deriv_laplace_rhob], bo, &
1446 norm_drhoa, gradient_cut, rweight, laplace1b, v_drhoa%array)
1447 END IF
1448 END IF
1449
1450 IF (ASSOCIATED(norm_drhob)) THEN
1451 CALL get_derivs_rho(norm_drho2b, norm_drhob, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1452 CALL update_deriv_rho(deriv_set1, [deriv_rhoa], bo, &
1453 norm_drhob, gradient_cut, rweight, rho1a, v_drhob%array)
1454 CALL update_deriv_rho(deriv_set1, [deriv_rhob], bo, &
1455 norm_drhob, gradient_cut, rweight, rho1b, v_drhob%array)
1456 CALL update_deriv_rho(deriv_set1, [deriv_norm_drhob], bo, &
1457 norm_drhob, gradient_cut, rweight, drb1drb, v_drhob%array)
1458 CALL update_deriv_drho_ab(deriv_set1, [deriv_norm_drhoa], bo, &
1459 norm_drhob, gradient_cut, rweight, drb1drb, dra1dra, v_drhob%array, v_drhoa%array)
1460 CALL update_deriv_drho_ab(deriv_set1, [deriv_norm_drho], bo, &
1461 norm_drhob, gradient_cut, rweight, drb1drb, dr1dr, v_drhob%array, v_drho%array)
1462 IF (tau_f) THEN
1463 CALL update_deriv_rho(deriv_set1, [deriv_tau_a], bo, &
1464 norm_drhob, gradient_cut, rweight, tau1a, v_drhob%array)
1465 CALL update_deriv_rho(deriv_set1, [deriv_tau_b], bo, &
1466 norm_drhob, gradient_cut, rweight, tau1b, v_drhob%array)
1467 END IF
1468 IF (laplace_f) THEN
1469 CALL update_deriv_rho(deriv_set1, [deriv_laplace_rhoa], bo, &
1470 norm_drhob, gradient_cut, rweight, laplace1a, v_drhob%array)
1471 CALL update_deriv_rho(deriv_set1, [deriv_laplace_rhob], bo, &
1472 norm_drhob, gradient_cut, rweight, laplace1b, v_drhob%array)
1473 END IF
1474 END IF
1475
1476 IF (ASSOCIATED(norm_drho)) THEN
1477 CALL get_derivs_rho(norm_drho2, norm_drho, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1478 CALL update_deriv_rho(deriv_set1, [deriv_rhoa], bo, &
1479 norm_drho, gradient_cut, rweight, rho1a, v_drho%array)
1480 CALL update_deriv_rho(deriv_set1, [deriv_rhob], bo, &
1481 norm_drho, gradient_cut, rweight, rho1b, v_drho%array)
1482 CALL update_deriv_rho(deriv_set1, [deriv_norm_drho], bo, &
1483 norm_drho, gradient_cut, rweight, dr1dr, v_drho%array)
1484 CALL update_deriv_drho_ab(deriv_set1, [deriv_norm_drhoa], bo, &
1485 norm_drho, gradient_cut, rweight, dr1dr, dra1dra, v_drho%array, v_drhoa%array)
1486 CALL update_deriv_drho_ab(deriv_set1, [deriv_norm_drhob], bo, &
1487 norm_drho, gradient_cut, rweight, dr1dr, drb1drb, v_drho%array, v_drhob%array)
1488 IF (tau_f) THEN
1489 CALL update_deriv_rho(deriv_set1, [deriv_tau_a], bo, &
1490 norm_drho, gradient_cut, rweight, tau1a, v_drho%array)
1491 CALL update_deriv_rho(deriv_set1, [deriv_tau_b], bo, &
1492 norm_drho, gradient_cut, rweight, tau1b, v_drho%array)
1493 END IF
1494 IF (laplace_f) THEN
1495 CALL update_deriv_rho(deriv_set1, [deriv_laplace_rhoa], bo, &
1496 norm_drho, gradient_cut, rweight, laplace1a, v_drho%array)
1497 CALL update_deriv_rho(deriv_set1, [deriv_laplace_rhob], bo, &
1498 norm_drho, gradient_cut, rweight, laplace1b, v_drho%array)
1499 END IF
1500 END IF
1501
1502 IF (laplace_f) THEN
1503
1504 CALL get_derivs_rho(laplace2a, laplacea, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1505
1506 ! Obtain the numerical 2nd derivatives w.r.t. to drho and collect the potential
1507 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_rhoa], bo, &
1508 rweight, rho1a, v_laplacea%array)
1509 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_rhob], bo, &
1510 rweight, rho1b, v_laplacea%array)
1511 IF (ASSOCIATED(norm_drho)) THEN
1512 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_norm_drho], bo, &
1513 rweight, dr1dr, v_laplacea%array)
1514 END IF
1515 IF (ASSOCIATED(norm_drhoa)) THEN
1516 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_norm_drhoa], bo, &
1517 rweight, dra1dra, v_laplacea%array)
1518 END IF
1519 IF (ASSOCIATED(norm_drhob)) THEN
1520 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_norm_drhob], bo, &
1521 rweight, drb1drb, v_laplacea%array)
1522 END IF
1523
1524 IF (ASSOCIATED(tau1a)) THEN
1525 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_tau_a], bo, &
1526 rweight, tau1a, v_laplacea%array)
1527 END IF
1528 IF (ASSOCIATED(tau1b)) THEN
1529 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_tau_b], bo, &
1530 rweight, tau1b, v_laplacea%array)
1531 END IF
1532
1533 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_laplace_rhoa], bo, &
1534 rweight, laplace1a, v_laplacea%array)
1535
1536 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_laplace_rhob], bo, &
1537 rweight, laplace1b, v_laplacea%array)
1538
1539 ! The same for the beta spin
1540 CALL get_derivs_rho(laplace2b, laplaceb, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1541
1542 ! Obtain the numerical 2nd derivatives w.r.t. to drho and collect the potential
1543 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_rhoa], bo, &
1544 rweight, rho1a, v_laplaceb%array)
1545 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_rhob], bo, &
1546 rweight, rho1b, v_laplaceb%array)
1547 IF (ASSOCIATED(norm_drho)) THEN
1548 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_norm_drho], bo, &
1549 rweight, dr1dr, v_laplaceb%array)
1550 END IF
1551 IF (ASSOCIATED(norm_drhoa)) THEN
1552 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_norm_drhoa], bo, &
1553 rweight, dra1dra, v_laplaceb%array)
1554 END IF
1555 IF (ASSOCIATED(norm_drhob)) THEN
1556 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_norm_drhob], bo, &
1557 rweight, drb1drb, v_laplaceb%array)
1558 END IF
1559
1560 IF (tau_f) THEN
1561 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_tau_a], bo, &
1562 rweight, tau1a, v_laplaceb%array)
1563 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_tau_b], bo, &
1564 rweight, tau1b, v_laplaceb%array)
1565 END IF
1566
1567 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_laplace_rhoa], bo, &
1568 rweight, laplace1a, v_laplaceb%array)
1569
1570 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_laplace_rhob], bo, &
1571 rweight, laplace1b, v_laplaceb%array)
1572 END IF
1573 END DO
1574
1575 CALL virial_drho_drho(virial_pw, drhoa, v_drhoa, virial_xc)
1576 CALL virial_drho_drho(virial_pw, drhob, v_drhob, virial_xc)
1577 CALL virial_drho_drho(virial_pw, drho, v_drho, virial_xc)
1578
1579 CALL deallocate_pw(v_drho, pw_pool)
1580 CALL deallocate_pw(v_drhoa, pw_pool)
1581 CALL deallocate_pw(v_drhob, pw_pool)
1582
1583 IF (laplace_f) THEN
1584 virial_pw%array(:, :, :) = -rhoa(:, :, :)
1585 CALL virial_laplace(virial_pw, pw_pool, virial_xc, v_laplacea%array)
1586 CALL deallocate_pw(v_laplacea, pw_pool)
1587
1588 virial_pw%array(:, :, :) = -rhob(:, :, :)
1589 CALL virial_laplace(virial_pw, pw_pool, virial_xc, v_laplaceb%array)
1590 CALL deallocate_pw(v_laplaceb, pw_pool)
1591 END IF
1592
1593 CALL deallocate_pw(virial_pw, pw_pool)
1594
1595 DO idir = 1, 3
1596 DEALLOCATE (drho(idir)%array)
1597 DEALLOCATE (drho1(idir)%array)
1598 END DO
1599 DEALLOCATE (dra1dra, drb1drb)
1600
1601 ELSE
1602 CALL xc_rho_set_get(rho1_set, rho=rho1, tau=tau1, laplace_rho=laplace1, can_return_null=.true.)
1603 CALL xc_rho_set_get(rho2_set, norm_drho=norm_drho2, laplace_rho=laplace2, can_return_null=.true.)
1604
1605 DO istep = -nsteps, nsteps
1606 IF (istep == 0) cycle
1607 rweight = rweights(istep, nsteps)/h
1608 step = real(istep, dp)*h
1609 CALL get_derivs_rho(norm_drho2, norm_drho, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1610
1611 ! Obtain the numerical 2nd derivatives w.r.t. to drho and collect the potential
1612 CALL update_deriv_rho(deriv_set1, [deriv_rho], bo, &
1613 norm_drho, gradient_cut, rweight, rho1, v_drho%array)
1614 CALL update_deriv_rho(deriv_set1, [deriv_norm_drho], bo, &
1615 norm_drho, gradient_cut, rweight, dr1dr, v_drho%array)
1616
1617 IF (tau_f) THEN
1618 CALL update_deriv_rho(deriv_set1, [deriv_tau], bo, &
1619 norm_drho, gradient_cut, rweight, tau1, v_drho%array)
1620 END IF
1621 IF (laplace_f) THEN
1622 CALL update_deriv_rho(deriv_set1, [deriv_laplace_rho], bo, &
1623 norm_drho, gradient_cut, rweight, laplace1, v_drho%array)
1624
1625 CALL get_derivs_rho(laplace2, laplace, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1626
1627 ! Obtain the numerical 2nd derivatives w.r.t. to drho and collect the potential
1628 CALL update_deriv(deriv_set1, laplace, rho_cutoff, [deriv_rho], bo, &
1629 rweight, rho1, v_laplace%array)
1630 CALL update_deriv(deriv_set1, laplace, rho_cutoff, [deriv_norm_drho], bo, &
1631 rweight, dr1dr, v_laplace%array)
1632
1633 IF (tau_f) THEN
1634 CALL update_deriv(deriv_set1, laplace, rho_cutoff, [deriv_tau], bo, &
1635 rweight, tau1, v_laplace%array)
1636 END IF
1637
1638 CALL update_deriv(deriv_set1, laplace, rho_cutoff, [deriv_laplace_rho], bo, &
1639 rweight, laplace1, v_laplace%array)
1640 END IF
1641 END DO
1642
1643 ! Calculate the virial contribution from the potential
1644 CALL virial_drho_drho(virial_pw, drho, v_drho, virial_xc)
1645
1646 CALL deallocate_pw(v_drho, pw_pool)
1647
1648 IF (laplace_f) THEN
1649 virial_pw%array(:, :, :) = -rho(:, :, :)
1650 CALL virial_laplace(virial_pw, pw_pool, virial_xc, v_laplace%array)
1651 CALL deallocate_pw(v_laplace, pw_pool)
1652 END IF
1653
1654 CALL deallocate_pw(virial_pw, pw_pool)
1655 END IF
1656
1657 END IF
1658
1659 CALL xc_dset_release(deriv_set1)
1660
1661 DEALLOCATE (dr1dr)
1662
1663 CALL xc_rho_set_release(rho1_set)
1664 CALL xc_rho_set_release(rho2_set)
1665 END IF
1666
1667 DO ispin = 1, SIZE(rho_r)
1668 CALL pw_pool%give_back_pw(rho_r(ispin))
1669 END DO
1670 DEALLOCATE (rho_r)
1671
1672 IF (ASSOCIATED(tau_r)) THEN
1673 DO ispin = 1, SIZE(tau_r)
1674 CALL pw_pool%give_back_pw(tau_r(ispin))
1675 END DO
1676 DEALLOCATE (tau_r)
1677 END IF
1678
1679 CALL timestop(handle)
1680
1681 END SUBROUTINE xc_calc_2nd_deriv_numerical
1682
1683! **************************************************************************************************
1684!> \brief ...
1685!> \param rho_r ...
1686!> \param rho_g ...
1687!> \param rho1_r ...
1688!> \param rhoa ...
1689!> \param rhob ...
1690!> \param vxc_rho ...
1691!> \param tau_r ...
1692!> \param tau1_r ...
1693!> \param tau_a ...
1694!> \param tau_b ...
1695!> \param vxc_tau ...
1696!> \param xc_section ...
1697!> \param pw_pool ...
1698!> \param step ...
1699! **************************************************************************************************
1700 SUBROUTINE calc_resp_potential_numer_ab(rho_r, rho_g, rho1_r, rhoa, rhob, vxc_rho, &
1701 tau_r, tau1_r, tau_a, tau_b, vxc_tau, &
1702 xc_section, weights, pw_pool, step)
1703
1704 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER, INTENT(IN) :: vxc_rho, vxc_tau
1705 TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(IN) :: rho1_r
1706 TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(IN), POINTER :: tau1_r
1707 TYPE(pw_r3d_rs_type), INTENT(IN), POINTER :: weights
1708 TYPE(pw_pool_type), INTENT(IN), POINTER :: pw_pool
1709 TYPE(section_vals_type), INTENT(IN), POINTER :: xc_section
1710 REAL(kind=dp), INTENT(IN) :: step
1711 REAL(kind=dp), DIMENSION(:, :, :), POINTER, INTENT(IN) :: rhoa, rhob, tau_a, tau_b
1712 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER, INTENT(IN) :: rho_r
1713 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
1714 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: tau_r
1715
1716 CHARACTER(len=*), PARAMETER :: routinen = 'calc_resp_potential_numer_ab'
1717
1718 INTEGER :: handle
1719 REAL(kind=dp) :: exc
1720 REAL(kind=dp), DIMENSION(3, 3) :: virial_dummy
1721
1722 CALL timeset(routinen, handle)
1723
1724!$OMP PARALLEL DEFAULT(NONE) SHARED(rho_r,rhoa,rhob,step,rho1_r,tau_r,tau_a,tau_b,tau1_r)
1725!$OMP WORKSHARE
1726 rho_r(1)%array(:, :, :) = rhoa(:, :, :) + step*rho1_r(1)%array(:, :, :)
1727!$OMP END WORKSHARE NOWAIT
1728!$OMP WORKSHARE
1729 rho_r(2)%array(:, :, :) = rhob(:, :, :) + step*rho1_r(2)%array(:, :, :)
1730!$OMP END WORKSHARE NOWAIT
1731 IF (ASSOCIATED(tau1_r) .AND. ASSOCIATED(tau_r) .AND. ASSOCIATED(tau_a) .AND. ASSOCIATED(tau_b)) THEN
1732!$OMP WORKSHARE
1733 tau_r(1)%array(:, :, :) = tau_a(:, :, :) + step*tau1_r(1)%array(:, :, :)
1734!$OMP END WORKSHARE NOWAIT
1735!$OMP WORKSHARE
1736 tau_r(2)%array(:, :, :) = tau_b(:, :, :) + step*tau1_r(2)%array(:, :, :)
1737!$OMP END WORKSHARE NOWAIT
1738 END IF
1739!$OMP END PARALLEL
1740 CALL xc_vxc_pw_create(vxc_rho, vxc_tau, exc, rho_r, rho_g, tau_r, xc_section, &
1741 weights, pw_pool, .false., virial_dummy)
1742
1743 CALL timestop(handle)
1744
1745 END SUBROUTINE calc_resp_potential_numer_ab
1746
1747! **************************************************************************************************
1748!> \brief calculates stress tensor and potential contributions from the first derivative
1749!> \param deriv_set ...
1750!> \param description ...
1751!> \param virial_pw ...
1752!> \param drho ...
1753!> \param drho1 ...
1754!> \param virial_xc ...
1755!> \param norm_drho ...
1756!> \param gradient_cut ...
1757!> \param dr1dr ...
1758!> \param v_drho ...
1759! **************************************************************************************************
1760 SUBROUTINE apply_drho(deriv_set, description, virial_pw, drho, drho1, &
1761 virial_xc, norm_drho, gradient_cut, dr1dr, v_drho)
1762
1763 TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set
1764 INTEGER, DIMENSION(:), INTENT(in) :: description
1765 TYPE(pw_r3d_rs_type), INTENT(IN) :: virial_pw
1766 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(IN) :: drho, drho1
1767 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT) :: virial_xc
1768 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: norm_drho
1769 REAL(kind=dp), INTENT(IN) :: gradient_cut
1770 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: dr1dr
1771 REAL(kind=dp), DIMENSION(:, :, :), INTENT(INOUT) :: v_drho
1772
1773 CHARACTER(len=*), PARAMETER :: routinen = 'apply_drho'
1774
1775 INTEGER :: handle
1776 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: deriv_data
1777 TYPE(xc_derivative_type), POINTER :: deriv_att
1778
1779 CALL timeset(routinen, handle)
1780
1781 deriv_att => xc_dset_get_derivative(deriv_set, description)
1782 IF (ASSOCIATED(deriv_att)) THEN
1783 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
1784 CALL virial_drho_drho1(virial_pw, drho, drho1, deriv_data, virial_xc)
1785
1786!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dr1dr,gradient_cut,norm_drho,v_drho,deriv_data)
1787 v_drho(:, :, :) = v_drho(:, :, :) + &
1788 deriv_data(:, :, :)*dr1dr(:, :, :)/max(gradient_cut, norm_drho(:, :, :))**2
1789!$OMP END PARALLEL WORKSHARE
1790 END IF
1791
1792 CALL timestop(handle)
1793
1794 END SUBROUTINE apply_drho
1795
1796! **************************************************************************************************
1797!> \brief adds potential contributions from derivatives of rho or diagonal terms of norm_drho
1798!> \param deriv_set1 ...
1799!> \param description ...
1800!> \param bo ...
1801!> \param norm_drho norm_drho of which derivative is calculated
1802!> \param gradient_cut ...
1803!> \param h ...
1804!> \param rho1 function to contract the derivative with (rho1 for rho, dr1dr for norm_drho)
1805!> \param v_drho ...
1806! **************************************************************************************************
1807 SUBROUTINE update_deriv_rho(deriv_set1, description, bo, norm_drho, gradient_cut, weight, rho1, v_drho)
1808
1809 TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set1
1810 INTEGER, DIMENSION(:), INTENT(in) :: description
1811 INTEGER, DIMENSION(2, 3), INTENT(IN) :: bo
1812 REAL(kind=dp), DIMENSION(bo(1, 1):bo(2, 1), bo(1, & 2):bo(2, 2), bo(1, 3):bo(2, 3)), INTENT(IN) :: norm_drho
1813 REAL(kind=dp), INTENT(IN) :: gradient_cut, weight
1814 REAL(kind=dp), DIMENSION(bo(1, 1):bo(2, 1), bo(1, & 2):bo(2, 2), bo(1, 3):bo(2, 3)), INTENT(IN) :: rho1
1815 REAL(kind=dp), DIMENSION(bo(1, 1):bo(2, 1), bo(1, & 2):bo(2, 2), bo(1, 3):bo(2, 3)), INTENT(INOUT) :: v_drho
1816
1817 CHARACTER(len=*), PARAMETER :: routinen = 'update_deriv_rho'
1818
1819 INTEGER :: handle, i, j, k
1820 REAL(kind=dp) :: de
1821 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: deriv_data1
1822 TYPE(xc_derivative_type), POINTER :: deriv_att1
1823
1824 CALL timeset(routinen, handle)
1825
1826 ! Obtain the numerical 2nd derivatives w.r.t. to drho and collect the potential
1827 deriv_att1 => xc_dset_get_derivative(deriv_set1, description)
1828 IF (ASSOCIATED(deriv_att1)) THEN
1829 CALL xc_derivative_get(deriv_att1, deriv_data=deriv_data1)
1830!$OMP PARALLEL DO DEFAULT(NONE) &
1831!$OMP SHARED(bo,deriv_data1,weight,norm_drho,v_drho,rho1,gradient_cut) &
1832!$OMP PRIVATE(i,j,k,de) &
1833!$OMP COLLAPSE(3)
1834 DO k = bo(1, 3), bo(2, 3)
1835 DO j = bo(1, 2), bo(2, 2)
1836 DO i = bo(1, 1), bo(2, 1)
1837 de = weight*deriv_data1(i, j, k)/max(gradient_cut, norm_drho(i, j, k))**2
1838 v_drho(i, j, k) = v_drho(i, j, k) - de*rho1(i, j, k)
1839 END DO
1840 END DO
1841 END DO
1842!$OMP END PARALLEL DO
1843 END IF
1844
1845 CALL timestop(handle)
1846
1847 END SUBROUTINE update_deriv_rho
1848
1849! **************************************************************************************************
1850!> \brief adds potential contributions from derivatives of a component with positive and negative values
1851!> \param deriv_set1 ...
1852!> \param description ...
1853!> \param bo ...
1854!> \param h ...
1855!> \param rho1 function to contract the derivative with (rho1 for rho, dr1dr for norm_drho)
1856!> \param v ...
1857! **************************************************************************************************
1858 SUBROUTINE update_deriv(deriv_set1, rho, rho_cutoff, description, bo, weight, rho1, v)
1859
1860 TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set1
1861 INTEGER, DIMENSION(:), INTENT(in) :: description
1862 INTEGER, DIMENSION(2, 3), INTENT(IN) :: bo
1863 REAL(kind=dp), INTENT(IN) :: weight, rho_cutoff
1864 REAL(kind=dp), DIMENSION(bo(1, 1):bo(2, 1), bo(1, & 2):bo(2, 2), bo(1, 3):bo(2, 3)), INTENT(IN) :: rho, rho1
1865 REAL(kind=dp), DIMENSION(bo(1, 1):bo(2, 1), bo(1, & 2):bo(2, 2), bo(1, 3):bo(2, 3)), INTENT(INOUT) :: v
1866
1867 CHARACTER(len=*), PARAMETER :: routinen = 'update_deriv'
1868
1869 INTEGER :: handle, i, j, k
1870 REAL(kind=dp) :: de
1871 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: deriv_data1
1872 TYPE(xc_derivative_type), POINTER :: deriv_att1
1873
1874 CALL timeset(routinen, handle)
1875
1876 ! Obtain the numerical 2nd derivatives w.r.t. to drho and collect the potential
1877 deriv_att1 => xc_dset_get_derivative(deriv_set1, description)
1878 IF (ASSOCIATED(deriv_att1)) THEN
1879 CALL xc_derivative_get(deriv_att1, deriv_data=deriv_data1)
1880!$OMP PARALLEL DO DEFAULT(NONE) &
1881!$OMP SHARED(bo,deriv_data1,weight,v,rho1,rho, rho_cutoff) &
1882!$OMP PRIVATE(i,j,k,de) &
1883!$OMP COLLAPSE(3)
1884 DO k = bo(1, 3), bo(2, 3)
1885 DO j = bo(1, 2), bo(2, 2)
1886 DO i = bo(1, 1), bo(2, 1)
1887 ! We have to consider that the given density (mostly the Laplacian) may have positive and negative values
1888 de = weight*deriv_data1(i, j, k)/sign(max(abs(rho(i, j, k)), rho_cutoff), rho(i, j, k))
1889 v(i, j, k) = v(i, j, k) + de*rho1(i, j, k)
1890 END DO
1891 END DO
1892 END DO
1893!$OMP END PARALLEL DO
1894 END IF
1895
1896 CALL timestop(handle)
1897
1898 END SUBROUTINE update_deriv
1899
1900! **************************************************************************************************
1901!> \brief adds mixed derivatives of norm_drho
1902!> \param deriv_set1 ...
1903!> \param description ...
1904!> \param bo ...
1905!> \param norm_drhoa norm_drho of which derivatives is calculated
1906!> \param gradient_cut ...
1907!> \param h ...
1908!> \param dra1dra dr1dr corresponding to norm_drho
1909!> \param drb1drb ...
1910!> \param v_drhoa potential corresponding to norm_drho
1911!> \param v_drhob ...
1912! **************************************************************************************************
1913 SUBROUTINE update_deriv_drho_ab(deriv_set1, description, bo, &
1914 norm_drhoa, gradient_cut, weight, dra1dra, drb1drb, v_drhoa, v_drhob)
1915
1916 TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set1
1917 INTEGER, DIMENSION(:), INTENT(in) :: description
1918 INTEGER, DIMENSION(2, 3), INTENT(IN) :: bo
1919 REAL(kind=dp), DIMENSION(bo(1, 1):bo(2, 1), bo(1, & 2):bo(2, 2), bo(1, 3):bo(2, 3)), INTENT(IN) :: norm_drhoa
1920 REAL(kind=dp), INTENT(IN) :: gradient_cut, weight
1921 REAL(kind=dp), DIMENSION(bo(1, 1):bo(2, 1), bo(1, & 2):bo(2, 2), bo(1, 3):bo(2, 3)), INTENT(IN) :: dra1dra, drb1drb
1922 REAL(kind=dp), DIMENSION(bo(1, 1):bo(2, 1), bo(1, & 2):bo(2, 2), bo(1, 3):bo(2, 3)), INTENT(INOUT) :: v_drhoa, v_drhob
1923
1924 CHARACTER(len=*), PARAMETER :: routinen = 'update_deriv_drho_ab'
1925
1926 INTEGER :: handle, i, j, k
1927 REAL(kind=dp) :: de
1928 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: deriv_data1
1929 TYPE(xc_derivative_type), POINTER :: deriv_att1
1930
1931 CALL timeset(routinen, handle)
1932
1933 deriv_att1 => xc_dset_get_derivative(deriv_set1, description)
1934 IF (ASSOCIATED(deriv_att1)) THEN
1935 CALL xc_derivative_get(deriv_att1, deriv_data=deriv_data1)
1936!$OMP PARALLEL DO DEFAULT(NONE) &
1937!$OMP PRIVATE(k,j,i,de) &
1938!$OMP SHARED(bo,drb1drb,dra1dra,deriv_data1,weight,gradient_cut,norm_drhoa,v_drhoa,v_drhob) &
1939!$OMP COLLAPSE(3)
1940 DO k = bo(1, 3), bo(2, 3)
1941 DO j = bo(1, 2), bo(2, 2)
1942 DO i = bo(1, 1), bo(2, 1)
1943 ! We introduce a factor of two because we will average between both numerical derivatives
1944 de = 0.5_dp*weight*deriv_data1(i, j, k)/max(gradient_cut, norm_drhoa(i, j, k))**2
1945 v_drhoa(i, j, k) = v_drhoa(i, j, k) - de*drb1drb(i, j, k)
1946 v_drhob(i, j, k) = v_drhob(i, j, k) - de*dra1dra(i, j, k)
1947 END DO
1948 END DO
1949 END DO
1950!$OMP END PARALLEL DO
1951 END IF
1952
1953 CALL timestop(handle)
1954
1955 END SUBROUTINE update_deriv_drho_ab
1956
1957! **************************************************************************************************
1958!> \brief calculate derivative sets for helper points
1959!> \param norm_drho2 norm_drho of new points
1960!> \param norm_drho norm_drho of KS density
1961!> \param h ...
1962!> \param xc_fun_section ...
1963!> \param lsd ...
1964!> \param rho2_set rho_set for new points
1965!> \param deriv_set1 will contain derivatives of the perturbed density
1966! **************************************************************************************************
1967 SUBROUTINE get_derivs_rho(norm_drho2, norm_drho, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1968 REAL(kind=dp), DIMENSION(:, :, :), INTENT(OUT) :: norm_drho2
1969 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: norm_drho
1970 REAL(kind=dp), INTENT(IN) :: step
1971 TYPE(section_vals_type), INTENT(IN), POINTER :: xc_fun_section
1972 LOGICAL, INTENT(IN) :: lsd
1973 TYPE(xc_rho_set_type), INTENT(INOUT) :: rho2_set
1974 TYPE(xc_derivative_set_type) :: deriv_set1
1975
1976 CHARACTER(len=*), PARAMETER :: routinen = 'get_derivs_rho'
1977
1978 INTEGER :: handle
1979
1980 CALL timeset(routinen, handle)
1981
1982 ! Copy the densities, do one step into the direction of drho
1983!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(norm_drho,norm_drho2,step)
1984 norm_drho2 = norm_drho*(1.0_dp + step)
1985!$OMP END PARALLEL WORKSHARE
1986
1987 CALL xc_dset_zero_all(deriv_set1)
1988
1989 ! Calculate the derivatives of the functional
1990 CALL xc_functionals_eval(xc_fun_section, &
1991 lsd=lsd, &
1992 rho_set=rho2_set, &
1993 deriv_set=deriv_set1, &
1994 deriv_order=1)
1995
1996 ! Return to the original values
1997!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(norm_drho,norm_drho2)
1998 norm_drho2 = norm_drho
1999!$OMP END PARALLEL WORKSHARE
2000
2001 CALL divide_by_norm_drho(deriv_set1, rho2_set, lsd)
2002
2003 CALL timestop(handle)
2004
2005 END SUBROUTINE get_derivs_rho
2006
2007! **************************************************************************************************
2008!> \brief Calculates the second derivative of E_xc at rho in the direction
2009!> rho1 (if you see the second derivative as bilinear form)
2010!> partial_rho|_(rho=rho) partial_rho|_(rho=rho) E_xc drho(rho1)drho
2011!> The other direction is still undetermined, thus it returns
2012!> a potential (partial integration is performed to reduce it to
2013!> function of rho, removing the dependence from its partial derivs)
2014!> Has to be called after the setup by xc_prep_2nd_deriv.
2015!> \param v_xc exchange-correlation potential
2016!> \param v_xc_tau ...
2017!> \param deriv_set derivatives of the exchange-correlation potential
2018!> \param rho_set object containing the density at which the derivatives were calculated
2019!> \param rho1_set object containing the density with which to fold
2020!> \param pw_pool the pool for the grids
2021!> \param xc_section XC parameters
2022!> \param gapw Gaussian and augmented plane waves calculation
2023!> \param vxg ...
2024!> \param tddfpt_fac factor that multiplies the crossterms (tddfpt triplets
2025!> on a closed shell system it should be -1, defaults to 1)
2026!> \param compute_virial ...
2027!> \param virial_xc ...
2028!> \note
2029!> The old version of this routine was smarter: it handled split_desc(1)
2030!> and split_desc(2) separately, thus the code automatically handled all
2031!> possible cross terms (you only had to check if it was diagonal to avoid
2032!> double counting). I think that is the way to go if you want to add more
2033!> terms (tau,rho in LSD,...). The problem with the old code was that it
2034!> because of the old functional structure it sometime guessed wrongly
2035!> which derivative was where. There were probably still bugs with gradient
2036!> corrected functionals (never tested), and it didn't contain first
2037!> derivatives with respect to drho (that contribute also to the second
2038!> derivative wrt. rho).
2039!> The code was a little complex because it really tried to handle any
2040!> functional derivative in the most efficient way with the given contents of
2041!> rho_set.
2042!> Anyway I strongly encourage whoever wants to modify this code to give a
2043!> look to the old version. [fawzi]
2044! **************************************************************************************************
2045 SUBROUTINE xc_calc_2nd_deriv_analytical(v_xc, v_xc_tau, deriv_set, rho_set, rho1_set, &
2046 pw_pool, xc_section, gapw, vxg, tddfpt_fac, &
2047 compute_virial, virial_xc, spinflip)
2048
2049 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_xc, v_xc_tau
2050 TYPE(xc_derivative_set_type) :: deriv_set
2051 TYPE(xc_rho_set_type), INTENT(IN) :: rho_set, rho1_set
2052 TYPE(pw_pool_type), POINTER :: pw_pool
2053 TYPE(section_vals_type), POINTER :: xc_section
2054 LOGICAL, INTENT(IN), OPTIONAL :: gapw
2055 REAL(kind=dp), DIMENSION(:, :, :, :), OPTIONAL, &
2056 POINTER :: vxg
2057 REAL(kind=dp), INTENT(in), OPTIONAL :: tddfpt_fac
2058 LOGICAL, INTENT(IN), OPTIONAL :: compute_virial
2059 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT), &
2060 OPTIONAL :: virial_xc
2061 LOGICAL, INTENT(in), OPTIONAL :: spinflip
2062
2063 CHARACTER(len=*), PARAMETER :: routinen = 'xc_calc_2nd_deriv_analytical'
2064
2065 INTEGER :: handle, i, ia, idir, ir, ispin, j, jdir, &
2066 k, nspins, xc_deriv_method_id
2067 INTEGER, DIMENSION(2, 3) :: bo
2068 LOGICAL :: gradient_f, lsd, my_compute_virial, alda0, &
2069 my_gapw, tau_f, laplace_f, rho_f, do_spinflip
2070 REAL(kind=dp) :: fac, gradient_cut, tmp, factor2, s, s_thresh
2071 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: dr1dr, dra1dra, drb1drb
2072 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: deriv_data, deriv_data2, &
2073 e_drhoa, e_drhob, e_drho, norm_drho, norm_drhoa, &
2074 norm_drhob, rho1, rho1a, rho1b, &
2075 tau1, tau1a, tau1b, laplace1, laplace1a, laplace1b, &
2076 rho, rhoa, rhob
2077 TYPE(cp_3d_r_cp_type), DIMENSION(3) :: drho, drho1, drho1a, drho1b, drhoa, drhob
2078 TYPE(pw_r3d_rs_type), DIMENSION(:), ALLOCATABLE :: v_drhoa, v_drhob, v_drho, v_laplace
2079 TYPE(pw_r3d_rs_type), DIMENSION(:, :), ALLOCATABLE :: v_drho_r
2080 TYPE(pw_r3d_rs_type) :: virial_pw
2081 TYPE(pw_c1d_gs_type) :: tmp_g, vxc_g
2082 TYPE(xc_derivative_type), POINTER :: deriv_att
2083
2084 CALL timeset(routinen, handle)
2085
2086 NULLIFY (e_drhoa, e_drhob, e_drho)
2087
2088 my_gapw = .false.
2089 IF (PRESENT(gapw)) my_gapw = gapw
2090
2091 my_compute_virial = .false.
2092 IF (PRESENT(compute_virial)) my_compute_virial = compute_virial
2093
2094 cpassert(ASSOCIATED(v_xc))
2095 cpassert(ASSOCIATED(xc_section))
2096 IF (my_gapw) THEN
2097 cpassert(PRESENT(vxg))
2098 END IF
2099 IF (my_compute_virial) THEN
2100 cpassert(PRESENT(virial_xc))
2101 END IF
2102
2103 CALL section_vals_val_get(xc_section, "XC_GRID%XC_DERIV", &
2104 i_val=xc_deriv_method_id)
2105 CALL xc_rho_set_get(rho_set, drho_cutoff=gradient_cut)
2106 nspins = SIZE(v_xc)
2107 lsd = ASSOCIATED(rho_set%rhoa)
2108 fac = 0.0_dp
2109 factor2 = 1.0_dp
2110 IF (PRESENT(tddfpt_fac)) fac = tddfpt_fac
2111 IF (PRESENT(tddfpt_fac)) factor2 = tddfpt_fac
2112 do_spinflip = .false.
2113 IF (PRESENT(spinflip)) do_spinflip = spinflip
2114
2115 bo = rho_set%local_bounds
2116
2117 CALL check_for_derivatives(deriv_set, lsd, rho_f, gradient_f, tau_f, laplace_f)
2118
2119 alda0 = .false.
2120 IF (gradient_f) THEN
2121 s_thresh = 1.0e-04
2122 ELSE
2123 s_thresh = 1.0e-10
2124 END IF
2125
2126 IF (tau_f) THEN
2127 cpassert(ASSOCIATED(v_xc_tau))
2128 END IF
2129
2130 IF (gradient_f) THEN
2131 ALLOCATE (v_drho_r(3, nspins), v_drho(nspins))
2132 DO ispin = 1, nspins
2133 DO idir = 1, 3
2134 CALL allocate_pw(v_drho_r(idir, ispin), pw_pool, bo)
2135 END DO
2136 CALL allocate_pw(v_drho(ispin), pw_pool, bo)
2137 END DO
2138
2139 IF (xc_requires_tmp_g(xc_deriv_method_id) .AND. .NOT. my_gapw) THEN
2140 IF (ASSOCIATED(pw_pool)) THEN
2141 CALL pw_pool%create_pw(tmp_g)
2142 CALL pw_pool%create_pw(vxc_g)
2143 ELSE
2144 ! remember to refix for gapw
2145 cpabort("XC_DERIV method is not implemented in GAPW")
2146 END IF
2147 END IF
2148 END IF
2149
2150 DO ispin = 1, nspins
2151 v_xc(ispin)%array = 0.0_dp
2152 END DO
2153
2154 IF (tau_f) THEN
2155 DO ispin = 1, nspins
2156 v_xc_tau(ispin)%array = 0.0_dp
2157 END DO
2158 END IF
2159
2160 IF (laplace_f .AND. my_gapw) THEN
2161 cpabort("Laplace-dependent functional not implemented with GAPW!")
2162 END IF
2163
2164 IF (my_compute_virial .AND. (gradient_f .OR. laplace_f)) CALL allocate_pw(virial_pw, pw_pool, bo)
2165
2166 IF (lsd) THEN
2167
2168 !-------------------!
2169 ! UNrestricted case !
2170 !-------------------!
2171
2172 IF (do_spinflip) THEN
2173 CALL xc_rho_set_get(rho1_set, rhoa=rho1a)
2174 CALL xc_rho_set_get(rho_set, rhoa=rhoa, rhob=rhob)
2175 ELSE
2176 CALL xc_rho_set_get(rho1_set, rhoa=rho1a, rhob=rho1b)
2177 END IF
2178
2179 IF (gradient_f) THEN
2180 CALL xc_rho_set_get(rho_set, drhoa=drhoa, drhob=drhob, &
2181 norm_drho=norm_drho, norm_drhoa=norm_drhoa, norm_drhob=norm_drhob)
2182 IF (do_spinflip) THEN
2183 CALL xc_rho_set_get(rho1_set, drhoa=drho1a)
2184 CALL calc_drho_from_a(drho1, drho1a)
2185 ELSE
2186 CALL xc_rho_set_get(rho1_set, drhoa=drho1a, drhob=drho1b)
2187 CALL calc_drho_from_ab(drho1, drho1a, drho1b)
2188 END IF
2189
2190 CALL calc_drho_from_ab(drho, drhoa, drhob)
2191
2192 CALL prepare_dr1dr(dra1dra, drhoa, drho1a)
2193 IF (do_spinflip) THEN
2194 CALL prepare_dr1dr(drb1drb, drhob, drho1a)
2195 CALL prepare_dr1dr(dr1dr, drho, drho1a)
2196 ELSE IF (nspins /= 1) THEN
2197 CALL prepare_dr1dr(drb1drb, drhob, drho1b)
2198 CALL prepare_dr1dr(dr1dr, drho, drho1)
2199 ELSE
2200 CALL prepare_dr1dr(drb1drb, drhob, drho1b)
2201 CALL prepare_dr1dr_ab(dr1dr, drhoa, drhob, drho1a, drho1b, fac)
2202 END IF
2203
2204 ALLOCATE (v_drhoa(nspins), v_drhob(nspins))
2205 DO ispin = 1, nspins
2206 CALL allocate_pw(v_drhoa(ispin), pw_pool, bo)
2207 CALL allocate_pw(v_drhob(ispin), pw_pool, bo)
2208 END DO
2209
2210 END IF
2211
2212 IF (laplace_f) THEN
2213 CALL xc_rho_set_get(rho1_set, laplace_rhoa=laplace1a, laplace_rhob=laplace1b)
2214
2215 ALLOCATE (v_laplace(nspins))
2216 DO ispin = 1, nspins
2217 CALL allocate_pw(v_laplace(ispin), pw_pool, bo)
2218 END DO
2219
2220 IF (my_compute_virial) CALL xc_rho_set_get(rho_set, rhoa=rhoa, rhob=rhob)
2221 END IF
2222
2223 IF (tau_f) THEN
2224 CALL xc_rho_set_get(rho1_set, tau_a=tau1a, tau_b=tau1b)
2225 END IF
2226
2227 IF (do_spinflip) THEN
2228
2229 ! vxc contributions
2230 ! vxc = (vxc^{\alpha}-vxc^{\beta})*rho1/(rhoa-rhob)
2231 ! Alpha LDA contribution
2232 ! | d e_xc d e_xc | rho1a
2233 ! vxca = |-------- - --------|*-------------
2234 ! | drhoa drhob | |rhoa - rhob|
2235 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa])
2236 IF (ASSOCIATED(deriv_att)) THEN
2237 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2238 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob])
2239 IF (ASSOCIATED(deriv_att)) THEN
2240 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
2241!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
2242!$OMP SHARED(bo,v_xc,deriv_data,deriv_data2,rho1a,rhoa,rhob,S_THRESH) COLLAPSE(3)
2243 DO k = bo(1, 3), bo(2, 3)
2244 DO j = bo(1, 2), bo(2, 2)
2245 DO i = bo(1, 1), bo(2, 1)
2246 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
2247 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2248 (deriv_data(i, j, k) - deriv_data2(i, j, k))*rho1a(i, j, k)/s
2249 END DO
2250 END DO
2251 END DO
2252!$OMP END PARALLEL DO
2253 END IF
2254 END IF
2255 ! GGA contributions to the spin-flip xcKernel
2256 ! GGA contribution
2257 ! | d e_xc d e_xc | 1
2258 ! vxca += |----------* dra1dra - ----------*drb1drb|*-------------
2259 ! | d|drhoa| d|drhob| | |rhoa - rhob|
2260 IF (.NOT. alda0) THEN
2261 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa])
2262 IF (ASSOCIATED(deriv_att)) THEN
2263 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2264 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob])
2265 IF (ASSOCIATED(deriv_att)) THEN
2266 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
2267!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
2268!$OMP SHARED(bo,deriv_data,deriv_data2,dra1dra,drb1drb,v_xc,rhoa,rhob,S_THRESH) COLLAPSE(3)
2269 DO k = bo(1, 3), bo(2, 3)
2270 DO j = bo(1, 2), bo(2, 2)
2271 DO i = bo(1, 1), bo(2, 1)
2272 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
2273 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2274 (deriv_data(i, j, k)*dra1dra(i, j, k) - &
2275 deriv_data2(i, j, k)*drb1drb(i, j, k))/s
2276 END DO
2277 END DO
2278 END DO
2279!$OMP END PARALLEL DO
2280 END IF
2281 END IF
2282 END IF
2283
2284 ELSE IF (nspins /= 1) THEN
2285
2286 ! Compute \sum_{\tau}fxc^{\sigma\tau}*\rho^{\tau}(1) over the grid points
2287 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa])
2288 IF (ASSOCIATED(deriv_att)) THEN
2289 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2290!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2291!$OMP SHARED(bo,v_xc,deriv_data,rho1a,fac) COLLAPSE(3)
2292 DO k = bo(1, 3), bo(2, 3)
2293 DO j = bo(1, 2), bo(2, 2)
2294 DO i = bo(1, 1), bo(2, 1)
2295 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2296 deriv_data(i, j, k)*rho1a(i, j, k)
2297 END DO
2298 END DO
2299 END DO
2300 END IF
2301 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhob])
2302 IF (ASSOCIATED(deriv_att)) THEN
2303 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2304!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2305!$OMP SHARED(bo,v_xc,deriv_data,rho1b,fac) COLLAPSE(3)
2306 DO k = bo(1, 3), bo(2, 3)
2307 DO j = bo(1, 2), bo(2, 2)
2308 DO i = bo(1, 1), bo(2, 1)
2309 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2310 deriv_data(i, j, k)*rho1b(i, j, k)
2311 END DO
2312 END DO
2313 END DO
2314 END IF
2315 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drho])
2316 IF (ASSOCIATED(deriv_att)) THEN
2317 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2318!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2319!$OMP SHARED(bo,v_xc,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
2320 DO k = bo(1, 3), bo(2, 3)
2321 DO j = bo(1, 2), bo(2, 2)
2322 DO i = bo(1, 1), bo(2, 1)
2323 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2324 deriv_data(i, j, k)*dr1dr(i, j, k)
2325 END DO
2326 END DO
2327 END DO
2328 END IF
2329 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drhoa])
2330 IF (ASSOCIATED(deriv_att)) THEN
2331 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2332!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2333!$OMP SHARED(bo,v_xc,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
2334 DO k = bo(1, 3), bo(2, 3)
2335 DO j = bo(1, 2), bo(2, 2)
2336 DO i = bo(1, 1), bo(2, 1)
2337 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2338 deriv_data(i, j, k)*dra1dra(i, j, k)
2339 END DO
2340 END DO
2341 END DO
2342 END IF
2343 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drhob])
2344 IF (ASSOCIATED(deriv_att)) THEN
2345 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2346!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2347!$OMP SHARED(bo,v_xc,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
2348 DO k = bo(1, 3), bo(2, 3)
2349 DO j = bo(1, 2), bo(2, 2)
2350 DO i = bo(1, 1), bo(2, 1)
2351 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2352 deriv_data(i, j, k)*drb1drb(i, j, k)
2353 END DO
2354 END DO
2355 END DO
2356 END IF
2357 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_tau_a])
2358 IF (ASSOCIATED(deriv_att)) THEN
2359 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2360!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2361!$OMP SHARED(bo,v_xc,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
2362 DO k = bo(1, 3), bo(2, 3)
2363 DO j = bo(1, 2), bo(2, 2)
2364 DO i = bo(1, 1), bo(2, 1)
2365 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2366 deriv_data(i, j, k)*tau1a(i, j, k)
2367 END DO
2368 END DO
2369 END DO
2370 END IF
2371 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_tau_b])
2372 IF (ASSOCIATED(deriv_att)) THEN
2373 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2374!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2375!$OMP SHARED(bo,v_xc,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
2376 DO k = bo(1, 3), bo(2, 3)
2377 DO j = bo(1, 2), bo(2, 2)
2378 DO i = bo(1, 1), bo(2, 1)
2379 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2380 deriv_data(i, j, k)*tau1b(i, j, k)
2381 END DO
2382 END DO
2383 END DO
2384 END IF
2385 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_laplace_rhoa])
2386 IF (ASSOCIATED(deriv_att)) THEN
2387 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2388!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2389!$OMP SHARED(bo,v_xc,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
2390 DO k = bo(1, 3), bo(2, 3)
2391 DO j = bo(1, 2), bo(2, 2)
2392 DO i = bo(1, 1), bo(2, 1)
2393 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2394 deriv_data(i, j, k)*laplace1a(i, j, k)
2395 END DO
2396 END DO
2397 END DO
2398 END IF
2399 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_laplace_rhob])
2400 IF (ASSOCIATED(deriv_att)) THEN
2401 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2402!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2403!$OMP SHARED(bo,v_xc,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
2404 DO k = bo(1, 3), bo(2, 3)
2405 DO j = bo(1, 2), bo(2, 2)
2406 DO i = bo(1, 1), bo(2, 1)
2407 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2408 deriv_data(i, j, k)*laplace1b(i, j, k)
2409 END DO
2410 END DO
2411 END DO
2412 END IF
2413
2414
2415 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhoa])
2416 IF (ASSOCIATED(deriv_att)) THEN
2417 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2418!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2419!$OMP SHARED(bo,v_xc,deriv_data,rho1a,fac) COLLAPSE(3)
2420 DO k = bo(1, 3), bo(2, 3)
2421 DO j = bo(1, 2), bo(2, 2)
2422 DO i = bo(1, 1), bo(2, 1)
2423 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2424 deriv_data(i, j, k)*rho1a(i, j, k)
2425 END DO
2426 END DO
2427 END DO
2428 END IF
2429 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob])
2430 IF (ASSOCIATED(deriv_att)) THEN
2431 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2432!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2433!$OMP SHARED(bo,v_xc,deriv_data,rho1b,fac) COLLAPSE(3)
2434 DO k = bo(1, 3), bo(2, 3)
2435 DO j = bo(1, 2), bo(2, 2)
2436 DO i = bo(1, 1), bo(2, 1)
2437 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2438 deriv_data(i, j, k)*rho1b(i, j, k)
2439 END DO
2440 END DO
2441 END DO
2442 END IF
2443 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_norm_drho])
2444 IF (ASSOCIATED(deriv_att)) THEN
2445 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2446!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2447!$OMP SHARED(bo,v_xc,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
2448 DO k = bo(1, 3), bo(2, 3)
2449 DO j = bo(1, 2), bo(2, 2)
2450 DO i = bo(1, 1), bo(2, 1)
2451 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2452 deriv_data(i, j, k)*dr1dr(i, j, k)
2453 END DO
2454 END DO
2455 END DO
2456 END IF
2457 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_norm_drhoa])
2458 IF (ASSOCIATED(deriv_att)) THEN
2459 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2460!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2461!$OMP SHARED(bo,v_xc,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
2462 DO k = bo(1, 3), bo(2, 3)
2463 DO j = bo(1, 2), bo(2, 2)
2464 DO i = bo(1, 1), bo(2, 1)
2465 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2466 deriv_data(i, j, k)*dra1dra(i, j, k)
2467 END DO
2468 END DO
2469 END DO
2470 END IF
2471 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_norm_drhob])
2472 IF (ASSOCIATED(deriv_att)) THEN
2473 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2474!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2475!$OMP SHARED(bo,v_xc,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
2476 DO k = bo(1, 3), bo(2, 3)
2477 DO j = bo(1, 2), bo(2, 2)
2478 DO i = bo(1, 1), bo(2, 1)
2479 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2480 deriv_data(i, j, k)*drb1drb(i, j, k)
2481 END DO
2482 END DO
2483 END DO
2484 END IF
2485 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_tau_a])
2486 IF (ASSOCIATED(deriv_att)) THEN
2487 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2488!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2489!$OMP SHARED(bo,v_xc,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
2490 DO k = bo(1, 3), bo(2, 3)
2491 DO j = bo(1, 2), bo(2, 2)
2492 DO i = bo(1, 1), bo(2, 1)
2493 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2494 deriv_data(i, j, k)*tau1a(i, j, k)
2495 END DO
2496 END DO
2497 END DO
2498 END IF
2499 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_tau_b])
2500 IF (ASSOCIATED(deriv_att)) THEN
2501 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2502!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2503!$OMP SHARED(bo,v_xc,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
2504 DO k = bo(1, 3), bo(2, 3)
2505 DO j = bo(1, 2), bo(2, 2)
2506 DO i = bo(1, 1), bo(2, 1)
2507 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2508 deriv_data(i, j, k)*tau1b(i, j, k)
2509 END DO
2510 END DO
2511 END DO
2512 END IF
2513 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_laplace_rhoa])
2514 IF (ASSOCIATED(deriv_att)) THEN
2515 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2516!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2517!$OMP SHARED(bo,v_xc,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
2518 DO k = bo(1, 3), bo(2, 3)
2519 DO j = bo(1, 2), bo(2, 2)
2520 DO i = bo(1, 1), bo(2, 1)
2521 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2522 deriv_data(i, j, k)*laplace1a(i, j, k)
2523 END DO
2524 END DO
2525 END DO
2526 END IF
2527 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_laplace_rhob])
2528 IF (ASSOCIATED(deriv_att)) THEN
2529 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2530!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2531!$OMP SHARED(bo,v_xc,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
2532 DO k = bo(1, 3), bo(2, 3)
2533 DO j = bo(1, 2), bo(2, 2)
2534 DO i = bo(1, 1), bo(2, 1)
2535 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2536 deriv_data(i, j, k)*laplace1b(i, j, k)
2537 END DO
2538 END DO
2539 END DO
2540 END IF
2541
2542
2543 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhoa])
2544 IF (ASSOCIATED(deriv_att)) THEN
2545 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2546!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2547!$OMP SHARED(bo,v_drho,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
2548 DO k = bo(1, 3), bo(2, 3)
2549 DO j = bo(1, 2), bo(2, 2)
2550 DO i = bo(1, 1), bo(2, 1)
2551 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2552 deriv_data(i, j, k)*rho1a(i, j, k)
2553 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2554 deriv_data(i, j, k)*rho1a(i, j, k)
2555 END DO
2556 END DO
2557 END DO
2558 END IF
2559 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhob])
2560 IF (ASSOCIATED(deriv_att)) THEN
2561 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2562!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2563!$OMP SHARED(bo,v_drho,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
2564 DO k = bo(1, 3), bo(2, 3)
2565 DO j = bo(1, 2), bo(2, 2)
2566 DO i = bo(1, 1), bo(2, 1)
2567 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2568 deriv_data(i, j, k)*rho1b(i, j, k)
2569 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2570 deriv_data(i, j, k)*rho1b(i, j, k)
2571 END DO
2572 END DO
2573 END DO
2574 END IF
2575 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drho])
2576 IF (ASSOCIATED(deriv_att)) THEN
2577 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2578!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2579!$OMP SHARED(bo,v_drho,deriv_data,dr1dr,fac) COLLAPSE(3)
2580 DO k = bo(1, 3), bo(2, 3)
2581 DO j = bo(1, 2), bo(2, 2)
2582 DO i = bo(1, 1), bo(2, 1)
2583 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2584 deriv_data(i, j, k)*dr1dr(i, j, k)
2585 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2586 deriv_data(i, j, k)*dr1dr(i, j, k)
2587 END DO
2588 END DO
2589 END DO
2590 END IF
2591 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhoa])
2592 IF (ASSOCIATED(deriv_att)) THEN
2593 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2594!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2595!$OMP SHARED(bo,v_drho,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
2596 DO k = bo(1, 3), bo(2, 3)
2597 DO j = bo(1, 2), bo(2, 2)
2598 DO i = bo(1, 1), bo(2, 1)
2599 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2600 deriv_data(i, j, k)*dra1dra(i, j, k)
2601 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2602 deriv_data(i, j, k)*dra1dra(i, j, k)
2603 END DO
2604 END DO
2605 END DO
2606 END IF
2607 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhob])
2608 IF (ASSOCIATED(deriv_att)) THEN
2609 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2610!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2611!$OMP SHARED(bo,v_drho,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
2612 DO k = bo(1, 3), bo(2, 3)
2613 DO j = bo(1, 2), bo(2, 2)
2614 DO i = bo(1, 1), bo(2, 1)
2615 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2616 deriv_data(i, j, k)*drb1drb(i, j, k)
2617 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2618 deriv_data(i, j, k)*drb1drb(i, j, k)
2619 END DO
2620 END DO
2621 END DO
2622 END IF
2623 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau_a])
2624 IF (ASSOCIATED(deriv_att)) THEN
2625 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2626!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2627!$OMP SHARED(bo,v_drho,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
2628 DO k = bo(1, 3), bo(2, 3)
2629 DO j = bo(1, 2), bo(2, 2)
2630 DO i = bo(1, 1), bo(2, 1)
2631 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2632 deriv_data(i, j, k)*tau1a(i, j, k)
2633 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2634 deriv_data(i, j, k)*tau1a(i, j, k)
2635 END DO
2636 END DO
2637 END DO
2638 END IF
2639 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau_b])
2640 IF (ASSOCIATED(deriv_att)) THEN
2641 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2642!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2643!$OMP SHARED(bo,v_drho,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
2644 DO k = bo(1, 3), bo(2, 3)
2645 DO j = bo(1, 2), bo(2, 2)
2646 DO i = bo(1, 1), bo(2, 1)
2647 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2648 deriv_data(i, j, k)*tau1b(i, j, k)
2649 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2650 deriv_data(i, j, k)*tau1b(i, j, k)
2651 END DO
2652 END DO
2653 END DO
2654 END IF
2656 IF (ASSOCIATED(deriv_att)) THEN
2657 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2658!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2659!$OMP SHARED(bo,v_drho,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
2660 DO k = bo(1, 3), bo(2, 3)
2661 DO j = bo(1, 2), bo(2, 2)
2662 DO i = bo(1, 1), bo(2, 1)
2663 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2664 deriv_data(i, j, k)*laplace1a(i, j, k)
2665 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2666 deriv_data(i, j, k)*laplace1a(i, j, k)
2667 END DO
2668 END DO
2669 END DO
2670 END IF
2672 IF (ASSOCIATED(deriv_att)) THEN
2673 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2674!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2675!$OMP SHARED(bo,v_drho,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
2676 DO k = bo(1, 3), bo(2, 3)
2677 DO j = bo(1, 2), bo(2, 2)
2678 DO i = bo(1, 1), bo(2, 1)
2679 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2680 deriv_data(i, j, k)*laplace1b(i, j, k)
2681 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2682 deriv_data(i, j, k)*laplace1b(i, j, k)
2683 END DO
2684 END DO
2685 END DO
2686 END IF
2687
2688 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
2689 IF (ASSOCIATED(deriv_att)) THEN
2690 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2691 CALL xc_derivative_get(deriv_att, deriv_data=e_drho)
2692
2693 IF (my_compute_virial) THEN
2694 CALL virial_drho_drho1(virial_pw, drho, drho1, deriv_data, virial_xc)
2695 END IF ! my_compute_virial
2696
2697!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dr1dr,gradient_cut,norm_drho,v_drho,deriv_data)
2698 v_drho(1)%array(:, :, :) = v_drho(1)%array(:, :, :) + &
2699 deriv_data(:, :, :)*dr1dr(:, :, :)/max(gradient_cut, norm_drho(:, :, :))**2
2700 v_drho(2)%array(:, :, :) = v_drho(2)%array(:, :, :) + &
2701 deriv_data(:, :, :)*dr1dr(:, :, :)/max(gradient_cut, norm_drho(:, :, :))**2
2702!$OMP END PARALLEL WORKSHARE
2703 END IF
2704
2705 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhoa])
2706 IF (ASSOCIATED(deriv_att)) THEN
2707 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2708!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2709!$OMP SHARED(bo,v_drhoa,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
2710 DO k = bo(1, 3), bo(2, 3)
2711 DO j = bo(1, 2), bo(2, 2)
2712 DO i = bo(1, 1), bo(2, 1)
2713 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2714 deriv_data(i, j, k)*rho1a(i, j, k)
2715 END DO
2716 END DO
2717 END DO
2718 END IF
2719 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhob])
2720 IF (ASSOCIATED(deriv_att)) THEN
2721 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2722!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2723!$OMP SHARED(bo,v_drhoa,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
2724 DO k = bo(1, 3), bo(2, 3)
2725 DO j = bo(1, 2), bo(2, 2)
2726 DO i = bo(1, 1), bo(2, 1)
2727 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2728 deriv_data(i, j, k)*rho1b(i, j, k)
2729 END DO
2730 END DO
2731 END DO
2732 END IF
2733 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drho])
2734 IF (ASSOCIATED(deriv_att)) THEN
2735 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2736!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2737!$OMP SHARED(bo,v_drhoa,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
2738 DO k = bo(1, 3), bo(2, 3)
2739 DO j = bo(1, 2), bo(2, 2)
2740 DO i = bo(1, 1), bo(2, 1)
2741 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2742 deriv_data(i, j, k)*dr1dr(i, j, k)
2743 END DO
2744 END DO
2745 END DO
2746 END IF
2747 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhoa])
2748 IF (ASSOCIATED(deriv_att)) THEN
2749 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2750!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2751!$OMP SHARED(bo,v_drhoa,deriv_data,dra1dra,fac) COLLAPSE(3)
2752 DO k = bo(1, 3), bo(2, 3)
2753 DO j = bo(1, 2), bo(2, 2)
2754 DO i = bo(1, 1), bo(2, 1)
2755 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2756 deriv_data(i, j, k)*dra1dra(i, j, k)
2757 END DO
2758 END DO
2759 END DO
2760 END IF
2761 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhob])
2762 IF (ASSOCIATED(deriv_att)) THEN
2763 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2764!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2765!$OMP SHARED(bo,v_drhoa,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
2766 DO k = bo(1, 3), bo(2, 3)
2767 DO j = bo(1, 2), bo(2, 2)
2768 DO i = bo(1, 1), bo(2, 1)
2769 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2770 deriv_data(i, j, k)*drb1drb(i, j, k)
2771 END DO
2772 END DO
2773 END DO
2774 END IF
2775 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_tau_a])
2776 IF (ASSOCIATED(deriv_att)) THEN
2777 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2778!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2779!$OMP SHARED(bo,v_drhoa,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
2780 DO k = bo(1, 3), bo(2, 3)
2781 DO j = bo(1, 2), bo(2, 2)
2782 DO i = bo(1, 1), bo(2, 1)
2783 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2784 deriv_data(i, j, k)*tau1a(i, j, k)
2785 END DO
2786 END DO
2787 END DO
2788 END IF
2789 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_tau_b])
2790 IF (ASSOCIATED(deriv_att)) THEN
2791 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2792!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2793!$OMP SHARED(bo,v_drhoa,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
2794 DO k = bo(1, 3), bo(2, 3)
2795 DO j = bo(1, 2), bo(2, 2)
2796 DO i = bo(1, 1), bo(2, 1)
2797 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2798 deriv_data(i, j, k)*tau1b(i, j, k)
2799 END DO
2800 END DO
2801 END DO
2802 END IF
2804 IF (ASSOCIATED(deriv_att)) THEN
2805 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2806!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2807!$OMP SHARED(bo,v_drhoa,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
2808 DO k = bo(1, 3), bo(2, 3)
2809 DO j = bo(1, 2), bo(2, 2)
2810 DO i = bo(1, 1), bo(2, 1)
2811 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2812 deriv_data(i, j, k)*laplace1a(i, j, k)
2813 END DO
2814 END DO
2815 END DO
2816 END IF
2818 IF (ASSOCIATED(deriv_att)) THEN
2819 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2820!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2821!$OMP SHARED(bo,v_drhoa,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
2822 DO k = bo(1, 3), bo(2, 3)
2823 DO j = bo(1, 2), bo(2, 2)
2824 DO i = bo(1, 1), bo(2, 1)
2825 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2826 deriv_data(i, j, k)*laplace1b(i, j, k)
2827 END DO
2828 END DO
2829 END DO
2830 END IF
2831
2832 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa])
2833 IF (ASSOCIATED(deriv_att)) THEN
2834 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2835 CALL xc_derivative_get(deriv_att, deriv_data=e_drhoa)
2836
2837 IF (my_compute_virial) THEN
2838 CALL virial_drho_drho1(virial_pw, drhoa, drho1a, deriv_data, virial_xc)
2839 END IF ! my_compute_virial
2840
2841!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dra1dra,gradient_cut,norm_drhoa,v_drhoa,deriv_data)
2842 v_drhoa(1)%array(:, :, :) = v_drhoa(1)%array(:, :, :) + &
2843 deriv_data(:, :, :)*dra1dra(:, :, :)/max(gradient_cut, norm_drhoa(:, :, :))**2
2844!$OMP END PARALLEL WORKSHARE
2845 END IF
2846
2847 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhoa])
2848 IF (ASSOCIATED(deriv_att)) THEN
2849 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2850!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2851!$OMP SHARED(bo,v_drhob,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
2852 DO k = bo(1, 3), bo(2, 3)
2853 DO j = bo(1, 2), bo(2, 2)
2854 DO i = bo(1, 1), bo(2, 1)
2855 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2856 deriv_data(i, j, k)*rho1a(i, j, k)
2857 END DO
2858 END DO
2859 END DO
2860 END IF
2861 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhob])
2862 IF (ASSOCIATED(deriv_att)) THEN
2863 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2864!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2865!$OMP SHARED(bo,v_drhob,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
2866 DO k = bo(1, 3), bo(2, 3)
2867 DO j = bo(1, 2), bo(2, 2)
2868 DO i = bo(1, 1), bo(2, 1)
2869 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2870 deriv_data(i, j, k)*rho1b(i, j, k)
2871 END DO
2872 END DO
2873 END DO
2874 END IF
2875 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_norm_drho])
2876 IF (ASSOCIATED(deriv_att)) THEN
2877 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2878!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2879!$OMP SHARED(bo,v_drhob,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
2880 DO k = bo(1, 3), bo(2, 3)
2881 DO j = bo(1, 2), bo(2, 2)
2882 DO i = bo(1, 1), bo(2, 1)
2883 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2884 deriv_data(i, j, k)*dr1dr(i, j, k)
2885 END DO
2886 END DO
2887 END DO
2888 END IF
2889 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_norm_drhoa])
2890 IF (ASSOCIATED(deriv_att)) THEN
2891 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2892!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2893!$OMP SHARED(bo,v_drhob,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
2894 DO k = bo(1, 3), bo(2, 3)
2895 DO j = bo(1, 2), bo(2, 2)
2896 DO i = bo(1, 1), bo(2, 1)
2897 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2898 deriv_data(i, j, k)*dra1dra(i, j, k)
2899 END DO
2900 END DO
2901 END DO
2902 END IF
2903 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_norm_drhob])
2904 IF (ASSOCIATED(deriv_att)) THEN
2905 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2906!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2907!$OMP SHARED(bo,v_drhob,deriv_data,drb1drb,fac) COLLAPSE(3)
2908 DO k = bo(1, 3), bo(2, 3)
2909 DO j = bo(1, 2), bo(2, 2)
2910 DO i = bo(1, 1), bo(2, 1)
2911 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2912 deriv_data(i, j, k)*drb1drb(i, j, k)
2913 END DO
2914 END DO
2915 END DO
2916 END IF
2917 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_tau_a])
2918 IF (ASSOCIATED(deriv_att)) THEN
2919 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2920!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2921!$OMP SHARED(bo,v_drhob,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
2922 DO k = bo(1, 3), bo(2, 3)
2923 DO j = bo(1, 2), bo(2, 2)
2924 DO i = bo(1, 1), bo(2, 1)
2925 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2926 deriv_data(i, j, k)*tau1a(i, j, k)
2927 END DO
2928 END DO
2929 END DO
2930 END IF
2931 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_tau_b])
2932 IF (ASSOCIATED(deriv_att)) THEN
2933 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2934!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2935!$OMP SHARED(bo,v_drhob,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
2936 DO k = bo(1, 3), bo(2, 3)
2937 DO j = bo(1, 2), bo(2, 2)
2938 DO i = bo(1, 1), bo(2, 1)
2939 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2940 deriv_data(i, j, k)*tau1b(i, j, k)
2941 END DO
2942 END DO
2943 END DO
2944 END IF
2946 IF (ASSOCIATED(deriv_att)) THEN
2947 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2948!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2949!$OMP SHARED(bo,v_drhob,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
2950 DO k = bo(1, 3), bo(2, 3)
2951 DO j = bo(1, 2), bo(2, 2)
2952 DO i = bo(1, 1), bo(2, 1)
2953 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2954 deriv_data(i, j, k)*laplace1a(i, j, k)
2955 END DO
2956 END DO
2957 END DO
2958 END IF
2960 IF (ASSOCIATED(deriv_att)) THEN
2961 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2962!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2963!$OMP SHARED(bo,v_drhob,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
2964 DO k = bo(1, 3), bo(2, 3)
2965 DO j = bo(1, 2), bo(2, 2)
2966 DO i = bo(1, 1), bo(2, 1)
2967 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2968 deriv_data(i, j, k)*laplace1b(i, j, k)
2969 END DO
2970 END DO
2971 END DO
2972 END IF
2973
2974 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob])
2975 IF (ASSOCIATED(deriv_att)) THEN
2976 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2977 CALL xc_derivative_get(deriv_att, deriv_data=e_drhob)
2978
2979 IF (my_compute_virial) THEN
2980 CALL virial_drho_drho1(virial_pw, drhob, drho1b, deriv_data, virial_xc)
2981 END IF ! my_compute_virial
2982
2983!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(drb1drb,gradient_cut,norm_drhob,v_drhob,deriv_data)
2984 v_drhob(2)%array(:, :, :) = v_drhob(2)%array(:, :, :) + &
2985 deriv_data(:, :, :)*drb1drb(:, :, :)/max(gradient_cut, norm_drhob(:, :, :))**2
2986!$OMP END PARALLEL WORKSHARE
2987 END IF
2988
2989 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_rhoa])
2990 IF (ASSOCIATED(deriv_att)) THEN
2991 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2992!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2993!$OMP SHARED(bo,v_xc_tau,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
2994 DO k = bo(1, 3), bo(2, 3)
2995 DO j = bo(1, 2), bo(2, 2)
2996 DO i = bo(1, 1), bo(2, 1)
2997 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
2998 deriv_data(i, j, k)*rho1a(i, j, k)
2999 END DO
3000 END DO
3001 END DO
3002 END IF
3003 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_rhob])
3004 IF (ASSOCIATED(deriv_att)) THEN
3005 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3006!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3007!$OMP SHARED(bo,v_xc_tau,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
3008 DO k = bo(1, 3), bo(2, 3)
3009 DO j = bo(1, 2), bo(2, 2)
3010 DO i = bo(1, 1), bo(2, 1)
3011 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3012 deriv_data(i, j, k)*rho1b(i, j, k)
3013 END DO
3014 END DO
3015 END DO
3016 END IF
3017 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_norm_drho])
3018 IF (ASSOCIATED(deriv_att)) THEN
3019 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3020!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3021!$OMP SHARED(bo,v_xc_tau,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
3022 DO k = bo(1, 3), bo(2, 3)
3023 DO j = bo(1, 2), bo(2, 2)
3024 DO i = bo(1, 1), bo(2, 1)
3025 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3026 deriv_data(i, j, k)*dr1dr(i, j, k)
3027 END DO
3028 END DO
3029 END DO
3030 END IF
3031 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_norm_drhoa])
3032 IF (ASSOCIATED(deriv_att)) THEN
3033 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3034!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3035!$OMP SHARED(bo,v_xc_tau,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
3036 DO k = bo(1, 3), bo(2, 3)
3037 DO j = bo(1, 2), bo(2, 2)
3038 DO i = bo(1, 1), bo(2, 1)
3039 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3040 deriv_data(i, j, k)*dra1dra(i, j, k)
3041 END DO
3042 END DO
3043 END DO
3044 END IF
3045 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_norm_drhob])
3046 IF (ASSOCIATED(deriv_att)) THEN
3047 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3048!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3049!$OMP SHARED(bo,v_xc_tau,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
3050 DO k = bo(1, 3), bo(2, 3)
3051 DO j = bo(1, 2), bo(2, 2)
3052 DO i = bo(1, 1), bo(2, 1)
3053 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3054 deriv_data(i, j, k)*drb1drb(i, j, k)
3055 END DO
3056 END DO
3057 END DO
3058 END IF
3059 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_tau_a])
3060 IF (ASSOCIATED(deriv_att)) THEN
3061 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3062!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3063!$OMP SHARED(bo,v_xc_tau,deriv_data,tau1a,fac) COLLAPSE(3)
3064 DO k = bo(1, 3), bo(2, 3)
3065 DO j = bo(1, 2), bo(2, 2)
3066 DO i = bo(1, 1), bo(2, 1)
3067 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3068 deriv_data(i, j, k)*tau1a(i, j, k)
3069 END DO
3070 END DO
3071 END DO
3072 END IF
3073 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_tau_b])
3074 IF (ASSOCIATED(deriv_att)) THEN
3075 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3076!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3077!$OMP SHARED(bo,v_xc_tau,deriv_data,tau1b,fac) COLLAPSE(3)
3078 DO k = bo(1, 3), bo(2, 3)
3079 DO j = bo(1, 2), bo(2, 2)
3080 DO i = bo(1, 1), bo(2, 1)
3081 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3082 deriv_data(i, j, k)*tau1b(i, j, k)
3083 END DO
3084 END DO
3085 END DO
3086 END IF
3087 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_laplace_rhoa])
3088 IF (ASSOCIATED(deriv_att)) THEN
3089 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3090!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3091!$OMP SHARED(bo,v_xc_tau,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
3092 DO k = bo(1, 3), bo(2, 3)
3093 DO j = bo(1, 2), bo(2, 2)
3094 DO i = bo(1, 1), bo(2, 1)
3095 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3096 deriv_data(i, j, k)*laplace1a(i, j, k)
3097 END DO
3098 END DO
3099 END DO
3100 END IF
3101 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_laplace_rhob])
3102 IF (ASSOCIATED(deriv_att)) THEN
3103 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3104!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3105!$OMP SHARED(bo,v_xc_tau,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
3106 DO k = bo(1, 3), bo(2, 3)
3107 DO j = bo(1, 2), bo(2, 2)
3108 DO i = bo(1, 1), bo(2, 1)
3109 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3110 deriv_data(i, j, k)*laplace1b(i, j, k)
3111 END DO
3112 END DO
3113 END DO
3114 END IF
3115
3116
3117 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_rhoa])
3118 IF (ASSOCIATED(deriv_att)) THEN
3119 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3120!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3121!$OMP SHARED(bo,v_xc_tau,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
3122 DO k = bo(1, 3), bo(2, 3)
3123 DO j = bo(1, 2), bo(2, 2)
3124 DO i = bo(1, 1), bo(2, 1)
3125 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3126 deriv_data(i, j, k)*rho1a(i, j, k)
3127 END DO
3128 END DO
3129 END DO
3130 END IF
3131 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_rhob])
3132 IF (ASSOCIATED(deriv_att)) THEN
3133 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3134!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3135!$OMP SHARED(bo,v_xc_tau,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
3136 DO k = bo(1, 3), bo(2, 3)
3137 DO j = bo(1, 2), bo(2, 2)
3138 DO i = bo(1, 1), bo(2, 1)
3139 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3140 deriv_data(i, j, k)*rho1b(i, j, k)
3141 END DO
3142 END DO
3143 END DO
3144 END IF
3145 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_norm_drho])
3146 IF (ASSOCIATED(deriv_att)) THEN
3147 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3148!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3149!$OMP SHARED(bo,v_xc_tau,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
3150 DO k = bo(1, 3), bo(2, 3)
3151 DO j = bo(1, 2), bo(2, 2)
3152 DO i = bo(1, 1), bo(2, 1)
3153 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3154 deriv_data(i, j, k)*dr1dr(i, j, k)
3155 END DO
3156 END DO
3157 END DO
3158 END IF
3159 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_norm_drhoa])
3160 IF (ASSOCIATED(deriv_att)) THEN
3161 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3162!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3163!$OMP SHARED(bo,v_xc_tau,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
3164 DO k = bo(1, 3), bo(2, 3)
3165 DO j = bo(1, 2), bo(2, 2)
3166 DO i = bo(1, 1), bo(2, 1)
3167 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3168 deriv_data(i, j, k)*dra1dra(i, j, k)
3169 END DO
3170 END DO
3171 END DO
3172 END IF
3173 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_norm_drhob])
3174 IF (ASSOCIATED(deriv_att)) THEN
3175 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3176!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3177!$OMP SHARED(bo,v_xc_tau,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
3178 DO k = bo(1, 3), bo(2, 3)
3179 DO j = bo(1, 2), bo(2, 2)
3180 DO i = bo(1, 1), bo(2, 1)
3181 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3182 deriv_data(i, j, k)*drb1drb(i, j, k)
3183 END DO
3184 END DO
3185 END DO
3186 END IF
3187 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_tau_a])
3188 IF (ASSOCIATED(deriv_att)) THEN
3189 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3190!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3191!$OMP SHARED(bo,v_xc_tau,deriv_data,tau1a,fac) COLLAPSE(3)
3192 DO k = bo(1, 3), bo(2, 3)
3193 DO j = bo(1, 2), bo(2, 2)
3194 DO i = bo(1, 1), bo(2, 1)
3195 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3196 deriv_data(i, j, k)*tau1a(i, j, k)
3197 END DO
3198 END DO
3199 END DO
3200 END IF
3201 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_tau_b])
3202 IF (ASSOCIATED(deriv_att)) THEN
3203 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3204!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3205!$OMP SHARED(bo,v_xc_tau,deriv_data,tau1b,fac) COLLAPSE(3)
3206 DO k = bo(1, 3), bo(2, 3)
3207 DO j = bo(1, 2), bo(2, 2)
3208 DO i = bo(1, 1), bo(2, 1)
3209 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3210 deriv_data(i, j, k)*tau1b(i, j, k)
3211 END DO
3212 END DO
3213 END DO
3214 END IF
3215 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_laplace_rhoa])
3216 IF (ASSOCIATED(deriv_att)) THEN
3217 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3218!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3219!$OMP SHARED(bo,v_xc_tau,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
3220 DO k = bo(1, 3), bo(2, 3)
3221 DO j = bo(1, 2), bo(2, 2)
3222 DO i = bo(1, 1), bo(2, 1)
3223 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3224 deriv_data(i, j, k)*laplace1a(i, j, k)
3225 END DO
3226 END DO
3227 END DO
3228 END IF
3229 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_laplace_rhob])
3230 IF (ASSOCIATED(deriv_att)) THEN
3231 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3232!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3233!$OMP SHARED(bo,v_xc_tau,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
3234 DO k = bo(1, 3), bo(2, 3)
3235 DO j = bo(1, 2), bo(2, 2)
3236 DO i = bo(1, 1), bo(2, 1)
3237 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3238 deriv_data(i, j, k)*laplace1b(i, j, k)
3239 END DO
3240 END DO
3241 END DO
3242 END IF
3243
3244
3245 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_rhoa])
3246 IF (ASSOCIATED(deriv_att)) THEN
3247 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3248!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3249!$OMP SHARED(bo,v_laplace,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
3250 DO k = bo(1, 3), bo(2, 3)
3251 DO j = bo(1, 2), bo(2, 2)
3252 DO i = bo(1, 1), bo(2, 1)
3253 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3254 deriv_data(i, j, k)*rho1a(i, j, k)
3255 END DO
3256 END DO
3257 END DO
3258 END IF
3259 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_rhob])
3260 IF (ASSOCIATED(deriv_att)) THEN
3261 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3262!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3263!$OMP SHARED(bo,v_laplace,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
3264 DO k = bo(1, 3), bo(2, 3)
3265 DO j = bo(1, 2), bo(2, 2)
3266 DO i = bo(1, 1), bo(2, 1)
3267 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3268 deriv_data(i, j, k)*rho1b(i, j, k)
3269 END DO
3270 END DO
3271 END DO
3272 END IF
3274 IF (ASSOCIATED(deriv_att)) THEN
3275 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3276!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3277!$OMP SHARED(bo,v_laplace,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
3278 DO k = bo(1, 3), bo(2, 3)
3279 DO j = bo(1, 2), bo(2, 2)
3280 DO i = bo(1, 1), bo(2, 1)
3281 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3282 deriv_data(i, j, k)*dr1dr(i, j, k)
3283 END DO
3284 END DO
3285 END DO
3286 END IF
3288 IF (ASSOCIATED(deriv_att)) THEN
3289 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3290!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3291!$OMP SHARED(bo,v_laplace,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
3292 DO k = bo(1, 3), bo(2, 3)
3293 DO j = bo(1, 2), bo(2, 2)
3294 DO i = bo(1, 1), bo(2, 1)
3295 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3296 deriv_data(i, j, k)*dra1dra(i, j, k)
3297 END DO
3298 END DO
3299 END DO
3300 END IF
3302 IF (ASSOCIATED(deriv_att)) THEN
3303 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3304!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3305!$OMP SHARED(bo,v_laplace,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
3306 DO k = bo(1, 3), bo(2, 3)
3307 DO j = bo(1, 2), bo(2, 2)
3308 DO i = bo(1, 1), bo(2, 1)
3309 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3310 deriv_data(i, j, k)*drb1drb(i, j, k)
3311 END DO
3312 END DO
3313 END DO
3314 END IF
3315 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_tau_a])
3316 IF (ASSOCIATED(deriv_att)) THEN
3317 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3318!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3319!$OMP SHARED(bo,v_laplace,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
3320 DO k = bo(1, 3), bo(2, 3)
3321 DO j = bo(1, 2), bo(2, 2)
3322 DO i = bo(1, 1), bo(2, 1)
3323 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3324 deriv_data(i, j, k)*tau1a(i, j, k)
3325 END DO
3326 END DO
3327 END DO
3328 END IF
3329 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_tau_b])
3330 IF (ASSOCIATED(deriv_att)) THEN
3331 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3332!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3333!$OMP SHARED(bo,v_laplace,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
3334 DO k = bo(1, 3), bo(2, 3)
3335 DO j = bo(1, 2), bo(2, 2)
3336 DO i = bo(1, 1), bo(2, 1)
3337 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3338 deriv_data(i, j, k)*tau1b(i, j, k)
3339 END DO
3340 END DO
3341 END DO
3342 END IF
3344 IF (ASSOCIATED(deriv_att)) THEN
3345 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3346!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3347!$OMP SHARED(bo,v_laplace,deriv_data,laplace1a,fac) COLLAPSE(3)
3348 DO k = bo(1, 3), bo(2, 3)
3349 DO j = bo(1, 2), bo(2, 2)
3350 DO i = bo(1, 1), bo(2, 1)
3351 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3352 deriv_data(i, j, k)*laplace1a(i, j, k)
3353 END DO
3354 END DO
3355 END DO
3356 END IF
3358 IF (ASSOCIATED(deriv_att)) THEN
3359 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3360!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3361!$OMP SHARED(bo,v_laplace,deriv_data,laplace1b,fac) COLLAPSE(3)
3362 DO k = bo(1, 3), bo(2, 3)
3363 DO j = bo(1, 2), bo(2, 2)
3364 DO i = bo(1, 1), bo(2, 1)
3365 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3366 deriv_data(i, j, k)*laplace1b(i, j, k)
3367 END DO
3368 END DO
3369 END DO
3370 END IF
3371
3372
3373 IF (my_compute_virial) THEN
3374 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa])
3375 IF (ASSOCIATED(deriv_att)) THEN
3376 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3377
3378 virial_pw%array(:, :, :) = -rho1a(:, :, :)
3379 CALL virial_laplace(virial_pw, pw_pool, virial_xc, deriv_data)
3380 END IF
3381 END IF ! my_compute_virial
3382 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob, deriv_rhoa])
3383 IF (ASSOCIATED(deriv_att)) THEN
3384 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3385!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3386!$OMP SHARED(bo,v_laplace,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
3387 DO k = bo(1, 3), bo(2, 3)
3388 DO j = bo(1, 2), bo(2, 2)
3389 DO i = bo(1, 1), bo(2, 1)
3390 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3391 deriv_data(i, j, k)*rho1a(i, j, k)
3392 END DO
3393 END DO
3394 END DO
3395 END IF
3396 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob, deriv_rhob])
3397 IF (ASSOCIATED(deriv_att)) THEN
3398 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3399!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3400!$OMP SHARED(bo,v_laplace,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
3401 DO k = bo(1, 3), bo(2, 3)
3402 DO j = bo(1, 2), bo(2, 2)
3403 DO i = bo(1, 1), bo(2, 1)
3404 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3405 deriv_data(i, j, k)*rho1b(i, j, k)
3406 END DO
3407 END DO
3408 END DO
3409 END IF
3411 IF (ASSOCIATED(deriv_att)) THEN
3412 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3413!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3414!$OMP SHARED(bo,v_laplace,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
3415 DO k = bo(1, 3), bo(2, 3)
3416 DO j = bo(1, 2), bo(2, 2)
3417 DO i = bo(1, 1), bo(2, 1)
3418 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3419 deriv_data(i, j, k)*dr1dr(i, j, k)
3420 END DO
3421 END DO
3422 END DO
3423 END IF
3425 IF (ASSOCIATED(deriv_att)) THEN
3426 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3427!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3428!$OMP SHARED(bo,v_laplace,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
3429 DO k = bo(1, 3), bo(2, 3)
3430 DO j = bo(1, 2), bo(2, 2)
3431 DO i = bo(1, 1), bo(2, 1)
3432 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3433 deriv_data(i, j, k)*dra1dra(i, j, k)
3434 END DO
3435 END DO
3436 END DO
3437 END IF
3439 IF (ASSOCIATED(deriv_att)) THEN
3440 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3441!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3442!$OMP SHARED(bo,v_laplace,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
3443 DO k = bo(1, 3), bo(2, 3)
3444 DO j = bo(1, 2), bo(2, 2)
3445 DO i = bo(1, 1), bo(2, 1)
3446 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3447 deriv_data(i, j, k)*drb1drb(i, j, k)
3448 END DO
3449 END DO
3450 END DO
3451 END IF
3452 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob, deriv_tau_a])
3453 IF (ASSOCIATED(deriv_att)) THEN
3454 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3455!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3456!$OMP SHARED(bo,v_laplace,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
3457 DO k = bo(1, 3), bo(2, 3)
3458 DO j = bo(1, 2), bo(2, 2)
3459 DO i = bo(1, 1), bo(2, 1)
3460 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3461 deriv_data(i, j, k)*tau1a(i, j, k)
3462 END DO
3463 END DO
3464 END DO
3465 END IF
3466 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob, deriv_tau_b])
3467 IF (ASSOCIATED(deriv_att)) THEN
3468 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3469!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3470!$OMP SHARED(bo,v_laplace,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
3471 DO k = bo(1, 3), bo(2, 3)
3472 DO j = bo(1, 2), bo(2, 2)
3473 DO i = bo(1, 1), bo(2, 1)
3474 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3475 deriv_data(i, j, k)*tau1b(i, j, k)
3476 END DO
3477 END DO
3478 END DO
3479 END IF
3481 IF (ASSOCIATED(deriv_att)) THEN
3482 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3483!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3484!$OMP SHARED(bo,v_laplace,deriv_data,laplace1a,fac) COLLAPSE(3)
3485 DO k = bo(1, 3), bo(2, 3)
3486 DO j = bo(1, 2), bo(2, 2)
3487 DO i = bo(1, 1), bo(2, 1)
3488 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3489 deriv_data(i, j, k)*laplace1a(i, j, k)
3490 END DO
3491 END DO
3492 END DO
3493 END IF
3495 IF (ASSOCIATED(deriv_att)) THEN
3496 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3497!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3498!$OMP SHARED(bo,v_laplace,deriv_data,laplace1b,fac) COLLAPSE(3)
3499 DO k = bo(1, 3), bo(2, 3)
3500 DO j = bo(1, 2), bo(2, 2)
3501 DO i = bo(1, 1), bo(2, 1)
3502 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3503 deriv_data(i, j, k)*laplace1b(i, j, k)
3504 END DO
3505 END DO
3506 END DO
3507 END IF
3508
3509
3510 IF (my_compute_virial) THEN
3511 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob])
3512 IF (ASSOCIATED(deriv_att)) THEN
3513 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3514
3515 virial_pw%array(:, :, :) = -rho1b(:, :, :)
3516 CALL virial_laplace(virial_pw, pw_pool, virial_xc, deriv_data)
3517 END IF
3518 END IF ! my_compute_virial
3519
3520
3521 ELSE
3522
3523 ! Compute (fxc^{\alpha\alpha}+-fxc^{\beta\beta})*\rho(1) over the grid points
3524 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa])
3525 IF (ASSOCIATED(deriv_att)) THEN
3526 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3527!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3528!$OMP SHARED(bo,v_xc,deriv_data,rho1a,fac) COLLAPSE(3)
3529 DO k = bo(1, 3), bo(2, 3)
3530 DO j = bo(1, 2), bo(2, 2)
3531 DO i = bo(1, 1), bo(2, 1)
3532 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3533 deriv_data(i, j, k)*rho1a(i, j, k)
3534 END DO
3535 END DO
3536 END DO
3537 END IF
3538 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drho])
3539 IF (ASSOCIATED(deriv_att)) THEN
3540 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3541!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3542!$OMP SHARED(bo,v_xc,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
3543 DO k = bo(1, 3), bo(2, 3)
3544 DO j = bo(1, 2), bo(2, 2)
3545 DO i = bo(1, 1), bo(2, 1)
3546 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3547 deriv_data(i, j, k)*dr1dr(i, j, k)
3548 END DO
3549 END DO
3550 END DO
3551 END IF
3552 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drhoa])
3553 IF (ASSOCIATED(deriv_att)) THEN
3554 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3555!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3556!$OMP SHARED(bo,v_xc,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
3557 DO k = bo(1, 3), bo(2, 3)
3558 DO j = bo(1, 2), bo(2, 2)
3559 DO i = bo(1, 1), bo(2, 1)
3560 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3561 deriv_data(i, j, k)*dra1dra(i, j, k)
3562 END DO
3563 END DO
3564 END DO
3565 END IF
3566 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_tau_a])
3567 IF (ASSOCIATED(deriv_att)) THEN
3568 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3569!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3570!$OMP SHARED(bo,v_xc,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
3571 DO k = bo(1, 3), bo(2, 3)
3572 DO j = bo(1, 2), bo(2, 2)
3573 DO i = bo(1, 1), bo(2, 1)
3574 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3575 deriv_data(i, j, k)*tau1a(i, j, k)
3576 END DO
3577 END DO
3578 END DO
3579 END IF
3580 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_laplace_rhoa])
3581 IF (ASSOCIATED(deriv_att)) THEN
3582 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3583!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3584!$OMP SHARED(bo,v_xc,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
3585 DO k = bo(1, 3), bo(2, 3)
3586 DO j = bo(1, 2), bo(2, 2)
3587 DO i = bo(1, 1), bo(2, 1)
3588 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3589 deriv_data(i, j, k)*laplace1a(i, j, k)
3590 END DO
3591 END DO
3592 END DO
3593 END IF
3594 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhob])
3595 IF (ASSOCIATED(deriv_att)) THEN
3596 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3597!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3598!$OMP SHARED(bo,v_xc,deriv_data,rho1b,fac) COLLAPSE(3)
3599 DO k = bo(1, 3), bo(2, 3)
3600 DO j = bo(1, 2), bo(2, 2)
3601 DO i = bo(1, 1), bo(2, 1)
3602 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3603 fac*deriv_data(i, j, k)*rho1b(i, j, k)
3604 END DO
3605 END DO
3606 END DO
3607 END IF
3608 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drhob])
3609 IF (ASSOCIATED(deriv_att)) THEN
3610 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3611!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3612!$OMP SHARED(bo,v_xc,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
3613 DO k = bo(1, 3), bo(2, 3)
3614 DO j = bo(1, 2), bo(2, 2)
3615 DO i = bo(1, 1), bo(2, 1)
3616 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3617 fac*deriv_data(i, j, k)*drb1drb(i, j, k)
3618 END DO
3619 END DO
3620 END DO
3621 END IF
3622 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_tau_b])
3623 IF (ASSOCIATED(deriv_att)) THEN
3624 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3625!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3626!$OMP SHARED(bo,v_xc,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
3627 DO k = bo(1, 3), bo(2, 3)
3628 DO j = bo(1, 2), bo(2, 2)
3629 DO i = bo(1, 1), bo(2, 1)
3630 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3631 fac*deriv_data(i, j, k)*tau1b(i, j, k)
3632 END DO
3633 END DO
3634 END DO
3635 END IF
3636 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_laplace_rhob])
3637 IF (ASSOCIATED(deriv_att)) THEN
3638 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3639!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3640!$OMP SHARED(bo,v_xc,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
3641 DO k = bo(1, 3), bo(2, 3)
3642 DO j = bo(1, 2), bo(2, 2)
3643 DO i = bo(1, 1), bo(2, 1)
3644 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3645 fac*deriv_data(i, j, k)*laplace1b(i, j, k)
3646 END DO
3647 END DO
3648 END DO
3649 END IF
3650
3651
3652 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhoa])
3653 IF (ASSOCIATED(deriv_att)) THEN
3654 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3655!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3656!$OMP SHARED(bo,v_drho,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
3657 DO k = bo(1, 3), bo(2, 3)
3658 DO j = bo(1, 2), bo(2, 2)
3659 DO i = bo(1, 1), bo(2, 1)
3660 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3661 deriv_data(i, j, k)*rho1a(i, j, k)
3662 END DO
3663 END DO
3664 END DO
3665 END IF
3666 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drho])
3667 IF (ASSOCIATED(deriv_att)) THEN
3668 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3669!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3670!$OMP SHARED(bo,v_drho,deriv_data,dr1dr,fac) COLLAPSE(3)
3671 DO k = bo(1, 3), bo(2, 3)
3672 DO j = bo(1, 2), bo(2, 2)
3673 DO i = bo(1, 1), bo(2, 1)
3674 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3675 deriv_data(i, j, k)*dr1dr(i, j, k)
3676 END DO
3677 END DO
3678 END DO
3679 END IF
3680 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhoa])
3681 IF (ASSOCIATED(deriv_att)) THEN
3682 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3683!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3684!$OMP SHARED(bo,v_drho,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
3685 DO k = bo(1, 3), bo(2, 3)
3686 DO j = bo(1, 2), bo(2, 2)
3687 DO i = bo(1, 1), bo(2, 1)
3688 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3689 deriv_data(i, j, k)*dra1dra(i, j, k)
3690 END DO
3691 END DO
3692 END DO
3693 END IF
3694 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau_a])
3695 IF (ASSOCIATED(deriv_att)) THEN
3696 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3697!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3698!$OMP SHARED(bo,v_drho,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
3699 DO k = bo(1, 3), bo(2, 3)
3700 DO j = bo(1, 2), bo(2, 2)
3701 DO i = bo(1, 1), bo(2, 1)
3702 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3703 deriv_data(i, j, k)*tau1a(i, j, k)
3704 END DO
3705 END DO
3706 END DO
3707 END IF
3709 IF (ASSOCIATED(deriv_att)) THEN
3710 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3711!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3712!$OMP SHARED(bo,v_drho,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
3713 DO k = bo(1, 3), bo(2, 3)
3714 DO j = bo(1, 2), bo(2, 2)
3715 DO i = bo(1, 1), bo(2, 1)
3716 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3717 deriv_data(i, j, k)*laplace1a(i, j, k)
3718 END DO
3719 END DO
3720 END DO
3721 END IF
3722 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhob])
3723 IF (ASSOCIATED(deriv_att)) THEN
3724 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3725!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3726!$OMP SHARED(bo,v_drho,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
3727 DO k = bo(1, 3), bo(2, 3)
3728 DO j = bo(1, 2), bo(2, 2)
3729 DO i = bo(1, 1), bo(2, 1)
3730 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3731 fac*deriv_data(i, j, k)*rho1b(i, j, k)
3732 END DO
3733 END DO
3734 END DO
3735 END IF
3736 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhob])
3737 IF (ASSOCIATED(deriv_att)) THEN
3738 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3739!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3740!$OMP SHARED(bo,v_drho,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
3741 DO k = bo(1, 3), bo(2, 3)
3742 DO j = bo(1, 2), bo(2, 2)
3743 DO i = bo(1, 1), bo(2, 1)
3744 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3745 fac*deriv_data(i, j, k)*drb1drb(i, j, k)
3746 END DO
3747 END DO
3748 END DO
3749 END IF
3750 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau_b])
3751 IF (ASSOCIATED(deriv_att)) THEN
3752 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3753!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3754!$OMP SHARED(bo,v_drho,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
3755 DO k = bo(1, 3), bo(2, 3)
3756 DO j = bo(1, 2), bo(2, 2)
3757 DO i = bo(1, 1), bo(2, 1)
3758 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3759 fac*deriv_data(i, j, k)*tau1b(i, j, k)
3760 END DO
3761 END DO
3762 END DO
3763 END IF
3765 IF (ASSOCIATED(deriv_att)) THEN
3766 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3767!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3768!$OMP SHARED(bo,v_drho,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
3769 DO k = bo(1, 3), bo(2, 3)
3770 DO j = bo(1, 2), bo(2, 2)
3771 DO i = bo(1, 1), bo(2, 1)
3772 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3773 fac*deriv_data(i, j, k)*laplace1b(i, j, k)
3774 END DO
3775 END DO
3776 END DO
3777 END IF
3778
3779 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
3780 IF (ASSOCIATED(deriv_att)) THEN
3781 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3782 CALL xc_derivative_get(deriv_att, deriv_data=e_drho)
3783
3784
3785!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dr1dr,gradient_cut,norm_drho,v_drho,deriv_data)
3786 v_drho(1)%array(:, :, :) = v_drho(1)%array(:, :, :) + &
3787 deriv_data(:, :, :)*dr1dr(:, :, :)/max(gradient_cut, norm_drho(:, :, :))**2
3788!$OMP END PARALLEL WORKSHARE
3789 END IF
3790
3791 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhoa])
3792 IF (ASSOCIATED(deriv_att)) THEN
3793 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3794!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3795!$OMP SHARED(bo,v_drhoa,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
3796 DO k = bo(1, 3), bo(2, 3)
3797 DO j = bo(1, 2), bo(2, 2)
3798 DO i = bo(1, 1), bo(2, 1)
3799 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3800 deriv_data(i, j, k)*rho1a(i, j, k)
3801 END DO
3802 END DO
3803 END DO
3804 END IF
3805 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drho])
3806 IF (ASSOCIATED(deriv_att)) THEN
3807 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3808!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3809!$OMP SHARED(bo,v_drhoa,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
3810 DO k = bo(1, 3), bo(2, 3)
3811 DO j = bo(1, 2), bo(2, 2)
3812 DO i = bo(1, 1), bo(2, 1)
3813 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3814 deriv_data(i, j, k)*dr1dr(i, j, k)
3815 END DO
3816 END DO
3817 END DO
3818 END IF
3819 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhoa])
3820 IF (ASSOCIATED(deriv_att)) THEN
3821 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3822!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3823!$OMP SHARED(bo,v_drhoa,deriv_data,dra1dra,fac) COLLAPSE(3)
3824 DO k = bo(1, 3), bo(2, 3)
3825 DO j = bo(1, 2), bo(2, 2)
3826 DO i = bo(1, 1), bo(2, 1)
3827 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3828 deriv_data(i, j, k)*dra1dra(i, j, k)
3829 END DO
3830 END DO
3831 END DO
3832 END IF
3833 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_tau_a])
3834 IF (ASSOCIATED(deriv_att)) THEN
3835 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3836!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3837!$OMP SHARED(bo,v_drhoa,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
3838 DO k = bo(1, 3), bo(2, 3)
3839 DO j = bo(1, 2), bo(2, 2)
3840 DO i = bo(1, 1), bo(2, 1)
3841 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3842 deriv_data(i, j, k)*tau1a(i, j, k)
3843 END DO
3844 END DO
3845 END DO
3846 END IF
3848 IF (ASSOCIATED(deriv_att)) THEN
3849 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3850!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3851!$OMP SHARED(bo,v_drhoa,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
3852 DO k = bo(1, 3), bo(2, 3)
3853 DO j = bo(1, 2), bo(2, 2)
3854 DO i = bo(1, 1), bo(2, 1)
3855 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3856 deriv_data(i, j, k)*laplace1a(i, j, k)
3857 END DO
3858 END DO
3859 END DO
3860 END IF
3861 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhob])
3862 IF (ASSOCIATED(deriv_att)) THEN
3863 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3864!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3865!$OMP SHARED(bo,v_drhoa,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
3866 DO k = bo(1, 3), bo(2, 3)
3867 DO j = bo(1, 2), bo(2, 2)
3868 DO i = bo(1, 1), bo(2, 1)
3869 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3870 fac*deriv_data(i, j, k)*rho1b(i, j, k)
3871 END DO
3872 END DO
3873 END DO
3874 END IF
3875 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhob])
3876 IF (ASSOCIATED(deriv_att)) THEN
3877 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3878!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3879!$OMP SHARED(bo,v_drhoa,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
3880 DO k = bo(1, 3), bo(2, 3)
3881 DO j = bo(1, 2), bo(2, 2)
3882 DO i = bo(1, 1), bo(2, 1)
3883 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3884 fac*deriv_data(i, j, k)*drb1drb(i, j, k)
3885 END DO
3886 END DO
3887 END DO
3888 END IF
3889 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_tau_b])
3890 IF (ASSOCIATED(deriv_att)) THEN
3891 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3892!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3893!$OMP SHARED(bo,v_drhoa,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
3894 DO k = bo(1, 3), bo(2, 3)
3895 DO j = bo(1, 2), bo(2, 2)
3896 DO i = bo(1, 1), bo(2, 1)
3897 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3898 fac*deriv_data(i, j, k)*tau1b(i, j, k)
3899 END DO
3900 END DO
3901 END DO
3902 END IF
3904 IF (ASSOCIATED(deriv_att)) THEN
3905 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3906!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3907!$OMP SHARED(bo,v_drhoa,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
3908 DO k = bo(1, 3), bo(2, 3)
3909 DO j = bo(1, 2), bo(2, 2)
3910 DO i = bo(1, 1), bo(2, 1)
3911 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3912 fac*deriv_data(i, j, k)*laplace1b(i, j, k)
3913 END DO
3914 END DO
3915 END DO
3916 END IF
3917
3918 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa])
3919 IF (ASSOCIATED(deriv_att)) THEN
3920 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3921 CALL xc_derivative_get(deriv_att, deriv_data=e_drhoa)
3922
3923
3924!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dra1dra,gradient_cut,norm_drhoa,v_drhoa,deriv_data)
3925 v_drhoa(1)%array(:, :, :) = v_drhoa(1)%array(:, :, :) + &
3926 deriv_data(:, :, :)*dra1dra(:, :, :)/max(gradient_cut, norm_drhoa(:, :, :))**2
3927!$OMP END PARALLEL WORKSHARE
3928 END IF
3929
3930 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_rhoa])
3931 IF (ASSOCIATED(deriv_att)) THEN
3932 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3933!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3934!$OMP SHARED(bo,v_xc_tau,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
3935 DO k = bo(1, 3), bo(2, 3)
3936 DO j = bo(1, 2), bo(2, 2)
3937 DO i = bo(1, 1), bo(2, 1)
3938 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3939 deriv_data(i, j, k)*rho1a(i, j, k)
3940 END DO
3941 END DO
3942 END DO
3943 END IF
3944 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_norm_drho])
3945 IF (ASSOCIATED(deriv_att)) THEN
3946 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3947!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3948!$OMP SHARED(bo,v_xc_tau,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
3949 DO k = bo(1, 3), bo(2, 3)
3950 DO j = bo(1, 2), bo(2, 2)
3951 DO i = bo(1, 1), bo(2, 1)
3952 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3953 deriv_data(i, j, k)*dr1dr(i, j, k)
3954 END DO
3955 END DO
3956 END DO
3957 END IF
3958 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_norm_drhoa])
3959 IF (ASSOCIATED(deriv_att)) THEN
3960 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3961!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3962!$OMP SHARED(bo,v_xc_tau,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
3963 DO k = bo(1, 3), bo(2, 3)
3964 DO j = bo(1, 2), bo(2, 2)
3965 DO i = bo(1, 1), bo(2, 1)
3966 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3967 deriv_data(i, j, k)*dra1dra(i, j, k)
3968 END DO
3969 END DO
3970 END DO
3971 END IF
3972 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_tau_a])
3973 IF (ASSOCIATED(deriv_att)) THEN
3974 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3975!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3976!$OMP SHARED(bo,v_xc_tau,deriv_data,tau1a,fac) COLLAPSE(3)
3977 DO k = bo(1, 3), bo(2, 3)
3978 DO j = bo(1, 2), bo(2, 2)
3979 DO i = bo(1, 1), bo(2, 1)
3980 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3981 deriv_data(i, j, k)*tau1a(i, j, k)
3982 END DO
3983 END DO
3984 END DO
3985 END IF
3986 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_laplace_rhoa])
3987 IF (ASSOCIATED(deriv_att)) THEN
3988 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3989!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3990!$OMP SHARED(bo,v_xc_tau,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
3991 DO k = bo(1, 3), bo(2, 3)
3992 DO j = bo(1, 2), bo(2, 2)
3993 DO i = bo(1, 1), bo(2, 1)
3994 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3995 deriv_data(i, j, k)*laplace1a(i, j, k)
3996 END DO
3997 END DO
3998 END DO
3999 END IF
4000 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_rhob])
4001 IF (ASSOCIATED(deriv_att)) THEN
4002 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4003!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4004!$OMP SHARED(bo,v_xc_tau,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
4005 DO k = bo(1, 3), bo(2, 3)
4006 DO j = bo(1, 2), bo(2, 2)
4007 DO i = bo(1, 1), bo(2, 1)
4008 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4009 fac*deriv_data(i, j, k)*rho1b(i, j, k)
4010 END DO
4011 END DO
4012 END DO
4013 END IF
4014 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_norm_drhob])
4015 IF (ASSOCIATED(deriv_att)) THEN
4016 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4017!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4018!$OMP SHARED(bo,v_xc_tau,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
4019 DO k = bo(1, 3), bo(2, 3)
4020 DO j = bo(1, 2), bo(2, 2)
4021 DO i = bo(1, 1), bo(2, 1)
4022 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4023 fac*deriv_data(i, j, k)*drb1drb(i, j, k)
4024 END DO
4025 END DO
4026 END DO
4027 END IF
4028 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_tau_b])
4029 IF (ASSOCIATED(deriv_att)) THEN
4030 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4031!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4032!$OMP SHARED(bo,v_xc_tau,deriv_data,tau1b,fac) COLLAPSE(3)
4033 DO k = bo(1, 3), bo(2, 3)
4034 DO j = bo(1, 2), bo(2, 2)
4035 DO i = bo(1, 1), bo(2, 1)
4036 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4037 fac*deriv_data(i, j, k)*tau1b(i, j, k)
4038 END DO
4039 END DO
4040 END DO
4041 END IF
4042 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_laplace_rhob])
4043 IF (ASSOCIATED(deriv_att)) THEN
4044 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4045!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4046!$OMP SHARED(bo,v_xc_tau,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
4047 DO k = bo(1, 3), bo(2, 3)
4048 DO j = bo(1, 2), bo(2, 2)
4049 DO i = bo(1, 1), bo(2, 1)
4050 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4051 fac*deriv_data(i, j, k)*laplace1b(i, j, k)
4052 END DO
4053 END DO
4054 END DO
4055 END IF
4056
4057
4058 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_rhoa])
4059 IF (ASSOCIATED(deriv_att)) THEN
4060 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4061!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4062!$OMP SHARED(bo,v_laplace,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
4063 DO k = bo(1, 3), bo(2, 3)
4064 DO j = bo(1, 2), bo(2, 2)
4065 DO i = bo(1, 1), bo(2, 1)
4066 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4067 deriv_data(i, j, k)*rho1a(i, j, k)
4068 END DO
4069 END DO
4070 END DO
4071 END IF
4073 IF (ASSOCIATED(deriv_att)) THEN
4074 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4075!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4076!$OMP SHARED(bo,v_laplace,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
4077 DO k = bo(1, 3), bo(2, 3)
4078 DO j = bo(1, 2), bo(2, 2)
4079 DO i = bo(1, 1), bo(2, 1)
4080 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4081 deriv_data(i, j, k)*dr1dr(i, j, k)
4082 END DO
4083 END DO
4084 END DO
4085 END IF
4087 IF (ASSOCIATED(deriv_att)) THEN
4088 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4089!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4090!$OMP SHARED(bo,v_laplace,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
4091 DO k = bo(1, 3), bo(2, 3)
4092 DO j = bo(1, 2), bo(2, 2)
4093 DO i = bo(1, 1), bo(2, 1)
4094 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4095 deriv_data(i, j, k)*dra1dra(i, j, k)
4096 END DO
4097 END DO
4098 END DO
4099 END IF
4100 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_tau_a])
4101 IF (ASSOCIATED(deriv_att)) THEN
4102 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4103!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4104!$OMP SHARED(bo,v_laplace,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
4105 DO k = bo(1, 3), bo(2, 3)
4106 DO j = bo(1, 2), bo(2, 2)
4107 DO i = bo(1, 1), bo(2, 1)
4108 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4109 deriv_data(i, j, k)*tau1a(i, j, k)
4110 END DO
4111 END DO
4112 END DO
4113 END IF
4115 IF (ASSOCIATED(deriv_att)) THEN
4116 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4117!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4118!$OMP SHARED(bo,v_laplace,deriv_data,laplace1a,fac) COLLAPSE(3)
4119 DO k = bo(1, 3), bo(2, 3)
4120 DO j = bo(1, 2), bo(2, 2)
4121 DO i = bo(1, 1), bo(2, 1)
4122 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4123 deriv_data(i, j, k)*laplace1a(i, j, k)
4124 END DO
4125 END DO
4126 END DO
4127 END IF
4128 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_rhob])
4129 IF (ASSOCIATED(deriv_att)) THEN
4130 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4131!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4132!$OMP SHARED(bo,v_laplace,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
4133 DO k = bo(1, 3), bo(2, 3)
4134 DO j = bo(1, 2), bo(2, 2)
4135 DO i = bo(1, 1), bo(2, 1)
4136 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4137 fac*deriv_data(i, j, k)*rho1b(i, j, k)
4138 END DO
4139 END DO
4140 END DO
4141 END IF
4143 IF (ASSOCIATED(deriv_att)) THEN
4144 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4145!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4146!$OMP SHARED(bo,v_laplace,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
4147 DO k = bo(1, 3), bo(2, 3)
4148 DO j = bo(1, 2), bo(2, 2)
4149 DO i = bo(1, 1), bo(2, 1)
4150 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4151 fac*deriv_data(i, j, k)*drb1drb(i, j, k)
4152 END DO
4153 END DO
4154 END DO
4155 END IF
4156 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_tau_b])
4157 IF (ASSOCIATED(deriv_att)) THEN
4158 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4159!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4160!$OMP SHARED(bo,v_laplace,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
4161 DO k = bo(1, 3), bo(2, 3)
4162 DO j = bo(1, 2), bo(2, 2)
4163 DO i = bo(1, 1), bo(2, 1)
4164 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4165 fac*deriv_data(i, j, k)*tau1b(i, j, k)
4166 END DO
4167 END DO
4168 END DO
4169 END IF
4171 IF (ASSOCIATED(deriv_att)) THEN
4172 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4173!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4174!$OMP SHARED(bo,v_laplace,deriv_data,laplace1b,fac) COLLAPSE(3)
4175 DO k = bo(1, 3), bo(2, 3)
4176 DO j = bo(1, 2), bo(2, 2)
4177 DO i = bo(1, 1), bo(2, 1)
4178 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4179 fac*deriv_data(i, j, k)*laplace1b(i, j, k)
4180 END DO
4181 END DO
4182 END DO
4183 END IF
4184
4185
4186
4187
4188 END IF
4189
4190 IF (gradient_f) THEN
4191 IF (.NOT. do_spinflip) THEN
4192
4193 IF (my_compute_virial) THEN
4194 CALL virial_drho_drho(virial_pw, drhoa, v_drhoa(1), virial_xc)
4195 CALL virial_drho_drho(virial_pw, drhob, v_drhob(2), virial_xc)
4196 DO idir = 1, 3
4197!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(drho,idir,v_drho,virial_pw)
4198 virial_pw%array(:, :, :) = drho(idir)%array(:, :, :)*(v_drho(1)%array(:, :, :) + v_drho(2)%array(:, :, :))
4199!$OMP END PARALLEL WORKSHARE
4200 DO jdir = 1, idir
4201 tmp = -0.5_dp*virial_pw%pw_grid%dvol*accurate_dot_product(virial_pw%array(:, :, :), &
4202 drho(jdir)%array(:, :, :))
4203 virial_xc(jdir, idir) = virial_xc(jdir, idir) + tmp
4204 virial_xc(idir, jdir) = virial_xc(jdir, idir)
4205 END DO
4206 END DO
4207 END IF ! my_compute_virial
4208
4209 IF (my_gapw) THEN
4210!$OMP PARALLEL DO DEFAULT(NONE) &
4211!$OMP PRIVATE(ia,idir,ispin,ir) &
4212!$OMP SHARED(bo,nspins,vxg,drhoa,drhob,v_drhoa,v_drhob,v_drho, &
4213!$OMP e_drhoa,e_drhob,e_drho,drho1a,drho1b,fac,drho,drho1) COLLAPSE(3)
4214 DO ir = bo(1, 2), bo(2, 2)
4215 DO ia = bo(1, 1), bo(2, 1)
4216 DO idir = 1, 3
4217 DO ispin = 1, nspins
4218 vxg(idir, ia, ir, ispin) = &
4219 -(v_drhoa(ispin)%array(ia, ir, 1)*drhoa(idir)%array(ia, ir, 1) + &
4220 v_drhob(ispin)%array(ia, ir, 1)*drhob(idir)%array(ia, ir, 1) + &
4221 v_drho(ispin)%array(ia, ir, 1)*drho(idir)%array(ia, ir, 1))
4222 END DO
4223 IF (ASSOCIATED(e_drhoa)) THEN
4224 vxg(idir, ia, ir, 1) = vxg(idir, ia, ir, 1) + &
4225 e_drhoa(ia, ir, 1)*drho1a(idir)%array(ia, ir, 1)
4226 END IF
4227 IF (nspins /= 1 .AND. ASSOCIATED(e_drhob)) THEN
4228 vxg(idir, ia, ir, 2) = vxg(idir, ia, ir, 2) + &
4229 e_drhob(ia, ir, 1)*drho1b(idir)%array(ia, ir, 1)
4230 END IF
4231 IF (ASSOCIATED(e_drho)) THEN
4232 IF (nspins /= 1) THEN
4233 vxg(idir, ia, ir, 1) = vxg(idir, ia, ir, 1) + &
4234 e_drho(ia, ir, 1)*drho1(idir)%array(ia, ir, 1)
4235 vxg(idir, ia, ir, 2) = vxg(idir, ia, ir, 2) + &
4236 e_drho(ia, ir, 1)*drho1(idir)%array(ia, ir, 1)
4237 ELSE
4238 vxg(idir, ia, ir, 1) = vxg(idir, ia, ir, 1) + &
4239 e_drho(ia, ir, 1)*(drho1a(idir)%array(ia, ir, 1) + &
4240 fac*drho1b(idir)%array(ia, ir, 1))
4241 END IF
4242 END IF
4243 END DO
4244 END DO
4245 END DO
4246!$OMP END PARALLEL DO
4247 ELSE
4248
4249 ! partial integration
4250 DO idir = 1, 3
4251
4252 DO ispin = 1, nspins
4253!$OMP PARALLEL WORKSHARE DEFAULT(NONE) &
4254!$OMP SHARED(v_drho_r,v_drhoa,v_drhob,v_drho,drhoa,drhob,drho,ispin,idir)
4255 v_drho_r(idir, ispin)%array(:, :, :) = &
4256 v_drhoa(ispin)%array(:, :, :)*drhoa(idir)%array(:, :, :) + &
4257 v_drhob(ispin)%array(:, :, :)*drhob(idir)%array(:, :, :) + &
4258 v_drho(ispin)%array(:, :, :)*drho(idir)%array(:, :, :)
4259!$OMP END PARALLEL WORKSHARE
4260 END DO
4261 IF (ASSOCIATED(e_drhoa)) THEN
4262!$OMP PARALLEL WORKSHARE DEFAULT(NONE) &
4263!$OMP SHARED(v_drho_r,e_drhoa,drho1a,idir)
4264 v_drho_r(idir, 1)%array(:, :, :) = v_drho_r(idir, 1)%array(:, :, :) - &
4265 e_drhoa(:, :, :)*drho1a(idir)%array(:, :, :)
4266!$OMP END PARALLEL WORKSHARE
4267 END IF
4268 IF (nspins /= 1 .AND. ASSOCIATED(e_drhob)) THEN
4269!$OMP PARALLEL WORKSHARE DEFAULT(NONE)&
4270!$OMP SHARED(v_drho_r,e_drhob,drho1b,idir)
4271 v_drho_r(idir, 2)%array(:, :, :) = v_drho_r(idir, 2)%array(:, :, :) - &
4272 e_drhob(:, :, :)*drho1b(idir)%array(:, :, :)
4273!$OMP END PARALLEL WORKSHARE
4274 END IF
4275 IF (ASSOCIATED(e_drho)) THEN
4276!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4277!$OMP SHARED(bo,v_drho_r,e_drho,drho1a,drho1b,drho1,fac,idir,nspins) COLLAPSE(3)
4278 DO k = bo(1, 3), bo(2, 3)
4279 DO j = bo(1, 2), bo(2, 2)
4280 DO i = bo(1, 1), bo(2, 1)
4281 IF (nspins /= 1) THEN
4282 v_drho_r(idir, 1)%array(i, j, k) = v_drho_r(idir, 1)%array(i, j, k) - &
4283 e_drho(i, j, k)*drho1(idir)%array(i, j, k)
4284 v_drho_r(idir, 2)%array(i, j, k) = v_drho_r(idir, 2)%array(i, j, k) - &
4285 e_drho(i, j, k)*drho1(idir)%array(i, j, k)
4286 ELSE
4287 v_drho_r(idir, 1)%array(i, j, k) = v_drho_r(idir, 1)%array(i, j, k) - &
4288 e_drho(i, j, k)*(drho1a(idir)%array(i, j, k) + &
4289 fac*drho1b(idir)%array(i, j, k))
4290 END IF
4291 END DO
4292 END DO
4293 END DO
4294!$OMP END PARALLEL DO
4295 END IF
4296 END DO
4297
4298 ! partial integration
4299 DO ispin = 1, nspins
4300 CALL xc_pw_divergence(xc_deriv_method_id, v_drho_r(:, ispin), tmp_g, vxc_g, v_xc(ispin))
4301 END DO ! ispin
4302
4303 END IF
4304
4305 END IF ! .NOT.do_spinflip
4306
4307 DO idir = 1, 3
4308 DEALLOCATE (drho(idir)%array)
4309 DEALLOCATE (drho1(idir)%array)
4310 END DO
4311
4312 DO ispin = 1, nspins
4313 CALL deallocate_pw(v_drhoa(ispin), pw_pool)
4314 CALL deallocate_pw(v_drhob(ispin), pw_pool)
4315 END DO
4316
4317 DEALLOCATE (v_drhoa, v_drhob)
4318
4319 END IF ! gradient_f
4320
4321 IF (laplace_f .AND. my_compute_virial) THEN
4322 virial_pw%array(:, :, :) = -rhoa(:, :, :)
4323 CALL virial_laplace(virial_pw, pw_pool, virial_xc, v_laplace(1)%array)
4324 virial_pw%array(:, :, :) = -rhob(:, :, :)
4325 CALL virial_laplace(virial_pw, pw_pool, virial_xc, v_laplace(2)%array)
4326 END IF
4327
4328 ELSE
4329
4330 !-----------------!
4331 ! restricted case !
4332 !-----------------!
4333
4334 CALL xc_rho_set_get(rho1_set, rho=rho1)
4335
4336 IF (gradient_f) THEN
4337 CALL xc_rho_set_get(rho_set, drho=drho, norm_drho=norm_drho)
4338 CALL xc_rho_set_get(rho1_set, drho=drho1)
4339 CALL prepare_dr1dr(dr1dr, drho, drho1)
4340 END IF
4341
4342 IF (laplace_f) THEN
4343 CALL xc_rho_set_get(rho1_set, laplace_rho=laplace1)
4344
4345 ALLOCATE (v_laplace(nspins))
4346 DO ispin = 1, nspins
4347 CALL allocate_pw(v_laplace(ispin), pw_pool, bo)
4348 END DO
4349
4350 IF (my_compute_virial) CALL xc_rho_set_get(rho_set, rho=rho)
4351 END IF
4352
4353 IF (tau_f) THEN
4354 CALL xc_rho_set_get(rho1_set, tau=tau1)
4355 END IF
4356
4357 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho])
4358 IF (ASSOCIATED(deriv_att)) THEN
4359 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4360!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4361!$OMP SHARED(bo,v_xc,deriv_data,rho1,fac) COLLAPSE(3)
4362 DO k = bo(1, 3), bo(2, 3)
4363 DO j = bo(1, 2), bo(2, 2)
4364 DO i = bo(1, 1), bo(2, 1)
4365 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
4366 deriv_data(i, j, k)*rho1(i, j, k)
4367 END DO
4368 END DO
4369 END DO
4370 END IF
4371 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_norm_drho])
4372 IF (ASSOCIATED(deriv_att)) THEN
4373 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4374!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4375!$OMP SHARED(bo,v_xc,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
4376 DO k = bo(1, 3), bo(2, 3)
4377 DO j = bo(1, 2), bo(2, 2)
4378 DO i = bo(1, 1), bo(2, 1)
4379 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
4380 deriv_data(i, j, k)*dr1dr(i, j, k)
4381 END DO
4382 END DO
4383 END DO
4384 END IF
4385 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_tau])
4386 IF (ASSOCIATED(deriv_att)) THEN
4387 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4388!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4389!$OMP SHARED(bo,v_xc,deriv_data,tau1,v_xc_tau,fac) COLLAPSE(3)
4390 DO k = bo(1, 3), bo(2, 3)
4391 DO j = bo(1, 2), bo(2, 2)
4392 DO i = bo(1, 1), bo(2, 1)
4393 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
4394 deriv_data(i, j, k)*tau1(i, j, k)
4395 END DO
4396 END DO
4397 END DO
4398 END IF
4399 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_laplace_rho])
4400 IF (ASSOCIATED(deriv_att)) THEN
4401 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4402!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4403!$OMP SHARED(bo,v_xc,deriv_data,laplace1,v_laplace,fac) COLLAPSE(3)
4404 DO k = bo(1, 3), bo(2, 3)
4405 DO j = bo(1, 2), bo(2, 2)
4406 DO i = bo(1, 1), bo(2, 1)
4407 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
4408 deriv_data(i, j, k)*laplace1(i, j, k)
4409 END DO
4410 END DO
4411 END DO
4412 END IF
4413
4414
4415 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rho])
4416 IF (ASSOCIATED(deriv_att)) THEN
4417 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4418!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4419!$OMP SHARED(bo,v_drho,deriv_data,rho1,v_xc,fac) COLLAPSE(3)
4420 DO k = bo(1, 3), bo(2, 3)
4421 DO j = bo(1, 2), bo(2, 2)
4422 DO i = bo(1, 1), bo(2, 1)
4423 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
4424 deriv_data(i, j, k)*rho1(i, j, k)
4425 END DO
4426 END DO
4427 END DO
4428 END IF
4429 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drho])
4430 IF (ASSOCIATED(deriv_att)) THEN
4431 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4432!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4433!$OMP SHARED(bo,v_drho,deriv_data,dr1dr,fac) COLLAPSE(3)
4434 DO k = bo(1, 3), bo(2, 3)
4435 DO j = bo(1, 2), bo(2, 2)
4436 DO i = bo(1, 1), bo(2, 1)
4437 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
4438 deriv_data(i, j, k)*dr1dr(i, j, k)
4439 END DO
4440 END DO
4441 END DO
4442 END IF
4443 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau])
4444 IF (ASSOCIATED(deriv_att)) THEN
4445 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4446!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4447!$OMP SHARED(bo,v_drho,deriv_data,tau1,v_xc_tau,fac) COLLAPSE(3)
4448 DO k = bo(1, 3), bo(2, 3)
4449 DO j = bo(1, 2), bo(2, 2)
4450 DO i = bo(1, 1), bo(2, 1)
4451 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
4452 deriv_data(i, j, k)*tau1(i, j, k)
4453 END DO
4454 END DO
4455 END DO
4456 END IF
4457 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_laplace_rho])
4458 IF (ASSOCIATED(deriv_att)) THEN
4459 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4460!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4461!$OMP SHARED(bo,v_drho,deriv_data,laplace1,v_laplace,fac) COLLAPSE(3)
4462 DO k = bo(1, 3), bo(2, 3)
4463 DO j = bo(1, 2), bo(2, 2)
4464 DO i = bo(1, 1), bo(2, 1)
4465 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
4466 deriv_data(i, j, k)*laplace1(i, j, k)
4467 END DO
4468 END DO
4469 END DO
4470 END IF
4471
4472 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
4473 IF (ASSOCIATED(deriv_att)) THEN
4474 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4475 CALL xc_derivative_get(deriv_att, deriv_data=e_drho)
4476
4477 IF (my_compute_virial) THEN
4478 CALL virial_drho_drho1(virial_pw, drho, drho1, deriv_data, virial_xc)
4479 END IF ! my_compute_virial
4480
4481!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dr1dr,gradient_cut,norm_drho,v_drho,deriv_data)
4482 v_drho(1)%array(:, :, :) = v_drho(1)%array(:, :, :) + &
4483 deriv_data(:, :, :)*dr1dr(:, :, :)/max(gradient_cut, norm_drho(:, :, :))**2
4484!$OMP END PARALLEL WORKSHARE
4485 END IF
4486
4487 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau, deriv_rho])
4488 IF (ASSOCIATED(deriv_att)) THEN
4489 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4490!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4491!$OMP SHARED(bo,v_xc_tau,deriv_data,rho1,v_xc,fac) COLLAPSE(3)
4492 DO k = bo(1, 3), bo(2, 3)
4493 DO j = bo(1, 2), bo(2, 2)
4494 DO i = bo(1, 1), bo(2, 1)
4495 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4496 deriv_data(i, j, k)*rho1(i, j, k)
4497 END DO
4498 END DO
4499 END DO
4500 END IF
4501 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau, deriv_norm_drho])
4502 IF (ASSOCIATED(deriv_att)) THEN
4503 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4504!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4505!$OMP SHARED(bo,v_xc_tau,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
4506 DO k = bo(1, 3), bo(2, 3)
4507 DO j = bo(1, 2), bo(2, 2)
4508 DO i = bo(1, 1), bo(2, 1)
4509 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4510 deriv_data(i, j, k)*dr1dr(i, j, k)
4511 END DO
4512 END DO
4513 END DO
4514 END IF
4515 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau, deriv_tau])
4516 IF (ASSOCIATED(deriv_att)) THEN
4517 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4518!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4519!$OMP SHARED(bo,v_xc_tau,deriv_data,tau1,fac) COLLAPSE(3)
4520 DO k = bo(1, 3), bo(2, 3)
4521 DO j = bo(1, 2), bo(2, 2)
4522 DO i = bo(1, 1), bo(2, 1)
4523 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4524 deriv_data(i, j, k)*tau1(i, j, k)
4525 END DO
4526 END DO
4527 END DO
4528 END IF
4529 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau, deriv_laplace_rho])
4530 IF (ASSOCIATED(deriv_att)) THEN
4531 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4532!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4533!$OMP SHARED(bo,v_xc_tau,deriv_data,laplace1,v_laplace,fac) COLLAPSE(3)
4534 DO k = bo(1, 3), bo(2, 3)
4535 DO j = bo(1, 2), bo(2, 2)
4536 DO i = bo(1, 1), bo(2, 1)
4537 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4538 deriv_data(i, j, k)*laplace1(i, j, k)
4539 END DO
4540 END DO
4541 END DO
4542 END IF
4543
4544
4545 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho, deriv_rho])
4546 IF (ASSOCIATED(deriv_att)) THEN
4547 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4548!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4549!$OMP SHARED(bo,v_laplace,deriv_data,rho1,v_xc,fac) COLLAPSE(3)
4550 DO k = bo(1, 3), bo(2, 3)
4551 DO j = bo(1, 2), bo(2, 2)
4552 DO i = bo(1, 1), bo(2, 1)
4553 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
4554 deriv_data(i, j, k)*rho1(i, j, k)
4555 END DO
4556 END DO
4557 END DO
4558 END IF
4559 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho, deriv_norm_drho])
4560 IF (ASSOCIATED(deriv_att)) THEN
4561 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4562!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4563!$OMP SHARED(bo,v_laplace,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
4564 DO k = bo(1, 3), bo(2, 3)
4565 DO j = bo(1, 2), bo(2, 2)
4566 DO i = bo(1, 1), bo(2, 1)
4567 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
4568 deriv_data(i, j, k)*dr1dr(i, j, k)
4569 END DO
4570 END DO
4571 END DO
4572 END IF
4573 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho, deriv_tau])
4574 IF (ASSOCIATED(deriv_att)) THEN
4575 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4576!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4577!$OMP SHARED(bo,v_laplace,deriv_data,tau1,v_xc_tau,fac) COLLAPSE(3)
4578 DO k = bo(1, 3), bo(2, 3)
4579 DO j = bo(1, 2), bo(2, 2)
4580 DO i = bo(1, 1), bo(2, 1)
4581 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
4582 deriv_data(i, j, k)*tau1(i, j, k)
4583 END DO
4584 END DO
4585 END DO
4586 END IF
4588 IF (ASSOCIATED(deriv_att)) THEN
4589 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4590!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4591!$OMP SHARED(bo,v_laplace,deriv_data,laplace1,fac) COLLAPSE(3)
4592 DO k = bo(1, 3), bo(2, 3)
4593 DO j = bo(1, 2), bo(2, 2)
4594 DO i = bo(1, 1), bo(2, 1)
4595 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
4596 deriv_data(i, j, k)*laplace1(i, j, k)
4597 END DO
4598 END DO
4599 END DO
4600 END IF
4601
4602
4603 IF (my_compute_virial) THEN
4604 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho])
4605 IF (ASSOCIATED(deriv_att)) THEN
4606 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4607
4608 virial_pw%array(:, :, :) = -rho1(:, :, :)
4609 CALL virial_laplace(virial_pw, pw_pool, virial_xc, deriv_data)
4610 END IF
4611 END IF ! my_compute_virial
4612
4613
4614 IF (gradient_f) THEN
4615
4616 IF (my_compute_virial) THEN
4617 CALL virial_drho_drho(virial_pw, drho, v_drho(1), virial_xc)
4618 END IF ! my_compute_virial
4619
4620 IF (my_gapw) THEN
4621
4622 DO idir = 1, 3
4623!$OMP PARALLEL DO DEFAULT(NONE) &
4624!$OMP PRIVATE(ia,ir) &
4625!$OMP SHARED(bo,vxg,drho,v_drho,e_drho,drho1,idir,factor2) &
4626!$OMP COLLAPSE(2)
4627 DO ia = bo(1, 1), bo(2, 1)
4628 DO ir = bo(1, 2), bo(2, 2)
4629 vxg(idir, ia, ir, 1) = -drho(idir)%array(ia, ir, 1)*v_drho(1)%array(ia, ir, 1)
4630 IF (ASSOCIATED(e_drho)) THEN
4631 vxg(idir, ia, ir, 1) = vxg(idir, ia, ir, 1) + factor2*drho1(idir)%array(ia, ir, 1)*e_drho(ia, ir, 1)
4632 END IF
4633 END DO
4634 END DO
4635!$OMP END PARALLEL DO
4636 END DO
4637
4638 ELSE
4639 ! partial integration
4640 DO idir = 1, 3
4641!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(v_drho_r,drho,v_drho,drho1,e_drho,idir)
4642 v_drho_r(idir, 1)%array(:, :, :) = drho(idir)%array(:, :, :)*v_drho(1)%array(:, :, :) - &
4643 drho1(idir)%array(:, :, :)*e_drho(:, :, :)
4644!$OMP END PARALLEL WORKSHARE
4645 END DO
4646
4647 CALL xc_pw_divergence(xc_deriv_method_id, v_drho_r(:, 1), tmp_g, vxc_g, v_xc(1))
4648 END IF
4649
4650 END IF
4651
4652 IF (laplace_f .AND. my_compute_virial) THEN
4653 virial_pw%array(:, :, :) = -rho(:, :, :)
4654 CALL virial_laplace(virial_pw, pw_pool, virial_xc, v_laplace(1)%array)
4655 END IF
4656
4657 END IF
4658
4659 IF (laplace_f) THEN
4660 DO ispin = 1, nspins
4661 CALL xc_pw_laplace(v_laplace(ispin), pw_pool, xc_deriv_method_id)
4662 CALL pw_axpy(v_laplace(ispin), v_xc(ispin))
4663 END DO
4664 END IF
4665
4666 IF (gradient_f) THEN
4667
4668 DO ispin = 1, nspins
4669 CALL deallocate_pw(v_drho(ispin), pw_pool)
4670 DO idir = 1, 3
4671 CALL deallocate_pw(v_drho_r(idir, ispin), pw_pool)
4672 END DO
4673 END DO
4674 DEALLOCATE (v_drho, v_drho_r)
4675
4676 END IF
4677
4678 IF (laplace_f) THEN
4679 DO ispin = 1, nspins
4680 CALL deallocate_pw(v_laplace(ispin), pw_pool)
4681 END DO
4682 DEALLOCATE (v_laplace)
4683 END IF
4684
4685 IF (ASSOCIATED(tmp_g%pw_grid) .AND. ASSOCIATED(pw_pool)) THEN
4686 CALL pw_pool%give_back_pw(tmp_g)
4687 END IF
4688
4689 IF (ASSOCIATED(vxc_g%pw_grid) .AND. ASSOCIATED(pw_pool)) THEN
4690 CALL pw_pool%give_back_pw(vxc_g)
4691 END IF
4692
4693 IF (my_compute_virial .AND. (gradient_f .OR. laplace_f)) THEN
4694 CALL deallocate_pw(virial_pw, pw_pool)
4695 END IF
4696
4697 CALL timestop(handle)
4698
4699 END SUBROUTINE xc_calc_2nd_deriv_analytical
4700
4701! **************************************************************************************************
4702!> \brief Calculates the third functional derivative of the exchange-correlation functional, E_xc.
4703!> Any GGA functional can be written as:
4704!>
4705!> E_xc[\rho] = \int e_xc(\rho,\nabla\rho)dr
4706!>
4707!> This routine gives you back the contraction of the derivatives of e_xc with respect to the
4708!> alpha or beta density or with respect to the norm of their gradients contracted with rho1.
4709!> For example, the alpha component would be (d stands for total derivative):
4710!>
4711!> d^3 e_xc
4712!> v_xc(1) = \sum_{s,s'}^{a,b} ---------------------\rhos1\rho1s'
4713!> d\rhoa d\rhos d\rhos'
4714!>
4715!> \param v_xc Third derivative of the exchange-correlation functional
4716!> \param v_xc_tau ...
4717!> \param deriv_set derivatives of the exchange-correlation potential, e_xc
4718!> \param rho_set object containing the density at which the derivatives were calculated, \rho
4719!> \param rho1_set object containing the density with which to fold, \rho1s
4720!> \param pw_pool the pool for the grids
4721!> \param xc_section XC parameters
4722!> \par History
4723!> * 07.2024 Created [LHS]
4724! **************************************************************************************************
4725 SUBROUTINE xc_calc_3rd_deriv_analytical(v_xc, v_xc_tau, deriv_set, rho_set, rho1_set, &
4726 pw_pool, xc_section, spinflip)
4727
4728 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_xc, v_xc_tau
4729 TYPE(xc_derivative_set_type) :: deriv_set
4730 TYPE(xc_rho_set_type), INTENT(IN) :: rho_set, rho1_set
4731 TYPE(pw_pool_type), POINTER :: pw_pool
4732 TYPE(section_vals_type), POINTER :: xc_section
4733 LOGICAL, INTENT(in), OPTIONAL :: spinflip
4734
4735 CHARACTER(len=*), PARAMETER :: routinen = 'xc_calc_3rd_deriv_analytical'
4736
4737 INTEGER :: handle, i, idir, ispin, j, &
4738 k, nspins, xc_deriv_method_id
4739 INTEGER, DIMENSION(2, 3) :: bo
4740 LOGICAL :: lsd, do_spinflip, alda0, &
4741 rho_f, gradient_f, tau_f, laplace_f
4742 REAL(kind=dp) :: s, s_thresh, s_thresh2, gradient_cut
4743 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: dr1dr, dra1dra, drb1drb
4744 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: deriv_data, deriv_data2, e_drhoa, e_drhob, &
4745 e_drho, norm_drho, norm_drhoa, &
4746 norm_drhob, rho1a, rho1b, &
4747 rhoa, rhob
4748 TYPE(cp_3d_r_cp_type), DIMENSION(3) :: drho, drho1, drho1a, drho1b, drhoa, drhob
4749 TYPE(pw_r3d_rs_type), DIMENSION(:), ALLOCATABLE :: v_drhoa, v_drhob, v_drho
4750 TYPE(pw_r3d_rs_type), DIMENSION(:, :), ALLOCATABLE :: v_drho_r
4751 TYPE(pw_c1d_gs_type) :: tmp_g, vxc_g
4752 TYPE(xc_derivative_type), POINTER :: deriv_att
4753
4754 CALL timeset(routinen, handle)
4755
4756 NULLIFY (e_drhoa, e_drhob, e_drho)
4757
4758 cpassert(ASSOCIATED(v_xc))
4759 cpassert(ASSOCIATED(xc_section))
4760
4761 ! Initialize parameters
4762 CALL section_vals_val_get(xc_section, "XC_GRID%XC_DERIV", &
4763 i_val=xc_deriv_method_id)
4764 !
4765 nspins = SIZE(v_xc)
4766 lsd = ASSOCIATED(rho_set%rhoa)
4767 !
4768 do_spinflip = .false.
4769 IF (PRESENT(spinflip)) do_spinflip = spinflip
4770 !
4771 bo = rho_set%local_bounds
4772 !
4773 CALL check_for_derivatives(deriv_set, lsd, rho_f, gradient_f, tau_f, laplace_f)
4774 !
4775 CALL xc_rho_set_get(rho_set, drho_cutoff=gradient_cut)
4776 !
4777 !S_THRESH has to be the same as S_THRESH in xc_calc_2nd_deriv_analytical
4778 alda0 = .false.
4779 s_thresh = 1.0e-04
4780 s_thresh2 = 1.0e-07
4781
4782 ! Initialize potential
4783 DO ispin = 1, nspins
4784 !CALL pw_zero(v_xc(ispin))
4785 v_xc(ispin)%array = 0.0_dp
4786 END DO
4787
4788 ! Create GGA fields
4789 IF (gradient_f) THEN
4790 ALLOCATE (v_drho_r(3, nspins), v_drho(nspins))
4791 DO ispin = 1, nspins
4792 DO idir = 1, 3
4793 CALL allocate_pw(v_drho_r(idir, ispin), pw_pool, bo)
4794 END DO
4795 CALL allocate_pw(v_drho(ispin), pw_pool, bo)
4796 END DO
4797
4798 IF (xc_requires_tmp_g(xc_deriv_method_id)) THEN
4799 IF (ASSOCIATED(pw_pool)) THEN
4800 CALL pw_pool%create_pw(tmp_g)
4801 CALL pw_pool%create_pw(vxc_g)
4802 ELSE
4803 ! remember to refix for gapw
4804 cpabort("XC_DERIV method is not implemented in GAPW")
4805 END IF
4806 END IF
4807
4808 END IF
4809
4810 ! Initialize mGGA potential
4811 IF (tau_f) THEN
4812 cpassert(ASSOCIATED(v_xc_tau))
4813 DO ispin = 1, nspins
4814 v_xc_tau(ispin)%array = 0.0_dp
4815 END DO
4816 END IF
4817
4818 IF (lsd) THEN
4819
4820 !-------------------!
4821 ! UNrestricted case !
4822 !-------------------!
4823
4824 IF (do_spinflip) THEN
4825 CALL xc_rho_set_get(rho1_set, rhoa=rho1a)
4826 CALL xc_rho_set_get(rho_set, rhoa=rhoa, rhob=rhob)
4827 ELSE
4828 CALL xc_rho_set_get(rho1_set, rhoa=rho1a, rhob=rho1b)
4829 END IF
4830
4831 IF (gradient_f) THEN
4832 CALL xc_rho_set_get(rho_set, drhoa=drhoa, drhob=drhob, &
4833 norm_drho=norm_drho, norm_drhoa=norm_drhoa, norm_drhob=norm_drhob)
4834 IF (do_spinflip) THEN
4835 CALL xc_rho_set_get(rho1_set, drhoa=drho1a)
4836 CALL calc_drho_from_a(drho1, drho1a)
4837 ELSE
4838 CALL xc_rho_set_get(rho1_set, drhoa=drho1a, drhob=drho1b)
4839 CALL calc_drho_from_ab(drho1, drho1a, drho1b)
4840 END IF
4841
4842 CALL calc_drho_from_ab(drho, drhoa, drhob)
4843
4844 CALL prepare_dr1dr(dra1dra, drhoa, drho1a)
4845 IF (do_spinflip) THEN
4846 CALL prepare_dr1dr(drb1drb, drhob, drho1a)
4847 CALL prepare_dr1dr(dr1dr, drho, drho1a)
4848 ELSE IF (nspins /= 1) THEN
4849 CALL prepare_dr1dr(drb1drb, drhob, drho1b)
4850 CALL prepare_dr1dr(dr1dr, drho, drho1)
4851 ELSE
4852 cpabort("Exchange-correlation's third derivative for closed-shell not yet implemented")
4853 END IF
4854
4855 ! Create vectors for partial integration term
4856 ALLOCATE (v_drhoa(nspins), v_drhob(nspins))
4857 DO ispin = 1, nspins
4858 CALL allocate_pw(v_drhoa(ispin), pw_pool, bo)
4859 CALL allocate_pw(v_drhob(ispin), pw_pool, bo)
4860 END DO
4861
4862 END IF
4863
4864 IF (laplace_f) THEN
4865 cpabort("Exchange-correlation's laplace analytic third derivative not implemented")
4866 END IF
4867
4868 IF (tau_f) THEN
4869 cpabort("Exchange-correlation's mGGA analytic third derivative not implemented")
4870 END IF
4871
4872 IF (nspins /= 1) THEN
4873
4874 IF (.NOT. do_spinflip) THEN
4875 ! Analytic third derivative of the excchange-correlation functional
4876 cpabort("Exchange-correlation's analytic third derivative not implemented")
4877
4878 ELSE
4879
4880 ! vxc contributions
4881 ! vxca = (vxc^{\alpha}-vxc^{\beta})*rho1/|rhoa-rhob|^2
4882 ! vxcb =-(vxc^{\alpha}-vxc^{\beta})*rho1/|rhoa-rhob|^2
4883 ! Alpha LDA contribution
4884 ! | d e_xc d e_xc | rho1a
4885 ! vxca = rho1a*|-------- - --------|*---------------
4886 ! | drhoa drhob | |rhoa - rhob|^2
4887 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa])
4888 IF (ASSOCIATED(deriv_att)) THEN
4889 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4890 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob])
4891 IF (ASSOCIATED(deriv_att)) THEN
4892 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
4893!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
4894!$OMP SHARED(bo,v_xc,deriv_data,deriv_data2,rho1a,rhoa,rhob,S_THRESH2) COLLAPSE(3)
4895 DO k = bo(1, 3), bo(2, 3)
4896 DO j = bo(1, 2), bo(2, 2)
4897 DO i = bo(1, 1), bo(2, 1)
4898 s = rhoa(i, j, k) - rhob(i, j, k)
4899 s = -sign(max(s**2, s_thresh2), s)
4900 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
4901 (deriv_data(i, j, k) - deriv_data2(i, j, k))*rho1a(i, j, k)**2/s
4902 END DO
4903 END DO
4904 END DO
4905!$OMP END PARALLEL DO
4906 END IF
4907 END IF
4908 ! GGA contributions to the spin-flip xcKernel
4909 ! Alpha GGA contributions
4910 ! | d e_xc d e_xc | rho1a
4911 ! vxca += + |----------*dra1dra - ----------*drb1drb|*---------------
4912 ! | d|drhoa| d|drhob| | |rhoa - rhob|^2
4913 IF (.NOT. alda0) THEN
4914 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa])
4915 IF (ASSOCIATED(deriv_att)) THEN
4916 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4917 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob])
4918 IF (ASSOCIATED(deriv_att)) THEN
4919 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
4920!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
4921!$OMP SHARED(bo,deriv_data,deriv_data2,dra1dra,drb1drb,v_xc,rho1a,rhoa,rhob,S_THRESH2) COLLAPSE(3)
4922 DO k = bo(1, 3), bo(2, 3)
4923 DO j = bo(1, 2), bo(2, 2)
4924 DO i = bo(1, 1), bo(2, 1)
4925 s = rhoa(i, j, k) - rhob(i, j, k)
4926 s = -sign(max(s**2, s_thresh2), s)
4927 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
4928 (deriv_data(i, j, k)*dra1dra(i, j, k) - deriv_data2(i, j, k)*drb1drb(i, j, k)) &
4929 *rho1a(i, j, k)/s
4930 END DO
4931 END DO
4932 END DO
4933!$OMP END PARALLEL DO
4934 END IF
4935 END IF
4936 END IF
4937 ! Beta contribution = - alpha
4938!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
4939!$OMP SHARED(bo,v_xc) COLLAPSE(3)
4940 DO k = bo(1, 3), bo(2, 3)
4941 DO j = bo(1, 2), bo(2, 2)
4942 DO i = bo(1, 1), bo(2, 1)
4943 v_xc(2)%array(i, j, k) = -v_xc(1)%array(i, j, k)
4944 END DO
4945 END DO
4946 END DO
4947!$OMP END PARALLEL DO
4948 ! fxc contributions
4949 ! vxca = rho1*(fxc^{\alpha\alpha}-fxc^{\alpha\beta})*rho1/|rhoa-rhob|
4950 ! vxcb = rho1*(fxc^{\beta\alpha}-fxc^{\beta\beta})*rho1/|rhoa-rhob|
4951 ! Alpha LDA contribution
4952 ! | d^2 e_xc d^2 e_xc | rho1a
4953 ! vxca += rho1a*|------------- - -------------|*-------------
4954 ! | drhoa drhoa drhoa drhob | |rhoa - rhob|
4955 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhob])
4956 IF (ASSOCIATED(deriv_att)) THEN
4957 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
4958 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa])
4959 IF (ASSOCIATED(deriv_att)) THEN
4960 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4961!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
4962!$OMP SHARED(bo,deriv_data,deriv_data2,rho1a,v_xc,rhoa,rhob,S_THRESH) COLLAPSE(3)
4963 DO k = bo(1, 3), bo(2, 3)
4964 DO j = bo(1, 2), bo(2, 2)
4965 DO i = bo(1, 1), bo(2, 1)
4966 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
4967 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
4968 rho1a(i, j, k)**2*(deriv_data(i, j, k) - deriv_data2(i, j, k))/s
4969 END DO
4970 END DO
4971 END DO
4972!$OMP END PARALLEL DO
4973 END IF
4974 END IF
4975 ! Beta LDA contribution
4976 ! | d^2 e_xc d^2 e_xc | rho1a
4977 ! vxcb += rho1a*|------------- - -------------|*-------------
4978 ! | drhob drhoa drhob drhob | |rhoa - rhob|
4979 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob])
4980 IF (ASSOCIATED(deriv_att)) THEN
4981 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
4982 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhoa])
4983 IF (ASSOCIATED(deriv_att)) THEN
4984 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4985!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
4986!$OMP SHARED(bo,deriv_data,deriv_data2,rho1a,v_xc,rhoa,rhob,S_THRESH) COLLAPSE(3)
4987 DO k = bo(1, 3), bo(2, 3)
4988 DO j = bo(1, 2), bo(2, 2)
4989 DO i = bo(1, 1), bo(2, 1)
4990 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
4991 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
4992 rho1a(i, j, k)**2*(deriv_data(i, j, k) - deriv_data2(i, j, k))/s
4993 END DO
4994 END DO
4995 END DO
4996!$OMP END PARALLEL DO
4997 END IF
4998 END IF
4999 ! Alpha GGA contribution
5000 IF (.NOT. alda0) THEN
5001 ! rho1a | d^2 e_xc d^2 e_xc |
5002 ! vxca += + -------------*|----------------*dra1dra - ----------------*drb1drb|
5003 ! |rhoa - rhob| | drhoa d|drhoa| drhoa d|drhob| |
5004 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drhob])
5005 IF (ASSOCIATED(deriv_att)) THEN
5006 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
5007 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drhoa])
5008 IF (ASSOCIATED(deriv_att)) THEN
5009 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5010!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
5011!$OMP SHARED(bo,deriv_data,deriv_data2,dra1dra,drb1drb,rho1a,v_xc,rhoa,rhob,S_THRESH) COLLAPSE(3)
5012 DO k = bo(1, 3), bo(2, 3)
5013 DO j = bo(1, 2), bo(2, 2)
5014 DO i = bo(1, 1), bo(2, 1)
5015 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
5016 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
5017 (deriv_data(i, j, k)*dra1dra(i, j, k) - deriv_data2(i, j, k)*drb1drb(i, j, k))* &
5018 rho1a(i, j, k)/s
5019 END DO
5020 END DO
5021 END DO
5022!$OMP END PARALLEL DO
5023 END IF
5024 END IF
5025 ! Beta GGA contribution
5026 ! rho1a | d^2 e_xc d^2 e_xc |
5027 ! vxcb += + -------------*|----------------*dra1dra - ----------------*drb1drb|
5028 ! |rhoa - rhob| | drhob d|drhoa| drhob d|drhob| |
5029 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_norm_drhob])
5030 IF (ASSOCIATED(deriv_att)) THEN
5031 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
5032 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_norm_drhoa])
5033 IF (ASSOCIATED(deriv_att)) THEN
5034 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5035!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
5036!$OMP SHARED(bo,deriv_data,deriv_data2,dra1dra,drb1drb,rho1a,v_xc,rhoa,rhob,S_THRESH) COLLAPSE(3)
5037 DO k = bo(1, 3), bo(2, 3)
5038 DO j = bo(1, 2), bo(2, 2)
5039 DO i = bo(1, 1), bo(2, 1)
5040 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
5041 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
5042 (deriv_data(i, j, k)*dra1dra(i, j, k) - deriv_data2(i, j, k)*drb1drb(i, j, k))* &
5043 rho1a(i, j, k)/s
5044 END DO
5045 END DO
5046 END DO
5047!$OMP END PARALLEL DO
5048 END IF
5049 END IF
5050 !
5051 !
5052 ! Calculate the vector for the partial integration term of GGA functionals
5053 ! First contribution alpha
5054 ! | d^2 e_xc d^2 e_xc |
5055 ! v_drhoa(1) += -|---------------- - ----------------|*rho1a
5056 ! | d|drhoa| drhoa d|drhoa| drhob |
5057 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhob])
5058 IF (ASSOCIATED(deriv_att)) THEN
5059 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
5060 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhoa])
5061 IF (ASSOCIATED(deriv_att)) THEN
5062 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5063!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
5064!$OMP SHARED(bo,deriv_data,deriv_data2,rho1a,v_drhoa) COLLAPSE(3)
5065 DO k = bo(1, 3), bo(2, 3)
5066 DO j = bo(1, 2), bo(2, 2)
5067 DO i = bo(1, 1), bo(2, 1)
5068 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
5069 (deriv_data(i, j, k) - deriv_data2(i, j, k))*rho1a(i, j, k)
5070 END DO
5071 END DO
5072 END DO
5073!$OMP END PARALLEL DO
5074 END IF
5075 END IF
5076 ! First contribution beta
5077 ! | d^2 e_xc d^2 e_xc |
5078 ! v_drhob(2) += +|---------------- - ----------------|*rho1a
5079 ! | d|drhob| drhob d|drhob| drhoa |
5080 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhoa])
5081 IF (ASSOCIATED(deriv_att)) THEN
5082 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
5083 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhob])
5084 IF (ASSOCIATED(deriv_att)) THEN
5085 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5086!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
5087!$OMP SHARED(bo,deriv_data,deriv_data2,rho1a,v_drhob) COLLAPSE(3)
5088 DO k = bo(1, 3), bo(2, 3)
5089 DO j = bo(1, 2), bo(2, 2)
5090 DO i = bo(1, 1), bo(2, 1)
5091 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) + &
5092 (deriv_data(i, j, k) - deriv_data2(i, j, k))*rho1a(i, j, k)
5093 END DO
5094 END DO
5095 END DO
5096!$OMP END PARALLEL DO
5097 END IF
5098 END IF
5099 ! First contribution spinless
5100 ! | d^2 e_xc d^2 e_xc |
5101 ! v_drho(1) += -|--------------- - ---------------|*rho1a
5102 ! | d|drho| drhoa d|drho| drhob |
5103 !
5104 ! | d^2 e_xc d^2 e_xc |
5105 ! v_drho(2) += -|--------------- - ---------------|*rho1a
5106 ! | d|drho| drhoa d|drho| drhob |
5107 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhoa])
5108 IF (ASSOCIATED(deriv_att)) THEN
5109 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5110 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhob])
5111 IF (ASSOCIATED(deriv_att)) THEN
5112 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
5113!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
5114!$OMP SHARED(bo,deriv_data,deriv_data2,rho1a,v_drho) COLLAPSE(3)
5115 DO k = bo(1, 3), bo(2, 3)
5116 DO j = bo(1, 2), bo(2, 2)
5117 DO i = bo(1, 1), bo(2, 1)
5118 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
5119 (deriv_data(i, j, k) - deriv_data2(i, j, k))*rho1a(i, j, k)
5120 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
5121 (deriv_data(i, j, k) - deriv_data2(i, j, k))*rho1a(i, j, k)
5122 END DO
5123 END DO
5124 END DO
5125!$OMP END PARALLEL DO
5126 END IF
5127 END IF
5128 ! Second contribution
5129 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhob])
5130 IF (ASSOCIATED(deriv_att)) THEN
5131 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
5132 ! d^2 e_xc d^2 e_xc
5133 ! v_drhoa(1) += - -------------------*dra1dra + ------------------*drb1drb
5134 ! d|drhoa| d|drhoa| d|drhoa| d|drhob|
5135 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhoa])
5136 IF (ASSOCIATED(deriv_att)) THEN
5137 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5138!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
5139!$OMP SHARED(bo,deriv_data,deriv_data2,dra1dra,drb1drb,v_drhoa) COLLAPSE(3)
5140 DO k = bo(1, 3), bo(2, 3)
5141 DO j = bo(1, 2), bo(2, 2)
5142 DO i = bo(1, 1), bo(2, 1)
5143 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
5144 deriv_data(i, j, k)*dra1dra(i, j, k) + deriv_data2(i, j, k)*drb1drb(i, j, k)
5145 END DO
5146 END DO
5147 END DO
5148!$OMP END PARALLEL DO
5149 END IF
5150 ! d^2 e_xc d^2 e_xc
5151 ! v_drhob(2) += - -------------------*dra1dra + -------------------*drb1drb
5152 ! d|drhoa| d|drhob| d|drhob| d|drhob|
5153 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_norm_drhob])
5154 IF (ASSOCIATED(deriv_att)) THEN
5155 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5156!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
5157!$OMP SHARED(bo,deriv_data,deriv_data2,dra1dra,drb1drb,v_drhob) COLLAPSE(3)
5158 DO k = bo(1, 3), bo(2, 3)
5159 DO j = bo(1, 2), bo(2, 2)
5160 DO i = bo(1, 1), bo(2, 1)
5161 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
5162 deriv_data(i, j, k)*dra1dra(i, j, k) + deriv_data2(i, j, k)*drb1drb(i, j, k)
5163 END DO
5164 END DO
5165 END DO
5166!$OMP END PARALLEL DO
5167 END IF
5168 END IF
5169 ! d^2 e_xc d^2 e_xc
5170 ! v_drho(1) += - ------------------*dra1dra + ------------------*drb1drb
5171 ! d|drho| d|drhoa| d|drho| d|drhob|
5172 !
5173 ! d^2 e_xc d^2 e_xc
5174 ! v_drho(2) += - ------------------*dra1dra + ------------------*drb1drb
5175 ! d|drho| d|drhoa| d|drho| d|drhob|
5176 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhob])
5177 IF (ASSOCIATED(deriv_att)) THEN
5178 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
5179 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhoa])
5180 IF (ASSOCIATED(deriv_att)) THEN
5181 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5182!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
5183!$OMP SHARED(bo,deriv_data,deriv_data2,dra1dra,drb1drb,v_drho) COLLAPSE(3)
5184 DO k = bo(1, 3), bo(2, 3)
5185 DO j = bo(1, 2), bo(2, 2)
5186 DO i = bo(1, 1), bo(2, 1)
5187 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
5188 deriv_data(i, j, k)*dra1dra(i, j, k) + &
5189 deriv_data2(i, j, k)*drb1drb(i, j, k)
5190 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
5191 deriv_data(i, j, k)*dra1dra(i, j, k) + &
5192 deriv_data2(i, j, k)*drb1drb(i, j, k)
5193 END DO
5194 END DO
5195 END DO
5196!$OMP END PARALLEL DO
5197 END IF
5198 END IF
5199 !
5200
5201 ! Last GGA contribution
5202 ! Alpha contribution
5203 ! d e_xc
5204 ! v_drhoa(1) += + ----------*dra1dra
5205 ! d|drhoa|
5206 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa])
5207 IF (ASSOCIATED(deriv_att)) THEN
5208 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5209 CALL xc_derivative_get(deriv_att, deriv_data=e_drhoa)
5210
5211!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dra1dra,gradient_cut,norm_drhoa,v_drhoa,deriv_data)
5212 v_drhoa(1)%array(:, :, :) = v_drhoa(1)%array(:, :, :) + &
5213 deriv_data(:, :, :)*dra1dra(:, :, :)/max(gradient_cut, norm_drhoa(:, :, :))**2
5214!$OMP END PARALLEL WORKSHARE
5215 END IF
5216 ! Beta contribution
5217 ! d e_xc
5218 ! v_drhob(2) += - ----------*drb1drb
5219 ! d|drhob|
5220 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob])
5221 IF (ASSOCIATED(deriv_att)) THEN
5222 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5223 CALL xc_derivative_get(deriv_att, deriv_data=e_drhob)
5224
5225!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(drb1drb,gradient_cut,norm_drhob,v_drhob,deriv_data)
5226 v_drhob(2)%array(:, :, :) = v_drhob(2)%array(:, :, :) - &
5227 deriv_data(:, :, :)*drb1drb(:, :, :)/max(gradient_cut, norm_drhob(:, :, :))**2
5228!$OMP END PARALLEL WORKSHARE
5229 END IF
5230 END IF ! If ALDA0
5231 END IF
5232
5233 ELSE
5234
5235 ! Analytic third derivative for closed-shell
5236 cpabort("Exchange-correlation's analytic third derivative not implemented")
5237
5238 END IF
5239
5240 IF (gradient_f) THEN
5241 IF (.NOT. alda0) THEN
5242
5243 ! partial integration
5244 DO idir = 1, 3
5245
5246 ! GGA contributions to the spin-flip xc-Kernel
5247 !
5248 ! v_drhoa(1)*drhoa(:)*rhoa1 v_drhob(1)*drhob(:)*rhoa1 v_drho(1)*drho(:)*rhoa1
5249 ! v_drho_r(:,1) = --------------------------- + --------------------------- + -------------------------
5250 ! |rhoa - rhob| |rhoa - rhob| |rhoa - rhob|
5251 !
5252 ! v_drhoa(2)*drhoa(:)*rhoa1 v_drhob(2)*drhob(:)*rhoa1 v_drho(2)*drho(:)*rhoa1
5253 ! v_drho_r(:,2) = --------------------------- + --------------------------- + -------------------------
5254 ! |rhoa - rhob| |rhoa - rhob| |rhoa - rhob|
5255 IF (do_spinflip) THEN
5256!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
5257!$OMP SHARED(bo,v_drho_r,v_drho,v_drhoa,v_drhob,rhoa,rhob,drho,drhoa,drhob,rho1a,idir,S_THRESH) COLLAPSE(3)
5258 DO k = bo(1, 3), bo(2, 3)
5259 DO j = bo(1, 2), bo(2, 2)
5260 DO i = bo(1, 1), bo(2, 1)
5261 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
5262 DO ispin = 1, 2
5263 v_drho_r(idir, ispin)%array(i, j, k) = v_drho_r(idir, ispin)%array(i, j, k) + &
5264 v_drhoa(ispin)%array(i, j, k)*drhoa(idir)%array(i, j, k)*rho1a(i, j, k)/s + &
5265 v_drhob(ispin)%array(i, j, k)*drhob(idir)%array(i, j, k)*rho1a(i, j, k)/s + &
5266 v_drho(ispin)%array(i, j, k)*drho(idir)%array(i, j, k)*rho1a(i, j, k)/s
5267 END DO
5268 END DO
5269 END DO
5270 END DO
5271!$OMP END PARALLEL DO
5272 END IF
5273 ! Last GGA contribution
5274 ! Alpha contribution
5275 ! rho1a d e_xc
5276 ! v_drho_r(:,1) += - -------------*----------*drho1a(:)
5277 ! |rhoa - rhob| d|drhoa|
5278 IF (ASSOCIATED(e_drhoa)) THEN
5279!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
5280!$OMP SHARED(bo,e_drhoa,v_drho_r,drho1a,rho1a,rhoa,rhob,S_THRESH,idir) COLLAPSE(3)
5281 DO k = bo(1, 3), bo(2, 3)
5282 DO j = bo(1, 2), bo(2, 2)
5283 DO i = bo(1, 1), bo(2, 1)
5284 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
5285 v_drho_r(idir, 1)%array(i, j, k) = v_drho_r(idir, 1)%array(i, j, k) - &
5286 e_drhoa(i, j, k)*drho1a(idir)%array(i, j, k)*rho1a(i, j, k)/s
5287 END DO
5288 END DO
5289 END DO
5290!$OMP END PARALLEL DO
5291 END IF
5292 ! Beta contribution
5293 ! rho1a d e_xc
5294 ! v_drho_r(:,2) += + -------------*----------*drho1a(:)
5295 ! |rhoa - rhob| d|drhob|
5296 IF (ASSOCIATED(e_drhob)) THEN
5297!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
5298!$OMP SHARED(bo,e_drhob,v_drho_r,drho1a,rho1a,rhoa,rhob,S_THRESH,idir) COLLAPSE(3)
5299 DO k = bo(1, 3), bo(2, 3)
5300 DO j = bo(1, 2), bo(2, 2)
5301 DO i = bo(1, 1), bo(2, 1)
5302 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
5303 v_drho_r(idir, 2)%array(i, j, k) = v_drho_r(idir, 2)%array(i, j, k) + &
5304 e_drhob(i, j, k)*drho1a(idir)%array(i, j, k)*rho1a(i, j, k)/s
5305 END DO
5306 END DO
5307 END DO
5308!$OMP END PARALLEL DO
5309 END IF
5310 END DO
5311
5312 ! partial integration: v_xc = v_xc - \nabla \cdot vdrho_r
5313 DO ispin = 1, nspins
5314 CALL xc_pw_divergence(xc_deriv_method_id, v_drho_r(:, ispin), tmp_g, vxc_g, v_xc(ispin))
5315 END DO ! ispin
5316 END IF ! ALDA0
5317
5318 DO idir = 1, 3
5319 DEALLOCATE (drho(idir)%array)
5320 DEALLOCATE (drho1(idir)%array)
5321 END DO
5322
5323 DO ispin = 1, nspins
5324 CALL deallocate_pw(v_drhoa(ispin), pw_pool)
5325 CALL deallocate_pw(v_drhob(ispin), pw_pool)
5326 END DO
5327
5328 DEALLOCATE (v_drhoa, v_drhob)
5329
5330 END IF ! gradient_f
5331
5332 ELSE
5333
5334 !-----------------!
5335 ! restricted case !
5336 !-----------------!
5337 cpabort("Exchange-correlation's analytic third derivative not implemented")
5338
5339 END IF
5340
5341 IF (gradient_f) THEN
5342
5343 DO ispin = 1, nspins
5344 CALL deallocate_pw(v_drho(ispin), pw_pool)
5345 DO idir = 1, 3
5346 CALL deallocate_pw(v_drho_r(idir, ispin), pw_pool)
5347 END DO
5348 END DO
5349 DEALLOCATE (v_drho, v_drho_r)
5350
5351 END IF
5352
5353 IF (ASSOCIATED(tmp_g%pw_grid) .AND. ASSOCIATED(pw_pool)) THEN
5354 CALL pw_pool%give_back_pw(tmp_g)
5355 END IF
5356
5357 IF (ASSOCIATED(vxc_g%pw_grid) .AND. ASSOCIATED(pw_pool)) THEN
5358 CALL pw_pool%give_back_pw(vxc_g)
5359 END IF
5360
5361 CALL timestop(handle)
5362 END SUBROUTINE xc_calc_3rd_deriv_analytical
5363
5364! **************************************************************************************************
5365!> \brief allocates grids using pw_pool (if associated) or with bounds
5366!> \param pw ...
5367!> \param pw_pool ...
5368!> \param bo ...
5369! **************************************************************************************************
5370 SUBROUTINE allocate_pw(pw, pw_pool, bo)
5371 TYPE(pw_r3d_rs_type), INTENT(OUT) :: pw
5372 TYPE(pw_pool_type), INTENT(IN), POINTER :: pw_pool
5373 INTEGER, DIMENSION(2, 3), INTENT(IN) :: bo
5374
5375 IF (ASSOCIATED(pw_pool)) THEN
5376 CALL pw_pool%create_pw(pw)
5377 CALL pw_zero(pw)
5378 ELSE
5379 ALLOCATE (pw%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
5380 pw%array = 0.0_dp
5381 END IF
5382
5383 END SUBROUTINE allocate_pw
5384
5385! **************************************************************************************************
5386!> \brief deallocates grid allocated with allocate_pw
5387!> \param pw ...
5388!> \param pw_pool ...
5389! **************************************************************************************************
5390 SUBROUTINE deallocate_pw(pw, pw_pool)
5391 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: pw
5392 TYPE(pw_pool_type), INTENT(IN), POINTER :: pw_pool
5393
5394 IF (ASSOCIATED(pw_pool)) THEN
5395 CALL pw_pool%give_back_pw(pw)
5396 ELSE
5397 CALL pw%release()
5398 END IF
5399
5400 END SUBROUTINE deallocate_pw
5401
5402! **************************************************************************************************
5403!> \brief updates virial from first derivative w.r.t. norm_drho
5404!> \param virial_pw ...
5405!> \param drho ...
5406!> \param drho1 ...
5407!> \param deriv_data ...
5408!> \param virial_xc ...
5409! **************************************************************************************************
5410 SUBROUTINE virial_drho_drho1(virial_pw, drho, drho1, deriv_data, virial_xc)
5411 TYPE(pw_r3d_rs_type), INTENT(IN) :: virial_pw
5412 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(IN) :: drho, drho1
5413 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: deriv_data
5414 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT) :: virial_xc
5415
5416 INTEGER :: idir, jdir
5417 REAL(kind=dp) :: tmp
5418
5419 DO idir = 1, 3
5420!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(drho,idir,virial_pw,deriv_data)
5421 virial_pw%array(:, :, :) = drho(idir)%array(:, :, :)*deriv_data(:, :, :)
5422!$OMP END PARALLEL WORKSHARE
5423 DO jdir = 1, 3
5424 tmp = virial_pw%pw_grid%dvol*accurate_dot_product(virial_pw%array(:, :, :), &
5425 drho1(jdir)%array(:, :, :))
5426 virial_xc(jdir, idir) = virial_xc(jdir, idir) + tmp
5427 virial_xc(idir, jdir) = virial_xc(idir, jdir) + tmp
5428 END DO
5429 END DO
5430
5431 END SUBROUTINE virial_drho_drho1
5432
5433! **************************************************************************************************
5434!> \brief Adds virial contribution from second order potential parts
5435!> \param virial_pw ...
5436!> \param drho ...
5437!> \param v_drho ...
5438!> \param virial_xc ...
5439! **************************************************************************************************
5440 SUBROUTINE virial_drho_drho(virial_pw, drho, v_drho, virial_xc)
5441 TYPE(pw_r3d_rs_type), INTENT(IN) :: virial_pw
5442 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(IN) :: drho
5443 TYPE(pw_r3d_rs_type), INTENT(IN) :: v_drho
5444 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT) :: virial_xc
5445
5446 INTEGER :: idir, jdir
5447 REAL(kind=dp) :: tmp
5448
5449 DO idir = 1, 3
5450!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(drho,idir,v_drho,virial_pw)
5451 virial_pw%array(:, :, :) = drho(idir)%array(:, :, :)*v_drho%array(:, :, :)
5452!$OMP END PARALLEL WORKSHARE
5453 DO jdir = 1, idir
5454 tmp = -virial_pw%pw_grid%dvol*accurate_dot_product(virial_pw%array(:, :, :), &
5455 drho(jdir)%array(:, :, :))
5456 virial_xc(jdir, idir) = virial_xc(jdir, idir) + tmp
5457 virial_xc(idir, jdir) = virial_xc(jdir, idir)
5458 END DO
5459 END DO
5460
5461 END SUBROUTINE virial_drho_drho
5462
5463! **************************************************************************************************
5464!> \brief ...
5465!> \param rho_r ...
5466!> \param pw_pool ...
5467!> \param virial_xc ...
5468!> \param deriv_data ...
5469! **************************************************************************************************
5470 SUBROUTINE virial_laplace(rho_r, pw_pool, virial_xc, deriv_data)
5471 TYPE(pw_r3d_rs_type), TARGET :: rho_r
5472 TYPE(pw_pool_type), POINTER, INTENT(IN) :: pw_pool
5473 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT) :: virial_xc
5474 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: deriv_data
5475
5476 CHARACTER(len=*), PARAMETER :: routinen = 'virial_laplace'
5477
5478 INTEGER :: handle, idir, jdir
5479 TYPE(pw_r3d_rs_type), POINTER :: virial_pw
5480 TYPE(pw_c1d_gs_type), POINTER :: tmp_g, rho_g
5481 INTEGER, DIMENSION(3) :: my_deriv
5482
5483 CALL timeset(routinen, handle)
5484
5485 NULLIFY (virial_pw, tmp_g, rho_g)
5486 ALLOCATE (virial_pw, tmp_g, rho_g)
5487 CALL pw_pool%create_pw(virial_pw)
5488 CALL pw_pool%create_pw(tmp_g)
5489 CALL pw_pool%create_pw(rho_g)
5490 CALL pw_zero(virial_pw)
5491 CALL pw_transfer(rho_r, rho_g)
5492 DO idir = 1, 3
5493 DO jdir = idir, 3
5494 CALL pw_copy(rho_g, tmp_g)
5495
5496 my_deriv = 0
5497 my_deriv(idir) = 1
5498 my_deriv(jdir) = my_deriv(jdir) + 1
5499
5500 CALL pw_derive(tmp_g, my_deriv)
5501 CALL pw_transfer(tmp_g, virial_pw)
5502 virial_xc(idir, jdir) = virial_xc(idir, jdir) - 2.0_dp*virial_pw%pw_grid%dvol* &
5503 accurate_dot_product(virial_pw%array(:, :, :), &
5504 deriv_data(:, :, :))
5505 virial_xc(jdir, idir) = virial_xc(idir, jdir)
5506 END DO
5507 END DO
5508 CALL pw_pool%give_back_pw(virial_pw)
5509 CALL pw_pool%give_back_pw(tmp_g)
5510 CALL pw_pool%give_back_pw(rho_g)
5511 DEALLOCATE (virial_pw, tmp_g, rho_g)
5512
5513 CALL timestop(handle)
5514
5515 END SUBROUTINE virial_laplace
5516
5517! **************************************************************************************************
5518!> \brief Prepare objects for the calculation of the 2nd derivatives of the density functional.
5519!> The calculation must then be performed with xc_calc_2nd_deriv.
5520!> \param deriv_set object containing the XC derivatives (out)
5521!> \param rho_set object that will contain the density at which the
5522!> derivatives were calculated
5523!> \param rho_r the place where you evaluate the derivative
5524!> \param pw_pool the pool for the grids
5525!> \param weights integration weights
5526!> \param xc_section which functional should be used and how to calculate it
5527!> \param tau_r kinetic energy density in real space
5528! **************************************************************************************************
5529 SUBROUTINE xc_prep_2nd_deriv(deriv_set, &
5530 rho_set, rho_r, pw_pool, weights, xc_section, tau_r)
5531
5532 TYPE(xc_derivative_set_type) :: deriv_set
5533 TYPE(xc_rho_set_type) :: rho_set
5534 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
5535 TYPE(pw_pool_type), POINTER :: pw_pool
5536 TYPE(pw_r3d_rs_type), POINTER :: weights
5537 TYPE(section_vals_type), POINTER :: xc_section
5538 TYPE(pw_r3d_rs_type), DIMENSION(:), &
5539 OPTIONAL, POINTER :: tau_r
5540
5541 CHARACTER(len=*), PARAMETER :: routinen = 'xc_prep_2nd_deriv'
5542
5543 INTEGER :: handle, nspins
5544 LOGICAL :: lsd
5545 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
5546 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: tau
5547
5548 CALL timeset(routinen, handle)
5549
5550 cpassert(ASSOCIATED(xc_section))
5551 cpassert(ASSOCIATED(pw_pool))
5552
5553 IF (xc_section_uses_gauxc(xc_section)) THEN
5554 CALL cp_abort(__location__, gauxc_high_deriv_message)
5555 END IF
5556
5557 nspins = SIZE(rho_r)
5558 lsd = (nspins /= 1)
5559
5560 NULLIFY (rho_g, tau)
5561 IF (PRESENT(tau_r)) tau => tau_r
5562
5563 IF (section_get_lval(xc_section, "2ND_DERIV_ANALYTICAL")) THEN
5564 CALL xc_rho_set_and_dset_create(rho_set, deriv_set, 2, &
5565 rho_r, rho_g, tau, xc_section, pw_pool, weights, &
5566 calc_potential=.true.)
5567 ELSE
5568 CALL xc_rho_set_and_dset_create(rho_set, deriv_set, 1, &
5569 rho_r, rho_g, tau, xc_section, pw_pool, weights, &
5570 calc_potential=.true.)
5571 END IF
5572
5573 CALL timestop(handle)
5574
5575 END SUBROUTINE xc_prep_2nd_deriv
5576
5577! **************************************************************************************************
5578!> \brief Prepare deriv_set for the calculation of the 3rd derivatives of the density functional.
5579!> The calculation must then be performed with xc_calc_3rd_deriv.
5580!> \param deriv_set object containing the XC derivatives (out)
5581!> \param rho_set object that will contain the density at which the
5582!> derivatives were calculated
5583!> \param rho_r the place where you evaluate the derivative
5584!> \param pw_pool the pool for the grids
5585!> \param weights integration weights
5586!> \param xc_section which functional should be used and how to calculate it
5587!> \param tau_r kinetic energy density in real space
5588!> \param do_sf Flag to activate the noncollinear kernel for spin flip calculations
5589!> \par History
5590!> * 07.2024 Created [LHS]
5591! **************************************************************************************************
5592 SUBROUTINE xc_prep_3rd_deriv(deriv_set, rho_set, rho_r, pw_pool, weights, &
5593 xc_section, tau_r, do_sf)
5594
5595 TYPE(xc_derivative_set_type) :: deriv_set
5596 TYPE(xc_rho_set_type) :: rho_set
5597 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
5598 TYPE(pw_pool_type), POINTER :: pw_pool
5599 TYPE(pw_r3d_rs_type), POINTER :: weights
5600 TYPE(section_vals_type), POINTER :: xc_section
5601 TYPE(pw_r3d_rs_type), DIMENSION(:), &
5602 OPTIONAL, POINTER :: tau_r
5603 LOGICAL, OPTIONAL :: do_sf
5604
5605 CHARACTER(len=*), PARAMETER :: routinen = 'xc_prep_3rd_deriv'
5606
5607 INTEGER :: handle, nspins
5608 LOGICAL :: lsd, my_do_sf
5609 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
5610 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: tau
5611
5612 CALL timeset(routinen, handle)
5613
5614 cpassert(ASSOCIATED(xc_section))
5615 cpassert(ASSOCIATED(pw_pool))
5616
5617 IF (xc_section_uses_gauxc(xc_section)) THEN
5618 CALL cp_abort(__location__, gauxc_high_deriv_message)
5619 END IF
5620
5621 nspins = SIZE(rho_r)
5622 lsd = (nspins /= 1)
5623
5624 NULLIFY (rho_g, tau)
5625 IF (PRESENT(tau_r)) tau => tau_r
5626
5627 my_do_sf = .false.
5628 IF (PRESENT(do_sf)) my_do_sf = do_sf
5629
5630 IF (do_sf) THEN
5631 CALL xc_rho_set_and_dset_create(rho_set, deriv_set, 2, &
5632 rho_r, rho_g, tau, xc_section, pw_pool, weights, &
5633 calc_potential=.true.)
5634 ELSE
5635 CALL xc_rho_set_and_dset_create(rho_set, deriv_set, 3, &
5636 rho_r, rho_g, tau, xc_section, pw_pool, weights, &
5637 calc_potential=.true.)
5638 END IF
5639
5640 CALL timestop(handle)
5641
5642 END SUBROUTINE xc_prep_3rd_deriv
5643
5644! **************************************************************************************************
5645!> \brief divides derivatives from deriv_set by norm_drho
5646!> \param deriv_set ...
5647!> \param rho_set ...
5648!> \param lsd ...
5649! **************************************************************************************************
5650 SUBROUTINE divide_by_norm_drho(deriv_set, rho_set, lsd)
5651
5652 TYPE(xc_derivative_set_type), INTENT(INOUT) :: deriv_set
5653 TYPE(xc_rho_set_type), INTENT(IN) :: rho_set
5654 LOGICAL, INTENT(IN) :: lsd
5655
5656 INTEGER, DIMENSION(:), POINTER :: split_desc
5657 INTEGER :: idesc
5658 INTEGER, DIMENSION(2, 3) :: bo
5659 REAL(kind=dp) :: drho_cutoff
5660 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: norm_drho, norm_drhoa, norm_drhob
5661 TYPE(cp_3d_r_cp_type), DIMENSION(3) :: drho, drhoa, drhob
5662 TYPE(cp_sll_xc_deriv_type), POINTER :: pos
5663 TYPE(xc_derivative_type), POINTER :: deriv_att
5664
5665! check for unknown derivatives and divide by norm_drho where necessary
5666
5667 bo = rho_set%local_bounds
5668 CALL xc_rho_set_get(rho_set, drho_cutoff=drho_cutoff, norm_drho=norm_drho, &
5669 norm_drhoa=norm_drhoa, norm_drhob=norm_drhob, &
5670 drho=drho, drhoa=drhoa, drhob=drhob, can_return_null=.true.)
5671
5672 pos => deriv_set%derivs
5673 DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
5674 CALL xc_derivative_get(deriv_att, split_desc=split_desc)
5675 DO idesc = 1, SIZE(split_desc)
5676 SELECT CASE (split_desc(idesc))
5677 CASE (deriv_norm_drho)
5678 IF (ASSOCIATED(norm_drho)) THEN
5679!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(deriv_att,norm_drho,drho_cutoff)
5680 deriv_att%deriv_data(:, :, :) = deriv_att%deriv_data(:, :, :)/ &
5681 max(norm_drho(:, :, :), drho_cutoff)
5682!$OMP END PARALLEL WORKSHARE
5683 ELSE IF (ASSOCIATED(drho(1)%array)) THEN
5684!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(deriv_att,drho,drho_cutoff)
5685 deriv_att%deriv_data(:, :, :) = deriv_att%deriv_data(:, :, :)/ &
5686 max(sqrt(drho(1)%array(:, :, :)**2 + &
5687 drho(2)%array(:, :, :)**2 + &
5688 drho(3)%array(:, :, :)**2), drho_cutoff)
5689!$OMP END PARALLEL WORKSHARE
5690 ELSE IF (ASSOCIATED(drhoa(1)%array) .AND. ASSOCIATED(drhob(1)%array)) THEN
5691!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(deriv_att,drhoa,drhob,drho_cutoff)
5692 deriv_att%deriv_data(:, :, :) = deriv_att%deriv_data(:, :, :)/ &
5693 max(sqrt((drhoa(1)%array(:, :, :) + drhob(1)%array(:, :, :))**2 + &
5694 (drhoa(2)%array(:, :, :) + drhob(2)%array(:, :, :))**2 + &
5695 (drhoa(3)%array(:, :, :) + drhob(3)%array(:, :, :))**2), drho_cutoff)
5696!$OMP END PARALLEL WORKSHARE
5697 ELSE
5698 cpabort("Normalization of derivative requires any of norm_drho, drho or drhoa+drhob!")
5699 END IF
5700 CASE (deriv_norm_drhoa)
5701 IF (ASSOCIATED(norm_drhoa)) THEN
5702!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(deriv_att,norm_drhoa,drho_cutoff)
5703 deriv_att%deriv_data(:, :, :) = deriv_att%deriv_data(:, :, :)/ &
5704 max(norm_drhoa(:, :, :), drho_cutoff)
5705!$OMP END PARALLEL WORKSHARE
5706 ELSE IF (ASSOCIATED(drhoa(1)%array)) THEN
5707!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(deriv_att,drhoa,drho_cutoff)
5708 deriv_att%deriv_data(:, :, :) = deriv_att%deriv_data(:, :, :)/ &
5709 max(sqrt(drhoa(1)%array(:, :, :)**2 + &
5710 drhoa(2)%array(:, :, :)**2 + &
5711 drhoa(3)%array(:, :, :)**2), drho_cutoff)
5712!$OMP END PARALLEL WORKSHARE
5713 ELSE
5714 cpabort("Normalization of derivative requires any of norm_drhoa or drhoa!")
5715 END IF
5716 CASE (deriv_norm_drhob)
5717 IF (ASSOCIATED(norm_drhob)) THEN
5718!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(deriv_att,norm_drhob,drho_cutoff)
5719 deriv_att%deriv_data(:, :, :) = deriv_att%deriv_data(:, :, :)/ &
5720 max(norm_drhob(:, :, :), drho_cutoff)
5721!$OMP END PARALLEL WORKSHARE
5722 ELSE IF (ASSOCIATED(drhob(1)%array)) THEN
5723!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(deriv_att,drhob,drho_cutoff)
5724 deriv_att%deriv_data(:, :, :) = deriv_att%deriv_data(:, :, :)/ &
5725 max(sqrt(drhob(1)%array(:, :, :)**2 + &
5726 drhob(2)%array(:, :, :)**2 + &
5727 drhob(3)%array(:, :, :)**2), drho_cutoff)
5728!$OMP END PARALLEL WORKSHARE
5729 ELSE
5730 cpabort("Normalization of derivative requires any of norm_drhob or drhob!")
5731 END IF
5733 IF (lsd) THEN
5734 cpabort(trim(id_to_desc(split_desc(idesc)))//" not handled in lsd!'")
5735 END IF
5737 CASE default
5738 cpabort("Unknown derivative id")
5739 END SELECT
5740 END DO
5741 END DO
5742
5743 END SUBROUTINE divide_by_norm_drho
5744
5745! **************************************************************************************************
5746!> \brief allocates and calculates drho from given spin densities drhoa, drhob
5747!> \param drho ...
5748!> \param drhoa ...
5749!> \param drhob ...
5750! **************************************************************************************************
5751 SUBROUTINE calc_drho_from_ab(drho, drhoa, drhob)
5752 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(OUT) :: drho
5753 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(IN) :: drhoa, drhob
5754
5755 CHARACTER(len=*), PARAMETER :: routinen = 'calc_drho_from_ab'
5756
5757 INTEGER :: handle, idir
5758
5759 CALL timeset(routinen, handle)
5760
5761 DO idir = 1, 3
5762 NULLIFY (drho(idir)%array)
5763 ALLOCATE (drho(idir)%array(lbound(drhoa(1)%array, 1):ubound(drhoa(1)%array, 1), &
5764 lbound(drhoa(1)%array, 2):ubound(drhoa(1)%array, 2), &
5765 lbound(drhoa(1)%array, 3):ubound(drhoa(1)%array, 3)))
5766!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(drho,drhoa,drhob,idir)
5767 drho(idir)%array(:, :, :) = drhoa(idir)%array(:, :, :) + drhob(idir)%array(:, :, :)
5768!$OMP END PARALLEL WORKSHARE
5769 END DO
5770
5771 CALL timestop(handle)
5772
5773 END SUBROUTINE calc_drho_from_ab
5774
5775! **************************************************************************************************
5776!> \brief allocates and calculates drho from given spin densities drhoa, drhob
5777!> \param drho ...
5778!> \param drhoa ...
5779!> \param drhob ...
5780! **************************************************************************************************
5781 SUBROUTINE calc_drho_from_a(drho, drhoa)
5782 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(OUT) :: drho
5783 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(IN) :: drhoa
5784
5785 CHARACTER(len=*), PARAMETER :: routinen = 'calc_drho_from_a'
5786
5787 INTEGER :: handle, idir
5788
5789 CALL timeset(routinen, handle)
5790
5791 DO idir = 1, 3
5792 NULLIFY (drho(idir)%array)
5793 ALLOCATE (drho(idir)%array(lbound(drhoa(1)%array, 1):ubound(drhoa(1)%array, 1), &
5794 lbound(drhoa(1)%array, 2):ubound(drhoa(1)%array, 2), &
5795 lbound(drhoa(1)%array, 3):ubound(drhoa(1)%array, 3)))
5796!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(drho,drhoa,idir)
5797 drho(idir)%array(:, :, :) = drhoa(idir)%array(:, :, :)
5798!$OMP END PARALLEL WORKSHARE
5799 END DO
5800
5801 CALL timestop(handle)
5802
5803 END SUBROUTINE calc_drho_from_a
5804
5805! **************************************************************************************************
5806!> \brief allocates and calculates dot products of two density gradients
5807!> \param dr1dr ...
5808!> \param drho ...
5809!> \param drho1 ...
5810! **************************************************************************************************
5811 SUBROUTINE prepare_dr1dr(dr1dr, drho, drho1)
5812 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :), &
5813 INTENT(OUT) :: dr1dr
5814 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(IN) :: drho, drho1
5815
5816 CHARACTER(len=*), PARAMETER :: routinen = 'prepare_dr1dr'
5817
5818 INTEGER :: handle, idir
5819
5820 CALL timeset(routinen, handle)
5821
5822 ALLOCATE (dr1dr(lbound(drho(1)%array, 1):ubound(drho(1)%array, 1), &
5823 lbound(drho(1)%array, 2):ubound(drho(1)%array, 2), &
5824 lbound(drho(1)%array, 3):ubound(drho(1)%array, 3)))
5825
5826!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dr1dr,drho,drho1)
5827 dr1dr(:, :, :) = drho(1)%array(:, :, :)*drho1(1)%array(:, :, :)
5828!$OMP END PARALLEL WORKSHARE
5829 DO idir = 2, 3
5830!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dr1dr,drho,drho1,idir)
5831 dr1dr(:, :, :) = dr1dr(:, :, :) + drho(idir)%array(:, :, :)*drho1(idir)%array(:, :, :)
5832!$OMP END PARALLEL WORKSHARE
5833 END DO
5834
5835 CALL timestop(handle)
5836
5837 END SUBROUTINE prepare_dr1dr
5838
5839! **************************************************************************************************
5840!> \brief allocates and calculates dot product of two densities for triplets
5841!> \param dr1dr ...
5842!> \param drhoa ...
5843!> \param drhob ...
5844!> \param drho1a ...
5845!> \param drho1b ...
5846!> \param fac ...
5847! **************************************************************************************************
5848 SUBROUTINE prepare_dr1dr_ab(dr1dr, drhoa, drhob, drho1a, drho1b, fac)
5849 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :), &
5850 INTENT(OUT) :: dr1dr
5851 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(IN) :: drhoa, drhob, drho1a, drho1b
5852 REAL(kind=dp), INTENT(IN) :: fac
5853
5854 CHARACTER(len=*), PARAMETER :: routinen = 'prepare_dr1dr_ab'
5855
5856 INTEGER :: handle, idir
5857
5858 CALL timeset(routinen, handle)
5859
5860 ALLOCATE (dr1dr(lbound(drhoa(1)%array, 1):ubound(drhoa(1)%array, 1), &
5861 lbound(drhoa(1)%array, 2):ubound(drhoa(1)%array, 2), &
5862 lbound(drhoa(1)%array, 3):ubound(drhoa(1)%array, 3)))
5863
5864!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(fac,dr1dr,drho1a,drho1b,drhoa,drhob)
5865 dr1dr(:, :, :) = drhoa(1)%array(:, :, :)*(drho1a(1)%array(:, :, :) + &
5866 fac*drho1b(1)%array(:, :, :)) + &
5867 drhob(1)%array(:, :, :)*(fac*drho1a(1)%array(:, :, :) + &
5868 drho1b(1)%array(:, :, :))
5869!$OMP END PARALLEL WORKSHARE
5870 DO idir = 2, 3
5871!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(fac,dr1dr,drho1a,drho1b,drhoa,drhob,idir)
5872 dr1dr(:, :, :) = dr1dr(:, :, :) + &
5873 drhoa(idir)%array(:, :, :)*(drho1a(idir)%array(:, :, :) + &
5874 fac*drho1b(idir)%array(:, :, :)) + &
5875 drhob(idir)%array(:, :, :)*(fac*drho1a(idir)%array(:, :, :) + &
5876 drho1b(idir)%array(:, :, :))
5877!$OMP END PARALLEL WORKSHARE
5878 END DO
5879
5880 CALL timestop(handle)
5881
5882 END SUBROUTINE prepare_dr1dr_ab
5883
5884! **************************************************************************************************
5885!> \brief checks for gradients
5886!> \param deriv_set ...
5887!> \param lsd ...
5888!> \param gradient_f ...
5889!> \param tau_f ...
5890!> \param laplace_f ...
5891! **************************************************************************************************
5892 SUBROUTINE check_for_derivatives(deriv_set, lsd, rho_f, gradient_f, tau_f, laplace_f)
5893 TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set
5894 LOGICAL, INTENT(IN) :: lsd
5895 LOGICAL, INTENT(OUT) :: rho_f, gradient_f, tau_f, laplace_f
5896
5897 CHARACTER(len=*), PARAMETER :: routinen = 'check_for_derivatives'
5898
5899 INTEGER :: handle, iorder, order
5900 INTEGER, DIMENSION(:), POINTER :: split_desc
5901 TYPE(cp_sll_xc_deriv_type), POINTER :: pos
5902 TYPE(xc_derivative_type), POINTER :: deriv_att
5903
5904 CALL timeset(routinen, handle)
5905
5906 rho_f = .false.
5907 gradient_f = .false.
5908 tau_f = .false.
5909 laplace_f = .false.
5910 ! check for unknown derivatives
5911 pos => deriv_set%derivs
5912 DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
5913 CALL xc_derivative_get(deriv_att, order=order, &
5914 split_desc=split_desc)
5915 IF (lsd) THEN
5916 DO iorder = 1, size(split_desc)
5917 SELECT CASE (split_desc(iorder))
5918 CASE (deriv_rhoa, deriv_rhob)
5919 rho_f = .true.
5921 gradient_f = .true.
5922 CASE (deriv_tau_a, deriv_tau_b)
5923 tau_f = .true.
5925 laplace_f = .true.
5927 cpabort("Derivative not handled in lsd!")
5928 CASE default
5929 cpabort("Unknown derivative id")
5930 END SELECT
5931 END DO
5932 ELSE
5933 DO iorder = 1, size(split_desc)
5934 SELECT CASE (split_desc(iorder))
5935 CASE (deriv_rho)
5936 rho_f = .true.
5937 CASE (deriv_tau)
5938 tau_f = .true.
5939 CASE (deriv_norm_drho)
5940 gradient_f = .true.
5941 CASE (deriv_laplace_rho)
5942 laplace_f = .true.
5943 CASE default
5944 cpabort("Unknown derivative id")
5945 END SELECT
5946 END DO
5947 END IF
5948 END DO
5949
5950 CALL timestop(handle)
5951
5952 END SUBROUTINE check_for_derivatives
5953
5954END MODULE xc
5955
static GRID_HOST_DEVICE double fac(const int i)
Factorial function, e.g. fac(5) = 5! = 120.
Definition grid_common.h:56
various utilities that regard array of different kinds: output, allocation,... maybe it is not a good...
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...
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
objects that represent the structure of input sections and the data contained in an input section
real(kind=dp) function, public section_get_rval(section_vals, keyword_name)
...
integer function, public section_get_ival(section_vals, keyword_name)
...
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
logical function, public section_get_lval(section_vals, keyword_name)
...
sums arrays of real/complex numbers with much reduced round-off as compared to a naive implementation...
Definition kahan_sum.F:29
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_path_length
Definition kinds.F:58
integer, parameter, public pw_mode_distributed
subroutine, public pw_derive(pw, n)
Calculate the derivative of a plane wave vector.
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Module with functions to handle derivative descriptors. derivative description are strings have the f...
integer, parameter, public deriv_norm_drho
integer, parameter, public deriv_laplace_rhob
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_laplace_rhoa
integer, parameter, public deriv_rho
integer, parameter, public deriv_norm_drhob
character(len=max_label_length) function, public id_to_desc(id)
...
integer, parameter, public deriv_laplace_rho
represent a group ofunctional derivatives
subroutine, public xc_dset_zero_all(deriv_set)
...
subroutine, public xc_dset_recover_pw(deriv_set, description, pw, pw_grid, pw_pool)
Recovers a derivative on a pw_r3d_rs_type, the caller is responsible to release the grid later If the...
type(xc_derivative_type) function, pointer, public xc_dset_get_derivative(derivative_set, description, allocate_deriv)
returns the requested xc_derivative
subroutine, public xc_dset_release(derivative_set)
releases a derivative set
subroutine, public xc_dset_create(derivative_set, pw_pool, local_bounds)
creates a derivative set object
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
type(xc_rho_cflags_type) function, public xc_functionals_get_needs(functionals, lsd, calc_potential)
...
subroutine, public xc_functionals_eval(functionals, lsd, rho_set, deriv_set, deriv_order)
...
logical function, public xc_section_uses_gauxc(xc_section)
...
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_recover_pw(rho_set, pw_grid, pw_pool, owns_data, 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, tau, tau_a, tau_b)
Shifts association of the requested array to a pw grid Requires that the corresponding component of r...
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...
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
contains utility functions for the xc package
Definition xc_util.F:14
subroutine, public xc_pw_divergence(xc_deriv_method_id, pw_to_deriv, tmp_g, vxc_g, vxc_r)
Calculates the divergence of pw_to_deriv.
Definition xc_util.F:253
subroutine, public xc_pw_smooth(pw_in, pw_out, xc_smooth_id)
...
Definition xc_util.F:73
elemental logical function, public xc_requires_tmp_g(xc_deriv_id)
...
Definition xc_util.F:58
Exchange and Correlation functional calculations.
Definition xc.F:17
subroutine, public xc_prep_2nd_deriv(deriv_set, rho_set, rho_r, pw_pool, weights, xc_section, tau_r)
Prepare objects for the calculation of the 2nd derivatives of the density functional....
Definition xc.F:5539
subroutine, public divide_by_norm_drho(deriv_set, rho_set, lsd)
divides derivatives from deriv_set by norm_drho
Definition xc.F:5659
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:2056
subroutine, public xc_calc_2nd_deriv_numerical(v_xc, v_tau, rho_set, rho1_r, rho1_g, tau1_r, pw_pool, weights, xc_section, do_triplet, calc_virial, virial_xc, deriv_set)
calculates 2nd derivative numerically
Definition xc.F:1062
real(kind=dp) function, public xc_exc_calc(rho_r, rho_g, tau, xc_section, weights, pw_pool)
calculates just the exchange and correlation energy (no vxc)
Definition xc.F:791
logical function, public xc_uses_norm_drho(xc_fun_section, lsd)
...
Definition xc.F:115
logical function, public xc_uses_kinetic_energy_density(xc_fun_section, lsd)
...
Definition xc.F:95
subroutine, public xc_vxc_pw_create(vxc_rho, vxc_tau, exc, rho_r, rho_g, tau, xc_section, weights, pw_pool, compute_virial, virial_xc, exc_r)
Exchange and Correlation functional calculations.
Definition xc.F:474
subroutine, public xc_calc_2nd_deriv(v_xc, v_xc_tau, deriv_set, rho_set, rho1_r, rho1_g, tau1_r, pw_pool, weights, 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:928
subroutine, public xc_exc_pw_create(rho_r, rho_g, tau, xc_section, weights, pw_pool, exc)
calculates just the exchange and correlation energy density
Definition xc.F:857
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:4735
subroutine, public xc_prep_3rd_deriv(deriv_set, rho_set, rho_r, pw_pool, weights, xc_section, tau_r, do_sf)
Prepare deriv_set for the calculation of the 3rd derivatives of the density functional....
Definition xc.F:5602
subroutine, public calc_xc_density(pot, rho, rho_cutoff)
Definition xc.F:402
subroutine, public smooth_cutoff(pot, rho, rhoa, rhob, rho_cutoff, rho_smooth_cutoff_range, e_0, e_0_scale_factor)
smooths the cutoff on rho with a function smoothderiv_rho that is 0 for rho<rho_cutoff and 1 for rho>...
Definition xc.F:242
represent a pointer to a contiguous 3d array
represent a single linked list that stores pointers to the elements
type of a logger, at the moment it contains just a print level starting at which level it should be l...
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