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 for an energy correction on top of a Kohn-Sham calculation
10 : !> \par History
11 : !> 03.2014 created
12 : !> 09.2019 Moved from KG to Kohn-Sham
13 : !> 08.2022 Add Density-Corrected DFT methods
14 : !> 04.2023 Add hybrid functionals for DC-DFT
15 : !> 10.2024 Add external energy method
16 : !> \author JGH
17 : ! **************************************************************************************************
18 : MODULE energy_corrections
19 : USE accint_weights_forces, ONLY: accint_weight_force
20 : USE admm_dm_methods, ONLY: admm_dm_calc_rho_aux
21 : USE admm_methods, ONLY: admm_mo_calc_rho_aux
22 : USE admm_types, ONLY: admm_type
23 : USE atomic_kind_types, ONLY: atomic_kind_type,&
24 : get_atomic_kind,&
25 : get_atomic_kind_set
26 : USE basis_set_types, ONLY: get_gto_basis_set,&
27 : gto_basis_set_type
28 : USE bibliography, ONLY: Belleflamme2023,&
29 : cite_reference
30 : USE cell_types, ONLY: cell_type,&
31 : pbc
32 : USE cp_blacs_env, ONLY: cp_blacs_env_type
33 : USE cp_control_types, ONLY: dft_control_type
34 : USE cp_dbcsr_api, ONLY: &
35 : dbcsr_add, dbcsr_copy, dbcsr_create, dbcsr_distribution_type, dbcsr_filter, &
36 : dbcsr_get_info, dbcsr_multiply, dbcsr_p_type, dbcsr_release, dbcsr_set, dbcsr_type, &
37 : dbcsr_type_symmetric
38 : USE cp_dbcsr_contrib, ONLY: dbcsr_dot
39 : USE cp_dbcsr_cp2k_link, ONLY: cp_dbcsr_alloc_block_from_nbl
40 : USE cp_dbcsr_operations, ONLY: copy_dbcsr_to_fm,&
41 : cp_dbcsr_sm_fm_multiply,&
42 : dbcsr_allocate_matrix_set,&
43 : dbcsr_deallocate_matrix_set
44 : USE cp_files, ONLY: close_file,&
45 : open_file
46 : USE cp_fm_basic_linalg, ONLY: cp_fm_scale_and_add,&
47 : cp_fm_trace
48 : USE cp_fm_struct, ONLY: cp_fm_struct_create,&
49 : cp_fm_struct_release,&
50 : cp_fm_struct_type
51 : USE cp_fm_types, ONLY: cp_fm_create,&
52 : cp_fm_get_info,&
53 : cp_fm_release,&
54 : cp_fm_set_submatrix,&
55 : cp_fm_to_fm,&
56 : cp_fm_type,&
57 : cp_fm_write_unformatted
58 : USE cp_log_handling, ONLY: cp_get_default_logger,&
59 : cp_logger_get_default_unit_nr,&
60 : cp_logger_type
61 : USE cp_output_handling, ONLY: cp_p_file,&
62 : cp_print_key_finished_output,&
63 : cp_print_key_should_output,&
64 : cp_print_key_unit_nr
65 : USE cp_result_methods, ONLY: cp_results_erase,&
66 : put_results
67 : USE cp_result_types, ONLY: cp_result_type
68 : USE cp_units, ONLY: cp_unit_from_cp2k
69 : USE distribution_1d_types, ONLY: distribution_1d_type
70 : USE distribution_2d_types, ONLY: distribution_2d_type
71 : USE ec_diag_solver, ONLY: ec_diag_solver_gamma,&
72 : ec_diag_solver_kp,&
73 : ec_ls_init,&
74 : ec_ls_solver,&
75 : ec_ot_diag_solver
76 : USE ec_efield_local, ONLY: ec_efield_integrals,&
77 : ec_efield_local_operator
78 : USE ec_env_types, ONLY: ec_env_potential_release,&
79 : energy_correction_type
80 : USE ec_external, ONLY: ec_ext_energy,&
81 : matrix_r_forces
82 : USE external_potential_types, ONLY: all_potential_type,&
83 : get_potential,&
84 : gth_potential_type,&
85 : sgp_potential_type
86 : USE hartree_local_methods, ONLY: Vh_1c_gg_integrals,&
87 : init_coulomb_local
88 : USE hartree_local_types, ONLY: hartree_local_create,&
89 : hartree_local_release,&
90 : hartree_local_type
91 : USE hfx_exx, ONLY: add_exx_to_rhs,&
92 : calculate_exx
93 : USE input_constants, ONLY: &
94 : do_admm_aux_exch_func_none, ec_diagonalization, ec_functional_dc, ec_functional_ext, &
95 : ec_functional_harris, ec_matrix_sign, ec_matrix_tc2, ec_matrix_trs4, ec_ot_diag, &
96 : vdw_pairpot_dftd3, vdw_pairpot_dftd3bj, xc_vdw_fun_pairpot
97 : USE input_section_types, ONLY: section_get_ival,&
98 : section_get_lval,&
99 : section_vals_duplicate,&
100 : section_vals_get,&
101 : section_vals_get_subs_vals,&
102 : section_vals_type,&
103 : section_vals_val_get,&
104 : section_vals_val_set
105 : USE kinds, ONLY: default_path_length,&
106 : default_string_length,&
107 : dp
108 : USE kpoint_io, ONLY: get_cell,&
109 : write_kpoints_file_header
110 : USE kpoint_methods, ONLY: kpoint_init_cell_index
111 : USE kpoint_types, ONLY: get_kpoint_info
112 : USE mao_basis, ONLY: mao_generate_basis
113 : USE mathlib, ONLY: det_3x3,&
114 : invmat_symm
115 : USE message_passing, ONLY: mp_para_env_type
116 : USE molecule_types, ONLY: molecule_type
117 : USE moments_utils, ONLY: get_reference_point
118 : USE parallel_gemm_api, ONLY: parallel_gemm
119 : USE particle_types, ONLY: particle_type
120 : USE paw_proj_set_types, ONLY: get_paw_proj_set,&
121 : paw_proj_set_type
122 : USE periodic_table, ONLY: ptable
123 : USE physcon, ONLY: bohr,&
124 : debye,&
125 : pascal
126 : USE pw_env_types, ONLY: pw_env_get,&
127 : pw_env_type
128 : USE pw_grid_types, ONLY: pw_grid_type
129 : USE pw_methods, ONLY: pw_axpy,&
130 : pw_copy,&
131 : pw_integral_ab,&
132 : pw_scale,&
133 : pw_transfer,&
134 : pw_zero
135 : USE pw_poisson_methods, ONLY: pw_poisson_solve
136 : USE pw_poisson_types, ONLY: pw_poisson_type
137 : USE pw_pool_types, ONLY: pw_pool_p_type,&
138 : pw_pool_type
139 : USE pw_types, ONLY: pw_c1d_gs_type,&
140 : pw_r3d_rs_type
141 : USE qs_collocate_density, ONLY: calculate_rho_elec
142 : USE qs_core_energies, ONLY: calculate_ecore_overlap,&
143 : calculate_ptrace
144 : USE qs_core_matrices, ONLY: core_matrices,&
145 : kinetic_energy_matrix
146 : USE qs_dispersion_pairpot, ONLY: calculate_dispersion_pairpot
147 : USE qs_dispersion_types, ONLY: qs_dispersion_type
148 : USE qs_energy_types, ONLY: qs_energy_type
149 : USE qs_environment_types, ONLY: get_qs_env,&
150 : qs_environment_type,&
151 : set_qs_env
152 : USE qs_force_types, ONLY: allocate_qs_force,&
153 : deallocate_qs_force,&
154 : qs_force_type,&
155 : total_qs_force,&
156 : zero_qs_force
157 : USE qs_fxc, ONLY: qs_fxc_create
158 : USE qs_gapw_densities, ONLY: prepare_gapw_den
159 : USE qs_integrate_potential, ONLY: integrate_rho_nlcc,&
160 : integrate_v_core_rspace,&
161 : integrate_v_rspace
162 : USE qs_kind_types, ONLY: get_qs_kind,&
163 : get_qs_kind_set,&
164 : qs_kind_type
165 : USE qs_kinetic, ONLY: build_kinetic_matrix
166 : USE qs_ks_atom, ONLY: update_ks_atom
167 : USE qs_ks_methods, ONLY: calc_rho_tot_gspace
168 : USE qs_ks_reference, ONLY: ks_ref_potential,&
169 : ks_ref_potential_atom
170 : USE qs_ks_types, ONLY: qs_ks_env_type
171 : USE qs_local_rho_types, ONLY: local_rho_set_create,&
172 : local_rho_set_release,&
173 : local_rho_type
174 : USE qs_moments, ONLY: build_local_moment_matrix
175 : USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
176 : USE qs_neighbor_lists, ONLY: atom2d_build,&
177 : atom2d_cleanup,&
178 : build_neighbor_lists,&
179 : local_atoms_type,&
180 : pair_radius_setup
181 : USE qs_oce_methods, ONLY: build_oce_matrices
182 : USE qs_oce_types, ONLY: allocate_oce_set,&
183 : create_oce_set,&
184 : oce_matrix_type
185 : USE qs_overlap, ONLY: build_overlap_matrix
186 : USE qs_rho0_ggrid, ONLY: integrate_vhg0_rspace,&
187 : rho0_s_grid_create
188 : USE qs_rho0_methods, ONLY: init_rho0
189 : USE qs_rho_atom_methods, ONLY: allocate_rho_atom_internals,&
190 : calculate_rho_atom_coeff
191 : USE qs_rho_atom_types, ONLY: rho_atom_type
192 : USE qs_rho_types, ONLY: qs_rho_create,&
193 : qs_rho_get,&
194 : qs_rho_set,&
195 : qs_rho_type
196 : USE qs_vxc, ONLY: qs_vxc_create
197 : USE qs_vxc_atom, ONLY: calculate_vxc_atom
198 : USE response_solver, ONLY: response_calculation,&
199 : response_force
200 : USE string_utilities, ONLY: uppercase
201 : USE task_list_methods, ONLY: generate_qs_task_list
202 : USE task_list_types, ONLY: allocate_task_list,&
203 : deallocate_task_list,&
204 : task_list_type
205 : USE trexio_utils, ONLY: write_trexio
206 : USE virial_methods, ONLY: one_third_sum_diag,&
207 : write_stress_tensor,&
208 : write_stress_tensor_components
209 : USE virial_types, ONLY: symmetrize_virial,&
210 : virial_type,&
211 : zero_virial
212 : USE voronoi_interface, ONLY: entry_voronoi_or_bqb
213 : #include "./base/base_uses.f90"
214 :
215 : IMPLICIT NONE
216 :
217 : PRIVATE
218 :
219 : ! Global parameters
220 :
221 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'energy_corrections'
222 :
223 : PUBLIC :: energy_correction
224 :
225 : CONTAINS
226 :
227 : ! **************************************************************************************************
228 : !> \brief Energy Correction to a Kohn-Sham simulation
229 : !> Available energy corrections: (1) Harris energy functional
230 : !> (2) Density-corrected DFT
231 : !> (3) Energy from external source
232 : !>
233 : !> \param qs_env ...
234 : !> \param ec_init ...
235 : !> \param calculate_forces ...
236 : !> \par History
237 : !> 03.2014 created
238 : !> \author JGH
239 : ! **************************************************************************************************
240 1216 : SUBROUTINE energy_correction(qs_env, ec_init, calculate_forces)
241 : TYPE(qs_environment_type), POINTER :: qs_env
242 : LOGICAL, INTENT(IN), OPTIONAL :: ec_init, calculate_forces
243 :
244 : CHARACTER(len=*), PARAMETER :: routineN = 'energy_correction'
245 :
246 : INTEGER :: handle, unit_nr
247 : LOGICAL :: my_calc_forces
248 : TYPE(cp_logger_type), POINTER :: logger
249 : TYPE(energy_correction_type), POINTER :: ec_env
250 : TYPE(qs_energy_type), POINTER :: energy
251 1216 : TYPE(qs_force_type), DIMENSION(:), POINTER :: ks_force
252 : TYPE(virial_type), POINTER :: virial
253 :
254 1216 : CALL timeset(routineN, handle)
255 :
256 1216 : logger => cp_get_default_logger()
257 1216 : IF (logger%para_env%is_source()) THEN
258 608 : unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
259 : ELSE
260 608 : unit_nr = -1
261 : END IF
262 :
263 1216 : CALL cite_reference(Belleflamme2023)
264 :
265 1216 : NULLIFY (ec_env)
266 1216 : CALL get_qs_env(qs_env, ec_env=ec_env)
267 :
268 : ! Skip energy correction if ground-state is NOT converged
269 1216 : IF (.NOT. ec_env%do_skip) THEN
270 :
271 1216 : ec_env%should_update = .TRUE.
272 1216 : IF (PRESENT(ec_init)) ec_env%should_update = ec_init
273 :
274 1216 : my_calc_forces = .FALSE.
275 1216 : IF (PRESENT(calculate_forces)) my_calc_forces = calculate_forces
276 :
277 1216 : IF (ec_env%should_update) THEN
278 718 : ec_env%old_etotal = 0.0_dp
279 718 : ec_env%etotal = 0.0_dp
280 718 : ec_env%eband = 0.0_dp
281 718 : ec_env%ehartree = 0.0_dp
282 718 : ec_env%ex = 0.0_dp
283 718 : ec_env%exc = 0.0_dp
284 718 : ec_env%vhxc = 0.0_dp
285 718 : ec_env%edispersion = 0.0_dp
286 718 : ec_env%exc_aux_fit = 0.0_dp
287 718 : ec_env%ekTS = 0.0_dp
288 718 : ec_env%exc1 = 0.0_dp
289 718 : ec_env%ehartree_1c = 0.0_dp
290 718 : ec_env%exc1_aux_fit = 0.0_dp
291 :
292 : ! Save total energy of reference calculation
293 718 : CALL get_qs_env(qs_env, energy=energy)
294 718 : ec_env%old_etotal = energy%total
295 :
296 : END IF
297 :
298 1216 : IF (my_calc_forces) THEN
299 498 : IF (unit_nr > 0) THEN
300 249 : WRITE (unit_nr, '(T2,A,A,A,A,A)') "!", REPEAT("-", 25), &
301 498 : " Energy Correction Forces ", REPEAT("-", 26), "!"
302 : END IF
303 498 : CALL get_qs_env(qs_env, force=ks_force, virial=virial)
304 498 : CALL zero_qs_force(ks_force)
305 498 : CALL zero_virial(virial, reset=.FALSE.)
306 : ELSE
307 718 : IF (unit_nr > 0) THEN
308 359 : WRITE (unit_nr, '(T2,A,A,A,A,A)') "!", REPEAT("-", 29), &
309 718 : " Energy Correction ", REPEAT("-", 29), "!"
310 : END IF
311 : END IF
312 :
313 : ! Perform the energy correction
314 1216 : CALL energy_correction_low(qs_env, ec_env, my_calc_forces, unit_nr)
315 :
316 : ! Update total energy in qs environment and amount fo correction
317 1216 : IF (ec_env%should_update) THEN
318 718 : energy%nonscf_correction = ec_env%etotal - ec_env%old_etotal
319 718 : energy%total = ec_env%etotal
320 : END IF
321 :
322 1216 : IF (.NOT. my_calc_forces .AND. unit_nr > 0) THEN
323 359 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Energy Correction ", energy%nonscf_correction
324 : END IF
325 1216 : IF (unit_nr > 0) THEN
326 608 : WRITE (unit_nr, '(T2,A,A,A)') "!", REPEAT("-", 77), "!"
327 : END IF
328 :
329 : ELSE
330 :
331 : ! Ground-state energy calculation did not converge,
332 : ! do not calculate energy correction
333 0 : IF (unit_nr > 0) THEN
334 0 : WRITE (unit_nr, '(T2,A,A,A)') "!", REPEAT("-", 77), "!"
335 0 : WRITE (unit_nr, '(T2,A,A,A,A,A)') "!", REPEAT("-", 26), &
336 0 : " Skip Energy Correction ", REPEAT("-", 27), "!"
337 0 : WRITE (unit_nr, '(T2,A,A,A)') "!", REPEAT("-", 77), "!"
338 : END IF
339 :
340 : END IF
341 :
342 1216 : CALL timestop(handle)
343 :
344 1216 : END SUBROUTINE energy_correction
345 :
346 : ! **************************************************************************************************
347 : !> \brief Energy Correction to a Kohn-Sham simulation
348 : !>
349 : !> \param qs_env ...
350 : !> \param ec_env ...
351 : !> \param calculate_forces ...
352 : !> \param unit_nr ...
353 : !> \par History
354 : !> 03.2014 created
355 : !> \author JGH
356 : ! **************************************************************************************************
357 1216 : SUBROUTINE energy_correction_low(qs_env, ec_env, calculate_forces, unit_nr)
358 : TYPE(qs_environment_type), POINTER :: qs_env
359 : TYPE(energy_correction_type), POINTER :: ec_env
360 : LOGICAL, INTENT(IN) :: calculate_forces
361 : INTEGER, INTENT(IN) :: unit_nr
362 :
363 : INTEGER :: ispin, nkind, nspins
364 : LOGICAL :: debug_f, gapw, gapw_xc
365 : REAL(KIND=dp) :: eps_fit, exc
366 : TYPE(dft_control_type), POINTER :: dft_control
367 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
368 1216 : POINTER :: sap_oce
369 : TYPE(oce_matrix_type), POINTER :: oce
370 1216 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
371 : TYPE(pw_env_type), POINTER :: pw_env
372 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
373 1216 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
374 :
375 1934 : IF (ec_env%should_update) THEN
376 718 : CALL ec_build_neighborlist(qs_env, ec_env)
377 718 : CALL ec_env_potential_release(ec_env)
378 : !
379 : CALL ks_ref_potential(qs_env, &
380 : ec_env%vh_rspace, &
381 : ec_env%vxc_rspace, &
382 : ec_env%vtau_rspace, &
383 : ec_env%vadmm_rspace, &
384 : ec_env%ehartree, exc, &
385 718 : vadmm_tau_rspace=ec_env%vadmm_tau_rspace)
386 : CALL ks_ref_potential_atom(qs_env, ec_env%local_rho_set, &
387 718 : ec_env%local_rho_set_admm, ec_env%vh_rspace)
388 :
389 1092 : SELECT CASE (ec_env%energy_functional)
390 : CASE (ec_functional_harris)
391 :
392 374 : CALL ec_build_core_hamiltonian(qs_env, ec_env)
393 374 : CALL ec_build_ks_matrix(qs_env, ec_env)
394 :
395 374 : IF (ec_env%mao) THEN
396 4 : CPASSERT(.NOT. ec_env%do_kpoints)
397 : ! MAO basis
398 4 : IF (ASSOCIATED(ec_env%mao_coef)) CALL dbcsr_deallocate_matrix_set(ec_env%mao_coef)
399 4 : NULLIFY (ec_env%mao_coef)
400 : CALL mao_generate_basis(qs_env, ec_env%mao_coef, ref_basis_set="HARRIS", &
401 : max_iter=ec_env%mao_max_iter, eps_grad=ec_env%mao_eps_grad, &
402 4 : eps1_mao=ec_env%mao_eps1, iolevel=ec_env%mao_iolevel, unit_nr=unit_nr)
403 : END IF
404 :
405 374 : CALL ec_ks_solver(qs_env, ec_env)
406 :
407 374 : CALL evaluate_ec_core_matrix_traces(qs_env, ec_env)
408 :
409 374 : IF (ec_env%write_harris_wfn) THEN
410 6 : CALL harris_wfn_output(qs_env, ec_env, unit_nr)
411 : END IF
412 :
413 : CASE (ec_functional_dc)
414 304 : CPASSERT(.NOT. ec_env%do_kpoints)
415 :
416 : ! Prepare Density-corrected DFT (DC-DFT) calculation
417 304 : CALL ec_dc_energy(qs_env, ec_env, calculate_forces=.FALSE.)
418 :
419 : ! Rebuild KS matrix with DC-DFT XC functional evaluated in ground-state density.
420 : ! KS matrix might contain unwanted contributions
421 : ! Calculate Hartree and XC related energies here
422 304 : CALL ec_build_ks_matrix(qs_env, ec_env)
423 :
424 : CASE (ec_functional_ext)
425 40 : CPASSERT(.NOT. ec_env%do_kpoints)
426 :
427 40 : CALL ec_ext_energy(qs_env, ec_env, calculate_forces=.FALSE.)
428 :
429 : CASE DEFAULT
430 718 : CPABORT("unknown energy correction")
431 : END SELECT
432 :
433 : ! dispersion through pairpotentials
434 718 : CALL ec_disp(qs_env, ec_env, calculate_forces=.FALSE.)
435 :
436 : ! Calculate total energy
437 718 : CALL ec_energy(ec_env, unit_nr)
438 :
439 : END IF
440 :
441 1216 : IF (calculate_forces) THEN
442 :
443 498 : debug_f = ec_env%debug_forces .OR. ec_env%debug_stress
444 :
445 498 : CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
446 498 : nspins = dft_control%nspins
447 498 : gapw = dft_control%qs_control%gapw
448 498 : gapw_xc = dft_control%qs_control%gapw_xc
449 498 : IF (gapw .OR. gapw_xc) THEN
450 : CALL get_qs_env(qs_env=qs_env, nkind=nkind, &
451 50 : qs_kind_set=qs_kind_set, particle_set=particle_set)
452 50 : NULLIFY (oce, sap_oce)
453 50 : CALL get_qs_env(qs_env=qs_env, oce=oce, sap_oce=sap_oce)
454 50 : CALL create_oce_set(oce)
455 50 : CALL allocate_oce_set(oce, nkind)
456 50 : eps_fit = dft_control%qs_control%gapw_control%eps_fit
457 : CALL build_oce_matrices(oce%intac, .TRUE., 1, qs_kind_set, particle_set, &
458 50 : sap_oce, eps_fit)
459 50 : CALL set_qs_env(qs_env, oce=oce)
460 : END IF
461 :
462 498 : CALL ec_disp(qs_env, ec_env, calculate_forces=.TRUE.)
463 :
464 768 : SELECT CASE (ec_env%energy_functional)
465 : CASE (ec_functional_harris)
466 :
467 : CALL ec_build_core_hamiltonian_force(qs_env, ec_env, &
468 : ec_env%matrix_p, &
469 : ec_env%matrix_s, &
470 270 : ec_env%matrix_w)
471 270 : CALL ec_build_ks_matrix_force(qs_env, ec_env)
472 270 : IF (ec_env%debug_external) THEN
473 0 : CALL write_response_interface(qs_env, ec_env)
474 0 : CALL init_response_deriv(qs_env, ec_env)
475 : END IF
476 :
477 : CASE (ec_functional_dc)
478 :
479 212 : CPASSERT(.NOT. ec_env%do_kpoints)
480 : ! Prepare Density-corrected DFT (DC-DFT) calculation
481 : ! by getting ground-state matrices
482 212 : CALL ec_dc_energy(qs_env, ec_env, calculate_forces=.TRUE.)
483 :
484 : CALL ec_build_core_hamiltonian_force(qs_env, ec_env, &
485 : ec_env%matrix_p, &
486 : ec_env%matrix_s, &
487 212 : ec_env%matrix_w)
488 212 : CALL ec_dc_build_ks_matrix_force(qs_env, ec_env)
489 212 : IF (ec_env%debug_external) THEN
490 0 : CALL write_response_interface(qs_env, ec_env)
491 0 : CALL init_response_deriv(qs_env, ec_env)
492 : END IF
493 :
494 : CASE (ec_functional_ext)
495 :
496 16 : CPASSERT(.NOT. ec_env%do_kpoints)
497 16 : CALL ec_ext_energy(qs_env, ec_env, calculate_forces=.TRUE.)
498 16 : CALL init_response_deriv(qs_env, ec_env)
499 : ! orthogonality force
500 : CALL matrix_r_forces(qs_env, ec_env%cpmos, ec_env%mo_occ, &
501 : ec_env%matrix_w(1, 1)%matrix, unit_nr, &
502 16 : ec_env%debug_forces, ec_env%debug_stress)
503 :
504 : CASE DEFAULT
505 498 : CPABORT("unknown energy correction")
506 : END SELECT
507 :
508 498 : IF (ec_env%do_error) THEN
509 8 : ALLOCATE (ec_env%cpref(nspins))
510 4 : DO ispin = 1, nspins
511 2 : CALL cp_fm_create(ec_env%cpref(ispin), ec_env%cpmos(ispin)%matrix_struct)
512 4 : CALL cp_fm_to_fm(ec_env%cpmos(ispin), ec_env%cpref(ispin))
513 : END DO
514 : END IF
515 :
516 498 : CALL response_calculation(qs_env, ec_env)
517 :
518 : ! Allocate response density on real space grid for use in properties
519 : ! Calculated in response_force
520 498 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
521 :
522 498 : CPASSERT(ASSOCIATED(pw_env))
523 498 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
524 1994 : ALLOCATE (ec_env%rhoz_r(nspins))
525 998 : DO ispin = 1, nspins
526 998 : CALL auxbas_pw_pool%create_pw(ec_env%rhoz_r(ispin))
527 : END DO
528 :
529 : CALL response_force(qs_env, &
530 : vh_rspace=ec_env%vh_rspace, &
531 : vxc_rspace=ec_env%vxc_rspace, &
532 : vtau_rspace=ec_env%vtau_rspace, &
533 : vadmm_rspace=ec_env%vadmm_rspace, &
534 : vadmm_tau_rspace=ec_env%vadmm_tau_rspace, &
535 : matrix_hz=ec_env%matrix_hz, &
536 : matrix_pz=ec_env%matrix_z, &
537 : matrix_pz_admm=ec_env%z_admm, &
538 : matrix_wz=ec_env%matrix_wz, &
539 : rhopz_r=ec_env%rhoz_r, &
540 : zehartree=ec_env%ehartree, &
541 : zexc=ec_env%exc, &
542 : zexc_aux_fit=ec_env%exc_aux_fit, &
543 : p_env=ec_env%p_env, &
544 498 : debug=debug_f)
545 :
546 498 : CALL output_response_deriv(qs_env, ec_env, unit_nr)
547 :
548 498 : CALL ec_properties(qs_env, ec_env)
549 :
550 498 : IF (ec_env%do_error) THEN
551 2 : CALL response_force_error(qs_env, ec_env, unit_nr)
552 : END IF
553 :
554 : ! Deallocate Harris density and response density on grid
555 498 : IF (ASSOCIATED(ec_env%rhoout_r)) THEN
556 966 : DO ispin = 1, nspins
557 966 : CALL auxbas_pw_pool%give_back_pw(ec_env%rhoout_r(ispin))
558 : END DO
559 482 : DEALLOCATE (ec_env%rhoout_r)
560 : END IF
561 498 : IF (ASSOCIATED(ec_env%rhoz_r)) THEN
562 998 : DO ispin = 1, nspins
563 998 : CALL auxbas_pw_pool%give_back_pw(ec_env%rhoz_r(ispin))
564 : END DO
565 498 : DEALLOCATE (ec_env%rhoz_r)
566 : END IF
567 :
568 : ! Deallocate matrices
569 498 : IF (ASSOCIATED(ec_env%matrix_ks)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_ks)
570 498 : IF (ASSOCIATED(ec_env%matrix_h)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_h)
571 498 : IF (ASSOCIATED(ec_env%matrix_s)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_s)
572 498 : IF (ASSOCIATED(ec_env%matrix_t)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_t)
573 498 : IF (ASSOCIATED(ec_env%matrix_p)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_p)
574 498 : IF (ASSOCIATED(ec_env%matrix_w)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_w)
575 498 : IF (ASSOCIATED(ec_env%matrix_hz)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_hz)
576 498 : IF (ASSOCIATED(ec_env%matrix_wz)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_wz)
577 498 : IF (ASSOCIATED(ec_env%matrix_z)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_z)
578 :
579 : END IF
580 :
581 1216 : END SUBROUTINE energy_correction_low
582 :
583 : ! **************************************************************************************************
584 : !> \brief Output response information to TREXIO file (for testing external method read in)
585 : !> \param qs_env ...
586 : !> \param ec_env ...
587 : !> \author JHU
588 : ! **************************************************************************************************
589 0 : SUBROUTINE write_response_interface(qs_env, ec_env)
590 : TYPE(qs_environment_type), POINTER :: qs_env
591 : TYPE(energy_correction_type), POINTER :: ec_env
592 :
593 : TYPE(section_vals_type), POINTER :: section, trexio_section
594 :
595 0 : section => section_vals_get_subs_vals(qs_env%input, "DFT%PRINT%TREXIO")
596 0 : NULLIFY (trexio_section)
597 0 : CALL section_vals_duplicate(section, trexio_section)
598 0 : CALL section_vals_val_set(trexio_section, "FILENAME", c_val=ec_env%exresp_fn)
599 0 : CALL section_vals_val_set(trexio_section, "CARTESIAN", l_val=.FALSE.)
600 0 : CALL write_trexio(qs_env, trexio_section, ec_env%matrix_hz)
601 :
602 0 : END SUBROUTINE write_response_interface
603 :
604 : ! **************************************************************************************************
605 : !> \brief Initialize arrays for response derivatives
606 : !> \param qs_env ...
607 : !> \param ec_env ...
608 : !> \author JHU
609 : ! **************************************************************************************************
610 16 : SUBROUTINE init_response_deriv(qs_env, ec_env)
611 : TYPE(qs_environment_type), POINTER :: qs_env
612 : TYPE(energy_correction_type), POINTER :: ec_env
613 :
614 : INTEGER :: natom
615 16 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
616 16 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
617 : TYPE(virial_type), POINTER :: virial
618 :
619 16 : CALL get_qs_env(qs_env, natom=natom)
620 48 : ALLOCATE (ec_env%rf(3, natom))
621 192 : ec_env%rf = 0.0_dp
622 208 : ec_env%rpv = 0.0_dp
623 16 : CALL get_qs_env(qs_env, force=force, virial=virial)
624 :
625 16 : CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
626 16 : CALL total_qs_force(ec_env%rf, force, atomic_kind_set)
627 :
628 16 : IF (virial%pv_availability .AND. (.NOT. virial%pv_numer)) THEN
629 0 : ec_env%rpv = virial%pv_virial
630 : END IF
631 :
632 16 : END SUBROUTINE init_response_deriv
633 :
634 : ! **************************************************************************************************
635 : !> \brief Write the reponse forces to file
636 : !> \param qs_env ...
637 : !> \param ec_env ...
638 : !> \param unit_nr ...
639 : !> \author JHU
640 : ! **************************************************************************************************
641 498 : SUBROUTINE output_response_deriv(qs_env, ec_env, unit_nr)
642 : TYPE(qs_environment_type), POINTER :: qs_env
643 : TYPE(energy_correction_type), POINTER :: ec_env
644 : INTEGER, INTENT(IN) :: unit_nr
645 :
646 : CHARACTER(LEN=default_string_length) :: unit_string
647 : INTEGER :: funit, ia, natom
648 : REAL(KIND=dp) :: evol, fconv
649 498 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: ftot
650 498 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
651 : TYPE(cell_type), POINTER :: cell
652 : TYPE(mp_para_env_type), POINTER :: para_env
653 498 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
654 498 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
655 : TYPE(virial_type), POINTER :: virial
656 :
657 498 : IF (ASSOCIATED(ec_env%rf)) THEN
658 16 : CALL get_qs_env(qs_env, natom=natom)
659 48 : ALLOCATE (ftot(3, natom))
660 16 : ftot = 0.0_dp
661 16 : CALL get_qs_env(qs_env, force=force, virial=virial, para_env=para_env)
662 :
663 16 : CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
664 16 : CALL total_qs_force(ftot, force, atomic_kind_set)
665 192 : ec_env%rf(1:3, 1:natom) = ftot(1:3, 1:natom) - ec_env%rf(1:3, 1:natom)
666 368 : CALL para_env%sum(ec_env%rf)
667 16 : DEALLOCATE (ftot)
668 :
669 16 : IF (virial%pv_availability .AND. (.NOT. virial%pv_numer)) THEN
670 0 : ec_env%rpv = virial%pv_virial - ec_env%rpv
671 0 : CALL para_env%sum(ec_env%rpv)
672 : ! Volume terms
673 0 : evol = ec_env%exc + ec_env%exc_aux_fit + 2.0_dp*ec_env%ehartree
674 0 : ec_env%rpv(1, 1) = ec_env%rpv(1, 1) - evol
675 0 : ec_env%rpv(2, 2) = ec_env%rpv(2, 2) - evol
676 0 : ec_env%rpv(3, 3) = ec_env%rpv(3, 3) - evol
677 : END IF
678 :
679 16 : CALL get_qs_env(qs_env, particle_set=particle_set, cell=cell)
680 : ! Conversion factor a.u. -> GPa
681 16 : unit_string = "GPa"
682 16 : fconv = cp_unit_from_cp2k(1.0_dp/cell%deth, TRIM(unit_string))
683 16 : IF (unit_nr > 0) THEN
684 8 : WRITE (unit_nr, '(/,T2,A)') "Write EXTERNAL Response Derivative: "//TRIM(ec_env%exresult_fn)
685 :
686 : CALL open_file(ec_env%exresult_fn, file_status="REPLACE", file_form="FORMATTED", &
687 8 : file_action="WRITE", unit_number=funit)
688 8 : WRITE (funit, "(T8,A,T58,A)") "COORDINATES [Bohr]", "RESPONSE FORCES [Hartree/Bohr]"
689 30 : DO ia = 1, natom
690 162 : WRITE (funit, "(2(3F15.8,5x))") particle_set(ia)%r(1:3), ec_env%rf(1:3, ia)
691 : END DO
692 8 : WRITE (funit, *)
693 8 : WRITE (funit, "(T8,A,T58,A)") "CELL [Bohr]", "RESPONSE PRESSURE [GPa]"
694 32 : DO ia = 1, 3
695 176 : WRITE (funit, "(3F15.8,5x,3F15.8)") cell%hmat(ia, 1:3), -fconv*ec_env%rpv(ia, 1:3)
696 : END DO
697 :
698 8 : CALL close_file(funit)
699 : END IF
700 : END IF
701 :
702 514 : END SUBROUTINE output_response_deriv
703 :
704 : ! **************************************************************************************************
705 : !> \brief Calculates the traces of the core matrices and the density matrix.
706 : !> \param qs_env ...
707 : !> \param ec_env ...
708 : !> \author Ole Schuett
709 : !> adapted for energy correction fbelle
710 : ! **************************************************************************************************
711 374 : SUBROUTINE evaluate_ec_core_matrix_traces(qs_env, ec_env)
712 : TYPE(qs_environment_type), POINTER :: qs_env
713 : TYPE(energy_correction_type), POINTER :: ec_env
714 :
715 : CHARACTER(LEN=*), PARAMETER :: routineN = 'evaluate_ec_core_matrix_traces'
716 :
717 : INTEGER :: handle
718 : TYPE(dft_control_type), POINTER :: dft_control
719 : TYPE(qs_energy_type), POINTER :: energy
720 :
721 374 : CALL timeset(routineN, handle)
722 374 : NULLIFY (energy)
723 :
724 374 : CALL get_qs_env(qs_env, dft_control=dft_control, energy=energy)
725 :
726 : ! Core hamiltonian energy
727 374 : CALL calculate_ptrace(ec_env%matrix_h, ec_env%matrix_p, energy%core, dft_control%nspins)
728 :
729 : ! kinetic energy
730 374 : CALL calculate_ptrace(ec_env%matrix_t, ec_env%matrix_p, energy%kinetic, dft_control%nspins)
731 :
732 374 : CALL timestop(handle)
733 :
734 374 : END SUBROUTINE evaluate_ec_core_matrix_traces
735 :
736 : ! **************************************************************************************************
737 : !> \brief Prepare DC-DFT calculation by copying unaffected ground-state matrices (core Hamiltonian,
738 : !> density matrix) into energy correction environment and rebuild the overlap matrix
739 : !>
740 : !> \param qs_env ...
741 : !> \param ec_env ...
742 : !> \param calculate_forces ...
743 : !> \par History
744 : !> 07.2022 created
745 : !> \author fbelle
746 : ! **************************************************************************************************
747 516 : SUBROUTINE ec_dc_energy(qs_env, ec_env, calculate_forces)
748 : TYPE(qs_environment_type), POINTER :: qs_env
749 : TYPE(energy_correction_type), POINTER :: ec_env
750 : LOGICAL, INTENT(IN) :: calculate_forces
751 :
752 : CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_dc_energy'
753 :
754 : CHARACTER(LEN=default_string_length) :: headline
755 : INTEGER :: handle, ispin, nspins
756 516 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_h, matrix_p, matrix_s, matrix_w
757 : TYPE(dft_control_type), POINTER :: dft_control
758 : TYPE(qs_energy_type), POINTER :: energy
759 : TYPE(qs_ks_env_type), POINTER :: ks_env
760 : TYPE(qs_rho_type), POINTER :: rho
761 :
762 516 : CALL timeset(routineN, handle)
763 :
764 516 : NULLIFY (dft_control, ks_env, matrix_h, matrix_p, matrix_s, matrix_w, rho)
765 : CALL get_qs_env(qs_env=qs_env, &
766 : dft_control=dft_control, &
767 : ks_env=ks_env, &
768 : matrix_h_kp=matrix_h, &
769 : matrix_s_kp=matrix_s, &
770 : matrix_w_kp=matrix_w, &
771 516 : rho=rho)
772 516 : CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
773 516 : nspins = dft_control%nspins
774 :
775 : ! For density-corrected DFT only the ground-state matrices are required
776 : ! Comply with ec_env environment for property calculations later
777 : CALL build_overlap_matrix(ks_env, matrixkp_s=ec_env%matrix_s, &
778 : matrix_name="OVERLAP MATRIX", &
779 : basis_type_a="HARRIS", &
780 : basis_type_b="HARRIS", &
781 516 : sab_nl=ec_env%sab_orb)
782 :
783 : ! Core Hamiltonian matrix
784 516 : IF (ASSOCIATED(ec_env%matrix_h)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_h)
785 516 : CALL dbcsr_allocate_matrix_set(ec_env%matrix_h, 1, 1)
786 516 : headline = "CORE HAMILTONIAN MATRIX"
787 516 : ALLOCATE (ec_env%matrix_h(1, 1)%matrix)
788 : CALL dbcsr_create(ec_env%matrix_h(1, 1)%matrix, name=TRIM(headline), &
789 516 : template=matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
790 516 : CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_h(1, 1)%matrix, ec_env%sab_orb)
791 516 : CALL dbcsr_copy(ec_env%matrix_h(1, 1)%matrix, matrix_h(1, 1)%matrix)
792 :
793 : ! Density matrix
794 516 : IF (ASSOCIATED(ec_env%matrix_p)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_p)
795 516 : CALL dbcsr_allocate_matrix_set(ec_env%matrix_p, nspins, 1)
796 516 : headline = "DENSITY MATRIX"
797 1040 : DO ispin = 1, nspins
798 524 : ALLOCATE (ec_env%matrix_p(ispin, 1)%matrix)
799 : CALL dbcsr_create(ec_env%matrix_p(ispin, 1)%matrix, name=TRIM(headline), &
800 524 : template=matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
801 524 : CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_p(ispin, 1)%matrix, ec_env%sab_orb)
802 1040 : CALL dbcsr_copy(ec_env%matrix_p(ispin, 1)%matrix, matrix_p(ispin, 1)%matrix)
803 : END DO
804 :
805 516 : IF (calculate_forces) THEN
806 :
807 : ! Energy-weighted density matrix
808 212 : IF (ASSOCIATED(ec_env%matrix_w)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_w)
809 212 : CALL dbcsr_allocate_matrix_set(ec_env%matrix_w, nspins, 1)
810 212 : headline = "ENERGY-WEIGHTED DENSITY MATRIX"
811 426 : DO ispin = 1, nspins
812 214 : ALLOCATE (ec_env%matrix_w(ispin, 1)%matrix)
813 : CALL dbcsr_create(ec_env%matrix_w(ispin, 1)%matrix, name=TRIM(headline), &
814 214 : template=matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
815 214 : CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_w(ispin, 1)%matrix, ec_env%sab_orb)
816 426 : CALL dbcsr_copy(ec_env%matrix_w(ispin, 1)%matrix, matrix_w(ispin, 1)%matrix)
817 : END DO
818 :
819 : END IF
820 :
821 : ! Electronic entropy term
822 516 : CALL get_qs_env(qs_env=qs_env, energy=energy)
823 516 : ec_env%ekTS = energy%ktS
824 :
825 : ! External field (nonperiodic case)
826 516 : ec_env%efield_nuclear = 0.0_dp
827 516 : ec_env%efield_elec = 0.0_dp
828 516 : CALL ec_efield_local_operator(qs_env, ec_env, calculate_forces=.FALSE.)
829 :
830 516 : CALL timestop(handle)
831 :
832 516 : END SUBROUTINE ec_dc_energy
833 :
834 : ! **************************************************************************************************
835 : !> \brief Kohn-Sham matrix contributions to force in DC-DFT
836 : !> also calculate right-hand-side matrix B for response equations AX=B
837 : !> \param qs_env ...
838 : !> \param ec_env ...
839 : !> \par History
840 : !> 08.2022 adapted from qs_ks_build_kohn_sham_matrix
841 : !> \author fbelle
842 : ! **************************************************************************************************
843 212 : SUBROUTINE ec_dc_build_ks_matrix_force(qs_env, ec_env)
844 : TYPE(qs_environment_type), POINTER :: qs_env
845 : TYPE(energy_correction_type), POINTER :: ec_env
846 :
847 : CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_dc_build_ks_matrix_force'
848 :
849 : CHARACTER(LEN=default_string_length) :: basis_type, unit_string
850 : INTEGER :: handle, i, iounit, ispin, natom, nspins
851 : LOGICAL :: debug_forces, debug_stress, do_ec_hfx, &
852 : gapw, gapw_xc, use_virial
853 : REAL(dp) :: dummy_real, dummy_real2(2), edisp, &
854 : ehartree, ehartree_1c, eovrl, exc, &
855 : exc1, fconv
856 212 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: ftot
857 : REAL(dp), DIMENSION(3) :: fodeb, fodeb2
858 : REAL(KIND=dp), DIMENSION(3, 3) :: h_stress, pv_loc, stdeb, sttot
859 : TYPE(admm_type), POINTER :: admm_env
860 212 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
861 : TYPE(cell_type), POINTER :: cell
862 : TYPE(cp_logger_type), POINTER :: logger
863 212 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s, scrm
864 212 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_p
865 : TYPE(dft_control_type), POINTER :: dft_control
866 : TYPE(hartree_local_type), POINTER :: hartree_local
867 : TYPE(local_rho_type), POINTER :: local_rho_set
868 : TYPE(mp_para_env_type), POINTER :: para_env
869 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
870 212 : POINTER :: sab_orb
871 : TYPE(oce_matrix_type), POINTER :: oce
872 : TYPE(pw_c1d_gs_type) :: rho_tot_gspace, v_hartree_gspace
873 : TYPE(pw_env_type), POINTER :: pw_env
874 : TYPE(pw_grid_type), POINTER :: pw_grid
875 : TYPE(pw_poisson_type), POINTER :: poisson_env
876 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
877 : TYPE(pw_r3d_rs_type) :: v_hartree_rspace
878 212 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r, v_rspace, v_rspace_in, &
879 212 : v_tau_rspace
880 : TYPE(pw_r3d_rs_type), POINTER :: rho_nlcc
881 212 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
882 212 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
883 : TYPE(qs_ks_env_type), POINTER :: ks_env
884 : TYPE(qs_rho_type), POINTER :: rho, rho1, rho_struct, rho_xc
885 : TYPE(section_vals_type), POINTER :: ec_hfx_sections
886 : TYPE(task_list_type), POINTER :: task_list
887 : TYPE(virial_type), POINTER :: virial
888 :
889 212 : CALL timeset(routineN, handle)
890 :
891 212 : debug_forces = ec_env%debug_forces
892 212 : debug_stress = ec_env%debug_stress
893 :
894 212 : logger => cp_get_default_logger()
895 212 : IF (logger%para_env%is_source()) THEN
896 106 : iounit = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
897 : ELSE
898 106 : iounit = -1
899 : END IF
900 :
901 212 : NULLIFY (atomic_kind_set, cell, dft_control, force, ks_env, &
902 212 : matrix_p, matrix_s, para_env, pw_env, rho, rho_nlcc, sab_orb, virial)
903 : CALL get_qs_env(qs_env=qs_env, &
904 : cell=cell, &
905 : dft_control=dft_control, &
906 : force=force, &
907 : ks_env=ks_env, &
908 : matrix_s=matrix_s, &
909 : para_env=para_env, &
910 : pw_env=pw_env, &
911 : rho=rho, &
912 : rho_xc=rho_xc, &
913 : rho_nlcc=rho_nlcc, &
914 212 : virial=virial)
915 212 : CPASSERT(ASSOCIATED(pw_env))
916 :
917 212 : nspins = dft_control%nspins
918 212 : use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
919 :
920 212 : fconv = 1.0E-9_dp*pascal/cell%deth
921 212 : IF (debug_stress .AND. use_virial) THEN
922 0 : sttot = virial%pv_virial
923 : END IF
924 :
925 : ! check for GAPW/GAPW_XC
926 212 : gapw = dft_control%qs_control%gapw
927 212 : gapw_xc = dft_control%qs_control%gapw_xc
928 212 : IF (gapw_xc) THEN
929 12 : CPASSERT(ASSOCIATED(rho_xc))
930 : END IF
931 212 : IF (gapw .OR. gapw_xc) THEN
932 38 : IF (use_virial) THEN
933 0 : CPABORT("DC-DFT + GAPW + Stress NYA")
934 : END IF
935 : END IF
936 :
937 : ! Get density matrix of reference calculation
938 212 : CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
939 :
940 212 : NULLIFY (hartree_local, local_rho_set)
941 212 : IF (gapw .OR. gapw_xc) THEN
942 : CALL get_qs_env(qs_env, &
943 : atomic_kind_set=atomic_kind_set, &
944 38 : qs_kind_set=qs_kind_set)
945 38 : CALL local_rho_set_create(local_rho_set)
946 : CALL allocate_rho_atom_internals(local_rho_set%rho_atom_set, atomic_kind_set, &
947 38 : qs_kind_set, dft_control, para_env)
948 38 : IF (gapw) THEN
949 26 : CALL get_qs_env(qs_env, natom=natom)
950 26 : CALL init_rho0(local_rho_set, qs_env, dft_control%qs_control%gapw_control)
951 26 : CALL rho0_s_grid_create(pw_env, local_rho_set%rho0_mpole)
952 26 : CALL hartree_local_create(hartree_local)
953 26 : CALL init_coulomb_local(hartree_local, natom)
954 : END IF
955 :
956 38 : CALL get_qs_env(qs_env=qs_env, oce=oce, sab_orb=sab_orb)
957 : CALL calculate_rho_atom_coeff(qs_env, matrix_p, local_rho_set%rho_atom_set, &
958 38 : qs_kind_set, oce, sab_orb, para_env)
959 38 : CALL prepare_gapw_den(qs_env, local_rho_set, do_rho0=gapw)
960 : END IF
961 :
962 212 : NULLIFY (auxbas_pw_pool, poisson_env)
963 : ! gets the tmp grids
964 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
965 212 : poisson_env=poisson_env)
966 :
967 : ! Calculate the Hartree potential
968 212 : CALL auxbas_pw_pool%create_pw(v_hartree_gspace)
969 212 : CALL auxbas_pw_pool%create_pw(rho_tot_gspace)
970 212 : CALL auxbas_pw_pool%create_pw(v_hartree_rspace)
971 :
972 : ! Get the total input density in g-space [ions + electrons]
973 212 : CALL calc_rho_tot_gspace(rho_tot_gspace, qs_env, rho)
974 :
975 : ! v_H[n_in]
976 212 : IF (use_virial) THEN
977 :
978 : ! Stress tensor - Volume and Green function contribution
979 56 : h_stress(:, :) = 0.0_dp
980 : CALL pw_poisson_solve(poisson_env, &
981 : density=rho_tot_gspace, &
982 : ehartree=ehartree, &
983 : vhartree=v_hartree_gspace, &
984 56 : h_stress=h_stress)
985 :
986 728 : virial%pv_ehartree = virial%pv_ehartree + h_stress/REAL(para_env%num_pe, dp)
987 728 : virial%pv_virial = virial%pv_virial + h_stress/REAL(para_env%num_pe, dp)
988 :
989 56 : IF (debug_stress) THEN
990 0 : stdeb = fconv*(h_stress/REAL(para_env%num_pe, dp))
991 0 : CALL para_env%sum(stdeb)
992 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
993 0 : 'STRESS| GREEN 1st V_H[n_in]*n_in ', one_third_sum_diag(stdeb), det_3x3(stdeb)
994 : END IF
995 :
996 : ELSE
997 : CALL pw_poisson_solve(poisson_env, rho_tot_gspace, ehartree, &
998 156 : v_hartree_gspace)
999 : END IF
1000 :
1001 212 : CALL pw_transfer(v_hartree_gspace, v_hartree_rspace)
1002 212 : CALL pw_scale(v_hartree_rspace, v_hartree_rspace%pw_grid%dvol)
1003 :
1004 : ! Save density on real space grid for use in properties
1005 212 : CALL qs_rho_get(rho, rho_r=rho_r)
1006 850 : ALLOCATE (ec_env%rhoout_r(nspins))
1007 426 : DO ispin = 1, nspins
1008 214 : CALL auxbas_pw_pool%create_pw(ec_env%rhoout_r(ispin))
1009 426 : CALL pw_copy(rho_r(ispin), ec_env%rhoout_r(ispin))
1010 : END DO
1011 :
1012 : ! Getting nuclear force contribution from the core charge density
1013 : ! Vh(rho_c + rho_in)
1014 314 : IF (debug_forces) fodeb(1:3) = force(1)%rho_core(1:3, 1)
1015 212 : IF (debug_stress .AND. use_virial) stdeb = virial%pv_ehartree
1016 212 : CALL integrate_v_core_rspace(v_hartree_rspace, qs_env)
1017 212 : IF (debug_forces) THEN
1018 136 : fodeb(1:3) = force(1)%rho_core(1:3, 1) - fodeb(1:3)
1019 34 : CALL para_env%sum(fodeb)
1020 34 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Vtot*dncore", fodeb
1021 : END IF
1022 212 : IF (debug_stress .AND. use_virial) THEN
1023 0 : stdeb = fconv*(virial%pv_ehartree - stdeb)
1024 0 : CALL para_env%sum(stdeb)
1025 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
1026 0 : 'STRESS| Vtot*dncore', one_third_sum_diag(stdeb), det_3x3(stdeb)
1027 : END IF
1028 :
1029 : ! v_XC[n_in]_DC
1030 : ! v_rspace and v_tau_rspace are generated from the auxbas pool
1031 212 : NULLIFY (v_rspace, v_tau_rspace)
1032 :
1033 : ! only activate stress calculation if
1034 212 : IF (use_virial) virial%pv_calculate = .TRUE.
1035 :
1036 : ! Exchange-correlation potential
1037 212 : IF (gapw_xc) THEN
1038 12 : CALL get_qs_env(qs_env=qs_env, rho_xc=rho_struct)
1039 : ELSE
1040 200 : CALL get_qs_env(qs_env=qs_env, rho=rho_struct)
1041 : END IF
1042 : CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho_struct, xc_section=ec_env%xc_section, &
1043 : vxc_rho=v_rspace, vxc_tau=v_tau_rspace, exc=exc, just_energy=.FALSE., &
1044 212 : edisp=edisp, dispersion_env=ec_env%dispersion_env)
1045 :
1046 314 : IF (debug_forces) fodeb(1:3) = force(1)%rho_elec(1:3, 1)
1047 212 : IF (debug_stress .AND. use_virial) stdeb = virial%pv_virial
1048 : !
1049 212 : NULLIFY (rho1)
1050 212 : CALL accint_weight_force(qs_env, rho_struct, rho1, 0, ec_env%xc_section)
1051 : !
1052 212 : IF (debug_forces) THEN
1053 136 : fodeb(1:3) = force(1)%rho_elec(1:3, 1) - fodeb(1:3)
1054 34 : CALL para_env%sum(fodeb)
1055 34 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Fxc*dw ", fodeb
1056 : END IF
1057 212 : IF (debug_stress .AND. use_virial) THEN
1058 0 : stdeb = fconv*(virial%pv_virial - stdeb)
1059 0 : CALL para_env%sum(stdeb)
1060 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
1061 0 : 'STRESS| INT Fxc*dw ', one_third_sum_diag(stdeb), det_3x3(stdeb)
1062 : END IF
1063 :
1064 212 : IF (.NOT. ASSOCIATED(v_rspace)) THEN
1065 0 : ALLOCATE (v_rspace(nspins))
1066 0 : DO ispin = 1, nspins
1067 0 : CALL auxbas_pw_pool%create_pw(v_rspace(ispin))
1068 0 : CALL pw_zero(v_rspace(ispin))
1069 : END DO
1070 : END IF
1071 :
1072 212 : IF (use_virial) THEN
1073 728 : virial%pv_exc = virial%pv_exc - virial%pv_xc
1074 728 : virial%pv_virial = virial%pv_virial - virial%pv_xc
1075 : ! virial%pv_xc will be zeroed in the xc routines
1076 : END IF
1077 :
1078 : ! initialize srcm matrix
1079 212 : NULLIFY (scrm)
1080 212 : CALL dbcsr_allocate_matrix_set(scrm, nspins)
1081 426 : DO ispin = 1, nspins
1082 214 : ALLOCATE (scrm(ispin)%matrix)
1083 214 : CALL dbcsr_create(scrm(ispin)%matrix, template=ec_env%matrix_ks(ispin, 1)%matrix)
1084 214 : CALL dbcsr_copy(scrm(ispin)%matrix, ec_env%matrix_ks(ispin, 1)%matrix)
1085 426 : CALL dbcsr_set(scrm(ispin)%matrix, 0.0_dp)
1086 : END DO
1087 :
1088 212 : pw_grid => v_hartree_rspace%pw_grid
1089 638 : ALLOCATE (v_rspace_in(nspins))
1090 426 : DO ispin = 1, nspins
1091 426 : CALL v_rspace_in(ispin)%create(pw_grid)
1092 : END DO
1093 :
1094 : ! v_rspace_in = v_H[n_in] + v_xc[n_in] calculated in ks_ref_potential
1095 426 : DO ispin = 1, nspins
1096 : ! v_xc[n_in]_GS
1097 214 : CALL pw_transfer(ec_env%vxc_rspace(ispin), v_rspace_in(ispin))
1098 426 : IF (.NOT. gapw_xc) THEN
1099 : ! add v_H[n_in] this is not really needed, see further down
1100 : ! but we do it for historical reasons
1101 : ! for gapw_xc we have to skip it as it is not integrated on the same grid
1102 202 : CALL pw_axpy(ec_env%vh_rspace, v_rspace_in(ispin))
1103 : END IF
1104 : END DO
1105 :
1106 : ! If hybrid functional in DC-DFT
1107 212 : ec_hfx_sections => section_vals_get_subs_vals(qs_env%input, "DFT%ENERGY_CORRECTION%XC%HF")
1108 212 : CALL section_vals_get(ec_hfx_sections, explicit=do_ec_hfx)
1109 :
1110 212 : IF (do_ec_hfx) THEN
1111 :
1112 44 : IF ((gapw .OR. gapw_xc) .AND. ec_env%do_ec_admm) THEN
1113 0 : CALL get_qs_env(qs_env, admm_env=admm_env)
1114 0 : IF (admm_env%aux_exch_func /= do_admm_aux_exch_func_none) THEN
1115 : ! define proper xc_section
1116 0 : CPABORT("GAPW HFX ADMM + Energy Correction NYA")
1117 : END IF
1118 : END IF
1119 :
1120 80 : IF (debug_forces) fodeb(1:3) = force(1)%fock_4c(1:3, 1)
1121 80 : IF (debug_forces) fodeb2(1:3) = force(1)%overlap_admm(1:3, 1)
1122 :
1123 : ! Calculate direct HFX forces here
1124 : ! Virial contribution (fock_4c) done inside calculate_exx
1125 44 : dummy_real = 0.0_dp
1126 : CALL calculate_exx(qs_env=qs_env, &
1127 : unit_nr=iounit, &
1128 : hfx_sections=ec_hfx_sections, &
1129 : x_data=ec_env%x_data, &
1130 : do_gw=.FALSE., &
1131 : do_admm=ec_env%do_ec_admm, &
1132 : calc_forces=.TRUE., &
1133 : reuse_hfx=ec_env%reuse_hfx, &
1134 : do_im_time=.FALSE., &
1135 : E_ex_from_GW=dummy_real, &
1136 : E_admm_from_GW=dummy_real2, &
1137 44 : t3=dummy_real)
1138 :
1139 44 : IF (debug_forces) THEN
1140 48 : fodeb(1:3) = force(1)%fock_4c(1:3, 1) - fodeb(1:3)
1141 12 : CALL para_env%sum(fodeb)
1142 12 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: P*hfx_DC ", fodeb
1143 :
1144 48 : fodeb2(1:3) = force(1)%overlap_admm(1:3, 1) - fodeb2(1:3)
1145 12 : CALL para_env%sum(fodeb2)
1146 12 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: P*hfx_DC*S ", fodeb2
1147 : END IF
1148 44 : IF (debug_stress .AND. use_virial) THEN
1149 0 : stdeb = -1.0_dp*fconv*virial%pv_fock_4c
1150 0 : CALL para_env%sum(stdeb)
1151 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
1152 0 : 'STRESS| P*hfx_DC ', one_third_sum_diag(stdeb), det_3x3(stdeb)
1153 : END IF
1154 :
1155 : END IF
1156 :
1157 : ! Stress-tensor contribution derivative of integrand
1158 : ! int v_Hxc[n_in]*n_out
1159 212 : IF (use_virial) THEN
1160 728 : pv_loc = virial%pv_virial
1161 : END IF
1162 :
1163 212 : IF (ASSOCIATED(rho_nlcc)) THEN
1164 8 : DO ispin = 1, nspins
1165 : CALL integrate_rho_nlcc(v_rspace(ispin), qs_env, &
1166 8 : debug_forces, debug_stress, "dnlcc*dVxc")
1167 : END DO
1168 : END IF
1169 :
1170 212 : basis_type = "HARRIS"
1171 212 : IF (gapw .OR. gapw_xc) THEN
1172 38 : task_list => ec_env%task_list_soft
1173 : ELSE
1174 174 : task_list => ec_env%task_list
1175 : END IF
1176 :
1177 314 : IF (debug_forces) fodeb(1:3) = force(1)%rho_elec(1:3, 1)
1178 212 : IF (debug_stress .AND. use_virial) stdeb = virial%pv_virial
1179 :
1180 426 : DO ispin = 1, nspins
1181 : ! Add v_H[n_in] + v_xc[n_in] = v_rspace
1182 214 : CALL pw_scale(v_rspace(ispin), v_rspace(ispin)%pw_grid%dvol)
1183 426 : IF (gapw_xc) THEN
1184 : ! integrate over potential <a|Vxc|b>
1185 : CALL integrate_v_rspace(v_rspace=v_rspace(ispin), &
1186 : hmat=scrm(ispin), &
1187 : pmat=matrix_p(ispin, 1), &
1188 : qs_env=qs_env, &
1189 : calculate_forces=.TRUE., &
1190 : basis_type=basis_type, &
1191 12 : task_list_external=task_list)
1192 : ! integrate over potential <a|Vh|b>
1193 : CALL integrate_v_rspace(v_rspace=v_hartree_rspace, &
1194 : hmat=scrm(ispin), &
1195 : pmat=matrix_p(ispin, 1), &
1196 : qs_env=qs_env, &
1197 : calculate_forces=.TRUE., &
1198 : basis_type=basis_type, &
1199 12 : task_list_external=ec_env%task_list)
1200 : ELSE
1201 202 : CALL pw_axpy(v_hartree_rspace, v_rspace(ispin))
1202 : ! integrate over potential <a|V|b>
1203 : CALL integrate_v_rspace(v_rspace=v_rspace(ispin), &
1204 : hmat=scrm(ispin), &
1205 : pmat=matrix_p(ispin, 1), &
1206 : qs_env=qs_env, &
1207 : calculate_forces=.TRUE., &
1208 : basis_type=basis_type, &
1209 202 : task_list_external=task_list)
1210 : END IF
1211 : END DO
1212 :
1213 212 : IF (debug_forces) THEN
1214 136 : fodeb(1:3) = force(1)%rho_elec(1:3, 1) - fodeb(1:3)
1215 34 : CALL para_env%sum(fodeb)
1216 34 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dVhxc ", fodeb
1217 : END IF
1218 212 : IF (debug_stress .AND. use_virial) THEN
1219 0 : stdeb = fconv*(virial%pv_virial - stdeb)
1220 0 : CALL para_env%sum(stdeb)
1221 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
1222 0 : 'STRESS| INT Pout*dVhxc ', one_third_sum_diag(stdeb), det_3x3(stdeb)
1223 : END IF
1224 :
1225 212 : IF (ASSOCIATED(v_tau_rspace)) THEN
1226 84 : IF (debug_forces) fodeb(1:3) = force(1)%rho_elec(1:3, 1)
1227 36 : IF (debug_stress .AND. use_virial) stdeb = virial%pv_virial
1228 74 : DO ispin = 1, nspins
1229 38 : CALL pw_scale(v_tau_rspace(ispin), v_tau_rspace(ispin)%pw_grid%dvol)
1230 : ! integrate over Tau-potential <nabla.a|V|nabla.b>
1231 : CALL integrate_v_rspace(v_rspace=v_tau_rspace(ispin), &
1232 : hmat=scrm(ispin), &
1233 : pmat=matrix_p(ispin, 1), &
1234 : qs_env=qs_env, &
1235 : calculate_forces=.TRUE., &
1236 : compute_tau=.TRUE., &
1237 : basis_type=basis_type, &
1238 74 : task_list_external=task_list)
1239 : END DO
1240 :
1241 36 : IF (debug_forces) THEN
1242 64 : fodeb(1:3) = force(1)%rho_elec(1:3, 1) - fodeb(1:3)
1243 16 : CALL para_env%sum(fodeb)
1244 16 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dVhxc_tau ", fodeb
1245 : END IF
1246 36 : IF (debug_stress .AND. use_virial) THEN
1247 0 : stdeb = fconv*(virial%pv_virial - stdeb)
1248 0 : CALL para_env%sum(stdeb)
1249 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
1250 0 : 'STRESS| INT Pout*dVhxc_tau ', one_third_sum_diag(stdeb), det_3x3(stdeb)
1251 : END IF
1252 : END IF
1253 :
1254 212 : IF (gapw .OR. gapw_xc) THEN
1255 38 : exc1 = 0.0_dp
1256 : CALL calculate_vxc_atom(qs_env, .FALSE., exc1, &
1257 : rho_atom_set_external=local_rho_set%rho_atom_set, &
1258 38 : xc_section_external=ec_env%xc_section)
1259 : END IF
1260 212 : IF (gapw) THEN
1261 86 : IF (debug_forces) fodeb(1:3) = force(1)%g0s_Vh_elec(1:3, 1)
1262 : CALL integrate_vhg0_rspace(qs_env, v_hartree_rspace, para_env, &
1263 26 : calculate_forces=.TRUE., local_rho_set=local_rho_set)
1264 26 : IF (debug_forces) THEN
1265 80 : fodeb(1:3) = force(1)%g0s_Vh_elec(1:3, 1) - fodeb(1:3)
1266 20 : CALL para_env%sum(fodeb)
1267 20 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: P*g0s_Vh_elec ", fodeb
1268 : END IF
1269 : ehartree_1c = 0.0_dp
1270 : CALL Vh_1c_gg_integrals(qs_env, ehartree_1c, hartree_local%ecoul_1c, local_rho_set, &
1271 26 : para_env, tddft=.FALSE., core_2nd=.FALSE.)
1272 : END IF
1273 :
1274 212 : IF (gapw .OR. gapw_xc) THEN
1275 : ! Single atom contributions in the KS matrix ***
1276 134 : IF (debug_forces) fodeb(1:3) = force(1)%vhxc_atom(1:3, 1)
1277 : CALL update_ks_atom(qs_env, scrm, matrix_p, forces=.TRUE., &
1278 38 : rho_atom_external=local_rho_set%rho_atom_set)
1279 38 : IF (debug_forces) THEN
1280 128 : fodeb(1:3) = force(1)%vhxc_atom(1:3, 1) - fodeb(1:3)
1281 32 : CALL para_env%sum(fodeb)
1282 32 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: P*vhxc_atom ", fodeb
1283 : END IF
1284 : END IF
1285 :
1286 : ! Stress-tensor
1287 212 : IF (use_virial) THEN
1288 728 : virial%pv_ehartree = virial%pv_ehartree + (virial%pv_virial - pv_loc)
1289 : END IF
1290 :
1291 : ! delete scrm matrix
1292 212 : CALL dbcsr_deallocate_matrix_set(scrm)
1293 :
1294 : !----------------------------------------------------
1295 : ! Right-hand-side matrix B for linear response equations AX = B
1296 : !----------------------------------------------------
1297 :
1298 : ! RHS = int v_Hxc[n]_DC - v_Hxc[n]_GS dr + alpha_DC * E_X[n] - alpha_gs * E_X[n]
1299 : ! = int v_Hxc[n]_DC - v_Hxc[n]_GS dr + alpha_DC / alpha_GS * E_X[n]_GS - E_X[n]_GS
1300 : !
1301 : ! with v_Hxc[n] = v_H[n] + v_xc[n]
1302 : !
1303 : ! Actually v_H[n_in] same for DC and GS, just there for convenience (v_H skipped for GAPW_XC)
1304 : ! v_xc[n_in]_GS = 0 if GS is HF BUT =/0 if hybrid
1305 : ! so, we keep this general form
1306 :
1307 212 : NULLIFY (ec_env%matrix_hz)
1308 212 : CALL dbcsr_allocate_matrix_set(ec_env%matrix_hz, nspins)
1309 426 : DO ispin = 1, nspins
1310 214 : ALLOCATE (ec_env%matrix_hz(ispin)%matrix)
1311 214 : CALL dbcsr_create(ec_env%matrix_hz(ispin)%matrix, template=matrix_s(1)%matrix)
1312 214 : CALL dbcsr_copy(ec_env%matrix_hz(ispin)%matrix, matrix_s(1)%matrix)
1313 426 : CALL dbcsr_set(ec_env%matrix_hz(ispin)%matrix, 0.0_dp)
1314 : END DO
1315 :
1316 426 : DO ispin = 1, nspins
1317 : ! v_rspace = v_rspace - v_rspace_in
1318 : ! = v_Hxc[n_in]_DC - v_Hxc[n_in]_GS
1319 426 : CALL pw_axpy(v_rspace_in(ispin), v_rspace(ispin), -1.0_dp)
1320 : END DO
1321 :
1322 426 : DO ispin = 1, nspins
1323 : CALL integrate_v_rspace(v_rspace=v_rspace(ispin), &
1324 : hmat=ec_env%matrix_hz(ispin), &
1325 : pmat=matrix_p(ispin, 1), &
1326 : qs_env=qs_env, &
1327 : calculate_forces=.FALSE., &
1328 : basis_type=basis_type, &
1329 426 : task_list_external=task_list)
1330 : END DO
1331 :
1332 : ! Check if mGGA functionals are used
1333 212 : IF (dft_control%use_kinetic_energy_density) THEN
1334 :
1335 : ! If DC-DFT without mGGA functional, this needs to be allocated now.
1336 52 : IF (.NOT. ASSOCIATED(v_tau_rspace)) THEN
1337 48 : ALLOCATE (v_tau_rspace(nspins))
1338 32 : DO ispin = 1, nspins
1339 16 : CALL auxbas_pw_pool%create_pw(v_tau_rspace(ispin))
1340 32 : CALL pw_zero(v_tau_rspace(ispin))
1341 : END DO
1342 : END IF
1343 :
1344 106 : DO ispin = 1, nspins
1345 : ! v_tau_rspace = v_Hxc_tau[n_in]_DC - v_Hxc_tau[n_in]_GS
1346 54 : IF (ASSOCIATED(ec_env%vtau_rspace)) THEN
1347 16 : CALL pw_axpy(ec_env%vtau_rspace(ispin), v_tau_rspace(ispin), -1.0_dp)
1348 : END IF
1349 : ! integrate over Tau-potential <nabla.a|V|nabla.b>
1350 : CALL integrate_v_rspace(v_rspace=v_tau_rspace(ispin), &
1351 : hmat=ec_env%matrix_hz(ispin), &
1352 : pmat=matrix_p(ispin, 1), &
1353 : qs_env=qs_env, &
1354 : calculate_forces=.FALSE., compute_tau=.TRUE., &
1355 : basis_type=basis_type, &
1356 106 : task_list_external=task_list)
1357 : END DO
1358 : END IF
1359 :
1360 212 : IF (gapw .OR. gapw_xc) THEN
1361 : ! Single atom contributions in the KS matrix ***
1362 : ! DC-DFT
1363 : CALL update_ks_atom(qs_env, ec_env%matrix_hz, matrix_p, .FALSE., &
1364 38 : rho_atom_external=local_rho_set%rho_atom_set, kintegral=1.0_dp)
1365 : ! Ref
1366 : CALL update_ks_atom(qs_env, ec_env%matrix_hz, matrix_p, .FALSE., &
1367 38 : rho_atom_external=ec_env%local_rho_set%rho_atom_set, kintegral=-1.0_dp)
1368 : END IF
1369 :
1370 : ! Need to also subtract HFX contribution of reference calculation from ec_env%matrix_hz
1371 : ! and/or add HFX contribution if DC-DFT ueses hybrid XC-functional
1372 : CALL add_exx_to_rhs(rhs=ec_env%matrix_hz, &
1373 : qs_env=qs_env, &
1374 : ext_hfx_section=ec_hfx_sections, &
1375 : x_data=ec_env%x_data, &
1376 : recalc_integrals=.FALSE., &
1377 : do_admm=ec_env%do_ec_admm, &
1378 : do_ec=.TRUE., &
1379 : do_exx=.FALSE., &
1380 212 : reuse_hfx=ec_env%reuse_hfx)
1381 :
1382 : ! Core overlap
1383 314 : IF (debug_forces) fodeb(1:3) = force(1)%core_overlap(1:3, 1)
1384 212 : IF (debug_stress .AND. use_virial) stdeb = virial%pv_ecore_overlap
1385 212 : CALL calculate_ecore_overlap(qs_env, para_env, .TRUE., E_overlap_core=eovrl)
1386 212 : IF (debug_forces) THEN
1387 136 : fodeb(1:3) = force(1)%core_overlap(1:3, 1) - fodeb(1:3)
1388 34 : CALL para_env%sum(fodeb)
1389 34 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: CoreOverlap", fodeb
1390 : END IF
1391 212 : IF (debug_stress .AND. use_virial) THEN
1392 0 : stdeb = fconv*(stdeb - virial%pv_ecore_overlap)
1393 0 : CALL para_env%sum(stdeb)
1394 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
1395 0 : 'STRESS| CoreOverlap ', one_third_sum_diag(stdeb), det_3x3(stdeb)
1396 : END IF
1397 :
1398 212 : IF (debug_forces) THEN
1399 34 : CALL get_qs_env(qs_env, natom=natom, atomic_kind_set=atomic_kind_set)
1400 102 : ALLOCATE (ftot(3, natom))
1401 34 : CALL total_qs_force(ftot, force, atomic_kind_set)
1402 136 : fodeb(1:3) = ftot(1:3, 1)
1403 34 : DEALLOCATE (ftot)
1404 34 : CALL para_env%sum(fodeb)
1405 34 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Force Explicit", fodeb
1406 : END IF
1407 :
1408 : ! return gapw arrays
1409 212 : IF (gapw .OR. gapw_xc) THEN
1410 38 : CALL local_rho_set_release(local_rho_set)
1411 : END IF
1412 212 : IF (gapw) THEN
1413 26 : CALL hartree_local_release(hartree_local)
1414 : END IF
1415 :
1416 : ! return pw grids
1417 426 : DO ispin = 1, nspins
1418 214 : CALL auxbas_pw_pool%give_back_pw(v_rspace(ispin))
1419 214 : CALL auxbas_pw_pool%give_back_pw(v_rspace_in(ispin))
1420 426 : IF (ASSOCIATED(v_tau_rspace)) THEN
1421 54 : CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
1422 : END IF
1423 : END DO
1424 :
1425 212 : DEALLOCATE (v_rspace, v_rspace_in)
1426 212 : IF (ASSOCIATED(v_tau_rspace)) DEALLOCATE (v_tau_rspace)
1427 : !
1428 212 : CALL auxbas_pw_pool%give_back_pw(rho_tot_gspace)
1429 212 : CALL auxbas_pw_pool%give_back_pw(v_hartree_gspace)
1430 212 : CALL auxbas_pw_pool%give_back_pw(v_hartree_rspace)
1431 :
1432 : ! Stress tensor - volume terms need to be stored,
1433 : ! for a sign correction in QS at the end of qs_force
1434 212 : IF (use_virial) THEN
1435 56 : IF (qs_env%energy_correction) THEN
1436 56 : ec_env%ehartree = ehartree
1437 56 : ec_env%exc = exc
1438 56 : IF (edisp /= 0.0_dp) ec_env%edispersion = edisp
1439 : END IF
1440 : END IF
1441 :
1442 212 : IF (debug_stress .AND. use_virial) THEN
1443 : ! In total: -1.0*E_H
1444 0 : stdeb = -1.0_dp*fconv*ehartree
1445 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
1446 0 : 'STRESS| VOL 1st v_H[n_in]*n_in', one_third_sum_diag(stdeb), det_3x3(stdeb)
1447 :
1448 0 : stdeb = -1.0_dp*fconv*exc
1449 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
1450 0 : 'STRESS| VOL 1st E_XC_DC[n_in]', one_third_sum_diag(stdeb), det_3x3(stdeb)
1451 :
1452 : ! For debugging, create a second virial environment,
1453 : ! apply volume terms immediately
1454 : BLOCK
1455 : TYPE(virial_type) :: virdeb
1456 0 : virdeb = virial
1457 :
1458 0 : CALL para_env%sum(virdeb%pv_overlap)
1459 0 : CALL para_env%sum(virdeb%pv_ekinetic)
1460 0 : CALL para_env%sum(virdeb%pv_ppl)
1461 0 : CALL para_env%sum(virdeb%pv_ppnl)
1462 0 : CALL para_env%sum(virdeb%pv_ecore_overlap)
1463 0 : CALL para_env%sum(virdeb%pv_ehartree)
1464 0 : CALL para_env%sum(virdeb%pv_exc)
1465 0 : CALL para_env%sum(virdeb%pv_exx)
1466 0 : CALL para_env%sum(virdeb%pv_vdw)
1467 0 : CALL para_env%sum(virdeb%pv_mp2)
1468 0 : CALL para_env%sum(virdeb%pv_nlcc)
1469 0 : CALL para_env%sum(virdeb%pv_gapw)
1470 0 : CALL para_env%sum(virdeb%pv_lrigpw)
1471 0 : CALL para_env%sum(virdeb%pv_virial)
1472 0 : CALL symmetrize_virial(virdeb)
1473 :
1474 : ! apply stress-tensor 1st terms
1475 0 : DO i = 1, 3
1476 0 : virdeb%pv_ehartree(i, i) = virdeb%pv_ehartree(i, i) - 2.0_dp*ehartree
1477 : virdeb%pv_virial(i, i) = virdeb%pv_virial(i, i) - exc &
1478 0 : - 2.0_dp*ehartree
1479 0 : virdeb%pv_exc(i, i) = virdeb%pv_exc(i, i) - exc
1480 : ! The factor 2 is a hack. It compensates the plus sign in h_stress/pw_poisson_solve.
1481 : ! The sign in pw_poisson_solve is correct for FIST, but not for QS.
1482 : ! There should be a more elegant solution to that ...
1483 : END DO
1484 :
1485 0 : CALL para_env%sum(sttot)
1486 0 : stdeb = fconv*(virdeb%pv_virial - sttot)
1487 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
1488 0 : 'STRESS| Explicit electronic stress ', one_third_sum_diag(stdeb), det_3x3(stdeb)
1489 :
1490 0 : stdeb = fconv*(virdeb%pv_virial)
1491 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
1492 0 : 'STRESS| Explicit total stress ', one_third_sum_diag(stdeb), det_3x3(stdeb)
1493 :
1494 0 : unit_string = "GPa" ! old default
1495 0 : CALL write_stress_tensor_components(virdeb, iounit, cell, unit_string)
1496 0 : CALL write_stress_tensor(virdeb%pv_virial, iounit, cell, unit_string, .FALSE.)
1497 :
1498 : END BLOCK
1499 : END IF
1500 :
1501 212 : CALL timestop(handle)
1502 :
1503 636 : END SUBROUTINE ec_dc_build_ks_matrix_force
1504 :
1505 : ! **************************************************************************************************
1506 : !> \brief ...
1507 : !> \param qs_env ...
1508 : !> \param ec_env ...
1509 : !> \param calculate_forces ...
1510 : ! **************************************************************************************************
1511 1216 : SUBROUTINE ec_disp(qs_env, ec_env, calculate_forces)
1512 : TYPE(qs_environment_type), POINTER :: qs_env
1513 : TYPE(energy_correction_type), POINTER :: ec_env
1514 : LOGICAL, INTENT(IN) :: calculate_forces
1515 :
1516 : REAL(KIND=dp) :: edisp, egcp
1517 :
1518 1216 : egcp = 0.0_dp
1519 1216 : CALL calculate_dispersion_pairpot(qs_env, ec_env%dispersion_env, edisp, calculate_forces)
1520 1216 : IF (.NOT. calculate_forces) THEN
1521 718 : ec_env%edispersion = ec_env%edispersion + edisp + egcp
1522 : END IF
1523 :
1524 1216 : END SUBROUTINE ec_disp
1525 :
1526 : ! **************************************************************************************************
1527 : !> \brief Construction of the Core Hamiltonian Matrix
1528 : !> Short version of qs_core_hamiltonian
1529 : !> \param qs_env ...
1530 : !> \param ec_env ...
1531 : !> \author Creation (03.2014,JGH)
1532 : ! **************************************************************************************************
1533 374 : SUBROUTINE ec_build_core_hamiltonian(qs_env, ec_env)
1534 : TYPE(qs_environment_type), POINTER :: qs_env
1535 : TYPE(energy_correction_type), POINTER :: ec_env
1536 :
1537 : CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_build_core_hamiltonian'
1538 :
1539 : CHARACTER(LEN=default_string_length) :: basis_type
1540 : INTEGER :: handle, img, nder, nhfimg, nimages
1541 : LOGICAL :: calculate_forces, use_virial
1542 374 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1543 : TYPE(dbcsr_type), POINTER :: smat
1544 : TYPE(dft_control_type), POINTER :: dft_control
1545 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1546 374 : POINTER :: sab_orb, sac_ae, sac_ppl, sap_ppnl
1547 374 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1548 374 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1549 : TYPE(qs_ks_env_type), POINTER :: ks_env
1550 :
1551 374 : CALL timeset(routineN, handle)
1552 :
1553 374 : NULLIFY (atomic_kind_set, dft_control, ks_env, particle_set, &
1554 374 : qs_kind_set)
1555 :
1556 : CALL get_qs_env(qs_env=qs_env, &
1557 : atomic_kind_set=atomic_kind_set, &
1558 : dft_control=dft_control, &
1559 : particle_set=particle_set, &
1560 : qs_kind_set=qs_kind_set, &
1561 374 : ks_env=ks_env)
1562 :
1563 : ! no k-points possible
1564 374 : nimages = dft_control%nimages
1565 374 : IF (nimages /= 1) THEN
1566 0 : CPABORT("K-points for Harris functional not implemented")
1567 : END IF
1568 :
1569 : ! check for GAPW/GAPW_XC
1570 374 : IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
1571 0 : CPABORT("Harris functional for GAPW not implemented")
1572 : END IF
1573 :
1574 : ! Do not calculate forces or stress tensor here
1575 374 : use_virial = .FALSE.
1576 374 : calculate_forces = .FALSE.
1577 :
1578 : ! get neighbor lists, we need the full sab_orb list from the ec_env
1579 374 : NULLIFY (sab_orb, sac_ae, sac_ppl, sap_ppnl)
1580 374 : sab_orb => ec_env%sab_orb
1581 374 : sac_ae => ec_env%sac_ae
1582 374 : sac_ppl => ec_env%sac_ppl
1583 374 : sap_ppnl => ec_env%sap_ppnl
1584 :
1585 374 : basis_type = "HARRIS"
1586 :
1587 374 : nder = 0
1588 : ! Overlap and kinetic energy matrices
1589 : CALL build_overlap_matrix(ks_env, matrixkp_s=ec_env%matrix_s, &
1590 : matrix_name="OVERLAP MATRIX", &
1591 : basis_type_a=basis_type, &
1592 : basis_type_b=basis_type, &
1593 374 : sab_nl=sab_orb, ext_kpoints=ec_env%kpoints)
1594 : CALL build_kinetic_matrix(ks_env, matrixkp_t=ec_env%matrix_t, &
1595 : matrix_name="KINETIC ENERGY MATRIX", &
1596 : basis_type=basis_type, &
1597 374 : sab_nl=sab_orb, ext_kpoints=ec_env%kpoints)
1598 :
1599 : ! initialize H matrix
1600 374 : nhfimg = SIZE(ec_env%matrix_s, 2)
1601 374 : CALL dbcsr_allocate_matrix_set(ec_env%matrix_h, 1, nhfimg)
1602 5776 : DO img = 1, nhfimg
1603 5402 : ALLOCATE (ec_env%matrix_h(1, img)%matrix)
1604 5402 : smat => ec_env%matrix_s(1, img)%matrix
1605 5402 : CALL dbcsr_create(ec_env%matrix_h(1, img)%matrix, template=smat)
1606 5776 : CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_h(1, img)%matrix, sab_orb)
1607 : END DO
1608 :
1609 : ! add kinetic energy
1610 5776 : DO img = 1, nhfimg
1611 : CALL dbcsr_copy(ec_env%matrix_h(1, img)%matrix, ec_env%matrix_t(1, img)%matrix, &
1612 5776 : keep_sparsity=.TRUE., name="CORE HAMILTONIAN MATRIX")
1613 : END DO
1614 :
1615 : CALL core_matrices(qs_env, ec_env%matrix_h, ec_env%matrix_p, calculate_forces, nder, &
1616 : ec_env=ec_env, ec_env_matrices=.TRUE., ext_kpoints=ec_env%kpoints, &
1617 374 : basis_type=basis_type)
1618 :
1619 : ! External field (nonperiodic case)
1620 374 : ec_env%efield_nuclear = 0.0_dp
1621 374 : CALL ec_efield_local_operator(qs_env, ec_env, calculate_forces)
1622 :
1623 374 : CALL timestop(handle)
1624 :
1625 374 : END SUBROUTINE ec_build_core_hamiltonian
1626 :
1627 : ! **************************************************************************************************
1628 : !> \brief Solve KS equation for a given matrix
1629 : !> calculate the complete KS matrix
1630 : !> \param qs_env ...
1631 : !> \param ec_env ...
1632 : !> \par History
1633 : !> 03.2014 adapted from qs_ks_build_kohn_sham_matrix [JGH]
1634 : !> \author JGH
1635 : ! **************************************************************************************************
1636 1356 : SUBROUTINE ec_build_ks_matrix(qs_env, ec_env)
1637 : TYPE(qs_environment_type), POINTER :: qs_env
1638 : TYPE(energy_correction_type), POINTER :: ec_env
1639 :
1640 : CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_build_ks_matrix'
1641 :
1642 : CHARACTER(LEN=default_string_length) :: headline
1643 : INTEGER :: handle, img, iounit, ispin, natom, &
1644 : nhfimg, nimages, nspins
1645 : LOGICAL :: calculate_forces, &
1646 : do_adiabatic_rescaling, do_ec_hfx, &
1647 : gapw, gapw_xc, hfx_treat_lsd_in_core, &
1648 : use_virial
1649 : REAL(dp) :: dummy_real, dummy_real2(2), edisp, eexc, &
1650 : eh1c, evhxc, exc1, t3
1651 : TYPE(admm_type), POINTER :: admm_env
1652 678 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1653 : TYPE(cp_logger_type), POINTER :: logger
1654 678 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_mat, ps_mat
1655 678 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp
1656 : TYPE(dbcsr_type), POINTER :: smat
1657 : TYPE(dft_control_type), POINTER :: dft_control
1658 : TYPE(hartree_local_type), POINTER :: hartree_local
1659 : TYPE(local_rho_type), POINTER :: local_rho_set_ec
1660 : TYPE(mp_para_env_type), POINTER :: para_env
1661 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1662 678 : POINTER :: sab
1663 : TYPE(oce_matrix_type), POINTER :: oce
1664 : TYPE(pw_env_type), POINTER :: pw_env
1665 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1666 678 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r, tau_r, v_rspace, v_tau_rspace
1667 : TYPE(qs_energy_type), POINTER :: energy
1668 678 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1669 : TYPE(qs_ks_env_type), POINTER :: ks_env
1670 : TYPE(qs_rho_type), POINTER :: rho, rho_xc
1671 : TYPE(section_vals_type), POINTER :: adiabatic_rescaling_section, &
1672 : ec_hfx_sections, ec_section
1673 :
1674 678 : CALL timeset(routineN, handle)
1675 :
1676 678 : logger => cp_get_default_logger()
1677 678 : IF (logger%para_env%is_source()) THEN
1678 339 : iounit = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
1679 : ELSE
1680 339 : iounit = -1
1681 : END IF
1682 :
1683 : ! get all information on the electronic density
1684 678 : NULLIFY (auxbas_pw_pool, dft_control, energy, ks_env, rho, rho_r, tau_r)
1685 : CALL get_qs_env(qs_env=qs_env, &
1686 : dft_control=dft_control, &
1687 : ks_env=ks_env, &
1688 678 : rho=rho, rho_xc=rho_xc)
1689 678 : nspins = dft_control%nspins
1690 678 : nimages = dft_control%nimages ! this is from the ref calculation
1691 678 : calculate_forces = .FALSE.
1692 678 : use_virial = .FALSE.
1693 :
1694 678 : gapw = dft_control%qs_control%gapw
1695 678 : gapw_xc = dft_control%qs_control%gapw_xc
1696 :
1697 : ! Kohn-Sham matrix
1698 678 : IF (ASSOCIATED(ec_env%matrix_ks)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_ks)
1699 678 : nhfimg = SIZE(ec_env%matrix_s, 2)
1700 678 : dft_control%nimages = nhfimg
1701 678 : CALL dbcsr_allocate_matrix_set(ec_env%matrix_ks, nspins, nhfimg)
1702 1362 : DO ispin = 1, nspins
1703 684 : headline = "KOHN-SHAM MATRIX"
1704 7074 : DO img = 1, nhfimg
1705 5712 : ALLOCATE (ec_env%matrix_ks(ispin, img)%matrix)
1706 5712 : smat => ec_env%matrix_s(1, img)%matrix
1707 : CALL dbcsr_create(ec_env%matrix_ks(ispin, img)%matrix, name=TRIM(headline), &
1708 5712 : template=smat, matrix_type=dbcsr_type_symmetric)
1709 : CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_ks(ispin, img)%matrix, &
1710 5712 : ec_env%sab_orb)
1711 6396 : CALL dbcsr_set(ec_env%matrix_ks(ispin, img)%matrix, 0.0_dp)
1712 : END DO
1713 : END DO
1714 :
1715 678 : NULLIFY (pw_env)
1716 678 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
1717 678 : CPASSERT(ASSOCIATED(pw_env))
1718 :
1719 : ! Exact exchange contribution (hybrid functionals)
1720 678 : ec_section => section_vals_get_subs_vals(qs_env%input, "DFT%ENERGY_CORRECTION")
1721 678 : ec_hfx_sections => section_vals_get_subs_vals(ec_section, "XC%HF")
1722 678 : CALL section_vals_get(ec_hfx_sections, explicit=do_ec_hfx)
1723 :
1724 678 : IF (do_ec_hfx) THEN
1725 :
1726 : ! Check what works
1727 68 : adiabatic_rescaling_section => section_vals_get_subs_vals(ec_section, "XC%ADIABATIC_RESCALING")
1728 68 : CALL section_vals_get(adiabatic_rescaling_section, explicit=do_adiabatic_rescaling)
1729 68 : IF (do_adiabatic_rescaling) THEN
1730 0 : CALL cp_abort(__LOCATION__, "Adiabatic rescaling NYI for energy correction")
1731 : END IF
1732 68 : CALL section_vals_val_get(ec_hfx_sections, "TREAT_LSD_IN_CORE", l_val=hfx_treat_lsd_in_core)
1733 68 : IF (hfx_treat_lsd_in_core) THEN
1734 0 : CALL cp_abort(__LOCATION__, "HFX_TREAT_LSD_IN_CORE NYI for energy correction")
1735 : END IF
1736 68 : IF (ec_env%do_kpoints) THEN
1737 0 : CALL cp_abort(__LOCATION__, "HFX and K-points NYI for energy correction")
1738 : END IF
1739 :
1740 : ! calculate the density matrix for the fitted mo_coeffs
1741 68 : IF (dft_control%do_admm) THEN
1742 20 : IF (dft_control%do_admm_mo) THEN
1743 20 : CPASSERT(.NOT. qs_env%run_rtp)
1744 20 : CALL admm_mo_calc_rho_aux(qs_env)
1745 0 : ELSE IF (dft_control%do_admm_dm) THEN
1746 0 : CALL admm_dm_calc_rho_aux(qs_env)
1747 : END IF
1748 : END IF
1749 :
1750 : ! Get exact exchange energy
1751 68 : dummy_real = 0.0_dp
1752 68 : t3 = 0.0_dp
1753 68 : CALL get_qs_env(qs_env, energy=energy)
1754 : CALL calculate_exx(qs_env=qs_env, &
1755 : unit_nr=iounit, &
1756 : hfx_sections=ec_hfx_sections, &
1757 : x_data=ec_env%x_data, &
1758 : do_gw=.FALSE., &
1759 : do_admm=ec_env%do_ec_admm, &
1760 : calc_forces=.FALSE., &
1761 : reuse_hfx=ec_env%reuse_hfx, &
1762 : do_im_time=.FALSE., &
1763 : E_ex_from_GW=dummy_real, &
1764 : E_admm_from_GW=dummy_real2, &
1765 68 : t3=dummy_real)
1766 :
1767 : ! Save exchange energy
1768 68 : ec_env%ex = energy%ex
1769 : ! Save EXX ADMM XC correction
1770 68 : IF (ec_env%do_ec_admm) THEN
1771 12 : ec_env%exc_aux_fit = energy%exc_aux_fit + energy%exc
1772 : END IF
1773 :
1774 : ! Add exact echange contribution of EC to EC Hamiltonian
1775 : ! do_ec = .FALSE prevents subtraction of HFX contribution of reference calculation
1776 : ! do_exx = .FALSE. prevents subtraction of reference XC contribution
1777 68 : ks_mat => ec_env%matrix_ks(:, 1)
1778 : CALL add_exx_to_rhs(rhs=ks_mat, &
1779 : qs_env=qs_env, &
1780 : ext_hfx_section=ec_hfx_sections, &
1781 : x_data=ec_env%x_data, &
1782 : recalc_integrals=.FALSE., &
1783 : do_admm=ec_env%do_ec_admm, &
1784 : do_ec=.FALSE., &
1785 : do_exx=.FALSE., &
1786 68 : reuse_hfx=ec_env%reuse_hfx)
1787 :
1788 : END IF
1789 :
1790 : ! v_rspace and v_tau_rspace are generated from the auxbas pool
1791 678 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
1792 678 : NULLIFY (v_rspace, v_tau_rspace)
1793 678 : IF (dft_control%qs_control%gapw_xc) THEN
1794 : CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho_xc, xc_section=ec_env%xc_section, &
1795 : vxc_rho=v_rspace, vxc_tau=v_tau_rspace, exc=eexc, just_energy=.FALSE., &
1796 36 : edisp=edisp, dispersion_env=ec_env%dispersion_env)
1797 : ELSE
1798 : CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho, xc_section=ec_env%xc_section, &
1799 : vxc_rho=v_rspace, vxc_tau=v_tau_rspace, exc=eexc, just_energy=.FALSE., &
1800 642 : edisp=edisp, dispersion_env=ec_env%dispersion_env)
1801 : END IF
1802 :
1803 678 : IF (.NOT. ASSOCIATED(v_rspace)) THEN
1804 0 : ALLOCATE (v_rspace(nspins))
1805 0 : DO ispin = 1, nspins
1806 0 : CALL auxbas_pw_pool%create_pw(v_rspace(ispin))
1807 0 : CALL pw_zero(v_rspace(ispin))
1808 : END DO
1809 : END IF
1810 :
1811 678 : evhxc = 0.0_dp
1812 678 : CALL qs_rho_get(rho, rho_r=rho_r)
1813 678 : IF (ASSOCIATED(v_tau_rspace)) THEN
1814 92 : CALL qs_rho_get(rho, tau_r=tau_r)
1815 : END IF
1816 1362 : DO ispin = 1, nspins
1817 : ! Add v_hartree + v_xc = v_rspace
1818 684 : CALL pw_scale(v_rspace(ispin), v_rspace(ispin)%pw_grid%dvol)
1819 684 : CALL pw_axpy(ec_env%vh_rspace, v_rspace(ispin))
1820 : ! integrate over potential <a|V|b>
1821 684 : ks_mat => ec_env%matrix_ks(ispin, :)
1822 : CALL integrate_v_rspace(v_rspace=v_rspace(ispin), &
1823 : hmat_kp=ks_mat, &
1824 : qs_env=qs_env, &
1825 : calculate_forces=.FALSE., &
1826 : basis_type="HARRIS", &
1827 684 : task_list_external=ec_env%task_list)
1828 :
1829 684 : IF (ASSOCIATED(v_tau_rspace)) THEN
1830 : ! integrate over Tau-potential <nabla.a|V|nabla.b>
1831 98 : CALL pw_scale(v_tau_rspace(ispin), v_tau_rspace(ispin)%pw_grid%dvol)
1832 : CALL integrate_v_rspace(v_rspace=v_tau_rspace(ispin), &
1833 : hmat_kp=ks_mat, &
1834 : qs_env=qs_env, &
1835 : calculate_forces=.FALSE., &
1836 : compute_tau=.TRUE., &
1837 : basis_type="HARRIS", &
1838 98 : task_list_external=ec_env%task_list)
1839 : END IF
1840 :
1841 : ! calclulate Int(vhxc*rho)dr and Int(vtau*tau)dr
1842 : evhxc = evhxc + pw_integral_ab(rho_r(ispin), v_rspace(ispin))/ &
1843 684 : v_rspace(1)%pw_grid%dvol
1844 1362 : IF (ASSOCIATED(v_tau_rspace)) THEN
1845 : evhxc = evhxc + pw_integral_ab(tau_r(ispin), v_tau_rspace(ispin))/ &
1846 98 : v_tau_rspace(ispin)%pw_grid%dvol
1847 : END IF
1848 :
1849 : END DO
1850 :
1851 678 : IF (gapw .OR. gapw_xc) THEN
1852 : ! check for basis, we can only do basis=orbital
1853 114 : IF (ec_env%basis_inconsistent) THEN
1854 0 : CPABORT("Energy corrction [GAPW] only with BASIS=ORBITAL possible")
1855 : END IF
1856 :
1857 114 : NULLIFY (hartree_local, local_rho_set_ec)
1858 : CALL get_qs_env(qs_env, para_env=para_env, &
1859 : atomic_kind_set=atomic_kind_set, &
1860 114 : qs_kind_set=qs_kind_set)
1861 114 : CALL local_rho_set_create(local_rho_set_ec)
1862 : CALL allocate_rho_atom_internals(local_rho_set_ec%rho_atom_set, atomic_kind_set, &
1863 114 : qs_kind_set, dft_control, para_env)
1864 114 : IF (gapw) THEN
1865 78 : CALL get_qs_env(qs_env, natom=natom)
1866 78 : CALL init_rho0(local_rho_set_ec, qs_env, dft_control%qs_control%gapw_control)
1867 78 : CALL rho0_s_grid_create(pw_env, local_rho_set_ec%rho0_mpole)
1868 78 : CALL hartree_local_create(hartree_local)
1869 78 : CALL init_coulomb_local(hartree_local, natom)
1870 : END IF
1871 :
1872 114 : CALL get_qs_env(qs_env=qs_env, oce=oce, sab_orb=sab)
1873 114 : CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
1874 : CALL calculate_rho_atom_coeff(qs_env, rho_ao_kp, local_rho_set_ec%rho_atom_set, &
1875 114 : qs_kind_set, oce, sab, para_env)
1876 114 : CALL prepare_gapw_den(qs_env, local_rho_set_ec, do_rho0=gapw)
1877 :
1878 : CALL calculate_vxc_atom(qs_env, .FALSE., exc1=exc1, xc_section_external=ec_env%xc_section, &
1879 114 : rho_atom_set_external=local_rho_set_ec%rho_atom_set)
1880 114 : ec_env%exc1 = exc1
1881 :
1882 114 : IF (gapw) THEN
1883 78 : CALL Vh_1c_gg_integrals(qs_env, eh1c, hartree_local%ecoul_1c, local_rho_set_ec, para_env, .FALSE.)
1884 : CALL integrate_vhg0_rspace(qs_env, ec_env%vh_rspace, para_env, calculate_forces=.FALSE., &
1885 78 : local_rho_set=local_rho_set_ec)
1886 78 : ec_env%ehartree_1c = eh1c
1887 : END IF
1888 114 : IF (dft_control%do_admm) THEN
1889 24 : CALL get_qs_env(qs_env, admm_env=admm_env)
1890 24 : IF (admm_env%aux_exch_func /= do_admm_aux_exch_func_none) THEN
1891 : ! define proper xc_section
1892 0 : CPABORT("GAPW HFX ADMM + Energy Correction NYA")
1893 : END IF
1894 : END IF
1895 :
1896 114 : ks_mat => ec_env%matrix_ks(:, 1)
1897 114 : ps_mat => ec_env%matrix_p(:, 1)
1898 : CALL update_ks_atom(qs_env, ks_mat, ps_mat, forces=.FALSE., &
1899 114 : rho_atom_external=local_rho_set_ec%rho_atom_set)
1900 :
1901 114 : CALL local_rho_set_release(local_rho_set_ec)
1902 114 : IF (gapw) THEN
1903 78 : CALL hartree_local_release(hartree_local)
1904 : END IF
1905 :
1906 : END IF
1907 :
1908 : ! return pw grids
1909 1362 : DO ispin = 1, nspins
1910 684 : CALL auxbas_pw_pool%give_back_pw(v_rspace(ispin))
1911 1362 : IF (ASSOCIATED(v_tau_rspace)) THEN
1912 98 : CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
1913 : END IF
1914 : END DO
1915 678 : DEALLOCATE (v_rspace)
1916 678 : IF (ASSOCIATED(v_tau_rspace)) DEALLOCATE (v_tau_rspace)
1917 :
1918 : ! energies
1919 678 : ec_env%exc = eexc
1920 678 : IF (edisp /= 0.0_dp) ec_env%edispersion = edisp
1921 678 : ec_env%vhxc = evhxc
1922 :
1923 : ! add the core matrix
1924 1362 : DO ispin = 1, nspins
1925 7074 : DO img = 1, nhfimg
1926 : CALL dbcsr_add(ec_env%matrix_ks(ispin, img)%matrix, ec_env%matrix_h(1, img)%matrix, &
1927 5712 : alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
1928 : CALL dbcsr_filter(ec_env%matrix_ks(ispin, img)%matrix, &
1929 6396 : dft_control%qs_control%eps_filter_matrix)
1930 : END DO
1931 : END DO
1932 :
1933 678 : dft_control%nimages = nimages
1934 :
1935 678 : CALL timestop(handle)
1936 :
1937 678 : END SUBROUTINE ec_build_ks_matrix
1938 :
1939 : ! **************************************************************************************************
1940 : !> \brief Construction of the Core Hamiltonian Matrix
1941 : !> Short version of qs_core_hamiltonian
1942 : !> \param qs_env ...
1943 : !> \param ec_env ...
1944 : !> \param matrix_p ...
1945 : !> \param matrix_s ...
1946 : !> \param matrix_w ...
1947 : !> \author Creation (03.2014,JGH)
1948 : ! **************************************************************************************************
1949 482 : SUBROUTINE ec_build_core_hamiltonian_force(qs_env, ec_env, matrix_p, matrix_s, matrix_w)
1950 : TYPE(qs_environment_type), POINTER :: qs_env
1951 : TYPE(energy_correction_type), POINTER :: ec_env
1952 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_p, matrix_s, matrix_w
1953 :
1954 : CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_build_core_hamiltonian_force'
1955 :
1956 : CHARACTER(LEN=default_string_length) :: basis_type
1957 : INTEGER :: handle, img, iounit, nder, nhfimg, &
1958 : nimages
1959 : LOGICAL :: calculate_forces, debug_forces, &
1960 : debug_stress, use_virial
1961 : REAL(KIND=dp) :: fconv
1962 : REAL(KIND=dp), DIMENSION(3) :: fodeb
1963 : REAL(KIND=dp), DIMENSION(3, 3) :: stdeb, sttot
1964 : TYPE(cell_type), POINTER :: cell
1965 : TYPE(cp_logger_type), POINTER :: logger
1966 482 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: scrm
1967 : TYPE(dft_control_type), POINTER :: dft_control
1968 : TYPE(mp_para_env_type), POINTER :: para_env
1969 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1970 482 : POINTER :: sab_orb
1971 482 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
1972 : TYPE(qs_ks_env_type), POINTER :: ks_env
1973 : TYPE(virial_type), POINTER :: virial
1974 :
1975 482 : CALL timeset(routineN, handle)
1976 :
1977 482 : debug_forces = ec_env%debug_forces
1978 482 : debug_stress = ec_env%debug_stress
1979 :
1980 482 : logger => cp_get_default_logger()
1981 482 : IF (logger%para_env%is_source()) THEN
1982 241 : iounit = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
1983 : ELSE
1984 : iounit = -1
1985 : END IF
1986 :
1987 482 : calculate_forces = .TRUE.
1988 :
1989 482 : basis_type = "HARRIS"
1990 :
1991 : ! no k-points possible
1992 482 : NULLIFY (cell, dft_control, force, ks_env, para_env, virial)
1993 : CALL get_qs_env(qs_env=qs_env, &
1994 : cell=cell, &
1995 : dft_control=dft_control, &
1996 : force=force, &
1997 : ks_env=ks_env, &
1998 : para_env=para_env, &
1999 482 : virial=virial)
2000 482 : nimages = dft_control%nimages
2001 482 : IF (nimages /= 1) THEN
2002 0 : CPABORT("K-points for Harris functional not implemented")
2003 : END IF
2004 : ! check for GAPW/GAPW_XC
2005 482 : IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
2006 38 : IF (ec_env%energy_functional == ec_functional_harris) THEN
2007 0 : CPABORT("Harris functional for GAPW not implemented")
2008 : END IF
2009 : END IF
2010 :
2011 : ! check for virial
2012 482 : use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
2013 :
2014 482 : fconv = 1.0E-9_dp*pascal/cell%deth
2015 482 : IF (debug_stress .AND. use_virial) THEN
2016 0 : sttot = virial%pv_virial
2017 : END IF
2018 :
2019 : ! get neighbor lists, we need the full sab_orb list from the ec_env
2020 482 : sab_orb => ec_env%sab_orb
2021 :
2022 : ! initialize src matrix
2023 482 : nhfimg = SIZE(matrix_s, 2)
2024 482 : NULLIFY (scrm)
2025 482 : CALL dbcsr_allocate_matrix_set(scrm, 1, nhfimg)
2026 3140 : DO img = 1, nhfimg
2027 2658 : ALLOCATE (scrm(1, img)%matrix)
2028 2658 : CALL dbcsr_create(scrm(1, img)%matrix, template=matrix_s(1, img)%matrix)
2029 3140 : CALL cp_dbcsr_alloc_block_from_nbl(scrm(1, img)%matrix, sab_orb)
2030 : END DO
2031 :
2032 482 : nder = 1
2033 482 : IF (SIZE(matrix_p, 1) == 2) THEN
2034 4 : DO img = 1, nhfimg
2035 : CALL dbcsr_add(matrix_w(1, img)%matrix, matrix_w(2, img)%matrix, &
2036 4 : alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
2037 : END DO
2038 : END IF
2039 :
2040 : ! Overlap and kinetic energy matrices
2041 584 : IF (debug_forces) fodeb(1:3) = force(1)%overlap(1:3, 1)
2042 482 : IF (debug_stress .AND. use_virial) stdeb = virial%pv_overlap
2043 : CALL build_overlap_matrix(ks_env, matrixkp_s=scrm, &
2044 : matrix_name="OVERLAP MATRIX", &
2045 : basis_type_a=basis_type, &
2046 : basis_type_b=basis_type, &
2047 : sab_nl=sab_orb, calculate_forces=.TRUE., &
2048 482 : matrixkp_p=matrix_w, ext_kpoints=ec_env%kpoints)
2049 :
2050 482 : IF (debug_forces) THEN
2051 136 : fodeb(1:3) = force(1)%overlap(1:3, 1) - fodeb(1:3)
2052 34 : CALL para_env%sum(fodeb)
2053 34 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Wout*dS ", fodeb
2054 : END IF
2055 482 : IF (debug_stress .AND. use_virial) THEN
2056 0 : stdeb = fconv*(virial%pv_overlap - stdeb)
2057 0 : CALL para_env%sum(stdeb)
2058 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2059 0 : 'STRESS| Wout*dS', one_third_sum_diag(stdeb), det_3x3(stdeb)
2060 : END IF
2061 :
2062 : CALL kinetic_energy_matrix(qs_env, matrixkp_t=scrm, matrix_p=matrix_p, &
2063 : calculate_forces=.TRUE., sab_orb=sab_orb, &
2064 : basis_type=basis_type, ext_kpoints=ec_env%kpoints, &
2065 482 : debug_forces=debug_forces, debug_stress=debug_stress)
2066 :
2067 : CALL core_matrices(qs_env, scrm, matrix_p, calculate_forces, nder, &
2068 : ec_env=ec_env, ec_env_matrices=.FALSE., basis_type=basis_type, &
2069 : ext_kpoints=ec_env%kpoints, &
2070 482 : debug_forces=debug_forces, debug_stress=debug_stress)
2071 :
2072 : ! External field (nonperiodic case)
2073 482 : ec_env%efield_nuclear = 0.0_dp
2074 584 : IF (calculate_forces .AND. debug_forces) fodeb(1:3) = force(1)%efield(1:3, 1)
2075 482 : CALL ec_efield_local_operator(qs_env, ec_env, calculate_forces)
2076 482 : IF (calculate_forces .AND. debug_forces) THEN
2077 136 : fodeb(1:3) = force(1)%efield(1:3, 1) - fodeb(1:3)
2078 34 : CALL para_env%sum(fodeb)
2079 34 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dEfield", fodeb
2080 : END IF
2081 482 : IF (debug_stress .AND. use_virial) THEN
2082 0 : stdeb = fconv*(virial%pv_virial - sttot)
2083 0 : CALL para_env%sum(stdeb)
2084 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2085 0 : 'STRESS| Stress Pout*dHcore ', one_third_sum_diag(stdeb), det_3x3(stdeb)
2086 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") ' '
2087 : END IF
2088 :
2089 : ! delete scr matrix
2090 482 : CALL dbcsr_deallocate_matrix_set(scrm)
2091 :
2092 482 : CALL timestop(handle)
2093 :
2094 482 : END SUBROUTINE ec_build_core_hamiltonian_force
2095 :
2096 : ! **************************************************************************************************
2097 : !> \brief Solve KS equation for a given matrix
2098 : !> \brief calculate the complete KS matrix
2099 : !> \param qs_env ...
2100 : !> \param ec_env ...
2101 : !> \par History
2102 : !> 03.2014 adapted from qs_ks_build_kohn_sham_matrix [JGH]
2103 : !> \author JGH
2104 : ! **************************************************************************************************
2105 270 : SUBROUTINE ec_build_ks_matrix_force(qs_env, ec_env)
2106 : TYPE(qs_environment_type), POINTER :: qs_env
2107 : TYPE(energy_correction_type), POINTER :: ec_env
2108 :
2109 : CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_build_ks_matrix_force'
2110 :
2111 : CHARACTER(LEN=default_string_length) :: unit_string
2112 : INTEGER :: handle, i, img, iounit, ispin, natom, &
2113 : nhfimg, nimages, nspins
2114 : LOGICAL :: debug_forces, debug_stress, do_ec_hfx, &
2115 : use_virial
2116 : REAL(dp) :: dehartree, dummy_real, dummy_real2(2), &
2117 : edisp, eexc, ehartree, eovrl, exc, &
2118 : fconv
2119 270 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: ftot
2120 : REAL(dp), DIMENSION(3) :: fodeb
2121 : REAL(KIND=dp), DIMENSION(3, 3) :: h_stress, pv_loc, stdeb, sttot
2122 270 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
2123 : TYPE(cell_type), POINTER :: cell
2124 : TYPE(cp_logger_type), POINTER :: logger
2125 270 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, rho_ao, scrmat
2126 270 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_p, matrix_s, scrm
2127 : TYPE(dft_control_type), POINTER :: dft_control
2128 : TYPE(mp_para_env_type), POINTER :: para_env
2129 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
2130 270 : POINTER :: sab_orb
2131 : TYPE(pw_c1d_gs_type) :: rho_tot_gspace, rhodn_tot_gspace, &
2132 : v_hartree_gspace
2133 270 : TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g, rhoout_g
2134 : TYPE(pw_c1d_gs_type), POINTER :: rho_core
2135 : TYPE(pw_env_type), POINTER :: pw_env
2136 : TYPE(pw_poisson_type), POINTER :: poisson_env
2137 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
2138 : TYPE(pw_r3d_rs_type) :: dv_hartree_rspace, v_hartree_rspace, &
2139 : vtot_rspace
2140 270 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r, rhoout_r, tau_r, tauout_r, &
2141 270 : v_rspace, v_tau_rspace, v_xc, v_xc_tau
2142 : TYPE(pw_r3d_rs_type), POINTER :: rho_nlcc
2143 270 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
2144 : TYPE(qs_ks_env_type), POINTER :: ks_env
2145 : TYPE(qs_rho_type), POINTER :: rho, rhoout
2146 270 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho0_atom_set, rho1_atom_set
2147 : TYPE(section_vals_type), POINTER :: ec_hfx_sections, xc_section
2148 : TYPE(virial_type), POINTER :: virial
2149 :
2150 270 : CALL timeset(routineN, handle)
2151 :
2152 270 : debug_forces = ec_env%debug_forces
2153 270 : debug_stress = ec_env%debug_stress
2154 :
2155 270 : logger => cp_get_default_logger()
2156 270 : IF (logger%para_env%is_source()) THEN
2157 135 : iounit = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
2158 : ELSE
2159 135 : iounit = -1
2160 : END IF
2161 :
2162 : ! get all information on the electronic density
2163 270 : NULLIFY (atomic_kind_set, cell, dft_control, force, ks_env, &
2164 270 : matrix_ks, matrix_p, matrix_s, para_env, rho, rho_core, &
2165 270 : rho_g, rho_r, rho_nlcc, sab_orb, tau_r, virial)
2166 : CALL get_qs_env(qs_env=qs_env, &
2167 : cell=cell, &
2168 : dft_control=dft_control, &
2169 : force=force, &
2170 : ks_env=ks_env, &
2171 : matrix_ks=matrix_ks, &
2172 : para_env=para_env, &
2173 : rho=rho, &
2174 : rho_nlcc=rho_nlcc, &
2175 : sab_orb=sab_orb, &
2176 270 : virial=virial)
2177 :
2178 270 : nspins = dft_control%nspins
2179 270 : use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
2180 :
2181 : ! Conversion factor a.u. -> GPa
2182 270 : unit_string = "GPa"
2183 270 : fconv = cp_unit_from_cp2k(1.0_dp/cell%deth, TRIM(unit_string))
2184 :
2185 270 : IF (debug_stress .AND. use_virial) THEN
2186 0 : sttot = virial%pv_virial
2187 : END IF
2188 :
2189 270 : NULLIFY (pw_env)
2190 270 : CALL get_qs_env(qs_env=qs_env, pw_env=pw_env)
2191 270 : CPASSERT(ASSOCIATED(pw_env))
2192 :
2193 270 : NULLIFY (auxbas_pw_pool, poisson_env)
2194 : ! gets the tmp grids
2195 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
2196 270 : poisson_env=poisson_env)
2197 :
2198 : ! Calculate the Hartree potential
2199 270 : CALL auxbas_pw_pool%create_pw(v_hartree_gspace)
2200 270 : CALL auxbas_pw_pool%create_pw(rhodn_tot_gspace)
2201 270 : CALL auxbas_pw_pool%create_pw(v_hartree_rspace)
2202 :
2203 270 : CALL pw_transfer(ec_env%vh_rspace, v_hartree_rspace)
2204 :
2205 : ! calculate output density on grid
2206 : ! rho_in(R): CALL qs_rho_get(rho, rho_r=rho_r)
2207 : ! rho_in(G): CALL qs_rho_get(rho, rho_g=rho_g)
2208 270 : CALL qs_rho_get(rho, rho_r=rho_r, rho_g=rho_g, tau_r=tau_r)
2209 270 : NULLIFY (rhoout_r, rhoout_g)
2210 1890 : ALLOCATE (rhoout_r(nspins), rhoout_g(nspins))
2211 540 : DO ispin = 1, nspins
2212 270 : CALL auxbas_pw_pool%create_pw(rhoout_r(ispin))
2213 540 : CALL auxbas_pw_pool%create_pw(rhoout_g(ispin))
2214 : END DO
2215 270 : CALL auxbas_pw_pool%create_pw(dv_hartree_rspace)
2216 270 : CALL auxbas_pw_pool%create_pw(vtot_rspace)
2217 :
2218 : ! set local number of images
2219 270 : nhfimg = SIZE(ec_env%matrix_s, 2)
2220 270 : nimages = dft_control%nimages
2221 270 : dft_control%nimages = nhfimg
2222 :
2223 270 : CALL pw_zero(rhodn_tot_gspace)
2224 540 : DO ispin = 1, nspins
2225 270 : rho_ao => ec_env%matrix_p(ispin, :)
2226 : CALL calculate_rho_elec(ks_env=ks_env, matrix_p_kp=rho_ao, &
2227 : rho=rhoout_r(ispin), &
2228 : rho_gspace=rhoout_g(ispin), &
2229 : basis_type="HARRIS", &
2230 540 : task_list_external=ec_env%task_list)
2231 : END DO
2232 :
2233 : ! Save Harris on real space grid for use in properties
2234 810 : ALLOCATE (ec_env%rhoout_r(nspins))
2235 540 : DO ispin = 1, nspins
2236 270 : CALL auxbas_pw_pool%create_pw(ec_env%rhoout_r(ispin))
2237 540 : CALL pw_copy(rhoout_r(ispin), ec_env%rhoout_r(ispin))
2238 : END DO
2239 :
2240 270 : NULLIFY (tauout_r)
2241 270 : IF (dft_control%use_kinetic_energy_density) THEN
2242 : BLOCK
2243 : TYPE(pw_c1d_gs_type) :: tauout_g
2244 96 : ALLOCATE (tauout_r(nspins))
2245 64 : DO ispin = 1, nspins
2246 64 : CALL auxbas_pw_pool%create_pw(tauout_r(ispin))
2247 : END DO
2248 32 : CALL auxbas_pw_pool%create_pw(tauout_g)
2249 :
2250 64 : DO ispin = 1, nspins
2251 : CALL calculate_rho_elec(ks_env=ks_env, matrix_p=ec_env%matrix_p(ispin, 1)%matrix, &
2252 : rho=tauout_r(ispin), &
2253 : rho_gspace=tauout_g, &
2254 : compute_tau=.TRUE., &
2255 : basis_type="HARRIS", &
2256 64 : task_list_external=ec_env%task_list)
2257 : END DO
2258 :
2259 64 : CALL auxbas_pw_pool%give_back_pw(tauout_g)
2260 : END BLOCK
2261 : END IF
2262 :
2263 : ! reset nimages to base method
2264 270 : dft_control%nimages = nimages
2265 :
2266 270 : IF (use_virial) THEN
2267 :
2268 : ! Calculate the Hartree potential
2269 112 : CALL auxbas_pw_pool%create_pw(rho_tot_gspace)
2270 :
2271 : ! Get the total input density in g-space [ions + electrons]
2272 112 : CALL calc_rho_tot_gspace(rho_tot_gspace, qs_env, rho)
2273 :
2274 : ! make rho_tot_gspace with output density
2275 112 : CALL get_qs_env(qs_env=qs_env, rho_core=rho_core)
2276 112 : CALL pw_copy(rho_core, rhodn_tot_gspace)
2277 224 : DO ispin = 1, dft_control%nspins
2278 224 : CALL pw_axpy(rhoout_g(ispin), rhodn_tot_gspace)
2279 : END DO
2280 :
2281 : ! Volume and Green function terms
2282 112 : h_stress(:, :) = 0.0_dp
2283 : CALL pw_poisson_solve(poisson_env, &
2284 : density=rho_tot_gspace, & ! n_in
2285 : ehartree=ehartree, &
2286 : vhartree=v_hartree_gspace, & ! v_H[n_in]
2287 : h_stress=h_stress, &
2288 112 : aux_density=rhodn_tot_gspace) ! n_out
2289 :
2290 1456 : virial%pv_ehartree = virial%pv_ehartree + h_stress/REAL(para_env%num_pe, dp)
2291 1456 : virial%pv_virial = virial%pv_virial + h_stress/REAL(para_env%num_pe, dp)
2292 :
2293 112 : IF (debug_stress) THEN
2294 0 : stdeb = fconv*(h_stress/REAL(para_env%num_pe, dp))
2295 0 : CALL para_env%sum(stdeb)
2296 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2297 0 : 'STRESS| GREEN 1st v_H[n_in]*n_out ', one_third_sum_diag(stdeb), det_3x3(stdeb)
2298 : END IF
2299 :
2300 : ! activate stress calculation
2301 112 : virial%pv_calculate = .TRUE.
2302 :
2303 112 : NULLIFY (v_rspace, v_tau_rspace)
2304 : CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho, xc_section=ec_env%xc_section, &
2305 : vxc_rho=v_rspace, vxc_tau=v_tau_rspace, exc=exc, just_energy=.FALSE., &
2306 112 : edisp=edisp, dispersion_env=ec_env%dispersion_env)
2307 :
2308 : ! Stress tensor XC-functional GGA contribution
2309 1456 : virial%pv_exc = virial%pv_exc - virial%pv_xc
2310 1456 : virial%pv_virial = virial%pv_virial - virial%pv_xc
2311 :
2312 112 : IF (debug_stress) THEN
2313 0 : stdeb = -1.0_dp*fconv*virial%pv_xc
2314 0 : CALL para_env%sum(stdeb)
2315 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2316 0 : 'STRESS| GGA 1st E_xc[Pin] ', one_third_sum_diag(stdeb), det_3x3(stdeb)
2317 : END IF
2318 :
2319 112 : IF (ASSOCIATED(v_rspace)) THEN
2320 224 : DO ispin = 1, nspins
2321 224 : CALL auxbas_pw_pool%give_back_pw(v_rspace(ispin))
2322 : END DO
2323 112 : DEALLOCATE (v_rspace)
2324 : END IF
2325 112 : IF (ASSOCIATED(v_tau_rspace)) THEN
2326 16 : DO ispin = 1, nspins
2327 16 : CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
2328 : END DO
2329 8 : DEALLOCATE (v_tau_rspace)
2330 : END IF
2331 112 : CALL pw_zero(rhodn_tot_gspace)
2332 :
2333 : END IF
2334 :
2335 : ! rho_out - rho_in
2336 540 : DO ispin = 1, nspins
2337 270 : CALL pw_axpy(rho_r(ispin), rhoout_r(ispin), -1.0_dp)
2338 270 : CALL pw_axpy(rho_g(ispin), rhoout_g(ispin), -1.0_dp)
2339 270 : CALL pw_axpy(rhoout_g(ispin), rhodn_tot_gspace)
2340 540 : IF (dft_control%use_kinetic_energy_density) CALL pw_axpy(tau_r(ispin), tauout_r(ispin), -1.0_dp)
2341 : END DO
2342 :
2343 : ! calculate associated hartree potential
2344 270 : IF (use_virial) THEN
2345 :
2346 : ! Stress tensor - 2nd derivative Volume and Green function contribution
2347 112 : h_stress(:, :) = 0.0_dp
2348 : CALL pw_poisson_solve(poisson_env, &
2349 : density=rhodn_tot_gspace, & ! delta_n
2350 : ehartree=dehartree, &
2351 : vhartree=v_hartree_gspace, & ! v_H[delta_n]
2352 : h_stress=h_stress, &
2353 112 : aux_density=rho_tot_gspace) ! n_in
2354 :
2355 112 : CALL auxbas_pw_pool%give_back_pw(rho_tot_gspace)
2356 :
2357 1456 : virial%pv_ehartree = virial%pv_ehartree + h_stress/REAL(para_env%num_pe, dp)
2358 1456 : virial%pv_virial = virial%pv_virial + h_stress/REAL(para_env%num_pe, dp)
2359 :
2360 112 : IF (debug_stress) THEN
2361 0 : stdeb = fconv*(h_stress/REAL(para_env%num_pe, dp))
2362 0 : CALL para_env%sum(stdeb)
2363 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2364 0 : 'STRESS| GREEN 2nd V_H[dP]*n_in ', one_third_sum_diag(stdeb), det_3x3(stdeb)
2365 : END IF
2366 :
2367 : ELSE
2368 : ! v_H[dn]
2369 : CALL pw_poisson_solve(poisson_env, rhodn_tot_gspace, dehartree, &
2370 158 : v_hartree_gspace)
2371 : END IF
2372 :
2373 270 : CALL pw_transfer(v_hartree_gspace, dv_hartree_rspace)
2374 270 : CALL pw_scale(dv_hartree_rspace, dv_hartree_rspace%pw_grid%dvol)
2375 : ! Getting nuclear force contribution from the core charge density
2376 : ! Vh(rho_in + rho_c) + Vh(rho_out - rho_in)
2377 270 : CALL pw_transfer(v_hartree_rspace, vtot_rspace)
2378 270 : CALL pw_axpy(dv_hartree_rspace, vtot_rspace)
2379 270 : IF (debug_forces) fodeb(1:3) = force(1)%rho_core(1:3, 1)
2380 270 : IF (debug_stress .AND. use_virial) stdeb = virial%pv_ehartree
2381 270 : CALL integrate_v_core_rspace(vtot_rspace, qs_env)
2382 270 : IF (debug_forces) THEN
2383 0 : fodeb(1:3) = force(1)%rho_core(1:3, 1) - fodeb(1:3)
2384 0 : CALL para_env%sum(fodeb)
2385 0 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Vtot*dncore", fodeb
2386 : END IF
2387 270 : IF (debug_stress .AND. use_virial) THEN
2388 0 : stdeb = fconv*(virial%pv_ehartree - stdeb)
2389 0 : CALL para_env%sum(stdeb)
2390 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2391 0 : 'STRESS| Vtot*dncore', one_third_sum_diag(stdeb), det_3x3(stdeb)
2392 : END IF
2393 : !
2394 : ! Pulay force from Tr P_in (V_H(drho)+ Fxc(rho_in)*drho)
2395 : ! RHS of CPKS equations: (V_H(drho)+ Fxc(rho_in)*drho)*C0
2396 : ! Fxc*drho term
2397 270 : xc_section => ec_env%xc_section
2398 :
2399 1614 : IF (use_virial) virial%pv_xc = 0.0_dp
2400 270 : NULLIFY (v_xc, v_xc_tau)
2401 270 : NULLIFY (rho0_atom_set, rho1_atom_set)
2402 270 : ALLOCATE (rhoout)
2403 270 : CALL qs_rho_create(rhoout)
2404 270 : IF (ASSOCIATED(rhoout_r)) THEN
2405 270 : CALL qs_rho_set(rhoout, rho_r=rhoout_r, rho_r_valid=.TRUE.)
2406 : END IF
2407 270 : IF (ASSOCIATED(rhoout_g)) THEN
2408 270 : CALL qs_rho_set(rhoout, rho_g=rhoout_g, rho_g_valid=.TRUE.)
2409 : END IF
2410 270 : IF (ASSOCIATED(tauout_r)) THEN
2411 32 : CALL qs_rho_set(rhoout, tau_r=tauout_r, tau_r_valid=.TRUE.)
2412 : END IF
2413 : !
2414 : CALL qs_fxc_create(qs_env, rho, rhoout, rho0_atom_set, xc_section, .FALSE., &
2415 : v_xc, v_xc_tau, rho1_atom_set, &
2416 : dispersion_env=ec_env%dispersion_env, &
2417 270 : compute_virial=use_virial, virial_xc=virial%pv_xc)
2418 : !
2419 270 : DEALLOCATE (rhoout)
2420 :
2421 270 : IF (use_virial) THEN
2422 : ! Stress-tensor XC-functional 2nd GGA terms
2423 1456 : virial%pv_exc = virial%pv_exc + virial%pv_xc
2424 1456 : virial%pv_virial = virial%pv_virial + virial%pv_xc
2425 : END IF
2426 270 : IF (debug_stress .AND. use_virial) THEN
2427 0 : stdeb = 1.0_dp*fconv*virial%pv_xc
2428 0 : CALL para_env%sum(stdeb)
2429 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2430 0 : 'STRESS| GGA 2nd f_Hxc[dP]*Pin ', one_third_sum_diag(stdeb), det_3x3(stdeb)
2431 : END IF
2432 : !
2433 270 : IF (ASSOCIATED(rho_nlcc)) THEN
2434 4 : DO ispin = 1, nspins
2435 : CALL integrate_rho_nlcc(v_xc(ispin), qs_env, &
2436 4 : debug_forces, debug_stress, "dnlcc*dVxc")
2437 : END DO
2438 : END IF
2439 : !
2440 270 : CALL get_qs_env(qs_env=qs_env, rho=rho, matrix_s_kp=matrix_s)
2441 270 : NULLIFY (ec_env%matrix_hz)
2442 270 : CALL dbcsr_allocate_matrix_set(ec_env%matrix_hz, nspins)
2443 540 : DO ispin = 1, nspins
2444 270 : ALLOCATE (ec_env%matrix_hz(ispin)%matrix)
2445 270 : CALL dbcsr_create(ec_env%matrix_hz(ispin)%matrix, template=matrix_s(1, 1)%matrix)
2446 270 : CALL dbcsr_copy(ec_env%matrix_hz(ispin)%matrix, matrix_s(1, 1)%matrix)
2447 540 : CALL dbcsr_set(ec_env%matrix_hz(ispin)%matrix, 0.0_dp)
2448 : END DO
2449 270 : CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
2450 : ! vtot = v_xc(ispin) + dv_hartree
2451 270 : IF (debug_forces) fodeb(1:3) = force(1)%rho_elec(1:3, 1)
2452 270 : IF (debug_stress .AND. use_virial) stdeb = virial%pv_virial
2453 :
2454 : ! Stress-tensor 2nd derivative integral contribution
2455 270 : IF (use_virial) THEN
2456 1456 : pv_loc = virial%pv_virial
2457 : END IF
2458 :
2459 540 : DO ispin = 1, nspins
2460 270 : CALL pw_scale(v_xc(ispin), v_xc(ispin)%pw_grid%dvol)
2461 270 : CALL pw_axpy(dv_hartree_rspace, v_xc(ispin))
2462 : CALL integrate_v_rspace(v_rspace=v_xc(ispin), &
2463 : hmat=ec_env%matrix_hz(ispin), &
2464 : pmat=matrix_p(ispin, 1), &
2465 : qs_env=qs_env, &
2466 540 : calculate_forces=.TRUE.)
2467 : END DO
2468 :
2469 270 : IF (debug_forces) THEN
2470 0 : fodeb(1:3) = force(1)%rho_elec(1:3, 1) - fodeb(1:3)
2471 0 : CALL para_env%sum(fodeb)
2472 0 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pin*dKdrho", fodeb
2473 : END IF
2474 270 : IF (debug_stress .AND. use_virial) THEN
2475 0 : stdeb = fconv*(virial%pv_virial - stdeb)
2476 0 : CALL para_env%sum(stdeb)
2477 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2478 0 : 'STRESS| INT 2nd f_Hxc[dP]*Pin ', one_third_sum_diag(stdeb), det_3x3(stdeb)
2479 : END IF
2480 :
2481 270 : IF (ASSOCIATED(v_xc_tau)) THEN
2482 16 : IF (debug_forces) fodeb(1:3) = force(1)%rho_elec(1:3, 1)
2483 16 : IF (debug_stress .AND. use_virial) stdeb = virial%pv_virial
2484 :
2485 32 : DO ispin = 1, nspins
2486 16 : CALL pw_scale(v_xc_tau(ispin), v_xc_tau(ispin)%pw_grid%dvol)
2487 : CALL integrate_v_rspace(v_rspace=v_xc_tau(ispin), &
2488 : hmat=ec_env%matrix_hz(ispin), &
2489 : pmat=matrix_p(ispin, 1), &
2490 : qs_env=qs_env, &
2491 : compute_tau=.TRUE., &
2492 32 : calculate_forces=.TRUE.)
2493 : END DO
2494 :
2495 16 : IF (debug_forces) THEN
2496 0 : fodeb(1:3) = force(1)%rho_elec(1:3, 1) - fodeb(1:3)
2497 0 : CALL para_env%sum(fodeb)
2498 0 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pin*dKtaudtau", fodeb
2499 : END IF
2500 16 : IF (debug_stress .AND. use_virial) THEN
2501 0 : stdeb = fconv*(virial%pv_virial - stdeb)
2502 0 : CALL para_env%sum(stdeb)
2503 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2504 0 : 'STRESS| INT 2nd f_xctau[dP]*Pin ', one_third_sum_diag(stdeb), det_3x3(stdeb)
2505 : END IF
2506 : END IF
2507 : ! Stress-tensor 2nd derivative integral contribution
2508 270 : IF (use_virial) THEN
2509 1456 : virial%pv_ehartree = virial%pv_ehartree + (virial%pv_virial - pv_loc)
2510 : END IF
2511 :
2512 : ! v_rspace and v_tau_rspace are generated from the auxbas pool
2513 270 : NULLIFY (v_rspace, v_tau_rspace)
2514 :
2515 : CALL qs_vxc_create(ks_env=ks_env, rho_struct=rho, xc_section=ec_env%xc_section, &
2516 : vxc_rho=v_rspace, vxc_tau=v_tau_rspace, exc=eexc, just_energy=.FALSE., &
2517 270 : edisp=edisp, dispersion_env=ec_env%dispersion_env)
2518 270 : IF (edisp /= 0.0_dp) eexc = eexc + edisp
2519 :
2520 270 : IF (ASSOCIATED(rho_nlcc)) THEN
2521 4 : DO ispin = 1, nspins
2522 : CALL integrate_rho_nlcc(v_rspace(ispin), qs_env, &
2523 4 : debug_forces, debug_stress, "dnlcc*dVxc")
2524 : END DO
2525 : END IF
2526 :
2527 270 : IF (use_virial) THEN
2528 112 : eexc = 0.0_dp
2529 112 : IF (ASSOCIATED(v_rspace)) THEN
2530 224 : DO ispin = 1, nspins
2531 : ! 2nd deriv xc-volume term
2532 224 : eexc = eexc + pw_integral_ab(rhoout_r(ispin), v_rspace(ispin))
2533 : END DO
2534 : END IF
2535 112 : IF (ASSOCIATED(v_tau_rspace)) THEN
2536 16 : DO ispin = 1, nspins
2537 : ! 2nd deriv xc-volume term
2538 16 : eexc = eexc + pw_integral_ab(tauout_r(ispin), v_tau_rspace(ispin))
2539 : END DO
2540 : END IF
2541 : END IF
2542 :
2543 270 : IF (.NOT. ASSOCIATED(v_rspace)) THEN
2544 0 : ALLOCATE (v_rspace(nspins))
2545 0 : DO ispin = 1, nspins
2546 0 : CALL auxbas_pw_pool%create_pw(v_rspace(ispin))
2547 0 : CALL pw_zero(v_rspace(ispin))
2548 : END DO
2549 : END IF
2550 :
2551 : ! Stress-tensor contribution derivative of integrand
2552 : ! int v_Hxc[n^în]*n^out
2553 270 : IF (use_virial) THEN
2554 1456 : pv_loc = virial%pv_virial
2555 : END IF
2556 : ! set local number of images
2557 270 : dft_control%nimages = nhfimg
2558 :
2559 : ! initialize srcm matrix
2560 270 : NULLIFY (scrm)
2561 270 : CALL dbcsr_allocate_matrix_set(scrm, nspins, nhfimg)
2562 540 : DO ispin = 1, nspins
2563 2986 : DO img = 1, nhfimg
2564 2446 : ALLOCATE (scrm(ispin, img)%matrix)
2565 2446 : CALL dbcsr_create(scrm(ispin, img)%matrix, template=ec_env%matrix_ks(ispin, img)%matrix)
2566 2446 : CALL dbcsr_copy(scrm(ispin, img)%matrix, ec_env%matrix_ks(ispin, img)%matrix)
2567 2716 : CALL dbcsr_set(scrm(ispin, img)%matrix, 0.0_dp)
2568 : END DO
2569 : END DO
2570 :
2571 270 : IF (debug_forces) fodeb(1:3) = force(1)%rho_elec(1:3, 1)
2572 270 : IF (debug_stress .AND. use_virial) stdeb = virial%pv_virial
2573 540 : DO ispin = 1, nspins
2574 : ! Add v_hartree + v_xc = v_rspace
2575 270 : CALL pw_scale(v_rspace(ispin), v_rspace(ispin)%pw_grid%dvol)
2576 270 : CALL pw_axpy(v_hartree_rspace, v_rspace(ispin))
2577 : ! integrate over potential <a|V|b>
2578 270 : rho_ao => ec_env%matrix_p(ispin, :)
2579 270 : scrmat => scrm(ispin, :)
2580 : CALL integrate_v_rspace(v_rspace=v_rspace(ispin), &
2581 : hmat_kp=scrmat, &
2582 : pmat_kp=rho_ao, &
2583 : qs_env=qs_env, &
2584 : calculate_forces=.TRUE., &
2585 : basis_type="HARRIS", &
2586 540 : task_list_external=ec_env%task_list)
2587 : END DO
2588 :
2589 270 : IF (debug_forces) THEN
2590 0 : fodeb(1:3) = force(1)%rho_elec(1:3, 1) - fodeb(1:3)
2591 0 : CALL para_env%sum(fodeb)
2592 0 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dVhxc ", fodeb
2593 : END IF
2594 270 : IF (debug_stress .AND. use_virial) THEN
2595 0 : stdeb = fconv*(virial%pv_virial - stdeb)
2596 0 : CALL para_env%sum(stdeb)
2597 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2598 0 : 'STRESS| INT Pout*dVhxc ', one_third_sum_diag(stdeb), det_3x3(stdeb)
2599 : END IF
2600 :
2601 : ! Stress-tensor
2602 270 : IF (use_virial) THEN
2603 1456 : virial%pv_ehartree = virial%pv_ehartree + (virial%pv_virial - pv_loc)
2604 : END IF
2605 :
2606 : ! reset nimages to base method
2607 270 : dft_control%nimages = nimages
2608 :
2609 270 : IF (ASSOCIATED(v_tau_rspace)) THEN
2610 16 : IF (debug_forces) fodeb(1:3) = force(1)%rho_elec(1:3, 1)
2611 32 : DO ispin = 1, nspins
2612 : ! integrate over Tau-potential <nabla.a|V|nabla.b>
2613 16 : CALL pw_scale(v_tau_rspace(ispin), v_tau_rspace(ispin)%pw_grid%dvol)
2614 16 : rho_ao => ec_env%matrix_p(ispin, :)
2615 16 : scrmat => scrm(ispin, :)
2616 : CALL integrate_v_rspace(v_rspace=v_tau_rspace(ispin), &
2617 : hmat_kp=scrmat, &
2618 : pmat_kp=rho_ao, &
2619 : qs_env=qs_env, &
2620 : calculate_forces=.TRUE., &
2621 : compute_tau=.TRUE., &
2622 : basis_type="HARRIS", &
2623 32 : task_list_external=ec_env%task_list)
2624 : END DO
2625 16 : IF (debug_forces) THEN
2626 0 : fodeb(1:3) = force(1)%rho_elec(1:3, 1) - fodeb(1:3)
2627 0 : CALL para_env%sum(fodeb)
2628 0 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*dVhxc_tau ", fodeb
2629 : END IF
2630 : END IF
2631 :
2632 : !------------------------------------------------------------------------------
2633 : ! HFX direct force
2634 : !------------------------------------------------------------------------------
2635 :
2636 : ! If hybrid functional
2637 270 : ec_hfx_sections => section_vals_get_subs_vals(qs_env%input, "DFT%ENERGY_CORRECTION%XC%HF")
2638 270 : CALL section_vals_get(ec_hfx_sections, explicit=do_ec_hfx)
2639 :
2640 270 : IF (do_ec_hfx) THEN
2641 :
2642 0 : IF (ec_env%do_kpoints) THEN
2643 0 : CALL cp_abort(__LOCATION__, "HFX and K-points NYI for energy correction")
2644 : END IF
2645 :
2646 0 : IF (debug_forces) fodeb(1:3) = force(1)%fock_4c(1:3, 1)
2647 0 : IF (use_virial) virial%pv_fock_4c = 0.0_dp
2648 :
2649 : CALL calculate_exx(qs_env=qs_env, &
2650 : unit_nr=iounit, &
2651 : hfx_sections=ec_hfx_sections, &
2652 : x_data=ec_env%x_data, &
2653 : do_gw=.FALSE., &
2654 : do_admm=ec_env%do_ec_admm, &
2655 : calc_forces=.TRUE., &
2656 : reuse_hfx=ec_env%reuse_hfx, &
2657 : do_im_time=.FALSE., &
2658 : E_ex_from_GW=dummy_real, &
2659 : E_admm_from_GW=dummy_real2, &
2660 0 : t3=dummy_real)
2661 :
2662 0 : IF (use_virial) THEN
2663 0 : virial%pv_exx = virial%pv_exx - virial%pv_fock_4c
2664 0 : virial%pv_virial = virial%pv_virial - virial%pv_fock_4c
2665 0 : virial%pv_calculate = .FALSE.
2666 : END IF
2667 0 : IF (debug_forces) THEN
2668 0 : fodeb(1:3) = force(1)%fock_4c(1:3, 1) - fodeb(1:3)
2669 0 : CALL para_env%sum(fodeb)
2670 0 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Pout*hfx ", fodeb
2671 : END IF
2672 0 : IF (debug_stress .AND. use_virial) THEN
2673 0 : stdeb = -1.0_dp*fconv*virial%pv_fock_4c
2674 0 : CALL para_env%sum(stdeb)
2675 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2676 0 : 'STRESS| Pout*hfx ', one_third_sum_diag(stdeb), det_3x3(stdeb)
2677 : END IF
2678 :
2679 : END IF
2680 :
2681 : ! delete scrm matrix
2682 270 : CALL dbcsr_deallocate_matrix_set(scrm)
2683 :
2684 : ! return pw grids
2685 270 : CALL auxbas_pw_pool%give_back_pw(v_hartree_rspace)
2686 540 : DO ispin = 1, nspins
2687 270 : CALL auxbas_pw_pool%give_back_pw(v_rspace(ispin))
2688 540 : IF (ASSOCIATED(v_tau_rspace)) THEN
2689 16 : CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
2690 : END IF
2691 : END DO
2692 270 : IF (ASSOCIATED(v_tau_rspace)) DEALLOCATE (v_tau_rspace)
2693 :
2694 : ! Core overlap
2695 270 : IF (debug_forces) fodeb(1:3) = force(1)%core_overlap(1:3, 1)
2696 270 : IF (debug_stress .AND. use_virial) stdeb = virial%pv_ecore_overlap
2697 270 : CALL calculate_ecore_overlap(qs_env, para_env, .TRUE., E_overlap_core=eovrl)
2698 270 : IF (debug_forces) THEN
2699 0 : fodeb(1:3) = force(1)%core_overlap(1:3, 1) - fodeb(1:3)
2700 0 : CALL para_env%sum(fodeb)
2701 0 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: CoreOverlap", fodeb
2702 : END IF
2703 270 : IF (debug_stress .AND. use_virial) THEN
2704 0 : stdeb = fconv*(stdeb - virial%pv_ecore_overlap)
2705 0 : CALL para_env%sum(stdeb)
2706 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2707 0 : 'STRESS| CoreOverlap ', one_third_sum_diag(stdeb), det_3x3(stdeb)
2708 : END IF
2709 :
2710 270 : IF (debug_forces) THEN
2711 0 : CALL get_qs_env(qs_env, natom=natom, atomic_kind_set=atomic_kind_set)
2712 0 : ALLOCATE (ftot(3, natom))
2713 0 : CALL total_qs_force(ftot, force, atomic_kind_set)
2714 0 : fodeb(1:3) = ftot(1:3, 1)
2715 0 : DEALLOCATE (ftot)
2716 0 : CALL para_env%sum(fodeb)
2717 0 : IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Force Explicit", fodeb
2718 : END IF
2719 :
2720 270 : DEALLOCATE (v_rspace)
2721 : !
2722 270 : CALL auxbas_pw_pool%give_back_pw(dv_hartree_rspace)
2723 270 : CALL auxbas_pw_pool%give_back_pw(vtot_rspace)
2724 540 : DO ispin = 1, nspins
2725 270 : CALL auxbas_pw_pool%give_back_pw(rhoout_r(ispin))
2726 270 : CALL auxbas_pw_pool%give_back_pw(rhoout_g(ispin))
2727 540 : CALL auxbas_pw_pool%give_back_pw(v_xc(ispin))
2728 : END DO
2729 270 : DEALLOCATE (rhoout_r, rhoout_g, v_xc)
2730 270 : IF (ASSOCIATED(tauout_r)) THEN
2731 64 : DO ispin = 1, nspins
2732 64 : CALL auxbas_pw_pool%give_back_pw(tauout_r(ispin))
2733 : END DO
2734 32 : DEALLOCATE (tauout_r)
2735 : END IF
2736 270 : IF (ASSOCIATED(v_xc_tau)) THEN
2737 32 : DO ispin = 1, nspins
2738 32 : CALL auxbas_pw_pool%give_back_pw(v_xc_tau(ispin))
2739 : END DO
2740 16 : DEALLOCATE (v_xc_tau)
2741 : END IF
2742 270 : CALL auxbas_pw_pool%give_back_pw(v_hartree_gspace)
2743 270 : CALL auxbas_pw_pool%give_back_pw(rhodn_tot_gspace)
2744 :
2745 : ! Stress tensor - volume terms need to be stored,
2746 : ! for a sign correction in QS at the end of qs_force
2747 270 : IF (use_virial) THEN
2748 112 : IF (qs_env%energy_correction) THEN
2749 112 : ec_env%ehartree = ehartree + dehartree
2750 112 : ec_env%exc = exc + eexc
2751 : END IF
2752 : END IF
2753 :
2754 270 : IF (debug_stress .AND. use_virial) THEN
2755 : ! In total: -1.0*E_H
2756 0 : stdeb = -1.0_dp*fconv*ehartree
2757 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2758 0 : 'STRESS| VOL 1st v_H[n_in]*n_out', one_third_sum_diag(stdeb), det_3x3(stdeb)
2759 :
2760 0 : stdeb = -1.0_dp*fconv*exc
2761 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2762 0 : 'STRESS| VOL 1st E_XC[n_in]', one_third_sum_diag(stdeb), det_3x3(stdeb)
2763 :
2764 0 : stdeb = -1.0_dp*fconv*dehartree
2765 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2766 0 : 'STRESS| VOL 2nd v_H[dP]*n_in', one_third_sum_diag(stdeb), det_3x3(stdeb)
2767 :
2768 0 : stdeb = -1.0_dp*fconv*eexc
2769 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2770 0 : 'STRESS| VOL 2nd v_XC[n_in]*dP', one_third_sum_diag(stdeb), det_3x3(stdeb)
2771 :
2772 : ! For debugging, create a second virial environment,
2773 : ! apply volume terms immediately
2774 : BLOCK
2775 : TYPE(virial_type) :: virdeb
2776 0 : virdeb = virial
2777 :
2778 0 : CALL para_env%sum(virdeb%pv_overlap)
2779 0 : CALL para_env%sum(virdeb%pv_ekinetic)
2780 0 : CALL para_env%sum(virdeb%pv_ppl)
2781 0 : CALL para_env%sum(virdeb%pv_ppnl)
2782 0 : CALL para_env%sum(virdeb%pv_ecore_overlap)
2783 0 : CALL para_env%sum(virdeb%pv_ehartree)
2784 0 : CALL para_env%sum(virdeb%pv_exc)
2785 0 : CALL para_env%sum(virdeb%pv_exx)
2786 0 : CALL para_env%sum(virdeb%pv_vdw)
2787 0 : CALL para_env%sum(virdeb%pv_mp2)
2788 0 : CALL para_env%sum(virdeb%pv_nlcc)
2789 0 : CALL para_env%sum(virdeb%pv_gapw)
2790 0 : CALL para_env%sum(virdeb%pv_lrigpw)
2791 0 : CALL para_env%sum(virdeb%pv_virial)
2792 0 : CALL symmetrize_virial(virdeb)
2793 :
2794 : ! apply stress-tensor 1st and 2nd volume terms
2795 0 : DO i = 1, 3
2796 0 : virdeb%pv_ehartree(i, i) = virdeb%pv_ehartree(i, i) - 2.0_dp*(ehartree + dehartree)
2797 : virdeb%pv_virial(i, i) = virdeb%pv_virial(i, i) - exc - eexc &
2798 0 : - 2.0_dp*(ehartree + dehartree)
2799 0 : virdeb%pv_exc(i, i) = virdeb%pv_exc(i, i) - exc - eexc
2800 : ! The factor 2 is a hack. It compensates the plus sign in h_stress/pw_poisson_solve.
2801 : ! The sign in pw_poisson_solve is correct for FIST, but not for QS.
2802 : ! There should be a more elegant solution to that ...
2803 : END DO
2804 :
2805 0 : CALL para_env%sum(sttot)
2806 0 : stdeb = fconv*(virdeb%pv_virial - sttot)
2807 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2808 0 : 'STRESS| Explicit electronic stress ', one_third_sum_diag(stdeb), det_3x3(stdeb)
2809 :
2810 0 : stdeb = fconv*(virdeb%pv_virial)
2811 0 : IF (iounit > 0) WRITE (UNIT=iounit, FMT="(T2,A,T41,2(1X,ES19.11))") &
2812 0 : 'STRESS| Explicit total stress ', one_third_sum_diag(stdeb), det_3x3(stdeb)
2813 :
2814 0 : CALL write_stress_tensor_components(virdeb, iounit, cell, unit_string)
2815 0 : CALL write_stress_tensor(virdeb%pv_virial, iounit, cell, unit_string, .FALSE.)
2816 :
2817 : END BLOCK
2818 : END IF
2819 :
2820 270 : CALL timestop(handle)
2821 :
2822 1080 : END SUBROUTINE ec_build_ks_matrix_force
2823 :
2824 : ! **************************************************************************************************
2825 : !> \brief Solve KS equation for a given matrix
2826 : !> \param qs_env ...
2827 : !> \param ec_env ...
2828 : !> \par History
2829 : !> 03.2014 created [JGH]
2830 : !> \author JGH
2831 : ! **************************************************************************************************
2832 374 : SUBROUTINE ec_ks_solver(qs_env, ec_env)
2833 :
2834 : TYPE(qs_environment_type), POINTER :: qs_env
2835 : TYPE(energy_correction_type), POINTER :: ec_env
2836 :
2837 : CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_ks_solver'
2838 :
2839 : CHARACTER(LEN=default_string_length) :: headline
2840 : INTEGER :: handle, img, ispin, nhfimg, nspins
2841 374 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: ksmat, pmat, smat, wmat
2842 : TYPE(dbcsr_type), POINTER :: tsmat
2843 : TYPE(dft_control_type), POINTER :: dft_control
2844 :
2845 374 : CALL timeset(routineN, handle)
2846 :
2847 374 : CALL get_qs_env(qs_env=qs_env, dft_control=dft_control)
2848 374 : nspins = dft_control%nspins
2849 374 : nhfimg = SIZE(ec_env%matrix_s, 2)
2850 :
2851 : ! create density matrix
2852 374 : IF (.NOT. ASSOCIATED(ec_env%matrix_p)) THEN
2853 314 : headline = "DENSITY MATRIX"
2854 314 : CALL dbcsr_allocate_matrix_set(ec_env%matrix_p, nspins, nhfimg)
2855 628 : DO ispin = 1, nspins
2856 4970 : DO img = 1, nhfimg
2857 4342 : tsmat => ec_env%matrix_s(1, img)%matrix
2858 4342 : ALLOCATE (ec_env%matrix_p(ispin, img)%matrix)
2859 : CALL dbcsr_create(ec_env%matrix_p(ispin, img)%matrix, &
2860 4342 : name=TRIM(headline), template=tsmat)
2861 : CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_p(ispin, img)%matrix, &
2862 4656 : ec_env%sab_orb)
2863 : END DO
2864 : END DO
2865 : END IF
2866 : ! create energy weighted density matrix
2867 374 : IF (.NOT. ASSOCIATED(ec_env%matrix_w)) THEN
2868 314 : headline = "ENERGY WEIGHTED DENSITY MATRIX"
2869 314 : CALL dbcsr_allocate_matrix_set(ec_env%matrix_w, nspins, nhfimg)
2870 628 : DO ispin = 1, nspins
2871 4970 : DO img = 1, nhfimg
2872 4342 : tsmat => ec_env%matrix_s(1, img)%matrix
2873 4342 : ALLOCATE (ec_env%matrix_w(ispin, img)%matrix)
2874 : CALL dbcsr_create(ec_env%matrix_w(ispin, img)%matrix, &
2875 4342 : name=TRIM(headline), template=tsmat)
2876 : CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_w(ispin, img)%matrix, &
2877 4656 : ec_env%sab_orb)
2878 : END DO
2879 : END DO
2880 : END IF
2881 :
2882 374 : IF (ec_env%mao) THEN
2883 4 : CALL mao_create_matrices(ec_env, ksmat, smat, pmat, wmat)
2884 : ELSE
2885 370 : ksmat => ec_env%matrix_ks
2886 370 : smat => ec_env%matrix_s
2887 370 : pmat => ec_env%matrix_p
2888 370 : wmat => ec_env%matrix_w
2889 : END IF
2890 :
2891 374 : IF (ec_env%do_kpoints) THEN
2892 22 : IF (ec_env%ks_solver /= ec_diagonalization) THEN
2893 : CALL cp_abort(__LOCATION__, "Harris functional with k-points "// &
2894 0 : "needs diagonalization solver")
2895 : END IF
2896 : END IF
2897 :
2898 714 : SELECT CASE (ec_env%ks_solver)
2899 : CASE (ec_diagonalization)
2900 340 : IF (ec_env%do_kpoints) THEN
2901 22 : CALL ec_diag_solver_kp(qs_env, ec_env, ksmat, smat, pmat, wmat)
2902 : ELSE
2903 318 : CALL ec_diag_solver_gamma(qs_env, ec_env, ksmat, smat, pmat, wmat)
2904 : END IF
2905 : CASE (ec_ot_diag)
2906 4 : CALL ec_ot_diag_solver(qs_env, ec_env, ksmat, smat, pmat, wmat)
2907 : CASE (ec_matrix_sign, ec_matrix_trs4, ec_matrix_tc2)
2908 30 : CALL ec_ls_init(qs_env, ksmat, smat)
2909 30 : CALL ec_ls_solver(qs_env, pmat, wmat, ec_ls_method=ec_env%ks_solver)
2910 : CASE DEFAULT
2911 374 : CPABORT("Option invalid or unavailable for ec_env%ks_solver")
2912 : END SELECT
2913 :
2914 374 : IF (ec_env%mao) THEN
2915 4 : CALL mao_release_matrices(ec_env, ksmat, smat, pmat, wmat)
2916 : END IF
2917 :
2918 374 : CALL timestop(handle)
2919 :
2920 374 : END SUBROUTINE ec_ks_solver
2921 :
2922 : ! **************************************************************************************************
2923 : !> \brief Create matrices with MAO sizes
2924 : !> \param ec_env ...
2925 : !> \param ksmat ...
2926 : !> \param smat ...
2927 : !> \param pmat ...
2928 : !> \param wmat ...
2929 : !> \par History
2930 : !> 08.2016 created [JGH]
2931 : !> \author JGH
2932 : ! **************************************************************************************************
2933 8 : SUBROUTINE mao_create_matrices(ec_env, ksmat, smat, pmat, wmat)
2934 :
2935 : TYPE(energy_correction_type), POINTER :: ec_env
2936 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: ksmat, smat, pmat, wmat
2937 :
2938 : CHARACTER(LEN=*), PARAMETER :: routineN = 'mao_create_matrices'
2939 :
2940 : INTEGER :: handle, ispin, nspins
2941 4 : INTEGER, DIMENSION(:), POINTER :: col_blk_sizes
2942 : TYPE(dbcsr_distribution_type) :: dbcsr_dist
2943 4 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mao_coef
2944 : TYPE(dbcsr_type) :: cgmat
2945 :
2946 4 : CALL timeset(routineN, handle)
2947 :
2948 4 : mao_coef => ec_env%mao_coef
2949 :
2950 4 : NULLIFY (ksmat, smat, pmat, wmat)
2951 4 : nspins = SIZE(ec_env%matrix_ks, 1)
2952 4 : CALL dbcsr_get_info(mao_coef(1)%matrix, col_blk_size=col_blk_sizes, distribution=dbcsr_dist)
2953 4 : CALL dbcsr_allocate_matrix_set(ksmat, nspins, 1)
2954 4 : CALL dbcsr_allocate_matrix_set(smat, nspins, 1)
2955 8 : DO ispin = 1, nspins
2956 4 : ALLOCATE (ksmat(ispin, 1)%matrix)
2957 : CALL dbcsr_create(ksmat(ispin, 1)%matrix, dist=dbcsr_dist, name="MAO KS mat", &
2958 : matrix_type=dbcsr_type_symmetric, row_blk_size=col_blk_sizes, &
2959 4 : col_blk_size=col_blk_sizes)
2960 4 : ALLOCATE (smat(ispin, 1)%matrix)
2961 : CALL dbcsr_create(smat(ispin, 1)%matrix, dist=dbcsr_dist, name="MAO S mat", &
2962 : matrix_type=dbcsr_type_symmetric, row_blk_size=col_blk_sizes, &
2963 8 : col_blk_size=col_blk_sizes)
2964 : END DO
2965 : !
2966 4 : CALL dbcsr_create(cgmat, name="TEMP matrix", template=mao_coef(1)%matrix)
2967 8 : DO ispin = 1, nspins
2968 : CALL dbcsr_multiply("N", "N", 1.0_dp, ec_env%matrix_s(1, 1)%matrix, mao_coef(ispin)%matrix, &
2969 4 : 0.0_dp, cgmat)
2970 4 : CALL dbcsr_multiply("T", "N", 1.0_dp, mao_coef(ispin)%matrix, cgmat, 0.0_dp, smat(ispin, 1)%matrix)
2971 : CALL dbcsr_multiply("N", "N", 1.0_dp, ec_env%matrix_ks(1, 1)%matrix, mao_coef(ispin)%matrix, &
2972 4 : 0.0_dp, cgmat)
2973 8 : CALL dbcsr_multiply("T", "N", 1.0_dp, mao_coef(ispin)%matrix, cgmat, 0.0_dp, ksmat(ispin, 1)%matrix)
2974 : END DO
2975 4 : CALL dbcsr_release(cgmat)
2976 :
2977 4 : CALL dbcsr_allocate_matrix_set(pmat, nspins, 1)
2978 8 : DO ispin = 1, nspins
2979 4 : ALLOCATE (pmat(ispin, 1)%matrix)
2980 4 : CALL dbcsr_create(pmat(ispin, 1)%matrix, template=smat(1, 1)%matrix, name="MAO P mat")
2981 8 : CALL cp_dbcsr_alloc_block_from_nbl(pmat(ispin, 1)%matrix, ec_env%sab_orb)
2982 : END DO
2983 :
2984 4 : CALL dbcsr_allocate_matrix_set(wmat, nspins, 1)
2985 8 : DO ispin = 1, nspins
2986 4 : ALLOCATE (wmat(ispin, 1)%matrix)
2987 4 : CALL dbcsr_create(wmat(ispin, 1)%matrix, template=smat(1, 1)%matrix, name="MAO W mat")
2988 8 : CALL cp_dbcsr_alloc_block_from_nbl(wmat(ispin, 1)%matrix, ec_env%sab_orb)
2989 : END DO
2990 :
2991 4 : CALL timestop(handle)
2992 :
2993 4 : END SUBROUTINE mao_create_matrices
2994 :
2995 : ! **************************************************************************************************
2996 : !> \brief Release matrices with MAO sizes
2997 : !> \param ec_env ...
2998 : !> \param ksmat ...
2999 : !> \param smat ...
3000 : !> \param pmat ...
3001 : !> \param wmat ...
3002 : !> \par History
3003 : !> 08.2016 created [JGH]
3004 : !> \author JGH
3005 : ! **************************************************************************************************
3006 4 : SUBROUTINE mao_release_matrices(ec_env, ksmat, smat, pmat, wmat)
3007 :
3008 : TYPE(energy_correction_type), POINTER :: ec_env
3009 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: ksmat, smat, pmat, wmat
3010 :
3011 : CHARACTER(LEN=*), PARAMETER :: routineN = 'mao_release_matrices'
3012 :
3013 : INTEGER :: handle, ispin, nspins
3014 4 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mao_coef
3015 : TYPE(dbcsr_type) :: cgmat
3016 :
3017 4 : CALL timeset(routineN, handle)
3018 :
3019 4 : mao_coef => ec_env%mao_coef
3020 4 : nspins = SIZE(mao_coef, 1)
3021 :
3022 : ! save pmat/wmat in full basis format
3023 4 : CALL dbcsr_create(cgmat, name="TEMP matrix", template=mao_coef(1)%matrix)
3024 8 : DO ispin = 1, nspins
3025 4 : CALL dbcsr_multiply("N", "N", 1.0_dp, mao_coef(ispin)%matrix, pmat(ispin, 1)%matrix, 0.0_dp, cgmat)
3026 : CALL dbcsr_multiply("N", "T", 1.0_dp, mao_coef(ispin)%matrix, cgmat, 0.0_dp, &
3027 4 : ec_env%matrix_p(ispin, 1)%matrix, retain_sparsity=.TRUE.)
3028 4 : CALL dbcsr_multiply("N", "N", 1.0_dp, mao_coef(ispin)%matrix, wmat(ispin, 1)%matrix, 0.0_dp, cgmat)
3029 : CALL dbcsr_multiply("N", "T", 1.0_dp, mao_coef(ispin)%matrix, cgmat, 0.0_dp, &
3030 8 : ec_env%matrix_w(ispin, 1)%matrix, retain_sparsity=.TRUE.)
3031 : END DO
3032 4 : CALL dbcsr_release(cgmat)
3033 :
3034 4 : CALL dbcsr_deallocate_matrix_set(ksmat)
3035 4 : CALL dbcsr_deallocate_matrix_set(smat)
3036 4 : CALL dbcsr_deallocate_matrix_set(pmat)
3037 4 : CALL dbcsr_deallocate_matrix_set(wmat)
3038 :
3039 4 : CALL timestop(handle)
3040 :
3041 4 : END SUBROUTINE mao_release_matrices
3042 :
3043 : ! **************************************************************************************************
3044 : !> \brief Calculate the energy correction
3045 : !> \param ec_env ...
3046 : !> \param unit_nr ...
3047 : !> \author Creation (03.2014,JGH)
3048 : ! **************************************************************************************************
3049 1436 : SUBROUTINE ec_energy(ec_env, unit_nr)
3050 : TYPE(energy_correction_type) :: ec_env
3051 : INTEGER, INTENT(IN) :: unit_nr
3052 :
3053 : CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_energy'
3054 :
3055 : INTEGER :: handle, nspins
3056 : REAL(KIND=dp) :: eband, trace
3057 :
3058 718 : CALL timeset(routineN, handle)
3059 :
3060 718 : nspins = SIZE(ec_env%matrix_p, 1)
3061 718 : CALL calculate_ptrace(ec_env%matrix_s, ec_env%matrix_p, trace, nspins)
3062 718 : IF (unit_nr > 0) WRITE (unit_nr, '(T3,A,T65,F16.10)') 'Tr[PS] ', trace
3063 :
3064 : ! Total energy depends on energy correction method
3065 1092 : SELECT CASE (ec_env%energy_functional)
3066 : CASE (ec_functional_harris)
3067 :
3068 : ! Get energy of "band structure" term
3069 374 : CALL calculate_ptrace(ec_env%matrix_ks, ec_env%matrix_p, eband, nspins, .TRUE.)
3070 374 : ec_env%eband = eband + ec_env%efield_nuclear
3071 :
3072 : ! Add Harris functional "correction" terms
3073 : ec_env%etotal = ec_env%eband + ec_env%ehartree + ec_env%exc - ec_env%vhxc + ec_env%ekTS + &
3074 374 : ec_env%edispersion - ec_env%ex
3075 374 : IF (unit_nr > 0) THEN
3076 187 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Eband ", ec_env%eband
3077 187 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Ehartree ", ec_env%ehartree
3078 187 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Exc ", ec_env%exc
3079 187 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Ex ", ec_env%ex
3080 187 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Evhxc ", ec_env%vhxc
3081 187 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Edisp ", ec_env%edispersion
3082 187 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Entropy ", ec_env%ekTS
3083 187 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Etotal Harris Functional ", ec_env%etotal
3084 : END IF
3085 :
3086 : CASE (ec_functional_dc)
3087 :
3088 : ! Core hamiltonian energy
3089 304 : CALL calculate_ptrace(ec_env%matrix_h, ec_env%matrix_p, ec_env%ecore, nspins)
3090 :
3091 304 : ec_env%ecore = ec_env%ecore + ec_env%efield_nuclear
3092 : ec_env%etotal = ec_env%ecore + ec_env%ehartree + ec_env%ehartree_1c + &
3093 : ec_env%exc + ec_env%exc1 + ec_env%ekTS + ec_env%edispersion + &
3094 304 : ec_env%ex + ec_env%exc_aux_fit + ec_env%exc1_aux_fit
3095 :
3096 304 : IF (unit_nr > 0) THEN
3097 152 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Ecore ", ec_env%ecore
3098 152 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Ehartree ", ec_env%ehartree + ec_env%ehartree_1c
3099 152 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Exc ", ec_env%exc + ec_env%exc1
3100 152 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Ex ", ec_env%ex
3101 152 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Exc_aux_fit", ec_env%exc_aux_fit + ec_env%exc1_aux_fit
3102 152 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Edisp ", ec_env%edispersion
3103 152 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Entropy ", ec_env%ekTS
3104 152 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Etotal Energy Functional ", ec_env%etotal
3105 : END IF
3106 :
3107 : CASE (ec_functional_ext)
3108 :
3109 40 : ec_env%etotal = ec_env%ex
3110 40 : IF (unit_nr > 0) THEN
3111 20 : WRITE (unit_nr, '(T3,A,T56,F25.15)') "Etotal Energy Functional ", ec_env%etotal
3112 : END IF
3113 :
3114 : CASE DEFAULT
3115 :
3116 718 : CPABORT("Option invalid or unavailable for ec_env%energy_functional")
3117 :
3118 : END SELECT
3119 :
3120 718 : CALL timestop(handle)
3121 :
3122 718 : END SUBROUTINE ec_energy
3123 :
3124 : ! **************************************************************************************************
3125 : !> \brief builds either the full neighborlist or neighborlists of molecular
3126 : !> \brief subsets, depending on parameter values
3127 : !> \param qs_env ...
3128 : !> \param ec_env ...
3129 : !> \par History
3130 : !> 2012.07 created [Martin Haeufel]
3131 : !> 2016.07 Adapted for Harris functional [JGH]
3132 : !> \author Martin Haeufel
3133 : ! **************************************************************************************************
3134 718 : SUBROUTINE ec_build_neighborlist(qs_env, ec_env)
3135 : TYPE(qs_environment_type), POINTER :: qs_env
3136 : TYPE(energy_correction_type), POINTER :: ec_env
3137 :
3138 : CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_build_neighborlist'
3139 :
3140 : INTEGER :: handle, ikind, nimages, nkind, zat
3141 : LOGICAL :: all_potential_present, gth_potential_present, paw_atom, paw_atom_present, &
3142 : sgp_potential_present, skip_load_balance_distributed
3143 : LOGICAL, ALLOCATABLE, DIMENSION(:) :: all_present, default_present, &
3144 718 : oce_present, orb_present, ppl_present, &
3145 : ppnl_present
3146 : REAL(dp) :: subcells
3147 718 : REAL(dp), ALLOCATABLE, DIMENSION(:) :: all_radius, c_radius, oce_radius, &
3148 : orb_radius, ppl_radius, ppnl_radius
3149 : REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: pair_radius
3150 : TYPE(all_potential_type), POINTER :: all_potential
3151 718 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
3152 : TYPE(cell_type), POINTER :: cell
3153 : TYPE(dft_control_type), POINTER :: dft_control
3154 : TYPE(distribution_1d_type), POINTER :: distribution_1d
3155 : TYPE(distribution_2d_type), POINTER :: distribution_2d
3156 : TYPE(gth_potential_type), POINTER :: gth_potential
3157 : TYPE(gto_basis_set_type), POINTER :: basis_set
3158 718 : TYPE(local_atoms_type), ALLOCATABLE, DIMENSION(:) :: atom2d
3159 718 : TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
3160 : TYPE(mp_para_env_type), POINTER :: para_env
3161 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
3162 718 : POINTER :: sab_cn, sab_vdw
3163 718 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
3164 : TYPE(paw_proj_set_type), POINTER :: paw_proj
3165 : TYPE(qs_dispersion_type), POINTER :: dispersion_env
3166 718 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
3167 : TYPE(qs_kind_type), POINTER :: qs_kind
3168 : TYPE(qs_ks_env_type), POINTER :: ks_env
3169 : TYPE(sgp_potential_type), POINTER :: sgp_potential
3170 :
3171 718 : CALL timeset(routineN, handle)
3172 :
3173 718 : CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set)
3174 : CALL get_qs_kind_set(qs_kind_set, &
3175 : paw_atom_present=paw_atom_present, &
3176 : all_potential_present=all_potential_present, &
3177 : gth_potential_present=gth_potential_present, &
3178 718 : sgp_potential_present=sgp_potential_present)
3179 718 : nkind = SIZE(qs_kind_set)
3180 3590 : ALLOCATE (c_radius(nkind), default_present(nkind))
3181 3590 : ALLOCATE (orb_radius(nkind), all_radius(nkind), ppl_radius(nkind), ppnl_radius(nkind))
3182 3590 : ALLOCATE (orb_present(nkind), all_present(nkind), ppl_present(nkind), ppnl_present(nkind))
3183 2872 : ALLOCATE (pair_radius(nkind, nkind))
3184 3086 : ALLOCATE (atom2d(nkind))
3185 :
3186 : CALL get_qs_env(qs_env, &
3187 : atomic_kind_set=atomic_kind_set, &
3188 : cell=cell, &
3189 : distribution_2d=distribution_2d, &
3190 : local_particles=distribution_1d, &
3191 : particle_set=particle_set, &
3192 718 : molecule_set=molecule_set)
3193 :
3194 : CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
3195 718 : molecule_set, .FALSE., particle_set)
3196 :
3197 1650 : DO ikind = 1, nkind
3198 932 : CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom2d(ikind)%list)
3199 932 : qs_kind => qs_kind_set(ikind)
3200 932 : CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set, basis_type="HARRIS")
3201 932 : IF (ASSOCIATED(basis_set)) THEN
3202 932 : orb_present(ikind) = .TRUE.
3203 932 : CALL get_gto_basis_set(gto_basis_set=basis_set, kind_radius=orb_radius(ikind))
3204 : ELSE
3205 0 : orb_present(ikind) = .FALSE.
3206 0 : orb_radius(ikind) = 0.0_dp
3207 : END IF
3208 : CALL get_qs_kind(qs_kind, all_potential=all_potential, &
3209 932 : gth_potential=gth_potential, sgp_potential=sgp_potential)
3210 932 : IF (gth_potential_present .OR. sgp_potential_present) THEN
3211 860 : IF (ASSOCIATED(gth_potential)) THEN
3212 : CALL get_potential(potential=gth_potential, &
3213 : ppl_present=ppl_present(ikind), &
3214 : ppl_radius=ppl_radius(ikind), &
3215 : ppnl_present=ppnl_present(ikind), &
3216 860 : ppnl_radius=ppnl_radius(ikind))
3217 0 : ELSE IF (ASSOCIATED(sgp_potential)) THEN
3218 : CALL get_potential(potential=sgp_potential, &
3219 : ppl_present=ppl_present(ikind), &
3220 : ppl_radius=ppl_radius(ikind), &
3221 : ppnl_present=ppnl_present(ikind), &
3222 0 : ppnl_radius=ppnl_radius(ikind))
3223 : ELSE
3224 0 : ppl_present(ikind) = .FALSE.
3225 0 : ppl_radius(ikind) = 0.0_dp
3226 0 : ppnl_present(ikind) = .FALSE.
3227 0 : ppnl_radius(ikind) = 0.0_dp
3228 : END IF
3229 : END IF
3230 : ! Check the presence of an all electron potential or ERFC potential
3231 1650 : IF (all_potential_present .OR. sgp_potential_present) THEN
3232 72 : all_present(ikind) = .FALSE.
3233 72 : all_radius(ikind) = 0.0_dp
3234 72 : IF (ASSOCIATED(all_potential)) THEN
3235 72 : all_present(ikind) = .TRUE.
3236 72 : CALL get_potential(potential=all_potential, core_charge_radius=all_radius(ikind))
3237 0 : ELSE IF (ASSOCIATED(sgp_potential)) THEN
3238 0 : IF (sgp_potential%ecp_local) THEN
3239 0 : all_present(ikind) = .TRUE.
3240 0 : CALL get_potential(potential=sgp_potential, core_charge_radius=all_radius(ikind))
3241 : END IF
3242 : END IF
3243 : END IF
3244 : END DO
3245 :
3246 718 : CALL section_vals_val_get(qs_env%input, "DFT%SUBCELLS", r_val=subcells)
3247 :
3248 : ! overlap
3249 718 : CALL pair_radius_setup(orb_present, orb_present, orb_radius, orb_radius, pair_radius)
3250 : CALL build_neighbor_lists(ec_env%sab_orb, particle_set, atom2d, cell, pair_radius, &
3251 718 : subcells=subcells, nlname="sab_orb")
3252 : ! kpoints
3253 718 : IF (ec_env%do_kpoints) THEN
3254 : ! pair_radius maybe needs adjustment for HFX?
3255 : CALL build_neighbor_lists(ec_env%sab_kp, particle_set, atom2d, cell, pair_radius, &
3256 22 : subcells=subcells, nlname="sab_kp")
3257 22 : IF (ec_env%do_ec_hfx) THEN
3258 : CALL build_neighbor_lists(ec_env%sab_kp_nosym, particle_set, atom2d, cell, pair_radius, &
3259 0 : subcells=subcells, nlname="sab_kp_nosym", symmetric=.FALSE.)
3260 : END IF
3261 22 : CALL get_qs_env(qs_env=qs_env, para_env=para_env)
3262 22 : CALL kpoint_init_cell_index(ec_env%kpoints, ec_env%sab_kp, para_env, nimages)
3263 : END IF
3264 :
3265 : ! pseudopotential/AE
3266 718 : IF (all_potential_present .OR. sgp_potential_present) THEN
3267 36 : IF (ANY(all_present)) THEN
3268 36 : CALL pair_radius_setup(orb_present, all_present, orb_radius, all_radius, pair_radius)
3269 : CALL build_neighbor_lists(ec_env%sac_ae, particle_set, atom2d, cell, pair_radius, &
3270 36 : subcells=subcells, operator_type="ABC", nlname="sac_ae")
3271 : END IF
3272 : END IF
3273 :
3274 718 : IF (gth_potential_present .OR. sgp_potential_present) THEN
3275 682 : IF (ANY(ppl_present)) THEN
3276 682 : CALL pair_radius_setup(orb_present, ppl_present, orb_radius, ppl_radius, pair_radius)
3277 : CALL build_neighbor_lists(ec_env%sac_ppl, particle_set, atom2d, cell, pair_radius, &
3278 682 : subcells=subcells, operator_type="ABC", nlname="sac_ppl")
3279 : END IF
3280 :
3281 696 : IF (ANY(ppnl_present)) THEN
3282 676 : CALL pair_radius_setup(orb_present, ppnl_present, orb_radius, ppnl_radius, pair_radius)
3283 : CALL build_neighbor_lists(ec_env%sap_ppnl, particle_set, atom2d, cell, pair_radius, &
3284 676 : subcells=subcells, operator_type="ABBA", nlname="sap_ppnl")
3285 : END IF
3286 : END IF
3287 :
3288 : ! Build the neighbor lists for the vdW pair potential
3289 718 : c_radius(:) = 0.0_dp
3290 718 : dispersion_env => ec_env%dispersion_env
3291 718 : sab_vdw => dispersion_env%sab_vdw
3292 718 : sab_cn => dispersion_env%sab_cn
3293 718 : IF (dispersion_env%type == xc_vdw_fun_pairpot) THEN
3294 0 : c_radius(:) = dispersion_env%rc_disp
3295 0 : default_present = .TRUE. !include all atoms in vdW (even without basis)
3296 0 : CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
3297 : CALL build_neighbor_lists(sab_vdw, particle_set, atom2d, cell, pair_radius, &
3298 0 : subcells=subcells, operator_type="PP", nlname="sab_vdw")
3299 0 : dispersion_env%sab_vdw => sab_vdw
3300 0 : IF (dispersion_env%pp_type == vdw_pairpot_dftd3 .OR. &
3301 : dispersion_env%pp_type == vdw_pairpot_dftd3bj) THEN
3302 : ! Build the neighbor lists for coordination numbers as needed by the DFT-D3 method
3303 0 : DO ikind = 1, nkind
3304 0 : CALL get_atomic_kind(atomic_kind_set(ikind), z=zat)
3305 0 : c_radius(ikind) = 4._dp*ptable(zat)%covalent_radius*bohr
3306 : END DO
3307 0 : CALL pair_radius_setup(default_present, default_present, c_radius, c_radius, pair_radius)
3308 : CALL build_neighbor_lists(sab_cn, particle_set, atom2d, cell, pair_radius, &
3309 0 : subcells=subcells, operator_type="PP", nlname="sab_cn")
3310 0 : dispersion_env%sab_cn => sab_cn
3311 : END IF
3312 : END IF
3313 :
3314 : ! PAW
3315 718 : IF (paw_atom_present) THEN
3316 : IF (paw_atom_present) THEN
3317 438 : ALLOCATE (oce_present(nkind), oce_radius(nkind))
3318 146 : oce_radius = 0.0_dp
3319 : END IF
3320 342 : DO ikind = 1, nkind
3321 : ! Warning: we use the same paw_proj_set as for the reference method
3322 196 : CALL get_qs_kind(qs_kind_set(ikind), paw_proj_set=paw_proj, paw_atom=paw_atom)
3323 342 : IF (paw_atom) THEN
3324 196 : oce_present(ikind) = .TRUE.
3325 196 : CALL get_paw_proj_set(paw_proj_set=paw_proj, rcprj=oce_radius(ikind))
3326 : ELSE
3327 0 : oce_present(ikind) = .FALSE.
3328 : END IF
3329 : END DO
3330 :
3331 : ! Build orbital-GAPW projector overlap list
3332 146 : IF (ANY(oce_present)) THEN
3333 146 : CALL pair_radius_setup(orb_present, oce_present, orb_radius, oce_radius, pair_radius)
3334 : CALL build_neighbor_lists(ec_env%sap_oce, particle_set, atom2d, cell, pair_radius, &
3335 146 : subcells=subcells, operator_type="ABBA", nlname="sap_oce")
3336 : END IF
3337 146 : DEALLOCATE (oce_present, oce_radius)
3338 : END IF
3339 :
3340 : ! Release work storage
3341 718 : CALL atom2d_cleanup(atom2d)
3342 718 : DEALLOCATE (atom2d)
3343 718 : DEALLOCATE (orb_present, default_present, all_present, ppl_present, ppnl_present)
3344 718 : DEALLOCATE (orb_radius, all_radius, ppl_radius, ppnl_radius, c_radius)
3345 718 : DEALLOCATE (pair_radius)
3346 :
3347 : ! Task list
3348 718 : CALL get_qs_env(qs_env, ks_env=ks_env, dft_control=dft_control)
3349 718 : skip_load_balance_distributed = dft_control%qs_control%skip_load_balance_distributed
3350 718 : IF (ASSOCIATED(ec_env%task_list)) CALL deallocate_task_list(ec_env%task_list)
3351 718 : CALL allocate_task_list(ec_env%task_list)
3352 : CALL generate_qs_task_list(ks_env, ec_env%task_list, basis_type="HARRIS", &
3353 : reorder_rs_grid_ranks=.FALSE., &
3354 : skip_load_balance_distributed=skip_load_balance_distributed, &
3355 : sab_orb_external=ec_env%sab_orb, &
3356 718 : ext_kpoints=ec_env%kpoints)
3357 : ! Task list soft
3358 718 : IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
3359 146 : IF (ASSOCIATED(ec_env%task_list_soft)) CALL deallocate_task_list(ec_env%task_list_soft)
3360 146 : CALL allocate_task_list(ec_env%task_list_soft)
3361 : CALL generate_qs_task_list(ks_env, ec_env%task_list_soft, basis_type="HARRIS_SOFT", &
3362 : reorder_rs_grid_ranks=.FALSE., &
3363 : skip_load_balance_distributed=skip_load_balance_distributed, &
3364 : sab_orb_external=ec_env%sab_orb, &
3365 146 : ext_kpoints=ec_env%kpoints)
3366 : END IF
3367 :
3368 718 : CALL timestop(handle)
3369 :
3370 2872 : END SUBROUTINE ec_build_neighborlist
3371 :
3372 : ! **************************************************************************************************
3373 : !> \brief ...
3374 : !> \param qs_env ...
3375 : !> \param ec_env ...
3376 : ! **************************************************************************************************
3377 498 : SUBROUTINE ec_properties(qs_env, ec_env)
3378 : TYPE(qs_environment_type), POINTER :: qs_env
3379 : TYPE(energy_correction_type), POINTER :: ec_env
3380 :
3381 : CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_properties'
3382 :
3383 : CHARACTER(LEN=8), DIMENSION(3) :: rlab
3384 : CHARACTER(LEN=default_path_length) :: filename, my_pos_voro
3385 : CHARACTER(LEN=default_string_length) :: description
3386 : INTEGER :: akind, handle, i, ia, iatom, idir, ikind, iounit, ispin, maxmom, nspins, &
3387 : reference, should_print_bqb, should_print_voro, unit_nr, unit_nr_voro
3388 : LOGICAL :: append_voro, magnetic, periodic, &
3389 : voro_print_txt
3390 : REAL(KIND=dp) :: charge, dd, focc, tmp
3391 : REAL(KIND=dp), DIMENSION(3) :: cdip, pdip, rcc, rdip, ria, tdip
3392 498 : REAL(KIND=dp), DIMENSION(:), POINTER :: ref_point
3393 : TYPE(atomic_kind_type), POINTER :: atomic_kind
3394 : TYPE(cell_type), POINTER :: cell
3395 : TYPE(cp_logger_type), POINTER :: logger
3396 : TYPE(cp_result_type), POINTER :: results
3397 498 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s, moments
3398 : TYPE(dft_control_type), POINTER :: dft_control
3399 : TYPE(distribution_1d_type), POINTER :: local_particles
3400 : TYPE(mp_para_env_type), POINTER :: para_env
3401 498 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
3402 : TYPE(pw_env_type), POINTER :: pw_env
3403 498 : TYPE(pw_pool_p_type), DIMENSION(:), POINTER :: pw_pools
3404 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
3405 : TYPE(pw_r3d_rs_type) :: rho_elec_rspace
3406 498 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
3407 : TYPE(section_vals_type), POINTER :: ec_section, print_key, print_key_bqb, &
3408 : print_key_voro
3409 :
3410 498 : CALL timeset(routineN, handle)
3411 :
3412 498 : rlab(1) = "X"
3413 498 : rlab(2) = "Y"
3414 498 : rlab(3) = "Z"
3415 :
3416 498 : logger => cp_get_default_logger()
3417 498 : IF (logger%para_env%is_source()) THEN
3418 249 : iounit = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
3419 : ELSE
3420 : iounit = -1
3421 : END IF
3422 :
3423 498 : NULLIFY (dft_control)
3424 498 : CALL get_qs_env(qs_env, dft_control=dft_control)
3425 498 : nspins = dft_control%nspins
3426 :
3427 498 : ec_section => section_vals_get_subs_vals(qs_env%input, "DFT%ENERGY_CORRECTION")
3428 : print_key => section_vals_get_subs_vals(section_vals=ec_section, &
3429 498 : subsection_name="PRINT%MOMENTS")
3430 :
3431 498 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key), cp_p_file)) THEN
3432 :
3433 20 : IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
3434 0 : CPABORT("Properties for GAPW in EC NYA")
3435 : END IF
3436 :
3437 : maxmom = section_get_ival(section_vals=ec_section, &
3438 20 : keyword_name="PRINT%MOMENTS%MAX_MOMENT")
3439 : periodic = section_get_lval(section_vals=ec_section, &
3440 20 : keyword_name="PRINT%MOMENTS%PERIODIC")
3441 : reference = section_get_ival(section_vals=ec_section, &
3442 20 : keyword_name="PRINT%MOMENTS%REFERENCE")
3443 : magnetic = section_get_lval(section_vals=ec_section, &
3444 20 : keyword_name="PRINT%MOMENTS%MAGNETIC")
3445 20 : NULLIFY (ref_point)
3446 20 : CALL section_vals_val_get(ec_section, "PRINT%MOMENTS%REF_POINT", r_vals=ref_point)
3447 : unit_nr = cp_print_key_unit_nr(logger=logger, basis_section=ec_section, &
3448 : print_key_path="PRINT%MOMENTS", extension=".dat", &
3449 20 : middle_name="moments", log_filename=.FALSE.)
3450 :
3451 20 : IF (iounit > 0) THEN
3452 10 : IF (unit_nr /= iounit .AND. unit_nr > 0) THEN
3453 0 : INQUIRE (UNIT=unit_nr, NAME=filename)
3454 : WRITE (UNIT=iounit, FMT="(/,T2,A,2(/,T3,A),/)") &
3455 0 : "MOMENTS", "The electric/magnetic moments are written to file:", &
3456 0 : TRIM(filename)
3457 : ELSE
3458 10 : WRITE (UNIT=iounit, FMT="(/,T2,A)") "ELECTRIC/MAGNETIC MOMENTS"
3459 : END IF
3460 : END IF
3461 :
3462 20 : IF (periodic) THEN
3463 0 : CPABORT("Periodic moments not implemented with EC")
3464 : ELSE
3465 20 : CPASSERT(maxmom < 2)
3466 20 : CPASSERT(.NOT. magnetic)
3467 20 : IF (maxmom == 1) THEN
3468 20 : CALL get_qs_env(qs_env=qs_env, cell=cell, para_env=para_env)
3469 : ! reference point
3470 20 : CALL get_reference_point(rcc, qs_env=qs_env, reference=reference, ref_point=ref_point)
3471 : ! nuclear contribution
3472 20 : cdip = 0.0_dp
3473 : CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, &
3474 20 : qs_kind_set=qs_kind_set, local_particles=local_particles)
3475 60 : DO ikind = 1, SIZE(local_particles%n_el)
3476 88 : DO ia = 1, local_particles%n_el(ikind)
3477 28 : iatom = local_particles%list(ikind)%array(ia)
3478 : ! fold atomic positions back into unit cell
3479 224 : ria = pbc(particle_set(iatom)%r - rcc, cell) + rcc
3480 112 : ria = ria - rcc
3481 28 : atomic_kind => particle_set(iatom)%atomic_kind
3482 28 : CALL get_atomic_kind(atomic_kind, kind_number=akind)
3483 28 : CALL get_qs_kind(qs_kind_set(akind), core_charge=charge)
3484 152 : cdip(1:3) = cdip(1:3) - charge*ria(1:3)
3485 : END DO
3486 : END DO
3487 20 : CALL para_env%sum(cdip)
3488 : !
3489 : ! direct density contribution
3490 20 : CALL ec_efield_integrals(qs_env, ec_env, rcc)
3491 : !
3492 20 : pdip = 0.0_dp
3493 40 : DO ispin = 1, nspins
3494 100 : DO idir = 1, 3
3495 : CALL dbcsr_dot(ec_env%matrix_p(ispin, 1)%matrix, &
3496 60 : ec_env%efield%dipmat(idir)%matrix, tmp)
3497 80 : pdip(idir) = pdip(idir) + tmp
3498 : END DO
3499 : END DO
3500 : !
3501 : ! response contribution
3502 20 : CALL get_qs_env(qs_env=qs_env, matrix_s=matrix_s)
3503 20 : NULLIFY (moments)
3504 20 : CALL dbcsr_allocate_matrix_set(moments, 4)
3505 100 : DO i = 1, 4
3506 80 : ALLOCATE (moments(i)%matrix)
3507 80 : CALL dbcsr_copy(moments(i)%matrix, matrix_s(1)%matrix, "Moments")
3508 100 : CALL dbcsr_set(moments(i)%matrix, 0.0_dp)
3509 : END DO
3510 20 : CALL build_local_moment_matrix(qs_env, moments, 1, ref_point=rcc)
3511 : !
3512 : focc = 2.0_dp
3513 20 : IF (nspins == 2) focc = 1.0_dp
3514 20 : rdip = 0.0_dp
3515 40 : DO ispin = 1, nspins
3516 100 : DO idir = 1, 3
3517 60 : CALL dbcsr_dot(ec_env%matrix_z(ispin)%matrix, moments(idir)%matrix, tmp)
3518 80 : rdip(idir) = rdip(idir) + tmp
3519 : END DO
3520 : END DO
3521 20 : CALL dbcsr_deallocate_matrix_set(moments)
3522 : !
3523 80 : tdip = -(rdip + pdip + cdip)
3524 20 : IF (unit_nr > 0) THEN
3525 10 : WRITE (unit_nr, "(T3,A)") "Dipoles are based on the traditional operator."
3526 40 : dd = SQRT(SUM(tdip(1:3)**2))*debye
3527 10 : WRITE (unit_nr, "(T3,A)") "Dipole moment [Debye]"
3528 : WRITE (unit_nr, "(T5,3(A,A,F14.8,1X),T60,A,T67,F14.8)") &
3529 40 : (TRIM(rlab(i)), "=", tdip(i)*debye, i=1, 3), "Total=", dd
3530 : END IF
3531 : END IF
3532 : END IF
3533 :
3534 : CALL cp_print_key_finished_output(unit_nr=unit_nr, logger=logger, &
3535 20 : basis_section=ec_section, print_key_path="PRINT%MOMENTS")
3536 20 : CALL get_qs_env(qs_env=qs_env, results=results)
3537 20 : description = "[DIPOLE]"
3538 20 : CALL cp_results_erase(results=results, description=description)
3539 20 : CALL put_results(results=results, description=description, values=tdip(1:3))
3540 : END IF
3541 :
3542 : ! Do a Voronoi Integration or write a compressed BQB File
3543 498 : print_key_voro => section_vals_get_subs_vals(ec_section, "PRINT%VORONOI")
3544 498 : print_key_bqb => section_vals_get_subs_vals(ec_section, "PRINT%E_DENSITY_BQB")
3545 498 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key_voro), cp_p_file)) THEN
3546 4 : should_print_voro = 1
3547 : ELSE
3548 494 : should_print_voro = 0
3549 : END IF
3550 498 : IF (BTEST(cp_print_key_should_output(logger%iter_info, print_key_bqb), cp_p_file)) THEN
3551 0 : should_print_bqb = 1
3552 : ELSE
3553 498 : should_print_bqb = 0
3554 : END IF
3555 498 : IF ((should_print_voro /= 0) .OR. (should_print_bqb /= 0)) THEN
3556 :
3557 4 : IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
3558 0 : CPABORT("Properties for GAPW in EC NYA")
3559 : END IF
3560 :
3561 : CALL get_qs_env(qs_env=qs_env, &
3562 4 : pw_env=pw_env)
3563 : CALL pw_env_get(pw_env=pw_env, &
3564 : auxbas_pw_pool=auxbas_pw_pool, &
3565 4 : pw_pools=pw_pools)
3566 4 : CALL auxbas_pw_pool%create_pw(pw=rho_elec_rspace)
3567 :
3568 4 : IF (dft_control%nspins > 1) THEN
3569 :
3570 : ! add Pout and Pz
3571 0 : CALL pw_copy(ec_env%rhoout_r(1), rho_elec_rspace)
3572 0 : CALL pw_axpy(ec_env%rhoout_r(2), rho_elec_rspace)
3573 :
3574 0 : CALL pw_axpy(ec_env%rhoz_r(1), rho_elec_rspace)
3575 0 : CALL pw_axpy(ec_env%rhoz_r(2), rho_elec_rspace)
3576 : ELSE
3577 :
3578 : ! add Pout and Pz
3579 4 : CALL pw_copy(ec_env%rhoout_r(1), rho_elec_rspace)
3580 4 : CALL pw_axpy(ec_env%rhoz_r(1), rho_elec_rspace)
3581 : END IF ! nspins
3582 :
3583 4 : IF (should_print_voro /= 0) THEN
3584 4 : CALL section_vals_val_get(print_key_voro, "OUTPUT_TEXT", l_val=voro_print_txt)
3585 4 : IF (voro_print_txt) THEN
3586 4 : append_voro = section_get_lval(ec_section, "PRINT%VORONOI%APPEND")
3587 4 : my_pos_voro = "REWIND"
3588 4 : IF (append_voro) THEN
3589 0 : my_pos_voro = "APPEND"
3590 : END IF
3591 : unit_nr_voro = cp_print_key_unit_nr(logger, ec_section, "PRINT%VORONOI", extension=".voronoi", &
3592 4 : file_position=my_pos_voro, log_filename=.FALSE.)
3593 : ELSE
3594 0 : unit_nr_voro = 0
3595 : END IF
3596 : ELSE
3597 0 : unit_nr_voro = 0
3598 : END IF
3599 :
3600 : CALL entry_voronoi_or_bqb(should_print_voro, should_print_bqb, print_key_voro, print_key_bqb, &
3601 4 : unit_nr_voro, qs_env, rho_elec_rspace)
3602 :
3603 4 : CALL auxbas_pw_pool%give_back_pw(rho_elec_rspace)
3604 :
3605 4 : IF (unit_nr_voro > 0) THEN
3606 2 : CALL cp_print_key_finished_output(unit_nr_voro, logger, ec_section, "PRINT%VORONOI")
3607 : END IF
3608 :
3609 : END IF
3610 :
3611 498 : CALL timestop(handle)
3612 :
3613 498 : END SUBROUTINE ec_properties
3614 : ! **************************************************************************************************
3615 : !> \brief ...
3616 : !> \param qs_env ...
3617 : !> \param ec_env ...
3618 : !> \param unit_nr ...
3619 : ! **************************************************************************************************
3620 6 : SUBROUTINE harris_wfn_output(qs_env, ec_env, unit_nr)
3621 : TYPE(qs_environment_type), POINTER :: qs_env
3622 : TYPE(energy_correction_type), POINTER :: ec_env
3623 : INTEGER, INTENT(IN) :: unit_nr
3624 :
3625 : CHARACTER(LEN=*), PARAMETER :: routineN = 'harris_wfn_output'
3626 :
3627 : INTEGER :: handle, ic, ires, ispin, nimages, nsize, &
3628 : nspin
3629 : INTEGER, DIMENSION(3) :: cell
3630 6 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
3631 : TYPE(cp_blacs_env_type), POINTER :: blacs_env
3632 : TYPE(cp_fm_struct_type), POINTER :: fm_struct
3633 : TYPE(cp_fm_type) :: fmat
3634 : TYPE(cp_logger_type), POINTER :: logger
3635 6 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: denmat
3636 : TYPE(mp_para_env_type), POINTER :: para_env
3637 6 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
3638 6 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
3639 : TYPE(section_vals_type), POINTER :: ec_section
3640 :
3641 : MARK_USED(unit_nr)
3642 :
3643 6 : CALL timeset(routineN, handle)
3644 :
3645 6 : logger => cp_get_default_logger()
3646 :
3647 6 : ec_section => section_vals_get_subs_vals(qs_env%input, "DFT%ENERGY_CORRECTION")
3648 6 : CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set, particle_set=particle_set)
3649 :
3650 6 : IF (ec_env%do_kpoints) THEN
3651 : ires = cp_print_key_unit_nr(logger, ec_section, "PRINT%HARRIS_OUTPUT_WFN", &
3652 : extension=".kp", file_status="REPLACE", file_action="WRITE", &
3653 6 : file_form="UNFORMATTED", middle_name="Harris")
3654 :
3655 6 : CALL write_kpoints_file_header(qs_kind_set, particle_set, ires, basis_type="HARRIS")
3656 :
3657 6 : denmat => ec_env%matrix_p
3658 6 : nspin = SIZE(denmat, 1)
3659 6 : nimages = SIZE(denmat, 2)
3660 6 : NULLIFY (cell_to_index)
3661 6 : IF (nimages > 1) THEN
3662 6 : CALL get_kpoint_info(kpoint=ec_env%kpoints, cell_to_index=cell_to_index)
3663 : END IF
3664 6 : CALL dbcsr_get_info(denmat(1, 1)%matrix, nfullrows_total=nsize)
3665 6 : NULLIFY (blacs_env, para_env)
3666 6 : CALL get_qs_env(qs_env=qs_env, blacs_env=blacs_env, para_env=para_env)
3667 6 : NULLIFY (fm_struct)
3668 : CALL cp_fm_struct_create(fm_struct, context=blacs_env, nrow_global=nsize, &
3669 6 : ncol_global=nsize, para_env=para_env)
3670 6 : CALL cp_fm_create(fmat, fm_struct)
3671 6 : CALL cp_fm_struct_release(fm_struct)
3672 :
3673 12 : DO ispin = 1, nspin
3674 6 : IF (ires > 0) WRITE (ires) ispin, nspin, nimages
3675 870 : DO ic = 1, nimages
3676 858 : IF (nimages > 1) THEN
3677 858 : cell = get_cell(ic, cell_to_index)
3678 : ELSE
3679 0 : cell = 0
3680 : END IF
3681 858 : IF (ires > 0) WRITE (ires) ic, cell
3682 858 : CALL copy_dbcsr_to_fm(denmat(ispin, ic)%matrix, fmat)
3683 864 : CALL cp_fm_write_unformatted(fmat, ires)
3684 : END DO
3685 : END DO
3686 :
3687 6 : CALL cp_print_key_finished_output(ires, logger, ec_section, "PRINT%HARRIS_OUTPUT_WFN")
3688 6 : CALL cp_fm_release(fmat)
3689 : ELSE
3690 : CALL cp_warn(__LOCATION__, &
3691 : "Orbital energy correction potential is an experimental feature. "// &
3692 0 : "Use it with extreme care")
3693 : END IF
3694 :
3695 6 : CALL timestop(handle)
3696 :
3697 6 : END SUBROUTINE harris_wfn_output
3698 :
3699 : ! **************************************************************************************************
3700 : !> \brief ...
3701 : !> \param qs_env ...
3702 : !> \param ec_env ...
3703 : !> \param unit_nr ...
3704 : ! **************************************************************************************************
3705 2 : SUBROUTINE response_force_error(qs_env, ec_env, unit_nr)
3706 : TYPE(qs_environment_type), POINTER :: qs_env
3707 : TYPE(energy_correction_type), POINTER :: ec_env
3708 : INTEGER, INTENT(IN) :: unit_nr
3709 :
3710 : CHARACTER(LEN=10) :: eformat
3711 : INTEGER :: feunit, funit, i, ia, ib, ispin, mref, &
3712 : na, nao, natom, nb, norb, nref, &
3713 : nsample, nspins
3714 4 : INTEGER, ALLOCATABLE, DIMENSION(:) :: natom_of_kind, rlist, t2cind
3715 : LOGICAL :: debug_f, do_resp, is_source
3716 : REAL(KIND=dp) :: focc, rfac, vres
3717 2 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: tvec, yvec
3718 4 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: eforce, fmlocal, fmreord, smat
3719 2 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: smpforce
3720 2 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
3721 : TYPE(cp_fm_struct_type), POINTER :: fm_struct, fm_struct_mat
3722 : TYPE(cp_fm_type) :: hmats
3723 2 : TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: rpmos, Spmos
3724 2 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
3725 : TYPE(dbcsr_type), POINTER :: mats
3726 : TYPE(mp_para_env_type), POINTER :: para_env
3727 2 : TYPE(qs_force_type), DIMENSION(:), POINTER :: ks_force, res_force
3728 : TYPE(virial_type) :: res_virial
3729 : TYPE(virial_type), POINTER :: ks_virial
3730 :
3731 2 : IF (unit_nr > 0) THEN
3732 1 : WRITE (unit_nr, '(/,T2,A,A,A,A,A)') "!", REPEAT("-", 25), &
3733 2 : " Response Force Error Est. ", REPEAT("-", 25), "!"
3734 1 : SELECT CASE (ec_env%error_method)
3735 : CASE ("F")
3736 0 : WRITE (unit_nr, '(T2,A)') " Response Force Error Est. using full RHS"
3737 : CASE ("D")
3738 0 : WRITE (unit_nr, '(T2,A)') " Response Force Error Est. using delta RHS"
3739 : CASE ("E")
3740 1 : WRITE (unit_nr, '(T2,A)') " Response Force Error Est. using extrapolated RHS"
3741 1 : WRITE (unit_nr, '(T2,A,E20.10)') " Extrapolation cutoff:", ec_env%error_cutoff
3742 1 : WRITE (unit_nr, '(T2,A,I10)') " Max. extrapolation size:", ec_env%error_subspace
3743 : CASE DEFAULT
3744 1 : CPABORT("Unknown Error Estimation Method")
3745 : END SELECT
3746 : END IF
3747 :
3748 2 : IF (ABS(ec_env%orbrot_index) > 1.E-8_dp .OR. ec_env%phase_index > 1.E-8_dp) THEN
3749 0 : CPABORT("Response error calculation for rotated orbital sets not implemented")
3750 : END IF
3751 :
3752 2 : SELECT CASE (ec_env%energy_functional)
3753 : CASE (ec_functional_harris)
3754 0 : CPWARN('Response force error calculation not possible for Harris functional.')
3755 : CASE (ec_functional_dc)
3756 0 : CPWARN('Response force error calculation not possible for DCDFT.')
3757 : CASE (ec_functional_ext)
3758 :
3759 : ! backup force array
3760 : CALL get_qs_env(qs_env, force=ks_force, virial=ks_virial, &
3761 2 : atomic_kind_set=atomic_kind_set)
3762 2 : CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, natom_of_kind=natom_of_kind)
3763 2 : NULLIFY (res_force)
3764 2 : CALL allocate_qs_force(res_force, natom_of_kind)
3765 2 : DEALLOCATE (natom_of_kind)
3766 2 : CALL zero_qs_force(res_force)
3767 2 : res_virial = ks_virial
3768 2 : CALL zero_virial(ks_virial, reset=.FALSE.)
3769 2 : CALL set_qs_env(qs_env, force=res_force)
3770 : !
3771 2 : CALL get_qs_env(qs_env, natom=natom)
3772 6 : ALLOCATE (eforce(3, natom))
3773 : !
3774 2 : CALL get_qs_env(qs_env, para_env=para_env)
3775 2 : is_source = para_env%is_source()
3776 : !
3777 2 : nspins = SIZE(ec_env%mo_occ)
3778 2 : CALL cp_fm_get_info(ec_env%mo_occ(1), nrow_global=nao)
3779 : !
3780 2 : IF (is_source) THEN
3781 : CALL open_file(ec_env%exresperr_fn, file_status="OLD", file_action="READ", &
3782 1 : file_form="FORMATTED", unit_number=funit)
3783 1 : READ (funit, '(A)') eformat
3784 1 : CALL uppercase(eformat)
3785 1 : READ (funit, *) nsample
3786 : END IF
3787 2 : CALL para_env%bcast(nsample, para_env%source)
3788 2 : CALL para_env%bcast(eformat, para_env%source)
3789 : !
3790 2 : CALL cp_fm_get_info(ec_env%mo_occ(1), matrix_struct=fm_struct)
3791 : CALL cp_fm_struct_create(fm_struct_mat, template_fmstruct=fm_struct, &
3792 2 : nrow_global=nao, ncol_global=nao)
3793 8 : ALLOCATE (fmlocal(nao, nao))
3794 2 : IF (ADJUSTL(TRIM(eformat)) == "TREXIO") THEN
3795 0 : ALLOCATE (fmreord(nao, nao))
3796 0 : CALL get_t2cindex(qs_env, t2cind)
3797 : END IF
3798 20 : ALLOCATE (rpmos(nsample, nspins))
3799 8 : ALLOCATE (smpforce(3, natom, nsample))
3800 2 : smpforce = 0.0_dp
3801 : !
3802 2 : focc = 2.0_dp
3803 2 : IF (nspins == 1) focc = 4.0_dp
3804 2 : CALL cp_fm_create(hmats, fm_struct_mat)
3805 : !
3806 12 : DO i = 1, nsample
3807 22 : DO ispin = 1, nspins
3808 10 : CALL cp_fm_create(rpmos(i, ispin), fm_struct)
3809 10 : IF (is_source) THEN
3810 5 : READ (funit, *) na, nb
3811 5 : CPASSERT(na == nao .AND. nb == nao)
3812 5 : READ (funit, *) fmlocal
3813 : ELSE
3814 5 : fmlocal = 0.0_dp
3815 : END IF
3816 10 : CALL para_env%bcast(fmlocal)
3817 : !
3818 10 : SELECT CASE (ADJUSTL(TRIM(eformat)))
3819 : CASE ("CP2K")
3820 : ! nothing to do
3821 : CASE ("TREXIO")
3822 : ! reshuffel indices
3823 0 : DO ia = 1, nao
3824 0 : DO ib = 1, nao
3825 0 : fmreord(ia, ib) = fmlocal(t2cind(ia), t2cind(ib))
3826 : END DO
3827 : END DO
3828 0 : fmlocal(1:nao, 1:nao) = fmreord(1:nao, 1:nao)
3829 : CASE DEFAULT
3830 10 : CPABORT("Error file dE/dC: unknown format")
3831 : END SELECT
3832 : !
3833 10 : CALL cp_fm_set_submatrix(hmats, fmlocal, 1, 1, nao, nao)
3834 10 : CALL cp_fm_get_info(rpmos(i, ispin), ncol_global=norb)
3835 : CALL parallel_gemm('N', 'N', nao, norb, nao, focc, hmats, &
3836 10 : ec_env%mo_occ(ispin), 0.0_dp, rpmos(i, ispin))
3837 30 : IF (ec_env%error_method == "D" .OR. ec_env%error_method == "E") THEN
3838 10 : CALL cp_fm_scale_and_add(1.0_dp, rpmos(i, ispin), -1.0_dp, ec_env%cpref(ispin))
3839 : END IF
3840 : END DO
3841 : END DO
3842 2 : CALL cp_fm_struct_release(fm_struct_mat)
3843 2 : IF (ADJUSTL(TRIM(eformat)) == "TREXIO") THEN
3844 0 : DEALLOCATE (fmreord, t2cind)
3845 : END IF
3846 :
3847 2 : IF (is_source) THEN
3848 1 : CALL close_file(funit)
3849 : END IF
3850 :
3851 2 : IF (unit_nr > 0) THEN
3852 : CALL open_file(ec_env%exresult_fn, file_status="OLD", file_form="FORMATTED", &
3853 1 : file_action="WRITE", file_position="APPEND", unit_number=feunit)
3854 1 : WRITE (feunit, "(/,6X,A)") " Response Forces from error sampling [Hartree/Bohr]"
3855 1 : i = 0
3856 1 : WRITE (feunit, "(5X,I8)") i
3857 4 : DO ia = 1, natom
3858 13 : WRITE (feunit, "(5X,3F20.12)") ec_env%rf(1:3, ia)
3859 : END DO
3860 : END IF
3861 :
3862 2 : debug_f = ec_env%debug_forces .OR. ec_env%debug_stress
3863 :
3864 2 : IF (ec_env%error_method == "E") THEN
3865 2 : CALL get_qs_env(qs_env, matrix_s=matrix_s)
3866 2 : mats => matrix_s(1)%matrix
3867 18 : ALLOCATE (Spmos(nsample, nspins))
3868 12 : DO i = 1, nsample
3869 22 : DO ispin = 1, nspins
3870 10 : CALL cp_fm_create(Spmos(i, ispin), fm_struct, set_zero=.TRUE.)
3871 20 : CALL cp_dbcsr_sm_fm_multiply(mats, rpmos(i, ispin), Spmos(i, ispin), norb)
3872 : END DO
3873 : END DO
3874 : END IF
3875 :
3876 2 : mref = ec_env%error_subspace
3877 2 : mref = MIN(mref, nsample)
3878 2 : nref = 0
3879 18 : ALLOCATE (smat(mref, mref), tvec(mref), yvec(mref), rlist(mref))
3880 2 : rlist = 0
3881 :
3882 2 : CALL cp_fm_release(ec_env%cpmos)
3883 :
3884 12 : DO i = 1, nsample
3885 10 : IF (unit_nr > 0) THEN
3886 5 : WRITE (unit_nr, '(T2,A,I6)') " Response Force Number ", i
3887 : END IF
3888 : !
3889 10 : CALL zero_qs_force(res_force)
3890 10 : CALL zero_virial(ks_virial, reset=.FALSE.)
3891 20 : DO ispin = 1, nspins
3892 20 : CALL dbcsr_set(ec_env%matrix_hz(ispin)%matrix, 0.0_dp)
3893 : END DO
3894 : !
3895 40 : ALLOCATE (ec_env%cpmos(nspins))
3896 20 : DO ispin = 1, nspins
3897 20 : CALL cp_fm_create(ec_env%cpmos(ispin), fm_struct)
3898 : END DO
3899 : !
3900 10 : do_resp = .TRUE.
3901 10 : IF (ec_env%error_method == "F" .OR. ec_env%error_method == "D") THEN
3902 0 : DO ispin = 1, nspins
3903 0 : CALL cp_fm_to_fm(rpmos(i, ispin), ec_env%cpmos(ispin))
3904 : END DO
3905 10 : ELSE IF (ec_env%error_method == "E") THEN
3906 10 : CALL cp_extrapolate(rpmos, Spmos, i, nref, rlist, smat, tvec, yvec, vres)
3907 10 : IF (vres > ec_env%error_cutoff .OR. nref < MIN(5, mref)) THEN
3908 20 : DO ispin = 1, nspins
3909 20 : CALL cp_fm_to_fm(rpmos(i, ispin), ec_env%cpmos(ispin))
3910 : END DO
3911 30 : DO ib = 1, nref
3912 20 : ia = rlist(ib)
3913 20 : rfac = -yvec(ib)
3914 50 : DO ispin = 1, nspins
3915 : CALL cp_fm_scale_and_add(1.0_dp, ec_env%cpmos(ispin), &
3916 40 : rfac, rpmos(ia, ispin))
3917 : END DO
3918 : END DO
3919 : ELSE
3920 : do_resp = .FALSE.
3921 : END IF
3922 10 : IF (unit_nr > 0) THEN
3923 : WRITE (unit_nr, '(T2,A,T60,I4,T69,F12.8)') &
3924 5 : " Response Vector Extrapolation [nref|delta] = ", nref, vres
3925 : END IF
3926 : ELSE
3927 0 : CPABORT("Unknown Error Estimation Method")
3928 : END IF
3929 :
3930 10 : IF (do_resp) THEN
3931 : CALL matrix_r_forces(qs_env, ec_env%cpmos, ec_env%mo_occ, &
3932 : ec_env%matrix_w(1, 1)%matrix, unit_nr, &
3933 10 : ec_env%debug_forces, ec_env%debug_stress)
3934 :
3935 10 : CALL response_calculation(qs_env, ec_env, silent=.TRUE.)
3936 :
3937 : CALL response_force(qs_env, &
3938 : vh_rspace=ec_env%vh_rspace, &
3939 : vxc_rspace=ec_env%vxc_rspace, &
3940 : vtau_rspace=ec_env%vtau_rspace, &
3941 : vadmm_rspace=ec_env%vadmm_rspace, &
3942 : vadmm_tau_rspace=ec_env%vadmm_tau_rspace, &
3943 : matrix_hz=ec_env%matrix_hz, &
3944 : matrix_pz=ec_env%matrix_z, &
3945 : matrix_pz_admm=ec_env%z_admm, &
3946 : matrix_wz=ec_env%matrix_wz, &
3947 : rhopz_r=ec_env%rhoz_r, &
3948 : zehartree=ec_env%ehartree, &
3949 : zexc=ec_env%exc, &
3950 : zexc_aux_fit=ec_env%exc_aux_fit, &
3951 : p_env=ec_env%p_env, &
3952 10 : debug=debug_f)
3953 10 : CALL total_qs_force(eforce, res_force, atomic_kind_set)
3954 10 : CALL para_env%sum(eforce)
3955 : ELSE
3956 0 : IF (unit_nr > 0) THEN
3957 0 : WRITE (unit_nr, '(T2,A)') " Response Force Calculation is skipped. "
3958 : END IF
3959 0 : eforce = 0.0_dp
3960 : END IF
3961 : !
3962 10 : IF (ec_env%error_method == "D") THEN
3963 0 : eforce(1:3, 1:natom) = eforce(1:3, 1:natom) + ec_env%rf(1:3, 1:natom)
3964 0 : smpforce(1:3, 1:natom, i) = eforce(1:3, 1:natom)
3965 10 : ELSE IF (ec_env%error_method == "E") THEN
3966 30 : DO ib = 1, nref
3967 20 : ia = rlist(ib)
3968 20 : rfac = yvec(ib)
3969 270 : eforce(1:3, 1:natom) = eforce(1:3, 1:natom) + rfac*smpforce(1:3, 1:natom, ia)
3970 : END DO
3971 130 : smpforce(1:3, 1:natom, i) = eforce(1:3, 1:natom)
3972 130 : eforce(1:3, 1:natom) = eforce(1:3, 1:natom) + ec_env%rf(1:3, 1:natom)
3973 10 : IF (do_resp .AND. nref < mref) THEN
3974 10 : nref = nref + 1
3975 10 : rlist(nref) = i
3976 : END IF
3977 : ELSE
3978 0 : smpforce(1:3, 1:natom, i) = eforce(1:3, 1:natom)
3979 : END IF
3980 :
3981 10 : IF (unit_nr > 0) THEN
3982 5 : WRITE (unit_nr, *) " FORCES"
3983 20 : DO ia = 1, natom
3984 15 : WRITE (unit_nr, "(i7,3F11.6,6X,3F11.6)") ia, eforce(1:3, ia), &
3985 80 : (eforce(1:3, ia) - ec_env%rf(1:3, ia))
3986 : END DO
3987 5 : WRITE (unit_nr, *)
3988 : ! force file
3989 5 : WRITE (feunit, "(5X,I8)") i
3990 20 : DO ia = 1, natom
3991 20 : WRITE (feunit, "(5X,3F20.12)") eforce(1:3, ia)
3992 : END DO
3993 : END IF
3994 :
3995 12 : CALL cp_fm_release(ec_env%cpmos)
3996 :
3997 : END DO
3998 :
3999 2 : IF (unit_nr > 0) THEN
4000 1 : CALL close_file(feunit)
4001 : END IF
4002 :
4003 2 : DEALLOCATE (smat, tvec, yvec, rlist)
4004 :
4005 2 : CALL cp_fm_release(hmats)
4006 2 : CALL cp_fm_release(rpmos)
4007 2 : IF (ec_env%error_method == "E") THEN
4008 2 : CALL cp_fm_release(Spmos)
4009 : END IF
4010 :
4011 2 : DEALLOCATE (eforce, smpforce)
4012 :
4013 : ! reset force array
4014 2 : CALL get_qs_env(qs_env, force=res_force, virial=ks_virial)
4015 2 : CALL set_qs_env(qs_env, force=ks_force)
4016 2 : CALL deallocate_qs_force(res_force)
4017 6 : ks_virial = res_virial
4018 :
4019 : CASE DEFAULT
4020 2 : CPABORT("unknown energy correction")
4021 : END SELECT
4022 :
4023 460 : END SUBROUTINE response_force_error
4024 :
4025 : ! **************************************************************************************************
4026 : !> \brief ...
4027 : !> \param rpmos ...
4028 : !> \param Spmos ...
4029 : !> \param ip ...
4030 : !> \param nref ...
4031 : !> \param rlist ...
4032 : !> \param smat ...
4033 : !> \param tvec ...
4034 : !> \param yvec ...
4035 : !> \param vres ...
4036 : ! **************************************************************************************************
4037 10 : SUBROUTINE cp_extrapolate(rpmos, Spmos, ip, nref, rlist, smat, tvec, yvec, vres)
4038 : TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: rpmos, Spmos
4039 : INTEGER, INTENT(IN) :: ip, nref
4040 : INTEGER, DIMENSION(:), INTENT(IN) :: rlist
4041 : REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT) :: smat
4042 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: tvec, yvec
4043 : REAL(KIND=dp), INTENT(OUT) :: vres
4044 :
4045 : INTEGER :: i, ia, j, ja
4046 : REAL(KIND=dp) :: aval
4047 10 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: sinv
4048 :
4049 310 : smat = 0.0_dp
4050 60 : tvec = 0.0_dp
4051 60 : yvec = 0.0_dp
4052 10 : aval = 0.0_dp
4053 :
4054 10 : IF (nref > 0) THEN
4055 32 : ALLOCATE (sinv(nref, nref))
4056 : !
4057 28 : DO i = 1, nref
4058 20 : ia = rlist(i)
4059 20 : tvec(i) = ctrace(rpmos(ip, :), Spmos(ia, :))
4060 40 : DO j = i + 1, nref
4061 20 : ja = rlist(j)
4062 20 : smat(j, i) = ctrace(rpmos(ja, :), Spmos(ia, :))
4063 40 : smat(i, j) = smat(j, i)
4064 : END DO
4065 28 : smat(i, i) = ctrace(rpmos(ia, :), Spmos(ia, :))
4066 : END DO
4067 8 : aval = ctrace(rpmos(ip, :), Spmos(ip, :))
4068 : !
4069 88 : sinv(1:nref, 1:nref) = smat(1:nref, 1:nref)
4070 8 : CALL invmat_symm(sinv(1:nref, 1:nref))
4071 : !
4072 108 : yvec(1:nref) = MATMUL(sinv(1:nref, 1:nref), tvec(1:nref))
4073 : !
4074 28 : vres = aval - SUM(yvec(1:nref)*tvec(1:nref))
4075 8 : vres = SQRT(ABS(vres))
4076 : !
4077 8 : DEALLOCATE (sinv)
4078 : ELSE
4079 2 : vres = 1.0_dp
4080 : END IF
4081 :
4082 10 : END SUBROUTINE cp_extrapolate
4083 :
4084 : ! **************************************************************************************************
4085 : !> \brief ...
4086 : !> \param ca ...
4087 : !> \param cb ...
4088 : !> \return ...
4089 : ! **************************************************************************************************
4090 68 : FUNCTION ctrace(ca, cb)
4091 : TYPE(cp_fm_type), DIMENSION(:) :: ca, cb
4092 : REAL(KIND=dp) :: ctrace
4093 :
4094 : INTEGER :: is, ns
4095 : REAL(KIND=dp) :: trace
4096 :
4097 68 : ns = SIZE(ca)
4098 68 : ctrace = 0.0_dp
4099 136 : DO is = 1, ns
4100 : trace = 0.0_dp
4101 68 : CALL cp_fm_trace(ca(is), cb(is), trace)
4102 136 : ctrace = ctrace + trace
4103 : END DO
4104 :
4105 68 : END FUNCTION ctrace
4106 :
4107 : ! **************************************************************************************************
4108 : !> \brief ...
4109 : !> \param qs_env ...
4110 : !> \param t2cind ...
4111 : ! **************************************************************************************************
4112 0 : SUBROUTINE get_t2cindex(qs_env, t2cind)
4113 : TYPE(qs_environment_type), POINTER :: qs_env
4114 : INTEGER, ALLOCATABLE, DIMENSION(:) :: t2cind
4115 :
4116 : INTEGER :: i, iatom, ikind, is, iset, ishell, k, l, &
4117 : m, natom, nset, nsgf, numshell
4118 0 : INTEGER, ALLOCATABLE, DIMENSION(:) :: lshell
4119 0 : INTEGER, DIMENSION(:), POINTER :: nshell
4120 0 : INTEGER, DIMENSION(:, :), POINTER :: lval
4121 : TYPE(gto_basis_set_type), POINTER :: basis_set
4122 0 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
4123 0 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
4124 :
4125 : ! Reorder index for basis functions from TREXIO to CP2K
4126 :
4127 0 : CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set, particle_set=particle_set, natom=natom)
4128 0 : CALL get_qs_kind_set(qs_kind_set, nshell=numshell, nsgf=nsgf)
4129 :
4130 0 : ALLOCATE (t2cind(nsgf))
4131 0 : ALLOCATE (lshell(numshell))
4132 :
4133 0 : ishell = 0
4134 0 : DO iatom = 1, natom
4135 0 : CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
4136 0 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_set, basis_type="ORB")
4137 0 : CALL get_gto_basis_set(basis_set, nset=nset, nshell=nshell, l=lval)
4138 0 : DO iset = 1, nset
4139 0 : DO is = 1, nshell(iset)
4140 0 : ishell = ishell + 1
4141 0 : l = lval(is, iset)
4142 0 : lshell(ishell) = l
4143 : END DO
4144 : END DO
4145 : END DO
4146 :
4147 : i = 0
4148 0 : DO ishell = 1, numshell
4149 0 : l = lshell(ishell)
4150 0 : DO k = 1, 2*l + 1
4151 0 : m = (-1)**k*FLOOR(REAL(k, KIND=dp)/2.0_dp)
4152 0 : t2cind(i + l + 1 + m) = i + k
4153 : END DO
4154 0 : i = i + 2*l + 1
4155 : END DO
4156 :
4157 0 : DEALLOCATE (lshell)
4158 :
4159 0 : END SUBROUTINE get_t2cindex
4160 :
4161 : END MODULE energy_corrections
|