(git:97cfbf5)
Loading...
Searching...
No Matches
qs_scf_diagonalization.F
Go to the documentation of this file.
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! **************************************************************************************************
20 USE cp_cfm_diag, ONLY: cp_cfm_geeig,&
23 USE cp_cfm_types, ONLY: cp_cfm_create,&
31 USE cp_dbcsr_api, ONLY: &
33 dbcsr_set, dbcsr_type, dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, &
34 dbcsr_type_symmetric
50 diag_type,&
58 USE cp_fm_types, ONLY: &
66 USE input_constants, ONLY: &
71 USE kinds, ONLY: dp
76 USE kpoint_types, ONLY: get_kpoint_info,&
79 USE machine, ONLY: m_flush,&
81 USE mathconstants, ONLY: gaussi,&
82 z_one,&
83 z_zero
100 USE qs_ks_types, ONLY: qs_ks_did_change,&
102 USE qs_matrix_pools, ONLY: mpools_get,&
110 USE qs_mo_types, ONLY: get_mo_set,&
116 USE qs_rho_types, ONLY: qs_rho_get,&
129 USE qs_scf_types, ONLY: qs_scf_env_type,&
132#include "./base/base_uses.f90"
133
134 IMPLICIT NONE
135
136 PRIVATE
137
138 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_scf_diagonalization'
139
144
145CONTAINS
146
147! **************************************************************************************************
148!> \brief the inner loop of scf, specific to diagonalization with S matrix
149!> basically, in goes the ks matrix out goes a new p matrix
150!> \param scf_env ...
151!> \param mos ...
152!> \param matrix_ks ...
153!> \param matrix_s ...
154!> \param scf_control ...
155!> \param scf_section ...
156!> \param diis_step ...
157!> \par History
158!> 03.2006 created [Joost VandeVondele]
159! **************************************************************************************************
160
161 SUBROUTINE general_eigenproblem(scf_env, mos, matrix_ks, &
162 matrix_s, scf_control, scf_section, &
163 diis_step)
164
165 TYPE(qs_scf_env_type), POINTER :: scf_env
166 TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
167 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
168 TYPE(scf_control_type), POINTER :: scf_control
169 TYPE(section_vals_type), POINTER :: scf_section
170 LOGICAL, INTENT(INOUT) :: diis_step
171
172 INTEGER :: ispin, nao, nspin
173 LOGICAL :: do_level_shift, owns_ortho, use_jacobi
174 REAL(kind=dp) :: diis_error, eps_diis
175 TYPE(cp_fm_type), POINTER :: ortho
176 TYPE(dbcsr_type), POINTER :: ortho_dbcsr
177
178 nspin = SIZE(matrix_ks)
179 NULLIFY (ortho, ortho_dbcsr)
180
181 DO ispin = 1, nspin
182 CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, &
183 scf_env%scf_work1(ispin))
184 END DO
185
186 eps_diis = scf_control%eps_diis
187
188 IF (scf_env%iter_count > 1 .AND. .NOT. scf_env%skip_diis) THEN
189 CALL qs_diis_b_step(scf_env%scf_diis_buffer, mos, scf_env%scf_work1, &
190 scf_env%scf_work2, scf_env%iter_delta, diis_error, diis_step, &
191 eps_diis, scf_control%nmixing, &
192 s_matrix=matrix_s, &
193 scf_section=scf_section)
194 ELSE
195 diis_step = .false.
196 END IF
197
198 do_level_shift = ((scf_control%level_shift /= 0.0_dp) .AND. &
199 ((scf_control%density_guess == core_guess) .OR. &
200 (scf_env%iter_count > 1)))
201
202 IF ((scf_env%iter_count > 1) .AND. &
203 (scf_env%iter_delta < scf_control%diagonalization%eps_jacobi)) THEN
204 use_jacobi = .true.
205 ELSE
206 use_jacobi = .false.
207 END IF
208
209 IF (diis_step) THEN
210 scf_env%iter_param = diis_error
211 IF (use_jacobi) THEN
212 scf_env%iter_method = "DIIS/Jacobi"
213 ELSE
214 scf_env%iter_method = "DIIS/Diag."
215 END IF
216 ELSE
217 IF (scf_env%mixing_method == 0) THEN
218 scf_env%iter_method = "NoMix/Diag."
219 ELSE IF (scf_env%mixing_method == 1) THEN
220 scf_env%iter_param = scf_env%p_mix_alpha
221 IF (use_jacobi) THEN
222 scf_env%iter_method = "P_Mix/Jacobi"
223 ELSE
224 scf_env%iter_method = "P_Mix/Diag."
225 END IF
226 ELSEIF (scf_env%mixing_method > 1) THEN
227 scf_env%iter_param = scf_env%mixing_store%alpha
228 IF (use_jacobi) THEN
229 scf_env%iter_method = trim(scf_env%mixing_store%iter_method)//"/Jacobi"
230 ELSE
231 scf_env%iter_method = trim(scf_env%mixing_store%iter_method)//"/Diag."
232 END IF
233 END IF
234 END IF
235
236 IF (scf_env%cholesky_method == cholesky_dbcsr) THEN
237 ortho_dbcsr => scf_env%ortho_dbcsr
238 DO ispin = 1, nspin
239 CALL eigensolver_dbcsr(matrix_ks=matrix_ks(ispin)%matrix, matrix_ks_fm=scf_env%scf_work1(ispin), &
240 mo_set=mos(ispin), &
241 ortho_dbcsr=ortho_dbcsr, &
242 ksbuf1=scf_env%buf1_dbcsr, ksbuf2=scf_env%buf2_dbcsr)
243 END DO
244
245 ELSE IF (scf_env%cholesky_method > cholesky_off) THEN
246 IF (scf_env%cholesky_method == cholesky_inverse) THEN
247 ortho => scf_env%ortho_m1
248 ELSE
249 ortho => scf_env%ortho
250 END IF
251
252 owns_ortho = .false.
253 IF (.NOT. ASSOCIATED(ortho)) THEN
254 ALLOCATE (ortho)
255 owns_ortho = .true.
256 END IF
257
258 DO ispin = 1, nspin
259 CALL cp_fm_get_info(scf_env%scf_work1(ispin), nrow_global=nao)
261 nao >= cusolver_n_min .AND. .NOT. do_level_shift) THEN
262 CALL eigensolver_generalized(matrix_ks_fm=scf_env%scf_work1(ispin), &
263 matrix_s=matrix_s(ispin)%matrix, &
264 mo_set=mos(ispin), &
265 work=scf_env%scf_work2)
266 ELSE
267 IF (do_level_shift) THEN
268 CALL eigensolver(matrix_ks_fm=scf_env%scf_work1(ispin), &
269 mo_set=mos(ispin), &
270 ortho=ortho, &
271 work=scf_env%scf_work2, &
272 cholesky_method=scf_env%cholesky_method, &
273 do_level_shift=do_level_shift, &
274 level_shift=scf_control%level_shift, &
275 matrix_u_fm=scf_env%ortho, &
276 use_jacobi=use_jacobi)
277 ELSE
278 CALL eigensolver(matrix_ks_fm=scf_env%scf_work1(ispin), &
279 mo_set=mos(ispin), &
280 ortho=ortho, &
281 work=scf_env%scf_work2, &
282 cholesky_method=scf_env%cholesky_method, &
283 do_level_shift=do_level_shift, &
284 level_shift=scf_control%level_shift, &
285 use_jacobi=use_jacobi)
286 END IF
287 END IF
288 END DO
289
290 IF (owns_ortho) DEALLOCATE (ortho)
291 ELSE
292 ortho => scf_env%ortho
293
294 owns_ortho = .false.
295 IF (.NOT. ASSOCIATED(ortho)) THEN
296 ALLOCATE (ortho)
297 owns_ortho = .true.
298 END IF
299
300 IF (do_level_shift) THEN
301 DO ispin = 1, nspin
302 IF (ASSOCIATED(scf_env%scf_work1_red) .AND. ASSOCIATED(scf_env%scf_work2_red) &
303 .AND. ASSOCIATED(scf_env%ortho_red) .AND. ASSOCIATED(scf_env%ortho_m1_red)) THEN
304 CALL eigensolver_symm(matrix_ks_fm=scf_env%scf_work1(ispin), &
305 mo_set=mos(ispin), &
306 ortho=ortho, &
307 work=scf_env%scf_work2, &
308 do_level_shift=do_level_shift, &
309 level_shift=scf_control%level_shift, &
310 matrix_u_fm=scf_env%ortho_m1, &
311 use_jacobi=use_jacobi, &
312 jacobi_threshold=scf_control%diagonalization%jacobi_threshold, &
313 matrix_ks_fm_red=scf_env%scf_work1_red(ispin), &
314 ortho_red=scf_env%ortho_red, &
315 work_red=scf_env%scf_work2_red, &
316 matrix_u_fm_red=scf_env%ortho_m1_red)
317 ELSE
318 CALL eigensolver_symm(matrix_ks_fm=scf_env%scf_work1(ispin), &
319 mo_set=mos(ispin), &
320 ortho=ortho, &
321 work=scf_env%scf_work2, &
322 do_level_shift=do_level_shift, &
323 level_shift=scf_control%level_shift, &
324 matrix_u_fm=scf_env%ortho_m1, &
325 use_jacobi=use_jacobi, &
326 jacobi_threshold=scf_control%diagonalization%jacobi_threshold)
327 END IF
328 END DO
329 ELSE
330 DO ispin = 1, nspin
331 IF (ASSOCIATED(scf_env%scf_work1_red) .AND. ASSOCIATED(scf_env%scf_work2_red) &
332 .AND. ASSOCIATED(scf_env%ortho_red)) THEN
333 CALL eigensolver_symm(matrix_ks_fm=scf_env%scf_work1(ispin), &
334 mo_set=mos(ispin), &
335 ortho=ortho, &
336 work=scf_env%scf_work2, &
337 do_level_shift=do_level_shift, &
338 level_shift=scf_control%level_shift, &
339 use_jacobi=use_jacobi, &
340 jacobi_threshold=scf_control%diagonalization%jacobi_threshold, &
341 matrix_ks_fm_red=scf_env%scf_work1_red(ispin), &
342 ortho_red=scf_env%ortho_red, &
343 work_red=scf_env%scf_work2_red)
344 ELSE
345 CALL eigensolver_symm(matrix_ks_fm=scf_env%scf_work1(ispin), &
346 mo_set=mos(ispin), &
347 ortho=ortho, &
348 work=scf_env%scf_work2, &
349 do_level_shift=do_level_shift, &
350 level_shift=scf_control%level_shift, &
351 use_jacobi=use_jacobi, &
352 jacobi_threshold=scf_control%diagonalization%jacobi_threshold)
353 END IF
354 END DO
355 END IF
356
357 IF (owns_ortho) DEALLOCATE (ortho)
358 END IF
359
360 END SUBROUTINE general_eigenproblem
361
362! **************************************************************************************************
363!> \brief ...
364!> \param scf_env ...
365!> \param mos ...
366!> \param matrix_ks ...
367!> \param matrix_s ...
368!> \param scf_control ...
369!> \param scf_section ...
370!> \param diis_step ...
371!> \param probe ...
372! **************************************************************************************************
373 SUBROUTINE do_general_diag(scf_env, mos, matrix_ks, &
374 matrix_s, scf_control, scf_section, &
375 diis_step, probe)
376
377 TYPE(qs_scf_env_type), POINTER :: scf_env
378 TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
379 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
380 TYPE(scf_control_type), POINTER :: scf_control
381 TYPE(section_vals_type), POINTER :: scf_section
382 LOGICAL, INTENT(INOUT) :: diis_step
383 TYPE(hairy_probes_type), DIMENSION(:), OPTIONAL, &
384 POINTER :: probe
385
386 INTEGER :: ispin, nspin
387 REAL(kind=dp) :: total_zeff_corr
388
389 nspin = SIZE(matrix_ks)
390
391 CALL general_eigenproblem(scf_env, mos, matrix_ks, &
392 matrix_s, scf_control, scf_section, diis_step)
393
394 total_zeff_corr = 0.0_dp
395 total_zeff_corr = scf_env%sum_zeff_corr
396
397 IF (abs(total_zeff_corr) > 0.0_dp) THEN
398 CALL set_mo_occupation(mo_array=mos, &
399 smear=scf_control%smear, tot_zeff_corr=total_zeff_corr)
400 ELSE
401 IF (PRESENT(probe) .EQV. .true.) THEN
402 scf_control%smear%do_smear = .false.
403 CALL set_mo_occupation(mo_array=mos, &
404 smear=scf_control%smear, &
405 probe=probe)
406 ELSE
407 IF (.NOT. scf_control%gce%do_gce) THEN
408 CALL set_mo_occupation(mo_array=mos, &
409 smear=scf_control%smear)
410 ELSE
411 CALL set_mo_occupation(mo_array=mos, &
412 smear=scf_control%smear, &
413 gce=scf_control%gce)
414 END IF
415 END IF
416 END IF
417
418 DO ispin = 1, nspin
419 CALL calculate_density_matrix(mos(ispin), &
420 scf_env%p_mix_new(ispin, 1)%matrix)
421 END DO
422
423 END SUBROUTINE do_general_diag
424
425! **************************************************************************************************
426!> \brief Kpoint diagonalization routine
427!> Transforms matrices to kpoint, distributes kpoint groups, performs
428!> general diagonalization (no storgae of overlap decomposition), stores
429!> MOs, calculates occupation numbers, calculates density matrices
430!> in kpoint representation, transforms density matrices to real space
431!> \param matrix_ks Kohn-sham matrices (RS indices, global)
432!> \param matrix_s Overlap matrices (RS indices, global)
433!> \param kpoints Kpoint environment
434!> \param scf_env SCF environment
435!> \param scf_control SCF control variables
436!> \param update_p ...
437!> \param diis_step ...
438!> \param diis_error ...
439!> \param qs_env ...
440!> \param probe ...
441!> \par History
442!> 08.2014 created [JGH]
443! **************************************************************************************************
444 SUBROUTINE do_general_diag_kp(matrix_ks, matrix_s, kpoints, scf_env, scf_control, update_p, &
445 diis_step, diis_error, qs_env, probe)
446
447 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks, matrix_s
448 TYPE(kpoint_type), POINTER :: kpoints
449 TYPE(qs_scf_env_type), POINTER :: scf_env
450 TYPE(scf_control_type), POINTER :: scf_control
451 LOGICAL, INTENT(IN) :: update_p
452 LOGICAL, INTENT(INOUT) :: diis_step
453 REAL(dp), INTENT(INOUT), OPTIONAL :: diis_error
454 TYPE(qs_environment_type), OPTIONAL, POINTER :: qs_env
455 TYPE(hairy_probes_type), DIMENSION(:), OPTIONAL, &
456 POINTER :: probe
457
458 CHARACTER(len=*), PARAMETER :: routinen = 'do_general_diag_kp'
459
460 COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:) :: coeffs
461 INTEGER :: handle, ib, igroup, ik, ikp, indx, &
462 ispin, jb, kplocal, nb, nkp, &
463 nkp_groups, nspin
464 INTEGER, DIMENSION(2) :: kp_range
465 INTEGER, DIMENSION(:, :), POINTER :: kp_dist
466 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
467 LOGICAL :: do_diis, my_kpgrp, use_real_wfn
468 REAL(kind=dp), DIMENSION(:), POINTER :: eigenvalues
469 REAL(kind=dp), DIMENSION(:, :), POINTER :: xkp
470 TYPE(copy_info_type), ALLOCATABLE, DIMENSION(:, :) :: info
471 TYPE(cp_cfm_type) :: cksmat, cmos, csmat, cwork
472 TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_ao_fm_pools
473 TYPE(cp_fm_struct_type), POINTER :: matrix_struct, mo_struct
474 TYPE(cp_fm_type) :: fmdummy, fmlocal, rksmat, rsmat
475 TYPE(cp_fm_type), DIMENSION(:), POINTER :: fmwork
476 TYPE(cp_fm_type), POINTER :: imos, mo_coeff, rmos
477 TYPE(dbcsr_type), POINTER :: cmatrix, rmatrix, tmpmat
478 TYPE(kpoint_env_type), POINTER :: kp
479 TYPE(mp_para_env_type), POINTER :: para_env, para_env_global
480 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
481 POINTER :: sab_nl
482 TYPE(qs_matrix_pools_type), POINTER :: mpools
483 TYPE(section_vals_type), POINTER :: scf_section
484
485 CALL timeset(routinen, handle)
486
487 NULLIFY (sab_nl)
488 CALL get_kpoint_info(kpoints, nkp=nkp, xkp=xkp, use_real_wfn=use_real_wfn, kp_range=kp_range, &
489 nkp_groups=nkp_groups, kp_dist=kp_dist, sab_nl=sab_nl, &
490 cell_to_index=cell_to_index)
491 cpassert(ASSOCIATED(sab_nl))
492 kplocal = kp_range(2) - kp_range(1) + 1
493
494 !Whether we use DIIS for k-points
495 do_diis = .false.
496 IF (scf_env%iter_count > 1 .AND. .NOT. scf_env%skip_diis .AND. .NOT. use_real_wfn &
497 .AND. PRESENT(diis_error) .AND. PRESENT(qs_env)) do_diis = .true.
498
499 ! allocate some work matrices
500 ALLOCATE (rmatrix, cmatrix, tmpmat)
501 CALL dbcsr_create(rmatrix, template=matrix_ks(1, 1)%matrix, &
502 matrix_type=dbcsr_type_symmetric)
503 CALL dbcsr_create(cmatrix, template=matrix_ks(1, 1)%matrix, &
504 matrix_type=dbcsr_type_antisymmetric)
505 CALL dbcsr_create(tmpmat, template=matrix_ks(1, 1)%matrix, &
506 matrix_type=dbcsr_type_no_symmetry)
507 CALL cp_dbcsr_alloc_block_from_nbl(rmatrix, sab_nl)
508 CALL cp_dbcsr_alloc_block_from_nbl(cmatrix, sab_nl)
509
510 fmwork => scf_env%scf_work1
511
512 ! fm pools to be used within a kpoint group
513 CALL get_kpoint_info(kpoints, mpools=mpools)
514 CALL mpools_get(mpools, ao_ao_fm_pools=ao_ao_fm_pools)
515
516 CALL fm_pool_create_fm(ao_ao_fm_pools(1)%pool, fmlocal)
517 CALL cp_fm_get_info(fmlocal, matrix_struct=matrix_struct)
518
519 IF (use_real_wfn) THEN
520 CALL cp_fm_create(rksmat, matrix_struct)
521 CALL cp_fm_create(rsmat, matrix_struct)
522 ELSE
523 CALL cp_cfm_create(cksmat, matrix_struct)
524 CALL cp_cfm_create(csmat, matrix_struct)
525 CALL cp_cfm_create(cwork, matrix_struct)
526 kp => kpoints%kp_env(1)%kpoint_env
527 CALL get_mo_set(kp%mos(1, 1), mo_coeff=mo_coeff)
528 CALL cp_fm_get_info(mo_coeff, matrix_struct=mo_struct)
529 CALL cp_cfm_create(cmos, mo_struct)
530 END IF
531
532 para_env => kpoints%blacs_env_all%para_env
533 nspin = SIZE(matrix_ks, 1)
534 ALLOCATE (info(kplocal*nspin*nkp_groups, 4))
535
536 ! Setup and start all the communication
537 indx = 0
538 DO ikp = 1, kplocal
539 DO ispin = 1, nspin
540 DO igroup = 1, nkp_groups
541 ! number of current kpoint
542 ik = kp_dist(1, igroup) + ikp - 1
543 my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
544 indx = indx + 1
545 IF (use_real_wfn) THEN
546 ! FT of matrices KS and S, then transfer to FM type
547 CALL dbcsr_set(rmatrix, 0.0_dp)
548 CALL rskp_transform(rmatrix=rmatrix, rsmat=matrix_ks, ispin=ispin, &
549 xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
550 CALL dbcsr_desymmetrize(rmatrix, tmpmat)
551 CALL copy_dbcsr_to_fm(tmpmat, fmwork(1))
552 ! s matrix is not spin dependent
553 CALL dbcsr_set(rmatrix, 0.0_dp)
554 CALL rskp_transform(rmatrix=rmatrix, rsmat=matrix_s, ispin=1, &
555 xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
556 CALL dbcsr_desymmetrize(rmatrix, tmpmat)
557 CALL copy_dbcsr_to_fm(tmpmat, fmwork(3))
558 ELSE
559 ! FT of matrices KS and S, then transfer to FM type
560 CALL dbcsr_set(rmatrix, 0.0_dp)
561 CALL dbcsr_set(cmatrix, 0.0_dp)
562 CALL rskp_transform(rmatrix=rmatrix, cmatrix=cmatrix, rsmat=matrix_ks, ispin=ispin, &
563 xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
564 CALL dbcsr_desymmetrize(rmatrix, tmpmat)
565 CALL copy_dbcsr_to_fm(tmpmat, fmwork(1))
566 CALL dbcsr_desymmetrize(cmatrix, tmpmat)
567 CALL copy_dbcsr_to_fm(tmpmat, fmwork(2))
568 ! s matrix is not spin dependent, double the work
569 CALL dbcsr_set(rmatrix, 0.0_dp)
570 CALL dbcsr_set(cmatrix, 0.0_dp)
571 CALL rskp_transform(rmatrix=rmatrix, cmatrix=cmatrix, rsmat=matrix_s, ispin=1, &
572 xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
573 CALL dbcsr_desymmetrize(rmatrix, tmpmat)
574 CALL copy_dbcsr_to_fm(tmpmat, fmwork(3))
575 CALL dbcsr_desymmetrize(cmatrix, tmpmat)
576 CALL copy_dbcsr_to_fm(tmpmat, fmwork(4))
577 END IF
578 ! transfer to kpoint group
579 ! redistribution of matrices, new blacs environment
580 ! fmwork -> fmlocal -> rksmat/cksmat
581 ! fmwork -> fmlocal -> rsmat/csmat
582 IF (use_real_wfn) THEN
583 IF (my_kpgrp) THEN
584 CALL cp_fm_start_copy_general(fmwork(1), rksmat, para_env, info(indx, 1))
585 CALL cp_fm_start_copy_general(fmwork(3), rsmat, para_env, info(indx, 2))
586 ELSE
587 CALL cp_fm_start_copy_general(fmwork(1), fmdummy, para_env, info(indx, 1))
588 CALL cp_fm_start_copy_general(fmwork(3), fmdummy, para_env, info(indx, 2))
589 END IF
590 ELSE
591 IF (my_kpgrp) THEN
592 CALL cp_fm_start_copy_general(fmwork(1), fmlocal, para_env, info(indx, 1))
593 CALL cp_fm_start_copy_general(fmwork(2), fmlocal, para_env, info(indx, 2))
594 CALL cp_fm_start_copy_general(fmwork(3), fmlocal, para_env, info(indx, 3))
595 CALL cp_fm_start_copy_general(fmwork(4), fmlocal, para_env, info(indx, 4))
596 ELSE
597 CALL cp_fm_start_copy_general(fmwork(1), fmdummy, para_env, info(indx, 1))
598 CALL cp_fm_start_copy_general(fmwork(2), fmdummy, para_env, info(indx, 2))
599 CALL cp_fm_start_copy_general(fmwork(3), fmdummy, para_env, info(indx, 3))
600 CALL cp_fm_start_copy_general(fmwork(4), fmdummy, para_env, info(indx, 4))
601 END IF
602 END IF
603 END DO
604 END DO
605 END DO
606
607 ! Finish communication then diagonalise in each group
608 IF (do_diis) THEN
609 CALL get_qs_env(qs_env, para_env=para_env_global)
610 scf_section => section_vals_get_subs_vals(qs_env%input, "DFT%SCF")
611 CALL qs_diis_b_info_kp(kpoints%scf_diis_buffer, ib, nb)
612 indx = 0
613 DO ikp = 1, kplocal
614 DO ispin = 1, nspin
615 DO igroup = 1, nkp_groups
616 ! number of current kpoint
617 ik = kp_dist(1, igroup) + ikp - 1
618 my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
619 indx = indx + 1
620 IF (my_kpgrp) THEN
621 CALL cp_fm_finish_copy_general(fmlocal, info(indx, 1))
622 CALL cp_cfm_scale_and_add_fm(z_zero, cksmat, z_one, fmlocal)
623 CALL cp_fm_finish_copy_general(fmlocal, info(indx, 2))
624 CALL cp_cfm_scale_and_add_fm(z_one, cksmat, gaussi, fmlocal)
625 CALL cp_fm_finish_copy_general(fmlocal, info(indx, 3))
626 CALL cp_cfm_scale_and_add_fm(z_zero, csmat, z_one, fmlocal)
627 CALL cp_fm_finish_copy_general(fmlocal, info(indx, 4))
628 CALL cp_cfm_scale_and_add_fm(z_one, csmat, gaussi, fmlocal)
629 END IF
630 END DO !igroup
631
632 kp => kpoints%kp_env(ikp)%kpoint_env
633 CALL qs_diis_b_calc_err_kp(kpoints%scf_diis_buffer, ib, kp%mos, cksmat, csmat, &
634 ispin, ikp, kplocal, scf_section)
635
636 END DO !ispin
637 END DO !ikp
638
639 ALLOCATE (coeffs(nb))
640 CALL qs_diis_b_step_kp(kpoints%scf_diis_buffer, coeffs, ib, nb, scf_env%iter_delta, diis_error, &
641 diis_step, scf_control%eps_diis, nspin, nkp, kplocal, scf_control%nmixing, &
642 scf_section, para_env_global)
643
644 !build the ks matrices and diagonalize
645 DO ikp = 1, kplocal
646 DO ispin = 1, nspin
647 kp => kpoints%kp_env(ikp)%kpoint_env
648 CALL cp_cfm_to_cfm(kpoints%scf_diis_buffer%smat(ikp), csmat)
649
650 CALL cp_cfm_set_all(cksmat, z_zero)
651 DO jb = 1, nb
652 CALL cp_cfm_scale_and_add(z_one, cksmat, coeffs(jb), kpoints%scf_diis_buffer%param(jb, ispin, ikp))
653 END DO
654
655 CALL get_mo_set(kp%mos(1, ispin), mo_coeff=rmos, eigenvalues=eigenvalues)
656 CALL get_mo_set(kp%mos(2, ispin), mo_coeff=imos)
657 IF (scf_env%cholesky_method == cholesky_off) THEN
658 CALL cp_cfm_geeig_canon(cksmat, csmat, cmos, eigenvalues, cwork, &
659 scf_control%eps_eigval)
660 ELSE
661 CALL cp_cfm_geeig(cksmat, csmat, cmos, eigenvalues, cwork)
662 END IF
663 ! copy eigenvalues to imag set (keep them in sync)
664 kp%mos(2, ispin)%eigenvalues = eigenvalues
665 ! split real and imaginary part of mos
666 CALL cp_cfm_to_fm(cmos, rmos, imos)
667 END DO
668 END DO
669
670 ELSE !no DIIS
671 diis_step = .false.
672 indx = 0
673 DO ikp = 1, kplocal
674 DO ispin = 1, nspin
675 DO igroup = 1, nkp_groups
676 ! number of current kpoint
677 ik = kp_dist(1, igroup) + ikp - 1
678 my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
679 indx = indx + 1
680 IF (my_kpgrp) THEN
681 IF (use_real_wfn) THEN
682 CALL cp_fm_finish_copy_general(rksmat, info(indx, 1))
683 CALL cp_fm_finish_copy_general(rsmat, info(indx, 2))
684 ELSE
685 CALL cp_fm_finish_copy_general(fmlocal, info(indx, 1))
686 CALL cp_cfm_scale_and_add_fm(z_zero, cksmat, z_one, fmlocal)
687 CALL cp_fm_finish_copy_general(fmlocal, info(indx, 2))
688 CALL cp_cfm_scale_and_add_fm(z_one, cksmat, gaussi, fmlocal)
689 CALL cp_fm_finish_copy_general(fmlocal, info(indx, 3))
690 CALL cp_cfm_scale_and_add_fm(z_zero, csmat, z_one, fmlocal)
691 CALL cp_fm_finish_copy_general(fmlocal, info(indx, 4))
692 CALL cp_cfm_scale_and_add_fm(z_one, csmat, gaussi, fmlocal)
693 END IF
694 END IF
695 END DO
696
697 ! Each kpoint group has now information on a kpoint to be diagonalized
698 ! General eigensolver Hermite or Symmetric
699 kp => kpoints%kp_env(ikp)%kpoint_env
700 IF (use_real_wfn) THEN
701 CALL get_mo_set(kp%mos(1, ispin), mo_coeff=mo_coeff, eigenvalues=eigenvalues)
702 IF (scf_env%cholesky_method == cholesky_off) THEN
703 CALL cp_fm_geeig_canon(rksmat, rsmat, mo_coeff, eigenvalues, fmlocal, &
704 scf_control%eps_eigval)
705 ELSE
706 CALL cp_fm_geeig(rksmat, rsmat, mo_coeff, eigenvalues, fmlocal)
707 END IF
708 ELSE
709 CALL get_mo_set(kp%mos(1, ispin), mo_coeff=rmos, eigenvalues=eigenvalues)
710 CALL get_mo_set(kp%mos(2, ispin), mo_coeff=imos)
711 IF (scf_env%cholesky_method == cholesky_off) THEN
712 CALL cp_cfm_geeig_canon(cksmat, csmat, cmos, eigenvalues, cwork, &
713 scf_control%eps_eigval)
714 ELSE
715 CALL cp_cfm_geeig(cksmat, csmat, cmos, eigenvalues, cwork)
716 END IF
717 ! copy eigenvalues to imag set (keep them in sync)
718 kp%mos(2, ispin)%eigenvalues = eigenvalues
719 ! split real and imaginary part of mos
720 CALL cp_cfm_to_fm(cmos, rmos, imos)
721 END IF
722 END DO
723 END DO
724 END IF
725
726 ! Clean up communication
727 indx = 0
728 DO ikp = 1, kplocal
729 DO ispin = 1, nspin
730 DO igroup = 1, nkp_groups
731 ! number of current kpoint
732 ik = kp_dist(1, igroup) + ikp - 1
733 my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
734 indx = indx + 1
735 IF (use_real_wfn) THEN
736 CALL cp_fm_cleanup_copy_general(info(indx, 1))
737 CALL cp_fm_cleanup_copy_general(info(indx, 2))
738 ELSE
739 CALL cp_fm_cleanup_copy_general(info(indx, 1))
740 CALL cp_fm_cleanup_copy_general(info(indx, 2))
741 CALL cp_fm_cleanup_copy_general(info(indx, 3))
742 CALL cp_fm_cleanup_copy_general(info(indx, 4))
743 END IF
744 END DO
745 END DO
746 END DO
747
748 ! All done
749 DEALLOCATE (info)
750
751 IF (update_p) THEN
752 ! MO occupations
753 IF (PRESENT(probe) .EQV. .true.) THEN
754 scf_control%smear%do_smear = .false.
755 CALL kpoint_set_mo_occupation(kpoints, scf_control%smear, &
756 probe=probe)
757 ELSE
758 CALL kpoint_set_mo_occupation(kpoints, scf_control%smear)
759 END IF
760 ! density matrices
761 CALL kpoint_density_matrices(kpoints)
762 ! density matrices in real space
763 CALL kpoint_density_transform(kpoints, scf_env%p_mix_new, .false., &
764 matrix_s(1, 1)%matrix, sab_nl, fmwork, overlap_rs=matrix_s)
765 END IF
766
767 CALL dbcsr_deallocate_matrix(rmatrix)
768 CALL dbcsr_deallocate_matrix(cmatrix)
769 CALL dbcsr_deallocate_matrix(tmpmat)
770
771 IF (use_real_wfn) THEN
772 CALL cp_fm_release(rksmat)
773 CALL cp_fm_release(rsmat)
774 ELSE
775 CALL cp_cfm_release(cksmat)
776 CALL cp_cfm_release(csmat)
777 CALL cp_cfm_release(cwork)
778 CALL cp_cfm_release(cmos)
779 END IF
780 CALL fm_pool_give_back_fm(ao_ao_fm_pools(1)%pool, fmlocal)
781
782 CALL timestop(handle)
783
784 END SUBROUTINE do_general_diag_kp
785
786! **************************************************************************************************
787!> \brief Kpoint diagonalization routine
788!> Transforms matrices to kpoint, distributes kpoint groups, performs
789!> general diagonalization (no storgae of overlap decomposition), stores
790!> MOs, calculates occupation numbers, calculates density matrices
791!> in kpoint representation, transforms density matrices to real space
792!> \param matrix_ks Kohn-sham matrices (RS indices, global)
793!> \param matrix_s Overlap matrices (RS indices, global)
794!> \param kpoints Kpoint environment
795!> \param fmwork FM work matrices [at least dimension 4] in full para_env
796!> \par History
797!> 08.2014 created [JGH]
798! **************************************************************************************************
799 SUBROUTINE diag_kp_basic(matrix_ks, matrix_s, kpoints, fmwork)
800
801 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks, matrix_s
802 TYPE(kpoint_type), POINTER :: kpoints
803 TYPE(cp_fm_type), DIMENSION(:), POINTER :: fmwork
804
805 CHARACTER(len=*), PARAMETER :: routinen = 'diag_kp_basic'
806
807 INTEGER :: handle, igroup, ik, ikp, indx, ispin, &
808 kplocal, nkp, nkp_groups, nspin
809 INTEGER, DIMENSION(2) :: kp_range
810 INTEGER, DIMENSION(:, :), POINTER :: kp_dist
811 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
812 LOGICAL :: my_kpgrp, use_real_wfn
813 REAL(kind=dp), DIMENSION(:), POINTER :: eigenvalues
814 REAL(kind=dp), DIMENSION(:, :), POINTER :: xkp
815 TYPE(copy_info_type), ALLOCATABLE, DIMENSION(:, :) :: info
816 TYPE(cp_cfm_type) :: cksmat, cmos, csmat, cwork
817 TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_ao_fm_pools
818 TYPE(cp_fm_struct_type), POINTER :: matrix_struct, mo_struct
819 TYPE(cp_fm_type) :: fmdummy, fmlocal, rksmat, rsmat
820 TYPE(cp_fm_type), POINTER :: imos, mo_coeff, rmos
821 TYPE(dbcsr_type), POINTER :: cmatrix, rmatrix, tempmat, tmpmat
822 TYPE(kpoint_env_type), POINTER :: kp
823 TYPE(mp_para_env_type), POINTER :: para_env
824 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
825 POINTER :: sab_nl
826 TYPE(qs_matrix_pools_type), POINTER :: mpools
827
828 CALL timeset(routinen, handle)
829
830 NULLIFY (sab_nl)
831 CALL get_kpoint_info(kpoints, nkp=nkp, xkp=xkp, use_real_wfn=use_real_wfn, kp_range=kp_range, &
832 nkp_groups=nkp_groups, kp_dist=kp_dist, sab_nl=sab_nl, &
833 cell_to_index=cell_to_index)
834 cpassert(ASSOCIATED(sab_nl))
835 kplocal = kp_range(2) - kp_range(1) + 1
836
837 ! use as template
838 tempmat => matrix_ks(1, 1)%matrix
839
840 ! allocate some work matrices
841 ALLOCATE (rmatrix, cmatrix, tmpmat)
842 CALL dbcsr_create(rmatrix, template=tempmat, matrix_type=dbcsr_type_symmetric)
843 CALL dbcsr_create(cmatrix, template=tempmat, matrix_type=dbcsr_type_antisymmetric)
844 CALL dbcsr_create(tmpmat, template=tempmat, matrix_type=dbcsr_type_no_symmetry)
845 CALL cp_dbcsr_alloc_block_from_nbl(rmatrix, sab_nl)
846 CALL cp_dbcsr_alloc_block_from_nbl(cmatrix, sab_nl)
847
848 ! fm pools to be used within a kpoint group
849 CALL get_kpoint_info(kpoints, mpools=mpools)
850 CALL mpools_get(mpools, ao_ao_fm_pools=ao_ao_fm_pools)
851
852 CALL fm_pool_create_fm(ao_ao_fm_pools(1)%pool, fmlocal)
853 CALL cp_fm_get_info(fmlocal, matrix_struct=matrix_struct)
854
855 IF (use_real_wfn) THEN
856 CALL cp_fm_create(rksmat, matrix_struct)
857 CALL cp_fm_create(rsmat, matrix_struct)
858 ELSE
859 CALL cp_cfm_create(cksmat, matrix_struct)
860 CALL cp_cfm_create(csmat, matrix_struct)
861 CALL cp_cfm_create(cwork, matrix_struct)
862 kp => kpoints%kp_env(1)%kpoint_env
863 CALL get_mo_set(kp%mos(1, 1), mo_coeff=mo_coeff)
864 CALL cp_fm_get_info(mo_coeff, matrix_struct=mo_struct)
865 CALL cp_cfm_create(cmos, mo_struct)
866 END IF
867
868 para_env => kpoints%blacs_env_all%para_env
869 nspin = SIZE(matrix_ks, 1)
870 ALLOCATE (info(kplocal*nspin*nkp_groups, 4))
871
872 ! Setup and start all the communication
873 indx = 0
874 DO ikp = 1, kplocal
875 DO ispin = 1, nspin
876 DO igroup = 1, nkp_groups
877 ! number of current kpoint
878 ik = kp_dist(1, igroup) + ikp - 1
879 my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
880 indx = indx + 1
881 IF (use_real_wfn) THEN
882 ! FT of matrices KS and S, then transfer to FM type
883 CALL dbcsr_set(rmatrix, 0.0_dp)
884 CALL rskp_transform(rmatrix=rmatrix, rsmat=matrix_ks, ispin=ispin, &
885 xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
886 CALL dbcsr_desymmetrize(rmatrix, tmpmat)
887 CALL copy_dbcsr_to_fm(tmpmat, fmwork(1))
888 ! s matrix is not spin dependent
889 CALL dbcsr_set(rmatrix, 0.0_dp)
890 CALL rskp_transform(rmatrix=rmatrix, rsmat=matrix_s, ispin=1, &
891 xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
892 CALL dbcsr_desymmetrize(rmatrix, tmpmat)
893 CALL copy_dbcsr_to_fm(tmpmat, fmwork(3))
894 ELSE
895 ! FT of matrices KS and S, then transfer to FM type
896 CALL dbcsr_set(rmatrix, 0.0_dp)
897 CALL dbcsr_set(cmatrix, 0.0_dp)
898 CALL rskp_transform(rmatrix=rmatrix, cmatrix=cmatrix, rsmat=matrix_ks, ispin=ispin, &
899 xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
900 CALL dbcsr_desymmetrize(rmatrix, tmpmat)
901 CALL copy_dbcsr_to_fm(tmpmat, fmwork(1))
902 CALL dbcsr_desymmetrize(cmatrix, tmpmat)
903 CALL copy_dbcsr_to_fm(tmpmat, fmwork(2))
904 ! s matrix is not spin dependent, double the work
905 CALL dbcsr_set(rmatrix, 0.0_dp)
906 CALL dbcsr_set(cmatrix, 0.0_dp)
907 CALL rskp_transform(rmatrix=rmatrix, cmatrix=cmatrix, rsmat=matrix_s, ispin=1, &
908 xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
909 CALL dbcsr_desymmetrize(rmatrix, tmpmat)
910 CALL copy_dbcsr_to_fm(tmpmat, fmwork(3))
911 CALL dbcsr_desymmetrize(cmatrix, tmpmat)
912 CALL copy_dbcsr_to_fm(tmpmat, fmwork(4))
913 END IF
914 ! transfer to kpoint group
915 ! redistribution of matrices, new blacs environment
916 ! fmwork -> fmlocal -> rksmat/cksmat
917 ! fmwork -> fmlocal -> rsmat/csmat
918 IF (use_real_wfn) THEN
919 IF (my_kpgrp) THEN
920 CALL cp_fm_start_copy_general(fmwork(1), rksmat, para_env, info(indx, 1))
921 CALL cp_fm_start_copy_general(fmwork(3), rsmat, para_env, info(indx, 2))
922 ELSE
923 CALL cp_fm_start_copy_general(fmwork(1), fmdummy, para_env, info(indx, 1))
924 CALL cp_fm_start_copy_general(fmwork(3), fmdummy, para_env, info(indx, 2))
925 END IF
926 ELSE
927 IF (my_kpgrp) THEN
928 CALL cp_fm_start_copy_general(fmwork(1), fmlocal, para_env, info(indx, 1))
929 CALL cp_fm_start_copy_general(fmwork(2), fmlocal, para_env, info(indx, 2))
930 CALL cp_fm_start_copy_general(fmwork(3), fmlocal, para_env, info(indx, 3))
931 CALL cp_fm_start_copy_general(fmwork(4), fmlocal, para_env, info(indx, 4))
932 ELSE
933 CALL cp_fm_start_copy_general(fmwork(1), fmdummy, para_env, info(indx, 1))
934 CALL cp_fm_start_copy_general(fmwork(2), fmdummy, para_env, info(indx, 2))
935 CALL cp_fm_start_copy_general(fmwork(3), fmdummy, para_env, info(indx, 3))
936 CALL cp_fm_start_copy_general(fmwork(4), fmdummy, para_env, info(indx, 4))
937 END IF
938 END IF
939 END DO
940 END DO
941 END DO
942
943 ! Finish communication then diagonalise in each group
944 indx = 0
945 DO ikp = 1, kplocal
946 DO ispin = 1, nspin
947 DO igroup = 1, nkp_groups
948 ! number of current kpoint
949 ik = kp_dist(1, igroup) + ikp - 1
950 my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
951 indx = indx + 1
952 IF (my_kpgrp) THEN
953 IF (use_real_wfn) THEN
954 CALL cp_fm_finish_copy_general(rksmat, info(indx, 1))
955 CALL cp_fm_finish_copy_general(rsmat, info(indx, 2))
956 ELSE
957 CALL cp_fm_finish_copy_general(fmlocal, info(indx, 1))
958 CALL cp_cfm_scale_and_add_fm(z_zero, cksmat, z_one, fmlocal)
959 CALL cp_fm_finish_copy_general(fmlocal, info(indx, 2))
960 CALL cp_cfm_scale_and_add_fm(z_one, cksmat, gaussi, fmlocal)
961 CALL cp_fm_finish_copy_general(fmlocal, info(indx, 3))
962 CALL cp_cfm_scale_and_add_fm(z_zero, csmat, z_one, fmlocal)
963 CALL cp_fm_finish_copy_general(fmlocal, info(indx, 4))
964 CALL cp_cfm_scale_and_add_fm(z_one, csmat, gaussi, fmlocal)
965 END IF
966 END IF
967 END DO
968
969 ! Each kpoint group has now information on a kpoint to be diagonalized
970 ! General eigensolver Hermite or Symmetric
971 kp => kpoints%kp_env(ikp)%kpoint_env
972 IF (use_real_wfn) THEN
973 CALL get_mo_set(kp%mos(1, ispin), mo_coeff=mo_coeff, eigenvalues=eigenvalues)
974 CALL cp_fm_geeig(rksmat, rsmat, mo_coeff, eigenvalues, fmlocal)
975 ELSE
976 CALL get_mo_set(kp%mos(1, ispin), mo_coeff=rmos, eigenvalues=eigenvalues)
977 CALL get_mo_set(kp%mos(2, ispin), mo_coeff=imos)
978 CALL cp_cfm_geeig(cksmat, csmat, cmos, eigenvalues, cwork)
979 ! copy eigenvalues to imag set (keep them in sync)
980 kp%mos(2, ispin)%eigenvalues = eigenvalues
981 ! split real and imaginary part of mos
982 CALL cp_cfm_to_fm(cmos, rmos, imos)
983 END IF
984 END DO
985 END DO
986
987 ! Clean up communication
988 indx = 0
989 DO ikp = 1, kplocal
990 DO ispin = 1, nspin
991 DO igroup = 1, nkp_groups
992 ! number of current kpoint
993 ik = kp_dist(1, igroup) + ikp - 1
994 my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
995 indx = indx + 1
996 IF (use_real_wfn) THEN
997 CALL cp_fm_cleanup_copy_general(info(indx, 1))
998 CALL cp_fm_cleanup_copy_general(info(indx, 2))
999 ELSE
1000 CALL cp_fm_cleanup_copy_general(info(indx, 1))
1001 CALL cp_fm_cleanup_copy_general(info(indx, 2))
1002 CALL cp_fm_cleanup_copy_general(info(indx, 3))
1003 CALL cp_fm_cleanup_copy_general(info(indx, 4))
1004 END IF
1005 END DO
1006 END DO
1007 END DO
1008
1009 ! All done
1010 DEALLOCATE (info)
1011
1012 CALL dbcsr_deallocate_matrix(rmatrix)
1013 CALL dbcsr_deallocate_matrix(cmatrix)
1014 CALL dbcsr_deallocate_matrix(tmpmat)
1015
1016 IF (use_real_wfn) THEN
1017 CALL cp_fm_release(rksmat)
1018 CALL cp_fm_release(rsmat)
1019 ELSE
1020 CALL cp_cfm_release(cksmat)
1021 CALL cp_cfm_release(csmat)
1022 CALL cp_cfm_release(cwork)
1023 CALL cp_cfm_release(cmos)
1024 END IF
1025 CALL fm_pool_give_back_fm(ao_ao_fm_pools(1)%pool, fmlocal)
1026
1027 CALL timestop(handle)
1028
1029 END SUBROUTINE diag_kp_basic
1030
1031! **************************************************************************************************
1032!> \brief inner loop within MOS subspace, to refine occupation and density,
1033!> before next diagonalization of the Hamiltonian
1034!> \param qs_env ...
1035!> \param scf_env ...
1036!> \param subspace_env ...
1037!> \param mos ...
1038!> \param rho ...
1039!> \param ks_env ...
1040!> \param scf_section ...
1041!> \param scf_control ...
1042!> \par History
1043!> 09.2009 created [MI]
1044!> \note it is assumed that when diagonalization is used, also some mixing procedure is active
1045! **************************************************************************************************
1046 SUBROUTINE do_scf_diag_subspace(qs_env, scf_env, subspace_env, mos, rho, &
1047 ks_env, scf_section, scf_control)
1048
1049 TYPE(qs_environment_type), POINTER :: qs_env
1050 TYPE(qs_scf_env_type), POINTER :: scf_env
1051 TYPE(subspace_env_type), POINTER :: subspace_env
1052 TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
1053 TYPE(qs_rho_type), POINTER :: rho
1054 TYPE(qs_ks_env_type), POINTER :: ks_env
1055 TYPE(section_vals_type), POINTER :: scf_section
1056 TYPE(scf_control_type), POINTER :: scf_control
1057
1058 CHARACTER(LEN=*), PARAMETER :: routinen = 'do_scf_diag_subspace'
1059 REAL(kind=dp), PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1060
1061 INTEGER :: handle, i, iloop, ispin, nao, nmo, &
1062 nspin, output_unit
1063 LOGICAL :: converged
1064 REAL(dp) :: ene_diff, ene_old, iter_delta, max_val, &
1065 sum_band, sum_val, t1, t2
1066 REAL(kind=dp), DIMENSION(:), POINTER :: mo_eigenvalues, mo_occupations
1067 TYPE(cp_1d_r_p_type), ALLOCATABLE, DIMENSION(:) :: eval_first, occ_first
1068 TYPE(cp_fm_type) :: work
1069 TYPE(cp_fm_type), POINTER :: c0, chc, evec, mo_coeff
1070 TYPE(cp_logger_type), POINTER :: logger
1071 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s, rho_ao
1072 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp
1073 TYPE(dft_control_type), POINTER :: dft_control
1074 TYPE(mp_para_env_type), POINTER :: para_env
1075 TYPE(qs_energy_type), POINTER :: energy
1076 TYPE(rho_atom_type), DIMENSION(:), POINTER :: rho_atom
1077
1078 CALL timeset(routinen, handle)
1079 NULLIFY (c0, chc, energy, evec, matrix_ks, mo_coeff, mo_eigenvalues, &
1080 mo_occupations, dft_control, rho_ao, rho_ao_kp)
1081
1082 logger => cp_get_default_logger()
1083 output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DIAG_SUB_SCF", &
1084 extension=".scfLog")
1085
1086 !Extra loop keeping mos unchanged and refining the subspace occupation
1087 nspin = SIZE(mos)
1088 CALL qs_rho_get(rho, rho_ao=rho_ao, rho_ao_kp=rho_ao_kp)
1089
1090 ALLOCATE (eval_first(nspin))
1091 ALLOCATE (occ_first(nspin))
1092 DO ispin = 1, nspin
1093 CALL get_mo_set(mo_set=mos(ispin), &
1094 nmo=nmo, &
1095 eigenvalues=mo_eigenvalues, &
1096 occupation_numbers=mo_occupations)
1097 ALLOCATE (eval_first(ispin)%array(nmo))
1098 ALLOCATE (occ_first(ispin)%array(nmo))
1099 eval_first(ispin)%array(1:nmo) = mo_eigenvalues(1:nmo)
1100 occ_first(ispin)%array(1:nmo) = mo_occupations(1:nmo)
1101 END DO
1102
1103 DO ispin = 1, nspin
1104 ! does not yet handle k-points
1105 CALL dbcsr_copy(subspace_env%p_matrix_store(ispin)%matrix, rho_ao(ispin)%matrix)
1106 CALL dbcsr_copy(rho_ao(ispin)%matrix, scf_env%p_mix_new(ispin, 1)%matrix)
1107 END DO
1108
1109 subspace_env%p_matrix_mix => scf_env%p_mix_new
1110
1111 NULLIFY (matrix_ks, energy, para_env, matrix_s)
1112 CALL get_qs_env(qs_env, &
1113 matrix_ks=matrix_ks, &
1114 energy=energy, &
1115 matrix_s=matrix_s, &
1116 para_env=para_env, &
1117 dft_control=dft_control)
1118
1119 ! mixing storage allocation
1120 IF (subspace_env%mixing_method >= gspace_mixing_nr) THEN
1121 CALL mixing_allocate(qs_env, subspace_env%mixing_method, scf_env%p_mix_new, &
1122 scf_env%p_delta, nspin, subspace_env%mixing_store)
1123 IF (dft_control%qs_control%gapw) THEN
1124 CALL get_qs_env(qs_env=qs_env, rho_atom_set=rho_atom)
1125 CALL mixing_init(subspace_env%mixing_method, rho, subspace_env%mixing_store, &
1126 para_env, rho_atom=rho_atom)
1127 ELSEIF (dft_control%qs_control%dftb .OR. dft_control%qs_control%xtb) THEN
1128 CALL charge_mixing_init(subspace_env%mixing_store)
1129 ELSEIF (dft_control%qs_control%semi_empirical) THEN
1130 cpabort('SE Code not possible')
1131 ELSE
1132 CALL mixing_init(subspace_env%mixing_method, rho, subspace_env%mixing_store, para_env)
1133 END IF
1134 END IF
1135
1136 ene_old = 0.0_dp
1137 ene_diff = 0.0_dp
1138 IF (output_unit > 0) THEN
1139 WRITE (output_unit, "(/T19,A)") '<<<<<<<<< SUBSPACE ROTATION <<<<<<<<<<'
1140 WRITE (output_unit, "(T4,A,T13,A,T21,A,T38,A,T51,A,T65,A/,T4,A)") &
1141 "In-step", "Time", "Convergence", "Band ene.", "Total ene.", "Energy diff.", repeat("-", 74)
1142 END IF
1143
1144 ! recalculate density matrix here
1145
1146 ! update of density
1147 CALL qs_rho_update_rho(rho, qs_env=qs_env)
1148
1149 DO iloop = 1, subspace_env%max_iter
1150 t1 = m_walltime()
1151 converged = .false.
1152 ene_old = energy%total
1153
1154 CALL qs_ks_did_change(ks_env, rho_changed=.true.)
1155 CALL qs_ks_update_qs_env(qs_env, calculate_forces=.false., &
1156 just_energy=.false., print_active=.false.)
1157
1158 max_val = 0.0_dp
1159 sum_val = 0.0_dp
1160 sum_band = 0.0_dp
1161 DO ispin = 1, SIZE(matrix_ks)
1162 CALL get_mo_set(mo_set=mos(ispin), &
1163 nao=nao, &
1164 nmo=nmo, &
1165 eigenvalues=mo_eigenvalues, &
1166 occupation_numbers=mo_occupations, &
1167 mo_coeff=mo_coeff)
1168
1169 !compute C'HC
1170 chc => subspace_env%chc_mat(ispin)
1171 evec => subspace_env%c_vec(ispin)
1172 c0 => subspace_env%c0(ispin)
1173 CALL cp_fm_to_fm(mo_coeff, c0)
1174 CALL cp_fm_create(work, c0%matrix_struct)
1175 CALL cp_dbcsr_sm_fm_multiply(matrix_ks(ispin)%matrix, c0, work, nmo)
1176 CALL parallel_gemm('T', 'N', nmo, nmo, nao, rone, c0, work, rzero, chc)
1177 CALL cp_fm_release(work)
1178 !diagonalize C'HC
1179 CALL choose_eigv_solver(chc, evec, mo_eigenvalues)
1180
1181 !rotate the mos by the eigenvectors of C'HC
1182 CALL parallel_gemm('N', 'N', nao, nmo, nmo, rone, c0, evec, rzero, mo_coeff)
1183
1184 IF (.NOT. scf_control%gce%do_gce) THEN
1185 CALL set_mo_occupation(mo_set=mos(ispin), &
1186 smear=scf_control%smear)
1187 ELSE
1188 CALL set_mo_occupation(mo_set=mos(ispin), &
1189 smear=scf_control%smear, &
1190 gce=scf_control%gce)
1191 END IF
1192
1193 ! does not yet handle k-points
1194 CALL calculate_density_matrix(mos(ispin), &
1195 subspace_env%p_matrix_mix(ispin, 1)%matrix)
1196
1197 DO i = 1, nmo
1198 sum_band = sum_band + mo_eigenvalues(i)*mo_occupations(i)
1199 END DO
1200
1201 !check for self consistency
1202 END DO
1203
1204 IF (subspace_env%mixing_method == direct_mixing_nr) THEN
1205 CALL scf_env_density_mixing(subspace_env%p_matrix_mix, &
1206 scf_env%mixing_store, rho_ao_kp, para_env, iter_delta, iloop)
1207 ELSE
1208 CALL self_consistency_check(rho_ao_kp, scf_env%p_delta, para_env, &
1209 subspace_env%p_matrix_mix, delta=iter_delta)
1210 END IF
1211
1212 DO ispin = 1, nspin
1213 ! does not yet handle k-points
1214 CALL dbcsr_copy(rho_ao(ispin)%matrix, subspace_env%p_matrix_mix(ispin, 1)%matrix)
1215 END DO
1216 ! update of density
1217 CALL qs_rho_update_rho(rho, qs_env=qs_env)
1218 ! Mixing in reciprocal space
1219 IF (subspace_env%mixing_method >= gspace_mixing_nr) THEN
1220 CALL gspace_mixing(qs_env, scf_env%mixing_method, subspace_env%mixing_store, &
1221 rho, para_env, scf_env%iter_count)
1222 END IF
1223
1224 ene_diff = energy%total - ene_old
1225 converged = (abs(ene_diff) < subspace_env%eps_ene .AND. &
1226 iter_delta < subspace_env%eps_adapt*scf_env%iter_delta)
1227 t2 = m_walltime()
1228 IF (output_unit > 0) THEN
1229 WRITE (output_unit, "(T4,I5,T11,F8.3,T18,E14.4,T34,F12.5,T46,F16.8,T62,E14.4)") &
1230 iloop, t2 - t1, iter_delta, sum_band, energy%total, ene_diff
1231 CALL m_flush(output_unit)
1232 END IF
1233 IF (converged) THEN
1234 IF (output_unit > 0) WRITE (output_unit, "(T10,A,I6,A,/)") &
1235 " Reached convergence in ", iloop, " iterations "
1236 EXIT
1237 END IF
1238
1239 END DO ! iloop
1240
1241 NULLIFY (subspace_env%p_matrix_mix)
1242 DO ispin = 1, nspin
1243 ! does not yet handle k-points
1244 CALL dbcsr_copy(scf_env%p_mix_new(ispin, 1)%matrix, rho_ao(ispin)%matrix)
1245 CALL dbcsr_copy(rho_ao(ispin)%matrix, subspace_env%p_matrix_store(ispin)%matrix)
1246
1247 DEALLOCATE (eval_first(ispin)%array, occ_first(ispin)%array)
1248 END DO
1249 DEALLOCATE (eval_first, occ_first)
1250
1251 CALL timestop(handle)
1252
1253 END SUBROUTINE do_scf_diag_subspace
1254
1255! **************************************************************************************************
1256!> \brief ...
1257!> \param subspace_env ...
1258!> \param qs_env ...
1259!> \param mos ...
1260! **************************************************************************************************
1261 SUBROUTINE diag_subspace_allocate(subspace_env, qs_env, mos)
1262
1263 TYPE(subspace_env_type), POINTER :: subspace_env
1264 TYPE(qs_environment_type), POINTER :: qs_env
1265 TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
1266
1267 CHARACTER(LEN=*), PARAMETER :: routinen = 'diag_subspace_allocate'
1268
1269 INTEGER :: handle, i, ispin, nmo, nspin
1270 TYPE(cp_fm_struct_type), POINTER :: fm_struct_tmp
1271 TYPE(cp_fm_type), POINTER :: mo_coeff
1272 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
1273 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1274 POINTER :: sab_orb
1275
1276 CALL timeset(routinen, handle)
1277
1278 NULLIFY (sab_orb, matrix_s)
1279 CALL get_qs_env(qs_env=qs_env, sab_orb=sab_orb, &
1280 matrix_s=matrix_s)
1281
1282 nspin = SIZE(mos)
1283! *** allocate p_atrix_store ***
1284 IF (.NOT. ASSOCIATED(subspace_env%p_matrix_store)) THEN
1285 CALL dbcsr_allocate_matrix_set(subspace_env%p_matrix_store, nspin)
1286
1287 DO i = 1, nspin
1288 ALLOCATE (subspace_env%p_matrix_store(i)%matrix)
1289 CALL dbcsr_create(matrix=subspace_env%p_matrix_store(i)%matrix, template=matrix_s(1)%matrix, &
1290 name="DENSITY_STORE", matrix_type=dbcsr_type_symmetric)
1291 CALL cp_dbcsr_alloc_block_from_nbl(subspace_env%p_matrix_store(i)%matrix, &
1292 sab_orb)
1293 CALL dbcsr_set(subspace_env%p_matrix_store(i)%matrix, 0.0_dp)
1294 END DO
1295
1296 END IF
1297
1298 ALLOCATE (subspace_env%chc_mat(nspin))
1299 ALLOCATE (subspace_env%c_vec(nspin))
1300 ALLOCATE (subspace_env%c0(nspin))
1301
1302 DO ispin = 1, nspin
1303 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nmo=nmo)
1304 CALL cp_fm_create(subspace_env%c0(ispin), mo_coeff%matrix_struct)
1305 NULLIFY (fm_struct_tmp)
1306 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nmo, ncol_global=nmo, &
1307 para_env=mo_coeff%matrix_struct%para_env, &
1308 context=mo_coeff%matrix_struct%context)
1309 CALL cp_fm_create(subspace_env%chc_mat(ispin), fm_struct_tmp, "chc")
1310 CALL cp_fm_create(subspace_env%c_vec(ispin), fm_struct_tmp, "vec")
1311 CALL cp_fm_struct_release(fm_struct_tmp)
1312 END DO
1313
1314 CALL timestop(handle)
1315
1316 END SUBROUTINE diag_subspace_allocate
1317
1318! **************************************************************************************************
1319!> \brief the inner loop of scf, specific to diagonalization without S matrix
1320!> basically, in goes the ks matrix out goes a new p matrix
1321!> \param scf_env ...
1322!> \param mos ...
1323!> \param matrix_ks ...
1324!> \param scf_control ...
1325!> \param scf_section ...
1326!> \param diis_step ...
1327!> \par History
1328!> 03.2006 created [Joost VandeVondele]
1329! **************************************************************************************************
1330 SUBROUTINE do_special_diag(scf_env, mos, matrix_ks, scf_control, &
1331 scf_section, diis_step)
1332
1333 TYPE(qs_scf_env_type), POINTER :: scf_env
1334 TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
1335 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks
1336 TYPE(scf_control_type), POINTER :: scf_control
1337 TYPE(section_vals_type), POINTER :: scf_section
1338 LOGICAL, INTENT(INOUT) :: diis_step
1339
1340 INTEGER :: ispin, nspin
1341 LOGICAL :: do_level_shift, use_jacobi
1342 REAL(kind=dp) :: diis_error
1343
1344 nspin = SIZE(matrix_ks)
1345
1346 DO ispin = 1, nspin
1347 CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, scf_env%scf_work1(ispin))
1348 END DO
1349 IF (scf_env%iter_count > 1 .AND. .NOT. scf_env%skip_diis) THEN
1350 CALL qs_diis_b_step(scf_env%scf_diis_buffer, mos, scf_env%scf_work1, &
1351 scf_env%scf_work2, scf_env%iter_delta, diis_error, diis_step, &
1352 scf_control%eps_diis, scf_control%nmixing, &
1353 scf_section=scf_section)
1354 ELSE
1355 diis_step = .false.
1356 END IF
1357
1358 IF ((scf_env%iter_count > 1) .AND. (scf_env%iter_delta < scf_control%diagonalization%eps_jacobi)) THEN
1359 use_jacobi = .true.
1360 ELSE
1361 use_jacobi = .false.
1362 END IF
1363
1364 do_level_shift = ((scf_control%level_shift /= 0.0_dp) .AND. &
1365 ((scf_control%density_guess == core_guess) .OR. (scf_env%iter_count > 1)))
1366 IF (diis_step) THEN
1367 scf_env%iter_param = diis_error
1368 IF (use_jacobi) THEN
1369 scf_env%iter_method = "DIIS/Jacobi"
1370 ELSE
1371 scf_env%iter_method = "DIIS/Diag."
1372 END IF
1373 ELSE
1374 IF (scf_env%mixing_method == 1) THEN
1375 scf_env%iter_param = scf_env%p_mix_alpha
1376 IF (use_jacobi) THEN
1377 scf_env%iter_method = "P_Mix/Jacobi"
1378 ELSE
1379 scf_env%iter_method = "P_Mix/Diag."
1380 END IF
1381 ELSEIF (scf_env%mixing_method > 1) THEN
1382 scf_env%iter_param = scf_env%mixing_store%alpha
1383 IF (use_jacobi) THEN
1384 scf_env%iter_method = trim(scf_env%mixing_store%iter_method)//"/Jacobi"
1385 ELSE
1386 scf_env%iter_method = trim(scf_env%mixing_store%iter_method)//"/Diag."
1387 END IF
1388 END IF
1389 END IF
1390 scf_env%iter_delta = 0.0_dp
1391
1392 DO ispin = 1, nspin
1393 CALL eigensolver_simple(matrix_ks=scf_env%scf_work1(ispin), &
1394 mo_set=mos(ispin), &
1395 work=scf_env%scf_work2, &
1396 do_level_shift=do_level_shift, &
1397 level_shift=scf_control%level_shift, &
1398 use_jacobi=use_jacobi, &
1399 jacobi_threshold=scf_control%diagonalization%jacobi_threshold)
1400 END DO
1401
1402 IF (.NOT. scf_control%gce%do_gce) THEN
1403 CALL set_mo_occupation(mo_array=mos, &
1404 smear=scf_control%smear)
1405 ELSE
1406 CALL set_mo_occupation(mo_array=mos, &
1407 smear=scf_control%smear, &
1408 gce=scf_control%gce)
1409 END IF
1410
1411 DO ispin = 1, nspin
1412 ! does not yet handle k-points
1413 CALL calculate_density_matrix(mos(ispin), &
1414 scf_env%p_mix_new(ispin, 1)%matrix)
1415 END DO
1416
1417 END SUBROUTINE do_special_diag
1418
1419! **************************************************************************************************
1420!> \brief the inner loop of scf, specific to iterative diagonalization using OT
1421!> with S matrix; basically, in goes the ks matrix out goes a new p matrix
1422!> \param scf_env ...
1423!> \param mos ...
1424!> \param matrix_ks ...
1425!> \param matrix_s ...
1426!> \param scf_control ...
1427!> \param scf_section ...
1428!> \param diis_step ...
1429!> \par History
1430!> 10.2008 created [JGH]
1431! **************************************************************************************************
1432 SUBROUTINE do_ot_diag(scf_env, mos, matrix_ks, matrix_s, &
1433 scf_control, scf_section, diis_step)
1434
1435 TYPE(qs_scf_env_type), POINTER :: scf_env
1436 TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
1437 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
1438 TYPE(scf_control_type), POINTER :: scf_control
1439 TYPE(section_vals_type), POINTER :: scf_section
1440 LOGICAL, INTENT(INOUT) :: diis_step
1441
1442 INTEGER :: homo, ispin, nmo, nspin
1443 REAL(kind=dp) :: diis_error, eps_iter
1444 REAL(kind=dp), DIMENSION(:), POINTER :: eigenvalues
1445 TYPE(cp_fm_type), POINTER :: mo_coeff
1446
1447 NULLIFY (eigenvalues)
1448
1449 nspin = SIZE(matrix_ks)
1450
1451 DO ispin = 1, nspin
1452 CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, &
1453 scf_env%scf_work1(ispin))
1454 END DO
1455
1456 IF ((scf_env%iter_count > 1) .AND. (.NOT. scf_env%skip_diis)) THEN
1457 CALL qs_diis_b_step(scf_env%scf_diis_buffer, mos, scf_env%scf_work1, &
1458 scf_env%scf_work2, scf_env%iter_delta, diis_error, diis_step, &
1459 scf_control%eps_diis, scf_control%nmixing, &
1460 s_matrix=matrix_s, &
1461 scf_section=scf_section)
1462 ELSE
1463 diis_step = .false.
1464 END IF
1465
1466 eps_iter = scf_control%diagonalization%eps_iter
1467 IF (diis_step) THEN
1468 scf_env%iter_param = diis_error
1469 scf_env%iter_method = "DIIS/OTdiag"
1470 DO ispin = 1, nspin
1471 CALL copy_fm_to_dbcsr(scf_env%scf_work1(ispin), &
1472 matrix_ks(ispin)%matrix, keep_sparsity=.true.)
1473 END DO
1474 eps_iter = max(eps_iter, scf_control%diagonalization%eps_adapt*diis_error)
1475 ELSE
1476 IF (scf_env%mixing_method == 1) THEN
1477 scf_env%iter_param = scf_env%p_mix_alpha
1478 scf_env%iter_method = "P_Mix/OTdiag."
1479 ELSEIF (scf_env%mixing_method > 1) THEN
1480 scf_env%iter_param = scf_env%mixing_store%alpha
1481 scf_env%iter_method = trim(scf_env%mixing_store%iter_method)//"/OTdiag."
1482 END IF
1483 END IF
1484
1485 scf_env%iter_delta = 0.0_dp
1486
1487 DO ispin = 1, nspin
1488 CALL get_mo_set(mos(ispin), &
1489 mo_coeff=mo_coeff, &
1490 eigenvalues=eigenvalues, &
1491 nmo=nmo, &
1492 homo=homo)
1493 CALL ot_eigensolver(matrix_h=matrix_ks(ispin)%matrix, &
1494 matrix_s=matrix_s(1)%matrix, &
1495 matrix_c_fm=mo_coeff, &
1496 preconditioner=scf_env%ot_preconditioner(1)%preconditioner, &
1497 eps_gradient=eps_iter, &
1498 iter_max=scf_control%diagonalization%max_iter, &
1499 silent=.true., &
1500 ot_settings=scf_control%diagonalization%ot_settings)
1501 CALL calculate_subspace_eigenvalues(mo_coeff, matrix_ks(ispin)%matrix, &
1502 evals_arg=eigenvalues, &
1503 do_rotation=.true.)
1504 CALL copy_fm_to_dbcsr(mos(ispin)%mo_coeff, &
1505 mos(ispin)%mo_coeff_b)
1506 !fm->dbcsr
1507 END DO
1508
1509 CALL set_mo_occupation(mo_array=mos, &
1510 smear=scf_control%smear)
1511
1512 DO ispin = 1, nspin
1513 ! does not yet handle k-points
1514 CALL calculate_density_matrix(mos(ispin), &
1515 scf_env%p_mix_new(ispin, 1)%matrix)
1516 END DO
1517
1518 END SUBROUTINE do_ot_diag
1519
1520! **************************************************************************************************
1521!> \brief Solve a set restricted open Kohn-Sham (ROKS) equations based on the
1522!> alpha and beta Kohn-Sham matrices from unrestricted Kohn-Sham.
1523!> \param scf_env ...
1524!> \param mos ...
1525!> \param matrix_ks ...
1526!> \param matrix_s ...
1527!> \param scf_control ...
1528!> \param scf_section ...
1529!> \param diis_step ...
1530!> \param orthogonal_basis ...
1531!> \par History
1532!> 04.2006 created [MK]
1533!> Revised (01.05.06,MK)
1534!> \note
1535!> this is only a high-spin ROKS.
1536! **************************************************************************************************
1537 SUBROUTINE do_roks_diag(scf_env, mos, matrix_ks, matrix_s, &
1538 scf_control, scf_section, diis_step, &
1539 orthogonal_basis)
1540
1541 ! Literature: - C. C. J. Roothaan, Rev. Mod. Phys. 32, 179 (1960)
1542 ! - M. F. Guest and V. R. Saunders, Mol. Phys. 28(3), 819 (1974)
1543 ! - M. Filatov and S. Shaik, Chem. Phys. Lett. 288, 689 (1998)
1544
1545 TYPE(qs_scf_env_type), POINTER :: scf_env
1546 TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
1547 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
1548 TYPE(scf_control_type), POINTER :: scf_control
1549 TYPE(section_vals_type), POINTER :: scf_section
1550 LOGICAL, INTENT(INOUT) :: diis_step
1551 LOGICAL, INTENT(IN) :: orthogonal_basis
1552
1553 CHARACTER(LEN=*), PARAMETER :: routinen = 'do_roks_diag'
1554
1555 INTEGER :: handle, homoa, homob, imo, nalpha, nao, &
1556 nbeta, nmo
1557 REAL(kind=dp) :: diis_error, level_shift_loc
1558 REAL(kind=dp), DIMENSION(:), POINTER :: eiga, eigb, occa, occb
1559 TYPE(cp_fm_type), POINTER :: ksa, ksb, mo2ao, moa, mob, ortho, work
1560
1561! -------------------------------------------------------------------------
1562
1563 CALL timeset(routinen, handle)
1564
1565 IF (scf_env%cholesky_method == cholesky_inverse) THEN
1566 ortho => scf_env%ortho_m1
1567 ELSE
1568 ortho => scf_env%ortho
1569 END IF
1570 work => scf_env%scf_work2
1571
1572 ksa => scf_env%scf_work1(1)
1573 ksb => scf_env%scf_work1(2)
1574
1575 CALL copy_dbcsr_to_fm(matrix_ks(1)%matrix, ksa)
1576 CALL copy_dbcsr_to_fm(matrix_ks(2)%matrix, ksb)
1577
1578 ! Get MO information
1579
1580 CALL get_mo_set(mo_set=mos(1), &
1581 nao=nao, &
1582 nmo=nmo, &
1583 nelectron=nalpha, &
1584 homo=homoa, &
1585 eigenvalues=eiga, &
1586 occupation_numbers=occa, &
1587 mo_coeff=moa)
1588
1589 CALL get_mo_set(mo_set=mos(2), &
1590 nelectron=nbeta, &
1591 homo=homob, &
1592 eigenvalues=eigb, &
1593 occupation_numbers=occb, &
1594 mo_coeff=mob)
1595
1596 ! Define the amount of level-shifting
1597
1598 IF ((scf_control%level_shift /= 0.0_dp) .AND. &
1599 ((scf_control%density_guess == core_guess) .OR. &
1600 (scf_control%density_guess == restart_guess) .OR. &
1601 (scf_env%iter_count > 1))) THEN
1602 level_shift_loc = scf_control%level_shift
1603 ELSE
1604 level_shift_loc = 0.0_dp
1605 END IF
1606
1607 IF ((scf_env%iter_count > 1) .OR. &
1608 (scf_control%density_guess == core_guess) .OR. &
1609 (scf_control%density_guess == restart_guess)) THEN
1610
1611 ! Transform the spin unrestricted alpha and beta Kohn-Sham matrices
1612 ! from AO basis to MO basis: K(MO) = C(T)*K(AO)*C
1613
1614 CALL cp_fm_symm("L", "U", nao, nao, 1.0_dp, ksa, moa, 0.0_dp, work)
1615 CALL parallel_gemm("T", "N", nao, nao, nao, 1.0_dp, moa, work, 0.0_dp, ksa)
1616
1617 CALL cp_fm_symm("L", "U", nao, nao, 1.0_dp, ksb, moa, 0.0_dp, work)
1618 CALL parallel_gemm("T", "N", nao, nao, nao, 1.0_dp, moa, work, 0.0_dp, ksb)
1619
1620 ! Combine the spin unrestricted alpha and beta Kohn-Sham matrices
1621 ! in the MO basis
1622
1623 IF (scf_control%roks_scheme == general_roks) THEN
1624 CALL combine_ks_matrices(ksa, ksb, occa, occb, scf_control%roks_f, &
1625 nalpha, nbeta)
1626 ELSE IF (scf_control%roks_scheme == high_spin_roks) THEN
1627 CALL combine_ks_matrices(ksa, ksb, occa, occb, scf_control%roks_parameter)
1628 ELSE
1629 cpabort("Unknown ROKS scheme requested")
1630 END IF
1631
1632 ! Back-transform the restricted open Kohn-Sham matrix from MO basis
1633 ! to AO basis
1634
1635 IF (orthogonal_basis) THEN
1636 ! Q = C
1637 mo2ao => moa
1638 ELSE
1639 ! Q = S*C
1640 mo2ao => mob
1641!MK CALL copy_sm_to_fm(matrix_s(1)%matrix,work)
1642!MK CALL cp_fm_symm("L", "U",nao, nao, 1.0_dp, work, moa, 0.0_dp, mo2ao)
1643 CALL cp_dbcsr_sm_fm_multiply(matrix_s(1)%matrix, moa, mo2ao, nao)
1644 END IF
1645
1646 ! K(AO) = Q*K(MO)*Q(T)
1647
1648 CALL parallel_gemm("N", "T", nao, nao, nao, 1.0_dp, ksa, mo2ao, 0.0_dp, work)
1649 CALL parallel_gemm("N", "N", nao, nao, nao, 1.0_dp, mo2ao, work, 0.0_dp, ksa)
1650
1651 ELSE
1652
1653 ! No transformation matrix available, yet. The closed shell part,
1654 ! i.e. the beta Kohn-Sham matrix in AO basis, is taken.
1655 ! There might be better choices, anyhow.
1656
1657 CALL cp_fm_to_fm(ksb, ksa)
1658
1659 END IF
1660
1661 ! Update DIIS buffer and possibly perform DIIS extrapolation step
1662
1663 IF (scf_env%iter_count > 1) THEN
1664 IF (orthogonal_basis) THEN
1665 CALL qs_diis_b_step(diis_buffer=scf_env%scf_diis_buffer, &
1666 mo_array=mos, &
1667 kc=scf_env%scf_work1, &
1668 sc=work, &
1669 delta=scf_env%iter_delta, &
1670 error_max=diis_error, &
1671 diis_step=diis_step, &
1672 eps_diis=scf_control%eps_diis, &
1673 scf_section=scf_section, &
1674 roks=.true.)
1675 cpassert(scf_env%iter_delta == scf_env%iter_delta)
1676 ELSE
1677 CALL qs_diis_b_step(diis_buffer=scf_env%scf_diis_buffer, &
1678 mo_array=mos, &
1679 kc=scf_env%scf_work1, &
1680 sc=work, &
1681 delta=scf_env%iter_delta, &
1682 error_max=diis_error, &
1683 diis_step=diis_step, &
1684 eps_diis=scf_control%eps_diis, &
1685 scf_section=scf_section, &
1686 s_matrix=matrix_s, &
1687 roks=.true.)
1688 END IF
1689 END IF
1690
1691 IF (diis_step) THEN
1692 scf_env%iter_param = diis_error
1693 scf_env%iter_method = "DIIS/Diag."
1694 ELSE
1695 IF (scf_env%mixing_method == 1) THEN
1696 scf_env%iter_param = scf_env%p_mix_alpha
1697 scf_env%iter_method = "P_Mix/Diag."
1698 ELSEIF (scf_env%mixing_method > 1) THEN
1699 scf_env%iter_param = scf_env%mixing_store%alpha
1700 scf_env%iter_method = trim(scf_env%mixing_store%iter_method)//"/Diag."
1701 END IF
1702 END IF
1703
1704 scf_env%iter_delta = 0.0_dp
1705
1706 IF (level_shift_loc /= 0.0_dp) THEN
1707
1708 ! Transform the current Kohn-Sham matrix from AO to MO basis
1709 ! for level-shifting using the current MO set
1710
1711 CALL cp_fm_symm("L", "U", nao, nao, 1.0_dp, ksa, moa, 0.0_dp, work)
1712 CALL parallel_gemm("T", "N", nao, nao, nao, 1.0_dp, moa, work, 0.0_dp, ksa)
1713
1714 ! Apply level-shifting using 50:50 split of the shift (could be relaxed)
1715
1716 DO imo = homob + 1, homoa
1717 CALL cp_fm_add_to_element(ksa, imo, imo, 0.5_dp*level_shift_loc)
1718 END DO
1719 DO imo = homoa + 1, nmo
1720 CALL cp_fm_add_to_element(ksa, imo, imo, level_shift_loc)
1721 END DO
1722
1723 ELSE IF (.NOT. orthogonal_basis) THEN
1724
1725 ! Transform the current Kohn-Sham matrix to an orthogonal basis
1726 SELECT CASE (scf_env%cholesky_method)
1727 CASE (cholesky_reduce)
1728 CALL cp_fm_cholesky_reduce(ksa, ortho)
1729 CASE (cholesky_restore)
1730 CALL cp_fm_uplo_to_full(ksa, work)
1731 CALL cp_fm_cholesky_restore(ksa, nao, ortho, work, &
1732 "SOLVE", pos="RIGHT")
1733 CALL cp_fm_cholesky_restore(work, nao, ortho, ksa, &
1734 "SOLVE", pos="LEFT", transa="T")
1735 CASE (cholesky_inverse)
1736 CALL cp_fm_uplo_to_full(ksa, work)
1737 CALL cp_fm_cholesky_restore(ksa, nao, ortho, work, &
1738 "MULTIPLY", pos="RIGHT")
1739 CALL cp_fm_cholesky_restore(work, nao, ortho, ksa, &
1740 "MULTIPLY", pos="LEFT", transa="T")
1741 CASE (cholesky_off)
1742 CALL cp_fm_symm("L", "U", nao, nao, 1.0_dp, ksa, ortho, 0.0_dp, work)
1743 CALL parallel_gemm("N", "N", nao, nao, nao, 1.0_dp, ortho, work, 0.0_dp, ksa)
1744 END SELECT
1745
1746 END IF
1747
1748 ! Diagonalization of the ROKS operator matrix
1749
1750 CALL choose_eigv_solver(ksa, work, eiga)
1751
1752 ! Back-transformation of the orthonormal eigenvectors if needed
1753
1754 IF (level_shift_loc /= 0.0_dp) THEN
1755 ! Use old MO set for back-transformation if level-shifting was applied
1756 CALL cp_fm_to_fm(moa, ortho)
1757 CALL parallel_gemm("N", "N", nao, nmo, nao, 1.0_dp, ortho, work, 0.0_dp, moa)
1758 ELSE
1759 IF (orthogonal_basis) THEN
1760 CALL cp_fm_to_fm(work, moa)
1761 ELSE
1762 SELECT CASE (scf_env%cholesky_method)
1764 CALL cp_fm_cholesky_restore(work, nmo, ortho, moa, "SOLVE")
1765 CASE (cholesky_inverse)
1766 CALL cp_fm_cholesky_restore(work, nmo, ortho, moa, "MULTIPLY")
1767 CASE (cholesky_off)
1768 CALL parallel_gemm("N", "N", nao, nmo, nao, 1.0_dp, ortho, work, 0.0_dp, moa)
1769 END SELECT
1770 END IF
1771 END IF
1772
1773 ! Correct MO eigenvalues, if level-shifting was applied
1774
1775 IF (level_shift_loc /= 0.0_dp) THEN
1776 DO imo = homob + 1, homoa
1777 eiga(imo) = eiga(imo) - 0.5_dp*level_shift_loc
1778 END DO
1779 DO imo = homoa + 1, nmo
1780 eiga(imo) = eiga(imo) - level_shift_loc
1781 END DO
1782 END IF
1783
1784 ! Update also the beta MO set
1785
1786 eigb(:) = eiga(:)
1787 CALL cp_fm_to_fm(moa, mob)
1788
1789 ! Calculate the new alpha and beta density matrix
1790
1791 ! does not yet handle k-points
1792 CALL calculate_density_matrix(mos(1), scf_env%p_mix_new(1, 1)%matrix)
1793 CALL calculate_density_matrix(mos(2), scf_env%p_mix_new(2, 1)%matrix)
1794
1795 CALL timestop(handle)
1796
1797 END SUBROUTINE do_roks_diag
1798
1799! **************************************************************************************************
1800!> \brief iterative diagonalization using the block Krylov-space approach
1801!> \param scf_env ...
1802!> \param mos ...
1803!> \param matrix_ks ...
1804!> \param scf_control ...
1805!> \param scf_section ...
1806!> \param check_moconv_only ...
1807!> \param
1808!> \par History
1809!> 05.2009 created [MI]
1810! **************************************************************************************************
1811
1812 SUBROUTINE do_block_krylov_diag(scf_env, mos, matrix_ks, &
1813 scf_control, scf_section, check_moconv_only)
1814
1815 TYPE(qs_scf_env_type), POINTER :: scf_env
1816 TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
1817 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks
1818 TYPE(scf_control_type), POINTER :: scf_control
1819 TYPE(section_vals_type), POINTER :: scf_section
1820 LOGICAL, INTENT(IN), OPTIONAL :: check_moconv_only
1821
1822 CHARACTER(LEN=*), PARAMETER :: routinen = 'do_block_krylov_diag'
1823 REAL(kind=dp), PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1824
1825 INTEGER :: handle, homo, ispin, iter, nao, nmo, &
1826 output_unit
1827 LOGICAL :: converged, my_check_moconv_only
1828 REAL(dp) :: eps_iter, t1, t2
1829 REAL(kind=dp), DIMENSION(:), POINTER :: mo_eigenvalues
1830 TYPE(cp_fm_type), POINTER :: c0, c1, chc, evec, ks, mo_coeff, ortho, &
1831 work
1832 TYPE(cp_logger_type), POINTER :: logger
1833
1834 logger => cp_get_default_logger()
1835 CALL timeset(routinen, handle)
1836
1837 output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%LANCZOS", &
1838 extension=".scfLog")
1839
1840 my_check_moconv_only = .false.
1841 IF (PRESENT(check_moconv_only)) my_check_moconv_only = check_moconv_only
1842
1843 NULLIFY (mo_coeff, ortho, work, ks)
1844 NULLIFY (mo_eigenvalues)
1845 NULLIFY (c0, c1)
1846
1847 IF (scf_env%cholesky_method == cholesky_inverse) THEN
1848 ortho => scf_env%ortho_m1
1849 ELSE
1850 ortho => scf_env%ortho
1851 END IF
1852 work => scf_env%scf_work2
1853
1854 DO ispin = 1, SIZE(matrix_ks)
1855 CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, &
1856 scf_env%scf_work1(ispin))
1857 END DO
1858
1859 IF (scf_env%mixing_method == 1) THEN
1860 scf_env%iter_param = scf_env%p_mix_alpha
1861 scf_env%iter_method = "P_Mix/Lanczos"
1862 ELSE
1863! scf_env%iter_param = scf_env%mixing_store%alpha
1864 scf_env%iter_method = trim(scf_env%mixing_store%iter_method)//"/Lanc."
1865 END IF
1866
1867 DO ispin = 1, SIZE(matrix_ks)
1868
1869 ks => scf_env%scf_work1(ispin)
1870 CALL cp_fm_uplo_to_full(ks, work)
1871
1872 CALL get_mo_set(mo_set=mos(ispin), &
1873 nao=nao, &
1874 nmo=nmo, &
1875 homo=homo, &
1876 eigenvalues=mo_eigenvalues, &
1877 mo_coeff=mo_coeff)
1878
1879 NULLIFY (c0, c1)
1880 c0 => scf_env%krylov_space%mo_conv(ispin)
1881 c1 => scf_env%krylov_space%mo_refine(ispin)
1882 SELECT CASE (scf_env%cholesky_method)
1883 CASE (cholesky_reduce)
1884 CALL cp_fm_cholesky_reduce(ks, ortho)
1885 CALL cp_fm_uplo_to_full(ks, work)
1886 CALL cp_fm_cholesky_restore(mo_coeff, nmo, ortho, c0, "MULTIPLY")
1887 CASE (cholesky_restore)
1888 CALL cp_fm_cholesky_restore(ks, nao, ortho, work, &
1889 "SOLVE", pos="RIGHT")
1890 CALL cp_fm_cholesky_restore(work, nao, ortho, ks, &
1891 "SOLVE", pos="LEFT", transa="T")
1892 CALL cp_fm_cholesky_restore(mo_coeff, nmo, ortho, c0, "MULTIPLY")
1893 CASE (cholesky_inverse)
1894 CALL cp_fm_cholesky_restore(ks, nao, ortho, work, &
1895 "MULTIPLY", pos="RIGHT")
1896 CALL cp_fm_cholesky_restore(work, nao, ortho, ks, &
1897 "MULTIPLY", pos="LEFT", transa="T")
1898 CALL cp_fm_cholesky_restore(mo_coeff, nmo, ortho, c0, "SOLVE")
1899 END SELECT
1900
1901 scf_env%krylov_space%nmo_nc = nmo
1902 scf_env%krylov_space%nmo_conv = 0
1903
1904 t1 = m_walltime()
1905 IF (output_unit > 0) THEN
1906 WRITE (output_unit, "(/T15,A)") '<<<<<<<<< LANCZOS REFINEMENT <<<<<<<<<<'
1907 WRITE (output_unit, "(T8,A,T15,A,T23,A,T36,A,T49,A,T60,A,/,T8,A)") &
1908 " Spin ", " Cycle ", &
1909 " conv. MOS ", " B2MAX ", " B2MIN ", " Time", repeat("-", 60)
1910 END IF
1911 eps_iter = max(scf_env%krylov_space%eps_conv, scf_env%krylov_space%eps_adapt*scf_env%iter_delta)
1912 iter = 0
1913 converged = .false.
1914 !Check convergence of MOS
1915 IF (my_check_moconv_only) THEN
1916
1917 CALL lanczos_refinement(scf_env%krylov_space, ks, c0, c1, mo_eigenvalues, &
1918 nao, eps_iter, ispin, check_moconv_only=my_check_moconv_only)
1919 t2 = m_walltime()
1920 IF (output_unit > 0) &
1921 WRITE (output_unit, '(T8,I3,T16,I5,T24,I6,T33,E12.4,2x,E12.4,T60,F8.3)') &
1922 ispin, iter, scf_env%krylov_space%nmo_conv, &
1923 scf_env%krylov_space%max_res_norm, scf_env%krylov_space%min_res_norm, t2 - t1
1924
1925 cycle
1926 ELSE
1927 !Block Lanczos refinement
1928 DO iter = 1, scf_env%krylov_space%max_iter
1929 CALL lanczos_refinement_2v(scf_env%krylov_space, ks, c0, c1, mo_eigenvalues, &
1930 nao, eps_iter, ispin)
1931 t2 = m_walltime()
1932 IF (output_unit > 0) THEN
1933 WRITE (output_unit, '(T8,I3,T16,I5,T24,I6,T33,E12.4,2x,E12.4,T60,F8.3)') &
1934 ispin, iter, scf_env%krylov_space%nmo_conv, &
1935 scf_env%krylov_space%max_res_norm, scf_env%krylov_space%min_res_norm, t2 - t1
1936 END IF
1937 t1 = m_walltime()
1938 IF (scf_env%krylov_space%max_res_norm < eps_iter) THEN
1939 converged = .true.
1940 IF (output_unit > 0) WRITE (output_unit, *) &
1941 " Reached convergence in ", iter, " iterations "
1942 EXIT
1943 END IF
1944 END DO
1945
1946 IF (.NOT. converged .AND. output_unit > 0) THEN
1947 WRITE (output_unit, "(T4, A)") " WARNING Lanczos refinement could "// &
1948 "not converge all the mos:"
1949 WRITE (output_unit, "(T40,A,T70,I10)") " number of not converged mos ", &
1950 scf_env%krylov_space%nmo_nc
1951 WRITE (output_unit, "(T40,A,T70,E10.2)") " max norm of the residual ", &
1952 scf_env%krylov_space%max_res_norm
1953
1954 END IF
1955
1956 ! For the moment skip the re-orthogonalization
1957 IF (.false.) THEN
1958 !Re-orthogonalization
1959 NULLIFY (chc, evec)
1960 chc => scf_env%krylov_space%chc_mat(ispin)
1961 evec => scf_env%krylov_space%c_vec(ispin)
1962 CALL parallel_gemm('N', 'N', nao, nmo, nao, rone, ks, c0, rzero, work)
1963 CALL parallel_gemm('T', 'N', nmo, nmo, nao, rone, c0, work, rzero, chc)
1964 !Diagonalize (C^t)HC
1965 CALL choose_eigv_solver(chc, evec, mo_eigenvalues)
1966 !Rotate the C vectors
1967 CALL parallel_gemm('N', 'N', nao, nmo, nmo, rone, c0, evec, rzero, c1)
1968 c0 => scf_env%krylov_space%mo_refine(ispin)
1969 END IF
1970
1971 IF (scf_env%cholesky_method == cholesky_inverse) THEN
1972 CALL cp_fm_cholesky_restore(c0, nmo, ortho, mo_coeff, "MULTIPLY")
1973 ELSE
1974 CALL cp_fm_cholesky_restore(c0, nmo, ortho, mo_coeff, "SOLVE")
1975 END IF
1976
1977 IF (.NOT. scf_control%gce%do_gce) THEN
1978 CALL set_mo_occupation(mo_set=mos(ispin), &
1979 smear=scf_control%smear)
1980 ELSE
1981 CALL set_mo_occupation(mo_set=mos(ispin), &
1982 smear=scf_control%smear, &
1983 gce=scf_control%gce)
1984 END IF
1985
1986 ! does not yet handle k-points
1987 CALL calculate_density_matrix(mos(ispin), &
1988 scf_env%p_mix_new(ispin, 1)%matrix)
1989 END IF
1990 END DO ! ispin
1991
1992 IF (output_unit > 0) THEN
1993 WRITE (output_unit, "(T15,A/)") '<<<<<<<<< END LANCZOS REFINEMENT <<<<<<<<<<'
1994 END IF
1995
1996 CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
1997 "PRINT%LANCZOS")
1998
1999 CALL timestop(handle)
2000
2001 END SUBROUTINE do_block_krylov_diag
2002
2003! **************************************************************************************************
2004!> \brief iterative diagonalization using the block davidson space approach
2005!> \param qs_env ...
2006!> \param scf_env ...
2007!> \param mos ...
2008!> \param matrix_ks ...
2009!> \param matrix_s ...
2010!> \param scf_control ...
2011!> \param scf_section ...
2012!> \param check_moconv_only ...
2013!> \param
2014!> \par History
2015!> 05.2011 created [MI]
2016! **************************************************************************************************
2017
2018 SUBROUTINE do_block_davidson_diag(qs_env, scf_env, mos, matrix_ks, matrix_s, &
2019 scf_control, scf_section, check_moconv_only)
2020
2021 TYPE(qs_environment_type), POINTER :: qs_env
2022 TYPE(qs_scf_env_type), POINTER :: scf_env
2023 TYPE(mo_set_type), DIMENSION(:), INTENT(INOUT) :: mos
2024 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_s
2025 TYPE(scf_control_type), POINTER :: scf_control
2026 TYPE(section_vals_type), POINTER :: scf_section
2027 LOGICAL, INTENT(IN), OPTIONAL :: check_moconv_only
2028
2029 CHARACTER(LEN=*), PARAMETER :: routinen = 'do_block_davidson_diag'
2030
2031 INTEGER :: handle, ispin, nspins, output_unit
2032 LOGICAL :: do_prec, my_check_moconv_only
2033 TYPE(cp_logger_type), POINTER :: logger
2034
2035 logger => cp_get_default_logger()
2036 CALL timeset(routinen, handle)
2037
2038 output_unit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DAVIDSON", &
2039 extension=".scfLog")
2040
2041 IF (output_unit > 0) &
2042 WRITE (output_unit, "(/T15,A)") '<<<<<<<<< DAVIDSON ITERATIONS <<<<<<<<<<'
2043
2044 IF (scf_env%mixing_method == 1) THEN
2045 scf_env%iter_param = scf_env%p_mix_alpha
2046 scf_env%iter_method = "P_Mix/Dav."
2047 ELSE
2048 scf_env%iter_param = scf_env%mixing_store%alpha
2049 scf_env%iter_method = trim(scf_env%mixing_store%iter_method)//"/Dav."
2050 END IF
2051
2052 my_check_moconv_only = .false.
2053 IF (PRESENT(check_moconv_only)) my_check_moconv_only = check_moconv_only
2054 do_prec = .false.
2055 IF (scf_env%block_davidson_env(1)%prec_type /= 0 .AND. &
2056 scf_env%iter_count >= scf_env%block_davidson_env(1)%first_prec) THEN
2057 do_prec = .true.
2058 END IF
2059
2060 nspins = SIZE(matrix_ks)
2061
2062 IF (do_prec .AND. (scf_env%iter_count == scf_env%block_davidson_env(1)%first_prec .OR. &
2063 modulo(scf_env%iter_count, scf_env%block_davidson_env(1)%niter_new_prec) == 0)) THEN
2064 CALL restart_preconditioner(qs_env, scf_env%ot_preconditioner, &
2065 prec_type=scf_env%block_davidson_env(1)%prec_type, nspins=nspins)
2066 CALL prepare_preconditioner(qs_env, mos, matrix_ks, matrix_s, scf_env%ot_preconditioner, &
2067 scf_env%block_davidson_env(1)%prec_type, &
2068 scf_env%block_davidson_env(1)%solver_type, &
2069 scf_env%block_davidson_env(1)%energy_gap, nspins, &
2070 convert_to_dbcsr=scf_env%block_davidson_env(1)%use_sparse_mos, &
2071 full_mo_set=.true.)
2072 END IF
2073
2074 DO ispin = 1, nspins
2075 IF (scf_env%block_davidson_env(ispin)%use_sparse_mos) THEN
2076 IF (.NOT. do_prec) THEN
2077 CALL generate_extended_space_sparse(scf_env%block_davidson_env(ispin), mos(ispin), &
2078 matrix_ks(ispin)%matrix, matrix_s(1)%matrix, output_unit)
2079 ELSE
2080 CALL generate_extended_space_sparse(scf_env%block_davidson_env(ispin), mos(ispin), &
2081 matrix_ks(ispin)%matrix, matrix_s(1)%matrix, output_unit, &
2082 scf_env%ot_preconditioner(ispin)%preconditioner)
2083 END IF
2084
2085 ELSE
2086 IF (.NOT. do_prec) THEN
2087 CALL generate_extended_space(scf_env%block_davidson_env(ispin), mos(ispin), &
2088 matrix_ks(ispin)%matrix, matrix_s(1)%matrix, output_unit)
2089 ELSE
2090 CALL generate_extended_space(scf_env%block_davidson_env(ispin), mos(ispin), &
2091 matrix_ks(ispin)%matrix, matrix_s(1)%matrix, output_unit, &
2092 scf_env%ot_preconditioner(ispin)%preconditioner)
2093 END IF
2094 END IF
2095 END DO !ispin
2096
2097 IF (.NOT. scf_control%gce%do_gce) THEN
2098 CALL set_mo_occupation(mo_array=mos, &
2099 smear=scf_control%smear)
2100 ELSE
2101 CALL set_mo_occupation(mo_array=mos, &
2102 smear=scf_control%smear, &
2103 gce=scf_control%gce)
2104 END IF
2105
2106 DO ispin = 1, nspins
2107 ! does not yet handle k-points
2108 CALL calculate_density_matrix(mos(ispin), &
2109 scf_env%p_mix_new(ispin, 1)%matrix)
2110 END DO
2111
2112 IF (output_unit > 0) THEN
2113 WRITE (output_unit, "(T15,A/)") '<<<<<<<<< END DAVIDSON ITERATION <<<<<<<<<<'
2114 END IF
2115
2116 CALL cp_print_key_finished_output(output_unit, logger, scf_section, &
2117 "PRINT%DAVIDSON")
2118
2119 CALL timestop(handle)
2120
2121 END SUBROUTINE do_block_davidson_diag
2122
2123! **************************************************************************************************
2124!> \brief Kpoint diagonalization routine
2125!> Transforms matrices to kpoint, distributes kpoint groups, performs diagonalization
2126!> \param matrix_s Overlap matrices (RS indices, global)
2127!> \param kpoints Kpoint environment
2128!> \param fmwork full matrices distributed over all groups
2129!> \par History
2130!> 02.2026 created [JGH]
2131! **************************************************************************************************
2132 SUBROUTINE diag_kp_smat(matrix_s, kpoints, fmwork)
2133
2134 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_s
2135 TYPE(kpoint_type), POINTER :: kpoints
2136 TYPE(cp_fm_type), DIMENSION(:) :: fmwork
2137
2138 CHARACTER(len=*), PARAMETER :: routinen = 'diag_kp_smat'
2139 COMPLEX(KIND=dp), PARAMETER :: cone = (1.0_dp, 0.0_dp), &
2140 czero = (0.0_dp, 0.0_dp)
2141
2142 COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:) :: ceig
2143 INTEGER :: handle, igroup, ik, ikp, indx, kplocal, &
2144 nao, nkp, nkp_groups
2145 INTEGER, DIMENSION(2) :: kp_range
2146 INTEGER, DIMENSION(:, :), POINTER :: kp_dist
2147 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
2148 LOGICAL :: my_kpgrp, use_real_wfn
2149 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues
2150 REAL(kind=dp), DIMENSION(:, :), POINTER :: xkp
2151 TYPE(copy_info_type), ALLOCATABLE, DIMENSION(:, :) :: info
2152 TYPE(cp_cfm_type) :: csmat, cwork
2153 TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_ao_fm_pools
2154 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
2155 TYPE(cp_fm_type) :: fmdummy, fmlocal, rsmat
2156 TYPE(dbcsr_type), POINTER :: cmatrix, rmatrix, tmpmat
2157 TYPE(kpoint_env_type), POINTER :: kp
2158 TYPE(mp_para_env_type), POINTER :: para_env
2159 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
2160 POINTER :: sab_nl
2161 TYPE(qs_matrix_pools_type), POINTER :: mpools
2162
2163 CALL timeset(routinen, handle)
2164
2165 NULLIFY (sab_nl)
2166 CALL get_kpoint_info(kpoints, nkp=nkp, xkp=xkp, use_real_wfn=use_real_wfn, kp_range=kp_range, &
2167 nkp_groups=nkp_groups, kp_dist=kp_dist, sab_nl=sab_nl, &
2168 cell_to_index=cell_to_index)
2169 cpassert(ASSOCIATED(sab_nl))
2170 kplocal = kp_range(2) - kp_range(1) + 1
2171
2172 ! allocate some work matrices
2173 ALLOCATE (rmatrix, cmatrix, tmpmat)
2174 CALL dbcsr_create(rmatrix, template=matrix_s(1, 1)%matrix, &
2175 matrix_type=dbcsr_type_symmetric)
2176 CALL dbcsr_create(cmatrix, template=matrix_s(1, 1)%matrix, &
2177 matrix_type=dbcsr_type_antisymmetric)
2178 CALL dbcsr_create(tmpmat, template=matrix_s(1, 1)%matrix, &
2179 matrix_type=dbcsr_type_no_symmetry)
2180 CALL cp_dbcsr_alloc_block_from_nbl(rmatrix, sab_nl)
2181 CALL cp_dbcsr_alloc_block_from_nbl(cmatrix, sab_nl)
2182
2183 ! fm pools to be used within a kpoint group
2184 CALL get_kpoint_info(kpoints, mpools=mpools)
2185 CALL mpools_get(mpools, ao_ao_fm_pools=ao_ao_fm_pools)
2186
2187 CALL fm_pool_create_fm(ao_ao_fm_pools(1)%pool, fmlocal)
2188 CALL cp_fm_get_info(fmlocal, matrix_struct=matrix_struct)
2189
2190 IF (use_real_wfn) THEN
2191 CALL cp_fm_create(rsmat, matrix_struct)
2192 ELSE
2193 CALL cp_cfm_create(csmat, matrix_struct)
2194 CALL cp_cfm_create(cwork, matrix_struct)
2195 END IF
2196
2197 CALL cp_fm_get_info(fmwork(1), nrow_global=nao)
2198 ALLOCATE (eigenvalues(nao), ceig(nao))
2199
2200 para_env => kpoints%blacs_env_all%para_env
2201 ALLOCATE (info(kplocal*nkp_groups, 2))
2202
2203 ! Setup and start all the communication
2204 indx = 0
2205 DO ikp = 1, kplocal
2206 DO igroup = 1, nkp_groups
2207 ! number of current kpoint
2208 ik = kp_dist(1, igroup) + ikp - 1
2209 my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
2210 indx = indx + 1
2211 IF (use_real_wfn) THEN
2212 CALL dbcsr_set(rmatrix, 0.0_dp)
2213 CALL rskp_transform(rmatrix=rmatrix, rsmat=matrix_s, ispin=1, &
2214 xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
2215 CALL dbcsr_desymmetrize(rmatrix, tmpmat)
2216 CALL copy_dbcsr_to_fm(tmpmat, fmwork(1))
2217 ELSE
2218 CALL dbcsr_set(rmatrix, 0.0_dp)
2219 CALL dbcsr_set(cmatrix, 0.0_dp)
2220 CALL rskp_transform(rmatrix=rmatrix, cmatrix=cmatrix, rsmat=matrix_s, ispin=1, &
2221 xkp=xkp(1:3, ik), cell_to_index=cell_to_index, sab_nl=sab_nl)
2222 CALL dbcsr_desymmetrize(rmatrix, tmpmat)
2223 CALL copy_dbcsr_to_fm(tmpmat, fmwork(1))
2224 CALL dbcsr_desymmetrize(cmatrix, tmpmat)
2225 CALL copy_dbcsr_to_fm(tmpmat, fmwork(2))
2226 END IF
2227 ! transfer to kpoint group
2228 ! redistribution of matrices, new blacs environment
2229 ! fmwork -> fmlocal -> rsmat/csmat
2230 IF (use_real_wfn) THEN
2231 IF (my_kpgrp) THEN
2232 CALL cp_fm_start_copy_general(fmwork(1), rsmat, para_env, info(indx, 1))
2233 ELSE
2234 CALL cp_fm_start_copy_general(fmwork(1), fmdummy, para_env, info(indx, 1))
2235 END IF
2236 ELSE
2237 IF (my_kpgrp) THEN
2238 CALL cp_fm_start_copy_general(fmwork(1), fmlocal, para_env, info(indx, 1))
2239 CALL cp_fm_start_copy_general(fmwork(2), fmlocal, para_env, info(indx, 2))
2240 ELSE
2241 CALL cp_fm_start_copy_general(fmwork(1), fmdummy, para_env, info(indx, 1))
2242 CALL cp_fm_start_copy_general(fmwork(2), fmdummy, para_env, info(indx, 2))
2243 END IF
2244 END IF
2245 END DO
2246 END DO
2247
2248 ! Finish communication then diagonalise in each group
2249 indx = 0
2250 DO ikp = 1, kplocal
2251 DO igroup = 1, nkp_groups
2252 ! number of current kpoint
2253 ik = kp_dist(1, igroup) + ikp - 1
2254 my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
2255 indx = indx + 1
2256 IF (my_kpgrp) THEN
2257 IF (use_real_wfn) THEN
2258 CALL cp_fm_finish_copy_general(rsmat, info(indx, 1))
2259 ELSE
2260 CALL cp_fm_finish_copy_general(fmlocal, info(indx, 1))
2261 CALL cp_cfm_scale_and_add_fm(z_zero, csmat, z_one, fmlocal)
2262 CALL cp_fm_finish_copy_general(fmlocal, info(indx, 2))
2263 CALL cp_cfm_scale_and_add_fm(z_one, csmat, gaussi, fmlocal)
2264 END IF
2265 END IF
2266 END DO
2267
2268 ! Each kpoint group has now information on a kpoint to be diagonalized
2269 ! Eigensolver Hermite or Symmetric
2270 kp => kpoints%kp_env(ikp)%kpoint_env
2271 IF (use_real_wfn) THEN
2272 CALL choose_eigv_solver(rsmat, fmlocal, eigenvalues)
2273 ELSE
2274 CALL cp_cfm_heevd(csmat, cwork, eigenvalues)
2275 END IF
2276 cpassert(all(eigenvalues(1:nao) >= 0.0_dp))
2277 IF (use_real_wfn) THEN
2278 CALL cp_fm_release(kp%shalf)
2279 CALL cp_fm_create(kp%shalf, matrix_struct)
2280 eigenvalues(1:nao) = sqrt(eigenvalues(1:nao))
2281 CALL cp_fm_to_fm(fmlocal, rsmat)
2282 CALL cp_fm_column_scale(rsmat, eigenvalues)
2283 CALL parallel_gemm("N", "T", nao, nao, nao, 1.0_dp, rsmat, fmlocal, &
2284 0.0_dp, kp%shalf)
2285 ELSE
2286 CALL cp_cfm_release(kp%cshalf)
2287 CALL cp_cfm_create(kp%cshalf, matrix_struct)
2288 ceig(1:nao) = sqrt(eigenvalues(1:nao))
2289 CALL cp_cfm_to_cfm(cwork, csmat)
2290 CALL cp_cfm_column_scale(csmat, ceig)
2291 CALL parallel_gemm("N", "C", nao, nao, nao, cone, csmat, cwork, &
2292 czero, kp%cshalf)
2293 END IF
2294 END DO
2295
2296 ! Clean up communication
2297 indx = 0
2298 DO ikp = 1, kplocal
2299 DO igroup = 1, nkp_groups
2300 ! number of current kpoint
2301 ik = kp_dist(1, igroup) + ikp - 1
2302 my_kpgrp = (ik >= kpoints%kp_range(1) .AND. ik <= kpoints%kp_range(2))
2303 indx = indx + 1
2304 IF (use_real_wfn) THEN
2305 CALL cp_fm_cleanup_copy_general(info(indx, 1))
2306 ELSE
2307 CALL cp_fm_cleanup_copy_general(info(indx, 1))
2308 CALL cp_fm_cleanup_copy_general(info(indx, 2))
2309 END IF
2310 END DO
2311 END DO
2312
2313 ! All done
2314 DEALLOCATE (info)
2315 DEALLOCATE (eigenvalues, ceig)
2316
2317 CALL dbcsr_deallocate_matrix(rmatrix)
2318 CALL dbcsr_deallocate_matrix(cmatrix)
2319 CALL dbcsr_deallocate_matrix(tmpmat)
2320
2321 IF (use_real_wfn) THEN
2322 CALL cp_fm_release(rsmat)
2323 ELSE
2324 CALL cp_cfm_release(csmat)
2325 CALL cp_cfm_release(cwork)
2326 END IF
2327 CALL fm_pool_give_back_fm(ao_ao_fm_pools(1)%pool, fmlocal)
2328
2329 CALL timestop(handle)
2330
2331 END SUBROUTINE diag_kp_smat
2332
2333END MODULE qs_scf_diagonalization
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
various utilities that regard array of different kinds: output, allocation,... maybe it is not a good...
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_scale_and_add(alpha, matrix_a, beta, matrix_b)
Scale and add two BLACS matrices (a = alpha*a + beta*b).
subroutine, public cp_cfm_scale_and_add_fm(alpha, matrix_a, beta, matrix_b)
Scale and add two BLACS matrices (a = alpha*a + beta*b). where b is a real matrix (adapted from cp_cf...
subroutine, public cp_cfm_column_scale(matrix_a, scaling)
Scales columns of the full matrix by corresponding factors.
used for collecting diagonalization schemes available for cp_cfm_type
Definition cp_cfm_diag.F:14
subroutine, public cp_cfm_geeig(amatrix, bmatrix, eigenvectors, eigenvalues, work)
General Eigenvalue Problem AX = BXE Single option version: Cholesky decomposition of B.
subroutine, public cp_cfm_heevd(matrix, eigenvectors, eigenvalues)
Perform a diagonalisation of a complex matrix.
Definition cp_cfm_diag.F:74
subroutine, public cp_cfm_geeig_canon(amatrix, bmatrix, eigenvectors, eigenvalues, work, epseig)
General Eigenvalue Problem AX = BXE Use canonical orthogonalization.
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_cfm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_set_all(matrix, alpha, beta)
Set all elements of the full matrix to alpha. Besides, set all diagonal matrix elements to beta (if g...
subroutine, public cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_deallocate_matrix(matrix)
...
subroutine, public dbcsr_desymmetrize(matrix_a, matrix_b)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_set(matrix, alpha)
...
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_column_scale(matrixa, scaling)
scales column i of matrix a with scaling(i)
subroutine, public cp_fm_uplo_to_full(matrix, work, uplo)
given a triangular matrix according to uplo, computes the corresponding full matrix
subroutine, public cp_fm_symm(side, uplo, m, n, alpha, matrix_a, matrix_b, beta, matrix_c)
computes matrix_c = beta * matrix_c + alpha * matrix_a * matrix_b computes matrix_c = beta * matrix_c...
various cholesky decomposition related routines
subroutine, public cp_fm_cholesky_restore(fm_matrix, neig, fm_matrixb, fm_matrixout, op, pos, transa)
apply Cholesky decomposition op can be "SOLVE" (out = U^-1 * in) or "MULTIPLY" (out = U * in) pos can...
subroutine, public cp_fm_cholesky_reduce(matrix, matrixb, itype)
reduce a matrix pencil A,B to normal form B has to be cholesky decomposed with cp_fm_cholesky_decompo...
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
Definition cp_fm_diag.F:17
integer, parameter, public fm_diag_type_cusolver
Definition cp_fm_diag.F:106
logical, save, public direct_generalized_diagonalization
Definition cp_fm_diag.F:100
subroutine, public cp_fm_geeig(amatrix, bmatrix, eigenvectors, eigenvalues, work)
General Eigenvalue Problem AX = BXE. Use cuSOLVERMp directly when requested and large enough; otherwi...
subroutine, public choose_eigv_solver(matrix, eigenvectors, eigenvalues, info)
Choose the Eigensolver depending on which library is available ELPA seems to be unstable for small sy...
Definition cp_fm_diag.F:245
integer, save, public diag_type
Definition cp_fm_diag.F:88
integer, parameter, public cusolver_n_min
Definition cp_fm_diag.F:94
subroutine, public cp_fm_geeig_canon(amatrix, bmatrix, eigenvectors, eigenvalues, work, epseig)
General Eigenvalue Problem AX = BXE Use canonical diagonalization : U*s**(-1/2)
pool for for elements that are retained and released
subroutine, public fm_pool_create_fm(pool, element, name)
returns an element, allocating it if none is in the pool
subroutine, public fm_pool_give_back_fm(pool, element)
returns the element to the pool
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_start_copy_general(source, destination, para_env, info)
Initiates the copy operation: get distribution data, post MPI isend and irecvs.
subroutine, public cp_fm_cleanup_copy_general(info)
Completes the copy operation: wait for comms clean up MPI state.
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_add_to_element(matrix, irow_global, icol_global, alpha)
...
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_finish_copy_general(destination, info)
Completes the copy operation: wait for comms, unpack, clean up MPI state.
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public core_guess
integer, parameter, public cholesky_restore
integer, parameter, public cholesky_dbcsr
integer, parameter, public cholesky_off
integer, parameter, public cholesky_reduce
integer, parameter, public high_spin_roks
integer, parameter, public cholesky_inverse
integer, parameter, public general_roks
integer, parameter, public restart_guess
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Routines needed for kpoint calculation.
subroutine, public kpoint_density_transform(kpoint, denmat, wtype, tempmat, sab_nl, fmwork, for_aux_fit, pmat_ext, overlap_rs)
generate real space density matrices in DBCSR format
subroutine, public rskp_transform(rmatrix, cmatrix, rsmat, ispin, xkp, cell_to_index, sab_nl, is_complex, rs_sign)
Transformation of real space matrices to a kpoint.
subroutine, public kpoint_density_matrices(kpoint, energy_weighted, for_aux_fit)
Calculate kpoint density matrices (rho(k), owned by kpoint groups)
subroutine, public kpoint_set_mo_occupation(kpoint, smear, probe)
Given the eigenvalues of all kpoints, calculates the occupation numbers.
Types and basic routines needed for a kpoint calculation.
subroutine, public get_kpoint_info(kpoint, kp_scheme, nkp_grid, kp_shift, symmetry, verbose, full_grid, use_real_wfn, eps_geo, parallel_group_size, kp_range, nkp, xkp, wkp, para_env, blacs_env_all, para_env_kp, para_env_inter_kp, blacs_env, kp_env, kp_aux_env, mpools, iogrp, nkp_groups, kp_dist, cell_to_index, index_to_cell, sab_nl, sab_nl_nosym, inversion_symmetry_only, symmetry_backend, symmetry_reduction_method, gamma_centered)
Retrieve information from a kpoint environment.
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition machine.F:124
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition machine.F:141
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public z_one
complex(kind=dp), parameter, public gaussi
complex(kind=dp), parameter, public z_zero
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes
computes preconditioners, and implements methods to apply them currently used in qs_ot
subroutine, public restart_preconditioner(qs_env, preconditioner, prec_type, nspins)
Allows for a restart of the preconditioner depending on the method it purges all arrays or keeps them...
subroutine, public prepare_preconditioner(qs_env, mos, matrix_ks, matrix_s, ot_preconditioner, prec_type, solver_type, energy_gap, nspins, has_unit_metric, convert_to_dbcsr, chol_type, full_mo_set)
...
collects routines that calculate density matrices
module that contains the definitions of the scf types
integer, parameter, public direct_mixing_nr
integer, parameter, public gspace_mixing_nr
Apply the direct inversion in the iterative subspace (DIIS) of Pulay in the framework of an SCF itera...
Definition qs_diis.F:21
subroutine, public qs_diis_b_info_kp(diis_buffer, ib, nb)
Update info about the current buffer step ib and the current number of buffers nb.
Definition qs_diis.F:989
subroutine, public qs_diis_b_calc_err_kp(diis_buffer, ib, mos, kc, sc, ispin, ikp, nkp_local, scf_section)
Calculate and store the error for a given k-point.
Definition qs_diis.F:1013
subroutine, public qs_diis_b_step_kp(diis_buffer, coeffs, ib, nb, delta, error_max, diis_step, eps_diis, nspin, nkp, nkp_local, nmixing, scf_section, para_env)
Update the SCF DIIS buffer, and if appropriate does a diis step, for k-points.
Definition qs_diis.F:1100
subroutine, public qs_diis_b_step(diis_buffer, mo_array, kc, sc, delta, error_max, diis_step, eps_diis, nmixing, s_matrix, scf_section, roks)
Update the SCF DIIS buffer, and if appropriate does a diis step.
Definition qs_diis.F:230
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
subroutine, public gspace_mixing(qs_env, mixing_method, mixing_store, rho, para_env, iter_count)
Driver for the g-space mixing, calls the proper routine given the requested method.
routines that build the Kohn-Sham matrix (i.e calculate the coulomb and xc parts
subroutine, public qs_ks_update_qs_env(qs_env, calculate_forces, just_energy, print_active)
updates the Kohn Sham matrix of the given qs_env (facility method)
subroutine, public qs_ks_did_change(ks_env, s_mstruct_changed, rho_changed, potential_changed, full_reset)
tells that some of the things relevant to the ks calculation did change. has to be called when change...
wrapper for the pools of matrixes
subroutine, public mpools_get(mpools, ao_mo_fm_pools, ao_ao_fm_pools, mo_mo_fm_pools, ao_mosub_fm_pools, mosub_mosub_fm_pools, maxao_maxmo_fm_pool, maxao_maxao_fm_pool, maxmo_maxmo_fm_pool)
returns various attributes of the mpools (notably the pools contained in it)
elemental subroutine, public charge_mixing_init(mixing_store)
initialiation needed when charge mixing is used
subroutine, public mixing_init(mixing_method, rho, mixing_store, para_env, rho_atom)
initialiation needed when gspace mixing is used
subroutine, public mixing_allocate(qs_env, mixing_method, p_mix_new, p_delta, nspins, mixing_store)
allocation needed when density mixing is used
subroutine, public self_consistency_check(rho_ao, p_delta, para_env, p_out, delta)
...
collects routines that perform operations directly related to MOs
Set occupation of molecular orbitals.
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
Define the neighbor list data types and the corresponding functionality.
an eigen-space solver for the generalised symmetric eigenvalue problem for sparse matrices,...
subroutine, public ot_eigensolver(matrix_h, matrix_s, matrix_orthogonal_space_fm, matrix_c_fm, preconditioner, eps_gradient, iter_max, size_ortho_space, silent, ot_settings)
...
methods of the rho structure (defined in qs_rho_types)
subroutine, public qs_rho_update_rho(rho_struct, qs_env, rho_xc_external, local_rho_set, task_list_external, task_list_external_soft, pw_env_external, para_env_external)
updates rho_r and rho_g to the rhorho_ao. if use_kinetic_energy_density also computes tau_r and tau_g...
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
module that contains the algorithms to perform an iterative diagonalization by the block-Davidson app...
subroutine, public generate_extended_space_sparse(bdav_env, mo_set, matrix_h, matrix_s, output_unit, preconditioner)
...
subroutine, public generate_extended_space(bdav_env, mo_set, matrix_h, matrix_s, output_unit, preconditioner)
...
Different diagonalization schemes that can be used for the iterative solution of the eigenvalue probl...
subroutine, public general_eigenproblem(scf_env, mos, matrix_ks, matrix_s, scf_control, scf_section, diis_step)
the inner loop of scf, specific to diagonalization with S matrix basically, in goes the ks matrix out...
subroutine, public diag_subspace_allocate(subspace_env, qs_env, mos)
...
subroutine, public do_ot_diag(scf_env, mos, matrix_ks, matrix_s, scf_control, scf_section, diis_step)
the inner loop of scf, specific to iterative diagonalization using OT with S matrix; basically,...
subroutine, public do_block_davidson_diag(qs_env, scf_env, mos, matrix_ks, matrix_s, scf_control, scf_section, check_moconv_only)
iterative diagonalization using the block davidson space approach
subroutine, public do_roks_diag(scf_env, mos, matrix_ks, matrix_s, scf_control, scf_section, diis_step, orthogonal_basis)
Solve a set restricted open Kohn-Sham (ROKS) equations based on the alpha and beta Kohn-Sham matrices...
subroutine, public diag_kp_basic(matrix_ks, matrix_s, kpoints, fmwork)
Kpoint diagonalization routine Transforms matrices to kpoint, distributes kpoint groups,...
subroutine, public do_scf_diag_subspace(qs_env, scf_env, subspace_env, mos, rho, ks_env, scf_section, scf_control)
inner loop within MOS subspace, to refine occupation and density, before next diagonalization of the ...
subroutine, public do_block_krylov_diag(scf_env, mos, matrix_ks, scf_control, scf_section, check_moconv_only)
iterative diagonalization using the block Krylov-space approach
subroutine, public do_special_diag(scf_env, mos, matrix_ks, scf_control, scf_section, diis_step)
the inner loop of scf, specific to diagonalization without S matrix basically, in goes the ks matrix ...
subroutine, public do_general_diag(scf_env, mos, matrix_ks, matrix_s, scf_control, scf_section, diis_step, probe)
...
subroutine, public do_general_diag_kp(matrix_ks, matrix_s, kpoints, scf_env, scf_control, update_p, diis_step, diis_error, qs_env, probe)
Kpoint diagonalization routine Transforms matrices to kpoint, distributes kpoint groups,...
subroutine, public diag_kp_smat(matrix_s, kpoints, fmwork)
Kpoint diagonalization routine Transforms matrices to kpoint, distributes kpoint groups,...
module that contains the algorithms to perform an iterative diagonalization by the block-Lanczos appr...
subroutine, public lanczos_refinement(krylov_space, ks, c0, c1, eval, nao, eps_iter, ispin, check_moconv_only)
lanczos refinement by blocks of non-converged MOs
subroutine, public lanczos_refinement_2v(krylov_space, ks, c0, c1, eval, nao, eps_iter, ispin, check_moconv_only)
...
groups fairly general SCF methods, so that modules other than qs_scf can use them too split off from ...
subroutine, public eigensolver_simple(matrix_ks, mo_set, work, do_level_shift, level_shift, use_jacobi, jacobi_threshold)
...
subroutine, public eigensolver_dbcsr(matrix_ks, matrix_ks_fm, mo_set, ortho_dbcsr, ksbuf1, ksbuf2)
...
subroutine, public scf_env_density_mixing(p_mix_new, mixing_store, rho_ao, para_env, iter_delta, iter_count, diis, invert)
perform (if requested) a density mixing
subroutine, public eigensolver(matrix_ks_fm, mo_set, ortho, work, cholesky_method, do_level_shift, level_shift, matrix_u_fm, use_jacobi)
Diagonalise the Kohn-Sham matrix to get a new set of MO eigen- vectors and MO eigenvalues....
subroutine, public eigensolver_symm(matrix_ks_fm, mo_set, ortho, work, do_level_shift, level_shift, matrix_u_fm, use_jacobi, jacobi_threshold, ortho_red, work_red, matrix_ks_fm_red, matrix_u_fm_red)
...
subroutine, public eigensolver_generalized(matrix_ks_fm, matrix_s, mo_set, work)
Solve the generalized eigenvalue problem using cusolverMpSygvd.
module that contains the definitions of the scf types
parameters that control an scf iteration
represent a pointer to a 1d array
Represent a complex full matrix.
keeps the information about the structure of a full matrix
Stores the state of a copy between cp_fm_start_copy_general and cp_fm_finish_copy_general.
represent a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
Keeps information about a specific k-point.
Contains information about kpoints.
stores all the informations relevant to an mpi environment
calculation environment to calculate the ks matrix, holds all the needed vars. assumes that the core ...
container for the pools of matrixes used by qs
keeps the density in various representations, keeping track of which ones are valid.