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 : !> \brief Utility routines for qs_scf
9 : ! **************************************************************************************************
10 : MODULE qs_scf_loop_utils
11 : USE cp_cfm_types, ONLY: cp_cfm_create,&
12 : cp_cfm_release,&
13 : cp_cfm_to_cfm,&
14 : cp_cfm_to_fm,&
15 : cp_cfm_type,&
16 : cp_fm_to_cfm
17 : USE cp_control_types, ONLY: dft_control_type,&
18 : hairy_probes_type
19 : USE cp_dbcsr_api, ONLY: dbcsr_copy,&
20 : dbcsr_get_info,&
21 : dbcsr_p_type,&
22 : dbcsr_release,&
23 : dbcsr_release_p,&
24 : dbcsr_scale,&
25 : dbcsr_set,&
26 : dbcsr_type
27 : USE cp_dbcsr_contrib, ONLY: dbcsr_dot,&
28 : dbcsr_get_diag,&
29 : dbcsr_scale_by_vector
30 : USE cp_dbcsr_operations, ONLY: copy_dbcsr_to_fm,&
31 : copy_fm_to_dbcsr,&
32 : cp_dbcsr_sm_fm_multiply,&
33 : dbcsr_allocate_matrix_set,&
34 : dbcsr_deallocate_matrix_set
35 : USE cp_external_control, ONLY: external_control
36 : USE cp_fm_basic_linalg, ONLY: cp_complex_fm_gemm,&
37 : cp_fm_column_scale,&
38 : cp_fm_scale_and_add
39 : USE cp_fm_struct, ONLY: cp_fm_struct_create,&
40 : cp_fm_struct_release,&
41 : cp_fm_struct_type
42 : USE cp_fm_types, ONLY: cp_fm_create,&
43 : cp_fm_get_info,&
44 : cp_fm_get_submatrix,&
45 : cp_fm_release,&
46 : cp_fm_set_submatrix,&
47 : cp_fm_to_fm,&
48 : cp_fm_type
49 : USE cp_log_handling, ONLY: cp_to_string
50 : USE dft_plus_u, ONLY: lowdin_kp_apply,&
51 : lowdin_kp_apply_mo,&
52 : lowdin_kp_kernel,&
53 : lowdin_kp_population
54 : USE ieee_arithmetic, ONLY: ieee_is_finite
55 : USE input_constants, ONLY: diag_update_method_adiis,&
56 : smear_fermi_dirac,&
57 : smear_gaussian,&
58 : smear_mp,&
59 : smear_mv
60 : USE input_section_types, ONLY: section_vals_get,&
61 : section_vals_get_subs_vals,&
62 : section_vals_type
63 : USE kinds, ONLY: default_string_length,&
64 : dp
65 : USE kpoint_methods, ONLY: kpoint_density_matrices,&
66 : kpoint_density_transform,&
67 : kpoint_set_mo_occupation
68 : USE kpoint_types, ONLY: get_kpoint_info,&
69 : kpoint_env_type,&
70 : kpoint_type
71 : USE message_passing, ONLY: mp_para_env_type
72 : USE physcon, ONLY: evolt
73 : USE qs_density_matrices, ONLY: calculate_density_matrix
74 : USE qs_density_mixing_types, ONLY: broyden_mixing_nr,&
75 : direct_mixing_nr,&
76 : gspace_mixing_nr,&
77 : modified_broyden_mixing_nr,&
78 : multisecant_mixing_nr,&
79 : new_pulay_mixing_nr,&
80 : no_mixing_nr,&
81 : pulay_mixing_nr
82 : USE qs_energy_types, ONLY: qs_energy_type
83 : USE qs_environment_types, ONLY: get_qs_env,&
84 : qs_environment_type
85 : USE qs_fb_env_methods, ONLY: fb_env_do_diag
86 : USE qs_gspace_mixing, ONLY: gspace_mixing
87 : USE qs_kind_types, ONLY: get_qs_kind,&
88 : qs_kind_type,&
89 : set_qs_kind
90 : USE qs_kpoint_operators, ONLY: kpoint_operator_context_create,&
91 : kpoint_operator_context_release,&
92 : kpoint_operator_context_type,&
93 : kpoint_operator_get,&
94 : kpoint_operator_get_local,&
95 : kpoint_operator_prepare,&
96 : kpoint_operator_store,&
97 : kpoint_slot_ks
98 : USE qs_kpp1_env_types, ONLY: kpp1_release,&
99 : qs_kpp1_env_type
100 : USE qs_ks_types, ONLY: qs_ks_did_change,&
101 : qs_ks_env_type
102 : USE qs_linres_kernel, ONLY: apply_hxc_kernel_kp
103 : USE qs_mixing_utils, ONLY: self_consistency_check
104 : USE qs_mo_occupation, ONLY: set_mo_occupation
105 : USE qs_mo_types, ONLY: get_mo_set,&
106 : mo_set_type
107 : USE qs_mom_methods, ONLY: do_mom_diag
108 : USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
109 : USE qs_ot, ONLY: &
110 : qs_ot_antihermitian_spectral_norm, qs_ot_density_secant_orbital_overlaps, &
111 : qs_ot_density_secant_projected_hessian, qs_ot_density_tangent, &
112 : qs_ot_finite_rotation_response, qs_ot_fixed_n_energy_gradient, &
113 : qs_ot_fixed_n_multigroup_schur_block, qs_ot_get_orbitals_complex, &
114 : qs_ot_get_orbitals_ref_complex, qs_ot_projected_response_update, qs_ot_symmetric_abs_solve
115 : USE qs_ot_minimizer, ONLY: ot_mermin_response_preparation_needed,&
116 : ot_mermin_secant_curvature,&
117 : ot_mini,&
118 : ot_mini_prepare_gradient
119 : USE qs_ot_scf, ONLY: ot_scf_destroy,&
120 : ot_scf_mini
121 : USE qs_ot_types, ONLY: qs_ot_channel_index,&
122 : qs_ot_check_channel_context,&
123 : qs_ot_physical_secant_type,&
124 : qs_ot_type
125 : USE qs_outer_scf, ONLY: outer_loop_gradient
126 : USE qs_rho_methods, ONLY: qs_rho_update_rho
127 : USE qs_rho_types, ONLY: qs_rho_get,&
128 : qs_rho_type
129 : USE qs_scf_diagonalization, ONLY: &
130 : do_block_davidson_diag, do_block_davidson_diag_kp, do_block_krylov_diag, do_general_diag, &
131 : do_general_diag_kp, do_ot_diag, do_ot_diag_kp, do_roks_diag, do_scf_diag_subspace, &
132 : do_special_diag
133 : USE qs_scf_methods, ONLY: cp_sm_mix,&
134 : scf_env_density_mixing
135 : USE qs_scf_output, ONLY: qs_scf_print_summary
136 : USE qs_scf_types, ONLY: &
137 : block_davidson_diag_method_nr, block_krylov_diag_method_nr, filter_matrix_diag_method_nr, &
138 : general_diag_method_nr, ot_diag_method_nr, ot_method_nr, qs_scf_env_type, &
139 : smeagol_method_nr, special_diag_method_nr
140 : USE scf_control_types, ONLY: scf_control_type,&
141 : smear_type
142 : USE smeagol_interface, ONLY: run_smeagol_emtrans
143 : USE smearing_utils, ONLY: Smearkp,&
144 : Smearkp2,&
145 : smearing_response_weight
146 : USE tblite_interface, ONLY: tb_native_scc_mixer_active
147 : #include "./base/base_uses.f90"
148 :
149 : IMPLICIT NONE
150 :
151 : PRIVATE
152 :
153 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_scf_loop_utils'
154 :
155 : PUBLIC :: qs_scf_set_loop_flags, &
156 : qs_scf_new_mos, qs_scf_new_mos_kp, &
157 : qs_scf_kp_ref_refresh_ready, qs_scf_kp_search_endpoint, &
158 : qs_scf_candidate_density_delta, qs_scf_commit_density_candidate, &
159 : qs_scf_density_mixing, qs_scf_check_inner_exit, &
160 : qs_scf_check_outer_exit, qs_scf_inner_finalize, qs_scf_rho_update
161 :
162 : CONTAINS
163 :
164 : ! **************************************************************************************************
165 : !> \brief identify an accepted OT search endpoint from its iteration label
166 : !> \param method OT iteration label
167 : !> \return true for the primary endpoint of every supported minimizer
168 : ! **************************************************************************************************
169 3030 : PURE FUNCTION qs_scf_kp_search_endpoint(method) RESULT(endpoint)
170 :
171 : CHARACTER(LEN=*), INTENT(IN) :: method
172 : LOGICAL :: endpoint
173 :
174 3030 : SELECT CASE (TRIM(method))
175 : CASE ("OT CG", "OT SD", "OT DIIS", "OT BROY", "OT LBFGS")
176 1228 : endpoint = .TRUE.
177 : CASE DEFAULT
178 3030 : endpoint = .FALSE.
179 : END SELECT
180 :
181 3030 : END FUNCTION qs_scf_kp_search_endpoint
182 :
183 : ! **************************************************************************************************
184 : !> \brief decide whether a mature variable-occupation REF chart should be rebuilt
185 : !> \param accepted_searches accepted search directions in the current REF chart
186 : !> \param residual current OT residual
187 : !> \param eps_scf requested SCF threshold
188 : !> \param base_state whether the current point can start a new search direction
189 : !> \param allow_exit_window whether a prior physical REF rebuild permits an exit-only rebuild
190 : !> \return true inside the asymptotic residual window after sufficient accepted history
191 : ! **************************************************************************************************
192 1178 : PURE FUNCTION qs_scf_kp_ref_refresh_ready( &
193 : accepted_searches, residual, eps_scf, base_state, allow_exit_window) &
194 : RESULT(refresh)
195 :
196 : INTEGER, INTENT(IN) :: accepted_searches
197 : REAL(KIND=dp), INTENT(IN) :: residual, eps_scf
198 : LOGICAL, INTENT(IN) :: base_state
199 : LOGICAL, INTENT(IN), OPTIONAL :: allow_exit_window
200 : LOGICAL :: refresh
201 :
202 : INTEGER, PARAMETER :: min_accepted_searches = 12
203 :
204 : LOGICAL :: exit_window
205 : REAL(KIND=dp) :: eps
206 :
207 1178 : eps = MAX(eps_scf, EPSILON(1.0_dp))
208 1178 : exit_window = .FALSE.
209 1178 : IF (PRESENT(allow_exit_window)) exit_window = allow_exit_window
210 : refresh = base_state .AND. accepted_searches >= min_accepted_searches .AND. &
211 : ((residual > 10.0_dp*eps .AND. residual <= 0.2_dp*SQRT(eps)) .OR. &
212 1178 : (exit_window .AND. residual > 0.25_dp*eps .AND. residual <= 10.0_dp*eps))
213 :
214 1178 : END FUNCTION qs_scf_kp_ref_refresh_ready
215 :
216 : ! **************************************************************************************************
217 : !> \brief computes properties for a given hamiltonian using the current wfn
218 : !> \param scf_env ...
219 : !> \param diis_step ...
220 : !> \param energy_only ...
221 : !> \param just_energy ...
222 : !> \param exit_inner_loop ...
223 : ! **************************************************************************************************
224 25875 : SUBROUTINE qs_scf_set_loop_flags(scf_env, diis_step, &
225 : energy_only, just_energy, exit_inner_loop)
226 :
227 : TYPE(qs_scf_env_type), POINTER :: scf_env
228 : LOGICAL :: diis_step, energy_only, just_energy, &
229 : exit_inner_loop
230 :
231 : ! Some flags needed to be set at the beginning of the loop
232 :
233 25875 : diis_step = .FALSE.
234 25875 : energy_only = .FALSE.
235 25875 : just_energy = .FALSE.
236 :
237 : ! SCF loop, optimisation of the wfn coefficients
238 : ! qs_env%rho%rho_r and qs_env%rho%rho_g should be up to date here
239 :
240 25875 : scf_env%iter_count = 0
241 25875 : scf_env%adiis_check_next = .FALSE.
242 25875 : scf_env%adiis_validated = .FALSE.
243 25875 : scf_env%step_norm = 0.0_dp
244 25875 : scf_env%raw_map_delta = 0.0_dp
245 25875 : scf_env%raw_map_delta_valid = .FALSE.
246 25875 : exit_inner_loop = .FALSE.
247 :
248 25875 : END SUBROUTINE qs_scf_set_loop_flags
249 :
250 : ! **************************************************************************************************
251 : !> \brief takes known energy and derivatives and produces new wfns
252 : !> and or density matrix
253 : !> \param qs_env ...
254 : !> \param scf_env ...
255 : !> \param scf_control ...
256 : !> \param scf_section ...
257 : !> \param diis_step ...
258 : !> \param energy_only ...
259 : !> \param probe ...
260 : ! **************************************************************************************************
261 202213 : SUBROUTINE qs_scf_new_mos(qs_env, scf_env, scf_control, scf_section, diis_step, &
262 : energy_only, probe)
263 : TYPE(qs_environment_type), POINTER :: qs_env
264 : TYPE(qs_scf_env_type), POINTER :: scf_env
265 : TYPE(scf_control_type), POINTER :: scf_control
266 : TYPE(section_vals_type), POINTER :: scf_section
267 : LOGICAL :: diis_step, energy_only
268 : TYPE(hairy_probes_type), DIMENSION(:), OPTIONAL, &
269 : POINTER :: probe
270 :
271 : CHARACTER(LEN=*), PARAMETER :: routineN = 'qs_scf_new_mos'
272 :
273 : INTEGER :: handle, ispin
274 : LOGICAL :: disable_diis, has_unit_metric, &
275 : skip_diag_sub
276 : REAL(KIND=dp) :: saved_eps_diis
277 202213 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
278 : TYPE(dft_control_type), POINTER :: dft_control
279 202213 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
280 : TYPE(qs_energy_type), POINTER :: energy
281 : TYPE(qs_ks_env_type), POINTER :: ks_env
282 : TYPE(qs_rho_type), POINTER :: rho
283 :
284 202213 : CALL timeset(routineN, handle)
285 :
286 202213 : NULLIFY (energy, ks_env, matrix_ks, matrix_s, rho, mos, dft_control)
287 :
288 : CALL get_qs_env(qs_env=qs_env, &
289 : matrix_s=matrix_s, energy=energy, &
290 : ks_env=ks_env, &
291 : matrix_ks=matrix_ks, rho=rho, mos=mos, &
292 : dft_control=dft_control, &
293 202213 : has_unit_metric=has_unit_metric)
294 202213 : scf_env%iter_param = 0.0_dp
295 :
296 : disable_diis = dft_control%qs_control%xtb_control%do_tblite .AND. &
297 202213 : tb_native_scc_mixer_active(dft_control)
298 : IF (disable_diis) THEN
299 12328 : saved_eps_diis = scf_control%eps_diis
300 12328 : scf_control%eps_diis = 0.0_dp
301 : END IF
302 :
303 : ! transfer total_zeff_corr from qs_env to scf_env only if
304 : ! correct_el_density_dip is switched on [SGh]
305 202213 : IF (dft_control%correct_el_density_dip) THEN
306 40 : scf_env%sum_zeff_corr = qs_env%total_zeff_corr
307 40 : IF (ABS(qs_env%total_zeff_corr) > 0.0_dp) THEN
308 40 : IF (scf_env%method /= general_diag_method_nr) THEN
309 : CALL cp_abort(__LOCATION__, &
310 : "Please use ALGORITHM STANDARD in "// &
311 : "SCF%DIAGONALIZATION if "// &
312 : "CORE_CORRECTION /= 0.0 and "// &
313 0 : "SURFACE_DIPOLE_CORRECTION TRUE ")
314 40 : ELSE IF (dft_control%roks) THEN
315 : CALL cp_abort(__LOCATION__, &
316 : "Combination of "// &
317 : "CORE_CORRECTION /= 0.0 and "// &
318 : "SURFACE_DIPOLE_CORRECTION TRUE "// &
319 0 : "is not implemented with ROKS")
320 40 : ELSE IF (scf_control%diagonalization%mom) THEN
321 : CALL cp_abort(__LOCATION__, &
322 : "Combination of "// &
323 : "CORE_CORRECTION /= 0.0 and "// &
324 : "SURFACE_DIPOLE_CORRECTION TRUE "// &
325 0 : "is not implemented with SCF%MOM")
326 : END IF
327 : END IF
328 : END IF
329 :
330 202213 : SELECT CASE (scf_env%method)
331 : CASE DEFAULT
332 : CALL cp_abort(__LOCATION__, &
333 : "unknown scf method: "// &
334 0 : cp_to_string(scf_env%method))
335 :
336 : ! *************************************************************************
337 : ! Filter matrix diagonalisation: ugly implementation at this point of time
338 : ! *************************************************************************
339 : CASE (filter_matrix_diag_method_nr)
340 :
341 80 : IF (ABS(qs_env%total_zeff_corr) > 0.0_dp) THEN
342 : CALL cp_abort(__LOCATION__, &
343 : "CORE_CORRECTION /= 0.0 plus SURFACE_DIPOLE_CORRECTION TRUE "// &
344 0 : "requires SCF%DIAGONALIZATION: ALGORITHM STANDARD")
345 : END IF
346 : CALL fb_env_do_diag(scf_env%filter_matrix_env, qs_env, &
347 80 : matrix_ks, matrix_s, scf_section, diis_step)
348 :
349 : ! Diagonlization in non orthonormal case
350 : CASE (general_diag_method_nr)
351 103057 : IF (dft_control%roks) THEN
352 : CALL do_roks_diag(scf_env, mos, matrix_ks, matrix_s, &
353 : scf_control, scf_section, diis_step, &
354 552 : has_unit_metric)
355 : ELSE
356 102505 : IF (scf_control%diagonalization%mom) THEN
357 : CALL do_mom_diag(scf_env, mos, matrix_ks, &
358 : matrix_s, scf_control, scf_section, &
359 342 : diis_step)
360 : ELSE
361 102163 : IF (dft_control%hairy_probes .EQV. .TRUE.) THEN
362 : CALL do_general_diag(scf_env, mos, matrix_ks, &
363 : matrix_s, scf_control, scf_section, &
364 : diis_step, &
365 14 : probe)
366 : ELSE
367 : CALL do_general_diag(scf_env, mos, matrix_ks, &
368 : matrix_s, scf_control, scf_section, &
369 102149 : diis_step)
370 : END IF
371 : END IF
372 102505 : IF (scf_control%do_diag_sub) THEN
373 : skip_diag_sub = (scf_env%subspace_env%eps_diag_sub > 0.0_dp) .AND. &
374 10 : (scf_env%iter_count == 1 .OR. scf_env%iter_delta > scf_env%subspace_env%eps_diag_sub)
375 : IF (.NOT. skip_diag_sub) THEN
376 : CALL do_scf_diag_subspace(qs_env, scf_env, scf_env%subspace_env, mos, rho, &
377 10 : ks_env, scf_section, scf_control)
378 : END IF
379 : END IF
380 : END IF
381 : ! Diagonlization in orthonormal case
382 : CASE (special_diag_method_nr)
383 18398 : IF (dft_control%roks) THEN
384 : CALL do_roks_diag(scf_env, mos, matrix_ks, matrix_s, &
385 : scf_control, scf_section, diis_step, &
386 522 : has_unit_metric)
387 : ELSE
388 : CALL do_special_diag(scf_env, mos, matrix_ks, &
389 : scf_control, scf_section, &
390 17876 : diis_step)
391 : END IF
392 : ! OT diagonalization
393 : CASE (ot_diag_method_nr)
394 : CALL do_ot_diag(scf_env, mos, matrix_ks, matrix_s, &
395 202 : scf_control, scf_section, diis_step)
396 : ! Block Krylov diagonlization
397 : CASE (block_krylov_diag_method_nr)
398 116 : IF ((scf_env%krylov_space%eps_std_diag > 0.0_dp) .AND. &
399 : (scf_env%iter_count == 1 .OR. scf_env%iter_delta > scf_env%krylov_space%eps_std_diag)) THEN
400 2 : IF (scf_env%krylov_space%always_check_conv) THEN
401 : CALL do_block_krylov_diag(scf_env, mos, matrix_ks, &
402 0 : scf_control, scf_section, check_moconv_only=.TRUE.)
403 : END IF
404 : CALL do_general_diag(scf_env, mos, matrix_ks, &
405 2 : matrix_s, scf_control, scf_section, diis_step)
406 : ELSE
407 : CALL do_block_krylov_diag(scf_env, mos, matrix_ks, &
408 114 : scf_control, scf_section)
409 : END IF
410 116 : IF (scf_control%do_diag_sub) THEN
411 : skip_diag_sub = (scf_env%subspace_env%eps_diag_sub > 0.0_dp) .AND. &
412 0 : (scf_env%iter_count == 1 .OR. scf_env%iter_delta > scf_env%subspace_env%eps_diag_sub)
413 : IF (.NOT. skip_diag_sub) THEN
414 : CALL do_scf_diag_subspace(qs_env, scf_env, scf_env%subspace_env, mos, rho, &
415 0 : ks_env, scf_section, scf_control)
416 : END IF
417 : END IF
418 : ! Block Davidson diagonlization
419 : CASE (block_davidson_diag_method_nr)
420 : CALL do_block_davidson_diag(qs_env, scf_env, mos, matrix_ks, matrix_s, scf_control, &
421 94 : scf_section, .FALSE.)
422 : ! OT without diagonlization. Needs special treatment for SCP runs
423 : CASE (ot_method_nr)
424 : CALL qs_scf_loop_do_ot(qs_env, scf_env, scf_control%smear, mos, rho, &
425 : qs_env%mo_derivs, energy%total, &
426 202213 : matrix_s, energy_only=energy_only, has_unit_metric=has_unit_metric)
427 : END SELECT
428 202213 : IF (disable_diis) scf_control%eps_diis = saved_eps_diis
429 :
430 202213 : energy%kTS = 0.0_dp
431 202213 : energy%efermi = 0.0_dp
432 202213 : CALL get_qs_env(qs_env, mos=mos)
433 439673 : DO ispin = 1, SIZE(mos)
434 237460 : energy%kTS = energy%kTS + mos(ispin)%kTS
435 439673 : energy%efermi = energy%efermi + mos(ispin)%mu
436 : END DO
437 202213 : energy%efermi = energy%efermi/REAL(SIZE(mos), KIND=dp)
438 :
439 202213 : CALL timestop(handle)
440 :
441 202213 : END SUBROUTINE qs_scf_new_mos
442 :
443 : ! **************************************************************************************************
444 : !> \brief Updates MOs and density matrix using diagonalization
445 : !> Kpoint code
446 : !> \param qs_env ...
447 : !> \param scf_env ...
448 : !> \param scf_control ...
449 : !> \param diis_step ...
450 : !> \param probe ...
451 : !> \param ot_kp_subspace_refresh ...
452 : !> \param allow_ot_kp_subspace_refresh ...
453 : !> \param allow_ot_kp_exit_refresh ...
454 : !> \param accepted_ot_kp_searches ...
455 : !> \param added_mos_auto_grow ...
456 : !> \param energy_only ...
457 : ! **************************************************************************************************
458 39424 : SUBROUTINE qs_scf_new_mos_kp(qs_env, scf_env, scf_control, diis_step, probe, &
459 : ot_kp_subspace_refresh, allow_ot_kp_subspace_refresh, &
460 : allow_ot_kp_exit_refresh, accepted_ot_kp_searches, &
461 : added_mos_auto_grow, energy_only)
462 : TYPE(qs_environment_type), POINTER :: qs_env
463 : TYPE(qs_scf_env_type), POINTER :: scf_env
464 : TYPE(scf_control_type), POINTER :: scf_control
465 : LOGICAL :: diis_step
466 : TYPE(hairy_probes_type), DIMENSION(:), OPTIONAL, &
467 : POINTER :: probe
468 : LOGICAL, INTENT(OUT), OPTIONAL :: ot_kp_subspace_refresh
469 : LOGICAL, INTENT(IN), OPTIONAL :: allow_ot_kp_subspace_refresh, &
470 : allow_ot_kp_exit_refresh
471 : INTEGER, INTENT(IN), OPTIONAL :: accepted_ot_kp_searches
472 : LOGICAL, INTENT(OUT), OPTIONAL :: added_mos_auto_grow, energy_only
473 :
474 : CHARACTER(LEN=*), PARAMETER :: routineN = 'qs_scf_new_mos_kp'
475 :
476 : INTEGER :: accepted_searches, handle, ispin, &
477 : refresh_count
478 : LOGICAL :: allow_exit_refresh, allow_refresh, base_state, disable_diis, has_unit_metric, &
479 : my_added_mos_auto_grow, ot_energy_only, refresh
480 : REAL(dp) :: diis_error, residual, saved_eps_diis
481 39424 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks, matrix_s, matrix_t
482 : TYPE(dft_control_type), POINTER :: dft_control
483 : TYPE(kpoint_type), POINTER :: kpoints
484 39424 : TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
485 : TYPE(mp_para_env_type), POINTER :: para_env
486 : TYPE(qs_energy_type), POINTER :: energy
487 :
488 39424 : CALL timeset(routineN, handle)
489 :
490 39424 : allow_refresh = .FALSE.
491 39424 : allow_exit_refresh = .FALSE.
492 39424 : accepted_searches = 0
493 39424 : my_added_mos_auto_grow = .FALSE.
494 39424 : refresh = .FALSE.
495 39424 : IF (PRESENT(allow_ot_kp_subspace_refresh)) allow_refresh = allow_ot_kp_subspace_refresh
496 39424 : IF (PRESENT(allow_ot_kp_exit_refresh)) allow_exit_refresh = allow_ot_kp_exit_refresh
497 39424 : IF (PRESENT(accepted_ot_kp_searches)) accepted_searches = accepted_ot_kp_searches
498 39424 : IF (PRESENT(ot_kp_subspace_refresh)) ot_kp_subspace_refresh = .FALSE.
499 39424 : IF (PRESENT(added_mos_auto_grow)) added_mos_auto_grow = .FALSE.
500 39424 : IF (PRESENT(energy_only)) energy_only = .FALSE.
501 :
502 39424 : NULLIFY (dft_control, energy, kpoints, matrix_ks, matrix_s, matrix_t, para_env)
503 :
504 39424 : CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, energy=energy, kpoints=kpoints)
505 39424 : CALL get_kpoint_info(kpoints, para_env=para_env)
506 39424 : CPASSERT(ASSOCIATED(para_env))
507 39424 : scf_env%iter_param = 0.0_dp
508 : disable_diis = dft_control%qs_control%xtb_control%do_tblite .AND. &
509 39424 : tb_native_scc_mixer_active(dft_control)
510 : IF (disable_diis) THEN
511 10502 : saved_eps_diis = scf_control%eps_diis
512 10502 : scf_control%eps_diis = 0.0_dp
513 : END IF
514 :
515 39424 : IF (dft_control%roks .AND. scf_env%method /= ot_method_nr) THEN
516 0 : CPABORT("KP code: ROKS method not available: ")
517 : END IF
518 :
519 39424 : SELECT CASE (scf_env%method)
520 : CASE DEFAULT
521 : CALL cp_abort(__LOCATION__, &
522 : "KP code: Unknown scf method: "// &
523 0 : cp_to_string(scf_env%method))
524 : CASE (general_diag_method_nr)
525 : ! Diagonlization in non orthonormal case
526 35388 : CALL get_qs_env(qs_env, matrix_ks_kp=matrix_ks, matrix_s_kp=matrix_s)
527 35388 : IF (scf_control%diagonalization%update_method == diag_update_method_adiis) THEN
528 80 : CPASSERT(ASSOCIATED(scf_env%scf_subspace_buffer))
529 80 : diis_error = scf_env%scf_subspace_buffer%last_old_fock_weight
530 : END IF
531 35388 : IF (dft_control%hairy_probes .EQV. .TRUE.) THEN
532 0 : scf_control%smear%do_smear = .FALSE.
533 : CALL do_general_diag_kp(matrix_ks, matrix_s, kpoints, scf_env, scf_control, .TRUE., &
534 0 : diis_step, diis_error, qs_env, probe)
535 : ELSE
536 : CALL do_general_diag_kp(matrix_ks, matrix_s, kpoints, scf_env, scf_control, .TRUE., &
537 : diis_step, diis_error, qs_env, &
538 35388 : added_mos_auto_grow=my_added_mos_auto_grow)
539 : END IF
540 35388 : IF (my_added_mos_auto_grow) THEN
541 0 : IF (PRESENT(added_mos_auto_grow)) added_mos_auto_grow = .TRUE.
542 0 : IF (disable_diis) scf_control%eps_diis = saved_eps_diis
543 0 : CALL timestop(handle)
544 10 : RETURN
545 : END IF
546 35388 : IF (scf_control%diagonalization%update_method == diag_update_method_adiis .AND. &
547 0 : .NOT. diis_step) THEN
548 48 : scf_env%iter_param = diis_error
549 48 : IF (scf_env%scf_subspace_buffer%last_restart) THEN
550 0 : scf_env%iter_method = "ADIIS/Rst."
551 : ELSE
552 48 : scf_env%iter_method = "ADIIS/Diag."
553 : END IF
554 35340 : ELSE IF (diis_step) THEN
555 10646 : scf_env%iter_param = diis_error
556 10646 : scf_env%iter_method = "DIIS/Diag."
557 : ELSE
558 24694 : IF (scf_env%mixing_method == 0) THEN
559 0 : scf_env%iter_method = "NoMix/Diag."
560 24694 : ELSE IF (scf_env%mixing_method == 1) THEN
561 20076 : scf_env%iter_param = scf_env%p_mix_alpha
562 20076 : scf_env%iter_method = "P_Mix/Diag."
563 4618 : ELSE IF (scf_env%mixing_method > 1) THEN
564 4618 : scf_env%iter_param = scf_env%mixing_store%alpha
565 4618 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Diag."
566 : END IF
567 : END IF
568 : CASE (special_diag_method_nr)
569 0 : CALL get_qs_env(qs_env=qs_env, has_unit_metric=has_unit_metric)
570 0 : CPASSERT(has_unit_metric)
571 : ! Diagonlization in orthonormal case
572 : CALL cp_abort(__LOCATION__, &
573 : "KP code: Scf method not available: "// &
574 0 : cp_to_string(scf_env%method))
575 : CASE (ot_diag_method_nr)
576 94 : CALL get_qs_env(qs_env, matrix_ks_kp=matrix_ks, matrix_s_kp=matrix_s, kinetic_kp=matrix_t)
577 : CALL do_ot_diag_kp(matrix_ks, matrix_s, matrix_t, kpoints, scf_env, scf_control, &
578 94 : diis_step, my_added_mos_auto_grow)
579 94 : IF (my_added_mos_auto_grow) THEN
580 0 : IF (PRESENT(added_mos_auto_grow)) added_mos_auto_grow = .TRUE.
581 0 : IF (disable_diis) scf_control%eps_diis = saved_eps_diis
582 0 : CALL timestop(handle)
583 0 : RETURN
584 : END IF
585 : CASE (block_krylov_diag_method_nr)
586 : CALL cp_abort(__LOCATION__, &
587 : "KP code: Scf method not available: "// &
588 0 : cp_to_string(scf_env%method))
589 : CASE (block_davidson_diag_method_nr)
590 918 : CALL get_qs_env(qs_env, matrix_ks_kp=matrix_ks, matrix_s_kp=matrix_s)
591 : CALL do_block_davidson_diag_kp(qs_env, scf_env, matrix_ks, matrix_s, kpoints, &
592 918 : scf_control, added_mos_auto_grow=my_added_mos_auto_grow)
593 918 : IF (my_added_mos_auto_grow) THEN
594 4 : IF (PRESENT(added_mos_auto_grow)) added_mos_auto_grow = .TRUE.
595 4 : IF (disable_diis) scf_control%eps_diis = saved_eps_diis
596 4 : CALL timestop(handle)
597 4 : RETURN
598 : END IF
599 : CASE (ot_method_nr)
600 3024 : CALL get_qs_env(qs_env, matrix_ks_kp=matrix_ks, matrix_s_kp=matrix_s)
601 : base_state = .NOT. scf_env%qs_ot_env(1)%energy_only .AND. &
602 : (scf_env%qs_ot_env(1)%line_search_count == 0 .OR. &
603 3024 : scf_env%qs_ot_env(1)%line_search_might_be_done)
604 3024 : residual = MAX(scf_env%iter_delta, scf_env%qs_ot_env(1)%delta)
605 : refresh = (allow_refresh .OR. allow_exit_refresh) .AND. &
606 : scf_env%qs_ot_env(1)%settings%do_ener .AND. &
607 : scf_env%qs_ot_env(1)%settings%occupation_preconditioner .AND. &
608 : (dft_control%smear .OR. scf_control%smear%do_smear) .AND. &
609 : qs_scf_kp_ref_refresh_ready(accepted_searches, residual, &
610 3024 : scf_control%eps_scf, base_state, allow_exit_refresh)
611 3024 : refresh_count = MERGE(1, 0, refresh)
612 3024 : CALL para_env%sum(refresh_count)
613 3024 : refresh = refresh_count > 0
614 3024 : IF (refresh) THEN
615 8 : IF (PRESENT(ot_kp_subspace_refresh)) ot_kp_subspace_refresh = .TRUE.
616 : ELSE
617 : CALL qs_scf_loop_do_ot_kp(qs_env, scf_env, matrix_ks, matrix_s, &
618 3016 : my_added_mos_auto_grow, ot_energy_only)
619 3016 : IF (PRESENT(energy_only)) energy_only = ot_energy_only
620 3016 : IF (my_added_mos_auto_grow) THEN
621 6 : IF (PRESENT(added_mos_auto_grow)) added_mos_auto_grow = .TRUE.
622 6 : IF (disable_diis) scf_control%eps_diis = saved_eps_diis
623 6 : CALL timestop(handle)
624 6 : RETURN
625 : END IF
626 3010 : IF (allow_exit_refresh .AND. scf_env%iter_delta <= scf_control%eps_scf) THEN
627 6 : base_state = qs_scf_kp_search_endpoint(scf_env%iter_method)
628 : refresh = qs_scf_kp_ref_refresh_ready( &
629 : accepted_searches, scf_env%iter_delta, scf_control%eps_scf, &
630 6 : base_state, allow_exit_window=.TRUE.)
631 6 : IF (refresh .AND. PRESENT(ot_kp_subspace_refresh)) THEN
632 0 : ot_kp_subspace_refresh = .TRUE.
633 : END IF
634 : END IF
635 3010 : refresh_count = MERGE(1, 0, refresh)
636 3010 : CALL para_env%sum(refresh_count)
637 3010 : refresh = refresh_count > 0
638 3010 : IF (refresh .AND. PRESENT(ot_kp_subspace_refresh)) THEN
639 0 : ot_kp_subspace_refresh = .TRUE.
640 : END IF
641 : END IF
642 : CASE (smeagol_method_nr)
643 : ! SMEAGOL interface
644 0 : diis_step = .FALSE.
645 0 : IF (scf_env%mixing_method == 0) THEN
646 0 : scf_env%iter_method = "NoMix/SMGL"
647 0 : ELSE IF (scf_env%mixing_method == 1) THEN
648 0 : scf_env%iter_param = scf_env%p_mix_alpha
649 0 : scf_env%iter_method = "P_Mix/SMGL"
650 0 : ELSE IF (scf_env%mixing_method > 1) THEN
651 0 : scf_env%iter_param = scf_env%mixing_store%alpha
652 0 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/SMGL"
653 : END IF
654 40436 : CALL run_smeagol_emtrans(qs_env, last=.FALSE., iter=scf_env%iter_count, rho_ao_kp=scf_env%p_mix_new)
655 : END SELECT
656 39414 : IF (disable_diis) scf_control%eps_diis = saved_eps_diis
657 :
658 39414 : CALL get_qs_env(qs_env=qs_env, energy=energy)
659 39414 : energy%kTS = 0.0_dp
660 39414 : energy%efermi = 0.0_dp
661 39414 : mos => kpoints%kp_env(1)%kpoint_env%mos
662 81732 : DO ispin = 1, SIZE(mos)
663 42318 : energy%kTS = energy%kTS + mos(ispin)%kTS
664 81732 : energy%efermi = energy%efermi + mos(ispin)%mu
665 : END DO
666 39414 : energy%efermi = energy%efermi/REAL(SIZE(mos), KIND=dp)
667 :
668 39414 : CALL timestop(handle)
669 :
670 39424 : END SUBROUTINE qs_scf_new_mos_kp
671 :
672 : ! **************************************************************************************************
673 : !> \brief K-point OT driver for local complex spin/k-point channels
674 : !> \param qs_env ...
675 : !> \param scf_env ...
676 : !> \param matrix_ks ...
677 : !> \param matrix_s ...
678 : !> \param added_mos_auto_grow ...
679 : !> \param energy_only ...
680 : ! **************************************************************************************************
681 3016 : SUBROUTINE qs_scf_loop_do_ot_kp(qs_env, scf_env, matrix_ks, matrix_s, added_mos_auto_grow, energy_only)
682 :
683 : TYPE(qs_environment_type), POINTER :: qs_env
684 : TYPE(qs_scf_env_type), POINTER :: scf_env
685 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks, matrix_s
686 : LOGICAL, INTENT(OUT) :: added_mos_auto_grow, energy_only
687 :
688 : CHARACTER(LEN=*), PARAMETER :: routineN = 'qs_scf_loop_do_ot_kp'
689 :
690 : INTEGER :: energy_spin, energy_start, first_channel, handle, homo, ikpoint, ispin, &
691 : local_channel, local_kpoint, nao, nkp_groups, nkpoint, nlocal_channels, nmo, &
692 : nspin_energy, nspin_ot
693 : INTEGER, DIMENSION(2) :: kp_range
694 : LOGICAL :: ot_gradient_prepared, &
695 : physical_base_state, restricted_roks, &
696 : use_real_wfn
697 : REAL(KIND=dp) :: trial_kTS
698 3016 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: orbital_scaling_factor, roks_occupation, &
699 3016 : trial_mu
700 3016 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: trial_eigenvalues, trial_occupation
701 3016 : REAL(KIND=dp), DIMENSION(:), POINTER :: eigenvalues, occupation_numbers, wkp
702 : TYPE(cp_cfm_type) :: active_mo_coeff_cfm, hc_cfm, physical_h
703 : TYPE(cp_fm_struct_type), POINTER :: active_mo_struct, chc_struct
704 : TYPE(cp_fm_type) :: active_mo_coeff, active_mo_coeff_im, &
705 : chc_im, chc_re, hc_im, hc_re, &
706 : hc_roks_im, hc_roks_re, mo_coeff, &
707 : mo_coeff_im
708 3016 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: fmwork
709 3016 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_hc, matrix_hc_im, &
710 3016 : matrix_hc_physical, &
711 3016 : matrix_hc_physical_im
712 3016 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: density_target, rho_ao_kp
713 : TYPE(dbcsr_type), POINTER :: matrix_k_im, matrix_k_re, matrix_s_im, &
714 : matrix_s_re
715 : TYPE(dft_control_type), POINTER :: dft_control
716 : TYPE(kpoint_env_type), POINTER :: kp
717 : TYPE(kpoint_type), POINTER :: kpoints
718 : TYPE(mp_para_env_type), POINTER :: para_env_inter_kp
719 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
720 3016 : POINTER :: sab_nl
721 : TYPE(qs_energy_type), POINTER :: energy
722 3016 : TYPE(qs_ot_type), DIMENSION(:), POINTER :: local_ot_env
723 : TYPE(qs_rho_type), POINTER :: rho
724 : TYPE(scf_control_type), POINTER :: scf_control
725 :
726 3016 : CALL timeset(routineN, handle)
727 3016 : added_mos_auto_grow = .FALSE.
728 3016 : ot_gradient_prepared = .FALSE.
729 :
730 3016 : NULLIFY (active_mo_struct, chc_struct, density_target, dft_control, energy, fmwork, kpoints, &
731 3016 : local_ot_env, matrix_hc, matrix_hc_im, matrix_k_im, matrix_k_re, matrix_s_im, &
732 3016 : matrix_hc_physical, matrix_hc_physical_im, matrix_s_re, &
733 3016 : occupation_numbers, para_env_inter_kp, rho, &
734 3016 : rho_ao_kp, sab_nl, scf_control, wkp)
735 :
736 3016 : CPASSERT(ASSOCIATED(scf_env%qs_ot_env))
737 : CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, energy=energy, kpoints=kpoints, rho=rho, &
738 3016 : scf_control=scf_control)
739 : CALL get_kpoint_info(kpoints, nkp=nkpoint, wkp=wkp, use_real_wfn=use_real_wfn, &
740 : kp_range=kp_range, nkp_groups=nkp_groups, para_env_inter_kp=para_env_inter_kp, &
741 3016 : sab_nl=sab_nl)
742 3016 : fmwork => scf_env%scf_work1
743 3016 : CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
744 3016 : CPASSERT(ASSOCIATED(sab_nl))
745 3016 : CPASSERT(ASSOCIATED(matrix_ks))
746 3016 : CPASSERT(ASSOCIATED(matrix_s))
747 :
748 3016 : IF (use_real_wfn) THEN
749 : CALL cp_abort(__LOCATION__, &
750 0 : "K-point OT driver currently supports complex k-point wavefunctions only.")
751 : END IF
752 3016 : IF (scf_env%qs_ot_env(1)%settings%ot_algorithm /= "TOD" .AND. &
753 : scf_env%qs_ot_env(1)%settings%ot_algorithm /= "REF") THEN
754 : CALL cp_abort(__LOCATION__, &
755 0 : "K-point OT driver supports OT%ALGORITHM STRICT or IRAC.")
756 : END IF
757 3016 : kp => kpoints%kp_env(1)%kpoint_env
758 3016 : restricted_roks = dft_control%restricted
759 3016 : nspin_ot = MERGE(1, SIZE(kp%mos), restricted_roks)
760 3016 : nspin_energy = MERGE(SIZE(kp%mos), nspin_ot, restricted_roks)
761 : CALL qs_ot_check_channel_context(scf_env%qs_ot_env, nspin_ot, &
762 : nkpoint=nkpoint, &
763 : restricted=ANY(scf_env%qs_ot_env(:)%restricted), &
764 : require_kpoint=.TRUE., &
765 : kp_range=kp_range, &
766 : wkp=wkp, &
767 : require_local_state=.TRUE., &
768 11630 : require_complex_state=.TRUE.)
769 :
770 3016 : IF (nkp_groups > 1) THEN
771 1574 : CALL kpoint_operator_store(kpoints, fmwork(1), matrix_ks, matrix_s)
772 : END IF
773 :
774 3016 : first_channel = qs_ot_channel_index(1, kp_range(1), nspin_ot)
775 3016 : nlocal_channels = SIZE(kpoints%kp_env)*nspin_ot
776 3016 : local_ot_env => scf_env%qs_ot_env(first_channel:first_channel + nlocal_channels - 1)
777 3016 : local_ot_env(1)%etotal = energy%total
778 : physical_base_state = local_ot_env(1)%settings%do_ener .AND. &
779 : .NOT. local_ot_env(1)%energy_only .AND. &
780 : (local_ot_env(1)%line_search_count == 0 .OR. &
781 3016 : local_ot_env(1)%line_search_might_be_done)
782 :
783 14739 : ALLOCATE (matrix_hc(nlocal_channels))
784 11723 : ALLOCATE (matrix_hc_im(nlocal_channels))
785 3016 : IF (local_ot_env(1)%settings%occupation_preconditioner) THEN
786 3956 : ALLOCATE (matrix_hc_physical(nlocal_channels))
787 3956 : ALLOCATE (matrix_hc_physical_im(nlocal_channels))
788 : END IF
789 8707 : DO local_channel = 1, nlocal_channels
790 5691 : NULLIFY (matrix_hc(local_channel)%matrix)
791 5691 : NULLIFY (matrix_hc_im(local_channel)%matrix)
792 5691 : ALLOCATE (matrix_hc(local_channel)%matrix)
793 5691 : ALLOCATE (matrix_hc_im(local_channel)%matrix)
794 5691 : CALL dbcsr_copy(matrix_hc(local_channel)%matrix, local_ot_env(local_channel)%matrix_x, name="matrix_hc")
795 : CALL dbcsr_copy(matrix_hc_im(local_channel)%matrix, local_ot_env(local_channel)%matrix_x_im, &
796 5691 : name="matrix_hc_im")
797 5691 : CALL dbcsr_set(matrix_hc(local_channel)%matrix, 0.0_dp)
798 5691 : CALL dbcsr_set(matrix_hc_im(local_channel)%matrix, 0.0_dp)
799 8707 : IF (local_ot_env(1)%settings%occupation_preconditioner) THEN
800 1664 : NULLIFY (matrix_hc_physical(local_channel)%matrix)
801 1664 : NULLIFY (matrix_hc_physical_im(local_channel)%matrix)
802 1664 : ALLOCATE (matrix_hc_physical(local_channel)%matrix)
803 1664 : ALLOCATE (matrix_hc_physical_im(local_channel)%matrix)
804 : CALL dbcsr_copy(matrix_hc_physical(local_channel)%matrix, &
805 1664 : local_ot_env(local_channel)%matrix_x, name="matrix_hc_physical")
806 : CALL dbcsr_copy(matrix_hc_physical_im(local_channel)%matrix, &
807 1664 : local_ot_env(local_channel)%matrix_x_im, name="matrix_hc_physical_im")
808 1664 : CALL dbcsr_set(matrix_hc_physical(local_channel)%matrix, 0.0_dp)
809 1664 : CALL dbcsr_set(matrix_hc_physical_im(local_channel)%matrix, 0.0_dp)
810 : END IF
811 : END DO
812 :
813 7967 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
814 4951 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
815 4951 : ikpoint = kp%nkpoint
816 4951 : CPASSERT(ASSOCIATED(kp%ot_hmat))
817 4951 : CPASSERT(SIZE(kp%ot_hmat, 1) >= 2)
818 13658 : DO ispin = 1, nspin_ot
819 5691 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
820 : CALL kpoint_operator_get_local( &
821 : matrix_ks, kpoints, kp, MIN(ispin, SIZE(matrix_ks, 1)), &
822 : kp%ot_hmat(1, MIN(ispin, SIZE(kp%ot_hmat, 2))), &
823 5691 : kp%ot_hmat(2, MIN(ispin, SIZE(kp%ot_hmat, 2))), matrix_k_re, matrix_k_im)
824 5691 : IF (physical_base_state .AND. nkp_groups == 1) THEN
825 : ! The direct single-group transform bypasses the full-matrix cache. Synchronize it
826 : ! at accepted endpoints so the physical Mermin history sees the H(k) used for H(k)C(k).
827 : CALL copy_dbcsr_to_fm( &
828 604 : matrix_k_re, kp%ot_hmat(1, MIN(ispin, SIZE(kp%ot_hmat, 2))))
829 : CALL copy_dbcsr_to_fm( &
830 604 : matrix_k_im, kp%ot_hmat(2, MIN(ispin, SIZE(kp%ot_hmat, 2))))
831 : END IF
832 :
833 : CALL get_mo_set(kp%mos(ispin), homo=homo, nao=nao, nmo=nmo, &
834 5691 : occupation_numbers=occupation_numbers)
835 5691 : CALL cp_fm_create(mo_coeff, kp%mos(ispin)%cmo_coeff%matrix_struct)
836 5691 : CALL cp_fm_create(mo_coeff_im, kp%mos(ispin)%cmo_coeff%matrix_struct)
837 5691 : CALL cp_cfm_to_fm(kp%mos(ispin)%cmo_coeff, mo_coeff, mo_coeff_im)
838 5691 : IF (local_ot_env(local_channel)%settings%do_ener) homo = nmo
839 5691 : CPASSERT(homo >= 1 .AND. homo <= nmo)
840 5691 : IF (.NOT. local_ot_env(local_channel)%settings%do_ener) THEN
841 26329 : IF (MAXVAL(ABS(occupation_numbers(1:homo) - occupation_numbers(1))) > &
842 : 100.0_dp*EPSILON(1.0_dp)) THEN
843 : CALL cp_abort(__LOCATION__, &
844 0 : "Fixed-occupation K-point OT requires uniform occupations within each channel.")
845 : END IF
846 3715 : IF (occupation_numbers(1) <= 100.0_dp*EPSILON(1.0_dp)) THEN
847 : CALL cp_abort(__LOCATION__, &
848 0 : "Fixed-occupation K-point OT encountered an empty active orbital block.")
849 : END IF
850 3715 : IF (homo < nmo) THEN
851 328 : IF (MAXVAL(ABS(occupation_numbers(homo + 1:nmo))) > 100.0_dp*EPSILON(1.0_dp)) THEN
852 : CALL cp_abort(__LOCATION__, &
853 0 : "Fixed-occupation K-point OT cannot optimize occupied padded MO columns.")
854 : END IF
855 : END IF
856 : END IF
857 : CALL cp_fm_struct_create(active_mo_struct, template_fmstruct=mo_coeff%matrix_struct, &
858 5691 : ncol_global=homo)
859 5691 : CALL cp_fm_create(active_mo_coeff, active_mo_struct)
860 5691 : CALL cp_fm_create(active_mo_coeff_im, active_mo_struct)
861 5691 : CALL cp_fm_to_fm(mo_coeff, active_mo_coeff, homo)
862 5691 : CALL cp_fm_to_fm(mo_coeff_im, active_mo_coeff_im, homo)
863 5691 : CALL cp_fm_create(hc_re, active_mo_struct)
864 5691 : CALL cp_fm_create(hc_im, active_mo_struct)
865 :
866 5691 : CALL cp_dbcsr_sm_fm_multiply(matrix_k_re, active_mo_coeff, hc_re, homo)
867 : CALL cp_dbcsr_sm_fm_multiply(matrix_k_im, active_mo_coeff_im, hc_re, homo, &
868 5691 : alpha=-1.0_dp, beta=1.0_dp)
869 5691 : CALL cp_dbcsr_sm_fm_multiply(matrix_k_re, active_mo_coeff_im, hc_im, homo)
870 : CALL cp_dbcsr_sm_fm_multiply(matrix_k_im, active_mo_coeff, hc_im, homo, &
871 5691 : alpha=1.0_dp, beta=1.0_dp)
872 5691 : IF (ALLOCATED(kpoints%lowdin_v)) THEN
873 572 : IF (ANY(kpoints%lowdin_v(:, ispin) /= 0.0_dp)) THEN
874 572 : CALL cp_cfm_create(active_mo_coeff_cfm, active_mo_struct)
875 572 : CALL cp_cfm_create(hc_cfm, active_mo_struct)
876 572 : CALL cp_cfm_to_cfm(kp%mos(ispin)%cmo_coeff, active_mo_coeff_cfm, homo)
877 572 : CALL cp_fm_to_cfm(hc_re, hc_im, hc_cfm)
878 572 : CALL lowdin_kp_apply_mo(kp, kpoints%lowdin_v(:, ispin), active_mo_coeff_cfm, hc_cfm)
879 572 : CALL cp_cfm_to_fm(hc_cfm, hc_re, hc_im)
880 572 : CALL cp_cfm_release(hc_cfm)
881 572 : CALL cp_cfm_release(active_mo_coeff_cfm)
882 : END IF
883 572 : IF (physical_base_state .AND. local_ot_env(local_channel)%settings%occupation_preconditioner) THEN
884 : ! H*C already includes +U; the physical secant history needs the same full H.
885 0 : CALL cp_cfm_create(physical_h, kp%ot_hmat(1, ispin)%matrix_struct)
886 0 : CALL cp_fm_to_cfm(kp%ot_hmat(1, ispin), kp%ot_hmat(2, ispin), physical_h)
887 0 : CALL lowdin_kp_apply(kp, kpoints%lowdin_v(:, ispin), cmat=physical_h)
888 0 : CALL cp_cfm_to_fm(physical_h, kp%ot_hmat(1, ispin), kp%ot_hmat(2, ispin))
889 0 : CALL cp_cfm_release(physical_h)
890 : END IF
891 : END IF
892 :
893 5691 : IF (restricted_roks) THEN
894 : ! ROKS has one complex orbital variable but two spin densities. Form the exact
895 : ! shared-orbital derivative before handing it to the one-channel OT minimizer.
896 137 : IF (local_ot_env(local_channel)%settings%do_ener) THEN
897 : CALL cp_fm_struct_create(chc_struct, template_fmstruct=active_mo_struct, &
898 50 : nrow_global=homo, ncol_global=homo)
899 50 : CALL cp_fm_create(chc_re, chc_struct)
900 50 : CALL cp_fm_create(chc_im, chc_struct)
901 : CALL multiply_complex_fm_adjoint( &
902 : active_mo_coeff, active_mo_coeff_im, hc_re, hc_im, &
903 50 : chc_re, chc_im, 1.0_dp, 0.0_dp)
904 50 : CALL copy_fm_to_dbcsr(chc_re, local_ot_env(local_channel)%rot_mat_chc)
905 : CALL dbcsr_get_diag(local_ot_env(local_channel)%rot_mat_chc, &
906 50 : local_ot_env(local_channel)%ener_rayleigh(1:homo))
907 : CALL local_ot_env(local_channel)%para_env%sum( &
908 1018 : local_ot_env(local_channel)%ener_rayleigh(1:homo))
909 50 : CALL cp_fm_release(chc_im)
910 50 : CALL cp_fm_release(chc_re)
911 50 : CALL cp_fm_struct_release(chc_struct)
912 : END IF
913 137 : CALL cp_fm_column_scale(hc_re, occupation_numbers(1:homo))
914 137 : CALL cp_fm_column_scale(hc_im, occupation_numbers(1:homo))
915 137 : CALL dbcsr_release_p(matrix_k_re)
916 137 : CALL dbcsr_release_p(matrix_k_im)
917 :
918 : CALL kpoint_operator_get_local( &
919 : matrix_ks, kpoints, kp, 2, kp%ot_hmat(1, 2), kp%ot_hmat(2, 2), &
920 137 : matrix_k_re, matrix_k_im)
921 137 : CALL get_mo_set(kp%mos(2), occupation_numbers=occupation_numbers, nmo=nmo)
922 411 : ALLOCATE (roks_occupation(homo))
923 137 : roks_occupation(:) = 0.0_dp
924 795 : roks_occupation(1:MIN(homo, nmo)) = occupation_numbers(1:MIN(homo, nmo))
925 :
926 137 : CALL cp_fm_create(hc_roks_re, active_mo_struct)
927 137 : CALL cp_fm_create(hc_roks_im, active_mo_struct)
928 137 : CALL cp_dbcsr_sm_fm_multiply(matrix_k_re, active_mo_coeff, hc_roks_re, homo)
929 : CALL cp_dbcsr_sm_fm_multiply(matrix_k_im, active_mo_coeff_im, hc_roks_re, homo, &
930 137 : alpha=-1.0_dp, beta=1.0_dp)
931 137 : CALL cp_dbcsr_sm_fm_multiply(matrix_k_re, active_mo_coeff_im, hc_roks_im, homo)
932 : CALL cp_dbcsr_sm_fm_multiply(matrix_k_im, active_mo_coeff, hc_roks_im, homo, &
933 137 : alpha=1.0_dp, beta=1.0_dp)
934 137 : IF (local_ot_env(local_channel)%settings%do_ener) THEN
935 : CALL cp_fm_struct_create(chc_struct, template_fmstruct=active_mo_struct, &
936 50 : nrow_global=homo, ncol_global=homo)
937 50 : CALL cp_fm_create(chc_re, chc_struct)
938 50 : CALL cp_fm_create(chc_im, chc_struct)
939 : CALL multiply_complex_fm_adjoint( &
940 : active_mo_coeff, active_mo_coeff_im, hc_roks_re, hc_roks_im, &
941 50 : chc_re, chc_im, 1.0_dp, 0.0_dp)
942 50 : CALL copy_fm_to_dbcsr(chc_re, local_ot_env(local_channel)%rot_mat_chc)
943 : CALL dbcsr_get_diag(local_ot_env(local_channel)%rot_mat_chc, &
944 50 : local_ot_env(local_channel)%ener_rayleigh(homo + 1:2*homo))
945 : CALL local_ot_env(local_channel)%para_env%sum( &
946 1018 : local_ot_env(local_channel)%ener_rayleigh(homo + 1:2*homo))
947 50 : CALL cp_fm_release(chc_im)
948 50 : CALL cp_fm_release(chc_re)
949 50 : CALL cp_fm_struct_release(chc_struct)
950 : END IF
951 137 : CALL cp_fm_column_scale(hc_roks_re, roks_occupation)
952 137 : CALL cp_fm_column_scale(hc_roks_im, roks_occupation)
953 137 : CALL cp_fm_scale_and_add(1.0_dp, hc_re, 1.0_dp, hc_roks_re)
954 137 : CALL cp_fm_scale_and_add(1.0_dp, hc_im, 1.0_dp, hc_roks_im)
955 137 : CALL cp_fm_release(hc_roks_re)
956 137 : CALL cp_fm_release(hc_roks_im)
957 411 : DEALLOCATE (roks_occupation)
958 : END IF
959 :
960 5691 : IF (local_ot_env(local_channel)%settings%do_ener) THEN
961 : CALL cp_fm_struct_create(chc_struct, template_fmstruct=active_mo_struct, &
962 1976 : nrow_global=homo, ncol_global=homo)
963 1976 : CALL cp_fm_create(chc_re, chc_struct)
964 1976 : CALL cp_fm_create(chc_im, chc_struct)
965 : CALL multiply_complex_fm_adjoint( &
966 : active_mo_coeff, active_mo_coeff_im, hc_re, hc_im, &
967 1976 : chc_re, chc_im, 1.0_dp, 0.0_dp)
968 1976 : CALL copy_fm_to_dbcsr(chc_re, local_ot_env(local_channel)%rot_mat_chc)
969 1976 : CPASSERT(ASSOCIATED(local_ot_env(local_channel)%rot_mat_chc_im))
970 1976 : CALL copy_fm_to_dbcsr(chc_im, local_ot_env(local_channel)%rot_mat_chc_im)
971 1976 : IF (.NOT. restricted_roks) THEN
972 : CALL dbcsr_get_diag(local_ot_env(local_channel)%rot_mat_chc, &
973 1926 : local_ot_env(local_channel)%ener_rayleigh)
974 1926 : CPASSERT(ASSOCIATED(local_ot_env(local_channel)%para_env))
975 : CALL local_ot_env(local_channel)%para_env%sum( &
976 28102 : local_ot_env(local_channel)%ener_rayleigh)
977 : END IF
978 1976 : CALL cp_fm_release(chc_im)
979 1976 : CALL cp_fm_release(chc_re)
980 1976 : CALL cp_fm_struct_release(chc_struct)
981 : END IF
982 :
983 5691 : CALL copy_fm_to_dbcsr(hc_re, matrix_hc(local_channel)%matrix)
984 5691 : CALL copy_fm_to_dbcsr(hc_im, matrix_hc_im(local_channel)%matrix)
985 :
986 5691 : CALL cp_fm_release(active_mo_coeff)
987 5691 : CALL cp_fm_release(active_mo_coeff_im)
988 5691 : CALL cp_fm_release(hc_re)
989 5691 : CALL cp_fm_release(hc_im)
990 5691 : CALL cp_fm_release(mo_coeff)
991 5691 : CALL cp_fm_release(mo_coeff_im)
992 5691 : CALL cp_fm_struct_release(active_mo_struct)
993 5691 : CALL dbcsr_release_p(matrix_k_re)
994 27715 : CALL dbcsr_release_p(matrix_k_im)
995 : END DO
996 : END DO
997 :
998 3016 : IF (local_ot_env(1)%settings%do_ener) THEN
999 : CALL qs_scf_loop_collect_ot_kp_trial_smearing( &
1000 : kpoints, local_ot_env, first_channel, nspin_ot, nspin_energy, restricted_roks, &
1001 : kp_range, wkp, para_env_inter_kp, scf_control%smear, &
1002 1378 : trial_eigenvalues, trial_occupation, trial_mu, trial_kTS)
1003 : END IF
1004 :
1005 7967 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
1006 4951 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
1007 4951 : ikpoint = kp%nkpoint
1008 13658 : DO ispin = 1, nspin_ot
1009 5691 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
1010 : CALL get_mo_set(kp%mos(ispin), homo=homo, nmo=nmo, &
1011 5691 : occupation_numbers=occupation_numbers)
1012 5691 : CALL cp_fm_create(mo_coeff, kp%mos(ispin)%cmo_coeff%matrix_struct)
1013 5691 : CALL cp_fm_create(mo_coeff_im, kp%mos(ispin)%cmo_coeff%matrix_struct)
1014 5691 : CALL cp_cfm_to_fm(kp%mos(ispin)%cmo_coeff, mo_coeff, mo_coeff_im)
1015 5691 : IF (local_ot_env(local_channel)%settings%do_ener) homo = nmo
1016 5691 : IF (physical_base_state .AND. &
1017 : local_ot_env(local_channel)%settings%occupation_preconditioner) THEN
1018 692 : IF (restricted_roks) THEN
1019 22 : IF (.NOT. (nspin_energy <= SIZE(local_ot_env(local_channel)%mermin_physical))) THEN
1020 0 : CALL cp_abort(__LOCATION__, "Missing Mermin physical spin state")
1021 : END IF
1022 66 : DO energy_spin = 1, nspin_energy
1023 : CALL qs_scf_kp_roll_physical_secant( &
1024 : local_ot_env(local_channel)%mermin_physical(energy_spin), &
1025 : mo_coeff, mo_coeff_im, kp%ot_hmat(1, energy_spin), &
1026 : kp%ot_hmat(2, energy_spin), &
1027 66 : trial_occupation(:, ikpoint, energy_spin))
1028 : END DO
1029 : ELSE
1030 : CALL qs_scf_kp_roll_physical_secant( &
1031 : local_ot_env(local_channel)%mermin_physical(1), mo_coeff, mo_coeff_im, &
1032 : kp%ot_hmat(1, MIN(ispin, SIZE(kp%ot_hmat, 2))), &
1033 : kp%ot_hmat(2, MIN(ispin, SIZE(kp%ot_hmat, 2))), &
1034 670 : trial_occupation(:, ikpoint, ispin))
1035 : END IF
1036 : END IF
1037 5691 : IF (local_ot_env(local_channel)%settings%occupation_preconditioner) THEN
1038 : CALL dbcsr_copy(matrix_hc_physical(local_channel)%matrix, &
1039 1664 : matrix_hc(local_channel)%matrix)
1040 : CALL dbcsr_copy(matrix_hc_physical_im(local_channel)%matrix, &
1041 1664 : matrix_hc_im(local_channel)%matrix)
1042 4992 : ALLOCATE (orbital_scaling_factor(homo))
1043 1664 : IF (restricted_roks) THEN
1044 534 : orbital_scaling_factor(:) = 2.0_dp*wkp(ikpoint)
1045 : ELSE
1046 : orbital_scaling_factor(:) = 2.0_dp*wkp(ikpoint)* &
1047 10238 : trial_occupation(1:homo, ikpoint, ispin)
1048 : END IF
1049 : CALL dbcsr_scale_by_vector(matrix_hc_physical(local_channel)%matrix, &
1050 1664 : alpha=orbital_scaling_factor, side='right')
1051 : CALL dbcsr_scale_by_vector(matrix_hc_physical_im(local_channel)%matrix, &
1052 1664 : alpha=orbital_scaling_factor, side='right')
1053 1664 : DEALLOCATE (orbital_scaling_factor)
1054 : END IF
1055 17073 : ALLOCATE (orbital_scaling_factor(homo))
1056 5691 : IF (local_ot_env(local_channel)%settings%occupation_preconditioner) THEN
1057 10772 : orbital_scaling_factor(:) = 2.0_dp*wkp(ikpoint)
1058 4027 : ELSE IF (restricted_roks) THEN
1059 261 : orbital_scaling_factor(:) = 2.0_dp*wkp(ikpoint)
1060 3940 : ELSE IF (local_ot_env(local_channel)%settings%do_ener) THEN
1061 : orbital_scaling_factor(:) = 2.0_dp*wkp(ikpoint)* &
1062 4776 : trial_occupation(1:homo, ikpoint, ispin)
1063 : ELSE
1064 26068 : orbital_scaling_factor(:) = 2.0_dp*wkp(ikpoint)*occupation_numbers(1:homo)
1065 : END IF
1066 : CALL dbcsr_scale_by_vector(matrix_hc(local_channel)%matrix, &
1067 5691 : alpha=orbital_scaling_factor, side='right')
1068 : CALL dbcsr_scale_by_vector(matrix_hc_im(local_channel)%matrix, &
1069 5691 : alpha=orbital_scaling_factor, side='right')
1070 5691 : DEALLOCATE (orbital_scaling_factor)
1071 5691 : CALL cp_fm_release(mo_coeff)
1072 16333 : CALL cp_fm_release(mo_coeff_im)
1073 : END DO
1074 : END DO
1075 :
1076 3016 : IF (local_ot_env(1)%settings%do_ener) THEN
1077 1378 : local_ot_env(1)%etotal = energy%total - energy%kTS + trial_kTS
1078 : CALL qs_scf_loop_prepare_ot_kp_energy_gradient( &
1079 : kpoints, local_ot_env, first_channel, nspin_ot, nspin_energy, restricted_roks, &
1080 : wkp, para_env_inter_kp, scf_control%smear, &
1081 1378 : trial_eigenvalues, trial_occupation, trial_mu)
1082 1378 : IF (local_ot_env(1)%settings%occupation_preconditioner) THEN
1083 : CALL ot_mini_prepare_gradient( &
1084 : local_ot_env, matrix_hc, matrix_hc_im=matrix_hc_im, &
1085 : matrix_hc_physical=matrix_hc_physical, &
1086 : matrix_hc_physical_im=matrix_hc_physical_im, &
1087 1146 : para_env_inter_kp=para_env_inter_kp)
1088 : ELSE
1089 : CALL ot_mini_prepare_gradient( &
1090 : local_ot_env, matrix_hc, matrix_hc_im=matrix_hc_im, &
1091 232 : para_env_inter_kp=para_env_inter_kp)
1092 : END IF
1093 1378 : ot_gradient_prepared = .TRUE.
1094 : ! A coupled response direction is consumed only when the minimizer starts a new
1095 : ! search. Line-search trial points still need their physical gradient, but rebuilding
1096 : ! the dense finite-rotation Hessian there cannot affect the accepted direction.
1097 1378 : IF (physical_base_state) THEN
1098 : CALL qs_scf_loop_prepare_ot_kp_rotation_response( &
1099 : qs_env, kpoints, local_ot_env, first_channel, nspin_ot, restricted_roks, &
1100 : wkp, para_env_inter_kp, sab_nl, fmwork, rho_ao_kp, &
1101 624 : scf_control%smear, trial_eigenvalues, trial_occupation, trial_mu)
1102 : END IF
1103 : IF (physical_base_state .AND. &
1104 624 : local_ot_env(1)%settings%occupation_preconditioner .AND. &
1105 : (local_ot_env(1)%settings%ot_method == "CG" .OR. &
1106 : local_ot_env(1)%settings%ot_method == "LBFG")) THEN
1107 856 : DO local_channel = 1, nlocal_channels
1108 1124 : CALL qs_scf_kp_store_mermin_gradient(local_ot_env(local_channel))
1109 : END DO
1110 : END IF
1111 : END IF
1112 3016 : IF (local_ot_env(1)%settings%occupation_preconditioner) THEN
1113 : CALL ot_mini(local_ot_env, matrix_hc, matrix_hc_im=matrix_hc_im, &
1114 : matrix_hc_physical=matrix_hc_physical, &
1115 : matrix_hc_physical_im=matrix_hc_physical_im, &
1116 : para_env_inter_kp=para_env_inter_kp, &
1117 1146 : gradient_prepared=ot_gradient_prepared)
1118 : ELSE
1119 : CALL ot_mini(local_ot_env, matrix_hc, matrix_hc_im=matrix_hc_im, &
1120 : para_env_inter_kp=para_env_inter_kp, &
1121 1870 : gradient_prepared=ot_gradient_prepared)
1122 : END IF
1123 3016 : scf_env%iter_delta = local_ot_env(1)%delta
1124 3016 : energy_only = local_ot_env(1)%energy_only
1125 :
1126 7967 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
1127 4951 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
1128 4951 : ikpoint = kp%nkpoint
1129 4951 : CPASSERT(ASSOCIATED(kp%ot_smat))
1130 4951 : CPASSERT(SIZE(kp%ot_smat) >= 2)
1131 : CALL kpoint_operator_get_local(matrix_s, kpoints, kp, 1, &
1132 : kp%ot_smat(1), kp%ot_smat(2), &
1133 4951 : matrix_s_re, matrix_s_im)
1134 10642 : DO ispin = 1, nspin_ot
1135 5691 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
1136 : CALL get_mo_set(kp%mos(ispin), homo=homo, eigenvalues=eigenvalues, &
1137 5691 : nao=nao, nmo=nmo)
1138 5691 : CALL cp_fm_create(mo_coeff, kp%mos(ispin)%cmo_coeff%matrix_struct)
1139 5691 : CALL cp_fm_create(mo_coeff_im, kp%mos(ispin)%cmo_coeff%matrix_struct)
1140 5691 : CALL cp_cfm_to_fm(kp%mos(ispin)%cmo_coeff, mo_coeff, mo_coeff_im)
1141 5691 : IF (local_ot_env(local_channel)%settings%do_ener) homo = nmo
1142 2634 : SELECT CASE (local_ot_env(local_channel)%settings%ot_algorithm)
1143 : CASE ("TOD")
1144 : CALL qs_ot_get_orbitals_complex(matrix_hc(local_channel)%matrix, &
1145 : matrix_hc_im(local_channel)%matrix, &
1146 : matrix_s_re, matrix_s_im, &
1147 2634 : local_ot_env(local_channel))
1148 : CASE ("REF")
1149 : CALL qs_ot_get_orbitals_ref_complex(matrix_hc(local_channel)%matrix, &
1150 : matrix_hc_im(local_channel)%matrix, &
1151 : matrix_s_re, matrix_s_im, &
1152 3057 : local_ot_env(local_channel), local_ot_env(1))
1153 : CASE DEFAULT
1154 5691 : CPABORT("K-point OT orbital update requires ALGORITHM STRICT or IRAC")
1155 : END SELECT
1156 : CALL cp_fm_struct_create(active_mo_struct, template_fmstruct=mo_coeff%matrix_struct, &
1157 5691 : ncol_global=homo)
1158 5691 : CALL cp_fm_create(active_mo_coeff, active_mo_struct)
1159 5691 : CALL cp_fm_create(active_mo_coeff_im, active_mo_struct)
1160 5691 : CALL copy_dbcsr_to_fm(matrix_hc(local_channel)%matrix, active_mo_coeff)
1161 5691 : CALL copy_dbcsr_to_fm(matrix_hc_im(local_channel)%matrix, active_mo_coeff_im)
1162 5691 : CALL cp_fm_to_fm(active_mo_coeff, mo_coeff, homo)
1163 5691 : CALL cp_fm_to_fm(active_mo_coeff_im, mo_coeff_im, homo)
1164 5691 : CALL cp_fm_to_cfm(mo_coeff, mo_coeff_im, kp%mos(ispin)%cmo_coeff)
1165 5691 : IF (local_ot_env(local_channel)%settings%do_ener .AND. .NOT. restricted_roks) THEN
1166 15014 : eigenvalues(1:homo) = local_ot_env(local_channel)%ener_x(:)
1167 : END IF
1168 5691 : CALL cp_fm_release(active_mo_coeff)
1169 5691 : CALL cp_fm_release(active_mo_coeff_im)
1170 5691 : CALL cp_fm_release(mo_coeff)
1171 5691 : CALL cp_fm_release(mo_coeff_im)
1172 22024 : CALL cp_fm_struct_release(active_mo_struct)
1173 : END DO
1174 4951 : IF (restricted_roks) THEN
1175 137 : CPASSERT(SIZE(kp%mos) == 2)
1176 137 : CALL cp_cfm_to_cfm(kp%mos(1)%cmo_coeff, kp%mos(2)%cmo_coeff)
1177 137 : IF (local_ot_env(local_channel)%settings%do_ener) THEN
1178 150 : DO energy_spin = 1, nspin_energy
1179 100 : energy_start = (energy_spin - 1)*homo + 1
1180 : kp%mos(energy_spin)%eigenvalues(1:homo) = &
1181 2086 : local_ot_env(local_channel)%ener_x(energy_start:energy_start + homo - 1)
1182 : END DO
1183 : END IF
1184 : END IF
1185 4951 : CALL dbcsr_release_p(matrix_s_re)
1186 7967 : CALL dbcsr_release_p(matrix_s_im)
1187 : END DO
1188 :
1189 3016 : IF (local_ot_env(1)%settings%do_ener) THEN
1190 : CALL kpoint_set_mo_occupation(kpoints, scf_control%smear, &
1191 : added_mos_auto=scf_control%added_mos_auto, &
1192 : added_mos_auto_grow=added_mos_auto_grow, &
1193 1378 : separate_spin_occupations=restricted_roks)
1194 : END IF
1195 :
1196 3016 : IF (ALLOCATED(trial_eigenvalues)) DEALLOCATE (trial_eigenvalues)
1197 3016 : IF (ALLOCATED(trial_occupation)) DEALLOCATE (trial_occupation)
1198 3016 : IF (ALLOCATED(trial_mu)) DEALLOCATE (trial_mu)
1199 :
1200 3016 : IF (.NOT. added_mos_auto_grow) THEN
1201 3010 : fmwork => scf_env%scf_work1
1202 3010 : IF (ASSOCIATED(scf_env%p_mix_new)) THEN
1203 0 : density_target => scf_env%p_mix_new
1204 : ELSE
1205 3010 : CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
1206 3010 : density_target => rho_ao_kp
1207 : END IF
1208 3010 : CALL kpoint_density_matrices(kpoints)
1209 : CALL kpoint_density_transform(kpoints, density_target, .FALSE., &
1210 : matrix_s(1, 1)%matrix, sab_nl, fmwork, &
1211 3010 : overlap_rs=matrix_s)
1212 : END IF
1213 3016 : scf_env%iter_method = scf_env%qs_ot_env(first_channel)%OT_METHOD_FULL
1214 3016 : scf_env%iter_param = scf_env%qs_ot_env(first_channel)%ds_min
1215 3016 : qs_env%broyden_adaptive_sigma = scf_env%qs_ot_env(first_channel)%broyden_adaptive_sigma
1216 :
1217 8707 : DO local_channel = 1, nlocal_channels
1218 5691 : CALL dbcsr_release(matrix_hc(local_channel)%matrix)
1219 5691 : CALL dbcsr_release(matrix_hc_im(local_channel)%matrix)
1220 5691 : DEALLOCATE (matrix_hc(local_channel)%matrix)
1221 5691 : DEALLOCATE (matrix_hc_im(local_channel)%matrix)
1222 8707 : IF (local_ot_env(1)%settings%occupation_preconditioner) THEN
1223 1664 : CALL dbcsr_release(matrix_hc_physical(local_channel)%matrix)
1224 1664 : CALL dbcsr_release(matrix_hc_physical_im(local_channel)%matrix)
1225 1664 : DEALLOCATE (matrix_hc_physical(local_channel)%matrix)
1226 1664 : DEALLOCATE (matrix_hc_physical_im(local_channel)%matrix)
1227 : END IF
1228 : END DO
1229 3016 : DEALLOCATE (matrix_hc, matrix_hc_im)
1230 3016 : IF (local_ot_env(1)%settings%occupation_preconditioner) THEN
1231 1146 : DEALLOCATE (matrix_hc_physical, matrix_hc_physical_im)
1232 : END IF
1233 :
1234 3016 : CALL timestop(handle)
1235 :
1236 6032 : END SUBROUTINE qs_scf_loop_do_ot_kp
1237 :
1238 : ! **************************************************************************************************
1239 : !> \brief roll one accepted physical K-point Mermin endpoint into a bounded response history
1240 : !> \param history physical history for one spin density
1241 : !> \param c_re current real orbital coefficients
1242 : !> \param c_im current imaginary orbital coefficients
1243 : !> \param h_re current real self-consistent Hamiltonian
1244 : !> \param h_im current imaginary self-consistent Hamiltonian
1245 : !> \param occupation current fixed-N occupations
1246 : ! **************************************************************************************************
1247 714 : SUBROUTINE qs_scf_kp_roll_physical_secant(history, c_re, c_im, h_re, h_im, occupation)
1248 : TYPE(qs_ot_physical_secant_type), INTENT(INOUT) :: history
1249 : TYPE(cp_fm_type), INTENT(IN), TARGET :: c_re, c_im, h_re, h_im
1250 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: occupation
1251 :
1252 : INTEGER :: nmo
1253 : LOGICAL :: previous_valid
1254 :
1255 714 : nmo = SIZE(occupation)
1256 714 : CPASSERT(nmo > 0)
1257 : previous_valid = history%reference_valid .AND. &
1258 : ASSOCIATED(history%c0) .AND. ASSOCIATED(history%c0_im) .AND. &
1259 : ASSOCIATED(history%h0) .AND. ASSOCIATED(history%h0_im) .AND. &
1260 714 : ALLOCATED(history%occupation0)
1261 614 : IF (previous_valid) previous_valid = SIZE(history%occupation0) == nmo
1262 100 : history%secant_valid = .FALSE.
1263 614 : IF (previous_valid) THEN
1264 614 : CALL store_physical_fm_matrix(history%c0, history%c_previous, "mermin_previous_c")
1265 614 : CALL store_physical_fm_matrix(history%c0_im, history%c_previous_im, "mermin_previous_c_im")
1266 614 : CALL store_physical_fm_matrix(h_re, history%y_previous, "mermin_previous_y")
1267 614 : CALL store_physical_fm_matrix(h_im, history%y_previous_im, "mermin_previous_y_im")
1268 : CALL cp_fm_scale_and_add( &
1269 614 : 1.0_dp, history%y_previous, -1.0_dp, history%h0)
1270 : CALL cp_fm_scale_and_add( &
1271 614 : 1.0_dp, history%y_previous_im, -1.0_dp, history%h0_im)
1272 614 : IF (ALLOCATED(history%occupation_previous)) THEN
1273 536 : IF (SIZE(history%occupation_previous) /= nmo) THEN
1274 0 : DEALLOCATE (history%occupation_previous)
1275 : END IF
1276 : END IF
1277 614 : IF (.NOT. ALLOCATED(history%occupation_previous)) THEN
1278 234 : ALLOCATE (history%occupation_previous(nmo))
1279 : END IF
1280 4312 : history%occupation_previous(:) = history%occupation0(:)
1281 614 : history%secant_valid = .TRUE.
1282 : END IF
1283 :
1284 714 : CALL store_physical_fm_matrix(c_re, history%c0, "mermin_c0")
1285 714 : CALL store_physical_fm_matrix(c_im, history%c0_im, "mermin_c0_im")
1286 714 : CALL store_physical_fm_matrix(h_re, history%h0, "mermin_h0")
1287 714 : CALL store_physical_fm_matrix(h_im, history%h0_im, "mermin_h0_im")
1288 714 : IF (ALLOCATED(history%occupation0)) THEN
1289 614 : IF (SIZE(history%occupation0) /= nmo) DEALLOCATE (history%occupation0)
1290 : END IF
1291 914 : IF (.NOT. ALLOCATED(history%occupation0)) ALLOCATE (history%occupation0(nmo))
1292 5022 : history%occupation0(:) = occupation(:)
1293 714 : history%reference_valid = .TRUE.
1294 :
1295 714 : END SUBROUTINE qs_scf_kp_roll_physical_secant
1296 :
1297 : ! **************************************************************************************************
1298 : !> \brief store the raw physical Mermin gradient at one accepted K-point endpoint
1299 : !> \param qs_ot_env local spin/K-point OT channel
1300 : ! **************************************************************************************************
1301 500 : SUBROUTINE qs_scf_kp_store_mermin_gradient(qs_ot_env)
1302 : TYPE(qs_ot_type) :: qs_ot_env
1303 :
1304 500 : CPASSERT(ASSOCIATED(qs_ot_env%matrix_mermin_g0))
1305 500 : CPASSERT(ASSOCIATED(qs_ot_env%matrix_mermin_g0_im))
1306 500 : CPASSERT(ASSOCIATED(qs_ot_env%rot_mat_mermin_g0))
1307 500 : CPASSERT(ASSOCIATED(qs_ot_env%rot_mat_mermin_g0_im))
1308 500 : CPASSERT(ALLOCATED(qs_ot_env%ener_mermin_g0))
1309 500 : CPASSERT(SIZE(qs_ot_env%ener_mermin_g0) == SIZE(qs_ot_env%ener_gx))
1310 :
1311 500 : CALL dbcsr_copy(qs_ot_env%matrix_mermin_g0, qs_ot_env%matrix_gx)
1312 500 : CALL dbcsr_copy(qs_ot_env%matrix_mermin_g0_im, qs_ot_env%matrix_gx_im)
1313 500 : CALL dbcsr_copy(qs_ot_env%rot_mat_mermin_g0, qs_ot_env%rot_mat_gx)
1314 500 : CALL dbcsr_copy(qs_ot_env%rot_mat_mermin_g0_im, qs_ot_env%rot_mat_gx_im)
1315 3452 : qs_ot_env%ener_mermin_g0(:) = qs_ot_env%ener_gx(:)
1316 500 : qs_ot_env%mermin_gradient_ref_valid = .TRUE.
1317 :
1318 500 : END SUBROUTINE qs_scf_kp_store_mermin_gradient
1319 :
1320 : ! **************************************************************************************************
1321 : !> \brief copy an owned physical full-matrix snapshot, reallocating on shape changes
1322 : !> \param source transient or persistent source matrix
1323 : !> \param snapshot owned response-history matrix
1324 : !> \param name matrix name
1325 : ! **************************************************************************************************
1326 5312 : SUBROUTINE store_physical_fm_matrix(source, snapshot, name)
1327 : TYPE(cp_fm_type), INTENT(IN), TARGET :: source
1328 : TYPE(cp_fm_type), INTENT(INOUT), POINTER :: snapshot
1329 : CHARACTER(LEN=*), INTENT(IN) :: name
1330 :
1331 : INTEGER :: ncol_snapshot, ncol_source, &
1332 : nrow_snapshot, nrow_source
1333 : LOGICAL :: shape_changed
1334 :
1335 5312 : CALL cp_fm_get_info(source, nrow_global=nrow_source, ncol_global=ncol_source)
1336 5312 : shape_changed = .FALSE.
1337 5312 : IF (ASSOCIATED(snapshot)) THEN
1338 4600 : CALL cp_fm_get_info(snapshot, nrow_global=nrow_snapshot, ncol_global=ncol_snapshot)
1339 4600 : shape_changed = nrow_snapshot /= nrow_source .OR. ncol_snapshot /= ncol_source
1340 : IF (shape_changed) THEN
1341 0 : CALL cp_fm_release(snapshot)
1342 0 : DEALLOCATE (snapshot)
1343 : END IF
1344 : END IF
1345 5312 : IF (.NOT. ASSOCIATED(snapshot)) THEN
1346 712 : ALLOCATE (snapshot)
1347 712 : CALL cp_fm_create(snapshot, source%matrix_struct, name=name)
1348 : END IF
1349 5312 : CALL cp_fm_to_fm(source, snapshot)
1350 :
1351 5312 : END SUBROUTINE store_physical_fm_matrix
1352 :
1353 : ! **************************************************************************************************
1354 : !> \brief project one accepted physical Hxc secant onto current-orbital density tangents
1355 : !> \param history accepted endpoint snapshots for one physical spin density
1356 : !> \param overlap_re real part of the AO overlap matrix
1357 : !> \param overlap_im imaginary part of the AO overlap matrix
1358 : !> \param density_modes current-orbital density tangents including the K-point weight
1359 : !> \param kpoint_weight irreducible K-point weight
1360 : !> \param density_norm_sq physical density-step norm
1361 : !> \param response_work density/Hamiltonian response work
1362 : !> \param density_overlap projections of the density step onto density_modes
1363 : !> \param response_overlap projections of the Hamiltonian step onto density_modes
1364 : !> \param valid whether a finite accepted secant was available
1365 : ! **************************************************************************************************
1366 256 : SUBROUTINE qs_scf_kp_physical_secant_overlaps( &
1367 256 : history, overlap_re, overlap_im, density_modes, kpoint_weight, density_norm_sq, &
1368 256 : response_work, density_overlap, response_overlap, valid)
1369 :
1370 : TYPE(qs_ot_physical_secant_type), INTENT(IN) :: history
1371 : TYPE(cp_fm_type), INTENT(IN) :: overlap_re, overlap_im
1372 : COMPLEX(KIND=dp), DIMENSION(:, :, :), INTENT(IN) :: density_modes
1373 : REAL(KIND=dp), INTENT(IN) :: kpoint_weight
1374 : REAL(KIND=dp), INTENT(OUT) :: density_norm_sq, response_work
1375 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: density_overlap, response_overlap
1376 : LOGICAL, INTENT(OUT) :: valid
1377 :
1378 256 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: hamiltonian_step_current, &
1379 256 : hamiltonian_step_previous, &
1380 256 : overlap_previous_current
1381 : INTEGER :: nmo
1382 256 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: dense_im, dense_re
1383 : TYPE(cp_fm_type) :: action_im, action_re, cross_im, cross_re, &
1384 : projection_im, projection_re
1385 :
1386 256 : nmo = SIZE(density_modes, 1)
1387 0 : CPASSERT(nmo > 0)
1388 256 : CPASSERT(SIZE(density_modes, 2) == nmo)
1389 256 : CPASSERT(SIZE(density_overlap) == SIZE(density_modes, 3))
1390 256 : CPASSERT(SIZE(response_overlap) == SIZE(density_modes, 3))
1391 : valid = history%secant_valid .AND. &
1392 : ASSOCIATED(history%c0) .AND. ASSOCIATED(history%c0_im) .AND. &
1393 : ASSOCIATED(history%c_previous) .AND. ASSOCIATED(history%c_previous_im) .AND. &
1394 : ASSOCIATED(history%y_previous) .AND. ASSOCIATED(history%y_previous_im) .AND. &
1395 256 : ALLOCATED(history%occupation0) .AND. ALLOCATED(history%occupation_previous)
1396 256 : density_norm_sq = 0.0_dp
1397 256 : response_work = 0.0_dp
1398 768 : density_overlap(:) = 0.0_dp
1399 768 : response_overlap(:) = 0.0_dp
1400 256 : IF (.NOT. valid) RETURN
1401 256 : CPASSERT(SIZE(history%occupation0) == nmo)
1402 256 : CPASSERT(SIZE(history%occupation_previous) == nmo)
1403 :
1404 : CALL cp_fm_create(action_re, history%c0%matrix_struct, &
1405 256 : name="mermin_hxc_action_re", set_zero=.TRUE.)
1406 : CALL cp_fm_create(action_im, history%c0%matrix_struct, &
1407 256 : name="mermin_hxc_action_im", set_zero=.TRUE.)
1408 : CALL cp_fm_create(cross_re, history%c0%matrix_struct, &
1409 256 : name="mermin_hxc_cross_re", nrow=nmo, ncol=nmo, set_zero=.TRUE.)
1410 : CALL cp_fm_create(cross_im, history%c0%matrix_struct, &
1411 256 : name="mermin_hxc_cross_im", nrow=nmo, ncol=nmo, set_zero=.TRUE.)
1412 : CALL cp_fm_create(projection_re, history%c0%matrix_struct, &
1413 256 : name="mermin_hxc_projection_re", nrow=nmo, ncol=nmo, set_zero=.TRUE.)
1414 : CALL cp_fm_create(projection_im, history%c0%matrix_struct, &
1415 256 : name="mermin_hxc_projection_im", nrow=nmo, ncol=nmo, set_zero=.TRUE.)
1416 : ALLOCATE (dense_re(nmo, nmo), dense_im(nmo, nmo), &
1417 : hamiltonian_step_current(nmo, nmo), hamiltonian_step_previous(nmo, nmo), &
1418 3328 : overlap_previous_current(nmo, nmo))
1419 :
1420 : CALL multiply_complex_fm_nn( &
1421 : overlap_re, overlap_im, history%c0, history%c0_im, &
1422 256 : action_re, action_im, 1.0_dp, 0.0_dp)
1423 : CALL multiply_complex_fm_adjoint( &
1424 : history%c_previous, history%c_previous_im, &
1425 256 : action_re, action_im, cross_re, cross_im, 1.0_dp, 0.0_dp)
1426 256 : CALL cp_fm_get_submatrix(cross_re, dense_re)
1427 256 : CALL cp_fm_get_submatrix(cross_im, dense_im)
1428 13680 : overlap_previous_current(:, :) = CMPLX(dense_re, dense_im, KIND=dp)
1429 :
1430 : CALL project_physical_response( &
1431 : history, history%c0, history%c0_im, &
1432 256 : action_re, action_im, projection_re, projection_im, hamiltonian_step_current)
1433 : CALL project_physical_response( &
1434 : history, history%c_previous, history%c_previous_im, &
1435 256 : action_re, action_im, projection_re, projection_im, hamiltonian_step_previous)
1436 : CALL qs_ot_density_secant_orbital_overlaps( &
1437 : overlap_previous_current, history%occupation_previous, history%occupation0, &
1438 : hamiltonian_step_previous, hamiltonian_step_current, &
1439 : density_modes, kpoint_weight, density_norm_sq, response_work, density_overlap, &
1440 256 : response_overlap, valid)
1441 :
1442 0 : DEALLOCATE (dense_re, dense_im, hamiltonian_step_current, &
1443 256 : hamiltonian_step_previous, overlap_previous_current)
1444 256 : CALL cp_fm_release(action_re)
1445 256 : CALL cp_fm_release(action_im)
1446 256 : CALL cp_fm_release(cross_re)
1447 256 : CALL cp_fm_release(cross_im)
1448 256 : CALL cp_fm_release(projection_re)
1449 512 : CALL cp_fm_release(projection_im)
1450 :
1451 : CONTAINS
1452 :
1453 : ! **************************************************************************************************
1454 : !> \brief ...
1455 : !> \param env ...
1456 : !> \param c_re ...
1457 : !> \param c_im ...
1458 : !> \param action_re ...
1459 : !> \param action_im ...
1460 : !> \param projected_re ...
1461 : !> \param projected_im ...
1462 : !> \param projected ...
1463 : ! **************************************************************************************************
1464 512 : SUBROUTINE project_physical_response( &
1465 512 : env, c_re, c_im, action_re, action_im, projected_re, projected_im, projected)
1466 : TYPE(qs_ot_physical_secant_type), INTENT(IN) :: env
1467 : TYPE(cp_fm_type), INTENT(IN) :: c_re, c_im, action_re, action_im, &
1468 : projected_re, projected_im
1469 : COMPLEX(KIND=dp), DIMENSION(:, :), INTENT(OUT) :: projected
1470 :
1471 : CALL multiply_complex_fm_nn( &
1472 : env%y_previous, env%y_previous_im, c_re, c_im, &
1473 512 : action_re, action_im, 1.0_dp, 0.0_dp)
1474 : CALL multiply_complex_fm_adjoint( &
1475 512 : c_re, c_im, action_re, action_im, projected_re, projected_im, 1.0_dp, 0.0_dp)
1476 512 : CALL cp_fm_get_submatrix(projected_re, dense_re)
1477 512 : CALL cp_fm_get_submatrix(projected_im, dense_im)
1478 27360 : projected(:, :) = CMPLX(dense_re, dense_im, KIND=dp)
1479 54720 : projected(:, :) = 0.5_dp*(projected + CONJG(TRANSPOSE(projected)))
1480 512 : END SUBROUTINE project_physical_response
1481 :
1482 : END SUBROUTINE qs_scf_kp_physical_secant_overlaps
1483 :
1484 : ! **************************************************************************************************
1485 : !> \brief accumulate C=beta*C+alpha*A*B for split-complex distributed full matrices
1486 : !> \param a_re ...
1487 : !> \param a_im ...
1488 : !> \param b_re ...
1489 : !> \param b_im ...
1490 : !> \param c_re ...
1491 : !> \param c_im ...
1492 : !> \param alpha ...
1493 : !> \param beta ...
1494 : ! **************************************************************************************************
1495 3102 : SUBROUTINE multiply_complex_fm_nn(a_re, a_im, b_re, b_im, c_re, c_im, alpha, beta)
1496 : TYPE(cp_fm_type), INTENT(IN) :: a_re, a_im, b_re, b_im, c_re, c_im
1497 : REAL(KIND=dp), INTENT(IN) :: alpha, beta
1498 :
1499 : INTEGER :: k, k_b, m, m_c, n, n_c
1500 :
1501 1034 : CALL cp_fm_get_info(a_re, nrow_global=m, ncol_global=k)
1502 1034 : CALL cp_fm_get_info(b_re, nrow_global=k_b, ncol_global=n)
1503 1034 : CALL cp_fm_get_info(c_re, nrow_global=m_c, ncol_global=n_c)
1504 1034 : CPASSERT(k_b == k .AND. m_c == m .AND. n_c == n)
1505 1034 : CALL cp_complex_fm_gemm('N', 'N', m, n, k, alpha, a_re, a_im, b_re, b_im, beta, c_re, c_im)
1506 :
1507 1034 : END SUBROUTINE multiply_complex_fm_nn
1508 :
1509 : ! **************************************************************************************************
1510 : !> \brief accumulate C=beta*C+alpha*A^H*B for split-complex distributed full matrices
1511 : !> \param a_re ...
1512 : !> \param a_im ...
1513 : !> \param b_re ...
1514 : !> \param b_im ...
1515 : !> \param c_re ...
1516 : !> \param c_im ...
1517 : !> \param alpha ...
1518 : !> \param beta ...
1519 : ! **************************************************************************************************
1520 9330 : SUBROUTINE multiply_complex_fm_adjoint(a_re, a_im, b_re, b_im, c_re, c_im, alpha, beta)
1521 : TYPE(cp_fm_type), INTENT(IN) :: a_re, a_im, b_re, b_im, c_re, c_im
1522 : REAL(KIND=dp), INTENT(IN) :: alpha, beta
1523 :
1524 : INTEGER :: k, k_b, m, m_c, n, n_c
1525 :
1526 3110 : CALL cp_fm_get_info(a_re, nrow_global=k, ncol_global=m)
1527 3110 : CALL cp_fm_get_info(b_re, nrow_global=k_b, ncol_global=n)
1528 3110 : CALL cp_fm_get_info(c_re, nrow_global=m_c, ncol_global=n_c)
1529 3110 : CPASSERT(k_b == k .AND. m_c == m .AND. n_c == n)
1530 3110 : CALL cp_complex_fm_gemm('C', 'N', m, n, k, alpha, a_re, a_im, b_re, b_im, beta, c_re, c_im)
1531 :
1532 3110 : END SUBROUTINE multiply_complex_fm_adjoint
1533 :
1534 : ! **************************************************************************************************
1535 : !> \brief accumulate C=beta*C+alpha*A*B^H for split-complex distributed full matrices
1536 : !> \param a_re real part of A
1537 : !> \param a_im imaginary part of A
1538 : !> \param b_re real part of B
1539 : !> \param b_im imaginary part of B
1540 : !> \param c_re real part of C
1541 : !> \param c_im imaginary part of C
1542 : !> \param alpha product scaling factor
1543 : !> \param beta initial C scaling factor
1544 : ! **************************************************************************************************
1545 714 : SUBROUTINE multiply_complex_fm_right_adjoint(a_re, a_im, b_re, b_im, c_re, c_im, alpha, beta)
1546 : TYPE(cp_fm_type), INTENT(IN) :: a_re, a_im, b_re, b_im, c_re, c_im
1547 : REAL(KIND=dp), INTENT(IN) :: alpha, beta
1548 :
1549 : INTEGER :: k, k_b, m, m_c, n, n_c
1550 :
1551 238 : CALL cp_fm_get_info(a_re, nrow_global=m, ncol_global=k)
1552 238 : CALL cp_fm_get_info(b_re, nrow_global=n, ncol_global=k_b)
1553 238 : CALL cp_fm_get_info(c_re, nrow_global=m_c, ncol_global=n_c)
1554 238 : CPASSERT(k_b == k .AND. m_c == m .AND. n_c == n)
1555 238 : CALL cp_complex_fm_gemm('N', 'C', m, n, k, alpha, a_re, a_im, b_re, b_im, beta, c_re, c_im)
1556 :
1557 238 : END SUBROUTINE multiply_complex_fm_right_adjoint
1558 :
1559 : ! **************************************************************************************************
1560 : !> \brief Evaluate the GPW Hartree-XC and Lowdin +U curvature of a complex K-point density mode.
1561 : !> \param qs_env ground-state QS environment defining the current density and XC kernel
1562 : !> \param kpoints K-point environment and group distribution
1563 : !> \param local_ot_env local spin/K-point OT channels
1564 : !> \param first_channel global index of the first local channel
1565 : !> \param nspin_ot number of physical spin channels
1566 : !> \param wkp irreducible K-point weights
1567 : !> \param para_env_inter_kp communicator between distributed K-point groups
1568 : !> \param sab_nl real-space neighbor lists used by the K-point density transform
1569 : !> \param fmwork full-matrix workspaces on the global communicator
1570 : !> \param rho_ao_kp template AO density matrices for the real-space images
1571 : !> \param channel_density_modes weighted current-orbital density modes per local channel
1572 : !> \param number_of_modes number of populated modes to apply
1573 : !> \param projected_hxc projected Hartree-XC Hessian in the supplied density-mode basis
1574 : !> \param valid whether the projected block is finite and Hermitian within tolerance
1575 : ! **************************************************************************************************
1576 114 : SUBROUTINE qs_scf_kp_exact_hxc_projected( &
1577 : qs_env, kpoints, local_ot_env, first_channel, nspin_ot, wkp, para_env_inter_kp, &
1578 228 : sab_nl, fmwork, rho_ao_kp, channel_density_modes, number_of_modes, &
1579 114 : projected_hxc, valid)
1580 :
1581 : TYPE(qs_environment_type), POINTER :: qs_env
1582 : TYPE(kpoint_type), POINTER :: kpoints
1583 : TYPE(qs_ot_type), DIMENSION(:), POINTER :: local_ot_env
1584 : INTEGER, INTENT(IN) :: first_channel, nspin_ot
1585 : REAL(KIND=dp), DIMENSION(:), POINTER :: wkp
1586 : TYPE(mp_para_env_type), POINTER :: para_env_inter_kp
1587 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1588 : POINTER :: sab_nl
1589 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: fmwork
1590 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp
1591 : COMPLEX(KIND=dp), DIMENSION(:, :, :, :), &
1592 : INTENT(IN) :: channel_density_modes
1593 : INTEGER, INTENT(IN) :: number_of_modes
1594 : REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT) :: projected_hxc
1595 : LOGICAL, INTENT(OUT) :: valid
1596 :
1597 114 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: projected
1598 : INTEGER :: ikpoint, ispin, local_channel, local_kpoint, nao, nimages, nkp_groups, &
1599 : nlocal_kpoints, nmo, nmode, response_mode, test_mode
1600 : LOGICAL :: do_hfx
1601 : REAL(KIND=dp) :: symmetry_error, symmetry_scale
1602 114 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: dense_im, dense_re, lowdin_response
1603 : TYPE(cp_cfm_type) :: action_cfm, coeff_cfm
1604 : TYPE(cp_fm_type) :: action_im, action_re, density_im, &
1605 : density_re, inactive_im, inactive_re, &
1606 : projected_im, projected_re
1607 114 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :) :: operator_im, operator_re
1608 114 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:, :, :) :: density_kp
1609 114 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: density_rs, potential_rs
1610 : TYPE(dbcsr_type), POINTER :: matrix_k_im, matrix_k_re, template
1611 : TYPE(dft_control_type), POINTER :: dft_control
1612 : TYPE(kpoint_env_type), POINTER :: kp
1613 114 : TYPE(kpoint_operator_context_type) :: hxc_op_ctx
1614 : TYPE(qs_kpp1_env_type) :: kernel_env
1615 : TYPE(section_vals_type), POINTER :: hfx_section, input
1616 :
1617 798 : projected_hxc(:, :) = 0.0_dp
1618 114 : symmetry_error = 0.0_dp
1619 114 : valid = .FALSE.
1620 114 : NULLIFY (density_rs, dft_control, hfx_section, input, matrix_k_im, matrix_k_re, &
1621 114 : potential_rs, template)
1622 114 : CALL get_qs_env(qs_env, dft_control=dft_control, input=input)
1623 : IF (dft_control%qs_control%semi_empirical .OR. dft_control%qs_control%dftb .OR. &
1624 : dft_control%qs_control%xtb .OR. dft_control%qs_control%gapw .OR. &
1625 : dft_control%qs_control%gapw_xc .OR. dft_control%qs_control%lrigpw .OR. &
1626 114 : dft_control%qs_control%rigpw .OR. dft_control%do_admm) RETURN
1627 98 : hfx_section => section_vals_get_subs_vals(input, "DFT%XC%HF")
1628 98 : CALL section_vals_get(hfx_section, explicit=do_hfx)
1629 98 : IF (do_hfx) RETURN
1630 98 : CALL get_kpoint_info(kpoints, nkp_groups=nkp_groups)
1631 :
1632 98 : nlocal_kpoints = SIZE(kpoints%kp_env)
1633 98 : nmo = SIZE(channel_density_modes, 1)
1634 98 : nmode = number_of_modes
1635 98 : nimages = SIZE(rho_ao_kp, 2)
1636 98 : CPASSERT(nmo > 0)
1637 98 : CPASSERT(nmode > 0 .AND. nmode <= SIZE(channel_density_modes, 3))
1638 98 : CPASSERT(SIZE(channel_density_modes, 2) == nmo)
1639 98 : CPASSERT(SIZE(channel_density_modes, 4) == SIZE(local_ot_env))
1640 98 : IF (.NOT. (SIZE(projected_hxc, 1) >= nmode .AND. SIZE(projected_hxc, 2) >= nmode)) THEN
1641 0 : CALL cp_abort(__LOCATION__, "Projected HXC matrix is too small")
1642 : END IF
1643 98 : CPASSERT(SIZE(rho_ao_kp, 1) == nspin_ot)
1644 98 : CPASSERT(ASSOCIATED(fmwork))
1645 :
1646 98 : template => rho_ao_kp(1, 1)%matrix
1647 98 : CALL cp_fm_get_info(local_ot_env(1)%mermin_physical(1)%c0, nrow_global=nao)
1648 1064 : ALLOCATE (operator_re(nlocal_kpoints, nspin_ot), operator_im(nlocal_kpoints, nspin_ot))
1649 238 : DO local_kpoint = 1, nlocal_kpoints
1650 378 : DO ispin = 1, nspin_ot
1651 : local_channel = qs_ot_channel_index( &
1652 : ispin, kpoints%kp_env(local_kpoint)%kpoint_env%nkpoint, nspin_ot) - &
1653 140 : first_channel + 1
1654 : CALL cp_fm_create(operator_re(local_kpoint, ispin), &
1655 : local_ot_env(local_channel)%mermin_physical(1)%c0%matrix_struct, &
1656 140 : name="hxc_operator_k_re", nrow=nao, ncol=nao, set_zero=.TRUE.)
1657 : CALL cp_fm_create(operator_im(local_kpoint, ispin), &
1658 : local_ot_env(local_channel)%mermin_physical(1)%c0%matrix_struct, &
1659 280 : name="hxc_operator_k_im", nrow=nao, ncol=nao, set_zero=.TRUE.)
1660 : END DO
1661 : END DO
1662 882 : ALLOCATE (dense_re(nmo, nmo), dense_im(nmo, nmo), projected(nmo, nmo))
1663 : ! The group communicators do not own the complete real-space operator;
1664 : ! redistribute it to every group through the service. The fm pair lives
1665 : ! on the OT channel distribution; the service transfers into it
1666 : ! directly, whatever that distribution is. The context spans every
1667 : ! response mode: nothing inside the loop changes the host k-point
1668 : ! environment, and every mode rebuilds potential_rs from the same
1669 : ! rho_ao_kp template, so the work trio distribution stays valid.
1670 98 : IF (nkp_groups > 1) THEN
1671 32 : CALL kpoint_operator_context_create(hxc_op_ctx, kpoints, fmwork(1), nspin_ot)
1672 : END IF
1673 266 : DO response_mode = 1, nmode
1674 1652 : ALLOCATE (density_kp(nlocal_kpoints, 2, nspin_ot))
1675 406 : DO local_kpoint = 1, nlocal_kpoints
1676 238 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
1677 238 : ikpoint = kp%nkpoint
1678 644 : DO ispin = 1, nspin_ot
1679 238 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
1680 238 : IF (.NOT. (ASSOCIATED(local_ot_env(local_channel)%mermin_physical(1)%c0))) THEN
1681 0 : CALL cp_abort(__LOCATION__, "Missing physical OT coefficients")
1682 : END IF
1683 238 : IF (.NOT. (ASSOCIATED(local_ot_env(local_channel)%mermin_physical(1)%c0_im))) THEN
1684 0 : CALL cp_abort(__LOCATION__, "Missing imaginary physical OT coefficients")
1685 : END IF
1686 : CALL cp_fm_create( &
1687 : density_re, local_ot_env(local_channel)%mermin_physical(1)%c0%matrix_struct, &
1688 238 : name="hxc_density_mode_re", nrow=nmo, ncol=nmo)
1689 : CALL cp_fm_create( &
1690 : density_im, local_ot_env(local_channel)%mermin_physical(1)%c0%matrix_struct, &
1691 238 : name="hxc_density_mode_im", nrow=nmo, ncol=nmo)
1692 : CALL cp_fm_set_submatrix( &
1693 : density_re, REAL(channel_density_modes(:, :, response_mode, local_channel), &
1694 8954 : KIND=dp)/wkp(ikpoint))
1695 : CALL cp_fm_set_submatrix( &
1696 : density_im, AIMAG(channel_density_modes(:, :, response_mode, local_channel))/ &
1697 8954 : wkp(ikpoint))
1698 : CALL cp_fm_create( &
1699 : action_re, local_ot_env(local_channel)%mermin_physical(1)%c0%matrix_struct, &
1700 238 : name="hxc_density_action_re", set_zero=.TRUE.)
1701 : CALL cp_fm_create( &
1702 : action_im, local_ot_env(local_channel)%mermin_physical(1)%c0%matrix_struct, &
1703 238 : name="hxc_density_action_im", set_zero=.TRUE.)
1704 : CALL multiply_complex_fm_nn( &
1705 : local_ot_env(local_channel)%mermin_physical(1)%c0, &
1706 : local_ot_env(local_channel)%mermin_physical(1)%c0_im, density_re, density_im, &
1707 238 : action_re, action_im, 1.0_dp, 0.0_dp)
1708 : CALL cp_fm_get_info( &
1709 238 : local_ot_env(local_channel)%mermin_physical(1)%c0, nrow_global=nao)
1710 : CALL cp_fm_create(density_kp(local_kpoint, 1, ispin), &
1711 : local_ot_env(local_channel)%mermin_physical(1)%c0%matrix_struct, &
1712 238 : name="hxc_density_k_re", nrow=nao, ncol=nao, set_zero=.TRUE.)
1713 : CALL cp_fm_create(density_kp(local_kpoint, 2, ispin), &
1714 : local_ot_env(local_channel)%mermin_physical(1)%c0%matrix_struct, &
1715 238 : name="hxc_density_k_im", nrow=nao, ncol=nao, set_zero=.TRUE.)
1716 : CALL multiply_complex_fm_right_adjoint( &
1717 : action_re, action_im, local_ot_env(local_channel)%mermin_physical(1)%c0, &
1718 : local_ot_env(local_channel)%mermin_physical(1)%c0_im, &
1719 : density_kp(local_kpoint, 1, ispin), density_kp(local_kpoint, 2, ispin), &
1720 238 : 1.0_dp, 0.0_dp)
1721 238 : CALL cp_fm_release(action_re)
1722 238 : CALL cp_fm_release(action_im)
1723 238 : CALL cp_fm_release(density_re)
1724 952 : CALL cp_fm_release(density_im)
1725 : END DO
1726 : END DO
1727 :
1728 168 : CALL dbcsr_allocate_matrix_set(density_rs, nspin_ot, nimages)
1729 336 : DO ispin = 1, nspin_ot
1730 37578 : DO local_kpoint = 1, nimages
1731 37242 : ALLOCATE (density_rs(ispin, local_kpoint)%matrix)
1732 : CALL dbcsr_copy(density_rs(ispin, local_kpoint)%matrix, &
1733 37242 : rho_ao_kp(ispin, local_kpoint)%matrix, name="Hxc density response")
1734 37410 : CALL dbcsr_set(density_rs(ispin, local_kpoint)%matrix, 0.0_dp)
1735 : END DO
1736 : END DO
1737 : CALL kpoint_density_transform(kpoints, density_rs, .FALSE., template, sab_nl, fmwork, &
1738 168 : pmat_ext=density_kp)
1739 168 : IF (ALLOCATED(kpoints%lowdin_v)) CALL lowdin_kp_kernel(qs_env, density_kp, lowdin_response)
1740 406 : DO local_kpoint = 1, nlocal_kpoints
1741 644 : DO ispin = 1, nspin_ot
1742 238 : CALL cp_fm_release(density_kp(local_kpoint, 1, ispin))
1743 476 : CALL cp_fm_release(density_kp(local_kpoint, 2, ispin))
1744 : END DO
1745 : END DO
1746 168 : DEALLOCATE (density_kp)
1747 :
1748 168 : CALL apply_hxc_kernel_kp(qs_env, kernel_env, density_rs, potential_rs)
1749 168 : IF (nkp_groups > 1) THEN
1750 : ! Refresh every response mode. The OT channel can use a different
1751 : ! group-local BLACS layout from the default AO/AO pool.
1752 54 : CALL kpoint_operator_prepare(hxc_op_ctx, potential_rs, kpoint_slot_ks, TARGET=operator_re(1, 1))
1753 216 : DO local_kpoint = 1, MAXVAL(kpoints%kp_dist(2, :) - kpoints%kp_dist(1, :) + 1)
1754 162 : DO ispin = 1, nspin_ot
1755 108 : IF (local_kpoint <= nlocal_kpoints) THEN
1756 : CALL kpoint_operator_get(hxc_op_ctx, local_kpoint, ispin, potential_rs, &
1757 : fm_re=operator_re(local_kpoint, ispin), &
1758 54 : fm_im=operator_im(local_kpoint, ispin), matrix_row=ispin, slot=kpoint_slot_ks)
1759 : ELSE
1760 : ! Participate in the global transfers without a local output in this round.
1761 : CALL kpoint_operator_get(hxc_op_ctx, local_kpoint, ispin, potential_rs, &
1762 0 : fm_re=inactive_re, fm_im=inactive_im, matrix_row=ispin, slot=kpoint_slot_ks)
1763 : END IF
1764 : END DO
1765 : END DO
1766 : END IF
1767 406 : DO local_kpoint = 1, nlocal_kpoints
1768 238 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
1769 238 : ikpoint = kp%nkpoint
1770 644 : DO ispin = 1, nspin_ot
1771 238 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
1772 : CALL cp_fm_create( &
1773 : action_re, local_ot_env(local_channel)%mermin_physical(1)%c0%matrix_struct, &
1774 238 : name="hxc_potential_action_re", set_zero=.TRUE.)
1775 : CALL cp_fm_create( &
1776 : action_im, local_ot_env(local_channel)%mermin_physical(1)%c0%matrix_struct, &
1777 238 : name="hxc_potential_action_im", set_zero=.TRUE.)
1778 : CALL kpoint_operator_get_local( &
1779 : potential_rs, kpoints, kp, ispin, operator_re(local_kpoint, ispin), &
1780 238 : operator_im(local_kpoint, ispin), matrix_k_re, matrix_k_im)
1781 : CALL cp_dbcsr_sm_fm_multiply( &
1782 238 : matrix_k_re, local_ot_env(local_channel)%mermin_physical(1)%c0, action_re, nmo)
1783 : CALL cp_dbcsr_sm_fm_multiply( &
1784 : matrix_k_im, local_ot_env(local_channel)%mermin_physical(1)%c0_im, action_re, nmo, &
1785 238 : alpha=-1.0_dp, beta=1.0_dp)
1786 : CALL cp_dbcsr_sm_fm_multiply( &
1787 238 : matrix_k_re, local_ot_env(local_channel)%mermin_physical(1)%c0_im, action_im, nmo)
1788 : CALL cp_dbcsr_sm_fm_multiply( &
1789 : matrix_k_im, local_ot_env(local_channel)%mermin_physical(1)%c0, action_im, nmo, &
1790 238 : alpha=1.0_dp, beta=1.0_dp)
1791 238 : IF (ALLOCATED(lowdin_response)) THEN
1792 0 : IF (ANY(lowdin_response(:, ispin) /= 0.0_dp)) THEN
1793 0 : CALL cp_cfm_create(coeff_cfm, local_ot_env(local_channel)%mermin_physical(1)%c0%matrix_struct)
1794 0 : CALL cp_cfm_create(action_cfm, action_re%matrix_struct)
1795 : CALL cp_fm_to_cfm(local_ot_env(local_channel)%mermin_physical(1)%c0, &
1796 0 : local_ot_env(local_channel)%mermin_physical(1)%c0_im, coeff_cfm)
1797 0 : CALL cp_fm_to_cfm(action_re, action_im, action_cfm)
1798 0 : CALL lowdin_kp_apply_mo(kp, lowdin_response(:, ispin), coeff_cfm, action_cfm)
1799 0 : CALL cp_cfm_to_fm(action_cfm, action_re, action_im)
1800 0 : CALL cp_cfm_release(action_cfm)
1801 0 : CALL cp_cfm_release(coeff_cfm)
1802 : END IF
1803 : END IF
1804 : CALL cp_fm_create( &
1805 : projected_re, local_ot_env(local_channel)%mermin_physical(1)%c0%matrix_struct, &
1806 238 : name="hxc_projected_re", nrow=nmo, ncol=nmo, set_zero=.TRUE.)
1807 : CALL cp_fm_create( &
1808 : projected_im, local_ot_env(local_channel)%mermin_physical(1)%c0%matrix_struct, &
1809 238 : name="hxc_projected_im", nrow=nmo, ncol=nmo, set_zero=.TRUE.)
1810 : CALL multiply_complex_fm_adjoint( &
1811 : local_ot_env(local_channel)%mermin_physical(1)%c0, &
1812 : local_ot_env(local_channel)%mermin_physical(1)%c0_im, action_re, action_im, &
1813 238 : projected_re, projected_im, 1.0_dp, 0.0_dp)
1814 238 : CALL cp_fm_get_submatrix(projected_re, dense_re)
1815 238 : CALL cp_fm_get_submatrix(projected_im, dense_im)
1816 8954 : projected(:, :) = CMPLX(dense_re, dense_im, KIND=dp)
1817 672 : DO test_mode = 1, nmode
1818 : projected_hxc(test_mode, response_mode) = &
1819 : projected_hxc(test_mode, response_mode) + REAL(SUM( &
1820 16596 : CONJG(channel_density_modes(:, :, test_mode, local_channel))*projected), KIND=dp)
1821 : END DO
1822 238 : CALL cp_fm_release(projected_re)
1823 238 : CALL cp_fm_release(projected_im)
1824 238 : CALL cp_fm_release(action_re)
1825 238 : CALL cp_fm_release(action_im)
1826 238 : CALL dbcsr_release_p(matrix_k_re)
1827 476 : CALL dbcsr_release_p(matrix_k_im)
1828 : END DO
1829 : END DO
1830 168 : CALL dbcsr_deallocate_matrix_set(density_rs)
1831 168 : CALL dbcsr_deallocate_matrix_set(potential_rs)
1832 266 : NULLIFY (density_rs, potential_rs)
1833 : END DO
1834 98 : IF (nkp_groups > 1) THEN
1835 32 : CALL kpoint_operator_context_release(hxc_op_ctx)
1836 : END IF
1837 :
1838 1274 : CALL para_env_inter_kp%sum(projected_hxc)
1839 : symmetry_error = MAXVAL(ABS( &
1840 : projected_hxc(1:nmode, 1:nmode) - &
1841 574 : TRANSPOSE(projected_hxc(1:nmode, 1:nmode))))
1842 : symmetry_scale = MAX(SQRT(EPSILON(1.0_dp)), &
1843 574 : MAXVAL(ABS(projected_hxc(1:nmode, 1:nmode))))
1844 : projected_hxc(1:nmode, 1:nmode) = 0.5_dp*( &
1845 : projected_hxc(1:nmode, 1:nmode) + &
1846 1050 : TRANSPOSE(projected_hxc(1:nmode, 1:nmode)))
1847 : valid = ALL(ieee_is_finite(projected_hxc(1:nmode, 1:nmode))) .AND. &
1848 : ieee_is_finite(symmetry_error) .AND. &
1849 574 : symmetry_error <= 1.0E-10_dp*symmetry_scale
1850 :
1851 98 : DEALLOCATE (dense_re, dense_im, projected)
1852 238 : DO local_kpoint = 1, nlocal_kpoints
1853 378 : DO ispin = 1, nspin_ot
1854 140 : CALL cp_fm_release(operator_re(local_kpoint, ispin))
1855 280 : CALL cp_fm_release(operator_im(local_kpoint, ispin))
1856 : END DO
1857 : END DO
1858 98 : DEALLOCATE (operator_re, operator_im)
1859 98 : CALL kpp1_release(kernel_env)
1860 :
1861 424 : END SUBROUTINE qs_scf_kp_exact_hxc_projected
1862 :
1863 : ! **************************************************************************************************
1864 : !> \brief project a split-complex Hamiltonian into a complex orbital basis
1865 : !> \param c_re real orbital coefficients
1866 : !> \param c_im imaginary orbital coefficients
1867 : !> \param h_re real Hamiltonian
1868 : !> \param h_im imaginary Hamiltonian
1869 : !> \param projected dense Hermitian projected Hamiltonian
1870 : ! **************************************************************************************************
1871 28 : SUBROUTINE qs_scf_kp_project_hamiltonian(c_re, c_im, h_re, h_im, projected)
1872 : TYPE(cp_fm_type), INTENT(IN) :: c_re, c_im, h_re, h_im
1873 : COMPLEX(KIND=dp), DIMENSION(:, :), INTENT(OUT) :: projected
1874 :
1875 : INTEGER :: nmo
1876 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: dense_im, dense_re
1877 : TYPE(cp_fm_type) :: action_im, action_re, projection_im, &
1878 : projection_re
1879 :
1880 28 : nmo = SIZE(projected, 1)
1881 28 : CPASSERT(nmo > 0 .AND. SIZE(projected, 2) == nmo)
1882 28 : CALL cp_fm_create(action_re, c_re%matrix_struct, name="ot_response_hc_re", set_zero=.TRUE.)
1883 28 : CALL cp_fm_create(action_im, c_re%matrix_struct, name="ot_response_hc_im", set_zero=.TRUE.)
1884 : CALL cp_fm_create(projection_re, c_re%matrix_struct, name="ot_response_chc_re", &
1885 28 : nrow=nmo, ncol=nmo, set_zero=.TRUE.)
1886 : CALL cp_fm_create(projection_im, c_re%matrix_struct, name="ot_response_chc_im", &
1887 28 : nrow=nmo, ncol=nmo, set_zero=.TRUE.)
1888 168 : ALLOCATE (dense_re(nmo, nmo), dense_im(nmo, nmo))
1889 :
1890 : CALL multiply_complex_fm_nn( &
1891 28 : h_re, h_im, c_re, c_im, action_re, action_im, 1.0_dp, 0.0_dp)
1892 : CALL multiply_complex_fm_adjoint( &
1893 28 : c_re, c_im, action_re, action_im, projection_re, projection_im, 1.0_dp, 0.0_dp)
1894 28 : CALL cp_fm_get_submatrix(projection_re, dense_re)
1895 28 : CALL cp_fm_get_submatrix(projection_im, dense_im)
1896 3108 : projected(:, :) = CMPLX(dense_re, dense_im, KIND=dp)
1897 6216 : projected(:, :) = 0.5_dp*(projected + CONJG(TRANSPOSE(projected)))
1898 :
1899 28 : DEALLOCATE (dense_re, dense_im)
1900 28 : CALL cp_fm_release(action_re)
1901 28 : CALL cp_fm_release(action_im)
1902 28 : CALL cp_fm_release(projection_re)
1903 28 : CALL cp_fm_release(projection_im)
1904 :
1905 28 : END SUBROUTINE qs_scf_kp_project_hamiltonian
1906 :
1907 : ! **************************************************************************************************
1908 : !> \brief collect the global fixed-N trial smearing state used by k-point OT
1909 : !> \param kpoints ...
1910 : !> \param local_ot_env ...
1911 : !> \param first_channel ...
1912 : !> \param nspin_ot ...
1913 : !> \param nspin_energy number of physical spin-resolved auxiliary-energy blocks
1914 : !> \param restricted_roks whether both energy blocks share one orbital channel
1915 : !> \param kp_range ...
1916 : !> \param wkp ...
1917 : !> \param para_env_inter_kp ...
1918 : !> \param smear ...
1919 : !> \param trial_eigenvalues ...
1920 : !> \param trial_occupation ...
1921 : !> \param trial_mu chemical potential for each spin channel
1922 : !> \param trial_kTS ...
1923 : ! **************************************************************************************************
1924 1378 : SUBROUTINE qs_scf_loop_collect_ot_kp_trial_smearing( &
1925 : kpoints, local_ot_env, first_channel, nspin_ot, nspin_energy, restricted_roks, &
1926 : kp_range, wkp, para_env_inter_kp, smear, trial_eigenvalues, trial_occupation, trial_mu, trial_kTS)
1927 :
1928 : TYPE(kpoint_type), POINTER :: kpoints
1929 : TYPE(qs_ot_type), DIMENSION(:), POINTER :: local_ot_env
1930 : INTEGER, INTENT(IN) :: first_channel, nspin_ot, nspin_energy
1931 : LOGICAL, INTENT(IN) :: restricted_roks
1932 : INTEGER, DIMENSION(2), INTENT(IN) :: kp_range
1933 : REAL(KIND=dp), DIMENSION(:), POINTER :: wkp
1934 : TYPE(mp_para_env_type), POINTER :: para_env_inter_kp
1935 : TYPE(smear_type), INTENT(IN) :: smear
1936 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
1937 : INTENT(OUT) :: trial_eigenvalues, trial_occupation
1938 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
1939 : INTENT(OUT) :: trial_mu
1940 : REAL(KIND=dp), INTENT(OUT) :: trial_kTS
1941 :
1942 : INTEGER :: energy_start, ikpoint, ispin, &
1943 : local_channel, local_kpoint, ne_a, &
1944 : ne_b, nelectron, nkpoint, nmo
1945 : REAL(KIND=dp) :: kTS, mu, nel, sigma
1946 : REAL(KIND=dp), DIMENSION(2) :: mus
1947 : TYPE(kpoint_env_type), POINTER :: kp
1948 :
1949 1378 : CPASSERT(smear%do_smear)
1950 2606 : SELECT CASE (smear%method)
1951 : CASE (smear_fermi_dirac)
1952 1228 : sigma = smear%electronic_temperature
1953 : CASE (smear_gaussian, smear_mp, smear_mv)
1954 150 : sigma = smear%smearing_width
1955 : CASE DEFAULT
1956 1378 : CPABORT("K-point Mermin OT does not support the selected smearing method")
1957 : END SELECT
1958 1378 : CPASSERT(sigma > EPSILON(sigma))
1959 1378 : CPASSERT(ASSOCIATED(para_env_inter_kp))
1960 1378 : CALL get_kpoint_info(kpoints, nkp=nkpoint)
1961 1378 : kp => kpoints%kp_env(1)%kpoint_env
1962 1378 : CALL get_mo_set(kp%mos(1), nelectron=nelectron, nmo=nmo)
1963 1378 : ne_a = nelectron
1964 1378 : ne_b = 0
1965 1378 : IF (nspin_energy == 2) CALL get_mo_set(kp%mos(2), nelectron=ne_b)
1966 :
1967 6890 : ALLOCATE (trial_eigenvalues(nmo, nkpoint, nspin_energy))
1968 5512 : ALLOCATE (trial_occupation(nmo, nkpoint, nspin_energy))
1969 4134 : ALLOCATE (trial_mu(nspin_energy))
1970 1378 : trial_eigenvalues(:, :, :) = 0.0_dp
1971 1378 : trial_occupation(:, :, :) = 0.0_dp
1972 1378 : mus(:) = 0.0_dp
1973 :
1974 3214 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
1975 1836 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
1976 1836 : ikpoint = kp%nkpoint
1977 1836 : CPASSERT(ikpoint >= kp_range(1) .AND. ikpoint <= kp_range(2))
1978 5240 : DO ispin = 1, nspin_energy
1979 : local_channel = qs_ot_channel_index(MERGE(1, ispin, restricted_roks), &
1980 3952 : ikpoint, nspin_ot) - first_channel + 1
1981 2026 : energy_start = 1
1982 2026 : IF (restricted_roks) energy_start = (ispin - 1)*nmo + 1
1983 : trial_eigenvalues(1:nmo, ikpoint, ispin) = &
1984 17918 : local_ot_env(local_channel)%ener_x(energy_start:energy_start + nmo - 1)
1985 : END DO
1986 : END DO
1987 1378 : CALL para_env_inter_kp%sum(trial_eigenvalues)
1988 :
1989 1378 : IF (nspin_energy == 1) THEN
1990 1188 : nel = REAL(nelectron, KIND=dp)
1991 : CALL Smearkp(trial_occupation(:, :, 1), mus(1), trial_kTS, &
1992 1188 : trial_eigenvalues(:, :, 1), nel, wkp, sigma, 2.0_dp, smear%method)
1993 190 : ELSE IF (restricted_roks .OR. smear%fixed_mag_mom > 0.0_dp) THEN
1994 94 : nel = REAL(ne_a, KIND=dp)
1995 : CALL Smearkp(trial_occupation(:, :, 1), mus(1), kTS, &
1996 94 : trial_eigenvalues(:, :, 1), nel, wkp, sigma, 1.0_dp, smear%method)
1997 94 : trial_kTS = kTS
1998 94 : nel = REAL(ne_b, KIND=dp)
1999 : CALL Smearkp(trial_occupation(:, :, 2), mus(2), kTS, &
2000 94 : trial_eigenvalues(:, :, 2), nel, wkp, sigma, 1.0_dp, smear%method)
2001 94 : trial_kTS = trial_kTS + kTS
2002 : ELSE
2003 96 : nel = REAL(ne_a + ne_b, KIND=dp)
2004 : CALL Smearkp2(trial_occupation, mu, trial_kTS, trial_eigenvalues, nel, wkp, &
2005 96 : sigma, smear%method)
2006 288 : mus(1:2) = mu
2007 : END IF
2008 2946 : trial_mu(:) = mus(1:nspin_energy)
2009 1378 : END SUBROUTINE qs_scf_loop_collect_ot_kp_trial_smearing
2010 :
2011 : ! **************************************************************************************************
2012 : !> \brief construct auxiliary-energy gradients on the global fixed-N Mermin surface
2013 : !> \param kpoints ...
2014 : !> \param local_ot_env ...
2015 : !> \param first_channel ...
2016 : !> \param nspin_ot ...
2017 : !> \param nspin_energy ...
2018 : !> \param restricted_roks ...
2019 : !> \param wkp ...
2020 : !> \param para_env_inter_kp ...
2021 : !> \param smear ...
2022 : !> \param trial_eigenvalues ...
2023 : !> \param trial_occupation ...
2024 : !> \param trial_mu ...
2025 : ! **************************************************************************************************
2026 1378 : SUBROUTINE qs_scf_loop_prepare_ot_kp_energy_gradient( &
2027 : kpoints, local_ot_env, first_channel, nspin_ot, nspin_energy, restricted_roks, &
2028 1378 : wkp, para_env_inter_kp, smear, trial_eigenvalues, trial_occupation, trial_mu)
2029 :
2030 : TYPE(kpoint_type), POINTER :: kpoints
2031 : TYPE(qs_ot_type), DIMENSION(:), POINTER :: local_ot_env
2032 : INTEGER, INTENT(IN) :: first_channel, nspin_ot, nspin_energy
2033 : LOGICAL, INTENT(IN) :: restricted_roks
2034 : REAL(KIND=dp), DIMENSION(:), POINTER :: wkp
2035 : TYPE(mp_para_env_type), POINTER :: para_env_inter_kp
2036 : TYPE(smear_type), INTENT(IN) :: smear
2037 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN) :: trial_eigenvalues, trial_occupation
2038 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: trial_mu
2039 :
2040 : INTEGER :: energy_start, group, ikpoint, imo, &
2041 : ispin, local_channel, local_kpoint, &
2042 : ngroups, nmo
2043 : REAL(KIND=dp) :: fixed_n_mean, maxocc, sigma
2044 1378 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: fixed_n_residual, fixed_n_weight, &
2045 1378 : preconditioner_count, &
2046 1378 : preconditioner_shift, response_weight
2047 : TYPE(kpoint_env_type), POINTER :: kp
2048 :
2049 1378 : IF (.NOT. local_ot_env(1)%settings%do_ener) RETURN
2050 :
2051 1378 : CPASSERT(smear%do_smear)
2052 1378 : CPASSERT(ASSOCIATED(para_env_inter_kp))
2053 2606 : SELECT CASE (smear%method)
2054 : CASE (smear_fermi_dirac)
2055 1228 : sigma = smear%electronic_temperature
2056 : CASE (smear_gaussian, smear_mp, smear_mv)
2057 150 : sigma = smear%smearing_width
2058 : CASE DEFAULT
2059 1378 : CPABORT("K-point Mermin OT does not support the selected smearing method")
2060 : END SELECT
2061 1378 : CPASSERT(sigma > EPSILON(sigma))
2062 :
2063 1378 : ngroups = 1
2064 1378 : IF (restricted_roks .OR. &
2065 94 : (nspin_energy == 2 .AND. smear%fixed_mag_mom > 0.0_dp)) ngroups = 2
2066 1378 : nmo = SIZE(trial_eigenvalues, 1)
2067 : ALLOCATE (fixed_n_residual(ngroups), fixed_n_weight(ngroups), &
2068 : preconditioner_count(ngroups), preconditioner_shift(ngroups), &
2069 9646 : response_weight(nmo))
2070 1378 : fixed_n_residual(:) = 0.0_dp
2071 1378 : fixed_n_weight(:) = 0.0_dp
2072 1378 : preconditioner_count(:) = 0.0_dp
2073 1378 : preconditioner_shift(:) = 0.0_dp
2074 :
2075 3214 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
2076 1836 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2077 1836 : ikpoint = kp%nkpoint
2078 5240 : DO ispin = 1, nspin_energy
2079 2026 : group = MERGE(ispin, 1, ngroups == nspin_energy)
2080 : local_channel = qs_ot_channel_index(MERGE(1, ispin, restricted_roks), &
2081 3952 : ikpoint, nspin_ot) - first_channel + 1
2082 2026 : energy_start = 1
2083 2026 : IF (restricted_roks) energy_start = (ispin - 1)*nmo + 1
2084 2026 : CALL get_mo_set(kp%mos(ispin), maxocc=maxocc, nmo=nmo)
2085 2026 : CPASSERT(maxocc > EPSILON(maxocc))
2086 2026 : IF (.NOT. (energy_start + nmo - 1 <= SIZE(local_ot_env(local_channel)%ener_x))) THEN
2087 0 : CALL cp_abort(__LOCATION__, "OT energy slice exceeds channel storage")
2088 : END IF
2089 : CALL smearing_response_weight( &
2090 : response_weight, trial_occupation(:, ikpoint, ispin), &
2091 : trial_eigenvalues(:, ikpoint, ispin), trial_mu(ispin), sigma, maxocc, nmo, &
2092 2026 : smear%method)
2093 16082 : response_weight(:) = wkp(ikpoint)*response_weight
2094 19944 : DO imo = 1, nmo
2095 : fixed_n_weight(group) = fixed_n_weight(group) + &
2096 14056 : response_weight(imo)
2097 : fixed_n_residual(group) = fixed_n_residual(group) + &
2098 : response_weight(imo)* &
2099 : (local_ot_env(local_channel)%ener_rayleigh(energy_start + imo - 1) - &
2100 16082 : trial_eigenvalues(imo, ikpoint, ispin))
2101 : END DO
2102 : END DO
2103 : END DO
2104 1378 : CALL para_env_inter_kp%sum(fixed_n_weight)
2105 1378 : CALL para_env_inter_kp%sum(fixed_n_residual)
2106 :
2107 1378 : IF (local_ot_env(1)%settings%occupation_preconditioner) THEN
2108 2670 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
2109 1524 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2110 1524 : ikpoint = kp%nkpoint
2111 4384 : DO ispin = 1, nspin_energy
2112 1714 : group = MERGE(ispin, 1, ngroups == nspin_energy)
2113 : local_channel = qs_ot_channel_index(MERGE(1, ispin, restricted_roks), &
2114 3328 : ikpoint, nspin_ot) - first_channel + 1
2115 1714 : CALL get_mo_set(kp%mos(ispin), nmo=nmo)
2116 1714 : energy_start = 1
2117 1714 : IF (restricted_roks) energy_start = (ispin - 1)*nmo + 1
2118 1714 : fixed_n_mean = 0.0_dp
2119 1714 : IF (ABS(fixed_n_weight(group)) > EPSILON(fixed_n_weight(group))) THEN
2120 1670 : fixed_n_mean = fixed_n_residual(group)/fixed_n_weight(group)
2121 : END IF
2122 : local_ot_env(local_channel)%ener_preconditioned_gx( &
2123 : energy_start:energy_start + nmo - 1) = fixed_n_mean - &
2124 : (local_ot_env(local_channel)%ener_rayleigh( &
2125 : energy_start:energy_start + nmo - 1) - &
2126 11306 : trial_eigenvalues(:, ikpoint, ispin))
2127 : preconditioner_shift(group) = preconditioner_shift(group) + &
2128 : SUM(local_ot_env(local_channel)%ener_preconditioned_gx( &
2129 11306 : energy_start:energy_start + nmo - 1))
2130 4952 : preconditioner_count(group) = preconditioner_count(group) + REAL(nmo, KIND=dp)
2131 : END DO
2132 : END DO
2133 1146 : CALL para_env_inter_kp%sum(preconditioner_shift)
2134 1146 : CALL para_env_inter_kp%sum(preconditioner_count)
2135 : END IF
2136 :
2137 3214 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
2138 1836 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2139 1836 : ikpoint = kp%nkpoint
2140 5240 : DO ispin = 1, nspin_energy
2141 2026 : group = MERGE(ispin, 1, ngroups == nspin_energy)
2142 : local_channel = qs_ot_channel_index(MERGE(1, ispin, restricted_roks), &
2143 3952 : ikpoint, nspin_ot) - first_channel + 1
2144 2026 : CALL get_mo_set(kp%mos(ispin), maxocc=maxocc, nmo=nmo)
2145 2026 : energy_start = 1
2146 2026 : IF (restricted_roks) energy_start = (ispin - 1)*nmo + 1
2147 2026 : IF (local_ot_env(local_channel)%settings%occupation_preconditioner .AND. &
2148 : preconditioner_count(group) > 0.0_dp) THEN
2149 : local_ot_env(local_channel)%ener_preconditioned_gx( &
2150 : energy_start:energy_start + nmo - 1) = &
2151 : local_ot_env(local_channel)%ener_preconditioned_gx( &
2152 : energy_start:energy_start + nmo - 1) - &
2153 11306 : preconditioner_shift(group)/preconditioner_count(group)
2154 : END IF
2155 : CALL smearing_response_weight( &
2156 : response_weight, trial_occupation(:, ikpoint, ispin), &
2157 : trial_eigenvalues(:, ikpoint, ispin), trial_mu(ispin), sigma, maxocc, nmo, &
2158 2026 : smear%method)
2159 16082 : response_weight(:) = wkp(ikpoint)*response_weight
2160 : CALL qs_ot_fixed_n_energy_gradient( &
2161 : local_ot_env(local_channel)%ener_rayleigh(energy_start:energy_start + nmo - 1), &
2162 : trial_eigenvalues(:, ikpoint, ispin), &
2163 : response_weight, fixed_n_weight(group), fixed_n_residual(group), &
2164 5888 : local_ot_env(local_channel)%ener_gx(energy_start:energy_start + nmo - 1))
2165 : END DO
2166 : END DO
2167 :
2168 0 : DEALLOCATE (fixed_n_residual, fixed_n_weight, preconditioner_count, preconditioner_shift, &
2169 1378 : response_weight)
2170 :
2171 1378 : END SUBROUTINE qs_scf_loop_prepare_ot_kp_energy_gradient
2172 :
2173 : ! **************************************************************************************************
2174 : !> \brief build a coupled finite-complex rotation/energy preconditioner for K-point Mermin OT
2175 : !> \param qs_env ground-state QS environment defining the current density and XC kernel
2176 : !> \param kpoints K-point environment
2177 : !> \param local_ot_env local spin/K-point OT channels
2178 : !> \param first_channel global index of the first local channel
2179 : !> \param nspin_ot number of spin channels
2180 : !> \param restricted_roks whether two physical spin densities share each orbital channel
2181 : !> \param wkp irreducible K-point weights
2182 : !> \param para_env_inter_kp communicator between distributed K-point groups
2183 : !> \param sab_nl real-space neighbor lists used by the K-point density transform
2184 : !> \param fmwork full-matrix workspaces on the global communicator
2185 : !> \param rho_ao_kp template AO density matrices for the real-space images
2186 : !> \param smear smearing settings
2187 : !> \param trial_eigenvalues current auxiliary band energies
2188 : !> \param trial_occupation current fixed-N occupations
2189 : !> \param trial_mu chemical potential for each spin channel
2190 : ! **************************************************************************************************
2191 624 : SUBROUTINE qs_scf_loop_prepare_ot_kp_rotation_response( &
2192 : qs_env, kpoints, local_ot_env, first_channel, nspin_ot, restricted_roks, &
2193 : wkp, para_env_inter_kp, sab_nl, fmwork, rho_ao_kp, smear, &
2194 624 : trial_eigenvalues, trial_occupation, trial_mu)
2195 : TYPE(qs_environment_type), POINTER :: qs_env
2196 : TYPE(kpoint_type), POINTER :: kpoints
2197 : TYPE(qs_ot_type), DIMENSION(:), POINTER :: local_ot_env
2198 : INTEGER, INTENT(IN) :: first_channel, nspin_ot
2199 : LOGICAL, INTENT(IN) :: restricted_roks
2200 : REAL(KIND=dp), DIMENSION(:), POINTER :: wkp
2201 : TYPE(mp_para_env_type), POINTER :: para_env_inter_kp
2202 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
2203 : POINTER :: sab_nl
2204 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: fmwork
2205 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp
2206 : TYPE(smear_type), INTENT(IN) :: smear
2207 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN) :: trial_eigenvalues, trial_occupation
2208 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: trial_mu
2209 :
2210 : INTEGER, PARAMETER :: finite_response_max_rotation = 800
2211 : REAL(KIND=dp), PARAMETER :: rotation_trust_rms = 0.25_dp, rotation_trust_spectral = 0.25_dp
2212 :
2213 624 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: chc, generator
2214 624 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: channel_generator, density_modes
2215 : COMPLEX(KIND=dp), ALLOCATABLE, &
2216 624 : DIMENSION(:, :, :, :) :: channel_density_modes
2217 : INTEGER :: energy_spin, energy_start, energy_stop, failure, gradient_secant_failure, group, &
2218 : i, ikpoint, ispin, j, local_channel, local_kpoint, nenergy, ngroups, nlocal_channels, &
2219 : nmo, nrotation, nrotation_groups, nspin_energy, physical_spin, r, rotation_group
2220 624 : INTEGER, ALLOCATABLE, DIMENSION(:, :) :: channel_response_group
2221 : LOGICAL :: accepted_cross_valid, accepted_curvature_valid, exact_hxc_valid, &
2222 : hxc_channel_valid, hxc_valid, projected_update_valid, shadow_pending, solve_valid
2223 : REAL(KIND=dp) :: accepted_cross, accepted_curvature, denominator, hxc_density_norm_sq, &
2224 : hxc_density_norm_sq_channel, hxc_response_work, hxc_response_work_channel, maxocc, &
2225 : response_cross, response_curvature_total, response_scale, shadow_curvature_total, sigma, &
2226 : tmp, unscaled_rotation_norm
2227 624 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: curvature_sum, energy_count, energy_mean, &
2228 624 : energy_metric_step, energy_shift, energy_weighted_sum, rayleigh_step, response_weight, &
2229 624 : rotation_count, rotation_norm, rotation_scale, schur_rhs, shadow_energy_mean, &
2230 624 : shadow_energy_metric_step, shadow_energy_weighted_sum, shadow_rayleigh_step, &
2231 624 : spin_rotation_gradient, vy
2232 624 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: channel_response_weight, &
2233 624 : channel_rotation_gradient, chc_im, chc_re, coupling, dense_im, dense_re, fixed_n_matrix, &
2234 624 : fixed_n_rhs, fixed_n_solution, generator_im, generator_re, previous_rotation_step, &
2235 624 : rayleigh_response, rhs, rotation_gradient, rotation_hessian, rotation_step, rotation_y, &
2236 624 : schur_block, solution, spin_rayleigh_response, spin_rotation_hessian, vz
2237 624 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: channel_rayleigh_response, &
2238 624 : channel_rotation_hessian, rotation_z
2239 : REAL(KIND=dp), DIMENSION(2) :: hxc_density_overlap, hxc_density_overlap_channel, &
2240 : hxc_response_overlap, hxc_response_overlap_channel, projected_coefficients, &
2241 : projected_gradient
2242 : REAL(KIND=dp), DIMENSION(2, 2) :: exact_hxc_correction, hxc_correction, &
2243 : projected_hessian
2244 : TYPE(cp_fm_type) :: mo_coeff, mo_coeff_im
2245 : TYPE(kpoint_env_type), POINTER :: kp
2246 :
2247 624 : nlocal_channels = SIZE(local_ot_env)
2248 1554 : DO local_channel = 1, nlocal_channels
2249 930 : local_ot_env(local_channel)%rotation_response_valid = .FALSE.
2250 930 : IF (ASSOCIATED(local_ot_env(local_channel)%rot_mat_response_gx)) THEN
2251 692 : CALL dbcsr_set(local_ot_env(local_channel)%rot_mat_response_gx, 0.0_dp)
2252 : END IF
2253 930 : IF (ASSOCIATED(local_ot_env(local_channel)%rot_mat_response_gx_im)) THEN
2254 692 : CALL dbcsr_set(local_ot_env(local_channel)%rot_mat_response_gx_im, 0.0_dp)
2255 : END IF
2256 930 : IF (ASSOCIATED(local_ot_env(local_channel)%ener_response_gx)) THEN
2257 5000 : local_ot_env(local_channel)%ener_response_gx(:) = 0.0_dp
2258 : END IF
2259 930 : IF (ASSOCIATED(local_ot_env(local_channel)%matrix_response_gx)) THEN
2260 500 : CALL dbcsr_set(local_ot_env(local_channel)%matrix_response_gx, 0.0_dp)
2261 : END IF
2262 1554 : IF (ASSOCIATED(local_ot_env(local_channel)%matrix_response_gx_im)) THEN
2263 500 : CALL dbcsr_set(local_ot_env(local_channel)%matrix_response_gx_im, 0.0_dp)
2264 : END IF
2265 : END DO
2266 624 : local_ot_env(1)%response_model_curvature = 0.0_dp
2267 624 : local_ot_env(1)%response_shadow_curvature = 0.0_dp
2268 624 : local_ot_env(1)%response_hxc_direction_valid = .FALSE.
2269 : IF (.NOT. local_ot_env(1)%settings%occupation_preconditioner .OR. &
2270 624 : .NOT. local_ot_env(1)%settings%do_rotation .OR. &
2271 : .NOT. local_ot_env(1)%settings%do_ener) RETURN
2272 : ! The dense candidate is accepted through a physical line search. DIIS and Broyden use the
2273 : ! cheaper fixed-N response in their history residuals, but have no comparable accepted-step
2274 : ! model and therefore must not pay for an unused finite-response construction.
2275 466 : IF (local_ot_env(1)%settings%ot_method /= "CG" .AND. &
2276 : local_ot_env(1)%settings%ot_method /= "LBFG") RETURN
2277 : ! ROKS has one orbital generator but two physical spin-density and fixed-N energy blocks.
2278 : ! Keep those blocks separate until their response metrics have been accumulated.
2279 356 : IF (.NOT. ot_mermin_response_preparation_needed( &
2280 : local_ot_env(1)%delta, local_ot_env(1)%response_candidate_directions, &
2281 : local_ot_env(1)%response_shadow_good_samples, &
2282 : local_ot_env(1)%response_candidate_good_samples, &
2283 : local_ot_env(1)%response_candidate_cooldown, &
2284 : local_ot_env(1)%response_shadow_pending)) RETURN
2285 214 : CPASSERT(smear%do_smear)
2286 214 : CPASSERT(ASSOCIATED(para_env_inter_kp))
2287 392 : SELECT CASE (smear%method)
2288 : CASE (smear_fermi_dirac)
2289 178 : sigma = smear%electronic_temperature
2290 : CASE (smear_gaussian, smear_mp, smear_mv)
2291 36 : sigma = smear%smearing_width
2292 : CASE DEFAULT
2293 214 : RETURN
2294 : END SELECT
2295 214 : CPASSERT(sigma > EPSILON(sigma))
2296 :
2297 214 : nmo = SIZE(trial_eigenvalues, 1)
2298 214 : nspin_energy = SIZE(trial_eigenvalues, 3)
2299 214 : nenergy = SIZE(local_ot_env(1)%ener_x)
2300 214 : CPASSERT(SIZE(trial_occupation, 1) == nmo)
2301 214 : CPASSERT(SIZE(trial_occupation, 3) == nspin_energy)
2302 214 : CPASSERT(nenergy == nmo*nspin_energy/nspin_ot)
2303 214 : nrotation = nmo*(nmo - 1)
2304 214 : IF (nrotation <= 0 .OR. nrotation > finite_response_max_rotation) RETURN
2305 532 : DO local_channel = 1, nlocal_channels
2306 318 : CPASSERT(local_ot_env(local_channel)%has_complex_kpoint_state)
2307 318 : CPASSERT(SIZE(local_ot_env(local_channel)%ener_x) == nenergy)
2308 318 : CPASSERT(ASSOCIATED(local_ot_env(local_channel)%rot_mat_response_gx))
2309 318 : CPASSERT(ASSOCIATED(local_ot_env(local_channel)%rot_mat_response_gx_im))
2310 532 : CPASSERT(ASSOCIATED(local_ot_env(local_channel)%ener_response_gx))
2311 : END DO
2312 :
2313 214 : ngroups = 1
2314 214 : IF (restricted_roks) THEN
2315 : ngroups = nspin_energy
2316 200 : ELSE IF (nspin_ot == 2 .AND. smear%fixed_mag_mom > 0.0_dp) THEN
2317 14 : ngroups = 2
2318 : END IF
2319 214 : nrotation_groups = ngroups
2320 214 : IF (restricted_roks) nrotation_groups = 1
2321 214 : shadow_pending = local_ot_env(1)%response_shadow_pending
2322 : ALLOCATE (coupling(nrotation, ngroups), curvature_sum(ngroups), energy_count(ngroups), &
2323 : energy_mean(ngroups), energy_metric_step(nenergy), energy_shift(ngroups), &
2324 : energy_weighted_sum(ngroups), rayleigh_step(nenergy), response_weight(nmo), &
2325 : rotation_count(nrotation_groups), rotation_norm(nrotation_groups), &
2326 : rotation_scale(nrotation_groups), schur_rhs(nrotation), &
2327 : shadow_energy_mean(ngroups), shadow_energy_metric_step(nenergy), &
2328 : shadow_energy_weighted_sum(ngroups), shadow_rayleigh_step(nenergy), &
2329 : vy(ngroups), vz(ngroups, ngroups), rayleigh_response(nenergy, nrotation), &
2330 : rhs(nrotation, ngroups + 1), rotation_gradient(nrotation, 1), &
2331 : rotation_hessian(nrotation, nrotation), &
2332 : spin_rotation_gradient(nrotation), &
2333 : spin_rayleigh_response(nmo, nrotation), &
2334 : spin_rotation_hessian(nrotation, nrotation), &
2335 : previous_rotation_step(nrotation, nlocal_channels), &
2336 : rotation_step(nrotation, nlocal_channels), &
2337 : rotation_y(nrotation, nlocal_channels), rotation_z(nrotation, nlocal_channels, ngroups), &
2338 : schur_block(nrotation, nrotation), solution(nrotation, ngroups + 1), &
2339 : fixed_n_matrix(ngroups, ngroups), fixed_n_rhs(ngroups, 1), &
2340 : fixed_n_solution(ngroups, 1), &
2341 : channel_rayleigh_response(nenergy, nrotation, nlocal_channels), &
2342 : channel_rotation_hessian(nrotation, nrotation, nlocal_channels), &
2343 : channel_rotation_gradient(nrotation, nlocal_channels), &
2344 : channel_response_weight(nenergy, nlocal_channels), &
2345 : channel_response_group(nenergy, nlocal_channels), &
2346 18832 : channel_generator(nmo, nmo, nlocal_channels), density_modes(nmo, nmo, 2))
2347 1070 : ALLOCATE (channel_density_modes(nmo, nmo, 2, nlocal_channels))
2348 214 : curvature_sum(:) = 0.0_dp
2349 214 : vy(:) = 0.0_dp
2350 214 : vz(:, :) = 0.0_dp
2351 214 : rotation_y(:, :) = 0.0_dp
2352 214 : rotation_z(:, :, :) = 0.0_dp
2353 214 : previous_rotation_step(:, :) = 0.0_dp
2354 214 : channel_rayleigh_response(:, :, :) = 0.0_dp
2355 214 : channel_rotation_hessian(:, :, :) = 0.0_dp
2356 214 : channel_rotation_gradient(:, :) = 0.0_dp
2357 214 : channel_response_weight(:, :) = 0.0_dp
2358 214 : channel_response_group(:, :) = 0
2359 214 : channel_generator(:, :, :) = CMPLX(0.0_dp, 0.0_dp, KIND=dp)
2360 214 : channel_density_modes(:, :, :, :) = CMPLX(0.0_dp, 0.0_dp, KIND=dp)
2361 214 : failure = 0
2362 214 : response_cross = 0.0_dp
2363 :
2364 512 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
2365 298 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2366 298 : ikpoint = kp%nkpoint
2367 830 : DO ispin = 1, nspin_ot
2368 318 : group = MERGE(ispin, 1, ngroups == nspin_ot)
2369 318 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
2370 : CALL qs_scf_loop_ot_matrix_to_dense( &
2371 318 : local_ot_env(local_channel)%rot_mat_x, local_ot_env(local_channel), generator_re)
2372 : CALL qs_scf_loop_ot_matrix_to_dense( &
2373 318 : local_ot_env(local_channel)%rot_mat_x_im, local_ot_env(local_channel), generator_im)
2374 1272 : ALLOCATE (generator(nmo, nmo))
2375 13266 : generator(:, :) = CMPLX(generator_re, generator_im, KIND=dp)
2376 13266 : channel_generator(:, :, local_channel) = generator
2377 9762 : rotation_gradient(:, 1) = 0.0_dp
2378 318 : rotation_hessian(:, :) = 0.0_dp
2379 318 : rayleigh_response(:, :) = 0.0_dp
2380 :
2381 318 : IF (restricted_roks) THEN
2382 14 : IF (.NOT. (ASSOCIATED(kp%ot_hmat) .AND. SIZE(kp%ot_hmat, 2) >= nspin_energy)) THEN
2383 0 : CALL cp_abort(__LOCATION__, "Missing OT Hamiltonian spin cache")
2384 : END IF
2385 14 : CALL cp_fm_create(mo_coeff, kp%mos(1)%cmo_coeff%matrix_struct)
2386 14 : CALL cp_fm_create(mo_coeff_im, kp%mos(1)%cmo_coeff%matrix_struct)
2387 14 : CALL cp_cfm_to_fm(kp%mos(1)%cmo_coeff, mo_coeff, mo_coeff_im)
2388 42 : DO energy_spin = 1, nspin_energy
2389 28 : energy_start = (energy_spin - 1)*nmo + 1
2390 28 : energy_stop = energy_start + nmo - 1
2391 28 : group = energy_spin
2392 28 : CALL get_mo_set(kp%mos(energy_spin), maxocc=maxocc)
2393 28 : CPASSERT(maxocc > EPSILON(maxocc))
2394 : CALL smearing_response_weight( &
2395 : response_weight, trial_occupation(:, ikpoint, energy_spin), &
2396 : trial_eigenvalues(:, ikpoint, energy_spin), trial_mu(energy_spin), &
2397 28 : sigma, maxocc, nmo, smear%method)
2398 308 : response_weight(:) = wkp(ikpoint)*response_weight
2399 308 : curvature_sum(group) = curvature_sum(group) + SUM(response_weight)
2400 308 : channel_response_weight(energy_start:energy_stop, local_channel) = response_weight
2401 308 : channel_response_group(energy_start:energy_stop, local_channel) = group
2402 :
2403 84 : ALLOCATE (chc(nmo, nmo))
2404 : CALL qs_scf_kp_project_hamiltonian( &
2405 : mo_coeff, mo_coeff_im, kp%ot_hmat(1, energy_spin), &
2406 28 : kp%ot_hmat(2, energy_spin), chc)
2407 : CALL qs_ot_finite_rotation_response( &
2408 : chc, generator, trial_occupation(:, ikpoint, energy_spin), wkp(ikpoint), &
2409 28 : spin_rotation_gradient, spin_rotation_hessian, spin_rayleigh_response)
2410 2548 : rotation_gradient(:, 1) = rotation_gradient(:, 1) + spin_rotation_gradient
2411 229348 : rotation_hessian(:, :) = rotation_hessian + spin_rotation_hessian
2412 27748 : rayleigh_response(energy_start:energy_stop, :) = spin_rayleigh_response
2413 70 : DEALLOCATE (chc)
2414 : END DO
2415 14 : CALL cp_fm_release(mo_coeff)
2416 14 : CALL cp_fm_release(mo_coeff_im)
2417 : ELSE
2418 304 : CALL get_mo_set(kp%mos(ispin), maxocc=maxocc)
2419 304 : CPASSERT(maxocc > EPSILON(maxocc))
2420 : CALL smearing_response_weight( &
2421 : response_weight, trial_occupation(:, ikpoint, ispin), &
2422 : trial_eigenvalues(:, ikpoint, ispin), trial_mu(ispin), sigma, maxocc, nmo, &
2423 304 : smear%method)
2424 1916 : response_weight(:) = wkp(ikpoint)*response_weight
2425 1916 : curvature_sum(group) = curvature_sum(group) + SUM(response_weight)
2426 1916 : channel_response_weight(:, local_channel) = response_weight
2427 1916 : channel_response_group(:, local_channel) = group
2428 : CALL qs_scf_loop_ot_matrix_to_dense( &
2429 304 : local_ot_env(local_channel)%rot_mat_chc, local_ot_env(local_channel), chc_re)
2430 : CALL qs_scf_loop_ot_matrix_to_dense( &
2431 304 : local_ot_env(local_channel)%rot_mat_chc_im, local_ot_env(local_channel), chc_im)
2432 912 : ALLOCATE (chc(nmo, nmo))
2433 11712 : chc(:, :) = CMPLX(chc_re, chc_im, KIND=dp)
2434 : CALL qs_ot_finite_rotation_response( &
2435 : chc, generator, trial_occupation(:, ikpoint, ispin), wkp(ikpoint), &
2436 304 : rotation_gradient(:, 1), rotation_hessian, rayleigh_response)
2437 608 : DEALLOCATE (chc, chc_im, chc_re)
2438 : END IF
2439 9762 : channel_rotation_gradient(:, local_channel) = rotation_gradient(:, 1)
2440 502794 : channel_rotation_hessian(:, :, local_channel) = rotation_hessian
2441 : CALL qs_ot_fixed_n_multigroup_schur_block( &
2442 : rotation_hessian, rayleigh_response, channel_response_weight(:, local_channel), &
2443 : channel_response_group(:, local_channel), rotation_gradient(:, 1), &
2444 318 : local_ot_env(local_channel)%ener_gx, schur_block, coupling, schur_rhs)
2445 9762 : rhs(:, 1) = schur_rhs
2446 678 : DO group = 1, ngroups
2447 11718 : rhs(:, group + 1) = coupling(:, group)
2448 : END DO
2449 : CALL qs_ot_symmetric_abs_solve( &
2450 318 : schur_block, rhs, solution, solve_valid, relative_floor=1.0E-4_dp)
2451 318 : IF (solve_valid) THEN
2452 9618 : rotation_y(:, local_channel) = solution(:, 1)
2453 630 : DO group = 1, ngroups
2454 11550 : rotation_z(:, local_channel, group) = solution(:, group + 1)
2455 : END DO
2456 91662 : channel_rayleigh_response(:, :, local_channel) = rayleigh_response
2457 630 : DO group = 1, ngroups
2458 11256 : vy(group) = vy(group) + DOT_PRODUCT(coupling(:, group), solution(:, 1))
2459 1050 : DO j = 1, ngroups
2460 : vz(group, j) = vz(group, j) + &
2461 14868 : DOT_PRODUCT(coupling(:, group), solution(:, j + 1))
2462 : END DO
2463 : END DO
2464 : ELSE
2465 24 : failure = 1
2466 : END IF
2467 318 : IF (shadow_pending .AND. local_ot_env(local_channel)%use_dx) THEN
2468 : CALL qs_scf_loop_ot_matrix_to_dense( &
2469 176 : local_ot_env(local_channel)%rot_mat_dx, local_ot_env(local_channel), dense_re)
2470 : CALL qs_scf_loop_ot_matrix_to_dense( &
2471 176 : local_ot_env(local_channel)%rot_mat_dx_im, local_ot_env(local_channel), dense_im)
2472 176 : r = 0
2473 1116 : DO i = 1, nmo - 1
2474 4452 : DO j = i + 1, nmo
2475 3336 : r = r + 1
2476 3336 : previous_rotation_step(r, local_channel) = dense_re(i, j)
2477 3336 : r = r + 1
2478 4276 : previous_rotation_step(r, local_channel) = dense_im(i, j)
2479 : END DO
2480 : END DO
2481 176 : CPASSERT(r == nrotation)
2482 176 : DEALLOCATE (dense_im, dense_re)
2483 : END IF
2484 616 : DEALLOCATE (generator, generator_im, generator_re)
2485 : END DO
2486 : END DO
2487 :
2488 214 : CALL para_env_inter_kp%sum(curvature_sum)
2489 214 : CALL para_env_inter_kp%sum(vy)
2490 214 : CALL para_env_inter_kp%sum(vz)
2491 214 : CALL para_env_inter_kp%sum(failure)
2492 214 : IF (failure /= 0) THEN
2493 0 : DEALLOCATE (coupling, curvature_sum, energy_count, energy_mean, energy_metric_step, &
2494 0 : energy_shift, energy_weighted_sum, rayleigh_step, response_weight, &
2495 0 : shadow_energy_mean, &
2496 0 : shadow_energy_metric_step, shadow_energy_weighted_sum, shadow_rayleigh_step, &
2497 0 : rotation_count, rotation_norm, rotation_scale, schur_rhs, vy, vz, &
2498 0 : rayleigh_response, rhs, rotation_gradient, rotation_hessian, &
2499 0 : spin_rotation_gradient, spin_rotation_hessian, spin_rayleigh_response, &
2500 0 : previous_rotation_step, rotation_step, &
2501 0 : rotation_y, rotation_z, schur_block, solution, channel_rayleigh_response, &
2502 0 : channel_rotation_hessian, channel_rotation_gradient, channel_response_weight, &
2503 0 : channel_density_modes, channel_response_group, channel_generator, &
2504 0 : fixed_n_matrix, fixed_n_rhs, &
2505 0 : fixed_n_solution, &
2506 30 : density_modes)
2507 30 : RETURN
2508 : END IF
2509 :
2510 664 : fixed_n_matrix(:, :) = 0.5_dp*(vz + TRANSPOSE(vz))
2511 396 : DO group = 1, ngroups
2512 396 : fixed_n_matrix(group, group) = fixed_n_matrix(group, group) + curvature_sum(group)
2513 : END DO
2514 396 : fixed_n_rhs(:, 1) = vy
2515 396 : fixed_n_solution(:, 1) = 0.0_dp
2516 184 : solve_valid = .FALSE.
2517 184 : IF (ngroups == 1) THEN
2518 156 : denominator = fixed_n_matrix(1, 1)
2519 156 : solve_valid = ABS(denominator) > EPSILON(denominator)
2520 156 : IF (solve_valid) fixed_n_solution(1, 1) = fixed_n_rhs(1, 1)/denominator
2521 28 : ELSE IF (ngroups == 2) THEN
2522 : denominator = fixed_n_matrix(1, 1)*fixed_n_matrix(2, 2) - &
2523 28 : fixed_n_matrix(1, 2)*fixed_n_matrix(2, 1)
2524 : solve_valid = ABS(denominator) > EPSILON(denominator)* &
2525 196 : MAX(1.0_dp, MAXVAL(ABS(fixed_n_matrix))**2)
2526 28 : IF (solve_valid) THEN
2527 : fixed_n_solution(1, 1) = (fixed_n_matrix(2, 2)*fixed_n_rhs(1, 1) - &
2528 14 : fixed_n_matrix(1, 2)*fixed_n_rhs(2, 1))/denominator
2529 : fixed_n_solution(2, 1) = (fixed_n_matrix(1, 1)*fixed_n_rhs(2, 1) - &
2530 14 : fixed_n_matrix(2, 1)*fixed_n_rhs(1, 1))/denominator
2531 : END IF
2532 : END IF
2533 580 : IF (.NOT. solve_valid .OR. .NOT. ALL(fixed_n_solution == fixed_n_solution)) THEN
2534 0 : DEALLOCATE (coupling, curvature_sum, energy_count, energy_mean, energy_metric_step, &
2535 0 : energy_shift, energy_weighted_sum, rayleigh_step, response_weight, &
2536 0 : shadow_energy_mean, shadow_energy_metric_step, shadow_energy_weighted_sum, &
2537 0 : shadow_rayleigh_step, rotation_count, rotation_norm, rotation_scale, &
2538 0 : schur_rhs, vy, vz, rayleigh_response, rhs, rotation_gradient, rotation_hessian, &
2539 0 : spin_rotation_gradient, spin_rotation_hessian, spin_rayleigh_response, &
2540 0 : previous_rotation_step, rotation_step, rotation_y, rotation_z, schur_block, &
2541 0 : solution, channel_rayleigh_response, channel_rotation_hessian, &
2542 0 : channel_rotation_gradient, channel_response_weight, channel_response_group, &
2543 14 : channel_generator, fixed_n_matrix, fixed_n_rhs, fixed_n_solution, density_modes)
2544 14 : RETURN
2545 : END IF
2546 :
2547 170 : rotation_norm(:) = 0.0_dp
2548 170 : rotation_count(:) = 0.0_dp
2549 412 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
2550 242 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2551 242 : ikpoint = kp%nkpoint
2552 654 : DO ispin = 1, nspin_ot
2553 242 : rotation_group = MERGE(ispin, 1, nrotation_groups == nspin_ot)
2554 242 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
2555 9110 : rotation_step(:, local_channel) = rotation_y(:, local_channel)
2556 498 : DO group = 1, ngroups
2557 : rotation_step(:, local_channel) = rotation_step(:, local_channel) - &
2558 : rotation_z(:, local_channel, group)* &
2559 10626 : fixed_n_solution(group, 1)
2560 : END DO
2561 : rotation_norm(rotation_group) = rotation_norm(rotation_group) + &
2562 : DOT_PRODUCT(rotation_step(:, local_channel), &
2563 9110 : rotation_step(:, local_channel))
2564 484 : rotation_count(rotation_group) = rotation_count(rotation_group) + REAL(nrotation, KIND=dp)
2565 : END DO
2566 : END DO
2567 170 : CALL para_env_inter_kp%sum(rotation_norm)
2568 170 : CALL para_env_inter_kp%sum(rotation_count)
2569 340 : rotation_scale(:) = 1.0_dp
2570 340 : DO group = 1, nrotation_groups
2571 340 : IF (rotation_norm(group) > EPSILON(rotation_norm(group))) THEN
2572 : rotation_scale(group) = MIN( &
2573 170 : 1.0_dp, rotation_trust_rms*SQRT(rotation_count(group)/rotation_norm(group)))
2574 : END IF
2575 : END DO
2576 :
2577 170 : energy_shift(:) = 0.0_dp
2578 170 : energy_count(:) = 0.0_dp
2579 412 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
2580 242 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2581 242 : ikpoint = kp%nkpoint
2582 654 : DO ispin = 1, nspin_ot
2583 242 : rotation_group = MERGE(ispin, 1, nrotation_groups == nspin_ot)
2584 242 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
2585 : rotation_step(:, local_channel) = &
2586 9110 : rotation_scale(rotation_group)*rotation_step(:, local_channel)
2587 : local_ot_env(local_channel)%ener_response_gx(:) = &
2588 : local_ot_env(local_channel)%ener_preconditioned_gx + &
2589 : MATMUL(channel_rayleigh_response(:, :, local_channel), &
2590 92758 : rotation_step(:, local_channel))
2591 1890 : DO i = 1, nenergy
2592 1648 : group = channel_response_group(i, local_channel)
2593 : energy_shift(group) = energy_shift(group) + &
2594 1648 : local_ot_env(local_channel)%ener_response_gx(i)
2595 1890 : energy_count(group) = energy_count(group) + 1.0_dp
2596 : END DO
2597 :
2598 1452 : ALLOCATE (dense_re(nmo, nmo), dense_im(nmo, nmo))
2599 242 : dense_re(:, :) = 0.0_dp
2600 242 : dense_im(:, :) = 0.0_dp
2601 242 : r = 0
2602 1508 : DO i = 1, nmo - 1
2603 5942 : DO j = i + 1, nmo
2604 4434 : r = r + 1
2605 4434 : dense_re(i, j) = rotation_step(r, local_channel)
2606 4434 : dense_re(j, i) = -rotation_step(r, local_channel)
2607 4434 : r = r + 1
2608 4434 : dense_im(i, j) = rotation_step(r, local_channel)
2609 5700 : dense_im(j, i) = rotation_step(r, local_channel)
2610 : END DO
2611 : END DO
2612 242 : CPASSERT(r == nrotation)
2613 : CALL qs_scf_loop_ot_dense_to_matrix( &
2614 : dense_re, local_ot_env(local_channel), &
2615 242 : local_ot_env(local_channel)%rot_mat_response_gx)
2616 : CALL qs_scf_loop_ot_dense_to_matrix( &
2617 : dense_im, local_ot_env(local_channel), &
2618 242 : local_ot_env(local_channel)%rot_mat_response_gx_im)
2619 242 : local_ot_env(local_channel)%rotation_response_valid = .TRUE.
2620 484 : DEALLOCATE (dense_im, dense_re)
2621 : END DO
2622 : END DO
2623 170 : CALL para_env_inter_kp%sum(energy_shift)
2624 170 : CALL para_env_inter_kp%sum(energy_count)
2625 412 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
2626 242 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2627 242 : ikpoint = kp%nkpoint
2628 654 : DO ispin = 1, nspin_ot
2629 242 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
2630 2132 : DO i = 1, nenergy
2631 1648 : group = channel_response_group(i, local_channel)
2632 1890 : IF (energy_count(group) > 0.0_dp) THEN
2633 : local_ot_env(local_channel)%ener_response_gx(i) = &
2634 : local_ot_env(local_channel)%ener_response_gx(i) - &
2635 1648 : energy_shift(group)/energy_count(group)
2636 : END IF
2637 : END DO
2638 : END DO
2639 : END DO
2640 :
2641 : ! The accepted gradient difference supplies the missing total cross curvature between the
2642 : ! finite rotation/energy candidate and the preceding accepted product direction. Keep the
2643 : ! dedicated endpoint history separate from CG's preconditioned-gradient history.
2644 170 : accepted_cross = 0.0_dp
2645 170 : accepted_cross_valid = .FALSE.
2646 170 : gradient_secant_failure = 0
2647 170 : IF (shadow_pending .AND. ABS(local_ot_env(1)%ds_min) > SQRT(EPSILON(1.0_dp))) THEN
2648 300 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
2649 176 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2650 176 : ikpoint = kp%nkpoint
2651 476 : DO ispin = 1, nspin_ot
2652 176 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
2653 : IF (local_ot_env(local_channel)%mermin_gradient_ref_valid .AND. &
2654 : ASSOCIATED(local_ot_env(local_channel)%rot_mat_mermin_g0) .AND. &
2655 176 : ASSOCIATED(local_ot_env(local_channel)%rot_mat_mermin_g0_im) .AND. &
2656 176 : ALLOCATED(local_ot_env(local_channel)%ener_mermin_g0)) THEN
2657 : CALL dbcsr_dot(local_ot_env(local_channel)%rot_mat_gx, &
2658 176 : local_ot_env(local_channel)%rot_mat_response_gx, tmp)
2659 176 : accepted_cross = accepted_cross + 0.5_dp*tmp
2660 : CALL dbcsr_dot(local_ot_env(local_channel)%rot_mat_mermin_g0, &
2661 176 : local_ot_env(local_channel)%rot_mat_response_gx, tmp)
2662 176 : accepted_cross = accepted_cross - 0.5_dp*tmp
2663 : CALL dbcsr_dot(local_ot_env(local_channel)%rot_mat_gx_im, &
2664 176 : local_ot_env(local_channel)%rot_mat_response_gx_im, tmp)
2665 176 : accepted_cross = accepted_cross + 0.5_dp*tmp
2666 : CALL dbcsr_dot(local_ot_env(local_channel)%rot_mat_mermin_g0_im, &
2667 176 : local_ot_env(local_channel)%rot_mat_response_gx_im, tmp)
2668 176 : accepted_cross = accepted_cross - 0.5_dp*tmp
2669 : accepted_cross = accepted_cross + &
2670 : DOT_PRODUCT( &
2671 : local_ot_env(local_channel)%ener_gx - &
2672 : local_ot_env(local_channel)%ener_mermin_g0, &
2673 1392 : local_ot_env(local_channel)%ener_response_gx)
2674 : ELSE
2675 0 : gradient_secant_failure = 1
2676 : END IF
2677 : END DO
2678 : END DO
2679 124 : CALL para_env_inter_kp%sum(accepted_cross)
2680 124 : CALL para_env_inter_kp%sum(gradient_secant_failure)
2681 124 : IF (gradient_secant_failure == 0) THEN
2682 124 : accepted_cross = accepted_cross/local_ot_env(1)%ds_min
2683 124 : accepted_cross_valid = ieee_is_finite(accepted_cross)
2684 : END IF
2685 : END IF
2686 : ! Evaluate the signed finite response in the same fixed-N tangent used to build the Schur
2687 : ! step. This is a prediction only; the minimizer calibrates it against accepted Mermin drops
2688 : ! before the candidate can be reused.
2689 170 : energy_weighted_sum(:) = 0.0_dp
2690 412 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
2691 242 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2692 242 : ikpoint = kp%nkpoint
2693 654 : DO ispin = 1, nspin_ot
2694 242 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
2695 2132 : DO i = 1, nenergy
2696 1648 : group = channel_response_group(i, local_channel)
2697 : energy_weighted_sum(group) = energy_weighted_sum(group) + &
2698 : channel_response_weight(i, local_channel)* &
2699 1890 : local_ot_env(local_channel)%ener_response_gx(i)
2700 : END DO
2701 : END DO
2702 : END DO
2703 170 : CALL para_env_inter_kp%sum(energy_weighted_sum)
2704 170 : energy_mean(:) = 0.0_dp
2705 354 : DO group = 1, ngroups
2706 354 : IF (ABS(curvature_sum(group)) > EPSILON(curvature_sum(group))) THEN
2707 184 : energy_mean(group) = energy_weighted_sum(group)/curvature_sum(group)
2708 : END IF
2709 : END DO
2710 :
2711 170 : response_curvature_total = 0.0_dp
2712 412 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
2713 242 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2714 242 : ikpoint = kp%nkpoint
2715 654 : DO ispin = 1, nspin_ot
2716 242 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
2717 1890 : DO i = 1, nenergy
2718 1648 : group = channel_response_group(i, local_channel)
2719 : energy_metric_step(i) = channel_response_weight(i, local_channel)* &
2720 : (local_ot_env(local_channel)%ener_response_gx(i) - &
2721 1890 : energy_mean(group))
2722 : END DO
2723 : rayleigh_step(:) = MATMUL(channel_rayleigh_response(:, :, local_channel), &
2724 89462 : rotation_step(:, local_channel))
2725 : response_curvature_total = response_curvature_total + &
2726 : DOT_PRODUCT(rotation_step(:, local_channel), &
2727 726 : MATMUL(channel_rotation_hessian(:, :, local_channel), &
2728 : rotation_step(:, local_channel))) - &
2729 : 2.0_dp*DOT_PRODUCT(rayleigh_step, energy_metric_step) + &
2730 509172 : DOT_PRODUCT(local_ot_env(local_channel)%ener_response_gx, energy_metric_step)
2731 : END DO
2732 : END DO
2733 170 : CALL para_env_inter_kp%sum(response_curvature_total)
2734 170 : local_ot_env(1)%response_model_curvature = response_curvature_total
2735 :
2736 170 : IF (shadow_pending) THEN
2737 124 : shadow_energy_weighted_sum(:) = 0.0_dp
2738 300 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
2739 176 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2740 176 : ikpoint = kp%nkpoint
2741 476 : DO ispin = 1, nspin_ot
2742 176 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
2743 1568 : DO i = 1, nenergy
2744 1216 : group = channel_response_group(i, local_channel)
2745 : shadow_energy_weighted_sum(group) = shadow_energy_weighted_sum(group) + &
2746 : channel_response_weight(i, local_channel)* &
2747 1392 : local_ot_env(local_channel)%ener_dx(i)
2748 : END DO
2749 : END DO
2750 : END DO
2751 124 : CALL para_env_inter_kp%sum(shadow_energy_weighted_sum)
2752 124 : shadow_energy_mean(:) = 0.0_dp
2753 258 : DO group = 1, ngroups
2754 258 : IF (ABS(curvature_sum(group)) > EPSILON(curvature_sum(group))) THEN
2755 134 : shadow_energy_mean(group) = shadow_energy_weighted_sum(group)/curvature_sum(group)
2756 : END IF
2757 : END DO
2758 :
2759 124 : shadow_curvature_total = 0.0_dp
2760 124 : projected_gradient(:) = 0.0_dp
2761 300 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
2762 176 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2763 176 : ikpoint = kp%nkpoint
2764 476 : DO ispin = 1, nspin_ot
2765 176 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
2766 1392 : DO i = 1, nenergy
2767 1216 : group = channel_response_group(i, local_channel)
2768 : energy_metric_step(i) = channel_response_weight(i, local_channel)* &
2769 : (local_ot_env(local_channel)%ener_response_gx(i) - &
2770 1216 : energy_mean(group))
2771 : shadow_energy_metric_step(i) = channel_response_weight(i, local_channel)* &
2772 : (local_ot_env(local_channel)%ener_dx(i) - &
2773 1392 : shadow_energy_mean(group))
2774 : END DO
2775 : rayleigh_step(:) = MATMUL(channel_rayleigh_response(:, :, local_channel), &
2776 67256 : rotation_step(:, local_channel))
2777 : shadow_rayleigh_step(:) = MATMUL( &
2778 : channel_rayleigh_response(:, :, local_channel), &
2779 67256 : previous_rotation_step(:, local_channel))
2780 : shadow_curvature_total = shadow_curvature_total + &
2781 : DOT_PRODUCT(previous_rotation_step(:, local_channel), &
2782 528 : MATMUL(channel_rotation_hessian(:, :, local_channel), &
2783 : previous_rotation_step(:, local_channel))) - &
2784 : 2.0_dp*DOT_PRODUCT(shadow_rayleigh_step, &
2785 : shadow_energy_metric_step) + &
2786 : DOT_PRODUCT(local_ot_env(local_channel)%ener_dx, &
2787 387616 : shadow_energy_metric_step)
2788 : response_cross = response_cross + &
2789 : DOT_PRODUCT(rotation_step(:, local_channel), &
2790 528 : MATMUL(channel_rotation_hessian(:, :, local_channel), &
2791 : previous_rotation_step(:, local_channel))) - &
2792 : DOT_PRODUCT(rayleigh_step, shadow_energy_metric_step) - &
2793 : DOT_PRODUCT(shadow_rayleigh_step, energy_metric_step) + &
2794 : 0.5_dp*( &
2795 : DOT_PRODUCT(local_ot_env(local_channel)%ener_response_gx, &
2796 : shadow_energy_metric_step) + &
2797 390048 : DOT_PRODUCT(local_ot_env(local_channel)%ener_dx, energy_metric_step))
2798 : projected_gradient(1) = projected_gradient(1) + &
2799 : DOT_PRODUCT(channel_rotation_gradient(:, local_channel), &
2800 : rotation_step(:, local_channel)) + &
2801 : DOT_PRODUCT(local_ot_env(local_channel)%ener_gx, &
2802 8064 : local_ot_env(local_channel)%ener_response_gx)
2803 : CALL dbcsr_dot(local_ot_env(local_channel)%matrix_gx, &
2804 176 : local_ot_env(local_channel)%matrix_dx, tmp)
2805 176 : projected_gradient(2) = projected_gradient(2) + tmp
2806 : CALL dbcsr_dot(local_ot_env(local_channel)%matrix_gx_im, &
2807 176 : local_ot_env(local_channel)%matrix_dx_im, tmp)
2808 176 : projected_gradient(2) = projected_gradient(2) + tmp
2809 : projected_gradient(2) = projected_gradient(2) + &
2810 : DOT_PRODUCT(channel_rotation_gradient(:, local_channel), &
2811 : previous_rotation_step(:, local_channel)) + &
2812 : DOT_PRODUCT(local_ot_env(local_channel)%ener_gx, &
2813 8416 : local_ot_env(local_channel)%ener_dx)
2814 : END DO
2815 : END DO
2816 124 : CALL para_env_inter_kp%sum(shadow_curvature_total)
2817 124 : CALL para_env_inter_kp%sum(response_cross)
2818 124 : CALL para_env_inter_kp%sum(projected_gradient)
2819 124 : local_ot_env(1)%response_shadow_curvature = shadow_curvature_total
2820 : END IF
2821 :
2822 : ! The frozen-H finite response above omits the self-consistent Hxc density response. Project
2823 : ! the most recent accepted physical density/Hamiltonian secant onto both the candidate and
2824 : ! conventional accepted directions. All spin/K-point overlaps are accumulated before the
2825 : ! minimum-Frobenius secant is formed: this is the direct-sum spin response, including the Hxc
2826 : ! cross-spin coupling, and not a sum of independently fitted spin Hessians. The resulting
2827 : ! sign-aware rank-two response is calibrated against accepted Mermin drops before it can replace
2828 : ! the conventional search direction.
2829 170 : hxc_density_norm_sq = 0.0_dp
2830 170 : hxc_response_work = 0.0_dp
2831 170 : hxc_density_overlap(:) = 0.0_dp
2832 170 : hxc_response_overlap(:) = 0.0_dp
2833 170 : failure = 0
2834 412 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
2835 242 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2836 242 : ikpoint = kp%nkpoint
2837 242 : CPASSERT(ASSOCIATED(kp%ot_smat))
2838 242 : CPASSERT(SIZE(kp%ot_smat) >= 2)
2839 654 : DO ispin = 1, nspin_ot
2840 242 : local_channel = qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
2841 968 : DO energy_spin = 1, MERGE(nspin_energy, 1, restricted_roks)
2842 256 : physical_spin = MERGE(energy_spin, ispin, restricted_roks)
2843 256 : energy_start = MERGE((energy_spin - 1)*nmo + 1, 1, restricted_roks)
2844 256 : energy_stop = energy_start + nmo - 1
2845 256 : group = channel_response_group(energy_start, local_channel)
2846 : energy_metric_step(energy_start:energy_stop) = &
2847 : -channel_response_weight(energy_start:energy_stop, local_channel)* &
2848 : (local_ot_env(local_channel)%ener_response_gx(energy_start:energy_stop) - &
2849 1904 : energy_mean(group))
2850 : CALL qs_ot_density_tangent( &
2851 : channel_generator(:, :, local_channel), &
2852 : trial_occupation(:, ikpoint, physical_spin), wkp(ikpoint), &
2853 : rotation_step(:, local_channel), &
2854 256 : energy_metric_step(energy_start:energy_stop), density_modes(:, :, 1))
2855 256 : IF (.NOT. restricted_roks) THEN
2856 10572 : channel_density_modes(:, :, 1, local_channel) = density_modes(:, :, 1)
2857 : END IF
2858 13680 : density_modes(:, :, 2) = CMPLX(0.0_dp, 0.0_dp, KIND=dp)
2859 256 : IF (shadow_pending) THEN
2860 : energy_metric_step(energy_start:energy_stop) = &
2861 : -channel_response_weight(energy_start:energy_stop, local_channel)* &
2862 : (local_ot_env(local_channel)%ener_dx(energy_start:energy_stop) - &
2863 1402 : shadow_energy_mean(group))
2864 : CALL qs_ot_density_tangent( &
2865 : channel_generator(:, :, local_channel), &
2866 : trial_occupation(:, ikpoint, physical_spin), wkp(ikpoint), &
2867 : previous_rotation_step(:, local_channel), &
2868 186 : energy_metric_step(energy_start:energy_stop), density_modes(:, :, 2))
2869 186 : IF (.NOT. restricted_roks) THEN
2870 7970 : channel_density_modes(:, :, 2, local_channel) = density_modes(:, :, 2)
2871 : END IF
2872 : END IF
2873 : CALL qs_scf_kp_physical_secant_overlaps( &
2874 : local_ot_env(local_channel)%mermin_physical(energy_spin), &
2875 : kp%ot_smat(1), kp%ot_smat(2), density_modes, wkp(ikpoint), &
2876 : hxc_density_norm_sq_channel, hxc_response_work_channel, &
2877 256 : hxc_density_overlap_channel, hxc_response_overlap_channel, hxc_channel_valid)
2878 498 : IF (hxc_channel_valid) THEN
2879 240 : hxc_density_norm_sq = hxc_density_norm_sq + hxc_density_norm_sq_channel
2880 240 : hxc_response_work = hxc_response_work + hxc_response_work_channel
2881 720 : hxc_density_overlap(:) = hxc_density_overlap + hxc_density_overlap_channel
2882 720 : hxc_response_overlap(:) = hxc_response_overlap + hxc_response_overlap_channel
2883 : ELSE
2884 16 : failure = 1
2885 : END IF
2886 : END DO
2887 : END DO
2888 : END DO
2889 170 : exact_hxc_correction(:, :) = 0.0_dp
2890 170 : exact_hxc_valid = .FALSE.
2891 170 : IF (local_ot_env(1)%settings%ot_method == "CG" .AND. .NOT. restricted_roks) THEN
2892 : CALL qs_scf_kp_exact_hxc_projected( &
2893 : qs_env, kpoints, local_ot_env, first_channel, nspin_ot, wkp, para_env_inter_kp, &
2894 : sab_nl, fmwork, rho_ao_kp, channel_density_modes, MERGE(2, 1, shadow_pending), &
2895 144 : exact_hxc_correction, exact_hxc_valid)
2896 : END IF
2897 170 : CALL para_env_inter_kp%sum(failure)
2898 170 : CALL para_env_inter_kp%sum(hxc_density_norm_sq)
2899 170 : CALL para_env_inter_kp%sum(hxc_response_work)
2900 170 : CALL para_env_inter_kp%sum(hxc_density_overlap)
2901 170 : CALL para_env_inter_kp%sum(hxc_response_overlap)
2902 170 : hxc_correction(:, :) = 0.0_dp
2903 170 : hxc_valid = .FALSE.
2904 170 : IF (failure == 0) THEN
2905 154 : IF (shadow_pending .AND. &
2906 : ABS(local_ot_env(1)%ds_min) > SQRT(EPSILON(1.0_dp))) THEN
2907 : CALL qs_ot_density_secant_projected_hessian( &
2908 : hxc_density_norm_sq, hxc_response_work, hxc_density_overlap, &
2909 : hxc_response_overlap, hxc_correction, hxc_valid, &
2910 110 : secant_mode=2, secant_position=local_ot_env(1)%ds_min)
2911 : ELSE
2912 : CALL qs_ot_density_secant_projected_hessian( &
2913 : hxc_density_norm_sq, hxc_response_work, hxc_density_overlap, &
2914 44 : hxc_response_overlap, hxc_correction, hxc_valid)
2915 : END IF
2916 : END IF
2917 170 : IF (exact_hxc_valid) THEN
2918 98 : hxc_correction(:, :) = exact_hxc_correction
2919 98 : hxc_valid = .TRUE.
2920 : END IF
2921 170 : IF (hxc_valid) THEN
2922 : local_ot_env(1)%response_model_curvature = &
2923 154 : local_ot_env(1)%response_model_curvature + hxc_correction(1, 1)
2924 154 : IF (shadow_pending) THEN
2925 : local_ot_env(1)%response_shadow_curvature = &
2926 110 : local_ot_env(1)%response_shadow_curvature + hxc_correction(2, 2)
2927 : END IF
2928 110 : IF (shadow_pending) THEN
2929 : CALL ot_mermin_secant_curvature( &
2930 : local_ot_env(1)%response_reference_energy, local_ot_env(1)%etotal, &
2931 : local_ot_env(1)%response_predicted_slope, local_ot_env(1)%ds_min, &
2932 110 : accepted_curvature, accepted_curvature_valid)
2933 110 : projected_hessian(1, 1) = response_curvature_total
2934 110 : projected_hessian(1, 2) = response_cross
2935 110 : projected_hessian(2, 1) = response_cross
2936 110 : projected_hessian(2, 2) = shadow_curvature_total
2937 110 : IF (accepted_cross_valid) THEN
2938 110 : projected_hessian(1, 2) = accepted_cross - hxc_correction(1, 2)
2939 110 : projected_hessian(2, 1) = projected_hessian(1, 2)
2940 : END IF
2941 110 : IF (accepted_curvature_valid) THEN
2942 110 : projected_hessian(2, 2) = accepted_curvature - hxc_correction(2, 2)
2943 110 : local_ot_env(1)%response_shadow_curvature = accepted_curvature
2944 : END IF
2945 : CALL qs_ot_projected_response_update( &
2946 : projected_hessian, hxc_correction, projected_coefficients, projected_update_valid, &
2947 110 : projected_gradient=projected_gradient)
2948 110 : IF (projected_update_valid) THEN
2949 110 : rotation_norm(:) = 0.0_dp
2950 110 : rotation_count(:) = 0.0_dp
2951 258 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
2952 148 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2953 148 : ikpoint = kp%nkpoint
2954 406 : DO ispin = 1, nspin_ot
2955 148 : rotation_group = MERGE(ispin, 1, nrotation_groups == nspin_ot)
2956 : local_channel = &
2957 148 : qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
2958 : rotation_step(:, local_channel) = &
2959 : projected_coefficients(1)*rotation_step(:, local_channel) + &
2960 4804 : projected_coefficients(2)*previous_rotation_step(:, local_channel)
2961 : local_ot_env(local_channel)%ener_response_gx(:) = &
2962 : projected_coefficients(1)* &
2963 : local_ot_env(local_channel)%ener_response_gx + &
2964 1112 : projected_coefficients(2)*local_ot_env(local_channel)%ener_dx
2965 : rotation_norm(rotation_group) = rotation_norm(rotation_group) + &
2966 : DOT_PRODUCT(rotation_step(:, local_channel), &
2967 4804 : rotation_step(:, local_channel))
2968 : rotation_count(rotation_group) = &
2969 296 : rotation_count(rotation_group) + REAL(nrotation, KIND=dp)
2970 : END DO
2971 : END DO
2972 110 : CALL para_env_inter_kp%sum(rotation_norm)
2973 110 : CALL para_env_inter_kp%sum(rotation_count)
2974 110 : response_scale = 1.0_dp
2975 220 : IF (SUM(rotation_norm) > EPSILON(SUM(rotation_norm))) THEN
2976 : response_scale = MIN( &
2977 : 1.0_dp, rotation_trust_rms* &
2978 330 : SQRT(SUM(rotation_count)/SUM(rotation_norm)))
2979 : END IF
2980 110 : unscaled_rotation_norm = 0.0_dp
2981 258 : DO local_channel = 1, nlocal_channels
2982 888 : ALLOCATE (dense_re(nmo, nmo), dense_im(nmo, nmo))
2983 148 : dense_re(:, :) = 0.0_dp
2984 148 : dense_im(:, :) = 0.0_dp
2985 148 : r = 0
2986 864 : DO i = 1, nmo - 1
2987 3192 : DO j = i + 1, nmo
2988 2328 : r = r + 1
2989 2328 : dense_re(i, j) = rotation_step(r, local_channel)
2990 2328 : dense_re(j, i) = -rotation_step(r, local_channel)
2991 2328 : r = r + 1
2992 2328 : dense_im(i, j) = rotation_step(r, local_channel)
2993 3044 : dense_im(j, i) = rotation_step(r, local_channel)
2994 : END DO
2995 : END DO
2996 148 : CPASSERT(r == nrotation)
2997 : unscaled_rotation_norm = MAX( &
2998 : unscaled_rotation_norm, qs_ot_antihermitian_spectral_norm( &
2999 6532 : CMPLX(dense_re, dense_im, KIND=dp)))
3000 258 : DEALLOCATE (dense_im, dense_re)
3001 : END DO
3002 110 : CALL para_env_inter_kp%max(unscaled_rotation_norm)
3003 110 : IF (unscaled_rotation_norm > EPSILON(unscaled_rotation_norm)) THEN
3004 : response_scale = MIN( &
3005 : response_scale, &
3006 110 : rotation_trust_spectral/unscaled_rotation_norm)
3007 : END IF
3008 258 : DO local_kpoint = 1, SIZE(kpoints%kp_env)
3009 148 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
3010 148 : ikpoint = kp%nkpoint
3011 406 : DO ispin = 1, nspin_ot
3012 : local_channel = &
3013 148 : qs_ot_channel_index(ispin, ikpoint, nspin_ot) - first_channel + 1
3014 : rotation_step(:, local_channel) = &
3015 4804 : response_scale*rotation_step(:, local_channel)
3016 : local_ot_env(local_channel)%ener_response_gx(:) = &
3017 1112 : response_scale*local_ot_env(local_channel)%ener_response_gx
3018 148 : IF (.NOT. (ASSOCIATED(local_ot_env(local_channel)%matrix_response_gx))) THEN
3019 0 : CALL cp_abort(__LOCATION__, "Missing OT response gradient")
3020 : END IF
3021 148 : IF (.NOT. (ASSOCIATED(local_ot_env(local_channel)%matrix_response_gx_im))) THEN
3022 0 : CALL cp_abort(__LOCATION__, "Missing imaginary OT response gradient")
3023 : END IF
3024 : CALL dbcsr_copy(local_ot_env(local_channel)%matrix_response_gx, &
3025 148 : local_ot_env(local_channel)%matrix_dx)
3026 : CALL dbcsr_scale(local_ot_env(local_channel)%matrix_response_gx, &
3027 148 : response_scale*projected_coefficients(2))
3028 : CALL dbcsr_copy(local_ot_env(local_channel)%matrix_response_gx_im, &
3029 148 : local_ot_env(local_channel)%matrix_dx_im)
3030 : CALL dbcsr_scale(local_ot_env(local_channel)%matrix_response_gx_im, &
3031 148 : response_scale*projected_coefficients(2))
3032 888 : ALLOCATE (dense_re(nmo, nmo), dense_im(nmo, nmo))
3033 148 : dense_re(:, :) = 0.0_dp
3034 148 : dense_im(:, :) = 0.0_dp
3035 148 : r = 0
3036 864 : DO i = 1, nmo - 1
3037 3192 : DO j = i + 1, nmo
3038 2328 : r = r + 1
3039 2328 : dense_re(i, j) = rotation_step(r, local_channel)
3040 2328 : dense_re(j, i) = -rotation_step(r, local_channel)
3041 2328 : r = r + 1
3042 2328 : dense_im(i, j) = rotation_step(r, local_channel)
3043 3044 : dense_im(j, i) = rotation_step(r, local_channel)
3044 : END DO
3045 : END DO
3046 148 : CPASSERT(r == nrotation)
3047 : CALL qs_scf_loop_ot_dense_to_matrix( &
3048 : dense_re, local_ot_env(local_channel), &
3049 148 : local_ot_env(local_channel)%rot_mat_response_gx)
3050 : CALL qs_scf_loop_ot_dense_to_matrix( &
3051 : dense_im, local_ot_env(local_channel), &
3052 148 : local_ot_env(local_channel)%rot_mat_response_gx_im)
3053 296 : DEALLOCATE (dense_im, dense_re)
3054 : END DO
3055 : END DO
3056 110 : local_ot_env(1)%response_hxc_direction_valid = .TRUE.
3057 : local_ot_env(1)%response_model_curvature = response_scale**2* &
3058 : DOT_PRODUCT(projected_coefficients, &
3059 : MATMUL(projected_hessian + hxc_correction, &
3060 1650 : projected_coefficients))
3061 : END IF
3062 : END IF
3063 : END IF
3064 :
3065 0 : DEALLOCATE (coupling, curvature_sum, energy_count, energy_mean, energy_metric_step, &
3066 0 : energy_shift, energy_weighted_sum, rayleigh_step, response_weight, shadow_energy_mean, &
3067 0 : shadow_energy_metric_step, shadow_energy_weighted_sum, shadow_rayleigh_step, &
3068 0 : rotation_count, rotation_norm, rotation_scale, schur_rhs, vy, vz, &
3069 0 : rayleigh_response, rhs, rotation_gradient, rotation_hessian, &
3070 0 : spin_rotation_gradient, spin_rotation_hessian, spin_rayleigh_response, &
3071 0 : previous_rotation_step, rotation_step, &
3072 0 : rotation_y, rotation_z, schur_block, solution, channel_rayleigh_response, &
3073 0 : channel_rotation_hessian, channel_rotation_gradient, channel_response_weight, &
3074 0 : channel_density_modes, channel_response_group, channel_generator, &
3075 0 : fixed_n_matrix, fixed_n_rhs, &
3076 0 : fixed_n_solution, &
3077 170 : density_modes)
3078 :
3079 1248 : END SUBROUTINE qs_scf_loop_prepare_ot_kp_rotation_response
3080 :
3081 : ! **************************************************************************************************
3082 : !> \brief copy a distributed OT matrix to a replicated dense matrix
3083 : !> \param matrix distributed matrix
3084 : !> \param ot_env channel owning the matrix distribution
3085 : !> \param dense replicated result
3086 : ! **************************************************************************************************
3087 1596 : SUBROUTINE qs_scf_loop_ot_matrix_to_dense(matrix, ot_env, dense)
3088 : TYPE(dbcsr_type), INTENT(IN) :: matrix
3089 : TYPE(qs_ot_type), INTENT(IN) :: ot_env
3090 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
3091 : INTENT(OUT) :: dense
3092 :
3093 : INTEGER :: ncol, nrow
3094 : TYPE(cp_fm_struct_type), POINTER :: fm_struct
3095 : TYPE(cp_fm_type) :: fm
3096 :
3097 1596 : NULLIFY (fm_struct)
3098 0 : CPASSERT(ASSOCIATED(ot_env%blacs_env))
3099 1596 : CPASSERT(ASSOCIATED(ot_env%para_env))
3100 1596 : CALL dbcsr_get_info(matrix, nfullrows_total=nrow, nfullcols_total=ncol)
3101 6384 : ALLOCATE (dense(nrow, ncol))
3102 : CALL cp_fm_struct_create(fm_struct, context=ot_env%blacs_env, para_env=ot_env%para_env, &
3103 1596 : nrow_global=nrow, ncol_global=ncol)
3104 1596 : CALL cp_fm_create(fm, fm_struct)
3105 1596 : CALL copy_dbcsr_to_fm(matrix, fm)
3106 1596 : CALL cp_fm_get_submatrix(fm, dense, n_rows=nrow, n_cols=ncol)
3107 1596 : CALL cp_fm_release(fm)
3108 1596 : CALL cp_fm_struct_release(fm_struct)
3109 :
3110 4788 : END SUBROUTINE qs_scf_loop_ot_matrix_to_dense
3111 :
3112 : ! **************************************************************************************************
3113 : !> \brief copy a replicated dense matrix into a distributed OT matrix
3114 : !> \param dense replicated source
3115 : !> \param ot_env channel owning the matrix distribution
3116 : !> \param matrix distributed result
3117 : ! **************************************************************************************************
3118 780 : SUBROUTINE qs_scf_loop_ot_dense_to_matrix(dense, ot_env, matrix)
3119 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN) :: dense
3120 : TYPE(qs_ot_type), INTENT(IN) :: ot_env
3121 : TYPE(dbcsr_type), INTENT(INOUT) :: matrix
3122 :
3123 : TYPE(cp_fm_struct_type), POINTER :: fm_struct
3124 : TYPE(cp_fm_type) :: fm
3125 :
3126 780 : NULLIFY (fm_struct)
3127 0 : CPASSERT(ASSOCIATED(ot_env%blacs_env))
3128 780 : CPASSERT(ASSOCIATED(ot_env%para_env))
3129 : CALL cp_fm_struct_create(fm_struct, context=ot_env%blacs_env, para_env=ot_env%para_env, &
3130 780 : nrow_global=SIZE(dense, 1), ncol_global=SIZE(dense, 2))
3131 780 : CALL cp_fm_create(fm, fm_struct)
3132 780 : CALL cp_fm_set_submatrix(fm, dense)
3133 780 : CALL copy_fm_to_dbcsr(fm, matrix)
3134 780 : CALL cp_fm_release(fm)
3135 780 : CALL cp_fm_struct_release(fm_struct)
3136 :
3137 780 : END SUBROUTINE qs_scf_loop_ot_dense_to_matrix
3138 :
3139 : ! **************************************************************************************************
3140 : !> \brief the inner loop of scf, specific to using to the orbital transformation method
3141 : !> basically, in goes the ks matrix out goes a new p matrix
3142 : !> \param qs_env ...
3143 : !> \param scf_env ...
3144 : !> \param smear ...
3145 : !> \param mos ...
3146 : !> \param rho ...
3147 : !> \param mo_derivs ...
3148 : !> \param total_energy ...
3149 : !> \param matrix_s ...
3150 : !> \param energy_only ...
3151 : !> \param has_unit_metric ...
3152 : !> \par History
3153 : !> 03.2006 created [Joost VandeVondele]
3154 : !> 2013 moved from qs_scf [Florian Schiffmann]
3155 : ! **************************************************************************************************
3156 80266 : SUBROUTINE qs_scf_loop_do_ot(qs_env, scf_env, smear, mos, rho, mo_derivs, total_energy, &
3157 : matrix_s, energy_only, has_unit_metric)
3158 :
3159 : TYPE(qs_environment_type), POINTER :: qs_env
3160 : TYPE(qs_scf_env_type), POINTER :: scf_env
3161 : TYPE(smear_type), POINTER :: smear
3162 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
3163 : TYPE(qs_rho_type), POINTER :: rho
3164 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mo_derivs
3165 : REAL(KIND=dp), INTENT(IN) :: total_energy
3166 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
3167 : LOGICAL, INTENT(INOUT) :: energy_only
3168 : LOGICAL, INTENT(IN) :: has_unit_metric
3169 :
3170 : CHARACTER(LEN=*), PARAMETER :: routineN = 'qs_scf_loop_do_ot'
3171 :
3172 : INTEGER :: handle, ispin
3173 80266 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rho_ao
3174 : TYPE(dbcsr_type), POINTER :: orthogonality_metric
3175 :
3176 80266 : CALL timeset(routineN, handle)
3177 80266 : NULLIFY (rho_ao)
3178 :
3179 80266 : CALL qs_rho_get(rho, rho_ao=rho_ao)
3180 :
3181 80266 : IF (has_unit_metric) THEN
3182 18414 : NULLIFY (orthogonality_metric)
3183 : ELSE
3184 61852 : orthogonality_metric => matrix_s(1)%matrix
3185 : END IF
3186 :
3187 : ! in case of LSD the first spin qs_ot_env will drive the minimization
3188 : ! in the case of a restricted calculation, it will make sure the spin orbitals are equal
3189 :
3190 : CALL ot_scf_mini(mos, mo_derivs, smear, orthogonality_metric, &
3191 : total_energy, energy_only, scf_env%iter_delta, &
3192 80266 : scf_env%qs_ot_env)
3193 :
3194 176127 : DO ispin = 1, SIZE(mos)
3195 176127 : CALL set_mo_occupation(mo_set=mos(ispin), smear=smear)
3196 : END DO
3197 :
3198 176127 : DO ispin = 1, SIZE(mos)
3199 : CALL calculate_density_matrix(mos(ispin), &
3200 : rho_ao(ispin)%matrix, &
3201 176127 : use_dbcsr=.TRUE.)
3202 : END DO
3203 :
3204 80266 : scf_env%iter_method = scf_env%qs_ot_env(1)%OT_METHOD_FULL
3205 80266 : scf_env%iter_param = scf_env%qs_ot_env(1)%ds_min
3206 80266 : qs_env%broyden_adaptive_sigma = scf_env%qs_ot_env(1)%broyden_adaptive_sigma
3207 :
3208 80266 : CALL timestop(handle)
3209 :
3210 80266 : END SUBROUTINE qs_scf_loop_do_ot
3211 :
3212 : ! **************************************************************************************************
3213 : !> \brief Measure the distance between the diagonalized candidate density and the current density.
3214 : !> \param scf_env Holds SCF environment information.
3215 : !> \param rho Current electron density.
3216 : !> \param para_env Parallel environment.
3217 : !> \param delta Maximum change of the density and any separately stored density coordinates.
3218 : !> \param kpoints Optional Bloch densities for the Lowdin convergence check.
3219 : ! **************************************************************************************************
3220 148 : SUBROUTINE qs_scf_candidate_density_delta(scf_env, rho, para_env, delta, kpoints)
3221 : TYPE(qs_scf_env_type), POINTER :: scf_env
3222 : TYPE(qs_rho_type), POINTER :: rho
3223 : TYPE(mp_para_env_type), POINTER :: para_env
3224 : REAL(KIND=dp), INTENT(OUT) :: delta
3225 : TYPE(kpoint_type), OPTIONAL, POINTER :: kpoints
3226 :
3227 : INTEGER :: ic, ispin
3228 : REAL(KIND=dp) :: tmp
3229 148 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp
3230 :
3231 148 : NULLIFY (rho_ao_kp)
3232 148 : CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
3233 :
3234 148 : CPASSERT(ASSOCIATED(scf_env%p_mix_new))
3235 148 : delta = 0.0_dp
3236 7910 : DO ic = 1, SIZE(scf_env%p_mix_new, 2)
3237 22642 : DO ispin = 1, SIZE(scf_env%p_mix_new, 1)
3238 : ! p_mix=1 leaves the candidate unchanged while cp_sm_mix evaluates
3239 : ! the same max-element density difference used by direct mixing.
3240 : CALL cp_sm_mix(m1=scf_env%p_mix_new(ispin, ic)%matrix, &
3241 : m2=rho_ao_kp(ispin, ic)%matrix, p_mix=1.0_dp, &
3242 14732 : delta=tmp, para_env=para_env)
3243 22494 : delta = MAX(delta, tmp)
3244 : END DO
3245 : END DO
3246 :
3247 148 : CALL lowdin_kp_population(kpoints, delta=delta)
3248 148 : END SUBROUTINE qs_scf_candidate_density_delta
3249 :
3250 : ! **************************************************************************************************
3251 : !> \brief Commit the diagonalized candidate density without numerical mixing.
3252 : !> \param scf_env Holds SCF environment information.
3253 : !> \param rho Electron density to update.
3254 : ! **************************************************************************************************
3255 148 : SUBROUTINE qs_scf_commit_density_candidate(scf_env, rho)
3256 : TYPE(qs_scf_env_type), POINTER :: scf_env
3257 : TYPE(qs_rho_type), POINTER :: rho
3258 :
3259 : CHARACTER(len=default_string_length) :: name
3260 : INTEGER :: ic, ispin
3261 148 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp
3262 :
3263 148 : NULLIFY (rho_ao_kp)
3264 148 : CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
3265 :
3266 148 : CPASSERT(ASSOCIATED(scf_env%p_mix_new))
3267 7910 : DO ic = 1, SIZE(scf_env%p_mix_new, 2)
3268 22642 : DO ispin = 1, SIZE(scf_env%p_mix_new, 1)
3269 14732 : CALL dbcsr_get_info(rho_ao_kp(ispin, ic)%matrix, name=name)
3270 22494 : CALL dbcsr_copy(rho_ao_kp(ispin, ic)%matrix, scf_env%p_mix_new(ispin, ic)%matrix, name=name)
3271 : END DO
3272 : END DO
3273 :
3274 148 : END SUBROUTINE qs_scf_commit_density_candidate
3275 :
3276 : ! **************************************************************************************************
3277 : !> \brief Performs the requested density mixing if any needed
3278 : !> \param scf_env Holds SCF environment information
3279 : !> \param rho All data for the electron density
3280 : !> \param para_env Parallel environment
3281 : !> \param diis_step Did we do a DIIS step?
3282 : !> \param kpoints Optional Bloch state with separate Lowdin density coordinates.
3283 : ! **************************************************************************************************
3284 238635 : SUBROUTINE qs_scf_density_mixing(scf_env, rho, para_env, diis_step, kpoints)
3285 : TYPE(qs_scf_env_type), POINTER :: scf_env
3286 : TYPE(qs_rho_type), POINTER :: rho
3287 : TYPE(mp_para_env_type), POINTER :: para_env
3288 : LOGICAL :: diis_step
3289 : TYPE(kpoint_type), OPTIONAL, POINTER :: kpoints
3290 :
3291 : REAL(KIND=dp) :: alpha
3292 238635 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp
3293 :
3294 238635 : NULLIFY (rho_ao_kp)
3295 :
3296 238635 : CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
3297 :
3298 382822 : SELECT CASE (scf_env%mixing_method)
3299 : CASE (direct_mixing_nr)
3300 : CALL scf_env_density_mixing(scf_env%p_mix_new, &
3301 : scf_env%mixing_store, rho_ao_kp, para_env, scf_env%iter_delta, scf_env%iter_count, &
3302 144187 : diis=diis_step)
3303 : CASE (gspace_mixing_nr, pulay_mixing_nr, broyden_mixing_nr, modified_broyden_mixing_nr, &
3304 : multisecant_mixing_nr, new_pulay_mixing_nr)
3305 : ! Compute the difference p_out-p_in
3306 : CALL self_consistency_check(rho_ao_kp, scf_env%p_delta, para_env, scf_env%p_mix_new, &
3307 11172 : delta=scf_env%iter_delta)
3308 : CASE (no_mixing_nr)
3309 : CASE DEFAULT
3310 : CALL cp_abort(__LOCATION__, &
3311 : "unknown scf mixing method: "// &
3312 238635 : cp_to_string(scf_env%mixing_method))
3313 : END SELECT
3314 :
3315 : ! Reciprocal-space mixing accepts the occupations later, together with the grid density.
3316 238635 : alpha = 0.0_dp
3317 238635 : IF (scf_env%mixing_method <= direct_mixing_nr) alpha = 1.0_dp
3318 238635 : IF (scf_env%mixing_method == direct_mixing_nr) THEN
3319 144187 : IF (.NOT. diis_step .AND. scf_env%iter_count >= scf_env%mixing_store%nskip_mixing) THEN
3320 47438 : alpha = scf_env%mixing_store%alpha
3321 : END IF
3322 : END IF
3323 238635 : CALL lowdin_kp_population(kpoints, delta=scf_env%iter_delta, alpha=alpha)
3324 :
3325 238635 : END SUBROUTINE qs_scf_density_mixing
3326 :
3327 : ! **************************************************************************************************
3328 : !> \brief checks whether exit conditions for outer loop are satisfied
3329 : !> \param qs_env ...
3330 : !> \param scf_env ...
3331 : !> \param scf_control ...
3332 : !> \param should_stop ...
3333 : !> \param outer_loop_converged ...
3334 : !> \param exit_outer_loop ...
3335 : ! **************************************************************************************************
3336 26444 : SUBROUTINE qs_scf_check_outer_exit(qs_env, scf_env, scf_control, should_stop, &
3337 : outer_loop_converged, exit_outer_loop)
3338 : TYPE(qs_environment_type), POINTER :: qs_env
3339 : TYPE(qs_scf_env_type), POINTER :: scf_env
3340 : TYPE(scf_control_type), POINTER :: scf_control
3341 : LOGICAL :: should_stop, outer_loop_converged, &
3342 : exit_outer_loop
3343 :
3344 : REAL(KIND=dp) :: outer_loop_eps
3345 :
3346 26444 : outer_loop_converged = .TRUE.
3347 26444 : IF (scf_control%outer_scf%have_scf) THEN
3348 : ! We have an outer SCF loop...
3349 6258 : scf_env%outer_scf%iter_count = scf_env%outer_scf%iter_count + 1
3350 6258 : outer_loop_converged = .FALSE.
3351 :
3352 6258 : CALL outer_loop_gradient(qs_env, scf_env)
3353 : ! Multiple constraints: get largest deviation
3354 12606 : outer_loop_eps = SQRT(MAXVAL(scf_env%outer_scf%gradient(:, scf_env%outer_scf%iter_count)**2))
3355 :
3356 6258 : IF (outer_loop_eps < scf_control%outer_scf%eps_scf) outer_loop_converged = .TRUE.
3357 : END IF
3358 :
3359 : exit_outer_loop = should_stop .OR. outer_loop_converged .OR. &
3360 26444 : scf_env%outer_scf%iter_count > scf_control%outer_scf%max_scf
3361 :
3362 26444 : END SUBROUTINE qs_scf_check_outer_exit
3363 :
3364 : ! **************************************************************************************************
3365 : !> \brief checks whether exit conditions for inner loop are satisfied
3366 : !> \param qs_env ...
3367 : !> \param scf_env ...
3368 : !> \param scf_control ...
3369 : !> \param should_stop ...
3370 : !> \param just_energy ...
3371 : !> \param exit_inner_loop ...
3372 : !> \param inner_loop_converged ...
3373 : !> \param output_unit ...
3374 : !> \param u_changed Whether a Lowdin k-point U step requires restarting the SCF history.
3375 : ! **************************************************************************************************
3376 477566 : SUBROUTINE qs_scf_check_inner_exit(qs_env, scf_env, scf_control, should_stop, just_energy, &
3377 : exit_inner_loop, inner_loop_converged, output_unit, u_changed)
3378 : TYPE(qs_environment_type), POINTER :: qs_env
3379 : TYPE(qs_scf_env_type), POINTER :: scf_env
3380 : TYPE(scf_control_type), POINTER :: scf_control
3381 : LOGICAL :: should_stop, just_energy, &
3382 : exit_inner_loop, inner_loop_converged
3383 : INTEGER :: output_unit
3384 : LOGICAL, INTENT(OUT) :: u_changed
3385 :
3386 : INTEGER :: ikind
3387 : LOGICAL :: davidson_tightening, u_pending, &
3388 : update_validated
3389 : REAL(KIND=dp) :: eps_u, ramp, target_u, u
3390 : TYPE(kpoint_type), POINTER :: kpoints
3391 238783 : TYPE(qs_kind_type), POINTER :: qs_kinds(:)
3392 :
3393 238783 : inner_loop_converged = .FALSE.
3394 238783 : exit_inner_loop = .FALSE.
3395 238783 : u_changed = .FALSE.
3396 238783 : u_pending = .FALSE.
3397 238783 : update_validated = scf_control%diagonalization%update_method /= diag_update_method_adiis
3398 238783 : IF (.NOT. update_validated) THEN
3399 148 : CPASSERT(ASSOCIATED(scf_env%scf_subspace_buffer))
3400 : update_validated = scf_env%adiis_validated .OR. &
3401 148 : scf_env%scf_subspace_buffer%diis_weight >= 1.0_dp
3402 : END IF
3403 :
3404 : CALL external_control(should_stop, "SCF", target_time=qs_env%target_time, &
3405 238783 : start_time=qs_env%start_time)
3406 238783 : CALL get_qs_env(qs_env, kpoints=kpoints, qs_kind_set=qs_kinds)
3407 238783 : IF (ASSOCIATED(kpoints)) THEN
3408 238783 : IF (ALLOCATED(kpoints%lowdin_q)) THEN
3409 1500 : DO ikind = 1, SIZE(qs_kinds)
3410 : CALL get_qs_kind(qs_kinds(ikind), u_minus_j=u, u_minus_j_target=target_u, &
3411 1000 : u_ramping=ramp, eps_u_ramping=eps_u)
3412 1000 : IF (ramp <= 0.0_dp .OR. u == target_u) CYCLE
3413 0 : u_pending = .TRUE.
3414 0 : IF (should_stop .OR. just_energy .OR. scf_env%iter_count >= scf_control%max_scf) CYCLE
3415 0 : IF (scf_control%use_ot .AND. .NOT. qs_scf_kp_search_endpoint(scf_env%iter_method)) CYCLE
3416 0 : IF (scf_env%iter_delta > eps_u .OR. .NOT. update_validated) CYCLE
3417 : ! Keep U fixed throughout trial energies and force evaluations.
3418 0 : u = MIN(u + ramp, target_u)
3419 0 : CALL set_qs_kind(qs_kinds(ikind), u_minus_j=u)
3420 0 : u_changed = .TRUE.
3421 0 : IF (output_unit > 0) WRITE (output_unit, '(T3,A,I0,A,F10.6,A)') &
3422 1500 : "DFT+U ramping: kind ", ikind, ", U(eff) = ", u*evolt, " eV"
3423 : END DO
3424 : END IF
3425 : END IF
3426 238783 : IF (u_changed) RETURN
3427 238783 : IF (scf_env%iter_delta < scf_control%eps_scf .AND. update_validated .AND. .NOT. u_pending) THEN
3428 : ! nested IFs on purpose: a .AND. chain leaves the evaluation order
3429 : ! unspecified. On non-Davidson runs the env array has size zero
3430 : ! while the tightening test below indexes its first channel
3431 22727 : davidson_tightening = .FALSE.
3432 22727 : IF (scf_env%method == block_davidson_diag_method_nr) THEN
3433 36 : IF (SIZE(scf_env%block_davidson_env) > 0) THEN
3434 : davidson_tightening = scf_env%block_davidson_env(1)%eps_iter_used > &
3435 : scf_env%block_davidson_env(1)%eps_iter .AND. &
3436 36 : scf_env%iter_delta < scf_env%block_davidson_env(1)%eps_iter_used
3437 : END IF
3438 : END IF
3439 : IF (davidson_tightening) THEN
3440 : ! the adaptive inner tolerance of the Davidson solve that produced
3441 : ! this mixing delta was looser than the delta itself. The apparent
3442 : ! convergence may be nothing but the noise floor of the loose
3443 : ! solve. Tighten the ratchet one decade below what that solve used
3444 : ! and keep iterating until the delta survives a tighter solve.
3445 0 : IF (output_unit > 0) THEN
3446 : WRITE (UNIT=output_unit, FMT="(T3,A,ES9.2,A)") &
3447 0 : "*** SCF delta below the loose Davidson tolerance ", &
3448 0 : scf_env%block_davidson_env(1)%eps_iter_used, " - tightening and continuing ***"
3449 : END IF
3450 : scf_env%block_davidson_env(1)%eps_iter_prev = &
3451 : MIN(scf_env%block_davidson_env(1)%eps_iter_prev, &
3452 : MAX(scf_env%block_davidson_env(1)%eps_iter, &
3453 0 : 0.1_dp*scf_env%block_davidson_env(1)%eps_iter_used))
3454 : ELSE
3455 22727 : IF (output_unit > 0) THEN
3456 : WRITE (UNIT=output_unit, FMT="(/,T3,A,I5,A/)") &
3457 11536 : "*** SCF run converged in ", scf_env%iter_count, " steps ***"
3458 : END IF
3459 22727 : inner_loop_converged = .TRUE.
3460 22727 : exit_inner_loop = .TRUE.
3461 : END IF
3462 216056 : ELSE IF (should_stop .OR. scf_env%iter_count >= scf_control%max_scf) THEN
3463 4000 : inner_loop_converged = .FALSE.
3464 4000 : IF (just_energy) THEN
3465 870 : exit_inner_loop = .FALSE.
3466 : ELSE
3467 3130 : exit_inner_loop = .TRUE.
3468 3130 : IF (output_unit > 0) THEN
3469 : WRITE (UNIT=output_unit, FMT="(/,T3,A,I5,A/)") &
3470 1566 : "Leaving inner SCF loop after reaching ", scf_env%iter_count, " steps."
3471 : END IF
3472 : END IF
3473 : END IF
3474 :
3475 238783 : END SUBROUTINE qs_scf_check_inner_exit
3476 :
3477 : ! **************************************************************************************************
3478 : !> \brief undoing density mixing. Important upon convergence
3479 : !> \param scf_env ...
3480 : !> \param rho ...
3481 : !> \param dft_control ...
3482 : !> \param para_env ...
3483 : !> \param diis_step ...
3484 : ! **************************************************************************************************
3485 25857 : SUBROUTINE qs_scf_undo_mixing(scf_env, rho, dft_control, para_env, diis_step)
3486 : TYPE(qs_scf_env_type), POINTER :: scf_env
3487 : TYPE(qs_rho_type), POINTER :: rho
3488 : TYPE(dft_control_type), POINTER :: dft_control
3489 : TYPE(mp_para_env_type), POINTER :: para_env
3490 : LOGICAL :: diis_step
3491 :
3492 : CHARACTER(len=default_string_length) :: name
3493 : INTEGER :: ic, ispin, nc
3494 25857 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp
3495 :
3496 25857 : NULLIFY (rho_ao_kp)
3497 :
3498 25857 : IF (scf_env%mixing_method > 0) THEN
3499 18080 : CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
3500 18080 : nc = SIZE(scf_env%p_mix_new, 2)
3501 35022 : SELECT CASE (scf_env%mixing_method)
3502 : CASE (direct_mixing_nr)
3503 : CALL scf_env_density_mixing(scf_env%p_mix_new, scf_env%mixing_store, &
3504 : rho_ao_kp, para_env, scf_env%iter_delta, &
3505 : scf_env%iter_count, diis=diis_step, &
3506 16942 : invert=.TRUE.)
3507 162196 : DO ic = 1, nc
3508 324860 : DO ispin = 1, dft_control%nspins
3509 162664 : CALL dbcsr_get_info(rho_ao_kp(ispin, ic)%matrix, name=name) ! keep the name
3510 307918 : CALL dbcsr_copy(rho_ao_kp(ispin, ic)%matrix, scf_env%p_mix_new(ispin, ic)%matrix, name=name)
3511 : END DO
3512 : END DO
3513 : CASE (gspace_mixing_nr, pulay_mixing_nr, broyden_mixing_nr, modified_broyden_mixing_nr, &
3514 : multisecant_mixing_nr, new_pulay_mixing_nr)
3515 91474 : DO ic = 1, nc
3516 156592 : DO ispin = 1, dft_control%nspins
3517 83198 : CALL dbcsr_get_info(rho_ao_kp(ispin, ic)%matrix, name=name) ! keep the name
3518 155454 : CALL dbcsr_copy(rho_ao_kp(ispin, ic)%matrix, scf_env%p_mix_new(ispin, ic)%matrix, name=name)
3519 : END DO
3520 : END DO
3521 : END SELECT
3522 : END IF
3523 25857 : END SUBROUTINE qs_scf_undo_mixing
3524 :
3525 : ! **************************************************************************************************
3526 : !> \brief Performs the updates rho (takes care of mixing as well)
3527 : !> \param rho ...
3528 : !> \param qs_env ...
3529 : !> \param scf_env ...
3530 : !> \param ks_env ...
3531 : !> \param mix_rho ...
3532 : ! **************************************************************************************************
3533 238783 : SUBROUTINE qs_scf_rho_update(rho, qs_env, scf_env, ks_env, mix_rho)
3534 : TYPE(qs_rho_type), POINTER :: rho
3535 : TYPE(qs_environment_type), POINTER :: qs_env
3536 : TYPE(qs_scf_env_type), POINTER :: scf_env
3537 : TYPE(qs_ks_env_type), POINTER :: ks_env
3538 : LOGICAL, INTENT(IN) :: mix_rho
3539 :
3540 238783 : REAL(KIND=dp), CONTIGUOUS, POINTER :: auxiliary(:, :)
3541 : TYPE(kpoint_type), POINTER :: kpoints
3542 : TYPE(mp_para_env_type), POINTER :: para_env
3543 :
3544 238783 : NULLIFY (para_env, auxiliary)
3545 238783 : CALL get_qs_env(qs_env, para_env=para_env, kpoints=kpoints)
3546 : ! ** update qs_env%rho
3547 238783 : CALL qs_rho_update_rho(rho, qs_env=qs_env)
3548 : ! ** Density mixing through density matrix or on the reciprocal space grid (exclusive)
3549 238783 : IF (mix_rho) THEN
3550 10034 : IF (ASSOCIATED(kpoints)) THEN
3551 10034 : IF (ALLOCATED(kpoints%lowdin_q)) THEN
3552 218 : CALL lowdin_kp_population(kpoints, alpha=1.0_dp)
3553 218 : auxiliary => kpoints%lowdin_q
3554 : END IF
3555 : END IF
3556 : CALL gspace_mixing(qs_env, scf_env%mixing_method, scf_env%mixing_store, rho, &
3557 10034 : para_env, scf_env%iter_count, auxiliary=auxiliary)
3558 :
3559 : END IF
3560 238783 : CALL qs_ks_did_change(ks_env, rho_changed=.TRUE.)
3561 :
3562 238783 : END SUBROUTINE qs_scf_rho_update
3563 :
3564 : ! **************************************************************************************************
3565 : !> \brief Performs the necessary steps before leaving innner scf loop
3566 : !> \param scf_env ...
3567 : !> \param qs_env ...
3568 : !> \param diis_step ...
3569 : !> \param output_unit ...
3570 : ! **************************************************************************************************
3571 25857 : SUBROUTINE qs_scf_inner_finalize(scf_env, qs_env, diis_step, output_unit)
3572 : TYPE(qs_scf_env_type), POINTER :: scf_env
3573 : TYPE(qs_environment_type), POINTER :: qs_env
3574 : LOGICAL :: diis_step
3575 : INTEGER, INTENT(IN) :: output_unit
3576 :
3577 : TYPE(dft_control_type), POINTER :: dft_control
3578 : TYPE(kpoint_type), POINTER :: kpoints
3579 : TYPE(mp_para_env_type), POINTER :: para_env
3580 : TYPE(qs_energy_type), POINTER :: energy
3581 : TYPE(qs_ks_env_type), POINTER :: ks_env
3582 : TYPE(qs_rho_type), POINTER :: rho
3583 :
3584 25857 : NULLIFY (energy, rho, dft_control, ks_env)
3585 :
3586 : CALL get_qs_env(qs_env=qs_env, energy=energy, ks_env=ks_env, &
3587 : rho=rho, dft_control=dft_control, para_env=para_env, &
3588 25857 : kpoints=kpoints)
3589 :
3590 25857 : CALL cleanup_scf_loop(scf_env)
3591 :
3592 : ! now, print out energies and charges corresponding to the obtained wfn
3593 : ! (this actually is not 100% consistent at this point)!
3594 25857 : CALL qs_scf_print_summary(output_unit, qs_env)
3595 :
3596 25857 : CALL qs_scf_undo_mixing(scf_env, rho, dft_control, para_env, diis_step)
3597 25857 : CALL lowdin_kp_population(kpoints, alpha=1.0_dp)
3598 :
3599 : ! *** update rspace rho since the mo changed
3600 : ! *** this might not always be needed (i.e. no post calculation / no forces )
3601 : ! *** but guarantees that rho and wfn are consistent at this point
3602 25857 : CALL qs_scf_rho_update(rho, qs_env, scf_env, ks_env, mix_rho=.FALSE.)
3603 :
3604 25857 : END SUBROUTINE qs_scf_inner_finalize
3605 :
3606 : ! **************************************************************************************************
3607 : !> \brief perform cleanup operations at the end of an scf loop
3608 : !> \param scf_env ...
3609 : !> \par History
3610 : !> 03.2006 created [Joost VandeVondele]
3611 : ! **************************************************************************************************
3612 25857 : SUBROUTINE cleanup_scf_loop(scf_env)
3613 : TYPE(qs_scf_env_type), INTENT(INOUT) :: scf_env
3614 :
3615 : CHARACTER(len=*), PARAMETER :: routineN = 'cleanup_scf_loop'
3616 :
3617 : INTEGER :: handle, ispin
3618 :
3619 25857 : CALL timeset(routineN, handle)
3620 :
3621 33622 : SELECT CASE (scf_env%method)
3622 : CASE (ot_method_nr)
3623 17729 : DO ispin = 1, SIZE(scf_env%qs_ot_env)
3624 17729 : CALL ot_scf_destroy(scf_env%qs_ot_env(ispin))
3625 : END DO
3626 7765 : DEALLOCATE (scf_env%qs_ot_env)
3627 : CASE (ot_diag_method_nr)
3628 : !
3629 : CASE (general_diag_method_nr)
3630 : !
3631 : CASE (special_diag_method_nr)
3632 : !
3633 : CASE (block_krylov_diag_method_nr, block_davidson_diag_method_nr)
3634 : !
3635 : CASE (filter_matrix_diag_method_nr)
3636 : !
3637 : CASE (smeagol_method_nr)
3638 : !
3639 : CASE DEFAULT
3640 : CALL cp_abort(__LOCATION__, &
3641 : "unknown scf method method:"// &
3642 25857 : cp_to_string(scf_env%method))
3643 : END SELECT
3644 :
3645 25857 : CALL timestop(handle)
3646 :
3647 25857 : END SUBROUTINE cleanup_scf_loop
3648 :
3649 594 : END MODULE qs_scf_loop_utils
|