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