Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief routines that build the Kohn-Sham matrix (i.e calculate the coulomb
10 : !> and xc parts
11 : !> \par History
12 : !> 05.2002 moved from qs_scf (see there the history) [fawzi]
13 : !> JGH [30.08.02] multi-grid arrays independent from density and potential
14 : !> 10.2002 introduced pools, uses updated rho as input,
15 : !> removed most temporary variables, renamed may vars,
16 : !> began conversion to LSD [fawzi]
17 : !> 10.2004 moved calculate_w_matrix here [Joost VandeVondele]
18 : !> introduced energy derivative wrt MOs [Joost VandeVondele]
19 : !> \author Fawzi Mohamed
20 : ! **************************************************************************************************
21 :
22 : MODULE qs_ks_utils
23 : USE admm_types, ONLY: admm_type,&
24 : get_admm_env
25 : USE atomic_kind_types, ONLY: atomic_kind_type,&
26 : get_atomic_kind
27 : USE cell_types, ONLY: cell_type
28 : USE cp_control_types, ONLY: dft_control_type
29 : USE cp_dbcsr_api, ONLY: &
30 : dbcsr_add, dbcsr_copy, dbcsr_deallocate_matrix, dbcsr_get_info, dbcsr_init_p, &
31 : dbcsr_multiply, dbcsr_p_type, dbcsr_release_p, dbcsr_scale, dbcsr_set, dbcsr_type
32 : USE cp_dbcsr_contrib, ONLY: dbcsr_dot,&
33 : dbcsr_scale_by_vector
34 : USE cp_dbcsr_operations, ONLY: copy_dbcsr_to_fm,&
35 : copy_fm_to_dbcsr,&
36 : cp_dbcsr_plus_fm_fm_t,&
37 : cp_dbcsr_sm_fm_multiply,&
38 : dbcsr_allocate_matrix_set,&
39 : dbcsr_deallocate_matrix_set
40 : USE cp_ddapc, ONLY: cp_ddapc_apply_CD
41 : USE cp_fm_struct, ONLY: cp_fm_struct_create,&
42 : cp_fm_struct_release,&
43 : cp_fm_struct_type
44 : USE cp_fm_types, ONLY: cp_fm_create,&
45 : cp_fm_get_info,&
46 : cp_fm_release,&
47 : cp_fm_set_all,&
48 : cp_fm_to_fm,&
49 : cp_fm_type
50 : USE cp_log_handling, ONLY: cp_get_default_logger,&
51 : cp_logger_type,&
52 : cp_to_string
53 : USE cp_output_handling, ONLY: cp_p_file,&
54 : cp_print_key_finished_output,&
55 : cp_print_key_should_output,&
56 : cp_print_key_unit_nr
57 : USE hfx_admm_utils, ONLY: tddft_hfx_matrix
58 : USE hfx_derivatives, ONLY: derivatives_four_center
59 : USE hfx_types, ONLY: hfx_type
60 : USE input_constants, ONLY: &
61 : cdft_alpha_constraint, cdft_beta_constraint, cdft_charge_constraint, &
62 : cdft_magnetization_constraint, do_admm_aux_exch_func_none, do_ppl_grid, sic_ad, sic_eo, &
63 : sic_list_all, sic_list_unpaired, sic_mauri_spz, sic_mauri_us, sic_none
64 : USE input_section_types, ONLY: section_vals_get_subs_vals,&
65 : section_vals_type,&
66 : section_vals_val_get
67 : USE kahan_sum, ONLY: accurate_dot_product,&
68 : accurate_sum
69 : USE kinds, ONLY: default_string_length,&
70 : dp
71 : USE kpoint_types, ONLY: get_kpoint_info,&
72 : kpoint_type
73 : USE lri_environment_methods, ONLY: v_int_ppl_update
74 : USE lri_environment_types, ONLY: lri_density_type,&
75 : lri_environment_type,&
76 : lri_kind_type
77 : USE lri_forces, ONLY: calculate_lri_forces,&
78 : calculate_ri_forces
79 : USE lri_ks_methods, ONLY: calculate_lri_ks_matrix,&
80 : calculate_ri_ks_matrix
81 : USE mathlib, ONLY: abnormal_value
82 : USE message_passing, ONLY: mp_para_env_type
83 : USE ps_implicit_types, ONLY: MIXED_BC,&
84 : MIXED_PERIODIC_BC,&
85 : NEUMANN_BC,&
86 : PERIODIC_BC
87 : USE pw_env_types, ONLY: pw_env_get,&
88 : pw_env_type
89 : USE pw_methods, ONLY: pw_axpy,&
90 : pw_copy,&
91 : pw_integral_ab,&
92 : pw_integrate_function,&
93 : pw_scale,&
94 : pw_transfer,&
95 : pw_zero
96 : USE pw_poisson_methods, ONLY: pw_poisson_solve
97 : USE pw_poisson_types, ONLY: pw_poisson_implicit,&
98 : pw_poisson_type
99 : USE pw_pool_types, ONLY: pw_pool_type
100 : USE pw_types, ONLY: pw_c1d_gs_type,&
101 : pw_r3d_rs_type
102 : USE qs_cdft_types, ONLY: cdft_control_type
103 : USE qs_charges_types, ONLY: qs_charges_type
104 : USE qs_collocate_density, ONLY: calculate_rho_elec
105 : USE qs_energy_types, ONLY: qs_energy_type
106 : USE qs_environment_types, ONLY: get_qs_env,&
107 : qs_environment_type
108 : USE qs_force_types, ONLY: qs_force_type
109 : USE qs_integrate_potential, ONLY: integrate_v_rspace,&
110 : integrate_v_rspace_diagonal,&
111 : integrate_v_rspace_one_center
112 : USE qs_kind_types, ONLY: get_qs_kind,&
113 : get_qs_kind_set,&
114 : qs_kind_type
115 : USE qs_ks_atom, ONLY: update_ks_atom
116 : USE qs_ks_qmmm_methods, ONLY: qmmm_modify_hartree_pot
117 : USE qs_ks_types, ONLY: get_ks_env,&
118 : qs_ks_env_type
119 : USE qs_mo_types, ONLY: get_mo_set,&
120 : mo_set_type
121 : USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
122 : USE qs_oce_types, ONLY: oce_matrix_type
123 : USE qs_rho_atom_methods, ONLY: allocate_rho_atom_internals,&
124 : calculate_rho_atom,&
125 : calculate_rho_atom_coeff
126 : USE qs_rho_atom_types, ONLY: deallocate_rho_atom_set,&
127 : rho_atom_type,&
128 : zero_rho_atom_integrals
129 : USE qs_rho_types, ONLY: qs_rho_get,&
130 : qs_rho_type
131 : USE qs_vxc_atom, ONLY: calculate_vxc_atom
132 : USE skala_gpw_functional, ONLY: native_skala_gapw_composite_direct_ao,&
133 : native_skala_gapw_composite_reference
134 : USE task_list_types, ONLY: task_list_type
135 : USE virial_types, ONLY: virial_type
136 : USE xc, ONLY: xc_exc_calc,&
137 : xc_vxc_pw_create
138 : USE xc_derivatives, ONLY: xc_functionals_get_needs
139 : USE xc_gauxc_functional, ONLY: apply_gauxc
140 : USE xc_rho_cflags_types, ONLY: xc_rho_cflags_type
141 : #include "./base/base_uses.f90"
142 :
143 : IMPLICIT NONE
144 :
145 : PRIVATE
146 :
147 : LOGICAL, PARAMETER :: debug_this_module = .TRUE.
148 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_ks_utils'
149 :
150 : PUBLIC :: low_spin_roks, sic_explicit_orbitals, calc_v_sic_rspace, check_sum_energies, print_densities, &
151 : print_detailed_energy, compute_matrix_vxc, compute_matrix_vxc_kp, sum_up_and_integrate, &
152 : calculate_zmp_potential, get_embed_potential_energy
153 :
154 : CONTAINS
155 :
156 : ! **************************************************************************************************
157 : !> \brief do ROKS calculations yielding low spin states
158 : !> \param energy ...
159 : !> \param qs_env ...
160 : !> \param dft_control ...
161 : !> \param do_hfx ...
162 : !> \param just_energy ...
163 : !> \param calculate_forces ...
164 : !> \param auxbas_pw_pool ...
165 : ! **************************************************************************************************
166 136161 : SUBROUTINE low_spin_roks(energy, qs_env, dft_control, do_hfx, just_energy, &
167 : calculate_forces, auxbas_pw_pool)
168 :
169 : TYPE(qs_energy_type), POINTER :: energy
170 : TYPE(qs_environment_type), POINTER :: qs_env
171 : TYPE(dft_control_type), POINTER :: dft_control
172 : LOGICAL, INTENT(IN) :: do_hfx, just_energy, calculate_forces
173 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
174 :
175 : CHARACTER(*), PARAMETER :: routineN = 'low_spin_roks'
176 :
177 : INTEGER :: handle, irep, ispin, iterm, k, k_alpha, &
178 : k_beta, n_rep, Nelectron, Nspin, Nterms
179 136161 : INTEGER, DIMENSION(:), POINTER :: ivec
180 136161 : INTEGER, DIMENSION(:, :, :), POINTER :: occupations
181 : LOGICAL :: compute_tau, compute_virial, gapw, &
182 : in_range, uniform_occupation, use_gauxc
183 : REAL(KIND=dp) :: ehfx, exc, exc1
184 : REAL(KIND=dp), DIMENSION(3, 3) :: virial_xc_tmp
185 136161 : REAL(KIND=dp), DIMENSION(:), POINTER :: energy_scaling, rvec, scaling
186 : TYPE(cell_type), POINTER :: cell
187 136161 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_h, matrix_hfx, matrix_p, mdummy, &
188 136161 : mo_derivs, rho_ao
189 136161 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_p2
190 : TYPE(dbcsr_type), POINTER :: dbcsr_deriv, fm_deriv, fm_scaled, &
191 : mo_coeff
192 136161 : TYPE(hfx_type), DIMENSION(:, :), POINTER :: x_data
193 136161 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mo_array
194 : TYPE(mp_para_env_type), POINTER :: para_env
195 136161 : TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g, tau_g
196 : TYPE(pw_env_type), POINTER :: pw_env
197 : TYPE(pw_pool_type), POINTER :: xc_pw_pool
198 : TYPE(pw_r3d_rs_type) :: work_v_rspace
199 136161 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r, tau, vxc, vxc_tau
200 : TYPE(pw_r3d_rs_type), POINTER :: weights
201 : TYPE(qs_ks_env_type), POINTER :: ks_env
202 : TYPE(qs_rho_type), POINTER :: rho
203 136161 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho_atom_set
204 : TYPE(section_vals_type), POINTER :: hfx_section, input, &
205 : low_spin_roks_section, xc_section
206 : TYPE(virial_type), POINTER :: virial
207 : TYPE(xc_rho_cflags_type) :: needs
208 :
209 135663 : IF (.NOT. dft_control%low_spin_roks) RETURN
210 :
211 498 : CALL timeset(routineN, handle)
212 :
213 498 : NULLIFY (ks_env, rho_ao, rho_atom_set)
214 498 : gapw = dft_control%qs_control%gapw
215 498 : use_gauxc = gapw .AND. dft_control%use_gauxc
216 498 : compute_tau = .FALSE.
217 :
218 : ! Test for not compatible options
219 498 : IF (dft_control%qs_control%gapw_xc) THEN
220 0 : CALL cp_abort(__LOCATION__, "GAPW_XC is not compatible with low spin ROKS method.")
221 : END IF
222 498 : IF (dft_control%do_admm) THEN
223 0 : CALL cp_abort(__LOCATION__, "ADMM not compatible with low spin ROKS method.")
224 : END IF
225 498 : IF (dft_control%do_admm) THEN
226 0 : IF (qs_env%admm_env%aux_exch_func /= do_admm_aux_exch_func_none) THEN
227 : CALL cp_abort(__LOCATION__, "ADMM with XC correction functional "// &
228 0 : "not compatible with low spin ROKS method.")
229 : END IF
230 : END IF
231 498 : IF (dft_control%qs_control%semi_empirical .OR. dft_control%qs_control%dftb .OR. &
232 : dft_control%qs_control%xtb) THEN
233 0 : CALL cp_abort(__LOCATION__, "SE/xTB/DFTB are not compatible with low spin ROKS method.")
234 : END IF
235 :
236 : CALL get_qs_env(qs_env, &
237 : ks_env=ks_env, &
238 : mo_derivs=mo_derivs, &
239 : mos=mo_array, &
240 : rho=rho, &
241 : pw_env=pw_env, &
242 : xcint_weights=weights, &
243 : input=input, &
244 : cell=cell, &
245 498 : virial=virial)
246 :
247 498 : CALL qs_rho_get(rho, rho_ao=rho_ao)
248 :
249 498 : compute_virial = virial%pv_calculate .AND. (.NOT. virial%pv_numer)
250 498 : xc_section => section_vals_get_subs_vals(input, "DFT%XC")
251 498 : hfx_section => section_vals_get_subs_vals(input, "DFT%XC%HF")
252 :
253 498 : IF (gapw) THEN
254 136 : IF (compute_virial) CPABORT("GAPW low spin ROKS stress is not implemented.")
255 136 : IF (calculate_forces) CPABORT("GAPW low spin ROKS forces are not implemented.")
256 136 : IF (.NOT. use_gauxc) THEN
257 : needs = xc_functionals_get_needs(section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL"), &
258 104 : lsd=.TRUE., calc_potential=.TRUE.)
259 104 : compute_tau = needs%tau .OR. needs%tau_spin
260 : END IF
261 : END IF
262 :
263 : ! The configuration corrections currently use unweighted grid integration.
264 498 : IF (ASSOCIATED(weights)) THEN
265 0 : CALL cp_abort(__LOCATION__, "No accurate xc integration possible.")
266 : END IF
267 : ! some assumptions need to be checked
268 : ! we have two spins
269 498 : CPASSERT(SIZE(mo_array, 1) == 2)
270 498 : Nspin = 2
271 : ! we want uniform occupations
272 498 : CALL get_mo_set(mo_set=mo_array(1), uniform_occupation=uniform_occupation)
273 498 : CPASSERT(uniform_occupation)
274 498 : CALL get_mo_set(mo_set=mo_array(2), mo_coeff_b=mo_coeff, uniform_occupation=uniform_occupation)
275 498 : CPASSERT(uniform_occupation)
276 498 : IF (do_hfx .AND. calculate_forces .AND. compute_virial) THEN
277 0 : CALL cp_abort(__LOCATION__, "ROKS virial with HFX not available.")
278 : END IF
279 :
280 498 : NULLIFY (dbcsr_deriv)
281 498 : CALL dbcsr_init_p(dbcsr_deriv)
282 498 : CALL dbcsr_copy(dbcsr_deriv, mo_derivs(1)%matrix)
283 498 : CALL dbcsr_set(dbcsr_deriv, 0.0_dp)
284 :
285 : ! basic info
286 498 : CALL get_mo_set(mo_set=mo_array(1), mo_coeff_b=mo_coeff)
287 498 : CALL dbcsr_get_info(mo_coeff, nfullcols_total=k_alpha)
288 498 : CALL get_mo_set(mo_set=mo_array(2), mo_coeff_b=mo_coeff)
289 498 : CALL dbcsr_get_info(mo_coeff, nfullcols_total=k_beta)
290 :
291 : ! read the input
292 498 : low_spin_roks_section => section_vals_get_subs_vals(input, "DFT%LOW_SPIN_ROKS")
293 :
294 498 : CALL section_vals_val_get(low_spin_roks_section, "ENERGY_SCALING", r_vals=rvec)
295 498 : Nterms = SIZE(rvec)
296 1494 : ALLOCATE (energy_scaling(Nterms))
297 2490 : energy_scaling = rvec !? just wondering, should this add up to 1, in which case we should cpp?
298 :
299 498 : CALL section_vals_val_get(low_spin_roks_section, "SPIN_CONFIGURATION", n_rep_val=n_rep)
300 498 : CPASSERT(n_rep == Nterms)
301 498 : CALL section_vals_val_get(low_spin_roks_section, "SPIN_CONFIGURATION", i_rep_val=1, i_vals=ivec)
302 498 : Nelectron = SIZE(ivec)
303 498 : CPASSERT(Nelectron == k_alpha - k_beta)
304 1992 : ALLOCATE (occupations(2, Nelectron, Nterms))
305 7470 : occupations = 0
306 1494 : DO iterm = 1, Nterms
307 996 : CALL section_vals_val_get(low_spin_roks_section, "SPIN_CONFIGURATION", i_rep_val=iterm, i_vals=ivec)
308 996 : CPASSERT(Nelectron == SIZE(ivec))
309 5976 : in_range = ALL(ivec >= 1) .AND. ALL(ivec <= 2)
310 996 : CPASSERT(in_range)
311 3486 : DO k = 1, Nelectron
312 2988 : occupations(ivec(k), k, iterm) = 1
313 : END DO
314 : END DO
315 :
316 : ! set up general data structures
317 : ! density matrices, kohn-sham matrices
318 :
319 498 : NULLIFY (matrix_p)
320 498 : CALL dbcsr_allocate_matrix_set(matrix_p, Nspin)
321 1494 : DO ispin = 1, Nspin
322 996 : ALLOCATE (matrix_p(ispin)%matrix)
323 : CALL dbcsr_copy(matrix_p(ispin)%matrix, rho_ao(1)%matrix, &
324 996 : name="density matrix low spin roks")
325 1494 : CALL dbcsr_set(matrix_p(ispin)%matrix, 0.0_dp)
326 : END DO
327 :
328 498 : NULLIFY (matrix_h)
329 498 : IF (.NOT. use_gauxc) THEN
330 466 : CALL dbcsr_allocate_matrix_set(matrix_h, Nspin)
331 1398 : DO ispin = 1, Nspin
332 932 : ALLOCATE (matrix_h(ispin)%matrix)
333 : CALL dbcsr_copy(matrix_h(ispin)%matrix, rho_ao(1)%matrix, &
334 932 : name="KS matrix low spin roks")
335 1398 : CALL dbcsr_set(matrix_h(ispin)%matrix, 0.0_dp)
336 : END DO
337 : END IF
338 :
339 498 : IF (do_hfx) THEN
340 250 : NULLIFY (matrix_hfx)
341 250 : CALL dbcsr_allocate_matrix_set(matrix_hfx, Nspin)
342 750 : DO ispin = 1, Nspin
343 500 : ALLOCATE (matrix_hfx(ispin)%matrix)
344 : CALL dbcsr_copy(matrix_hfx(ispin)%matrix, rho_ao(1)%matrix, &
345 750 : name="HFX matrix low spin roks")
346 : END DO
347 : END IF
348 :
349 : ! grids in real and g space for rho and vxc
350 : ! GAPW meta-GGAs need the kinetic-energy density of each configuration.
351 498 : NULLIFY (rho_r, rho_g, tau, tau_g, vxc_tau, vxc)
352 498 : CALL pw_env_get(pw_env, xc_pw_pool=xc_pw_pool)
353 :
354 498 : IF (.NOT. use_gauxc) THEN
355 1398 : ALLOCATE (rho_r(Nspin))
356 1398 : ALLOCATE (rho_g(Nspin))
357 626 : IF (compute_tau) ALLOCATE (tau(Nspin), tau_g(Nspin))
358 1398 : DO ispin = 1, Nspin
359 932 : CALL auxbas_pw_pool%create_pw(rho_r(ispin))
360 932 : CALL auxbas_pw_pool%create_pw(rho_g(ispin))
361 1398 : IF (compute_tau) THEN
362 80 : CALL auxbas_pw_pool%create_pw(tau(ispin))
363 80 : CALL auxbas_pw_pool%create_pw(tau_g(ispin))
364 : END IF
365 : END DO
366 466 : CALL auxbas_pw_pool%create_pw(work_v_rspace)
367 : END IF
368 :
369 : ! get mo matrices needed to construct the density matrices
370 : ! we will base all on the alpha spin matrix, obviously possible in ROKS
371 498 : CALL get_mo_set(mo_set=mo_array(1), mo_coeff_b=mo_coeff)
372 498 : NULLIFY (fm_scaled, fm_deriv)
373 498 : CALL dbcsr_init_p(fm_scaled)
374 498 : CALL dbcsr_init_p(fm_deriv)
375 498 : CALL dbcsr_copy(fm_scaled, mo_coeff)
376 498 : CALL dbcsr_copy(fm_deriv, mo_coeff)
377 :
378 1494 : ALLOCATE (scaling(k_alpha))
379 :
380 : ! for each term, add it with the given scaling factor to the energy, and compute the required derivatives
381 1494 : DO iterm = 1, Nterms
382 :
383 2988 : DO ispin = 1, Nspin
384 : ! compute the proper density matrices with the required occupations
385 1992 : CALL dbcsr_set(matrix_p(ispin)%matrix, 0.0_dp)
386 17024 : scaling = 1.0_dp
387 5976 : scaling(k_alpha - Nelectron + 1:k_alpha) = occupations(ispin, :, iterm)
388 1992 : CALL dbcsr_copy(fm_scaled, mo_coeff)
389 1992 : CALL dbcsr_scale_by_vector(fm_scaled, scaling, side='right')
390 : CALL dbcsr_multiply('n', 't', 1.0_dp, mo_coeff, fm_scaled, &
391 1992 : 0.0_dp, matrix_p(ispin)%matrix, retain_sparsity=.TRUE.)
392 2988 : IF (.NOT. use_gauxc) THEN
393 : ! compute the densities on the grid
394 : CALL calculate_rho_elec(matrix_p=matrix_p(ispin)%matrix, &
395 : rho=rho_r(ispin), rho_gspace=rho_g(ispin), &
396 1864 : ks_env=ks_env, soft_valid=gapw)
397 1864 : IF (compute_tau) THEN
398 : CALL calculate_rho_elec(matrix_p=matrix_p(ispin)%matrix, &
399 : rho=tau(ispin), rho_gspace=tau_g(ispin), &
400 160 : ks_env=ks_env, soft_valid=gapw, compute_tau=.TRUE.)
401 : END IF
402 : END IF
403 : END DO
404 :
405 996 : IF (gapw .AND. .NOT. use_gauxc) THEN
406 208 : CALL low_spin_roks_gapw_xc(qs_env, matrix_p, rho_atom_set, xc_section, just_energy, exc1)
407 208 : energy%exc1 = energy%exc1 + energy_scaling(iterm)*exc1
408 : END IF
409 :
410 : ! GauXC evaluates each configuration on the complete molecular AO density.
411 : ! Its matrix already contains all rho/gradient/tau/model-chain derivatives.
412 932 : IF (use_gauxc) THEN
413 64 : IF (ASSOCIATED(matrix_h)) CALL dbcsr_deallocate_matrix_set(matrix_h)
414 64 : matrix_p2(1:Nspin, 1:1) => matrix_p(1:Nspin)
415 : CALL apply_gauxc(qs_env, xc_section, .FALSE., rho_ao_external=matrix_p2, &
416 64 : exc_external=exc, matrix_vxc_external=matrix_h)
417 932 : ELSE IF (just_energy) THEN
418 : exc = xc_exc_calc(rho_r=rho_r, rho_g=rho_g, tau=tau, xc_section=xc_section, &
419 168 : weights=weights, pw_pool=xc_pw_pool)
420 : ELSE
421 764 : CPASSERT(.NOT. compute_virial)
422 : CALL xc_vxc_pw_create(vxc_rho=vxc, rho_r=rho_r, &
423 : rho_g=rho_g, tau=tau, vxc_tau=vxc_tau, exc=exc, xc_section=xc_section, &
424 : weights=weights, pw_pool=xc_pw_pool, &
425 764 : compute_virial=.FALSE., virial_xc=virial_xc_tmp)
426 : END IF
427 :
428 996 : energy%exc = energy%exc + energy_scaling(iterm)*exc
429 :
430 996 : IF (do_hfx) THEN
431 : ! Add Hartree-Fock contribution
432 1500 : DO ispin = 1, Nspin
433 1500 : CALL dbcsr_set(matrix_hfx(ispin)%matrix, 0.0_dp)
434 : END DO
435 500 : ehfx = energy%ex
436 : CALL tddft_hfx_matrix(matrix_hfx, matrix_p, qs_env, &
437 500 : recalc_integrals=.FALSE., update_energy=.TRUE.)
438 500 : energy%ex = ehfx + energy_scaling(iterm)*energy%ex
439 : END IF
440 :
441 : ! add the corresponding derivatives to the MO derivatives
442 1494 : IF (.NOT. just_energy) THEN
443 804 : IF (use_gauxc) THEN
444 120 : DO ispin = 1, Nspin
445 120 : CALL dbcsr_scale(matrix_h(ispin)%matrix, energy_scaling(iterm))
446 : END DO
447 : ELSE
448 : ! get the potential in matrix form
449 2292 : DO ispin = 1, Nspin
450 1528 : CALL dbcsr_set(matrix_h(ispin)%matrix, 0.0_dp)
451 : ! use a work_v_rspace
452 1528 : CALL pw_axpy(vxc(ispin), work_v_rspace, energy_scaling(iterm)*vxc(ispin)%pw_grid%dvol, 0.0_dp)
453 : CALL integrate_v_rspace(v_rspace=work_v_rspace, pmat=matrix_p(ispin), hmat=matrix_h(ispin), &
454 1528 : qs_env=qs_env, calculate_forces=calculate_forces, gapw=gapw)
455 1528 : CALL auxbas_pw_pool%give_back_pw(vxc(ispin))
456 2292 : IF (ASSOCIATED(vxc_tau)) THEN
457 : CALL pw_axpy(vxc_tau(ispin), work_v_rspace, &
458 96 : energy_scaling(iterm)*vxc_tau(ispin)%pw_grid%dvol, 0.0_dp)
459 : CALL integrate_v_rspace(v_rspace=work_v_rspace, pmat=matrix_p(ispin), hmat=matrix_h(ispin), &
460 96 : qs_env=qs_env, calculate_forces=.FALSE., gapw=gapw, compute_tau=.TRUE.)
461 96 : CALL auxbas_pw_pool%give_back_pw(vxc_tau(ispin))
462 : END IF
463 : END DO
464 764 : DEALLOCATE (vxc)
465 764 : IF (ASSOCIATED(vxc_tau)) DEALLOCATE (vxc_tau)
466 :
467 764 : IF (gapw) THEN
468 : CALL update_ks_atom(qs_env, matrix_h, matrix_p, .FALSE., &
469 128 : rho_atom_external=rho_atom_set, kscale=energy_scaling(iterm))
470 : END IF
471 : END IF
472 :
473 804 : IF (do_hfx) THEN
474 : ! add HFX contribution
475 1212 : DO ispin = 1, Nspin
476 : CALL dbcsr_add(matrix_h(ispin)%matrix, matrix_hfx(ispin)%matrix, &
477 1212 : 1.0_dp, energy_scaling(iterm))
478 : END DO
479 404 : IF (calculate_forces) THEN
480 8 : CALL get_qs_env(qs_env, x_data=x_data, para_env=para_env)
481 8 : IF (x_data(1, 1)%n_rep_hf /= 1) THEN
482 : CALL cp_abort(__LOCATION__, "Multiple HFX section forces not compatible "// &
483 0 : "with low spin ROKS method.")
484 : END IF
485 8 : IF (x_data(1, 1)%do_hfx_ri) THEN
486 0 : CALL cp_abort(__LOCATION__, "HFX_RI forces not compatible with low spin ROKS method.")
487 : ELSE
488 8 : irep = 1
489 8 : NULLIFY (mdummy)
490 8 : matrix_p2(1:Nspin, 1:1) => matrix_p(1:Nspin)
491 : CALL derivatives_four_center(qs_env, matrix_p2, mdummy, hfx_section, para_env, &
492 : irep, compute_virial, &
493 8 : adiabatic_rescale_factor=energy_scaling(iterm))
494 : END IF
495 : END IF
496 :
497 : END IF
498 :
499 : ! add this to the mo_derivs, again based on the alpha mo_coeff
500 2412 : DO ispin = 1, Nspin
501 : CALL dbcsr_multiply('n', 'n', 1.0_dp, matrix_h(ispin)%matrix, mo_coeff, &
502 1608 : 0.0_dp, dbcsr_deriv, last_column=k_alpha)
503 :
504 13536 : scaling = 1.0_dp
505 4824 : scaling(k_alpha - Nelectron + 1:k_alpha) = occupations(ispin, :, iterm)
506 1608 : CALL dbcsr_scale_by_vector(dbcsr_deriv, scaling, side='right')
507 2412 : CALL dbcsr_add(mo_derivs(1)%matrix, dbcsr_deriv, 1.0_dp, 1.0_dp)
508 : END DO
509 :
510 : END IF
511 :
512 : END DO
513 :
514 : ! release allocated memory
515 498 : IF (.NOT. use_gauxc) THEN
516 1398 : DO ispin = 1, Nspin
517 932 : CALL auxbas_pw_pool%give_back_pw(rho_r(ispin))
518 932 : CALL auxbas_pw_pool%give_back_pw(rho_g(ispin))
519 1398 : IF (compute_tau) THEN
520 80 : CALL auxbas_pw_pool%give_back_pw(tau(ispin))
521 80 : CALL auxbas_pw_pool%give_back_pw(tau_g(ispin))
522 : END IF
523 : END DO
524 466 : DEALLOCATE (rho_r, rho_g)
525 466 : IF (compute_tau) DEALLOCATE (tau, tau_g)
526 466 : CALL auxbas_pw_pool%give_back_pw(work_v_rspace)
527 : END IF
528 498 : CALL dbcsr_deallocate_matrix_set(matrix_p)
529 498 : IF (ASSOCIATED(matrix_h)) CALL dbcsr_deallocate_matrix_set(matrix_h)
530 498 : IF (do_hfx) THEN
531 250 : CALL dbcsr_deallocate_matrix_set(matrix_hfx)
532 : END IF
533 :
534 498 : CALL dbcsr_release_p(fm_deriv)
535 498 : CALL dbcsr_release_p(fm_scaled)
536 :
537 498 : DEALLOCATE (occupations)
538 498 : DEALLOCATE (energy_scaling)
539 498 : DEALLOCATE (scaling)
540 :
541 498 : CALL dbcsr_release_p(dbcsr_deriv)
542 :
543 498 : IF (ASSOCIATED(rho_atom_set)) CALL deallocate_rho_atom_set(rho_atom_set)
544 :
545 498 : CALL timestop(handle)
546 :
547 138651 : END SUBROUTINE low_spin_roks
548 :
549 : ! **************************************************************************************************
550 : !> \brief Evaluate the atomic XC correction for one low-spin ROKS configuration.
551 : !> Keep atomic densities and potential integrals separate from the reference
552 : !> state. All configurations share the total density, so no electrostatic
553 : !> correction or compensation-charge update is needed here.
554 : !> \param qs_env Quickstep environment
555 : !> \param matrix_p Spin density matrices of the configuration
556 : !> \param rho_atom_set Scratch atomic densities and XC potential integrals
557 : !> \param xc_section Exchange-correlation input
558 : !> \param just_energy Skip potential integrals when only the energy is requested
559 : !> \param exc1 Atomic hard-minus-soft XC energy
560 : ! **************************************************************************************************
561 208 : SUBROUTINE low_spin_roks_gapw_xc(qs_env, matrix_p, rho_atom_set, xc_section, just_energy, exc1)
562 : TYPE(qs_environment_type), POINTER :: qs_env
563 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_p
564 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho_atom_set
565 : TYPE(section_vals_type), POINTER :: xc_section
566 : LOGICAL, INTENT(IN) :: just_energy
567 : REAL(KIND=dp), INTENT(OUT) :: exc1
568 :
569 : INTEGER :: ikind, natom
570 208 : INTEGER, DIMENSION(:), POINTER :: atom_list
571 : LOGICAL :: paw_atom
572 : REAL(KIND=dp) :: hard_abs_spin, hard_spin, soft_abs_spin, &
573 : soft_spin
574 : REAL(KIND=dp), DIMENSION(2) :: hard_total, soft_total
575 208 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
576 208 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_p2
577 : TYPE(dft_control_type), POINTER :: dft_control
578 : TYPE(mp_para_env_type), POINTER :: para_env
579 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
580 208 : POINTER :: sab
581 : TYPE(oce_matrix_type), POINTER :: oce
582 208 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
583 :
584 : CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set, &
585 208 : dft_control=dft_control, para_env=para_env, oce=oce, sab_orb=sab)
586 208 : CPASSERT(dft_control%nspins == 2)
587 208 : CPASSERT(dft_control%nimages == 1)
588 208 : IF (.NOT. ASSOCIATED(rho_atom_set)) THEN
589 104 : CALL allocate_rho_atom_internals(rho_atom_set, atomic_kind_set, qs_kind_set, dft_control, para_env)
590 : END IF
591 208 : matrix_p2(1:2, 1:1) => matrix_p
592 208 : CALL calculate_rho_atom_coeff(qs_env, matrix_p2, rho_atom_set, qs_kind_set, oce, sab, para_env)
593 :
594 : ! Only local diagnostics: do not overwrite the reference charge summaries.
595 208 : hard_total = 0.0_dp
596 208 : soft_total = 0.0_dp
597 208 : hard_spin = 0.0_dp
598 208 : soft_spin = 0.0_dp
599 208 : hard_abs_spin = 0.0_dp
600 208 : soft_abs_spin = 0.0_dp
601 416 : DO ikind = 1, SIZE(atomic_kind_set)
602 208 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
603 208 : CALL get_qs_kind(qs_kind_set(ikind), paw_atom=paw_atom)
604 416 : IF (paw_atom) THEN
605 : CALL calculate_rho_atom(para_env, rho_atom_set, qs_kind_set(ikind), atom_list, natom, 2, &
606 208 : hard_total, soft_total, hard_spin, soft_spin, hard_abs_spin, soft_abs_spin)
607 : END IF
608 : END DO
609 208 : CALL zero_rho_atom_integrals(rho_atom_set)
610 208 : exc1 = 0.0_dp
611 : CALL calculate_vxc_atom(qs_env, just_energy, exc1, rho_atom_set_external=rho_atom_set, &
612 208 : xc_section_external=xc_section, calculate_forces=.FALSE.)
613 208 : END SUBROUTINE low_spin_roks_gapw_xc
614 :
615 : ! **************************************************************************************************
616 : !> \brief do sic calculations on explicit orbitals
617 : !> \param energy ...
618 : !> \param qs_env ...
619 : !> \param dft_control ...
620 : !> \param poisson_env ...
621 : !> \param just_energy ...
622 : !> \param calculate_forces ...
623 : !> \param auxbas_pw_pool ...
624 : ! **************************************************************************************************
625 136161 : SUBROUTINE sic_explicit_orbitals(energy, qs_env, dft_control, poisson_env, just_energy, &
626 : calculate_forces, auxbas_pw_pool)
627 :
628 : TYPE(qs_energy_type), POINTER :: energy
629 : TYPE(qs_environment_type), POINTER :: qs_env
630 : TYPE(dft_control_type), POINTER :: dft_control
631 : TYPE(pw_poisson_type), POINTER :: poisson_env
632 : LOGICAL, INTENT(IN) :: just_energy, calculate_forces
633 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
634 :
635 : CHARACTER(*), PARAMETER :: routineN = 'sic_explicit_orbitals'
636 :
637 : INTEGER :: handle, i, Iorb, k_alpha, k_beta, Norb
638 136161 : INTEGER, ALLOCATABLE, DIMENSION(:, :) :: sic_orbital_list
639 : LOGICAL :: compute_virial, uniform_occupation
640 : REAL(KIND=dp) :: ener, exc
641 : REAL(KIND=dp), DIMENSION(3, 3) :: virial_xc_tmp
642 : TYPE(cell_type), POINTER :: cell
643 : TYPE(cp_fm_struct_type), POINTER :: fm_struct_tmp
644 : TYPE(cp_fm_type) :: matrix_hv, matrix_v
645 136161 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: mo_derivs_local
646 : TYPE(cp_fm_type), POINTER :: mo_coeff
647 : TYPE(dbcsr_p_type) :: orb_density_matrix_p, orb_h_p
648 136161 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mo_derivs, rho_ao, tmp_dbcsr
649 : TYPE(dbcsr_type), POINTER :: orb_density_matrix, orb_h
650 136161 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mo_array
651 : TYPE(pw_c1d_gs_type) :: work_v_gspace
652 136161 : TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
653 : TYPE(pw_c1d_gs_type), TARGET :: orb_rho_g, tmp_g
654 : TYPE(pw_env_type), POINTER :: pw_env
655 : TYPE(pw_pool_type), POINTER :: xc_pw_pool
656 : TYPE(pw_r3d_rs_type) :: work_v_rspace
657 136161 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r, tau, vxc, vxc_tau
658 : TYPE(pw_r3d_rs_type), POINTER :: weights
659 : TYPE(pw_r3d_rs_type), TARGET :: orb_rho_r, tmp_r
660 : TYPE(qs_ks_env_type), POINTER :: ks_env
661 : TYPE(qs_rho_type), POINTER :: rho
662 : TYPE(section_vals_type), POINTER :: input, xc_section
663 : TYPE(virial_type), POINTER :: virial
664 :
665 136161 : IF (dft_control%sic_method_id /= sic_eo) RETURN
666 :
667 0 : CALL timeset(routineN, handle)
668 :
669 0 : NULLIFY (tau, vxc_tau, mo_derivs, ks_env, rho_ao)
670 :
671 : ! generate the lists of orbitals that need sic treatment
672 : CALL get_qs_env(qs_env, &
673 : ks_env=ks_env, &
674 : mo_derivs=mo_derivs, &
675 : mos=mo_array, &
676 : rho=rho, &
677 : xcint_weights=weights, &
678 : pw_env=pw_env, &
679 : input=input, &
680 : cell=cell, &
681 0 : virial=virial)
682 :
683 0 : CALL qs_rho_get(rho, rho_ao=rho_ao)
684 :
685 0 : compute_virial = virial%pv_calculate .AND. (.NOT. virial%pv_numer)
686 0 : xc_section => section_vals_get_subs_vals(input, "DFT%XC")
687 :
688 0 : DO i = 1, SIZE(mo_array) !fm->dbcsr
689 0 : IF (mo_array(i)%use_mo_coeff_b) THEN !fm->dbcsr
690 : CALL copy_dbcsr_to_fm(mo_array(i)%mo_coeff_b, &
691 0 : mo_array(i)%mo_coeff) !fm->dbcsr
692 : END IF !fm->dbcsr
693 : END DO !fm->dbcsr
694 :
695 0 : CALL pw_env_get(pw_env, xc_pw_pool=xc_pw_pool)
696 :
697 : ! we have two spins
698 0 : CPASSERT(SIZE(mo_array, 1) == 2)
699 : ! we want uniform occupations
700 0 : CALL get_mo_set(mo_set=mo_array(1), uniform_occupation=uniform_occupation)
701 0 : CPASSERT(uniform_occupation)
702 0 : CALL get_mo_set(mo_set=mo_array(2), mo_coeff=mo_coeff, uniform_occupation=uniform_occupation)
703 0 : CPASSERT(uniform_occupation)
704 :
705 0 : NULLIFY (tmp_dbcsr)
706 0 : CALL dbcsr_allocate_matrix_set(tmp_dbcsr, SIZE(mo_derivs, 1))
707 0 : DO i = 1, SIZE(mo_derivs, 1) !fm->dbcsr
708 : !
709 0 : NULLIFY (tmp_dbcsr(i)%matrix)
710 0 : CALL dbcsr_init_p(tmp_dbcsr(i)%matrix)
711 0 : CALL dbcsr_copy(tmp_dbcsr(i)%matrix, mo_derivs(i)%matrix)
712 0 : CALL dbcsr_set(tmp_dbcsr(i)%matrix, 0.0_dp)
713 : END DO !fm->dbcsr
714 :
715 0 : k_alpha = 0; k_beta = 0
716 0 : SELECT CASE (dft_control%sic_list_id)
717 : CASE (sic_list_all)
718 :
719 0 : CALL get_mo_set(mo_set=mo_array(1), mo_coeff=mo_coeff)
720 0 : CALL cp_fm_get_info(mo_coeff, ncol_global=k_alpha)
721 :
722 0 : IF (SIZE(mo_array, 1) > 1) THEN
723 0 : CALL get_mo_set(mo_set=mo_array(2), mo_coeff=mo_coeff)
724 0 : CALL cp_fm_get_info(mo_coeff, ncol_global=k_beta)
725 : END IF
726 :
727 0 : Norb = k_alpha + k_beta
728 0 : ALLOCATE (sic_orbital_list(3, Norb))
729 :
730 0 : iorb = 0
731 0 : DO i = 1, k_alpha
732 0 : iorb = iorb + 1
733 0 : sic_orbital_list(1, iorb) = 1
734 0 : sic_orbital_list(2, iorb) = i
735 0 : sic_orbital_list(3, iorb) = 1
736 : END DO
737 0 : DO i = 1, k_beta
738 0 : iorb = iorb + 1
739 0 : sic_orbital_list(1, iorb) = 2
740 0 : sic_orbital_list(2, iorb) = i
741 0 : IF (SIZE(mo_derivs, 1) == 1) THEN
742 0 : sic_orbital_list(3, iorb) = 1
743 : ELSE
744 0 : sic_orbital_list(3, iorb) = 2
745 : END IF
746 : END DO
747 :
748 : CASE (sic_list_unpaired)
749 : ! we have two spins
750 0 : CPASSERT(SIZE(mo_array, 1) == 2)
751 : ! we have them restricted
752 0 : CPASSERT(SIZE(mo_derivs, 1) == 1)
753 0 : CPASSERT(dft_control%restricted)
754 :
755 0 : CALL get_mo_set(mo_set=mo_array(1), mo_coeff=mo_coeff)
756 0 : CALL cp_fm_get_info(mo_coeff, ncol_global=k_alpha)
757 :
758 0 : CALL get_mo_set(mo_set=mo_array(2), mo_coeff=mo_coeff)
759 0 : CALL cp_fm_get_info(mo_coeff, ncol_global=k_beta)
760 :
761 0 : Norb = k_alpha - k_beta
762 0 : ALLOCATE (sic_orbital_list(3, Norb))
763 :
764 0 : iorb = 0
765 0 : DO i = k_beta + 1, k_alpha
766 0 : iorb = iorb + 1
767 0 : sic_orbital_list(1, iorb) = 1
768 0 : sic_orbital_list(2, iorb) = i
769 : ! we are guaranteed to be restricted
770 0 : sic_orbital_list(3, iorb) = 1
771 : END DO
772 :
773 : CASE DEFAULT
774 0 : CPABORT("Unknown dft_control%sic_list_id")
775 : END SELECT
776 :
777 : ! data needed for each of the orbs
778 0 : CALL auxbas_pw_pool%create_pw(orb_rho_r)
779 0 : CALL auxbas_pw_pool%create_pw(tmp_r)
780 0 : CALL auxbas_pw_pool%create_pw(orb_rho_g)
781 0 : CALL auxbas_pw_pool%create_pw(tmp_g)
782 0 : CALL auxbas_pw_pool%create_pw(work_v_gspace)
783 0 : CALL auxbas_pw_pool%create_pw(work_v_rspace)
784 :
785 0 : ALLOCATE (orb_density_matrix)
786 : CALL dbcsr_copy(orb_density_matrix, rho_ao(1)%matrix, &
787 0 : name="orb_density_matrix")
788 0 : CALL dbcsr_set(orb_density_matrix, 0.0_dp)
789 0 : orb_density_matrix_p%matrix => orb_density_matrix
790 :
791 0 : ALLOCATE (orb_h)
792 : CALL dbcsr_copy(orb_h, rho_ao(1)%matrix, &
793 0 : name="orb_density_matrix")
794 0 : CALL dbcsr_set(orb_h, 0.0_dp)
795 0 : orb_h_p%matrix => orb_h
796 :
797 0 : CALL get_mo_set(mo_set=mo_array(1), mo_coeff=mo_coeff)
798 :
799 : CALL cp_fm_struct_create(fm_struct_tmp, ncol_global=1, &
800 0 : template_fmstruct=mo_coeff%matrix_struct)
801 0 : CALL cp_fm_create(matrix_v, fm_struct_tmp, name="matrix_v")
802 0 : CALL cp_fm_create(matrix_hv, fm_struct_tmp, name="matrix_hv")
803 0 : CALL cp_fm_struct_release(fm_struct_tmp)
804 :
805 0 : ALLOCATE (mo_derivs_local(SIZE(mo_array, 1)))
806 0 : DO I = 1, SIZE(mo_array, 1)
807 0 : CALL get_mo_set(mo_set=mo_array(i), mo_coeff=mo_coeff)
808 0 : CALL cp_fm_create(mo_derivs_local(I), mo_coeff%matrix_struct)
809 : END DO
810 :
811 0 : ALLOCATE (rho_r(2))
812 0 : rho_r(1) = orb_rho_r
813 0 : rho_r(2) = tmp_r
814 0 : CALL pw_zero(tmp_r)
815 :
816 0 : ALLOCATE (rho_g(2))
817 0 : rho_g(1) = orb_rho_g
818 0 : rho_g(2) = tmp_g
819 0 : CALL pw_zero(tmp_g)
820 :
821 0 : NULLIFY (vxc)
822 : ! now apply to SIC correction to each selected orbital
823 0 : DO iorb = 1, Norb
824 : ! extract the proper orbital from the mo_coeff
825 0 : CALL get_mo_set(mo_set=mo_array(sic_orbital_list(1, iorb)), mo_coeff=mo_coeff)
826 0 : CALL cp_fm_to_fm(mo_coeff, matrix_v, 1, sic_orbital_list(2, iorb), 1)
827 :
828 : ! construct the density matrix and the corresponding density
829 0 : CALL dbcsr_set(orb_density_matrix, 0.0_dp)
830 : CALL cp_dbcsr_plus_fm_fm_t(orb_density_matrix, matrix_v=matrix_v, ncol=1, &
831 0 : alpha=1.0_dp)
832 :
833 : CALL calculate_rho_elec(matrix_p=orb_density_matrix, &
834 : rho=orb_rho_r, rho_gspace=orb_rho_g, &
835 0 : ks_env=ks_env)
836 :
837 : ! compute the energy functional for this orbital and its derivative
838 :
839 0 : CALL pw_poisson_solve(poisson_env, orb_rho_g, ener, work_v_gspace)
840 : ! no PBC correction is done here, see "calc_v_sic_rspace" for SIC methods
841 : ! with PBC aware corrections
842 0 : energy%hartree = energy%hartree - dft_control%sic_scaling_a*ener
843 0 : IF (.NOT. just_energy) THEN
844 0 : CALL pw_transfer(work_v_gspace, work_v_rspace)
845 0 : CALL pw_scale(work_v_rspace, -dft_control%sic_scaling_a*work_v_rspace%pw_grid%dvol)
846 0 : CALL dbcsr_set(orb_h, 0.0_dp)
847 : END IF
848 :
849 0 : IF (just_energy) THEN
850 : exc = xc_exc_calc(rho_r=rho_r, rho_g=rho_g, tau=tau, xc_section=xc_section, &
851 0 : weights=weights, pw_pool=xc_pw_pool)
852 : ELSE
853 0 : CPASSERT(.NOT. compute_virial)
854 : CALL xc_vxc_pw_create(vxc_rho=vxc, rho_r=rho_r, &
855 : rho_g=rho_g, tau=tau, vxc_tau=vxc_tau, exc=exc, xc_section=xc_section, &
856 : weights=weights, pw_pool=xc_pw_pool, &
857 0 : compute_virial=compute_virial, virial_xc=virial_xc_tmp)
858 : ! add to the existing work_v_rspace
859 0 : CALL pw_axpy(vxc(1), work_v_rspace, -dft_control%sic_scaling_b*vxc(1)%pw_grid%dvol)
860 : END IF
861 0 : energy%exc = energy%exc - dft_control%sic_scaling_b*exc
862 :
863 0 : IF (.NOT. just_energy) THEN
864 : ! note, orb_h (which is being pointed to with orb_h_p) is zeroed above
865 : CALL integrate_v_rspace(v_rspace=work_v_rspace, pmat=orb_density_matrix_p, hmat=orb_h_p, &
866 0 : qs_env=qs_env, calculate_forces=calculate_forces)
867 :
868 : ! add this to the mo_derivs
869 0 : CALL cp_dbcsr_sm_fm_multiply(orb_h, matrix_v, matrix_hv, 1)
870 : ! silly trick, copy to an array of the right size and add to mo_derivs
871 0 : CALL cp_fm_set_all(mo_derivs_local(sic_orbital_list(3, iorb)), 0.0_dp)
872 0 : CALL cp_fm_to_fm(matrix_hv, mo_derivs_local(sic_orbital_list(3, iorb)), 1, 1, sic_orbital_list(2, iorb))
873 : CALL copy_fm_to_dbcsr(mo_derivs_local(sic_orbital_list(3, iorb)), &
874 0 : tmp_dbcsr(sic_orbital_list(3, iorb))%matrix)
875 : CALL dbcsr_add(mo_derivs(sic_orbital_list(3, iorb))%matrix, &
876 0 : tmp_dbcsr(sic_orbital_list(3, iorb))%matrix, 1.0_dp, 1.0_dp)
877 : !
878 : ! need to deallocate vxc
879 0 : CALL xc_pw_pool%give_back_pw(vxc(1))
880 0 : CALL xc_pw_pool%give_back_pw(vxc(2))
881 0 : DEALLOCATE (vxc)
882 :
883 : END IF
884 :
885 : END DO
886 :
887 0 : CALL auxbas_pw_pool%give_back_pw(orb_rho_r)
888 0 : CALL auxbas_pw_pool%give_back_pw(tmp_r)
889 0 : CALL auxbas_pw_pool%give_back_pw(orb_rho_g)
890 0 : CALL auxbas_pw_pool%give_back_pw(tmp_g)
891 0 : CALL auxbas_pw_pool%give_back_pw(work_v_gspace)
892 0 : CALL auxbas_pw_pool%give_back_pw(work_v_rspace)
893 :
894 0 : CALL dbcsr_deallocate_matrix(orb_density_matrix)
895 0 : CALL dbcsr_deallocate_matrix(orb_h)
896 0 : CALL cp_fm_release(matrix_v)
897 0 : CALL cp_fm_release(matrix_hv)
898 0 : CALL cp_fm_release(mo_derivs_local)
899 0 : DEALLOCATE (rho_r)
900 0 : DEALLOCATE (rho_g)
901 :
902 0 : CALL dbcsr_deallocate_matrix_set(tmp_dbcsr) !fm->dbcsr
903 :
904 0 : CALL timestop(handle)
905 :
906 136161 : END SUBROUTINE sic_explicit_orbitals
907 :
908 : ! **************************************************************************************************
909 : !> \brief do sic calculations on the spin density
910 : !> \param v_sic_rspace ...
911 : !> \param energy ...
912 : !> \param qs_env ...
913 : !> \param dft_control ...
914 : !> \param rho ...
915 : !> \param poisson_env ...
916 : !> \param just_energy ...
917 : !> \param calculate_forces ...
918 : !> \param auxbas_pw_pool ...
919 : ! **************************************************************************************************
920 136161 : SUBROUTINE calc_v_sic_rspace(v_sic_rspace, energy, &
921 : qs_env, dft_control, rho, poisson_env, just_energy, &
922 : calculate_forces, auxbas_pw_pool)
923 :
924 : TYPE(pw_r3d_rs_type), POINTER :: v_sic_rspace
925 : TYPE(qs_energy_type), POINTER :: energy
926 : TYPE(qs_environment_type), POINTER :: qs_env
927 : TYPE(dft_control_type), POINTER :: dft_control
928 : TYPE(qs_rho_type), POINTER :: rho
929 : TYPE(pw_poisson_type), POINTER :: poisson_env
930 : LOGICAL, INTENT(IN) :: just_energy, calculate_forces
931 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
932 :
933 : INTEGER :: i, nelec, nelec_a, nelec_b, nforce
934 : REAL(kind=dp) :: ener, full_scaling, scaling
935 136161 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: store_forces
936 136161 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mo_array
937 : TYPE(pw_c1d_gs_type) :: work_rho, work_v
938 136161 : TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g
939 136161 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
940 :
941 136161 : NULLIFY (mo_array, rho_g)
942 :
943 136161 : IF (dft_control%sic_method_id == sic_none) RETURN
944 94 : IF (dft_control%sic_method_id == sic_eo) RETURN
945 :
946 94 : IF (dft_control%qs_control%gapw) THEN
947 0 : CPABORT("sic and GAPW not yet compatible")
948 : END IF
949 :
950 : ! OK, right now we like two spins to do sic, could be relaxed for AD
951 94 : CPASSERT(dft_control%nspins == 2)
952 :
953 94 : CALL auxbas_pw_pool%create_pw(work_rho)
954 94 : CALL auxbas_pw_pool%create_pw(work_v)
955 :
956 94 : CALL qs_rho_get(rho, rho_g=rho_g)
957 :
958 : ! Hartree sic corrections
959 188 : SELECT CASE (dft_control%sic_method_id)
960 : CASE (sic_mauri_us, sic_mauri_spz)
961 94 : CALL pw_copy(rho_g(1), work_rho)
962 94 : CALL pw_axpy(rho_g(2), work_rho, alpha=-1._dp)
963 94 : CALL pw_poisson_solve(poisson_env, work_rho, ener, work_v)
964 : CASE (sic_ad)
965 : ! find out how many elecs we have
966 0 : CALL get_qs_env(qs_env, mos=mo_array)
967 0 : CALL get_mo_set(mo_set=mo_array(1), nelectron=nelec_a)
968 0 : CALL get_mo_set(mo_set=mo_array(2), nelectron=nelec_b)
969 0 : nelec = nelec_a + nelec_b
970 0 : CALL pw_copy(rho_g(1), work_rho)
971 0 : CALL pw_axpy(rho_g(2), work_rho)
972 0 : scaling = 1.0_dp/REAL(nelec, KIND=dp)
973 0 : CALL pw_scale(work_rho, scaling)
974 0 : CALL pw_poisson_solve(poisson_env, work_rho, ener, work_v)
975 : CASE DEFAULT
976 188 : CPABORT("Unknown sic method id")
977 : END SELECT
978 :
979 : ! Correct for DDAP charges (if any)
980 : ! storing whatever force might be there from previous decoupling
981 94 : IF (calculate_forces) THEN
982 12 : CALL get_qs_env(qs_env=qs_env, force=force)
983 12 : nforce = 0
984 36 : DO i = 1, SIZE(force)
985 36 : nforce = nforce + SIZE(force(i)%ch_pulay, 2)
986 : END DO
987 36 : ALLOCATE (store_forces(3, nforce))
988 36 : nforce = 0
989 36 : DO i = 1, SIZE(force)
990 312 : store_forces(1:3, nforce + 1:nforce + SIZE(force(i)%ch_pulay, 2)) = force(i)%ch_pulay(:, :)
991 312 : force(i)%ch_pulay(:, :) = 0.0_dp
992 36 : nforce = nforce + SIZE(force(i)%ch_pulay, 2)
993 : END DO
994 : END IF
995 :
996 : CALL cp_ddapc_apply_CD(qs_env, &
997 : work_rho, &
998 : ener, &
999 : v_hartree_gspace=work_v, &
1000 : calculate_forces=calculate_forces, &
1001 94 : Itype_of_density="SPIN")
1002 :
1003 188 : SELECT CASE (dft_control%sic_method_id)
1004 : CASE (sic_mauri_us, sic_mauri_spz)
1005 94 : full_scaling = -dft_control%sic_scaling_a
1006 : CASE (sic_ad)
1007 0 : full_scaling = -dft_control%sic_scaling_a*nelec
1008 : CASE DEFAULT
1009 94 : CPABORT("Unknown sic method id")
1010 : END SELECT
1011 94 : energy%hartree = energy%hartree + full_scaling*ener
1012 :
1013 : ! add scaled forces, restoring the old
1014 94 : IF (calculate_forces) THEN
1015 12 : nforce = 0
1016 36 : DO i = 1, SIZE(force)
1017 : force(i)%ch_pulay(:, :) = force(i)%ch_pulay(:, :)*full_scaling + &
1018 312 : store_forces(1:3, nforce + 1:nforce + SIZE(force(i)%ch_pulay, 2))
1019 36 : nforce = nforce + SIZE(force(i)%ch_pulay, 2)
1020 : END DO
1021 : END IF
1022 :
1023 94 : IF (.NOT. just_energy) THEN
1024 60 : ALLOCATE (v_sic_rspace)
1025 60 : CALL auxbas_pw_pool%create_pw(v_sic_rspace)
1026 60 : CALL pw_transfer(work_v, v_sic_rspace)
1027 : ! also take into account the scaling (in addition to the volume element)
1028 : CALL pw_scale(v_sic_rspace, &
1029 60 : dft_control%sic_scaling_a*v_sic_rspace%pw_grid%dvol)
1030 : END IF
1031 :
1032 94 : CALL auxbas_pw_pool%give_back_pw(work_rho)
1033 94 : CALL auxbas_pw_pool%give_back_pw(work_v)
1034 :
1035 136255 : END SUBROUTINE calc_v_sic_rspace
1036 :
1037 : ! **************************************************************************************************
1038 : !> \brief Check each term of the energy and sum to total
1039 : !> \param energy ...
1040 : ! **************************************************************************************************
1041 136095 : SUBROUTINE check_sum_energies(energy)
1042 : TYPE(qs_energy_type), INTENT(INOUT), POINTER :: energy
1043 :
1044 : ! Reset the total energy counter, just in case
1045 : ! it is used to store some intermediate value
1046 136095 : energy%total = 0.0_dp
1047 :
1048 136095 : CALL check_sum_energy(energy%total, energy%core_overlap, "Core overlap energy")
1049 136095 : CALL check_sum_energy(energy%total, energy%core_self, "Core self energy")
1050 136095 : CALL check_sum_energy(energy%total, energy%core_cneo, "Quantum nuclear core energy")
1051 136095 : CALL check_sum_energy(energy%total, energy%core, "Core Hamiltonian energy")
1052 136095 : CALL check_sum_energy(energy%total, energy%hartree, "Hartree energy")
1053 136095 : CALL check_sum_energy(energy%total, energy%hartree_1c, "Energy from GAPW local Eh = 1 center integrals")
1054 136095 : CALL check_sum_energy(energy%total, energy%exc, "Exchange-correlation energy")
1055 136095 : CALL check_sum_energy(energy%total, energy%exc1, "Exc1 energy")
1056 136095 : CALL check_sum_energy(energy%total, energy%ex, "Ex energy")
1057 136095 : CALL check_sum_energy(energy%total, energy%dispersion, "Dispersion energy")
1058 136095 : CALL check_sum_energy(energy%total, energy%gcp, "gCP energy")
1059 136095 : CALL check_sum_energy(energy%total, energy%qmmm_el, "QM/MM Electrostatic energy")
1060 136095 : CALL check_sum_energy(energy%total, energy%mulliken, "Mulliken restraint energy")
1061 272294 : CALL check_sum_energy(energy%total, SUM(energy%ddapc_restraint), "DDAPC restraint energy")
1062 136095 : CALL check_sum_energy(energy%total, energy%s2_restraint, "S2 restraint energy")
1063 136095 : CALL check_sum_energy(energy%total, energy%dft_plus_u, "DFT+U energy")
1064 136095 : CALL check_sum_energy(energy%total, energy%kTS, "Electronic entropic contribution energy")
1065 136095 : CALL check_sum_energy(energy%total, energy%efield, "Electric field interaction energy")
1066 136095 : CALL check_sum_energy(energy%total, energy%efield_core, "Electric field core interaction energy")
1067 136095 : CALL check_sum_energy(energy%total, energy%ee, "External potential interaction energy")
1068 136095 : CALL check_sum_energy(energy%total, energy%ee_core, "External potential core interaction energy")
1069 136095 : CALL check_sum_energy(energy%total, energy%exc_aux_fit, "Wfn fit exchange-correlation energy")
1070 136095 : CALL check_sum_energy(energy%total, energy%image_charge, "QM/MM image charge energy energy")
1071 136095 : CALL check_sum_energy(energy%total, energy%sccs_pol, "SCCS polarisation energy")
1072 136095 : CALL check_sum_energy(energy%total, energy%cdft, "CDFT constraint energy")
1073 136095 : CALL check_sum_energy(energy%total, energy%exc1_aux_fit, "Wfn fit soft/hard atomic rho1 Exc contribution energy")
1074 136095 : CALL check_sum_energy(energy%total, energy%embed_corr, "Embedding potential correction energy")
1075 :
1076 136095 : IF (abnormal_value(energy%total)) THEN
1077 : CALL cp_abort(__LOCATION__, &
1078 0 : "Total energy after summing up the terms is an abnormal value (NaN/Inf).")
1079 : END IF
1080 :
1081 136095 : END SUBROUTINE check_sum_energies
1082 :
1083 : ! **************************************************************************************************
1084 : !> \brief Check one term of the energy and sum to total if normal
1085 : !> \param total ...
1086 : !> \param term ...
1087 : !> \param name ...
1088 : ! **************************************************************************************************
1089 3674565 : SUBROUTINE check_sum_energy(total, term, name)
1090 : REAL(KIND=dp), INTENT(INOUT) :: total
1091 : REAL(KIND=dp), INTENT(IN) :: term
1092 : CHARACTER(LEN=*), INTENT(IN) :: name
1093 :
1094 3674565 : IF (abnormal_value(term)) THEN
1095 : CALL cp_abort(__LOCATION__, &
1096 0 : TRIM(name)//" is an abnormal value (NaN/Inf).")
1097 : ELSE
1098 3674565 : total = total + term
1099 : END IF
1100 :
1101 3674565 : END SUBROUTINE check_sum_energy
1102 :
1103 : ! **************************************************************************************************
1104 : !> \brief ...
1105 : !> \param qs_env ...
1106 : !> \param rho ...
1107 : ! **************************************************************************************************
1108 272210 : SUBROUTINE print_densities(qs_env, rho)
1109 : TYPE(qs_environment_type), POINTER :: qs_env
1110 : TYPE(qs_rho_type), POINTER :: rho
1111 :
1112 : INTEGER :: img, ispin, n_electrons, output_unit
1113 : REAL(dp) :: tot1_h, tot1_s, tot_rho_r, trace, &
1114 : trace_tmp
1115 136105 : REAL(KIND=dp), DIMENSION(:), POINTER :: tot_rho_r_arr
1116 : TYPE(cell_type), POINTER :: cell
1117 : TYPE(cp_logger_type), POINTER :: logger
1118 136105 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_s, rho_ao
1119 : TYPE(dft_control_type), POINTER :: dft_control
1120 : TYPE(qs_charges_type), POINTER :: qs_charges
1121 136105 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1122 : TYPE(section_vals_type), POINTER :: input, scf_section
1123 :
1124 136105 : NULLIFY (qs_charges, qs_kind_set, cell, input, logger, scf_section, matrix_s, &
1125 136105 : dft_control, tot_rho_r_arr, rho_ao)
1126 :
1127 272210 : logger => cp_get_default_logger()
1128 :
1129 : CALL get_qs_env(qs_env, &
1130 : qs_kind_set=qs_kind_set, &
1131 : cell=cell, qs_charges=qs_charges, &
1132 : input=input, &
1133 : matrix_s_kp=matrix_s, &
1134 136105 : dft_control=dft_control)
1135 :
1136 136105 : CALL get_qs_kind_set(qs_kind_set, nelectron=n_electrons)
1137 :
1138 136105 : scf_section => section_vals_get_subs_vals(input, "DFT%SCF")
1139 : output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%TOTAL_DENSITIES", &
1140 136105 : extension=".scfLog")
1141 :
1142 136105 : CALL qs_rho_get(rho, tot_rho_r=tot_rho_r_arr, rho_ao_kp=rho_ao)
1143 136105 : n_electrons = n_electrons - dft_control%charge
1144 136105 : tot_rho_r = accurate_sum(tot_rho_r_arr)
1145 :
1146 136105 : trace = 0
1147 136105 : IF (BTEST(cp_print_key_should_output(logger%iter_info, scf_section, "PRINT%TOTAL_DENSITIES"), cp_p_file)) THEN
1148 4154 : DO ispin = 1, dft_control%nspins
1149 7526 : DO img = 1, dft_control%nimages
1150 3372 : CALL dbcsr_dot(rho_ao(ispin, img)%matrix, matrix_s(1, img)%matrix, trace_tmp)
1151 5848 : trace = trace + trace_tmp
1152 : END DO
1153 : END DO
1154 : END IF
1155 :
1156 136105 : IF (output_unit > 0) THEN
1157 839 : WRITE (UNIT=output_unit, FMT="(/,T3,A,T41,F20.10)") "Trace(PS):", trace
1158 : WRITE (UNIT=output_unit, FMT="((T3,A,T41,2F20.10))") &
1159 839 : "Electronic density on regular grids: ", &
1160 839 : tot_rho_r, &
1161 : tot_rho_r + &
1162 839 : REAL(n_electrons, dp), &
1163 839 : "Core density on regular grids:", &
1164 839 : qs_charges%total_rho_core_rspace, &
1165 : qs_charges%total_rho_core_rspace + &
1166 : qs_charges%total_rho1_hard_nuc - &
1167 1678 : REAL(n_electrons + dft_control%charge, dp)
1168 : END IF
1169 136105 : IF (dft_control%qs_control%gapw) THEN
1170 23922 : tot1_h = qs_charges%total_rho1_hard(1)
1171 23922 : tot1_s = qs_charges%total_rho1_soft(1)
1172 28278 : DO ispin = 2, dft_control%nspins
1173 4356 : tot1_h = tot1_h + qs_charges%total_rho1_hard(ispin)
1174 28278 : tot1_s = tot1_s + qs_charges%total_rho1_soft(ispin)
1175 : END DO
1176 23922 : IF (output_unit > 0) THEN
1177 : WRITE (UNIT=output_unit, FMT="((T3,A,T41,2F20.10))") &
1178 399 : "Hard and soft densities (Lebedev):", &
1179 798 : tot1_h, tot1_s
1180 : WRITE (UNIT=output_unit, FMT="(T3,A,T41,F20.10)") &
1181 399 : "Total Rho_soft + Rho1_hard - Rho1_soft (r-space): ", &
1182 399 : tot_rho_r + tot1_h - tot1_s, &
1183 399 : "Total charge density (r-space): ", &
1184 : tot_rho_r + tot1_h - tot1_s &
1185 : + qs_charges%total_rho_core_rspace &
1186 798 : + qs_charges%total_rho1_hard_nuc
1187 399 : IF (qs_charges%total_rho1_hard_nuc /= 0.0_dp) THEN
1188 : WRITE (UNIT=output_unit, FMT="(T3,A,T41,F20.10)") &
1189 0 : "Total CNEO nuc. char. den. (Lebedev): ", &
1190 0 : qs_charges%total_rho1_hard_nuc, &
1191 0 : "Total CNEO soft char. den. (Lebedev): ", &
1192 0 : qs_charges%total_rho1_soft_nuc_lebedev, &
1193 0 : "Total CNEO soft char. den. (r-space): ", &
1194 0 : qs_charges%total_rho1_soft_nuc_rspace, &
1195 0 : "Total soft Rho_e+n+0 (g-space):", &
1196 0 : qs_charges%total_rho_gspace
1197 : ELSE
1198 : WRITE (UNIT=output_unit, FMT="(T3,A,T41,F20.10)") &
1199 399 : "Total Rho_soft + Rho0_soft (g-space):", &
1200 798 : qs_charges%total_rho_gspace
1201 : END IF
1202 : END IF
1203 : qs_charges%background = tot_rho_r + tot1_h - tot1_s + &
1204 : qs_charges%total_rho_core_rspace + &
1205 23922 : qs_charges%total_rho1_hard_nuc
1206 : ! only add total_rho1_hard_nuc for gapw as cneo requires gapw
1207 112183 : ELSE IF (dft_control%qs_control%gapw_xc) THEN
1208 4448 : tot1_h = qs_charges%total_rho1_hard(1)
1209 4448 : tot1_s = qs_charges%total_rho1_soft(1)
1210 4826 : DO ispin = 2, dft_control%nspins
1211 378 : tot1_h = tot1_h + qs_charges%total_rho1_hard(ispin)
1212 4826 : tot1_s = tot1_s + qs_charges%total_rho1_soft(ispin)
1213 : END DO
1214 4448 : IF (output_unit > 0) THEN
1215 : WRITE (UNIT=output_unit, FMT="(/,(T3,A,T41,2F20.10))") &
1216 0 : "Hard and soft densities (Lebedev):", &
1217 0 : tot1_h, tot1_s
1218 : WRITE (UNIT=output_unit, FMT="(T3,A,T41,F20.10)") &
1219 0 : "Total Rho_soft + Rho1_hard - Rho1_soft (r-space): ", &
1220 0 : accurate_sum(tot_rho_r_arr) + tot1_h - tot1_s
1221 : END IF
1222 : qs_charges%background = tot_rho_r + &
1223 4448 : qs_charges%total_rho_core_rspace
1224 : ELSE
1225 107735 : IF (output_unit > 0) THEN
1226 : WRITE (UNIT=output_unit, FMT="(T3,A,T41,F20.10)") &
1227 440 : "Total charge density on r-space grids: ", &
1228 : tot_rho_r + &
1229 440 : qs_charges%total_rho_core_rspace, &
1230 440 : "Total charge density g-space grids: ", &
1231 880 : qs_charges%total_rho_gspace
1232 : END IF
1233 : qs_charges%background = tot_rho_r + &
1234 107735 : qs_charges%total_rho_core_rspace
1235 : END IF
1236 136105 : IF (output_unit > 0) WRITE (UNIT=output_unit, FMT="()")
1237 136105 : qs_charges%background = qs_charges%background/cell%deth
1238 :
1239 : CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
1240 136105 : "PRINT%TOTAL_DENSITIES")
1241 :
1242 136105 : END SUBROUTINE print_densities
1243 :
1244 : ! **************************************************************************************************
1245 : !> \brief Print detailed energies
1246 : !>
1247 : !> \param qs_env ...
1248 : !> \param dft_control ...
1249 : !> \param input ...
1250 : !> \param energy ...
1251 : !> \param mulliken_order_p ...
1252 : !> \par History
1253 : !> refactoring 04.03.2011 [MI]
1254 : !> \author
1255 : ! **************************************************************************************************
1256 136105 : SUBROUTINE print_detailed_energy(qs_env, dft_control, input, energy, mulliken_order_p)
1257 :
1258 : TYPE(qs_environment_type), POINTER :: qs_env
1259 : TYPE(dft_control_type), POINTER :: dft_control
1260 : TYPE(section_vals_type), POINTER :: input
1261 : TYPE(qs_energy_type), POINTER :: energy
1262 : REAL(KIND=dp), INTENT(IN) :: mulliken_order_p
1263 :
1264 : INTEGER :: bc, n, output_unit, psolver
1265 : REAL(KIND=dp) :: ddapc_order_p, implicit_ps_ehartree, &
1266 : s2_order_p
1267 : TYPE(cp_logger_type), POINTER :: logger
1268 : TYPE(pw_env_type), POINTER :: pw_env
1269 :
1270 136105 : logger => cp_get_default_logger()
1271 :
1272 136105 : NULLIFY (pw_env)
1273 136105 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
1274 136105 : psolver = pw_env%poisson_env%parameters%solver
1275 :
1276 : output_unit = cp_print_key_unit_nr(logger, input, "DFT%SCF%PRINT%DETAILED_ENERGY", &
1277 136105 : extension=".scfLog")
1278 136105 : IF (output_unit > 0) THEN
1279 492 : IF (dft_control%do_admm) THEN
1280 : WRITE (UNIT=output_unit, FMT="((T3,A,T60,F20.10))") &
1281 0 : "Wfn fit exchange-correlation energy: ", energy%exc_aux_fit
1282 0 : IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
1283 : WRITE (UNIT=output_unit, FMT="((T3,A,T60,F20.10))") &
1284 0 : "Wfn fit soft/hard atomic rho1 Exc contribution: ", energy%exc1_aux_fit
1285 : END IF
1286 : END IF
1287 492 : IF (dft_control%do_admm) THEN
1288 0 : IF (psolver == pw_poisson_implicit) THEN
1289 0 : implicit_ps_ehartree = pw_env%poisson_env%implicit_env%ehartree
1290 0 : bc = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
1291 0 : SELECT CASE (bc)
1292 : CASE (MIXED_PERIODIC_BC, MIXED_BC)
1293 : WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
1294 0 : "Core Hamiltonian energy: ", energy%core, &
1295 0 : "Hartree energy: ", implicit_ps_ehartree, &
1296 0 : "Electric enthalpy: ", energy%hartree, &
1297 0 : "Exchange-correlation energy: ", energy%exc + energy%exc_aux_fit
1298 : CASE (PERIODIC_BC, NEUMANN_BC)
1299 : WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
1300 0 : "Core Hamiltonian energy: ", energy%core, &
1301 0 : "Hartree energy: ", energy%hartree, &
1302 0 : "Exchange-correlation energy: ", energy%exc + energy%exc_aux_fit
1303 : END SELECT
1304 : ELSE
1305 : WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
1306 0 : "Core Hamiltonian energy: ", energy%core, &
1307 0 : "Hartree energy: ", energy%hartree, &
1308 0 : "Exchange-correlation energy: ", energy%exc + energy%exc_aux_fit
1309 : END IF
1310 : ELSE
1311 : !ZMP to print some variables at each step
1312 492 : IF (dft_control%apply_external_density) THEN
1313 : WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
1314 0 : "DOING ZMP CALCULATION FROM EXTERNAL DENSITY "
1315 : WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
1316 0 : "Core Hamiltonian energy: ", energy%core, &
1317 0 : "Hartree energy: ", energy%hartree
1318 492 : ELSE IF (dft_control%apply_external_vxc) THEN
1319 : WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
1320 0 : "DOING ZMP READING EXTERNAL VXC "
1321 : WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
1322 0 : "Core Hamiltonian energy: ", energy%core, &
1323 0 : "Hartree energy: ", energy%hartree
1324 : ELSE
1325 492 : IF (psolver == pw_poisson_implicit) THEN
1326 0 : implicit_ps_ehartree = pw_env%poisson_env%implicit_env%ehartree
1327 0 : bc = pw_env%poisson_env%parameters%ps_implicit_params%boundary_condition
1328 0 : SELECT CASE (bc)
1329 : CASE (MIXED_PERIODIC_BC, MIXED_BC)
1330 : WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
1331 0 : "Core Hamiltonian energy: ", energy%core, &
1332 0 : "Hartree energy: ", implicit_ps_ehartree, &
1333 0 : "Electric enthalpy: ", energy%hartree, &
1334 0 : "Exchange-correlation energy: ", energy%exc
1335 : CASE (PERIODIC_BC, NEUMANN_BC)
1336 : WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
1337 0 : "Core Hamiltonian energy: ", energy%core, &
1338 0 : "Hartree energy: ", energy%hartree, &
1339 0 : "Exchange-correlation energy: ", energy%exc
1340 : END SELECT
1341 : ELSE
1342 : WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
1343 492 : "Core Hamiltonian energy: ", energy%core, &
1344 492 : "Hartree energy: ", energy%hartree, &
1345 984 : "Exchange-correlation energy: ", energy%exc
1346 : END IF
1347 : END IF
1348 : END IF
1349 :
1350 492 : IF (dft_control%apply_external_density) THEN
1351 : WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
1352 0 : "Integral of the (density * v_xc): ", energy%exc
1353 : END IF
1354 :
1355 492 : IF (energy%e_hartree /= 0.0_dp) THEN
1356 : WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
1357 460 : "Coulomb (electron-electron) energy: ", energy%e_hartree
1358 : END IF
1359 492 : IF (energy%dispersion /= 0.0_dp) THEN
1360 : WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
1361 0 : "Dispersion energy: ", energy%dispersion
1362 : END IF
1363 492 : IF (energy%efield /= 0.0_dp) THEN
1364 : WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
1365 0 : "Electric field interaction energy: ", energy%efield
1366 : END IF
1367 492 : IF (energy%gcp /= 0.0_dp) THEN
1368 : WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
1369 0 : "gCP energy: ", energy%gcp
1370 : END IF
1371 492 : IF (dft_control%qs_control%gapw) THEN
1372 : WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
1373 32 : "GAPW| Exc from hard and soft atomic rho1: ", energy%exc1 + energy%exc1_aux_fit, &
1374 64 : "GAPW| local Eh = 1 center integrals: ", energy%hartree_1c
1375 : END IF
1376 492 : IF (dft_control%qs_control%gapw_xc) THEN
1377 : WRITE (UNIT=output_unit, FMT="(/,(T3,A,T61,F20.10))") &
1378 0 : "GAPW| Exc from hard and soft atomic rho1: ", energy%exc1 + energy%exc1_aux_fit
1379 : END IF
1380 492 : IF (dft_control%dft_plus_u) THEN
1381 : WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
1382 0 : "DFT+U energy:", energy%dft_plus_u
1383 : END IF
1384 492 : IF (qs_env%qmmm) THEN
1385 : WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
1386 0 : "QM/MM Electrostatic energy: ", energy%qmmm_el
1387 0 : IF (qs_env%qmmm_env_qm%image_charge) THEN
1388 : WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
1389 0 : "QM/MM image charge energy: ", energy%image_charge
1390 : END IF
1391 : END IF
1392 492 : IF (dft_control%qs_control%mulliken_restraint) THEN
1393 : WRITE (UNIT=output_unit, FMT="(T3,A,T41,2F20.10)") &
1394 0 : "Mulliken restraint (order_p,energy) : ", mulliken_order_p, energy%mulliken
1395 : END IF
1396 492 : IF (dft_control%qs_control%ddapc_restraint) THEN
1397 40 : DO n = 1, SIZE(dft_control%qs_control%ddapc_restraint_control)
1398 : ddapc_order_p = &
1399 20 : dft_control%qs_control%ddapc_restraint_control(n)%ddapc_order_p
1400 : WRITE (UNIT=output_unit, FMT="(T3,A,T41,2F20.10)") &
1401 40 : "DDAPC restraint (order_p,energy) : ", ddapc_order_p, energy%ddapc_restraint(n)
1402 : END DO
1403 : END IF
1404 492 : IF (dft_control%qs_control%s2_restraint) THEN
1405 0 : s2_order_p = dft_control%qs_control%s2_restraint_control%s2_order_p
1406 : WRITE (UNIT=output_unit, FMT="(T3,A,T41,2F20.10)") &
1407 0 : "S2 restraint (order_p,energy) : ", s2_order_p, energy%s2_restraint
1408 : END IF
1409 492 : IF (energy%core_cneo /= 0.0_dp) THEN
1410 : WRITE (UNIT=output_unit, FMT="(T3,A,T61,F20.10)") &
1411 0 : "CNEO| quantum nuclear core energy: ", energy%core_cneo
1412 : END IF
1413 :
1414 : END IF ! output_unit
1415 : CALL cp_print_key_finished_output(output_unit, logger, input, &
1416 136105 : "DFT%SCF%PRINT%DETAILED_ENERGY")
1417 :
1418 136105 : END SUBROUTINE print_detailed_energy
1419 :
1420 : ! **************************************************************************************************
1421 : !> \brief compute matrix_vxc, defined via the potential created by qs_vxc_create
1422 : !> ignores things like tau functional, gapw, sic, ...
1423 : !> so only OK for GGA & GPW right now
1424 : !> \param qs_env ...
1425 : !> \param v_rspace ...
1426 : !> \param matrix_vxc ...
1427 : !> \param gapw_full_basis ...
1428 : !> \par History
1429 : !> created 23.10.2012 [Joost VandeVondele]
1430 : !> \author
1431 : ! **************************************************************************************************
1432 10 : SUBROUTINE compute_matrix_vxc(qs_env, v_rspace, matrix_vxc, gapw_full_basis)
1433 : TYPE(qs_environment_type), POINTER :: qs_env
1434 : TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(IN) :: v_rspace
1435 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_vxc
1436 : LOGICAL, INTENT(IN), OPTIONAL :: gapw_full_basis
1437 :
1438 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_matrix_vxc'
1439 :
1440 : INTEGER :: handle, ispin
1441 : LOGICAL :: gapw
1442 10 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks
1443 : TYPE(dft_control_type), POINTER :: dft_control
1444 :
1445 10 : CALL timeset(routineN, handle)
1446 :
1447 : ! create the matrix using matrix_ks as a template
1448 10 : IF (ASSOCIATED(matrix_vxc)) THEN
1449 0 : CALL dbcsr_deallocate_matrix_set(matrix_vxc)
1450 : END IF
1451 10 : CALL get_qs_env(qs_env, matrix_ks=matrix_ks)
1452 44 : ALLOCATE (matrix_vxc(SIZE(matrix_ks)))
1453 24 : DO ispin = 1, SIZE(matrix_ks)
1454 14 : NULLIFY (matrix_vxc(ispin)%matrix)
1455 14 : CALL dbcsr_init_p(matrix_vxc(ispin)%matrix)
1456 : CALL dbcsr_copy(matrix_vxc(ispin)%matrix, matrix_ks(ispin)%matrix, &
1457 14 : name="Matrix VXC of spin "//cp_to_string(ispin))
1458 24 : CALL dbcsr_set(matrix_vxc(ispin)%matrix, 0.0_dp)
1459 : END DO
1460 :
1461 : ! and integrate
1462 10 : CALL get_qs_env(qs_env, dft_control=dft_control)
1463 10 : gapw = dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc
1464 10 : IF (PRESENT(gapw_full_basis)) THEN
1465 0 : IF (gapw_full_basis) gapw = .FALSE.
1466 : END IF
1467 24 : DO ispin = 1, SIZE(matrix_ks)
1468 : CALL integrate_v_rspace(v_rspace=v_rspace(ispin), &
1469 : hmat=matrix_vxc(ispin), &
1470 : qs_env=qs_env, &
1471 : calculate_forces=.FALSE., &
1472 14 : gapw=gapw)
1473 : ! scale by the volume element... should really become part of integrate_v_rspace
1474 24 : CALL dbcsr_scale(matrix_vxc(ispin)%matrix, v_rspace(ispin)%pw_grid%dvol)
1475 : END DO
1476 :
1477 10 : CALL timestop(handle)
1478 :
1479 10 : END SUBROUTINE compute_matrix_vxc
1480 :
1481 : ! **************************************************************************************************
1482 : !> \brief Build the XC potential matrix for k-point/image-resolved KS matrices.
1483 : !> \param qs_env Quickstep environment
1484 : !> \param v_rspace XC potential on the real-space grid
1485 : !> \param matrix_vxc_kp k-point/image-resolved XC potential matrix
1486 : !> \param gapw_full_basis ...
1487 : !> \author
1488 : ! **************************************************************************************************
1489 0 : SUBROUTINE compute_matrix_vxc_kp(qs_env, v_rspace, matrix_vxc_kp, gapw_full_basis)
1490 : TYPE(qs_environment_type), POINTER :: qs_env
1491 : TYPE(pw_r3d_rs_type), DIMENSION(:), INTENT(IN) :: v_rspace
1492 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_vxc_kp
1493 : LOGICAL, INTENT(IN), OPTIONAL :: gapw_full_basis
1494 :
1495 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_matrix_vxc_kp'
1496 :
1497 : INTEGER :: handle, img, ispin
1498 : LOGICAL :: gapw
1499 0 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ksmat
1500 0 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks_kp
1501 : TYPE(dft_control_type), POINTER :: dft_control
1502 :
1503 0 : CALL timeset(routineN, handle)
1504 :
1505 : ! create the matrix using matrix_ks as a template
1506 0 : IF (ASSOCIATED(matrix_vxc_kp)) THEN
1507 0 : CALL dbcsr_deallocate_matrix_set(matrix_vxc_kp)
1508 : END IF
1509 0 : CALL get_qs_env(qs_env, dft_control=dft_control, matrix_ks_kp=matrix_ks_kp)
1510 0 : ALLOCATE (matrix_vxc_kp(SIZE(matrix_ks_kp, 1), SIZE(matrix_ks_kp, 2)))
1511 0 : DO img = 1, SIZE(matrix_ks_kp, 2)
1512 0 : DO ispin = 1, SIZE(matrix_ks_kp, 1)
1513 0 : NULLIFY (matrix_vxc_kp(ispin, img)%matrix)
1514 0 : CALL dbcsr_init_p(matrix_vxc_kp(ispin, img)%matrix)
1515 : CALL dbcsr_copy(matrix_vxc_kp(ispin, img)%matrix, matrix_ks_kp(ispin, img)%matrix, &
1516 0 : name="Matrix VXC of spin "//cp_to_string(ispin)//" image "//cp_to_string(img))
1517 0 : CALL dbcsr_set(matrix_vxc_kp(ispin, img)%matrix, 0.0_dp)
1518 : END DO
1519 : END DO
1520 :
1521 : ! and integrate
1522 0 : gapw = dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc
1523 0 : IF (PRESENT(gapw_full_basis)) THEN
1524 0 : IF (gapw_full_basis) gapw = .FALSE.
1525 : END IF
1526 0 : DO ispin = 1, SIZE(matrix_ks_kp, 1)
1527 0 : ksmat => matrix_vxc_kp(ispin, :)
1528 : CALL integrate_v_rspace(v_rspace=v_rspace(ispin), &
1529 : hmat_kp=ksmat, &
1530 : qs_env=qs_env, &
1531 : calculate_forces=.FALSE., &
1532 0 : gapw=gapw)
1533 : ! scale by the volume element... should really become part of integrate_v_rspace
1534 0 : DO img = 1, SIZE(matrix_ks_kp, 2)
1535 0 : CALL dbcsr_scale(matrix_vxc_kp(ispin, img)%matrix, v_rspace(ispin)%pw_grid%dvol)
1536 : END DO
1537 : END DO
1538 :
1539 0 : CALL timestop(handle)
1540 :
1541 0 : END SUBROUTINE compute_matrix_vxc_kp
1542 :
1543 : ! **************************************************************************************************
1544 : !> \brief Sum up all potentials defined on the grid and integrate
1545 : !>
1546 : !> \param qs_env ...
1547 : !> \param ks_matrix ...
1548 : !> \param rho ...
1549 : !> \param my_rho ...
1550 : !> \param vppl_rspace ...
1551 : !> \param v_rspace_new ...
1552 : !> \param v_rspace_new_aux_fit ...
1553 : !> \param v_tau_rspace ...
1554 : !> \param v_tau_rspace_aux_fit ...
1555 : !> \param v_sic_rspace ...
1556 : !> \param v_spin_ddapc_rest_r ...
1557 : !> \param v_sccs_rspace ...
1558 : !> \param v_rspace_embed ...
1559 : !> \param cdft_control ...
1560 : !> \param calculate_forces ...
1561 : !> \par History
1562 : !> - refactoring 04.03.2011 [MI]
1563 : !> - SCCS implementation (16.10.2013,MK)
1564 : !> \author
1565 : ! **************************************************************************************************
1566 125433 : SUBROUTINE sum_up_and_integrate(qs_env, ks_matrix, rho, my_rho, &
1567 : vppl_rspace, v_rspace_new, &
1568 : v_rspace_new_aux_fit, v_tau_rspace, &
1569 : v_tau_rspace_aux_fit, &
1570 : v_sic_rspace, v_spin_ddapc_rest_r, &
1571 : v_sccs_rspace, v_rspace_embed, cdft_control, &
1572 : calculate_forces)
1573 :
1574 : TYPE(qs_environment_type), POINTER :: qs_env
1575 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: ks_matrix
1576 : TYPE(qs_rho_type), POINTER :: rho
1577 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: my_rho
1578 : TYPE(pw_r3d_rs_type), POINTER :: vppl_rspace
1579 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_rspace_new, v_rspace_new_aux_fit, &
1580 : v_tau_rspace, v_tau_rspace_aux_fit
1581 : TYPE(pw_r3d_rs_type), POINTER :: v_sic_rspace, v_spin_ddapc_rest_r, &
1582 : v_sccs_rspace
1583 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_rspace_embed
1584 : TYPE(cdft_control_type), POINTER :: cdft_control
1585 : LOGICAL, INTENT(in) :: calculate_forces
1586 :
1587 : CHARACTER(LEN=*), PARAMETER :: routineN = 'sum_up_and_integrate'
1588 :
1589 : CHARACTER(LEN=default_string_length) :: basis_type
1590 : INTEGER :: handle, igroup, ikind, img, ispin, &
1591 : nkind, nspins
1592 125433 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
1593 : LOGICAL :: do_ppl, gapw, gapw_composite_direct_ao, &
1594 : gapw_composite_reference, gapw_xc, &
1595 : lrigpw, rigpw, use_work_v_rspace
1596 : REAL(KIND=dp) :: csign, dvol, fadm
1597 : TYPE(admm_type), POINTER :: admm_env
1598 125433 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1599 125433 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ksmat, rho_ao, rho_ao_nokp, smat
1600 125433 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks_aux_fit, &
1601 125433 : matrix_ks_aux_fit_dft, rho_ao_aux, &
1602 125433 : rho_ao_kp
1603 : TYPE(dft_control_type), POINTER :: dft_control
1604 : TYPE(kpoint_type), POINTER :: kpoints
1605 : TYPE(lri_density_type), POINTER :: lri_density
1606 : TYPE(lri_environment_type), POINTER :: lri_env
1607 125433 : TYPE(lri_kind_type), DIMENSION(:), POINTER :: lri_v_int
1608 : TYPE(mp_para_env_type), POINTER :: para_env
1609 : TYPE(pw_env_type), POINTER :: pw_env
1610 : TYPE(pw_poisson_type), POINTER :: poisson_env
1611 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1612 : TYPE(pw_r3d_rs_type), POINTER :: v_rspace, v_rspace_used, vee
1613 : TYPE(pw_r3d_rs_type), TARGET :: v_rspace_work
1614 : TYPE(qs_ks_env_type), POINTER :: ks_env
1615 : TYPE(qs_rho_type), POINTER :: rho_aux_fit
1616 : TYPE(section_vals_type), POINTER :: input, xc_section
1617 : TYPE(task_list_type), POINTER :: task_list
1618 :
1619 125433 : CALL timeset(routineN, handle)
1620 :
1621 125433 : NULLIFY (auxbas_pw_pool, dft_control, pw_env, matrix_ks_aux_fit, &
1622 125433 : v_rspace, rho_aux_fit, vee, rho_ao, rho_ao_kp, rho_ao_aux, &
1623 125433 : ksmat, matrix_ks_aux_fit_dft, lri_env, lri_density, atomic_kind_set, &
1624 125433 : rho_ao_nokp, ks_env, admm_env, task_list, v_rspace_used, input, xc_section)
1625 :
1626 : CALL get_qs_env(qs_env, &
1627 : dft_control=dft_control, &
1628 : input=input, &
1629 : pw_env=pw_env, &
1630 : v_hartree_rspace=v_rspace, &
1631 125433 : vee=vee)
1632 :
1633 125433 : CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
1634 125433 : CALL pw_env_get(pw_env, poisson_env=poisson_env, auxbas_pw_pool=auxbas_pw_pool)
1635 125433 : gapw = dft_control%qs_control%gapw
1636 125433 : gapw_xc = dft_control%qs_control%gapw_xc
1637 125433 : xc_section => section_vals_get_subs_vals(input, "DFT%XC")
1638 : gapw_composite_reference = native_skala_gapw_composite_reference(xc_section) .AND. &
1639 125433 : (gapw .OR. gapw_xc)
1640 : gapw_composite_direct_ao = gapw_composite_reference .AND. &
1641 0 : native_skala_gapw_composite_direct_ao(xc_section)
1642 125433 : do_ppl = dft_control%qs_control%do_ppl_method == do_ppl_grid
1643 :
1644 125433 : rigpw = dft_control%qs_control%rigpw
1645 125433 : lrigpw = dft_control%qs_control%lrigpw
1646 125433 : IF (lrigpw .OR. rigpw) THEN
1647 : CALL get_qs_env(qs_env, &
1648 : lri_env=lri_env, &
1649 : lri_density=lri_density, &
1650 492 : atomic_kind_set=atomic_kind_set)
1651 : END IF
1652 :
1653 125433 : nspins = dft_control%nspins
1654 :
1655 : ! sum up potentials and integrate
1656 125433 : IF (ASSOCIATED(v_rspace_new)) THEN
1657 251541 : DO ispin = 1, nspins
1658 137118 : IF (gapw_composite_reference) THEN
1659 : ! The direct AO diagnostic uses the full ORB basis. The reconstructed path uses
1660 : ! the soft basis here and adds the hard-minus-soft adjoint through update_ks_atom.
1661 0 : CALL pw_scale(v_rspace_new(ispin), v_rspace_new(ispin)%pw_grid%dvol)
1662 0 : rho_ao => rho_ao_kp(ispin, :)
1663 0 : ksmat => ks_matrix(ispin, :)
1664 : CALL integrate_v_rspace(v_rspace=v_rspace_new(ispin), &
1665 : pmat_kp=rho_ao, hmat_kp=ksmat, &
1666 : qs_env=qs_env, &
1667 : calculate_forces=calculate_forces, &
1668 0 : gapw=gapw .AND. .NOT. gapw_composite_direct_ao)
1669 0 : CALL pw_copy(v_rspace, v_rspace_new(ispin))
1670 137118 : ELSE IF (gapw_xc) THEN
1671 : ! SIC not implemented (or at least not tested)
1672 4450 : CPASSERT(dft_control%sic_method_id == sic_none)
1673 : !Only the xc potential, because it has to be integrated with the soft basis
1674 4450 : CALL pw_scale(v_rspace_new(ispin), v_rspace_new(ispin)%pw_grid%dvol)
1675 :
1676 : ! add the xc part due to v_rspace soft
1677 4450 : rho_ao => rho_ao_kp(ispin, :)
1678 4450 : ksmat => ks_matrix(ispin, :)
1679 : CALL integrate_v_rspace(v_rspace=v_rspace_new(ispin), &
1680 : pmat_kp=rho_ao, hmat_kp=ksmat, &
1681 : qs_env=qs_env, &
1682 : calculate_forces=calculate_forces, &
1683 4450 : gapw=gapw_xc)
1684 :
1685 : ! Now the Hartree potential to be integrated with the full basis
1686 4450 : CALL pw_copy(v_rspace, v_rspace_new(ispin))
1687 : ELSE
1688 : ! Add v_hartree + v_xc = v_rspace_new
1689 132668 : CALL pw_axpy(v_rspace, v_rspace_new(ispin), 1.0_dp, v_rspace_new(ispin)%pw_grid%dvol)
1690 : END IF ! gapw_xc
1691 137118 : IF (dft_control%qs_control%ddapc_explicit_potential) THEN
1692 184 : IF (dft_control%qs_control%ddapc_restraint_is_spin) THEN
1693 184 : IF (ispin == 1) THEN
1694 92 : CALL pw_axpy(v_spin_ddapc_rest_r, v_rspace_new(ispin), 1.0_dp)
1695 : ELSE
1696 92 : CALL pw_axpy(v_spin_ddapc_rest_r, v_rspace_new(ispin), -1.0_dp)
1697 : END IF
1698 : ELSE
1699 0 : CALL pw_axpy(v_spin_ddapc_rest_r, v_rspace_new(ispin), 1.0_dp)
1700 : END IF
1701 : END IF
1702 : ! CDFT constraint contribution
1703 137118 : IF (dft_control%qs_control%cdft) THEN
1704 12392 : DO igroup = 1, SIZE(cdft_control%group)
1705 7216 : SELECT CASE (cdft_control%group(igroup)%constraint_type)
1706 : CASE (cdft_charge_constraint)
1707 32 : csign = 1.0_dp
1708 : CASE (cdft_magnetization_constraint)
1709 32 : IF (ispin == 1) THEN
1710 : csign = 1.0_dp
1711 : ELSE
1712 16 : csign = -1.0_dp
1713 : END IF
1714 : CASE (cdft_alpha_constraint)
1715 2016 : csign = 1.0_dp
1716 2016 : IF (ispin == 2) CYCLE
1717 : CASE (cdft_beta_constraint)
1718 2016 : csign = 1.0_dp
1719 2016 : IF (ispin == 1) CYCLE
1720 : CASE DEFAULT
1721 7216 : CPABORT("Unknown constraint type.")
1722 : END SELECT
1723 : CALL pw_axpy(cdft_control%group(igroup)%weight, v_rspace_new(ispin), &
1724 12392 : csign*cdft_control%strength(igroup))
1725 : END DO
1726 : END IF
1727 : ! functional derivative of the Hartree energy wrt the density in the presence of dielectric
1728 : ! (vhartree + v_eps); v_eps is nonzero only if the dielectric constant is defind as a function
1729 : ! of the charge density
1730 137118 : IF (poisson_env%parameters%solver == pw_poisson_implicit) THEN
1731 486 : dvol = poisson_env%implicit_env%v_eps%pw_grid%dvol
1732 486 : CALL pw_axpy(poisson_env%implicit_env%v_eps, v_rspace_new(ispin), dvol)
1733 : END IF
1734 : ! Add SCCS contribution
1735 137118 : IF (dft_control%do_sccs) THEN
1736 282 : CALL pw_axpy(v_sccs_rspace, v_rspace_new(ispin))
1737 : END IF
1738 : ! External electrostatic potential
1739 137118 : IF (dft_control%apply_external_potential) THEN
1740 : CALL qmmm_modify_hartree_pot(v_hartree=v_rspace_new(ispin), &
1741 364 : v_qmmm=vee, scale=-1.0_dp)
1742 : END IF
1743 137118 : IF (do_ppl) THEN
1744 66 : CPASSERT(.NOT. gapw)
1745 66 : CALL pw_axpy(vppl_rspace, v_rspace_new(ispin), vppl_rspace%pw_grid%dvol)
1746 : END IF
1747 : ! the electrostatic sic contribution
1748 137238 : SELECT CASE (dft_control%sic_method_id)
1749 : CASE (sic_none)
1750 : !
1751 : CASE (sic_mauri_us, sic_mauri_spz)
1752 120 : IF (ispin == 1) THEN
1753 60 : CALL pw_axpy(v_sic_rspace, v_rspace_new(ispin), -1.0_dp)
1754 : ELSE
1755 60 : CALL pw_axpy(v_sic_rspace, v_rspace_new(ispin), 1.0_dp)
1756 : END IF
1757 : CASE (sic_ad)
1758 137118 : CALL pw_axpy(v_sic_rspace, v_rspace_new(ispin), -1.0_dp)
1759 : CASE (sic_eo)
1760 : ! NOTHING TO BE DONE
1761 : END SELECT
1762 : ! DFT embedding
1763 137118 : IF (dft_control%apply_embed_pot) THEN
1764 838 : CALL pw_axpy(v_rspace_embed(ispin), v_rspace_new(ispin), v_rspace_embed(ispin)%pw_grid%dvol)
1765 838 : CALL auxbas_pw_pool%give_back_pw(v_rspace_embed(ispin))
1766 : END IF
1767 137118 : IF (lrigpw) THEN
1768 478 : lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
1769 478 : CALL get_qs_env(qs_env, nkind=nkind, para_env=para_env)
1770 1430 : DO ikind = 1, nkind
1771 308200 : lri_v_int(ikind)%v_int = 0.0_dp
1772 : END DO
1773 : CALL integrate_v_rspace_one_center(v_rspace_new(ispin), qs_env, &
1774 478 : lri_v_int, calculate_forces, "LRI_AUX")
1775 1430 : DO ikind = 1, nkind
1776 614970 : CALL para_env%sum(lri_v_int(ikind)%v_int)
1777 : END DO
1778 478 : IF (lri_env%exact_1c_terms) THEN
1779 36 : rho_ao => my_rho(ispin, :)
1780 36 : ksmat => ks_matrix(ispin, :)
1781 : CALL integrate_v_rspace_diagonal(v_rspace_new(ispin), ksmat(1)%matrix, &
1782 : rho_ao(1)%matrix, qs_env, &
1783 36 : calculate_forces, "ORB")
1784 : END IF
1785 478 : IF (lri_env%ppl_ri) THEN
1786 8 : CALL v_int_ppl_update(qs_env, lri_v_int, calculate_forces)
1787 : END IF
1788 136640 : ELSE IF (rigpw) THEN
1789 26 : lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
1790 26 : CALL get_qs_env(qs_env, nkind=nkind, para_env=para_env)
1791 52 : DO ikind = 1, nkind
1792 1144 : lri_v_int(ikind)%v_int = 0.0_dp
1793 : END DO
1794 : CALL integrate_v_rspace_one_center(v_rspace_new(ispin), qs_env, &
1795 26 : lri_v_int, calculate_forces, "RI_HXC")
1796 52 : DO ikind = 1, nkind
1797 2236 : CALL para_env%sum(lri_v_int(ikind)%v_int)
1798 : END DO
1799 : ELSE
1800 136614 : rho_ao => my_rho(ispin, :)
1801 136614 : ksmat => ks_matrix(ispin, :)
1802 : CALL integrate_v_rspace(v_rspace=v_rspace_new(ispin), &
1803 : pmat_kp=rho_ao, hmat_kp=ksmat, &
1804 : qs_env=qs_env, &
1805 : calculate_forces=calculate_forces, &
1806 136614 : gapw=gapw .AND. .NOT. gapw_composite_direct_ao)
1807 : END IF
1808 251541 : CALL auxbas_pw_pool%give_back_pw(v_rspace_new(ispin))
1809 : END DO ! ispin
1810 :
1811 114483 : SELECT CASE (dft_control%sic_method_id)
1812 : CASE (sic_none)
1813 : CASE (sic_mauri_us, sic_mauri_spz, sic_ad)
1814 60 : CALL auxbas_pw_pool%give_back_pw(v_sic_rspace)
1815 114483 : DEALLOCATE (v_sic_rspace)
1816 : END SELECT
1817 114423 : DEALLOCATE (v_rspace_new)
1818 :
1819 : ELSE
1820 : ! not implemented (or at least not tested)
1821 11010 : CPASSERT(dft_control%sic_method_id == sic_none)
1822 11010 : CPASSERT(.NOT. dft_control%qs_control%ddapc_restraint_is_spin)
1823 24306 : DO ispin = 1, nspins
1824 13296 : use_work_v_rspace = dft_control%qs_control%cdft
1825 13296 : IF (use_work_v_rspace) THEN
1826 168 : CALL auxbas_pw_pool%create_pw(v_rspace_work)
1827 168 : CALL pw_copy(v_rspace, v_rspace_work)
1828 168 : v_rspace_used => v_rspace_work
1829 : ELSE
1830 13128 : v_rspace_used => v_rspace
1831 : END IF
1832 : ! CDFT constraint contribution
1833 13296 : IF (dft_control%qs_control%cdft) THEN
1834 336 : DO igroup = 1, SIZE(cdft_control%group)
1835 168 : SELECT CASE (cdft_control%group(igroup)%constraint_type)
1836 : CASE (cdft_charge_constraint)
1837 0 : csign = 1.0_dp
1838 : CASE (cdft_magnetization_constraint)
1839 0 : IF (ispin == 1) THEN
1840 : csign = 1.0_dp
1841 : ELSE
1842 0 : csign = -1.0_dp
1843 : END IF
1844 : CASE (cdft_alpha_constraint)
1845 0 : csign = 1.0_dp
1846 0 : IF (ispin == 2) CYCLE
1847 : CASE (cdft_beta_constraint)
1848 0 : csign = 1.0_dp
1849 0 : IF (ispin == 1) CYCLE
1850 : CASE DEFAULT
1851 168 : CPABORT("Unknown constraint type.")
1852 : END SELECT
1853 : CALL pw_axpy(cdft_control%group(igroup)%weight, v_rspace_used, &
1854 336 : csign*cdft_control%strength(igroup))
1855 : END DO
1856 : END IF
1857 : ! extra contribution attributed to the dependency of the dielectric constant to the charge density
1858 13296 : IF (poisson_env%parameters%solver == pw_poisson_implicit) THEN
1859 0 : dvol = poisson_env%implicit_env%v_eps%pw_grid%dvol
1860 0 : CALL pw_axpy(poisson_env%implicit_env%v_eps, v_rspace_used, dvol)
1861 : END IF
1862 : ! Add SCCS contribution
1863 13296 : IF (dft_control%do_sccs) THEN
1864 0 : CALL pw_axpy(v_sccs_rspace, v_rspace_used)
1865 : END IF
1866 : ! DFT embedding
1867 13296 : IF (dft_control%apply_embed_pot) THEN
1868 12 : CALL pw_axpy(v_rspace_embed(ispin), v_rspace_used, v_rspace_embed(ispin)%pw_grid%dvol)
1869 12 : CALL auxbas_pw_pool%give_back_pw(v_rspace_embed(ispin))
1870 : END IF
1871 13296 : IF (lrigpw) THEN
1872 0 : lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
1873 0 : CALL get_qs_env(qs_env, nkind=nkind, para_env=para_env)
1874 0 : DO ikind = 1, nkind
1875 0 : lri_v_int(ikind)%v_int = 0.0_dp
1876 : END DO
1877 : CALL integrate_v_rspace_one_center(v_rspace_used, qs_env, &
1878 0 : lri_v_int, calculate_forces, "LRI_AUX")
1879 0 : DO ikind = 1, nkind
1880 0 : CALL para_env%sum(lri_v_int(ikind)%v_int)
1881 : END DO
1882 0 : IF (lri_env%exact_1c_terms) THEN
1883 0 : rho_ao => my_rho(ispin, :)
1884 0 : ksmat => ks_matrix(ispin, :)
1885 : CALL integrate_v_rspace_diagonal(v_rspace_used, ksmat(1)%matrix, &
1886 : rho_ao(1)%matrix, qs_env, &
1887 0 : calculate_forces, "ORB")
1888 : END IF
1889 0 : IF (lri_env%ppl_ri) THEN
1890 0 : CALL v_int_ppl_update(qs_env, lri_v_int, calculate_forces)
1891 : END IF
1892 13296 : ELSE IF (rigpw) THEN
1893 0 : lri_v_int => lri_density%lri_coefs(ispin)%lri_kinds
1894 0 : CALL get_qs_env(qs_env, nkind=nkind, para_env=para_env)
1895 0 : DO ikind = 1, nkind
1896 0 : lri_v_int(ikind)%v_int = 0.0_dp
1897 : END DO
1898 : CALL integrate_v_rspace_one_center(v_rspace_used, qs_env, &
1899 0 : lri_v_int, calculate_forces, "RI_HXC")
1900 0 : DO ikind = 1, nkind
1901 0 : CALL para_env%sum(lri_v_int(ikind)%v_int)
1902 : END DO
1903 : ELSE
1904 13296 : rho_ao => my_rho(ispin, :)
1905 13296 : ksmat => ks_matrix(ispin, :)
1906 : CALL integrate_v_rspace(v_rspace=v_rspace_used, &
1907 : pmat_kp=rho_ao, &
1908 : hmat_kp=ksmat, &
1909 : qs_env=qs_env, &
1910 : calculate_forces=calculate_forces, &
1911 13296 : gapw=gapw)
1912 : END IF
1913 24306 : IF (use_work_v_rspace) CALL auxbas_pw_pool%give_back_pw(v_rspace_work)
1914 : END DO
1915 : END IF ! ASSOCIATED(v_rspace_new)
1916 :
1917 : ! **** LRIGPW: KS matrix from integrated potential
1918 125433 : IF (lrigpw) THEN
1919 466 : CALL get_qs_env(qs_env, ks_env=ks_env)
1920 466 : CALL get_ks_env(ks_env=ks_env, kpoints=kpoints)
1921 466 : CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
1922 944 : DO ispin = 1, nspins
1923 478 : ksmat => ks_matrix(ispin, :)
1924 : CALL calculate_lri_ks_matrix(lri_env, lri_v_int, ksmat, atomic_kind_set, &
1925 944 : cell_to_index=cell_to_index)
1926 : END DO
1927 466 : IF (calculate_forces) THEN
1928 24 : CALL calculate_lri_forces(lri_env, lri_density, qs_env, rho_ao_kp, atomic_kind_set)
1929 : END IF
1930 124967 : ELSE IF (rigpw) THEN
1931 26 : CALL get_qs_env(qs_env, matrix_s=smat)
1932 52 : DO ispin = 1, nspins
1933 : CALL calculate_ri_ks_matrix(lri_env, lri_v_int, ks_matrix(ispin, 1)%matrix, &
1934 52 : smat(1)%matrix, atomic_kind_set, ispin)
1935 : END DO
1936 26 : IF (calculate_forces) THEN
1937 2 : rho_ao_nokp => rho_ao_kp(:, 1)
1938 2 : CALL calculate_ri_forces(lri_env, lri_density, qs_env, rho_ao_nokp, atomic_kind_set)
1939 : END IF
1940 : END IF
1941 :
1942 125433 : IF (ASSOCIATED(v_tau_rspace)) THEN
1943 3332 : IF (lrigpw .OR. rigpw) THEN
1944 0 : CPABORT("LRIGPW/RIGPW not implemented for meta-GGAs")
1945 : END IF
1946 7260 : DO ispin = 1, nspins
1947 3928 : CALL pw_scale(v_tau_rspace(ispin), v_tau_rspace(ispin)%pw_grid%dvol)
1948 :
1949 3928 : rho_ao => rho_ao_kp(ispin, :)
1950 3928 : ksmat => ks_matrix(ispin, :)
1951 : CALL integrate_v_rspace(v_rspace=v_tau_rspace(ispin), &
1952 : pmat_kp=rho_ao, hmat_kp=ksmat, &
1953 : qs_env=qs_env, &
1954 : calculate_forces=calculate_forces, compute_tau=.TRUE., &
1955 : gapw=(gapw .OR. gapw_xc) .AND. &
1956 6956 : .NOT. gapw_composite_direct_ao)
1957 7260 : CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
1958 : END DO
1959 3332 : DEALLOCATE (v_tau_rspace)
1960 : END IF
1961 :
1962 : ! Add contributions from ADMM if requested
1963 125433 : IF (dft_control%do_admm) THEN
1964 12318 : CALL get_qs_env(qs_env, admm_env=admm_env)
1965 : CALL get_admm_env(admm_env, matrix_ks_aux_fit_kp=matrix_ks_aux_fit, rho_aux_fit=rho_aux_fit, &
1966 12318 : matrix_ks_aux_fit_dft_kp=matrix_ks_aux_fit_dft)
1967 12318 : CALL qs_rho_get(rho_aux_fit, rho_ao_kp=rho_ao_aux)
1968 12318 : IF (ASSOCIATED(v_rspace_new_aux_fit)) THEN
1969 18806 : DO ispin = 1, nspins
1970 : ! Calculate the xc potential
1971 10262 : CALL pw_scale(v_rspace_new_aux_fit(ispin), v_rspace_new_aux_fit(ispin)%pw_grid%dvol)
1972 :
1973 : ! set matrix_ks_aux_fit_dft = matrix_ks_aux_fit(k_HF)
1974 25464 : DO img = 1, dft_control%nimages
1975 : CALL dbcsr_copy(matrix_ks_aux_fit_dft(ispin, img)%matrix, matrix_ks_aux_fit(ispin, img)%matrix, &
1976 25464 : name="DFT exch. part of matrix_ks_aux_fit")
1977 : END DO
1978 :
1979 : ! Add potential to ks_matrix aux_fit, skip integration if no DFT correction
1980 :
1981 10262 : IF (admm_env%aux_exch_func /= do_admm_aux_exch_func_none) THEN
1982 :
1983 : !GPW by default. IF GAPW, then take relevant task list and basis
1984 10262 : CALL get_admm_env(admm_env, task_list_aux_fit=task_list)
1985 10262 : basis_type = "AUX_FIT"
1986 10262 : IF (admm_env%do_gapw) THEN
1987 3832 : task_list => admm_env%admm_gapw_env%task_list
1988 3832 : basis_type = "AUX_FIT_SOFT"
1989 : END IF
1990 10262 : fadm = 1.0_dp
1991 : ! Calculate bare scaling of force according to Merlot, 1. IF: ADMMP, 2. IF: ADMMS,
1992 10262 : IF (admm_env%do_admmp) THEN
1993 444 : fadm = admm_env%gsi(ispin)**2
1994 9818 : ELSE IF (admm_env%do_admms) THEN
1995 476 : fadm = (admm_env%gsi(ispin))**(2.0_dp/3.0_dp)
1996 : END IF
1997 :
1998 10262 : rho_ao => rho_ao_aux(ispin, :)
1999 10262 : ksmat => matrix_ks_aux_fit(ispin, :)
2000 :
2001 : CALL integrate_v_rspace(v_rspace=v_rspace_new_aux_fit(ispin), &
2002 : pmat_kp=rho_ao, &
2003 : hmat_kp=ksmat, &
2004 : qs_env=qs_env, &
2005 : calculate_forces=calculate_forces, &
2006 : force_adm=fadm, &
2007 : gapw=.FALSE., & !even if actual GAPW calculation, want to use AUX_FIT_SOFT
2008 : basis_type=basis_type, &
2009 10262 : task_list_external=task_list)
2010 : END IF
2011 :
2012 : ! matrix_ks_aux_fit_dft(x_DFT)=matrix_ks_aux_fit_dft(old,k_HF)-matrix_ks_aux_fit(k_HF-x_DFT)
2013 25464 : DO img = 1, dft_control%nimages
2014 : CALL dbcsr_add(matrix_ks_aux_fit_dft(ispin, img)%matrix, &
2015 25464 : matrix_ks_aux_fit(ispin, img)%matrix, 1.0_dp, -1.0_dp)
2016 : END DO
2017 :
2018 18806 : CALL auxbas_pw_pool%give_back_pw(v_rspace_new_aux_fit(ispin))
2019 : END DO
2020 8544 : DEALLOCATE (v_rspace_new_aux_fit)
2021 : END IF
2022 : ! Clean up v_tau_rspace_aux_fit, which is actually not needed
2023 12318 : IF (ASSOCIATED(v_tau_rspace_aux_fit)) THEN
2024 0 : DO ispin = 1, nspins
2025 0 : CALL auxbas_pw_pool%give_back_pw(v_tau_rspace_aux_fit(ispin))
2026 : END DO
2027 0 : DEALLOCATE (v_tau_rspace_aux_fit)
2028 : END IF
2029 : END IF
2030 :
2031 125433 : IF (dft_control%apply_embed_pot) DEALLOCATE (v_rspace_embed)
2032 :
2033 125433 : CALL timestop(handle)
2034 :
2035 125433 : END SUBROUTINE sum_up_and_integrate
2036 :
2037 : !**************************************************************************
2038 : !> \brief Calculate the ZMP potential and energy as in Zhao, Morrison Parr
2039 : !> PRA 50i, 2138 (1994)
2040 : !> V_c^\lambda defined as int_rho-rho_0/r-r' or rho-rho_0 times a Lagrange
2041 : !> multiplier, plus Fermi-Amaldi potential that should give the V_xc in the
2042 : !> limit \lambda --> \infty
2043 : !>
2044 : !> \param qs_env ...
2045 : !> \param v_rspace_new ...
2046 : !> \param rho ...
2047 : !> \param exc ...
2048 : !> \author D. Varsano [daniele.varsano@nano.cnr.it]
2049 : ! **************************************************************************************************
2050 106 : SUBROUTINE calculate_zmp_potential(qs_env, v_rspace_new, rho, exc)
2051 :
2052 : TYPE(qs_environment_type), POINTER :: qs_env
2053 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_rspace_new
2054 : TYPE(qs_rho_type), POINTER :: rho
2055 : REAL(KIND=dp) :: exc
2056 :
2057 : CHARACTER(*), PARAMETER :: routineN = 'calculate_zmp_potential'
2058 :
2059 : INTEGER :: handle, my_val, nelectron, nspins
2060 : INTEGER, DIMENSION(2) :: nelectron_spin
2061 : LOGICAL :: do_zmp_read, fermi_amaldi
2062 : REAL(KIND=dp) :: lambda
2063 106 : REAL(KIND=dp), DIMENSION(:), POINTER :: tot_rho_ext_r
2064 : TYPE(dft_control_type), POINTER :: dft_control
2065 106 : TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_ext_g, rho_g
2066 : TYPE(pw_env_type), POINTER :: pw_env
2067 : TYPE(pw_poisson_type), POINTER :: poisson_env
2068 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
2069 : TYPE(pw_r3d_rs_type) :: v_xc_rspace
2070 106 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
2071 : TYPE(qs_ks_env_type), POINTER :: ks_env
2072 : TYPE(section_vals_type), POINTER :: ext_den_section, input
2073 :
2074 : !, v_h_gspace, &
2075 :
2076 106 : CALL timeset(routineN, handle)
2077 106 : NULLIFY (auxbas_pw_pool)
2078 106 : NULLIFY (pw_env)
2079 106 : NULLIFY (poisson_env)
2080 106 : NULLIFY (v_rspace_new)
2081 106 : NULLIFY (dft_control)
2082 106 : NULLIFY (rho_r, rho_g, tot_rho_ext_r, rho_ext_g)
2083 : CALL get_qs_env(qs_env=qs_env, &
2084 : pw_env=pw_env, &
2085 : ks_env=ks_env, &
2086 : rho=rho, &
2087 : input=input, &
2088 : nelectron_spin=nelectron_spin, &
2089 106 : dft_control=dft_control)
2090 : CALL pw_env_get(pw_env=pw_env, &
2091 : auxbas_pw_pool=auxbas_pw_pool, &
2092 106 : poisson_env=poisson_env)
2093 106 : CALL qs_rho_get(rho, rho_r=rho_r, rho_g=rho_g)
2094 106 : nspins = 1
2095 212 : ALLOCATE (v_rspace_new(nspins))
2096 106 : CALL auxbas_pw_pool%create_pw(pw=v_rspace_new(1))
2097 106 : CALL auxbas_pw_pool%create_pw(pw=v_xc_rspace)
2098 :
2099 106 : CALL pw_zero(v_rspace_new(1))
2100 106 : do_zmp_read = dft_control%apply_external_vxc
2101 106 : IF (do_zmp_read) THEN
2102 0 : CALL pw_copy(qs_env%external_vxc, v_rspace_new(1))
2103 : exc = accurate_dot_product(v_rspace_new(1)%array, rho_r(1)%array)* &
2104 0 : v_rspace_new(1)%pw_grid%dvol
2105 : ELSE
2106 318 : BLOCK
2107 : REAL(KIND=dp) :: factor
2108 : TYPE(pw_c1d_gs_type) :: rho_eff_gspace, v_xc_gspace
2109 106 : CALL auxbas_pw_pool%create_pw(pw=rho_eff_gspace)
2110 106 : CALL auxbas_pw_pool%create_pw(pw=v_xc_gspace)
2111 106 : CALL pw_zero(rho_eff_gspace)
2112 106 : CALL pw_zero(v_xc_gspace)
2113 106 : CALL pw_zero(v_xc_rspace)
2114 106 : factor = pw_integrate_function(rho_g(1))
2115 : CALL qs_rho_get(qs_env%rho_external, &
2116 : rho_g=rho_ext_g, &
2117 106 : tot_rho_r=tot_rho_ext_r)
2118 106 : factor = tot_rho_ext_r(1)/factor
2119 :
2120 106 : CALL pw_axpy(rho_g(1), rho_eff_gspace, alpha=factor)
2121 106 : CALL pw_axpy(rho_ext_g(1), rho_eff_gspace, alpha=-1.0_dp)
2122 106 : ext_den_section => section_vals_get_subs_vals(input, "DFT%EXTERNAL_DENSITY")
2123 106 : CALL section_vals_val_get(ext_den_section, "LAMBDA", r_val=lambda)
2124 106 : CALL section_vals_val_get(ext_den_section, "ZMP_CONSTRAINT", i_val=my_val)
2125 106 : CALL section_vals_val_get(ext_den_section, "FERMI_AMALDI", l_val=fermi_amaldi)
2126 :
2127 106 : CALL pw_scale(rho_eff_gspace, a=lambda)
2128 106 : nelectron = nelectron_spin(1)
2129 106 : factor = -1.0_dp/nelectron
2130 106 : CALL pw_axpy(rho_g(1), rho_eff_gspace, alpha=factor)
2131 :
2132 106 : CALL pw_poisson_solve(poisson_env, rho_eff_gspace, vhartree=v_xc_gspace)
2133 106 : CALL pw_transfer(v_xc_gspace, v_rspace_new(1))
2134 106 : CALL pw_copy(v_rspace_new(1), v_xc_rspace)
2135 :
2136 106 : exc = 0.0_dp
2137 106 : exc = pw_integral_ab(v_rspace_new(1), rho_r(1))
2138 :
2139 : !Note that this is not the xc energy but \int(\rho*v_xc)
2140 : !Vxc---> v_rspace_new
2141 : !Exc---> energy%exc
2142 106 : CALL auxbas_pw_pool%give_back_pw(rho_eff_gspace)
2143 212 : CALL auxbas_pw_pool%give_back_pw(v_xc_gspace)
2144 : END BLOCK
2145 : END IF
2146 :
2147 106 : CALL auxbas_pw_pool%give_back_pw(v_xc_rspace)
2148 :
2149 106 : CALL timestop(handle)
2150 :
2151 106 : END SUBROUTINE calculate_zmp_potential
2152 :
2153 : ! **************************************************************************************************
2154 : !> \brief ...
2155 : !> \param qs_env ...
2156 : !> \param rho ...
2157 : !> \param v_rspace_embed ...
2158 : !> \param dft_control ...
2159 : !> \param embed_corr ...
2160 : !> \param just_energy ...
2161 : ! **************************************************************************************************
2162 822 : SUBROUTINE get_embed_potential_energy(qs_env, rho, v_rspace_embed, dft_control, embed_corr, &
2163 : just_energy)
2164 : TYPE(qs_environment_type), POINTER :: qs_env
2165 : TYPE(qs_rho_type), POINTER :: rho
2166 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_rspace_embed
2167 : TYPE(dft_control_type), POINTER :: dft_control
2168 : REAL(KIND=dp) :: embed_corr
2169 : LOGICAL :: just_energy
2170 :
2171 : CHARACTER(*), PARAMETER :: routineN = 'get_embed_potential_energy'
2172 :
2173 : INTEGER :: handle, ispin
2174 : REAL(KIND=dp) :: embed_corr_local
2175 : TYPE(pw_env_type), POINTER :: pw_env
2176 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
2177 822 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r
2178 :
2179 822 : CALL timeset(routineN, handle)
2180 :
2181 822 : NULLIFY (auxbas_pw_pool)
2182 822 : NULLIFY (pw_env)
2183 822 : NULLIFY (rho_r)
2184 : CALL get_qs_env(qs_env=qs_env, &
2185 : pw_env=pw_env, &
2186 822 : rho=rho)
2187 : CALL pw_env_get(pw_env=pw_env, &
2188 822 : auxbas_pw_pool=auxbas_pw_pool)
2189 822 : CALL qs_rho_get(rho, rho_r=rho_r)
2190 3722 : ALLOCATE (v_rspace_embed(dft_control%nspins))
2191 :
2192 822 : embed_corr = 0.0_dp
2193 :
2194 2078 : DO ispin = 1, dft_control%nspins
2195 1256 : CALL auxbas_pw_pool%create_pw(pw=v_rspace_embed(ispin))
2196 1256 : CALL pw_zero(v_rspace_embed(ispin))
2197 :
2198 1256 : CALL pw_copy(qs_env%embed_pot, v_rspace_embed(ispin))
2199 1256 : embed_corr_local = 0.0_dp
2200 :
2201 : ! Spin embedding potential in open-shell case
2202 1256 : IF (dft_control%nspins == 2) THEN
2203 868 : IF (ispin == 1) CALL pw_axpy(qs_env%spin_embed_pot, v_rspace_embed(ispin), 1.0_dp)
2204 868 : IF (ispin == 2) CALL pw_axpy(qs_env%spin_embed_pot, v_rspace_embed(ispin), -1.0_dp)
2205 : END IF
2206 : ! Integrate the density*potential
2207 1256 : embed_corr_local = pw_integral_ab(v_rspace_embed(ispin), rho_r(ispin))
2208 :
2209 2078 : embed_corr = embed_corr + embed_corr_local
2210 :
2211 : END DO
2212 :
2213 : ! If only energy requiested we delete the potential
2214 822 : IF (just_energy) THEN
2215 692 : DO ispin = 1, dft_control%nspins
2216 692 : CALL auxbas_pw_pool%give_back_pw(v_rspace_embed(ispin))
2217 : END DO
2218 286 : DEALLOCATE (v_rspace_embed)
2219 : END IF
2220 :
2221 822 : CALL timestop(handle)
2222 :
2223 822 : END SUBROUTINE get_embed_potential_energy
2224 :
2225 : END MODULE qs_ks_utils
|