Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief routines that build the integrals of the Vxc potential calculated
10 : !> for the atomic density in the basis set of spherical primitives
11 : ! **************************************************************************************************
12 : MODULE qs_vxc_atom
13 : USE atomic_kind_types, ONLY: atomic_kind_type,&
14 : get_atomic_kind
15 : USE basis_set_types, ONLY: get_gto_basis_set,&
16 : gto_basis_set_type
17 : USE cp_control_types, ONLY: dft_control_type
18 : USE input_constants, ONLY: xc_none
19 : USE input_section_types, ONLY: section_vals_get_subs_vals,&
20 : section_vals_type,&
21 : section_vals_val_get
22 : USE kinds, ONLY: dp
23 : USE memory_utilities, ONLY: reallocate
24 : USE message_passing, ONLY: mp_para_env_type
25 : USE orbital_pointers, ONLY: indso,&
26 : nsoset
27 : USE paw_basis_types, ONLY: get_paw_basis_info
28 : USE qs_environment_types, ONLY: get_qs_env,&
29 : qs_environment_type
30 : USE qs_grid_atom, ONLY: grid_atom_type
31 : USE qs_harmonics_atom, ONLY: get_none0_cg_list,&
32 : harmonics_atom_type
33 : USE qs_kind_types, ONLY: get_qs_kind,&
34 : has_nlcc,&
35 : qs_kind_type
36 : USE qs_linres_types, ONLY: nablavks_atom_type
37 : USE qs_rho_atom_types, ONLY: get_rho_atom,&
38 : rho_atom_coeff,&
39 : rho_atom_type
40 : USE util, ONLY: get_limit
41 : USE xc_atom, ONLY: fill_rho_set,&
42 : vxc_of_r_new,&
43 : xc_2nd_deriv_of_r,&
44 : xc_rho_set_atom_update
45 : USE xc_derivative_set_types, ONLY: xc_derivative_set_type,&
46 : xc_dset_create,&
47 : xc_dset_release,&
48 : xc_dset_zero_all
49 : USE xc_derivatives, ONLY: xc_functionals_get_needs
50 : USE xc_rho_cflags_types, ONLY: xc_rho_cflags_type
51 : USE xc_rho_set_types, ONLY: xc_rho_set_create,&
52 : xc_rho_set_release,&
53 : xc_rho_set_type
54 : #include "./base/base_uses.f90"
55 :
56 : IMPLICIT NONE
57 :
58 : PRIVATE
59 :
60 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_vxc_atom'
61 :
62 : PUBLIC :: calculate_vxc_atom, &
63 : calculate_xc_2nd_deriv_atom, &
64 : calc_rho_angular, &
65 : calculate_gfxc_atom, &
66 : gfxc_atom_diff, &
67 : gaVxcgb_noGC
68 :
69 : CONTAINS
70 :
71 : ! **************************************************************************************************
72 : !> \brief ...
73 : !> \param qs_env ...
74 : !> \param energy_only ...
75 : !> \param exc1 the on-body ex energy contribution
76 : !> \param gradient_atom_set ...
77 : !> \param adiabatic_rescale_factor ...
78 : !> \param kind_set_external provides a non-default kind_set to use
79 : !> \param rho_atom_set_external provides a non-default atomic density set to use
80 : !> \param xc_section_external provides an external non-default XC
81 : ! **************************************************************************************************
82 57162 : SUBROUTINE calculate_vxc_atom(qs_env, energy_only, exc1, gradient_atom_set, &
83 : adiabatic_rescale_factor, kind_set_external, &
84 : rho_atom_set_external, xc_section_external)
85 :
86 : TYPE(qs_environment_type), POINTER :: qs_env
87 : LOGICAL, INTENT(IN) :: energy_only
88 : REAL(dp), INTENT(INOUT) :: exc1
89 : TYPE(nablavks_atom_type), DIMENSION(:), OPTIONAL, &
90 : POINTER :: gradient_atom_set
91 : REAL(dp), INTENT(IN), OPTIONAL :: adiabatic_rescale_factor
92 : TYPE(qs_kind_type), DIMENSION(:), OPTIONAL, &
93 : POINTER :: kind_set_external
94 : TYPE(rho_atom_type), DIMENSION(:), OPTIONAL, &
95 : POINTER :: rho_atom_set_external
96 : TYPE(section_vals_type), OPTIONAL, POINTER :: xc_section_external
97 :
98 : CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_vxc_atom'
99 :
100 : INTEGER :: bo(2), handle, ia, iat, iatom, idir, &
101 : ikind, ir, ispin, myfun, na, natom, &
102 : nr, nspins, num_pe
103 : INTEGER, DIMENSION(2, 3) :: bounds
104 19054 : INTEGER, DIMENSION(:), POINTER :: atom_list
105 : LOGICAL :: donlcc, epr_xc, gradient_f, lsd, nlcc, &
106 : paw_atom, tau_f
107 : REAL(dp) :: density_cut, exc_h, exc_s, gradient_cut, &
108 : my_adiabatic_rescale_factor, tau_cut
109 : REAL(dp), DIMENSION(1, 1, 1) :: tau_d
110 : REAL(dp), DIMENSION(1, 1, 1, 1) :: rho_d
111 38108 : REAL(dp), DIMENSION(:, :), POINTER :: rho_nlcc, weight
112 38108 : REAL(dp), DIMENSION(:, :, :), POINTER :: rho_h, rho_s, tau_h, tau_s, vtau_h, &
113 19054 : vtau_s, vxc_h, vxc_s
114 38108 : REAL(dp), DIMENSION(:, :, :, :), POINTER :: drho_h, drho_s, vxg_h, vxg_s
115 19054 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
116 : TYPE(dft_control_type), POINTER :: dft_control
117 : TYPE(grid_atom_type), POINTER :: grid_atom
118 : TYPE(gto_basis_set_type), POINTER :: basis_1c
119 : TYPE(harmonics_atom_type), POINTER :: harmonics
120 : TYPE(mp_para_env_type), POINTER :: para_env
121 19054 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: my_kind_set
122 19054 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: dr_h, dr_s, int_hh, int_ss, r_h, r_s
123 19054 : TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER :: r_h_d, r_s_d
124 19054 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: my_rho_atom_set
125 : TYPE(rho_atom_type), POINTER :: rho_atom
126 : TYPE(section_vals_type), POINTER :: input, my_xc_section, xc_fun_section
127 : TYPE(xc_derivative_set_type) :: deriv_set
128 : TYPE(xc_rho_cflags_type) :: needs
129 : TYPE(xc_rho_set_type) :: rho_set_h, rho_set_s
130 :
131 : ! -------------------------------------------------------------------------
132 :
133 19054 : CALL timeset(routineN, handle)
134 :
135 19054 : NULLIFY (atom_list)
136 19054 : NULLIFY (my_kind_set)
137 19054 : NULLIFY (atomic_kind_set)
138 19054 : NULLIFY (grid_atom)
139 19054 : NULLIFY (harmonics)
140 19054 : NULLIFY (input)
141 19054 : NULLIFY (para_env)
142 19054 : NULLIFY (rho_atom)
143 19054 : NULLIFY (my_rho_atom_set)
144 19054 : NULLIFY (rho_nlcc)
145 :
146 19054 : epr_xc = .FALSE.
147 19054 : IF (PRESENT(gradient_atom_set)) THEN
148 10 : epr_xc = .TRUE.
149 : END IF
150 :
151 19054 : IF (PRESENT(adiabatic_rescale_factor)) THEN
152 44 : my_adiabatic_rescale_factor = adiabatic_rescale_factor
153 : ELSE
154 19010 : my_adiabatic_rescale_factor = 1.0_dp
155 : END IF
156 :
157 : CALL get_qs_env(qs_env=qs_env, &
158 : dft_control=dft_control, &
159 : para_env=para_env, &
160 : atomic_kind_set=atomic_kind_set, &
161 : qs_kind_set=my_kind_set, &
162 : input=input, &
163 19054 : rho_atom_set=my_rho_atom_set)
164 :
165 19054 : IF (PRESENT(kind_set_external)) my_kind_set => kind_set_external
166 19054 : IF (PRESENT(rho_atom_set_external)) my_rho_atom_set => rho_atom_set_external
167 :
168 19054 : nlcc = has_nlcc(my_kind_set)
169 :
170 19054 : IF (epr_xc) THEN
171 : my_xc_section => section_vals_get_subs_vals(input, &
172 10 : "PROPERTIES%LINRES%EPR%PRINT%G_TENSOR%XC")
173 : ELSE
174 19044 : my_xc_section => section_vals_get_subs_vals(input, "DFT%XC")
175 : END IF
176 :
177 19054 : IF (PRESENT(xc_section_external)) my_xc_section => xc_section_external
178 :
179 19054 : xc_fun_section => section_vals_get_subs_vals(my_xc_section, "XC_FUNCTIONAL")
180 : CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", &
181 19054 : i_val=myfun)
182 :
183 19054 : IF (myfun == xc_none) THEN
184 2440 : exc1 = 0.0_dp
185 10380 : my_rho_atom_set(:)%exc_h = 0.0_dp
186 10380 : my_rho_atom_set(:)%exc_s = 0.0_dp
187 : ELSE
188 : CALL section_vals_val_get(my_xc_section, "DENSITY_CUTOFF", &
189 16614 : r_val=density_cut)
190 : CALL section_vals_val_get(my_xc_section, "GRADIENT_CUTOFF", &
191 16614 : r_val=gradient_cut)
192 : CALL section_vals_val_get(my_xc_section, "TAU_CUTOFF", &
193 16614 : r_val=tau_cut)
194 :
195 16614 : lsd = dft_control%lsd
196 16614 : nspins = dft_control%nspins
197 : needs = xc_functionals_get_needs(xc_fun_section, &
198 : lsd=lsd, &
199 16614 : calc_potential=.TRUE.)
200 :
201 : ! whatever the xc, if epr_xc, drho_spin is needed
202 16614 : IF (epr_xc) needs%drho_spin = .TRUE.
203 :
204 16614 : gradient_f = (needs%drho .OR. needs%drho_spin)
205 16614 : tau_f = (needs%tau .OR. needs%tau_spin)
206 :
207 : ! Initialize energy contribution from the one center XC terms to zero
208 16614 : exc1 = 0.0_dp
209 :
210 : ! Nullify some pointers for work-arrays
211 16614 : NULLIFY (rho_h, drho_h, rho_s, drho_s, weight)
212 16614 : NULLIFY (vxc_h, vxc_s, vxg_h, vxg_s)
213 16614 : NULLIFY (tau_h, tau_s)
214 16614 : NULLIFY (vtau_h, vtau_s)
215 :
216 : ! Here starts the loop over all the atoms
217 :
218 49960 : DO ikind = 1, SIZE(atomic_kind_set)
219 33346 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
220 : CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
221 33346 : harmonics=harmonics, grid_atom=grid_atom)
222 33346 : CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
223 :
224 33346 : IF (.NOT. paw_atom) CYCLE
225 :
226 30538 : nr = grid_atom%nr
227 30538 : na = grid_atom%ng_sphere
228 :
229 : ! Prepare the structures needed to calculate and store the xc derivatives
230 :
231 : ! Array dimension: here anly one dimensional arrays are used,
232 : ! i.e. only the first column of deriv_data is read.
233 : ! The other to dimensions are set to size equal 1
234 305380 : bounds(1:2, 1:3) = 1
235 30538 : bounds(2, 1) = na
236 30538 : bounds(2, 2) = nr
237 :
238 : ! create a place where to put the derivatives
239 30538 : CALL xc_dset_create(deriv_set, local_bounds=bounds)
240 : ! create the place where to store the argument for the functionals
241 : CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
242 30538 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
243 : CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
244 30538 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
245 :
246 : ! allocate the required 3d arrays where to store rho and drho
247 30538 : CALL xc_rho_set_atom_update(rho_set_h, needs, nspins, bounds)
248 30538 : CALL xc_rho_set_atom_update(rho_set_s, needs, nspins, bounds)
249 :
250 30538 : CALL reallocate(rho_h, 1, na, 1, nr, 1, nspins)
251 30538 : CALL reallocate(rho_s, 1, na, 1, nr, 1, nspins)
252 30538 : weight => grid_atom%weight
253 30538 : CALL reallocate(vxc_h, 1, na, 1, nr, 1, nspins)
254 30538 : CALL reallocate(vxc_s, 1, na, 1, nr, 1, nspins)
255 : !
256 30538 : IF (gradient_f) THEN
257 18308 : CALL reallocate(drho_h, 1, 4, 1, na, 1, nr, 1, nspins)
258 18308 : CALL reallocate(drho_s, 1, 4, 1, na, 1, nr, 1, nspins)
259 18308 : CALL reallocate(vxg_h, 1, 3, 1, na, 1, nr, 1, nspins)
260 18308 : CALL reallocate(vxg_s, 1, 3, 1, na, 1, nr, 1, nspins)
261 : END IF
262 :
263 30538 : IF (tau_f) THEN
264 444 : CALL reallocate(tau_h, 1, na, 1, nr, 1, nspins)
265 444 : CALL reallocate(tau_s, 1, na, 1, nr, 1, nspins)
266 444 : CALL reallocate(vtau_h, 1, na, 1, nr, 1, nspins)
267 444 : CALL reallocate(vtau_s, 1, na, 1, nr, 1, nspins)
268 : END IF
269 :
270 : ! NLCC: prepare rho and drho of the core charge for this KIND
271 30538 : donlcc = .FALSE.
272 30538 : IF (nlcc) THEN
273 52 : NULLIFY (rho_nlcc)
274 52 : rho_nlcc => my_kind_set(ikind)%nlcc_pot
275 52 : IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
276 : END IF
277 :
278 : ! Distribute the atoms of this kind
279 :
280 30538 : num_pe = para_env%num_pe
281 30538 : bo = get_limit(natom, para_env%num_pe, para_env%mepos)
282 :
283 54940 : DO iat = bo(1), bo(2)
284 24402 : iatom = atom_list(iat)
285 :
286 24402 : my_rho_atom_set(iatom)%exc_h = 0.0_dp
287 24402 : my_rho_atom_set(iatom)%exc_s = 0.0_dp
288 :
289 24402 : rho_atom => my_rho_atom_set(iatom)
290 86040274 : rho_h = 0.0_dp
291 86040274 : rho_s = 0.0_dp
292 24402 : IF (gradient_f) THEN
293 14369 : NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
294 : CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, &
295 : rho_rad_s=r_s, drho_rad_h=dr_h, &
296 : drho_rad_s=dr_s, rho_rad_h_d=r_h_d, &
297 14369 : rho_rad_s_d=r_s_d)
298 222077009 : drho_h = 0.0_dp
299 222077009 : drho_s = 0.0_dp
300 : ELSE
301 10033 : NULLIFY (r_h, r_s)
302 10033 : CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
303 10033 : rho_d = 0.0_dp
304 : END IF
305 24402 : IF (tau_f) THEN
306 : !compute tau on the grid all at once
307 308 : CALL calc_tau_atom(tau_h, tau_s, rho_atom, my_kind_set(ikind), nspins)
308 : ELSE
309 24094 : tau_d = 0.0_dp
310 : END IF
311 :
312 1415042 : DO ir = 1, nr
313 : CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
314 : ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, &
315 1390640 : r_h_d, r_s_d, drho_h, drho_s)
316 1415042 : IF (donlcc) THEN
317 : CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
318 2600 : ir, rho_nlcc(:, 1), rho_h, rho_s, rho_nlcc(:, 2), drho_h, drho_s)
319 : END IF
320 : END DO
321 1415042 : DO ir = 1, nr
322 1415042 : IF (tau_f) THEN
323 16700 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
324 16700 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
325 1373940 : ELSE IF (gradient_f) THEN
326 719190 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_d, na, ir)
327 719190 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_d, na, ir)
328 : ELSE
329 654750 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rho_d, tau_d, na, ir)
330 654750 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rho_d, tau_d, na, ir)
331 : END IF
332 : END DO
333 :
334 : !-------------------!
335 : ! hard atom density !
336 : !-------------------!
337 24402 : CALL xc_dset_zero_all(deriv_set)
338 : CALL vxc_of_r_new(xc_fun_section, rho_set_h, deriv_set, 1, needs, weight, &
339 : lsd, na, nr, exc_h, vxc_h, vxg_h, vtau_h, energy_only=energy_only, &
340 24402 : epr_xc=epr_xc, adiabatic_rescale_factor=my_adiabatic_rescale_factor)
341 24402 : rho_atom%exc_h = rho_atom%exc_h + exc_h
342 :
343 : !-------------------!
344 : ! soft atom density !
345 : !-------------------!
346 24402 : CALL xc_dset_zero_all(deriv_set)
347 : CALL vxc_of_r_new(xc_fun_section, rho_set_s, deriv_set, 1, needs, weight, &
348 : lsd, na, nr, exc_s, vxc_s, vxg_s, vtau_s, energy_only=energy_only, &
349 24402 : epr_xc=epr_xc, adiabatic_rescale_factor=my_adiabatic_rescale_factor)
350 24402 : rho_atom%exc_s = rho_atom%exc_s + exc_s
351 :
352 24402 : IF (epr_xc) THEN
353 45 : DO ispin = 1, nspins
354 135 : DO idir = 1, 3
355 4620 : DO ir = 1, nr
356 229590 : DO ia = 1, na
357 : gradient_atom_set(iatom)%nablavks_vec_rad_h(idir, ispin)%r_coef(ir, ia) = &
358 : gradient_atom_set(iatom)%nablavks_vec_rad_h(idir, ispin)%r_coef(ir, ia) &
359 225000 : + vxg_h(idir, ia, ir, ispin)
360 : gradient_atom_set(iatom)%nablavks_vec_rad_s(idir, ispin)%r_coef(ir, ia) = &
361 : gradient_atom_set(iatom)%nablavks_vec_rad_s(idir, ispin)%r_coef(ir, ia) &
362 229500 : + vxg_s(idir, ia, ir, ispin)
363 : END DO ! ia
364 : END DO ! ir
365 : END DO ! idir
366 : END DO ! ispin
367 : END IF
368 :
369 : ! Add contributions to the exc energy
370 :
371 24402 : exc1 = exc1 + rho_atom%exc_h - rho_atom%exc_s
372 :
373 : ! Integration to get the matrix elements relative to the vxc_atom
374 : ! here the products with the primitives is done: gaVxcgb
375 : ! internal transformation to get the integral in cartesian Gaussians
376 :
377 24402 : IF (.NOT. energy_only) THEN
378 22980 : NULLIFY (int_hh, int_ss)
379 22980 : CALL get_rho_atom(rho_atom=rho_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
380 22980 : IF (gradient_f) THEN
381 : CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
382 13129 : grid_atom, basis_1c, harmonics, nspins)
383 : ELSE
384 : CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
385 9851 : grid_atom, basis_1c, harmonics, nspins)
386 : END IF
387 22980 : IF (tau_f) THEN
388 : CALL dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, &
389 308 : grid_atom, basis_1c, harmonics, nspins)
390 : END IF
391 : END IF ! energy_only
392 54940 : NULLIFY (r_h, r_s, dr_h, dr_s)
393 : END DO ! iat
394 :
395 : ! Release the xc structure used to store the xc derivatives
396 30538 : CALL xc_dset_release(deriv_set)
397 30538 : CALL xc_rho_set_release(rho_set_h)
398 111036 : CALL xc_rho_set_release(rho_set_s)
399 :
400 : END DO ! ikind
401 :
402 16614 : CALL para_env%sum(exc1)
403 :
404 16614 : IF (ASSOCIATED(rho_h)) DEALLOCATE (rho_h)
405 16614 : IF (ASSOCIATED(rho_s)) DEALLOCATE (rho_s)
406 16614 : IF (ASSOCIATED(vxc_h)) DEALLOCATE (vxc_h)
407 16614 : IF (ASSOCIATED(vxc_s)) DEALLOCATE (vxc_s)
408 :
409 16614 : IF (gradient_f) THEN
410 10098 : IF (ASSOCIATED(drho_h)) DEALLOCATE (drho_h)
411 10098 : IF (ASSOCIATED(drho_s)) DEALLOCATE (drho_s)
412 10098 : IF (ASSOCIATED(vxg_h)) DEALLOCATE (vxg_h)
413 10098 : IF (ASSOCIATED(vxg_s)) DEALLOCATE (vxg_s)
414 : END IF
415 :
416 16614 : IF (tau_f) THEN
417 244 : IF (ASSOCIATED(tau_h)) DEALLOCATE (tau_h)
418 244 : IF (ASSOCIATED(tau_s)) DEALLOCATE (tau_s)
419 244 : IF (ASSOCIATED(vtau_h)) DEALLOCATE (vtau_h)
420 244 : IF (ASSOCIATED(vtau_s)) DEALLOCATE (vtau_s)
421 : END IF
422 :
423 : END IF !xc_none
424 :
425 19054 : CALL timestop(handle)
426 :
427 819322 : END SUBROUTINE calculate_vxc_atom
428 :
429 : ! **************************************************************************************************
430 : !> \brief ...
431 : !> \param rho_atom_set ...
432 : !> \param rho1_atom_set ...
433 : !> \param qs_env ...
434 : !> \param xc_section ...
435 : !> \param para_env ...
436 : !> \param do_tddfpt2 New implementation of TDDFT.
437 : !> \param do_triplet ...
438 : !> \param kind_set_external ...
439 : ! **************************************************************************************************
440 16956 : SUBROUTINE calculate_xc_2nd_deriv_atom(rho_atom_set, rho1_atom_set, qs_env, xc_section, para_env, &
441 : do_tddfpt2, do_triplet, kind_set_external)
442 :
443 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho_atom_set, rho1_atom_set
444 : TYPE(qs_environment_type), POINTER :: qs_env
445 : TYPE(section_vals_type), POINTER :: xc_section
446 : TYPE(mp_para_env_type), INTENT(IN) :: para_env
447 : LOGICAL, INTENT(IN), OPTIONAL :: do_tddfpt2, do_triplet
448 : TYPE(qs_kind_type), DIMENSION(:), OPTIONAL, &
449 : POINTER :: kind_set_external
450 :
451 : CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_xc_2nd_deriv_atom'
452 :
453 : INTEGER :: atom, handle, iatom, ikind, ir, na, &
454 : natom, nr, nspins
455 : INTEGER, DIMENSION(2) :: local_loop_limit
456 : INTEGER, DIMENSION(2, 3) :: bounds
457 2826 : INTEGER, DIMENSION(:), POINTER :: atom_list
458 : LOGICAL :: gradient_functional, lsd, paw_atom, &
459 : scale_rho, tau_f
460 : REAL(KIND=dp) :: density_cut, gradient_cut, rtot, tau_cut
461 : REAL(KIND=dp), CONTIGUOUS, DIMENSION(:, :, :), &
462 2826 : POINTER :: vxc_h, vxc_s
463 : REAL(KIND=dp), DIMENSION(1, 1, 1) :: rtau
464 : REAL(KIND=dp), DIMENSION(1, 1, 1, 1) :: rrho
465 2826 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: weight
466 8478 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: rho1_h, rho1_s, rho_h, rho_s, tau1_h, &
467 2826 : tau1_s, tau_h, tau_s
468 5652 : REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER :: drho1_h, drho1_s, drho_h, drho_s, vxg_h, &
469 2826 : vxg_s
470 2826 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
471 : TYPE(grid_atom_type), POINTER :: grid_atom
472 : TYPE(gto_basis_set_type), POINTER :: basis_1c
473 : TYPE(harmonics_atom_type), POINTER :: harmonics
474 2826 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: my_kind_set, qs_kind_set
475 2826 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: dr1_h, dr1_s, dr_h, dr_s, int_hh, &
476 2826 : int_ss, r1_h, r1_s, r_h, r_s
477 2826 : TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER :: r1_h_d, r1_s_d, r_h_d, r_s_d
478 : TYPE(rho_atom_type), POINTER :: rho1_atom, rho_atom
479 : TYPE(section_vals_type), POINTER :: input, xc_fun_section
480 : TYPE(xc_derivative_set_type) :: deriv_set
481 : TYPE(xc_rho_cflags_type) :: needs
482 : TYPE(xc_rho_set_type) :: rho1_set_h, rho1_set_s, rho_set_h, &
483 : rho_set_s
484 :
485 : ! -------------------------------------------------------------------------
486 :
487 2826 : CALL timeset(routineN, handle)
488 :
489 2826 : NULLIFY (qs_kind_set)
490 2826 : NULLIFY (rho_h, rho_s, drho_h, drho_s, weight)
491 2826 : NULLIFY (rho1_h, rho1_s, drho1_h, drho1_s)
492 2826 : NULLIFY (vxc_h, vxc_s, vxg_h, vxg_s)
493 2826 : NULLIFY (tau_h, tau_s, tau1_h, tau1_s)
494 :
495 : CALL get_qs_env(qs_env=qs_env, &
496 : input=input, &
497 : qs_kind_set=qs_kind_set, &
498 2826 : atomic_kind_set=atomic_kind_set)
499 :
500 2826 : IF (PRESENT(kind_set_external)) THEN
501 320 : my_kind_set => kind_set_external
502 : ELSE
503 2506 : my_kind_set => qs_kind_set
504 : END IF
505 :
506 2826 : CALL section_vals_val_get(input, "DFT%LSD", l_val=lsd)
507 : CALL section_vals_val_get(xc_section, "DENSITY_CUTOFF", &
508 2826 : r_val=density_cut)
509 : CALL section_vals_val_get(xc_section, "GRADIENT_CUTOFF", &
510 2826 : r_val=gradient_cut)
511 : CALL section_vals_val_get(xc_section, "TAU_CUTOFF", &
512 2826 : r_val=tau_cut)
513 :
514 : xc_fun_section => section_vals_get_subs_vals(xc_section, &
515 2826 : "XC_FUNCTIONAL")
516 2826 : IF (lsd) THEN
517 64 : nspins = 2
518 : ELSE
519 2762 : nspins = 1
520 : END IF
521 :
522 2826 : scale_rho = .FALSE.
523 2826 : IF (PRESENT(do_tddfpt2) .AND. PRESENT(do_triplet)) THEN
524 1308 : IF (nspins == 1 .AND. do_triplet) THEN
525 182 : lsd = .TRUE.
526 182 : scale_rho = .TRUE.
527 : END IF
528 1518 : ELSEIF (PRESENT(do_triplet)) THEN
529 1354 : IF (nspins == 1 .AND. do_triplet) lsd = .TRUE.
530 : END IF
531 :
532 : needs = xc_functionals_get_needs(xc_fun_section, lsd=lsd, &
533 2826 : calc_potential=.TRUE.)
534 2826 : gradient_functional = needs%drho .OR. needs%drho_spin
535 2826 : tau_f = (needs%tau .OR. needs%tau_spin)
536 : IF (tau_f) THEN
537 0 : CPABORT("Tau functionals not implemented for GAPW 2nd derivatives")
538 : ELSE
539 2826 : rtau = 0.0_dp
540 : END IF
541 :
542 : ! Here starts the loop over all the atoms
543 9218 : DO ikind = 1, SIZE(atomic_kind_set)
544 :
545 6392 : NULLIFY (atom_list, harmonics, grid_atom)
546 6392 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
547 : CALL get_qs_kind(my_kind_set(ikind), paw_atom=paw_atom, &
548 6392 : harmonics=harmonics, grid_atom=grid_atom)
549 6392 : CALL get_qs_kind(my_kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
550 6392 : IF (.NOT. paw_atom) CYCLE
551 :
552 6034 : nr = grid_atom%nr
553 6034 : na = grid_atom%ng_sphere
554 :
555 : ! Array dimension: here anly one dimensional arrays are used,
556 : ! i.e. only the first column of deriv_data is read.
557 : ! The other to dimensions are set to size equal 1.
558 60340 : bounds(1:2, 1:3) = 1
559 6034 : bounds(2, 1) = na
560 6034 : bounds(2, 2) = nr
561 :
562 6034 : CALL xc_dset_create(deriv_set, local_bounds=bounds)
563 : CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
564 6034 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
565 : CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
566 6034 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
567 : CALL xc_rho_set_create(rho1_set_h, bounds, rho_cutoff=density_cut, &
568 6034 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
569 : CALL xc_rho_set_create(rho1_set_s, bounds, rho_cutoff=density_cut, &
570 6034 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
571 :
572 : ! allocate the required 3d arrays where to store rho and drho
573 6034 : IF (nspins == 1 .AND. .NOT. lsd) THEN
574 5640 : CALL xc_rho_set_atom_update(rho_set_h, needs, 1, bounds)
575 5640 : CALL xc_rho_set_atom_update(rho1_set_h, needs, 1, bounds)
576 5640 : CALL xc_rho_set_atom_update(rho_set_s, needs, 1, bounds)
577 5640 : CALL xc_rho_set_atom_update(rho1_set_s, needs, 1, bounds)
578 : ELSE
579 394 : CALL xc_rho_set_atom_update(rho_set_h, needs, 2, bounds)
580 394 : CALL xc_rho_set_atom_update(rho1_set_h, needs, 2, bounds)
581 394 : CALL xc_rho_set_atom_update(rho_set_s, needs, 2, bounds)
582 394 : CALL xc_rho_set_atom_update(rho1_set_s, needs, 2, bounds)
583 : END IF
584 :
585 : ALLOCATE (rho_h(1:na, 1:nr, 1:nspins), rho1_h(1:na, 1:nr, 1:nspins), &
586 84476 : rho_s(1:na, 1:nr, 1:nspins), rho1_s(1:na, 1:nr, 1:nspins))
587 :
588 42238 : ALLOCATE (vxc_h(1:na, 1:nr, 1:nspins), vxc_s(1:na, 1:nr, 1:nspins))
589 15643664 : vxc_h = 0.0_dp
590 15643664 : vxc_s = 0.0_dp
591 :
592 6034 : weight => grid_atom%weight
593 :
594 6034 : IF (gradient_functional) THEN
595 : ALLOCATE (drho_h(1:4, 1:na, 1:nr, 1:nspins), drho1_h(1:4, 1:na, 1:nr, 1:nspins), &
596 62468 : drho_s(1:4, 1:na, 1:nr, 1:nspins), drho1_s(1:4, 1:na, 1:nr, 1:nspins))
597 35696 : ALLOCATE (vxg_h(1:3, 1:na, 1:nr, 1:nspins), vxg_s(1:3, 1:na, 1:nr, 1:nspins))
598 : ELSE
599 : ALLOCATE (drho_h(1, 1, 1, 1), drho1_h(1, 1, 1, 1), &
600 1572 : drho_s(1, 1, 1, 1), drho1_s(1, 1, 1, 1))
601 1572 : ALLOCATE (vxg_h(1, 1, 1, 1), vxg_s(1, 1, 1, 1))
602 1572 : rrho = 0.0_dp
603 : END IF
604 45824780 : vxg_h = 0.0_dp
605 45824780 : vxg_s = 0.0_dp
606 :
607 : ! parallelization
608 6034 : local_loop_limit = get_limit(natom, para_env%num_pe, para_env%mepos)
609 :
610 10237 : DO iatom = local_loop_limit(1), local_loop_limit(2) !1,natom
611 4203 : atom = atom_list(iatom)
612 :
613 4203 : rho_atom_set(atom)%exc_h = 0.0_dp
614 4203 : rho_atom_set(atom)%exc_s = 0.0_dp
615 4203 : rho1_atom_set(atom)%exc_h = 0.0_dp
616 4203 : rho1_atom_set(atom)%exc_s = 0.0_dp
617 :
618 4203 : rho_atom => rho_atom_set(atom)
619 4203 : rho1_atom => rho1_atom_set(atom)
620 4203 : NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
621 4203 : NULLIFY (r1_h, r1_s, dr1_h, dr1_s, r1_h_d, r1_s_d)
622 10889320 : rho_h = 0.0_dp
623 10889320 : rho_s = 0.0_dp
624 10889320 : rho1_h = 0.0_dp
625 10889320 : rho1_s = 0.0_dp
626 4203 : IF (gradient_functional) THEN
627 : CALL get_rho_atom(rho_atom=rho_atom, &
628 : rho_rad_h=r_h, rho_rad_s=r_s, &
629 : drho_rad_h=dr_h, drho_rad_s=dr_s, &
630 3120 : rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
631 : CALL get_rho_atom(rho_atom=rho1_atom, &
632 : rho_rad_h=r1_h, rho_rad_s=r1_s, &
633 : drho_rad_h=dr1_h, drho_rad_s=dr1_s, &
634 3120 : rho_rad_h_d=r1_h_d, rho_rad_s_d=r1_s_d)
635 79927888 : drho_h = 0.0_dp; drho_s = 0.0_dp
636 79927888 : drho1_h = 0.0_dp; drho1_s = 0.0_dp
637 : ELSE
638 : CALL get_rho_atom(rho_atom=rho_atom, &
639 1083 : rho_rad_h=r_h, rho_rad_s=r_s)
640 : CALL get_rho_atom(rho_atom=rho1_atom, &
641 1083 : rho_rad_h=r1_h, rho_rad_s=r1_s)
642 : END IF
643 :
644 4203 : rtot = 0.0_dp
645 :
646 214353 : DO ir = 1, nr
647 : CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_functional, &
648 : ir, r_h, r_s, rho_h, rho_s, dr_h, dr_s, r_h_d, r_s_d, &
649 210150 : drho_h, drho_s)
650 : CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_functional, &
651 : ir, r1_h, r1_s, rho1_h, rho1_s, dr1_h, dr1_s, r1_h_d, r1_s_d, &
652 214353 : drho1_h, drho1_s)
653 : END DO
654 4203 : IF (scale_rho) THEN
655 497640 : rho_h = 2.0_dp*rho_h
656 497640 : rho_s = 2.0_dp*rho_s
657 195 : IF (gradient_functional) THEN
658 1882800 : drho_h = 2.0_dp*drho_h
659 1882800 : drho_s = 2.0_dp*drho_s
660 : END IF
661 : END IF
662 :
663 214353 : DO ir = 1, nr
664 214353 : IF (tau_f) THEN
665 0 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
666 0 : CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, drho1_h, tau1_h, na, ir)
667 0 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
668 0 : CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, drho1_s, tau1_s, na, ir)
669 210150 : ELSE IF (gradient_functional) THEN
670 156000 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, rtau, na, ir)
671 156000 : CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, drho1_h, rtau, na, ir)
672 156000 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, rtau, na, ir)
673 156000 : CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, drho1_s, rtau, na, ir)
674 : ELSE
675 54150 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rrho, rtau, na, ir)
676 54150 : CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, rrho, rtau, na, ir)
677 54150 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rrho, rtau, na, ir)
678 54150 : CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, rrho, rtau, na, ir)
679 : END IF
680 : END DO
681 :
682 : CALL xc_2nd_deriv_of_r(xc_section=xc_section, &
683 : rho_set=rho_set_h, rho1_set=rho1_set_h, &
684 : deriv_set=deriv_set, &
685 4203 : w=weight, vxc=vxc_h, vxg=vxg_h, do_triplet=do_triplet)
686 : CALL xc_2nd_deriv_of_r(xc_section=xc_section, &
687 : rho_set=rho_set_s, rho1_set=rho1_set_s, &
688 : deriv_set=deriv_set, &
689 4203 : w=weight, vxc=vxc_s, vxg=vxg_s, do_triplet=do_triplet)
690 :
691 4203 : CALL get_rho_atom(rho_atom=rho1_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
692 4203 : IF (gradient_functional) THEN
693 : CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
694 3120 : grid_atom, basis_1c, harmonics, nspins)
695 : ELSE
696 : CALL gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, &
697 1083 : grid_atom, basis_1c, harmonics, nspins)
698 : END IF
699 :
700 10237 : NULLIFY (r_h, r_s, dr_h, dr_s)
701 :
702 : END DO
703 :
704 : ! some cleanup
705 6034 : NULLIFY (weight)
706 6034 : DEALLOCATE (rho_h, rho_s, rho1_h, rho1_s, vxc_h, vxc_s)
707 6034 : DEALLOCATE (drho_h, drho_s, vxg_h, vxg_s)
708 6034 : DEALLOCATE (drho1_h, drho1_s)
709 :
710 6034 : CALL xc_dset_release(deriv_set)
711 6034 : CALL xc_rho_set_release(rho_set_h)
712 6034 : CALL xc_rho_set_release(rho1_set_h)
713 6034 : CALL xc_rho_set_release(rho_set_s)
714 21644 : CALL xc_rho_set_release(rho1_set_s)
715 :
716 : END DO
717 :
718 2826 : CALL timestop(handle)
719 :
720 240210 : END SUBROUTINE calculate_xc_2nd_deriv_atom
721 :
722 : ! **************************************************************************************************
723 : !> \brief ...
724 : !> \param qs_env ...
725 : !> \param rho0_atom_set ...
726 : !> \param rho1_atom_set ...
727 : !> \param rho2_atom_set ...
728 : !> \param kind_set ...
729 : !> \param xc_section ...
730 : !> \param is_triplet ...
731 : !> \param accuracy ...
732 : ! **************************************************************************************************
733 0 : SUBROUTINE calculate_gfxc_atom(qs_env, rho0_atom_set, rho1_atom_set, rho2_atom_set, &
734 : kind_set, xc_section, is_triplet, accuracy)
735 :
736 : TYPE(qs_environment_type), POINTER :: qs_env
737 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho0_atom_set, rho1_atom_set, &
738 : rho2_atom_set
739 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: kind_set
740 : TYPE(section_vals_type), OPTIONAL, POINTER :: xc_section
741 : LOGICAL, INTENT(IN) :: is_triplet
742 : INTEGER, INTENT(IN) :: accuracy
743 :
744 : CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_gfxc_atom'
745 : REAL(KIND=dp), PARAMETER :: epsrho = 5.e-4_dp
746 :
747 : INTEGER :: bo(2), handle, iat, iatom, ikind, ir, &
748 : istep, mspins, myfun, na, natom, nf, &
749 : nr, ns, nspins, nstep, num_pe
750 : INTEGER, DIMENSION(2, 3) :: bounds
751 0 : INTEGER, DIMENSION(:), POINTER :: atom_list
752 : LOGICAL :: donlcc, gradient_f, lsd, nlcc, paw_atom, &
753 : tau_f
754 : REAL(dp) :: beta, density_cut, exc_h, exc_s, &
755 : gradient_cut, oeps1, oeps2, tau_cut
756 : REAL(dp), DIMENSION(1, 1, 1) :: tau_d
757 : REAL(dp), DIMENSION(1, 1, 1, 1) :: rho_d
758 0 : REAL(dp), DIMENSION(:, :), POINTER :: rho_nlcc, weight
759 0 : REAL(dp), DIMENSION(:, :, :), POINTER :: rho0_h, rho0_s, rho1_h, rho1_s, rho_h, &
760 0 : rho_s, tau0_h, tau0_s, tau1_h, tau1_s, &
761 0 : tau_h, tau_s, vtau_h, vtau_s, vxc_h, &
762 0 : vxc_s
763 0 : REAL(dp), DIMENSION(:, :, :, :), POINTER :: drho0_h, drho0_s, drho1_h, drho1_s, &
764 0 : drho_h, drho_s, vxg_h, vxg_s
765 : REAL(KIND=dp), DIMENSION(-4:4) :: ak, bl
766 0 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
767 : TYPE(dft_control_type), POINTER :: dft_control
768 : TYPE(grid_atom_type), POINTER :: grid_atom
769 : TYPE(gto_basis_set_type), POINTER :: basis_1c
770 : TYPE(harmonics_atom_type), POINTER :: harmonics
771 : TYPE(mp_para_env_type), POINTER :: para_env
772 0 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: dr_h, dr_s, fint_hh, fint_ss, int_hh, &
773 0 : int_ss, r_h, r_s
774 0 : TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER :: r_h_d, r_s_d
775 : TYPE(rho_atom_type), POINTER :: rho0_atom, rho1_atom, rho2_atom
776 : TYPE(section_vals_type), POINTER :: xc_fun_section
777 : TYPE(xc_derivative_set_type) :: deriv_set
778 : TYPE(xc_rho_cflags_type) :: needs
779 : TYPE(xc_rho_set_type) :: rho_set_h, rho_set_s
780 :
781 0 : CALL timeset(routineN, handle)
782 :
783 0 : ak = 0.0_dp
784 0 : bl = 0.0_dp
785 0 : SELECT CASE (accuracy)
786 : CASE (:4)
787 0 : nstep = 2
788 0 : ak(-2:2) = (/1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp/)/12.0_dp
789 0 : bl(-2:2) = (/-1.0_dp, 16.0_dp, -30.0_dp, 16.0_dp, -1.0_dp/)/12.0_dp
790 : CASE (5:7)
791 0 : nstep = 3
792 0 : ak(-3:3) = (/-1.0_dp, 9.0_dp, -45.0_dp, 0.0_dp, 45.0_dp, -9.0_dp, 1.0_dp/)/60.0_dp
793 0 : bl(-3:3) = (/2.0_dp, -27.0_dp, 270.0_dp, -490.0_dp, 270.0_dp, -27.0_dp, 2.0_dp/)/180.0_dp
794 : CASE (8:)
795 0 : nstep = 4
796 : ak(-4:4) = (/1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
797 0 : 224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp/)/280.0_dp
798 : bl(-4:4) = (/-1.0_dp, 128.0_dp/9.0_dp, -112.0_dp, 896.0_dp, -14350.0_dp/9.0_dp, &
799 0 : 896.0_dp, -112.0_dp, 128.0_dp/9.0_dp, -1.0_dp/)/560.0_dp
800 : END SELECT
801 0 : oeps1 = 1.0_dp/epsrho
802 0 : oeps2 = 1.0_dp/(epsrho**2)
803 :
804 : CALL get_qs_env(qs_env=qs_env, &
805 : dft_control=dft_control, &
806 : para_env=para_env, &
807 0 : atomic_kind_set=atomic_kind_set)
808 :
809 0 : xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
810 0 : CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", i_val=myfun)
811 :
812 0 : IF (myfun == xc_none) THEN
813 : ! no action needed?
814 : ELSE
815 0 : CALL section_vals_val_get(xc_section, "DENSITY_CUTOFF", r_val=density_cut)
816 0 : CALL section_vals_val_get(xc_section, "GRADIENT_CUTOFF", r_val=gradient_cut)
817 0 : CALL section_vals_val_get(xc_section, "TAU_CUTOFF", r_val=tau_cut)
818 :
819 0 : nlcc = has_nlcc(kind_set)
820 0 : lsd = dft_control%lsd
821 0 : nspins = dft_control%nspins
822 0 : mspins = nspins
823 0 : IF (is_triplet) THEN
824 0 : CPASSERT(nspins == 1)
825 0 : lsd = .TRUE.
826 0 : mspins = 2
827 : END IF
828 0 : needs = xc_functionals_get_needs(xc_fun_section, lsd=lsd, calc_potential=.TRUE.)
829 0 : gradient_f = (needs%drho .OR. needs%drho_spin)
830 0 : tau_f = (needs%tau .OR. needs%tau_spin)
831 :
832 : ! Here starts the loop over all the atoms
833 0 : DO ikind = 1, SIZE(atomic_kind_set)
834 0 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
835 : CALL get_qs_kind(kind_set(ikind), paw_atom=paw_atom, &
836 0 : harmonics=harmonics, grid_atom=grid_atom)
837 0 : CALL get_qs_kind(kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
838 :
839 0 : IF (.NOT. paw_atom) CYCLE
840 :
841 0 : nr = grid_atom%nr
842 0 : na = grid_atom%ng_sphere
843 :
844 : ! Prepare the structures needed to calculate and store the xc derivatives
845 :
846 : ! Array dimension: here anly one dimensional arrays are used,
847 : ! i.e. only the first column of deriv_data is read.
848 : ! The other to dimensions are set to size equal 1
849 0 : bounds(1:2, 1:3) = 1
850 0 : bounds(2, 1) = na
851 0 : bounds(2, 2) = nr
852 :
853 : ! create a place where to put the derivatives
854 0 : CALL xc_dset_create(deriv_set, local_bounds=bounds)
855 : ! create the place where to store the argument for the functionals
856 : CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
857 0 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
858 : CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
859 0 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
860 :
861 : ! allocate the required 3d arrays where to store rho and drho
862 0 : CALL xc_rho_set_atom_update(rho_set_h, needs, mspins, bounds)
863 0 : CALL xc_rho_set_atom_update(rho_set_s, needs, mspins, bounds)
864 :
865 0 : weight => grid_atom%weight
866 :
867 : ALLOCATE (rho_h(na, nr, mspins), rho_s(na, nr, mspins), &
868 : rho0_h(na, nr, nspins), rho0_s(na, nr, nspins), &
869 0 : rho1_h(na, nr, nspins), rho1_s(na, nr, nspins))
870 0 : ALLOCATE (vxc_h(na, nr, mspins), vxc_s(na, nr, mspins))
871 0 : IF (gradient_f) THEN
872 : ALLOCATE (drho_h(4, na, nr, mspins), drho_s(4, na, nr, mspins), &
873 : drho0_h(4, na, nr, nspins), drho0_s(4, na, nr, nspins), &
874 0 : drho1_h(4, na, nr, nspins), drho1_s(4, na, nr, nspins))
875 0 : ALLOCATE (vxg_h(3, na, nr, mspins), vxg_s(3, na, nr, mspins))
876 : END IF
877 0 : IF (tau_f) THEN
878 : ALLOCATE (tau_h(na, nr, mspins), tau_s(na, nr, mspins), &
879 : tau0_h(na, nr, nspins), tau0_s(na, nr, nspins), &
880 0 : tau1_h(na, nr, nspins), tau1_s(na, nr, nspins))
881 0 : ALLOCATE (vtau_h(na, nr, mspins), vtau_s(na, nr, mspins))
882 : END IF
883 : !
884 : ! NLCC: prepare rho and drho of the core charge for this KIND
885 0 : donlcc = .FALSE.
886 0 : IF (nlcc) THEN
887 0 : NULLIFY (rho_nlcc)
888 0 : rho_nlcc => kind_set(ikind)%nlcc_pot
889 0 : IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
890 : END IF
891 :
892 : ! Distribute the atoms of this kind
893 0 : num_pe = para_env%num_pe
894 0 : bo = get_limit(natom, num_pe, para_env%mepos)
895 :
896 0 : DO iat = bo(1), bo(2)
897 0 : iatom = atom_list(iat)
898 : !
899 0 : NULLIFY (int_hh, int_ss)
900 0 : rho0_atom => rho0_atom_set(iatom)
901 0 : CALL get_rho_atom(rho_atom=rho0_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
902 0 : ALLOCATE (fint_ss(nspins), fint_hh(nspins))
903 0 : DO ns = 1, nspins
904 0 : nf = SIZE(int_ss(ns)%r_coef, 1)
905 0 : ALLOCATE (fint_ss(ns)%r_coef(nf, nf))
906 0 : nf = SIZE(int_hh(ns)%r_coef, 1)
907 0 : ALLOCATE (fint_hh(ns)%r_coef(nf, nf))
908 : END DO
909 :
910 : ! RHO0
911 0 : rho0_h = 0.0_dp
912 0 : rho0_s = 0.0_dp
913 0 : rho0_atom => rho0_atom_set(iatom)
914 0 : IF (gradient_f) THEN
915 0 : NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
916 : CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
917 0 : drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
918 0 : drho0_h = 0.0_dp
919 0 : drho0_s = 0.0_dp
920 : ELSE
921 0 : NULLIFY (r_h, r_s)
922 0 : CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s)
923 0 : rho_d = 0.0_dp
924 : END IF
925 0 : DO ir = 1, nr
926 : CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
927 : ir, r_h, r_s, rho0_h, rho0_s, dr_h, dr_s, &
928 0 : r_h_d, r_s_d, drho0_h, drho0_s)
929 0 : IF (donlcc) THEN
930 : CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
931 0 : ir, rho_nlcc(:, 1), rho0_h, rho0_s, rho_nlcc(:, 2), drho0_h, drho0_s)
932 : END IF
933 : END DO
934 0 : IF (tau_f) THEN
935 : !compute tau on the grid all at once
936 0 : CALL calc_tau_atom(tau0_h, tau0_s, rho0_atom, kind_set(ikind), nspins)
937 : ELSE
938 0 : tau_d = 0.0_dp
939 : END IF
940 : ! RHO1
941 0 : rho1_h = 0.0_dp
942 0 : rho1_s = 0.0_dp
943 0 : rho1_atom => rho1_atom_set(iatom)
944 0 : IF (gradient_f) THEN
945 0 : NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
946 : CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
947 0 : drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
948 0 : drho1_h = 0.0_dp
949 0 : drho1_s = 0.0_dp
950 : ELSE
951 0 : NULLIFY (r_h, r_s)
952 0 : CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s)
953 : END IF
954 0 : DO ir = 1, nr
955 : CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
956 : ir, r_h, r_s, rho1_h, rho1_s, dr_h, dr_s, &
957 0 : r_h_d, r_s_d, drho1_h, drho1_s)
958 : END DO
959 0 : IF (tau_f) THEN
960 : !compute tau on the grid all at once
961 0 : CALL calc_tau_atom(tau1_h, tau1_s, rho1_atom, kind_set(ikind), nspins)
962 : END IF
963 : ! RHO2
964 0 : rho2_atom => rho2_atom_set(iatom)
965 :
966 0 : DO istep = -nstep, nstep
967 :
968 0 : beta = REAL(istep, KIND=dp)*epsrho
969 :
970 0 : IF (is_triplet) THEN
971 0 : rho_h(:, :, 1) = rho0_h(:, :, 1) + beta*rho1_h(:, :, 1)
972 0 : rho_h(:, :, 2) = rho0_h(:, :, 1)
973 0 : rho_h = 0.5_dp*rho_h
974 0 : rho_s(:, :, 1) = rho0_s(:, :, 1) + beta*rho1_s(:, :, 1)
975 0 : rho_s(:, :, 2) = rho0_s(:, :, 1)
976 0 : rho_s = 0.5_dp*rho_s
977 0 : IF (gradient_f) THEN
978 0 : drho_h(:, :, :, 1) = drho0_h(:, :, :, 1) + beta*drho1_h(:, :, :, 1)
979 0 : drho_h(:, :, :, 2) = drho0_h(:, :, :, 1)
980 0 : drho_h = 0.5_dp*drho_h
981 0 : drho_s(:, :, :, 1) = drho0_s(:, :, :, 1) + beta*drho1_s(:, :, :, 1)
982 0 : drho_s(:, :, :, 2) = drho0_s(:, :, :, 1)
983 0 : drho_s = 0.5_dp*drho_s
984 : END IF
985 0 : IF (tau_f) THEN
986 0 : tau_h(:, :, 1) = tau0_h(:, :, 1) + beta*tau1_h(:, :, 1)
987 0 : tau_h(:, :, 2) = tau0_h(:, :, 1)
988 0 : tau_h = 0.5_dp*tau0_h
989 0 : tau_s(:, :, 1) = tau0_s(:, :, 1) + beta*tau1_s(:, :, 1)
990 0 : tau_s(:, :, 2) = tau0_s(:, :, 1)
991 0 : tau_s = 0.5_dp*tau0_s
992 : END IF
993 : ELSE
994 0 : rho_h = rho0_h + beta*rho1_h
995 0 : rho_s = rho0_s + beta*rho1_s
996 0 : IF (gradient_f) THEN
997 0 : drho_h = drho0_h + beta*drho1_h
998 0 : drho_s = drho0_s + beta*drho1_s
999 : END IF
1000 0 : IF (tau_f) THEN
1001 0 : tau_h = tau0_h + beta*tau1_h
1002 0 : tau_s = tau0_s + beta*tau1_s
1003 : END IF
1004 : END IF
1005 : !
1006 0 : IF (gradient_f) THEN
1007 : drho_h(4, :, :, :) = SQRT( &
1008 : drho_h(1, :, :, :)*drho_h(1, :, :, :) + &
1009 : drho_h(2, :, :, :)*drho_h(2, :, :, :) + &
1010 0 : drho_h(3, :, :, :)*drho_h(3, :, :, :))
1011 :
1012 : drho_s(4, :, :, :) = SQRT( &
1013 : drho_s(1, :, :, :)*drho_s(1, :, :, :) + &
1014 : drho_s(2, :, :, :)*drho_s(2, :, :, :) + &
1015 0 : drho_s(3, :, :, :)*drho_s(3, :, :, :))
1016 : END IF
1017 :
1018 0 : DO ir = 1, nr
1019 0 : IF (tau_f) THEN
1020 0 : CALL fill_rho_set(rho_set_h, lsd, mspins, needs, rho_h, drho_h, tau_h, na, ir)
1021 0 : CALL fill_rho_set(rho_set_s, lsd, mspins, needs, rho_s, drho_s, tau_s, na, ir)
1022 0 : ELSE IF (gradient_f) THEN
1023 0 : CALL fill_rho_set(rho_set_h, lsd, mspins, needs, rho_h, drho_h, tau_d, na, ir)
1024 0 : CALL fill_rho_set(rho_set_s, lsd, mspins, needs, rho_s, drho_s, tau_d, na, ir)
1025 : ELSE
1026 0 : CALL fill_rho_set(rho_set_h, lsd, mspins, needs, rho_h, rho_d, tau_d, na, ir)
1027 0 : CALL fill_rho_set(rho_set_s, lsd, mspins, needs, rho_s, rho_d, tau_d, na, ir)
1028 : END IF
1029 : END DO
1030 :
1031 : ! hard atom density !
1032 0 : CALL xc_dset_zero_all(deriv_set)
1033 : CALL vxc_of_r_new(xc_fun_section, rho_set_h, deriv_set, 1, needs, weight, &
1034 0 : lsd, na, nr, exc_h, vxc_h, vxg_h, vtau_h)
1035 0 : IF (is_triplet) THEN
1036 0 : vxc_h(:, :, 1) = vxc_h(:, :, 1) - vxc_h(:, :, 2)
1037 0 : IF (gradient_f) THEN
1038 0 : vxg_h(:, :, :, 1) = vxg_h(:, :, :, 1) - vxg_h(:, :, :, 2)
1039 : END IF
1040 0 : IF (tau_f) THEN
1041 0 : vtau_h(:, :, 1) = vtau_h(:, :, 1) - vtau_h(:, :, 2)
1042 : END IF
1043 : END IF
1044 : ! soft atom density !
1045 0 : CALL xc_dset_zero_all(deriv_set)
1046 : CALL vxc_of_r_new(xc_fun_section, rho_set_s, deriv_set, 1, needs, weight, &
1047 0 : lsd, na, nr, exc_s, vxc_s, vxg_s, vtau_s)
1048 0 : IF (is_triplet) THEN
1049 0 : vxc_s(:, :, 1) = vxc_s(:, :, 1) - vxc_s(:, :, 2)
1050 0 : IF (gradient_f) THEN
1051 0 : vxg_s(:, :, :, 1) = vxg_s(:, :, :, 1) - vxg_s(:, :, :, 2)
1052 : END IF
1053 0 : IF (tau_f) THEN
1054 0 : vtau_s(:, :, 1) = vtau_s(:, :, 1) - vtau_s(:, :, 2)
1055 : END IF
1056 : END IF
1057 : ! potentials
1058 0 : DO ns = 1, nspins
1059 0 : fint_hh(ns)%r_coef(:, :) = 0.0_dp
1060 0 : fint_ss(ns)%r_coef(:, :) = 0.0_dp
1061 : END DO
1062 0 : IF (gradient_f) THEN
1063 : CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, fint_hh, fint_ss, &
1064 0 : grid_atom, basis_1c, harmonics, nspins)
1065 : ELSE
1066 : CALL gaVxcgb_noGC(vxc_h, vxc_s, fint_hh, fint_ss, &
1067 0 : grid_atom, basis_1c, harmonics, nspins)
1068 : END IF
1069 0 : IF (tau_f) THEN
1070 : CALL dgaVtaudgb(vtau_h, vtau_s, fint_hh, fint_ss, &
1071 0 : grid_atom, basis_1c, harmonics, nspins)
1072 : END IF
1073 : ! first derivative fxc
1074 0 : NULLIFY (int_hh, int_ss)
1075 0 : CALL get_rho_atom(rho_atom=rho1_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
1076 0 : DO ns = 1, nspins
1077 0 : int_ss(ns)%r_coef(:, :) = int_ss(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_ss(ns)%r_coef(:, :)
1078 0 : int_hh(ns)%r_coef(:, :) = int_hh(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_hh(ns)%r_coef(:, :)
1079 : END DO
1080 : ! second derivative gxc
1081 0 : NULLIFY (int_hh, int_ss)
1082 0 : CALL get_rho_atom(rho_atom=rho2_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
1083 0 : DO ns = 1, nspins
1084 0 : int_ss(ns)%r_coef(:, :) = int_ss(ns)%r_coef(:, :) + oeps2*bl(istep)*fint_ss(ns)%r_coef(:, :)
1085 0 : int_hh(ns)%r_coef(:, :) = int_hh(ns)%r_coef(:, :) + oeps2*bl(istep)*fint_hh(ns)%r_coef(:, :)
1086 : END DO
1087 : END DO
1088 : !
1089 0 : DO ns = 1, nspins
1090 0 : DEALLOCATE (fint_ss(ns)%r_coef)
1091 0 : DEALLOCATE (fint_hh(ns)%r_coef)
1092 : END DO
1093 0 : DEALLOCATE (fint_ss, fint_hh)
1094 :
1095 : END DO ! iat
1096 :
1097 : ! Release the xc structure used to store the xc derivatives
1098 0 : CALL xc_dset_release(deriv_set)
1099 0 : CALL xc_rho_set_release(rho_set_h)
1100 0 : CALL xc_rho_set_release(rho_set_s)
1101 :
1102 0 : DEALLOCATE (rho_h, rho_s, rho0_h, rho0_s, rho1_h, rho1_s)
1103 0 : DEALLOCATE (vxc_h, vxc_s)
1104 0 : IF (gradient_f) THEN
1105 0 : DEALLOCATE (drho_h, drho_s, drho0_h, drho0_s, drho1_h, drho1_s)
1106 0 : DEALLOCATE (vxg_h, vxg_s)
1107 : END IF
1108 0 : IF (tau_f) THEN
1109 0 : DEALLOCATE (tau_h, tau_s, tau0_h, tau0_s, tau1_h, tau1_s)
1110 0 : DEALLOCATE (vtau_h, vtau_s)
1111 : END IF
1112 :
1113 : END DO ! ikind
1114 :
1115 : END IF !xc_none
1116 :
1117 0 : CALL timestop(handle)
1118 :
1119 0 : END SUBROUTINE calculate_gfxc_atom
1120 :
1121 : ! **************************************************************************************************
1122 : !> \brief ...
1123 : !> \param qs_env ...
1124 : !> \param rho0_atom_set ...
1125 : !> \param rho1_atom_set ...
1126 : !> \param rho2_atom_set ...
1127 : !> \param kind_set ...
1128 : !> \param xc_section ...
1129 : !> \param is_triplet ...
1130 : !> \param accuracy ...
1131 : !> \param epsrho ...
1132 : ! **************************************************************************************************
1133 156 : SUBROUTINE gfxc_atom_diff(qs_env, rho0_atom_set, rho1_atom_set, rho2_atom_set, &
1134 : kind_set, xc_section, is_triplet, accuracy, epsrho)
1135 :
1136 : TYPE(qs_environment_type), POINTER :: qs_env
1137 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho0_atom_set, rho1_atom_set, &
1138 : rho2_atom_set
1139 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: kind_set
1140 : TYPE(section_vals_type), OPTIONAL, POINTER :: xc_section
1141 : LOGICAL, INTENT(IN) :: is_triplet
1142 : INTEGER, INTENT(IN) :: accuracy
1143 : REAL(KIND=dp), INTENT(IN) :: epsrho
1144 :
1145 : CHARACTER(LEN=*), PARAMETER :: routineN = 'gfxc_atom_diff'
1146 :
1147 : INTEGER :: bo(2), handle, iat, iatom, ikind, ir, &
1148 : istep, mspins, myfun, na, natom, nf, &
1149 : nr, ns, nspins, nstep, num_pe
1150 : INTEGER, DIMENSION(2, 3) :: bounds
1151 52 : INTEGER, DIMENSION(:), POINTER :: atom_list
1152 : LOGICAL :: donlcc, gradient_f, lsd, nlcc, paw_atom, &
1153 : tau_f
1154 : REAL(dp) :: beta, density_cut, gradient_cut, oeps1, &
1155 : tau_cut
1156 52 : REAL(dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER :: vxc_h, vxc_s
1157 : REAL(dp), DIMENSION(1, 1, 1) :: tau_d
1158 : REAL(dp), DIMENSION(1, 1, 1, 1) :: rho_d
1159 104 : REAL(dp), DIMENSION(:, :), POINTER :: rho_nlcc, weight
1160 104 : REAL(dp), DIMENSION(:, :, :), POINTER :: rho0_h, rho0_s, rho1_h, rho1_s, rho_h, &
1161 104 : rho_s, tau0_h, tau0_s, tau1_h, tau1_s, &
1162 52 : tau_h, tau_s, vtau_h, vtau_s
1163 52 : REAL(dp), DIMENSION(:, :, :, :), POINTER :: drho0_h, drho0_s, drho1_h, drho1_s, &
1164 104 : drho_h, drho_s, vxg_h, vxg_s
1165 : REAL(KIND=dp), DIMENSION(-4:4) :: ak
1166 52 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1167 : TYPE(dft_control_type), POINTER :: dft_control
1168 : TYPE(grid_atom_type), POINTER :: grid_atom
1169 : TYPE(gto_basis_set_type), POINTER :: basis_1c
1170 : TYPE(harmonics_atom_type), POINTER :: harmonics
1171 : TYPE(mp_para_env_type), POINTER :: para_env
1172 52 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: dr_h, dr_s, fint_hh, fint_ss, int_hh, &
1173 52 : int_ss, r_h, r_s
1174 52 : TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER :: r_h_d, r_s_d
1175 : TYPE(rho_atom_type), POINTER :: rho0_atom, rho1_atom, rho2_atom
1176 : TYPE(section_vals_type), POINTER :: xc_fun_section
1177 : TYPE(xc_derivative_set_type) :: deriv_set
1178 : TYPE(xc_rho_cflags_type) :: needs
1179 : TYPE(xc_rho_set_type) :: rho1_set_h, rho1_set_s, rho_set_h, &
1180 : rho_set_s
1181 :
1182 52 : CALL timeset(routineN, handle)
1183 :
1184 52 : ak = 0.0_dp
1185 52 : SELECT CASE (accuracy)
1186 : CASE (:4)
1187 0 : nstep = 2
1188 0 : ak(-2:2) = (/1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp/)/12.0_dp
1189 : CASE (5:7)
1190 416 : nstep = 3
1191 416 : ak(-3:3) = (/-1.0_dp, 9.0_dp, -45.0_dp, 0.0_dp, 45.0_dp, -9.0_dp, 1.0_dp/)/60.0_dp
1192 : CASE (8:)
1193 0 : nstep = 4
1194 : ak(-4:4) = (/1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
1195 52 : 224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp/)/280.0_dp
1196 : END SELECT
1197 52 : oeps1 = 1.0_dp/epsrho
1198 :
1199 : CALL get_qs_env(qs_env=qs_env, &
1200 : dft_control=dft_control, &
1201 : para_env=para_env, &
1202 52 : atomic_kind_set=atomic_kind_set)
1203 :
1204 52 : xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
1205 52 : CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", i_val=myfun)
1206 :
1207 52 : IF (myfun == xc_none) THEN
1208 : ! no action needed?
1209 : ELSE
1210 : ! calculate fxc
1211 : CALL calculate_xc_2nd_deriv_atom(rho0_atom_set, rho1_atom_set, qs_env, xc_section, para_env, &
1212 52 : do_triplet=is_triplet, kind_set_external=kind_set)
1213 :
1214 52 : CALL section_vals_val_get(xc_section, "DENSITY_CUTOFF", r_val=density_cut)
1215 52 : CALL section_vals_val_get(xc_section, "GRADIENT_CUTOFF", r_val=gradient_cut)
1216 52 : CALL section_vals_val_get(xc_section, "TAU_CUTOFF", r_val=tau_cut)
1217 :
1218 52 : nlcc = has_nlcc(kind_set)
1219 52 : lsd = dft_control%lsd
1220 52 : nspins = dft_control%nspins
1221 52 : mspins = nspins
1222 52 : IF (is_triplet) THEN
1223 6 : CPASSERT(nspins == 1)
1224 6 : lsd = .TRUE.
1225 6 : mspins = 2
1226 : END IF
1227 52 : needs = xc_functionals_get_needs(xc_fun_section, lsd=lsd, calc_potential=.TRUE.)
1228 52 : gradient_f = (needs%drho .OR. needs%drho_spin)
1229 52 : tau_f = (needs%tau .OR. needs%tau_spin)
1230 :
1231 : ! Here starts the loop over all the atoms
1232 178 : DO ikind = 1, SIZE(atomic_kind_set)
1233 126 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
1234 : CALL get_qs_kind(kind_set(ikind), paw_atom=paw_atom, &
1235 126 : harmonics=harmonics, grid_atom=grid_atom)
1236 126 : CALL get_qs_kind(kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
1237 :
1238 126 : IF (.NOT. paw_atom) CYCLE
1239 :
1240 120 : nr = grid_atom%nr
1241 120 : na = grid_atom%ng_sphere
1242 :
1243 : ! Prepare the structures needed to calculate and store the xc derivatives
1244 :
1245 : ! Array dimension: here anly one dimensional arrays are used,
1246 : ! i.e. only the first column of deriv_data is read.
1247 : ! The other to dimensions are set to size equal 1
1248 1200 : bounds(1:2, 1:3) = 1
1249 120 : bounds(2, 1) = na
1250 120 : bounds(2, 2) = nr
1251 :
1252 : ! create a place where to put the derivatives
1253 120 : CALL xc_dset_create(deriv_set, local_bounds=bounds)
1254 : ! create the place where to store the argument for the functionals
1255 : CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
1256 120 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
1257 : CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
1258 120 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
1259 : CALL xc_rho_set_create(rho1_set_h, bounds, rho_cutoff=density_cut, &
1260 120 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
1261 : CALL xc_rho_set_create(rho1_set_s, bounds, rho_cutoff=density_cut, &
1262 120 : drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
1263 :
1264 : ! allocate the required 3d arrays where to store rho and drho
1265 120 : CALL xc_rho_set_atom_update(rho_set_h, needs, mspins, bounds)
1266 120 : CALL xc_rho_set_atom_update(rho_set_s, needs, mspins, bounds)
1267 120 : CALL xc_rho_set_atom_update(rho1_set_h, needs, mspins, bounds)
1268 120 : CALL xc_rho_set_atom_update(rho1_set_s, needs, mspins, bounds)
1269 :
1270 120 : weight => grid_atom%weight
1271 :
1272 : ALLOCATE (rho_h(na, nr, nspins), rho_s(na, nr, nspins), &
1273 : rho0_h(na, nr, nspins), rho0_s(na, nr, nspins), &
1274 2400 : rho1_h(na, nr, nspins), rho1_s(na, nr, nspins))
1275 840 : ALLOCATE (vxc_h(na, nr, nspins), vxc_s(na, nr, nspins))
1276 120 : IF (gradient_f) THEN
1277 : ALLOCATE (drho_h(4, na, nr, nspins), drho_s(4, na, nr, nspins), &
1278 : drho0_h(4, na, nr, nspins), drho0_s(4, na, nr, nspins), &
1279 1600 : drho1_h(4, na, nr, nspins), drho1_s(4, na, nr, nspins))
1280 640 : ALLOCATE (vxg_h(3, na, nr, nspins), vxg_s(3, na, nr, nspins))
1281 : END IF
1282 120 : IF (tau_f) THEN
1283 : ALLOCATE (tau_h(na, nr, nspins), tau_s(na, nr, nspins), &
1284 : tau0_h(na, nr, nspins), tau0_s(na, nr, nspins), &
1285 0 : tau1_h(na, nr, nspins), tau1_s(na, nr, nspins))
1286 0 : ALLOCATE (vtau_h(na, nr, nspins), vtau_s(na, nr, nspins))
1287 : END IF
1288 : !
1289 : ! NLCC: prepare rho and drho of the core charge for this KIND
1290 120 : donlcc = .FALSE.
1291 120 : IF (nlcc) THEN
1292 0 : NULLIFY (rho_nlcc)
1293 0 : rho_nlcc => kind_set(ikind)%nlcc_pot
1294 0 : IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
1295 : END IF
1296 :
1297 : ! Distribute the atoms of this kind
1298 120 : num_pe = para_env%num_pe
1299 120 : bo = get_limit(natom, num_pe, para_env%mepos)
1300 :
1301 205 : DO iat = bo(1), bo(2)
1302 85 : iatom = atom_list(iat)
1303 : !
1304 85 : NULLIFY (int_hh, int_ss)
1305 85 : rho0_atom => rho0_atom_set(iatom)
1306 85 : CALL get_rho_atom(rho_atom=rho0_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
1307 510 : ALLOCATE (fint_ss(nspins), fint_hh(nspins))
1308 170 : DO ns = 1, nspins
1309 85 : nf = SIZE(int_ss(ns)%r_coef, 1)
1310 340 : ALLOCATE (fint_ss(ns)%r_coef(nf, nf))
1311 85 : nf = SIZE(int_hh(ns)%r_coef, 1)
1312 425 : ALLOCATE (fint_hh(ns)%r_coef(nf, nf))
1313 : END DO
1314 :
1315 : ! RHO0
1316 216920 : rho0_h = 0.0_dp
1317 216920 : rho0_s = 0.0_dp
1318 85 : rho0_atom => rho0_atom_set(iatom)
1319 85 : IF (gradient_f) THEN
1320 57 : NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
1321 : CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
1322 57 : drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
1323 715464 : drho0_h = 0.0_dp
1324 715464 : drho0_s = 0.0_dp
1325 : ELSE
1326 28 : NULLIFY (r_h, r_s)
1327 28 : CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s)
1328 28 : rho_d = 0.0_dp
1329 : END IF
1330 4335 : DO ir = 1, nr
1331 : CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
1332 : ir, r_h, r_s, rho0_h, rho0_s, dr_h, dr_s, &
1333 4250 : r_h_d, r_s_d, drho0_h, drho0_s)
1334 4335 : IF (donlcc) THEN
1335 : CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
1336 0 : ir, rho_nlcc(:, 1), rho0_h, rho0_s, rho_nlcc(:, 2), drho0_h, drho0_s)
1337 : END IF
1338 : END DO
1339 85 : IF (tau_f) THEN
1340 : !compute tau on the grid all at once
1341 0 : CALL calc_tau_atom(tau0_h, tau0_s, rho0_atom, kind_set(ikind), nspins)
1342 : ELSE
1343 85 : tau_d = 0.0_dp
1344 : END IF
1345 : ! RHO1
1346 216920 : rho1_h = 0.0_dp
1347 216920 : rho1_s = 0.0_dp
1348 85 : rho1_atom => rho1_atom_set(iatom)
1349 85 : IF (gradient_f) THEN
1350 57 : NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
1351 : CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
1352 57 : drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
1353 715464 : drho1_h = 0.0_dp
1354 715464 : drho1_s = 0.0_dp
1355 : ELSE
1356 28 : NULLIFY (r_h, r_s)
1357 28 : CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s)
1358 : END IF
1359 4335 : DO ir = 1, nr
1360 : CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
1361 : ir, r_h, r_s, rho1_h, rho1_s, dr_h, dr_s, &
1362 4335 : r_h_d, r_s_d, drho1_h, drho1_s)
1363 : END DO
1364 85 : IF (tau_f) THEN
1365 : !compute tau on the grid all at once
1366 0 : CALL calc_tau_atom(tau1_h, tau1_s, rho1_atom, kind_set(ikind), nspins)
1367 : END IF
1368 :
1369 4335 : DO ir = 1, nr
1370 4335 : IF (tau_f) THEN
1371 0 : CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, drho1_h, tau1_h, na, ir)
1372 0 : CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, drho1_s, tau1_s, na, ir)
1373 4250 : ELSE IF (gradient_f) THEN
1374 2850 : CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, drho1_h, tau_d, na, ir)
1375 2850 : CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, drho1_s, tau_d, na, ir)
1376 : ELSE
1377 1400 : CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, rho_d, tau_d, na, ir)
1378 1400 : CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, rho_d, tau_d, na, ir)
1379 : END IF
1380 : END DO
1381 :
1382 : ! RHO2
1383 85 : rho2_atom => rho2_atom_set(iatom)
1384 :
1385 680 : DO istep = -nstep, nstep
1386 :
1387 595 : beta = REAL(istep, KIND=dp)*epsrho
1388 :
1389 3036285 : rho_h = rho0_h + beta*rho1_h
1390 3036285 : rho_s = rho0_s + beta*rho1_s
1391 595 : IF (gradient_f) THEN
1392 10016097 : drho_h = drho0_h + beta*drho1_h
1393 10016097 : drho_s = drho0_s + beta*drho1_s
1394 : END IF
1395 595 : IF (tau_f) THEN
1396 0 : tau_h = tau0_h + beta*tau1_h
1397 0 : tau_s = tau0_s + beta*tau1_s
1398 : END IF
1399 : !
1400 595 : IF (gradient_f) THEN
1401 : drho_h(4, :, :, :) = SQRT( &
1402 : drho_h(1, :, :, :)*drho_h(1, :, :, :) + &
1403 : drho_h(2, :, :, :)*drho_h(2, :, :, :) + &
1404 1018248 : drho_h(3, :, :, :)*drho_h(3, :, :, :))
1405 :
1406 : drho_s(4, :, :, :) = SQRT( &
1407 : drho_s(1, :, :, :)*drho_s(1, :, :, :) + &
1408 : drho_s(2, :, :, :)*drho_s(2, :, :, :) + &
1409 1018248 : drho_s(3, :, :, :)*drho_s(3, :, :, :))
1410 : END IF
1411 :
1412 30345 : DO ir = 1, nr
1413 30345 : IF (tau_f) THEN
1414 0 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
1415 0 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
1416 29750 : ELSE IF (gradient_f) THEN
1417 19950 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_d, na, ir)
1418 19950 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_d, na, ir)
1419 : ELSE
1420 9800 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rho_d, tau_d, na, ir)
1421 9800 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rho_d, tau_d, na, ir)
1422 : END IF
1423 : END DO
1424 :
1425 : ! hard atom density !
1426 595 : CALL xc_dset_zero_all(deriv_set)
1427 : CALL xc_2nd_deriv_of_r(xc_section=xc_section, &
1428 : rho_set=rho_set_h, rho1_set=rho1_set_h, &
1429 : deriv_set=deriv_set, &
1430 595 : w=weight, vxc=vxc_h, vxg=vxg_h, do_triplet=is_triplet)
1431 : ! soft atom density !
1432 595 : CALL xc_dset_zero_all(deriv_set)
1433 : CALL xc_2nd_deriv_of_r(xc_section=xc_section, &
1434 : rho_set=rho_set_s, rho1_set=rho1_set_s, &
1435 : deriv_set=deriv_set, &
1436 595 : w=weight, vxc=vxc_s, vxg=vxg_s, do_triplet=is_triplet)
1437 : ! potentials
1438 1190 : DO ns = 1, nspins
1439 1184855 : fint_hh(ns)%r_coef(:, :) = 0.0_dp
1440 1185450 : fint_ss(ns)%r_coef(:, :) = 0.0_dp
1441 : END DO
1442 595 : IF (gradient_f) THEN
1443 : CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, fint_hh, fint_ss, &
1444 399 : grid_atom, basis_1c, harmonics, nspins)
1445 : ELSE
1446 : CALL gaVxcgb_noGC(vxc_h, vxc_s, fint_hh, fint_ss, &
1447 196 : grid_atom, basis_1c, harmonics, nspins)
1448 : END IF
1449 595 : IF (tau_f) THEN
1450 : CALL dgaVtaudgb(vtau_h, vtau_s, fint_hh, fint_ss, &
1451 0 : grid_atom, basis_1c, harmonics, nspins)
1452 : END IF
1453 : ! second derivative gxc
1454 595 : NULLIFY (int_hh, int_ss)
1455 595 : CALL get_rho_atom(rho_atom=rho2_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
1456 1275 : DO ns = 1, nspins
1457 2369115 : int_ss(ns)%r_coef(:, :) = int_ss(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_ss(ns)%r_coef(:, :)
1458 2369710 : int_hh(ns)%r_coef(:, :) = int_hh(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_hh(ns)%r_coef(:, :)
1459 : END DO
1460 : END DO
1461 : !
1462 170 : DO ns = 1, nspins
1463 85 : DEALLOCATE (fint_ss(ns)%r_coef)
1464 170 : DEALLOCATE (fint_hh(ns)%r_coef)
1465 : END DO
1466 205 : DEALLOCATE (fint_ss, fint_hh)
1467 :
1468 : END DO ! iat
1469 :
1470 : ! Release the xc structure used to store the xc derivatives
1471 120 : CALL xc_dset_release(deriv_set)
1472 120 : CALL xc_rho_set_release(rho_set_h)
1473 120 : CALL xc_rho_set_release(rho_set_s)
1474 120 : CALL xc_rho_set_release(rho1_set_h)
1475 120 : CALL xc_rho_set_release(rho1_set_s)
1476 :
1477 120 : DEALLOCATE (rho_h, rho_s, rho0_h, rho0_s, rho1_h, rho1_s)
1478 120 : DEALLOCATE (vxc_h, vxc_s)
1479 120 : IF (gradient_f) THEN
1480 80 : DEALLOCATE (drho_h, drho_s, drho0_h, drho0_s, drho1_h, drho1_s)
1481 80 : DEALLOCATE (vxg_h, vxg_s)
1482 : END IF
1483 418 : IF (tau_f) THEN
1484 0 : DEALLOCATE (tau_h, tau_s, tau0_h, tau0_s, tau1_h, tau1_s)
1485 0 : DEALLOCATE (vtau_h, vtau_s)
1486 : END IF
1487 :
1488 : END DO ! ikind
1489 :
1490 : END IF !xc_none
1491 :
1492 52 : CALL timestop(handle)
1493 :
1494 3796 : END SUBROUTINE gfxc_atom_diff
1495 :
1496 : ! **************************************************************************************************
1497 : !> \brief ...
1498 : !> \param grid_atom ...
1499 : !> \param harmonics ...
1500 : !> \param nspins ...
1501 : !> \param grad_func ...
1502 : !> \param ir ...
1503 : !> \param r_h ...
1504 : !> \param r_s ...
1505 : !> \param rho_h ...
1506 : !> \param rho_s ...
1507 : !> \param dr_h ...
1508 : !> \param dr_s ...
1509 : !> \param r_h_d ...
1510 : !> \param r_s_d ...
1511 : !> \param drho_h ...
1512 : !> \param drho_s ...
1513 : ! **************************************************************************************************
1514 1819440 : SUBROUTINE calc_rho_angular(grid_atom, harmonics, nspins, grad_func, &
1515 : ir, r_h, r_s, rho_h, rho_s, &
1516 : dr_h, dr_s, r_h_d, r_s_d, drho_h, drho_s)
1517 :
1518 : TYPE(grid_atom_type), POINTER :: grid_atom
1519 : TYPE(harmonics_atom_type), POINTER :: harmonics
1520 : INTEGER, INTENT(IN) :: nspins
1521 : LOGICAL, INTENT(IN) :: grad_func
1522 : INTEGER, INTENT(IN) :: ir
1523 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: r_h, r_s
1524 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: rho_h, rho_s
1525 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: dr_h, dr_s
1526 : TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER :: r_h_d, r_s_d
1527 : REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER :: drho_h, drho_s
1528 :
1529 : INTEGER :: ia, iso, ispin, na
1530 : REAL(KIND=dp) :: rad, urad
1531 :
1532 1819440 : CPASSERT(ASSOCIATED(r_h))
1533 1819440 : CPASSERT(ASSOCIATED(r_s))
1534 1819440 : CPASSERT(ASSOCIATED(rho_h))
1535 1819440 : CPASSERT(ASSOCIATED(rho_s))
1536 1819440 : IF (grad_func) THEN
1537 1053590 : CPASSERT(ASSOCIATED(dr_h))
1538 1053590 : CPASSERT(ASSOCIATED(dr_s))
1539 1053590 : CPASSERT(ASSOCIATED(r_h_d))
1540 1053590 : CPASSERT(ASSOCIATED(r_s_d))
1541 1053590 : CPASSERT(ASSOCIATED(drho_h))
1542 1053590 : CPASSERT(ASSOCIATED(drho_s))
1543 : END IF
1544 :
1545 1819440 : na = grid_atom%ng_sphere
1546 1819440 : rad = grid_atom%rad(ir)
1547 1819440 : urad = grid_atom%oorad2l(ir, 1)
1548 3939120 : DO ispin = 1, nspins
1549 31337040 : DO iso = 1, harmonics%max_iso_not0
1550 1400955120 : DO ia = 1, na
1551 : rho_h(ia, ir, ispin) = rho_h(ia, ir, ispin) + &
1552 1371437520 : r_h(ispin)%r_coef(ir, iso)*harmonics%slm(ia, iso)
1553 : rho_s(ia, ir, ispin) = rho_s(ia, ir, ispin) + &
1554 1398835440 : r_s(ispin)%r_coef(ir, iso)*harmonics%slm(ia, iso)
1555 : END DO ! ia
1556 : END DO ! iso
1557 : END DO ! ispin
1558 :
1559 1819440 : IF (grad_func) THEN
1560 2260770 : DO ispin = 1, nspins
1561 18552990 : DO iso = 1, harmonics%max_iso_not0
1562 833651920 : DO ia = 1, na
1563 :
1564 : ! components of the gradient of rho1 hard
1565 : drho_h(1, ia, ir, ispin) = drho_h(1, ia, ir, ispin) + &
1566 : dr_h(ispin)%r_coef(ir, iso)* &
1567 : harmonics%a(1, ia)*harmonics%slm(ia, iso) + &
1568 : r_h_d(1, ispin)%r_coef(ir, iso)* &
1569 816152520 : harmonics%slm(ia, iso)
1570 :
1571 : drho_h(2, ia, ir, ispin) = drho_h(2, ia, ir, ispin) + &
1572 : dr_h(ispin)%r_coef(ir, iso)* &
1573 : harmonics%a(2, ia)*harmonics%slm(ia, iso) + &
1574 : r_h_d(2, ispin)%r_coef(ir, iso)* &
1575 816152520 : harmonics%slm(ia, iso)
1576 :
1577 : drho_h(3, ia, ir, ispin) = drho_h(3, ia, ir, ispin) + &
1578 : dr_h(ispin)%r_coef(ir, iso)* &
1579 : harmonics%a(3, ia)*harmonics%slm(ia, iso) + &
1580 : r_h_d(3, ispin)%r_coef(ir, iso)* &
1581 816152520 : harmonics%slm(ia, iso)
1582 :
1583 : ! components of the gradient of rho1 soft
1584 : drho_s(1, ia, ir, ispin) = drho_s(1, ia, ir, ispin) + &
1585 : dr_s(ispin)%r_coef(ir, iso)* &
1586 : harmonics%a(1, ia)*harmonics%slm(ia, iso) + &
1587 : r_s_d(1, ispin)%r_coef(ir, iso)* &
1588 816152520 : harmonics%slm(ia, iso)
1589 :
1590 : drho_s(2, ia, ir, ispin) = drho_s(2, ia, ir, ispin) + &
1591 : dr_s(ispin)%r_coef(ir, iso)* &
1592 : harmonics%a(2, ia)*harmonics%slm(ia, iso) + &
1593 : r_s_d(2, ispin)%r_coef(ir, iso)* &
1594 816152520 : harmonics%slm(ia, iso)
1595 :
1596 : drho_s(3, ia, ir, ispin) = drho_s(3, ia, ir, ispin) + &
1597 : dr_s(ispin)%r_coef(ir, iso)* &
1598 : harmonics%a(3, ia)*harmonics%slm(ia, iso) + &
1599 : r_s_d(3, ispin)%r_coef(ir, iso)* &
1600 816152520 : harmonics%slm(ia, iso)
1601 :
1602 : drho_h(4, ia, ir, ispin) = SQRT( &
1603 : drho_h(1, ia, ir, ispin)*drho_h(1, ia, ir, ispin) + &
1604 : drho_h(2, ia, ir, ispin)*drho_h(2, ia, ir, ispin) + &
1605 816152520 : drho_h(3, ia, ir, ispin)*drho_h(3, ia, ir, ispin))
1606 :
1607 : drho_s(4, ia, ir, ispin) = SQRT( &
1608 : drho_s(1, ia, ir, ispin)*drho_s(1, ia, ir, ispin) + &
1609 : drho_s(2, ia, ir, ispin)*drho_s(2, ia, ir, ispin) + &
1610 832444740 : drho_s(3, ia, ir, ispin)*drho_s(3, ia, ir, ispin))
1611 :
1612 : END DO ! ia
1613 : END DO ! iso
1614 : END DO ! ispin
1615 : END IF
1616 :
1617 1819440 : END SUBROUTINE calc_rho_angular
1618 :
1619 : ! **************************************************************************************************
1620 : !> \brief Computes tau hard and soft on the atomic grids for meta-GGA calculations
1621 : !> \param tau_h the hard part of tau
1622 : !> \param tau_s the soft part of tau
1623 : !> \param rho_atom ...
1624 : !> \param qs_kind ...
1625 : !> \param nspins ...
1626 : !> \note This is a rewrite to correct a meta-GGA GAPW bug. This is more brute force than the original,
1627 : !> which was done along in qs_rho_atom_methods.F, but makes sure that no corner is cut in
1628 : !> terms of accuracy (A. Bussy)
1629 : ! **************************************************************************************************
1630 308 : SUBROUTINE calc_tau_atom(tau_h, tau_s, rho_atom, qs_kind, nspins)
1631 :
1632 : REAL(dp), DIMENSION(:, :, :), INTENT(INOUT) :: tau_h, tau_s
1633 : TYPE(rho_atom_type), POINTER :: rho_atom
1634 : TYPE(qs_kind_type), INTENT(IN) :: qs_kind
1635 : INTEGER, INTENT(IN) :: nspins
1636 :
1637 : CHARACTER(len=*), PARAMETER :: routineN = 'calc_tau_atom'
1638 :
1639 : INTEGER :: dir, handle, ia, ip, ipgf, ir, iset, &
1640 : iso, ispin, jp, jpgf, jset, jso, l, &
1641 : maxso, na, nr, nset, starti, startj
1642 308 : INTEGER, DIMENSION(:), POINTER :: lmax, lmin, npgf, o2nindex
1643 : REAL(dp) :: cpc_h, cpc_s
1644 308 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: fga, fgr, r1, r2
1645 308 : REAL(dp), ALLOCATABLE, DIMENSION(:, :, :) :: a1, a2
1646 308 : REAL(dp), DIMENSION(:, :), POINTER :: slm, zet
1647 308 : REAL(dp), DIMENSION(:, :, :), POINTER :: dslm_dxyz
1648 : TYPE(grid_atom_type), POINTER :: grid_atom
1649 : TYPE(gto_basis_set_type), POINTER :: basis_1c
1650 : TYPE(harmonics_atom_type), POINTER :: harmonics
1651 :
1652 308 : NULLIFY (harmonics, grid_atom, basis_1c, lmax, lmin, npgf, zet, slm, dslm_dxyz, o2nindex)
1653 :
1654 308 : CALL timeset(routineN, handle)
1655 :
1656 : !We need to put 0.5* grad_g1 dot grad_gw on the grid
1657 : !For this we need grid info, basis info, and projector info
1658 308 : CALL get_qs_kind(qs_kind, grid_atom=grid_atom, harmonics=harmonics)
1659 308 : CALL get_qs_kind(qs_kind, basis_set=basis_1c, basis_type="GAPW_1C")
1660 :
1661 308 : nr = grid_atom%nr
1662 308 : na = grid_atom%ng_sphere
1663 :
1664 308 : slm => harmonics%slm
1665 308 : dslm_dxyz => harmonics%dslm_dxyz
1666 :
1667 308 : CALL get_paw_basis_info(basis_1c, o2nindex=o2nindex)
1668 :
1669 : !zeroing tau, assuming it is already allocated
1670 945916 : tau_h = 0.0_dp
1671 945916 : tau_s = 0.0_dp
1672 :
1673 : CALL get_gto_basis_set(gto_basis_set=basis_1c, lmax=lmax, lmin=lmin, npgf=npgf, &
1674 308 : nset=nset, zet=zet, maxso=maxso)
1675 :
1676 : !Separate the functions into purely r and purely angular parts, precompute them all
1677 2156 : ALLOCATE (a1(na, nset*maxso, 3), a2(na, nset*maxso, 3))
1678 1848 : ALLOCATE (r1(nr, nset*maxso), r2(nr, nset*maxso))
1679 3859916 : a1 = 0.0_dp; a2 = 0.0_dp
1680 1300788 : r1 = 0.0_dp; r2 = 0.0_dp
1681 :
1682 1008 : DO iset = 1, nset
1683 3200 : DO ipgf = 1, npgf(iset)
1684 2192 : starti = (iset - 1)*maxso + (ipgf - 1)*nsoset(lmax(iset))
1685 8211 : DO iso = nsoset(lmin(iset) - 1) + 1, nsoset(lmax(iset))
1686 5319 : l = indso(1, iso)
1687 :
1688 : ! The x derivative of the spherical orbital, divided in angular and radial parts
1689 : ! Two of each are needed because d/dx(r^l Y_lm) * exp(-al*r^2) + r^l Y_lm * ! d/dx(exp-al*r^2)
1690 :
1691 : ! the purely radial part of d/dx(r^l Y_lm) * exp(-al*r^2) (same for y, z)
1692 289469 : r1(1:nr, starti + iso) = grid_atom%rad(1:nr)**(l - 1)*EXP(-zet(ipgf, iset)*grid_atom%rad2(1:nr))
1693 :
1694 : ! the purely radial part of r^l Y_lm * d/dx(exp-al*r^2) (same for y, z)
1695 : r2(1:nr, starti + iso) = -2.0_dp*zet(ipgf, iset)*grid_atom%rad(1:nr)**(l + 1) &
1696 289469 : *EXP(-zet(ipgf, iset)*grid_atom%rad2(1:nr))
1697 :
1698 23468 : DO dir = 1, 3
1699 : ! the purely angular part of d/dx(r^l Y_lm) * exp(-al*r^2)
1700 853119 : a1(1:na, starti + iso, dir) = dslm_dxyz(dir, 1:na, iso)
1701 :
1702 : ! the purely angular part of r^l Y_lm * d/dx(exp-al*r^2)
1703 858438 : a2(1:na, starti + iso, dir) = harmonics%a(dir, 1:na)*slm(1:na, iso)
1704 : END DO
1705 :
1706 : END DO !iso
1707 : END DO !ipgf
1708 : END DO !iset
1709 :
1710 : !Compute the matrix products
1711 924 : ALLOCATE (fga(na, 1))
1712 924 : ALLOCATE (fgr(nr, 1))
1713 33960 : fga = 0.0_dp; fgr = 0.0_dp
1714 :
1715 1008 : DO iset = 1, nset
1716 2984 : DO jset = 1, nset
1717 9254 : DO ipgf = 1, npgf(iset)
1718 6578 : starti = (iset - 1)*maxso + (ipgf - 1)*nsoset(lmax(iset))
1719 33710 : DO jpgf = 1, npgf(jset)
1720 25156 : startj = (jset - 1)*maxso + (jpgf - 1)*nsoset(lmax(jset))
1721 :
1722 99450 : DO iso = nsoset(lmin(iset) - 1) + 1, nsoset(lmax(iset))
1723 296525 : DO jso = nsoset(lmin(jset) - 1) + 1, nsoset(lmax(jset))
1724 :
1725 203653 : ip = o2nindex(starti + iso)
1726 203653 : jp = o2nindex(startj + jso)
1727 :
1728 : !Two component per function => 4 terms in total
1729 :
1730 : ! take r1*a1(dir) * r1*a1(dir)
1731 10704803 : fgr(1:nr, 1) = r1(1:nr, starti + iso)*r1(1:nr, startj + jso)
1732 814612 : DO dir = 1, 3
1733 31846869 : fga(1:na, 1) = a1(1:na, starti + iso, dir)*a1(1:na, startj + jso, dir)
1734 :
1735 1425571 : DO ispin = 1, nspins
1736 : !get the projectors
1737 610959 : cpc_h = rho_atom%cpc_h(ispin)%r_coef(ip, jp)
1738 610959 : cpc_s = rho_atom%cpc_s(ispin)%r_coef(ip, jp)
1739 :
1740 : !compute contribution to tau
1741 32725368 : DO ir = 1, nr
1742 1676082909 : DO ia = 1, na
1743 : tau_h(ia, ir, ispin) = tau_h(ia, ir, ispin) + 0.5_dp*cpc_h* &
1744 1643968500 : fgr(ir, 1)*fga(ia, 1)
1745 :
1746 : tau_s(ia, ir, ispin) = tau_s(ia, ir, ispin) + 0.5_dp*cpc_s* &
1747 1675471950 : fgr(ir, 1)*fga(ia, 1)
1748 : END DO
1749 : END DO
1750 :
1751 : END DO !ispin
1752 : END DO !dir
1753 :
1754 : ! add r1*a1(dir) * r2*a2(dir)
1755 10704803 : fgr(1:nr, 1) = r1(1:nr, starti + iso)*r2(1:nr, startj + jso)
1756 814612 : DO dir = 1, 3
1757 31846869 : fga(1:na, 1) = a1(1:na, starti + iso, dir)*a2(1:na, startj + jso, dir)
1758 :
1759 1425571 : DO ispin = 1, nspins
1760 : !get the projectors
1761 610959 : cpc_h = rho_atom%cpc_h(ispin)%r_coef(ip, jp)
1762 610959 : cpc_s = rho_atom%cpc_s(ispin)%r_coef(ip, jp)
1763 :
1764 : !compute contribution to tau
1765 32725368 : DO ir = 1, nr
1766 1676082909 : DO ia = 1, na
1767 : tau_h(ia, ir, ispin) = tau_h(ia, ir, ispin) + 0.5_dp*cpc_h* &
1768 1643968500 : fgr(ir, 1)*fga(ia, 1)
1769 :
1770 : tau_s(ia, ir, ispin) = tau_s(ia, ir, ispin) + 0.5_dp*cpc_s* &
1771 1675471950 : fgr(ir, 1)*fga(ia, 1)
1772 : END DO
1773 : END DO
1774 :
1775 : END DO !ispin
1776 : END DO !dir
1777 :
1778 : ! add r2*a2(dir) * V * r1*a1(dir)
1779 10704803 : fgr(1:nr, 1) = r2(1:nr, starti + iso)*r1(1:nr, startj + jso)
1780 814612 : DO dir = 1, 3
1781 31846869 : fga(1:na, 1) = a2(1:na, starti + iso, dir)*a1(1:na, startj + jso, dir)
1782 :
1783 1425571 : DO ispin = 1, nspins
1784 : !get the projectors
1785 610959 : cpc_h = rho_atom%cpc_h(ispin)%r_coef(ip, jp)
1786 610959 : cpc_s = rho_atom%cpc_s(ispin)%r_coef(ip, jp)
1787 :
1788 : !compute contribution to tau
1789 32725368 : DO ir = 1, nr
1790 1676082909 : DO ia = 1, na
1791 : tau_h(ia, ir, ispin) = tau_h(ia, ir, ispin) + 0.5_dp*cpc_h* &
1792 1643968500 : fgr(ir, 1)*fga(ia, 1)
1793 :
1794 : tau_s(ia, ir, ispin) = tau_s(ia, ir, ispin) + 0.5_dp*cpc_s* &
1795 1675471950 : fgr(ir, 1)*fga(ia, 1)
1796 : END DO
1797 : END DO
1798 :
1799 : END DO !ispin
1800 : END DO !dir
1801 :
1802 : ! add the last term: r2*a2(dir) * r2*a2(dir)
1803 10704803 : fgr(1:nr, 1) = r2(1:nr, starti + iso)*r2(1:nr, startj + jso)
1804 882328 : DO dir = 1, 3
1805 31846869 : fga(1:na, 1) = a2(1:na, starti + iso, dir)*a2(1:na, startj + jso, dir)
1806 :
1807 1425571 : DO ispin = 1, nspins
1808 : !get the projectors
1809 610959 : cpc_h = rho_atom%cpc_h(ispin)%r_coef(ip, jp)
1810 610959 : cpc_s = rho_atom%cpc_s(ispin)%r_coef(ip, jp)
1811 :
1812 : !compute contribution to tau
1813 32725368 : DO ir = 1, nr
1814 1676082909 : DO ia = 1, na
1815 : tau_h(ia, ir, ispin) = tau_h(ia, ir, ispin) + 0.5_dp*cpc_h* &
1816 1643968500 : fgr(ir, 1)*fga(ia, 1)
1817 :
1818 : tau_s(ia, ir, ispin) = tau_s(ia, ir, ispin) + 0.5_dp*cpc_s* &
1819 1675471950 : fgr(ir, 1)*fga(ia, 1)
1820 : END DO
1821 : END DO
1822 :
1823 : END DO !ispin
1824 : END DO !dir
1825 :
1826 : END DO !jso
1827 : END DO !iso
1828 :
1829 : END DO !jpgf
1830 : END DO !ipgf
1831 : END DO !jset
1832 : END DO !iset
1833 :
1834 308 : DEALLOCATE (o2nindex)
1835 :
1836 308 : CALL timestop(handle)
1837 :
1838 924 : END SUBROUTINE calc_tau_atom
1839 :
1840 : ! **************************************************************************************************
1841 : !> \brief ...
1842 : !> \param grid_atom ...
1843 : !> \param nspins ...
1844 : !> \param grad_func ...
1845 : !> \param ir ...
1846 : !> \param rho_nlcc ...
1847 : !> \param rho_h ...
1848 : !> \param rho_s ...
1849 : !> \param drho_nlcc ...
1850 : !> \param drho_h ...
1851 : !> \param drho_s ...
1852 : ! **************************************************************************************************
1853 2600 : SUBROUTINE calc_rho_nlcc(grid_atom, nspins, grad_func, &
1854 2600 : ir, rho_nlcc, rho_h, rho_s, drho_nlcc, drho_h, drho_s)
1855 :
1856 : TYPE(grid_atom_type), POINTER :: grid_atom
1857 : INTEGER, INTENT(IN) :: nspins
1858 : LOGICAL, INTENT(IN) :: grad_func
1859 : INTEGER, INTENT(IN) :: ir
1860 : REAL(KIND=dp), DIMENSION(:) :: rho_nlcc
1861 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: rho_h, rho_s
1862 : REAL(KIND=dp), DIMENSION(:) :: drho_nlcc
1863 : REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER :: drho_h, drho_s
1864 :
1865 : INTEGER :: ia, ispin, na
1866 : REAL(KIND=dp) :: drho, dx, dy, dz, rad, rho, urad, xsp
1867 :
1868 2600 : CPASSERT(ASSOCIATED(rho_h))
1869 2600 : CPASSERT(ASSOCIATED(rho_s))
1870 2600 : IF (grad_func) THEN
1871 2600 : CPASSERT(ASSOCIATED(drho_h))
1872 2600 : CPASSERT(ASSOCIATED(drho_s))
1873 : END IF
1874 :
1875 2600 : na = grid_atom%ng_sphere
1876 2600 : rad = grid_atom%rad(ir)
1877 2600 : urad = grid_atom%oorad2l(ir, 1)
1878 :
1879 2600 : xsp = REAL(nspins, KIND=dp)
1880 2600 : rho = rho_nlcc(ir)/xsp
1881 5200 : DO ispin = 1, nspins
1882 132600 : rho_h(1:na, ir, ispin) = rho_h(1:na, ir, ispin) + rho
1883 135200 : rho_s(1:na, ir, ispin) = rho_s(1:na, ir, ispin) + rho
1884 : END DO ! ispin
1885 :
1886 2600 : IF (grad_func) THEN
1887 2600 : drho = drho_nlcc(ir)/xsp
1888 5200 : DO ispin = 1, nspins
1889 135200 : DO ia = 1, na
1890 130000 : IF (grid_atom%azi(ia) == 0.0_dp) THEN
1891 : dx = 0.0_dp
1892 : dy = 0.0_dp
1893 : ELSE
1894 117000 : dx = grid_atom%sin_pol(ia)*grid_atom%sin_azi(ia)
1895 117000 : dy = grid_atom%sin_pol(ia)*grid_atom%cos_azi(ia)
1896 : END IF
1897 130000 : dz = grid_atom%cos_pol(ia)
1898 : ! components of the gradient of rho1 hard
1899 130000 : drho_h(1, ia, ir, ispin) = drho_h(1, ia, ir, ispin) + drho*dx
1900 130000 : drho_h(2, ia, ir, ispin) = drho_h(2, ia, ir, ispin) + drho*dy
1901 130000 : drho_h(3, ia, ir, ispin) = drho_h(3, ia, ir, ispin) + drho*dz
1902 : ! components of the gradient of rho1 soft
1903 130000 : drho_s(1, ia, ir, ispin) = drho_s(1, ia, ir, ispin) + drho*dx
1904 130000 : drho_s(2, ia, ir, ispin) = drho_s(2, ia, ir, ispin) + drho*dy
1905 130000 : drho_s(3, ia, ir, ispin) = drho_s(3, ia, ir, ispin) + drho*dz
1906 : ! norm of gradient
1907 : drho_h(4, ia, ir, ispin) = SQRT( &
1908 : drho_h(1, ia, ir, ispin)*drho_h(1, ia, ir, ispin) + &
1909 : drho_h(2, ia, ir, ispin)*drho_h(2, ia, ir, ispin) + &
1910 130000 : drho_h(3, ia, ir, ispin)*drho_h(3, ia, ir, ispin))
1911 :
1912 : drho_s(4, ia, ir, ispin) = SQRT( &
1913 : drho_s(1, ia, ir, ispin)*drho_s(1, ia, ir, ispin) + &
1914 : drho_s(2, ia, ir, ispin)*drho_s(2, ia, ir, ispin) + &
1915 132600 : drho_s(3, ia, ir, ispin)*drho_s(3, ia, ir, ispin))
1916 : END DO ! ia
1917 : END DO ! ispin
1918 : END IF
1919 :
1920 2600 : END SUBROUTINE calc_rho_nlcc
1921 :
1922 : ! **************************************************************************************************
1923 : !> \brief ...
1924 : !> \param vxc_h ...
1925 : !> \param vxc_s ...
1926 : !> \param int_hh ...
1927 : !> \param int_ss ...
1928 : !> \param grid_atom ...
1929 : !> \param basis_1c ...
1930 : !> \param harmonics ...
1931 : !> \param nspins ...
1932 : ! **************************************************************************************************
1933 11130 : SUBROUTINE gaVxcgb_noGC(vxc_h, vxc_s, int_hh, int_ss, grid_atom, basis_1c, harmonics, nspins)
1934 :
1935 : REAL(dp), DIMENSION(:, :, :), POINTER :: vxc_h, vxc_s
1936 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: int_hh, int_ss
1937 : TYPE(grid_atom_type), POINTER :: grid_atom
1938 : TYPE(gto_basis_set_type), POINTER :: basis_1c
1939 : TYPE(harmonics_atom_type), POINTER :: harmonics
1940 : INTEGER, INTENT(IN) :: nspins
1941 :
1942 : CHARACTER(len=*), PARAMETER :: routineN = 'gaVxcgb_noGC'
1943 :
1944 : INTEGER :: handle, ia, ic, icg, ipgf1, ipgf2, ir, iset1, iset2, iso, iso1, iso2, ispin, l, &
1945 : ld, lmax12, lmax_expansion, lmin12, m1, m2, max_iso_not0, max_iso_not0_local, max_s_harm, &
1946 : maxl, maxso, n1, n2, na, ngau1, ngau2, nngau1, nr, nset, size1
1947 : INTEGER, ALLOCATABLE, DIMENSION(:) :: cg_n_list
1948 : INTEGER, ALLOCATABLE, DIMENSION(:, :, :) :: cg_list
1949 11130 : INTEGER, DIMENSION(:), POINTER :: lmax, lmin, npgf
1950 11130 : REAL(dp), ALLOCATABLE, DIMENSION(:) :: g1, g2
1951 11130 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: gg, gVg_h, gVg_s, matso_h, matso_s, vx
1952 11130 : REAL(dp), DIMENSION(:, :), POINTER :: zet
1953 : REAL(dp), DIMENSION(:, :, :), POINTER :: my_CG
1954 :
1955 11130 : CALL timeset(routineN, handle)
1956 :
1957 11130 : NULLIFY (lmin, lmax, npgf, zet, my_CG)
1958 :
1959 : CALL get_gto_basis_set(gto_basis_set=basis_1c, lmax=lmax, lmin=lmin, &
1960 : maxso=maxso, maxl=maxl, npgf=npgf, &
1961 11130 : nset=nset, zet=zet)
1962 :
1963 11130 : nr = grid_atom%nr
1964 11130 : na = grid_atom%ng_sphere
1965 11130 : my_CG => harmonics%my_CG
1966 11130 : max_iso_not0 = harmonics%max_iso_not0
1967 11130 : lmax_expansion = indso(1, max_iso_not0)
1968 11130 : max_s_harm = harmonics%max_s_harm
1969 :
1970 77910 : ALLOCATE (g1(nr), g2(nr), gg(nr, 0:2*maxl))
1971 66780 : ALLOCATE (gVg_h(na, 0:2*maxl), gVg_s(na, 0:2*maxl))
1972 : ALLOCATE (matso_h(nsoset(maxl), nsoset(maxl)), &
1973 66780 : matso_s(nsoset(maxl), nsoset(maxl)))
1974 44520 : ALLOCATE (vx(na, nr))
1975 66780 : ALLOCATE (cg_list(2, nsoset(maxl)**2, max_s_harm), cg_n_list(max_s_harm))
1976 :
1977 713930 : g1 = 0.0_dp
1978 713930 : g2 = 0.0_dp
1979 11130 : m1 = 0
1980 37301 : DO iset1 = 1, nset
1981 26171 : n1 = nsoset(lmax(iset1))
1982 26171 : m2 = 0
1983 104104 : DO iset2 = 1, nset
1984 : CALL get_none0_cg_list(my_CG, lmin(iset1), lmax(iset1), lmin(iset2), lmax(iset2), &
1985 77933 : max_s_harm, lmax_expansion, cg_list, cg_n_list, max_iso_not0_local)
1986 77933 : CPASSERT(max_iso_not0_local .LE. max_iso_not0)
1987 :
1988 77933 : n2 = nsoset(lmax(iset2))
1989 285340 : DO ipgf1 = 1, npgf(iset1)
1990 207407 : ngau1 = n1*(ipgf1 - 1) + m1
1991 207407 : size1 = nsoset(lmax(iset1)) - nsoset(lmin(iset1) - 1)
1992 207407 : nngau1 = nsoset(lmin(iset1) - 1) + ngau1
1993 :
1994 12701757 : g1(1:nr) = EXP(-zet(ipgf1, iset1)*grid_atom%rad2(1:nr))
1995 990514 : DO ipgf2 = 1, npgf(iset2)
1996 705174 : ngau2 = n2*(ipgf2 - 1) + m2
1997 :
1998 42454574 : g2(1:nr) = EXP(-zet(ipgf2, iset2)*grid_atom%rad2(1:nr))
1999 705174 : lmin12 = lmin(iset1) + lmin(iset2)
2000 705174 : lmax12 = lmax(iset1) + lmax(iset2)
2001 :
2002 : ! reduce expansion local densities
2003 912581 : IF (lmin12 .LE. lmax_expansion) THEN
2004 :
2005 188648786 : gg = 0.0_dp
2006 704229 : IF (lmin12 == 0) THEN
2007 25158111 : gg(1:nr, lmin12) = g1(1:nr)*g2(1:nr)
2008 : ELSE
2009 17248268 : gg(1:nr, lmin12) = grid_atom%rad2l(1:nr, lmin12)*g1(1:nr)*g2(1:nr)
2010 : END IF
2011 :
2012 : ! limit the expansion of the local densities to a max L
2013 704229 : IF (lmax12 .GT. lmax_expansion) lmax12 = lmax_expansion
2014 :
2015 989825 : DO l = lmin12 + 1, lmax12
2016 19770425 : gg(1:nr, l) = grid_atom%rad(1:nr)*gg(:, l - 1)
2017 : END DO
2018 :
2019 1563382 : DO ispin = 1, nspins
2020 859153 : ld = lmax12 + 1
2021 55319803 : DO ir = 1, nr
2022 2778352303 : vx(1:na, ir) = vxc_h(1:na, ir, ispin)
2023 : END DO
2024 : CALL dgemm('N', 'N', na, ld, nr, 1.0_dp, vx(1:na, 1:nr), na, &
2025 859153 : gg(1:nr, 0:lmax12), nr, 0.0_dp, gVg_h(1:na, 0:lmax12), na)
2026 55319803 : DO ir = 1, nr
2027 2778352303 : vx(1:na, ir) = vxc_s(1:na, ir, ispin)
2028 : END DO
2029 : CALL dgemm('N', 'N', na, ld, nr, 1.0_dp, vx(1:na, 1:nr), na, &
2030 859153 : gg(1:nr, 0:lmax12), nr, 0.0_dp, gVg_s(1:na, 0:lmax12), na)
2031 :
2032 80831721 : matso_h = 0.0_dp
2033 80831721 : matso_s = 0.0_dp
2034 6523692 : DO iso = 1, max_iso_not0_local
2035 16789867 : DO icg = 1, cg_n_list(iso)
2036 10266175 : iso1 = cg_list(1, icg, iso)
2037 10266175 : iso2 = cg_list(2, icg, iso)
2038 10266175 : l = indso(1, iso1) + indso(1, iso2)
2039 :
2040 10266175 : CPASSERT(l <= lmax_expansion)
2041 529239464 : DO ia = 1, na
2042 : matso_h(iso1, iso2) = matso_h(iso1, iso2) + &
2043 : gVg_h(ia, l)* &
2044 : my_CG(iso1, iso2, iso)* &
2045 513308750 : harmonics%slm(ia, iso)
2046 : matso_s(iso1, iso2) = matso_s(iso1, iso2) + &
2047 : gVg_s(ia, l)* &
2048 : my_CG(iso1, iso2, iso)* &
2049 523574925 : harmonics%slm(ia, iso)
2050 : END DO
2051 : END DO
2052 : END DO
2053 :
2054 : ! Write in the global matrix
2055 3717179 : DO ic = nsoset(lmin(iset2) - 1) + 1, nsoset(lmax(iset2))
2056 2153797 : iso1 = nsoset(lmin(iset1) - 1) + 1
2057 2153797 : iso2 = ngau2 + ic
2058 : CALL daxpy(size1, 1.0_dp, matso_h(iso1, ic), 1, &
2059 2153797 : int_hh(ispin)%r_coef(nngau1 + 1, iso2), 1)
2060 : CALL daxpy(size1, 1.0_dp, matso_s(iso1, ic), 1, &
2061 3012950 : int_ss(ispin)%r_coef(nngau1 + 1, iso2), 1)
2062 : END DO
2063 :
2064 : END DO ! ispin
2065 :
2066 : END IF ! lmax_expansion
2067 :
2068 : END DO ! ipfg2
2069 : END DO ! ipfg1
2070 182037 : m2 = m2 + maxso
2071 : END DO ! iset2
2072 37301 : m1 = m1 + maxso
2073 : END DO ! iset1
2074 :
2075 11130 : DEALLOCATE (g1, g2, gg, matso_h, matso_s, gVg_s, gVg_h, vx)
2076 :
2077 11130 : DEALLOCATE (cg_list, cg_n_list)
2078 :
2079 11130 : CALL timestop(handle)
2080 :
2081 11130 : END SUBROUTINE gaVxcgb_noGC
2082 :
2083 : ! **************************************************************************************************
2084 : !> \brief ...
2085 : !> \param vxc_h ...
2086 : !> \param vxc_s ...
2087 : !> \param vxg_h ...
2088 : !> \param vxg_s ...
2089 : !> \param int_hh ...
2090 : !> \param int_ss ...
2091 : !> \param grid_atom ...
2092 : !> \param basis_1c ...
2093 : !> \param harmonics ...
2094 : !> \param nspins ...
2095 : ! **************************************************************************************************
2096 16648 : SUBROUTINE gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, int_hh, int_ss, &
2097 : grid_atom, basis_1c, harmonics, nspins)
2098 :
2099 : REAL(dp), DIMENSION(:, :, :), POINTER :: vxc_h, vxc_s
2100 : REAL(dp), DIMENSION(:, :, :, :), POINTER :: vxg_h, vxg_s
2101 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: int_hh, int_ss
2102 : TYPE(grid_atom_type), POINTER :: grid_atom
2103 : TYPE(gto_basis_set_type), POINTER :: basis_1c
2104 : TYPE(harmonics_atom_type), POINTER :: harmonics
2105 : INTEGER, INTENT(IN) :: nspins
2106 :
2107 : CHARACTER(len=*), PARAMETER :: routineN = 'gaVxcgb_GC'
2108 :
2109 : INTEGER :: dmax_iso_not0_local, handle, ia, ic, icg, ipgf1, ipgf2, ir, iset1, iset2, iso, &
2110 : iso1, iso2, ispin, l, lmax12, lmax_expansion, lmin12, m1, m2, max_iso_not0, &
2111 : max_iso_not0_local, max_s_harm, maxl, maxso, n1, n2, na, ngau1, ngau2, nngau1, nr, nset, &
2112 : size1
2113 : INTEGER, ALLOCATABLE, DIMENSION(:) :: cg_n_list, dcg_n_list
2114 : INTEGER, ALLOCATABLE, DIMENSION(:, :, :) :: cg_list, dcg_list
2115 16648 : INTEGER, DIMENSION(:), POINTER :: lmax, lmin, npgf
2116 : REAL(dp) :: urad
2117 16648 : REAL(dp), ALLOCATABLE, DIMENSION(:) :: g1, g2
2118 16648 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: dgg, gg, gVXCg_h, gVXCg_s, matso_h, &
2119 16648 : matso_s
2120 16648 : REAL(dp), ALLOCATABLE, DIMENSION(:, :, :) :: gVXGg_h, gVXGg_s
2121 16648 : REAL(dp), DIMENSION(:, :), POINTER :: zet
2122 : REAL(dp), DIMENSION(:, :, :), POINTER :: my_CG
2123 : REAL(dp), DIMENSION(:, :, :, :), POINTER :: my_CG_dxyz
2124 :
2125 16648 : CALL timeset(routineN, handle)
2126 :
2127 16648 : NULLIFY (lmin, lmax, npgf, zet, my_CG, my_CG_dxyz)
2128 :
2129 : CALL get_gto_basis_set(gto_basis_set=basis_1c, lmax=lmax, lmin=lmin, &
2130 : maxso=maxso, maxl=maxl, npgf=npgf, &
2131 16648 : nset=nset, zet=zet)
2132 :
2133 16648 : nr = grid_atom%nr
2134 16648 : na = grid_atom%ng_sphere
2135 16648 : my_CG => harmonics%my_CG
2136 16648 : my_CG_dxyz => harmonics%my_CG_dxyz
2137 16648 : max_iso_not0 = harmonics%max_iso_not0
2138 16648 : lmax_expansion = indso(1, max_iso_not0)
2139 16648 : max_s_harm = harmonics%max_s_harm
2140 :
2141 149832 : ALLOCATE (g1(nr), g2(nr), gg(nr, 0:2*maxl), dgg(nr, 0:2*maxl))
2142 99888 : ALLOCATE (gVXCg_h(na, 0:2*maxl), gVXCg_s(na, 0:2*maxl))
2143 99888 : ALLOCATE (gVXGg_h(3, na, 0:2*maxl), gVXGg_s(3, na, 0:2*maxl))
2144 : ALLOCATE (cg_list(2, nsoset(maxl)**2, max_s_harm), cg_n_list(max_s_harm), &
2145 149832 : dcg_list(2, nsoset(maxl)**2, max_s_harm), dcg_n_list(max_s_harm))
2146 :
2147 : ALLOCATE (matso_h(nsoset(maxl), nsoset(maxl)), &
2148 99888 : matso_s(nsoset(maxl), nsoset(maxl)))
2149 :
2150 35696 : DO ispin = 1, nspins
2151 :
2152 996528 : g1 = 0.0_dp
2153 996528 : g2 = 0.0_dp
2154 19048 : m1 = 0
2155 82715 : DO iset1 = 1, nset
2156 47019 : n1 = nsoset(lmax(iset1))
2157 47019 : m2 = 0
2158 206790 : DO iset2 = 1, nset
2159 : CALL get_none0_cg_list(my_CG, lmin(iset1), lmax(iset1), lmin(iset2), lmax(iset2), &
2160 159771 : max_s_harm, lmax_expansion, cg_list, cg_n_list, max_iso_not0_local)
2161 159771 : CPASSERT(max_iso_not0_local .LE. max_iso_not0)
2162 : CALL get_none0_cg_list(my_CG_dxyz, lmin(iset1), lmax(iset1), lmin(iset2), lmax(iset2), &
2163 159771 : max_s_harm, lmax_expansion, dcg_list, dcg_n_list, dmax_iso_not0_local)
2164 :
2165 159771 : n2 = nsoset(lmax(iset2))
2166 498766 : DO ipgf1 = 1, npgf(iset1)
2167 338995 : ngau1 = n1*(ipgf1 - 1) + m1
2168 338995 : size1 = nsoset(lmax(iset1)) - nsoset(lmin(iset1) - 1)
2169 338995 : nngau1 = nsoset(lmin(iset1) - 1) + ngau1
2170 :
2171 18009825 : g1(1:nr) = EXP(-zet(ipgf1, iset1)*grid_atom%rad2(1:nr))
2172 1321824 : DO ipgf2 = 1, npgf(iset2)
2173 823058 : ngau2 = n2*(ipgf2 - 1) + m2
2174 :
2175 44002638 : g2(1:nr) = EXP(-zet(ipgf2, iset2)*grid_atom%rad2(1:nr))
2176 823058 : lmin12 = lmin(iset1) + lmin(iset2)
2177 823058 : lmax12 = lmax(iset1) + lmax(iset2)
2178 :
2179 : !test reduce expansion local densities
2180 823058 : IF (lmin12 .LE. lmax_expansion) THEN
2181 :
2182 185462284 : gg = 0.0_dp
2183 185462284 : dgg = 0.0_dp
2184 :
2185 822458 : IF (lmin12 == 0) THEN
2186 30060597 : gg(1:nr, lmin12) = g1(1:nr)*g2(1:nr)
2187 : ELSE
2188 13911441 : gg(1:nr, lmin12) = grid_atom%rad2l(1:nr, lmin12)*g1(1:nr)*g2(1:nr)
2189 : END IF
2190 :
2191 : !test reduce expansion local densities
2192 822458 : IF (lmax12 .GT. lmax_expansion) lmax12 = lmax_expansion
2193 :
2194 1301010 : DO l = lmin12 + 1, lmax12
2195 25864952 : gg(1:nr, l) = grid_atom%rad(1:nr)*gg(:, l - 1)
2196 : dgg(1:nr, l - 1) = dgg(1:nr, l - 1) - 2.0_dp*(zet(ipgf1, iset1) + &
2197 26687410 : zet(ipgf2, iset2))*gg(1:nr, l)
2198 : END DO
2199 : dgg(1:nr, lmax12) = dgg(1:nr, lmax12) - 2.0_dp*(zet(ipgf1, iset1) + &
2200 : zet(ipgf2, iset2))*grid_atom%rad(1:nr)* &
2201 43972038 : gg(1:nr, lmax12)
2202 :
2203 175698560 : gVXCg_h = 0.0_dp
2204 175698560 : gVXCg_s = 0.0_dp
2205 690031268 : gVXGg_h = 0.0_dp
2206 690031268 : gVXGg_s = 0.0_dp
2207 :
2208 : ! Cross Term
2209 2123468 : DO l = lmin12, lmax12
2210 67125200 : DO ia = 1, na
2211 3496644142 : DO ir = 1, nr
2212 : gVXCg_h(ia, l) = gVXCg_h(ia, l) + &
2213 : gg(ir, l)*vxc_h(ia, ir, ispin) + &
2214 : dgg(ir, l)* &
2215 : (vxg_h(1, ia, ir, ispin)*harmonics%a(1, ia) + &
2216 : vxg_h(2, ia, ir, ispin)*harmonics%a(2, ia) + &
2217 3430341400 : vxg_h(3, ia, ir, ispin)*harmonics%a(3, ia))
2218 :
2219 : gVXCg_s(ia, l) = gVXCg_s(ia, l) + &
2220 : gg(ir, l)*vxc_s(ia, ir, ispin) + &
2221 : dgg(ir, l)* &
2222 : (vxg_s(1, ia, ir, ispin)*harmonics%a(1, ia) + &
2223 : vxg_s(2, ia, ir, ispin)*harmonics%a(2, ia) + &
2224 3430341400 : vxg_s(3, ia, ir, ispin)*harmonics%a(3, ia))
2225 :
2226 3430341400 : urad = grid_atom%oorad2l(ir, 1)
2227 :
2228 : gVXGg_h(1, ia, l) = gVXGg_h(1, ia, l) + &
2229 : vxg_h(1, ia, ir, ispin)* &
2230 3430341400 : gg(ir, l)*urad
2231 :
2232 : gVXGg_h(2, ia, l) = gVXGg_h(2, ia, l) + &
2233 : vxg_h(2, ia, ir, ispin)* &
2234 3430341400 : gg(ir, l)*urad
2235 :
2236 : gVXGg_h(3, ia, l) = gVXGg_h(3, ia, l) + &
2237 : vxg_h(3, ia, ir, ispin)* &
2238 3430341400 : gg(ir, l)*urad
2239 :
2240 : gVXGg_s(1, ia, l) = gVXGg_s(1, ia, l) + &
2241 : vxg_s(1, ia, ir, ispin)* &
2242 3430341400 : gg(ir, l)*urad
2243 :
2244 : gVXGg_s(2, ia, l) = gVXGg_s(2, ia, l) + &
2245 : vxg_s(2, ia, ir, ispin)* &
2246 3430341400 : gg(ir, l)*urad
2247 :
2248 : gVXGg_s(3, ia, l) = gVXGg_s(3, ia, l) + &
2249 : vxg_s(3, ia, ir, ispin)* &
2250 3495343132 : gg(ir, l)*urad
2251 :
2252 : END DO ! ir
2253 : END DO ! ia
2254 : END DO ! l
2255 :
2256 65854302 : matso_h = 0.0_dp
2257 65854302 : matso_s = 0.0_dp
2258 5476224 : DO iso = 1, max_iso_not0_local
2259 14629934 : DO icg = 1, cg_n_list(iso)
2260 9153710 : iso1 = cg_list(1, icg, iso)
2261 9153710 : iso2 = cg_list(2, icg, iso)
2262 :
2263 9153710 : l = indso(1, iso1) + indso(1, iso2)
2264 :
2265 : !test reduce expansion local densities
2266 9153710 : CPASSERT(l <= lmax_expansion)
2267 471244636 : DO ia = 1, na
2268 : matso_h(iso1, iso2) = matso_h(iso1, iso2) + &
2269 : gVXCg_h(ia, l)* &
2270 : harmonics%slm(ia, iso)* &
2271 457437160 : my_CG(iso1, iso2, iso)
2272 : matso_s(iso1, iso2) = matso_s(iso1, iso2) + &
2273 : gVXCg_s(ia, l)* &
2274 : harmonics%slm(ia, iso)* &
2275 466590870 : my_CG(iso1, iso2, iso)
2276 : END DO ! ia
2277 :
2278 : !test reduce expansion local densities
2279 :
2280 : END DO
2281 :
2282 : END DO ! iso
2283 :
2284 2913706 : DO iso = 1, dmax_iso_not0_local
2285 16847874 : DO icg = 1, dcg_n_list(iso)
2286 13934168 : iso1 = dcg_list(1, icg, iso)
2287 13934168 : iso2 = dcg_list(2, icg, iso)
2288 :
2289 13934168 : l = indso(1, iso1) + indso(1, iso2)
2290 : !test reduce expansion local densities
2291 13934168 : CPASSERT(l <= lmax_expansion)
2292 711994484 : DO ia = 1, na
2293 : matso_h(iso1, iso2) = matso_h(iso1, iso2) + &
2294 : (gVXGg_h(1, ia, l)*my_CG_dxyz(1, iso1, iso2, iso) + &
2295 : gVXGg_h(2, ia, l)*my_CG_dxyz(2, iso1, iso2, iso) + &
2296 : gVXGg_h(3, ia, l)*my_CG_dxyz(3, iso1, iso2, iso))* &
2297 695969068 : harmonics%slm(ia, iso)
2298 :
2299 : matso_s(iso1, iso2) = matso_s(iso1, iso2) + &
2300 : (gVXGg_s(1, ia, l)*my_CG_dxyz(1, iso1, iso2, iso) + &
2301 : gVXGg_s(2, ia, l)*my_CG_dxyz(2, iso1, iso2, iso) + &
2302 : gVXGg_s(3, ia, l)*my_CG_dxyz(3, iso1, iso2, iso))* &
2303 709903236 : harmonics%slm(ia, iso)
2304 :
2305 : END DO ! ia
2306 :
2307 : !test reduce expansion local densities
2308 :
2309 : END DO ! icg
2310 : END DO ! iso
2311 : !test reduce expansion local densities
2312 : END IF ! lmax_expansion
2313 :
2314 : ! Write in the global matrix
2315 3167403 : DO ic = nsoset(lmin(iset2) - 1) + 1, nsoset(lmax(iset2))
2316 2005350 : iso1 = nsoset(lmin(iset1) - 1) + 1
2317 2005350 : iso2 = ngau2 + ic
2318 : CALL daxpy(size1, 1.0_dp, matso_h(iso1, ic), 1, &
2319 2005350 : int_hh(ispin)%r_coef(nngau1 + 1, iso2), 1)
2320 : CALL daxpy(size1, 1.0_dp, matso_s(iso1, ic), 1, &
2321 2828408 : int_ss(ispin)%r_coef(nngau1 + 1, iso2), 1)
2322 : END DO
2323 :
2324 : END DO ! ipfg2
2325 : END DO ! ipfg1
2326 526332 : m2 = m2 + maxso
2327 : END DO ! iset2
2328 66067 : m1 = m1 + maxso
2329 : END DO ! iset1
2330 : END DO ! ispin
2331 :
2332 16648 : DEALLOCATE (g1, g2, gg, dgg, matso_h, matso_s, gVXCg_h, gVXCg_s, gVXGg_h, gVXGg_s)
2333 16648 : DEALLOCATE (cg_list, cg_n_list, dcg_list, dcg_n_list)
2334 :
2335 16648 : CALL timestop(handle)
2336 :
2337 16648 : END SUBROUTINE gaVxcgb_GC
2338 :
2339 : ! **************************************************************************************************
2340 : !> \brief Integrates 0.5 * grad_ga .dot. (V_tau * grad_gb) on the atomic grid for meta-GGA
2341 : !> \param vtau_h the har tau potential
2342 : !> \param vtau_s the soft tau potential
2343 : !> \param int_hh ...
2344 : !> \param int_ss ...
2345 : !> \param grid_atom ...
2346 : !> \param basis_1c ...
2347 : !> \param harmonics ...
2348 : !> \param nspins ...
2349 : !> \note This is a rewrite to correct meta-GGA GAPW bug. This is more brute force than the original
2350 : !> but makes sure that no corner is cut in terms of accuracy (A. Bussy)
2351 : ! **************************************************************************************************
2352 308 : SUBROUTINE dgaVtaudgb(vtau_h, vtau_s, int_hh, int_ss, &
2353 : grid_atom, basis_1c, harmonics, nspins)
2354 :
2355 : REAL(dp), DIMENSION(:, :, :), POINTER :: vtau_h, vtau_s
2356 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: int_hh, int_ss
2357 : TYPE(grid_atom_type), POINTER :: grid_atom
2358 : TYPE(gto_basis_set_type), POINTER :: basis_1c
2359 : TYPE(harmonics_atom_type), POINTER :: harmonics
2360 : INTEGER, INTENT(IN) :: nspins
2361 :
2362 : CHARACTER(len=*), PARAMETER :: routineN = 'dgaVtaudgb'
2363 :
2364 : INTEGER :: dir, handle, ipgf, iset, iso, ispin, &
2365 : jpgf, jset, jso, l, maxso, na, nr, &
2366 : nset, starti, startj
2367 308 : INTEGER, DIMENSION(:), POINTER :: lmax, lmin, npgf
2368 308 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: fga, fgr, r1, r2, work
2369 308 : REAL(dp), ALLOCATABLE, DIMENSION(:, :, :) :: a1, a2, intso_h, intso_s
2370 308 : REAL(dp), DIMENSION(:, :), POINTER :: slm, zet
2371 308 : REAL(dp), DIMENSION(:, :, :), POINTER :: dslm_dxyz
2372 :
2373 308 : CALL timeset(routineN, handle)
2374 :
2375 308 : NULLIFY (zet, slm, dslm_dxyz, lmax, lmin, npgf)
2376 :
2377 : CALL get_gto_basis_set(gto_basis_set=basis_1c, lmax=lmax, lmin=lmin, &
2378 308 : maxso=maxso, npgf=npgf, nset=nset, zet=zet)
2379 :
2380 308 : na = grid_atom%ng_sphere
2381 308 : nr = grid_atom%nr
2382 :
2383 308 : slm => harmonics%slm
2384 308 : dslm_dxyz => harmonics%dslm_dxyz
2385 :
2386 : ! Separate the functions into purely r and purely angular parts and precompute them all
2387 : ! Not memory intensive since 1D arrays
2388 2156 : ALLOCATE (a1(na, nset*maxso, 3), a2(na, nset*maxso, 3))
2389 1848 : ALLOCATE (r1(nr, nset*maxso), r2(nr, nset*maxso))
2390 3859916 : a1 = 0.0_dp; a2 = 0.0_dp
2391 1300788 : r1 = 0.0_dp; r2 = 0.0_dp
2392 :
2393 1008 : DO iset = 1, nset
2394 3200 : DO ipgf = 1, npgf(iset)
2395 2192 : starti = (iset - 1)*maxso + (ipgf - 1)*nsoset(lmax(iset))
2396 8211 : DO iso = nsoset(lmin(iset) - 1) + 1, nsoset(lmax(iset))
2397 5319 : l = indso(1, iso)
2398 :
2399 : ! The x derivative of the spherical orbital, divided in angular and radial parts
2400 : ! Two of each are needed because d/dx(r^l Y_lm) * exp(-al*r^2) + r^l Y_lm * d/dx(exp-al*r^2)
2401 :
2402 : ! the purely radial part of d/dx(r^l Y_lm) * exp(-al*r^2) (same for y,z)
2403 289469 : r1(1:nr, starti + iso) = grid_atom%rad(1:nr)**(l - 1)*EXP(-zet(ipgf, iset)*grid_atom%rad2(1:nr))
2404 :
2405 : ! the purely radial part of r^l Y_lm * d/dx(exp-al*r^2) (same for y,z)
2406 : r2(1:nr, starti + iso) = -2.0_dp*zet(ipgf, iset)*grid_atom%rad(1:nr)**(l + 1) &
2407 289469 : *EXP(-zet(ipgf, iset)*grid_atom%rad2(1:nr))
2408 :
2409 23468 : DO dir = 1, 3
2410 : ! the purely angular part of d/dx(r^l Y_lm) * exp(-al*r^2)
2411 853119 : a1(1:na, starti + iso, dir) = dslm_dxyz(dir, 1:na, iso)
2412 :
2413 : ! the purely angular part of r^l Y_lm * d/dx(exp-al*r^2)
2414 858438 : a2(1:na, starti + iso, dir) = harmonics%a(dir, 1:na)*slm(1:na, iso)
2415 : END DO
2416 :
2417 : END DO !iso
2418 : END DO !ipgf
2419 : END DO !iset
2420 :
2421 : !Do the integration in terms of matrix-matrix multiplications
2422 1540 : ALLOCATE (intso_h(nset*maxso, nset*maxso, nspins))
2423 1232 : ALLOCATE (intso_s(nset*maxso, nset*maxso, nspins))
2424 5111456 : intso_h = 0.0_dp; intso_s = 0.0_dp
2425 :
2426 924 : ALLOCATE (fga(na, 1))
2427 924 : ALLOCATE (fgr(nr, 1))
2428 616 : ALLOCATE (work(na, 1))
2429 50604 : fga = 0.0_dp; fgr = 0.0_dp; work = 0.0_dp
2430 :
2431 1008 : DO iset = 1, nset
2432 2984 : DO jset = 1, nset
2433 9254 : DO ipgf = 1, npgf(iset)
2434 6578 : starti = (iset - 1)*maxso + (ipgf - 1)*nsoset(lmax(iset))
2435 33710 : DO jpgf = 1, npgf(jset)
2436 25156 : startj = (jset - 1)*maxso + (jpgf - 1)*nsoset(lmax(jset))
2437 :
2438 99450 : DO iso = nsoset(lmin(iset) - 1) + 1, nsoset(lmax(iset))
2439 296525 : DO jso = nsoset(lmin(jset) - 1) + 1, nsoset(lmax(jset))
2440 :
2441 : !Two component per function => 4 terms in total
2442 :
2443 : ! take 0.5*r1*a1(dir) * V * r1*a1(dir)
2444 10704803 : fgr(1:nr, 1) = r1(1:nr, starti + iso)*r1(1:nr, startj + jso)
2445 814612 : DO dir = 1, 3
2446 31846869 : fga(1:na, 1) = a1(1:na, starti + iso, dir)*a1(1:na, startj + jso, dir)
2447 :
2448 1425571 : DO ispin = 1, nspins
2449 : CALL dgemm('N', 'N', na, 1, nr, 0.5_dp, vtau_h(:, :, ispin), na, fgr, &
2450 610959 : nr, 0.0_dp, work, na)
2451 : CALL dgemm('T', 'N', 1, 1, na, 1.0_dp, work, na, fga, na, 1.0_dp, &
2452 610959 : intso_h(starti + iso:, startj + jso, ispin), 1)
2453 :
2454 : CALL dgemm('N', 'N', na, 1, nr, 0.5_dp, vtau_s(:, :, ispin), na, fgr, &
2455 610959 : nr, 0.0_dp, work, na)
2456 : CALL dgemm('T', 'N', 1, 1, na, 1.0_dp, work, na, fga, na, 1.0_dp, &
2457 1221918 : intso_s(starti + iso:, startj + jso, ispin), 1)
2458 : END DO
2459 : END DO !dir
2460 :
2461 : ! add 0.5*r1*a1(dir) * V * r2*a2(dir)
2462 10704803 : fgr(1:nr, 1) = r1(1:nr, starti + iso)*r2(1:nr, startj + jso)
2463 814612 : DO dir = 1, 3
2464 31846869 : fga(1:na, 1) = a1(1:na, starti + iso, dir)*a2(1:na, startj + jso, dir)
2465 :
2466 1425571 : DO ispin = 1, nspins
2467 : CALL dgemm('N', 'N', na, 1, nr, 0.5_dp, vtau_h(:, :, ispin), na, fgr, &
2468 610959 : nr, 0.0_dp, work, na)
2469 : CALL dgemm('T', 'N', 1, 1, na, 1.0_dp, work, na, fga, na, 1.0_dp, &
2470 610959 : intso_h(starti + iso:, startj + jso, ispin), 1)
2471 :
2472 : CALL dgemm('N', 'N', na, 1, nr, 0.5_dp, vtau_s(:, :, ispin), na, fgr, &
2473 610959 : nr, 0.0_dp, work, na)
2474 : CALL dgemm('T', 'N', 1, 1, na, 1.0_dp, work, na, fga, na, 1.0_dp, &
2475 1221918 : intso_s(starti + iso:, startj + jso, ispin), 1)
2476 : END DO
2477 : END DO !dir
2478 :
2479 : ! add 0.5*r2*a2(dir) * V * r1*a1(dir)
2480 10704803 : fgr(1:nr, 1) = r2(1:nr, starti + iso)*r1(1:nr, startj + jso)
2481 814612 : DO dir = 1, 3
2482 31846869 : fga(1:na, 1) = a2(1:na, starti + iso, dir)*a1(1:na, startj + jso, dir)
2483 :
2484 1425571 : DO ispin = 1, nspins
2485 : CALL dgemm('N', 'N', na, 1, nr, 0.5_dp, vtau_h(:, :, ispin), na, fgr, &
2486 610959 : nr, 0.0_dp, work, na)
2487 : CALL dgemm('T', 'N', 1, 1, na, 1.0_dp, work, na, fga, na, 1.0_dp, &
2488 610959 : intso_h(starti + iso:, startj + jso, ispin), 1)
2489 :
2490 : CALL dgemm('N', 'N', na, 1, nr, 0.5_dp, vtau_s(:, :, ispin), na, fgr, &
2491 610959 : nr, 0.0_dp, work, na)
2492 : CALL dgemm('T', 'N', 1, 1, na, 1.0_dp, work, na, fga, na, 1.0_dp, &
2493 1221918 : intso_s(starti + iso:, startj + jso, ispin), 1)
2494 : END DO
2495 : END DO !dir
2496 :
2497 : ! add the last term: 0.5*r2*a2(dir) * V * r2*a2(dir)
2498 10704803 : fgr(1:nr, 1) = r2(1:nr, starti + iso)*r2(1:nr, startj + jso)
2499 882328 : DO dir = 1, 3
2500 31846869 : fga(1:na, 1) = a2(1:na, starti + iso, dir)*a2(1:na, startj + jso, dir)
2501 :
2502 1425571 : DO ispin = 1, nspins
2503 : CALL dgemm('N', 'N', na, 1, nr, 0.5_dp, vtau_h(:, :, ispin), na, fgr, &
2504 610959 : nr, 0.0_dp, work, na)
2505 : CALL dgemm('T', 'N', 1, 1, na, 1.0_dp, work, na, fga, na, 1.0_dp, &
2506 610959 : intso_h(starti + iso:, startj + jso, ispin), 1)
2507 :
2508 : CALL dgemm('N', 'N', na, 1, nr, 0.5_dp, vtau_s(:, :, ispin), na, fgr, &
2509 610959 : nr, 0.0_dp, work, na)
2510 : CALL dgemm('T', 'N', 1, 1, na, 1.0_dp, work, na, fga, na, 1.0_dp, &
2511 1221918 : intso_s(starti + iso:, startj + jso, ispin), 1)
2512 : END DO
2513 : END DO !dir
2514 :
2515 : END DO !jso
2516 : END DO !iso
2517 :
2518 : END DO !jpgf
2519 : END DO !ipgf
2520 : END DO !jset
2521 : END DO !iset
2522 :
2523 : ! Put the integrals in the rho_atom data structure
2524 616 : DO ispin = 1, nspins
2525 2555574 : int_hh(ispin)%r_coef(:, :) = int_hh(ispin)%r_coef(:, :) + intso_h(:, :, ispin)
2526 2555882 : int_ss(ispin)%r_coef(:, :) = int_ss(ispin)%r_coef(:, :) + intso_s(:, :, ispin)
2527 : END DO
2528 :
2529 308 : CALL timestop(handle)
2530 :
2531 616 : END SUBROUTINE dgaVtaudgb
2532 :
2533 : END MODULE qs_vxc_atom
|