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_cfm_basic_linalg, ONLY: cp_cfm_column_scale,&
18 : cp_cfm_scale_and_add,&
19 : cp_cfm_scale_and_add_fm
20 : USE cp_cfm_diag, ONLY: cp_cfm_geeig,&
21 : cp_cfm_geeig_canon,&
22 : cp_cfm_heevd
23 : USE cp_cfm_types, ONLY: cp_cfm_create,&
24 : cp_cfm_release,&
25 : cp_cfm_set_all,&
26 : cp_cfm_to_cfm,&
27 : cp_cfm_to_fm,&
28 : cp_cfm_type
29 : USE cp_control_types, ONLY: dft_control_type,&
30 : hairy_probes_type
31 : USE cp_dbcsr_api, ONLY: &
32 : dbcsr_copy, dbcsr_create, dbcsr_deallocate_matrix, dbcsr_desymmetrize, dbcsr_p_type, &
33 : dbcsr_set, dbcsr_type, dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, &
34 : dbcsr_type_symmetric
35 : USE cp_dbcsr_cp2k_link, ONLY: cp_dbcsr_alloc_block_from_nbl
36 : USE cp_dbcsr_operations, ONLY: copy_dbcsr_to_fm,&
37 : copy_fm_to_dbcsr,&
38 : cp_dbcsr_sm_fm_multiply,&
39 : dbcsr_allocate_matrix_set
40 : USE cp_fm_basic_linalg, ONLY: cp_fm_column_scale,&
41 : cp_fm_symm,&
42 : cp_fm_uplo_to_full
43 : USE cp_fm_cholesky, ONLY: cp_fm_cholesky_reduce,&
44 : cp_fm_cholesky_restore
45 : USE cp_fm_diag, ONLY: FM_DIAG_TYPE_CUSOLVER,&
46 : choose_eigv_solver,&
47 : cp_fm_geeig,&
48 : cp_fm_geeig_canon,&
49 : cusolver_generalized,&
50 : diag_type
51 : USE cp_fm_pool_types, ONLY: cp_fm_pool_p_type,&
52 : fm_pool_create_fm,&
53 : fm_pool_give_back_fm
54 : USE cp_fm_struct, ONLY: cp_fm_struct_create,&
55 : cp_fm_struct_release,&
56 : cp_fm_struct_type
57 : USE cp_fm_types, ONLY: &
58 : copy_info_type, cp_fm_add_to_element, cp_fm_cleanup_copy_general, cp_fm_create, &
59 : cp_fm_finish_copy_general, cp_fm_get_info, cp_fm_release, cp_fm_start_copy_general, &
60 : cp_fm_to_fm, cp_fm_type
61 : USE cp_log_handling, ONLY: cp_get_default_logger,&
62 : cp_logger_type
63 : USE cp_output_handling, ONLY: cp_print_key_finished_output,&
64 : cp_print_key_unit_nr
65 : USE input_constants, ONLY: &
66 : cholesky_dbcsr, cholesky_inverse, cholesky_off, cholesky_reduce, cholesky_restore, &
67 : core_guess, general_roks, high_spin_roks, restart_guess
68 : USE input_section_types, ONLY: section_vals_get_subs_vals,&
69 : section_vals_type
70 : USE kinds, ONLY: dp
71 : USE kpoint_methods, ONLY: kpoint_density_matrices,&
72 : kpoint_density_transform,&
73 : kpoint_set_mo_occupation,&
74 : rskp_transform
75 : USE kpoint_types, ONLY: get_kpoint_info,&
76 : kpoint_env_type,&
77 : kpoint_type
78 : USE machine, ONLY: m_flush,&
79 : m_walltime
80 : USE mathconstants, ONLY: gaussi,&
81 : z_one,&
82 : z_zero
83 : USE message_passing, ONLY: mp_para_env_type
84 : USE parallel_gemm_api, ONLY: parallel_gemm
85 : USE preconditioner, ONLY: prepare_preconditioner,&
86 : restart_preconditioner
87 : USE qs_density_matrices, ONLY: calculate_density_matrix
88 : USE qs_density_mixing_types, ONLY: direct_mixing_nr,&
89 : gspace_mixing_nr
90 : USE qs_diis, ONLY: qs_diis_b_calc_err_kp,&
91 : qs_diis_b_info_kp,&
92 : qs_diis_b_step,&
93 : qs_diis_b_step_kp
94 : USE qs_energy_types, ONLY: qs_energy_type
95 : USE qs_environment_types, ONLY: get_qs_env,&
96 : qs_environment_type
97 : USE qs_gspace_mixing, ONLY: gspace_mixing
98 : USE qs_ks_methods, ONLY: qs_ks_update_qs_env
99 : USE qs_ks_types, ONLY: qs_ks_did_change,&
100 : qs_ks_env_type
101 : USE qs_matrix_pools, ONLY: mpools_get,&
102 : qs_matrix_pools_type
103 : USE qs_mixing_utils, ONLY: charge_mixing_init,&
104 : mixing_allocate,&
105 : mixing_init,&
106 : self_consistency_check
107 : USE qs_mo_methods, ONLY: calculate_subspace_eigenvalues
108 : USE qs_mo_occupation, ONLY: set_mo_occupation
109 : USE qs_mo_types, ONLY: get_mo_set,&
110 : mo_set_type
111 : USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
112 : USE qs_ot_eigensolver, ONLY: ot_eigensolver
113 : USE qs_rho_atom_types, ONLY: rho_atom_type
114 : USE qs_rho_methods, ONLY: qs_rho_update_rho
115 : USE qs_rho_types, ONLY: qs_rho_get,&
116 : qs_rho_type
117 : USE qs_scf_block_davidson, ONLY: generate_extended_space,&
118 : generate_extended_space_sparse
119 : USE qs_scf_lanczos, ONLY: lanczos_refinement,&
120 : lanczos_refinement_2v
121 : USE qs_scf_methods, ONLY: combine_ks_matrices,&
122 : eigensolver,&
123 : eigensolver_dbcsr,&
124 : eigensolver_generalized,&
125 : eigensolver_simple,&
126 : eigensolver_symm,&
127 : scf_env_density_mixing
128 : USE qs_scf_types, ONLY: qs_scf_env_type,&
129 : subspace_env_type
130 : USE scf_control_types, ONLY: scf_control_type
131 : #include "./base/base_uses.f90"
132 :
133 : IMPLICIT NONE
134 :
135 : PRIVATE
136 :
137 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_scf_diagonalization'
138 :
139 : PUBLIC :: do_general_diag, do_general_diag_kp, do_roks_diag, &
140 : do_special_diag, do_ot_diag, do_block_davidson_diag, &
141 : do_block_krylov_diag, do_scf_diag_subspace, diag_subspace_allocate, &
142 : general_eigenproblem, diag_kp_smat, diag_kp_basic
143 :
144 : CONTAINS
145 :
146 : ! **************************************************************************************************
147 : !> \brief the inner loop of scf, specific to diagonalization with S matrix
148 : !> basically, in goes the ks matrix out goes a new p matrix
149 : !> \param scf_env ...
150 : !> \param mos ...
151 : !> \param matrix_ks ...
152 : !> \param matrix_s ...
153 : !> \param scf_control ...
154 : !> \param scf_section ...
155 : !> \param diis_step ...
156 : !> \par History
157 : !> 03.2006 created [Joost VandeVondele]
158 : ! **************************************************************************************************
159 :
160 77755 : SUBROUTINE general_eigenproblem(scf_env, mos, matrix_ks, &
161 : matrix_s, scf_control, scf_section, &
162 : diis_step)
163 :
164 : TYPE(qs_scf_env_type), POINTER :: scf_env
165 : TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
166 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
167 : TYPE(scf_control_type), POINTER :: scf_control
168 : TYPE(section_vals_type), POINTER :: scf_section
169 : LOGICAL, INTENT(INOUT) :: diis_step
170 :
171 : INTEGER :: ispin, nspin
172 : LOGICAL :: do_level_shift, owns_ortho, use_jacobi
173 : REAL(KIND=dp) :: diis_error, eps_diis
174 : TYPE(cp_fm_type), POINTER :: ortho
175 : TYPE(dbcsr_type), POINTER :: ortho_dbcsr
176 :
177 77755 : nspin = SIZE(matrix_ks)
178 77755 : NULLIFY (ortho, ortho_dbcsr)
179 :
180 165576 : DO ispin = 1, nspin
181 : CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, &
182 165576 : scf_env%scf_work1(ispin))
183 : END DO
184 :
185 77755 : eps_diis = scf_control%eps_diis
186 :
187 77755 : IF (scf_env%iter_count > 1 .AND. .NOT. scf_env%skip_diis) THEN
188 : CALL qs_diis_b_step(scf_env%scf_diis_buffer, mos, scf_env%scf_work1, &
189 : scf_env%scf_work2, scf_env%iter_delta, diis_error, diis_step, &
190 : eps_diis, scf_control%nmixing, &
191 : s_matrix=matrix_s, &
192 64545 : scf_section=scf_section)
193 : ELSE
194 13210 : diis_step = .FALSE.
195 : END IF
196 :
197 : do_level_shift = ((scf_control%level_shift /= 0.0_dp) .AND. &
198 : ((scf_control%density_guess == core_guess) .OR. &
199 77755 : (scf_env%iter_count > 1)))
200 :
201 77755 : IF ((scf_env%iter_count > 1) .AND. &
202 : (scf_env%iter_delta < scf_control%diagonalization%eps_jacobi)) THEN
203 0 : use_jacobi = .TRUE.
204 : ELSE
205 77755 : use_jacobi = .FALSE.
206 : END IF
207 :
208 77755 : IF (diis_step) THEN
209 45683 : scf_env%iter_param = diis_error
210 45683 : IF (use_jacobi) THEN
211 0 : scf_env%iter_method = "DIIS/Jacobi"
212 : ELSE
213 45683 : scf_env%iter_method = "DIIS/Diag."
214 : END IF
215 : ELSE
216 32072 : IF (scf_env%mixing_method == 0) THEN
217 0 : scf_env%iter_method = "NoMix/Diag."
218 32072 : ELSE IF (scf_env%mixing_method == 1) THEN
219 30342 : scf_env%iter_param = scf_env%p_mix_alpha
220 30342 : IF (use_jacobi) THEN
221 0 : scf_env%iter_method = "P_Mix/Jacobi"
222 : ELSE
223 30342 : scf_env%iter_method = "P_Mix/Diag."
224 : END IF
225 1730 : ELSEIF (scf_env%mixing_method > 1) THEN
226 1730 : scf_env%iter_param = scf_env%mixing_store%alpha
227 1730 : IF (use_jacobi) THEN
228 0 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Jacobi"
229 : ELSE
230 1730 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Diag."
231 : END IF
232 : END IF
233 : END IF
234 :
235 77755 : IF (scf_env%cholesky_method == cholesky_dbcsr) THEN
236 1072 : ortho_dbcsr => scf_env%ortho_dbcsr
237 3198 : DO ispin = 1, nspin
238 : CALL eigensolver_dbcsr(matrix_ks=matrix_ks(ispin)%matrix, matrix_ks_fm=scf_env%scf_work1(ispin), &
239 : mo_set=mos(ispin), &
240 : ortho_dbcsr=ortho_dbcsr, &
241 3198 : ksbuf1=scf_env%buf1_dbcsr, ksbuf2=scf_env%buf2_dbcsr)
242 : END DO
243 :
244 76683 : ELSE IF (scf_env%cholesky_method > cholesky_off) THEN
245 76249 : IF (scf_env%cholesky_method == cholesky_inverse) THEN
246 152 : ortho => scf_env%ortho_m1
247 : ELSE
248 76097 : ortho => scf_env%ortho
249 : END IF
250 :
251 76249 : owns_ortho = .FALSE.
252 76249 : IF (.NOT. ASSOCIATED(ortho)) THEN
253 0 : ALLOCATE (ortho)
254 0 : owns_ortho = .TRUE.
255 : END IF
256 :
257 161428 : DO ispin = 1, nspin
258 161428 : IF (diag_type == FM_DIAG_TYPE_CUSOLVER .AND. cusolver_generalized .AND. .NOT. do_level_shift) THEN
259 : CALL eigensolver_generalized(matrix_ks_fm=scf_env%scf_work1(ispin), &
260 : matrix_s=matrix_s(ispin)%matrix, &
261 : mo_set=mos(ispin), &
262 0 : work=scf_env%scf_work2)
263 : ELSE
264 85179 : IF (do_level_shift) THEN
265 : CALL eigensolver(matrix_ks_fm=scf_env%scf_work1(ispin), &
266 : mo_set=mos(ispin), &
267 : ortho=ortho, &
268 : work=scf_env%scf_work2, &
269 : cholesky_method=scf_env%cholesky_method, &
270 : do_level_shift=do_level_shift, &
271 : level_shift=scf_control%level_shift, &
272 : matrix_u_fm=scf_env%ortho, &
273 124 : use_jacobi=use_jacobi)
274 : ELSE
275 : CALL eigensolver(matrix_ks_fm=scf_env%scf_work1(ispin), &
276 : mo_set=mos(ispin), &
277 : ortho=ortho, &
278 : work=scf_env%scf_work2, &
279 : cholesky_method=scf_env%cholesky_method, &
280 : do_level_shift=do_level_shift, &
281 : level_shift=scf_control%level_shift, &
282 85055 : use_jacobi=use_jacobi)
283 : END IF
284 : END IF
285 : END DO
286 :
287 76249 : IF (owns_ortho) DEALLOCATE (ortho)
288 : ELSE
289 434 : ortho => scf_env%ortho
290 :
291 434 : owns_ortho = .FALSE.
292 434 : IF (.NOT. ASSOCIATED(ortho)) THEN
293 0 : ALLOCATE (ortho)
294 0 : owns_ortho = .TRUE.
295 : END IF
296 :
297 434 : IF (do_level_shift) THEN
298 172 : DO ispin = 1, nspin
299 : IF (ASSOCIATED(scf_env%scf_work1_red) .AND. ASSOCIATED(scf_env%scf_work2_red) &
300 172 : .AND. ASSOCIATED(scf_env%ortho_red) .AND. ASSOCIATED(scf_env%ortho_m1_red)) THEN
301 : CALL eigensolver_symm(matrix_ks_fm=scf_env%scf_work1(ispin), &
302 : mo_set=mos(ispin), &
303 : ortho=ortho, &
304 : work=scf_env%scf_work2, &
305 : do_level_shift=do_level_shift, &
306 : level_shift=scf_control%level_shift, &
307 : matrix_u_fm=scf_env%ortho_m1, &
308 : use_jacobi=use_jacobi, &
309 : jacobi_threshold=scf_control%diagonalization%jacobi_threshold, &
310 : matrix_ks_fm_red=scf_env%scf_work1_red(ispin), &
311 : ortho_red=scf_env%ortho_red, &
312 : work_red=scf_env%scf_work2_red, &
313 86 : matrix_u_fm_red=scf_env%ortho_m1_red)
314 : ELSE
315 : CALL eigensolver_symm(matrix_ks_fm=scf_env%scf_work1(ispin), &
316 : mo_set=mos(ispin), &
317 : ortho=ortho, &
318 : work=scf_env%scf_work2, &
319 : do_level_shift=do_level_shift, &
320 : level_shift=scf_control%level_shift, &
321 : matrix_u_fm=scf_env%ortho_m1, &
322 : use_jacobi=use_jacobi, &
323 0 : jacobi_threshold=scf_control%diagonalization%jacobi_threshold)
324 : END IF
325 : END DO
326 : ELSE
327 778 : DO ispin = 1, nspin
328 : IF (ASSOCIATED(scf_env%scf_work1_red) .AND. ASSOCIATED(scf_env%scf_work2_red) &
329 778 : .AND. ASSOCIATED(scf_env%ortho_red)) THEN
330 : CALL eigensolver_symm(matrix_ks_fm=scf_env%scf_work1(ispin), &
331 : mo_set=mos(ispin), &
332 : ortho=ortho, &
333 : work=scf_env%scf_work2, &
334 : do_level_shift=do_level_shift, &
335 : level_shift=scf_control%level_shift, &
336 : use_jacobi=use_jacobi, &
337 : jacobi_threshold=scf_control%diagonalization%jacobi_threshold, &
338 : matrix_ks_fm_red=scf_env%scf_work1_red(ispin), &
339 : ortho_red=scf_env%ortho_red, &
340 430 : work_red=scf_env%scf_work2_red)
341 : ELSE
342 : CALL eigensolver_symm(matrix_ks_fm=scf_env%scf_work1(ispin), &
343 : mo_set=mos(ispin), &
344 : ortho=ortho, &
345 : work=scf_env%scf_work2, &
346 : do_level_shift=do_level_shift, &
347 : level_shift=scf_control%level_shift, &
348 : use_jacobi=use_jacobi, &
349 0 : jacobi_threshold=scf_control%diagonalization%jacobi_threshold)
350 : END IF
351 : END DO
352 : END IF
353 :
354 434 : IF (owns_ortho) DEALLOCATE (ortho)
355 : END IF
356 :
357 77755 : END SUBROUTINE general_eigenproblem
358 :
359 : ! **************************************************************************************************
360 : !> \brief ...
361 : !> \param scf_env ...
362 : !> \param mos ...
363 : !> \param matrix_ks ...
364 : !> \param matrix_s ...
365 : !> \param scf_control ...
366 : !> \param scf_section ...
367 : !> \param diis_step ...
368 : !> \param probe ...
369 : ! **************************************************************************************************
370 76715 : SUBROUTINE do_general_diag(scf_env, mos, matrix_ks, &
371 : matrix_s, scf_control, scf_section, &
372 : diis_step, probe)
373 :
374 : TYPE(qs_scf_env_type), POINTER :: scf_env
375 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
376 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
377 : TYPE(scf_control_type), POINTER :: scf_control
378 : TYPE(section_vals_type), POINTER :: scf_section
379 : LOGICAL, INTENT(INOUT) :: diis_step
380 : TYPE(hairy_probes_type), DIMENSION(:), OPTIONAL, &
381 : POINTER :: probe
382 :
383 : INTEGER :: ispin, nspin
384 : REAL(KIND=dp) :: total_zeff_corr
385 :
386 76715 : nspin = SIZE(matrix_ks)
387 :
388 : CALL general_eigenproblem(scf_env, mos, matrix_ks, &
389 76715 : matrix_s, scf_control, scf_section, diis_step)
390 :
391 : total_zeff_corr = 0.0_dp
392 76715 : total_zeff_corr = scf_env%sum_zeff_corr
393 :
394 76715 : IF (ABS(total_zeff_corr) > 0.0_dp) THEN
395 : CALL set_mo_occupation(mo_array=mos, &
396 40 : smear=scf_control%smear, tot_zeff_corr=total_zeff_corr)
397 : ELSE
398 76675 : IF (PRESENT(probe) .EQV. .TRUE.) THEN
399 14 : scf_control%smear%do_smear = .FALSE.
400 : CALL set_mo_occupation(mo_array=mos, &
401 : smear=scf_control%smear, &
402 14 : probe=probe)
403 : ELSE
404 : CALL set_mo_occupation(mo_array=mos, &
405 76661 : smear=scf_control%smear)
406 : END IF
407 : END IF
408 :
409 162456 : DO ispin = 1, nspin
410 : CALL calculate_density_matrix(mos(ispin), &
411 162456 : scf_env%p_mix_new(ispin, 1)%matrix)
412 : END DO
413 :
414 76715 : END SUBROUTINE do_general_diag
415 :
416 : ! **************************************************************************************************
417 : !> \brief Kpoint diagonalization routine
418 : !> Transforms matrices to kpoint, distributes kpoint groups, performs
419 : !> general diagonalization (no storgae of overlap decomposition), stores
420 : !> MOs, calculates occupation numbers, calculates density matrices
421 : !> in kpoint representation, transforms density matrices to real space
422 : !> \param matrix_ks Kohn-sham matrices (RS indices, global)
423 : !> \param matrix_s Overlap matrices (RS indices, global)
424 : !> \param kpoints Kpoint environment
425 : !> \param scf_env SCF environment
426 : !> \param scf_control SCF control variables
427 : !> \param update_p ...
428 : !> \param diis_step ...
429 : !> \param diis_error ...
430 : !> \param qs_env ...
431 : !> \param probe ...
432 : !> \par History
433 : !> 08.2014 created [JGH]
434 : ! **************************************************************************************************
435 4746 : SUBROUTINE do_general_diag_kp(matrix_ks, matrix_s, kpoints, scf_env, scf_control, update_p, &
436 : diis_step, diis_error, qs_env, probe)
437 :
438 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks, matrix_s
439 : TYPE(kpoint_type), POINTER :: kpoints
440 : TYPE(qs_scf_env_type), POINTER :: scf_env
441 : TYPE(scf_control_type), POINTER :: scf_control
442 : LOGICAL, INTENT(IN) :: update_p
443 : LOGICAL, INTENT(INOUT) :: diis_step
444 : REAL(dp), INTENT(INOUT), OPTIONAL :: diis_error
445 : TYPE(qs_environment_type), OPTIONAL, POINTER :: qs_env
446 : TYPE(hairy_probes_type), DIMENSION(:), OPTIONAL, &
447 : POINTER :: probe
448 :
449 : CHARACTER(len=*), PARAMETER :: routineN = 'do_general_diag_kp'
450 :
451 4746 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:) :: coeffs
452 : INTEGER :: handle, ib, igroup, ik, ikp, indx, &
453 : ispin, jb, kplocal, nb, nkp, &
454 : nkp_groups, nspin
455 : INTEGER, DIMENSION(2) :: kp_range
456 4746 : INTEGER, DIMENSION(:, :), POINTER :: kp_dist
457 4746 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
458 : LOGICAL :: do_diis, my_kpgrp, use_real_wfn
459 4746 : REAL(KIND=dp), DIMENSION(:), POINTER :: eigenvalues
460 4746 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: xkp
461 4746 : TYPE(copy_info_type), ALLOCATABLE, DIMENSION(:, :) :: info
462 : TYPE(cp_cfm_type) :: cksmat, cmos, csmat, cwork
463 4746 : TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_ao_fm_pools
464 : TYPE(cp_fm_struct_type), POINTER :: matrix_struct, mo_struct
465 : TYPE(cp_fm_type) :: fmdummy, fmlocal, rksmat, rsmat
466 4746 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: fmwork
467 : TYPE(cp_fm_type), POINTER :: imos, mo_coeff, rmos
468 : TYPE(dbcsr_type), POINTER :: cmatrix, rmatrix, tmpmat
469 : TYPE(kpoint_env_type), POINTER :: kp
470 : TYPE(mp_para_env_type), POINTER :: para_env, para_env_global
471 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
472 4746 : POINTER :: sab_nl
473 : TYPE(qs_matrix_pools_type), POINTER :: mpools
474 : TYPE(section_vals_type), POINTER :: scf_section
475 :
476 4746 : CALL timeset(routineN, handle)
477 :
478 4746 : NULLIFY (sab_nl)
479 : CALL get_kpoint_info(kpoints, nkp=nkp, xkp=xkp, use_real_wfn=use_real_wfn, kp_range=kp_range, &
480 : nkp_groups=nkp_groups, kp_dist=kp_dist, sab_nl=sab_nl, &
481 4746 : cell_to_index=cell_to_index)
482 4746 : CPASSERT(ASSOCIATED(sab_nl))
483 4746 : kplocal = kp_range(2) - kp_range(1) + 1
484 :
485 : !Whether we use DIIS for k-points
486 4746 : do_diis = .FALSE.
487 : IF (scf_env%iter_count > 1 .AND. .NOT. scf_env%skip_diis .AND. .NOT. use_real_wfn &
488 4746 : .AND. PRESENT(diis_error) .AND. PRESENT(qs_env)) do_diis = .TRUE.
489 :
490 : ! allocate some work matrices
491 4746 : ALLOCATE (rmatrix, cmatrix, tmpmat)
492 : CALL dbcsr_create(rmatrix, template=matrix_ks(1, 1)%matrix, &
493 4746 : matrix_type=dbcsr_type_symmetric)
494 : CALL dbcsr_create(cmatrix, template=matrix_ks(1, 1)%matrix, &
495 4746 : matrix_type=dbcsr_type_antisymmetric)
496 : CALL dbcsr_create(tmpmat, template=matrix_ks(1, 1)%matrix, &
497 4746 : matrix_type=dbcsr_type_no_symmetry)
498 4746 : CALL cp_dbcsr_alloc_block_from_nbl(rmatrix, sab_nl)
499 4746 : CALL cp_dbcsr_alloc_block_from_nbl(cmatrix, sab_nl)
500 :
501 4746 : fmwork => scf_env%scf_work1
502 :
503 : ! fm pools to be used within a kpoint group
504 4746 : CALL get_kpoint_info(kpoints, mpools=mpools)
505 4746 : CALL mpools_get(mpools, ao_ao_fm_pools=ao_ao_fm_pools)
506 :
507 4746 : CALL fm_pool_create_fm(ao_ao_fm_pools(1)%pool, fmlocal)
508 4746 : CALL cp_fm_get_info(fmlocal, matrix_struct=matrix_struct)
509 :
510 4746 : IF (use_real_wfn) THEN
511 68 : CALL cp_fm_create(rksmat, matrix_struct)
512 68 : CALL cp_fm_create(rsmat, matrix_struct)
513 : ELSE
514 4678 : CALL cp_cfm_create(cksmat, matrix_struct)
515 4678 : CALL cp_cfm_create(csmat, matrix_struct)
516 4678 : CALL cp_cfm_create(cwork, matrix_struct)
517 4678 : kp => kpoints%kp_env(1)%kpoint_env
518 4678 : CALL get_mo_set(kp%mos(1, 1), mo_coeff=mo_coeff)
519 4678 : CALL cp_fm_get_info(mo_coeff, matrix_struct=mo_struct)
520 4678 : CALL cp_cfm_create(cmos, mo_struct)
521 : END IF
522 :
523 4746 : para_env => kpoints%blacs_env_all%para_env
524 4746 : nspin = SIZE(matrix_ks, 1)
525 174414 : ALLOCATE (info(kplocal*nspin*nkp_groups, 4))
526 :
527 : ! Setup and start all the communication
528 4746 : indx = 0
529 22018 : DO ikp = 1, kplocal
530 41198 : DO ispin = 1, nspin
531 62258 : DO igroup = 1, nkp_groups
532 : ! number of current kpoint
533 25806 : ik = kp_dist(1, igroup) + ikp - 1
534 25806 : my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
535 25806 : indx = indx + 1
536 25806 : IF (use_real_wfn) THEN
537 : ! FT of matrices KS and S, then transfer to FM type
538 94 : CALL dbcsr_set(rmatrix, 0.0_dp)
539 : CALL rskp_transform(rmatrix=rmatrix, rsmat=matrix_ks, ispin=ispin, &
540 94 : xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
541 94 : CALL dbcsr_desymmetrize(rmatrix, tmpmat)
542 94 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(1))
543 : ! s matrix is not spin dependent
544 94 : CALL dbcsr_set(rmatrix, 0.0_dp)
545 : CALL rskp_transform(rmatrix=rmatrix, rsmat=matrix_s, ispin=1, &
546 94 : xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
547 94 : CALL dbcsr_desymmetrize(rmatrix, tmpmat)
548 94 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(3))
549 : ELSE
550 : ! FT of matrices KS and S, then transfer to FM type
551 25712 : CALL dbcsr_set(rmatrix, 0.0_dp)
552 25712 : CALL dbcsr_set(cmatrix, 0.0_dp)
553 : CALL rskp_transform(rmatrix=rmatrix, cmatrix=cmatrix, rsmat=matrix_ks, ispin=ispin, &
554 25712 : xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
555 25712 : CALL dbcsr_desymmetrize(rmatrix, tmpmat)
556 25712 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(1))
557 25712 : CALL dbcsr_desymmetrize(cmatrix, tmpmat)
558 25712 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(2))
559 : ! s matrix is not spin dependent, double the work
560 25712 : CALL dbcsr_set(rmatrix, 0.0_dp)
561 25712 : CALL dbcsr_set(cmatrix, 0.0_dp)
562 : CALL rskp_transform(rmatrix=rmatrix, cmatrix=cmatrix, rsmat=matrix_s, ispin=1, &
563 25712 : xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
564 25712 : CALL dbcsr_desymmetrize(rmatrix, tmpmat)
565 25712 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(3))
566 25712 : CALL dbcsr_desymmetrize(cmatrix, tmpmat)
567 25712 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(4))
568 : END IF
569 : ! transfer to kpoint group
570 : ! redistribution of matrices, new blacs environment
571 : ! fmwork -> fmlocal -> rksmat/cksmat
572 : ! fmwork -> fmlocal -> rsmat/csmat
573 44986 : IF (use_real_wfn) THEN
574 94 : IF (my_kpgrp) THEN
575 94 : CALL cp_fm_start_copy_general(fmwork(1), rksmat, para_env, info(indx, 1))
576 94 : CALL cp_fm_start_copy_general(fmwork(3), rsmat, para_env, info(indx, 2))
577 : ELSE
578 0 : CALL cp_fm_start_copy_general(fmwork(1), fmdummy, para_env, info(indx, 1))
579 0 : CALL cp_fm_start_copy_general(fmwork(3), fmdummy, para_env, info(indx, 2))
580 : END IF
581 : ELSE
582 25712 : IF (my_kpgrp) THEN
583 19086 : CALL cp_fm_start_copy_general(fmwork(1), fmlocal, para_env, info(indx, 1))
584 19086 : CALL cp_fm_start_copy_general(fmwork(2), fmlocal, para_env, info(indx, 2))
585 19086 : CALL cp_fm_start_copy_general(fmwork(3), fmlocal, para_env, info(indx, 3))
586 19086 : CALL cp_fm_start_copy_general(fmwork(4), fmlocal, para_env, info(indx, 4))
587 : ELSE
588 6626 : CALL cp_fm_start_copy_general(fmwork(1), fmdummy, para_env, info(indx, 1))
589 6626 : CALL cp_fm_start_copy_general(fmwork(2), fmdummy, para_env, info(indx, 2))
590 6626 : CALL cp_fm_start_copy_general(fmwork(3), fmdummy, para_env, info(indx, 3))
591 6626 : CALL cp_fm_start_copy_general(fmwork(4), fmdummy, para_env, info(indx, 4))
592 : END IF
593 : END IF
594 : END DO
595 : END DO
596 : END DO
597 :
598 : ! Finish communication then diagonalise in each group
599 4746 : IF (do_diis) THEN
600 2952 : CALL get_qs_env(qs_env, para_env=para_env_global)
601 2952 : scf_section => section_vals_get_subs_vals(qs_env%input, "DFT%SCF")
602 2952 : CALL qs_diis_b_info_kp(kpoints%scf_diis_buffer, ib, nb)
603 2952 : indx = 0
604 11058 : DO ikp = 1, kplocal
605 20566 : DO ispin = 1, nspin
606 22498 : DO igroup = 1, nkp_groups
607 : ! number of current kpoint
608 12990 : ik = kp_dist(1, igroup) + ikp - 1
609 12990 : my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
610 3482 : indx = indx + 1
611 9508 : IF (my_kpgrp) THEN
612 9508 : CALL cp_fm_finish_copy_general(fmlocal, info(indx, 1))
613 9508 : CALL cp_cfm_scale_and_add_fm(z_zero, cksmat, z_one, fmlocal)
614 9508 : CALL cp_fm_finish_copy_general(fmlocal, info(indx, 2))
615 9508 : CALL cp_cfm_scale_and_add_fm(z_one, cksmat, gaussi, fmlocal)
616 9508 : CALL cp_fm_finish_copy_general(fmlocal, info(indx, 3))
617 9508 : CALL cp_cfm_scale_and_add_fm(z_zero, csmat, z_one, fmlocal)
618 9508 : CALL cp_fm_finish_copy_general(fmlocal, info(indx, 4))
619 9508 : CALL cp_cfm_scale_and_add_fm(z_one, csmat, gaussi, fmlocal)
620 : END IF
621 : END DO !igroup
622 :
623 9508 : kp => kpoints%kp_env(ikp)%kpoint_env
624 : CALL qs_diis_b_calc_err_kp(kpoints%scf_diis_buffer, ib, kp%mos, cksmat, csmat, &
625 17614 : ispin, ikp, kplocal, scf_section)
626 :
627 : END DO !ispin
628 : END DO !ikp
629 :
630 8856 : ALLOCATE (coeffs(nb))
631 : CALL qs_diis_b_step_kp(kpoints%scf_diis_buffer, coeffs, ib, nb, scf_env%iter_delta, diis_error, &
632 : diis_step, scf_control%eps_diis, nspin, nkp, kplocal, scf_control%nmixing, &
633 2952 : scf_section, para_env_global)
634 :
635 : !build the ks matrices and diagonalize
636 14010 : DO ikp = 1, kplocal
637 20566 : DO ispin = 1, nspin
638 9508 : kp => kpoints%kp_env(ikp)%kpoint_env
639 9508 : CALL cp_cfm_to_cfm(kpoints%scf_diis_buffer%smat(ikp), csmat)
640 :
641 9508 : CALL cp_cfm_set_all(cksmat, z_zero)
642 35602 : DO jb = 1, nb
643 35602 : CALL cp_cfm_scale_and_add(z_one, cksmat, coeffs(jb), kpoints%scf_diis_buffer%param(jb, ispin, ikp))
644 : END DO
645 :
646 9508 : CALL get_mo_set(kp%mos(1, ispin), mo_coeff=rmos, eigenvalues=eigenvalues)
647 9508 : CALL get_mo_set(kp%mos(2, ispin), mo_coeff=imos)
648 9508 : IF (scf_env%cholesky_method == cholesky_off) THEN
649 : CALL cp_cfm_geeig_canon(cksmat, csmat, cmos, eigenvalues, cwork, &
650 16 : scf_control%eps_eigval)
651 : ELSE
652 9492 : CALL cp_cfm_geeig(cksmat, csmat, cmos, eigenvalues, cwork)
653 : END IF
654 : ! copy eigenvalues to imag set (keep them in sync)
655 213708 : kp%mos(2, ispin)%eigenvalues = eigenvalues
656 : ! split real and imaginary part of mos
657 17614 : CALL cp_cfm_to_fm(cmos, rmos, imos)
658 : END DO
659 : END DO
660 :
661 : ELSE !no DIIS
662 1794 : diis_step = .FALSE.
663 1794 : indx = 0
664 10960 : DO ikp = 1, kplocal
665 20632 : DO ispin = 1, nspin
666 22488 : DO igroup = 1, nkp_groups
667 : ! number of current kpoint
668 12816 : ik = kp_dist(1, igroup) + ikp - 1
669 12816 : my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
670 3144 : indx = indx + 1
671 9672 : IF (my_kpgrp) THEN
672 9672 : IF (use_real_wfn) THEN
673 94 : CALL cp_fm_finish_copy_general(rksmat, info(indx, 1))
674 94 : CALL cp_fm_finish_copy_general(rsmat, info(indx, 2))
675 : ELSE
676 9578 : CALL cp_fm_finish_copy_general(fmlocal, info(indx, 1))
677 9578 : CALL cp_cfm_scale_and_add_fm(z_zero, cksmat, z_one, fmlocal)
678 9578 : CALL cp_fm_finish_copy_general(fmlocal, info(indx, 2))
679 9578 : CALL cp_cfm_scale_and_add_fm(z_one, cksmat, gaussi, fmlocal)
680 9578 : CALL cp_fm_finish_copy_general(fmlocal, info(indx, 3))
681 9578 : CALL cp_cfm_scale_and_add_fm(z_zero, csmat, z_one, fmlocal)
682 9578 : CALL cp_fm_finish_copy_general(fmlocal, info(indx, 4))
683 9578 : CALL cp_cfm_scale_and_add_fm(z_one, csmat, gaussi, fmlocal)
684 : END IF
685 : END IF
686 : END DO
687 :
688 : ! Each kpoint group has now information on a kpoint to be diagonalized
689 : ! General eigensolver Hermite or Symmetric
690 9672 : kp => kpoints%kp_env(ikp)%kpoint_env
691 18838 : IF (use_real_wfn) THEN
692 94 : CALL get_mo_set(kp%mos(1, ispin), mo_coeff=mo_coeff, eigenvalues=eigenvalues)
693 94 : IF (scf_env%cholesky_method == cholesky_off) THEN
694 : CALL cp_fm_geeig_canon(rksmat, rsmat, mo_coeff, eigenvalues, fmlocal, &
695 40 : scf_control%eps_eigval)
696 : ELSE
697 54 : CALL cp_fm_geeig(rksmat, rsmat, mo_coeff, eigenvalues, fmlocal)
698 : END IF
699 : ELSE
700 9578 : CALL get_mo_set(kp%mos(1, ispin), mo_coeff=rmos, eigenvalues=eigenvalues)
701 9578 : CALL get_mo_set(kp%mos(2, ispin), mo_coeff=imos)
702 9578 : IF (scf_env%cholesky_method == cholesky_off) THEN
703 : CALL cp_cfm_geeig_canon(cksmat, csmat, cmos, eigenvalues, cwork, &
704 1098 : scf_control%eps_eigval)
705 : ELSE
706 8480 : CALL cp_cfm_geeig(cksmat, csmat, cmos, eigenvalues, cwork)
707 : END IF
708 : ! copy eigenvalues to imag set (keep them in sync)
709 467352 : kp%mos(2, ispin)%eigenvalues = eigenvalues
710 : ! split real and imaginary part of mos
711 9578 : CALL cp_cfm_to_fm(cmos, rmos, imos)
712 : END IF
713 : END DO
714 : END DO
715 : END IF
716 :
717 : ! Clean up communication
718 4746 : indx = 0
719 22018 : DO ikp = 1, kplocal
720 41198 : DO ispin = 1, nspin
721 62258 : DO igroup = 1, nkp_groups
722 : ! number of current kpoint
723 25806 : ik = kp_dist(1, igroup) + ikp - 1
724 25806 : my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
725 25806 : indx = indx + 1
726 44986 : IF (use_real_wfn) THEN
727 94 : CALL cp_fm_cleanup_copy_general(info(indx, 1))
728 94 : CALL cp_fm_cleanup_copy_general(info(indx, 2))
729 : ELSE
730 25712 : CALL cp_fm_cleanup_copy_general(info(indx, 1))
731 25712 : CALL cp_fm_cleanup_copy_general(info(indx, 2))
732 25712 : CALL cp_fm_cleanup_copy_general(info(indx, 3))
733 25712 : CALL cp_fm_cleanup_copy_general(info(indx, 4))
734 : END IF
735 : END DO
736 : END DO
737 : END DO
738 :
739 : ! All done
740 112716 : DEALLOCATE (info)
741 :
742 4746 : IF (update_p) THEN
743 : ! MO occupations
744 4736 : IF (PRESENT(probe) .EQV. .TRUE.) THEN
745 0 : scf_control%smear%do_smear = .FALSE.
746 : CALL kpoint_set_mo_occupation(kpoints, scf_control%smear, &
747 0 : probe=probe)
748 : ELSE
749 4736 : CALL kpoint_set_mo_occupation(kpoints, scf_control%smear)
750 : END IF
751 : ! density matrices
752 4736 : CALL kpoint_density_matrices(kpoints)
753 : ! density matrices in real space
754 : CALL kpoint_density_transform(kpoints, scf_env%p_mix_new, .FALSE., &
755 4736 : matrix_s(1, 1)%matrix, sab_nl, fmwork)
756 : END IF
757 :
758 4746 : CALL dbcsr_deallocate_matrix(rmatrix)
759 4746 : CALL dbcsr_deallocate_matrix(cmatrix)
760 4746 : CALL dbcsr_deallocate_matrix(tmpmat)
761 :
762 4746 : IF (use_real_wfn) THEN
763 68 : CALL cp_fm_release(rksmat)
764 68 : CALL cp_fm_release(rsmat)
765 : ELSE
766 4678 : CALL cp_cfm_release(cksmat)
767 4678 : CALL cp_cfm_release(csmat)
768 4678 : CALL cp_cfm_release(cwork)
769 4678 : CALL cp_cfm_release(cmos)
770 : END IF
771 4746 : CALL fm_pool_give_back_fm(ao_ao_fm_pools(1)%pool, fmlocal)
772 :
773 4746 : CALL timestop(handle)
774 :
775 14238 : END SUBROUTINE do_general_diag_kp
776 :
777 : ! **************************************************************************************************
778 : !> \brief Kpoint diagonalization routine
779 : !> Transforms matrices to kpoint, distributes kpoint groups, performs
780 : !> general diagonalization (no storgae of overlap decomposition), stores
781 : !> MOs, calculates occupation numbers, calculates density matrices
782 : !> in kpoint representation, transforms density matrices to real space
783 : !> \param matrix_ks Kohn-sham matrices (RS indices, global)
784 : !> \param matrix_s Overlap matrices (RS indices, global)
785 : !> \param kpoints Kpoint environment
786 : !> \param fmwork FM work matrices [at least dimension 4] in full para_env
787 : !> \par History
788 : !> 08.2014 created [JGH]
789 : ! **************************************************************************************************
790 10 : SUBROUTINE diag_kp_basic(matrix_ks, matrix_s, kpoints, fmwork)
791 :
792 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks, matrix_s
793 : TYPE(kpoint_type), POINTER :: kpoints
794 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: fmwork
795 :
796 : CHARACTER(len=*), PARAMETER :: routineN = 'diag_kp_basic'
797 :
798 : INTEGER :: handle, igroup, ik, ikp, indx, ispin, &
799 : kplocal, nkp, nkp_groups, nspin
800 : INTEGER, DIMENSION(2) :: kp_range
801 10 : INTEGER, DIMENSION(:, :), POINTER :: kp_dist
802 10 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
803 : LOGICAL :: my_kpgrp, use_real_wfn
804 10 : REAL(KIND=dp), DIMENSION(:), POINTER :: eigenvalues
805 10 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: xkp
806 10 : TYPE(copy_info_type), ALLOCATABLE, DIMENSION(:, :) :: info
807 : TYPE(cp_cfm_type) :: cksmat, cmos, csmat, cwork
808 10 : TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_ao_fm_pools
809 : TYPE(cp_fm_struct_type), POINTER :: matrix_struct, mo_struct
810 : TYPE(cp_fm_type) :: fmdummy, fmlocal, rksmat, rsmat
811 : TYPE(cp_fm_type), POINTER :: imos, mo_coeff, rmos
812 : TYPE(dbcsr_type), POINTER :: cmatrix, rmatrix, tempmat, tmpmat
813 : TYPE(kpoint_env_type), POINTER :: kp
814 : TYPE(mp_para_env_type), POINTER :: para_env
815 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
816 10 : POINTER :: sab_nl
817 : TYPE(qs_matrix_pools_type), POINTER :: mpools
818 :
819 10 : CALL timeset(routineN, handle)
820 :
821 10 : NULLIFY (sab_nl)
822 : CALL get_kpoint_info(kpoints, nkp=nkp, xkp=xkp, use_real_wfn=use_real_wfn, kp_range=kp_range, &
823 : nkp_groups=nkp_groups, kp_dist=kp_dist, sab_nl=sab_nl, &
824 10 : cell_to_index=cell_to_index)
825 10 : CPASSERT(ASSOCIATED(sab_nl))
826 10 : kplocal = kp_range(2) - kp_range(1) + 1
827 :
828 : ! use as template
829 10 : tempmat => matrix_ks(1, 1)%matrix
830 :
831 : ! allocate some work matrices
832 10 : ALLOCATE (rmatrix, cmatrix, tmpmat)
833 10 : CALL dbcsr_create(rmatrix, template=tempmat, matrix_type=dbcsr_type_symmetric)
834 10 : CALL dbcsr_create(cmatrix, template=tempmat, matrix_type=dbcsr_type_antisymmetric)
835 10 : CALL dbcsr_create(tmpmat, template=tempmat, matrix_type=dbcsr_type_no_symmetry)
836 10 : CALL cp_dbcsr_alloc_block_from_nbl(rmatrix, sab_nl)
837 10 : CALL cp_dbcsr_alloc_block_from_nbl(cmatrix, sab_nl)
838 :
839 : ! fm pools to be used within a kpoint group
840 10 : CALL get_kpoint_info(kpoints, mpools=mpools)
841 10 : CALL mpools_get(mpools, ao_ao_fm_pools=ao_ao_fm_pools)
842 :
843 10 : CALL fm_pool_create_fm(ao_ao_fm_pools(1)%pool, fmlocal)
844 10 : CALL cp_fm_get_info(fmlocal, matrix_struct=matrix_struct)
845 :
846 10 : IF (use_real_wfn) THEN
847 0 : CALL cp_fm_create(rksmat, matrix_struct)
848 0 : CALL cp_fm_create(rsmat, matrix_struct)
849 : ELSE
850 10 : CALL cp_cfm_create(cksmat, matrix_struct)
851 10 : CALL cp_cfm_create(csmat, matrix_struct)
852 10 : CALL cp_cfm_create(cwork, matrix_struct)
853 10 : kp => kpoints%kp_env(1)%kpoint_env
854 10 : CALL get_mo_set(kp%mos(1, 1), mo_coeff=mo_coeff)
855 10 : CALL cp_fm_get_info(mo_coeff, matrix_struct=mo_struct)
856 10 : CALL cp_cfm_create(cmos, mo_struct)
857 : END IF
858 :
859 10 : para_env => kpoints%blacs_env_all%para_env
860 10 : nspin = SIZE(matrix_ks, 1)
861 310 : ALLOCATE (info(kplocal*nspin*nkp_groups, 4))
862 :
863 : ! Setup and start all the communication
864 10 : indx = 0
865 50 : DO ikp = 1, kplocal
866 90 : DO ispin = 1, nspin
867 120 : DO igroup = 1, nkp_groups
868 : ! number of current kpoint
869 40 : ik = kp_dist(1, igroup) + ikp - 1
870 40 : my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
871 40 : indx = indx + 1
872 40 : IF (use_real_wfn) THEN
873 : ! FT of matrices KS and S, then transfer to FM type
874 0 : CALL dbcsr_set(rmatrix, 0.0_dp)
875 : CALL rskp_transform(rmatrix=rmatrix, rsmat=matrix_ks, ispin=ispin, &
876 0 : xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
877 0 : CALL dbcsr_desymmetrize(rmatrix, tmpmat)
878 0 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(1))
879 : ! s matrix is not spin dependent
880 0 : CALL dbcsr_set(rmatrix, 0.0_dp)
881 : CALL rskp_transform(rmatrix=rmatrix, rsmat=matrix_s, ispin=1, &
882 0 : xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
883 0 : CALL dbcsr_desymmetrize(rmatrix, tmpmat)
884 0 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(3))
885 : ELSE
886 : ! FT of matrices KS and S, then transfer to FM type
887 40 : CALL dbcsr_set(rmatrix, 0.0_dp)
888 40 : CALL dbcsr_set(cmatrix, 0.0_dp)
889 : CALL rskp_transform(rmatrix=rmatrix, cmatrix=cmatrix, rsmat=matrix_ks, ispin=ispin, &
890 40 : xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
891 40 : CALL dbcsr_desymmetrize(rmatrix, tmpmat)
892 40 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(1))
893 40 : CALL dbcsr_desymmetrize(cmatrix, tmpmat)
894 40 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(2))
895 : ! s matrix is not spin dependent, double the work
896 40 : CALL dbcsr_set(rmatrix, 0.0_dp)
897 40 : CALL dbcsr_set(cmatrix, 0.0_dp)
898 : CALL rskp_transform(rmatrix=rmatrix, cmatrix=cmatrix, rsmat=matrix_s, ispin=1, &
899 40 : xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
900 40 : CALL dbcsr_desymmetrize(rmatrix, tmpmat)
901 40 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(3))
902 40 : CALL dbcsr_desymmetrize(cmatrix, tmpmat)
903 40 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(4))
904 : END IF
905 : ! transfer to kpoint group
906 : ! redistribution of matrices, new blacs environment
907 : ! fmwork -> fmlocal -> rksmat/cksmat
908 : ! fmwork -> fmlocal -> rsmat/csmat
909 80 : IF (use_real_wfn) THEN
910 0 : IF (my_kpgrp) THEN
911 0 : CALL cp_fm_start_copy_general(fmwork(1), rksmat, para_env, info(indx, 1))
912 0 : CALL cp_fm_start_copy_general(fmwork(3), rsmat, para_env, info(indx, 2))
913 : ELSE
914 0 : CALL cp_fm_start_copy_general(fmwork(1), fmdummy, para_env, info(indx, 1))
915 0 : CALL cp_fm_start_copy_general(fmwork(3), fmdummy, para_env, info(indx, 2))
916 : END IF
917 : ELSE
918 40 : IF (my_kpgrp) THEN
919 40 : CALL cp_fm_start_copy_general(fmwork(1), fmlocal, para_env, info(indx, 1))
920 40 : CALL cp_fm_start_copy_general(fmwork(2), fmlocal, para_env, info(indx, 2))
921 40 : CALL cp_fm_start_copy_general(fmwork(3), fmlocal, para_env, info(indx, 3))
922 40 : CALL cp_fm_start_copy_general(fmwork(4), fmlocal, para_env, info(indx, 4))
923 : ELSE
924 0 : CALL cp_fm_start_copy_general(fmwork(1), fmdummy, para_env, info(indx, 1))
925 0 : CALL cp_fm_start_copy_general(fmwork(2), fmdummy, para_env, info(indx, 2))
926 0 : CALL cp_fm_start_copy_general(fmwork(3), fmdummy, para_env, info(indx, 3))
927 0 : CALL cp_fm_start_copy_general(fmwork(4), fmdummy, para_env, info(indx, 4))
928 : END IF
929 : END IF
930 : END DO
931 : END DO
932 : END DO
933 :
934 : ! Finish communication then diagonalise in each group
935 : indx = 0
936 50 : DO ikp = 1, kplocal
937 90 : DO ispin = 1, nspin
938 80 : DO igroup = 1, nkp_groups
939 : ! number of current kpoint
940 40 : ik = kp_dist(1, igroup) + ikp - 1
941 40 : my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
942 0 : indx = indx + 1
943 40 : IF (my_kpgrp) THEN
944 40 : IF (use_real_wfn) THEN
945 0 : CALL cp_fm_finish_copy_general(rksmat, info(indx, 1))
946 0 : CALL cp_fm_finish_copy_general(rsmat, info(indx, 2))
947 : ELSE
948 40 : CALL cp_fm_finish_copy_general(fmlocal, info(indx, 1))
949 40 : CALL cp_cfm_scale_and_add_fm(z_zero, cksmat, z_one, fmlocal)
950 40 : CALL cp_fm_finish_copy_general(fmlocal, info(indx, 2))
951 40 : CALL cp_cfm_scale_and_add_fm(z_one, cksmat, gaussi, fmlocal)
952 40 : CALL cp_fm_finish_copy_general(fmlocal, info(indx, 3))
953 40 : CALL cp_cfm_scale_and_add_fm(z_zero, csmat, z_one, fmlocal)
954 40 : CALL cp_fm_finish_copy_general(fmlocal, info(indx, 4))
955 40 : CALL cp_cfm_scale_and_add_fm(z_one, csmat, gaussi, fmlocal)
956 : END IF
957 : END IF
958 : END DO
959 :
960 : ! Each kpoint group has now information on a kpoint to be diagonalized
961 : ! General eigensolver Hermite or Symmetric
962 40 : kp => kpoints%kp_env(ikp)%kpoint_env
963 80 : IF (use_real_wfn) THEN
964 0 : CALL get_mo_set(kp%mos(1, ispin), mo_coeff=mo_coeff, eigenvalues=eigenvalues)
965 0 : CALL cp_fm_geeig(rksmat, rsmat, mo_coeff, eigenvalues, fmlocal)
966 : ELSE
967 40 : CALL get_mo_set(kp%mos(1, ispin), mo_coeff=rmos, eigenvalues=eigenvalues)
968 40 : CALL get_mo_set(kp%mos(2, ispin), mo_coeff=imos)
969 40 : CALL cp_cfm_geeig(cksmat, csmat, cmos, eigenvalues, cwork)
970 : ! copy eigenvalues to imag set (keep them in sync)
971 2640 : kp%mos(2, ispin)%eigenvalues = eigenvalues
972 : ! split real and imaginary part of mos
973 40 : CALL cp_cfm_to_fm(cmos, rmos, imos)
974 : END IF
975 : END DO
976 : END DO
977 :
978 : ! Clean up communication
979 : indx = 0
980 50 : DO ikp = 1, kplocal
981 90 : DO ispin = 1, nspin
982 120 : DO igroup = 1, nkp_groups
983 : ! number of current kpoint
984 40 : ik = kp_dist(1, igroup) + ikp - 1
985 40 : my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
986 40 : indx = indx + 1
987 80 : IF (use_real_wfn) THEN
988 0 : CALL cp_fm_cleanup_copy_general(info(indx, 1))
989 0 : CALL cp_fm_cleanup_copy_general(info(indx, 2))
990 : ELSE
991 40 : CALL cp_fm_cleanup_copy_general(info(indx, 1))
992 40 : CALL cp_fm_cleanup_copy_general(info(indx, 2))
993 40 : CALL cp_fm_cleanup_copy_general(info(indx, 3))
994 40 : CALL cp_fm_cleanup_copy_general(info(indx, 4))
995 : END IF
996 : END DO
997 : END DO
998 : END DO
999 :
1000 : ! All done
1001 180 : DEALLOCATE (info)
1002 :
1003 10 : CALL dbcsr_deallocate_matrix(rmatrix)
1004 10 : CALL dbcsr_deallocate_matrix(cmatrix)
1005 10 : CALL dbcsr_deallocate_matrix(tmpmat)
1006 :
1007 10 : IF (use_real_wfn) THEN
1008 0 : CALL cp_fm_release(rksmat)
1009 0 : CALL cp_fm_release(rsmat)
1010 : ELSE
1011 10 : CALL cp_cfm_release(cksmat)
1012 10 : CALL cp_cfm_release(csmat)
1013 10 : CALL cp_cfm_release(cwork)
1014 10 : CALL cp_cfm_release(cmos)
1015 : END IF
1016 10 : CALL fm_pool_give_back_fm(ao_ao_fm_pools(1)%pool, fmlocal)
1017 :
1018 10 : CALL timestop(handle)
1019 :
1020 20 : END SUBROUTINE diag_kp_basic
1021 :
1022 : ! **************************************************************************************************
1023 : !> \brief inner loop within MOS subspace, to refine occupation and density,
1024 : !> before next diagonalization of the Hamiltonian
1025 : !> \param qs_env ...
1026 : !> \param scf_env ...
1027 : !> \param subspace_env ...
1028 : !> \param mos ...
1029 : !> \param rho ...
1030 : !> \param ks_env ...
1031 : !> \param scf_section ...
1032 : !> \param scf_control ...
1033 : !> \par History
1034 : !> 09.2009 created [MI]
1035 : !> \note it is assumed that when diagonalization is used, also some mixing procedure is active
1036 : ! **************************************************************************************************
1037 10 : SUBROUTINE do_scf_diag_subspace(qs_env, scf_env, subspace_env, mos, rho, &
1038 : ks_env, scf_section, scf_control)
1039 :
1040 : TYPE(qs_environment_type), POINTER :: qs_env
1041 : TYPE(qs_scf_env_type), POINTER :: scf_env
1042 : TYPE(subspace_env_type), POINTER :: subspace_env
1043 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
1044 : TYPE(qs_rho_type), POINTER :: rho
1045 : TYPE(qs_ks_env_type), POINTER :: ks_env
1046 : TYPE(section_vals_type), POINTER :: scf_section
1047 : TYPE(scf_control_type), POINTER :: scf_control
1048 :
1049 : CHARACTER(LEN=*), PARAMETER :: routineN = 'do_scf_diag_subspace'
1050 : REAL(KIND=dp), PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1051 :
1052 : INTEGER :: handle, i, iloop, ispin, nao, nmo, &
1053 : nspin, output_unit
1054 : LOGICAL :: converged
1055 : REAL(dp) :: ene_diff, ene_old, iter_delta, max_val, &
1056 : sum_band, sum_val, t1, t2
1057 10 : REAL(KIND=dp), DIMENSION(:), POINTER :: mo_eigenvalues, mo_occupations
1058 10 : TYPE(cp_1d_r_p_type), ALLOCATABLE, DIMENSION(:) :: eval_first, occ_first
1059 : TYPE(cp_fm_type) :: work
1060 : TYPE(cp_fm_type), POINTER :: c0, chc, evec, mo_coeff
1061 : TYPE(cp_logger_type), POINTER :: logger
1062 10 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s, rho_ao
1063 10 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp
1064 : TYPE(dft_control_type), POINTER :: dft_control
1065 : TYPE(mp_para_env_type), POINTER :: para_env
1066 : TYPE(qs_energy_type), POINTER :: energy
1067 10 : TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho_atom
1068 :
1069 10 : CALL timeset(routineN, handle)
1070 10 : NULLIFY (c0, chc, energy, evec, matrix_ks, mo_coeff, mo_eigenvalues, &
1071 10 : mo_occupations, dft_control, rho_ao, rho_ao_kp)
1072 :
1073 10 : logger => cp_get_default_logger()
1074 : output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIAG_SUB_SCF", &
1075 10 : extension=".scfLog")
1076 :
1077 : !Extra loop keeping mos unchanged and refining the subspace occupation
1078 10 : nspin = SIZE(mos)
1079 10 : CALL qs_rho_get(rho, rho_ao=rho_ao, rho_ao_kp=rho_ao_kp)
1080 :
1081 40 : ALLOCATE (eval_first(nspin))
1082 40 : ALLOCATE (occ_first(nspin))
1083 20 : DO ispin = 1, nspin
1084 : CALL get_mo_set(mo_set=mos(ispin), &
1085 : nmo=nmo, &
1086 : eigenvalues=mo_eigenvalues, &
1087 10 : occupation_numbers=mo_occupations)
1088 30 : ALLOCATE (eval_first(ispin)%array(nmo))
1089 20 : ALLOCATE (occ_first(ispin)%array(nmo))
1090 50 : eval_first(ispin)%array(1:nmo) = mo_eigenvalues(1:nmo)
1091 70 : occ_first(ispin)%array(1:nmo) = mo_occupations(1:nmo)
1092 : END DO
1093 :
1094 20 : DO ispin = 1, nspin
1095 : ! does not yet handle k-points
1096 10 : CALL dbcsr_copy(subspace_env%p_matrix_store(ispin)%matrix, rho_ao(ispin)%matrix)
1097 20 : CALL dbcsr_copy(rho_ao(ispin)%matrix, scf_env%p_mix_new(ispin, 1)%matrix)
1098 : END DO
1099 :
1100 10 : subspace_env%p_matrix_mix => scf_env%p_mix_new
1101 :
1102 10 : NULLIFY (matrix_ks, energy, para_env, matrix_s)
1103 : CALL get_qs_env(qs_env, &
1104 : matrix_ks=matrix_ks, &
1105 : energy=energy, &
1106 : matrix_s=matrix_s, &
1107 : para_env=para_env, &
1108 10 : dft_control=dft_control)
1109 :
1110 : ! mixing storage allocation
1111 10 : IF (subspace_env%mixing_method >= gspace_mixing_nr) THEN
1112 : CALL mixing_allocate(qs_env, subspace_env%mixing_method, scf_env%p_mix_new, &
1113 0 : scf_env%p_delta, nspin, subspace_env%mixing_store)
1114 0 : IF (dft_control%qs_control%gapw) THEN
1115 0 : CALL get_qs_env(qs_env=qs_env, rho_atom_set=rho_atom)
1116 : CALL mixing_init(subspace_env%mixing_method, rho, subspace_env%mixing_store, &
1117 0 : para_env, rho_atom=rho_atom)
1118 0 : ELSEIF (dft_control%qs_control%dftb .OR. dft_control%qs_control%xtb) THEN
1119 0 : CALL charge_mixing_init(subspace_env%mixing_store)
1120 0 : ELSEIF (dft_control%qs_control%semi_empirical) THEN
1121 0 : CPABORT('SE Code not possible')
1122 : ELSE
1123 0 : CALL mixing_init(subspace_env%mixing_method, rho, subspace_env%mixing_store, para_env)
1124 : END IF
1125 : END IF
1126 :
1127 10 : ene_old = 0.0_dp
1128 10 : ene_diff = 0.0_dp
1129 10 : IF (output_unit > 0) THEN
1130 0 : WRITE (output_unit, "(/T19,A)") '<<<<<<<<< SUBSPACE ROTATION <<<<<<<<<<'
1131 : WRITE (output_unit, "(T4,A,T13,A,T21,A,T38,A,T51,A,T65,A/,T4,A)") &
1132 0 : "In-step", "Time", "Convergence", "Band ene.", "Total ene.", "Energy diff.", REPEAT("-", 74)
1133 : END IF
1134 :
1135 : ! recalculate density matrix here
1136 :
1137 : ! update of density
1138 10 : CALL qs_rho_update_rho(rho, qs_env=qs_env)
1139 :
1140 22 : DO iloop = 1, subspace_env%max_iter
1141 20 : t1 = m_walltime()
1142 20 : converged = .FALSE.
1143 20 : ene_old = energy%total
1144 :
1145 20 : CALL qs_ks_did_change(ks_env, rho_changed=.TRUE.)
1146 : CALL qs_ks_update_qs_env(qs_env, calculate_forces=.FALSE., &
1147 20 : just_energy=.FALSE., print_active=.FALSE.)
1148 :
1149 20 : max_val = 0.0_dp
1150 20 : sum_val = 0.0_dp
1151 20 : sum_band = 0.0_dp
1152 40 : DO ispin = 1, SIZE(matrix_ks)
1153 : CALL get_mo_set(mo_set=mos(ispin), &
1154 : nao=nao, &
1155 : nmo=nmo, &
1156 : eigenvalues=mo_eigenvalues, &
1157 : occupation_numbers=mo_occupations, &
1158 20 : mo_coeff=mo_coeff)
1159 :
1160 : !compute C'HC
1161 20 : chc => subspace_env%chc_mat(ispin)
1162 20 : evec => subspace_env%c_vec(ispin)
1163 20 : c0 => subspace_env%c0(ispin)
1164 20 : CALL cp_fm_to_fm(mo_coeff, c0)
1165 20 : CALL cp_fm_create(work, c0%matrix_struct)
1166 20 : CALL cp_dbcsr_sm_fm_multiply(matrix_ks(ispin)%matrix, c0, work, nmo)
1167 20 : CALL parallel_gemm('T', 'N', nmo, nmo, nao, rone, c0, work, rzero, chc)
1168 20 : CALL cp_fm_release(work)
1169 : !diagonalize C'HC
1170 20 : CALL choose_eigv_solver(chc, evec, mo_eigenvalues)
1171 :
1172 : !rotate the mos by the eigenvectors of C'HC
1173 20 : CALL parallel_gemm('N', 'N', nao, nmo, nmo, rone, c0, evec, rzero, mo_coeff)
1174 :
1175 : CALL set_mo_occupation(mo_set=mos(ispin), &
1176 20 : smear=scf_control%smear)
1177 :
1178 : ! does not yet handle k-points
1179 : CALL calculate_density_matrix(mos(ispin), &
1180 20 : subspace_env%p_matrix_mix(ispin, 1)%matrix)
1181 :
1182 160 : DO i = 1, nmo
1183 100 : sum_band = sum_band + mo_eigenvalues(i)*mo_occupations(i)
1184 : END DO
1185 :
1186 : !check for self consistency
1187 : END DO
1188 :
1189 20 : IF (subspace_env%mixing_method == direct_mixing_nr) THEN
1190 : CALL scf_env_density_mixing(subspace_env%p_matrix_mix, &
1191 20 : scf_env%mixing_store, rho_ao_kp, para_env, iter_delta, iloop)
1192 : ELSE
1193 : CALL self_consistency_check(rho_ao_kp, scf_env%p_delta, para_env, &
1194 0 : subspace_env%p_matrix_mix, delta=iter_delta)
1195 : END IF
1196 :
1197 40 : DO ispin = 1, nspin
1198 : ! does not yet handle k-points
1199 40 : CALL dbcsr_copy(rho_ao(ispin)%matrix, subspace_env%p_matrix_mix(ispin, 1)%matrix)
1200 : END DO
1201 : ! update of density
1202 20 : CALL qs_rho_update_rho(rho, qs_env=qs_env)
1203 : ! Mixing in reciprocal space
1204 20 : IF (subspace_env%mixing_method >= gspace_mixing_nr) THEN
1205 : CALL gspace_mixing(qs_env, scf_env%mixing_method, subspace_env%mixing_store, &
1206 0 : rho, para_env, scf_env%iter_count)
1207 : END IF
1208 :
1209 20 : ene_diff = energy%total - ene_old
1210 : converged = (ABS(ene_diff) < subspace_env%eps_ene .AND. &
1211 20 : iter_delta < subspace_env%eps_adapt*scf_env%iter_delta)
1212 20 : t2 = m_walltime()
1213 20 : IF (output_unit > 0) THEN
1214 : WRITE (output_unit, "(T4,I5,T11,F8.3,T18,E14.4,T34,F12.5,T46,F16.8,T62,E14.4)") &
1215 0 : iloop, t2 - t1, iter_delta, sum_band, energy%total, ene_diff
1216 0 : CALL m_flush(output_unit)
1217 : END IF
1218 22 : IF (converged) THEN
1219 8 : IF (output_unit > 0) WRITE (output_unit, "(T10,A,I6,A,/)") &
1220 0 : " Reached convergence in ", iloop, " iterations "
1221 : EXIT
1222 : END IF
1223 :
1224 : END DO ! iloop
1225 :
1226 10 : NULLIFY (subspace_env%p_matrix_mix)
1227 20 : DO ispin = 1, nspin
1228 : ! does not yet handle k-points
1229 10 : CALL dbcsr_copy(scf_env%p_mix_new(ispin, 1)%matrix, rho_ao(ispin)%matrix)
1230 10 : CALL dbcsr_copy(rho_ao(ispin)%matrix, subspace_env%p_matrix_store(ispin)%matrix)
1231 :
1232 20 : DEALLOCATE (eval_first(ispin)%array, occ_first(ispin)%array)
1233 : END DO
1234 10 : DEALLOCATE (eval_first, occ_first)
1235 :
1236 10 : CALL timestop(handle)
1237 :
1238 10 : END SUBROUTINE do_scf_diag_subspace
1239 :
1240 : ! **************************************************************************************************
1241 : !> \brief ...
1242 : !> \param subspace_env ...
1243 : !> \param qs_env ...
1244 : !> \param mos ...
1245 : ! **************************************************************************************************
1246 2 : SUBROUTINE diag_subspace_allocate(subspace_env, qs_env, mos)
1247 :
1248 : TYPE(subspace_env_type), POINTER :: subspace_env
1249 : TYPE(qs_environment_type), POINTER :: qs_env
1250 : TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
1251 :
1252 : CHARACTER(LEN=*), PARAMETER :: routineN = 'diag_subspace_allocate'
1253 :
1254 : INTEGER :: handle, i, ispin, nmo, nspin
1255 : TYPE(cp_fm_struct_type), POINTER :: fm_struct_tmp
1256 : TYPE(cp_fm_type), POINTER :: mo_coeff
1257 2 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
1258 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1259 2 : POINTER :: sab_orb
1260 :
1261 2 : CALL timeset(routineN, handle)
1262 :
1263 2 : NULLIFY (sab_orb, matrix_s)
1264 : CALL get_qs_env(qs_env=qs_env, sab_orb=sab_orb, &
1265 2 : matrix_s=matrix_s)
1266 :
1267 2 : nspin = SIZE(mos)
1268 : ! *** allocate p_atrix_store ***
1269 2 : IF (.NOT. ASSOCIATED(subspace_env%p_matrix_store)) THEN
1270 2 : CALL dbcsr_allocate_matrix_set(subspace_env%p_matrix_store, nspin)
1271 :
1272 4 : DO i = 1, nspin
1273 2 : ALLOCATE (subspace_env%p_matrix_store(i)%matrix)
1274 : CALL dbcsr_create(matrix=subspace_env%p_matrix_store(i)%matrix, template=matrix_s(1)%matrix, &
1275 2 : name="DENSITY_STORE", matrix_type=dbcsr_type_symmetric)
1276 : CALL cp_dbcsr_alloc_block_from_nbl(subspace_env%p_matrix_store(i)%matrix, &
1277 2 : sab_orb)
1278 4 : CALL dbcsr_set(subspace_env%p_matrix_store(i)%matrix, 0.0_dp)
1279 : END DO
1280 :
1281 : END IF
1282 :
1283 8 : ALLOCATE (subspace_env%chc_mat(nspin))
1284 8 : ALLOCATE (subspace_env%c_vec(nspin))
1285 8 : ALLOCATE (subspace_env%c0(nspin))
1286 :
1287 4 : DO ispin = 1, nspin
1288 2 : CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nmo=nmo)
1289 2 : CALL cp_fm_create(subspace_env%c0(ispin), mo_coeff%matrix_struct)
1290 2 : NULLIFY (fm_struct_tmp)
1291 : CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nmo, ncol_global=nmo, &
1292 : para_env=mo_coeff%matrix_struct%para_env, &
1293 2 : context=mo_coeff%matrix_struct%context)
1294 2 : CALL cp_fm_create(subspace_env%chc_mat(ispin), fm_struct_tmp, "chc")
1295 2 : CALL cp_fm_create(subspace_env%c_vec(ispin), fm_struct_tmp, "vec")
1296 6 : CALL cp_fm_struct_release(fm_struct_tmp)
1297 : END DO
1298 :
1299 2 : CALL timestop(handle)
1300 :
1301 2 : END SUBROUTINE diag_subspace_allocate
1302 :
1303 : ! **************************************************************************************************
1304 : !> \brief the inner loop of scf, specific to diagonalization without S matrix
1305 : !> basically, in goes the ks matrix out goes a new p matrix
1306 : !> \param scf_env ...
1307 : !> \param mos ...
1308 : !> \param matrix_ks ...
1309 : !> \param scf_control ...
1310 : !> \param scf_section ...
1311 : !> \param diis_step ...
1312 : !> \par History
1313 : !> 03.2006 created [Joost VandeVondele]
1314 : ! **************************************************************************************************
1315 17898 : SUBROUTINE do_special_diag(scf_env, mos, matrix_ks, scf_control, &
1316 : scf_section, diis_step)
1317 :
1318 : TYPE(qs_scf_env_type), POINTER :: scf_env
1319 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
1320 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks
1321 : TYPE(scf_control_type), POINTER :: scf_control
1322 : TYPE(section_vals_type), POINTER :: scf_section
1323 : LOGICAL, INTENT(INOUT) :: diis_step
1324 :
1325 : INTEGER :: ispin, nspin
1326 : LOGICAL :: do_level_shift, use_jacobi
1327 : REAL(KIND=dp) :: diis_error
1328 :
1329 17898 : nspin = SIZE(matrix_ks)
1330 :
1331 36570 : DO ispin = 1, nspin
1332 36570 : CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, scf_env%scf_work1(ispin))
1333 : END DO
1334 17898 : IF (scf_env%iter_count > 1 .AND. .NOT. scf_env%skip_diis) THEN
1335 : CALL qs_diis_b_step(scf_env%scf_diis_buffer, mos, scf_env%scf_work1, &
1336 : scf_env%scf_work2, scf_env%iter_delta, diis_error, diis_step, &
1337 : scf_control%eps_diis, scf_control%nmixing, &
1338 15304 : scf_section=scf_section)
1339 : ELSE
1340 2594 : diis_step = .FALSE.
1341 : END IF
1342 :
1343 17898 : IF ((scf_env%iter_count > 1) .AND. (scf_env%iter_delta < scf_control%diagonalization%eps_jacobi)) THEN
1344 18 : use_jacobi = .TRUE.
1345 : ELSE
1346 17880 : use_jacobi = .FALSE.
1347 : END IF
1348 :
1349 : do_level_shift = ((scf_control%level_shift /= 0.0_dp) .AND. &
1350 17898 : ((scf_control%density_guess == core_guess) .OR. (scf_env%iter_count > 1)))
1351 17898 : IF (diis_step) THEN
1352 11880 : scf_env%iter_param = diis_error
1353 11880 : IF (use_jacobi) THEN
1354 18 : scf_env%iter_method = "DIIS/Jacobi"
1355 : ELSE
1356 11862 : scf_env%iter_method = "DIIS/Diag."
1357 : END IF
1358 : ELSE
1359 6018 : IF (scf_env%mixing_method == 1) THEN
1360 6018 : scf_env%iter_param = scf_env%p_mix_alpha
1361 6018 : IF (use_jacobi) THEN
1362 0 : scf_env%iter_method = "P_Mix/Jacobi"
1363 : ELSE
1364 6018 : scf_env%iter_method = "P_Mix/Diag."
1365 : END IF
1366 0 : ELSEIF (scf_env%mixing_method > 1) THEN
1367 0 : scf_env%iter_param = scf_env%mixing_store%alpha
1368 0 : IF (use_jacobi) THEN
1369 0 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Jacobi"
1370 : ELSE
1371 0 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Diag."
1372 : END IF
1373 : END IF
1374 : END IF
1375 17898 : scf_env%iter_delta = 0.0_dp
1376 :
1377 36570 : DO ispin = 1, nspin
1378 : CALL eigensolver_simple(matrix_ks=scf_env%scf_work1(ispin), &
1379 : mo_set=mos(ispin), &
1380 : work=scf_env%scf_work2, &
1381 : do_level_shift=do_level_shift, &
1382 : level_shift=scf_control%level_shift, &
1383 : use_jacobi=use_jacobi, &
1384 36570 : jacobi_threshold=scf_control%diagonalization%jacobi_threshold)
1385 : END DO
1386 :
1387 : CALL set_mo_occupation(mo_array=mos, &
1388 17898 : smear=scf_control%smear)
1389 :
1390 36570 : DO ispin = 1, nspin
1391 : ! does not yet handle k-points
1392 : CALL calculate_density_matrix(mos(ispin), &
1393 36570 : scf_env%p_mix_new(ispin, 1)%matrix)
1394 : END DO
1395 :
1396 17898 : END SUBROUTINE do_special_diag
1397 :
1398 : ! **************************************************************************************************
1399 : !> \brief the inner loop of scf, specific to iterative diagonalization using OT
1400 : !> with S matrix; basically, in goes the ks matrix out goes a new p matrix
1401 : !> \param scf_env ...
1402 : !> \param mos ...
1403 : !> \param matrix_ks ...
1404 : !> \param matrix_s ...
1405 : !> \param scf_control ...
1406 : !> \param scf_section ...
1407 : !> \param diis_step ...
1408 : !> \par History
1409 : !> 10.2008 created [JGH]
1410 : ! **************************************************************************************************
1411 64 : SUBROUTINE do_ot_diag(scf_env, mos, matrix_ks, matrix_s, &
1412 : scf_control, scf_section, diis_step)
1413 :
1414 : TYPE(qs_scf_env_type), POINTER :: scf_env
1415 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
1416 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
1417 : TYPE(scf_control_type), POINTER :: scf_control
1418 : TYPE(section_vals_type), POINTER :: scf_section
1419 : LOGICAL, INTENT(INOUT) :: diis_step
1420 :
1421 : INTEGER :: homo, ispin, nmo, nspin
1422 : REAL(KIND=dp) :: diis_error, eps_iter
1423 64 : REAL(KIND=dp), DIMENSION(:), POINTER :: eigenvalues
1424 : TYPE(cp_fm_type), POINTER :: mo_coeff
1425 :
1426 64 : NULLIFY (eigenvalues)
1427 :
1428 64 : nspin = SIZE(matrix_ks)
1429 :
1430 172 : DO ispin = 1, nspin
1431 : CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, &
1432 172 : scf_env%scf_work1(ispin))
1433 : END DO
1434 :
1435 64 : IF ((scf_env%iter_count > 1) .AND. (.NOT. scf_env%skip_diis)) THEN
1436 : CALL qs_diis_b_step(scf_env%scf_diis_buffer, mos, scf_env%scf_work1, &
1437 : scf_env%scf_work2, scf_env%iter_delta, diis_error, diis_step, &
1438 : scf_control%eps_diis, scf_control%nmixing, &
1439 : s_matrix=matrix_s, &
1440 48 : scf_section=scf_section)
1441 : ELSE
1442 16 : diis_step = .FALSE.
1443 : END IF
1444 :
1445 64 : eps_iter = scf_control%diagonalization%eps_iter
1446 64 : IF (diis_step) THEN
1447 20 : scf_env%iter_param = diis_error
1448 20 : scf_env%iter_method = "DIIS/OTdiag"
1449 54 : DO ispin = 1, nspin
1450 : CALL copy_fm_to_dbcsr(scf_env%scf_work1(ispin), &
1451 54 : matrix_ks(ispin)%matrix, keep_sparsity=.TRUE.)
1452 : END DO
1453 20 : eps_iter = MAX(eps_iter, scf_control%diagonalization%eps_adapt*diis_error)
1454 : ELSE
1455 44 : IF (scf_env%mixing_method == 1) THEN
1456 44 : scf_env%iter_param = scf_env%p_mix_alpha
1457 44 : scf_env%iter_method = "P_Mix/OTdiag."
1458 0 : ELSEIF (scf_env%mixing_method > 1) THEN
1459 0 : scf_env%iter_param = scf_env%mixing_store%alpha
1460 0 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/OTdiag."
1461 : END IF
1462 : END IF
1463 :
1464 64 : scf_env%iter_delta = 0.0_dp
1465 :
1466 172 : DO ispin = 1, nspin
1467 : CALL get_mo_set(mos(ispin), &
1468 : mo_coeff=mo_coeff, &
1469 : eigenvalues=eigenvalues, &
1470 : nmo=nmo, &
1471 108 : homo=homo)
1472 : CALL ot_eigensolver(matrix_h=matrix_ks(ispin)%matrix, &
1473 : matrix_s=matrix_s(1)%matrix, &
1474 : matrix_c_fm=mo_coeff, &
1475 : preconditioner=scf_env%ot_preconditioner(1)%preconditioner, &
1476 : eps_gradient=eps_iter, &
1477 : iter_max=scf_control%diagonalization%max_iter, &
1478 : silent=.TRUE., &
1479 108 : ot_settings=scf_control%diagonalization%ot_settings)
1480 : CALL calculate_subspace_eigenvalues(mo_coeff, matrix_ks(ispin)%matrix, &
1481 : evals_arg=eigenvalues, &
1482 108 : do_rotation=.TRUE.)
1483 : CALL copy_fm_to_dbcsr(mos(ispin)%mo_coeff, &
1484 280 : mos(ispin)%mo_coeff_b)
1485 : !fm->dbcsr
1486 : END DO
1487 :
1488 : CALL set_mo_occupation(mo_array=mos, &
1489 64 : smear=scf_control%smear)
1490 :
1491 172 : DO ispin = 1, nspin
1492 : ! does not yet handle k-points
1493 : CALL calculate_density_matrix(mos(ispin), &
1494 172 : scf_env%p_mix_new(ispin, 1)%matrix)
1495 : END DO
1496 :
1497 64 : END SUBROUTINE do_ot_diag
1498 :
1499 : ! **************************************************************************************************
1500 : !> \brief Solve a set restricted open Kohn-Sham (ROKS) equations based on the
1501 : !> alpha and beta Kohn-Sham matrices from unrestricted Kohn-Sham.
1502 : !> \param scf_env ...
1503 : !> \param mos ...
1504 : !> \param matrix_ks ...
1505 : !> \param matrix_s ...
1506 : !> \param scf_control ...
1507 : !> \param scf_section ...
1508 : !> \param diis_step ...
1509 : !> \param orthogonal_basis ...
1510 : !> \par History
1511 : !> 04.2006 created [MK]
1512 : !> Revised (01.05.06,MK)
1513 : !> \note
1514 : !> this is only a high-spin ROKS.
1515 : ! **************************************************************************************************
1516 1104 : SUBROUTINE do_roks_diag(scf_env, mos, matrix_ks, matrix_s, &
1517 : scf_control, scf_section, diis_step, &
1518 : orthogonal_basis)
1519 :
1520 : ! Literature: - C. C. J. Roothaan, Rev. Mod. Phys. 32, 179 (1960)
1521 : ! - M. F. Guest and V. R. Saunders, Mol. Phys. 28(3), 819 (1974)
1522 : ! - M. Filatov and S. Shaik, Chem. Phys. Lett. 288, 689 (1998)
1523 :
1524 : TYPE(qs_scf_env_type), POINTER :: scf_env
1525 : TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
1526 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
1527 : TYPE(scf_control_type), POINTER :: scf_control
1528 : TYPE(section_vals_type), POINTER :: scf_section
1529 : LOGICAL, INTENT(INOUT) :: diis_step
1530 : LOGICAL, INTENT(IN) :: orthogonal_basis
1531 :
1532 : CHARACTER(LEN=*), PARAMETER :: routineN = 'do_roks_diag'
1533 :
1534 : INTEGER :: handle, homoa, homob, imo, nalpha, nao, &
1535 : nbeta, nmo
1536 : REAL(KIND=dp) :: diis_error, level_shift_loc
1537 1104 : REAL(KIND=dp), DIMENSION(:), POINTER :: eiga, eigb, occa, occb
1538 : TYPE(cp_fm_type), POINTER :: ksa, ksb, mo2ao, moa, mob, ortho, work
1539 :
1540 : ! -------------------------------------------------------------------------
1541 :
1542 1104 : CALL timeset(routineN, handle)
1543 :
1544 1104 : IF (scf_env%cholesky_method == cholesky_inverse) THEN
1545 0 : ortho => scf_env%ortho_m1
1546 : ELSE
1547 1104 : ortho => scf_env%ortho
1548 : END IF
1549 1104 : work => scf_env%scf_work2
1550 :
1551 1104 : ksa => scf_env%scf_work1(1)
1552 1104 : ksb => scf_env%scf_work1(2)
1553 :
1554 1104 : CALL copy_dbcsr_to_fm(matrix_ks(1)%matrix, ksa)
1555 1104 : CALL copy_dbcsr_to_fm(matrix_ks(2)%matrix, ksb)
1556 :
1557 : ! Get MO information
1558 :
1559 : CALL get_mo_set(mo_set=mos(1), &
1560 : nao=nao, &
1561 : nmo=nmo, &
1562 : nelectron=nalpha, &
1563 : homo=homoa, &
1564 : eigenvalues=eiga, &
1565 : occupation_numbers=occa, &
1566 1104 : mo_coeff=moa)
1567 :
1568 : CALL get_mo_set(mo_set=mos(2), &
1569 : nelectron=nbeta, &
1570 : homo=homob, &
1571 : eigenvalues=eigb, &
1572 : occupation_numbers=occb, &
1573 1104 : mo_coeff=mob)
1574 :
1575 : ! Define the amount of level-shifting
1576 :
1577 1104 : IF ((scf_control%level_shift /= 0.0_dp) .AND. &
1578 : ((scf_control%density_guess == core_guess) .OR. &
1579 : (scf_control%density_guess == restart_guess) .OR. &
1580 : (scf_env%iter_count > 1))) THEN
1581 20 : level_shift_loc = scf_control%level_shift
1582 : ELSE
1583 1084 : level_shift_loc = 0.0_dp
1584 : END IF
1585 :
1586 : IF ((scf_env%iter_count > 1) .OR. &
1587 1104 : (scf_control%density_guess == core_guess) .OR. &
1588 : (scf_control%density_guess == restart_guess)) THEN
1589 :
1590 : ! Transform the spin unrestricted alpha and beta Kohn-Sham matrices
1591 : ! from AO basis to MO basis: K(MO) = C(T)*K(AO)*C
1592 :
1593 998 : CALL cp_fm_symm("L", "U", nao, nao, 1.0_dp, ksa, moa, 0.0_dp, work)
1594 998 : CALL parallel_gemm("T", "N", nao, nao, nao, 1.0_dp, moa, work, 0.0_dp, ksa)
1595 :
1596 998 : CALL cp_fm_symm("L", "U", nao, nao, 1.0_dp, ksb, moa, 0.0_dp, work)
1597 998 : CALL parallel_gemm("T", "N", nao, nao, nao, 1.0_dp, moa, work, 0.0_dp, ksb)
1598 :
1599 : ! Combine the spin unrestricted alpha and beta Kohn-Sham matrices
1600 : ! in the MO basis
1601 :
1602 998 : IF (scf_control%roks_scheme == general_roks) THEN
1603 : CALL combine_ks_matrices(ksa, ksb, occa, occb, scf_control%roks_f, &
1604 0 : nalpha, nbeta)
1605 998 : ELSE IF (scf_control%roks_scheme == high_spin_roks) THEN
1606 998 : CALL combine_ks_matrices(ksa, ksb, occa, occb, scf_control%roks_parameter)
1607 : ELSE
1608 0 : CPABORT("Unknown ROKS scheme requested")
1609 : END IF
1610 :
1611 : ! Back-transform the restricted open Kohn-Sham matrix from MO basis
1612 : ! to AO basis
1613 :
1614 998 : IF (orthogonal_basis) THEN
1615 : ! Q = C
1616 454 : mo2ao => moa
1617 : ELSE
1618 : ! Q = S*C
1619 544 : mo2ao => mob
1620 : !MK CALL copy_sm_to_fm(matrix_s(1)%matrix,work)
1621 : !MK CALL cp_fm_symm("L", "U",nao, nao, 1.0_dp, work, moa, 0.0_dp, mo2ao)
1622 544 : CALL cp_dbcsr_sm_fm_multiply(matrix_s(1)%matrix, moa, mo2ao, nao)
1623 : END IF
1624 :
1625 : ! K(AO) = Q*K(MO)*Q(T)
1626 :
1627 998 : CALL parallel_gemm("N", "T", nao, nao, nao, 1.0_dp, ksa, mo2ao, 0.0_dp, work)
1628 998 : CALL parallel_gemm("N", "N", nao, nao, nao, 1.0_dp, mo2ao, work, 0.0_dp, ksa)
1629 :
1630 : ELSE
1631 :
1632 : ! No transformation matrix available, yet. The closed shell part,
1633 : ! i.e. the beta Kohn-Sham matrix in AO basis, is taken.
1634 : ! There might be better choices, anyhow.
1635 :
1636 106 : CALL cp_fm_to_fm(ksb, ksa)
1637 :
1638 : END IF
1639 :
1640 : ! Update DIIS buffer and possibly perform DIIS extrapolation step
1641 :
1642 1104 : IF (scf_env%iter_count > 1) THEN
1643 992 : IF (orthogonal_basis) THEN
1644 : CALL qs_diis_b_step(diis_buffer=scf_env%scf_diis_buffer, &
1645 : mo_array=mos, &
1646 : kc=scf_env%scf_work1, &
1647 : sc=work, &
1648 : delta=scf_env%iter_delta, &
1649 : error_max=diis_error, &
1650 : diis_step=diis_step, &
1651 : eps_diis=scf_control%eps_diis, &
1652 : scf_section=scf_section, &
1653 450 : roks=.TRUE.)
1654 450 : CPASSERT(scf_env%iter_delta == scf_env%iter_delta)
1655 : ELSE
1656 : CALL qs_diis_b_step(diis_buffer=scf_env%scf_diis_buffer, &
1657 : mo_array=mos, &
1658 : kc=scf_env%scf_work1, &
1659 : sc=work, &
1660 : delta=scf_env%iter_delta, &
1661 : error_max=diis_error, &
1662 : diis_step=diis_step, &
1663 : eps_diis=scf_control%eps_diis, &
1664 : scf_section=scf_section, &
1665 : s_matrix=matrix_s, &
1666 542 : roks=.TRUE.)
1667 : END IF
1668 : END IF
1669 :
1670 1104 : IF (diis_step) THEN
1671 692 : scf_env%iter_param = diis_error
1672 692 : scf_env%iter_method = "DIIS/Diag."
1673 : ELSE
1674 412 : IF (scf_env%mixing_method == 1) THEN
1675 412 : scf_env%iter_param = scf_env%p_mix_alpha
1676 412 : scf_env%iter_method = "P_Mix/Diag."
1677 0 : ELSEIF (scf_env%mixing_method > 1) THEN
1678 0 : scf_env%iter_param = scf_env%mixing_store%alpha
1679 0 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Diag."
1680 : END IF
1681 : END IF
1682 :
1683 1104 : scf_env%iter_delta = 0.0_dp
1684 :
1685 1104 : IF (level_shift_loc /= 0.0_dp) THEN
1686 :
1687 : ! Transform the current Kohn-Sham matrix from AO to MO basis
1688 : ! for level-shifting using the current MO set
1689 :
1690 20 : CALL cp_fm_symm("L", "U", nao, nao, 1.0_dp, ksa, moa, 0.0_dp, work)
1691 20 : CALL parallel_gemm("T", "N", nao, nao, nao, 1.0_dp, moa, work, 0.0_dp, ksa)
1692 :
1693 : ! Apply level-shifting using 50:50 split of the shift (could be relaxed)
1694 :
1695 60 : DO imo = homob + 1, homoa
1696 60 : CALL cp_fm_add_to_element(ksa, imo, imo, 0.5_dp*level_shift_loc)
1697 : END DO
1698 220 : DO imo = homoa + 1, nmo
1699 220 : CALL cp_fm_add_to_element(ksa, imo, imo, level_shift_loc)
1700 : END DO
1701 :
1702 1084 : ELSE IF (.NOT. orthogonal_basis) THEN
1703 :
1704 : ! Transform the current Kohn-Sham matrix to an orthogonal basis
1705 572 : SELECT CASE (scf_env%cholesky_method)
1706 : CASE (cholesky_reduce)
1707 0 : CALL cp_fm_cholesky_reduce(ksa, ortho)
1708 : CASE (cholesky_restore)
1709 508 : CALL cp_fm_uplo_to_full(ksa, work)
1710 : CALL cp_fm_cholesky_restore(ksa, nao, ortho, work, &
1711 508 : "SOLVE", pos="RIGHT")
1712 : CALL cp_fm_cholesky_restore(work, nao, ortho, ksa, &
1713 508 : "SOLVE", pos="LEFT", transa="T")
1714 : CASE (cholesky_inverse)
1715 0 : CALL cp_fm_uplo_to_full(ksa, work)
1716 : CALL cp_fm_cholesky_restore(ksa, nao, ortho, work, &
1717 0 : "MULTIPLY", pos="RIGHT")
1718 : CALL cp_fm_cholesky_restore(work, nao, ortho, ksa, &
1719 0 : "MULTIPLY", pos="LEFT", transa="T")
1720 : CASE (cholesky_off)
1721 64 : CALL cp_fm_symm("L", "U", nao, nao, 1.0_dp, ksa, ortho, 0.0_dp, work)
1722 636 : CALL parallel_gemm("N", "N", nao, nao, nao, 1.0_dp, ortho, work, 0.0_dp, ksa)
1723 : END SELECT
1724 :
1725 : END IF
1726 :
1727 : ! Diagonalization of the ROKS operator matrix
1728 :
1729 1104 : CALL choose_eigv_solver(ksa, work, eiga)
1730 :
1731 : ! Back-transformation of the orthonormal eigenvectors if needed
1732 :
1733 1104 : IF (level_shift_loc /= 0.0_dp) THEN
1734 : ! Use old MO set for back-transformation if level-shifting was applied
1735 20 : CALL cp_fm_to_fm(moa, ortho)
1736 20 : CALL parallel_gemm("N", "N", nao, nmo, nao, 1.0_dp, ortho, work, 0.0_dp, moa)
1737 : ELSE
1738 1084 : IF (orthogonal_basis) THEN
1739 512 : CALL cp_fm_to_fm(work, moa)
1740 : ELSE
1741 1080 : SELECT CASE (scf_env%cholesky_method)
1742 : CASE (cholesky_reduce, cholesky_restore)
1743 508 : CALL cp_fm_cholesky_restore(work, nmo, ortho, moa, "SOLVE")
1744 : CASE (cholesky_inverse)
1745 0 : CALL cp_fm_cholesky_restore(work, nmo, ortho, moa, "MULTIPLY")
1746 : CASE (cholesky_off)
1747 572 : CALL parallel_gemm("N", "N", nao, nmo, nao, 1.0_dp, ortho, work, 0.0_dp, moa)
1748 : END SELECT
1749 : END IF
1750 : END IF
1751 :
1752 : ! Correct MO eigenvalues, if level-shifting was applied
1753 :
1754 1104 : IF (level_shift_loc /= 0.0_dp) THEN
1755 60 : DO imo = homob + 1, homoa
1756 60 : eiga(imo) = eiga(imo) - 0.5_dp*level_shift_loc
1757 : END DO
1758 220 : DO imo = homoa + 1, nmo
1759 220 : eiga(imo) = eiga(imo) - level_shift_loc
1760 : END DO
1761 : END IF
1762 :
1763 : ! Update also the beta MO set
1764 :
1765 34556 : eigb(:) = eiga(:)
1766 1104 : CALL cp_fm_to_fm(moa, mob)
1767 :
1768 : ! Calculate the new alpha and beta density matrix
1769 :
1770 : ! does not yet handle k-points
1771 1104 : CALL calculate_density_matrix(mos(1), scf_env%p_mix_new(1, 1)%matrix)
1772 1104 : CALL calculate_density_matrix(mos(2), scf_env%p_mix_new(2, 1)%matrix)
1773 :
1774 1104 : CALL timestop(handle)
1775 :
1776 1104 : END SUBROUTINE do_roks_diag
1777 :
1778 : ! **************************************************************************************************
1779 : !> \brief iterative diagonalization using the block Krylov-space approach
1780 : !> \param scf_env ...
1781 : !> \param mos ...
1782 : !> \param matrix_ks ...
1783 : !> \param scf_control ...
1784 : !> \param scf_section ...
1785 : !> \param check_moconv_only ...
1786 : !> \param
1787 : !> \par History
1788 : !> 05.2009 created [MI]
1789 : ! **************************************************************************************************
1790 :
1791 38 : SUBROUTINE do_block_krylov_diag(scf_env, mos, matrix_ks, &
1792 : scf_control, scf_section, check_moconv_only)
1793 :
1794 : TYPE(qs_scf_env_type), POINTER :: scf_env
1795 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
1796 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks
1797 : TYPE(scf_control_type), POINTER :: scf_control
1798 : TYPE(section_vals_type), POINTER :: scf_section
1799 : LOGICAL, INTENT(IN), OPTIONAL :: check_moconv_only
1800 :
1801 : CHARACTER(LEN=*), PARAMETER :: routineN = 'do_block_krylov_diag'
1802 : REAL(KIND=dp), PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1803 :
1804 : INTEGER :: handle, homo, ispin, iter, nao, nmo, &
1805 : output_unit
1806 : LOGICAL :: converged, my_check_moconv_only
1807 : REAL(dp) :: eps_iter, t1, t2
1808 38 : REAL(KIND=dp), DIMENSION(:), POINTER :: mo_eigenvalues
1809 : TYPE(cp_fm_type), POINTER :: c0, c1, chc, evec, ks, mo_coeff, ortho, &
1810 : work
1811 : TYPE(cp_logger_type), POINTER :: logger
1812 :
1813 76 : logger => cp_get_default_logger()
1814 38 : CALL timeset(routineN, handle)
1815 :
1816 : output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%LANCZOS", &
1817 38 : extension=".scfLog")
1818 :
1819 38 : my_check_moconv_only = .FALSE.
1820 38 : IF (PRESENT(check_moconv_only)) my_check_moconv_only = check_moconv_only
1821 :
1822 38 : NULLIFY (mo_coeff, ortho, work, ks)
1823 38 : NULLIFY (mo_eigenvalues)
1824 38 : NULLIFY (c0, c1)
1825 :
1826 38 : IF (scf_env%cholesky_method == cholesky_inverse) THEN
1827 38 : ortho => scf_env%ortho_m1
1828 : ELSE
1829 0 : ortho => scf_env%ortho
1830 : END IF
1831 38 : work => scf_env%scf_work2
1832 :
1833 76 : DO ispin = 1, SIZE(matrix_ks)
1834 : CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, &
1835 76 : scf_env%scf_work1(ispin))
1836 : END DO
1837 :
1838 38 : IF (scf_env%mixing_method == 1) THEN
1839 0 : scf_env%iter_param = scf_env%p_mix_alpha
1840 0 : scf_env%iter_method = "P_Mix/Lanczos"
1841 : ELSE
1842 : ! scf_env%iter_param = scf_env%mixing_store%alpha
1843 38 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Lanc."
1844 : END IF
1845 :
1846 76 : DO ispin = 1, SIZE(matrix_ks)
1847 :
1848 38 : ks => scf_env%scf_work1(ispin)
1849 38 : CALL cp_fm_uplo_to_full(ks, work)
1850 :
1851 : CALL get_mo_set(mo_set=mos(ispin), &
1852 : nao=nao, &
1853 : nmo=nmo, &
1854 : homo=homo, &
1855 : eigenvalues=mo_eigenvalues, &
1856 38 : mo_coeff=mo_coeff)
1857 :
1858 38 : NULLIFY (c0, c1)
1859 38 : c0 => scf_env%krylov_space%mo_conv(ispin)
1860 38 : c1 => scf_env%krylov_space%mo_refine(ispin)
1861 38 : SELECT CASE (scf_env%cholesky_method)
1862 : CASE (cholesky_reduce)
1863 0 : CALL cp_fm_cholesky_reduce(ks, ortho)
1864 0 : CALL cp_fm_uplo_to_full(ks, work)
1865 0 : CALL cp_fm_cholesky_restore(mo_coeff, nmo, ortho, c0, "MULTIPLY")
1866 : CASE (cholesky_restore)
1867 : CALL cp_fm_cholesky_restore(ks, nao, ortho, work, &
1868 0 : "SOLVE", pos="RIGHT")
1869 : CALL cp_fm_cholesky_restore(work, nao, ortho, ks, &
1870 0 : "SOLVE", pos="LEFT", transa="T")
1871 0 : CALL cp_fm_cholesky_restore(mo_coeff, nmo, ortho, c0, "MULTIPLY")
1872 : CASE (cholesky_inverse)
1873 : CALL cp_fm_cholesky_restore(ks, nao, ortho, work, &
1874 38 : "MULTIPLY", pos="RIGHT")
1875 : CALL cp_fm_cholesky_restore(work, nao, ortho, ks, &
1876 38 : "MULTIPLY", pos="LEFT", transa="T")
1877 76 : CALL cp_fm_cholesky_restore(mo_coeff, nmo, ortho, c0, "SOLVE")
1878 : END SELECT
1879 :
1880 38 : scf_env%krylov_space%nmo_nc = nmo
1881 38 : scf_env%krylov_space%nmo_conv = 0
1882 :
1883 38 : t1 = m_walltime()
1884 38 : IF (output_unit > 0) THEN
1885 0 : WRITE (output_unit, "(/T15,A)") '<<<<<<<<< LANCZOS REFINEMENT <<<<<<<<<<'
1886 : WRITE (output_unit, "(T8,A,T15,A,T23,A,T36,A,T49,A,T60,A,/,T8,A)") &
1887 0 : " Spin ", " Cycle ", &
1888 0 : " conv. MOS ", " B2MAX ", " B2MIN ", " Time", REPEAT("-", 60)
1889 : END IF
1890 38 : eps_iter = MAX(scf_env%krylov_space%eps_conv, scf_env%krylov_space%eps_adapt*scf_env%iter_delta)
1891 38 : iter = 0
1892 38 : converged = .FALSE.
1893 : !Check convergence of MOS
1894 114 : IF (my_check_moconv_only) THEN
1895 :
1896 : CALL lanczos_refinement(scf_env%krylov_space, ks, c0, c1, mo_eigenvalues, &
1897 0 : nao, eps_iter, ispin, check_moconv_only=my_check_moconv_only)
1898 0 : t2 = m_walltime()
1899 0 : IF (output_unit > 0) &
1900 : WRITE (output_unit, '(T8,I3,T16,I5,T24,I6,T33,E12.4,2x,E12.4,T60,F8.3)') &
1901 0 : ispin, iter, scf_env%krylov_space%nmo_conv, &
1902 0 : scf_env%krylov_space%max_res_norm, scf_env%krylov_space%min_res_norm, t2 - t1
1903 :
1904 : CYCLE
1905 : ELSE
1906 : !Block Lanczos refinement
1907 620 : DO iter = 1, scf_env%krylov_space%max_iter
1908 : CALL lanczos_refinement_2v(scf_env%krylov_space, ks, c0, c1, mo_eigenvalues, &
1909 592 : nao, eps_iter, ispin)
1910 592 : t2 = m_walltime()
1911 592 : IF (output_unit > 0) THEN
1912 : WRITE (output_unit, '(T8,I3,T16,I5,T24,I6,T33,E12.4,2x,E12.4,T60,F8.3)') &
1913 0 : ispin, iter, scf_env%krylov_space%nmo_conv, &
1914 0 : scf_env%krylov_space%max_res_norm, scf_env%krylov_space%min_res_norm, t2 - t1
1915 : END IF
1916 592 : t1 = m_walltime()
1917 620 : IF (scf_env%krylov_space%max_res_norm < eps_iter) THEN
1918 10 : converged = .TRUE.
1919 10 : IF (output_unit > 0) WRITE (output_unit, *) &
1920 0 : " Reached convergence in ", iter, " iterations "
1921 : EXIT
1922 : END IF
1923 : END DO
1924 :
1925 38 : IF (.NOT. converged .AND. output_unit > 0) THEN
1926 : WRITE (output_unit, "(T4, A)") " WARNING Lanczos refinement could "// &
1927 0 : "not converge all the mos:"
1928 0 : WRITE (output_unit, "(T40,A,T70,I10)") " number of not converged mos ", &
1929 0 : scf_env%krylov_space%nmo_nc
1930 0 : WRITE (output_unit, "(T40,A,T70,E10.2)") " max norm of the residual ", &
1931 0 : scf_env%krylov_space%max_res_norm
1932 :
1933 : END IF
1934 :
1935 : ! For the moment skip the re-orthogonalization
1936 : IF (.FALSE.) THEN
1937 : !Re-orthogonalization
1938 : NULLIFY (chc, evec)
1939 : chc => scf_env%krylov_space%chc_mat(ispin)
1940 : evec => scf_env%krylov_space%c_vec(ispin)
1941 : CALL parallel_gemm('N', 'N', nao, nmo, nao, rone, ks, c0, rzero, work)
1942 : CALL parallel_gemm('T', 'N', nmo, nmo, nao, rone, c0, work, rzero, chc)
1943 : !Diagonalize (C^t)HC
1944 : CALL choose_eigv_solver(chc, evec, mo_eigenvalues)
1945 : !Rotate the C vectors
1946 : CALL parallel_gemm('N', 'N', nao, nmo, nmo, rone, c0, evec, rzero, c1)
1947 : c0 => scf_env%krylov_space%mo_refine(ispin)
1948 : END IF
1949 :
1950 38 : IF (scf_env%cholesky_method == cholesky_inverse) THEN
1951 38 : CALL cp_fm_cholesky_restore(c0, nmo, ortho, mo_coeff, "MULTIPLY")
1952 : ELSE
1953 0 : CALL cp_fm_cholesky_restore(c0, nmo, ortho, mo_coeff, "SOLVE")
1954 : END IF
1955 :
1956 : CALL set_mo_occupation(mo_set=mos(ispin), &
1957 38 : smear=scf_control%smear)
1958 :
1959 : ! does not yet handle k-points
1960 : CALL calculate_density_matrix(mos(ispin), &
1961 38 : scf_env%p_mix_new(ispin, 1)%matrix)
1962 : END IF
1963 : END DO ! ispin
1964 :
1965 38 : IF (output_unit > 0) THEN
1966 0 : WRITE (output_unit, "(T15,A/)") '<<<<<<<<< END LANCZOS REFINEMENT <<<<<<<<<<'
1967 : END IF
1968 :
1969 : CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
1970 38 : "PRINT%LANCZOS")
1971 :
1972 38 : CALL timestop(handle)
1973 :
1974 38 : END SUBROUTINE do_block_krylov_diag
1975 :
1976 : ! **************************************************************************************************
1977 : !> \brief iterative diagonalization using the block davidson space approach
1978 : !> \param qs_env ...
1979 : !> \param scf_env ...
1980 : !> \param mos ...
1981 : !> \param matrix_ks ...
1982 : !> \param matrix_s ...
1983 : !> \param scf_control ...
1984 : !> \param scf_section ...
1985 : !> \param check_moconv_only ...
1986 : !> \param
1987 : !> \par History
1988 : !> 05.2011 created [MI]
1989 : ! **************************************************************************************************
1990 :
1991 84 : SUBROUTINE do_block_davidson_diag(qs_env, scf_env, mos, matrix_ks, matrix_s, &
1992 : scf_control, scf_section, check_moconv_only)
1993 :
1994 : TYPE(qs_environment_type), POINTER :: qs_env
1995 : TYPE(qs_scf_env_type), POINTER :: scf_env
1996 : TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
1997 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
1998 : TYPE(scf_control_type), POINTER :: scf_control
1999 : TYPE(section_vals_type), POINTER :: scf_section
2000 : LOGICAL, INTENT(IN), OPTIONAL :: check_moconv_only
2001 :
2002 : CHARACTER(LEN=*), PARAMETER :: routineN = 'do_block_davidson_diag'
2003 :
2004 : INTEGER :: handle, ispin, nspins, output_unit
2005 : LOGICAL :: do_prec, my_check_moconv_only
2006 : TYPE(cp_logger_type), POINTER :: logger
2007 :
2008 84 : logger => cp_get_default_logger()
2009 84 : CALL timeset(routineN, handle)
2010 :
2011 : output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DAVIDSON", &
2012 84 : extension=".scfLog")
2013 :
2014 84 : IF (output_unit > 0) &
2015 0 : WRITE (output_unit, "(/T15,A)") '<<<<<<<<< DAVIDSON ITERATIONS <<<<<<<<<<'
2016 :
2017 84 : IF (scf_env%mixing_method == 1) THEN
2018 0 : scf_env%iter_param = scf_env%p_mix_alpha
2019 0 : scf_env%iter_method = "P_Mix/Dav."
2020 : ELSE
2021 84 : scf_env%iter_param = scf_env%mixing_store%alpha
2022 84 : scf_env%iter_method = TRIM(scf_env%mixing_store%iter_method)//"/Dav."
2023 : END IF
2024 :
2025 84 : my_check_moconv_only = .FALSE.
2026 84 : IF (PRESENT(check_moconv_only)) my_check_moconv_only = check_moconv_only
2027 84 : do_prec = .FALSE.
2028 84 : IF (scf_env%block_davidson_env(1)%prec_type /= 0 .AND. &
2029 : scf_env%iter_count >= scf_env%block_davidson_env(1)%first_prec) THEN
2030 76 : do_prec = .TRUE.
2031 : END IF
2032 :
2033 84 : nspins = SIZE(matrix_ks)
2034 :
2035 84 : IF (do_prec .AND. (scf_env%iter_count == scf_env%block_davidson_env(1)%first_prec .OR. &
2036 : MODULO(scf_env%iter_count, scf_env%block_davidson_env(1)%niter_new_prec) == 0)) THEN
2037 : CALL restart_preconditioner(qs_env, scf_env%ot_preconditioner, &
2038 16 : prec_type=scf_env%block_davidson_env(1)%prec_type, nspins=nspins)
2039 : CALL prepare_preconditioner(qs_env, mos, matrix_ks, matrix_s, scf_env%ot_preconditioner, &
2040 : scf_env%block_davidson_env(1)%prec_type, &
2041 : scf_env%block_davidson_env(1)%solver_type, &
2042 : scf_env%block_davidson_env(1)%energy_gap, nspins, &
2043 : convert_to_dbcsr=scf_env%block_davidson_env(1)%use_sparse_mos, &
2044 16 : full_mo_set=.TRUE.)
2045 : END IF
2046 :
2047 178 : DO ispin = 1, nspins
2048 178 : IF (scf_env%block_davidson_env(ispin)%use_sparse_mos) THEN
2049 64 : IF (.NOT. do_prec) THEN
2050 : CALL generate_extended_space_sparse(scf_env%block_davidson_env(ispin), mos(ispin), &
2051 8 : matrix_ks(ispin)%matrix, matrix_s(1)%matrix, output_unit)
2052 : ELSE
2053 : CALL generate_extended_space_sparse(scf_env%block_davidson_env(ispin), mos(ispin), &
2054 : matrix_ks(ispin)%matrix, matrix_s(1)%matrix, output_unit, &
2055 56 : scf_env%ot_preconditioner(ispin)%preconditioner)
2056 : END IF
2057 :
2058 : ELSE
2059 30 : IF (.NOT. do_prec) THEN
2060 : CALL generate_extended_space(scf_env%block_davidson_env(ispin), mos(ispin), &
2061 2 : matrix_ks(ispin)%matrix, matrix_s(1)%matrix, output_unit)
2062 : ELSE
2063 : CALL generate_extended_space(scf_env%block_davidson_env(ispin), mos(ispin), &
2064 : matrix_ks(ispin)%matrix, matrix_s(1)%matrix, output_unit, &
2065 28 : scf_env%ot_preconditioner(ispin)%preconditioner)
2066 : END IF
2067 : END IF
2068 : END DO !ispin
2069 :
2070 : CALL set_mo_occupation(mo_array=mos, &
2071 84 : smear=scf_control%smear)
2072 :
2073 178 : DO ispin = 1, nspins
2074 : ! does not yet handle k-points
2075 : CALL calculate_density_matrix(mos(ispin), &
2076 178 : scf_env%p_mix_new(ispin, 1)%matrix)
2077 : END DO
2078 :
2079 84 : IF (output_unit > 0) THEN
2080 0 : WRITE (output_unit, "(T15,A/)") '<<<<<<<<< END DAVIDSON ITERATION <<<<<<<<<<'
2081 : END IF
2082 :
2083 : CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
2084 84 : "PRINT%DAVIDSON")
2085 :
2086 84 : CALL timestop(handle)
2087 :
2088 84 : END SUBROUTINE do_block_davidson_diag
2089 :
2090 : ! **************************************************************************************************
2091 : !> \brief Kpoint diagonalization routine
2092 : !> Transforms matrices to kpoint, distributes kpoint groups, performs diagonalization
2093 : !> \param matrix_s Overlap matrices (RS indices, global)
2094 : !> \param kpoints Kpoint environment
2095 : !> \param fmwork full matrices distributed over all groups
2096 : !> \par History
2097 : !> 02.2026 created [JGH]
2098 : ! **************************************************************************************************
2099 0 : SUBROUTINE diag_kp_smat(matrix_s, kpoints, fmwork)
2100 :
2101 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_s
2102 : TYPE(kpoint_type), POINTER :: kpoints
2103 : TYPE(cp_fm_type), DIMENSION(:) :: fmwork
2104 :
2105 : CHARACTER(len=*), PARAMETER :: routineN = 'diag_kp_smat'
2106 : COMPLEX(KIND=dp), PARAMETER :: cone = (1.0_dp, 0.0_dp), &
2107 : czero = (0.0_dp, 0.0_dp)
2108 :
2109 0 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:) :: ceig
2110 : INTEGER :: handle, igroup, ik, ikp, indx, kplocal, &
2111 : nao, nkp, nkp_groups
2112 : INTEGER, DIMENSION(2) :: kp_range
2113 0 : INTEGER, DIMENSION(:, :), POINTER :: kp_dist
2114 0 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
2115 : LOGICAL :: my_kpgrp, use_real_wfn
2116 0 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues
2117 0 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: xkp
2118 0 : TYPE(copy_info_type), ALLOCATABLE, DIMENSION(:, :) :: info
2119 : TYPE(cp_cfm_type) :: csmat, cwork
2120 0 : TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_ao_fm_pools
2121 : TYPE(cp_fm_struct_type), POINTER :: matrix_struct
2122 : TYPE(cp_fm_type) :: fmdummy, fmlocal, rsmat
2123 : TYPE(dbcsr_type), POINTER :: cmatrix, rmatrix, tmpmat
2124 : TYPE(kpoint_env_type), POINTER :: kp
2125 : TYPE(mp_para_env_type), POINTER :: para_env
2126 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
2127 0 : POINTER :: sab_nl
2128 : TYPE(qs_matrix_pools_type), POINTER :: mpools
2129 :
2130 0 : CALL timeset(routineN, handle)
2131 :
2132 0 : NULLIFY (sab_nl)
2133 : CALL get_kpoint_info(kpoints, nkp=nkp, xkp=xkp, use_real_wfn=use_real_wfn, kp_range=kp_range, &
2134 : nkp_groups=nkp_groups, kp_dist=kp_dist, sab_nl=sab_nl, &
2135 0 : cell_to_index=cell_to_index)
2136 0 : CPASSERT(ASSOCIATED(sab_nl))
2137 0 : kplocal = kp_range(2) - kp_range(1) + 1
2138 :
2139 : ! allocate some work matrices
2140 0 : ALLOCATE (rmatrix, cmatrix, tmpmat)
2141 : CALL dbcsr_create(rmatrix, template=matrix_s(1, 1)%matrix, &
2142 0 : matrix_type=dbcsr_type_symmetric)
2143 : CALL dbcsr_create(cmatrix, template=matrix_s(1, 1)%matrix, &
2144 0 : matrix_type=dbcsr_type_antisymmetric)
2145 : CALL dbcsr_create(tmpmat, template=matrix_s(1, 1)%matrix, &
2146 0 : matrix_type=dbcsr_type_no_symmetry)
2147 0 : CALL cp_dbcsr_alloc_block_from_nbl(rmatrix, sab_nl)
2148 0 : CALL cp_dbcsr_alloc_block_from_nbl(cmatrix, sab_nl)
2149 :
2150 : ! fm pools to be used within a kpoint group
2151 0 : CALL get_kpoint_info(kpoints, mpools=mpools)
2152 0 : CALL mpools_get(mpools, ao_ao_fm_pools=ao_ao_fm_pools)
2153 :
2154 0 : CALL fm_pool_create_fm(ao_ao_fm_pools(1)%pool, fmlocal)
2155 0 : CALL cp_fm_get_info(fmlocal, matrix_struct=matrix_struct)
2156 :
2157 0 : IF (use_real_wfn) THEN
2158 0 : CALL cp_fm_create(rsmat, matrix_struct)
2159 : ELSE
2160 0 : CALL cp_cfm_create(csmat, matrix_struct)
2161 0 : CALL cp_cfm_create(cwork, matrix_struct)
2162 : END IF
2163 :
2164 0 : CALL cp_fm_get_info(fmwork(1), nrow_global=nao)
2165 0 : ALLOCATE (eigenvalues(nao), ceig(nao))
2166 :
2167 0 : para_env => kpoints%blacs_env_all%para_env
2168 0 : ALLOCATE (info(kplocal*nkp_groups, 2))
2169 :
2170 : ! Setup and start all the communication
2171 0 : indx = 0
2172 0 : DO ikp = 1, kplocal
2173 0 : DO igroup = 1, nkp_groups
2174 : ! number of current kpoint
2175 0 : ik = kp_dist(1, igroup) + ikp - 1
2176 0 : my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
2177 0 : indx = indx + 1
2178 0 : IF (use_real_wfn) THEN
2179 0 : CALL dbcsr_set(rmatrix, 0.0_dp)
2180 : CALL rskp_transform(rmatrix=rmatrix, rsmat=matrix_s, ispin=1, &
2181 0 : xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
2182 0 : CALL dbcsr_desymmetrize(rmatrix, tmpmat)
2183 0 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(1))
2184 : ELSE
2185 0 : CALL dbcsr_set(rmatrix, 0.0_dp)
2186 0 : CALL dbcsr_set(cmatrix, 0.0_dp)
2187 : CALL rskp_transform(rmatrix=rmatrix, cmatrix=cmatrix, rsmat=matrix_s, ispin=1, &
2188 0 : xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
2189 0 : CALL dbcsr_desymmetrize(rmatrix, tmpmat)
2190 0 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(1))
2191 0 : CALL dbcsr_desymmetrize(cmatrix, tmpmat)
2192 0 : CALL copy_dbcsr_to_fm(tmpmat, fmwork(2))
2193 : END IF
2194 : ! transfer to kpoint group
2195 : ! redistribution of matrices, new blacs environment
2196 : ! fmwork -> fmlocal -> rsmat/csmat
2197 0 : IF (use_real_wfn) THEN
2198 0 : IF (my_kpgrp) THEN
2199 0 : CALL cp_fm_start_copy_general(fmwork(1), rsmat, para_env, info(indx, 1))
2200 : ELSE
2201 0 : CALL cp_fm_start_copy_general(fmwork(1), fmdummy, para_env, info(indx, 1))
2202 : END IF
2203 : ELSE
2204 0 : IF (my_kpgrp) THEN
2205 0 : CALL cp_fm_start_copy_general(fmwork(1), fmlocal, para_env, info(indx, 1))
2206 0 : CALL cp_fm_start_copy_general(fmwork(2), fmlocal, para_env, info(indx, 2))
2207 : ELSE
2208 0 : CALL cp_fm_start_copy_general(fmwork(1), fmdummy, para_env, info(indx, 1))
2209 0 : CALL cp_fm_start_copy_general(fmwork(2), fmdummy, para_env, info(indx, 2))
2210 : END IF
2211 : END IF
2212 : END DO
2213 : END DO
2214 :
2215 : ! Finish communication then diagonalise in each group
2216 : indx = 0
2217 0 : DO ikp = 1, kplocal
2218 0 : DO igroup = 1, nkp_groups
2219 : ! number of current kpoint
2220 0 : ik = kp_dist(1, igroup) + ikp - 1
2221 0 : my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
2222 0 : indx = indx + 1
2223 0 : IF (my_kpgrp) THEN
2224 0 : IF (use_real_wfn) THEN
2225 0 : CALL cp_fm_finish_copy_general(rsmat, info(indx, 1))
2226 : ELSE
2227 0 : CALL cp_fm_finish_copy_general(fmlocal, info(indx, 1))
2228 0 : CALL cp_cfm_scale_and_add_fm(z_zero, csmat, z_one, fmlocal)
2229 0 : CALL cp_fm_finish_copy_general(fmlocal, info(indx, 2))
2230 0 : CALL cp_cfm_scale_and_add_fm(z_one, csmat, gaussi, fmlocal)
2231 : END IF
2232 : END IF
2233 : END DO
2234 :
2235 : ! Each kpoint group has now information on a kpoint to be diagonalized
2236 : ! Eigensolver Hermite or Symmetric
2237 0 : kp => kpoints%kp_env(ikp)%kpoint_env
2238 0 : IF (use_real_wfn) THEN
2239 0 : CALL choose_eigv_solver(rsmat, fmlocal, eigenvalues)
2240 : ELSE
2241 0 : CALL cp_cfm_heevd(csmat, cwork, eigenvalues)
2242 : END IF
2243 0 : CPASSERT(ALL(eigenvalues(1:nao) >= 0.0_dp))
2244 0 : IF (use_real_wfn) THEN
2245 0 : CALL cp_fm_release(kp%shalf)
2246 0 : CALL cp_fm_create(kp%shalf, matrix_struct)
2247 0 : eigenvalues(1:nao) = SQRT(eigenvalues(1:nao))
2248 0 : CALL cp_fm_to_fm(fmlocal, rsmat)
2249 0 : CALL cp_fm_column_scale(rsmat, eigenvalues)
2250 : CALL parallel_gemm("N", "T", nao, nao, nao, 1.0_dp, rsmat, fmlocal, &
2251 0 : 0.0_dp, kp%shalf)
2252 : ELSE
2253 0 : CALL cp_cfm_release(kp%cshalf)
2254 0 : CALL cp_cfm_create(kp%cshalf, matrix_struct)
2255 0 : ceig(1:nao) = SQRT(eigenvalues(1:nao))
2256 0 : CALL cp_cfm_to_cfm(cwork, csmat)
2257 0 : CALL cp_cfm_column_scale(csmat, ceig)
2258 : CALL parallel_gemm("N", "T", nao, nao, nao, cone, csmat, cwork, &
2259 0 : czero, kp%cshalf)
2260 : END IF
2261 : END DO
2262 :
2263 : ! Clean up communication
2264 : indx = 0
2265 0 : DO ikp = 1, kplocal
2266 0 : DO igroup = 1, nkp_groups
2267 : ! number of current kpoint
2268 0 : ik = kp_dist(1, igroup) + ikp - 1
2269 0 : my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
2270 0 : indx = indx + 1
2271 0 : IF (use_real_wfn) THEN
2272 0 : CALL cp_fm_cleanup_copy_general(info(indx, 1))
2273 : ELSE
2274 0 : CALL cp_fm_cleanup_copy_general(info(indx, 1))
2275 0 : CALL cp_fm_cleanup_copy_general(info(indx, 2))
2276 : END IF
2277 : END DO
2278 : END DO
2279 :
2280 : ! All done
2281 0 : DEALLOCATE (info)
2282 0 : DEALLOCATE (eigenvalues, ceig)
2283 :
2284 0 : CALL dbcsr_deallocate_matrix(rmatrix)
2285 0 : CALL dbcsr_deallocate_matrix(cmatrix)
2286 0 : CALL dbcsr_deallocate_matrix(tmpmat)
2287 :
2288 0 : IF (use_real_wfn) THEN
2289 0 : CALL cp_fm_release(rsmat)
2290 : ELSE
2291 0 : CALL cp_cfm_release(csmat)
2292 0 : CALL cp_cfm_release(cwork)
2293 : END IF
2294 0 : CALL fm_pool_give_back_fm(ao_ao_fm_pools(1)%pool, fmlocal)
2295 :
2296 0 : CALL timestop(handle)
2297 :
2298 0 : END SUBROUTINE diag_kp_smat
2299 :
2300 : END MODULE qs_scf_diagonalization
|