Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Calculate the saop potential
10 : ! **************************************************************************************************
11 : MODULE xc_pot_saop
12 : USE atomic_kind_types, ONLY: atomic_kind_type,&
13 : get_atomic_kind
14 : USE basis_set_types, ONLY: gto_basis_set_type
15 : USE cp_array_utils, ONLY: cp_1d_r_p_type
16 : USE cp_control_types, ONLY: dft_control_type
17 : USE cp_dbcsr_api, ONLY: dbcsr_copy,&
18 : dbcsr_deallocate_matrix,&
19 : dbcsr_p_type,&
20 : dbcsr_set
21 : USE cp_dbcsr_operations, ONLY: cp_dbcsr_plus_fm_fm_t,&
22 : dbcsr_allocate_matrix_set,&
23 : dbcsr_deallocate_matrix_set
24 : USE cp_fm_types, ONLY: cp_fm_create,&
25 : cp_fm_get_info,&
26 : cp_fm_get_submatrix,&
27 : cp_fm_p_type,&
28 : cp_fm_release,&
29 : cp_fm_set_all,&
30 : cp_fm_set_submatrix,&
31 : cp_fm_type
32 : USE input_constants, ONLY: do_method_gapw,&
33 : oe_gllb,&
34 : oe_lb,&
35 : oe_saop,&
36 : xc_funct_no_shortcut
37 : USE input_section_types, ONLY: &
38 : section_vals_create, section_vals_duplicate, section_vals_get_subs_vals, &
39 : section_vals_release, section_vals_retain, section_vals_set_subs_vals, section_vals_type, &
40 : section_vals_val_get, section_vals_val_set
41 : USE kinds, ONLY: dp
42 : USE mathconstants, ONLY: pi
43 : USE message_passing, ONLY: mp_para_env_type
44 : USE pw_env_types, ONLY: pw_env_get,&
45 : pw_env_type
46 : USE pw_methods, ONLY: pw_axpy,&
47 : pw_copy,&
48 : pw_scale,&
49 : pw_zero
50 : USE pw_pool_types, ONLY: pw_pool_type
51 : USE pw_types, ONLY: pw_c1d_gs_type,&
52 : pw_r3d_rs_type
53 : USE qs_collocate_density, ONLY: calculate_rho_elec
54 : USE qs_environment_types, ONLY: get_qs_env,&
55 : qs_environment_type
56 : USE qs_gapw_densities, ONLY: prepare_gapw_den
57 : USE qs_grid_atom, ONLY: grid_atom_type
58 : USE qs_harmonics_atom, ONLY: harmonics_atom_type
59 : USE qs_integrate_potential, ONLY: integrate_v_rspace
60 : USE qs_kind_types, ONLY: get_qs_kind,&
61 : qs_kind_type
62 : USE qs_ks_atom, ONLY: update_ks_atom
63 : USE qs_ks_types, ONLY: qs_ks_env_type
64 : USE qs_local_rho_types, ONLY: local_rho_set_create,&
65 : local_rho_set_release,&
66 : local_rho_type
67 : USE qs_mo_types, ONLY: get_mo_set,&
68 : mo_set_type
69 : USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
70 : USE qs_oce_types, ONLY: oce_matrix_type
71 : USE qs_rho_atom_methods, ONLY: allocate_rho_atom_internals,&
72 : calculate_rho_atom_coeff
73 : USE qs_rho_atom_types, ONLY: get_rho_atom,&
74 : rho_atom_coeff,&
75 : rho_atom_type
76 : USE qs_rho_types, ONLY: qs_rho_get,&
77 : qs_rho_type
78 : USE qs_vxc_atom, ONLY: calc_rho_angular,&
79 : gaVxcgb_noGC
80 : USE util, ONLY: get_limit
81 : USE virial_types, ONLY: virial_type
82 : USE xc, ONLY: xc_vxc_pw_create1
83 : USE xc_atom, ONLY: fill_rho_set,&
84 : vxc_of_r_new,&
85 : xc_rho_set_atom_update
86 : USE xc_derivative_set_types, ONLY: xc_derivative_set_type,&
87 : xc_dset_create,&
88 : xc_dset_get_derivative,&
89 : xc_dset_release,&
90 : xc_dset_zero_all
91 : USE xc_derivative_types, ONLY: xc_derivative_get,&
92 : xc_derivative_type
93 : USE xc_derivatives, ONLY: xc_functionals_eval
94 : USE xc_rho_cflags_types, ONLY: xc_rho_cflags_setall,&
95 : xc_rho_cflags_type
96 : USE xc_rho_set_types, ONLY: xc_rho_set_create,&
97 : xc_rho_set_release,&
98 : xc_rho_set_type,&
99 : xc_rho_set_update
100 : USE xc_xbecke88, ONLY: xb88_lda_info,&
101 : xb88_lsd_info
102 : #include "./base/base_uses.f90"
103 :
104 : IMPLICIT NONE
105 :
106 : PRIVATE
107 :
108 : PUBLIC :: add_saop_pot
109 :
110 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xc_pot_saop'
111 :
112 : ! should be eliminated
113 : REAL(KIND=dp), PARAMETER :: alpha = 1.19_dp, beta = 0.01_dp, K_rho = 0.42_dp
114 : REAL(KIND=dp), PARAMETER :: kappa = 0.804_dp, mu = 0.21951_dp, &
115 : beta_ec = 0.066725_dp, gamma_saop = 0.031091_dp
116 :
117 : CONTAINS
118 :
119 : ! **************************************************************************************************
120 : !> \brief ...
121 : !> \param ks_matrix ...
122 : !> \param qs_env ...
123 : !> \param oe_corr ...
124 : ! **************************************************************************************************
125 16 : SUBROUTINE add_saop_pot(ks_matrix, qs_env, oe_corr)
126 :
127 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_matrix
128 : TYPE(qs_environment_type), POINTER :: qs_env
129 : INTEGER, INTENT(IN) :: oe_corr
130 :
131 : INTEGER :: dft_method_id, homo, i, ispin, j, k, &
132 : nspins, orb, xc_deriv_method_id, &
133 : xc_rho_smooth_id
134 : INTEGER, DIMENSION(2) :: ncol, nrow
135 : INTEGER, DIMENSION(2, 3) :: bo
136 : LOGICAL :: compute_virial, gapw, lsd
137 : REAL(KIND=dp) :: density_cut, efac, gradient_cut, &
138 : tau_cut, we_GLLB, we_LB, xc_energy
139 16 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: coeff_col
140 : REAL(KIND=dp), DIMENSION(3, 3) :: virial_xc_tmp
141 16 : REAL(KIND=dp), DIMENSION(:), POINTER :: mo_eigenvalues
142 16 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: e_uniform
143 16 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: single_mo_coeff
144 : TYPE(cp_fm_type), POINTER :: mo_coeff
145 32 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: orbital_density_matrix, rho_struct_ao
146 16 : TYPE(mo_set_type), DIMENSION(:), POINTER :: molecular_orbitals
147 : TYPE(pw_c1d_gs_type) :: orbital_g
148 16 : TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
149 : TYPE(pw_env_type), POINTER :: pw_env
150 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
151 : TYPE(pw_r3d_rs_type) :: orbital
152 16 : TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:) :: vxc_GLLB, vxc_SAOP
153 32 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r, rho_struct_r, tau, vxc_LB, &
154 16 : vxc_tau, vxc_tmp
155 : TYPE(qs_ks_env_type), POINTER :: ks_env
156 : TYPE(qs_rho_type), POINTER :: rho_struct
157 : TYPE(section_vals_type), POINTER :: input, xc_fun_section_orig, &
158 : xc_fun_section_tmp, xc_section_orig, &
159 : xc_section_tmp
160 : TYPE(virial_type), POINTER :: virial
161 : TYPE(xc_derivative_set_type) :: deriv_set
162 : TYPE(xc_derivative_type), POINTER :: deriv
163 : TYPE(xc_rho_cflags_type) :: needs
164 : TYPE(xc_rho_set_type) :: rho_set
165 :
166 16 : NULLIFY (ks_env, pw_env, auxbas_pw_pool, input)
167 16 : NULLIFY (rho_g, rho_r, tau, rho_struct, e_uniform)
168 16 : NULLIFY (vxc_LB, vxc_tmp, vxc_tau)
169 16 : NULLIFY (mo_eigenvalues, deriv, rho_struct_r, rho_struct_ao)
170 16 : NULLIFY (orbital_density_matrix, xc_section_tmp, xc_fun_section_tmp)
171 :
172 : CALL get_qs_env(qs_env, &
173 : ks_env=ks_env, &
174 : rho=rho_struct, &
175 : pw_env=pw_env, &
176 : input=input, &
177 : virial=virial, &
178 16 : mos=molecular_orbitals)
179 16 : compute_virial = virial%pv_calculate .AND. (.NOT. virial%pv_numer)
180 16 : CALL section_vals_val_get(input, "DFT%QS%METHOD", i_val=dft_method_id)
181 16 : gapw = (dft_method_id == do_method_gapw)
182 :
183 16 : xc_section_orig => section_vals_get_subs_vals(input, "DFT%XC")
184 16 : CALL section_vals_retain(xc_section_orig)
185 16 : CALL section_vals_duplicate(xc_section_orig, xc_section_tmp)
186 :
187 : CALL section_vals_val_get(xc_section_orig, "DENSITY_CUTOFF", &
188 16 : r_val=density_cut)
189 : CALL section_vals_val_get(xc_section_orig, "GRADIENT_CUTOFF", &
190 16 : r_val=gradient_cut)
191 : CALL section_vals_val_get(xc_section_orig, "TAU_CUTOFF", &
192 16 : r_val=tau_cut)
193 :
194 16 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
195 :
196 16 : CALL section_vals_val_get(input, "DFT%LSD", l_val=lsd)
197 16 : IF (lsd) THEN
198 6 : nspins = 2
199 : ELSE
200 10 : nspins = 1
201 : END IF
202 :
203 70 : ALLOCATE (single_mo_coeff(nspins))
204 16 : CALL dbcsr_allocate_matrix_set(orbital_density_matrix, nspins)
205 16 : CALL qs_rho_get(rho_struct, rho_r=rho_struct_r, rho_ao=rho_struct_ao)
206 16 : rho_r => rho_struct_r
207 38 : DO ispin = 1, nspins
208 22 : ALLOCATE (orbital_density_matrix(ispin)%matrix)
209 : CALL dbcsr_copy(orbital_density_matrix(ispin)%matrix, &
210 38 : rho_struct_ao(ispin)%matrix, "orbital density")
211 : END DO
212 160 : bo = rho_r(1)%pw_grid%bounds_local
213 :
214 : !---------------------------!
215 : ! create the density needed !
216 : !---------------------------!
217 : CALL xc_rho_set_create(rho_set, bo, &
218 : density_cut, &
219 : gradient_cut, &
220 16 : tau_cut)
221 16 : CALL xc_rho_cflags_setall(needs, .FALSE.)
222 16 : IF (lsd) THEN
223 6 : CALL xb88_lsd_info(needs=needs)
224 6 : needs%norm_drho = .TRUE.
225 : ELSE
226 10 : CALL xb88_lda_info(needs=needs)
227 : END IF
228 : CALL section_vals_val_get(xc_section_orig, "XC_GRID%XC_DERIV", &
229 16 : i_val=xc_deriv_method_id)
230 : CALL section_vals_val_get(xc_section_orig, "XC_GRID%XC_SMOOTH_RHO", &
231 16 : i_val=xc_rho_smooth_id)
232 : CALL xc_rho_set_update(rho_set, rho_r, rho_g, tau, needs, &
233 : xc_deriv_method_id, &
234 : xc_rho_smooth_id, &
235 16 : auxbas_pw_pool)
236 :
237 : !----------------------------------------!
238 : ! Construct the LB94 potential in vxc_LB !
239 : !----------------------------------------!
240 : xc_fun_section_orig => section_vals_get_subs_vals(xc_section_orig, &
241 16 : "XC_FUNCTIONAL")
242 16 : CALL section_vals_create(xc_fun_section_tmp, xc_fun_section_orig%section)
243 : CALL section_vals_val_set(xc_fun_section_tmp, "_SECTION_PARAMETERS_", &
244 16 : i_val=xc_funct_no_shortcut)
245 : CALL section_vals_val_set(xc_fun_section_tmp, "XALPHA%_SECTION_PARAMETERS_", &
246 16 : l_val=.TRUE.)
247 : CALL section_vals_set_subs_vals(xc_section_tmp, "XC_FUNCTIONAL", &
248 16 : xc_fun_section_tmp)
249 :
250 16 : CPASSERT(.NOT. compute_virial)
251 : ! CALL xc_vxc_pw_create(vxc_tmp, vxc_tau, xc_energy, rho_r, rho_g, tau, &
252 : ! xc_section_tmp, auxbas_pw_pool, &
253 : ! compute_virial=.FALSE., virial_xc=virial_xc_tmp)
254 : CALL xc_vxc_pw_create1(vxc_tmp, vxc_tau, rho_r, rho_g, tau, xc_energy, &
255 : xc_section_tmp, auxbas_pw_pool, &
256 16 : compute_virial=.FALSE., virial_xc=virial_xc_tmp)
257 :
258 : CALL section_vals_val_set(xc_fun_section_tmp, "XALPHA%_SECTION_PARAMETERS_", &
259 16 : l_val=.FALSE.)
260 : CALL section_vals_val_set(xc_fun_section_tmp, "PZ81%_SECTION_PARAMETERS_", &
261 16 : l_val=.TRUE.)
262 :
263 16 : CPASSERT(.NOT. compute_virial)
264 : ! CALL xc_vxc_pw_create(vxc_LB, vxc_tau, xc_energy, rho_r, rho_g, tau, &
265 : ! xc_section_tmp, auxbas_pw_pool, &
266 : ! compute_virial=.FALSE., virial_xc=virial_xc_tmp)
267 : CALL xc_vxc_pw_create1(vxc_LB, vxc_tau, rho_r, rho_g, tau, xc_energy, &
268 : xc_section_tmp, auxbas_pw_pool, &
269 16 : compute_virial=.FALSE., virial_xc=virial_xc_tmp)
270 :
271 38 : DO ispin = 1, nspins
272 38 : CALL pw_axpy(vxc_tmp(ispin), vxc_LB(ispin), alpha)
273 : END DO
274 :
275 38 : DO ispin = 1, nspins
276 22 : CALL add_lb_pot(vxc_tmp(ispin)%array, rho_set, lsd, ispin)
277 38 : CALL pw_axpy(vxc_tmp(ispin), vxc_LB(ispin), -1.0_dp)
278 : END DO
279 :
280 : !-----------------------------------------------------------------------------------!
281 : ! Construct 2 times PBE one particle density from the PZ correlation energy density !
282 : !-----------------------------------------------------------------------------------!
283 16 : CALL xc_dset_create(deriv_set, local_bounds=bo)
284 : CALL xc_functionals_eval(xc_fun_section_tmp, &
285 : lsd=lsd, &
286 : rho_set=rho_set, &
287 : deriv_set=deriv_set, &
288 16 : deriv_order=0)
289 :
290 16 : deriv => xc_dset_get_derivative(deriv_set, [INTEGER::])
291 16 : CALL xc_derivative_get(deriv, deriv_data=e_uniform)
292 :
293 70 : ALLOCATE (vxc_GLLB(nspins))
294 38 : DO ispin = 1, nspins
295 38 : CALL auxbas_pw_pool%create_pw(vxc_GLLB(ispin))
296 : END DO
297 :
298 38 : DO ispin = 1, nspins
299 38 : CALL calc_2excpbe(vxc_GLLB(ispin)%array, rho_set, e_uniform, lsd)
300 : END DO
301 :
302 16 : CALL xc_dset_release(deriv_set)
303 :
304 16 : CALL auxbas_pw_pool%create_pw(orbital)
305 16 : CALL auxbas_pw_pool%create_pw(orbital_g)
306 :
307 38 : DO ispin = 1, nspins
308 :
309 : CALL get_mo_set(molecular_orbitals(ispin), &
310 : mo_coeff=mo_coeff, &
311 : eigenvalues=mo_eigenvalues, &
312 22 : homo=homo)
313 : CALL cp_fm_create(single_mo_coeff(ispin), &
314 : mo_coeff%matrix_struct, &
315 22 : "orbital density matrix")
316 :
317 : CALL cp_fm_get_info(single_mo_coeff(ispin), &
318 22 : nrow_global=nrow(ispin), ncol_global=ncol(ispin))
319 66 : ALLOCATE (coeff_col(nrow(ispin), 1))
320 :
321 22 : CALL pw_zero(vxc_tmp(ispin))
322 :
323 106 : DO orb = 1, homo - 1
324 :
325 84 : efac = K_rho*SQRT(mo_eigenvalues(homo) - mo_eigenvalues(orb))
326 84 : IF (.NOT. lsd) efac = 2.0_dp*efac
327 :
328 84 : CALL cp_fm_set_all(single_mo_coeff(ispin), 0.0_dp)
329 : CALL cp_fm_get_submatrix(mo_coeff, coeff_col, &
330 84 : 1, orb, nrow(ispin), 1)
331 : CALL cp_fm_set_submatrix(single_mo_coeff(ispin), coeff_col, &
332 84 : 1, orb)
333 84 : CALL dbcsr_set(orbital_density_matrix(ispin)%matrix, 0.0_dp)
334 : CALL cp_dbcsr_plus_fm_fm_t(orbital_density_matrix(ispin)%matrix, &
335 : matrix_v=single_mo_coeff(ispin), &
336 : ncol=ncol(ispin), &
337 84 : alpha=1.0_dp)
338 84 : CALL pw_zero(orbital)
339 84 : CALL pw_zero(orbital_g)
340 : CALL calculate_rho_elec(matrix_p=orbital_density_matrix(ispin)%matrix, &
341 : rho=orbital, rho_gspace=orbital_g, &
342 84 : ks_env=ks_env)
343 :
344 106 : CALL pw_axpy(orbital, vxc_tmp(ispin), efac)
345 :
346 : END DO
347 22 : DEALLOCATE (coeff_col)
348 :
349 776 : DO k = bo(1, 3), bo(2, 3)
350 27510 : DO j = bo(1, 2), bo(2, 2)
351 514675 : DO i = bo(1, 1), bo(2, 1)
352 513921 : IF (rho_r(ispin)%array(i, j, k) > density_cut) THEN
353 : vxc_tmp(ispin)%array(i, j, k) = vxc_tmp(ispin)%array(i, j, k)/ &
354 487187 : rho_r(ispin)%array(i, j, k)
355 : ELSE
356 0 : vxc_tmp(ispin)%array(i, j, k) = 0.0_dp
357 : END IF
358 : END DO
359 : END DO
360 : END DO
361 :
362 60 : CALL pw_axpy(vxc_tmp(ispin), vxc_GLLB(ispin), 1.0_dp)
363 :
364 : END DO
365 :
366 : !---------------!
367 : ! Assemble SAOP !
368 : !---------------!
369 54 : ALLOCATE (vxc_SAOP(nspins))
370 :
371 38 : DO ispin = 1, nspins
372 :
373 : CALL get_mo_set(molecular_orbitals(ispin), &
374 : mo_coeff=mo_coeff, &
375 : eigenvalues=mo_eigenvalues, &
376 22 : homo=homo)
377 22 : CALL auxbas_pw_pool%create_pw(vxc_SAOP(ispin))
378 22 : CALL pw_zero(vxc_SAOP(ispin))
379 :
380 66 : ALLOCATE (coeff_col(nrow(ispin), 1))
381 :
382 128 : DO orb = 1, homo
383 :
384 106 : we_LB = EXP(-2.0_dp*(mo_eigenvalues(homo) - mo_eigenvalues(orb))**2)
385 106 : we_GLLB = 1.0_dp - we_LB
386 106 : IF (.NOT. lsd) THEN
387 40 : we_LB = 2.0_dp*we_LB
388 40 : we_GLLB = 2.0_dp*we_GLLB
389 : END IF
390 :
391 : vxc_tmp(ispin)%array = we_LB*vxc_LB(ispin)%array + &
392 5220786 : we_GLLB*vxc_GLLB(ispin)%array
393 :
394 106 : CALL cp_fm_set_all(single_mo_coeff(ispin), 0.0_dp)
395 : CALL cp_fm_get_submatrix(mo_coeff, coeff_col, &
396 106 : 1, orb, nrow(ispin), 1)
397 : CALL cp_fm_set_submatrix(single_mo_coeff(ispin), coeff_col, &
398 106 : 1, orb)
399 106 : CALL dbcsr_set(orbital_density_matrix(ispin)%matrix, 0.0_dp)
400 : CALL cp_dbcsr_plus_fm_fm_t(orbital_density_matrix(ispin)%matrix, &
401 : matrix_v=single_mo_coeff(ispin), &
402 : ncol=ncol(ispin), &
403 106 : alpha=1.0_dp)
404 106 : CALL pw_zero(orbital)
405 106 : CALL pw_zero(orbital_g)
406 : CALL calculate_rho_elec(matrix_p=orbital_density_matrix(ispin)%matrix, &
407 : rho=orbital, rho_gspace=orbital_g, &
408 106 : ks_env=ks_env)
409 :
410 : vxc_SAOP(ispin)%array = vxc_SAOP(ispin)%array + &
411 2610468 : orbital%array*vxc_tmp(ispin)%array
412 :
413 : END DO
414 :
415 22 : CALL dbcsr_deallocate_matrix(orbital_density_matrix(ispin)%matrix)
416 :
417 22 : DEALLOCATE (coeff_col)
418 :
419 814 : DO k = bo(1, 3), bo(2, 3)
420 27510 : DO j = bo(1, 2), bo(2, 2)
421 514675 : DO i = bo(1, 1), bo(2, 1)
422 513921 : IF (rho_r(ispin)%array(i, j, k) > density_cut) THEN
423 : vxc_SAOP(ispin)%array(i, j, k) = vxc_SAOP(ispin)%array(i, j, k)/ &
424 487187 : rho_r(ispin)%array(i, j, k)
425 : ELSE
426 0 : vxc_SAOP(ispin)%array(i, j, k) = 0.0_dp
427 : END IF
428 : END DO
429 : END DO
430 : END DO
431 :
432 : END DO
433 :
434 16 : CALL cp_fm_release(single_mo_coeff)
435 :
436 16 : CALL xc_rho_set_release(rho_set, auxbas_pw_pool)
437 16 : CALL auxbas_pw_pool%give_back_pw(orbital)
438 16 : CALL auxbas_pw_pool%give_back_pw(orbital_g)
439 :
440 : !--------------------!
441 : ! Do the integration !
442 : !--------------------!
443 38 : DO ispin = 1, nspins
444 :
445 22 : IF (oe_corr == oe_lb) THEN
446 0 : CALL pw_copy(vxc_LB(ispin), vxc_SAOP(ispin))
447 22 : ELSE IF (oe_corr == oe_gllb) THEN
448 0 : CALL pw_copy(vxc_GLLB(ispin), vxc_SAOP(ispin))
449 : END IF
450 22 : CALL pw_scale(vxc_SAOP(ispin), vxc_SAOP(ispin)%pw_grid%dvol)
451 :
452 : CALL integrate_v_rspace(v_rspace=vxc_SAOP(ispin), pmat=rho_struct_ao(ispin), &
453 : hmat=ks_matrix(ispin), qs_env=qs_env, &
454 : calculate_forces=.FALSE., &
455 38 : gapw=gapw)
456 :
457 : END DO
458 :
459 38 : DO ispin = 1, nspins
460 22 : CALL auxbas_pw_pool%give_back_pw(vxc_SAOP(ispin))
461 22 : CALL auxbas_pw_pool%give_back_pw(vxc_GLLB(ispin))
462 22 : CALL vxc_LB(ispin)%release()
463 38 : CALL vxc_tmp(ispin)%release()
464 : END DO
465 16 : DEALLOCATE (vxc_GLLB, vxc_LB, vxc_tmp, orbital_density_matrix)
466 :
467 16 : DEALLOCATE (vxc_SAOP)
468 :
469 16 : CALL section_vals_release(xc_fun_section_tmp)
470 16 : CALL section_vals_release(xc_section_tmp)
471 16 : CALL section_vals_release(xc_section_orig)
472 :
473 : !-----------------------!
474 : ! Call the GAPW routine !
475 : !-----------------------!
476 16 : IF (gapw) THEN
477 0 : CALL gapw_add_atomic_saop_pot(qs_env, oe_corr)
478 : END IF
479 :
480 400 : END SUBROUTINE add_saop_pot
481 :
482 : ! **************************************************************************************************
483 : !> \brief ...
484 : !> \param qs_env ...
485 : !> \param oe_corr ...
486 : ! **************************************************************************************************
487 0 : SUBROUTINE gapw_add_atomic_saop_pot(qs_env, oe_corr)
488 :
489 : TYPE(qs_environment_type), POINTER :: qs_env
490 : INTEGER, INTENT(IN) :: oe_corr
491 :
492 : INTEGER :: ia, iat, iatom, ikind, ir, ispin, na, &
493 : natom, nr, ns, nspins, orb
494 : INTEGER, DIMENSION(2) :: bo, homo, ncol, nrow
495 : INTEGER, DIMENSION(2, 3) :: bounds
496 0 : INTEGER, DIMENSION(:), POINTER :: atom_list
497 : LOGICAL :: lsd, paw_atom
498 0 : REAL(dp), DIMENSION(:, :, :), POINTER :: tau
499 : REAL(KIND=dp) :: density_cut, efac, exc, gradient_cut, &
500 : tau_cut, we_GLLB, we_LB
501 0 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: coeff_col
502 0 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: weight
503 0 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: dummy, e_uniform, rho_h, rho_s, vtau, &
504 0 : vxc_GLLB_h, vxc_GLLB_s, vxc_LB_h, vxc_LB_s, vxc_SAOP_h, vxc_SAOP_s, vxc_tmp_h, vxc_tmp_s
505 0 : REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER :: drho_h, drho_s, vxg
506 0 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
507 0 : TYPE(cp_1d_r_p_type), DIMENSION(:), POINTER :: mo_eigenvalues
508 0 : TYPE(cp_fm_p_type), ALLOCATABLE, DIMENSION(:) :: mo_coeff
509 0 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: single_mo_coeff
510 0 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, orbital_density_matrix, &
511 0 : rho_struct_ao
512 0 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: ksmat, psmat
513 : TYPE(dft_control_type), POINTER :: dft_control
514 : TYPE(grid_atom_type), POINTER :: atomic_grid, grid_atom
515 : TYPE(gto_basis_set_type), POINTER :: orb_basis
516 : TYPE(harmonics_atom_type), POINTER :: harmonics
517 : TYPE(local_rho_type), POINTER :: local_rho_set
518 0 : TYPE(mo_set_type), DIMENSION(:), POINTER :: molecular_orbitals
519 : TYPE(mp_para_env_type), POINTER :: para_env
520 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
521 0 : POINTER :: sab
522 : TYPE(oce_matrix_type), POINTER :: oce
523 0 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
524 : TYPE(qs_rho_type), POINTER :: rho_structure
525 0 : TYPE(rho_atom_coeff), DIMENSION(:), POINTER :: dr_h, dr_s, int_hh, int_ss, r_h, r_s
526 0 : TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER :: r_h_d, r_s_d
527 0 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho_atom_set
528 : TYPE(rho_atom_type), POINTER :: rho_atom
529 : TYPE(section_vals_type), POINTER :: input, xc_fun_section_orig, &
530 : xc_fun_section_tmp, xc_section_orig, &
531 : xc_section_tmp
532 : TYPE(xc_derivative_set_type) :: deriv_set
533 : TYPE(xc_derivative_type), POINTER :: deriv
534 : TYPE(xc_rho_cflags_type) :: needs, needs_orbs
535 : TYPE(xc_rho_set_type) :: orb_rho_set_h, orb_rho_set_s, rho_set_h, &
536 : rho_set_s
537 :
538 0 : NULLIFY (weight, rho_h, rho_s, vxc_LB_h, vxc_LB_s, vxc_GLLB_h, vxc_GLLB_s, &
539 0 : vxc_tmp_h, vxc_tmp_s, vtau, dummy, e_uniform, drho_h, drho_s, vxg, atom_list, &
540 0 : atomic_kind_set, qs_kind_set, deriv, atomic_grid, rho_struct_ao, &
541 0 : harmonics, molecular_orbitals, rho_structure, r_h, r_s, dr_h, dr_s, &
542 0 : r_h_d, r_s_d, rho_atom_set, rho_atom, para_env, &
543 0 : mo_eigenvalues, local_rho_set, matrix_ks, &
544 0 : orbital_density_matrix, vxc_SAOP_h, vxc_SAOP_s)
545 :
546 : ! tau is needed for fill_rho_set, but should never be used
547 0 : NULLIFY (tau)
548 0 : NULLIFY (dft_control, oce, sab)
549 :
550 : CALL get_qs_env(qs_env, input=input, &
551 : rho=rho_structure, &
552 : mos=molecular_orbitals, &
553 : atomic_kind_set=atomic_kind_set, &
554 : qs_kind_set=qs_kind_set, &
555 : rho_atom_set=rho_atom_set, &
556 : matrix_ks=matrix_ks, &
557 : dft_control=dft_control, &
558 : para_env=para_env, &
559 0 : oce=oce, sab_orb=sab)
560 :
561 0 : CALL qs_rho_get(rho_structure, rho_ao=rho_struct_ao)
562 :
563 0 : xc_section_orig => section_vals_get_subs_vals(input, "DFT%XC")
564 0 : CALL section_vals_retain(xc_section_orig)
565 0 : CALL section_vals_duplicate(xc_section_orig, xc_section_tmp)
566 :
567 : ! [SC] the following code can be traced back to SVN rev. 4296 (git:f97138b) that
568 : ! has removed the component 'nspins' from the derived type 'dft_control_type'.
569 : ! Is it worth to remove the code below in favour of 'dft_control%nspins'
570 : ! since its reintroduction? Note that in case of ROKS calculations,
571 : ! 'lsd == .FALSE.' but 'dft_control%nspins == 2'.
572 0 : CALL section_vals_val_get(input, "DFT%LSD", l_val=lsd)
573 0 : IF (lsd) THEN
574 0 : nspins = 2
575 : ELSE
576 0 : nspins = 1
577 : END IF
578 :
579 : CALL section_vals_val_get(xc_section_orig, "DENSITY_CUTOFF", &
580 0 : r_val=density_cut)
581 : CALL section_vals_val_get(xc_section_orig, "GRADIENT_CUTOFF", &
582 0 : r_val=gradient_cut)
583 : CALL section_vals_val_get(xc_section_orig, "TAU_CUTOFF", &
584 0 : r_val=tau_cut)
585 :
586 : ! remap pointer
587 0 : ns = SIZE(rho_struct_ao)
588 0 : psmat(1:ns, 1:1) => rho_struct_ao(1:ns)
589 0 : CALL calculate_rho_atom_coeff(qs_env, psmat, rho_atom_set, qs_kind_set, oce, sab, para_env)
590 0 : CALL prepare_gapw_den(qs_env)
591 :
592 0 : ALLOCATE (mo_coeff(nspins), single_mo_coeff(nspins), mo_eigenvalues(nspins))
593 :
594 0 : CALL dbcsr_allocate_matrix_set(orbital_density_matrix, nspins)
595 :
596 0 : DO ispin = 1, nspins
597 : CALL get_mo_set(molecular_orbitals(ispin), &
598 : mo_coeff=mo_coeff(ispin)%matrix, &
599 : eigenvalues=mo_eigenvalues(ispin)%array, &
600 0 : homo=homo(ispin))
601 : CALL cp_fm_create(single_mo_coeff(ispin), &
602 : mo_coeff(ispin)%matrix%matrix_struct, &
603 0 : "orbital density matrix")
604 : CALL cp_fm_get_info(single_mo_coeff(ispin), &
605 0 : nrow_global=nrow(ispin), ncol_global=ncol(ispin))
606 0 : ALLOCATE (orbital_density_matrix(ispin)%matrix)
607 : CALL dbcsr_copy(orbital_density_matrix(ispin)%matrix, &
608 : rho_struct_ao(ispin)%matrix, &
609 0 : "orbital density")
610 : END DO
611 0 : CALL local_rho_set_create(local_rho_set)
612 : CALL allocate_rho_atom_internals(local_rho_set%rho_atom_set, atomic_kind_set, &
613 0 : qs_kind_set, dft_control, para_env)
614 :
615 0 : DO ikind = 1, SIZE(atomic_kind_set)
616 0 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
617 :
618 : CALL get_qs_kind(qs_kind_set(ikind), paw_atom=paw_atom, &
619 0 : harmonics=harmonics, grid_atom=atomic_grid)
620 0 : IF (.NOT. paw_atom) CYCLE
621 :
622 0 : nr = atomic_grid%nr
623 0 : na = atomic_grid%ng_sphere
624 0 : bounds(1:2, 1:3) = 1
625 0 : bounds(2, 1) = na
626 0 : bounds(2, 2) = nr
627 :
628 0 : CALL xc_dset_create(deriv_set, local_bounds=bounds)
629 :
630 : CALL xc_rho_set_create(rho_set_h, bounds, density_cut, &
631 0 : gradient_cut, tau_cut)
632 : CALL xc_rho_set_create(rho_set_s, bounds, density_cut, &
633 0 : gradient_cut, tau_cut)
634 : CALL xc_rho_set_create(orb_rho_set_h, bounds, density_cut, &
635 0 : gradient_cut, tau_cut)
636 : CALL xc_rho_set_create(orb_rho_set_s, bounds, density_cut, &
637 0 : gradient_cut, tau_cut)
638 :
639 0 : CALL xc_rho_cflags_setall(needs, .FALSE.)
640 0 : IF (lsd) THEN
641 0 : CALL xb88_lsd_info(needs=needs)
642 0 : needs%norm_drho = .TRUE.
643 : ELSE
644 0 : CALL xb88_lda_info(needs=needs)
645 : END IF
646 0 : CALL xc_rho_set_atom_update(rho_set_h, needs, nspins, bounds)
647 0 : CALL xc_rho_set_atom_update(rho_set_s, needs, nspins, bounds)
648 0 : CALL xc_rho_cflags_setall(needs_orbs, .FALSE.)
649 0 : needs_orbs%rho = .TRUE.
650 0 : IF (lsd) needs_orbs%rho_spin = .TRUE.
651 0 : CALL xc_rho_set_atom_update(orb_rho_set_h, needs, nspins, bounds)
652 0 : CALL xc_rho_set_atom_update(orb_rho_set_s, needs, nspins, bounds)
653 :
654 0 : ALLOCATE (rho_h(1:na, 1:nr, 1:nspins), rho_s(1:na, 1:nr, 1:nspins))
655 0 : ALLOCATE (weight(1:na, 1:nr))
656 0 : ALLOCATE (vxc_LB_h(1:na, 1:nr, 1:nspins), vxc_LB_s(1:na, 1:nr, 1:nspins))
657 0 : ALLOCATE (vxc_GLLB_h(1:na, 1:nr, 1:nspins), vxc_GLLB_s(1:na, 1:nr, 1:nspins))
658 0 : ALLOCATE (vxc_tmp_h(1:na, 1:nr, 1:nspins), vxc_tmp_s(1:na, 1:nr, 1:nspins))
659 0 : ALLOCATE (vxc_SAOP_h(1:na, 1:nr, 1:nspins), vxc_SAOP_s(1:na, 1:nr, 1:nspins))
660 0 : ALLOCATE (drho_h(1:4, 1:na, 1:nr, 1:nspins), drho_s(1:4, 1:na, 1:nr, 1:nspins))
661 :
662 : ! Distribute the atoms of this kind
663 0 : bo = get_limit(natom, para_env%num_pe, para_env%mepos)
664 :
665 0 : DO iat = 1, natom !bo(1),bo(2)
666 0 : iatom = atom_list(iat)
667 :
668 0 : rho_atom => rho_atom_set(iatom)
669 0 : NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
670 : CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, &
671 : rho_rad_s=r_s, drho_rad_h=dr_h, &
672 : drho_rad_s=dr_s, rho_rad_h_d=r_h_d, &
673 0 : rho_rad_s_d=r_s_d)
674 0 : rho_h = 0.0_dp
675 0 : rho_s = 0.0_dp
676 0 : drho_h = 0.0_dp
677 0 : drho_s = 0.0_dp
678 0 : DO ir = 1, nr
679 : CALL calc_rho_angular(atomic_grid, harmonics, nspins, .TRUE., &
680 : ir, r_h, r_s, rho_h, rho_s, &
681 0 : dr_h, dr_s, r_h_d, r_s_d, drho_h, drho_s)
682 : END DO
683 0 : DO ir = 1, nr
684 0 : CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau, na, ir)
685 0 : CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau, na, ir)
686 : END DO
687 0 : DO ir = 1, nr
688 0 : DO ia = 1, na
689 0 : weight(ia, ir) = atomic_grid%wr(ir)*atomic_grid%wa(ia)
690 : END DO
691 : END DO
692 :
693 : !-----------------------------!
694 : ! 1. Slater exchange for LB94 !
695 : !-----------------------------!
696 : xc_fun_section_orig => section_vals_get_subs_vals(xc_section_orig, &
697 0 : "XC_FUNCTIONAL")
698 0 : CALL section_vals_create(xc_fun_section_tmp, xc_fun_section_orig%section)
699 : CALL section_vals_val_set(xc_fun_section_tmp, "_SECTION_PARAMETERS_", &
700 0 : i_val=xc_funct_no_shortcut)
701 : CALL section_vals_val_set(xc_fun_section_tmp, "XALPHA%_SECTION_PARAMETERS_", &
702 0 : l_val=.TRUE.)
703 : CALL section_vals_set_subs_vals(xc_section_tmp, "XC_FUNCTIONAL", &
704 0 : xc_fun_section_tmp)
705 :
706 : !---------------------!
707 : ! Both: hard and soft !
708 : !---------------------!
709 0 : CALL xc_dset_zero_all(deriv_set)
710 : CALL vxc_of_r_new(xc_fun_section_tmp, rho_set_h, deriv_set, 1, needs, &
711 0 : weight, lsd, na, nr, exc, vxc_tmp_h, vxg, vtau)
712 0 : CALL xc_dset_zero_all(deriv_set)
713 : CALL vxc_of_r_new(xc_fun_section_tmp, rho_set_s, deriv_set, 1, needs, &
714 0 : weight, lsd, na, nr, exc, vxc_tmp_s, vxg, vtau)
715 :
716 : !-------------------------------------------!
717 : ! 2. PZ correlation for LB94 and ec_uniform !
718 : !-------------------------------------------!
719 : CALL section_vals_val_set(xc_fun_section_tmp, "XALPHA%_SECTION_PARAMETERS_", &
720 0 : l_val=.FALSE.)
721 : CALL section_vals_val_set(xc_fun_section_tmp, "PZ81%_SECTION_PARAMETERS_", &
722 0 : l_val=.TRUE.)
723 :
724 : !------!
725 : ! Hard !
726 : !------!
727 0 : CALL xc_dset_zero_all(deriv_set)
728 : CALL vxc_of_r_new(xc_fun_section_tmp, rho_set_h, deriv_set, 1, needs, &
729 0 : weight, lsd, na, nr, exc, vxc_LB_h, vxg, vtau)
730 0 : vxc_LB_h = vxc_LB_h + alpha*vxc_tmp_h
731 0 : DO ispin = 1, nspins
732 0 : dummy => vxc_tmp_h(:, :, ispin:ispin)
733 0 : CALL add_lb_pot(dummy, rho_set_h, lsd, ispin)
734 0 : vxc_LB_h(:, :, ispin) = vxc_LB_h(:, :, ispin) - weight(:, :)*vxc_tmp_h(:, :, ispin)
735 : END DO
736 0 : NULLIFY (dummy)
737 :
738 0 : vxc_GLLB_h = 0.0_dp
739 0 : deriv => xc_dset_get_derivative(deriv_set, [INTEGER::])
740 0 : CPASSERT(ASSOCIATED(deriv))
741 0 : CALL xc_derivative_get(deriv, deriv_data=e_uniform)
742 0 : DO ispin = 1, nspins
743 0 : dummy => vxc_GLLB_h(:, :, ispin:ispin)
744 0 : CALL calc_2excpbe(dummy, rho_set_h, e_uniform, lsd)
745 0 : vxc_GLLB_h(:, :, ispin) = vxc_GLLB_h(:, :, ispin)*weight(:, :)
746 : END DO
747 0 : NULLIFY (deriv, dummy, e_uniform)
748 :
749 : !------!
750 : ! Soft !
751 : !------!
752 0 : CALL xc_dset_zero_all(deriv_set)
753 : CALL vxc_of_r_new(xc_fun_section_tmp, rho_set_s, deriv_set, 1, needs, &
754 0 : weight, lsd, na, nr, exc, vxc_LB_s, vxg, vtau)
755 :
756 0 : vxc_LB_s = vxc_LB_s + alpha*vxc_tmp_s
757 0 : DO ispin = 1, nspins
758 0 : dummy => vxc_tmp_s(:, :, ispin:ispin)
759 0 : CALL add_lb_pot(dummy, rho_set_s, lsd, ispin)
760 0 : vxc_LB_s(:, :, ispin) = vxc_LB_s(:, :, ispin) - weight(:, :)*vxc_tmp_s(:, :, ispin)
761 : END DO
762 0 : NULLIFY (dummy)
763 :
764 0 : vxc_GLLB_s = 0.0_dp
765 0 : deriv => xc_dset_get_derivative(deriv_set, [INTEGER::])
766 0 : CPASSERT(ASSOCIATED(deriv))
767 0 : CALL xc_derivative_get(deriv, deriv_data=e_uniform)
768 0 : DO ispin = 1, nspins
769 0 : dummy => vxc_GLLB_s(:, :, ispin:ispin)
770 0 : CALL calc_2excpbe(dummy, rho_set_s, e_uniform, lsd)
771 0 : vxc_GLLB_s(:, :, ispin) = vxc_GLLB_s(:, :, ispin)*weight(:, :)
772 : END DO
773 0 : NULLIFY (deriv, dummy, e_uniform)
774 :
775 : !------------------!
776 : ! Now the orbitals !
777 : !------------------!
778 0 : vxc_tmp_h = 0.0_dp; vxc_tmp_s = 0.0_dp
779 :
780 0 : DO ispin = 1, nspins
781 :
782 0 : DO orb = 1, homo(ispin) - 1
783 :
784 0 : ALLOCATE (coeff_col(nrow(ispin), 1))
785 :
786 : efac = K_rho*SQRT(mo_eigenvalues(ispin)%array(homo(ispin)) - &
787 0 : mo_eigenvalues(ispin)%array(orb))
788 0 : IF (.NOT. lsd) efac = 2.0_dp*efac
789 :
790 0 : CALL cp_fm_set_all(single_mo_coeff(ispin), 0.0_dp)
791 : CALL cp_fm_get_submatrix(mo_coeff(ispin)%matrix, coeff_col, &
792 0 : 1, orb, nrow(ispin), 1)
793 : CALL cp_fm_set_submatrix(single_mo_coeff(ispin), coeff_col, &
794 0 : 1, orb)
795 0 : CALL dbcsr_set(orbital_density_matrix(ispin)%matrix, 0.0_dp)
796 : CALL cp_dbcsr_plus_fm_fm_t(orbital_density_matrix(ispin)%matrix, &
797 : matrix_v=single_mo_coeff(ispin), &
798 : ncol=ncol(ispin), &
799 0 : alpha=1.0_dp)
800 :
801 0 : DEALLOCATE (coeff_col)
802 :
803 : ! This calculates the CPC and density on the grids for every atom even though
804 : ! we need it only for iatom at the moment. It seems that to circumvent this,
805 : ! the routines must be adapted to calculate just iatom
806 : ! remap pointer
807 0 : ns = SIZE(orbital_density_matrix)
808 0 : psmat(1:ns, 1:1) => orbital_density_matrix(1:ns)
809 0 : CALL calculate_rho_atom_coeff(qs_env, psmat, local_rho_set%rho_atom_set, qs_kind_set, oce, sab, para_env)
810 0 : CALL prepare_gapw_den(qs_env, local_rho_set, .FALSE.)
811 :
812 0 : rho_atom => local_rho_set%rho_atom_set(iatom)
813 0 : NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
814 0 : CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
815 0 : rho_h = 0.0_dp
816 0 : rho_s = 0.0_dp
817 0 : drho_h = 0.0_dp
818 0 : drho_s = 0.0_dp
819 0 : DO ir = 1, nr
820 : CALL calc_rho_angular(atomic_grid, harmonics, nspins, .FALSE., &
821 : ir, r_h, r_s, rho_h, rho_s, &
822 0 : dr_h, dr_s, r_h_d, r_s_d, drho_h, drho_s)
823 : END DO
824 0 : DO ir = 1, nr
825 0 : CALL fill_rho_set(orb_rho_set_h, lsd, nspins, needs_orbs, rho_h, drho_h, tau, na, ir)
826 0 : CALL fill_rho_set(orb_rho_set_s, lsd, nspins, needs_orbs, rho_s, drho_s, tau, na, ir)
827 : END DO
828 :
829 0 : IF (lsd) THEN
830 0 : IF (ispin == 1) THEN
831 0 : vxc_tmp_h(:, :, 1) = vxc_tmp_h(:, :, 1) + efac*orb_rho_set_h%rhoa(:, :, 1)
832 0 : vxc_tmp_s(:, :, 1) = vxc_tmp_s(:, :, 1) + efac*orb_rho_set_s%rhoa(:, :, 1)
833 : ELSE
834 0 : vxc_tmp_h(:, :, 2) = vxc_tmp_h(:, :, 2) + efac*orb_rho_set_h%rhob(:, :, 1)
835 0 : vxc_tmp_s(:, :, 2) = vxc_tmp_s(:, :, 2) + efac*orb_rho_set_s%rhob(:, :, 1)
836 : END IF
837 : ELSE
838 0 : vxc_tmp_h(:, :, 1) = vxc_tmp_h(:, :, 1) + efac*orb_rho_set_h%rho(:, :, 1)
839 0 : vxc_tmp_s(:, :, 1) = vxc_tmp_s(:, :, 1) + efac*orb_rho_set_s%rho(:, :, 1)
840 : END IF
841 :
842 : END DO ! orb
843 :
844 : END DO ! ispin
845 :
846 0 : IF (lsd) THEN
847 0 : DO ir = 1, nr
848 0 : DO ia = 1, na
849 0 : IF (rho_set_h%rhoa(ia, ir, 1) > rho_set_h%rho_cutoff) &
850 : vxc_GLLB_h(ia, ir, 1) = vxc_GLLB_h(ia, ir, 1) + &
851 0 : weight(ia, ir)*vxc_tmp_h(ia, ir, 1)/rho_set_h%rhoa(ia, ir, 1)
852 0 : IF (rho_set_h%rhob(ia, ir, 1) > rho_set_h%rho_cutoff) &
853 : vxc_GLLB_h(ia, ir, 2) = vxc_GLLB_h(ia, ir, 2) + &
854 0 : weight(ia, ir)*vxc_tmp_h(ia, ir, 2)/rho_set_h%rhob(ia, ir, 1)
855 0 : IF (rho_set_s%rhoa(ia, ir, 1) > rho_set_s%rho_cutoff) &
856 : vxc_GLLB_s(ia, ir, 1) = vxc_GLLB_s(ia, ir, 1) + &
857 0 : weight(ia, ir)*vxc_tmp_s(ia, ir, 1)/rho_set_s%rhoa(ia, ir, 1)
858 0 : IF (rho_set_s%rhob(ia, ir, 1) > rho_set_s%rho_cutoff) &
859 : vxc_GLLB_s(ia, ir, 2) = vxc_GLLB_s(ia, ir, 2) + &
860 0 : weight(ia, ir)*vxc_tmp_s(ia, ir, 2)/rho_set_s%rhob(ia, ir, 1)
861 : END DO
862 : END DO
863 : ELSE
864 0 : DO ir = 1, nr
865 0 : DO ia = 1, na
866 0 : IF (rho_set_h%rho(ia, ir, 1) > rho_set_h%rho_cutoff) &
867 : vxc_GLLB_h(ia, ir, 1) = vxc_GLLB_h(ia, ir, 1) + &
868 0 : weight(ia, ir)*vxc_tmp_h(ia, ir, 1)/rho_set_h%rho(ia, ir, 1)
869 0 : IF (rho_set_s%rho(ia, ir, 1) > rho_set_s%rho_cutoff) &
870 : vxc_GLLB_s(ia, ir, 1) = vxc_GLLB_s(ia, ir, 1) + &
871 0 : weight(ia, ir)*vxc_tmp_s(ia, ir, 1)/rho_set_s%rho(ia, ir, 1)
872 : END DO
873 : END DO
874 : END IF
875 :
876 0 : vxc_SAOP_h = 0.0_dp; vxc_SAOP_s = 0.0_dp
877 :
878 0 : DO ispin = 1, nspins
879 :
880 0 : DO orb = 1, homo(ispin)
881 :
882 0 : ALLOCATE (coeff_col(nrow(ispin), 1))
883 :
884 : we_LB = EXP(-2.0_dp*(mo_eigenvalues(ispin)%array(homo(ispin)) - &
885 0 : mo_eigenvalues(ispin)%array(orb))**2)
886 0 : we_GLLB = 1.0_dp - we_LB
887 0 : IF (.NOT. lsd) THEN
888 0 : we_LB = 2.0_dp*we_LB
889 0 : we_GLLB = 2.0_dp*we_GLLB
890 : END IF
891 :
892 : vxc_tmp_h(:, :, ispin) = we_LB*vxc_LB_h(:, :, ispin) + &
893 0 : we_GLLB*vxc_GLLB_h(:, :, ispin)
894 : vxc_tmp_s(:, :, ispin) = we_LB*vxc_LB_s(:, :, ispin) + &
895 0 : we_GLLB*vxc_GLLB_s(:, :, ispin)
896 :
897 0 : CALL cp_fm_set_all(single_mo_coeff(ispin), 0.0_dp)
898 : CALL cp_fm_get_submatrix(mo_coeff(ispin)%matrix, coeff_col, &
899 0 : 1, orb, nrow(ispin), 1)
900 : CALL cp_fm_set_submatrix(single_mo_coeff(ispin), coeff_col, &
901 0 : 1, orb)
902 0 : CALL dbcsr_set(orbital_density_matrix(ispin)%matrix, 0.0_dp)
903 : CALL cp_dbcsr_plus_fm_fm_t(orbital_density_matrix(ispin)%matrix, &
904 : matrix_v=single_mo_coeff(ispin), &
905 : ncol=ncol(ispin), &
906 0 : alpha=1.0_dp)
907 :
908 0 : DEALLOCATE (coeff_col)
909 :
910 : ! This calculates the CPC and density on the grids for every atom even though
911 : ! we need it only for iatom at the moment. It seems that to circumvent this,
912 : ! the routines must be adapted to calculate just iatom
913 : ! remap pointer
914 0 : ns = SIZE(orbital_density_matrix)
915 0 : psmat(1:ns, 1:1) => orbital_density_matrix(1:ns)
916 0 : CALL calculate_rho_atom_coeff(qs_env, psmat, local_rho_set%rho_atom_set, qs_kind_set, oce, sab, para_env)
917 0 : CALL prepare_gapw_den(qs_env, local_rho_set, .FALSE.)
918 :
919 0 : rho_atom => local_rho_set%rho_atom_set(iatom)
920 0 : NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
921 0 : CALL get_rho_atom(rho_atom=rho_atom, rho_rad_h=r_h, rho_rad_s=r_s)
922 0 : rho_h = 0.0_dp
923 0 : rho_s = 0.0_dp
924 0 : drho_h = 0.0_dp
925 0 : drho_s = 0.0_dp
926 0 : DO ir = 1, nr
927 : CALL calc_rho_angular(atomic_grid, harmonics, nspins, .FALSE., &
928 : ir, r_h, r_s, rho_h, rho_s, &
929 0 : dr_h, dr_s, r_h_d, r_s_d, drho_h, drho_s)
930 : END DO
931 0 : DO ir = 1, nr
932 0 : CALL fill_rho_set(orb_rho_set_h, lsd, nspins, needs_orbs, rho_h, drho_h, tau, na, ir)
933 0 : CALL fill_rho_set(orb_rho_set_s, lsd, nspins, needs_orbs, rho_s, drho_s, tau, na, ir)
934 : END DO
935 :
936 0 : IF (lsd) THEN
937 0 : IF (ispin == 1) THEN
938 0 : vxc_SAOP_h(:, :, 1) = vxc_SAOP_h(:, :, 1) + vxc_tmp_h(:, :, 1)*orb_rho_set_h%rhoa(:, :, 1)
939 0 : vxc_SAOP_s(:, :, 1) = vxc_SAOP_s(:, :, 1) + vxc_tmp_s(:, :, 1)*orb_rho_set_s%rhoa(:, :, 1)
940 : ELSE
941 0 : vxc_SAOP_h(:, :, 2) = vxc_SAOP_h(:, :, 2) + vxc_tmp_h(:, :, 2)*orb_rho_set_h%rhob(:, :, 1)
942 0 : vxc_SAOP_s(:, :, 2) = vxc_SAOP_s(:, :, 2) + vxc_tmp_s(:, :, 2)*orb_rho_set_s%rhob(:, :, 1)
943 : END IF
944 : ELSE
945 0 : vxc_SAOP_h(:, :, 1) = vxc_SAOP_h(:, :, 1) + vxc_tmp_h(:, :, 1)*orb_rho_set_h%rho(:, :, 1)
946 0 : vxc_SAOP_s(:, :, 1) = vxc_SAOP_s(:, :, 1) + vxc_tmp_s(:, :, 1)*orb_rho_set_s%rho(:, :, 1)
947 : END IF
948 :
949 : END DO ! orb
950 :
951 : END DO ! ispin
952 :
953 0 : IF (lsd) THEN
954 0 : DO ir = 1, nr
955 0 : DO ia = 1, na
956 0 : IF (rho_set_h%rhoa(ia, ir, 1) > rho_set_h%rho_cutoff) THEN
957 0 : vxc_SAOP_h(ia, ir, 1) = vxc_SAOP_h(ia, ir, 1)/rho_set_h%rhoa(ia, ir, 1)
958 : ELSE
959 0 : vxc_SAOP_h(ia, ir, 1) = 0.0_dp
960 : END IF
961 0 : IF (rho_set_h%rhob(ia, ir, 1) > rho_set_h%rho_cutoff) THEN
962 0 : vxc_SAOP_h(ia, ir, 2) = vxc_SAOP_h(ia, ir, 2)/rho_set_h%rhob(ia, ir, 1)
963 : ELSE
964 0 : vxc_SAOP_h(ia, ir, 2) = 0.0_dp
965 : END IF
966 0 : IF (rho_set_s%rhoa(ia, ir, 1) > rho_set_s%rho_cutoff) THEN
967 0 : vxc_SAOP_s(ia, ir, 1) = vxc_SAOP_s(ia, ir, 1)/rho_set_s%rhoa(ia, ir, 1)
968 : ELSE
969 0 : vxc_SAOP_s(ia, ir, 1) = 0.0_dp
970 : END IF
971 0 : IF (rho_set_s%rhob(ia, ir, 1) > rho_set_s%rho_cutoff) THEN
972 0 : vxc_SAOP_s(ia, ir, 2) = vxc_SAOP_s(ia, ir, 2)/rho_set_s%rhob(ia, ir, 1)
973 : ELSE
974 0 : vxc_SAOP_s(ia, ir, 2) = 0.0_dp
975 : END IF
976 : END DO
977 : END DO
978 : ELSE
979 0 : DO ir = 1, nr
980 0 : DO ia = 1, na
981 0 : IF (rho_set_h%rho(ia, ir, 1) > rho_set_h%rho_cutoff) THEN
982 0 : vxc_SAOP_h(ia, ir, 1) = vxc_SAOP_h(ia, ir, 1)/rho_set_h%rho(ia, ir, 1)
983 : ELSE
984 0 : vxc_SAOP_h(ia, ir, 1) = 0.0_dp
985 : END IF
986 0 : IF (rho_set_s%rho(ia, ir, 1) > rho_set_s%rho_cutoff) THEN
987 0 : vxc_SAOP_s(ia, ir, 1) = vxc_SAOP_s(ia, ir, 1)/rho_set_s%rho(ia, ir, 1)
988 : ELSE
989 0 : vxc_SAOP_s(ia, ir, 1) = 0.0_dp
990 : END IF
991 : END DO
992 : END DO
993 : END IF
994 :
995 0 : rho_atom => rho_atom_set(iatom)
996 0 : CALL get_rho_atom(rho_atom=rho_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
997 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis, &
998 0 : harmonics=harmonics, grid_atom=grid_atom)
999 0 : SELECT CASE (oe_corr)
1000 : CASE (oe_lb)
1001 0 : CALL gaVxcgb_noGC(vxc_LB_h, vxc_LB_s, int_hh, int_ss, grid_atom, orb_basis, harmonics, nspins)
1002 : CASE (oe_gllb)
1003 0 : CALL gaVxcgb_noGC(vxc_GLLB_h, vxc_GLLB_s, int_hh, int_ss, grid_atom, orb_basis, harmonics, nspins)
1004 : CASE (oe_saop)
1005 0 : CALL gaVxcgb_noGC(vxc_SAOP_h, vxc_SAOP_s, int_hh, int_ss, grid_atom, orb_basis, harmonics, nspins)
1006 : CASE default
1007 0 : CPABORT("Unknown correction!")
1008 : END SELECT
1009 :
1010 : END DO
1011 :
1012 0 : DEALLOCATE (rho_h, rho_s, weight)
1013 0 : DEALLOCATE (vxc_LB_h, vxc_LB_s)
1014 0 : DEALLOCATE (vxc_GLLB_h, vxc_GLLB_s)
1015 0 : DEALLOCATE (vxc_tmp_h, vxc_tmp_s)
1016 0 : DEALLOCATE (vxc_SAOP_h, vxc_SAOP_s)
1017 0 : DEALLOCATE (drho_h, drho_s)
1018 :
1019 0 : CALL xc_dset_release(deriv_set)
1020 0 : CALL xc_rho_set_release(rho_set_h)
1021 0 : CALL xc_rho_set_release(rho_set_s)
1022 0 : CALL xc_rho_set_release(orb_rho_set_h)
1023 0 : CALL xc_rho_set_release(orb_rho_set_s)
1024 :
1025 : END DO
1026 :
1027 : ! remap pointer
1028 0 : ns = SIZE(matrix_ks)
1029 0 : ksmat(1:ns, 1:1) => matrix_ks(1:ns)
1030 0 : ns = SIZE(rho_struct_ao)
1031 0 : psmat(1:ns, 1:1) => rho_struct_ao(1:ns)
1032 :
1033 0 : CALL update_ks_atom(qs_env, ksmat, psmat, forces=.FALSE.)
1034 :
1035 : !---------!
1036 : ! Cleanup !
1037 : !---------!
1038 0 : CALL section_vals_release(xc_fun_section_tmp)
1039 0 : CALL section_vals_release(xc_section_tmp)
1040 0 : CALL section_vals_release(xc_section_orig)
1041 :
1042 0 : CALL local_rho_set_release(local_rho_set)
1043 0 : CALL cp_fm_release(single_mo_coeff)
1044 0 : DEALLOCATE (mo_coeff, mo_eigenvalues)
1045 0 : CALL dbcsr_deallocate_matrix_set(orbital_density_matrix)
1046 :
1047 0 : END SUBROUTINE gapw_add_atomic_saop_pot
1048 :
1049 : ! **************************************************************************************************
1050 : !> \brief ...
1051 : !> \param pot ...
1052 : !> \param rho_set ...
1053 : !> \param lsd ...
1054 : !> \param spin ...
1055 : ! **************************************************************************************************
1056 22 : SUBROUTINE add_lb_pot(pot, rho_set, lsd, spin)
1057 :
1058 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: pot
1059 : TYPE(xc_rho_set_type), INTENT(IN) :: rho_set
1060 : LOGICAL, INTENT(IN) :: lsd
1061 : INTEGER, INTENT(IN) :: spin
1062 :
1063 : REAL(KIND=dp), PARAMETER :: ob3 = 1.0_dp/3.0_dp
1064 :
1065 : INTEGER :: i, j, k
1066 : INTEGER, DIMENSION(2, 3) :: bo
1067 : REAL(KIND=dp) :: n, n_13, x, x2
1068 :
1069 220 : bo = rho_set%local_bounds
1070 :
1071 776 : DO k = bo(1, 3), bo(2, 3)
1072 27510 : DO j = bo(1, 2), bo(2, 2)
1073 514675 : DO i = bo(1, 1), bo(2, 1)
1074 513921 : IF (.NOT. lsd) THEN
1075 137875 : IF (rho_set%rho(i, j, k) > rho_set%rho_cutoff) THEN
1076 137875 : n = rho_set%rho(i, j, k)/2.0_dp
1077 137875 : n_13 = n**ob3
1078 137875 : x = (rho_set%norm_drho(i, j, k)/2.0_dp)/(n*n_13)
1079 137875 : x2 = x*x
1080 137875 : pot(i, j, k) = beta*x2*n_13/(1.0_dp + 3.0_dp*beta*x*LOG(x + SQRT(x2 + 1.0_dp)))
1081 : END IF
1082 : ELSE
1083 349312 : IF (spin == 1) THEN
1084 174656 : IF (rho_set%rhoa(i, j, k) > rho_set%rho_cutoff) THEN
1085 174656 : n_13 = rho_set%rhoa_1_3(i, j, k)
1086 174656 : x = rho_set%norm_drhoa(i, j, k)/(rho_set%rhoa(i, j, k)*n_13)
1087 174656 : x2 = x*x
1088 174656 : pot(i, j, k) = beta*x2*n_13/(1.0_dp + 3.0_dp*beta*x*LOG(SQRT(x2 + 1.0_dp) + x))
1089 : END IF
1090 174656 : ELSE IF (spin == 2) THEN
1091 174656 : IF (rho_set%rhob(i, j, k) > rho_set%rho_cutoff) THEN
1092 174656 : n_13 = rho_set%rhob_1_3(i, j, k)
1093 174656 : x = rho_set%norm_drhob(i, j, k)/(rho_set%rhob(i, j, k)*n_13)
1094 174656 : x2 = x*x
1095 174656 : pot(i, j, k) = beta*x2*n_13/(1.0_dp + 3.0_dp*beta*x*LOG(SQRT(x2 + 1.0_dp) + x))
1096 : END IF
1097 : END IF
1098 : END IF
1099 : END DO
1100 : END DO
1101 : END DO
1102 :
1103 22 : END SUBROUTINE add_lb_pot
1104 :
1105 : ! **************************************************************************************************
1106 : !> \brief ...
1107 : !> \param pot ...
1108 : !> \param rho_set ...
1109 : !> \param e_uniform ...
1110 : !> \param lsd ...
1111 : ! **************************************************************************************************
1112 22 : SUBROUTINE calc_2excpbe(pot, rho_set, e_uniform, lsd)
1113 :
1114 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: pot
1115 : TYPE(xc_rho_set_type), INTENT(IN) :: rho_set
1116 : REAL(KIND=dp), DIMENSION(:, :, :), POINTER :: e_uniform
1117 : LOGICAL, INTENT(IN) :: lsd
1118 :
1119 : INTEGER :: i, j, k
1120 : INTEGER, DIMENSION(2, 3) :: bo
1121 : REAL(KIND=dp) :: e_unif, rho
1122 :
1123 220 : bo = rho_set%local_bounds
1124 :
1125 776 : DO k = bo(1, 3), bo(2, 3)
1126 27510 : DO j = bo(1, 2), bo(2, 2)
1127 514675 : DO i = bo(1, 1), bo(2, 1)
1128 513921 : IF (.NOT. lsd) THEN
1129 137875 : IF (rho_set%rho(i, j, k) > rho_set%rho_cutoff) THEN
1130 137875 : e_unif = e_uniform(i, j, k)/rho_set%rho(i, j, k)
1131 : ELSE
1132 0 : e_unif = 0.0_dp
1133 : END IF
1134 : pot(i, j, k) = &
1135 : 2.0_dp* &
1136 : calc_ecpbe_r(rho_set%rho(i, j, k), rho_set%norm_drho(i, j, k), &
1137 : e_unif, rho_set%rho_cutoff, rho_set%drho_cutoff) + &
1138 : 2.0_dp* &
1139 : calc_expbe_r(rho_set%rho(i, j, k), rho_set%norm_drho(i, j, k), &
1140 137875 : rho_set%rho_cutoff, rho_set%drho_cutoff)
1141 : ELSE
1142 349312 : rho = rho_set%rhoa(i, j, k) + rho_set%rhob(i, j, k)
1143 349312 : IF (rho > rho_set%rho_cutoff) THEN
1144 349312 : e_unif = e_uniform(i, j, k)/rho
1145 : ELSE
1146 0 : e_unif = 0.0_dp
1147 : END IF
1148 : pot(i, j, k) = &
1149 : 2.0_dp* &
1150 : calc_ecpbe_u(rho_set%rhoa(i, j, k), rho_set%rhob(i, j, k), rho_set%norm_drho(i, j, k), &
1151 : e_unif, &
1152 : rho_set%rho_cutoff, rho_set%drho_cutoff) + &
1153 : 2.0_dp* &
1154 : calc_expbe_u(rho_set%rhoa(i, j, k), rho_set%rhob(i, j, k), rho_set%norm_drho(i, j, k), &
1155 349312 : rho_set%rho_cutoff, rho_set%drho_cutoff)
1156 : END IF
1157 : END DO
1158 : END DO
1159 : END DO
1160 :
1161 22 : END SUBROUTINE calc_2excpbe
1162 :
1163 : ! **************************************************************************************************
1164 : !> \brief ...
1165 : !> \param ra ...
1166 : !> \param rb ...
1167 : !> \param ngr ...
1168 : !> \param ec_unif ...
1169 : !> \param rc ...
1170 : !> \param ngrc ...
1171 : !> \return ...
1172 : ! **************************************************************************************************
1173 349312 : FUNCTION calc_ecpbe_u(ra, rb, ngr, ec_unif, rc, ngrc) RESULT(res)
1174 :
1175 : REAL(kind=dp), INTENT(in) :: ra, rb, ngr, ec_unif, rc, ngrc
1176 : REAL(kind=dp) :: res
1177 :
1178 : REAL(kind=dp), PARAMETER :: ob3 = 1.0_dp/3.0_dp, tb3 = 2.0_dp/3.0_dp
1179 :
1180 : REAL(kind=dp) :: A, At2, H, kf, kl, ks, phi, phi3, r, t2, &
1181 : zeta
1182 :
1183 349312 : r = ra + rb
1184 349312 : H = 0.0_dp
1185 349312 : IF (r > rc .AND. ngr > ngrc) THEN
1186 349312 : zeta = (ra - rb)/r
1187 349312 : IF (zeta > 1.0_dp) zeta = 1.0_dp ! machine precision problem
1188 349312 : IF (zeta < -1.0_dp) zeta = -1.0_dp ! machine precision problem
1189 349312 : phi = ((1.0_dp + zeta)**tb3 + (1.0_dp - zeta)**tb3)/2.0_dp
1190 349312 : phi3 = phi*phi*phi
1191 349312 : kf = (3.0_dp*r*pi*pi)**ob3
1192 349312 : ks = SQRT(4.0_dp*kf/pi)
1193 349312 : t2 = (ngr/(2.0_dp*phi*ks*r))**2
1194 349312 : A = beta_ec/gamma_saop/(EXP(-ec_unif/(gamma_saop*phi3)) - 1.0_dp)
1195 349312 : At2 = A*t2
1196 349312 : kl = (1.0_dp + At2)/(1.0_dp + At2 + At2*At2)
1197 349312 : H = gamma_saop*LOG(1.0_dp + beta_ec/gamma_saop*t2*kl)
1198 : END IF
1199 349312 : res = ec_unif + H
1200 :
1201 349312 : END FUNCTION calc_ecpbe_u
1202 :
1203 : ! **************************************************************************************************
1204 : !> \brief ...
1205 : !> \param r ...
1206 : !> \param ngr ...
1207 : !> \param ec_unif ...
1208 : !> \param rc ...
1209 : !> \param ngrc ...
1210 : !> \return ...
1211 : ! **************************************************************************************************
1212 137875 : FUNCTION calc_ecpbe_r(r, ngr, ec_unif, rc, ngrc) RESULT(res)
1213 :
1214 : REAL(kind=dp), INTENT(in) :: r, ngr, ec_unif, rc, ngrc
1215 : REAL(kind=dp) :: res
1216 :
1217 : REAL(kind=dp) :: A, At2, H, kf, kl, ks, t2
1218 :
1219 137875 : H = 0.0_dp
1220 137875 : IF (r > rc .AND. ngr > ngrc) THEN
1221 137875 : kf = (3.0_dp*r*pi*pi)**(1.0_dp/3.0_dp)
1222 137875 : ks = SQRT(4.0_dp*kf/pi)
1223 137875 : t2 = (ngr/(2.0_dp*ks*r))**2
1224 137875 : A = beta_ec/gamma_saop/(EXP(-ec_unif/gamma_saop) - 1.0_dp)
1225 137875 : At2 = A*t2
1226 137875 : kl = (1.0_dp + At2)/(1.0_dp + At2 + At2*At2)
1227 137875 : H = gamma_saop*LOG(1.0_dp + beta_ec/gamma_saop*t2*kl)
1228 : END IF
1229 137875 : res = ec_unif + H
1230 :
1231 137875 : END FUNCTION calc_ecpbe_r
1232 :
1233 : ! **************************************************************************************************
1234 : !> \brief ...
1235 : !> \param ra ...
1236 : !> \param rb ...
1237 : !> \param ngr ...
1238 : !> \param rc ...
1239 : !> \param ngrc ...
1240 : !> \return ...
1241 : ! **************************************************************************************************
1242 349312 : FUNCTION calc_expbe_u(ra, rb, ngr, rc, ngrc) RESULT(res)
1243 :
1244 : REAL(kind=dp), INTENT(in) :: ra, rb, ngr, rc, ngrc
1245 : REAL(kind=dp) :: res
1246 :
1247 : REAL(kind=dp) :: r
1248 :
1249 349312 : r = ra + rb
1250 349312 : res = calc_expbe_r(r, ngr, rc, ngrc)
1251 :
1252 349312 : END FUNCTION calc_expbe_u
1253 :
1254 : ! **************************************************************************************************
1255 : !> \brief ...
1256 : !> \param r ...
1257 : !> \param ngr ...
1258 : !> \param rc ...
1259 : !> \param ngrc ...
1260 : !> \return ...
1261 : ! **************************************************************************************************
1262 487187 : FUNCTION calc_expbe_r(r, ngr, rc, ngrc) RESULT(res)
1263 :
1264 : REAL(kind=dp), INTENT(in) :: r, ngr, rc, ngrc
1265 : REAL(kind=dp) :: res
1266 :
1267 : REAL(kind=dp) :: ex_unif, fx, kf, s
1268 :
1269 487187 : IF (r > rc) THEN
1270 487187 : kf = (3.0_dp*r*pi*pi)**(1.0_dp/3.0_dp)
1271 487187 : ex_unif = -3.0_dp*kf/(4.0_dp*pi)
1272 487187 : fx = 1.0_dp
1273 487187 : IF (ngr > ngrc) THEN
1274 487187 : s = ngr/(2.0_dp*kf*r)
1275 487187 : fx = fx + kappa - kappa/(1.0_dp + mu*s*s/kappa)
1276 : END IF
1277 487187 : res = ex_unif*fx
1278 : ELSE
1279 : res = 0.0_dp
1280 : END IF
1281 :
1282 487187 : END FUNCTION calc_expbe_r
1283 :
1284 : END MODULE xc_pot_saop
|