Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Different diagonalization schemes that can be used
10 : !> for the iterative solution of the eigenvalue problem
11 : !> \par History
12 : !> started from routines previously located in the qs_scf module
13 : !> 05.2009
14 : ! **************************************************************************************************
15 : MODULE qs_scf_diagonalization
16 : USE cp_array_utils, ONLY: cp_1d_r_p_type
17 : USE cp_blacs_env, ONLY: cp_blacs_env_type
18 : USE cp_cfm_basic_linalg, ONLY: cp_cfm_column_scale,&
19 : cp_cfm_scale_and_add,&
20 : cp_cfm_scale_and_add_fm
21 : USE cp_cfm_diag, ONLY: cp_cfm_diag_workspace_type,&
22 : cp_cfm_geeig,&
23 : cp_cfm_geeig_canon,&
24 : cp_cfm_geeig_canon_local,&
25 : cp_cfm_geeig_local,&
26 : cp_cfm_heevd,&
27 : cp_cfm_local_workspace_prepare
28 : USE cp_cfm_types, ONLY: cp_cfm_create,&
29 : cp_cfm_release,&
30 : cp_cfm_set_all,&
31 : cp_cfm_to_cfm,&
32 : cp_cfm_to_fm,&
33 : cp_cfm_type,&
34 : cp_fm_to_cfm
35 : USE cp_control_types, ONLY: dft_control_type,&
36 : hairy_probes_type
37 : USE cp_dbcsr_api, ONLY: &
38 : dbcsr_copy, dbcsr_create, dbcsr_deallocate_matrix, dbcsr_init_p, dbcsr_p_type, &
39 : dbcsr_release_p, dbcsr_set, dbcsr_type, dbcsr_type_symmetric
40 : USE cp_dbcsr_cp2k_link, ONLY: cp_dbcsr_alloc_block_from_nbl
41 : USE cp_dbcsr_operations, ONLY: copy_dbcsr_to_fm,&
42 : copy_fm_to_dbcsr,&
43 : cp_dbcsr_sm_fm_multiply,&
44 : dbcsr_allocate_matrix_set
45 : USE cp_fm_basic_linalg, ONLY: cp_fm_column_scale,&
46 : cp_fm_scale_and_add,&
47 : cp_fm_symm,&
48 : cp_fm_uplo_to_full
49 : USE cp_fm_cholesky, ONLY: cp_fm_cholesky_reduce,&
50 : cp_fm_cholesky_restore
51 : USE cp_fm_diag, ONLY: choose_eigv_solver,&
52 : cp_fm_geeig,&
53 : cp_fm_geeig_canon,&
54 : diag_check_requested,&
55 : direct_generalized_diagonalization
56 : USE cp_fm_pool_types, ONLY: cp_fm_pool_p_type,&
57 : fm_pool_create_fm,&
58 : fm_pool_get_el_struct,&
59 : fm_pool_give_back_fm
60 : USE cp_fm_struct, ONLY: cp_fm_struct_create,&
61 : cp_fm_struct_release,&
62 : cp_fm_struct_type
63 : USE cp_fm_types, ONLY: cp_fm_add_to_element,&
64 : cp_fm_create,&
65 : cp_fm_get_info,&
66 : cp_fm_release,&
67 : cp_fm_to_fm,&
68 : cp_fm_type
69 : USE cp_log_handling, ONLY: cp_get_default_logger,&
70 : cp_logger_get_default_unit_nr,&
71 : cp_logger_type
72 : USE cp_output_handling, ONLY: cp_print_key_finished_output,&
73 : cp_print_key_unit_nr,&
74 : debug_print_level
75 : USE dft_plus_u, ONLY: lowdin_kp_apply
76 : USE ieee_arithmetic, ONLY: ieee_is_finite
77 : USE input_constants, ONLY: &
78 : cholesky_dbcsr, cholesky_inverse, cholesky_off, cholesky_reduce, cholesky_restore, &
79 : core_guess, diag_update_method_adiis, general_roks, high_spin_roks, ot_precond_full_all, &
80 : ot_precond_full_kinetic, ot_precond_full_single_inverse, ot_precond_none, &
81 : ot_precond_s_inverse, restart_guess
82 : USE input_cp2k_kpoints, ONLY: lattice_fft_auto,&
83 : lattice_fft_off,&
84 : lattice_fft_on
85 : USE input_section_types, ONLY: section_vals_get_subs_vals,&
86 : section_vals_type
87 : USE kinds, ONLY: dp,&
88 : int_8
89 : USE kpoint_methods, ONLY: kpoint_density_matrices,&
90 : kpoint_density_transform,&
91 : kpoint_set_mo_occupation,&
92 : rskp_grid_type,&
93 : rskp_transform_grid_prepare,&
94 : rskp_transform_grid_release
95 : USE kpoint_types, ONLY: get_kpoint_info,&
96 : kpoint_env_type,&
97 : kpoint_type
98 : USE local_gemm_api, ONLY: LOCAL_GEMM_PU_GPU,&
99 : local_gemm_ctxt_type
100 : USE machine, ONLY: m_flush,&
101 : m_walltime
102 : USE mathconstants, ONLY: z_one,&
103 : z_zero
104 : USE message_passing, ONLY: mp_para_env_type
105 : USE parallel_gemm_api, ONLY: parallel_gemm
106 : USE preconditioner, ONLY: dbcsr_pair_to_cfm,&
107 : make_preconditioner_complex_full_kinetic,&
108 : make_preconditioner_complex_full_s_inverse,&
109 : prepare_preconditioner,&
110 : restart_preconditioner
111 : USE preconditioner_makes, ONLY: make_complex_full_all,&
112 : make_complex_full_single_inverse
113 : USE preconditioner_types, ONLY: destroy_preconditioner,&
114 : init_preconditioner
115 : USE qs_density_matrices, ONLY: calculate_density_matrix
116 : USE qs_density_mixing_types, ONLY: direct_mixing_nr,&
117 : gspace_mixing_nr
118 : USE qs_diis, ONLY: qs_diis_b_calc_err_kp,&
119 : qs_diis_b_check_i_alloc_kp,&
120 : qs_diis_b_clear,&
121 : qs_diis_b_clear_kp,&
122 : qs_diis_b_info_kp,&
123 : qs_diis_b_step,&
124 : qs_diis_b_step_kp
125 : USE qs_energy_types, ONLY: qs_energy_type
126 : USE qs_environment_types, ONLY: get_qs_env,&
127 : qs_environment_type
128 : USE qs_gspace_mixing, ONLY: gspace_mixing
129 : USE qs_kpoint_operators, ONLY: &
130 : kpoint_operator_context_create, kpoint_operator_context_release, &
131 : kpoint_operator_context_type, kpoint_operator_evaluate, kpoint_operator_finish, &
132 : kpoint_operator_get, kpoint_operator_get_local, kpoint_operator_prepare, &
133 : kpoint_operator_start, kpoint_operator_store, kpoint_operator_work_size, kpoint_slot_ks, &
134 : kpoint_slot_s, kpoint_slot_t, kpoint_spin_free
135 : USE qs_ks_methods, ONLY: qs_ks_update_qs_env
136 : USE qs_ks_types, ONLY: qs_ks_did_change,&
137 : qs_ks_env_type
138 : USE qs_matrix_pools, ONLY: mpools_get,&
139 : qs_matrix_pools_type
140 : USE qs_mixing_utils, ONLY: charge_mixing_init,&
141 : mixing_allocate,&
142 : mixing_init,&
143 : self_consistency_check
144 : USE qs_mo_methods, ONLY: calculate_subspace_eigenvalues
145 : USE qs_mo_occupation, ONLY: set_mo_occupation
146 : USE qs_mo_types, ONLY: get_mo_set,&
147 : mo_set_type
148 : USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
149 : USE qs_ot_eigensolver, ONLY: ot_eigensolver,&
150 : ot_eigensolver_complex
151 : USE qs_rho_atom_types, ONLY: rho_atom_type
152 : USE qs_rho_methods, ONLY: qs_rho_update_rho
153 : USE qs_rho_types, ONLY: qs_rho_get,&
154 : qs_rho_type
155 : USE qs_scf_block_davidson, ONLY: generate_extended_space,&
156 : generate_extended_space_c,&
157 : generate_extended_space_sparse
158 : USE qs_scf_lanczos, ONLY: lanczos_refinement,&
159 : lanczos_refinement_2v
160 : USE qs_scf_methods, ONLY: combine_ks_matrices,&
161 : eigensolver,&
162 : eigensolver_dbcsr,&
163 : eigensolver_generalized,&
164 : eigensolver_simple,&
165 : eigensolver_symm,&
166 : scf_env_density_mixing
167 : USE qs_scf_types, ONLY: qs_scf_env_type,&
168 : subspace_env_type
169 : USE scf_control_types, ONLY: scf_control_type
170 :
171 : !$ USE OMP_LIB, ONLY: omp_get_max_threads, &
172 : !$ omp_get_thread_num
173 : #include "./base/base_uses.f90"
174 :
175 : IMPLICIT NONE
176 :
177 : PRIVATE
178 :
179 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_scf_diagonalization'
180 :
181 : TYPE, PRIVATE :: kp_diag_workspace_type
182 : TYPE(cp_cfm_type) :: cksmat, cmos, csmat, csmat_base, cwork
183 : TYPE(cp_cfm_diag_workspace_type) :: solver
184 : TYPE(local_gemm_ctxt_type) :: gemm_ctx
185 : COMPLEX(KIND=dp), ALLOCATABLE :: phase(:, :)
186 : END TYPE kp_diag_workspace_type
187 :
188 : PUBLIC :: do_general_diag, do_general_diag_kp, do_roks_diag, &
189 : do_special_diag, do_ot_diag, do_ot_diag_kp, do_block_davidson_diag, &
190 : do_block_davidson_diag_kp, &
191 : do_block_krylov_diag, do_scf_diag_subspace, diag_subspace_allocate, &
192 : general_eigenproblem, diag_kp_smat, diag_kp_basic
193 :
194 : CONTAINS
195 :
196 : ! **************************************************************************************************
197 : !> \brief Fade candidate regularization through handover; never regularize a raw-map check.
198 : !> \param scf_env Current SCF state.
199 : !> \return ...
200 : ! **************************************************************************************************
201 206 : FUNCTION adiis_candidate_shift(scf_env) RESULT(shift)
202 : TYPE(qs_scf_env_type), INTENT(IN) :: scf_env
203 : REAL(KIND=dp) :: shift
204 :
205 206 : shift = 0.0_dp
206 206 : IF (scf_env%iter_count <= 1 .OR. scf_env%adiis_check_next) RETURN
207 190 : IF (.NOT. ASSOCIATED(scf_env%scf_subspace_buffer)) RETURN
208 190 : shift = scf_env%adiis_shift*(1.0_dp - scf_env%scf_subspace_buffer%diis_weight)
209 190 : END FUNCTION adiis_candidate_shift
210 :
211 : ! **************************************************************************************************
212 : !> \brief Add -shift*S*C*(occupation/maxocc)*C^T*S to a candidate Fock matrix.
213 : !> The occupied projector does not require any stored virtual orbitals.
214 : !> \param fock Candidate matrix; physical F[P] and all history matrices remain unchanged.
215 : !> \param overlap AO overlap.
216 : !> \param mos Previous physical orbitals and occupations.
217 : !> \param shift Nonnegative regularization parameter in hartree.
218 : ! **************************************************************************************************
219 84 : SUBROUTINE shift_candidate_real(fock, overlap, mos, shift)
220 : TYPE(cp_fm_type), INTENT(INOUT) :: fock
221 : TYPE(cp_fm_type), INTENT(IN) :: overlap
222 : TYPE(mo_set_type), INTENT(IN) :: mos
223 : REAL(KIND=dp), INTENT(IN) :: shift
224 :
225 : INTEGER :: nao, nmo
226 : REAL(KIND=dp) :: maxocc
227 28 : REAL(KIND=dp), DIMENSION(:), POINTER :: occupation
228 : TYPE(cp_fm_type) :: sc
229 : TYPE(cp_fm_type), POINTER :: coeff
230 :
231 0 : IF (shift == 0.0_dp) RETURN
232 28 : CALL get_mo_set(mos, nao=nao, nmo=nmo, maxocc=maxocc, occupation_numbers=occupation, mo_coeff=coeff)
233 28 : CALL cp_fm_create(sc, coeff%matrix_struct)
234 28 : CALL parallel_gemm("N", "N", nao, nmo, nao, 1.0_dp, overlap, coeff, 0.0_dp, sc)
235 406 : CALL cp_fm_column_scale(sc, SQRT(MAX(0.0_dp, occupation/maxocc)))
236 28 : CALL parallel_gemm("N", "T", nao, nao, nmo, -shift, sc, sc, 1.0_dp, fock)
237 28 : CALL cp_fm_release(sc)
238 28 : END SUBROUTINE shift_candidate_real
239 :
240 : ! **************************************************************************************************
241 : !> \brief Complex occupied-space shift, using conjugate transpose and existing eigensolver workspaces.
242 : !> \param fock Candidate Fock matrix, modified in place.
243 : !> \param overlap AO overlap, unchanged.
244 : !> \param mos Previous complex MOs.
245 : !> \param coeff AO/MO eigensolver workspace.
246 : !> \param work AO/AO eigensolver workspace.
247 : !> \param shift Nonnegative regularization parameter in hartree.
248 : !> \param local Whether the matrices are complete on this rank.
249 : !> \param gemm_ctx Private local GEMM context, unused for distributed groups.
250 : ! **************************************************************************************************
251 158 : SUBROUTINE shift_candidate_complex(fock, overlap, mos, coeff, work, shift, local, gemm_ctx)
252 : TYPE(cp_cfm_type), INTENT(INOUT) :: fock
253 : TYPE(cp_cfm_type), INTENT(IN) :: overlap
254 : TYPE(mo_set_type), INTENT(IN) :: mos
255 : TYPE(cp_cfm_type), INTENT(INOUT) :: coeff, work
256 : REAL(KIND=dp), INTENT(IN) :: shift
257 : LOGICAL, INTENT(IN) :: local
258 : TYPE(local_gemm_ctxt_type), INTENT(INOUT) :: gemm_ctx
259 :
260 : INTEGER :: nao, nmo
261 : REAL(KIND=dp) :: maxocc
262 138 : REAL(KIND=dp), DIMENSION(:), POINTER :: occupation
263 : TYPE(cp_cfm_type), POINTER :: cmos
264 :
265 118 : IF (shift == 0.0_dp) RETURN
266 20 : CALL get_mo_set(mos, nao=nao, nmo=nmo, maxocc=maxocc, occupation_numbers=occupation, cmo_coeff=cmos)
267 20 : CALL cp_cfm_to_cfm(cmos, coeff)
268 320 : CALL cp_cfm_column_scale(coeff, CMPLX(SQRT(MAX(0.0_dp, occupation/maxocc)), KIND=dp))
269 20 : IF (local) THEN
270 60 : CPASSERT(PRODUCT(overlap%matrix_struct%context%num_pe) == 1)
271 60 : CPASSERT(PRODUCT(coeff%matrix_struct%context%num_pe) == 1)
272 60 : CPASSERT(PRODUCT(work%matrix_struct%context%num_pe) == 1)
273 60 : CPASSERT(PRODUCT(fock%matrix_struct%context%num_pe) == 1)
274 : CALL gemm_ctx%gemm("N", "N", nao, nmo, nao, z_one, &
275 : overlap%local_data, SIZE(overlap%local_data, 1), &
276 : coeff%local_data, SIZE(coeff%local_data, 1), z_zero, &
277 20 : work%local_data, SIZE(work%local_data, 1))
278 : CALL gemm_ctx%gemm("N", "C", nao, nao, nmo, CMPLX(-shift, KIND=dp), &
279 : work%local_data, SIZE(work%local_data, 1), &
280 : work%local_data, SIZE(work%local_data, 1), z_one, &
281 20 : fock%local_data, SIZE(fock%local_data, 1))
282 : ELSE
283 0 : CALL parallel_gemm("N", "N", nao, nmo, nao, z_one, overlap, coeff, z_zero, work)
284 0 : CALL parallel_gemm("N", "C", nao, nao, nmo, CMPLX(-shift, KIND=dp), work, work, z_one, fock)
285 : END IF
286 138 : END SUBROUTINE shift_candidate_complex
287 :
288 : ! **************************************************************************************************
289 : !> \brief the inner loop of scf, specific to diagonalization with S matrix
290 : !> basically, in goes the ks matrix out goes a new p matrix
291 : !> \param scf_env ...
292 : !> \param mos ...
293 : !> \param matrix_ks ...
294 : !> \param matrix_s ...
295 : !> \param scf_control ...
296 : !> \param scf_section ...
297 : !> \param diis_step ...
298 : !> \par History
299 : !> 03.2006 created [Joost VandeVondele]
300 : ! **************************************************************************************************
301 :
302 103223 : SUBROUTINE general_eigenproblem(scf_env, mos, matrix_ks, &
303 : matrix_s, scf_control, scf_section, &
304 : diis_step)
305 :
306 : TYPE(qs_scf_env_type), POINTER :: scf_env
307 : TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
308 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
309 : TYPE(scf_control_type), POINTER :: scf_control
310 : TYPE(section_vals_type), POINTER :: scf_section
311 : LOGICAL, INTENT(INOUT) :: diis_step
312 :
313 : INTEGER :: cdiis_cholesky_method, cdiis_ncall, &
314 : ispin, nspin
315 : LOGICAL :: cdiis_step, do_level_shift, owns_ortho, &
316 : use_adiis, use_cdiis, use_jacobi, &
317 : use_subspace_fock
318 : REAL(KIND=dp) :: candidate_shift, cdiis_error, &
319 : diis_error, diis_weight, eps_diis
320 : TYPE(cp_fm_type), POINTER :: ortho
321 : TYPE(dbcsr_type), POINTER :: effective_ks_dbcsr, ortho_dbcsr
322 :
323 103223 : nspin = SIZE(matrix_ks)
324 103223 : NULLIFY (effective_ks_dbcsr, ortho, ortho_dbcsr)
325 :
326 103223 : use_adiis = scf_control%diagonalization%update_method == diag_update_method_adiis
327 103223 : use_subspace_fock = .FALSE.
328 103223 : IF (use_adiis) THEN
329 68 : IF (.NOT. ASSOCIATED(scf_env%scf_subspace_buffer)) THEN
330 0 : CPABORT("ADIIS is only available in the main Quickstep SCF workflow")
331 : END IF
332 68 : use_subspace_fock = scf_env%scf_subspace_buffer%use_combined_fock
333 : END IF
334 :
335 103223 : eps_diis = scf_control%eps_diis
336 103223 : use_cdiis = .FALSE.
337 103223 : IF (use_adiis .AND. ASSOCIATED(scf_env%scf_diis_buffer)) THEN
338 : IF (.NOT. scf_env%skip_diis .AND. scf_env%iter_count > 1 .AND. &
339 : .NOT. scf_env%adiis_check_next .AND. &
340 68 : .NOT. scf_env%scf_subspace_buffer%last_restart .AND. &
341 : scf_env%scf_subspace_buffer%nstored > 0) THEN
342 62 : use_cdiis = scf_env%iter_delta < eps_diis .OR. scf_env%scf_diis_buffer%ncall > 0
343 : END IF
344 : END IF
345 :
346 224920 : DO ispin = 1, nspin
347 224920 : IF (use_subspace_fock .AND. .NOT. use_cdiis) THEN
348 : CALL copy_dbcsr_to_fm(scf_env%scf_subspace_buffer%combined_fock(ispin, 1)%matrix, &
349 20 : scf_env%scf_work1(ispin), scf_env%fm_copy_plan(ispin), check_plan=.TRUE.)
350 : ELSE
351 : CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, scf_env%scf_work1(ispin), &
352 121677 : scf_env%fm_copy_plan(ispin), check_plan=.TRUE.)
353 : END IF
354 : END DO
355 :
356 103223 : IF (use_adiis) THEN
357 68 : diis_step = .FALSE.
358 68 : diis_error = scf_env%scf_subspace_buffer%last_old_fock_weight
359 68 : diis_weight = scf_env%scf_subspace_buffer%diis_weight
360 68 : IF (use_cdiis) THEN
361 46 : cdiis_ncall = scf_env%scf_diis_buffer%ncall
362 : CALL qs_diis_b_step(scf_env%scf_diis_buffer, mos, scf_env%scf_work1, &
363 : scf_env%scf_work2, scf_env%iter_delta, cdiis_error, cdiis_step, &
364 46 : eps_diis, 2, s_matrix=matrix_s, scf_section=scf_section)
365 46 : IF (.NOT. ieee_is_finite(cdiis_error) .OR. cdiis_error >= eps_diis) THEN
366 6 : cdiis_step = .FALSE.
367 6 : IF (cdiis_ncall < scf_env%scf_diis_buffer%nbuffer) THEN
368 : ! The rejected state has not overwritten a full circular buffer.
369 6 : scf_env%scf_diis_buffer%ncall = cdiis_ncall
370 : ELSE
371 0 : CALL qs_diis_b_clear(scf_env%scf_diis_buffer)
372 0 : diis_weight = 0.0_dp
373 : END IF
374 : END IF
375 46 : IF (cdiis_step) THEN
376 : ! Use one half-weight handover step; MAX_DIIS only controls the buffer capacity.
377 34 : diis_weight = MIN(1.0_dp, diis_weight + 0.5_dp)
378 : ELSE
379 : ! A rejected or deferred CDIIS step must not leave a partial raw-Fock blend active.
380 12 : diis_weight = 0.0_dp
381 : END IF
382 46 : IF (diis_weight < 1.0_dp) THEN
383 54 : DO ispin = 1, nspin
384 36 : IF (use_subspace_fock) THEN
385 : CALL copy_dbcsr_to_fm( &
386 : scf_env%scf_subspace_buffer%combined_fock(ispin, 1)%matrix, scf_env%scf_work2, &
387 32 : scf_env%fm_copy_plan(ispin), check_plan=.TRUE.)
388 : ELSE
389 : CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, scf_env%scf_work2, &
390 4 : scf_env%fm_copy_plan(ispin), check_plan=.TRUE.)
391 : END IF
392 : CALL cp_fm_scale_and_add(diis_weight, scf_env%scf_work1(ispin), &
393 54 : 1.0_dp - diis_weight, scf_env%scf_work2)
394 : END DO
395 : END IF
396 46 : diis_step = cdiis_step .AND. diis_weight >= 1.0_dp
397 46 : IF (diis_step) diis_error = cdiis_error
398 22 : ELSE IF (ASSOCIATED(scf_env%scf_diis_buffer)) THEN
399 22 : IF (scf_env%scf_diis_buffer%ncall > 0) CALL qs_diis_b_clear(scf_env%scf_diis_buffer)
400 22 : diis_weight = 0.0_dp
401 : END IF
402 68 : scf_env%scf_subspace_buffer%diis_weight = diis_weight
403 : ELSE
404 103155 : IF (scf_env%iter_count > 1 .AND. .NOT. scf_env%skip_diis) THEN
405 : CALL qs_diis_b_step(scf_env%scf_diis_buffer, mos, scf_env%scf_work1, &
406 : scf_env%scf_work2, scf_env%iter_delta, diis_error, diis_step, &
407 : eps_diis, scf_control%nmixing, &
408 : s_matrix=matrix_s, &
409 83097 : scf_section=scf_section)
410 : ELSE
411 20058 : diis_step = .FALSE.
412 : END IF
413 : END IF
414 :
415 103223 : candidate_shift = 0.0_dp
416 103223 : IF (use_adiis) candidate_shift = adiis_candidate_shift(scf_env)
417 103223 : IF (candidate_shift > 0.0_dp) THEN
418 14 : CALL copy_dbcsr_to_fm(matrix_s(1)%matrix, scf_env%scf_work2, scf_env%fm_copy_plan(0), check_plan=.TRUE.)
419 42 : DO ispin = 1, nspin
420 42 : CALL shift_candidate_real(scf_env%scf_work1(ispin), scf_env%scf_work2, mos(ispin), candidate_shift)
421 : END DO
422 : END IF
423 :
424 : do_level_shift = ((scf_control%level_shift /= 0.0_dp) .AND. &
425 : ((scf_control%density_guess == core_guess) .OR. &
426 103223 : (scf_env%iter_count > 1)))
427 :
428 103223 : IF (.NOT. use_adiis .AND. (scf_env%iter_count > 1) .AND. &
429 : (scf_env%iter_delta < scf_control%diagonalization%eps_jacobi)) THEN
430 0 : use_jacobi = .TRUE.
431 : ELSE
432 103155 : use_jacobi = .FALSE.
433 : END IF
434 :
435 68 : IF (use_adiis .AND. .NOT. diis_step) THEN
436 40 : scf_env%iter_param = diis_error
437 40 : IF (scf_env%scf_subspace_buffer%last_restart) THEN
438 0 : scf_env%iter_method = "ADIIS/Rst."
439 : ELSE
440 40 : scf_env%iter_method = "ADIIS/Diag."
441 : END IF
442 103183 : ELSE IF (diis_step) THEN
443 51147 : scf_env%iter_param = diis_error
444 51147 : IF (use_jacobi) THEN
445 0 : scf_env%iter_method = "DIIS/Jacobi"
446 : ELSE
447 51147 : scf_env%iter_method = "DIIS/Diag."
448 : END IF
449 : ELSE
450 52036 : IF (scf_env%mixing_method == 0) THEN
451 0 : scf_env%iter_method = "NoMix/Diag."
452 52036 : ELSE IF (scf_env%mixing_method == 1) THEN
453 45986 : scf_env%iter_param = scf_env%p_mix_alpha
454 45986 : IF (use_jacobi) THEN
455 0 : scf_env%iter_method = "P_Mix/Jacobi"
456 : ELSE
457 45986 : scf_env%iter_method = "P_Mix/Diag."
458 : END IF
459 6050 : ELSE IF (scf_env%mixing_method > 1) THEN
460 6050 : scf_env%iter_param = scf_env%mixing_store%alpha
461 6050 : IF (use_jacobi) THEN
462 0 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Jacobi"
463 : ELSE
464 6050 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Diag."
465 : END IF
466 : END IF
467 : END IF
468 :
469 103223 : IF (scf_env%cholesky_method == cholesky_dbcsr .AND. .NOT. use_cdiis) THEN
470 1072 : ortho_dbcsr => scf_env%ortho_dbcsr
471 3198 : DO ispin = 1, nspin
472 2126 : effective_ks_dbcsr => matrix_ks(ispin)%matrix
473 2126 : IF (use_subspace_fock) THEN
474 0 : effective_ks_dbcsr => scf_env%scf_subspace_buffer%combined_fock(ispin, 1)%matrix
475 : END IF
476 : CALL eigensolver_dbcsr(matrix_ks=effective_ks_dbcsr, matrix_ks_fm=scf_env%scf_work1(ispin), &
477 : mo_set=mos(ispin), &
478 : ortho_dbcsr=ortho_dbcsr, &
479 3198 : ksbuf1=scf_env%buf1_dbcsr, ksbuf2=scf_env%buf2_dbcsr)
480 : END DO
481 :
482 102151 : ELSE IF (scf_env%cholesky_method > cholesky_off) THEN
483 101717 : cdiis_cholesky_method = scf_env%cholesky_method
484 101717 : IF (cdiis_cholesky_method == cholesky_dbcsr) THEN
485 0 : cdiis_cholesky_method = cholesky_inverse
486 : END IF
487 101717 : IF (scf_env%cholesky_method == cholesky_inverse) THEN
488 612 : ortho => scf_env%ortho_m1
489 : ELSE
490 101105 : ortho => scf_env%ortho
491 : END IF
492 :
493 101717 : owns_ortho = .FALSE.
494 101717 : IF (.NOT. ASSOCIATED(ortho)) THEN
495 0 : ALLOCATE (ortho)
496 0 : owns_ortho = .TRUE.
497 : END IF
498 :
499 220772 : DO ispin = 1, nspin
500 220772 : IF (direct_generalized_diagonalization .AND. .NOT. do_level_shift) THEN
501 : CALL eigensolver_generalized(matrix_ks_fm=scf_env%scf_work1(ispin), &
502 : matrix_s=matrix_s(ispin)%matrix, &
503 : mo_set=mos(ispin), &
504 0 : work=scf_env%scf_work2)
505 : ELSE
506 119055 : IF (do_level_shift) THEN
507 : CALL eigensolver(matrix_ks_fm=scf_env%scf_work1(ispin), &
508 : mo_set=mos(ispin), &
509 : ortho=ortho, &
510 : work=scf_env%scf_work2, &
511 : cholesky_method=cdiis_cholesky_method, &
512 : do_level_shift=do_level_shift, &
513 : level_shift=scf_control%level_shift, &
514 : matrix_u_fm=scf_env%ortho, &
515 150 : use_jacobi=use_jacobi)
516 : ELSE
517 : CALL eigensolver(matrix_ks_fm=scf_env%scf_work1(ispin), &
518 : mo_set=mos(ispin), &
519 : ortho=ortho, &
520 : work=scf_env%scf_work2, &
521 : cholesky_method=cdiis_cholesky_method, &
522 : do_level_shift=do_level_shift, &
523 : level_shift=scf_control%level_shift, &
524 118905 : use_jacobi=use_jacobi)
525 : END IF
526 : END IF
527 : END DO
528 :
529 101717 : IF (scf_env%cholesky_method /= cholesky_dbcsr) THEN
530 101717 : scf_env%cholesky_method = cdiis_cholesky_method
531 : END IF
532 :
533 101717 : IF (owns_ortho) DEALLOCATE (ortho)
534 : ELSE
535 434 : ortho => scf_env%ortho
536 :
537 434 : owns_ortho = .FALSE.
538 434 : IF (.NOT. ASSOCIATED(ortho)) THEN
539 0 : ALLOCATE (ortho)
540 0 : owns_ortho = .TRUE.
541 : END IF
542 :
543 434 : IF (do_level_shift) THEN
544 172 : DO ispin = 1, nspin
545 : IF (ASSOCIATED(scf_env%scf_work1_red) .AND. ASSOCIATED(scf_env%scf_work2_red) &
546 172 : .AND. ASSOCIATED(scf_env%ortho_red) .AND. ASSOCIATED(scf_env%ortho_m1_red)) THEN
547 : CALL eigensolver_symm(matrix_ks_fm=scf_env%scf_work1(ispin), &
548 : mo_set=mos(ispin), &
549 : ortho=ortho, &
550 : work=scf_env%scf_work2, &
551 : do_level_shift=do_level_shift, &
552 : level_shift=scf_control%level_shift, &
553 : matrix_u_fm=scf_env%ortho_m1, &
554 : use_jacobi=use_jacobi, &
555 : jacobi_threshold=scf_control%diagonalization%jacobi_threshold, &
556 : matrix_ks_fm_red=scf_env%scf_work1_red(ispin), &
557 : ortho_red=scf_env%ortho_red, &
558 : work_red=scf_env%scf_work2_red, &
559 86 : matrix_u_fm_red=scf_env%ortho_m1_red)
560 : ELSE
561 : CALL eigensolver_symm(matrix_ks_fm=scf_env%scf_work1(ispin), &
562 : mo_set=mos(ispin), &
563 : ortho=ortho, &
564 : work=scf_env%scf_work2, &
565 : do_level_shift=do_level_shift, &
566 : level_shift=scf_control%level_shift, &
567 : matrix_u_fm=scf_env%ortho_m1, &
568 : use_jacobi=use_jacobi, &
569 0 : jacobi_threshold=scf_control%diagonalization%jacobi_threshold)
570 : END IF
571 : END DO
572 : ELSE
573 778 : DO ispin = 1, nspin
574 : IF (ASSOCIATED(scf_env%scf_work1_red) .AND. ASSOCIATED(scf_env%scf_work2_red) &
575 778 : .AND. ASSOCIATED(scf_env%ortho_red)) THEN
576 : CALL eigensolver_symm(matrix_ks_fm=scf_env%scf_work1(ispin), &
577 : mo_set=mos(ispin), &
578 : ortho=ortho, &
579 : work=scf_env%scf_work2, &
580 : do_level_shift=do_level_shift, &
581 : level_shift=scf_control%level_shift, &
582 : use_jacobi=use_jacobi, &
583 : jacobi_threshold=scf_control%diagonalization%jacobi_threshold, &
584 : matrix_ks_fm_red=scf_env%scf_work1_red(ispin), &
585 : ortho_red=scf_env%ortho_red, &
586 430 : work_red=scf_env%scf_work2_red)
587 : ELSE
588 : CALL eigensolver_symm(matrix_ks_fm=scf_env%scf_work1(ispin), &
589 : mo_set=mos(ispin), &
590 : ortho=ortho, &
591 : work=scf_env%scf_work2, &
592 : do_level_shift=do_level_shift, &
593 : level_shift=scf_control%level_shift, &
594 : use_jacobi=use_jacobi, &
595 0 : jacobi_threshold=scf_control%diagonalization%jacobi_threshold)
596 : END IF
597 : END DO
598 : END IF
599 :
600 434 : IF (owns_ortho) DEALLOCATE (ortho)
601 : END IF
602 :
603 103223 : END SUBROUTINE general_eigenproblem
604 :
605 : ! **************************************************************************************************
606 : !> \brief ...
607 : !> \param scf_env ...
608 : !> \param mos ...
609 : !> \param matrix_ks ...
610 : !> \param matrix_s ...
611 : !> \param scf_control ...
612 : !> \param scf_section ...
613 : !> \param diis_step ...
614 : !> \param probe ...
615 : ! **************************************************************************************************
616 102165 : SUBROUTINE do_general_diag(scf_env, mos, matrix_ks, &
617 : matrix_s, scf_control, scf_section, &
618 : diis_step, probe)
619 :
620 : TYPE(qs_scf_env_type), POINTER :: scf_env
621 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
622 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
623 : TYPE(scf_control_type), POINTER :: scf_control
624 : TYPE(section_vals_type), POINTER :: scf_section
625 : LOGICAL, INTENT(INOUT) :: diis_step
626 : TYPE(hairy_probes_type), DIMENSION(:), OPTIONAL, &
627 : POINTER :: probe
628 :
629 : INTEGER :: ispin, nspin
630 : REAL(KIND=dp) :: total_zeff_corr
631 :
632 102165 : nspin = SIZE(matrix_ks)
633 :
634 : CALL general_eigenproblem(scf_env, mos, matrix_ks, &
635 102165 : matrix_s, scf_control, scf_section, diis_step)
636 :
637 : total_zeff_corr = 0.0_dp
638 102165 : total_zeff_corr = scf_env%sum_zeff_corr
639 :
640 102165 : IF (ABS(total_zeff_corr) > 0.0_dp) THEN
641 : CALL set_mo_occupation(mo_array=mos, &
642 40 : smear=scf_control%smear, tot_zeff_corr=total_zeff_corr)
643 : ELSE
644 102125 : IF (PRESENT(probe) .EQV. .TRUE.) THEN
645 14 : scf_control%smear%do_smear = .FALSE.
646 : CALL set_mo_occupation(mo_array=mos, &
647 : smear=scf_control%smear, &
648 14 : probe=probe)
649 : ELSE
650 102111 : IF (.NOT. scf_control%gce%do_gce) THEN
651 : CALL set_mo_occupation(mo_array=mos, &
652 101743 : smear=scf_control%smear)
653 : ELSE
654 : CALL set_mo_occupation(mo_array=mos, &
655 : smear=scf_control%smear, &
656 368 : gce=scf_control%gce)
657 : END IF
658 : END IF
659 : END IF
660 :
661 221746 : DO ispin = 1, nspin
662 : CALL calculate_density_matrix(mos(ispin), &
663 221746 : scf_env%p_mix_new(ispin, 1)%matrix)
664 : END DO
665 :
666 102165 : END SUBROUTINE do_general_diag
667 :
668 : ! **************************************************************************************************
669 : !> \brief Kpoint diagonalization routine
670 : !> Transforms matrices to kpoint, distributes kpoint groups, performs
671 : !> general diagonalization (no storgae of overlap decomposition), stores
672 : !> MOs, calculates occupation numbers, calculates density matrices
673 : !> in kpoint representation, transforms density matrices to real space
674 : !> \param matrix_ks Kohn-sham matrices (RS indices, global)
675 : !> \param matrix_s Overlap matrices (RS indices, global)
676 : !> \param kpoints Kpoint environment
677 : !> \param scf_env SCF environment
678 : !> \param scf_control SCF control variables
679 : !> \param update_p ...
680 : !> \param diis_step ...
681 : !> \param diis_error ...
682 : !> \param qs_env ...
683 : !> \param probe ...
684 : !> \param added_mos_auto_grow true when the adaptive virtual-space buffer must grow
685 : !> \param potential Fixed Lowdin orbital potential for non-self-consistent k points.
686 : !> \par History
687 : !> 08.2014 created [JGH]
688 : ! **************************************************************************************************
689 35572 : SUBROUTINE do_general_diag_kp(matrix_ks, matrix_s, kpoints, scf_env, scf_control, update_p, &
690 35572 : diis_step, diis_error, qs_env, probe, added_mos_auto_grow, potential)
691 :
692 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks, matrix_s
693 : TYPE(kpoint_type), POINTER :: kpoints
694 : TYPE(qs_scf_env_type), POINTER :: scf_env
695 : TYPE(scf_control_type), POINTER :: scf_control
696 : LOGICAL, INTENT(IN) :: update_p
697 : LOGICAL, INTENT(INOUT) :: diis_step
698 : REAL(dp), INTENT(INOUT), OPTIONAL :: diis_error
699 : TYPE(qs_environment_type), OPTIONAL, POINTER :: qs_env
700 : TYPE(hairy_probes_type), DIMENSION(:), OPTIONAL, &
701 : POINTER :: probe
702 : LOGICAL, INTENT(OUT), OPTIONAL :: added_mos_auto_grow
703 : REAL(dp), INTENT(IN), OPTIONAL, TARGET :: potential(:, :)
704 :
705 : CHARACTER(len=*), PARAMETER :: routineN = 'do_general_diag_kp'
706 :
707 35572 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:) :: coeffs
708 35572 : REAL(dp), POINTER :: effective_u(:, :), adiis_u(:, :)
709 : INTEGER :: cdiis_ncall, handle, ib, ikp, ispin, kplocal, kpmax, &
710 : lattice_fft, nb, nkp, nspin, omp_threads, nworkers, nentry
711 : INTEGER, DIMENSION(2) :: kp_range
712 : INTEGER, DIMENSION(3) :: nkp_grid
713 35572 : INTEGER, DIMENSION(:, :), POINTER :: kp_dist
714 35572 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
715 : LOGICAL :: adiis_cdiis, cache_smat, cdiis_step, do_diis, my_added_mos_auto_grow, prepared_ops, prepared_part, &
716 : reuse_smat, spin_grid_fft, use_adiis, use_grid_fft, use_local_kpoints, use_real_wfn
717 : REAL(KIND=dp) :: diis_weight
718 35572 : REAL(KIND=dp), DIMENSION(:), POINTER :: eigenvalues
719 35572 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: xkp
720 : TYPE(cp_cfm_type), POINTER :: cksmat, cmos, csmat, cwork
721 35572 : TYPE(kp_diag_workspace_type), ALLOCATABLE, TARGET :: workspace(:)
722 35572 : TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_ao_fm_pools
723 : TYPE(cp_fm_struct_type), POINTER :: matrix_struct, mo_struct
724 : TYPE(cp_fm_type) :: fmlocal, rksmat, rsmat
725 35572 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: fmwork
726 : TYPE(cp_fm_type), POINTER :: mo_coeff
727 35572 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: adiis_ks, effective_ks
728 : TYPE(dbcsr_type), POINTER :: rmatrix
729 : TYPE(kpoint_env_type), POINTER :: kp
730 35572 : TYPE(kpoint_operator_context_type) :: op_ctx
731 : TYPE(mp_para_env_type), POINTER :: para_env
732 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
733 35572 : POINTER :: sab_nl
734 : TYPE(qs_matrix_pools_type), POINTER :: mpools
735 35572 : TYPE(rskp_grid_type) :: s_grid
736 35572 : TYPE(rskp_grid_type), ALLOCATABLE, DIMENSION(:) :: ks_grid
737 : TYPE(section_vals_type), POINTER :: scf_section
738 :
739 35572 : CALL timeset(routineN, handle)
740 :
741 35572 : my_added_mos_auto_grow = .FALSE.
742 35572 : IF (PRESENT(added_mos_auto_grow)) added_mos_auto_grow = .FALSE.
743 :
744 35572 : NULLIFY (adiis_ks, effective_ks, sab_nl)
745 : CALL get_kpoint_info(kpoints, nkp=nkp, xkp=xkp, use_real_wfn=use_real_wfn, kp_range=kp_range, &
746 : kp_dist=kp_dist, sab_nl=sab_nl, &
747 35572 : cell_to_index=cell_to_index, nkp_grid=nkp_grid, lattice_fft=lattice_fft)
748 35572 : CPASSERT(ASSOCIATED(sab_nl))
749 35572 : kplocal = kp_range(2) - kp_range(1) + 1
750 96360 : kpmax = MAXVAL(kp_dist(2, :) - kp_dist(1, :) + 1)
751 :
752 : !Whether we use DIIS for k-points
753 35572 : do_diis = .FALSE.
754 35572 : use_adiis = update_p .AND. scf_control%diagonalization%update_method == diag_update_method_adiis
755 35572 : IF (use_adiis) THEN
756 80 : CPASSERT(ASSOCIATED(scf_env%scf_subspace_buffer))
757 : END IF
758 35572 : adiis_cdiis = .FALSE.
759 35572 : IF (use_adiis .AND. ASSOCIATED(kpoints%scf_diis_buffer)) THEN
760 : IF (scf_env%iter_count > 1 .AND. .NOT. scf_env%skip_diis .AND. &
761 : .NOT. scf_env%adiis_check_next .AND. &
762 : .NOT. scf_env%scf_subspace_buffer%last_restart .AND. &
763 : scf_env%scf_subspace_buffer%nstored > 0 .AND. &
764 80 : PRESENT(diis_error) .AND. PRESENT(qs_env)) THEN
765 : adiis_cdiis = scf_env%iter_delta < scf_control%eps_diis .OR. &
766 74 : kpoints%scf_diis_buffer%ncall > 0
767 : END IF
768 : END IF
769 : IF ((.NOT. use_adiis .AND. scf_env%iter_count > 1 .AND. .NOT. scf_env%skip_diis .AND. &
770 35572 : .NOT. use_real_wfn .AND. PRESENT(diis_error) .AND. PRESENT(qs_env)) .OR. &
771 27462 : adiis_cdiis) do_diis = .TRUE.
772 :
773 35572 : adiis_ks => matrix_ks
774 35572 : NULLIFY (adiis_u)
775 35572 : IF (ALLOCATED(kpoints%lowdin_v)) adiis_u => kpoints%lowdin_v
776 35572 : IF (use_adiis) THEN
777 80 : IF (scf_env%scf_subspace_buffer%use_combined_fock) THEN
778 32 : adiis_ks => scf_env%scf_subspace_buffer%combined_fock
779 32 : IF (ASSOCIATED(adiis_u)) adiis_u => scf_env%scf_subspace_buffer%combined_aux
780 : END IF
781 : END IF
782 35572 : effective_ks => matrix_ks
783 35572 : NULLIFY (effective_u)
784 35572 : IF (ALLOCATED(kpoints%lowdin_v)) effective_u => kpoints%lowdin_v
785 35572 : IF (PRESENT(potential)) THEN
786 0 : CPASSERT(.NOT. update_p)
787 0 : effective_u => potential
788 : END IF
789 35572 : IF (use_adiis .AND. .NOT. adiis_cdiis) THEN
790 30 : effective_ks => adiis_ks
791 30 : effective_u => adiis_u
792 : END IF
793 35572 : IF (use_adiis .AND. .NOT. do_diis) THEN
794 30 : scf_env%scf_subspace_buffer%diis_weight = 0.0_dp
795 30 : IF (ASSOCIATED(kpoints%scf_diis_buffer)) THEN
796 30 : IF (kpoints%scf_diis_buffer%ncall > 0) CALL qs_diis_b_clear_kp(kpoints%scf_diis_buffer)
797 : END IF
798 : END IF
799 :
800 35572 : para_env => kpoints%blacs_env_all%para_env
801 35572 : nspin = SIZE(matrix_ks, 1)
802 35572 : omp_threads = 1
803 35572 : !$ omp_threads = omp_get_max_threads()
804 : ! One-rank groups use the same worker path for MPI, OpenMP and hybrid jobs.
805 35572 : use_local_kpoints = kpoints%para_env_kp%num_pe == 1 .AND. .NOT. use_real_wfn
806 35572 : IF (diag_check_requested()) use_local_kpoints = .FALSE.
807 35572 : IF (para_env%num_pe == 1 .AND. omp_threads == 1) THEN
808 0 : IF (lattice_fft == lattice_fft_on .OR. (lattice_fft == lattice_fft_auto .AND. nkp >= 27)) THEN
809 0 : use_local_kpoints = .FALSE.
810 : END IF
811 : END IF
812 35572 : ib = 0
813 35572 : nb = 0
814 35572 : NULLIFY (scf_section)
815 :
816 35572 : NULLIFY (rmatrix)
817 :
818 35572 : fmwork => scf_env%scf_work1
819 : ! Both real and complex operators share the same assembly and transfer context.
820 35572 : CALL kpoint_operator_context_create(op_ctx, kpoints, fmwork(1), nspin)
821 :
822 : ! fm pools to be used within a kpoint group
823 35572 : CALL get_kpoint_info(kpoints, mpools=mpools)
824 35572 : CALL mpools_get(mpools, ao_ao_fm_pools=ao_ao_fm_pools)
825 :
826 35572 : CALL fm_pool_create_fm(ao_ao_fm_pools(1)%pool, fmlocal)
827 35572 : CALL cp_fm_get_info(fmlocal, matrix_struct=matrix_struct)
828 :
829 35572 : IF (use_real_wfn) THEN
830 : CALL cp_fm_create(rksmat, matrix_struct)
831 : CALL cp_fm_create(rsmat, matrix_struct)
832 : END IF
833 : ! Retain the unmodified S(k) for this SCF run, outside the driver-local
834 : ! operator context. Solvers receive work copies because they overwrite S.
835 35572 : cache_smat = para_env%num_pe > 1 .AND. update_p .AND. .NOT. use_real_wfn
836 35572 : reuse_smat = .FALSE.
837 35572 : IF (cache_smat) THEN
838 35258 : reuse_smat = ALLOCATED(kpoints%scf_smat)
839 35258 : IF (.NOT. reuse_smat) THEN
840 18918 : ALLOCATE (kpoints%scf_smat(kplocal))
841 11426 : DO ikp = 1, kplocal
842 11426 : CALL cp_cfm_create(kpoints%scf_smat(ikp), matrix_struct)
843 : END DO
844 : END IF
845 35258 : CPASSERT(SIZE(kpoints%scf_smat) == kplocal)
846 : END IF
847 :
848 : ! Prepare H/S before starting any round. ADIIS can replace only the idle KS slot.
849 35572 : prepared_ops = .FALSE.
850 : ! A single distributed group can also assemble its prepared local tiles.
851 35572 : IF (para_env%num_pe > 1 .OR. use_local_kpoints) THEN
852 35572 : CALL kpoint_operator_prepare(op_ctx, effective_ks, kpoint_slot_ks, prepared_ops)
853 35572 : IF (.NOT. reuse_smat) THEN
854 4060 : CALL kpoint_operator_prepare(op_ctx, matrix_s, kpoint_slot_s, prepared_part, matrix_row=kpoint_spin_free)
855 4070 : prepared_ops = prepared_ops .AND. prepared_part
856 : END IF
857 : END IF
858 :
859 35572 : use_local_kpoints = use_local_kpoints .AND. prepared_ops
860 35572 : nworkers = 1
861 35572 : nentry = 0
862 35572 : IF (use_local_kpoints) THEN
863 25216 : nworkers = MIN(omp_threads, kplocal)
864 25216 : CALL kpoint_operator_work_size(op_ctx, nentry)
865 : END IF
866 35572 : IF (.NOT. use_real_wfn .OR. do_diis) THEN
867 35442 : kp => kpoints%kp_env(1)%kpoint_env
868 35442 : IF (use_real_wfn) THEN
869 0 : CALL get_mo_set(kp%mos(1), mo_coeff=mo_coeff)
870 0 : CALL cp_fm_get_info(mo_coeff, matrix_struct=mo_struct)
871 : ELSE
872 35442 : mo_struct => kp%mos(1)%cmo_coeff%matrix_struct
873 : END IF
874 : CALL kp_diag_workspaces_create(workspace, nworkers, matrix_struct, mo_struct, nentry, &
875 35442 : use_local_kpoints, scf_env%cholesky_method == cholesky_off)
876 35442 : cksmat => workspace(1)%cksmat
877 35442 : csmat => workspace(1)%csmat
878 35442 : cwork => workspace(1)%cwork
879 35442 : cmos => workspace(1)%cmos
880 : END IF
881 :
882 : ! For a complete Monkhorst-Pack grid, transform every MPI-local DBCSR block over all k points
883 : ! in one lattice FFT. The established per-k phase sum remains the exact memory/irregular-grid
884 : ! fallback. Divide the conservative memory budget between H spins and S.
885 144516 : ALLOCATE (ks_grid(nspin))
886 35564 : SELECT CASE (lattice_fft)
887 : CASE (lattice_fft_auto)
888 35564 : use_grid_fft = nkp >= 27
889 : CASE (lattice_fft_on)
890 8 : use_grid_fft = .TRUE.
891 : CASE (lattice_fft_off)
892 0 : use_grid_fft = .FALSE.
893 : CASE DEFAULT
894 35572 : CPABORT("Unknown lattice FFT selection mode")
895 : END SELECT
896 35572 : IF (prepared_ops) use_grid_fft = .FALSE.
897 : ! The driver needs sparse scratch only for forward lattice-FFT preparation.
898 35572 : IF (use_grid_fft) THEN
899 0 : ALLOCATE (rmatrix)
900 0 : CALL dbcsr_create(rmatrix, template=matrix_ks(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
901 0 : CALL cp_dbcsr_alloc_block_from_nbl(rmatrix, sab_nl)
902 : END IF
903 35572 : IF (use_grid_fft .AND. .NOT. reuse_smat) THEN
904 : CALL rskp_transform_grid_prepare(s_grid, rmatrix, matrix_s, 1, xkp, nkp_grid, &
905 : cell_to_index, sab_nl, use_grid_fft, &
906 0 : max_storage_bytes=512_int_8*1024_int_8**2/INT(nspin + 1, int_8))
907 : END IF
908 35572 : IF (use_grid_fft) THEN
909 0 : DO ispin = 1, nspin
910 : CALL rskp_transform_grid_prepare(ks_grid(ispin), rmatrix, effective_ks, ispin, xkp, nkp_grid, &
911 : cell_to_index, sab_nl, spin_grid_fft, &
912 0 : max_storage_bytes=512_int_8*1024_int_8**2/INT(nspin + 1, int_8))
913 0 : use_grid_fft = use_grid_fft .AND. spin_grid_fft
914 : END DO
915 : END IF
916 35572 : IF (.NOT. use_grid_fft) THEN
917 35572 : CALL rskp_transform_grid_release(s_grid)
918 73372 : DO ispin = 1, nspin
919 73372 : CALL rskp_transform_grid_release(ks_grid(ispin))
920 : END DO
921 : END IF
922 :
923 : ! Setup and start all the communication.
924 35572 : IF (.NOT. use_local_kpoints) THEN
925 31392 : DO ikp = 1, kpmax
926 56266 : DO ispin = 1, nspin
927 : CALL kpoint_operator_start(op_ctx, ikp, ispin, effective_ks, kpoint_slot_ks, &
928 24874 : ks_grid(ispin), use_grid_fft, matrix_row=ispin)
929 45910 : IF (.NOT. cache_smat .OR. (.NOT. reuse_smat .AND. ispin == 1)) THEN
930 : CALL kpoint_operator_start(op_ctx, ikp, ispin, matrix_s, kpoint_slot_s, s_grid, &
931 3624 : use_grid_fft, matrix_row=kpoint_spin_free)
932 : END IF
933 : END DO
934 : END DO
935 : END IF
936 :
937 : ! Finish communication then diagonalise in each group
938 35572 : diis_weight = 1.0_dp
939 35572 : IF (do_diis) THEN
940 27462 : scf_section => section_vals_get_subs_vals(qs_env%input, "DFT%SCF")
941 27462 : cdiis_ncall = kpoints%scf_diis_buffer%ncall
942 27462 : CALL qs_diis_b_info_kp(kpoints%scf_diis_buffer, ib, nb)
943 27462 : CALL qs_diis_b_check_i_alloc_kp(kpoints%scf_diis_buffer, matrix_struct, nspin, kplocal, scf_section)
944 27462 : IF (use_local_kpoints) THEN
945 : CALL kp_diag_local_phase(op_ctx, kpoints, workspace, scf_env, scf_control, nspin, &
946 19720 : cache_smat, reuse_smat, use_adiis, ib, .TRUE., 1.0_dp, potential=effective_u)
947 : ELSE
948 19540 : DO ikp = 1, kpmax
949 34482 : DO ispin = 1, nspin
950 14942 : CALL harvest_operators(ikp, ispin)
951 14942 : IF (ikp > kplocal) CYCLE
952 : CALL qs_diis_b_calc_err_kp(kpoints%scf_diis_buffer, ib, kp%mos, cksmat, csmat, &
953 : ispin, ikp, cmos, real_wfn=use_real_wfn, &
954 26740 : local=.FALSE., gemm_ctx=workspace(1)%gemm_ctx)
955 :
956 : END DO !ispin
957 : END DO !ikp
958 :
959 : END IF
960 :
961 82386 : ALLOCATE (coeffs(nb))
962 : CALL qs_diis_b_step_kp(kpoints%scf_diis_buffer, coeffs, ib, nb, scf_env%iter_delta, diis_error, &
963 : cdiis_step, scf_control%eps_diis, nspin, nkp, kplocal, &
964 : MERGE(2, scf_control%nmixing, use_adiis), &
965 54874 : scf_section, kpoints%para_env_inter_kp)
966 : diis_weight = 1.0_dp
967 27462 : IF (use_adiis) THEN
968 50 : diis_weight = scf_env%scf_subspace_buffer%diis_weight
969 50 : IF (.NOT. ieee_is_finite(diis_error) .OR. diis_error >= scf_control%eps_diis) THEN
970 6 : cdiis_step = .FALSE.
971 6 : IF (cdiis_ncall < kpoints%scf_diis_buffer%nbuffer) THEN
972 : ! The rejected state has not overwritten a full circular buffer.
973 6 : kpoints%scf_diis_buffer%ncall = cdiis_ncall
974 : ELSE
975 0 : CALL qs_diis_b_clear_kp(kpoints%scf_diis_buffer)
976 0 : diis_weight = 0.0_dp
977 : END IF
978 : END IF
979 50 : IF (cdiis_step) THEN
980 : ! Use one half-weight handover step; MAX_DIIS only controls the buffer capacity.
981 38 : diis_weight = MIN(1.0_dp, diis_weight + 0.5_dp)
982 : ELSE
983 : ! A rejected or deferred CDIIS step must not leave a partial raw-Fock blend active.
984 12 : diis_weight = 0.0_dp
985 : END IF
986 50 : scf_env%scf_subspace_buffer%diis_weight = diis_weight
987 50 : diis_step = cdiis_step .AND. diis_weight >= 1.0_dp
988 50 : IF (.NOT. diis_step) diis_error = scf_env%scf_subspace_buffer%last_old_fock_weight
989 : ELSE
990 27412 : diis_step = cdiis_step
991 : END IF
992 :
993 : ! All first-pass instances have finished. Capture the selected
994 : ! ADIIS operator once instead of retransferring it in every round.
995 54924 : IF (use_adiis .AND. diis_weight < 1.0_dp) THEN
996 18 : CALL kpoint_operator_prepare(op_ctx, adiis_ks, kpoint_slot_ks, prepared_part)
997 : ! A collective prepare rejection must return all ranks to the transfer path.
998 18 : use_local_kpoints = use_local_kpoints .AND. prepared_part
999 : END IF
1000 :
1001 : ELSE
1002 8110 : IF (.NOT. update_p .OR. use_adiis) diis_step = .FALSE.
1003 : END IF
1004 :
1005 35572 : IF (use_local_kpoints) THEN
1006 : ! Unallocated arrays and disassociated pointers are absent at nonpointer optional dummies.
1007 25216 : IF (do_diis) effective_u => adiis_u
1008 : CALL kp_diag_local_phase(op_ctx, kpoints, workspace, scf_env, scf_control, nspin, &
1009 25216 : cache_smat, reuse_smat, use_adiis, ib, .FALSE., diis_weight, coeffs, effective_u)
1010 : ELSE
1011 31392 : DO ikp = 1, kpmax
1012 56266 : DO ispin = 1, nspin
1013 24874 : IF (do_diis) THEN
1014 14942 : IF (use_adiis .AND. diis_weight < 1.0_dp) THEN
1015 : CALL kpoint_operator_start(op_ctx, ikp, ispin, adiis_ks, kpoint_slot_ks, &
1016 0 : use_grid=.FALSE., matrix_row=ispin)
1017 0 : CALL kpoint_operator_finish(op_ctx, ikp, ispin, kpoint_slot_ks, cwork)
1018 0 : IF (ikp <= kplocal .AND. ASSOCIATED(adiis_u)) THEN
1019 0 : CALL lowdin_kp_apply(kpoints%kp_env(ikp)%kpoint_env, adiis_u(:, ispin), cmat=cwork)
1020 : END IF
1021 : END IF
1022 14942 : IF (ikp > kplocal) CYCLE
1023 14942 : CALL cp_cfm_to_cfm(kpoints%scf_diis_buffer%smat(ikp), csmat)
1024 14942 : CALL kp_diis_candidate(kpoints, ikp, ispin, coeffs, diis_weight, cksmat, cwork)
1025 14942 : IF (use_real_wfn) THEN
1026 0 : CALL cp_cfm_to_fm(cksmat, rksmat, fmlocal)
1027 0 : CALL cp_cfm_to_fm(csmat, rsmat, fmlocal)
1028 : END IF
1029 : ELSE
1030 9932 : CALL harvest_operators(ikp, ispin)
1031 9932 : IF (ikp > kplocal) CYCLE
1032 : END IF
1033 24874 : kp => kpoints%kp_env(ikp)%kpoint_env
1034 45910 : IF (use_real_wfn) THEN
1035 156 : CALL get_mo_set(kp%mos(ispin), mo_coeff=mo_coeff, eigenvalues=eigenvalues)
1036 156 : IF (use_adiis) CALL shift_candidate_real(rksmat, rsmat, kp%mos(ispin), &
1037 0 : adiis_candidate_shift(scf_env))
1038 156 : IF (scf_env%cholesky_method == cholesky_off) THEN
1039 40 : CALL cp_fm_geeig_canon(rksmat, rsmat, mo_coeff, eigenvalues, fmlocal, scf_control%eps_eigval)
1040 : ELSE
1041 116 : CALL cp_fm_geeig(rksmat, rsmat, mo_coeff, eigenvalues, fmlocal)
1042 : END IF
1043 : ELSE
1044 24718 : CALL kp_solve_complex(kp%mos(ispin), workspace(1), scf_env, scf_control, use_adiis, .FALSE.)
1045 : END IF
1046 : END DO
1047 : END DO
1048 : END IF
1049 35572 : IF (ALLOCATED(coeffs)) DEALLOCATE (coeffs)
1050 :
1051 35572 : CALL kpoint_operator_context_release(op_ctx)
1052 :
1053 35572 : IF (update_p) THEN
1054 : ! MO occupations
1055 35388 : IF (PRESENT(probe) .EQV. .TRUE.) THEN
1056 0 : scf_control%smear%do_smear = .FALSE.
1057 : CALL kpoint_set_mo_occupation(kpoints, scf_control%smear, &
1058 0 : probe=probe)
1059 : ELSE
1060 : CALL kpoint_set_mo_occupation(kpoints, scf_control%smear, &
1061 : added_mos_auto=scf_control%added_mos_auto, &
1062 35388 : added_mos_auto_grow=my_added_mos_auto_grow)
1063 : END IF
1064 35388 : IF (my_added_mos_auto_grow) THEN
1065 0 : IF (PRESENT(added_mos_auto_grow)) added_mos_auto_grow = .TRUE.
1066 : ELSE
1067 : ! density matrices
1068 35388 : CALL kpoint_density_matrices(kpoints)
1069 : ! density matrices in real space
1070 : CALL kpoint_density_transform(kpoints, scf_env%p_mix_new, .FALSE., &
1071 35388 : matrix_s(1, 1)%matrix, sab_nl, fmwork, overlap_rs=matrix_s)
1072 : END IF
1073 : END IF
1074 :
1075 35572 : IF (ASSOCIATED(rmatrix)) CALL dbcsr_deallocate_matrix(rmatrix)
1076 35572 : CALL rskp_transform_grid_release(s_grid)
1077 73372 : DO ispin = 1, nspin
1078 73372 : CALL rskp_transform_grid_release(ks_grid(ispin))
1079 : END DO
1080 73372 : DEALLOCATE (ks_grid)
1081 :
1082 35572 : IF (use_real_wfn) THEN
1083 130 : CALL cp_fm_release(rksmat)
1084 130 : CALL cp_fm_release(rsmat)
1085 : END IF
1086 35572 : IF (ALLOCATED(workspace)) CALL kp_diag_workspaces_release(workspace)
1087 35572 : CALL fm_pool_give_back_fm(ao_ao_fm_pools(1)%pool, fmlocal)
1088 :
1089 106716 : CALL timestop(handle)
1090 :
1091 : CONTAINS
1092 :
1093 : ! Serialized harvest only. Inactive tail rounds participate in every transfer,
1094 : ! then return before reading a local matrix or publishing the overlap cache.
1095 : ! **************************************************************************************************
1096 : !> \brief ...
1097 : !> \param round ...
1098 : !> \param spin ...
1099 : ! **************************************************************************************************
1100 24874 : SUBROUTINE harvest_operators(round, spin)
1101 : INTEGER, INTENT(IN) :: round, spin
1102 :
1103 24874 : IF (use_real_wfn) THEN
1104 156 : CALL kpoint_operator_finish(op_ctx, round, spin, kpoint_slot_ks, fm_re=rksmat)
1105 156 : CALL kpoint_operator_finish(op_ctx, round, spin, kpoint_slot_s, fm_re=rsmat)
1106 156 : IF (round <= kplocal .AND. ASSOCIATED(effective_u)) THEN
1107 0 : CALL lowdin_kp_apply(kpoints%kp_env(round)%kpoint_env, effective_u(:, spin), rmat=rksmat)
1108 : END IF
1109 156 : IF (round <= kplocal .AND. do_diis) THEN
1110 0 : CALL cp_cfm_scale_and_add_fm(z_zero, cksmat, z_one, rksmat)
1111 0 : CALL cp_cfm_scale_and_add_fm(z_zero, csmat, z_one, rsmat)
1112 : END IF
1113 : ELSE
1114 24718 : CALL kpoint_operator_finish(op_ctx, round, spin, kpoint_slot_ks, cksmat)
1115 24718 : IF (round <= kplocal .AND. ASSOCIATED(effective_u)) THEN
1116 0 : CALL lowdin_kp_apply(kpoints%kp_env(round)%kpoint_env, effective_u(:, spin), cmat=cksmat)
1117 : END IF
1118 24718 : IF (.NOT. cache_smat .OR. (.NOT. reuse_smat .AND. spin == 1)) THEN
1119 3468 : CALL kpoint_operator_finish(op_ctx, round, spin, kpoint_slot_s, csmat)
1120 : END IF
1121 : END IF
1122 :
1123 24874 : IF (round > kplocal) RETURN
1124 24874 : kp => kpoints%kp_env(round)%kpoint_env
1125 24874 : IF (cache_smat) THEN
1126 23720 : IF (.NOT. reuse_smat .AND. spin == 1) THEN
1127 2470 : CALL cp_cfm_to_cfm(csmat, kpoints%scf_smat(round))
1128 : ELSE
1129 21250 : CALL cp_cfm_to_cfm(kpoints%scf_smat(round), csmat)
1130 : END IF
1131 : END IF
1132 : END SUBROUTINE harvest_operators
1133 :
1134 : END SUBROUTINE do_general_diag_kp
1135 :
1136 : ! **************************************************************************************************
1137 : !> \brief Execute a local numerical phase. All SCF decisions and collectives belong to the caller.
1138 : !> \param ctx immutable prepared operators
1139 : !> \param kpoints host environment
1140 : !> \param workspace private dense/phase/LAPACK storage per worker
1141 : !> \param scf_env SCF settings (read only during this phase)
1142 : !> \param scf_control SCF control
1143 : !> \param nspin spin count
1144 : !> \param cache_smat retain the unmodified overlap
1145 : !> \param reuse_smat overlap cache is already valid
1146 : !> \param use_adiis shift an ADIIS candidate only
1147 : !> \param ib DIIS insertion index
1148 : !> \param store_error store raw F and its residual instead of solving
1149 : !> \param diis_weight weight of the CDIIS candidate
1150 : !> \param coeffs optional DIIS coefficients for the second phase
1151 : !> \param potential optional Lowdin orbital potential paired with the prepared Hamiltonian
1152 : ! **************************************************************************************************
1153 44936 : SUBROUTINE kp_diag_local_phase(ctx, kpoints, workspace, scf_env, scf_control, nspin, &
1154 44936 : cache_smat, reuse_smat, use_adiis, ib, store_error, diis_weight, coeffs, potential)
1155 : TYPE(kpoint_operator_context_type), INTENT(IN) :: ctx
1156 : TYPE(kpoint_type), POINTER :: kpoints
1157 : TYPE(kp_diag_workspace_type), TARGET, INTENT(INOUT) :: workspace(:)
1158 : TYPE(qs_scf_env_type), POINTER :: scf_env
1159 : TYPE(scf_control_type), POINTER :: scf_control
1160 : INTEGER, INTENT(IN) :: nspin, ib
1161 : LOGICAL, INTENT(IN) :: cache_smat, reuse_smat, use_adiis, store_error
1162 : REAL(KIND=dp), INTENT(IN) :: diis_weight
1163 : COMPLEX(KIND=dp), OPTIONAL, INTENT(IN) :: coeffs(:)
1164 : REAL(dp), OPTIONAL, INTENT(IN) :: potential(:, :)
1165 :
1166 : INTEGER :: ik, ikp, ispin, kplocal, nworkers, thread
1167 : LOGICAL :: build_h, build_s
1168 : TYPE(kpoint_env_type), POINTER :: kp
1169 : TYPE(kp_diag_workspace_type), POINTER :: work
1170 :
1171 44936 : kplocal = kpoints%kp_range(2) - kpoints%kp_range(1) + 1
1172 44936 : nworkers = SIZE(workspace)
1173 44936 : build_s = .NOT. PRESENT(coeffs) .AND. .NOT. reuse_smat
1174 19720 : build_h = .NOT. PRESENT(coeffs) .OR. diis_weight < 1.0_dp
1175 : ! Each one-rank group owns complete matrices: assemble directly into solver storage.
1176 : ! Keep the workspace binding explicit and thread-private for classic ifort.
1177 : !$OMP PARALLEL DO DEFAULT(NONE) SCHEDULE(DYNAMIC, 1) NUM_THREADS(nworkers) IF(nworkers > 1) &
1178 : !$OMP SHARED(ctx,kpoints,workspace,scf_env,scf_control,nspin,cache_smat,reuse_smat,use_adiis,ib, &
1179 : !$OMP store_error,diis_weight,coeffs,potential,kplocal,nworkers,build_h,build_s) &
1180 44936 : !$OMP PRIVATE(ik,ikp,ispin,thread,kp,work)
1181 : DO ikp = 1, kplocal
1182 : thread = 1
1183 : !$ thread = omp_get_thread_num() + 1
1184 : ik = kpoints%kp_range(1) + ikp - 1
1185 : kp => kpoints%kp_env(ikp)%kpoint_env
1186 : work => workspace(thread)
1187 : IF (build_s) THEN
1188 : CALL kpoint_operator_evaluate(ctx, 1, kpoint_slot_s, ik, work%phase, work%csmat_base)
1189 : END IF
1190 : DO ispin = 1, nspin
1191 : IF (build_h) THEN
1192 : IF (PRESENT(coeffs)) THEN
1193 : CALL kpoint_operator_evaluate(ctx, ispin, kpoint_slot_ks, ik, work%phase, work%csmat_base)
1194 : IF (PRESENT(potential)) CALL lowdin_kp_apply(kp, potential(:, ispin), cmat=work%csmat_base)
1195 : ELSE
1196 : CALL kpoint_operator_evaluate(ctx, ispin, kpoint_slot_ks, ik, work%phase, work%cksmat)
1197 : IF (PRESENT(potential)) CALL lowdin_kp_apply(kp, potential(:, ispin), cmat=work%cksmat)
1198 : END IF
1199 : END IF
1200 : IF (PRESENT(coeffs)) THEN
1201 : CALL cp_cfm_to_cfm(kpoints%scf_diis_buffer%smat(ikp), work%csmat)
1202 : CALL kp_diis_candidate(kpoints, ikp, ispin, coeffs, diis_weight, work%cksmat, work%csmat_base)
1203 : ELSE
1204 : IF (reuse_smat) THEN
1205 : CALL cp_cfm_to_cfm(kpoints%scf_smat(ikp), work%csmat)
1206 : ELSE
1207 : CALL cp_cfm_to_cfm(work%csmat_base, work%csmat)
1208 : END IF
1209 : IF (cache_smat .AND. .NOT. reuse_smat .AND. ispin == 1) THEN
1210 : CALL cp_cfm_to_cfm(work%csmat, kpoints%scf_smat(ikp))
1211 : END IF
1212 : END IF
1213 : IF (store_error) THEN
1214 : CALL qs_diis_b_calc_err_kp(kpoints%scf_diis_buffer, ib, kp%mos, work%cksmat, work%csmat, &
1215 : ispin, ikp, work%cmos, local=.TRUE., gemm_ctx=work%gemm_ctx)
1216 : ELSE
1217 : CALL kp_solve_complex(kp%mos(ispin), work, scf_env, scf_control, use_adiis, .TRUE.)
1218 : END IF
1219 : END DO
1220 : END DO
1221 : !$OMP END PARALLEL DO
1222 :
1223 44936 : END SUBROUTINE kp_diag_local_phase
1224 :
1225 : ! **************************************************************************************************
1226 : !> \brief Form the same candidate on local and distributed layouts, preserving raw DIIS history.
1227 : !> \param kpoints host DIIS buffer
1228 : !> \param ikp local k-point index
1229 : !> \param ispin spin index
1230 : !> \param coeffs DIIS coefficients
1231 : !> \param weight CDIIS blend weight
1232 : !> \param fock output candidate
1233 : !> \param adiis_fock ADIIS candidate, read only when weight is less than one
1234 : ! **************************************************************************************************
1235 48600 : SUBROUTINE kp_diis_candidate(kpoints, ikp, ispin, coeffs, weight, fock, adiis_fock)
1236 : TYPE(kpoint_type), POINTER :: kpoints
1237 : INTEGER, INTENT(IN) :: ikp, ispin
1238 : COMPLEX(KIND=dp), INTENT(IN) :: coeffs(:)
1239 : REAL(KIND=dp), INTENT(IN) :: weight
1240 : TYPE(cp_cfm_type), INTENT(INOUT) :: fock
1241 : TYPE(cp_cfm_type), INTENT(IN) :: adiis_fock
1242 :
1243 : INTEGER :: jb
1244 :
1245 48600 : CALL cp_cfm_set_all(fock, z_zero)
1246 211663 : DO jb = 1, SIZE(coeffs)
1247 211663 : CALL cp_cfm_scale_and_add(z_one, fock, coeffs(jb), kpoints%scf_diis_buffer%param(jb, ispin, ikp))
1248 : END DO
1249 48600 : IF (weight < 1.0_dp) CALL cp_cfm_scale_and_add(CMPLX(weight, KIND=dp), fock, &
1250 30 : CMPLX(1.0_dp - weight, KIND=dp), adiis_fock)
1251 48600 : END SUBROUTINE kp_diis_candidate
1252 :
1253 : ! **************************************************************************************************
1254 : !> \brief Shift, solve and publish a complex SCF candidate using private scratch.
1255 : !> \param mos complex MO set
1256 : !> \param work private workspace
1257 : !> \param scf_env SCF settings
1258 : !> \param scf_control SCF control
1259 : !> \param use_adiis apply the candidate shift
1260 : !> \param local select the one-rank local solver; otherwise honor the configured backend
1261 : ! **************************************************************************************************
1262 73095 : SUBROUTINE kp_solve_complex(mos, work, scf_env, scf_control, use_adiis, local)
1263 : TYPE(mo_set_type), INTENT(INOUT) :: mos
1264 : TYPE(kp_diag_workspace_type), INTENT(INOUT) :: work
1265 : TYPE(qs_scf_env_type), POINTER :: scf_env
1266 : TYPE(scf_control_type), POINTER :: scf_control
1267 : LOGICAL, INTENT(IN) :: use_adiis, local
1268 :
1269 73095 : REAL(KIND=dp), POINTER :: eigenvalues(:)
1270 :
1271 73095 : CALL get_mo_set(mos, eigenvalues=eigenvalues)
1272 73095 : IF (use_adiis) CALL shift_candidate_complex(work%cksmat, work%csmat, mos, work%cmos, work%cwork, &
1273 138 : adiis_candidate_shift(scf_env), local, work%gemm_ctx)
1274 73095 : IF (scf_env%cholesky_method == cholesky_off) THEN
1275 4482 : IF (local) THEN
1276 : CALL cp_cfm_geeig_canon_local(work%cksmat, work%csmat, mos%cmo_coeff, eigenvalues, work%cwork, &
1277 1400 : scf_control%eps_eigval, ws=work%solver)
1278 : ELSE
1279 : CALL cp_cfm_geeig_canon(work%cksmat, work%csmat, mos%cmo_coeff, eigenvalues, work%cwork, &
1280 3082 : scf_control%eps_eigval)
1281 : END IF
1282 : ELSE
1283 68613 : IF (local) THEN
1284 46977 : CALL cp_cfm_geeig_local(work%cksmat, work%csmat, mos%cmo_coeff, eigenvalues, ws=work%solver)
1285 : ELSE
1286 21636 : CALL cp_cfm_geeig(work%cksmat, work%csmat, mos%cmo_coeff, eigenvalues, work%cwork)
1287 : END IF
1288 : END IF
1289 73095 : END SUBROUTINE kp_solve_complex
1290 :
1291 : ! **************************************************************************************************
1292 : !> \brief Allocate all worker storage before launching numerical phases.
1293 : !> \param workspace returned private workspaces
1294 : !> \param nworkers number of workers
1295 : !> \param matrix_struct AO layout of the k-point group
1296 : !> \param mo_struct MO layout of the k-point group
1297 : !> \param nentry number of phase-sum entries
1298 : !> \param local allocate local phase and solver scratch
1299 : !> \param canonical use the canonical solver
1300 : ! **************************************************************************************************
1301 35442 : SUBROUTINE kp_diag_workspaces_create(workspace, nworkers, matrix_struct, mo_struct, nentry, local, canonical)
1302 : TYPE(kp_diag_workspace_type), ALLOCATABLE, &
1303 : INTENT(OUT) :: workspace(:)
1304 : INTEGER, INTENT(IN) :: nworkers
1305 : TYPE(cp_fm_struct_type), POINTER :: matrix_struct, mo_struct
1306 : INTEGER, INTENT(IN) :: nentry
1307 : LOGICAL, INTENT(IN) :: local, canonical
1308 :
1309 : INTEGER :: i, n
1310 :
1311 141768 : ALLOCATE (workspace(nworkers))
1312 70884 : DO i = 1, nworkers
1313 35442 : CALL cp_cfm_create(workspace(i)%cksmat, matrix_struct)
1314 35442 : CALL cp_cfm_create(workspace(i)%csmat, matrix_struct)
1315 35442 : CALL cp_cfm_create(workspace(i)%cwork, matrix_struct)
1316 35442 : CALL cp_cfm_create(workspace(i)%cmos, mo_struct)
1317 35442 : IF (.NOT. local) CYCLE
1318 25216 : CALL workspace(i)%gemm_ctx%create(LOCAL_GEMM_PU_GPU, timing=.FALSE.)
1319 25216 : CALL cp_cfm_create(workspace(i)%csmat_base, matrix_struct)
1320 75648 : ALLOCATE (workspace(i)%phase(1, nentry))
1321 25216 : n = matrix_struct%nrow_global
1322 60658 : IF (canonical) THEN
1323 596 : CALL cp_cfm_local_workspace_prepare(workspace(i)%solver, n, workspace(i)%cksmat%local_data)
1324 : ELSE
1325 : CALL cp_cfm_local_workspace_prepare(workspace(i)%solver, n, workspace(i)%cksmat%local_data, &
1326 24620 : workspace(i)%csmat%local_data)
1327 : END IF
1328 : END DO
1329 35442 : END SUBROUTINE kp_diag_workspaces_create
1330 :
1331 : ! **************************************************************************************************
1332 : !> \brief Release dense matrices and automatic phase/LAPACK allocations after all workers finish.
1333 : !> \param workspace private workspaces
1334 : ! **************************************************************************************************
1335 35442 : SUBROUTINE kp_diag_workspaces_release(workspace)
1336 : TYPE(kp_diag_workspace_type), ALLOCATABLE, &
1337 : INTENT(INOUT) :: workspace(:)
1338 :
1339 : INTEGER :: i
1340 :
1341 70884 : DO i = 1, SIZE(workspace)
1342 35442 : CALL workspace(i)%gemm_ctx%destroy()
1343 35442 : CALL cp_cfm_release(workspace(i)%cksmat)
1344 35442 : CALL cp_cfm_release(workspace(i)%csmat)
1345 35442 : CALL cp_cfm_release(workspace(i)%csmat_base)
1346 35442 : CALL cp_cfm_release(workspace(i)%cwork)
1347 70884 : CALL cp_cfm_release(workspace(i)%cmos)
1348 : END DO
1349 70884 : DEALLOCATE (workspace)
1350 35442 : END SUBROUTINE kp_diag_workspaces_release
1351 :
1352 : ! **************************************************************************************************
1353 : !> \brief Kpoint diagonalization routine
1354 : !> Transforms matrices to kpoint, distributes kpoint groups, performs
1355 : !> general diagonalization (no storgae of overlap decomposition), stores
1356 : !> MOs, calculates occupation numbers, calculates density matrices
1357 : !> in kpoint representation, transforms density matrices to real space
1358 : !> \param matrix_ks Kohn-sham matrices (RS indices, global)
1359 : !> \param matrix_s Overlap matrices (RS indices, global)
1360 : !> \param kpoints Kpoint environment
1361 : !> \param fmwork global-layout FM template in the first array entry
1362 : !> \par History
1363 : !> 08.2014 created [JGH]
1364 : ! **************************************************************************************************
1365 22 : SUBROUTINE diag_kp_basic(matrix_ks, matrix_s, kpoints, fmwork)
1366 :
1367 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks, matrix_s
1368 : TYPE(kpoint_type), POINTER :: kpoints
1369 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: fmwork
1370 :
1371 : CHARACTER(len=*), PARAMETER :: routineN = 'diag_kp_basic'
1372 :
1373 : INTEGER :: handle, ikp, ispin, kplocal, kpmax, nspin
1374 : INTEGER, DIMENSION(2) :: kp_range
1375 22 : INTEGER, DIMENSION(:, :), POINTER :: kp_dist
1376 : LOGICAL :: use_real_wfn
1377 22 : REAL(KIND=dp), DIMENSION(:), POINTER :: eigenvalues
1378 : TYPE(cp_cfm_type) :: cksmat, cmos, csmat, cwork
1379 22 : TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_ao_fm_pools
1380 : TYPE(cp_fm_struct_type), POINTER :: matrix_struct, mo_struct
1381 : TYPE(cp_fm_type) :: fmlocal, rksmat, rsmat
1382 : TYPE(cp_fm_type), POINTER :: mo_coeff
1383 : TYPE(kpoint_env_type), POINTER :: kp
1384 22 : TYPE(kpoint_operator_context_type) :: op_ctx
1385 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1386 22 : POINTER :: sab_nl
1387 : TYPE(qs_matrix_pools_type), POINTER :: mpools
1388 :
1389 22 : CALL timeset(routineN, handle)
1390 :
1391 22 : NULLIFY (sab_nl)
1392 : CALL get_kpoint_info(kpoints, use_real_wfn=use_real_wfn, kp_range=kp_range, &
1393 22 : kp_dist=kp_dist, sab_nl=sab_nl)
1394 22 : CPASSERT(ASSOCIATED(sab_nl))
1395 22 : kplocal = kp_range(2) - kp_range(1) + 1
1396 46 : kpmax = MAXVAL(kp_dist(2, :) - kp_dist(1, :) + 1)
1397 :
1398 : ! fm pools to be used within a kpoint group
1399 22 : CALL get_kpoint_info(kpoints, mpools=mpools)
1400 22 : CALL mpools_get(mpools, ao_ao_fm_pools=ao_ao_fm_pools)
1401 :
1402 22 : CALL fm_pool_create_fm(ao_ao_fm_pools(1)%pool, fmlocal)
1403 22 : CALL cp_fm_get_info(fmlocal, matrix_struct=matrix_struct)
1404 :
1405 22 : IF (use_real_wfn) THEN
1406 0 : CALL cp_fm_create(rksmat, matrix_struct)
1407 0 : CALL cp_fm_create(rsmat, matrix_struct)
1408 : ELSE
1409 22 : CALL cp_cfm_create(cksmat, matrix_struct)
1410 22 : CALL cp_cfm_create(csmat, matrix_struct)
1411 22 : CALL cp_cfm_create(cwork, matrix_struct)
1412 22 : kp => kpoints%kp_env(1)%kpoint_env
1413 22 : mo_struct => kp%mos(1)%cmo_coeff%matrix_struct
1414 22 : CALL cp_cfm_create(cmos, mo_struct)
1415 : END IF
1416 :
1417 22 : nspin = SIZE(matrix_ks, 1)
1418 22 : CALL kpoint_operator_context_create(op_ctx, kpoints, fmwork(1), nspin)
1419 22 : CALL kpoint_operator_prepare(op_ctx, matrix_ks, kpoint_slot_ks)
1420 22 : CALL kpoint_operator_prepare(op_ctx, matrix_s, kpoint_slot_s, matrix_row=kpoint_spin_free)
1421 94 : DO ikp = 1, kpmax
1422 166 : DO ispin = 1, nspin
1423 : CALL kpoint_operator_start(op_ctx, ikp, ispin, matrix_ks, kpoint_slot_ks, &
1424 72 : use_grid=.FALSE., matrix_row=ispin)
1425 : CALL kpoint_operator_start(op_ctx, ikp, ispin, matrix_s, kpoint_slot_s, &
1426 144 : use_grid=.FALSE., matrix_row=kpoint_spin_free)
1427 : END DO
1428 : END DO
1429 :
1430 : ! Finish communication then diagonalise in each group
1431 94 : DO ikp = 1, kpmax
1432 166 : DO ispin = 1, nspin
1433 72 : IF (use_real_wfn) THEN
1434 0 : CALL kpoint_operator_finish(op_ctx, ikp, ispin, kpoint_slot_ks, fm_re=rksmat)
1435 0 : CALL kpoint_operator_finish(op_ctx, ikp, ispin, kpoint_slot_s, fm_re=rsmat)
1436 : ELSE
1437 72 : CALL kpoint_operator_finish(op_ctx, ikp, ispin, kpoint_slot_ks, cksmat)
1438 72 : CALL kpoint_operator_finish(op_ctx, ikp, ispin, kpoint_slot_s, csmat)
1439 : END IF
1440 :
1441 : ! Each kpoint group has now information on a kpoint to be diagonalized
1442 : ! General eigensolver Hermite or Symmetric
1443 72 : IF (ikp > kplocal) CYCLE
1444 72 : kp => kpoints%kp_env(ikp)%kpoint_env
1445 144 : IF (use_real_wfn) THEN
1446 0 : CALL get_mo_set(kp%mos(ispin), mo_coeff=mo_coeff, eigenvalues=eigenvalues)
1447 0 : CALL cp_fm_geeig(rksmat, rsmat, mo_coeff, eigenvalues, fmlocal)
1448 : ELSE
1449 72 : CALL get_mo_set(kp%mos(ispin), eigenvalues=eigenvalues)
1450 72 : CALL cp_cfm_geeig(cksmat, csmat, cmos, eigenvalues, cwork)
1451 72 : CALL cp_cfm_to_cfm(cmos, kp%mos(ispin)%cmo_coeff)
1452 : END IF
1453 : END DO
1454 : END DO
1455 :
1456 22 : CALL kpoint_operator_context_release(op_ctx)
1457 :
1458 22 : IF (use_real_wfn) THEN
1459 0 : CALL cp_fm_release(rksmat)
1460 0 : CALL cp_fm_release(rsmat)
1461 : ELSE
1462 22 : CALL cp_cfm_release(cksmat)
1463 22 : CALL cp_cfm_release(csmat)
1464 22 : CALL cp_cfm_release(cwork)
1465 22 : CALL cp_cfm_release(cmos)
1466 : END IF
1467 22 : CALL fm_pool_give_back_fm(ao_ao_fm_pools(1)%pool, fmlocal)
1468 :
1469 22 : CALL timestop(handle)
1470 :
1471 44 : END SUBROUTINE diag_kp_basic
1472 :
1473 : ! **************************************************************************************************
1474 : !> \brief inner loop within MOS subspace, to refine occupation and density,
1475 : !> before next diagonalization of the Hamiltonian
1476 : !> \param qs_env ...
1477 : !> \param scf_env ...
1478 : !> \param subspace_env ...
1479 : !> \param mos ...
1480 : !> \param rho ...
1481 : !> \param ks_env ...
1482 : !> \param scf_section ...
1483 : !> \param scf_control ...
1484 : !> \par History
1485 : !> 09.2009 created [MI]
1486 : !> \note it is assumed that when diagonalization is used, also some mixing procedure is active
1487 : ! **************************************************************************************************
1488 10 : SUBROUTINE do_scf_diag_subspace(qs_env, scf_env, subspace_env, mos, rho, &
1489 : ks_env, scf_section, scf_control)
1490 :
1491 : TYPE(qs_environment_type), POINTER :: qs_env
1492 : TYPE(qs_scf_env_type), POINTER :: scf_env
1493 : TYPE(subspace_env_type), POINTER :: subspace_env
1494 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
1495 : TYPE(qs_rho_type), POINTER :: rho
1496 : TYPE(qs_ks_env_type), POINTER :: ks_env
1497 : TYPE(section_vals_type), POINTER :: scf_section
1498 : TYPE(scf_control_type), POINTER :: scf_control
1499 :
1500 : CHARACTER(LEN=*), PARAMETER :: routineN = 'do_scf_diag_subspace'
1501 : REAL(KIND=dp), PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1502 :
1503 : INTEGER :: handle, i, iloop, ispin, nao, nmo, &
1504 : nspin, output_unit
1505 : LOGICAL :: converged
1506 : REAL(dp) :: ene_diff, ene_old, iter_delta, max_val, &
1507 : sum_band, sum_val, t1, t2
1508 10 : REAL(KIND=dp), DIMENSION(:), POINTER :: mo_eigenvalues, mo_occupations
1509 10 : TYPE(cp_1d_r_p_type), ALLOCATABLE, DIMENSION(:) :: eval_first, occ_first
1510 : TYPE(cp_fm_type) :: work
1511 : TYPE(cp_fm_type), POINTER :: c0, chc, evec, mo_coeff
1512 : TYPE(cp_logger_type), POINTER :: logger
1513 10 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s, rho_ao
1514 10 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp
1515 : TYPE(dft_control_type), POINTER :: dft_control
1516 : TYPE(mp_para_env_type), POINTER :: para_env
1517 : TYPE(qs_energy_type), POINTER :: energy
1518 10 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho_atom
1519 :
1520 10 : CALL timeset(routineN, handle)
1521 10 : NULLIFY (c0, chc, energy, evec, matrix_ks, mo_coeff, mo_eigenvalues, &
1522 10 : mo_occupations, dft_control, rho_ao, rho_ao_kp)
1523 :
1524 10 : logger => cp_get_default_logger()
1525 : output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIAG_SUB_SCF", &
1526 10 : extension=".scfLog")
1527 :
1528 : !Extra loop keeping mos unchanged and refining the subspace occupation
1529 10 : nspin = SIZE(mos)
1530 10 : CALL qs_rho_get(rho, rho_ao=rho_ao, rho_ao_kp=rho_ao_kp)
1531 :
1532 40 : ALLOCATE (eval_first(nspin))
1533 40 : ALLOCATE (occ_first(nspin))
1534 20 : DO ispin = 1, nspin
1535 : CALL get_mo_set(mo_set=mos(ispin), &
1536 : nmo=nmo, &
1537 : eigenvalues=mo_eigenvalues, &
1538 10 : occupation_numbers=mo_occupations)
1539 30 : ALLOCATE (eval_first(ispin)%array(nmo))
1540 20 : ALLOCATE (occ_first(ispin)%array(nmo))
1541 50 : eval_first(ispin)%array(1:nmo) = mo_eigenvalues(1:nmo)
1542 70 : occ_first(ispin)%array(1:nmo) = mo_occupations(1:nmo)
1543 : END DO
1544 :
1545 20 : DO ispin = 1, nspin
1546 : ! does not yet handle k-points
1547 10 : CALL dbcsr_copy(subspace_env%p_matrix_store(ispin)%matrix, rho_ao(ispin)%matrix)
1548 20 : CALL dbcsr_copy(rho_ao(ispin)%matrix, scf_env%p_mix_new(ispin, 1)%matrix)
1549 : END DO
1550 :
1551 10 : subspace_env%p_matrix_mix => scf_env%p_mix_new
1552 :
1553 10 : NULLIFY (matrix_ks, energy, para_env, matrix_s)
1554 : CALL get_qs_env(qs_env, &
1555 : matrix_ks=matrix_ks, &
1556 : energy=energy, &
1557 : matrix_s=matrix_s, &
1558 : para_env=para_env, &
1559 10 : dft_control=dft_control)
1560 :
1561 : ! mixing storage allocation
1562 10 : IF (subspace_env%mixing_method >= gspace_mixing_nr) THEN
1563 : CALL mixing_allocate(qs_env, subspace_env%mixing_method, scf_env%p_mix_new, &
1564 0 : scf_env%p_delta, nspin, subspace_env%mixing_store)
1565 0 : IF (dft_control%qs_control%gapw) THEN
1566 0 : CALL get_qs_env(qs_env=qs_env, rho_atom_set=rho_atom)
1567 : CALL mixing_init(subspace_env%mixing_method, rho, subspace_env%mixing_store, &
1568 0 : para_env, rho_atom=rho_atom)
1569 0 : ELSE IF (dft_control%qs_control%dftb .OR. dft_control%qs_control%xtb) THEN
1570 0 : CALL charge_mixing_init(subspace_env%mixing_store)
1571 0 : ELSE IF (dft_control%qs_control%semi_empirical) THEN
1572 0 : CPABORT('SE Code not possible')
1573 : ELSE
1574 0 : CALL mixing_init(subspace_env%mixing_method, rho, subspace_env%mixing_store, para_env)
1575 : END IF
1576 : END IF
1577 :
1578 10 : ene_old = 0.0_dp
1579 : ene_diff = 0.0_dp
1580 10 : IF (output_unit > 0) THEN
1581 0 : WRITE (output_unit, "(/T19,A)") '<<<<<<<<< SUBSPACE ROTATION <<<<<<<<<<'
1582 : WRITE (output_unit, "(T4,A,T13,A,T21,A,T38,A,T51,A,T65,A/,T4,A)") &
1583 0 : "In-step", "Time", "Convergence", "Band ene.", "Total ene.", "Energy diff.", REPEAT("-", 74)
1584 : END IF
1585 :
1586 : ! recalculate density matrix here
1587 :
1588 : ! update of density
1589 10 : CALL qs_rho_update_rho(rho, qs_env=qs_env)
1590 :
1591 22 : DO iloop = 1, subspace_env%max_iter
1592 20 : t1 = m_walltime()
1593 20 : converged = .FALSE.
1594 20 : ene_old = energy%total
1595 :
1596 20 : CALL qs_ks_did_change(ks_env, rho_changed=.TRUE.)
1597 : CALL qs_ks_update_qs_env(qs_env, calculate_forces=.FALSE., &
1598 20 : just_energy=.FALSE., print_active=.FALSE.)
1599 :
1600 20 : max_val = 0.0_dp
1601 20 : sum_val = 0.0_dp
1602 20 : sum_band = 0.0_dp
1603 40 : DO ispin = 1, SIZE(matrix_ks)
1604 : CALL get_mo_set(mo_set=mos(ispin), &
1605 : nao=nao, &
1606 : nmo=nmo, &
1607 : eigenvalues=mo_eigenvalues, &
1608 : occupation_numbers=mo_occupations, &
1609 20 : mo_coeff=mo_coeff)
1610 :
1611 : !compute C'HC
1612 20 : chc => subspace_env%chc_mat(ispin)
1613 20 : evec => subspace_env%c_vec(ispin)
1614 20 : c0 => subspace_env%c0(ispin)
1615 20 : CALL cp_fm_to_fm(mo_coeff, c0)
1616 20 : CALL cp_fm_create(work, c0%matrix_struct)
1617 20 : CALL cp_dbcsr_sm_fm_multiply(matrix_ks(ispin)%matrix, c0, work, nmo)
1618 20 : CALL parallel_gemm('T', 'N', nmo, nmo, nao, rone, c0, work, rzero, chc)
1619 20 : CALL cp_fm_release(work)
1620 : !diagonalize C'HC
1621 20 : CALL choose_eigv_solver(chc, evec, mo_eigenvalues)
1622 :
1623 : !rotate the mos by the eigenvectors of C'HC
1624 20 : CALL parallel_gemm('N', 'N', nao, nmo, nmo, rone, c0, evec, rzero, mo_coeff)
1625 :
1626 20 : IF (.NOT. scf_control%gce%do_gce) THEN
1627 : CALL set_mo_occupation(mo_set=mos(ispin), &
1628 20 : smear=scf_control%smear)
1629 : ELSE
1630 : CALL set_mo_occupation(mo_set=mos(ispin), &
1631 : smear=scf_control%smear, &
1632 0 : gce=scf_control%gce)
1633 : END IF
1634 :
1635 : ! does not yet handle k-points
1636 : CALL calculate_density_matrix(mos(ispin), &
1637 20 : subspace_env%p_matrix_mix(ispin, 1)%matrix)
1638 :
1639 160 : DO i = 1, nmo
1640 100 : sum_band = sum_band + mo_eigenvalues(i)*mo_occupations(i)
1641 : END DO
1642 :
1643 : !check for self consistency
1644 : END DO
1645 :
1646 20 : IF (subspace_env%mixing_method == direct_mixing_nr) THEN
1647 : CALL scf_env_density_mixing(subspace_env%p_matrix_mix, &
1648 20 : scf_env%mixing_store, rho_ao_kp, para_env, iter_delta, iloop)
1649 : ELSE
1650 : CALL self_consistency_check(rho_ao_kp, scf_env%p_delta, para_env, &
1651 0 : subspace_env%p_matrix_mix, delta=iter_delta)
1652 : END IF
1653 :
1654 40 : DO ispin = 1, nspin
1655 : ! does not yet handle k-points
1656 40 : CALL dbcsr_copy(rho_ao(ispin)%matrix, subspace_env%p_matrix_mix(ispin, 1)%matrix)
1657 : END DO
1658 : ! update of density
1659 20 : CALL qs_rho_update_rho(rho, qs_env=qs_env)
1660 : ! Mixing in reciprocal space
1661 20 : IF (subspace_env%mixing_method >= gspace_mixing_nr) THEN
1662 : CALL gspace_mixing(qs_env, scf_env%mixing_method, subspace_env%mixing_store, &
1663 0 : rho, para_env, scf_env%iter_count)
1664 : END IF
1665 :
1666 20 : ene_diff = energy%total - ene_old
1667 : converged = (ABS(ene_diff) < subspace_env%eps_ene .AND. &
1668 20 : iter_delta < subspace_env%eps_adapt*scf_env%iter_delta)
1669 20 : t2 = m_walltime()
1670 20 : IF (output_unit > 0) THEN
1671 : WRITE (output_unit, "(T4,I5,T11,F8.3,T18,E14.4,T34,F12.5,T46,F16.8,T62,E14.4)") &
1672 0 : iloop, t2 - t1, iter_delta, sum_band, energy%total, ene_diff
1673 0 : CALL m_flush(output_unit)
1674 : END IF
1675 22 : IF (converged) THEN
1676 8 : IF (output_unit > 0) WRITE (output_unit, "(T10,A,I6,A,/)") &
1677 0 : " Reached convergence in ", iloop, " iterations "
1678 : EXIT
1679 : END IF
1680 :
1681 : END DO ! iloop
1682 :
1683 10 : NULLIFY (subspace_env%p_matrix_mix)
1684 20 : DO ispin = 1, nspin
1685 : ! does not yet handle k-points
1686 10 : CALL dbcsr_copy(scf_env%p_mix_new(ispin, 1)%matrix, rho_ao(ispin)%matrix)
1687 10 : CALL dbcsr_copy(rho_ao(ispin)%matrix, subspace_env%p_matrix_store(ispin)%matrix)
1688 :
1689 20 : DEALLOCATE (eval_first(ispin)%array, occ_first(ispin)%array)
1690 : END DO
1691 10 : DEALLOCATE (eval_first, occ_first)
1692 :
1693 10 : CALL timestop(handle)
1694 :
1695 10 : END SUBROUTINE do_scf_diag_subspace
1696 :
1697 : ! **************************************************************************************************
1698 : !> \brief ...
1699 : !> \param subspace_env ...
1700 : !> \param qs_env ...
1701 : !> \param mos ...
1702 : ! **************************************************************************************************
1703 2 : SUBROUTINE diag_subspace_allocate(subspace_env, qs_env, mos)
1704 :
1705 : TYPE(subspace_env_type), POINTER :: subspace_env
1706 : TYPE(qs_environment_type), POINTER :: qs_env
1707 : TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
1708 :
1709 : CHARACTER(LEN=*), PARAMETER :: routineN = 'diag_subspace_allocate'
1710 :
1711 : INTEGER :: handle, i, ispin, nmo, nspin
1712 : TYPE(cp_fm_struct_type), POINTER :: fm_struct_tmp
1713 : TYPE(cp_fm_type), POINTER :: mo_coeff
1714 2 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
1715 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1716 2 : POINTER :: sab_orb
1717 :
1718 2 : CALL timeset(routineN, handle)
1719 :
1720 2 : NULLIFY (sab_orb, matrix_s)
1721 : CALL get_qs_env(qs_env=qs_env, sab_orb=sab_orb, &
1722 2 : matrix_s=matrix_s)
1723 :
1724 2 : nspin = SIZE(mos)
1725 : ! *** allocate p_atrix_store ***
1726 2 : IF (.NOT. ASSOCIATED(subspace_env%p_matrix_store)) THEN
1727 2 : CALL dbcsr_allocate_matrix_set(subspace_env%p_matrix_store, nspin)
1728 :
1729 4 : DO i = 1, nspin
1730 2 : ALLOCATE (subspace_env%p_matrix_store(i)%matrix)
1731 : CALL dbcsr_create(matrix=subspace_env%p_matrix_store(i)%matrix, template=matrix_s(1)%matrix, &
1732 2 : name="DENSITY_STORE", matrix_type=dbcsr_type_symmetric)
1733 : CALL cp_dbcsr_alloc_block_from_nbl(subspace_env%p_matrix_store(i)%matrix, &
1734 2 : sab_orb)
1735 4 : CALL dbcsr_set(subspace_env%p_matrix_store(i)%matrix, 0.0_dp)
1736 : END DO
1737 :
1738 : END IF
1739 :
1740 8 : ALLOCATE (subspace_env%chc_mat(nspin))
1741 6 : ALLOCATE (subspace_env%c_vec(nspin))
1742 6 : ALLOCATE (subspace_env%c0(nspin))
1743 :
1744 4 : DO ispin = 1, nspin
1745 2 : CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nmo=nmo)
1746 2 : CALL cp_fm_create(subspace_env%c0(ispin), mo_coeff%matrix_struct)
1747 2 : NULLIFY (fm_struct_tmp)
1748 : CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nmo, ncol_global=nmo, &
1749 : para_env=mo_coeff%matrix_struct%para_env, &
1750 2 : context=mo_coeff%matrix_struct%context)
1751 2 : CALL cp_fm_create(subspace_env%chc_mat(ispin), fm_struct_tmp, "chc")
1752 2 : CALL cp_fm_create(subspace_env%c_vec(ispin), fm_struct_tmp, "vec")
1753 6 : CALL cp_fm_struct_release(fm_struct_tmp)
1754 : END DO
1755 :
1756 2 : CALL timestop(handle)
1757 :
1758 2 : END SUBROUTINE diag_subspace_allocate
1759 :
1760 : ! **************************************************************************************************
1761 : !> \brief the inner loop of scf, specific to diagonalization without S matrix
1762 : !> basically, in goes the ks matrix out goes a new p matrix
1763 : !> \param scf_env ...
1764 : !> \param mos ...
1765 : !> \param matrix_ks ...
1766 : !> \param scf_control ...
1767 : !> \param scf_section ...
1768 : !> \param diis_step ...
1769 : !> \par History
1770 : !> 03.2006 created [Joost VandeVondele]
1771 : ! **************************************************************************************************
1772 17876 : SUBROUTINE do_special_diag(scf_env, mos, matrix_ks, scf_control, &
1773 : scf_section, diis_step)
1774 :
1775 : TYPE(qs_scf_env_type), POINTER :: scf_env
1776 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
1777 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks
1778 : TYPE(scf_control_type), POINTER :: scf_control
1779 : TYPE(section_vals_type), POINTER :: scf_section
1780 : LOGICAL, INTENT(INOUT) :: diis_step
1781 :
1782 : INTEGER :: ispin, nspin
1783 : LOGICAL :: do_level_shift, use_jacobi
1784 : REAL(KIND=dp) :: diis_error
1785 :
1786 17876 : nspin = SIZE(matrix_ks)
1787 :
1788 36518 : DO ispin = 1, nspin
1789 : CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, scf_env%scf_work1(ispin), &
1790 36518 : scf_env%fm_copy_plan(ispin), check_plan=.TRUE.)
1791 : END DO
1792 17876 : IF (scf_env%iter_count > 1 .AND. .NOT. scf_env%skip_diis) THEN
1793 : CALL qs_diis_b_step(scf_env%scf_diis_buffer, mos, scf_env%scf_work1, &
1794 : scf_env%scf_work2, scf_env%iter_delta, diis_error, diis_step, &
1795 : scf_control%eps_diis, scf_control%nmixing, &
1796 15282 : scf_section=scf_section)
1797 : ELSE
1798 2594 : diis_step = .FALSE.
1799 : END IF
1800 :
1801 17876 : IF ((scf_env%iter_count > 1) .AND. (scf_env%iter_delta < scf_control%diagonalization%eps_jacobi)) THEN
1802 18 : use_jacobi = .TRUE.
1803 : ELSE
1804 17858 : use_jacobi = .FALSE.
1805 : END IF
1806 :
1807 : do_level_shift = ((scf_control%level_shift /= 0.0_dp) .AND. &
1808 17876 : ((scf_control%density_guess == core_guess) .OR. (scf_env%iter_count > 1)))
1809 17876 : IF (diis_step) THEN
1810 11870 : scf_env%iter_param = diis_error
1811 11870 : IF (use_jacobi) THEN
1812 18 : scf_env%iter_method = "DIIS/Jacobi"
1813 : ELSE
1814 11852 : scf_env%iter_method = "DIIS/Diag."
1815 : END IF
1816 : ELSE
1817 6006 : IF (scf_env%mixing_method == 1) THEN
1818 6006 : scf_env%iter_param = scf_env%p_mix_alpha
1819 6006 : IF (use_jacobi) THEN
1820 0 : scf_env%iter_method = "P_Mix/Jacobi"
1821 : ELSE
1822 6006 : scf_env%iter_method = "P_Mix/Diag."
1823 : END IF
1824 0 : ELSE IF (scf_env%mixing_method > 1) THEN
1825 0 : scf_env%iter_param = scf_env%mixing_store%alpha
1826 0 : IF (use_jacobi) THEN
1827 0 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Jacobi"
1828 : ELSE
1829 0 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Diag."
1830 : END IF
1831 : END IF
1832 : END IF
1833 17876 : scf_env%iter_delta = 0.0_dp
1834 :
1835 36518 : DO ispin = 1, nspin
1836 : CALL eigensolver_simple(matrix_ks=scf_env%scf_work1(ispin), &
1837 : mo_set=mos(ispin), &
1838 : work=scf_env%scf_work2, &
1839 : do_level_shift=do_level_shift, &
1840 : level_shift=scf_control%level_shift, &
1841 : use_jacobi=use_jacobi, &
1842 36518 : jacobi_threshold=scf_control%diagonalization%jacobi_threshold)
1843 : END DO
1844 :
1845 17876 : IF (.NOT. scf_control%gce%do_gce) THEN
1846 : CALL set_mo_occupation(mo_array=mos, &
1847 17876 : smear=scf_control%smear)
1848 : ELSE
1849 : CALL set_mo_occupation(mo_array=mos, &
1850 : smear=scf_control%smear, &
1851 0 : gce=scf_control%gce)
1852 : END IF
1853 :
1854 36518 : DO ispin = 1, nspin
1855 : ! does not yet handle k-points
1856 : CALL calculate_density_matrix(mos(ispin), &
1857 36518 : scf_env%p_mix_new(ispin, 1)%matrix)
1858 : END DO
1859 :
1860 17876 : END SUBROUTINE do_special_diag
1861 :
1862 : ! **************************************************************************************************
1863 : !> \brief the inner loop of scf, specific to iterative diagonalization using OT
1864 : !> with S matrix; basically, in goes the ks matrix out goes a new p matrix
1865 : !> \param scf_env ...
1866 : !> \param mos ...
1867 : !> \param matrix_ks ...
1868 : !> \param matrix_s ...
1869 : !> \param scf_control ...
1870 : !> \param scf_section ...
1871 : !> \param diis_step ...
1872 : !> \par History
1873 : !> 10.2008 created [JGH]
1874 : ! **************************************************************************************************
1875 202 : SUBROUTINE do_ot_diag(scf_env, mos, matrix_ks, matrix_s, &
1876 : scf_control, scf_section, diis_step)
1877 :
1878 : TYPE(qs_scf_env_type), POINTER :: scf_env
1879 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
1880 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
1881 : TYPE(scf_control_type), POINTER :: scf_control
1882 : TYPE(section_vals_type), POINTER :: scf_section
1883 : LOGICAL, INTENT(INOUT) :: diis_step
1884 :
1885 : INTEGER :: homo, ispin, nmo, nspin
1886 : REAL(KIND=dp) :: diis_error, eps_iter
1887 202 : REAL(KIND=dp), DIMENSION(:), POINTER :: eigenvalues
1888 : TYPE(cp_fm_type), POINTER :: mo_coeff
1889 :
1890 202 : NULLIFY (eigenvalues)
1891 :
1892 202 : nspin = SIZE(matrix_ks)
1893 :
1894 448 : DO ispin = 1, nspin
1895 : CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, &
1896 448 : scf_env%scf_work1(ispin))
1897 : END DO
1898 :
1899 202 : IF ((scf_env%iter_count > 1) .AND. (.NOT. scf_env%skip_diis)) THEN
1900 : CALL qs_diis_b_step(scf_env%scf_diis_buffer, mos, scf_env%scf_work1, &
1901 : scf_env%scf_work2, scf_env%iter_delta, diis_error, diis_step, &
1902 : scf_control%eps_diis, scf_control%nmixing, &
1903 : s_matrix=matrix_s, &
1904 180 : scf_section=scf_section)
1905 : ELSE
1906 22 : diis_step = .FALSE.
1907 : END IF
1908 :
1909 202 : eps_iter = scf_control%diagonalization%eps_iter
1910 202 : IF (diis_step) THEN
1911 130 : scf_env%iter_param = diis_error
1912 130 : scf_env%iter_method = "DIIS/OTdiag"
1913 274 : DO ispin = 1, nspin
1914 : CALL copy_fm_to_dbcsr(scf_env%scf_work1(ispin), &
1915 274 : matrix_ks(ispin)%matrix, keep_sparsity=.TRUE.)
1916 : END DO
1917 130 : eps_iter = MAX(eps_iter, scf_control%diagonalization%eps_adapt*diis_error)
1918 : ELSE
1919 72 : IF (scf_env%mixing_method == 1) THEN
1920 72 : scf_env%iter_param = scf_env%p_mix_alpha
1921 72 : scf_env%iter_method = "P_Mix/OTdiag."
1922 0 : ELSE IF (scf_env%mixing_method > 1) THEN
1923 0 : scf_env%iter_param = scf_env%mixing_store%alpha
1924 0 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/OTdiag."
1925 : END IF
1926 : END IF
1927 :
1928 202 : scf_env%iter_delta = 0.0_dp
1929 :
1930 448 : DO ispin = 1, nspin
1931 : CALL get_mo_set(mos(ispin), &
1932 : mo_coeff=mo_coeff, &
1933 : eigenvalues=eigenvalues, &
1934 : nmo=nmo, &
1935 246 : homo=homo)
1936 : CALL ot_eigensolver(matrix_h=matrix_ks(ispin)%matrix, &
1937 : matrix_s=matrix_s(1)%matrix, &
1938 : matrix_c_fm=mo_coeff, &
1939 : preconditioner=scf_env%ot_preconditioner( &
1940 : MIN(ispin, SIZE(scf_env%ot_preconditioner)))%preconditioner, &
1941 : eps_gradient=eps_iter, &
1942 : iter_max=scf_control%diagonalization%max_iter, &
1943 : silent=.TRUE., &
1944 246 : ot_settings=scf_control%diagonalization%ot_settings)
1945 : CALL calculate_subspace_eigenvalues(mo_coeff, matrix_ks(ispin)%matrix, &
1946 : evals_arg=eigenvalues, &
1947 246 : do_rotation=.TRUE.)
1948 : CALL copy_fm_to_dbcsr(mos(ispin)%mo_coeff, &
1949 694 : mos(ispin)%mo_coeff_b)
1950 : !fm->dbcsr
1951 : END DO
1952 :
1953 : CALL set_mo_occupation(mo_array=mos, &
1954 202 : smear=scf_control%smear)
1955 :
1956 448 : DO ispin = 1, nspin
1957 : ! does not yet handle k-points
1958 : CALL calculate_density_matrix(mos(ispin), &
1959 448 : scf_env%p_mix_new(ispin, 1)%matrix)
1960 : END DO
1961 :
1962 202 : END SUBROUTINE do_ot_diag
1963 :
1964 : ! **************************************************************************************************
1965 : !> \brief fixed-H OT diagonalization for real or complex K-point channels
1966 : !> \param matrix_ks real-space Kohn-Sham matrices
1967 : !> \param matrix_s real-space overlap matrices
1968 : !> \param matrix_t ...
1969 : !> \param kpoints K-point environment
1970 : !> \param scf_env SCF environment
1971 : !> \param scf_control SCF controls
1972 : !> \param diis_step set false; density mixing remains the outer accelerator
1973 : !> \param added_mos_auto_grow request a larger adaptive virtual-space buffer
1974 : ! **************************************************************************************************
1975 94 : SUBROUTINE do_ot_diag_kp(matrix_ks, matrix_s, matrix_t, kpoints, scf_env, scf_control, &
1976 : diis_step, added_mos_auto_grow)
1977 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks, matrix_s, matrix_t
1978 : TYPE(kpoint_type), POINTER :: kpoints
1979 : TYPE(qs_scf_env_type), POINTER :: scf_env
1980 : TYPE(scf_control_type), POINTER :: scf_control
1981 : LOGICAL, INTENT(INOUT) :: diis_step
1982 : LOGICAL, INTENT(OUT) :: added_mos_auto_grow
1983 :
1984 : INTEGER :: ikp, ispin, ks_spin, nspin
1985 : LOGICAL :: store_kinetic, use_real_wfn
1986 : REAL(KIND=dp) :: eps_iter
1987 94 : REAL(KIND=dp), DIMENSION(:), POINTER :: eigenvalues
1988 : TYPE(cp_cfm_type) :: cmo_work
1989 : TYPE(cp_fm_type) :: coeff_im_work
1990 94 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: fmwork
1991 : TYPE(cp_fm_type), POINTER :: coeff_re
1992 : TYPE(dbcsr_type), POINTER :: matrix_h_im, matrix_h_re, matrix_s_im, &
1993 : matrix_s_re, matrix_t_im, matrix_t_re
1994 : TYPE(kpoint_env_type), POINTER :: kp
1995 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1996 94 : POINTER :: sab_nl
1997 :
1998 94 : NULLIFY (coeff_re, eigenvalues, fmwork, kp, matrix_h_im, matrix_h_re, &
1999 94 : matrix_s_im, matrix_s_re, matrix_t_im, matrix_t_re, sab_nl)
2000 94 : added_mos_auto_grow = .FALSE.
2001 94 : diis_step = .FALSE.
2002 94 : eps_iter = scf_control%diagonalization%eps_iter
2003 94 : nspin = SIZE(matrix_ks, 1)
2004 : store_kinetic = scf_control%diagonalization%ot_settings%preconditioner_type == &
2005 94 : ot_precond_full_kinetic
2006 94 : IF (store_kinetic) THEN
2007 0 : CPASSERT(ASSOCIATED(matrix_t))
2008 : END IF
2009 94 : CALL get_kpoint_info(kpoints, use_real_wfn=use_real_wfn, sab_nl=sab_nl)
2010 94 : CPASSERT(ASSOCIATED(sab_nl))
2011 :
2012 : ! A full diagonalization supplies an orthonormal start after initialization or an
2013 : ! ADDED_MOS AUTO resize. Subsequent SCF steps only redistribute H(k) and S(k).
2014 94 : IF (scf_env%iter_count <= 1) THEN
2015 : CALL do_general_diag_kp(matrix_ks, matrix_s, kpoints, scf_env, scf_control, &
2016 10 : .FALSE., diis_step)
2017 : END IF
2018 94 : IF (store_kinetic) THEN
2019 0 : CALL kpoint_operator_store(kpoints, scf_env%scf_work1(1), matrix_ks, matrix_s, matrix_t)
2020 : ELSE
2021 94 : CALL kpoint_operator_store(kpoints, scf_env%scf_work1(1), matrix_ks, matrix_s)
2022 : END IF
2023 :
2024 94 : scf_env%iter_delta = 0.0_dp
2025 266 : DO ikp = 1, SIZE(kpoints%kp_env)
2026 172 : kp => kpoints%kp_env(ikp)%kpoint_env
2027 172 : CPASSERT(ASSOCIATED(kp%ot_hmat) .AND. ASSOCIATED(kp%ot_smat))
2028 172 : IF (SIZE(kp%ot_smat) >= 2) THEN
2029 : CALL kpoint_operator_get_local(matrix_s, kpoints, kp, 1, &
2030 : kp%ot_smat(1), kp%ot_smat(2), &
2031 172 : matrix_s_re, matrix_s_im)
2032 : ELSE
2033 : CALL kpoint_operator_get_local(matrix_s, kpoints, kp, 1, &
2034 : kp%ot_smat(1), kp%ot_smat(1), &
2035 0 : matrix_s_re, matrix_s_im)
2036 0 : CALL dbcsr_set(matrix_s_im, 0.0_dp)
2037 : END IF
2038 172 : IF (store_kinetic) THEN
2039 0 : CPASSERT(ASSOCIATED(kp%ot_tmat))
2040 0 : IF (SIZE(kp%ot_tmat) >= 2) THEN
2041 : CALL kpoint_operator_get_local(matrix_t, kpoints, kp, 1, &
2042 : kp%ot_tmat(1), kp%ot_tmat(2), &
2043 0 : matrix_t_re, matrix_t_im)
2044 : ELSE
2045 : CALL kpoint_operator_get_local(matrix_t, kpoints, kp, 1, &
2046 : kp%ot_tmat(1), kp%ot_tmat(1), &
2047 0 : matrix_t_re, matrix_t_im)
2048 0 : CALL dbcsr_set(matrix_t_im, 0.0_dp)
2049 : END IF
2050 : END IF
2051 344 : DO ispin = 1, nspin
2052 172 : ks_spin = MIN(ispin, SIZE(kp%ot_hmat, 2))
2053 172 : IF (SIZE(kp%ot_hmat, 1) >= 2) THEN
2054 : CALL kpoint_operator_get_local(matrix_ks, kpoints, kp, ks_spin, &
2055 : kp%ot_hmat(1, ks_spin), kp%ot_hmat(2, ks_spin), &
2056 172 : matrix_h_re, matrix_h_im)
2057 : ELSE
2058 : CALL kpoint_operator_get_local(matrix_ks, kpoints, kp, ks_spin, &
2059 : kp%ot_hmat(1, ks_spin), kp%ot_hmat(1, ks_spin), &
2060 0 : matrix_h_re, matrix_h_im)
2061 0 : CALL dbcsr_set(matrix_h_im, 0.0_dp)
2062 : END IF
2063 172 : CALL get_mo_set(kp%mos(ispin), eigenvalues=eigenvalues)
2064 172 : IF (use_real_wfn) THEN
2065 0 : CALL get_mo_set(kp%mos(ispin), mo_coeff=coeff_re)
2066 : CALL cp_fm_create(coeff_im_work, coeff_re%matrix_struct, &
2067 0 : name='real k-point OT imaginary work')
2068 0 : CALL cp_cfm_create(cmo_work, coeff_re%matrix_struct)
2069 0 : CALL cp_cfm_scale_and_add_fm(z_zero, cmo_work, z_one, coeff_re)
2070 : CALL ot_eigensolver_complex(matrix_h=matrix_h_re, matrix_h_im=matrix_h_im, &
2071 : matrix_s=matrix_s_re, matrix_s_im=matrix_s_im, &
2072 : matrix_c_cfm=cmo_work, &
2073 : eps_gradient=eps_iter, &
2074 : iter_max=scf_control%diagonalization%max_iter, &
2075 : eigenvalues=eigenvalues, silent=.TRUE., &
2076 : ot_settings=scf_control%diagonalization%ot_settings, &
2077 : matrix_t=matrix_t_re, matrix_t_im=matrix_t_im, &
2078 0 : mo_set=kp%mos(ispin))
2079 0 : CALL cp_cfm_to_fm(cmo_work, coeff_re, coeff_im_work)
2080 0 : CALL cp_cfm_release(cmo_work)
2081 0 : CALL cp_fm_release(coeff_im_work)
2082 : ELSE
2083 : CALL ot_eigensolver_complex(matrix_h=matrix_h_re, matrix_h_im=matrix_h_im, &
2084 : matrix_s=matrix_s_re, matrix_s_im=matrix_s_im, &
2085 : matrix_c_cfm=kp%mos(ispin)%cmo_coeff, &
2086 : eps_gradient=eps_iter, &
2087 : iter_max=scf_control%diagonalization%max_iter, &
2088 : eigenvalues=eigenvalues, silent=.TRUE., &
2089 : ot_settings=scf_control%diagonalization%ot_settings, &
2090 : matrix_t=matrix_t_re, matrix_t_im=matrix_t_im, &
2091 172 : mo_set=kp%mos(ispin))
2092 : END IF
2093 172 : CALL dbcsr_release_p(matrix_h_re)
2094 344 : CALL dbcsr_release_p(matrix_h_im)
2095 : END DO
2096 172 : CALL dbcsr_release_p(matrix_s_re)
2097 172 : CALL dbcsr_release_p(matrix_s_im)
2098 172 : IF (ASSOCIATED(matrix_t_re)) CALL dbcsr_release_p(matrix_t_re)
2099 266 : IF (ASSOCIATED(matrix_t_im)) CALL dbcsr_release_p(matrix_t_im)
2100 : END DO
2101 :
2102 : CALL kpoint_set_mo_occupation(kpoints, scf_control%smear, &
2103 : added_mos_auto=scf_control%added_mos_auto, &
2104 94 : added_mos_auto_grow=added_mos_auto_grow)
2105 94 : IF (added_mos_auto_grow) RETURN
2106 :
2107 94 : CALL kpoint_density_matrices(kpoints)
2108 94 : fmwork => scf_env%scf_work1
2109 : CALL kpoint_density_transform(kpoints, scf_env%p_mix_new, .FALSE., &
2110 94 : matrix_s(1, 1)%matrix, sab_nl, fmwork, overlap_rs=matrix_s)
2111 94 : IF (scf_env%mixing_method == 0) THEN
2112 0 : scf_env%iter_method = 'NoMix/OTdiag.'
2113 94 : ELSE IF (scf_env%mixing_method == 1) THEN
2114 60 : scf_env%iter_param = scf_env%p_mix_alpha
2115 60 : scf_env%iter_method = 'P_Mix/OTdiag.'
2116 : ELSE
2117 34 : scf_env%iter_param = scf_env%mixing_store%alpha
2118 34 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//'/OTdiag.'
2119 : END IF
2120 94 : END SUBROUTINE do_ot_diag_kp
2121 :
2122 : ! **************************************************************************************************
2123 : !> \brief Solve a set restricted open Kohn-Sham (ROKS) equations based on the
2124 : !> alpha and beta Kohn-Sham matrices from unrestricted Kohn-Sham.
2125 : !> \param scf_env ...
2126 : !> \param mos ...
2127 : !> \param matrix_ks ...
2128 : !> \param matrix_s ...
2129 : !> \param scf_control ...
2130 : !> \param scf_section ...
2131 : !> \param diis_step ...
2132 : !> \param orthogonal_basis ...
2133 : !> \par History
2134 : !> 04.2006 created [MK]
2135 : !> Revised (01.05.06,MK)
2136 : !> \note
2137 : !> this is only a high-spin ROKS.
2138 : ! **************************************************************************************************
2139 1074 : SUBROUTINE do_roks_diag(scf_env, mos, matrix_ks, matrix_s, &
2140 : scf_control, scf_section, diis_step, &
2141 : orthogonal_basis)
2142 :
2143 : ! Literature: - C. C. J. Roothaan, Rev. Mod. Phys. 32, 179 (1960)
2144 : ! - M. F. Guest and V. R. Saunders, Mol. Phys. 28(3), 819 (1974)
2145 : ! - M. Filatov and S. Shaik, Chem. Phys. Lett. 288, 689 (1998)
2146 :
2147 : TYPE(qs_scf_env_type), POINTER :: scf_env
2148 : TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
2149 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
2150 : TYPE(scf_control_type), POINTER :: scf_control
2151 : TYPE(section_vals_type), POINTER :: scf_section
2152 : LOGICAL, INTENT(INOUT) :: diis_step
2153 : LOGICAL, INTENT(IN) :: orthogonal_basis
2154 :
2155 : CHARACTER(LEN=*), PARAMETER :: routineN = 'do_roks_diag'
2156 :
2157 : INTEGER :: handle, homoa, homob, imo, nalpha, nao, &
2158 : nbeta, nmo
2159 : REAL(KIND=dp) :: diis_error, level_shift_loc
2160 1074 : REAL(KIND=dp), DIMENSION(:), POINTER :: eiga, eigb, occa, occb
2161 : TYPE(cp_fm_type), POINTER :: ksa, ksb, mo2ao, moa, mob, ortho, work
2162 :
2163 : ! -------------------------------------------------------------------------
2164 :
2165 1074 : CALL timeset(routineN, handle)
2166 :
2167 1074 : IF (scf_env%cholesky_method == cholesky_inverse) THEN
2168 0 : ortho => scf_env%ortho_m1
2169 : ELSE
2170 1074 : ortho => scf_env%ortho
2171 : END IF
2172 1074 : work => scf_env%scf_work2
2173 :
2174 1074 : ksa => scf_env%scf_work1(1)
2175 1074 : ksb => scf_env%scf_work1(2)
2176 :
2177 1074 : CALL copy_dbcsr_to_fm(matrix_ks(1)%matrix, ksa, scf_env%fm_copy_plan(1), check_plan=.TRUE.)
2178 1074 : CALL copy_dbcsr_to_fm(matrix_ks(2)%matrix, ksb, scf_env%fm_copy_plan(2), check_plan=.TRUE.)
2179 :
2180 : ! Get MO information
2181 :
2182 : CALL get_mo_set(mo_set=mos(1), &
2183 : nao=nao, &
2184 : nmo=nmo, &
2185 : nelectron=nalpha, &
2186 : homo=homoa, &
2187 : eigenvalues=eiga, &
2188 : occupation_numbers=occa, &
2189 1074 : mo_coeff=moa)
2190 :
2191 : CALL get_mo_set(mo_set=mos(2), &
2192 : nelectron=nbeta, &
2193 : homo=homob, &
2194 : eigenvalues=eigb, &
2195 : occupation_numbers=occb, &
2196 1074 : mo_coeff=mob)
2197 :
2198 : ! Define the amount of level-shifting
2199 :
2200 1074 : IF ((scf_control%level_shift /= 0.0_dp) .AND. &
2201 : ((scf_control%density_guess == core_guess) .OR. &
2202 : (scf_control%density_guess == restart_guess) .OR. &
2203 : (scf_env%iter_count > 1))) THEN
2204 20 : level_shift_loc = scf_control%level_shift
2205 : ELSE
2206 1054 : level_shift_loc = 0.0_dp
2207 : END IF
2208 :
2209 : IF ((scf_env%iter_count > 1) .OR. &
2210 1074 : (scf_control%density_guess == core_guess) .OR. &
2211 : (scf_control%density_guess == restart_guess)) THEN
2212 :
2213 : ! Transform the spin unrestricted alpha and beta Kohn-Sham matrices
2214 : ! from AO basis to MO basis: K(MO) = C(T)*K(AO)*C
2215 :
2216 966 : CALL cp_fm_symm("L", "U", nao, nao, 1.0_dp, ksa, moa, 0.0_dp, work)
2217 966 : CALL parallel_gemm("T", "N", nao, nao, nao, 1.0_dp, moa, work, 0.0_dp, ksa)
2218 :
2219 966 : CALL cp_fm_symm("L", "U", nao, nao, 1.0_dp, ksb, moa, 0.0_dp, work)
2220 966 : CALL parallel_gemm("T", "N", nao, nao, nao, 1.0_dp, moa, work, 0.0_dp, ksb)
2221 :
2222 : ! Combine the spin unrestricted alpha and beta Kohn-Sham matrices
2223 : ! in the MO basis
2224 :
2225 966 : IF (scf_control%roks_scheme == general_roks) THEN
2226 : CALL combine_ks_matrices(ksa, ksb, occa, occb, scf_control%roks_f, &
2227 0 : nalpha, nbeta)
2228 966 : ELSE IF (scf_control%roks_scheme == high_spin_roks) THEN
2229 966 : CALL combine_ks_matrices(ksa, ksb, occa, occb, scf_control%roks_parameter)
2230 : ELSE
2231 0 : CPABORT("Unknown ROKS scheme requested")
2232 : END IF
2233 :
2234 : ! Back-transform the restricted open Kohn-Sham matrix from MO basis
2235 : ! to AO basis
2236 :
2237 966 : IF (orthogonal_basis) THEN
2238 : ! Q = C
2239 464 : mo2ao => moa
2240 : ELSE
2241 : ! Q = S*C
2242 502 : mo2ao => mob
2243 : !MK CALL copy_sm_to_fm(matrix_s(1)%matrix,work)
2244 : !MK CALL cp_fm_symm("L", "U",nao, nao, 1.0_dp, work, moa, 0.0_dp, mo2ao)
2245 502 : CALL cp_dbcsr_sm_fm_multiply(matrix_s(1)%matrix, moa, mo2ao, nao)
2246 : END IF
2247 :
2248 : ! K(AO) = Q*K(MO)*Q(T)
2249 :
2250 966 : CALL parallel_gemm("N", "T", nao, nao, nao, 1.0_dp, ksa, mo2ao, 0.0_dp, work)
2251 966 : CALL parallel_gemm("N", "N", nao, nao, nao, 1.0_dp, mo2ao, work, 0.0_dp, ksa)
2252 :
2253 : ELSE
2254 :
2255 : ! No transformation matrix available, yet. The closed shell part,
2256 : ! i.e. the beta Kohn-Sham matrix in AO basis, is taken.
2257 : ! There might be better choices, anyhow.
2258 :
2259 108 : CALL cp_fm_to_fm(ksb, ksa)
2260 :
2261 : END IF
2262 :
2263 : ! Update DIIS buffer and possibly perform DIIS extrapolation step
2264 :
2265 1074 : IF (scf_env%iter_count > 1) THEN
2266 960 : IF (orthogonal_basis) THEN
2267 : CALL qs_diis_b_step(diis_buffer=scf_env%scf_diis_buffer, &
2268 : mo_array=mos, &
2269 : kc=scf_env%scf_work1, &
2270 : sc=work, &
2271 : delta=scf_env%iter_delta, &
2272 : error_max=diis_error, &
2273 : diis_step=diis_step, &
2274 : eps_diis=scf_control%eps_diis, &
2275 : scf_section=scf_section, &
2276 460 : roks=.TRUE.)
2277 460 : CPASSERT(scf_env%iter_delta == scf_env%iter_delta)
2278 : ELSE
2279 : CALL qs_diis_b_step(diis_buffer=scf_env%scf_diis_buffer, &
2280 : mo_array=mos, &
2281 : kc=scf_env%scf_work1, &
2282 : sc=work, &
2283 : delta=scf_env%iter_delta, &
2284 : error_max=diis_error, &
2285 : diis_step=diis_step, &
2286 : eps_diis=scf_control%eps_diis, &
2287 : scf_section=scf_section, &
2288 : s_matrix=matrix_s, &
2289 500 : roks=.TRUE.)
2290 : END IF
2291 : END IF
2292 :
2293 1074 : IF (diis_step) THEN
2294 722 : scf_env%iter_param = diis_error
2295 722 : scf_env%iter_method = "DIIS/Diag."
2296 : ELSE
2297 352 : IF (scf_env%mixing_method == 1) THEN
2298 352 : scf_env%iter_param = scf_env%p_mix_alpha
2299 352 : scf_env%iter_method = "P_Mix/Diag."
2300 0 : ELSE IF (scf_env%mixing_method > 1) THEN
2301 0 : scf_env%iter_param = scf_env%mixing_store%alpha
2302 0 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Diag."
2303 : END IF
2304 : END IF
2305 :
2306 1074 : scf_env%iter_delta = 0.0_dp
2307 :
2308 1074 : IF (level_shift_loc /= 0.0_dp) THEN
2309 :
2310 : ! Transform the current Kohn-Sham matrix from AO to MO basis
2311 : ! for level-shifting using the current MO set
2312 :
2313 20 : CALL cp_fm_symm("L", "U", nao, nao, 1.0_dp, ksa, moa, 0.0_dp, work)
2314 20 : CALL parallel_gemm("T", "N", nao, nao, nao, 1.0_dp, moa, work, 0.0_dp, ksa)
2315 :
2316 : ! Apply level-shifting using 50:50 split of the shift (could be relaxed)
2317 :
2318 60 : DO imo = homob + 1, homoa
2319 60 : CALL cp_fm_add_to_element(ksa, imo, imo, 0.5_dp*level_shift_loc)
2320 : END DO
2321 220 : DO imo = homoa + 1, nmo
2322 220 : CALL cp_fm_add_to_element(ksa, imo, imo, level_shift_loc)
2323 : END DO
2324 :
2325 1054 : ELSE IF (.NOT. orthogonal_basis) THEN
2326 :
2327 : ! Transform the current Kohn-Sham matrix to an orthogonal basis
2328 532 : SELECT CASE (scf_env%cholesky_method)
2329 : CASE (cholesky_reduce)
2330 0 : CALL cp_fm_cholesky_reduce(ksa, ortho)
2331 : CASE (cholesky_restore)
2332 468 : CALL cp_fm_uplo_to_full(ksa, work)
2333 : CALL cp_fm_cholesky_restore(ksa, nao, ortho, work, &
2334 468 : "SOLVE", pos="RIGHT")
2335 : CALL cp_fm_cholesky_restore(work, nao, ortho, ksa, &
2336 468 : "SOLVE", pos="LEFT", transa="T")
2337 : CASE (cholesky_inverse)
2338 0 : CALL cp_fm_uplo_to_full(ksa, work)
2339 : CALL cp_fm_cholesky_restore(ksa, nao, ortho, work, &
2340 0 : "MULTIPLY", pos="RIGHT")
2341 : CALL cp_fm_cholesky_restore(work, nao, ortho, ksa, &
2342 0 : "MULTIPLY", pos="LEFT", transa="T")
2343 : CASE (cholesky_off)
2344 64 : CALL cp_fm_symm("L", "U", nao, nao, 1.0_dp, ksa, ortho, 0.0_dp, work)
2345 596 : CALL parallel_gemm("N", "N", nao, nao, nao, 1.0_dp, ortho, work, 0.0_dp, ksa)
2346 : END SELECT
2347 :
2348 : END IF
2349 :
2350 : ! Diagonalization of the ROKS operator matrix
2351 :
2352 1074 : CALL choose_eigv_solver(ksa, work, eiga)
2353 :
2354 : ! Back-transformation of the orthonormal eigenvectors if needed
2355 :
2356 1074 : IF (level_shift_loc /= 0.0_dp) THEN
2357 : ! Use old MO set for back-transformation if level-shifting was applied
2358 20 : CALL cp_fm_to_fm(moa, ortho)
2359 20 : CALL parallel_gemm("N", "N", nao, nmo, nao, 1.0_dp, ortho, work, 0.0_dp, moa)
2360 : ELSE
2361 1054 : IF (orthogonal_basis) THEN
2362 522 : CALL cp_fm_to_fm(work, moa)
2363 : ELSE
2364 1000 : SELECT CASE (scf_env%cholesky_method)
2365 : CASE (cholesky_reduce, cholesky_restore)
2366 468 : CALL cp_fm_cholesky_restore(work, nmo, ortho, moa, "SOLVE")
2367 : CASE (cholesky_inverse)
2368 0 : CALL cp_fm_cholesky_restore(work, nmo, ortho, moa, "MULTIPLY")
2369 : CASE (cholesky_off)
2370 532 : CALL parallel_gemm("N", "N", nao, nmo, nao, 1.0_dp, ortho, work, 0.0_dp, moa)
2371 : END SELECT
2372 : END IF
2373 : END IF
2374 :
2375 : ! Correct MO eigenvalues, if level-shifting was applied
2376 :
2377 1074 : IF (level_shift_loc /= 0.0_dp) THEN
2378 60 : DO imo = homob + 1, homoa
2379 60 : eiga(imo) = eiga(imo) - 0.5_dp*level_shift_loc
2380 : END DO
2381 220 : DO imo = homoa + 1, nmo
2382 220 : eiga(imo) = eiga(imo) - level_shift_loc
2383 : END DO
2384 : END IF
2385 :
2386 : ! Update also the beta MO set
2387 :
2388 33270 : eigb(:) = eiga(:)
2389 1074 : CALL cp_fm_to_fm(moa, mob)
2390 :
2391 : ! Calculate the new alpha and beta density matrix
2392 :
2393 : ! does not yet handle k-points
2394 1074 : CALL calculate_density_matrix(mos(1), scf_env%p_mix_new(1, 1)%matrix)
2395 1074 : CALL calculate_density_matrix(mos(2), scf_env%p_mix_new(2, 1)%matrix)
2396 :
2397 1074 : CALL timestop(handle)
2398 :
2399 1074 : END SUBROUTINE do_roks_diag
2400 :
2401 : ! **************************************************************************************************
2402 : !> \brief iterative diagonalization using the block Krylov-space approach
2403 : !> \param scf_env ...
2404 : !> \param mos ...
2405 : !> \param matrix_ks ...
2406 : !> \param scf_control ...
2407 : !> \param scf_section ...
2408 : !> \param check_moconv_only ...
2409 : !> \param
2410 : !> \par History
2411 : !> 05.2009 created [MI]
2412 : ! **************************************************************************************************
2413 :
2414 114 : SUBROUTINE do_block_krylov_diag(scf_env, mos, matrix_ks, &
2415 : scf_control, scf_section, check_moconv_only)
2416 :
2417 : TYPE(qs_scf_env_type), POINTER :: scf_env
2418 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
2419 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks
2420 : TYPE(scf_control_type), POINTER :: scf_control
2421 : TYPE(section_vals_type), POINTER :: scf_section
2422 : LOGICAL, INTENT(IN), OPTIONAL :: check_moconv_only
2423 :
2424 : CHARACTER(LEN=*), PARAMETER :: routineN = 'do_block_krylov_diag'
2425 : REAL(KIND=dp), PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
2426 :
2427 : INTEGER :: handle, homo, ispin, iter, nao, nmo, &
2428 : output_unit
2429 : LOGICAL :: converged, my_check_moconv_only
2430 : REAL(dp) :: eps_iter, t1, t2
2431 114 : REAL(KIND=dp), DIMENSION(:), POINTER :: mo_eigenvalues
2432 : TYPE(cp_fm_type), POINTER :: c0, c1, chc, evec, ks, mo_coeff, ortho, &
2433 : work
2434 : TYPE(cp_logger_type), POINTER :: logger
2435 :
2436 228 : logger => cp_get_default_logger()
2437 114 : CALL timeset(routineN, handle)
2438 :
2439 : output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%LANCZOS", &
2440 114 : extension=".scfLog")
2441 :
2442 114 : my_check_moconv_only = .FALSE.
2443 114 : IF (PRESENT(check_moconv_only)) my_check_moconv_only = check_moconv_only
2444 :
2445 114 : NULLIFY (mo_coeff, ortho, work, ks)
2446 114 : NULLIFY (mo_eigenvalues)
2447 114 : NULLIFY (c0, c1)
2448 :
2449 114 : IF (scf_env%cholesky_method == cholesky_inverse) THEN
2450 38 : ortho => scf_env%ortho_m1
2451 : ELSE
2452 76 : ortho => scf_env%ortho
2453 : END IF
2454 114 : work => scf_env%scf_work2
2455 :
2456 228 : DO ispin = 1, SIZE(matrix_ks)
2457 : CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, &
2458 228 : scf_env%scf_work1(ispin), scf_env%fm_copy_plan(ispin), check_plan=.TRUE.)
2459 : END DO
2460 :
2461 114 : IF (scf_env%mixing_method == 1) THEN
2462 0 : scf_env%iter_param = scf_env%p_mix_alpha
2463 0 : scf_env%iter_method = "P_Mix/Lanczos"
2464 : ELSE
2465 : ! scf_env%iter_param = scf_env%mixing_store%alpha
2466 114 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Lanc."
2467 : END IF
2468 :
2469 228 : DO ispin = 1, SIZE(matrix_ks)
2470 :
2471 114 : ks => scf_env%scf_work1(ispin)
2472 114 : CALL cp_fm_uplo_to_full(ks, work)
2473 :
2474 : CALL get_mo_set(mo_set=mos(ispin), &
2475 : nao=nao, &
2476 : nmo=nmo, &
2477 : homo=homo, &
2478 : eigenvalues=mo_eigenvalues, &
2479 114 : mo_coeff=mo_coeff)
2480 :
2481 114 : NULLIFY (c0, c1)
2482 114 : c0 => scf_env%krylov_space%mo_conv(ispin)
2483 114 : c1 => scf_env%krylov_space%mo_refine(ispin)
2484 114 : SELECT CASE (scf_env%cholesky_method)
2485 : CASE (cholesky_reduce)
2486 0 : CALL cp_fm_cholesky_reduce(ks, ortho)
2487 0 : CALL cp_fm_uplo_to_full(ks, work)
2488 0 : CALL cp_fm_cholesky_restore(mo_coeff, nmo, ortho, c0, "MULTIPLY")
2489 : CASE (cholesky_restore)
2490 : CALL cp_fm_cholesky_restore(ks, nao, ortho, work, &
2491 76 : "SOLVE", pos="RIGHT")
2492 : CALL cp_fm_cholesky_restore(work, nao, ortho, ks, &
2493 76 : "SOLVE", pos="LEFT", transa="T")
2494 76 : CALL cp_fm_cholesky_restore(mo_coeff, nmo, ortho, c0, "MULTIPLY")
2495 : CASE (cholesky_inverse)
2496 : CALL cp_fm_cholesky_restore(ks, nao, ortho, work, &
2497 38 : "MULTIPLY", pos="RIGHT")
2498 : CALL cp_fm_cholesky_restore(work, nao, ortho, ks, &
2499 38 : "MULTIPLY", pos="LEFT", transa="T")
2500 152 : CALL cp_fm_cholesky_restore(mo_coeff, nmo, ortho, c0, "SOLVE")
2501 : END SELECT
2502 :
2503 114 : scf_env%krylov_space%nmo_nc = nmo
2504 114 : scf_env%krylov_space%nmo_conv = 0
2505 :
2506 114 : t1 = m_walltime()
2507 114 : IF (output_unit > 0) THEN
2508 0 : WRITE (output_unit, "(/T15,A)") '<<<<<<<<< LANCZOS REFINEMENT <<<<<<<<<<'
2509 : WRITE (output_unit, "(T8,A,T15,A,T23,A,T36,A,T49,A,T60,A,/,T8,A)") &
2510 0 : " Spin ", " Cycle ", &
2511 0 : " conv. MOS ", " B2MAX ", " B2MIN ", " Time", REPEAT("-", 60)
2512 : END IF
2513 114 : eps_iter = MAX(scf_env%krylov_space%eps_conv, scf_env%krylov_space%eps_adapt*scf_env%iter_delta)
2514 114 : iter = 0
2515 114 : converged = .FALSE.
2516 : !Check convergence of MOS
2517 342 : IF (my_check_moconv_only) THEN
2518 :
2519 : CALL lanczos_refinement(scf_env%krylov_space, ks, c0, c1, mo_eigenvalues, &
2520 0 : nao, eps_iter, ispin, check_moconv_only=my_check_moconv_only)
2521 0 : t2 = m_walltime()
2522 0 : IF (output_unit > 0) THEN
2523 : WRITE (output_unit, '(T8,I3,T16,I5,T24,I6,T33,E12.4,2x,E12.4,T60,F8.3)') &
2524 0 : ispin, iter, scf_env%krylov_space%nmo_conv, &
2525 0 : scf_env%krylov_space%max_res_norm, scf_env%krylov_space%min_res_norm, t2 - t1
2526 : END IF
2527 :
2528 : CYCLE
2529 : ELSE
2530 : !Block Lanczos refinement
2531 848 : DO iter = 1, scf_env%krylov_space%max_iter
2532 : CALL lanczos_refinement_2v(scf_env%krylov_space, ks, c0, c1, mo_eigenvalues, &
2533 744 : nao, eps_iter, ispin)
2534 744 : t2 = m_walltime()
2535 744 : IF (output_unit > 0) THEN
2536 : WRITE (output_unit, '(T8,I3,T16,I5,T24,I6,T33,E12.4,2x,E12.4,T60,F8.3)') &
2537 0 : ispin, iter, scf_env%krylov_space%nmo_conv, &
2538 0 : scf_env%krylov_space%max_res_norm, scf_env%krylov_space%min_res_norm, t2 - t1
2539 : END IF
2540 744 : t1 = m_walltime()
2541 848 : IF (scf_env%krylov_space%max_res_norm < eps_iter) THEN
2542 10 : converged = .TRUE.
2543 10 : IF (output_unit > 0) WRITE (output_unit, *) &
2544 0 : " Reached convergence in ", iter, " iterations "
2545 : EXIT
2546 : END IF
2547 : END DO
2548 :
2549 114 : IF (.NOT. converged .AND. output_unit > 0) THEN
2550 : WRITE (output_unit, "(T4, A)") " WARNING Lanczos refinement could "// &
2551 0 : "not converge all the mos:"
2552 0 : WRITE (output_unit, "(T40,A,T70,I10)") " number of not converged mos ", &
2553 0 : scf_env%krylov_space%nmo_nc
2554 0 : WRITE (output_unit, "(T40,A,T70,E10.2)") " max norm of the residual ", &
2555 0 : scf_env%krylov_space%max_res_norm
2556 :
2557 : END IF
2558 :
2559 : ! For the moment skip the re-orthogonalization
2560 : IF (.FALSE.) THEN
2561 : !Re-orthogonalization
2562 : NULLIFY (chc, evec)
2563 : chc => scf_env%krylov_space%chc_mat(ispin)
2564 : evec => scf_env%krylov_space%c_vec(ispin)
2565 : CALL parallel_gemm('N', 'N', nao, nmo, nao, rone, ks, c0, rzero, work)
2566 : CALL parallel_gemm('T', 'N', nmo, nmo, nao, rone, c0, work, rzero, chc)
2567 : !Diagonalize (C^t)HC
2568 : CALL choose_eigv_solver(chc, evec, mo_eigenvalues)
2569 : !Rotate the C vectors
2570 : CALL parallel_gemm('N', 'N', nao, nmo, nmo, rone, c0, evec, rzero, c1)
2571 : c0 => scf_env%krylov_space%mo_refine(ispin)
2572 : END IF
2573 :
2574 114 : IF (scf_env%cholesky_method == cholesky_inverse) THEN
2575 38 : CALL cp_fm_cholesky_restore(c0, nmo, ortho, mo_coeff, "MULTIPLY")
2576 : ELSE
2577 76 : CALL cp_fm_cholesky_restore(c0, nmo, ortho, mo_coeff, "SOLVE")
2578 : END IF
2579 :
2580 114 : IF (.NOT. scf_control%gce%do_gce) THEN
2581 : CALL set_mo_occupation(mo_set=mos(ispin), &
2582 114 : smear=scf_control%smear)
2583 : ELSE
2584 : CALL set_mo_occupation(mo_set=mos(ispin), &
2585 : smear=scf_control%smear, &
2586 0 : gce=scf_control%gce)
2587 : END IF
2588 :
2589 : ! does not yet handle k-points
2590 : CALL calculate_density_matrix(mos(ispin), &
2591 114 : scf_env%p_mix_new(ispin, 1)%matrix)
2592 : END IF
2593 : END DO ! ispin
2594 :
2595 114 : IF (output_unit > 0) THEN
2596 0 : WRITE (output_unit, "(T15,A/)") '<<<<<<<<< END LANCZOS REFINEMENT <<<<<<<<<<'
2597 : END IF
2598 :
2599 : CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
2600 114 : "PRINT%LANCZOS")
2601 :
2602 114 : CALL timestop(handle)
2603 :
2604 114 : END SUBROUTINE do_block_krylov_diag
2605 :
2606 : ! **************************************************************************************************
2607 : !> \brief iterative diagonalization using the block davidson space approach
2608 : !> \param qs_env ...
2609 : !> \param scf_env ...
2610 : !> \param mos ...
2611 : !> \param matrix_ks ...
2612 : !> \param matrix_s ...
2613 : !> \param scf_control ...
2614 : !> \param scf_section ...
2615 : !> \param check_moconv_only ...
2616 : !> \param
2617 : !> \par History
2618 : !> 05.2011 created [MI]
2619 : ! **************************************************************************************************
2620 :
2621 94 : SUBROUTINE do_block_davidson_diag(qs_env, scf_env, mos, matrix_ks, matrix_s, &
2622 : scf_control, scf_section, check_moconv_only)
2623 :
2624 : TYPE(qs_environment_type), POINTER :: qs_env
2625 : TYPE(qs_scf_env_type), POINTER :: scf_env
2626 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
2627 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
2628 : TYPE(scf_control_type), POINTER :: scf_control
2629 : TYPE(section_vals_type), POINTER :: scf_section
2630 : LOGICAL, INTENT(IN), OPTIONAL :: check_moconv_only
2631 :
2632 : CHARACTER(LEN=*), PARAMETER :: routineN = 'do_block_davidson_diag'
2633 :
2634 : INTEGER :: handle, ispin, nspins, output_unit
2635 : LOGICAL :: do_prec, my_check_moconv_only
2636 : TYPE(cp_logger_type), POINTER :: logger
2637 :
2638 94 : logger => cp_get_default_logger()
2639 94 : CALL timeset(routineN, handle)
2640 :
2641 : output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DAVIDSON", &
2642 94 : extension=".scfLog")
2643 :
2644 94 : IF (output_unit > 0) THEN
2645 0 : WRITE (output_unit, "(/T15,A)") '<<<<<<<<< DAVIDSON ITERATIONS <<<<<<<<<<'
2646 : END IF
2647 :
2648 94 : IF (scf_env%mixing_method == 1) THEN
2649 0 : scf_env%iter_param = scf_env%p_mix_alpha
2650 0 : scf_env%iter_method = "P_Mix/Dav."
2651 : ELSE
2652 94 : scf_env%iter_param = scf_env%mixing_store%alpha
2653 94 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Dav."
2654 : END IF
2655 :
2656 94 : my_check_moconv_only = .FALSE.
2657 94 : IF (PRESENT(check_moconv_only)) my_check_moconv_only = check_moconv_only
2658 94 : do_prec = .FALSE.
2659 94 : IF (scf_env%block_davidson_env(1)%prec_type /= 0 .AND. &
2660 : scf_env%iter_count >= scf_env%block_davidson_env(1)%first_prec) THEN
2661 84 : do_prec = .TRUE.
2662 : END IF
2663 :
2664 94 : nspins = SIZE(matrix_ks)
2665 :
2666 94 : IF (do_prec .AND. (scf_env%iter_count == scf_env%block_davidson_env(1)%first_prec .OR. &
2667 : MODULO(scf_env%iter_count, scf_env%block_davidson_env(1)%niter_new_prec) == 0)) THEN
2668 : CALL restart_preconditioner(qs_env, scf_env%ot_preconditioner, &
2669 18 : prec_type=scf_env%block_davidson_env(1)%prec_type, nspins=nspins)
2670 : CALL prepare_preconditioner(qs_env, mos, matrix_ks, matrix_s, scf_env%ot_preconditioner, &
2671 : scf_env%block_davidson_env(1)%prec_type, &
2672 : scf_env%block_davidson_env(1)%solver_type, &
2673 : scf_env%block_davidson_env(1)%energy_gap, nspins, &
2674 : convert_to_dbcsr=scf_env%block_davidson_env(1)%use_sparse_mos, &
2675 18 : full_mo_set=.TRUE.)
2676 : END IF
2677 :
2678 198 : DO ispin = 1, nspins
2679 198 : IF (scf_env%block_davidson_env(ispin)%use_sparse_mos) THEN
2680 64 : IF (.NOT. do_prec) THEN
2681 : CALL generate_extended_space_sparse(scf_env%block_davidson_env(ispin), mos(ispin), &
2682 8 : matrix_ks(ispin)%matrix, matrix_s(1)%matrix, output_unit)
2683 : ELSE
2684 : CALL generate_extended_space_sparse(scf_env%block_davidson_env(ispin), mos(ispin), &
2685 : matrix_ks(ispin)%matrix, matrix_s(1)%matrix, output_unit, &
2686 56 : scf_env%ot_preconditioner(ispin)%preconditioner)
2687 : END IF
2688 :
2689 : ELSE
2690 40 : IF (.NOT. do_prec) THEN
2691 : CALL generate_extended_space(scf_env%block_davidson_env(ispin), mos(ispin), &
2692 4 : matrix_ks(ispin)%matrix, matrix_s(1)%matrix, output_unit)
2693 : ELSE
2694 : CALL generate_extended_space(scf_env%block_davidson_env(ispin), mos(ispin), &
2695 : matrix_ks(ispin)%matrix, matrix_s(1)%matrix, output_unit, &
2696 36 : scf_env%ot_preconditioner(ispin)%preconditioner)
2697 : END IF
2698 : END IF
2699 : END DO !ispin
2700 :
2701 94 : IF (.NOT. scf_control%gce%do_gce) THEN
2702 : CALL set_mo_occupation(mo_array=mos, &
2703 94 : smear=scf_control%smear)
2704 : ELSE
2705 : CALL set_mo_occupation(mo_array=mos, &
2706 : smear=scf_control%smear, &
2707 0 : gce=scf_control%gce)
2708 : END IF
2709 :
2710 198 : DO ispin = 1, nspins
2711 : ! does not yet handle k-points
2712 : CALL calculate_density_matrix(mos(ispin), &
2713 198 : scf_env%p_mix_new(ispin, 1)%matrix)
2714 : END DO
2715 :
2716 94 : IF (output_unit > 0) THEN
2717 0 : WRITE (output_unit, "(T15,A/)") '<<<<<<<<< END DAVIDSON ITERATION <<<<<<<<<<'
2718 : END IF
2719 :
2720 : CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
2721 94 : "PRINT%DAVIDSON")
2722 :
2723 94 : CALL timestop(handle)
2724 :
2725 94 : END SUBROUTINE do_block_davidson_diag
2726 :
2727 : ! **************************************************************************************************
2728 : !> \brief block-Davidson SCF step for complex K points, one channel per
2729 : !> (local kpoint, spin); mirrors do_block_davidson_diag for the
2730 : !> preconditioner scheduling and do_general_diag_kp for the H(k)/S(k)
2731 : !> assembly and the density exit chain
2732 : !> \param qs_env ...
2733 : !> \param scf_env ...
2734 : !> \param matrix_ks_kp real-space Kohn-Sham matrices, dbcsr image set
2735 : !> \param matrix_s_kp real-space overlap matrix, dbcsr image set
2736 : !> \param kpoints ...
2737 : !> \param scf_control ...
2738 : !> \param added_mos_auto_grow ...
2739 : ! **************************************************************************************************
2740 918 : SUBROUTINE do_block_davidson_diag_kp(qs_env, scf_env, matrix_ks_kp, matrix_s_kp, kpoints, &
2741 : scf_control, added_mos_auto_grow)
2742 :
2743 : TYPE(qs_environment_type), POINTER :: qs_env
2744 : TYPE(qs_scf_env_type), POINTER :: scf_env
2745 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks_kp, matrix_s_kp
2746 : TYPE(kpoint_type), POINTER :: kpoints
2747 : TYPE(scf_control_type), POINTER :: scf_control
2748 : LOGICAL, INTENT(OUT), OPTIONAL :: added_mos_auto_grow
2749 :
2750 : CHARACTER(LEN=*), PARAMETER :: routineN = 'do_block_davidson_diag_kp'
2751 : REAL(KIND=dp), PARAMETER :: empty_factor = 5.0_dp, &
2752 : eps_iter_cap = 1.0E-4_dp
2753 :
2754 : INTEGER :: channel, first_prec, handle, ispin, iw, &
2755 : iwork, kplocal, kpmax, local_kpoint, &
2756 : nchannels, nspin, output_unit
2757 : INTEGER, DIMENSION(2) :: kp_range
2758 918 : INTEGER, DIMENSION(:, :), POINTER :: kp_dist
2759 918 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
2760 : LOGICAL :: do_prec, my_added_mos_auto_grow, &
2761 : use_real_wfn
2762 : REAL(KIND=dp) :: eps_iter, eps_iter_empty
2763 918 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: xkp
2764 : TYPE(cp_cfm_type) :: cksmat, csmat, csmat_base
2765 918 : TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_ao_fm_pools, kp_ao_ao_fm_pools
2766 : TYPE(cp_fm_struct_type), POINTER :: matrix_struct
2767 918 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: fmwork
2768 : TYPE(cp_logger_type), POINTER :: logger
2769 : TYPE(kpoint_env_type), POINTER :: kp
2770 918 : TYPE(kpoint_operator_context_type) :: op_ctx
2771 : TYPE(mp_para_env_type), POINTER :: para_env
2772 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
2773 918 : POINTER :: sab_nl
2774 : TYPE(qs_matrix_pools_type), POINTER :: kp_mpools, mpools
2775 : TYPE(section_vals_type), POINTER :: scf_section
2776 :
2777 : ! bounds of the adaptive inner tolerance. The loose phase is capped for
2778 : ! the residual-norm semantics of EPS_ITER. A residual of order 1/k would
2779 : ! leave an eigenvector error of order 10 percent at a typical metallic
2780 : ! gap. Unoccupied MOS converge empty_factor times looser. The tracking
2781 : ! divides the mixing delta by noise_scale: the SCF convergence measure
2782 : ! is the LARGEST ELEMENT of the density residual, in which the
2783 : ! per-column residuals of a whole block accumulate. The measured
2784 : ! amplification is ~20 on a smeared Bi2S3/MoS2 slab, so tracking at
2785 : ! delta/100 keeps the injected noise below the outer convergence level.
2786 :
2787 1836 : logger => cp_get_default_logger()
2788 918 : CALL timeset(routineN, handle)
2789 :
2790 918 : scf_section => section_vals_get_subs_vals(qs_env%input, "DFT%SCF")
2791 : output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DAVIDSON", &
2792 918 : extension=".scfLog")
2793 918 : IF (output_unit > 0) THEN
2794 0 : WRITE (output_unit, "(/T15,A)") '<<<<<<<<< DAVIDSON ITERATIONS <<<<<<<<<<'
2795 : END IF
2796 :
2797 : CALL get_kpoint_info(kpoints, kp_range=kp_range, kp_dist=kp_dist, xkp=xkp, &
2798 : use_real_wfn=use_real_wfn, sab_nl=sab_nl, &
2799 918 : cell_to_index=cell_to_index, mpools=kp_mpools)
2800 918 : IF (use_real_wfn) THEN
2801 0 : CPABORT('Davidson Kp requires complex K-point MOS')
2802 : END IF
2803 918 : para_env => kpoints%blacs_env_all%para_env
2804 918 : kplocal = kp_range(2) - kp_range(1) + 1
2805 2408 : kpmax = MAXVAL(kp_dist(2, :) - kp_dist(1, :) + 1)
2806 918 : nspin = SIZE(matrix_ks_kp, 1)
2807 918 : nchannels = kplocal*nspin
2808 :
2809 918 : IF (scf_env%mixing_method == 1) THEN
2810 684 : scf_env%iter_param = scf_env%p_mix_alpha
2811 684 : scf_env%iter_method = "P_Mix/Dav."
2812 234 : ELSE IF (scf_env%mixing_method > 1) THEN
2813 234 : scf_env%iter_param = scf_env%mixing_store%alpha
2814 234 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Dav."
2815 : END IF
2816 :
2817 : ! preconditioner scheduling, mirrors do_block_davidson_diag. The first
2818 : ! K-point SCF step cold-starts unless extrapolation prefilled the MOS
2819 : ! (mos_prefilled). The FULL_ALL maker consumes the MO coefficients and
2820 : ! eigenvalues, so building before the first solve completed would feed it
2821 : ! uninitialized data and stall the Davidson convergence. Keep first_prec
2822 : ! clamped past that step in both cases. Warming it up under prefilled MOS
2823 : ! would mix two variables at once.
2824 918 : first_prec = MAX(scf_env%block_davidson_env(1)%first_prec, 2)
2825 918 : do_prec = .FALSE.
2826 918 : IF (scf_env%block_davidson_env(1)%prec_type /= ot_precond_none .AND. &
2827 : scf_env%iter_count >= first_prec) THEN
2828 818 : do_prec = .TRUE.
2829 : END IF
2830 : ! adaptive inner tolerance from EPS_ADAPT: loose while the density is
2831 : ! still far from self-consistency, tightening with the outer error
2832 : ! scaled by noise_scale (mirrors the block Krylov scheduling in
2833 : ! do_block_krylov_diag). The
2834 : ! ratchet is monotone across SCF steps: the threshold may tighten but
2835 : ! never relax again. A rebounding outer error would otherwise re-loosen
2836 : ! the solver, and the run could stop on a near-zero mixing delta of a
2837 : ! pair of identical, sloppily converged densities. The cap bounds the
2838 : ! early loose phase. Unoccupied MOS converge empty_factor times
2839 : ! looser (the occupancy decides which columns qualify, see
2840 : ! generate_extended_space_c). There is no restoration of the
2841 : ! user threshold at the end. The tolerance stays a margin below the
2842 : ! outer error. The MOS the run exits with satisfy that same margin
2843 : ! rather than the nominal EPS_ITER.
2844 918 : eps_iter = scf_env%block_davidson_env(1)%eps_iter
2845 918 : eps_iter_empty = eps_iter
2846 918 : IF (scf_control%diagonalization%eps_adapt > 0.0_dp .AND. scf_env%iter_delta > 0.0_dp) THEN
2847 : ! stall escape: when the mixing delta sank below the tolerance the
2848 : ! last solve used, that solve's own sloppiness may be the noise floor
2849 : ! pinning the delta. Tighten one decade below what that solve used.
2850 : ! Tightening relative to the OPERATING tolerance instead of the
2851 : ! dipped delta bounds the reaction to transient mixing dips (a
2852 : ! momentary overshoot must not collapse the threshold by orders of
2853 : ! magnitude and destabilise the mixer), while a genuine stall moves
2854 : ! the threshold down decade by decade. Checking on the stall alone
2855 : ! keeps the loose phase as loose as EPS_ADAPT allows
2856 86 : IF (scf_env%iter_delta < scf_env%block_davidson_env(1)%eps_iter_used) THEN
2857 : scf_env%block_davidson_env(1)%eps_iter_prev = &
2858 : MIN(scf_env%block_davidson_env(1)%eps_iter_prev, &
2859 : MAX(scf_env%block_davidson_env(1)%eps_iter, &
2860 4 : 0.1_dp*scf_env%block_davidson_env(1)%eps_iter_used))
2861 : END IF
2862 : ! candidate: looser than the user value, capped; ratchet: only
2863 : ! tighter than the previous adaptive value, which lives in the
2864 : ! persistent channel settings (a local variable would reset on
2865 : ! every call into this driver)
2866 : eps_iter = MIN(MAX(eps_iter, MIN(scf_control%diagonalization%eps_adapt*scf_env%iter_delta/ &
2867 : scf_env%block_davidson_env(1)%noise_scale, &
2868 86 : eps_iter_cap)), scf_env%block_davidson_env(1)%eps_iter_prev)
2869 86 : eps_iter_empty = empty_factor*eps_iter
2870 : ! record what this solve uses, after every override above: the outer
2871 : ! loop compares the mixing delta against it (qs_scf_check_inner_exit)
2872 86 : scf_env%block_davidson_env(1)%eps_iter_prev = eps_iter
2873 86 : scf_env%block_davidson_env(1)%eps_iter_used = eps_iter
2874 : END IF
2875 : ! schedule trace of the adaptive tolerance, one line per SCF step at
2876 : ! DEBUG print level
2877 918 : IF (scf_control%diagonalization%eps_adapt > 0.0_dp .AND. para_env%is_source() .AND. &
2878 : logger%iter_info%print_level >= debug_print_level) THEN
2879 0 : iw = cp_logger_get_default_unit_nr()
2880 0 : IF (iw > 0) THEN
2881 : WRITE (UNIT=iw, FMT="(T3,'EPS_ADAPT step',I5,' delta=',ES9.2,' eps_occ=',ES9.2,' eps_empty=',ES9.2)") &
2882 0 : scf_env%iter_count, scf_env%iter_delta, eps_iter, eps_iter_empty
2883 : END IF
2884 : END IF
2885 :
2886 : ! work matrices: global scratch fms (also the operator-context
2887 : ! template), two k-group fms as preconditioner outputs, and the
2888 : ! complex H(k)/S(k)
2889 918 : CALL get_qs_env(qs_env, mpools=mpools)
2890 918 : CALL mpools_get(mpools, ao_ao_fm_pools=ao_ao_fm_pools)
2891 4590 : ALLOCATE (fmwork(4))
2892 4590 : DO iwork = 1, 4
2893 4590 : CALL fm_pool_create_fm(ao_ao_fm_pools(1)%pool, fmwork(iwork))
2894 : END DO
2895 918 : CALL kpoint_operator_context_create(op_ctx, kpoints, fmwork(1), nspin)
2896 918 : CALL kpoint_operator_prepare(op_ctx, matrix_ks_kp, kpoint_slot_ks)
2897 918 : CALL kpoint_operator_prepare(op_ctx, matrix_s_kp, kpoint_slot_s, matrix_row=kpoint_spin_free)
2898 918 : CALL mpools_get(kp_mpools, ao_ao_fm_pools=kp_ao_ao_fm_pools)
2899 918 : matrix_struct => fm_pool_get_el_struct(kp_ao_ao_fm_pools(1)%pool)
2900 918 : CALL cp_cfm_create(cksmat, matrix_struct, name="dav_hk")
2901 918 : CALL cp_cfm_create(csmat, matrix_struct, name="dav_sk")
2902 918 : CALL cp_cfm_create(csmat_base, matrix_struct, name="dav_sk_base")
2903 :
2904 918 : IF (do_prec .AND. (scf_env%iter_count == first_prec .OR. &
2905 : MODULO(scf_env%iter_count, &
2906 : scf_env%block_davidson_env(1)%niter_new_prec) == 0)) THEN
2907 : CALL davidson_kp_prepare_preconditioners( &
2908 58 : qs_env, scf_env, matrix_ks_kp, matrix_s_kp, kpoints, op_ctx)
2909 : END IF
2910 :
2911 2822 : DO local_kpoint = 1, kpmax
2912 : ! Every k-point group executes the same sequence of global transforms.
2913 : ! Groups without a k point in the last round still participate
2914 : ! in the service calls, but skip their local solver work.
2915 : CALL kpoint_operator_get(op_ctx, local_kpoint, kpoint_spin_free, matrix_s_kp, &
2916 1904 : cmat=csmat_base, matrix_row=kpoint_spin_free, slot=kpoint_slot_s)
2917 :
2918 4802 : DO ispin = 1, nspin
2919 : CALL kpoint_operator_get(op_ctx, local_kpoint, ispin, matrix_ks_kp, &
2920 1980 : cmat=cksmat, matrix_row=ispin, slot=kpoint_slot_ks)
2921 1980 : IF (local_kpoint > kplocal) CYCLE
2922 1980 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
2923 1980 : CALL cp_cfm_to_cfm(csmat_base, csmat)
2924 :
2925 3884 : IF (scf_env%iter_count == 1 .AND. .NOT. kp%mos_prefilled) THEN
2926 : ! K-point MOS enter the first SCF step allocated but uninitialized.
2927 : ! The stored S(k) copy is restored for every spin because
2928 : ! cp_cfm_geeig overwrites its matrix arguments.
2929 74 : CALL cold_start_mo_init(kp, ispin, cksmat, csmat)
2930 : ELSE
2931 1906 : channel = (local_kpoint - 1)*nspin + ispin
2932 1906 : IF (do_prec) THEN
2933 : CALL generate_extended_space_c(scf_env%block_davidson_env(channel), &
2934 : kp%mos(ispin), cksmat, csmat, output_unit, &
2935 : eps_iter, eps_iter_empty, &
2936 1778 : scf_env%ot_preconditioner(channel)%preconditioner)
2937 : ELSE
2938 : CALL generate_extended_space_c(scf_env%block_davidson_env(channel), &
2939 : kp%mos(ispin), cksmat, csmat, output_unit, &
2940 128 : eps_iter, eps_iter_empty)
2941 : END IF
2942 : END IF
2943 : END DO
2944 : END DO
2945 :
2946 : ! occupations and density, same exit chain as do_general_diag_kp
2947 : my_added_mos_auto_grow = .FALSE.
2948 : CALL kpoint_set_mo_occupation(kpoints, scf_control%smear, &
2949 : added_mos_auto=scf_control%added_mos_auto, &
2950 918 : added_mos_auto_grow=my_added_mos_auto_grow)
2951 918 : IF (my_added_mos_auto_grow) THEN
2952 : ! the virtual-space buffer is too small for the smearing tail; the
2953 : ! outer loop grows the MOS and redoes this SCF step, the density of
2954 : ! the abandoned step must not be assembled
2955 4 : IF (PRESENT(added_mos_auto_grow)) added_mos_auto_grow = .TRUE.
2956 : ELSE
2957 914 : CALL kpoint_density_matrices(kpoints)
2958 : CALL kpoint_density_transform(kpoints, scf_env%p_mix_new, .FALSE., &
2959 914 : matrix_s_kp(1, 1)%matrix, sab_nl, fmwork, overlap_rs=matrix_s_kp)
2960 : END IF
2961 :
2962 918 : CALL cp_cfm_release(cksmat)
2963 918 : CALL cp_cfm_release(csmat)
2964 918 : CALL cp_cfm_release(csmat_base)
2965 918 : CALL kpoint_operator_context_release(op_ctx)
2966 4590 : DO iwork = 1, 4
2967 4590 : CALL fm_pool_give_back_fm(ao_ao_fm_pools(1)%pool, fmwork(iwork))
2968 : END DO
2969 918 : DEALLOCATE (fmwork)
2970 :
2971 918 : IF (output_unit > 0) THEN
2972 0 : WRITE (output_unit, "(T15,A/)") '<<<<<<<<< END DAVIDSON ITERATION <<<<<<<<<<'
2973 : END IF
2974 : CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
2975 918 : "PRINT%DAVIDSON")
2976 :
2977 918 : CALL timestop(handle)
2978 :
2979 2754 : END SUBROUTINE do_block_davidson_diag_kp
2980 :
2981 : ! **************************************************************************************************
2982 : !> \brief first-SCF-step initialization of the K-point MOS of one spin by one
2983 : !> direct diagonalization of H(k); both arguments are assembled by the
2984 : !> caller because cp_cfm_geeig overwrites them
2985 : !> \param kp kpoint environment holding the complex MO set
2986 : !> \param ispin ...
2987 : !> \param cksmat complex H(k), assembled by the caller
2988 : !> \param csmat complex S(k), assembled by the caller
2989 : ! **************************************************************************************************
2990 148 : SUBROUTINE cold_start_mo_init(kp, ispin, cksmat, csmat)
2991 :
2992 : TYPE(kpoint_env_type), POINTER :: kp
2993 : INTEGER, INTENT(IN) :: ispin
2994 : TYPE(cp_cfm_type) :: cksmat, csmat
2995 :
2996 : CHARACTER(LEN=*), PARAMETER :: routineN = 'cold_start_mo_init'
2997 :
2998 : INTEGER :: handle
2999 74 : REAL(KIND=dp), DIMENSION(:), POINTER :: eigenvalues
3000 : TYPE(cp_cfm_type) :: cwork
3001 :
3002 74 : CALL timeset(routineN, handle)
3003 :
3004 74 : CALL get_mo_set(kp%mos(ispin), eigenvalues=eigenvalues)
3005 74 : CALL cp_cfm_create(cwork, cksmat%matrix_struct, name="dav_cold_cwork")
3006 74 : CALL cp_cfm_geeig(cksmat, csmat, kp%mos(ispin)%cmo_coeff, eigenvalues, cwork)
3007 74 : CALL cp_cfm_release(cwork)
3008 :
3009 74 : CALL timestop(handle)
3010 :
3011 74 : END SUBROUTINE cold_start_mo_init
3012 :
3013 : ! **************************************************************************************************
3014 : !> \brief builds one complex K-point preconditioner per (local kpoint, spin)
3015 : !> channel; mirrors prepare_qs_ot_kpoint_preconditioners
3016 : !> \param qs_env ...
3017 : !> \param scf_env ...
3018 : !> \param matrix_ks_kp ...
3019 : !> \param matrix_s_kp ...
3020 : !> \param kpoints ...
3021 : !> \param op_ctx ...
3022 : ! **************************************************************************************************
3023 58 : SUBROUTINE davidson_kp_prepare_preconditioners( &
3024 : qs_env, scf_env, matrix_ks_kp, matrix_s_kp, kpoints, op_ctx)
3025 :
3026 : TYPE(qs_environment_type), POINTER :: qs_env
3027 : TYPE(qs_scf_env_type), POINTER :: scf_env
3028 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks_kp, matrix_s_kp
3029 : TYPE(kpoint_type), POINTER :: kpoints
3030 : TYPE(kpoint_operator_context_type) :: op_ctx
3031 :
3032 : CHARACTER(LEN=*), PARAMETER :: routineN = 'davidson_kp_prepare_preconditioners'
3033 :
3034 : INTEGER :: channel, handle, ispin, kplocal, kpmax, &
3035 : local_kpoint, nchannels, nmo, nspin, &
3036 : prec_type, solver_type
3037 : INTEGER, DIMENSION(2) :: kp_range
3038 58 : INTEGER, DIMENSION(:, :), POINTER :: kp_dist
3039 58 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
3040 : REAL(KIND=dp) :: energy_gap
3041 58 : REAL(KIND=dp), DIMENSION(:), POINTER :: eigenvalues
3042 58 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: xkp
3043 : TYPE(cp_blacs_env_type), POINTER :: blacs_env
3044 : TYPE(cp_cfm_type) :: matrix_c, matrix_h, matrix_s
3045 58 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_t_kp
3046 : TYPE(dbcsr_type), POINTER :: matrix_h_im, matrix_h_re, matrix_s_im, &
3047 : matrix_s_re, matrix_t_im, matrix_t_re
3048 : TYPE(kpoint_env_type), POINTER :: kp
3049 : TYPE(mp_para_env_type), POINTER :: para_env
3050 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
3051 58 : POINTER :: sab_nl
3052 :
3053 58 : CALL timeset(routineN, handle)
3054 :
3055 : CALL get_kpoint_info(kpoints, kp_range=kp_range, kp_dist=kp_dist, xkp=xkp, sab_nl=sab_nl, &
3056 58 : cell_to_index=cell_to_index)
3057 58 : CALL get_qs_env(qs_env, kinetic_kp=matrix_t_kp)
3058 : ! the preconditioner fms must live on the kpoint-group BLACS context,
3059 : ! the context of the MOS they are applied with
3060 58 : blacs_env => kpoints%blacs_env
3061 58 : para_env => kpoints%para_env_kp
3062 58 : kplocal = kp_range(2) - kp_range(1) + 1
3063 152 : kpmax = MAXVAL(kp_dist(2, :) - kp_dist(1, :) + 1)
3064 58 : nspin = SIZE(matrix_ks_kp, 1)
3065 58 : nchannels = kplocal*nspin
3066 58 : prec_type = scf_env%block_davidson_env(1)%prec_type
3067 58 : solver_type = scf_env%block_davidson_env(1)%solver_type
3068 58 : energy_gap = scf_env%block_davidson_env(1)%energy_gap
3069 :
3070 : ! channel storage: every (kpoint, spin) channel carries its own
3071 : ! preconditioner, because S(k) and H(k) differ per kpoint. The Gamma
3072 : ! reuse pattern of restart_preconditioner (a single entry for the
3073 : ! spin-independent types) must not be used here.
3074 58 : IF (ASSOCIATED(scf_env%ot_preconditioner)) THEN
3075 120 : DO channel = 1, SIZE(scf_env%ot_preconditioner)
3076 120 : IF (ASSOCIATED(scf_env%ot_preconditioner(channel)%preconditioner)) THEN
3077 82 : CALL destroy_preconditioner(scf_env%ot_preconditioner(channel)%preconditioner)
3078 82 : DEALLOCATE (scf_env%ot_preconditioner(channel)%preconditioner)
3079 : END IF
3080 : END DO
3081 38 : DEALLOCATE (scf_env%ot_preconditioner)
3082 38 : NULLIFY (scf_env%ot_preconditioner)
3083 : END IF
3084 302 : ALLOCATE (scf_env%ot_preconditioner(nchannels))
3085 186 : DO channel = 1, nchannels
3086 640 : ALLOCATE (scf_env%ot_preconditioner(channel)%preconditioner)
3087 : CALL init_preconditioner(scf_env%ot_preconditioner(channel)%preconditioner, &
3088 186 : para_env, blacs_env)
3089 : END DO
3090 :
3091 58 : NULLIFY (eigenvalues, matrix_h_im, matrix_h_re, matrix_s_im, matrix_s_re, &
3092 58 : matrix_t_im, matrix_t_re)
3093 58 : IF (prec_type == ot_precond_full_kinetic) THEN
3094 28 : CPASSERT(ASSOCIATED(matrix_t_kp))
3095 28 : CALL kpoint_operator_prepare(op_ctx, matrix_t_kp, kpoint_slot_t, matrix_row=kpoint_spin_free)
3096 : END IF
3097 :
3098 182 : DO local_kpoint = 1, kpmax
3099 : ! S(k) is spin independent. Build it with the same global-group
3100 : ! redistribution protocol as the Davidson operator itself, directly
3101 : ! as the group-local block-cyclic DBCSR pair of the preconditioner
3102 : ! makers.
3103 124 : CALL dbcsr_init_p(matrix_s_re)
3104 124 : CALL dbcsr_init_p(matrix_s_im)
3105 : CALL kpoint_operator_get(op_ctx, local_kpoint, kpoint_spin_free, matrix_s_kp, &
3106 : mat_re=matrix_s_re, mat_im=matrix_s_im, &
3107 124 : matrix_row=kpoint_spin_free, slot=kpoint_slot_s)
3108 :
3109 124 : IF (prec_type == ot_precond_full_kinetic) THEN
3110 56 : CALL dbcsr_init_p(matrix_t_re)
3111 56 : CALL dbcsr_init_p(matrix_t_im)
3112 : CALL kpoint_operator_get(op_ctx, local_kpoint, kpoint_spin_free, matrix_t_kp, &
3113 : mat_re=matrix_t_re, mat_im=matrix_t_im, &
3114 56 : matrix_row=kpoint_spin_free, slot=kpoint_slot_t)
3115 : END IF
3116 :
3117 252 : DO ispin = 1, nspin
3118 128 : IF (prec_type == ot_precond_full_all .OR. prec_type == ot_precond_full_single_inverse) THEN
3119 56 : CALL dbcsr_init_p(matrix_h_re)
3120 56 : CALL dbcsr_init_p(matrix_h_im)
3121 : CALL kpoint_operator_get(op_ctx, local_kpoint, ispin, matrix_ks_kp, &
3122 56 : mat_re=matrix_h_re, mat_im=matrix_h_im, matrix_row=ispin, slot=kpoint_slot_ks)
3123 : END IF
3124 128 : IF (local_kpoint <= kplocal) THEN
3125 128 : kp => kpoints%kp_env(local_kpoint)%kpoint_env
3126 128 : channel = (local_kpoint - 1)*nspin + ispin
3127 128 : IF (prec_type == ot_precond_full_all .OR. prec_type == ot_precond_full_single_inverse) THEN
3128 : ! Davidson iterates the full MO set, so its active space is all nmo
3129 : ! MOs of the channel: assemble the complex channel matrices on the
3130 : ! kpoint-group context and call the complex H-based cores directly
3131 : ! (mirrors the complex preconditioners of the K-point OT case; the
3132 : ! FULL_SINGLE_INVERSE variant trades the state selectivity of
3133 : ! FULL_ALL for one shifted factorization and a gemm application)
3134 : CALL get_mo_set(kp%mos(ispin), eigenvalues=eigenvalues, &
3135 56 : nmo=nmo)
3136 56 : CALL cp_cfm_create(matrix_c, kp%mos(ispin)%cmo_coeff%matrix_struct, name="dav pc C")
3137 56 : CALL cp_cfm_to_cfm(kp%mos(ispin)%cmo_coeff, matrix_c)
3138 : CALL dbcsr_pair_to_cfm(matrix_h_re, matrix_h_im, &
3139 : scf_env%ot_preconditioner(channel)%preconditioner, &
3140 56 : 'dav pc H', matrix_h)
3141 : CALL dbcsr_pair_to_cfm(matrix_s_re, matrix_s_im, &
3142 : scf_env%ot_preconditioner(channel)%preconditioner, &
3143 56 : 'dav pc S', matrix_s)
3144 56 : IF (prec_type == ot_precond_full_all) THEN
3145 : CALL make_complex_full_all(scf_env%ot_preconditioner(channel)%preconditioner, &
3146 : matrix_c, matrix_h, matrix_s, eigenvalues(1:nmo), &
3147 40 : energy_gap)
3148 : ELSE
3149 : CALL make_complex_full_single_inverse( &
3150 : scf_env%ot_preconditioner(channel)%preconditioner, &
3151 16 : matrix_c, matrix_h, matrix_s, energy_gap)
3152 : END IF
3153 56 : CALL cp_cfm_release(matrix_c)
3154 56 : CALL cp_cfm_release(matrix_h)
3155 56 : CALL cp_cfm_release(matrix_s)
3156 72 : ELSE IF (prec_type == ot_precond_full_kinetic) THEN
3157 : CALL make_preconditioner_complex_full_kinetic( &
3158 : scf_env%ot_preconditioner(channel)%preconditioner, &
3159 56 : matrix_t_re, matrix_t_im, matrix_s_re, matrix_s_im, energy_gap, solver_type)
3160 16 : ELSE IF (prec_type == ot_precond_s_inverse) THEN
3161 : CALL make_preconditioner_complex_full_s_inverse( &
3162 : scf_env%ot_preconditioner(channel)%preconditioner, &
3163 16 : matrix_s_re, matrix_s_im, solver_type)
3164 : END IF
3165 : END IF
3166 252 : IF (prec_type == ot_precond_full_all .OR. prec_type == ot_precond_full_single_inverse) THEN
3167 56 : CALL dbcsr_release_p(matrix_h_re)
3168 56 : CALL dbcsr_release_p(matrix_h_im)
3169 : END IF
3170 : END DO
3171 :
3172 124 : CALL dbcsr_release_p(matrix_s_re)
3173 124 : CALL dbcsr_release_p(matrix_s_im)
3174 182 : IF (prec_type == ot_precond_full_kinetic) THEN
3175 56 : CALL dbcsr_release_p(matrix_t_re)
3176 56 : CALL dbcsr_release_p(matrix_t_im)
3177 : END IF
3178 : END DO
3179 :
3180 58 : CALL timestop(handle)
3181 :
3182 58 : END SUBROUTINE davidson_kp_prepare_preconditioners
3183 :
3184 : ! **************************************************************************************************
3185 : !> \brief Kpoint diagonalization routine
3186 : !> Transforms matrices to kpoint, distributes kpoint groups, performs diagonalization
3187 : !> \param matrix_s Overlap matrices (RS indices, global)
3188 : !> \param kpoints Kpoint environment
3189 : !> \param fmwork full matrices distributed over all groups
3190 : !> \param lowdin_forces retain the overlap spectrum for Lowdin force/stress derivatives
3191 : !> \par History
3192 : !> 02.2026 created [JGH]
3193 : ! **************************************************************************************************
3194 132 : SUBROUTINE diag_kp_smat(matrix_s, kpoints, fmwork, lowdin_forces)
3195 :
3196 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_s
3197 : TYPE(kpoint_type), POINTER :: kpoints
3198 : TYPE(cp_fm_type), DIMENSION(:) :: fmwork
3199 : LOGICAL, INTENT(IN), OPTIONAL :: lowdin_forces
3200 :
3201 : CHARACTER(len=*), PARAMETER :: routineN = 'diag_kp_smat'
3202 : COMPLEX(KIND=dp), PARAMETER :: cone = (1.0_dp, 0.0_dp), &
3203 : czero = (0.0_dp, 0.0_dp)
3204 :
3205 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:) :: ceig
3206 : INTEGER :: handle, ikp, kplocal, kpmax, nao
3207 : INTEGER, DIMENSION(2) :: kp_range
3208 132 : INTEGER, DIMENSION(:, :), POINTER :: kp_dist
3209 : LOGICAL :: save_spectrum, use_real_wfn
3210 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues
3211 : TYPE(cp_cfm_type) :: csmat, cwork
3212 132 : TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_ao_fm_pools
3213 : TYPE(cp_fm_struct_type), POINTER :: matrix_struct
3214 : TYPE(cp_fm_type) :: fmlocal, rsmat
3215 : TYPE(kpoint_env_type), POINTER :: kp
3216 132 : TYPE(kpoint_operator_context_type) :: op_ctx
3217 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
3218 132 : POINTER :: sab_nl
3219 : TYPE(qs_matrix_pools_type), POINTER :: mpools
3220 :
3221 132 : CALL timeset(routineN, handle)
3222 :
3223 132 : NULLIFY (sab_nl)
3224 : CALL get_kpoint_info(kpoints, use_real_wfn=use_real_wfn, kp_range=kp_range, &
3225 132 : kp_dist=kp_dist, sab_nl=sab_nl)
3226 132 : CPASSERT(ASSOCIATED(sab_nl))
3227 132 : kplocal = kp_range(2) - kp_range(1) + 1
3228 384 : kpmax = MAXVAL(kp_dist(2, :) - kp_dist(1, :) + 1)
3229 :
3230 : ! fm pools to be used within a kpoint group
3231 132 : CALL get_kpoint_info(kpoints, mpools=mpools)
3232 132 : CALL mpools_get(mpools, ao_ao_fm_pools=ao_ao_fm_pools)
3233 :
3234 132 : CALL fm_pool_create_fm(ao_ao_fm_pools(1)%pool, fmlocal)
3235 132 : CALL cp_fm_get_info(fmlocal, matrix_struct=matrix_struct)
3236 :
3237 132 : IF (use_real_wfn) THEN
3238 0 : CALL cp_fm_create(rsmat, matrix_struct)
3239 : ELSE
3240 132 : CALL cp_cfm_create(csmat, matrix_struct)
3241 132 : CALL cp_cfm_create(cwork, matrix_struct)
3242 : END IF
3243 :
3244 132 : CALL cp_fm_get_info(fmwork(1), nrow_global=nao)
3245 660 : ALLOCATE (eigenvalues(nao), ceig(nao))
3246 :
3247 : ! The overlap is spin free: the routine drives every instance under the
3248 : ! single spin-free key.
3249 132 : CALL kpoint_operator_context_create(op_ctx, kpoints, fmwork(1), 1)
3250 132 : CALL kpoint_operator_prepare(op_ctx, matrix_s, kpoint_slot_s, matrix_row=kpoint_spin_free)
3251 628 : DO ikp = 1, kpmax
3252 : CALL kpoint_operator_start(op_ctx, ikp, kpoint_spin_free, matrix_s, kpoint_slot_s, &
3253 628 : use_grid=.FALSE., matrix_row=kpoint_spin_free)
3254 : END DO
3255 :
3256 : ! Finish communication then diagonalise in each group
3257 628 : DO ikp = 1, kpmax
3258 496 : IF (use_real_wfn) THEN
3259 0 : CALL kpoint_operator_finish(op_ctx, ikp, kpoint_spin_free, kpoint_slot_s, fm_re=rsmat)
3260 : ELSE
3261 496 : CALL kpoint_operator_finish(op_ctx, ikp, kpoint_spin_free, kpoint_slot_s, csmat)
3262 : END IF
3263 :
3264 : ! Each kpoint group has now information on a kpoint to be diagonalized
3265 : ! Eigensolver Hermite or Symmetric
3266 496 : IF (ikp > kplocal) CYCLE
3267 496 : kp => kpoints%kp_env(ikp)%kpoint_env
3268 496 : save_spectrum = ALLOCATED(kp%lowdin_sqrt)
3269 496 : IF (PRESENT(lowdin_forces)) save_spectrum = lowdin_forces
3270 496 : CALL cp_cfm_release(kp%lowdin_evec)
3271 496 : IF (ALLOCATED(kp%lowdin_sqrt)) DEALLOCATE (kp%lowdin_sqrt)
3272 496 : IF (use_real_wfn) THEN
3273 0 : CALL choose_eigv_solver(rsmat, fmlocal, eigenvalues)
3274 : ELSE
3275 496 : CALL cp_cfm_heevd(csmat, cwork, eigenvalues)
3276 : END IF
3277 8440 : CPASSERT(ALL(eigenvalues(1:nao) >= 0.0_dp))
3278 496 : IF (save_spectrum) THEN
3279 384 : IF (ANY(eigenvalues <= 0.0_dp)) THEN
3280 0 : CPABORT("Lowdin forces require a positive definite overlap")
3281 : END IF
3282 32 : ALLOCATE (kp%lowdin_sqrt(nao))
3283 384 : kp%lowdin_sqrt(:) = SQRT(eigenvalues)
3284 16 : CALL cp_cfm_create(kp%lowdin_evec, matrix_struct)
3285 16 : IF (use_real_wfn) THEN
3286 0 : CALL cp_fm_to_cfm(fmlocal, mtarget=kp%lowdin_evec)
3287 : ELSE
3288 16 : CALL cp_cfm_to_cfm(cwork, kp%lowdin_evec)
3289 : END IF
3290 : END IF
3291 628 : IF (use_real_wfn) THEN
3292 0 : CALL cp_fm_release(kp%shalf)
3293 0 : CALL cp_fm_create(kp%shalf, matrix_struct)
3294 0 : eigenvalues(1:nao) = SQRT(eigenvalues(1:nao))
3295 0 : CALL cp_fm_to_fm(fmlocal, rsmat)
3296 0 : CALL cp_fm_column_scale(rsmat, eigenvalues)
3297 : CALL parallel_gemm("N", "T", nao, nao, nao, 1.0_dp, rsmat, fmlocal, &
3298 0 : 0.0_dp, kp%shalf)
3299 : ELSE
3300 496 : CALL cp_cfm_release(kp%cshalf)
3301 496 : CALL cp_cfm_create(kp%cshalf, matrix_struct)
3302 8440 : ceig(1:nao) = SQRT(eigenvalues(1:nao))
3303 496 : CALL cp_cfm_to_cfm(cwork, csmat)
3304 496 : CALL cp_cfm_column_scale(csmat, ceig)
3305 : CALL parallel_gemm("N", "C", nao, nao, nao, cone, csmat, cwork, &
3306 496 : czero, kp%cshalf)
3307 : END IF
3308 : END DO
3309 :
3310 132 : CALL kpoint_operator_context_release(op_ctx)
3311 :
3312 : ! All done
3313 132 : DEALLOCATE (eigenvalues, ceig)
3314 :
3315 132 : IF (use_real_wfn) THEN
3316 0 : CALL cp_fm_release(rsmat)
3317 : ELSE
3318 132 : CALL cp_cfm_release(csmat)
3319 132 : CALL cp_cfm_release(cwork)
3320 : END IF
3321 132 : CALL fm_pool_give_back_fm(ao_ao_fm_pools(1)%pool, fmlocal)
3322 :
3323 132 : CALL timestop(handle)
3324 :
3325 528 : END SUBROUTINE diag_kp_smat
3326 :
3327 : END MODULE qs_scf_diagonalization
|