(git:561f475)
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/OneDFT/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 ELSEIF (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 ELSEIF (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 ELSEIF (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 ELSEIF (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)) &
993 cpabort("Tau-dependent functionals requires allocated kinetic energy density grid")
994 ALLOCATE (v_xc_tau(nspins))
995 DO ispin = 1, nspins
996 CALL pw_pool%create_pw(v_xc_tau(ispin))
997 CALL pw_zero(v_xc_tau(ispin))
998 END DO
999 END IF
1000
1001 IF (section_get_lval(xc_section, "2ND_DERIV_ANALYTICAL")) THEN
1002 !------!
1003 ! rho1 !
1004 !------!
1005 bo = rho1_r(1)%pw_grid%bounds_local
1006 ! create the place where to store the argument for the functionals
1007 CALL xc_rho_set_create(rho1_set, bo, &
1008 rho_cutoff=section_get_rval(xc_section, "DENSITY_CUTOFF"), &
1009 drho_cutoff=section_get_rval(xc_section, "GRADIENT_CUTOFF"), &
1010 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
1011
1012 ! calculate the arguments needed by the functionals
1013 CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
1014 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
1015 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
1016 pw_pool, spinflip=my_do_sf)
1017
1018 fac = 0._dp
1019 IF (nspins == 1 .AND. my_do_excitations) THEN
1020 IF (my_do_triplet) fac = -1.0_dp
1021 END IF
1022
1023 CALL xc_calc_2nd_deriv_analytical(v_xc, v_xc_tau, deriv_set, rho_set, &
1024 rho1_set, pw_pool, xc_section, &
1025 gapw, vxg=vxg, spinflip=my_do_sf, tddfpt_fac=fac, &
1026 compute_virial=compute_virial, virial_xc=virial_xc)
1027
1028 CALL xc_rho_set_release(rho1_set)
1029
1030 ELSE
1031 IF (gapw) cpabort("Numerical 2nd derivatives not implemented with GAPW")
1032
1033 CALL xc_calc_2nd_deriv_numerical(v_xc, v_xc_tau, rho_set, rho1_r, rho1_g, tau1_r, &
1034 pw_pool, weights, xc_section, &
1035 my_do_excitations .AND. my_do_triplet, &
1036 compute_virial, virial_xc, deriv_set)
1037 END IF
1038
1039 CALL timestop(handle)
1040
1041 END SUBROUTINE xc_calc_2nd_deriv
1042
1043! **************************************************************************************************
1044!> \brief calculates 2nd derivative numerically
1045!> \param v_xc potential to be calculated (has to be allocated already)
1046!> \param v_tau tau-part of the potential to be calculated (has to be allocated already)
1047!> \param rho_set KS density from xc_prep_2nd_deriv
1048!> \param rho1_r first-order density in r-space
1049!> \param rho1_g first-order density in g-space
1050!> \param tau1_r first-order kinetic-energy density in r-space
1051!> \param pw_pool pw pool for new grids
1052!> \param xc_section XC section to calculate the derivatives from
1053!> \param do_triplet ...
1054!> \param calc_virial whether to calculate virial terms
1055!> \param virial_xc collects stress tensor components (no metaGGAs!)
1056!> \param deriv_set deriv set from xc_prep_2nd_deriv (only for virials)
1057! **************************************************************************************************
1058 SUBROUTINE xc_calc_2nd_deriv_numerical(v_xc, v_tau, rho_set, rho1_r, rho1_g, tau1_r, &
1059 pw_pool, weights, xc_section, &
1060 do_triplet, calc_virial, virial_xc, deriv_set)
1061
1062 TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(IN), POINTER :: v_xc, v_tau
1063 TYPE(xc_rho_set_type), INTENT(IN) :: rho_set
1064 TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(IN), POINTER :: rho1_r, tau1_r
1065 TYPE(pw_c1d_gs_type), DIMENSION(:), INTENT(IN), POINTER :: rho1_g
1066 TYPE(pw_pool_type), INTENT(IN), POINTER :: pw_pool
1067 TYPE(pw_r3d_rs_type), INTENT(IN), POINTER :: weights
1068 TYPE(section_vals_type), INTENT(IN), POINTER :: xc_section
1069 LOGICAL, INTENT(IN) :: do_triplet
1070 LOGICAL, INTENT(IN), OPTIONAL :: calc_virial
1071 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT), &
1072 OPTIONAL :: virial_xc
1073 TYPE(xc_derivative_set_type), OPTIONAL :: deriv_set
1074
1075 CHARACTER(len=*), PARAMETER :: routinen = 'xc_calc_2nd_deriv_numerical'
1076 REAL(kind=dp), DIMENSION(-4:4, 4), PARAMETER :: &
1077 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, &
1078 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, &
1079 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, &
1080 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])
1081
1082 INTEGER :: handle, idir, ispin, nspins, istep, nsteps
1083 INTEGER, DIMENSION(2, 3) :: bo
1084 LOGICAL :: gradient_f, lsd, my_calc_virial, tau_f, laplace_f, rho_f
1085 REAL(kind=dp) :: exc, gradient_cut, h, rweight, step, rho_cutoff
1086 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: dr1dr, dra1dra, drb1drb
1087 REAL(kind=dp), DIMENSION(3, 3) :: virial_dummy
1088 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: norm_drho, norm_drho2, norm_drho2a, &
1089 norm_drho2b, norm_drhoa, norm_drhob, &
1090 rho, rho1, rho1a, rho1b, rhoa, rhob, &
1091 tau_a, tau_b, tau, tau1, tau1a, tau1b, laplace, laplace1, &
1092 laplacea, laplaceb, laplace1a, laplace1b, &
1093 laplace2, laplace2a, laplace2b, deriv_data
1094 TYPE(cp_3d_r_cp_type), DIMENSION(3) :: drho, drho1, drho1a, drho1b, drhoa, drhob
1095 TYPE(pw_r3d_rs_type) :: v_drho, v_drhoa, v_drhob
1096 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: vxc_rho, vxc_tau
1097 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
1098 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r, tau_r
1099 TYPE(pw_r3d_rs_type) :: virial_pw, v_laplace, v_laplacea, v_laplaceb
1100 TYPE(section_vals_type), POINTER :: xc_fun_section
1101 TYPE(xc_derivative_set_type) :: deriv_set1
1102 TYPE(xc_rho_cflags_type) :: needs
1103 TYPE(xc_rho_set_type) :: rho1_set, rho2_set
1104
1105 CALL timeset(routinen, handle)
1106
1107 my_calc_virial = .false.
1108 IF (PRESENT(calc_virial) .AND. PRESENT(virial_xc)) my_calc_virial = calc_virial
1109
1110 nspins = SIZE(v_xc)
1111
1112 NULLIFY (tau, tau_r, tau_a, tau_b)
1113
1114 h = section_get_rval(xc_section, "STEP_SIZE")
1115 nsteps = section_get_ival(xc_section, "NSTEPS")
1116 IF (nsteps < lbound(rweights, 2) .OR. nspins > ubound(rweights, 2)) THEN
1117 cpabort("The number of steps must be a value from 1 to 4.")
1118 END IF
1119
1120 IF (nspins == 2) THEN
1121 NULLIFY (vxc_rho, rho_g, vxc_tau)
1122 ALLOCATE (rho_r(2))
1123 DO ispin = 1, nspins
1124 CALL pw_pool%create_pw(rho_r(ispin))
1125 END DO
1126 IF (ASSOCIATED(tau1_r) .AND. ASSOCIATED(v_tau)) THEN
1127 ALLOCATE (tau_r(2))
1128 DO ispin = 1, nspins
1129 CALL pw_pool%create_pw(tau_r(ispin))
1130 END DO
1131 END IF
1132 CALL xc_rho_set_get(rho_set, can_return_null=.true., rhoa=rhoa, rhob=rhob, tau_a=tau_a, tau_b=tau_b)
1133 DO istep = -nsteps, nsteps
1134 IF (istep == 0) cycle
1135 rweight = rweights(istep, nsteps)/h
1136 step = real(istep, dp)*h
1137 CALL calc_resp_potential_numer_ab(rho_r, rho_g, rho1_r, rhoa, rhob, vxc_rho, &
1138 tau_r, tau1_r, tau_a, tau_b, vxc_tau, xc_section, &
1139 weights, pw_pool, step)
1140 DO ispin = 1, nspins
1141 CALL pw_axpy(vxc_rho(ispin), v_xc(ispin), rweight)
1142 IF (ASSOCIATED(vxc_tau) .AND. ASSOCIATED(v_tau)) THEN
1143 CALL pw_axpy(vxc_tau(ispin), v_tau(ispin), rweight)
1144 END IF
1145 END DO
1146 DO ispin = 1, nspins
1147 CALL vxc_rho(ispin)%release()
1148 END DO
1149 DEALLOCATE (vxc_rho)
1150 IF (ASSOCIATED(vxc_tau)) THEN
1151 DO ispin = 1, nspins
1152 CALL vxc_tau(ispin)%release()
1153 END DO
1154 DEALLOCATE (vxc_tau)
1155 END IF
1156 END DO
1157 ELSE IF (nspins == 1 .AND. do_triplet) THEN
1158 NULLIFY (vxc_rho, vxc_tau, rho_g)
1159 ALLOCATE (rho_r(2))
1160 DO ispin = 1, 2
1161 CALL pw_pool%create_pw(rho_r(ispin))
1162 END DO
1163 IF (ASSOCIATED(tau1_r) .AND. ASSOCIATED(v_tau)) THEN
1164 ALLOCATE (tau_r(2))
1165 DO ispin = 1, nspins
1166 CALL pw_pool%create_pw(tau_r(ispin))
1167 END DO
1168 END IF
1169 CALL xc_rho_set_get(rho_set, can_return_null=.true., rhoa=rhoa, rhob=rhob, tau_a=tau_a, tau_b=tau_b)
1170 DO istep = -nsteps, nsteps
1171 IF (istep == 0) cycle
1172 rweight = rweights(istep, nsteps)/h
1173 step = real(istep, dp)*h
1174 ! K(alpha,alpha)
1175!$OMP PARALLEL DEFAULT(NONE) SHARED(rho_r,rhoa,rhob,step,rho1_r,tau_r,tau_a,tau_b,tau1_r)
1176!$OMP WORKSHARE
1177 rho_r(1)%array(:, :, :) = rhoa(:, :, :) + step*rho1_r(1)%array(:, :, :)
1178!$OMP END WORKSHARE NOWAIT
1179!$OMP WORKSHARE
1180 rho_r(2)%array(:, :, :) = rhob(:, :, :)
1181!$OMP END WORKSHARE NOWAIT
1182 IF (ASSOCIATED(tau1_r)) THEN
1183!$OMP WORKSHARE
1184 tau_r(1)%array(:, :, :) = tau_a(:, :, :) + step*tau1_r(1)%array(:, :, :)
1185!$OMP END WORKSHARE NOWAIT
1186!$OMP WORKSHARE
1187 tau_r(2)%array(:, :, :) = tau_b(:, :, :)
1188!$OMP END WORKSHARE NOWAIT
1189 END IF
1190!$OMP END PARALLEL
1191 CALL xc_vxc_pw_create(vxc_rho, vxc_tau, exc, rho_r, rho_g, tau_r, xc_section, &
1192 weights, pw_pool, .false., virial_dummy)
1193 CALL pw_axpy(vxc_rho(1), v_xc(1), rweight)
1194 IF (ASSOCIATED(vxc_tau) .AND. ASSOCIATED(v_tau)) THEN
1195 CALL pw_axpy(vxc_tau(1), v_tau(1), rweight)
1196 END IF
1197 DO ispin = 1, 2
1198 CALL vxc_rho(ispin)%release()
1199 END DO
1200 DEALLOCATE (vxc_rho)
1201 IF (ASSOCIATED(vxc_tau)) THEN
1202 DO ispin = 1, 2
1203 CALL vxc_tau(ispin)%release()
1204 END DO
1205 DEALLOCATE (vxc_tau)
1206 END IF
1207!$OMP PARALLEL DEFAULT(NONE) SHARED(rho_r,rhoa,rhob,step,rho1_r,tau_r,tau_a,tau_b,tau1_r)
1208!$OMP WORKSHARE
1209 ! K(alpha,beta)
1210 rho_r(1)%array(:, :, :) = rhoa(:, :, :)
1211!$OMP END WORKSHARE NOWAIT
1212!$OMP WORKSHARE
1213 rho_r(2)%array(:, :, :) = rhob(:, :, :) + step*rho1_r(1)%array(:, :, :)
1214!$OMP END WORKSHARE NOWAIT
1215 IF (ASSOCIATED(tau1_r)) THEN
1216!$OMP WORKSHARE
1217 tau_r(1)%array(:, :, :) = tau_a(:, :, :)
1218!$OMP END WORKSHARE NOWAIT
1219!$OMP WORKSHARE
1220 tau_r(2)%array(:, :, :) = tau_b(:, :, :) + step*tau1_r(1)%array(:, :, :)
1221!$OMP END WORKSHARE NOWAIT
1222 END IF
1223!$OMP END PARALLEL
1224 CALL xc_vxc_pw_create(vxc_rho, vxc_tau, exc, rho_r, rho_g, tau_r, xc_section, &
1225 weights, pw_pool, .false., virial_dummy)
1226 CALL pw_axpy(vxc_rho(1), v_xc(1), rweight)
1227 IF (ASSOCIATED(vxc_tau) .AND. ASSOCIATED(v_tau)) THEN
1228 CALL pw_axpy(vxc_tau(1), v_tau(1), rweight)
1229 END IF
1230 DO ispin = 1, 2
1231 CALL vxc_rho(ispin)%release()
1232 END DO
1233 DEALLOCATE (vxc_rho)
1234 IF (ASSOCIATED(vxc_tau)) THEN
1235 DO ispin = 1, 2
1236 CALL vxc_tau(ispin)%release()
1237 END DO
1238 DEALLOCATE (vxc_tau)
1239 END IF
1240 END DO
1241 ELSE
1242 NULLIFY (vxc_rho, rho_r, rho_g, vxc_tau, tau_r, tau)
1243 ALLOCATE (rho_r(1))
1244 CALL pw_pool%create_pw(rho_r(1))
1245 IF (ASSOCIATED(tau1_r) .AND. ASSOCIATED(v_tau)) THEN
1246 ALLOCATE (tau_r(1))
1247 CALL pw_pool%create_pw(tau_r(1))
1248 END IF
1249 CALL xc_rho_set_get(rho_set, can_return_null=.true., rho=rho, tau=tau)
1250 DO istep = -nsteps, nsteps
1251 IF (istep == 0) cycle
1252 rweight = rweights(istep, nsteps)/h
1253 step = real(istep, dp)*h
1254!$OMP PARALLEL DEFAULT(NONE) SHARED(rho_r,rho,step,rho1_r,tau1_r,tau,tau_r)
1255!$OMP WORKSHARE
1256 rho_r(1)%array(:, :, :) = rho(:, :, :) + step*rho1_r(1)%array(:, :, :)
1257!$OMP END WORKSHARE NOWAIT
1258 IF (ASSOCIATED(tau1_r) .AND. ASSOCIATED(tau) .AND. ASSOCIATED(tau1_r)) THEN
1259!$OMP WORKSHARE
1260 tau_r(1)%array(:, :, :) = tau(:, :, :) + step*tau1_r(1)%array(:, :, :)
1261!$OMP END WORKSHARE NOWAIT
1262 END IF
1263!$OMP END PARALLEL
1264 CALL xc_vxc_pw_create(vxc_rho, vxc_tau, exc, rho_r, rho_g, tau_r, xc_section, &
1265 weights, pw_pool, .false., virial_dummy)
1266 CALL pw_axpy(vxc_rho(1), v_xc(1), rweight)
1267 IF (ASSOCIATED(vxc_tau) .AND. ASSOCIATED(v_tau)) THEN
1268 CALL pw_axpy(vxc_tau(1), v_tau(1), rweight)
1269 END IF
1270 CALL vxc_rho(1)%release()
1271 DEALLOCATE (vxc_rho)
1272 IF (ASSOCIATED(vxc_tau)) THEN
1273 CALL vxc_tau(1)%release()
1274 DEALLOCATE (vxc_tau)
1275 END IF
1276 END DO
1277 END IF
1278
1279 IF (my_calc_virial) THEN
1280 lsd = (nspins == 2)
1281 IF (nspins == 1 .AND. do_triplet) THEN
1282 lsd = .true.
1283 END IF
1284
1285 CALL check_for_derivatives(deriv_set, (nspins == 2), rho_f, gradient_f, tau_f, laplace_f)
1286
1287 ! Calculate the virial terms
1288 ! Those arising from the first derivatives are treated like in xc_calc_2nd_deriv_analytical
1289 ! Those arising from the second derivatives are calculated numerically
1290 ! We assume that all metaGGA functionals require the gradient
1291 IF (gradient_f) THEN
1292 bo = rho_set%local_bounds
1293
1294 ! Create the work grid for the virial terms
1295 CALL allocate_pw(virial_pw, pw_pool, bo)
1296
1297 gradient_cut = section_get_rval(xc_section, "GRADIENT_CUTOFF")
1298
1299 ! create the container to store the argument of the functionals
1300 CALL xc_rho_set_create(rho1_set, bo, &
1301 rho_cutoff=section_get_rval(xc_section, "DENSITY_CUTOFF"), &
1302 drho_cutoff=gradient_cut, &
1303 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
1304
1305 xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
1306 needs = xc_functionals_get_needs(xc_fun_section, lsd, .true.)
1307
1308 ! calculate the arguments needed by the functionals
1309 CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
1310 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
1311 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
1312 pw_pool)
1313
1314 IF (lsd) THEN
1315 CALL xc_rho_set_get(rho_set, drhoa=drhoa, drhob=drhob, norm_drho=norm_drho, &
1316 norm_drhoa=norm_drhoa, norm_drhob=norm_drhob, tau_a=tau_a, tau_b=tau_b, &
1317 laplace_rhoa=laplacea, laplace_rhob=laplaceb, can_return_null=.true.)
1318 CALL xc_rho_set_get(rho1_set, rhoa=rho1a, rhob=rho1b, drhoa=drho1a, drhob=drho1b, laplace_rhoa=laplace1a, &
1319 laplace_rhob=laplace1b, can_return_null=.true.)
1320
1321 CALL calc_drho_from_ab(drho, drhoa, drhob)
1322 CALL calc_drho_from_ab(drho1, drho1a, drho1b)
1323 ELSE
1324 CALL xc_rho_set_get(rho_set, drho=drho, norm_drho=norm_drho, tau=tau, laplace_rho=laplace, can_return_null=.true.)
1325 CALL xc_rho_set_get(rho1_set, rho=rho1, drho=drho1, laplace_rho=laplace1, can_return_null=.true.)
1326 END IF
1327
1328 CALL prepare_dr1dr(dr1dr, drho, drho1)
1329
1330 IF (lsd) THEN
1331 CALL prepare_dr1dr(dra1dra, drhoa, drho1a)
1332 CALL prepare_dr1dr(drb1drb, drhob, drho1b)
1333
1334 CALL allocate_pw(v_drho, pw_pool, bo)
1335 CALL allocate_pw(v_drhoa, pw_pool, bo)
1336 CALL allocate_pw(v_drhob, pw_pool, bo)
1337
1338 IF (ASSOCIATED(norm_drhoa)) CALL apply_drho(deriv_set, [deriv_norm_drhoa], virial_pw, &
1339 drhoa, drho1a, virial_xc, &
1340 norm_drhoa, gradient_cut, dra1dra, v_drhoa%array)
1341 IF (ASSOCIATED(norm_drhob)) CALL apply_drho(deriv_set, [deriv_norm_drhob], virial_pw, &
1342 drhob, drho1b, virial_xc, &
1343 norm_drhob, gradient_cut, drb1drb, v_drhob%array)
1344 IF (ASSOCIATED(norm_drho)) CALL apply_drho(deriv_set, [deriv_norm_drho], virial_pw, &
1345 drho, drho1, virial_xc, &
1346 norm_drho, gradient_cut, dr1dr, v_drho%array)
1347 IF (laplace_f) THEN
1348 CALL xc_derivative_get(xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa]), deriv_data=deriv_data)
1349 cpassert(ASSOCIATED(deriv_data))
1350 virial_pw%array(:, :, :) = -rho1a(:, :, :)
1351 CALL virial_laplace(virial_pw, pw_pool, virial_xc, deriv_data)
1352
1353 CALL allocate_pw(v_laplacea, pw_pool, bo)
1354
1355 CALL xc_derivative_get(xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob]), deriv_data=deriv_data)
1356 cpassert(ASSOCIATED(deriv_data))
1357 virial_pw%array(:, :, :) = -rho1b(:, :, :)
1358 CALL virial_laplace(virial_pw, pw_pool, virial_xc, deriv_data)
1359
1360 CALL allocate_pw(v_laplaceb, pw_pool, bo)
1361 END IF
1362
1363 ELSE
1364
1365 ! Create the work grid for the potential of the gradient part
1366 CALL allocate_pw(v_drho, pw_pool, bo)
1367
1368 CALL apply_drho(deriv_set, [deriv_norm_drho], virial_pw, drho, drho1, virial_xc, &
1369 norm_drho, gradient_cut, dr1dr, v_drho%array)
1370 IF (laplace_f) THEN
1371 CALL xc_derivative_get(xc_dset_get_derivative(deriv_set, [deriv_laplace_rho]), deriv_data=deriv_data)
1372 cpassert(ASSOCIATED(deriv_data))
1373 virial_pw%array(:, :, :) = -rho1(:, :, :)
1374 CALL virial_laplace(virial_pw, pw_pool, virial_xc, deriv_data)
1375
1376 CALL allocate_pw(v_laplace, pw_pool, bo)
1377 END IF
1378
1379 END IF
1380
1381 IF (lsd) THEN
1382 rho_r(1)%array = rhoa
1383 rho_r(2)%array = rhob
1384 ELSE
1385 rho_r(1)%array = rho
1386 END IF
1387 IF (ASSOCIATED(tau1_r)) THEN
1388 IF (lsd) THEN
1389 tau_r(1)%array = tau_a
1390 tau_r(2)%array = tau_b
1391 ELSE
1392 tau_r(1)%array = tau
1393 END IF
1394 END IF
1395
1396 ! Create deriv sets with same densities but different gradients
1397 CALL xc_dset_create(deriv_set1, pw_pool)
1398
1399 rho_cutoff = section_get_rval(xc_section, "DENSITY_CUTOFF")
1400
1401 ! create the place where to store the argument for the functionals
1402 CALL xc_rho_set_create(rho2_set, bo, &
1403 rho_cutoff=rho_cutoff, &
1404 drho_cutoff=section_get_rval(xc_section, "GRADIENT_CUTOFF"), &
1405 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
1406
1407 ! calculate the arguments needed by the functionals
1408 CALL xc_rho_set_update(rho2_set, rho_r, rho_g, tau_r, needs, &
1409 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
1410 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
1411 pw_pool)
1412
1413 IF (lsd) THEN
1414 CALL xc_rho_set_get(rho1_set, rhoa=rho1a, rhob=rho1b, tau_a=tau1a, tau_b=tau1b, &
1415 laplace_rhoa=laplace1a, laplace_rhob=laplace1b, can_return_null=.true.)
1416 CALL xc_rho_set_get(rho2_set, norm_drhoa=norm_drho2a, norm_drhob=norm_drho2b, &
1417 norm_drho=norm_drho2, laplace_rhoa=laplace2a, laplace_rhob=laplace2b, can_return_null=.true.)
1418
1419 DO istep = -nsteps, nsteps
1420 IF (istep == 0) cycle
1421 rweight = rweights(istep, nsteps)/h
1422 step = real(istep, dp)*h
1423 IF (ASSOCIATED(norm_drhoa)) THEN
1424 CALL get_derivs_rho(norm_drho2a, norm_drhoa, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1425 CALL update_deriv_rho(deriv_set1, [deriv_rhoa], bo, &
1426 norm_drhoa, gradient_cut, rweight, rho1a, v_drhoa%array)
1427 CALL update_deriv_rho(deriv_set1, [deriv_rhob], bo, &
1428 norm_drhoa, gradient_cut, rweight, rho1b, v_drhoa%array)
1429 CALL update_deriv_rho(deriv_set1, [deriv_norm_drhoa], bo, &
1430 norm_drhoa, gradient_cut, rweight, dra1dra, v_drhoa%array)
1431 CALL update_deriv_drho_ab(deriv_set1, [deriv_norm_drhob], bo, &
1432 norm_drhoa, gradient_cut, rweight, dra1dra, drb1drb, v_drhoa%array, v_drhob%array)
1433 CALL update_deriv_drho_ab(deriv_set1, [deriv_norm_drho], bo, &
1434 norm_drhoa, gradient_cut, rweight, dra1dra, dr1dr, v_drhoa%array, v_drho%array)
1435 IF (tau_f) THEN
1436 CALL update_deriv_rho(deriv_set1, [deriv_tau_a], bo, &
1437 norm_drhoa, gradient_cut, rweight, tau1a, v_drhoa%array)
1438 CALL update_deriv_rho(deriv_set1, [deriv_tau_b], bo, &
1439 norm_drhoa, gradient_cut, rweight, tau1b, v_drhoa%array)
1440 END IF
1441 IF (laplace_f) THEN
1442 CALL update_deriv_rho(deriv_set1, [deriv_laplace_rhoa], bo, &
1443 norm_drhoa, gradient_cut, rweight, laplace1a, v_drhoa%array)
1444 CALL update_deriv_rho(deriv_set1, [deriv_laplace_rhob], bo, &
1445 norm_drhoa, gradient_cut, rweight, laplace1b, v_drhoa%array)
1446 END IF
1447 END IF
1448
1449 IF (ASSOCIATED(norm_drhob)) THEN
1450 CALL get_derivs_rho(norm_drho2b, norm_drhob, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1451 CALL update_deriv_rho(deriv_set1, [deriv_rhoa], bo, &
1452 norm_drhob, gradient_cut, rweight, rho1a, v_drhob%array)
1453 CALL update_deriv_rho(deriv_set1, [deriv_rhob], bo, &
1454 norm_drhob, gradient_cut, rweight, rho1b, v_drhob%array)
1455 CALL update_deriv_rho(deriv_set1, [deriv_norm_drhob], bo, &
1456 norm_drhob, gradient_cut, rweight, drb1drb, v_drhob%array)
1457 CALL update_deriv_drho_ab(deriv_set1, [deriv_norm_drhoa], bo, &
1458 norm_drhob, gradient_cut, rweight, drb1drb, dra1dra, v_drhob%array, v_drhoa%array)
1459 CALL update_deriv_drho_ab(deriv_set1, [deriv_norm_drho], bo, &
1460 norm_drhob, gradient_cut, rweight, drb1drb, dr1dr, v_drhob%array, v_drho%array)
1461 IF (tau_f) THEN
1462 CALL update_deriv_rho(deriv_set1, [deriv_tau_a], bo, &
1463 norm_drhob, gradient_cut, rweight, tau1a, v_drhob%array)
1464 CALL update_deriv_rho(deriv_set1, [deriv_tau_b], bo, &
1465 norm_drhob, gradient_cut, rweight, tau1b, v_drhob%array)
1466 END IF
1467 IF (laplace_f) THEN
1468 CALL update_deriv_rho(deriv_set1, [deriv_laplace_rhoa], bo, &
1469 norm_drhob, gradient_cut, rweight, laplace1a, v_drhob%array)
1470 CALL update_deriv_rho(deriv_set1, [deriv_laplace_rhob], bo, &
1471 norm_drhob, gradient_cut, rweight, laplace1b, v_drhob%array)
1472 END IF
1473 END IF
1474
1475 IF (ASSOCIATED(norm_drho)) THEN
1476 CALL get_derivs_rho(norm_drho2, norm_drho, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1477 CALL update_deriv_rho(deriv_set1, [deriv_rhoa], bo, &
1478 norm_drho, gradient_cut, rweight, rho1a, v_drho%array)
1479 CALL update_deriv_rho(deriv_set1, [deriv_rhob], bo, &
1480 norm_drho, gradient_cut, rweight, rho1b, v_drho%array)
1481 CALL update_deriv_rho(deriv_set1, [deriv_norm_drho], bo, &
1482 norm_drho, gradient_cut, rweight, dr1dr, v_drho%array)
1483 CALL update_deriv_drho_ab(deriv_set1, [deriv_norm_drhoa], bo, &
1484 norm_drho, gradient_cut, rweight, dr1dr, dra1dra, v_drho%array, v_drhoa%array)
1485 CALL update_deriv_drho_ab(deriv_set1, [deriv_norm_drhob], bo, &
1486 norm_drho, gradient_cut, rweight, dr1dr, drb1drb, v_drho%array, v_drhob%array)
1487 IF (tau_f) THEN
1488 CALL update_deriv_rho(deriv_set1, [deriv_tau_a], bo, &
1489 norm_drho, gradient_cut, rweight, tau1a, v_drho%array)
1490 CALL update_deriv_rho(deriv_set1, [deriv_tau_b], bo, &
1491 norm_drho, gradient_cut, rweight, tau1b, v_drho%array)
1492 END IF
1493 IF (laplace_f) THEN
1494 CALL update_deriv_rho(deriv_set1, [deriv_laplace_rhoa], bo, &
1495 norm_drho, gradient_cut, rweight, laplace1a, v_drho%array)
1496 CALL update_deriv_rho(deriv_set1, [deriv_laplace_rhob], bo, &
1497 norm_drho, gradient_cut, rweight, laplace1b, v_drho%array)
1498 END IF
1499 END IF
1500
1501 IF (laplace_f) THEN
1502
1503 CALL get_derivs_rho(laplace2a, laplacea, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1504
1505 ! Obtain the numerical 2nd derivatives w.r.t. to drho and collect the potential
1506 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_rhoa], bo, &
1507 rweight, rho1a, v_laplacea%array)
1508 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_rhob], bo, &
1509 rweight, rho1b, v_laplacea%array)
1510 IF (ASSOCIATED(norm_drho)) THEN
1511 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_norm_drho], bo, &
1512 rweight, dr1dr, v_laplacea%array)
1513 END IF
1514 IF (ASSOCIATED(norm_drhoa)) THEN
1515 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_norm_drhoa], bo, &
1516 rweight, dra1dra, v_laplacea%array)
1517 END IF
1518 IF (ASSOCIATED(norm_drhob)) THEN
1519 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_norm_drhob], bo, &
1520 rweight, drb1drb, v_laplacea%array)
1521 END IF
1522
1523 IF (ASSOCIATED(tau1a)) THEN
1524 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_tau_a], bo, &
1525 rweight, tau1a, v_laplacea%array)
1526 END IF
1527 IF (ASSOCIATED(tau1b)) THEN
1528 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_tau_b], bo, &
1529 rweight, tau1b, v_laplacea%array)
1530 END IF
1531
1532 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_laplace_rhoa], bo, &
1533 rweight, laplace1a, v_laplacea%array)
1534
1535 CALL update_deriv(deriv_set1, laplacea, rho_cutoff, [deriv_laplace_rhob], bo, &
1536 rweight, laplace1b, v_laplacea%array)
1537
1538 ! The same for the beta spin
1539 CALL get_derivs_rho(laplace2b, laplaceb, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1540
1541 ! Obtain the numerical 2nd derivatives w.r.t. to drho and collect the potential
1542 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_rhoa], bo, &
1543 rweight, rho1a, v_laplaceb%array)
1544 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_rhob], bo, &
1545 rweight, rho1b, v_laplaceb%array)
1546 IF (ASSOCIATED(norm_drho)) THEN
1547 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_norm_drho], bo, &
1548 rweight, dr1dr, v_laplaceb%array)
1549 END IF
1550 IF (ASSOCIATED(norm_drhoa)) THEN
1551 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_norm_drhoa], bo, &
1552 rweight, dra1dra, v_laplaceb%array)
1553 END IF
1554 IF (ASSOCIATED(norm_drhob)) THEN
1555 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_norm_drhob], bo, &
1556 rweight, drb1drb, v_laplaceb%array)
1557 END IF
1558
1559 IF (tau_f) THEN
1560 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_tau_a], bo, &
1561 rweight, tau1a, v_laplaceb%array)
1562 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_tau_b], bo, &
1563 rweight, tau1b, v_laplaceb%array)
1564 END IF
1565
1566 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_laplace_rhoa], bo, &
1567 rweight, laplace1a, v_laplaceb%array)
1568
1569 CALL update_deriv(deriv_set1, laplaceb, rho_cutoff, [deriv_laplace_rhob], bo, &
1570 rweight, laplace1b, v_laplaceb%array)
1571 END IF
1572 END DO
1573
1574 CALL virial_drho_drho(virial_pw, drhoa, v_drhoa, virial_xc)
1575 CALL virial_drho_drho(virial_pw, drhob, v_drhob, virial_xc)
1576 CALL virial_drho_drho(virial_pw, drho, v_drho, virial_xc)
1577
1578 CALL deallocate_pw(v_drho, pw_pool)
1579 CALL deallocate_pw(v_drhoa, pw_pool)
1580 CALL deallocate_pw(v_drhob, pw_pool)
1581
1582 IF (laplace_f) THEN
1583 virial_pw%array(:, :, :) = -rhoa(:, :, :)
1584 CALL virial_laplace(virial_pw, pw_pool, virial_xc, v_laplacea%array)
1585 CALL deallocate_pw(v_laplacea, pw_pool)
1586
1587 virial_pw%array(:, :, :) = -rhob(:, :, :)
1588 CALL virial_laplace(virial_pw, pw_pool, virial_xc, v_laplaceb%array)
1589 CALL deallocate_pw(v_laplaceb, pw_pool)
1590 END IF
1591
1592 CALL deallocate_pw(virial_pw, pw_pool)
1593
1594 DO idir = 1, 3
1595 DEALLOCATE (drho(idir)%array)
1596 DEALLOCATE (drho1(idir)%array)
1597 END DO
1598 DEALLOCATE (dra1dra, drb1drb)
1599
1600 ELSE
1601 CALL xc_rho_set_get(rho1_set, rho=rho1, tau=tau1, laplace_rho=laplace1, can_return_null=.true.)
1602 CALL xc_rho_set_get(rho2_set, norm_drho=norm_drho2, laplace_rho=laplace2, can_return_null=.true.)
1603
1604 DO istep = -nsteps, nsteps
1605 IF (istep == 0) cycle
1606 rweight = rweights(istep, nsteps)/h
1607 step = real(istep, dp)*h
1608 CALL get_derivs_rho(norm_drho2, norm_drho, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1609
1610 ! Obtain the numerical 2nd derivatives w.r.t. to drho and collect the potential
1611 CALL update_deriv_rho(deriv_set1, [deriv_rho], bo, &
1612 norm_drho, gradient_cut, rweight, rho1, v_drho%array)
1613 CALL update_deriv_rho(deriv_set1, [deriv_norm_drho], bo, &
1614 norm_drho, gradient_cut, rweight, dr1dr, v_drho%array)
1615
1616 IF (tau_f) THEN
1617 CALL update_deriv_rho(deriv_set1, [deriv_tau], bo, &
1618 norm_drho, gradient_cut, rweight, tau1, v_drho%array)
1619 END IF
1620 IF (laplace_f) THEN
1621 CALL update_deriv_rho(deriv_set1, [deriv_laplace_rho], bo, &
1622 norm_drho, gradient_cut, rweight, laplace1, v_drho%array)
1623
1624 CALL get_derivs_rho(laplace2, laplace, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1625
1626 ! Obtain the numerical 2nd derivatives w.r.t. to drho and collect the potential
1627 CALL update_deriv(deriv_set1, laplace, rho_cutoff, [deriv_rho], bo, &
1628 rweight, rho1, v_laplace%array)
1629 CALL update_deriv(deriv_set1, laplace, rho_cutoff, [deriv_norm_drho], bo, &
1630 rweight, dr1dr, v_laplace%array)
1631
1632 IF (tau_f) THEN
1633 CALL update_deriv(deriv_set1, laplace, rho_cutoff, [deriv_tau], bo, &
1634 rweight, tau1, v_laplace%array)
1635 END IF
1636
1637 CALL update_deriv(deriv_set1, laplace, rho_cutoff, [deriv_laplace_rho], bo, &
1638 rweight, laplace1, v_laplace%array)
1639 END IF
1640 END DO
1641
1642 ! Calculate the virial contribution from the potential
1643 CALL virial_drho_drho(virial_pw, drho, v_drho, virial_xc)
1644
1645 CALL deallocate_pw(v_drho, pw_pool)
1646
1647 IF (laplace_f) THEN
1648 virial_pw%array(:, :, :) = -rho(:, :, :)
1649 CALL virial_laplace(virial_pw, pw_pool, virial_xc, v_laplace%array)
1650 CALL deallocate_pw(v_laplace, pw_pool)
1651 END IF
1652
1653 CALL deallocate_pw(virial_pw, pw_pool)
1654 END IF
1655
1656 END IF
1657
1658 CALL xc_dset_release(deriv_set1)
1659
1660 DEALLOCATE (dr1dr)
1661
1662 CALL xc_rho_set_release(rho1_set)
1663 CALL xc_rho_set_release(rho2_set)
1664 END IF
1665
1666 DO ispin = 1, SIZE(rho_r)
1667 CALL pw_pool%give_back_pw(rho_r(ispin))
1668 END DO
1669 DEALLOCATE (rho_r)
1670
1671 IF (ASSOCIATED(tau_r)) THEN
1672 DO ispin = 1, SIZE(tau_r)
1673 CALL pw_pool%give_back_pw(tau_r(ispin))
1674 END DO
1675 DEALLOCATE (tau_r)
1676 END IF
1677
1678 CALL timestop(handle)
1679
1680 END SUBROUTINE xc_calc_2nd_deriv_numerical
1681
1682! **************************************************************************************************
1683!> \brief ...
1684!> \param rho_r ...
1685!> \param rho_g ...
1686!> \param rho1_r ...
1687!> \param rhoa ...
1688!> \param rhob ...
1689!> \param vxc_rho ...
1690!> \param tau_r ...
1691!> \param tau1_r ...
1692!> \param tau_a ...
1693!> \param tau_b ...
1694!> \param vxc_tau ...
1695!> \param xc_section ...
1696!> \param pw_pool ...
1697!> \param step ...
1698! **************************************************************************************************
1699 SUBROUTINE calc_resp_potential_numer_ab(rho_r, rho_g, rho1_r, rhoa, rhob, vxc_rho, &
1700 tau_r, tau1_r, tau_a, tau_b, vxc_tau, &
1701 xc_section, weights, pw_pool, step)
1702
1703 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER, INTENT(IN) :: vxc_rho, vxc_tau
1704 TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(IN) :: rho1_r
1705 TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(IN), POINTER :: tau1_r
1706 TYPE(pw_r3d_rs_type), INTENT(IN), POINTER :: weights
1707 TYPE(pw_pool_type), INTENT(IN), POINTER :: pw_pool
1708 TYPE(section_vals_type), INTENT(IN), POINTER :: xc_section
1709 REAL(kind=dp), INTENT(IN) :: step
1710 REAL(kind=dp), DIMENSION(:, :, :), POINTER, INTENT(IN) :: rhoa, rhob, tau_a, tau_b
1711 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER, INTENT(IN) :: rho_r
1712 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
1713 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: tau_r
1714
1715 CHARACTER(len=*), PARAMETER :: routinen = 'calc_resp_potential_numer_ab'
1716
1717 INTEGER :: handle
1718 REAL(kind=dp) :: exc
1719 REAL(kind=dp), DIMENSION(3, 3) :: virial_dummy
1720
1721 CALL timeset(routinen, handle)
1722
1723!$OMP PARALLEL DEFAULT(NONE) SHARED(rho_r,rhoa,rhob,step,rho1_r,tau_r,tau_a,tau_b,tau1_r)
1724!$OMP WORKSHARE
1725 rho_r(1)%array(:, :, :) = rhoa(:, :, :) + step*rho1_r(1)%array(:, :, :)
1726!$OMP END WORKSHARE NOWAIT
1727!$OMP WORKSHARE
1728 rho_r(2)%array(:, :, :) = rhob(:, :, :) + step*rho1_r(2)%array(:, :, :)
1729!$OMP END WORKSHARE NOWAIT
1730 IF (ASSOCIATED(tau1_r) .AND. ASSOCIATED(tau_r) .AND. ASSOCIATED(tau_a) .AND. ASSOCIATED(tau_b)) THEN
1731!$OMP WORKSHARE
1732 tau_r(1)%array(:, :, :) = tau_a(:, :, :) + step*tau1_r(1)%array(:, :, :)
1733!$OMP END WORKSHARE NOWAIT
1734!$OMP WORKSHARE
1735 tau_r(2)%array(:, :, :) = tau_b(:, :, :) + step*tau1_r(2)%array(:, :, :)
1736!$OMP END WORKSHARE NOWAIT
1737 END IF
1738!$OMP END PARALLEL
1739 CALL xc_vxc_pw_create(vxc_rho, vxc_tau, exc, rho_r, rho_g, tau_r, xc_section, &
1740 weights, pw_pool, .false., virial_dummy)
1741
1742 CALL timestop(handle)
1743
1744 END SUBROUTINE calc_resp_potential_numer_ab
1745
1746! **************************************************************************************************
1747!> \brief calculates stress tensor and potential contributions from the first derivative
1748!> \param deriv_set ...
1749!> \param description ...
1750!> \param virial_pw ...
1751!> \param drho ...
1752!> \param drho1 ...
1753!> \param virial_xc ...
1754!> \param norm_drho ...
1755!> \param gradient_cut ...
1756!> \param dr1dr ...
1757!> \param v_drho ...
1758! **************************************************************************************************
1759 SUBROUTINE apply_drho(deriv_set, description, virial_pw, drho, drho1, &
1760 virial_xc, norm_drho, gradient_cut, dr1dr, v_drho)
1761
1762 TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set
1763 INTEGER, DIMENSION(:), INTENT(in) :: description
1764 TYPE(pw_r3d_rs_type), INTENT(IN) :: virial_pw
1765 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(IN) :: drho, drho1
1766 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT) :: virial_xc
1767 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: norm_drho
1768 REAL(kind=dp), INTENT(IN) :: gradient_cut
1769 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: dr1dr
1770 REAL(kind=dp), DIMENSION(:, :, :), INTENT(INOUT) :: v_drho
1771
1772 CHARACTER(len=*), PARAMETER :: routinen = 'apply_drho'
1773
1774 INTEGER :: handle
1775 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: deriv_data
1776 TYPE(xc_derivative_type), POINTER :: deriv_att
1777
1778 CALL timeset(routinen, handle)
1779
1780 deriv_att => xc_dset_get_derivative(deriv_set, description)
1781 IF (ASSOCIATED(deriv_att)) THEN
1782 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
1783 CALL virial_drho_drho1(virial_pw, drho, drho1, deriv_data, virial_xc)
1784
1785!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dr1dr,gradient_cut,norm_drho,v_drho,deriv_data)
1786 v_drho(:, :, :) = v_drho(:, :, :) + &
1787 deriv_data(:, :, :)*dr1dr(:, :, :)/max(gradient_cut, norm_drho(:, :, :))**2
1788!$OMP END PARALLEL WORKSHARE
1789 END IF
1790
1791 CALL timestop(handle)
1792
1793 END SUBROUTINE apply_drho
1794
1795! **************************************************************************************************
1796!> \brief adds potential contributions from derivatives of rho or diagonal terms of norm_drho
1797!> \param deriv_set1 ...
1798!> \param description ...
1799!> \param bo ...
1800!> \param norm_drho norm_drho of which derivative is calculated
1801!> \param gradient_cut ...
1802!> \param h ...
1803!> \param rho1 function to contract the derivative with (rho1 for rho, dr1dr for norm_drho)
1804!> \param v_drho ...
1805! **************************************************************************************************
1806 SUBROUTINE update_deriv_rho(deriv_set1, description, bo, norm_drho, gradient_cut, weight, rho1, v_drho)
1807
1808 TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set1
1809 INTEGER, DIMENSION(:), INTENT(in) :: description
1810 INTEGER, DIMENSION(2, 3), INTENT(IN) :: bo
1811 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
1812 REAL(kind=dp), INTENT(IN) :: gradient_cut, weight
1813 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
1814 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
1815
1816 CHARACTER(len=*), PARAMETER :: routinen = 'update_deriv_rho'
1817
1818 INTEGER :: handle, i, j, k
1819 REAL(kind=dp) :: de
1820 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: deriv_data1
1821 TYPE(xc_derivative_type), POINTER :: deriv_att1
1822
1823 CALL timeset(routinen, handle)
1824
1825 ! Obtain the numerical 2nd derivatives w.r.t. to drho and collect the potential
1826 deriv_att1 => xc_dset_get_derivative(deriv_set1, description)
1827 IF (ASSOCIATED(deriv_att1)) THEN
1828 CALL xc_derivative_get(deriv_att1, deriv_data=deriv_data1)
1829!$OMP PARALLEL DO DEFAULT(NONE) &
1830!$OMP SHARED(bo,deriv_data1,weight,norm_drho,v_drho,rho1,gradient_cut) &
1831!$OMP PRIVATE(i,j,k,de) &
1832!$OMP COLLAPSE(3)
1833 DO k = bo(1, 3), bo(2, 3)
1834 DO j = bo(1, 2), bo(2, 2)
1835 DO i = bo(1, 1), bo(2, 1)
1836 de = weight*deriv_data1(i, j, k)/max(gradient_cut, norm_drho(i, j, k))**2
1837 v_drho(i, j, k) = v_drho(i, j, k) - de*rho1(i, j, k)
1838 END DO
1839 END DO
1840 END DO
1841!$OMP END PARALLEL DO
1842 END IF
1843
1844 CALL timestop(handle)
1845
1846 END SUBROUTINE update_deriv_rho
1847
1848! **************************************************************************************************
1849!> \brief adds potential contributions from derivatives of a component with positive and negative values
1850!> \param deriv_set1 ...
1851!> \param description ...
1852!> \param bo ...
1853!> \param h ...
1854!> \param rho1 function to contract the derivative with (rho1 for rho, dr1dr for norm_drho)
1855!> \param v ...
1856! **************************************************************************************************
1857 SUBROUTINE update_deriv(deriv_set1, rho, rho_cutoff, description, bo, weight, rho1, v)
1858
1859 TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set1
1860 INTEGER, DIMENSION(:), INTENT(in) :: description
1861 INTEGER, DIMENSION(2, 3), INTENT(IN) :: bo
1862 REAL(kind=dp), INTENT(IN) :: weight, rho_cutoff
1863 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
1864 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
1865
1866 CHARACTER(len=*), PARAMETER :: routinen = 'update_deriv'
1867
1868 INTEGER :: handle, i, j, k
1869 REAL(kind=dp) :: de
1870 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: deriv_data1
1871 TYPE(xc_derivative_type), POINTER :: deriv_att1
1872
1873 CALL timeset(routinen, handle)
1874
1875 ! Obtain the numerical 2nd derivatives w.r.t. to drho and collect the potential
1876 deriv_att1 => xc_dset_get_derivative(deriv_set1, description)
1877 IF (ASSOCIATED(deriv_att1)) THEN
1878 CALL xc_derivative_get(deriv_att1, deriv_data=deriv_data1)
1879!$OMP PARALLEL DO DEFAULT(NONE) &
1880!$OMP SHARED(bo,deriv_data1,weight,v,rho1,rho, rho_cutoff) &
1881!$OMP PRIVATE(i,j,k,de) &
1882!$OMP COLLAPSE(3)
1883 DO k = bo(1, 3), bo(2, 3)
1884 DO j = bo(1, 2), bo(2, 2)
1885 DO i = bo(1, 1), bo(2, 1)
1886 ! We have to consider that the given density (mostly the Laplacian) may have positive and negative values
1887 de = weight*deriv_data1(i, j, k)/sign(max(abs(rho(i, j, k)), rho_cutoff), rho(i, j, k))
1888 v(i, j, k) = v(i, j, k) + de*rho1(i, j, k)
1889 END DO
1890 END DO
1891 END DO
1892!$OMP END PARALLEL DO
1893 END IF
1894
1895 CALL timestop(handle)
1896
1897 END SUBROUTINE update_deriv
1898
1899! **************************************************************************************************
1900!> \brief adds mixed derivatives of norm_drho
1901!> \param deriv_set1 ...
1902!> \param description ...
1903!> \param bo ...
1904!> \param norm_drhoa norm_drho of which derivatives is calculated
1905!> \param gradient_cut ...
1906!> \param h ...
1907!> \param dra1dra dr1dr corresponding to norm_drho
1908!> \param drb1drb ...
1909!> \param v_drhoa potential corresponding to norm_drho
1910!> \param v_drhob ...
1911! **************************************************************************************************
1912 SUBROUTINE update_deriv_drho_ab(deriv_set1, description, bo, &
1913 norm_drhoa, gradient_cut, weight, dra1dra, drb1drb, v_drhoa, v_drhob)
1914
1915 TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set1
1916 INTEGER, DIMENSION(:), INTENT(in) :: description
1917 INTEGER, DIMENSION(2, 3), INTENT(IN) :: bo
1918 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
1919 REAL(kind=dp), INTENT(IN) :: gradient_cut, weight
1920 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
1921 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
1922
1923 CHARACTER(len=*), PARAMETER :: routinen = 'update_deriv_drho_ab'
1924
1925 INTEGER :: handle, i, j, k
1926 REAL(kind=dp) :: de
1927 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: deriv_data1
1928 TYPE(xc_derivative_type), POINTER :: deriv_att1
1929
1930 CALL timeset(routinen, handle)
1931
1932 deriv_att1 => xc_dset_get_derivative(deriv_set1, description)
1933 IF (ASSOCIATED(deriv_att1)) THEN
1934 CALL xc_derivative_get(deriv_att1, deriv_data=deriv_data1)
1935!$OMP PARALLEL DO DEFAULT(NONE) &
1936!$OMP PRIVATE(k,j,i,de) &
1937!$OMP SHARED(bo,drb1drb,dra1dra,deriv_data1,weight,gradient_cut,norm_drhoa,v_drhoa,v_drhob) &
1938!$OMP COLLAPSE(3)
1939 DO k = bo(1, 3), bo(2, 3)
1940 DO j = bo(1, 2), bo(2, 2)
1941 DO i = bo(1, 1), bo(2, 1)
1942 ! We introduce a factor of two because we will average between both numerical derivatives
1943 de = 0.5_dp*weight*deriv_data1(i, j, k)/max(gradient_cut, norm_drhoa(i, j, k))**2
1944 v_drhoa(i, j, k) = v_drhoa(i, j, k) - de*drb1drb(i, j, k)
1945 v_drhob(i, j, k) = v_drhob(i, j, k) - de*dra1dra(i, j, k)
1946 END DO
1947 END DO
1948 END DO
1949!$OMP END PARALLEL DO
1950 END IF
1951
1952 CALL timestop(handle)
1953
1954 END SUBROUTINE update_deriv_drho_ab
1955
1956! **************************************************************************************************
1957!> \brief calculate derivative sets for helper points
1958!> \param norm_drho2 norm_drho of new points
1959!> \param norm_drho norm_drho of KS density
1960!> \param h ...
1961!> \param xc_fun_section ...
1962!> \param lsd ...
1963!> \param rho2_set rho_set for new points
1964!> \param deriv_set1 will contain derivatives of the perturbed density
1965! **************************************************************************************************
1966 SUBROUTINE get_derivs_rho(norm_drho2, norm_drho, step, xc_fun_section, lsd, rho2_set, deriv_set1)
1967 REAL(kind=dp), DIMENSION(:, :, :), INTENT(OUT) :: norm_drho2
1968 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: norm_drho
1969 REAL(kind=dp), INTENT(IN) :: step
1970 TYPE(section_vals_type), INTENT(IN), POINTER :: xc_fun_section
1971 LOGICAL, INTENT(IN) :: lsd
1972 TYPE(xc_rho_set_type), INTENT(INOUT) :: rho2_set
1973 TYPE(xc_derivative_set_type) :: deriv_set1
1974
1975 CHARACTER(len=*), PARAMETER :: routinen = 'get_derivs_rho'
1976
1977 INTEGER :: handle
1978
1979 CALL timeset(routinen, handle)
1980
1981 ! Copy the densities, do one step into the direction of drho
1982!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(norm_drho,norm_drho2,step)
1983 norm_drho2 = norm_drho*(1.0_dp + step)
1984!$OMP END PARALLEL WORKSHARE
1985
1986 CALL xc_dset_zero_all(deriv_set1)
1987
1988 ! Calculate the derivatives of the functional
1989 CALL xc_functionals_eval(xc_fun_section, &
1990 lsd=lsd, &
1991 rho_set=rho2_set, &
1992 deriv_set=deriv_set1, &
1993 deriv_order=1)
1994
1995 ! Return to the original values
1996!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(norm_drho,norm_drho2)
1997 norm_drho2 = norm_drho
1998!$OMP END PARALLEL WORKSHARE
1999
2000 CALL divide_by_norm_drho(deriv_set1, rho2_set, lsd)
2001
2002 CALL timestop(handle)
2003
2004 END SUBROUTINE get_derivs_rho
2005
2006! **************************************************************************************************
2007!> \brief Calculates the second derivative of E_xc at rho in the direction
2008!> rho1 (if you see the second derivative as bilinear form)
2009!> partial_rho|_(rho=rho) partial_rho|_(rho=rho) E_xc drho(rho1)drho
2010!> The other direction is still undetermined, thus it returns
2011!> a potential (partial integration is performed to reduce it to
2012!> function of rho, removing the dependence from its partial derivs)
2013!> Has to be called after the setup by xc_prep_2nd_deriv.
2014!> \param v_xc exchange-correlation potential
2015!> \param v_xc_tau ...
2016!> \param deriv_set derivatives of the exchange-correlation potential
2017!> \param rho_set object containing the density at which the derivatives were calculated
2018!> \param rho1_set object containing the density with which to fold
2019!> \param pw_pool the pool for the grids
2020!> \param xc_section XC parameters
2021!> \param gapw Gaussian and augmented plane waves calculation
2022!> \param vxg ...
2023!> \param tddfpt_fac factor that multiplies the crossterms (tddfpt triplets
2024!> on a closed shell system it should be -1, defaults to 1)
2025!> \param compute_virial ...
2026!> \param virial_xc ...
2027!> \note
2028!> The old version of this routine was smarter: it handled split_desc(1)
2029!> and split_desc(2) separately, thus the code automatically handled all
2030!> possible cross terms (you only had to check if it was diagonal to avoid
2031!> double counting). I think that is the way to go if you want to add more
2032!> terms (tau,rho in LSD,...). The problem with the old code was that it
2033!> because of the old functional structure it sometime guessed wrongly
2034!> which derivative was where. There were probably still bugs with gradient
2035!> corrected functionals (never tested), and it didn't contain first
2036!> derivatives with respect to drho (that contribute also to the second
2037!> derivative wrt. rho).
2038!> The code was a little complex because it really tried to handle any
2039!> functional derivative in the most efficient way with the given contents of
2040!> rho_set.
2041!> Anyway I strongly encourage whoever wants to modify this code to give a
2042!> look to the old version. [fawzi]
2043! **************************************************************************************************
2044 SUBROUTINE xc_calc_2nd_deriv_analytical(v_xc, v_xc_tau, deriv_set, rho_set, rho1_set, &
2045 pw_pool, xc_section, gapw, vxg, tddfpt_fac, &
2046 compute_virial, virial_xc, spinflip)
2047
2048 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_xc, v_xc_tau
2049 TYPE(xc_derivative_set_type) :: deriv_set
2050 TYPE(xc_rho_set_type), INTENT(IN) :: rho_set, rho1_set
2051 TYPE(pw_pool_type), POINTER :: pw_pool
2052 TYPE(section_vals_type), POINTER :: xc_section
2053 LOGICAL, INTENT(IN), OPTIONAL :: gapw
2054 REAL(kind=dp), DIMENSION(:, :, :, :), OPTIONAL, &
2055 POINTER :: vxg
2056 REAL(kind=dp), INTENT(in), OPTIONAL :: tddfpt_fac
2057 LOGICAL, INTENT(IN), OPTIONAL :: compute_virial
2058 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT), &
2059 OPTIONAL :: virial_xc
2060 LOGICAL, INTENT(in), OPTIONAL :: spinflip
2061
2062 CHARACTER(len=*), PARAMETER :: routinen = 'xc_calc_2nd_deriv_analytical'
2063
2064 INTEGER :: handle, i, ia, idir, ir, ispin, j, jdir, &
2065 k, nspins, xc_deriv_method_id
2066 INTEGER, DIMENSION(2, 3) :: bo
2067 LOGICAL :: gradient_f, lsd, my_compute_virial, alda0, &
2068 my_gapw, tau_f, laplace_f, rho_f, do_spinflip
2069 REAL(kind=dp) :: fac, gradient_cut, tmp, factor2, s, s_thresh
2070 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: dr1dr, dra1dra, drb1drb
2071 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: deriv_data, deriv_data2, &
2072 e_drhoa, e_drhob, e_drho, norm_drho, norm_drhoa, &
2073 norm_drhob, rho1, rho1a, rho1b, &
2074 tau1, tau1a, tau1b, laplace1, laplace1a, laplace1b, &
2075 rho, rhoa, rhob
2076 TYPE(cp_3d_r_cp_type), DIMENSION(3) :: drho, drho1, drho1a, drho1b, drhoa, drhob
2077 TYPE(pw_r3d_rs_type), DIMENSION(:), ALLOCATABLE :: v_drhoa, v_drhob, v_drho, v_laplace
2078 TYPE(pw_r3d_rs_type), DIMENSION(:, :), ALLOCATABLE :: v_drho_r
2079 TYPE(pw_r3d_rs_type) :: virial_pw
2080 TYPE(pw_c1d_gs_type) :: tmp_g, vxc_g
2081 TYPE(xc_derivative_type), POINTER :: deriv_att
2082
2083 CALL timeset(routinen, handle)
2084
2085 NULLIFY (e_drhoa, e_drhob, e_drho)
2086
2087 my_gapw = .false.
2088 IF (PRESENT(gapw)) my_gapw = gapw
2089
2090 my_compute_virial = .false.
2091 IF (PRESENT(compute_virial)) my_compute_virial = compute_virial
2092
2093 cpassert(ASSOCIATED(v_xc))
2094 cpassert(ASSOCIATED(xc_section))
2095 IF (my_gapw) THEN
2096 cpassert(PRESENT(vxg))
2097 END IF
2098 IF (my_compute_virial) THEN
2099 cpassert(PRESENT(virial_xc))
2100 END IF
2101
2102 CALL section_vals_val_get(xc_section, "XC_GRID%XC_DERIV", &
2103 i_val=xc_deriv_method_id)
2104 CALL xc_rho_set_get(rho_set, drho_cutoff=gradient_cut)
2105 nspins = SIZE(v_xc)
2106 lsd = ASSOCIATED(rho_set%rhoa)
2107 fac = 0.0_dp
2108 factor2 = 1.0_dp
2109 IF (PRESENT(tddfpt_fac)) fac = tddfpt_fac
2110 IF (PRESENT(tddfpt_fac)) factor2 = tddfpt_fac
2111 do_spinflip = .false.
2112 IF (PRESENT(spinflip)) do_spinflip = spinflip
2113
2114 bo = rho_set%local_bounds
2115
2116 CALL check_for_derivatives(deriv_set, lsd, rho_f, gradient_f, tau_f, laplace_f)
2117
2118 alda0 = .false.
2119 IF (gradient_f) THEN
2120 s_thresh = 1.0e-04
2121 ELSE
2122 s_thresh = 1.0e-10
2123 END IF
2124
2125 IF (tau_f) THEN
2126 cpassert(ASSOCIATED(v_xc_tau))
2127 END IF
2128
2129 IF (gradient_f) THEN
2130 ALLOCATE (v_drho_r(3, nspins), v_drho(nspins))
2131 DO ispin = 1, nspins
2132 DO idir = 1, 3
2133 CALL allocate_pw(v_drho_r(idir, ispin), pw_pool, bo)
2134 END DO
2135 CALL allocate_pw(v_drho(ispin), pw_pool, bo)
2136 END DO
2137
2138 IF (xc_requires_tmp_g(xc_deriv_method_id) .AND. .NOT. my_gapw) THEN
2139 IF (ASSOCIATED(pw_pool)) THEN
2140 CALL pw_pool%create_pw(tmp_g)
2141 CALL pw_pool%create_pw(vxc_g)
2142 ELSE
2143 ! remember to refix for gapw
2144 cpabort("XC_DERIV method is not implemented in GAPW")
2145 END IF
2146 END IF
2147 END IF
2148
2149 DO ispin = 1, nspins
2150 v_xc(ispin)%array = 0.0_dp
2151 END DO
2152
2153 IF (tau_f) THEN
2154 DO ispin = 1, nspins
2155 v_xc_tau(ispin)%array = 0.0_dp
2156 END DO
2157 END IF
2158
2159 IF (laplace_f .AND. my_gapw) &
2160 cpabort("Laplace-dependent functional not implemented with GAPW!")
2161
2162 IF (my_compute_virial .AND. (gradient_f .OR. laplace_f)) CALL allocate_pw(virial_pw, pw_pool, bo)
2163
2164 IF (lsd) THEN
2165
2166 !-------------------!
2167 ! UNrestricted case !
2168 !-------------------!
2169
2170 IF (do_spinflip) THEN
2171 CALL xc_rho_set_get(rho1_set, rhoa=rho1a)
2172 CALL xc_rho_set_get(rho_set, rhoa=rhoa, rhob=rhob)
2173 ELSE
2174 CALL xc_rho_set_get(rho1_set, rhoa=rho1a, rhob=rho1b)
2175 END IF
2176
2177 IF (gradient_f) THEN
2178 CALL xc_rho_set_get(rho_set, drhoa=drhoa, drhob=drhob, &
2179 norm_drho=norm_drho, norm_drhoa=norm_drhoa, norm_drhob=norm_drhob)
2180 IF (do_spinflip) THEN
2181 CALL xc_rho_set_get(rho1_set, drhoa=drho1a)
2182 CALL calc_drho_from_a(drho1, drho1a)
2183 ELSE
2184 CALL xc_rho_set_get(rho1_set, drhoa=drho1a, drhob=drho1b)
2185 CALL calc_drho_from_ab(drho1, drho1a, drho1b)
2186 END IF
2187
2188 CALL calc_drho_from_ab(drho, drhoa, drhob)
2189
2190 CALL prepare_dr1dr(dra1dra, drhoa, drho1a)
2191 IF (do_spinflip) THEN
2192 CALL prepare_dr1dr(drb1drb, drhob, drho1a)
2193 CALL prepare_dr1dr(dr1dr, drho, drho1a)
2194 ELSE IF (nspins /= 1) THEN
2195 CALL prepare_dr1dr(drb1drb, drhob, drho1b)
2196 CALL prepare_dr1dr(dr1dr, drho, drho1)
2197 ELSE
2198 CALL prepare_dr1dr(drb1drb, drhob, drho1b)
2199 CALL prepare_dr1dr_ab(dr1dr, drhoa, drhob, drho1a, drho1b, fac)
2200 END IF
2201
2202 ALLOCATE (v_drhoa(nspins), v_drhob(nspins))
2203 DO ispin = 1, nspins
2204 CALL allocate_pw(v_drhoa(ispin), pw_pool, bo)
2205 CALL allocate_pw(v_drhob(ispin), pw_pool, bo)
2206 END DO
2207
2208 END IF
2209
2210 IF (laplace_f) THEN
2211 CALL xc_rho_set_get(rho1_set, laplace_rhoa=laplace1a, laplace_rhob=laplace1b)
2212
2213 ALLOCATE (v_laplace(nspins))
2214 DO ispin = 1, nspins
2215 CALL allocate_pw(v_laplace(ispin), pw_pool, bo)
2216 END DO
2217
2218 IF (my_compute_virial) CALL xc_rho_set_get(rho_set, rhoa=rhoa, rhob=rhob)
2219 END IF
2220
2221 IF (tau_f) THEN
2222 CALL xc_rho_set_get(rho1_set, tau_a=tau1a, tau_b=tau1b)
2223 END IF
2224
2225 IF (do_spinflip) THEN
2226
2227 ! vxc contributions
2228 ! vxc = (vxc^{\alpha}-vxc^{\beta})*rho1/(rhoa-rhob)
2229 ! Alpha LDA contribution
2230 ! | d e_xc d e_xc | rho1a
2231 ! vxca = |-------- - --------|*-------------
2232 ! | drhoa drhob | |rhoa - rhob|
2233 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa])
2234 IF (ASSOCIATED(deriv_att)) THEN
2235 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2236 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob])
2237 IF (ASSOCIATED(deriv_att)) THEN
2238 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
2239!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
2240!$OMP SHARED(bo,v_xc,deriv_data,deriv_data2,rho1a,rhoa,rhob,S_THRESH) COLLAPSE(3)
2241 DO k = bo(1, 3), bo(2, 3)
2242 DO j = bo(1, 2), bo(2, 2)
2243 DO i = bo(1, 1), bo(2, 1)
2244 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
2245 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2246 (deriv_data(i, j, k) - deriv_data2(i, j, k))*rho1a(i, j, k)/s
2247 END DO
2248 END DO
2249 END DO
2250!$OMP END PARALLEL DO
2251 END IF
2252 END IF
2253 ! GGA contributions to the spin-flip xcKernel
2254 ! GGA contribution
2255 ! | d e_xc d e_xc | 1
2256 ! vxca += |----------* dra1dra - ----------*drb1drb|*-------------
2257 ! | d|drhoa| d|drhob| | |rhoa - rhob|
2258 IF (.NOT. alda0) THEN
2259 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa])
2260 IF (ASSOCIATED(deriv_att)) THEN
2261 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2262 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob])
2263 IF (ASSOCIATED(deriv_att)) THEN
2264 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
2265!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
2266!$OMP SHARED(bo,deriv_data,deriv_data2,dra1dra,drb1drb,v_xc,rhoa,rhob,S_THRESH) COLLAPSE(3)
2267 DO k = bo(1, 3), bo(2, 3)
2268 DO j = bo(1, 2), bo(2, 2)
2269 DO i = bo(1, 1), bo(2, 1)
2270 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
2271 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2272 (deriv_data(i, j, k)*dra1dra(i, j, k) - &
2273 deriv_data2(i, j, k)*drb1drb(i, j, k))/s
2274 END DO
2275 END DO
2276 END DO
2277!$OMP END PARALLEL DO
2278 END IF
2279 END IF
2280 END IF
2281
2282 ELSE IF (nspins /= 1) THEN
2283
2284 ! Compute \sum_{\tau}fxc^{\sigma\tau}*\rho^{\tau}(1) over the grid points
2285 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa])
2286 IF (ASSOCIATED(deriv_att)) THEN
2287 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2288!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2289!$OMP SHARED(bo,v_xc,deriv_data,rho1a,fac) COLLAPSE(3)
2290 DO k = bo(1, 3), bo(2, 3)
2291 DO j = bo(1, 2), bo(2, 2)
2292 DO i = bo(1, 1), bo(2, 1)
2293 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2294 deriv_data(i, j, k)*rho1a(i, j, k)
2295 END DO
2296 END DO
2297 END DO
2298 END IF
2299 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhob])
2300 IF (ASSOCIATED(deriv_att)) THEN
2301 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2302!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2303!$OMP SHARED(bo,v_xc,deriv_data,rho1b,fac) COLLAPSE(3)
2304 DO k = bo(1, 3), bo(2, 3)
2305 DO j = bo(1, 2), bo(2, 2)
2306 DO i = bo(1, 1), bo(2, 1)
2307 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2308 deriv_data(i, j, k)*rho1b(i, j, k)
2309 END DO
2310 END DO
2311 END DO
2312 END IF
2313 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drho])
2314 IF (ASSOCIATED(deriv_att)) THEN
2315 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2316!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2317!$OMP SHARED(bo,v_xc,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
2318 DO k = bo(1, 3), bo(2, 3)
2319 DO j = bo(1, 2), bo(2, 2)
2320 DO i = bo(1, 1), bo(2, 1)
2321 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2322 deriv_data(i, j, k)*dr1dr(i, j, k)
2323 END DO
2324 END DO
2325 END DO
2326 END IF
2327 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drhoa])
2328 IF (ASSOCIATED(deriv_att)) THEN
2329 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2330!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2331!$OMP SHARED(bo,v_xc,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
2332 DO k = bo(1, 3), bo(2, 3)
2333 DO j = bo(1, 2), bo(2, 2)
2334 DO i = bo(1, 1), bo(2, 1)
2335 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2336 deriv_data(i, j, k)*dra1dra(i, j, k)
2337 END DO
2338 END DO
2339 END DO
2340 END IF
2341 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drhob])
2342 IF (ASSOCIATED(deriv_att)) THEN
2343 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2344!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2345!$OMP SHARED(bo,v_xc,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
2346 DO k = bo(1, 3), bo(2, 3)
2347 DO j = bo(1, 2), bo(2, 2)
2348 DO i = bo(1, 1), bo(2, 1)
2349 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2350 deriv_data(i, j, k)*drb1drb(i, j, k)
2351 END DO
2352 END DO
2353 END DO
2354 END IF
2355 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_tau_a])
2356 IF (ASSOCIATED(deriv_att)) THEN
2357 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2358!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2359!$OMP SHARED(bo,v_xc,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
2360 DO k = bo(1, 3), bo(2, 3)
2361 DO j = bo(1, 2), bo(2, 2)
2362 DO i = bo(1, 1), bo(2, 1)
2363 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2364 deriv_data(i, j, k)*tau1a(i, j, k)
2365 END DO
2366 END DO
2367 END DO
2368 END IF
2369 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_tau_b])
2370 IF (ASSOCIATED(deriv_att)) THEN
2371 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2372!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2373!$OMP SHARED(bo,v_xc,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
2374 DO k = bo(1, 3), bo(2, 3)
2375 DO j = bo(1, 2), bo(2, 2)
2376 DO i = bo(1, 1), bo(2, 1)
2377 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2378 deriv_data(i, j, k)*tau1b(i, j, k)
2379 END DO
2380 END DO
2381 END DO
2382 END IF
2383 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_laplace_rhoa])
2384 IF (ASSOCIATED(deriv_att)) THEN
2385 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2386!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2387!$OMP SHARED(bo,v_xc,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
2388 DO k = bo(1, 3), bo(2, 3)
2389 DO j = bo(1, 2), bo(2, 2)
2390 DO i = bo(1, 1), bo(2, 1)
2391 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2392 deriv_data(i, j, k)*laplace1a(i, j, k)
2393 END DO
2394 END DO
2395 END DO
2396 END IF
2397 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_laplace_rhob])
2398 IF (ASSOCIATED(deriv_att)) THEN
2399 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2400!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2401!$OMP SHARED(bo,v_xc,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
2402 DO k = bo(1, 3), bo(2, 3)
2403 DO j = bo(1, 2), bo(2, 2)
2404 DO i = bo(1, 1), bo(2, 1)
2405 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
2406 deriv_data(i, j, k)*laplace1b(i, j, k)
2407 END DO
2408 END DO
2409 END DO
2410 END IF
2411
2412
2413 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhoa])
2414 IF (ASSOCIATED(deriv_att)) THEN
2415 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2416!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2417!$OMP SHARED(bo,v_xc,deriv_data,rho1a,fac) COLLAPSE(3)
2418 DO k = bo(1, 3), bo(2, 3)
2419 DO j = bo(1, 2), bo(2, 2)
2420 DO i = bo(1, 1), bo(2, 1)
2421 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2422 deriv_data(i, j, k)*rho1a(i, j, k)
2423 END DO
2424 END DO
2425 END DO
2426 END IF
2427 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob])
2428 IF (ASSOCIATED(deriv_att)) THEN
2429 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2430!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2431!$OMP SHARED(bo,v_xc,deriv_data,rho1b,fac) COLLAPSE(3)
2432 DO k = bo(1, 3), bo(2, 3)
2433 DO j = bo(1, 2), bo(2, 2)
2434 DO i = bo(1, 1), bo(2, 1)
2435 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2436 deriv_data(i, j, k)*rho1b(i, j, k)
2437 END DO
2438 END DO
2439 END DO
2440 END IF
2441 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_norm_drho])
2442 IF (ASSOCIATED(deriv_att)) THEN
2443 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2444!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2445!$OMP SHARED(bo,v_xc,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
2446 DO k = bo(1, 3), bo(2, 3)
2447 DO j = bo(1, 2), bo(2, 2)
2448 DO i = bo(1, 1), bo(2, 1)
2449 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2450 deriv_data(i, j, k)*dr1dr(i, j, k)
2451 END DO
2452 END DO
2453 END DO
2454 END IF
2455 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_norm_drhoa])
2456 IF (ASSOCIATED(deriv_att)) THEN
2457 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2458!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2459!$OMP SHARED(bo,v_xc,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
2460 DO k = bo(1, 3), bo(2, 3)
2461 DO j = bo(1, 2), bo(2, 2)
2462 DO i = bo(1, 1), bo(2, 1)
2463 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2464 deriv_data(i, j, k)*dra1dra(i, j, k)
2465 END DO
2466 END DO
2467 END DO
2468 END IF
2469 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_norm_drhob])
2470 IF (ASSOCIATED(deriv_att)) THEN
2471 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2472!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2473!$OMP SHARED(bo,v_xc,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
2474 DO k = bo(1, 3), bo(2, 3)
2475 DO j = bo(1, 2), bo(2, 2)
2476 DO i = bo(1, 1), bo(2, 1)
2477 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2478 deriv_data(i, j, k)*drb1drb(i, j, k)
2479 END DO
2480 END DO
2481 END DO
2482 END IF
2483 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_tau_a])
2484 IF (ASSOCIATED(deriv_att)) THEN
2485 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2486!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2487!$OMP SHARED(bo,v_xc,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
2488 DO k = bo(1, 3), bo(2, 3)
2489 DO j = bo(1, 2), bo(2, 2)
2490 DO i = bo(1, 1), bo(2, 1)
2491 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2492 deriv_data(i, j, k)*tau1a(i, j, k)
2493 END DO
2494 END DO
2495 END DO
2496 END IF
2497 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_tau_b])
2498 IF (ASSOCIATED(deriv_att)) THEN
2499 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2500!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2501!$OMP SHARED(bo,v_xc,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
2502 DO k = bo(1, 3), bo(2, 3)
2503 DO j = bo(1, 2), bo(2, 2)
2504 DO i = bo(1, 1), bo(2, 1)
2505 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2506 deriv_data(i, j, k)*tau1b(i, j, k)
2507 END DO
2508 END DO
2509 END DO
2510 END IF
2511 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_laplace_rhoa])
2512 IF (ASSOCIATED(deriv_att)) THEN
2513 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2514!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2515!$OMP SHARED(bo,v_xc,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
2516 DO k = bo(1, 3), bo(2, 3)
2517 DO j = bo(1, 2), bo(2, 2)
2518 DO i = bo(1, 1), bo(2, 1)
2519 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2520 deriv_data(i, j, k)*laplace1a(i, j, k)
2521 END DO
2522 END DO
2523 END DO
2524 END IF
2525 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_laplace_rhob])
2526 IF (ASSOCIATED(deriv_att)) THEN
2527 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2528!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2529!$OMP SHARED(bo,v_xc,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
2530 DO k = bo(1, 3), bo(2, 3)
2531 DO j = bo(1, 2), bo(2, 2)
2532 DO i = bo(1, 1), bo(2, 1)
2533 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
2534 deriv_data(i, j, k)*laplace1b(i, j, k)
2535 END DO
2536 END DO
2537 END DO
2538 END IF
2539
2540
2541 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhoa])
2542 IF (ASSOCIATED(deriv_att)) THEN
2543 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2544!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2545!$OMP SHARED(bo,v_drho,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
2546 DO k = bo(1, 3), bo(2, 3)
2547 DO j = bo(1, 2), bo(2, 2)
2548 DO i = bo(1, 1), bo(2, 1)
2549 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2550 deriv_data(i, j, k)*rho1a(i, j, k)
2551 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2552 deriv_data(i, j, k)*rho1a(i, j, k)
2553 END DO
2554 END DO
2555 END DO
2556 END IF
2557 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhob])
2558 IF (ASSOCIATED(deriv_att)) THEN
2559 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2560!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2561!$OMP SHARED(bo,v_drho,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
2562 DO k = bo(1, 3), bo(2, 3)
2563 DO j = bo(1, 2), bo(2, 2)
2564 DO i = bo(1, 1), bo(2, 1)
2565 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2566 deriv_data(i, j, k)*rho1b(i, j, k)
2567 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2568 deriv_data(i, j, k)*rho1b(i, j, k)
2569 END DO
2570 END DO
2571 END DO
2572 END IF
2573 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drho])
2574 IF (ASSOCIATED(deriv_att)) THEN
2575 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2576!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2577!$OMP SHARED(bo,v_drho,deriv_data,dr1dr,fac) COLLAPSE(3)
2578 DO k = bo(1, 3), bo(2, 3)
2579 DO j = bo(1, 2), bo(2, 2)
2580 DO i = bo(1, 1), bo(2, 1)
2581 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2582 deriv_data(i, j, k)*dr1dr(i, j, k)
2583 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2584 deriv_data(i, j, k)*dr1dr(i, j, k)
2585 END DO
2586 END DO
2587 END DO
2588 END IF
2589 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhoa])
2590 IF (ASSOCIATED(deriv_att)) THEN
2591 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2592!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2593!$OMP SHARED(bo,v_drho,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
2594 DO k = bo(1, 3), bo(2, 3)
2595 DO j = bo(1, 2), bo(2, 2)
2596 DO i = bo(1, 1), bo(2, 1)
2597 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2598 deriv_data(i, j, k)*dra1dra(i, j, k)
2599 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2600 deriv_data(i, j, k)*dra1dra(i, j, k)
2601 END DO
2602 END DO
2603 END DO
2604 END IF
2605 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhob])
2606 IF (ASSOCIATED(deriv_att)) THEN
2607 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2608!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2609!$OMP SHARED(bo,v_drho,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
2610 DO k = bo(1, 3), bo(2, 3)
2611 DO j = bo(1, 2), bo(2, 2)
2612 DO i = bo(1, 1), bo(2, 1)
2613 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2614 deriv_data(i, j, k)*drb1drb(i, j, k)
2615 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2616 deriv_data(i, j, k)*drb1drb(i, j, k)
2617 END DO
2618 END DO
2619 END DO
2620 END IF
2621 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau_a])
2622 IF (ASSOCIATED(deriv_att)) THEN
2623 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2624!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2625!$OMP SHARED(bo,v_drho,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
2626 DO k = bo(1, 3), bo(2, 3)
2627 DO j = bo(1, 2), bo(2, 2)
2628 DO i = bo(1, 1), bo(2, 1)
2629 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2630 deriv_data(i, j, k)*tau1a(i, j, k)
2631 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2632 deriv_data(i, j, k)*tau1a(i, j, k)
2633 END DO
2634 END DO
2635 END DO
2636 END IF
2637 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau_b])
2638 IF (ASSOCIATED(deriv_att)) THEN
2639 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2640!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2641!$OMP SHARED(bo,v_drho,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
2642 DO k = bo(1, 3), bo(2, 3)
2643 DO j = bo(1, 2), bo(2, 2)
2644 DO i = bo(1, 1), bo(2, 1)
2645 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2646 deriv_data(i, j, k)*tau1b(i, j, k)
2647 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2648 deriv_data(i, j, k)*tau1b(i, j, k)
2649 END DO
2650 END DO
2651 END DO
2652 END IF
2654 IF (ASSOCIATED(deriv_att)) THEN
2655 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2656!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2657!$OMP SHARED(bo,v_drho,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
2658 DO k = bo(1, 3), bo(2, 3)
2659 DO j = bo(1, 2), bo(2, 2)
2660 DO i = bo(1, 1), bo(2, 1)
2661 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2662 deriv_data(i, j, k)*laplace1a(i, j, k)
2663 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2664 deriv_data(i, j, k)*laplace1a(i, j, k)
2665 END DO
2666 END DO
2667 END DO
2668 END IF
2670 IF (ASSOCIATED(deriv_att)) THEN
2671 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2672!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2673!$OMP SHARED(bo,v_drho,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
2674 DO k = bo(1, 3), bo(2, 3)
2675 DO j = bo(1, 2), bo(2, 2)
2676 DO i = bo(1, 1), bo(2, 1)
2677 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
2678 deriv_data(i, j, k)*laplace1b(i, j, k)
2679 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
2680 deriv_data(i, j, k)*laplace1b(i, j, k)
2681 END DO
2682 END DO
2683 END DO
2684 END IF
2685
2686 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
2687 IF (ASSOCIATED(deriv_att)) THEN
2688 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2689 CALL xc_derivative_get(deriv_att, deriv_data=e_drho)
2690
2691 IF (my_compute_virial) THEN
2692 CALL virial_drho_drho1(virial_pw, drho, drho1, deriv_data, virial_xc)
2693 END IF ! my_compute_virial
2694
2695!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dr1dr,gradient_cut,norm_drho,v_drho,deriv_data)
2696 v_drho(1)%array(:, :, :) = v_drho(1)%array(:, :, :) + &
2697 deriv_data(:, :, :)*dr1dr(:, :, :)/max(gradient_cut, norm_drho(:, :, :))**2
2698 v_drho(2)%array(:, :, :) = v_drho(2)%array(:, :, :) + &
2699 deriv_data(:, :, :)*dr1dr(:, :, :)/max(gradient_cut, norm_drho(:, :, :))**2
2700!$OMP END PARALLEL WORKSHARE
2701 END IF
2702
2703 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhoa])
2704 IF (ASSOCIATED(deriv_att)) THEN
2705 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2706!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2707!$OMP SHARED(bo,v_drhoa,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
2708 DO k = bo(1, 3), bo(2, 3)
2709 DO j = bo(1, 2), bo(2, 2)
2710 DO i = bo(1, 1), bo(2, 1)
2711 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2712 deriv_data(i, j, k)*rho1a(i, j, k)
2713 END DO
2714 END DO
2715 END DO
2716 END IF
2717 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhob])
2718 IF (ASSOCIATED(deriv_att)) THEN
2719 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2720!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2721!$OMP SHARED(bo,v_drhoa,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
2722 DO k = bo(1, 3), bo(2, 3)
2723 DO j = bo(1, 2), bo(2, 2)
2724 DO i = bo(1, 1), bo(2, 1)
2725 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2726 deriv_data(i, j, k)*rho1b(i, j, k)
2727 END DO
2728 END DO
2729 END DO
2730 END IF
2731 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drho])
2732 IF (ASSOCIATED(deriv_att)) THEN
2733 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2734!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2735!$OMP SHARED(bo,v_drhoa,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
2736 DO k = bo(1, 3), bo(2, 3)
2737 DO j = bo(1, 2), bo(2, 2)
2738 DO i = bo(1, 1), bo(2, 1)
2739 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2740 deriv_data(i, j, k)*dr1dr(i, j, k)
2741 END DO
2742 END DO
2743 END DO
2744 END IF
2745 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhoa])
2746 IF (ASSOCIATED(deriv_att)) THEN
2747 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2748!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2749!$OMP SHARED(bo,v_drhoa,deriv_data,dra1dra,fac) COLLAPSE(3)
2750 DO k = bo(1, 3), bo(2, 3)
2751 DO j = bo(1, 2), bo(2, 2)
2752 DO i = bo(1, 1), bo(2, 1)
2753 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2754 deriv_data(i, j, k)*dra1dra(i, j, k)
2755 END DO
2756 END DO
2757 END DO
2758 END IF
2759 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhob])
2760 IF (ASSOCIATED(deriv_att)) THEN
2761 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2762!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2763!$OMP SHARED(bo,v_drhoa,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
2764 DO k = bo(1, 3), bo(2, 3)
2765 DO j = bo(1, 2), bo(2, 2)
2766 DO i = bo(1, 1), bo(2, 1)
2767 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2768 deriv_data(i, j, k)*drb1drb(i, j, k)
2769 END DO
2770 END DO
2771 END DO
2772 END IF
2773 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_tau_a])
2774 IF (ASSOCIATED(deriv_att)) THEN
2775 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2776!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2777!$OMP SHARED(bo,v_drhoa,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
2778 DO k = bo(1, 3), bo(2, 3)
2779 DO j = bo(1, 2), bo(2, 2)
2780 DO i = bo(1, 1), bo(2, 1)
2781 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2782 deriv_data(i, j, k)*tau1a(i, j, k)
2783 END DO
2784 END DO
2785 END DO
2786 END IF
2787 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_tau_b])
2788 IF (ASSOCIATED(deriv_att)) THEN
2789 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2790!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2791!$OMP SHARED(bo,v_drhoa,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
2792 DO k = bo(1, 3), bo(2, 3)
2793 DO j = bo(1, 2), bo(2, 2)
2794 DO i = bo(1, 1), bo(2, 1)
2795 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2796 deriv_data(i, j, k)*tau1b(i, j, k)
2797 END DO
2798 END DO
2799 END DO
2800 END IF
2802 IF (ASSOCIATED(deriv_att)) THEN
2803 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2804!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2805!$OMP SHARED(bo,v_drhoa,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
2806 DO k = bo(1, 3), bo(2, 3)
2807 DO j = bo(1, 2), bo(2, 2)
2808 DO i = bo(1, 1), bo(2, 1)
2809 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2810 deriv_data(i, j, k)*laplace1a(i, j, k)
2811 END DO
2812 END DO
2813 END DO
2814 END IF
2816 IF (ASSOCIATED(deriv_att)) THEN
2817 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2818!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2819!$OMP SHARED(bo,v_drhoa,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
2820 DO k = bo(1, 3), bo(2, 3)
2821 DO j = bo(1, 2), bo(2, 2)
2822 DO i = bo(1, 1), bo(2, 1)
2823 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
2824 deriv_data(i, j, k)*laplace1b(i, j, k)
2825 END DO
2826 END DO
2827 END DO
2828 END IF
2829
2830 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa])
2831 IF (ASSOCIATED(deriv_att)) THEN
2832 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2833 CALL xc_derivative_get(deriv_att, deriv_data=e_drhoa)
2834
2835 IF (my_compute_virial) THEN
2836 CALL virial_drho_drho1(virial_pw, drhoa, drho1a, deriv_data, virial_xc)
2837 END IF ! my_compute_virial
2838
2839!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dra1dra,gradient_cut,norm_drhoa,v_drhoa,deriv_data)
2840 v_drhoa(1)%array(:, :, :) = v_drhoa(1)%array(:, :, :) + &
2841 deriv_data(:, :, :)*dra1dra(:, :, :)/max(gradient_cut, norm_drhoa(:, :, :))**2
2842!$OMP END PARALLEL WORKSHARE
2843 END IF
2844
2845 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhoa])
2846 IF (ASSOCIATED(deriv_att)) THEN
2847 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2848!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2849!$OMP SHARED(bo,v_drhob,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
2850 DO k = bo(1, 3), bo(2, 3)
2851 DO j = bo(1, 2), bo(2, 2)
2852 DO i = bo(1, 1), bo(2, 1)
2853 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2854 deriv_data(i, j, k)*rho1a(i, j, k)
2855 END DO
2856 END DO
2857 END DO
2858 END IF
2859 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhob])
2860 IF (ASSOCIATED(deriv_att)) THEN
2861 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2862!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2863!$OMP SHARED(bo,v_drhob,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
2864 DO k = bo(1, 3), bo(2, 3)
2865 DO j = bo(1, 2), bo(2, 2)
2866 DO i = bo(1, 1), bo(2, 1)
2867 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2868 deriv_data(i, j, k)*rho1b(i, j, k)
2869 END DO
2870 END DO
2871 END DO
2872 END IF
2873 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_norm_drho])
2874 IF (ASSOCIATED(deriv_att)) THEN
2875 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2876!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2877!$OMP SHARED(bo,v_drhob,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
2878 DO k = bo(1, 3), bo(2, 3)
2879 DO j = bo(1, 2), bo(2, 2)
2880 DO i = bo(1, 1), bo(2, 1)
2881 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2882 deriv_data(i, j, k)*dr1dr(i, j, k)
2883 END DO
2884 END DO
2885 END DO
2886 END IF
2887 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_norm_drhoa])
2888 IF (ASSOCIATED(deriv_att)) THEN
2889 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2890!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2891!$OMP SHARED(bo,v_drhob,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
2892 DO k = bo(1, 3), bo(2, 3)
2893 DO j = bo(1, 2), bo(2, 2)
2894 DO i = bo(1, 1), bo(2, 1)
2895 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2896 deriv_data(i, j, k)*dra1dra(i, j, k)
2897 END DO
2898 END DO
2899 END DO
2900 END IF
2901 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_norm_drhob])
2902 IF (ASSOCIATED(deriv_att)) THEN
2903 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2904!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2905!$OMP SHARED(bo,v_drhob,deriv_data,drb1drb,fac) COLLAPSE(3)
2906 DO k = bo(1, 3), bo(2, 3)
2907 DO j = bo(1, 2), bo(2, 2)
2908 DO i = bo(1, 1), bo(2, 1)
2909 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2910 deriv_data(i, j, k)*drb1drb(i, j, k)
2911 END DO
2912 END DO
2913 END DO
2914 END IF
2915 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_tau_a])
2916 IF (ASSOCIATED(deriv_att)) THEN
2917 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2918!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2919!$OMP SHARED(bo,v_drhob,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
2920 DO k = bo(1, 3), bo(2, 3)
2921 DO j = bo(1, 2), bo(2, 2)
2922 DO i = bo(1, 1), bo(2, 1)
2923 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2924 deriv_data(i, j, k)*tau1a(i, j, k)
2925 END DO
2926 END DO
2927 END DO
2928 END IF
2929 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_tau_b])
2930 IF (ASSOCIATED(deriv_att)) THEN
2931 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2932!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2933!$OMP SHARED(bo,v_drhob,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
2934 DO k = bo(1, 3), bo(2, 3)
2935 DO j = bo(1, 2), bo(2, 2)
2936 DO i = bo(1, 1), bo(2, 1)
2937 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2938 deriv_data(i, j, k)*tau1b(i, j, k)
2939 END DO
2940 END DO
2941 END DO
2942 END IF
2944 IF (ASSOCIATED(deriv_att)) THEN
2945 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2946!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2947!$OMP SHARED(bo,v_drhob,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
2948 DO k = bo(1, 3), bo(2, 3)
2949 DO j = bo(1, 2), bo(2, 2)
2950 DO i = bo(1, 1), bo(2, 1)
2951 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2952 deriv_data(i, j, k)*laplace1a(i, j, k)
2953 END DO
2954 END DO
2955 END DO
2956 END IF
2958 IF (ASSOCIATED(deriv_att)) THEN
2959 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2960!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2961!$OMP SHARED(bo,v_drhob,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
2962 DO k = bo(1, 3), bo(2, 3)
2963 DO j = bo(1, 2), bo(2, 2)
2964 DO i = bo(1, 1), bo(2, 1)
2965 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
2966 deriv_data(i, j, k)*laplace1b(i, j, k)
2967 END DO
2968 END DO
2969 END DO
2970 END IF
2971
2972 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob])
2973 IF (ASSOCIATED(deriv_att)) THEN
2974 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2975 CALL xc_derivative_get(deriv_att, deriv_data=e_drhob)
2976
2977 IF (my_compute_virial) THEN
2978 CALL virial_drho_drho1(virial_pw, drhob, drho1b, deriv_data, virial_xc)
2979 END IF ! my_compute_virial
2980
2981!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(drb1drb,gradient_cut,norm_drhob,v_drhob,deriv_data)
2982 v_drhob(2)%array(:, :, :) = v_drhob(2)%array(:, :, :) + &
2983 deriv_data(:, :, :)*drb1drb(:, :, :)/max(gradient_cut, norm_drhob(:, :, :))**2
2984!$OMP END PARALLEL WORKSHARE
2985 END IF
2986
2987 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_rhoa])
2988 IF (ASSOCIATED(deriv_att)) THEN
2989 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
2990!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
2991!$OMP SHARED(bo,v_xc_tau,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
2992 DO k = bo(1, 3), bo(2, 3)
2993 DO j = bo(1, 2), bo(2, 2)
2994 DO i = bo(1, 1), bo(2, 1)
2995 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
2996 deriv_data(i, j, k)*rho1a(i, j, k)
2997 END DO
2998 END DO
2999 END DO
3000 END IF
3001 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_rhob])
3002 IF (ASSOCIATED(deriv_att)) THEN
3003 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3004!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3005!$OMP SHARED(bo,v_xc_tau,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
3006 DO k = bo(1, 3), bo(2, 3)
3007 DO j = bo(1, 2), bo(2, 2)
3008 DO i = bo(1, 1), bo(2, 1)
3009 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3010 deriv_data(i, j, k)*rho1b(i, j, k)
3011 END DO
3012 END DO
3013 END DO
3014 END IF
3015 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_norm_drho])
3016 IF (ASSOCIATED(deriv_att)) THEN
3017 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3018!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3019!$OMP SHARED(bo,v_xc_tau,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
3020 DO k = bo(1, 3), bo(2, 3)
3021 DO j = bo(1, 2), bo(2, 2)
3022 DO i = bo(1, 1), bo(2, 1)
3023 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3024 deriv_data(i, j, k)*dr1dr(i, j, k)
3025 END DO
3026 END DO
3027 END DO
3028 END IF
3029 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_norm_drhoa])
3030 IF (ASSOCIATED(deriv_att)) THEN
3031 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3032!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3033!$OMP SHARED(bo,v_xc_tau,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
3034 DO k = bo(1, 3), bo(2, 3)
3035 DO j = bo(1, 2), bo(2, 2)
3036 DO i = bo(1, 1), bo(2, 1)
3037 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3038 deriv_data(i, j, k)*dra1dra(i, j, k)
3039 END DO
3040 END DO
3041 END DO
3042 END IF
3043 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_norm_drhob])
3044 IF (ASSOCIATED(deriv_att)) THEN
3045 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3046!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3047!$OMP SHARED(bo,v_xc_tau,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
3048 DO k = bo(1, 3), bo(2, 3)
3049 DO j = bo(1, 2), bo(2, 2)
3050 DO i = bo(1, 1), bo(2, 1)
3051 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3052 deriv_data(i, j, k)*drb1drb(i, j, k)
3053 END DO
3054 END DO
3055 END DO
3056 END IF
3057 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_tau_a])
3058 IF (ASSOCIATED(deriv_att)) THEN
3059 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3060!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3061!$OMP SHARED(bo,v_xc_tau,deriv_data,tau1a,fac) COLLAPSE(3)
3062 DO k = bo(1, 3), bo(2, 3)
3063 DO j = bo(1, 2), bo(2, 2)
3064 DO i = bo(1, 1), bo(2, 1)
3065 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3066 deriv_data(i, j, k)*tau1a(i, j, k)
3067 END DO
3068 END DO
3069 END DO
3070 END IF
3071 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_tau_b])
3072 IF (ASSOCIATED(deriv_att)) THEN
3073 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3074!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3075!$OMP SHARED(bo,v_xc_tau,deriv_data,tau1b,fac) COLLAPSE(3)
3076 DO k = bo(1, 3), bo(2, 3)
3077 DO j = bo(1, 2), bo(2, 2)
3078 DO i = bo(1, 1), bo(2, 1)
3079 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3080 deriv_data(i, j, k)*tau1b(i, j, k)
3081 END DO
3082 END DO
3083 END DO
3084 END IF
3085 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_laplace_rhoa])
3086 IF (ASSOCIATED(deriv_att)) THEN
3087 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3088!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3089!$OMP SHARED(bo,v_xc_tau,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
3090 DO k = bo(1, 3), bo(2, 3)
3091 DO j = bo(1, 2), bo(2, 2)
3092 DO i = bo(1, 1), bo(2, 1)
3093 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3094 deriv_data(i, j, k)*laplace1a(i, j, k)
3095 END DO
3096 END DO
3097 END DO
3098 END IF
3099 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_laplace_rhob])
3100 IF (ASSOCIATED(deriv_att)) THEN
3101 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3102!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3103!$OMP SHARED(bo,v_xc_tau,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
3104 DO k = bo(1, 3), bo(2, 3)
3105 DO j = bo(1, 2), bo(2, 2)
3106 DO i = bo(1, 1), bo(2, 1)
3107 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3108 deriv_data(i, j, k)*laplace1b(i, j, k)
3109 END DO
3110 END DO
3111 END DO
3112 END IF
3113
3114
3115 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_rhoa])
3116 IF (ASSOCIATED(deriv_att)) THEN
3117 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3118!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3119!$OMP SHARED(bo,v_xc_tau,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
3120 DO k = bo(1, 3), bo(2, 3)
3121 DO j = bo(1, 2), bo(2, 2)
3122 DO i = bo(1, 1), bo(2, 1)
3123 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3124 deriv_data(i, j, k)*rho1a(i, j, k)
3125 END DO
3126 END DO
3127 END DO
3128 END IF
3129 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_rhob])
3130 IF (ASSOCIATED(deriv_att)) THEN
3131 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3132!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3133!$OMP SHARED(bo,v_xc_tau,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
3134 DO k = bo(1, 3), bo(2, 3)
3135 DO j = bo(1, 2), bo(2, 2)
3136 DO i = bo(1, 1), bo(2, 1)
3137 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3138 deriv_data(i, j, k)*rho1b(i, j, k)
3139 END DO
3140 END DO
3141 END DO
3142 END IF
3143 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_norm_drho])
3144 IF (ASSOCIATED(deriv_att)) THEN
3145 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3146!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3147!$OMP SHARED(bo,v_xc_tau,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
3148 DO k = bo(1, 3), bo(2, 3)
3149 DO j = bo(1, 2), bo(2, 2)
3150 DO i = bo(1, 1), bo(2, 1)
3151 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3152 deriv_data(i, j, k)*dr1dr(i, j, k)
3153 END DO
3154 END DO
3155 END DO
3156 END IF
3157 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_norm_drhoa])
3158 IF (ASSOCIATED(deriv_att)) THEN
3159 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3160!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3161!$OMP SHARED(bo,v_xc_tau,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
3162 DO k = bo(1, 3), bo(2, 3)
3163 DO j = bo(1, 2), bo(2, 2)
3164 DO i = bo(1, 1), bo(2, 1)
3165 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3166 deriv_data(i, j, k)*dra1dra(i, j, k)
3167 END DO
3168 END DO
3169 END DO
3170 END IF
3171 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_norm_drhob])
3172 IF (ASSOCIATED(deriv_att)) THEN
3173 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3174!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3175!$OMP SHARED(bo,v_xc_tau,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
3176 DO k = bo(1, 3), bo(2, 3)
3177 DO j = bo(1, 2), bo(2, 2)
3178 DO i = bo(1, 1), bo(2, 1)
3179 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3180 deriv_data(i, j, k)*drb1drb(i, j, k)
3181 END DO
3182 END DO
3183 END DO
3184 END IF
3185 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_tau_a])
3186 IF (ASSOCIATED(deriv_att)) THEN
3187 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3188!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3189!$OMP SHARED(bo,v_xc_tau,deriv_data,tau1a,fac) COLLAPSE(3)
3190 DO k = bo(1, 3), bo(2, 3)
3191 DO j = bo(1, 2), bo(2, 2)
3192 DO i = bo(1, 1), bo(2, 1)
3193 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3194 deriv_data(i, j, k)*tau1a(i, j, k)
3195 END DO
3196 END DO
3197 END DO
3198 END IF
3199 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_tau_b])
3200 IF (ASSOCIATED(deriv_att)) THEN
3201 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3202!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3203!$OMP SHARED(bo,v_xc_tau,deriv_data,tau1b,fac) COLLAPSE(3)
3204 DO k = bo(1, 3), bo(2, 3)
3205 DO j = bo(1, 2), bo(2, 2)
3206 DO i = bo(1, 1), bo(2, 1)
3207 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3208 deriv_data(i, j, k)*tau1b(i, j, k)
3209 END DO
3210 END DO
3211 END DO
3212 END IF
3213 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_laplace_rhoa])
3214 IF (ASSOCIATED(deriv_att)) THEN
3215 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3216!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3217!$OMP SHARED(bo,v_xc_tau,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
3218 DO k = bo(1, 3), bo(2, 3)
3219 DO j = bo(1, 2), bo(2, 2)
3220 DO i = bo(1, 1), bo(2, 1)
3221 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3222 deriv_data(i, j, k)*laplace1a(i, j, k)
3223 END DO
3224 END DO
3225 END DO
3226 END IF
3227 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b, deriv_laplace_rhob])
3228 IF (ASSOCIATED(deriv_att)) THEN
3229 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3230!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3231!$OMP SHARED(bo,v_xc_tau,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
3232 DO k = bo(1, 3), bo(2, 3)
3233 DO j = bo(1, 2), bo(2, 2)
3234 DO i = bo(1, 1), bo(2, 1)
3235 v_xc_tau(2)%array(i, j, k) = v_xc_tau(2)%array(i, j, k) + &
3236 deriv_data(i, j, k)*laplace1b(i, j, k)
3237 END DO
3238 END DO
3239 END DO
3240 END IF
3241
3242
3243 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_rhoa])
3244 IF (ASSOCIATED(deriv_att)) THEN
3245 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3246!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3247!$OMP SHARED(bo,v_laplace,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
3248 DO k = bo(1, 3), bo(2, 3)
3249 DO j = bo(1, 2), bo(2, 2)
3250 DO i = bo(1, 1), bo(2, 1)
3251 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3252 deriv_data(i, j, k)*rho1a(i, j, k)
3253 END DO
3254 END DO
3255 END DO
3256 END IF
3257 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_rhob])
3258 IF (ASSOCIATED(deriv_att)) THEN
3259 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3260!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3261!$OMP SHARED(bo,v_laplace,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
3262 DO k = bo(1, 3), bo(2, 3)
3263 DO j = bo(1, 2), bo(2, 2)
3264 DO i = bo(1, 1), bo(2, 1)
3265 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3266 deriv_data(i, j, k)*rho1b(i, j, k)
3267 END DO
3268 END DO
3269 END DO
3270 END IF
3272 IF (ASSOCIATED(deriv_att)) THEN
3273 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3274!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3275!$OMP SHARED(bo,v_laplace,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
3276 DO k = bo(1, 3), bo(2, 3)
3277 DO j = bo(1, 2), bo(2, 2)
3278 DO i = bo(1, 1), bo(2, 1)
3279 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3280 deriv_data(i, j, k)*dr1dr(i, j, k)
3281 END DO
3282 END DO
3283 END DO
3284 END IF
3286 IF (ASSOCIATED(deriv_att)) THEN
3287 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3288!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3289!$OMP SHARED(bo,v_laplace,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
3290 DO k = bo(1, 3), bo(2, 3)
3291 DO j = bo(1, 2), bo(2, 2)
3292 DO i = bo(1, 1), bo(2, 1)
3293 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3294 deriv_data(i, j, k)*dra1dra(i, j, k)
3295 END DO
3296 END DO
3297 END DO
3298 END IF
3300 IF (ASSOCIATED(deriv_att)) THEN
3301 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3302!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3303!$OMP SHARED(bo,v_laplace,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
3304 DO k = bo(1, 3), bo(2, 3)
3305 DO j = bo(1, 2), bo(2, 2)
3306 DO i = bo(1, 1), bo(2, 1)
3307 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3308 deriv_data(i, j, k)*drb1drb(i, j, k)
3309 END DO
3310 END DO
3311 END DO
3312 END IF
3313 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_tau_a])
3314 IF (ASSOCIATED(deriv_att)) THEN
3315 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3316!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3317!$OMP SHARED(bo,v_laplace,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
3318 DO k = bo(1, 3), bo(2, 3)
3319 DO j = bo(1, 2), bo(2, 2)
3320 DO i = bo(1, 1), bo(2, 1)
3321 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3322 deriv_data(i, j, k)*tau1a(i, j, k)
3323 END DO
3324 END DO
3325 END DO
3326 END IF
3327 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_tau_b])
3328 IF (ASSOCIATED(deriv_att)) THEN
3329 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3330!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3331!$OMP SHARED(bo,v_laplace,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
3332 DO k = bo(1, 3), bo(2, 3)
3333 DO j = bo(1, 2), bo(2, 2)
3334 DO i = bo(1, 1), bo(2, 1)
3335 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3336 deriv_data(i, j, k)*tau1b(i, j, k)
3337 END DO
3338 END DO
3339 END DO
3340 END IF
3342 IF (ASSOCIATED(deriv_att)) THEN
3343 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3344!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3345!$OMP SHARED(bo,v_laplace,deriv_data,laplace1a,fac) COLLAPSE(3)
3346 DO k = bo(1, 3), bo(2, 3)
3347 DO j = bo(1, 2), bo(2, 2)
3348 DO i = bo(1, 1), bo(2, 1)
3349 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3350 deriv_data(i, j, k)*laplace1a(i, j, k)
3351 END DO
3352 END DO
3353 END DO
3354 END IF
3356 IF (ASSOCIATED(deriv_att)) THEN
3357 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3358!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3359!$OMP SHARED(bo,v_laplace,deriv_data,laplace1b,fac) COLLAPSE(3)
3360 DO k = bo(1, 3), bo(2, 3)
3361 DO j = bo(1, 2), bo(2, 2)
3362 DO i = bo(1, 1), bo(2, 1)
3363 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
3364 deriv_data(i, j, k)*laplace1b(i, j, k)
3365 END DO
3366 END DO
3367 END DO
3368 END IF
3369
3370
3371 IF (my_compute_virial) THEN
3372 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa])
3373 IF (ASSOCIATED(deriv_att)) THEN
3374 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3375
3376 virial_pw%array(:, :, :) = -rho1a(:, :, :)
3377 CALL virial_laplace(virial_pw, pw_pool, virial_xc, deriv_data)
3378 END IF
3379 END IF ! my_compute_virial
3380 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob, deriv_rhoa])
3381 IF (ASSOCIATED(deriv_att)) THEN
3382 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3383!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3384!$OMP SHARED(bo,v_laplace,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
3385 DO k = bo(1, 3), bo(2, 3)
3386 DO j = bo(1, 2), bo(2, 2)
3387 DO i = bo(1, 1), bo(2, 1)
3388 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3389 deriv_data(i, j, k)*rho1a(i, j, k)
3390 END DO
3391 END DO
3392 END DO
3393 END IF
3394 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob, deriv_rhob])
3395 IF (ASSOCIATED(deriv_att)) THEN
3396 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3397!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3398!$OMP SHARED(bo,v_laplace,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
3399 DO k = bo(1, 3), bo(2, 3)
3400 DO j = bo(1, 2), bo(2, 2)
3401 DO i = bo(1, 1), bo(2, 1)
3402 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3403 deriv_data(i, j, k)*rho1b(i, j, k)
3404 END DO
3405 END DO
3406 END DO
3407 END IF
3409 IF (ASSOCIATED(deriv_att)) THEN
3410 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3411!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3412!$OMP SHARED(bo,v_laplace,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
3413 DO k = bo(1, 3), bo(2, 3)
3414 DO j = bo(1, 2), bo(2, 2)
3415 DO i = bo(1, 1), bo(2, 1)
3416 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3417 deriv_data(i, j, k)*dr1dr(i, j, k)
3418 END DO
3419 END DO
3420 END DO
3421 END IF
3423 IF (ASSOCIATED(deriv_att)) THEN
3424 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3425!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3426!$OMP SHARED(bo,v_laplace,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
3427 DO k = bo(1, 3), bo(2, 3)
3428 DO j = bo(1, 2), bo(2, 2)
3429 DO i = bo(1, 1), bo(2, 1)
3430 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3431 deriv_data(i, j, k)*dra1dra(i, j, k)
3432 END DO
3433 END DO
3434 END DO
3435 END IF
3437 IF (ASSOCIATED(deriv_att)) THEN
3438 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3439!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3440!$OMP SHARED(bo,v_laplace,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
3441 DO k = bo(1, 3), bo(2, 3)
3442 DO j = bo(1, 2), bo(2, 2)
3443 DO i = bo(1, 1), bo(2, 1)
3444 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3445 deriv_data(i, j, k)*drb1drb(i, j, k)
3446 END DO
3447 END DO
3448 END DO
3449 END IF
3450 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob, deriv_tau_a])
3451 IF (ASSOCIATED(deriv_att)) THEN
3452 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3453!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3454!$OMP SHARED(bo,v_laplace,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
3455 DO k = bo(1, 3), bo(2, 3)
3456 DO j = bo(1, 2), bo(2, 2)
3457 DO i = bo(1, 1), bo(2, 1)
3458 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3459 deriv_data(i, j, k)*tau1a(i, j, k)
3460 END DO
3461 END DO
3462 END DO
3463 END IF
3464 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob, deriv_tau_b])
3465 IF (ASSOCIATED(deriv_att)) THEN
3466 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3467!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3468!$OMP SHARED(bo,v_laplace,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
3469 DO k = bo(1, 3), bo(2, 3)
3470 DO j = bo(1, 2), bo(2, 2)
3471 DO i = bo(1, 1), bo(2, 1)
3472 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3473 deriv_data(i, j, k)*tau1b(i, j, k)
3474 END DO
3475 END DO
3476 END DO
3477 END IF
3479 IF (ASSOCIATED(deriv_att)) THEN
3480 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3481!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3482!$OMP SHARED(bo,v_laplace,deriv_data,laplace1a,fac) COLLAPSE(3)
3483 DO k = bo(1, 3), bo(2, 3)
3484 DO j = bo(1, 2), bo(2, 2)
3485 DO i = bo(1, 1), bo(2, 1)
3486 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3487 deriv_data(i, j, k)*laplace1a(i, j, k)
3488 END DO
3489 END DO
3490 END DO
3491 END IF
3493 IF (ASSOCIATED(deriv_att)) THEN
3494 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3495!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3496!$OMP SHARED(bo,v_laplace,deriv_data,laplace1b,fac) COLLAPSE(3)
3497 DO k = bo(1, 3), bo(2, 3)
3498 DO j = bo(1, 2), bo(2, 2)
3499 DO i = bo(1, 1), bo(2, 1)
3500 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
3501 deriv_data(i, j, k)*laplace1b(i, j, k)
3502 END DO
3503 END DO
3504 END DO
3505 END IF
3506
3507
3508 IF (my_compute_virial) THEN
3509 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhob])
3510 IF (ASSOCIATED(deriv_att)) THEN
3511 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3512
3513 virial_pw%array(:, :, :) = -rho1b(:, :, :)
3514 CALL virial_laplace(virial_pw, pw_pool, virial_xc, deriv_data)
3515 END IF
3516 END IF ! my_compute_virial
3517
3518
3519 ELSE
3520
3521 ! Compute (fxc^{\alpha\alpha}+-fxc^{\beta\beta})*\rho(1) over the grid points
3522 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa])
3523 IF (ASSOCIATED(deriv_att)) THEN
3524 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3525!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3526!$OMP SHARED(bo,v_xc,deriv_data,rho1a,fac) COLLAPSE(3)
3527 DO k = bo(1, 3), bo(2, 3)
3528 DO j = bo(1, 2), bo(2, 2)
3529 DO i = bo(1, 1), bo(2, 1)
3530 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3531 deriv_data(i, j, k)*rho1a(i, j, k)
3532 END DO
3533 END DO
3534 END DO
3535 END IF
3536 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drho])
3537 IF (ASSOCIATED(deriv_att)) THEN
3538 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3539!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3540!$OMP SHARED(bo,v_xc,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
3541 DO k = bo(1, 3), bo(2, 3)
3542 DO j = bo(1, 2), bo(2, 2)
3543 DO i = bo(1, 1), bo(2, 1)
3544 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3545 deriv_data(i, j, k)*dr1dr(i, j, k)
3546 END DO
3547 END DO
3548 END DO
3549 END IF
3550 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drhoa])
3551 IF (ASSOCIATED(deriv_att)) THEN
3552 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3553!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3554!$OMP SHARED(bo,v_xc,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
3555 DO k = bo(1, 3), bo(2, 3)
3556 DO j = bo(1, 2), bo(2, 2)
3557 DO i = bo(1, 1), bo(2, 1)
3558 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3559 deriv_data(i, j, k)*dra1dra(i, j, k)
3560 END DO
3561 END DO
3562 END DO
3563 END IF
3564 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_tau_a])
3565 IF (ASSOCIATED(deriv_att)) THEN
3566 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3567!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3568!$OMP SHARED(bo,v_xc,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
3569 DO k = bo(1, 3), bo(2, 3)
3570 DO j = bo(1, 2), bo(2, 2)
3571 DO i = bo(1, 1), bo(2, 1)
3572 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3573 deriv_data(i, j, k)*tau1a(i, j, k)
3574 END DO
3575 END DO
3576 END DO
3577 END IF
3578 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_laplace_rhoa])
3579 IF (ASSOCIATED(deriv_att)) THEN
3580 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3581!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3582!$OMP SHARED(bo,v_xc,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
3583 DO k = bo(1, 3), bo(2, 3)
3584 DO j = bo(1, 2), bo(2, 2)
3585 DO i = bo(1, 1), bo(2, 1)
3586 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3587 deriv_data(i, j, k)*laplace1a(i, j, k)
3588 END DO
3589 END DO
3590 END DO
3591 END IF
3592 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhob])
3593 IF (ASSOCIATED(deriv_att)) THEN
3594 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3595!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3596!$OMP SHARED(bo,v_xc,deriv_data,rho1b,fac) COLLAPSE(3)
3597 DO k = bo(1, 3), bo(2, 3)
3598 DO j = bo(1, 2), bo(2, 2)
3599 DO i = bo(1, 1), bo(2, 1)
3600 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3601 fac*deriv_data(i, j, k)*rho1b(i, j, k)
3602 END DO
3603 END DO
3604 END DO
3605 END IF
3606 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drhob])
3607 IF (ASSOCIATED(deriv_att)) THEN
3608 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3609!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3610!$OMP SHARED(bo,v_xc,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
3611 DO k = bo(1, 3), bo(2, 3)
3612 DO j = bo(1, 2), bo(2, 2)
3613 DO i = bo(1, 1), bo(2, 1)
3614 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3615 fac*deriv_data(i, j, k)*drb1drb(i, j, k)
3616 END DO
3617 END DO
3618 END DO
3619 END IF
3620 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_tau_b])
3621 IF (ASSOCIATED(deriv_att)) THEN
3622 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3623!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3624!$OMP SHARED(bo,v_xc,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
3625 DO k = bo(1, 3), bo(2, 3)
3626 DO j = bo(1, 2), bo(2, 2)
3627 DO i = bo(1, 1), bo(2, 1)
3628 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3629 fac*deriv_data(i, j, k)*tau1b(i, j, k)
3630 END DO
3631 END DO
3632 END DO
3633 END IF
3634 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_laplace_rhob])
3635 IF (ASSOCIATED(deriv_att)) THEN
3636 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3637!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3638!$OMP SHARED(bo,v_xc,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
3639 DO k = bo(1, 3), bo(2, 3)
3640 DO j = bo(1, 2), bo(2, 2)
3641 DO i = bo(1, 1), bo(2, 1)
3642 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
3643 fac*deriv_data(i, j, k)*laplace1b(i, j, k)
3644 END DO
3645 END DO
3646 END DO
3647 END IF
3648
3649
3650 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhoa])
3651 IF (ASSOCIATED(deriv_att)) THEN
3652 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3653!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3654!$OMP SHARED(bo,v_drho,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
3655 DO k = bo(1, 3), bo(2, 3)
3656 DO j = bo(1, 2), bo(2, 2)
3657 DO i = bo(1, 1), bo(2, 1)
3658 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3659 deriv_data(i, j, k)*rho1a(i, j, k)
3660 END DO
3661 END DO
3662 END DO
3663 END IF
3664 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drho])
3665 IF (ASSOCIATED(deriv_att)) THEN
3666 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3667!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3668!$OMP SHARED(bo,v_drho,deriv_data,dr1dr,fac) COLLAPSE(3)
3669 DO k = bo(1, 3), bo(2, 3)
3670 DO j = bo(1, 2), bo(2, 2)
3671 DO i = bo(1, 1), bo(2, 1)
3672 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3673 deriv_data(i, j, k)*dr1dr(i, j, k)
3674 END DO
3675 END DO
3676 END DO
3677 END IF
3678 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhoa])
3679 IF (ASSOCIATED(deriv_att)) THEN
3680 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3681!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3682!$OMP SHARED(bo,v_drho,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
3683 DO k = bo(1, 3), bo(2, 3)
3684 DO j = bo(1, 2), bo(2, 2)
3685 DO i = bo(1, 1), bo(2, 1)
3686 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3687 deriv_data(i, j, k)*dra1dra(i, j, k)
3688 END DO
3689 END DO
3690 END DO
3691 END IF
3692 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau_a])
3693 IF (ASSOCIATED(deriv_att)) THEN
3694 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3695!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3696!$OMP SHARED(bo,v_drho,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
3697 DO k = bo(1, 3), bo(2, 3)
3698 DO j = bo(1, 2), bo(2, 2)
3699 DO i = bo(1, 1), bo(2, 1)
3700 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3701 deriv_data(i, j, k)*tau1a(i, j, k)
3702 END DO
3703 END DO
3704 END DO
3705 END IF
3707 IF (ASSOCIATED(deriv_att)) THEN
3708 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3709!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3710!$OMP SHARED(bo,v_drho,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
3711 DO k = bo(1, 3), bo(2, 3)
3712 DO j = bo(1, 2), bo(2, 2)
3713 DO i = bo(1, 1), bo(2, 1)
3714 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3715 deriv_data(i, j, k)*laplace1a(i, j, k)
3716 END DO
3717 END DO
3718 END DO
3719 END IF
3720 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhob])
3721 IF (ASSOCIATED(deriv_att)) THEN
3722 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3723!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3724!$OMP SHARED(bo,v_drho,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
3725 DO k = bo(1, 3), bo(2, 3)
3726 DO j = bo(1, 2), bo(2, 2)
3727 DO i = bo(1, 1), bo(2, 1)
3728 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3729 fac*deriv_data(i, j, k)*rho1b(i, j, k)
3730 END DO
3731 END DO
3732 END DO
3733 END IF
3734 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhob])
3735 IF (ASSOCIATED(deriv_att)) THEN
3736 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3737!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3738!$OMP SHARED(bo,v_drho,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
3739 DO k = bo(1, 3), bo(2, 3)
3740 DO j = bo(1, 2), bo(2, 2)
3741 DO i = bo(1, 1), bo(2, 1)
3742 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3743 fac*deriv_data(i, j, k)*drb1drb(i, j, k)
3744 END DO
3745 END DO
3746 END DO
3747 END IF
3748 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau_b])
3749 IF (ASSOCIATED(deriv_att)) THEN
3750 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3751!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3752!$OMP SHARED(bo,v_drho,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
3753 DO k = bo(1, 3), bo(2, 3)
3754 DO j = bo(1, 2), bo(2, 2)
3755 DO i = bo(1, 1), bo(2, 1)
3756 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3757 fac*deriv_data(i, j, k)*tau1b(i, j, k)
3758 END DO
3759 END DO
3760 END DO
3761 END IF
3763 IF (ASSOCIATED(deriv_att)) THEN
3764 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3765!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3766!$OMP SHARED(bo,v_drho,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
3767 DO k = bo(1, 3), bo(2, 3)
3768 DO j = bo(1, 2), bo(2, 2)
3769 DO i = bo(1, 1), bo(2, 1)
3770 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
3771 fac*deriv_data(i, j, k)*laplace1b(i, j, k)
3772 END DO
3773 END DO
3774 END DO
3775 END IF
3776
3777 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
3778 IF (ASSOCIATED(deriv_att)) THEN
3779 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3780 CALL xc_derivative_get(deriv_att, deriv_data=e_drho)
3781
3782
3783!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dr1dr,gradient_cut,norm_drho,v_drho,deriv_data)
3784 v_drho(1)%array(:, :, :) = v_drho(1)%array(:, :, :) + &
3785 deriv_data(:, :, :)*dr1dr(:, :, :)/max(gradient_cut, norm_drho(:, :, :))**2
3786!$OMP END PARALLEL WORKSHARE
3787 END IF
3788
3789 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhoa])
3790 IF (ASSOCIATED(deriv_att)) THEN
3791 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3792!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3793!$OMP SHARED(bo,v_drhoa,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
3794 DO k = bo(1, 3), bo(2, 3)
3795 DO j = bo(1, 2), bo(2, 2)
3796 DO i = bo(1, 1), bo(2, 1)
3797 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3798 deriv_data(i, j, k)*rho1a(i, j, k)
3799 END DO
3800 END DO
3801 END DO
3802 END IF
3803 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drho])
3804 IF (ASSOCIATED(deriv_att)) THEN
3805 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3806!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3807!$OMP SHARED(bo,v_drhoa,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
3808 DO k = bo(1, 3), bo(2, 3)
3809 DO j = bo(1, 2), bo(2, 2)
3810 DO i = bo(1, 1), bo(2, 1)
3811 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3812 deriv_data(i, j, k)*dr1dr(i, j, k)
3813 END DO
3814 END DO
3815 END DO
3816 END IF
3817 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhoa])
3818 IF (ASSOCIATED(deriv_att)) THEN
3819 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3820!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3821!$OMP SHARED(bo,v_drhoa,deriv_data,dra1dra,fac) COLLAPSE(3)
3822 DO k = bo(1, 3), bo(2, 3)
3823 DO j = bo(1, 2), bo(2, 2)
3824 DO i = bo(1, 1), bo(2, 1)
3825 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3826 deriv_data(i, j, k)*dra1dra(i, j, k)
3827 END DO
3828 END DO
3829 END DO
3830 END IF
3831 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_tau_a])
3832 IF (ASSOCIATED(deriv_att)) THEN
3833 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3834!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3835!$OMP SHARED(bo,v_drhoa,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
3836 DO k = bo(1, 3), bo(2, 3)
3837 DO j = bo(1, 2), bo(2, 2)
3838 DO i = bo(1, 1), bo(2, 1)
3839 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3840 deriv_data(i, j, k)*tau1a(i, j, k)
3841 END DO
3842 END DO
3843 END DO
3844 END IF
3846 IF (ASSOCIATED(deriv_att)) THEN
3847 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3848!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3849!$OMP SHARED(bo,v_drhoa,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
3850 DO k = bo(1, 3), bo(2, 3)
3851 DO j = bo(1, 2), bo(2, 2)
3852 DO i = bo(1, 1), bo(2, 1)
3853 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3854 deriv_data(i, j, k)*laplace1a(i, j, k)
3855 END DO
3856 END DO
3857 END DO
3858 END IF
3859 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhob])
3860 IF (ASSOCIATED(deriv_att)) THEN
3861 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3862!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3863!$OMP SHARED(bo,v_drhoa,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
3864 DO k = bo(1, 3), bo(2, 3)
3865 DO j = bo(1, 2), bo(2, 2)
3866 DO i = bo(1, 1), bo(2, 1)
3867 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3868 fac*deriv_data(i, j, k)*rho1b(i, j, k)
3869 END DO
3870 END DO
3871 END DO
3872 END IF
3873 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhob])
3874 IF (ASSOCIATED(deriv_att)) THEN
3875 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3876!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3877!$OMP SHARED(bo,v_drhoa,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
3878 DO k = bo(1, 3), bo(2, 3)
3879 DO j = bo(1, 2), bo(2, 2)
3880 DO i = bo(1, 1), bo(2, 1)
3881 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3882 fac*deriv_data(i, j, k)*drb1drb(i, j, k)
3883 END DO
3884 END DO
3885 END DO
3886 END IF
3887 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_tau_b])
3888 IF (ASSOCIATED(deriv_att)) THEN
3889 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3890!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3891!$OMP SHARED(bo,v_drhoa,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
3892 DO k = bo(1, 3), bo(2, 3)
3893 DO j = bo(1, 2), bo(2, 2)
3894 DO i = bo(1, 1), bo(2, 1)
3895 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3896 fac*deriv_data(i, j, k)*tau1b(i, j, k)
3897 END DO
3898 END DO
3899 END DO
3900 END IF
3902 IF (ASSOCIATED(deriv_att)) THEN
3903 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3904!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3905!$OMP SHARED(bo,v_drhoa,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
3906 DO k = bo(1, 3), bo(2, 3)
3907 DO j = bo(1, 2), bo(2, 2)
3908 DO i = bo(1, 1), bo(2, 1)
3909 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
3910 fac*deriv_data(i, j, k)*laplace1b(i, j, k)
3911 END DO
3912 END DO
3913 END DO
3914 END IF
3915
3916 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa])
3917 IF (ASSOCIATED(deriv_att)) THEN
3918 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3919 CALL xc_derivative_get(deriv_att, deriv_data=e_drhoa)
3920
3921
3922!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dra1dra,gradient_cut,norm_drhoa,v_drhoa,deriv_data)
3923 v_drhoa(1)%array(:, :, :) = v_drhoa(1)%array(:, :, :) + &
3924 deriv_data(:, :, :)*dra1dra(:, :, :)/max(gradient_cut, norm_drhoa(:, :, :))**2
3925!$OMP END PARALLEL WORKSHARE
3926 END IF
3927
3928 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_rhoa])
3929 IF (ASSOCIATED(deriv_att)) THEN
3930 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3931!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3932!$OMP SHARED(bo,v_xc_tau,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
3933 DO k = bo(1, 3), bo(2, 3)
3934 DO j = bo(1, 2), bo(2, 2)
3935 DO i = bo(1, 1), bo(2, 1)
3936 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3937 deriv_data(i, j, k)*rho1a(i, j, k)
3938 END DO
3939 END DO
3940 END DO
3941 END IF
3942 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_norm_drho])
3943 IF (ASSOCIATED(deriv_att)) THEN
3944 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3945!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3946!$OMP SHARED(bo,v_xc_tau,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
3947 DO k = bo(1, 3), bo(2, 3)
3948 DO j = bo(1, 2), bo(2, 2)
3949 DO i = bo(1, 1), bo(2, 1)
3950 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3951 deriv_data(i, j, k)*dr1dr(i, j, k)
3952 END DO
3953 END DO
3954 END DO
3955 END IF
3956 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_norm_drhoa])
3957 IF (ASSOCIATED(deriv_att)) THEN
3958 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3959!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3960!$OMP SHARED(bo,v_xc_tau,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
3961 DO k = bo(1, 3), bo(2, 3)
3962 DO j = bo(1, 2), bo(2, 2)
3963 DO i = bo(1, 1), bo(2, 1)
3964 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3965 deriv_data(i, j, k)*dra1dra(i, j, k)
3966 END DO
3967 END DO
3968 END DO
3969 END IF
3970 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_tau_a])
3971 IF (ASSOCIATED(deriv_att)) THEN
3972 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3973!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3974!$OMP SHARED(bo,v_xc_tau,deriv_data,tau1a,fac) COLLAPSE(3)
3975 DO k = bo(1, 3), bo(2, 3)
3976 DO j = bo(1, 2), bo(2, 2)
3977 DO i = bo(1, 1), bo(2, 1)
3978 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3979 deriv_data(i, j, k)*tau1a(i, j, k)
3980 END DO
3981 END DO
3982 END DO
3983 END IF
3984 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_laplace_rhoa])
3985 IF (ASSOCIATED(deriv_att)) THEN
3986 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
3987!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
3988!$OMP SHARED(bo,v_xc_tau,deriv_data,laplace1a,v_laplace,fac) COLLAPSE(3)
3989 DO k = bo(1, 3), bo(2, 3)
3990 DO j = bo(1, 2), bo(2, 2)
3991 DO i = bo(1, 1), bo(2, 1)
3992 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
3993 deriv_data(i, j, k)*laplace1a(i, j, k)
3994 END DO
3995 END DO
3996 END DO
3997 END IF
3998 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_rhob])
3999 IF (ASSOCIATED(deriv_att)) THEN
4000 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4001!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4002!$OMP SHARED(bo,v_xc_tau,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
4003 DO k = bo(1, 3), bo(2, 3)
4004 DO j = bo(1, 2), bo(2, 2)
4005 DO i = bo(1, 1), bo(2, 1)
4006 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4007 fac*deriv_data(i, j, k)*rho1b(i, j, k)
4008 END DO
4009 END DO
4010 END DO
4011 END IF
4012 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_norm_drhob])
4013 IF (ASSOCIATED(deriv_att)) THEN
4014 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4015!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4016!$OMP SHARED(bo,v_xc_tau,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
4017 DO k = bo(1, 3), bo(2, 3)
4018 DO j = bo(1, 2), bo(2, 2)
4019 DO i = bo(1, 1), bo(2, 1)
4020 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4021 fac*deriv_data(i, j, k)*drb1drb(i, j, k)
4022 END DO
4023 END DO
4024 END DO
4025 END IF
4026 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_tau_b])
4027 IF (ASSOCIATED(deriv_att)) THEN
4028 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4029!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4030!$OMP SHARED(bo,v_xc_tau,deriv_data,tau1b,fac) COLLAPSE(3)
4031 DO k = bo(1, 3), bo(2, 3)
4032 DO j = bo(1, 2), bo(2, 2)
4033 DO i = bo(1, 1), bo(2, 1)
4034 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4035 fac*deriv_data(i, j, k)*tau1b(i, j, k)
4036 END DO
4037 END DO
4038 END DO
4039 END IF
4040 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a, deriv_laplace_rhob])
4041 IF (ASSOCIATED(deriv_att)) THEN
4042 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4043!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4044!$OMP SHARED(bo,v_xc_tau,deriv_data,laplace1b,v_laplace,fac) COLLAPSE(3)
4045 DO k = bo(1, 3), bo(2, 3)
4046 DO j = bo(1, 2), bo(2, 2)
4047 DO i = bo(1, 1), bo(2, 1)
4048 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4049 fac*deriv_data(i, j, k)*laplace1b(i, j, k)
4050 END DO
4051 END DO
4052 END DO
4053 END IF
4054
4055
4056 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_rhoa])
4057 IF (ASSOCIATED(deriv_att)) THEN
4058 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4059!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4060!$OMP SHARED(bo,v_laplace,deriv_data,rho1a,v_xc,fac) COLLAPSE(3)
4061 DO k = bo(1, 3), bo(2, 3)
4062 DO j = bo(1, 2), bo(2, 2)
4063 DO i = bo(1, 1), bo(2, 1)
4064 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4065 deriv_data(i, j, k)*rho1a(i, j, k)
4066 END DO
4067 END DO
4068 END DO
4069 END IF
4071 IF (ASSOCIATED(deriv_att)) THEN
4072 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4073!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4074!$OMP SHARED(bo,v_laplace,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
4075 DO k = bo(1, 3), bo(2, 3)
4076 DO j = bo(1, 2), bo(2, 2)
4077 DO i = bo(1, 1), bo(2, 1)
4078 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4079 deriv_data(i, j, k)*dr1dr(i, j, k)
4080 END DO
4081 END DO
4082 END DO
4083 END IF
4085 IF (ASSOCIATED(deriv_att)) THEN
4086 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4087!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4088!$OMP SHARED(bo,v_laplace,deriv_data,dra1dra,v_drhoa,fac) COLLAPSE(3)
4089 DO k = bo(1, 3), bo(2, 3)
4090 DO j = bo(1, 2), bo(2, 2)
4091 DO i = bo(1, 1), bo(2, 1)
4092 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4093 deriv_data(i, j, k)*dra1dra(i, j, k)
4094 END DO
4095 END DO
4096 END DO
4097 END IF
4098 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_tau_a])
4099 IF (ASSOCIATED(deriv_att)) THEN
4100 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4101!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4102!$OMP SHARED(bo,v_laplace,deriv_data,tau1a,v_xc_tau,fac) COLLAPSE(3)
4103 DO k = bo(1, 3), bo(2, 3)
4104 DO j = bo(1, 2), bo(2, 2)
4105 DO i = bo(1, 1), bo(2, 1)
4106 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4107 deriv_data(i, j, k)*tau1a(i, j, k)
4108 END DO
4109 END DO
4110 END DO
4111 END IF
4113 IF (ASSOCIATED(deriv_att)) THEN
4114 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4115!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4116!$OMP SHARED(bo,v_laplace,deriv_data,laplace1a,fac) COLLAPSE(3)
4117 DO k = bo(1, 3), bo(2, 3)
4118 DO j = bo(1, 2), bo(2, 2)
4119 DO i = bo(1, 1), bo(2, 1)
4120 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4121 deriv_data(i, j, k)*laplace1a(i, j, k)
4122 END DO
4123 END DO
4124 END DO
4125 END IF
4126 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_rhob])
4127 IF (ASSOCIATED(deriv_att)) THEN
4128 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4129!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4130!$OMP SHARED(bo,v_laplace,deriv_data,rho1b,v_xc,fac) COLLAPSE(3)
4131 DO k = bo(1, 3), bo(2, 3)
4132 DO j = bo(1, 2), bo(2, 2)
4133 DO i = bo(1, 1), bo(2, 1)
4134 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4135 fac*deriv_data(i, j, k)*rho1b(i, j, k)
4136 END DO
4137 END DO
4138 END DO
4139 END IF
4141 IF (ASSOCIATED(deriv_att)) THEN
4142 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4143!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4144!$OMP SHARED(bo,v_laplace,deriv_data,drb1drb,v_drhob,fac) COLLAPSE(3)
4145 DO k = bo(1, 3), bo(2, 3)
4146 DO j = bo(1, 2), bo(2, 2)
4147 DO i = bo(1, 1), bo(2, 1)
4148 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4149 fac*deriv_data(i, j, k)*drb1drb(i, j, k)
4150 END DO
4151 END DO
4152 END DO
4153 END IF
4154 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rhoa, deriv_tau_b])
4155 IF (ASSOCIATED(deriv_att)) THEN
4156 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4157!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4158!$OMP SHARED(bo,v_laplace,deriv_data,tau1b,v_xc_tau,fac) COLLAPSE(3)
4159 DO k = bo(1, 3), bo(2, 3)
4160 DO j = bo(1, 2), bo(2, 2)
4161 DO i = bo(1, 1), bo(2, 1)
4162 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4163 fac*deriv_data(i, j, k)*tau1b(i, j, k)
4164 END DO
4165 END DO
4166 END DO
4167 END IF
4169 IF (ASSOCIATED(deriv_att)) THEN
4170 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4171!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4172!$OMP SHARED(bo,v_laplace,deriv_data,laplace1b,fac) COLLAPSE(3)
4173 DO k = bo(1, 3), bo(2, 3)
4174 DO j = bo(1, 2), bo(2, 2)
4175 DO i = bo(1, 1), bo(2, 1)
4176 v_laplace(2)%array(i, j, k) = v_laplace(2)%array(i, j, k) + &
4177 fac*deriv_data(i, j, k)*laplace1b(i, j, k)
4178 END DO
4179 END DO
4180 END DO
4181 END IF
4182
4183
4184
4185
4186 END IF
4187
4188 IF (gradient_f) THEN
4189 IF (.NOT. do_spinflip) THEN
4190
4191 IF (my_compute_virial) THEN
4192 CALL virial_drho_drho(virial_pw, drhoa, v_drhoa(1), virial_xc)
4193 CALL virial_drho_drho(virial_pw, drhob, v_drhob(2), virial_xc)
4194 DO idir = 1, 3
4195!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(drho,idir,v_drho,virial_pw)
4196 virial_pw%array(:, :, :) = drho(idir)%array(:, :, :)*(v_drho(1)%array(:, :, :) + v_drho(2)%array(:, :, :))
4197!$OMP END PARALLEL WORKSHARE
4198 DO jdir = 1, idir
4199 tmp = -0.5_dp*virial_pw%pw_grid%dvol*accurate_dot_product(virial_pw%array(:, :, :), &
4200 drho(jdir)%array(:, :, :))
4201 virial_xc(jdir, idir) = virial_xc(jdir, idir) + tmp
4202 virial_xc(idir, jdir) = virial_xc(jdir, idir)
4203 END DO
4204 END DO
4205 END IF ! my_compute_virial
4206
4207 IF (my_gapw) THEN
4208!$OMP PARALLEL DO DEFAULT(NONE) &
4209!$OMP PRIVATE(ia,idir,ispin,ir) &
4210!$OMP SHARED(bo,nspins,vxg,drhoa,drhob,v_drhoa,v_drhob,v_drho, &
4211!$OMP e_drhoa,e_drhob,e_drho,drho1a,drho1b,fac,drho,drho1) COLLAPSE(3)
4212 DO ir = bo(1, 2), bo(2, 2)
4213 DO ia = bo(1, 1), bo(2, 1)
4214 DO idir = 1, 3
4215 DO ispin = 1, nspins
4216 vxg(idir, ia, ir, ispin) = &
4217 -(v_drhoa(ispin)%array(ia, ir, 1)*drhoa(idir)%array(ia, ir, 1) + &
4218 v_drhob(ispin)%array(ia, ir, 1)*drhob(idir)%array(ia, ir, 1) + &
4219 v_drho(ispin)%array(ia, ir, 1)*drho(idir)%array(ia, ir, 1))
4220 END DO
4221 IF (ASSOCIATED(e_drhoa)) THEN
4222 vxg(idir, ia, ir, 1) = vxg(idir, ia, ir, 1) + &
4223 e_drhoa(ia, ir, 1)*drho1a(idir)%array(ia, ir, 1)
4224 END IF
4225 IF (nspins /= 1 .AND. ASSOCIATED(e_drhob)) THEN
4226 vxg(idir, ia, ir, 2) = vxg(idir, ia, ir, 2) + &
4227 e_drhob(ia, ir, 1)*drho1b(idir)%array(ia, ir, 1)
4228 END IF
4229 IF (ASSOCIATED(e_drho)) THEN
4230 IF (nspins /= 1) THEN
4231 vxg(idir, ia, ir, 1) = vxg(idir, ia, ir, 1) + &
4232 e_drho(ia, ir, 1)*drho1(idir)%array(ia, ir, 1)
4233 vxg(idir, ia, ir, 2) = vxg(idir, ia, ir, 2) + &
4234 e_drho(ia, ir, 1)*drho1(idir)%array(ia, ir, 1)
4235 ELSE
4236 vxg(idir, ia, ir, 1) = vxg(idir, ia, ir, 1) + &
4237 e_drho(ia, ir, 1)*(drho1a(idir)%array(ia, ir, 1) + &
4238 fac*drho1b(idir)%array(ia, ir, 1))
4239 END IF
4240 END IF
4241 END DO
4242 END DO
4243 END DO
4244!$OMP END PARALLEL DO
4245 ELSE
4246
4247 ! partial integration
4248 DO idir = 1, 3
4249
4250 DO ispin = 1, nspins
4251!$OMP PARALLEL WORKSHARE DEFAULT(NONE) &
4252!$OMP SHARED(v_drho_r,v_drhoa,v_drhob,v_drho,drhoa,drhob,drho,ispin,idir)
4253 v_drho_r(idir, ispin)%array(:, :, :) = &
4254 v_drhoa(ispin)%array(:, :, :)*drhoa(idir)%array(:, :, :) + &
4255 v_drhob(ispin)%array(:, :, :)*drhob(idir)%array(:, :, :) + &
4256 v_drho(ispin)%array(:, :, :)*drho(idir)%array(:, :, :)
4257!$OMP END PARALLEL WORKSHARE
4258 END DO
4259 IF (ASSOCIATED(e_drhoa)) THEN
4260!$OMP PARALLEL WORKSHARE DEFAULT(NONE) &
4261!$OMP SHARED(v_drho_r,e_drhoa,drho1a,idir)
4262 v_drho_r(idir, 1)%array(:, :, :) = v_drho_r(idir, 1)%array(:, :, :) - &
4263 e_drhoa(:, :, :)*drho1a(idir)%array(:, :, :)
4264!$OMP END PARALLEL WORKSHARE
4265 END IF
4266 IF (nspins /= 1 .AND. ASSOCIATED(e_drhob)) THEN
4267!$OMP PARALLEL WORKSHARE DEFAULT(NONE)&
4268!$OMP SHARED(v_drho_r,e_drhob,drho1b,idir)
4269 v_drho_r(idir, 2)%array(:, :, :) = v_drho_r(idir, 2)%array(:, :, :) - &
4270 e_drhob(:, :, :)*drho1b(idir)%array(:, :, :)
4271!$OMP END PARALLEL WORKSHARE
4272 END IF
4273 IF (ASSOCIATED(e_drho)) THEN
4274!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4275!$OMP SHARED(bo,v_drho_r,e_drho,drho1a,drho1b,drho1,fac,idir,nspins) COLLAPSE(3)
4276 DO k = bo(1, 3), bo(2, 3)
4277 DO j = bo(1, 2), bo(2, 2)
4278 DO i = bo(1, 1), bo(2, 1)
4279 IF (nspins /= 1) THEN
4280 v_drho_r(idir, 1)%array(i, j, k) = v_drho_r(idir, 1)%array(i, j, k) - &
4281 e_drho(i, j, k)*drho1(idir)%array(i, j, k)
4282 v_drho_r(idir, 2)%array(i, j, k) = v_drho_r(idir, 2)%array(i, j, k) - &
4283 e_drho(i, j, k)*drho1(idir)%array(i, j, k)
4284 ELSE
4285 v_drho_r(idir, 1)%array(i, j, k) = v_drho_r(idir, 1)%array(i, j, k) - &
4286 e_drho(i, j, k)*(drho1a(idir)%array(i, j, k) + &
4287 fac*drho1b(idir)%array(i, j, k))
4288 END IF
4289 END DO
4290 END DO
4291 END DO
4292!$OMP END PARALLEL DO
4293 END IF
4294 END DO
4295
4296 ! partial integration
4297 DO ispin = 1, nspins
4298 CALL xc_pw_divergence(xc_deriv_method_id, v_drho_r(:, ispin), tmp_g, vxc_g, v_xc(ispin))
4299 END DO ! ispin
4300
4301 END IF
4302
4303 END IF ! .NOT.do_spinflip
4304
4305 DO idir = 1, 3
4306 DEALLOCATE (drho(idir)%array)
4307 DEALLOCATE (drho1(idir)%array)
4308 END DO
4309
4310 DO ispin = 1, nspins
4311 CALL deallocate_pw(v_drhoa(ispin), pw_pool)
4312 CALL deallocate_pw(v_drhob(ispin), pw_pool)
4313 END DO
4314
4315 DEALLOCATE (v_drhoa, v_drhob)
4316
4317 END IF ! gradient_f
4318
4319 IF (laplace_f .AND. my_compute_virial) THEN
4320 virial_pw%array(:, :, :) = -rhoa(:, :, :)
4321 CALL virial_laplace(virial_pw, pw_pool, virial_xc, v_laplace(1)%array)
4322 virial_pw%array(:, :, :) = -rhob(:, :, :)
4323 CALL virial_laplace(virial_pw, pw_pool, virial_xc, v_laplace(2)%array)
4324 END IF
4325
4326 ELSE
4327
4328 !-----------------!
4329 ! restricted case !
4330 !-----------------!
4331
4332 CALL xc_rho_set_get(rho1_set, rho=rho1)
4333
4334 IF (gradient_f) THEN
4335 CALL xc_rho_set_get(rho_set, drho=drho, norm_drho=norm_drho)
4336 CALL xc_rho_set_get(rho1_set, drho=drho1)
4337 CALL prepare_dr1dr(dr1dr, drho, drho1)
4338 END IF
4339
4340 IF (laplace_f) THEN
4341 CALL xc_rho_set_get(rho1_set, laplace_rho=laplace1)
4342
4343 ALLOCATE (v_laplace(nspins))
4344 DO ispin = 1, nspins
4345 CALL allocate_pw(v_laplace(ispin), pw_pool, bo)
4346 END DO
4347
4348 IF (my_compute_virial) CALL xc_rho_set_get(rho_set, rho=rho)
4349 END IF
4350
4351 IF (tau_f) THEN
4352 CALL xc_rho_set_get(rho1_set, tau=tau1)
4353 END IF
4354
4355 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_rho])
4356 IF (ASSOCIATED(deriv_att)) THEN
4357 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4358!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4359!$OMP SHARED(bo,v_xc,deriv_data,rho1,fac) COLLAPSE(3)
4360 DO k = bo(1, 3), bo(2, 3)
4361 DO j = bo(1, 2), bo(2, 2)
4362 DO i = bo(1, 1), bo(2, 1)
4363 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
4364 deriv_data(i, j, k)*rho1(i, j, k)
4365 END DO
4366 END DO
4367 END DO
4368 END IF
4369 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_norm_drho])
4370 IF (ASSOCIATED(deriv_att)) THEN
4371 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4372!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4373!$OMP SHARED(bo,v_xc,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
4374 DO k = bo(1, 3), bo(2, 3)
4375 DO j = bo(1, 2), bo(2, 2)
4376 DO i = bo(1, 1), bo(2, 1)
4377 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
4378 deriv_data(i, j, k)*dr1dr(i, j, k)
4379 END DO
4380 END DO
4381 END DO
4382 END IF
4383 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_tau])
4384 IF (ASSOCIATED(deriv_att)) THEN
4385 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4386!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4387!$OMP SHARED(bo,v_xc,deriv_data,tau1,v_xc_tau,fac) COLLAPSE(3)
4388 DO k = bo(1, 3), bo(2, 3)
4389 DO j = bo(1, 2), bo(2, 2)
4390 DO i = bo(1, 1), bo(2, 1)
4391 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
4392 deriv_data(i, j, k)*tau1(i, j, k)
4393 END DO
4394 END DO
4395 END DO
4396 END IF
4397 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho, deriv_laplace_rho])
4398 IF (ASSOCIATED(deriv_att)) THEN
4399 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4400!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4401!$OMP SHARED(bo,v_xc,deriv_data,laplace1,v_laplace,fac) COLLAPSE(3)
4402 DO k = bo(1, 3), bo(2, 3)
4403 DO j = bo(1, 2), bo(2, 2)
4404 DO i = bo(1, 1), bo(2, 1)
4405 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
4406 deriv_data(i, j, k)*laplace1(i, j, k)
4407 END DO
4408 END DO
4409 END DO
4410 END IF
4411
4412
4413 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rho])
4414 IF (ASSOCIATED(deriv_att)) THEN
4415 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4416!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4417!$OMP SHARED(bo,v_drho,deriv_data,rho1,v_xc,fac) COLLAPSE(3)
4418 DO k = bo(1, 3), bo(2, 3)
4419 DO j = bo(1, 2), bo(2, 2)
4420 DO i = bo(1, 1), bo(2, 1)
4421 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
4422 deriv_data(i, j, k)*rho1(i, j, k)
4423 END DO
4424 END DO
4425 END DO
4426 END IF
4427 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drho])
4428 IF (ASSOCIATED(deriv_att)) THEN
4429 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4430!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4431!$OMP SHARED(bo,v_drho,deriv_data,dr1dr,fac) COLLAPSE(3)
4432 DO k = bo(1, 3), bo(2, 3)
4433 DO j = bo(1, 2), bo(2, 2)
4434 DO i = bo(1, 1), bo(2, 1)
4435 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
4436 deriv_data(i, j, k)*dr1dr(i, j, k)
4437 END DO
4438 END DO
4439 END DO
4440 END IF
4441 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_tau])
4442 IF (ASSOCIATED(deriv_att)) THEN
4443 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4444!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4445!$OMP SHARED(bo,v_drho,deriv_data,tau1,v_xc_tau,fac) COLLAPSE(3)
4446 DO k = bo(1, 3), bo(2, 3)
4447 DO j = bo(1, 2), bo(2, 2)
4448 DO i = bo(1, 1), bo(2, 1)
4449 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
4450 deriv_data(i, j, k)*tau1(i, j, k)
4451 END DO
4452 END DO
4453 END DO
4454 END IF
4455 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_laplace_rho])
4456 IF (ASSOCIATED(deriv_att)) THEN
4457 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4458!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4459!$OMP SHARED(bo,v_drho,deriv_data,laplace1,v_laplace,fac) COLLAPSE(3)
4460 DO k = bo(1, 3), bo(2, 3)
4461 DO j = bo(1, 2), bo(2, 2)
4462 DO i = bo(1, 1), bo(2, 1)
4463 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
4464 deriv_data(i, j, k)*laplace1(i, j, k)
4465 END DO
4466 END DO
4467 END DO
4468 END IF
4469
4470 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
4471 IF (ASSOCIATED(deriv_att)) THEN
4472 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4473 CALL xc_derivative_get(deriv_att, deriv_data=e_drho)
4474
4475 IF (my_compute_virial) THEN
4476 CALL virial_drho_drho1(virial_pw, drho, drho1, deriv_data, virial_xc)
4477 END IF ! my_compute_virial
4478
4479!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dr1dr,gradient_cut,norm_drho,v_drho,deriv_data)
4480 v_drho(1)%array(:, :, :) = v_drho(1)%array(:, :, :) + &
4481 deriv_data(:, :, :)*dr1dr(:, :, :)/max(gradient_cut, norm_drho(:, :, :))**2
4482!$OMP END PARALLEL WORKSHARE
4483 END IF
4484
4485 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau, deriv_rho])
4486 IF (ASSOCIATED(deriv_att)) THEN
4487 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4488!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4489!$OMP SHARED(bo,v_xc_tau,deriv_data,rho1,v_xc,fac) COLLAPSE(3)
4490 DO k = bo(1, 3), bo(2, 3)
4491 DO j = bo(1, 2), bo(2, 2)
4492 DO i = bo(1, 1), bo(2, 1)
4493 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4494 deriv_data(i, j, k)*rho1(i, j, k)
4495 END DO
4496 END DO
4497 END DO
4498 END IF
4499 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau, deriv_norm_drho])
4500 IF (ASSOCIATED(deriv_att)) THEN
4501 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4502!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4503!$OMP SHARED(bo,v_xc_tau,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
4504 DO k = bo(1, 3), bo(2, 3)
4505 DO j = bo(1, 2), bo(2, 2)
4506 DO i = bo(1, 1), bo(2, 1)
4507 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4508 deriv_data(i, j, k)*dr1dr(i, j, k)
4509 END DO
4510 END DO
4511 END DO
4512 END IF
4513 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau, deriv_tau])
4514 IF (ASSOCIATED(deriv_att)) THEN
4515 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4516!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4517!$OMP SHARED(bo,v_xc_tau,deriv_data,tau1,fac) COLLAPSE(3)
4518 DO k = bo(1, 3), bo(2, 3)
4519 DO j = bo(1, 2), bo(2, 2)
4520 DO i = bo(1, 1), bo(2, 1)
4521 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4522 deriv_data(i, j, k)*tau1(i, j, k)
4523 END DO
4524 END DO
4525 END DO
4526 END IF
4527 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau, deriv_laplace_rho])
4528 IF (ASSOCIATED(deriv_att)) THEN
4529 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4530!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4531!$OMP SHARED(bo,v_xc_tau,deriv_data,laplace1,v_laplace,fac) COLLAPSE(3)
4532 DO k = bo(1, 3), bo(2, 3)
4533 DO j = bo(1, 2), bo(2, 2)
4534 DO i = bo(1, 1), bo(2, 1)
4535 v_xc_tau(1)%array(i, j, k) = v_xc_tau(1)%array(i, j, k) + &
4536 deriv_data(i, j, k)*laplace1(i, j, k)
4537 END DO
4538 END DO
4539 END DO
4540 END IF
4541
4542
4543 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho, deriv_rho])
4544 IF (ASSOCIATED(deriv_att)) THEN
4545 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4546!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4547!$OMP SHARED(bo,v_laplace,deriv_data,rho1,v_xc,fac) COLLAPSE(3)
4548 DO k = bo(1, 3), bo(2, 3)
4549 DO j = bo(1, 2), bo(2, 2)
4550 DO i = bo(1, 1), bo(2, 1)
4551 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
4552 deriv_data(i, j, k)*rho1(i, j, k)
4553 END DO
4554 END DO
4555 END DO
4556 END IF
4557 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho, deriv_norm_drho])
4558 IF (ASSOCIATED(deriv_att)) THEN
4559 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4560!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4561!$OMP SHARED(bo,v_laplace,deriv_data,dr1dr,v_drho,fac) COLLAPSE(3)
4562 DO k = bo(1, 3), bo(2, 3)
4563 DO j = bo(1, 2), bo(2, 2)
4564 DO i = bo(1, 1), bo(2, 1)
4565 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
4566 deriv_data(i, j, k)*dr1dr(i, j, k)
4567 END DO
4568 END DO
4569 END DO
4570 END IF
4571 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho, deriv_tau])
4572 IF (ASSOCIATED(deriv_att)) THEN
4573 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4574!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4575!$OMP SHARED(bo,v_laplace,deriv_data,tau1,v_xc_tau,fac) COLLAPSE(3)
4576 DO k = bo(1, 3), bo(2, 3)
4577 DO j = bo(1, 2), bo(2, 2)
4578 DO i = bo(1, 1), bo(2, 1)
4579 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
4580 deriv_data(i, j, k)*tau1(i, j, k)
4581 END DO
4582 END DO
4583 END DO
4584 END IF
4586 IF (ASSOCIATED(deriv_att)) THEN
4587 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4588!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
4589!$OMP SHARED(bo,v_laplace,deriv_data,laplace1,fac) COLLAPSE(3)
4590 DO k = bo(1, 3), bo(2, 3)
4591 DO j = bo(1, 2), bo(2, 2)
4592 DO i = bo(1, 1), bo(2, 1)
4593 v_laplace(1)%array(i, j, k) = v_laplace(1)%array(i, j, k) + &
4594 deriv_data(i, j, k)*laplace1(i, j, k)
4595 END DO
4596 END DO
4597 END DO
4598 END IF
4599
4600
4601 IF (my_compute_virial) THEN
4602 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_laplace_rho])
4603 IF (ASSOCIATED(deriv_att)) THEN
4604 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4605
4606 virial_pw%array(:, :, :) = -rho1(:, :, :)
4607 CALL virial_laplace(virial_pw, pw_pool, virial_xc, deriv_data)
4608 END IF
4609 END IF ! my_compute_virial
4610
4611
4612 IF (gradient_f) THEN
4613
4614 IF (my_compute_virial) THEN
4615 CALL virial_drho_drho(virial_pw, drho, v_drho(1), virial_xc)
4616 END IF ! my_compute_virial
4617
4618 IF (my_gapw) THEN
4619
4620 DO idir = 1, 3
4621!$OMP PARALLEL DO DEFAULT(NONE) &
4622!$OMP PRIVATE(ia,ir) &
4623!$OMP SHARED(bo,vxg,drho,v_drho,e_drho,drho1,idir,factor2) &
4624!$OMP COLLAPSE(2)
4625 DO ia = bo(1, 1), bo(2, 1)
4626 DO ir = bo(1, 2), bo(2, 2)
4627 vxg(idir, ia, ir, 1) = -drho(idir)%array(ia, ir, 1)*v_drho(1)%array(ia, ir, 1)
4628 IF (ASSOCIATED(e_drho)) THEN
4629 vxg(idir, ia, ir, 1) = vxg(idir, ia, ir, 1) + factor2*drho1(idir)%array(ia, ir, 1)*e_drho(ia, ir, 1)
4630 END IF
4631 END DO
4632 END DO
4633!$OMP END PARALLEL DO
4634 END DO
4635
4636 ELSE
4637 ! partial integration
4638 DO idir = 1, 3
4639!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(v_drho_r,drho,v_drho,drho1,e_drho,idir)
4640 v_drho_r(idir, 1)%array(:, :, :) = drho(idir)%array(:, :, :)*v_drho(1)%array(:, :, :) - &
4641 drho1(idir)%array(:, :, :)*e_drho(:, :, :)
4642!$OMP END PARALLEL WORKSHARE
4643 END DO
4644
4645 CALL xc_pw_divergence(xc_deriv_method_id, v_drho_r(:, 1), tmp_g, vxc_g, v_xc(1))
4646 END IF
4647
4648 END IF
4649
4650 IF (laplace_f .AND. my_compute_virial) THEN
4651 virial_pw%array(:, :, :) = -rho(:, :, :)
4652 CALL virial_laplace(virial_pw, pw_pool, virial_xc, v_laplace(1)%array)
4653 END IF
4654
4655 END IF
4656
4657 IF (laplace_f) THEN
4658 DO ispin = 1, nspins
4659 CALL xc_pw_laplace(v_laplace(ispin), pw_pool, xc_deriv_method_id)
4660 CALL pw_axpy(v_laplace(ispin), v_xc(ispin))
4661 END DO
4662 END IF
4663
4664 IF (gradient_f) THEN
4665
4666 DO ispin = 1, nspins
4667 CALL deallocate_pw(v_drho(ispin), pw_pool)
4668 DO idir = 1, 3
4669 CALL deallocate_pw(v_drho_r(idir, ispin), pw_pool)
4670 END DO
4671 END DO
4672 DEALLOCATE (v_drho, v_drho_r)
4673
4674 END IF
4675
4676 IF (laplace_f) THEN
4677 DO ispin = 1, nspins
4678 CALL deallocate_pw(v_laplace(ispin), pw_pool)
4679 END DO
4680 DEALLOCATE (v_laplace)
4681 END IF
4682
4683 IF (ASSOCIATED(tmp_g%pw_grid) .AND. ASSOCIATED(pw_pool)) THEN
4684 CALL pw_pool%give_back_pw(tmp_g)
4685 END IF
4686
4687 IF (ASSOCIATED(vxc_g%pw_grid) .AND. ASSOCIATED(pw_pool)) THEN
4688 CALL pw_pool%give_back_pw(vxc_g)
4689 END IF
4690
4691 IF (my_compute_virial .AND. (gradient_f .OR. laplace_f)) THEN
4692 CALL deallocate_pw(virial_pw, pw_pool)
4693 END IF
4694
4695 CALL timestop(handle)
4696
4697 END SUBROUTINE xc_calc_2nd_deriv_analytical
4698
4699! **************************************************************************************************
4700!> \brief Calculates the third functional derivative of the exchange-correlation functional, E_xc.
4701!> Any GGA functional can be written as:
4702!>
4703!> E_xc[\rho] = \int e_xc(\rho,\nabla\rho)dr
4704!>
4705!> This routine gives you back the contraction of the derivatives of e_xc with respect to the
4706!> alpha or beta density or with respect to the norm of their gradients contracted with rho1.
4707!> For example, the alpha component would be (d stands for total derivative):
4708!>
4709!> d^3 e_xc
4710!> v_xc(1) = \sum_{s,s'}^{a,b} ---------------------\rhos1\rho1s'
4711!> d\rhoa d\rhos d\rhos'
4712!>
4713!> \param v_xc Third derivative of the exchange-correlation functional
4714!> \param v_xc_tau ...
4715!> \param deriv_set derivatives of the exchange-correlation potential, e_xc
4716!> \param rho_set object containing the density at which the derivatives were calculated, \rho
4717!> \param rho1_set object containing the density with which to fold, \rho1s
4718!> \param pw_pool the pool for the grids
4719!> \param xc_section XC parameters
4720!> \par History
4721!> * 07.2024 Created [LHS]
4722! **************************************************************************************************
4723 SUBROUTINE xc_calc_3rd_deriv_analytical(v_xc, v_xc_tau, deriv_set, rho_set, rho1_set, &
4724 pw_pool, xc_section, spinflip)
4725
4726 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_xc, v_xc_tau
4727 TYPE(xc_derivative_set_type) :: deriv_set
4728 TYPE(xc_rho_set_type), INTENT(IN) :: rho_set, rho1_set
4729 TYPE(pw_pool_type), POINTER :: pw_pool
4730 TYPE(section_vals_type), POINTER :: xc_section
4731 LOGICAL, INTENT(in), OPTIONAL :: spinflip
4732
4733 CHARACTER(len=*), PARAMETER :: routinen = 'xc_calc_3rd_deriv_analytical'
4734
4735 INTEGER :: handle, i, idir, ispin, j, &
4736 k, nspins, xc_deriv_method_id
4737 INTEGER, DIMENSION(2, 3) :: bo
4738 LOGICAL :: lsd, do_spinflip, alda0, &
4739 rho_f, gradient_f, tau_f, laplace_f
4740 REAL(kind=dp) :: s, s_thresh, s_thresh2, gradient_cut
4741 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: dr1dr, dra1dra, drb1drb
4742 REAL(kind=dp), DIMENSION(:, :, :), POINTER :: deriv_data, deriv_data2, e_drhoa, e_drhob, &
4743 e_drho, norm_drho, norm_drhoa, &
4744 norm_drhob, rho1a, rho1b, &
4745 rhoa, rhob
4746 TYPE(cp_3d_r_cp_type), DIMENSION(3) :: drho, drho1, drho1a, drho1b, drhoa, drhob
4747 TYPE(pw_r3d_rs_type), DIMENSION(:), ALLOCATABLE :: v_drhoa, v_drhob, v_drho
4748 TYPE(pw_r3d_rs_type), DIMENSION(:, :), ALLOCATABLE :: v_drho_r
4749 TYPE(pw_c1d_gs_type) :: tmp_g, vxc_g
4750 TYPE(xc_derivative_type), POINTER :: deriv_att
4751
4752 CALL timeset(routinen, handle)
4753
4754 NULLIFY (e_drhoa, e_drhob, e_drho)
4755
4756 cpassert(ASSOCIATED(v_xc))
4757 cpassert(ASSOCIATED(xc_section))
4758
4759 ! Initialize parameters
4760 CALL section_vals_val_get(xc_section, "XC_GRID%XC_DERIV", &
4761 i_val=xc_deriv_method_id)
4762 !
4763 nspins = SIZE(v_xc)
4764 lsd = ASSOCIATED(rho_set%rhoa)
4765 !
4766 do_spinflip = .false.
4767 IF (PRESENT(spinflip)) do_spinflip = spinflip
4768 !
4769 bo = rho_set%local_bounds
4770 !
4771 CALL check_for_derivatives(deriv_set, lsd, rho_f, gradient_f, tau_f, laplace_f)
4772 !
4773 CALL xc_rho_set_get(rho_set, drho_cutoff=gradient_cut)
4774 !
4775 !S_THRESH has to be the same as S_THRESH in xc_calc_2nd_deriv_analytical
4776 alda0 = .false.
4777 s_thresh = 1.0e-04
4778 s_thresh2 = 1.0e-07
4779
4780 ! Initialize potential
4781 DO ispin = 1, nspins
4782 !CALL pw_zero(v_xc(ispin))
4783 v_xc(ispin)%array = 0.0_dp
4784 END DO
4785
4786 ! Create GGA fields
4787 IF (gradient_f) THEN
4788 ALLOCATE (v_drho_r(3, nspins), v_drho(nspins))
4789 DO ispin = 1, nspins
4790 DO idir = 1, 3
4791 CALL allocate_pw(v_drho_r(idir, ispin), pw_pool, bo)
4792 END DO
4793 CALL allocate_pw(v_drho(ispin), pw_pool, bo)
4794 END DO
4795
4796 IF (xc_requires_tmp_g(xc_deriv_method_id)) THEN
4797 IF (ASSOCIATED(pw_pool)) THEN
4798 CALL pw_pool%create_pw(tmp_g)
4799 CALL pw_pool%create_pw(vxc_g)
4800 ELSE
4801 ! remember to refix for gapw
4802 cpabort("XC_DERIV method is not implemented in GAPW")
4803 END IF
4804 END IF
4805
4806 END IF
4807
4808 ! Initialize mGGA potential
4809 IF (tau_f) THEN
4810 cpassert(ASSOCIATED(v_xc_tau))
4811 DO ispin = 1, nspins
4812 v_xc_tau(ispin)%array = 0.0_dp
4813 END DO
4814 END IF
4815
4816 IF (lsd) THEN
4817
4818 !-------------------!
4819 ! UNrestricted case !
4820 !-------------------!
4821
4822 IF (do_spinflip) THEN
4823 CALL xc_rho_set_get(rho1_set, rhoa=rho1a)
4824 CALL xc_rho_set_get(rho_set, rhoa=rhoa, rhob=rhob)
4825 ELSE
4826 CALL xc_rho_set_get(rho1_set, rhoa=rho1a, rhob=rho1b)
4827 END IF
4828
4829 IF (gradient_f) THEN
4830 CALL xc_rho_set_get(rho_set, drhoa=drhoa, drhob=drhob, &
4831 norm_drho=norm_drho, norm_drhoa=norm_drhoa, norm_drhob=norm_drhob)
4832 IF (do_spinflip) THEN
4833 CALL xc_rho_set_get(rho1_set, drhoa=drho1a)
4834 CALL calc_drho_from_a(drho1, drho1a)
4835 ELSE
4836 CALL xc_rho_set_get(rho1_set, drhoa=drho1a, drhob=drho1b)
4837 CALL calc_drho_from_ab(drho1, drho1a, drho1b)
4838 END IF
4839
4840 CALL calc_drho_from_ab(drho, drhoa, drhob)
4841
4842 CALL prepare_dr1dr(dra1dra, drhoa, drho1a)
4843 IF (do_spinflip) THEN
4844 CALL prepare_dr1dr(drb1drb, drhob, drho1a)
4845 CALL prepare_dr1dr(dr1dr, drho, drho1a)
4846 ELSE IF (nspins /= 1) THEN
4847 CALL prepare_dr1dr(drb1drb, drhob, drho1b)
4848 CALL prepare_dr1dr(dr1dr, drho, drho1)
4849 ELSE
4850 cpabort("Exchange-correlation's third derivative for closed-shell not yet implemented")
4851 END IF
4852
4853 ! Create vectors for partial integration term
4854 ALLOCATE (v_drhoa(nspins), v_drhob(nspins))
4855 DO ispin = 1, nspins
4856 CALL allocate_pw(v_drhoa(ispin), pw_pool, bo)
4857 CALL allocate_pw(v_drhob(ispin), pw_pool, bo)
4858 END DO
4859
4860 END IF
4861
4862 IF (laplace_f) THEN
4863 cpabort("Exchange-correlation's laplace analytic third derivative not implemented")
4864 END IF
4865
4866 IF (tau_f) THEN
4867 cpabort("Exchange-correlation's mGGA analytic third derivative not implemented")
4868 END IF
4869
4870 IF (nspins /= 1) THEN
4871
4872 IF (.NOT. do_spinflip) THEN
4873 ! Analytic third derivative of the excchange-correlation functional
4874 cpabort("Exchange-correlation's analytic third derivative not implemented")
4875
4876 ELSE
4877
4878 ! vxc contributions
4879 ! vxca = (vxc^{\alpha}-vxc^{\beta})*rho1/|rhoa-rhob|^2
4880 ! vxcb =-(vxc^{\alpha}-vxc^{\beta})*rho1/|rhoa-rhob|^2
4881 ! Alpha LDA contribution
4882 ! | d e_xc d e_xc | rho1a
4883 ! vxca = rho1a*|-------- - --------|*---------------
4884 ! | drhoa drhob | |rhoa - rhob|^2
4885 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa])
4886 IF (ASSOCIATED(deriv_att)) THEN
4887 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4888 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob])
4889 IF (ASSOCIATED(deriv_att)) THEN
4890 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
4891!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
4892!$OMP SHARED(bo,v_xc,deriv_data,deriv_data2,rho1a,rhoa,rhob,S_THRESH2) COLLAPSE(3)
4893 DO k = bo(1, 3), bo(2, 3)
4894 DO j = bo(1, 2), bo(2, 2)
4895 DO i = bo(1, 1), bo(2, 1)
4896 s = rhoa(i, j, k) - rhob(i, j, k)
4897 s = -sign(max(s**2, s_thresh2), s)
4898 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
4899 (deriv_data(i, j, k) - deriv_data2(i, j, k))*rho1a(i, j, k)**2/s
4900 END DO
4901 END DO
4902 END DO
4903!$OMP END PARALLEL DO
4904 END IF
4905 END IF
4906 ! GGA contributions to the spin-flip xcKernel
4907 ! Alpha GGA contributions
4908 ! | d e_xc d e_xc | rho1a
4909 ! vxca += + |----------*dra1dra - ----------*drb1drb|*---------------
4910 ! | d|drhoa| d|drhob| | |rhoa - rhob|^2
4911 IF (.NOT. alda0) THEN
4912 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa])
4913 IF (ASSOCIATED(deriv_att)) THEN
4914 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4915 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob])
4916 IF (ASSOCIATED(deriv_att)) THEN
4917 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
4918!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
4919!$OMP SHARED(bo,deriv_data,deriv_data2,dra1dra,drb1drb,v_xc,rho1a,rhoa,rhob,S_THRESH2) COLLAPSE(3)
4920 DO k = bo(1, 3), bo(2, 3)
4921 DO j = bo(1, 2), bo(2, 2)
4922 DO i = bo(1, 1), bo(2, 1)
4923 s = rhoa(i, j, k) - rhob(i, j, k)
4924 s = -sign(max(s**2, s_thresh2), s)
4925 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
4926 (deriv_data(i, j, k)*dra1dra(i, j, k) - deriv_data2(i, j, k)*drb1drb(i, j, k)) &
4927 *rho1a(i, j, k)/s
4928 END DO
4929 END DO
4930 END DO
4931!$OMP END PARALLEL DO
4932 END IF
4933 END IF
4934 END IF
4935 ! Beta contribution = - alpha
4936!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
4937!$OMP SHARED(bo,v_xc) COLLAPSE(3)
4938 DO k = bo(1, 3), bo(2, 3)
4939 DO j = bo(1, 2), bo(2, 2)
4940 DO i = bo(1, 1), bo(2, 1)
4941 v_xc(2)%array(i, j, k) = -v_xc(1)%array(i, j, k)
4942 END DO
4943 END DO
4944 END DO
4945!$OMP END PARALLEL DO
4946 ! fxc contributions
4947 ! vxca = rho1*(fxc^{\alpha\alpha}-fxc^{\alpha\beta})*rho1/|rhoa-rhob|
4948 ! vxcb = rho1*(fxc^{\beta\alpha}-fxc^{\beta\beta})*rho1/|rhoa-rhob|
4949 ! Alpha LDA contribution
4950 ! | d^2 e_xc d^2 e_xc | rho1a
4951 ! vxca += rho1a*|------------- - -------------|*-------------
4952 ! | drhoa drhoa drhoa drhob | |rhoa - rhob|
4953 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhob])
4954 IF (ASSOCIATED(deriv_att)) THEN
4955 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
4956 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa])
4957 IF (ASSOCIATED(deriv_att)) THEN
4958 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4959!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
4960!$OMP SHARED(bo,deriv_data,deriv_data2,rho1a,v_xc,rhoa,rhob,S_THRESH) COLLAPSE(3)
4961 DO k = bo(1, 3), bo(2, 3)
4962 DO j = bo(1, 2), bo(2, 2)
4963 DO i = bo(1, 1), bo(2, 1)
4964 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
4965 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
4966 rho1a(i, j, k)**2*(deriv_data(i, j, k) - deriv_data2(i, j, k))/s
4967 END DO
4968 END DO
4969 END DO
4970!$OMP END PARALLEL DO
4971 END IF
4972 END IF
4973 ! Beta LDA contribution
4974 ! | d^2 e_xc d^2 e_xc | rho1a
4975 ! vxcb += rho1a*|------------- - -------------|*-------------
4976 ! | drhob drhoa drhob drhob | |rhoa - rhob|
4977 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob])
4978 IF (ASSOCIATED(deriv_att)) THEN
4979 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
4980 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhoa])
4981 IF (ASSOCIATED(deriv_att)) THEN
4982 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
4983!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
4984!$OMP SHARED(bo,deriv_data,deriv_data2,rho1a,v_xc,rhoa,rhob,S_THRESH) COLLAPSE(3)
4985 DO k = bo(1, 3), bo(2, 3)
4986 DO j = bo(1, 2), bo(2, 2)
4987 DO i = bo(1, 1), bo(2, 1)
4988 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
4989 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
4990 rho1a(i, j, k)**2*(deriv_data(i, j, k) - deriv_data2(i, j, k))/s
4991 END DO
4992 END DO
4993 END DO
4994!$OMP END PARALLEL DO
4995 END IF
4996 END IF
4997 ! Alpha GGA contribution
4998 IF (.NOT. alda0) THEN
4999 ! rho1a | d^2 e_xc d^2 e_xc |
5000 ! vxca += + -------------*|----------------*dra1dra - ----------------*drb1drb|
5001 ! |rhoa - rhob| | drhoa d|drhoa| drhoa d|drhob| |
5002 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drhob])
5003 IF (ASSOCIATED(deriv_att)) THEN
5004 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
5005 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_norm_drhoa])
5006 IF (ASSOCIATED(deriv_att)) THEN
5007 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5008!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
5009!$OMP SHARED(bo,deriv_data,deriv_data2,dra1dra,drb1drb,rho1a,v_xc,rhoa,rhob,S_THRESH) COLLAPSE(3)
5010 DO k = bo(1, 3), bo(2, 3)
5011 DO j = bo(1, 2), bo(2, 2)
5012 DO i = bo(1, 1), bo(2, 1)
5013 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
5014 v_xc(1)%array(i, j, k) = v_xc(1)%array(i, j, k) + &
5015 (deriv_data(i, j, k)*dra1dra(i, j, k) - deriv_data2(i, j, k)*drb1drb(i, j, k))* &
5016 rho1a(i, j, k)/s
5017 END DO
5018 END DO
5019 END DO
5020!$OMP END PARALLEL DO
5021 END IF
5022 END IF
5023 ! Beta GGA contribution
5024 ! rho1a | d^2 e_xc d^2 e_xc |
5025 ! vxcb += + -------------*|----------------*dra1dra - ----------------*drb1drb|
5026 ! |rhoa - rhob| | drhob d|drhoa| drhob d|drhob| |
5027 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_norm_drhob])
5028 IF (ASSOCIATED(deriv_att)) THEN
5029 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
5030 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_norm_drhoa])
5031 IF (ASSOCIATED(deriv_att)) THEN
5032 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5033!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
5034!$OMP SHARED(bo,deriv_data,deriv_data2,dra1dra,drb1drb,rho1a,v_xc,rhoa,rhob,S_THRESH) COLLAPSE(3)
5035 DO k = bo(1, 3), bo(2, 3)
5036 DO j = bo(1, 2), bo(2, 2)
5037 DO i = bo(1, 1), bo(2, 1)
5038 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
5039 v_xc(2)%array(i, j, k) = v_xc(2)%array(i, j, k) + &
5040 (deriv_data(i, j, k)*dra1dra(i, j, k) - deriv_data2(i, j, k)*drb1drb(i, j, k))* &
5041 rho1a(i, j, k)/s
5042 END DO
5043 END DO
5044 END DO
5045!$OMP END PARALLEL DO
5046 END IF
5047 END IF
5048 !
5049 !
5050 ! Calculate the vector for the partial integration term of GGA functionals
5051 ! First contribution alpha
5052 ! | d^2 e_xc d^2 e_xc |
5053 ! v_drhoa(1) += -|---------------- - ----------------|*rho1a
5054 ! | d|drhoa| drhoa d|drhoa| drhob |
5055 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhob])
5056 IF (ASSOCIATED(deriv_att)) THEN
5057 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
5058 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_rhoa])
5059 IF (ASSOCIATED(deriv_att)) THEN
5060 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5061!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
5062!$OMP SHARED(bo,deriv_data,deriv_data2,rho1a,v_drhoa) COLLAPSE(3)
5063 DO k = bo(1, 3), bo(2, 3)
5064 DO j = bo(1, 2), bo(2, 2)
5065 DO i = bo(1, 1), bo(2, 1)
5066 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
5067 (deriv_data(i, j, k) - deriv_data2(i, j, k))*rho1a(i, j, k)
5068 END DO
5069 END DO
5070 END DO
5071!$OMP END PARALLEL DO
5072 END IF
5073 END IF
5074 ! First contribution beta
5075 ! | d^2 e_xc d^2 e_xc |
5076 ! v_drhob(2) += +|---------------- - ----------------|*rho1a
5077 ! | d|drhob| drhob d|drhob| drhoa |
5078 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhoa])
5079 IF (ASSOCIATED(deriv_att)) THEN
5080 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
5081 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_rhob])
5082 IF (ASSOCIATED(deriv_att)) THEN
5083 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5084!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
5085!$OMP SHARED(bo,deriv_data,deriv_data2,rho1a,v_drhob) COLLAPSE(3)
5086 DO k = bo(1, 3), bo(2, 3)
5087 DO j = bo(1, 2), bo(2, 2)
5088 DO i = bo(1, 1), bo(2, 1)
5089 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) + &
5090 (deriv_data(i, j, k) - deriv_data2(i, j, k))*rho1a(i, j, k)
5091 END DO
5092 END DO
5093 END DO
5094!$OMP END PARALLEL DO
5095 END IF
5096 END IF
5097 ! First contribution spinless
5098 ! | d^2 e_xc d^2 e_xc |
5099 ! v_drho(1) += -|--------------- - ---------------|*rho1a
5100 ! | d|drho| drhoa d|drho| drhob |
5101 !
5102 ! | d^2 e_xc d^2 e_xc |
5103 ! v_drho(2) += -|--------------- - ---------------|*rho1a
5104 ! | d|drho| drhoa d|drho| drhob |
5105 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhoa])
5106 IF (ASSOCIATED(deriv_att)) THEN
5107 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5108 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_rhob])
5109 IF (ASSOCIATED(deriv_att)) THEN
5110 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
5111!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
5112!$OMP SHARED(bo,deriv_data,deriv_data2,rho1a,v_drho) COLLAPSE(3)
5113 DO k = bo(1, 3), bo(2, 3)
5114 DO j = bo(1, 2), bo(2, 2)
5115 DO i = bo(1, 1), bo(2, 1)
5116 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
5117 (deriv_data(i, j, k) - deriv_data2(i, j, k))*rho1a(i, j, k)
5118 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
5119 (deriv_data(i, j, k) - deriv_data2(i, j, k))*rho1a(i, j, k)
5120 END DO
5121 END DO
5122 END DO
5123!$OMP END PARALLEL DO
5124 END IF
5125 END IF
5126 ! Second contribution
5127 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhob])
5128 IF (ASSOCIATED(deriv_att)) THEN
5129 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
5130 ! d^2 e_xc d^2 e_xc
5131 ! v_drhoa(1) += - -------------------*dra1dra + ------------------*drb1drb
5132 ! d|drhoa| d|drhoa| d|drhoa| d|drhob|
5133 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa, deriv_norm_drhoa])
5134 IF (ASSOCIATED(deriv_att)) THEN
5135 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5136!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
5137!$OMP SHARED(bo,deriv_data,deriv_data2,dra1dra,drb1drb,v_drhoa) COLLAPSE(3)
5138 DO k = bo(1, 3), bo(2, 3)
5139 DO j = bo(1, 2), bo(2, 2)
5140 DO i = bo(1, 1), bo(2, 1)
5141 v_drhoa(1)%array(i, j, k) = v_drhoa(1)%array(i, j, k) - &
5142 deriv_data(i, j, k)*dra1dra(i, j, k) + deriv_data2(i, j, k)*drb1drb(i, j, k)
5143 END DO
5144 END DO
5145 END DO
5146!$OMP END PARALLEL DO
5147 END IF
5148 ! d^2 e_xc d^2 e_xc
5149 ! v_drhob(2) += - -------------------*dra1dra + -------------------*drb1drb
5150 ! d|drhoa| d|drhob| d|drhob| d|drhob|
5151 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob, deriv_norm_drhob])
5152 IF (ASSOCIATED(deriv_att)) THEN
5153 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5154!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
5155!$OMP SHARED(bo,deriv_data,deriv_data2,dra1dra,drb1drb,v_drhob) COLLAPSE(3)
5156 DO k = bo(1, 3), bo(2, 3)
5157 DO j = bo(1, 2), bo(2, 2)
5158 DO i = bo(1, 1), bo(2, 1)
5159 v_drhob(2)%array(i, j, k) = v_drhob(2)%array(i, j, k) - &
5160 deriv_data(i, j, k)*dra1dra(i, j, k) + deriv_data2(i, j, k)*drb1drb(i, j, k)
5161 END DO
5162 END DO
5163 END DO
5164!$OMP END PARALLEL DO
5165 END IF
5166 END IF
5167 ! d^2 e_xc d^2 e_xc
5168 ! v_drho(1) += - ------------------*dra1dra + ------------------*drb1drb
5169 ! d|drho| d|drhoa| d|drho| d|drhob|
5170 !
5171 ! d^2 e_xc d^2 e_xc
5172 ! v_drho(2) += - ------------------*dra1dra + ------------------*drb1drb
5173 ! d|drho| d|drhoa| d|drho| d|drhob|
5174 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhob])
5175 IF (ASSOCIATED(deriv_att)) THEN
5176 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data2)
5177 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho, deriv_norm_drhoa])
5178 IF (ASSOCIATED(deriv_att)) THEN
5179 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5180!$OMP PARALLEL DO PRIVATE(k,j,i) DEFAULT(NONE)&
5181!$OMP SHARED(bo,deriv_data,deriv_data2,dra1dra,drb1drb,v_drho) COLLAPSE(3)
5182 DO k = bo(1, 3), bo(2, 3)
5183 DO j = bo(1, 2), bo(2, 2)
5184 DO i = bo(1, 1), bo(2, 1)
5185 v_drho(1)%array(i, j, k) = v_drho(1)%array(i, j, k) - &
5186 deriv_data(i, j, k)*dra1dra(i, j, k) + &
5187 deriv_data2(i, j, k)*drb1drb(i, j, k)
5188 v_drho(2)%array(i, j, k) = v_drho(2)%array(i, j, k) - &
5189 deriv_data(i, j, k)*dra1dra(i, j, k) + &
5190 deriv_data2(i, j, k)*drb1drb(i, j, k)
5191 END DO
5192 END DO
5193 END DO
5194!$OMP END PARALLEL DO
5195 END IF
5196 END IF
5197 !
5198
5199 ! Last GGA contribution
5200 ! Alpha contribution
5201 ! d e_xc
5202 ! v_drhoa(1) += + ----------*dra1dra
5203 ! d|drhoa|
5204 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa])
5205 IF (ASSOCIATED(deriv_att)) THEN
5206 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5207 CALL xc_derivative_get(deriv_att, deriv_data=e_drhoa)
5208
5209!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dra1dra,gradient_cut,norm_drhoa,v_drhoa,deriv_data)
5210 v_drhoa(1)%array(:, :, :) = v_drhoa(1)%array(:, :, :) + &
5211 deriv_data(:, :, :)*dra1dra(:, :, :)/max(gradient_cut, norm_drhoa(:, :, :))**2
5212!$OMP END PARALLEL WORKSHARE
5213 END IF
5214 ! Beta contribution
5215 ! d e_xc
5216 ! v_drhob(2) += - ----------*drb1drb
5217 ! d|drhob|
5218 deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob])
5219 IF (ASSOCIATED(deriv_att)) THEN
5220 CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
5221 CALL xc_derivative_get(deriv_att, deriv_data=e_drhob)
5222
5223!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(drb1drb,gradient_cut,norm_drhob,v_drhob,deriv_data)
5224 v_drhob(2)%array(:, :, :) = v_drhob(2)%array(:, :, :) - &
5225 deriv_data(:, :, :)*drb1drb(:, :, :)/max(gradient_cut, norm_drhob(:, :, :))**2
5226!$OMP END PARALLEL WORKSHARE
5227 END IF
5228 END IF ! If ALDA0
5229 END IF
5230
5231 ELSE
5232
5233 ! Analytic third derivative for closed-shell
5234 cpabort("Exchange-correlation's analytic third derivative not implemented")
5235
5236 END IF
5237
5238 IF (gradient_f) THEN
5239 IF (.NOT. alda0) THEN
5240
5241 ! partial integration
5242 DO idir = 1, 3
5243
5244 ! GGA contributions to the spin-flip xc-Kernel
5245 !
5246 ! v_drhoa(1)*drhoa(:)*rhoa1 v_drhob(1)*drhob(:)*rhoa1 v_drho(1)*drho(:)*rhoa1
5247 ! v_drho_r(:,1) = --------------------------- + --------------------------- + -------------------------
5248 ! |rhoa - rhob| |rhoa - rhob| |rhoa - rhob|
5249 !
5250 ! v_drhoa(2)*drhoa(:)*rhoa1 v_drhob(2)*drhob(:)*rhoa1 v_drho(2)*drho(:)*rhoa1
5251 ! v_drho_r(:,2) = --------------------------- + --------------------------- + -------------------------
5252 ! |rhoa - rhob| |rhoa - rhob| |rhoa - rhob|
5253 IF (do_spinflip) THEN
5254!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
5255!$OMP SHARED(bo,v_drho_r,v_drho,v_drhoa,v_drhob,rhoa,rhob,drho,drhoa,drhob,rho1a,idir,S_THRESH) COLLAPSE(3)
5256 DO k = bo(1, 3), bo(2, 3)
5257 DO j = bo(1, 2), bo(2, 2)
5258 DO i = bo(1, 1), bo(2, 1)
5259 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
5260 DO ispin = 1, 2
5261 v_drho_r(idir, ispin)%array(i, j, k) = v_drho_r(idir, ispin)%array(i, j, k) + &
5262 v_drhoa(ispin)%array(i, j, k)*drhoa(idir)%array(i, j, k)*rho1a(i, j, k)/s + &
5263 v_drhob(ispin)%array(i, j, k)*drhob(idir)%array(i, j, k)*rho1a(i, j, k)/s + &
5264 v_drho(ispin)%array(i, j, k)*drho(idir)%array(i, j, k)*rho1a(i, j, k)/s
5265 END DO
5266 END DO
5267 END DO
5268 END DO
5269!$OMP END PARALLEL DO
5270 END IF
5271 ! Last GGA contribution
5272 ! Alpha contribution
5273 ! rho1a d e_xc
5274 ! v_drho_r(:,1) += - -------------*----------*drho1a(:)
5275 ! |rhoa - rhob| d|drhoa|
5276 IF (ASSOCIATED(e_drhoa)) THEN
5277!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
5278!$OMP SHARED(bo,e_drhoa,v_drho_r,drho1a,rho1a,rhoa,rhob,S_THRESH,idir) COLLAPSE(3)
5279 DO k = bo(1, 3), bo(2, 3)
5280 DO j = bo(1, 2), bo(2, 2)
5281 DO i = bo(1, 1), bo(2, 1)
5282 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
5283 v_drho_r(idir, 1)%array(i, j, k) = v_drho_r(idir, 1)%array(i, j, k) - &
5284 e_drhoa(i, j, k)*drho1a(idir)%array(i, j, k)*rho1a(i, j, k)/s
5285 END DO
5286 END DO
5287 END DO
5288!$OMP END PARALLEL DO
5289 END IF
5290 ! Beta contribution
5291 ! rho1a d e_xc
5292 ! v_drho_r(:,2) += + -------------*----------*drho1a(:)
5293 ! |rhoa - rhob| d|drhob|
5294 IF (ASSOCIATED(e_drhob)) THEN
5295!$OMP PARALLEL DO PRIVATE(k,j,i,s) DEFAULT(NONE)&
5296!$OMP SHARED(bo,e_drhob,v_drho_r,drho1a,rho1a,rhoa,rhob,S_THRESH,idir) COLLAPSE(3)
5297 DO k = bo(1, 3), bo(2, 3)
5298 DO j = bo(1, 2), bo(2, 2)
5299 DO i = bo(1, 1), bo(2, 1)
5300 s = max(abs(rhoa(i, j, k) - rhob(i, j, k)), s_thresh)
5301 v_drho_r(idir, 2)%array(i, j, k) = v_drho_r(idir, 2)%array(i, j, k) + &
5302 e_drhob(i, j, k)*drho1a(idir)%array(i, j, k)*rho1a(i, j, k)/s
5303 END DO
5304 END DO
5305 END DO
5306!$OMP END PARALLEL DO
5307 END IF
5308 END DO
5309
5310 ! partial integration: v_xc = v_xc - \nabla \cdot vdrho_r
5311 DO ispin = 1, nspins
5312 CALL xc_pw_divergence(xc_deriv_method_id, v_drho_r(:, ispin), tmp_g, vxc_g, v_xc(ispin))
5313 END DO ! ispin
5314 END IF ! ALDA0
5315
5316 DO idir = 1, 3
5317 DEALLOCATE (drho(idir)%array)
5318 DEALLOCATE (drho1(idir)%array)
5319 END DO
5320
5321 DO ispin = 1, nspins
5322 CALL deallocate_pw(v_drhoa(ispin), pw_pool)
5323 CALL deallocate_pw(v_drhob(ispin), pw_pool)
5324 END DO
5325
5326 DEALLOCATE (v_drhoa, v_drhob)
5327
5328 END IF ! gradient_f
5329
5330 ELSE
5331
5332 !-----------------!
5333 ! restricted case !
5334 !-----------------!
5335 cpabort("Exchange-correlation's analytic third derivative not implemented")
5336
5337 END IF
5338
5339 IF (gradient_f) THEN
5340
5341 DO ispin = 1, nspins
5342 CALL deallocate_pw(v_drho(ispin), pw_pool)
5343 DO idir = 1, 3
5344 CALL deallocate_pw(v_drho_r(idir, ispin), pw_pool)
5345 END DO
5346 END DO
5347 DEALLOCATE (v_drho, v_drho_r)
5348
5349 END IF
5350
5351 IF (ASSOCIATED(tmp_g%pw_grid) .AND. ASSOCIATED(pw_pool)) THEN
5352 CALL pw_pool%give_back_pw(tmp_g)
5353 END IF
5354
5355 IF (ASSOCIATED(vxc_g%pw_grid) .AND. ASSOCIATED(pw_pool)) THEN
5356 CALL pw_pool%give_back_pw(vxc_g)
5357 END IF
5358
5359 CALL timestop(handle)
5360 END SUBROUTINE xc_calc_3rd_deriv_analytical
5361
5362! **************************************************************************************************
5363!> \brief allocates grids using pw_pool (if associated) or with bounds
5364!> \param pw ...
5365!> \param pw_pool ...
5366!> \param bo ...
5367! **************************************************************************************************
5368 SUBROUTINE allocate_pw(pw, pw_pool, bo)
5369 TYPE(pw_r3d_rs_type), INTENT(OUT) :: pw
5370 TYPE(pw_pool_type), INTENT(IN), POINTER :: pw_pool
5371 INTEGER, DIMENSION(2, 3), INTENT(IN) :: bo
5372
5373 IF (ASSOCIATED(pw_pool)) THEN
5374 CALL pw_pool%create_pw(pw)
5375 CALL pw_zero(pw)
5376 ELSE
5377 ALLOCATE (pw%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
5378 pw%array = 0.0_dp
5379 END IF
5380
5381 END SUBROUTINE allocate_pw
5382
5383! **************************************************************************************************
5384!> \brief deallocates grid allocated with allocate_pw
5385!> \param pw ...
5386!> \param pw_pool ...
5387! **************************************************************************************************
5388 SUBROUTINE deallocate_pw(pw, pw_pool)
5389 TYPE(pw_r3d_rs_type), INTENT(INOUT) :: pw
5390 TYPE(pw_pool_type), INTENT(IN), POINTER :: pw_pool
5391
5392 IF (ASSOCIATED(pw_pool)) THEN
5393 CALL pw_pool%give_back_pw(pw)
5394 ELSE
5395 CALL pw%release()
5396 END IF
5397
5398 END SUBROUTINE deallocate_pw
5399
5400! **************************************************************************************************
5401!> \brief updates virial from first derivative w.r.t. norm_drho
5402!> \param virial_pw ...
5403!> \param drho ...
5404!> \param drho1 ...
5405!> \param deriv_data ...
5406!> \param virial_xc ...
5407! **************************************************************************************************
5408 SUBROUTINE virial_drho_drho1(virial_pw, drho, drho1, deriv_data, virial_xc)
5409 TYPE(pw_r3d_rs_type), INTENT(IN) :: virial_pw
5410 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(IN) :: drho, drho1
5411 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: deriv_data
5412 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT) :: virial_xc
5413
5414 INTEGER :: idir, jdir
5415 REAL(kind=dp) :: tmp
5416
5417 DO idir = 1, 3
5418!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(drho,idir,virial_pw,deriv_data)
5419 virial_pw%array(:, :, :) = drho(idir)%array(:, :, :)*deriv_data(:, :, :)
5420!$OMP END PARALLEL WORKSHARE
5421 DO jdir = 1, 3
5422 tmp = virial_pw%pw_grid%dvol*accurate_dot_product(virial_pw%array(:, :, :), &
5423 drho1(jdir)%array(:, :, :))
5424 virial_xc(jdir, idir) = virial_xc(jdir, idir) + tmp
5425 virial_xc(idir, jdir) = virial_xc(idir, jdir) + tmp
5426 END DO
5427 END DO
5428
5429 END SUBROUTINE virial_drho_drho1
5430
5431! **************************************************************************************************
5432!> \brief Adds virial contribution from second order potential parts
5433!> \param virial_pw ...
5434!> \param drho ...
5435!> \param v_drho ...
5436!> \param virial_xc ...
5437! **************************************************************************************************
5438 SUBROUTINE virial_drho_drho(virial_pw, drho, v_drho, virial_xc)
5439 TYPE(pw_r3d_rs_type), INTENT(IN) :: virial_pw
5440 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(IN) :: drho
5441 TYPE(pw_r3d_rs_type), INTENT(IN) :: v_drho
5442 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT) :: virial_xc
5443
5444 INTEGER :: idir, jdir
5445 REAL(kind=dp) :: tmp
5446
5447 DO idir = 1, 3
5448!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(drho,idir,v_drho,virial_pw)
5449 virial_pw%array(:, :, :) = drho(idir)%array(:, :, :)*v_drho%array(:, :, :)
5450!$OMP END PARALLEL WORKSHARE
5451 DO jdir = 1, idir
5452 tmp = -virial_pw%pw_grid%dvol*accurate_dot_product(virial_pw%array(:, :, :), &
5453 drho(jdir)%array(:, :, :))
5454 virial_xc(jdir, idir) = virial_xc(jdir, idir) + tmp
5455 virial_xc(idir, jdir) = virial_xc(jdir, idir)
5456 END DO
5457 END DO
5458
5459 END SUBROUTINE virial_drho_drho
5460
5461! **************************************************************************************************
5462!> \brief ...
5463!> \param rho_r ...
5464!> \param pw_pool ...
5465!> \param virial_xc ...
5466!> \param deriv_data ...
5467! **************************************************************************************************
5468 SUBROUTINE virial_laplace(rho_r, pw_pool, virial_xc, deriv_data)
5469 TYPE(pw_r3d_rs_type), TARGET :: rho_r
5470 TYPE(pw_pool_type), POINTER, INTENT(IN) :: pw_pool
5471 REAL(kind=dp), DIMENSION(3, 3), INTENT(INOUT) :: virial_xc
5472 REAL(kind=dp), DIMENSION(:, :, :), INTENT(IN) :: deriv_data
5473
5474 CHARACTER(len=*), PARAMETER :: routinen = 'virial_laplace'
5475
5476 INTEGER :: handle, idir, jdir
5477 TYPE(pw_r3d_rs_type), POINTER :: virial_pw
5478 TYPE(pw_c1d_gs_type), POINTER :: tmp_g, rho_g
5479 INTEGER, DIMENSION(3) :: my_deriv
5480
5481 CALL timeset(routinen, handle)
5482
5483 NULLIFY (virial_pw, tmp_g, rho_g)
5484 ALLOCATE (virial_pw, tmp_g, rho_g)
5485 CALL pw_pool%create_pw(virial_pw)
5486 CALL pw_pool%create_pw(tmp_g)
5487 CALL pw_pool%create_pw(rho_g)
5488 CALL pw_zero(virial_pw)
5489 CALL pw_transfer(rho_r, rho_g)
5490 DO idir = 1, 3
5491 DO jdir = idir, 3
5492 CALL pw_copy(rho_g, tmp_g)
5493
5494 my_deriv = 0
5495 my_deriv(idir) = 1
5496 my_deriv(jdir) = my_deriv(jdir) + 1
5497
5498 CALL pw_derive(tmp_g, my_deriv)
5499 CALL pw_transfer(tmp_g, virial_pw)
5500 virial_xc(idir, jdir) = virial_xc(idir, jdir) - 2.0_dp*virial_pw%pw_grid%dvol* &
5501 accurate_dot_product(virial_pw%array(:, :, :), &
5502 deriv_data(:, :, :))
5503 virial_xc(jdir, idir) = virial_xc(idir, jdir)
5504 END DO
5505 END DO
5506 CALL pw_pool%give_back_pw(virial_pw)
5507 CALL pw_pool%give_back_pw(tmp_g)
5508 CALL pw_pool%give_back_pw(rho_g)
5509 DEALLOCATE (virial_pw, tmp_g, rho_g)
5510
5511 CALL timestop(handle)
5512
5513 END SUBROUTINE virial_laplace
5514
5515! **************************************************************************************************
5516!> \brief Prepare objects for the calculation of the 2nd derivatives of the density functional.
5517!> The calculation must then be performed with xc_calc_2nd_deriv.
5518!> \param deriv_set object containing the XC derivatives (out)
5519!> \param rho_set object that will contain the density at which the
5520!> derivatives were calculated
5521!> \param rho_r the place where you evaluate the derivative
5522!> \param pw_pool the pool for the grids
5523!> \param weights integration weights
5524!> \param xc_section which functional should be used and how to calculate it
5525!> \param tau_r kinetic energy density in real space
5526! **************************************************************************************************
5527 SUBROUTINE xc_prep_2nd_deriv(deriv_set, &
5528 rho_set, rho_r, pw_pool, weights, xc_section, tau_r)
5529
5530 TYPE(xc_derivative_set_type) :: deriv_set
5531 TYPE(xc_rho_set_type) :: rho_set
5532 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
5533 TYPE(pw_pool_type), POINTER :: pw_pool
5534 TYPE(pw_r3d_rs_type), POINTER :: weights
5535 TYPE(section_vals_type), POINTER :: xc_section
5536 TYPE(pw_r3d_rs_type), DIMENSION(:), &
5537 OPTIONAL, POINTER :: tau_r
5538
5539 CHARACTER(len=*), PARAMETER :: routinen = 'xc_prep_2nd_deriv'
5540
5541 INTEGER :: handle, nspins
5542 LOGICAL :: lsd
5543 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
5544 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: tau
5545
5546 CALL timeset(routinen, handle)
5547
5548 cpassert(ASSOCIATED(xc_section))
5549 cpassert(ASSOCIATED(pw_pool))
5550
5551 IF (xc_section_uses_gauxc(xc_section)) THEN
5552 CALL cp_abort(__location__, gauxc_high_deriv_message)
5553 END IF
5554
5555 nspins = SIZE(rho_r)
5556 lsd = (nspins /= 1)
5557
5558 NULLIFY (rho_g, tau)
5559 IF (PRESENT(tau_r)) &
5560 tau => tau_r
5561
5562 IF (section_get_lval(xc_section, "2ND_DERIV_ANALYTICAL")) THEN
5563 CALL xc_rho_set_and_dset_create(rho_set, deriv_set, 2, &
5564 rho_r, rho_g, tau, xc_section, pw_pool, weights, &
5565 calc_potential=.true.)
5566 ELSE
5567 CALL xc_rho_set_and_dset_create(rho_set, deriv_set, 1, &
5568 rho_r, rho_g, tau, xc_section, pw_pool, weights, &
5569 calc_potential=.true.)
5570 END IF
5571
5572 CALL timestop(handle)
5573
5574 END SUBROUTINE xc_prep_2nd_deriv
5575
5576! **************************************************************************************************
5577!> \brief Prepare deriv_set for the calculation of the 3rd derivatives of the density functional.
5578!> The calculation must then be performed with xc_calc_3rd_deriv.
5579!> \param deriv_set object containing the XC derivatives (out)
5580!> \param rho_set object that will contain the density at which the
5581!> derivatives were calculated
5582!> \param rho_r the place where you evaluate the derivative
5583!> \param pw_pool the pool for the grids
5584!> \param weights integration weights
5585!> \param xc_section which functional should be used and how to calculate it
5586!> \param tau_r kinetic energy density in real space
5587!> \param do_sf Flag to activate the noncollinear kernel for spin flip calculations
5588!> \par History
5589!> * 07.2024 Created [LHS]
5590! **************************************************************************************************
5591 SUBROUTINE xc_prep_3rd_deriv(deriv_set, rho_set, rho_r, pw_pool, weights, &
5592 xc_section, tau_r, do_sf)
5593
5594 TYPE(xc_derivative_set_type) :: deriv_set
5595 TYPE(xc_rho_set_type) :: rho_set
5596 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
5597 TYPE(pw_pool_type), POINTER :: pw_pool
5598 TYPE(pw_r3d_rs_type), POINTER :: weights
5599 TYPE(section_vals_type), POINTER :: xc_section
5600 TYPE(pw_r3d_rs_type), DIMENSION(:), &
5601 OPTIONAL, POINTER :: tau_r
5602 LOGICAL, OPTIONAL :: do_sf
5603
5604 CHARACTER(len=*), PARAMETER :: routinen = 'xc_prep_3rd_deriv'
5605
5606 INTEGER :: handle, nspins
5607 LOGICAL :: lsd, my_do_sf
5608 TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
5609 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: tau
5610
5611 CALL timeset(routinen, handle)
5612
5613 cpassert(ASSOCIATED(xc_section))
5614 cpassert(ASSOCIATED(pw_pool))
5615
5616 IF (xc_section_uses_gauxc(xc_section)) THEN
5617 CALL cp_abort(__location__, gauxc_high_deriv_message)
5618 END IF
5619
5620 nspins = SIZE(rho_r)
5621 lsd = (nspins /= 1)
5622
5623 NULLIFY (rho_g, tau)
5624 IF (PRESENT(tau_r)) &
5625 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) &
5734 cpabort(trim(id_to_desc(split_desc(idesc)))//" not handled in lsd!'")
5736 CASE default
5737 cpabort("Unknown derivative id")
5738 END SELECT
5739 END DO
5740 END DO
5741
5742 END SUBROUTINE divide_by_norm_drho
5743
5744! **************************************************************************************************
5745!> \brief allocates and calculates drho from given spin densities drhoa, drhob
5746!> \param drho ...
5747!> \param drhoa ...
5748!> \param drhob ...
5749! **************************************************************************************************
5750 SUBROUTINE calc_drho_from_ab(drho, drhoa, drhob)
5751 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(OUT) :: drho
5752 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(IN) :: drhoa, drhob
5753
5754 CHARACTER(len=*), PARAMETER :: routinen = 'calc_drho_from_ab'
5755
5756 INTEGER :: handle, idir
5757
5758 CALL timeset(routinen, handle)
5759
5760 DO idir = 1, 3
5761 NULLIFY (drho(idir)%array)
5762 ALLOCATE (drho(idir)%array(lbound(drhoa(1)%array, 1):ubound(drhoa(1)%array, 1), &
5763 lbound(drhoa(1)%array, 2):ubound(drhoa(1)%array, 2), &
5764 lbound(drhoa(1)%array, 3):ubound(drhoa(1)%array, 3)))
5765!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(drho,drhoa,drhob,idir)
5766 drho(idir)%array(:, :, :) = drhoa(idir)%array(:, :, :) + drhob(idir)%array(:, :, :)
5767!$OMP END PARALLEL WORKSHARE
5768 END DO
5769
5770 CALL timestop(handle)
5771
5772 END SUBROUTINE calc_drho_from_ab
5773
5774! **************************************************************************************************
5775!> \brief allocates and calculates drho from given spin densities drhoa, drhob
5776!> \param drho ...
5777!> \param drhoa ...
5778!> \param drhob ...
5779! **************************************************************************************************
5780 SUBROUTINE calc_drho_from_a(drho, drhoa)
5781 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(OUT) :: drho
5782 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(IN) :: drhoa
5783
5784 CHARACTER(len=*), PARAMETER :: routinen = 'calc_drho_from_a'
5785
5786 INTEGER :: handle, idir
5787
5788 CALL timeset(routinen, handle)
5789
5790 DO idir = 1, 3
5791 NULLIFY (drho(idir)%array)
5792 ALLOCATE (drho(idir)%array(lbound(drhoa(1)%array, 1):ubound(drhoa(1)%array, 1), &
5793 lbound(drhoa(1)%array, 2):ubound(drhoa(1)%array, 2), &
5794 lbound(drhoa(1)%array, 3):ubound(drhoa(1)%array, 3)))
5795!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(drho,drhoa,idir)
5796 drho(idir)%array(:, :, :) = drhoa(idir)%array(:, :, :)
5797!$OMP END PARALLEL WORKSHARE
5798 END DO
5799
5800 CALL timestop(handle)
5801
5802 END SUBROUTINE calc_drho_from_a
5803
5804! **************************************************************************************************
5805!> \brief allocates and calculates dot products of two density gradients
5806!> \param dr1dr ...
5807!> \param drho ...
5808!> \param drho1 ...
5809! **************************************************************************************************
5810 SUBROUTINE prepare_dr1dr(dr1dr, drho, drho1)
5811 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :), &
5812 INTENT(OUT) :: dr1dr
5813 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(IN) :: drho, drho1
5814
5815 CHARACTER(len=*), PARAMETER :: routinen = 'prepare_dr1dr'
5816
5817 INTEGER :: handle, idir
5818
5819 CALL timeset(routinen, handle)
5820
5821 ALLOCATE (dr1dr(lbound(drho(1)%array, 1):ubound(drho(1)%array, 1), &
5822 lbound(drho(1)%array, 2):ubound(drho(1)%array, 2), &
5823 lbound(drho(1)%array, 3):ubound(drho(1)%array, 3)))
5824
5825!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dr1dr,drho,drho1)
5826 dr1dr(:, :, :) = drho(1)%array(:, :, :)*drho1(1)%array(:, :, :)
5827!$OMP END PARALLEL WORKSHARE
5828 DO idir = 2, 3
5829!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(dr1dr,drho,drho1,idir)
5830 dr1dr(:, :, :) = dr1dr(:, :, :) + drho(idir)%array(:, :, :)*drho1(idir)%array(:, :, :)
5831!$OMP END PARALLEL WORKSHARE
5832 END DO
5833
5834 CALL timestop(handle)
5835
5836 END SUBROUTINE prepare_dr1dr
5837
5838! **************************************************************************************************
5839!> \brief allocates and calculates dot product of two densities for triplets
5840!> \param dr1dr ...
5841!> \param drhoa ...
5842!> \param drhob ...
5843!> \param drho1a ...
5844!> \param drho1b ...
5845!> \param fac ...
5846! **************************************************************************************************
5847 SUBROUTINE prepare_dr1dr_ab(dr1dr, drhoa, drhob, drho1a, drho1b, fac)
5848 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :), &
5849 INTENT(OUT) :: dr1dr
5850 TYPE(cp_3d_r_cp_type), DIMENSION(3), INTENT(IN) :: drhoa, drhob, drho1a, drho1b
5851 REAL(kind=dp), INTENT(IN) :: fac
5852
5853 CHARACTER(len=*), PARAMETER :: routinen = 'prepare_dr1dr_ab'
5854
5855 INTEGER :: handle, idir
5856
5857 CALL timeset(routinen, handle)
5858
5859 ALLOCATE (dr1dr(lbound(drhoa(1)%array, 1):ubound(drhoa(1)%array, 1), &
5860 lbound(drhoa(1)%array, 2):ubound(drhoa(1)%array, 2), &
5861 lbound(drhoa(1)%array, 3):ubound(drhoa(1)%array, 3)))
5862
5863!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(fac,dr1dr,drho1a,drho1b,drhoa,drhob)
5864 dr1dr(:, :, :) = drhoa(1)%array(:, :, :)*(drho1a(1)%array(:, :, :) + &
5865 fac*drho1b(1)%array(:, :, :)) + &
5866 drhob(1)%array(:, :, :)*(fac*drho1a(1)%array(:, :, :) + &
5867 drho1b(1)%array(:, :, :))
5868!$OMP END PARALLEL WORKSHARE
5869 DO idir = 2, 3
5870!$OMP PARALLEL WORKSHARE DEFAULT(NONE) SHARED(fac,dr1dr,drho1a,drho1b,drhoa,drhob,idir)
5871 dr1dr(:, :, :) = dr1dr(:, :, :) + &
5872 drhoa(idir)%array(:, :, :)*(drho1a(idir)%array(:, :, :) + &
5873 fac*drho1b(idir)%array(:, :, :)) + &
5874 drhob(idir)%array(:, :, :)*(fac*drho1a(idir)%array(:, :, :) + &
5875 drho1b(idir)%array(:, :, :))
5876!$OMP END PARALLEL WORKSHARE
5877 END DO
5878
5879 CALL timestop(handle)
5880
5881 END SUBROUTINE prepare_dr1dr_ab
5882
5883! **************************************************************************************************
5884!> \brief checks for gradients
5885!> \param deriv_set ...
5886!> \param lsd ...
5887!> \param gradient_f ...
5888!> \param tau_f ...
5889!> \param laplace_f ...
5890! **************************************************************************************************
5891 SUBROUTINE check_for_derivatives(deriv_set, lsd, rho_f, gradient_f, tau_f, laplace_f)
5892 TYPE(xc_derivative_set_type), INTENT(IN) :: deriv_set
5893 LOGICAL, INTENT(IN) :: lsd
5894 LOGICAL, INTENT(OUT) :: rho_f, gradient_f, tau_f, laplace_f
5895
5896 CHARACTER(len=*), PARAMETER :: routinen = 'check_for_derivatives'
5897
5898 INTEGER :: handle, iorder, order
5899 INTEGER, DIMENSION(:), POINTER :: split_desc
5900 TYPE(cp_sll_xc_deriv_type), POINTER :: pos
5901 TYPE(xc_derivative_type), POINTER :: deriv_att
5902
5903 CALL timeset(routinen, handle)
5904
5905 rho_f = .false.
5906 gradient_f = .false.
5907 tau_f = .false.
5908 laplace_f = .false.
5909 ! check for unknown derivatives
5910 pos => deriv_set%derivs
5911 DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
5912 CALL xc_derivative_get(deriv_att, order=order, &
5913 split_desc=split_desc)
5914 IF (lsd) THEN
5915 DO iorder = 1, size(split_desc)
5916 SELECT CASE (split_desc(iorder))
5917 CASE (deriv_rhoa, deriv_rhob)
5918 rho_f = .true.
5920 gradient_f = .true.
5921 CASE (deriv_tau_a, deriv_tau_b)
5922 tau_f = .true.
5924 laplace_f = .true.
5926 cpabort("Derivative not handled in lsd!")
5927 CASE default
5928 cpabort("Unknown derivative id")
5929 END SELECT
5930 END DO
5931 ELSE
5932 DO iorder = 1, size(split_desc)
5933 SELECT CASE (split_desc(iorder))
5934 CASE (deriv_rho)
5935 rho_f = .true.
5936 CASE (deriv_tau)
5937 tau_f = .true.
5938 CASE (deriv_norm_drho)
5939 gradient_f = .true.
5940 CASE (deriv_laplace_rho)
5941 laplace_f = .true.
5942 CASE default
5943 cpabort("Unknown derivative id")
5944 END SELECT
5945 END DO
5946 END IF
5947 END DO
5948
5949 CALL timestop(handle)
5950
5951 END SUBROUTINE check_for_derivatives
5952
5953END MODULE xc
5954
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:5537
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:2055
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:1061
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:4733
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:5601
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