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