49 USE dbcsr_api,
ONLY: &
50 dbcsr_add, dbcsr_copy, dbcsr_create, dbcsr_dot, dbcsr_maxabs, dbcsr_multiply, &
51 dbcsr_p_type, dbcsr_release, dbcsr_set, dbcsr_transposed, dbcsr_type
61 qs_diis_buffer_type_kp,&
62 qs_diis_buffer_type_sparse
68 #include "./base/base_uses.f90"
74 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_diis'
102 TYPE(qs_diis_buffer_type),
INTENT(OUT) :: diis_buffer
103 INTEGER,
INTENT(in) :: nbuffer
105 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_diis_b_create'
111 CALL timeset(routinen, handle)
113 NULLIFY (diis_buffer%b_matrix)
114 NULLIFY (diis_buffer%error)
115 NULLIFY (diis_buffer%param)
116 diis_buffer%nbuffer = nbuffer
117 diis_buffer%ncall = 0
119 CALL timestop(handle)
138 SUBROUTINE qs_diis_b_check_i_alloc(diis_buffer, matrix_struct, nspin, &
141 TYPE(qs_diis_buffer_type),
INTENT(INOUT) :: diis_buffer
142 TYPE(cp_fm_struct_type),
POINTER :: matrix_struct
143 INTEGER,
INTENT(IN) :: nspin
144 TYPE(section_vals_type),
POINTER :: scf_section
146 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_check_i_alloc'
148 INTEGER :: handle, ibuffer, ispin, nbuffer, &
150 TYPE(cp_logger_type),
POINTER :: logger
154 CALL timeset(routinen, handle)
158 nbuffer = diis_buffer%nbuffer
160 IF (.NOT.
ASSOCIATED(diis_buffer%error))
THEN
161 ALLOCATE (diis_buffer%error(nbuffer, nspin))
164 DO ibuffer = 1, nbuffer
166 name=
"qs_diis_b%error("// &
167 trim(adjustl(cp_to_string(ibuffer)))//
","// &
168 trim(adjustl(cp_to_string(ibuffer)))//
")", &
169 matrix_struct=matrix_struct)
174 IF (.NOT.
ASSOCIATED(diis_buffer%param))
THEN
175 ALLOCATE (diis_buffer%param(nbuffer, nspin))
178 DO ibuffer = 1, nbuffer
180 name=
"qs_diis_b%param("// &
181 trim(adjustl(cp_to_string(ibuffer)))//
","// &
182 trim(adjustl(cp_to_string(ibuffer)))//
")", &
183 matrix_struct=matrix_struct)
188 IF (.NOT.
ASSOCIATED(diis_buffer%b_matrix))
THEN
189 ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
190 diis_buffer%b_matrix = 0.0_dp
193 IF (output_unit > 0)
THEN
194 WRITE (unit=output_unit, fmt=
"(/,T9,A)") &
195 "DIIS | The SCF DIIS buffer was allocated and initialized"
201 CALL timestop(handle)
203 END SUBROUTINE qs_diis_b_check_i_alloc
227 diis_step, eps_diis, nmixing, s_matrix, scf_section, roks)
229 TYPE(qs_diis_buffer_type),
POINTER :: diis_buffer
230 TYPE(mo_set_type),
DIMENSION(:),
INTENT(IN) :: mo_array
231 TYPE(cp_fm_type),
DIMENSION(:),
POINTER :: kc
232 TYPE(cp_fm_type),
INTENT(IN) :: sc
233 REAL(kind=
dp),
INTENT(IN) :: delta
234 REAL(kind=
dp),
INTENT(OUT) :: error_max
235 LOGICAL,
INTENT(OUT) :: diis_step
236 REAL(kind=
dp),
INTENT(IN) :: eps_diis
237 INTEGER,
INTENT(IN),
OPTIONAL :: nmixing
238 TYPE(dbcsr_p_type),
DIMENSION(:),
OPTIONAL, &
240 TYPE(section_vals_type),
POINTER :: scf_section
241 LOGICAL,
INTENT(IN),
OPTIONAL :: roks
243 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_step'
244 REAL(kind=
dp),
PARAMETER :: eigenvalue_threshold = 1.0e-12_dp
246 CHARACTER(LEN=2*default_string_length) :: message
247 INTEGER :: handle, homo, ib, imo, ispin, jb, &
248 my_nmixing, nao, nb, nb1, nmo, nspin, &
250 LOGICAL :: eigenvectors_discarded, my_roks
251 REAL(kind=
dp) :: maxocc, tmp
252 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: ev, occ
253 REAL(kind=
dp),
DIMENSION(:),
POINTER :: occa, occb
254 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b
255 TYPE(cp_fm_struct_type),
POINTER :: matrix_struct
256 TYPE(cp_fm_type),
POINTER :: c, new_errors, old_errors, parameters
257 TYPE(cp_logger_type),
POINTER :: logger
261 CALL timeset(routinen, handle)
263 nspin =
SIZE(mo_array)
266 IF (
PRESENT(roks))
THEN
274 IF (
PRESENT(nmixing)) my_nmixing = nmixing
276 NULLIFY (c, new_errors, old_errors, parameters, matrix_struct, a, b, occa, occb)
281 IF (diis_buffer%nbuffer < 1)
THEN
282 CALL timestop(handle)
287 matrix_struct=matrix_struct)
288 CALL qs_diis_b_check_i_alloc(diis_buffer, &
289 matrix_struct=matrix_struct, &
291 scf_section=scf_section)
295 ib =
modulo(diis_buffer%ncall, diis_buffer%nbuffer) + 1
296 diis_buffer%ncall = diis_buffer%ncall + 1
297 nb = min(diis_buffer%ncall, diis_buffer%nbuffer)
306 occupation_numbers=occa, &
309 new_errors => diis_buffer%error(ib, ispin)
310 parameters => diis_buffer%param(ib, ispin)
314 CALL cp_fm_to_fm(kc(ispin), parameters)
321 occupation_numbers=occb)
324 occ(imo) = sqrt(occa(imo) + occb(imo))
327 CALL cp_fm_to_fm(c, sc)
331 CALL cp_fm_symm(
"L",
"U", nao, homo, 1.0_dp, parameters, sc, 0.0_dp, kc(ispin))
333 IF (
PRESENT(s_matrix))
THEN
336 CALL cp_fm_symm(
"L",
"U", nao, homo, 1.0_dp, new_errors, c, 0.0_dp, sc)
343 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, sc, kc(ispin), 0.0_dp, new_errors)
344 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, kc(ispin), sc, -1.0_dp, new_errors)
351 CALL cp_fm_symm(
"L",
"U", nao, homo, maxocc, parameters, c, 0.0_dp, kc(ispin))
353 IF (
PRESENT(s_matrix))
THEN
357 CALL cp_fm_symm(
"L",
"U", nao, homo, 2.0_dp, new_errors, c, 0.0_dp, sc)
359 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, sc, kc(ispin), 0.0_dp, new_errors)
360 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, kc(ispin), sc, -1.0_dp, new_errors)
363 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, c, kc(ispin), 0.0_dp, new_errors)
364 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, kc(ispin), c, -1.0_dp, new_errors)
370 error_max = max(error_max, tmp)
376 diis_step = ((diis_buffer%ncall >= my_nmixing) .AND. (delta < eps_diis))
380 IF (output_unit > 0)
THEN
381 WRITE (unit=output_unit, fmt=
"(/,T9,A,I4,/,(T9,A,ES12.3))") &
382 "DIIS | Current SCF DIIS buffer size: ", nb, &
383 "DIIS | Maximum SCF DIIS error vector element:", error_max, &
384 "DIIS | Current SCF convergence: ", delta, &
385 "DIIS | Threshold value for a DIIS step: ", eps_diis
386 IF (error_max < eps_diis)
THEN
387 WRITE (unit=output_unit, fmt=
"(T9,A)") &
388 "DIIS | => The SCF DIIS buffer will be updated"
390 WRITE (unit=output_unit, fmt=
"(T9,A)") &
391 "DIIS | => No update of the SCF DIIS buffer"
393 IF (diis_step .AND. (error_max < eps_diis))
THEN
394 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
395 "DIIS | => A SCF DIIS step will be performed"
397 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
398 "DIIS | => No SCF DIIS step will be performed"
404 IF (error_max < eps_diis)
THEN
406 b => diis_buffer%b_matrix
411 old_errors => diis_buffer%error(jb, ispin)
412 new_errors => diis_buffer%error(ib, ispin)
413 CALL cp_fm_trace(old_errors, new_errors, tmp)
414 b(jb, ib) = b(jb, ib) + tmp
416 b(ib, jb) = b(jb, ib)
431 ALLOCATE (a(nb1, nb1))
432 ALLOCATE (b(nb1, nb1))
437 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
439 b(1:nb, nb1) = -1.0_dp
440 b(nb1, 1:nb) = -1.0_dp
448 a(1:nb1, 1:nb1) = b(1:nb1, 1:nb1)
450 eigenvectors_discarded = .false.
453 IF (abs(ev(jb)) < eigenvalue_threshold)
THEN
454 IF (output_unit > 0)
THEN
455 IF (.NOT. eigenvectors_discarded)
THEN
456 WRITE (unit=output_unit, fmt=
"(T9,A)") &
457 "DIIS | Checking eigenvalues of the DIIS error matrix"
459 WRITE (unit=message, fmt=
"(T9,A,I6,A,ES10.1,A,ES10.1)") &
460 "DIIS | Eigenvalue ", jb,
" = ", ev(jb),
" is smaller than "// &
461 "threshold ", eigenvalue_threshold
463 WRITE (unit=output_unit, fmt=
"(T9,A)") trim(message)
464 eigenvectors_discarded = .true.
466 a(1:nb1, jb) = 0.0_dp
468 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
472 IF ((output_unit > 0) .AND. eigenvectors_discarded)
THEN
473 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
474 "DIIS | The corresponding eigenvectors were discarded"
477 ev(1:nb) = matmul(a(1:nb, 1:nb1), b(nb1, 1:nb1))
484 parameters => diis_buffer%param(jb, ispin)
496 parameters => diis_buffer%param(ib, ispin)
497 CALL cp_fm_to_fm(parameters, kc(ispin))
505 CALL timestop(handle)
518 TYPE(qs_diis_buffer_type),
INTENT(INOUT) :: diis_buffer
520 diis_buffer%ncall = 0
543 diis_step, eps_diis, nmixing, s_matrix, threshold)
547 TYPE(qs_diis_buffer_type_sparse),
POINTER :: diis_buffer
548 TYPE(qs_environment_type),
POINTER :: qs_env
549 TYPE(ls_scf_env_type) :: ls_scf_env
550 INTEGER,
INTENT(IN) :: unit_nr, iscf
551 LOGICAL,
INTENT(OUT) :: diis_step
552 REAL(kind=
dp),
INTENT(IN) :: eps_diis
553 INTEGER,
INTENT(IN),
OPTIONAL :: nmixing
554 TYPE(dbcsr_type),
OPTIONAL :: s_matrix
555 REAL(kind=
dp),
INTENT(IN) :: threshold
557 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_step_4lscf'
558 REAL(kind=
dp),
PARAMETER :: eigenvalue_threshold = 1.0e-12_dp
560 INTEGER :: handle, ib, ispin, jb, my_nmixing, nb, &
562 REAL(kind=
dp) :: error_max, tmp
563 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: ev
564 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b
565 TYPE(cp_logger_type),
POINTER :: logger
566 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks
567 TYPE(dbcsr_type) :: matrix_kserr_t, matrix_tmp
568 TYPE(dbcsr_type),
POINTER :: new_errors, old_errors, parameters
569 TYPE(mp_para_env_type),
POINTER :: para_env
571 CALL timeset(routinen, handle)
572 nspin = ls_scf_env%nspins
575 IF (
PRESENT(nmixing)) my_nmixing = nmixing
576 NULLIFY (new_errors, old_errors, parameters, a, b)
579 IF (diis_buffer%nbuffer < 1)
THEN
580 CALL timestop(handle)
588 CALL qs_diis_b_check_i_alloc_sparse( &
594 ib =
modulo(diis_buffer%ncall, diis_buffer%nbuffer) + 1
595 diis_buffer%ncall = diis_buffer%ncall + 1
596 nb = min(diis_buffer%ncall, diis_buffer%nbuffer)
598 CALL dbcsr_create(matrix_tmp, &
599 template=ls_scf_env%matrix_ks(1), &
601 CALL dbcsr_set(matrix_tmp, 0.0_dp)
602 CALL dbcsr_create(matrix_kserr_t, &
603 template=ls_scf_env%matrix_ks(1), &
605 CALL dbcsr_set(matrix_kserr_t, 0.0_dp)
609 new_errors => diis_buffer%error(ib, ispin)%matrix
610 parameters => diis_buffer%param(ib, ispin)%matrix
612 CALL dbcsr_copy(parameters, &
613 matrix_ks(ispin)%matrix)
615 IF (
PRESENT(s_matrix))
THEN
618 CALL dbcsr_multiply(
"N",
"N", &
619 1.0_dp, ls_scf_env%matrix_p(ispin), &
621 0.0_dp, matrix_tmp, &
622 filter_eps=threshold)
624 CALL dbcsr_multiply(
"N",
"N", &
625 1.0_dp, matrix_ks(ispin)%matrix, &
627 0.0_dp, new_errors, &
628 filter_eps=threshold)
630 CALL dbcsr_transposed(matrix_kserr_t, &
633 CALL dbcsr_add(new_errors, &
639 CALL dbcsr_multiply(
"N",
"N", &
640 1.0_dp, matrix_ks(ispin)%matrix, &
641 ls_scf_env%matrix_p(ispin), &
642 0.0_dp, new_errors, &
643 filter_eps=threshold)
645 CALL dbcsr_transposed(matrix_kserr_t, &
648 CALL dbcsr_add(new_errors, &
653 tmp = dbcsr_maxabs(new_errors)
654 error_max = max(error_max, tmp)
660 diis_step = (diis_buffer%ncall >= my_nmixing)
662 IF (unit_nr > 0)
THEN
663 WRITE (unit_nr,
'(A29,I3,A3,4(I3,A1))') &
664 "DIIS: (ncall,nbuffer,ib,nb)=(", iscf,
")=(", &
665 diis_buffer%ncall,
",", diis_buffer%nbuffer,
",", ib,
",", nb,
")"
666 WRITE (unit_nr,
'(A57,I3,A3,L1,A1,F10.8,A1,F4.2,A1,L1,A1)') &
667 "DIIS: (diis_step,error_max,eps_diis,error_max<eps_diis)=(", &
668 iscf,
")=(", diis_step,
",", error_max,
",", eps_diis,
",", &
669 (error_max < eps_diis),
")"
670 WRITE (unit_nr,
'(A75)') &
671 "DIIS: diis_step=T : Perform DIIS error_max<eps_diis=T : Update DIIS buffer"
675 IF (error_max < eps_diis)
THEN
676 b => diis_buffer%b_matrix
680 old_errors => diis_buffer%error(jb, ispin)%matrix
681 new_errors => diis_buffer%error(ib, ispin)%matrix
682 CALL dbcsr_dot(old_errors, &
685 b(jb, ib) = b(jb, ib) + tmp
687 b(ib, jb) = b(jb, ib)
696 ALLOCATE (a(nb1, nb1))
697 ALLOCATE (b(nb1, nb1))
700 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
701 b(1:nb, nb1) = -1.0_dp
702 b(nb1, 1:nb) = -1.0_dp
706 a(1:nb1, 1:nb1) = b(1:nb1, 1:nb1)
708 IF (abs(ev(jb)) < eigenvalue_threshold)
THEN
709 a(1:nb1, jb) = 0.0_dp
711 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
715 ev(1:nb) = matmul(a(1:nb, 1:nb1), b(nb1, 1:nb1))
718 IF (iscf .GE. ls_scf_env%iter_ini_diis)
THEN
720 IF (unit_nr > 0)
THEN
721 WRITE (unit_nr,
'(A40,I3)')
'DIIS: Updating Kohn-Sham matrix at iscf=', iscf
725 CALL dbcsr_set(matrix_ks(ispin)%matrix, &
728 parameters => diis_buffer%param(jb, ispin)%matrix
729 CALL dbcsr_add(matrix_ks(ispin)%matrix, parameters, &
741 parameters => diis_buffer%param(ib, ispin)%matrix
742 CALL dbcsr_copy(parameters, &
743 matrix_ks(ispin)%matrix)
746 CALL dbcsr_release(matrix_tmp)
747 CALL dbcsr_release(matrix_kserr_t)
748 CALL timestop(handle)
765 SUBROUTINE qs_diis_b_check_i_alloc_sparse(diis_buffer, ls_scf_env, &
768 TYPE(qs_diis_buffer_type_sparse),
INTENT(INOUT) :: diis_buffer
769 TYPE(ls_scf_env_type) :: ls_scf_env
770 INTEGER,
INTENT(IN) :: nspin
772 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_check_i_alloc_sparse'
774 INTEGER :: handle, ibuffer, ispin, nbuffer
775 TYPE(cp_logger_type),
POINTER :: logger
779 CALL timeset(routinen, handle)
783 nbuffer = diis_buffer%nbuffer
785 IF (.NOT.
ASSOCIATED(diis_buffer%error))
THEN
786 ALLOCATE (diis_buffer%error(nbuffer, nspin))
789 DO ibuffer = 1, nbuffer
790 ALLOCATE (diis_buffer%error(ibuffer, ispin)%matrix)
792 CALL dbcsr_create(diis_buffer%error(ibuffer, ispin)%matrix, &
793 template=ls_scf_env%matrix_ks(1), &
799 IF (.NOT.
ASSOCIATED(diis_buffer%param))
THEN
800 ALLOCATE (diis_buffer%param(nbuffer, nspin))
803 DO ibuffer = 1, nbuffer
804 ALLOCATE (diis_buffer%param(ibuffer, ispin)%matrix)
805 CALL dbcsr_create(diis_buffer%param(ibuffer, ispin)%matrix, &
806 template=ls_scf_env%matrix_ks(1), &
812 IF (.NOT.
ASSOCIATED(diis_buffer%b_matrix))
THEN
813 ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
815 diis_buffer%b_matrix = 0.0_dp
818 CALL timestop(handle)
820 END SUBROUTINE qs_diis_b_check_i_alloc_sparse
832 TYPE(qs_diis_buffer_type_sparse),
INTENT(INOUT) :: diis_buffer
834 diis_buffer%ncall = 0
848 TYPE(qs_diis_buffer_type_sparse),
INTENT(OUT) :: diis_buffer
849 INTEGER,
INTENT(in) :: nbuffer
851 NULLIFY (diis_buffer%b_matrix)
852 NULLIFY (diis_buffer%error)
853 NULLIFY (diis_buffer%param)
854 diis_buffer%nbuffer = nbuffer
855 diis_buffer%ncall = 0
866 TYPE(qs_diis_buffer_type_kp),
INTENT(OUT) :: diis_buffer
867 INTEGER,
INTENT(in) :: nbuffer
869 NULLIFY (diis_buffer%b_matrix)
870 NULLIFY (diis_buffer%error)
871 NULLIFY (diis_buffer%param)
872 NULLIFY (diis_buffer%smat)
873 diis_buffer%nbuffer = nbuffer
874 diis_buffer%ncall = 0
887 SUBROUTINE qs_diis_b_check_i_alloc_kp(diis_buffer, matrix_struct, nspin, nkp, scf_section)
889 TYPE(qs_diis_buffer_type_kp),
INTENT(INOUT) :: diis_buffer
890 TYPE(cp_fm_struct_type),
POINTER :: matrix_struct
891 INTEGER,
INTENT(IN) :: nspin, nkp
892 TYPE(section_vals_type),
POINTER :: scf_section
894 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_check_i_alloc_kp'
896 INTEGER :: handle, ibuffer, ikp, ispin, nbuffer, &
898 TYPE(cp_logger_type),
POINTER :: logger
902 CALL timeset(routinen, handle)
906 nbuffer = diis_buffer%nbuffer
908 IF (.NOT.
ASSOCIATED(diis_buffer%error))
THEN
909 ALLOCATE (diis_buffer%error(nbuffer, nspin, nkp))
913 DO ibuffer = 1, nbuffer
915 name=
"qs_diis_b%error("// &
916 trim(adjustl(cp_to_string(ibuffer)))//
","// &
917 trim(adjustl(cp_to_string(ibuffer)))//
")", &
918 matrix_struct=matrix_struct)
924 IF (.NOT.
ASSOCIATED(diis_buffer%param))
THEN
925 ALLOCATE (diis_buffer%param(nbuffer, nspin, nkp))
929 DO ibuffer = 1, nbuffer
931 name=
"qs_diis_b%param("// &
932 trim(adjustl(cp_to_string(ibuffer)))//
","// &
933 trim(adjustl(cp_to_string(ibuffer)))//
")", &
934 matrix_struct=matrix_struct)
940 IF (.NOT.
ASSOCIATED(diis_buffer%smat))
THEN
941 ALLOCATE (diis_buffer%smat(nkp))
944 name=
"kp_cfm_smat("// &
945 trim(adjustl(cp_to_string(ibuffer)))//
","// &
946 trim(adjustl(cp_to_string(ibuffer)))//
")", &
947 matrix_struct=matrix_struct)
951 IF (.NOT.
ASSOCIATED(diis_buffer%b_matrix))
THEN
952 ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
953 diis_buffer%b_matrix = 0.0_dp
956 IF (output_unit > 0)
THEN
957 WRITE (unit=output_unit, fmt=
"(/,T9,A)") &
958 "DIIS | The SCF DIIS buffer was allocated and initialized"
964 CALL timestop(handle)
966 END SUBROUTINE qs_diis_b_check_i_alloc_kp
974 TYPE(qs_diis_buffer_type_kp),
INTENT(INOUT) :: diis_buffer
976 diis_buffer%ncall = 0
987 TYPE(qs_diis_buffer_type_kp),
POINTER :: diis_buffer
988 INTEGER,
INTENT(OUT) :: ib, nb
990 ib =
modulo(diis_buffer%ncall, diis_buffer%nbuffer) + 1
991 diis_buffer%ncall = diis_buffer%ncall + 1
992 nb = min(diis_buffer%ncall, diis_buffer%nbuffer)
1011 TYPE(qs_diis_buffer_type_kp),
POINTER :: diis_buffer
1012 INTEGER,
INTENT(IN) :: ib
1013 TYPE(mo_set_type),
DIMENSION(:, :),
POINTER :: mos
1014 TYPE(cp_cfm_type),
INTENT(INOUT) :: kc, sc
1015 INTEGER,
INTENT(IN) :: ispin, ikp, nkp_local
1016 TYPE(section_vals_type),
POINTER :: scf_section
1018 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_calc_err_kp'
1020 INTEGER :: handle, homo, nao, nmo, nspin
1022 TYPE(cp_cfm_type) :: cmos
1023 TYPE(cp_cfm_type),
POINTER :: new_errors, parameters, smat
1024 TYPE(cp_fm_struct_type),
POINTER :: matrix_struct
1025 TYPE(cp_fm_type),
POINTER :: imos, rmos
1027 NULLIFY (matrix_struct, imos, rmos, parameters, new_errors, smat)
1029 CALL timeset(routinen, handle)
1035 IF (diis_buffer%nbuffer < 1)
THEN
1036 CALL timestop(handle)
1039 nspin =
SIZE(mos, 2)
1042 CALL qs_diis_b_check_i_alloc_kp(diis_buffer, &
1043 matrix_struct=matrix_struct, &
1044 nspin=nspin, nkp=nkp_local, &
1045 scf_section=scf_section)
1048 CALL get_mo_set(mos(1, ispin), nao=nao, nmo=nmo, homo=homo, mo_coeff=rmos, maxocc=maxocc)
1049 CALL get_mo_set(mos(2, ispin), mo_coeff=imos)
1050 NULLIFY (matrix_struct)
1055 new_errors => diis_buffer%error(ib, ispin, ikp)
1056 parameters => diis_buffer%param(ib, ispin, ikp)
1057 smat => diis_buffer%smat(ikp)
1060 CALL cp_cfm_to_cfm(kc, parameters)
1061 CALL cp_cfm_to_cfm(sc, smat)
1064 CALL parallel_gemm(
"N",
"N", nao, homo, nao, cmplx(maxocc, kind=
dp), parameters, cmos, (0.0_dp, 0.0_dp), kc)
1066 CALL parallel_gemm(
"N",
"N", nao, homo, nao, (2.0_dp, 0.0_dp), smat, cmos, (0.0_dp, 0.0_dp), sc)
1069 CALL parallel_gemm(
"N",
"T", nao, nao, homo, (1.0_dp, 0.0_dp), sc, kc, (0.0_dp, 0.0_dp), new_errors)
1070 CALL parallel_gemm(
"N",
"T", nao, nao, homo, (1.0_dp, 0.0_dp), kc, sc, (-1.0_dp, 0.0_dp), new_errors)
1075 CALL timestop(handle)
1097 nspin, nkp, nkp_local, nmixing, scf_section, para_env)
1099 TYPE(qs_diis_buffer_type_kp),
POINTER :: diis_buffer
1100 COMPLEX(KIND=dp),
DIMENSION(:),
INTENT(INOUT) :: coeffs
1101 INTEGER,
INTENT(IN) :: ib, nb
1102 REAL(kind=
dp),
INTENT(IN) :: delta
1103 REAL(kind=
dp),
INTENT(OUT) :: error_max
1104 LOGICAL,
INTENT(OUT) :: diis_step
1105 REAL(kind=
dp),
INTENT(IN) :: eps_diis
1106 INTEGER,
INTENT(IN) :: nspin, nkp, nkp_local
1107 INTEGER,
INTENT(IN),
OPTIONAL :: nmixing
1108 TYPE(section_vals_type),
POINTER :: scf_section
1109 TYPE(mp_para_env_type),
POINTER :: para_env
1111 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_step_kp'
1112 REAL(kind=
dp),
PARAMETER :: eigenvalue_threshold = 1.0e-12_dp
1114 CHARACTER(LEN=2*default_string_length) :: message
1115 COMPLEX(KIND=dp) :: tmp
1116 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: a, b
1117 INTEGER :: handle, ikp, ispin, jb, my_nmixing, nb1, &
1119 LOGICAL :: eigenvectors_discarded
1120 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: ev
1121 TYPE(cp_cfm_type) :: old_errors
1122 TYPE(cp_cfm_type),
POINTER :: new_errors
1123 TYPE(cp_fm_struct_type),
POINTER :: matrix_struct
1124 TYPE(cp_fm_type) :: ierr, rerr
1125 TYPE(cp_logger_type),
POINTER :: logger
1127 NULLIFY (matrix_struct, new_errors, logger)
1129 CALL timeset(routinen, handle)
1134 IF (
PRESENT(nmixing)) my_nmixing = nmixing
1139 IF (diis_buffer%nbuffer < 1)
THEN
1140 CALL timestop(handle)
1145 diis_step = ((diis_buffer%ncall >= my_nmixing) .AND. (delta < eps_diis))
1148 CALL cp_cfm_get_info(diis_buffer%error(ib, 1, 1), matrix_struct=matrix_struct)
1152 ALLOCATE (b(nb, nb))
1155 DO ikp = 1, nkp_local
1157 new_errors => diis_buffer%error(ib, ispin, ikp)
1158 CALL cp_cfm_to_fm(diis_buffer%error(jb, ispin, ikp), rerr, ierr)
1162 b(jb, ib) = b(jb, ib) + 1.0_dp/real(nkp,
dp)*tmp
1165 b(ib, jb) = conjg(b(jb, ib))
1167 CALL cp_fm_release(ierr)
1168 CALL cp_fm_release(rerr)
1170 CALL para_env%sum(b)
1172 error_max = sqrt(real(b(ib, ib))**2 + aimag(b(ib, ib))**2)
1175 extension=
".scfLog")
1176 IF (output_unit > 0)
THEN
1177 WRITE (unit=output_unit, fmt=
"(/,T9,A,I4,/,(T9,A,ES12.3))") &
1178 "DIIS | Current SCF DIIS buffer size: ", nb, &
1179 "DIIS | Maximum SCF DIIS error at last step: ", error_max, &
1180 "DIIS | Current SCF convergence: ", delta, &
1181 "DIIS | Threshold value for a DIIS step: ", eps_diis
1182 IF (error_max < eps_diis)
THEN
1183 WRITE (unit=output_unit, fmt=
"(T9,A)") &
1184 "DIIS | => The SCF DIIS buffer will be updated"
1186 WRITE (unit=output_unit, fmt=
"(T9,A)") &
1187 "DIIS | => No update of the SCF DIIS buffer"
1189 IF (diis_step .AND. (error_max < eps_diis))
THEN
1190 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
1191 "DIIS | => A SCF DIIS step will be performed"
1193 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
1194 "DIIS | => No SCF DIIS step will be performed"
1199 IF (error_max < eps_diis)
THEN
1201 diis_buffer%b_matrix(ib, jb) = b(ib, jb)
1202 diis_buffer%b_matrix(jb, ib) = b(jb, ib)
1215 ALLOCATE (a(nb1, nb1))
1216 ALLOCATE (b(nb1, nb1))
1220 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
1222 b(1:nb, nb1) = -1.0_dp
1223 b(nb1, 1:nb) = -1.0_dp
1224 b(nb1, nb1) = 0.0_dp
1228 a(1:nb1, 1:nb1) = 0.0_dp
1229 CALL complex_diag(b(1:nb1, 1:nb1), a(1:nb1, 1:nb1), ev(1:nb1))
1230 b(1:nb1, 1:nb1) = a(1:nb1, 1:nb1)
1232 eigenvectors_discarded = .false.
1235 IF (abs(ev(jb)) < eigenvalue_threshold)
THEN
1236 IF (output_unit > 0)
THEN
1237 IF (.NOT. eigenvectors_discarded)
THEN
1238 WRITE (unit=output_unit, fmt=
"(T9,A)") &
1239 "DIIS | Checking eigenvalues of the DIIS error matrix"
1241 WRITE (unit=message, fmt=
"(T9,A,I6,A,ES10.1,A,ES10.1)") &
1242 "DIIS | Eigenvalue ", jb,
" = ", ev(jb),
" is smaller than "// &
1243 "threshold ", eigenvalue_threshold
1245 WRITE (unit=output_unit, fmt=
"(T9,A)") trim(message)
1246 eigenvectors_discarded = .true.
1248 a(1:nb1, jb) = 0.0_dp
1250 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
1254 IF ((output_unit > 0) .AND. eigenvectors_discarded)
THEN
1255 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
1256 "DIIS | The corresponding eigenvectors were discarded"
1259 coeffs(1:nb) = -matmul(a(1:nb, 1:nb1), conjg(b(nb1, 1:nb1)))
1269 CALL timestop(handle)
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_trace(matrix_a, matrix_b, trace)
Returns the trace of matrix_a^T matrix_b, i.e sum_{i,j}(matrix_a(i,j)*matrix_b(i,j)) .
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_create(matrix, matrix_struct, name)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_fm_to_cfm(msourcer, msourcei, mtarget)
Construct a complex full matrix by taking its real and imaginary parts from two separate real-value f...
subroutine, public cp_cfm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, matrix_struct, para_env)
Returns information about a full matrix.
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.
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS 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_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
subroutine, public cp_fm_scale(alpha, matrix_a)
scales a matrix matrix_a = alpha * matrix_b
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...
represent the structure of a full matrix
represent a full matrix distributed on many processors
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_maxabsval(matrix, a_max, ir_max, ic_max)
find the maximum absolute value of the matrix element maxval(abs(matrix))
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
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,...
Types needed for a linear scaling quickstep SCF run based on the density matrix.
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
Collection of simple mathematical functions and subroutines.
subroutine, public complex_diag(matrix, eigenvectors, eigenvalues)
Diagonalizes a local complex Hermitian matrix using LAPACK. Based on cp_cfm_heevd.
subroutine, public diamat_all(a, eigval, dac)
Diagonalize the symmetric n by n matrix a using the LAPACK library. Only the upper triangle of matrix...
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes
buffer for the diis of the scf
Apply the direct inversion in the iterative subspace (DIIS) of Pulay in the framework of an SCF itera...
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.
pure subroutine, public qs_diis_b_create_sparse(diis_buffer, nbuffer)
Allocates an SCF DIIS buffer for LS-SCF calculation.
pure subroutine, public qs_diis_b_clear(diis_buffer)
clears the buffer
subroutine, public qs_diis_b_create(diis_buffer, nbuffer)
Allocates an SCF DIIS buffer.
subroutine, public qs_diis_b_step_4lscf(diis_buffer, qs_env, ls_scf_env, unit_nr, iscf, diis_step, eps_diis, nmixing, s_matrix, threshold)
Update the SCF DIIS buffer in linear scaling SCF (LS-SCF), and if appropriate does a diis step.
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.
subroutine, public qs_diis_b_create_kp(diis_buffer, nbuffer)
Allocates an SCF DIIS buffer for k-points.
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.
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.
pure subroutine, public qs_diis_b_clear_sparse(diis_buffer)
clears the DIIS buffer in LS-SCF calculation
pure subroutine, public qs_diis_b_clear_kp(diis_buffer)
clears the buffer
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, 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_nonbond, sab_almo, sab_kp, sab_kp_nosym, 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, 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, ecoul_1c, rho0_s_rs, rho0_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, 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, rhs)
Get the QUICKSTEP environment.
Definition and initialisation of the mo data type.
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.
Utilities for string manipulations.
subroutine, public compress(string, full)
Eliminate multiple space characters in a string. If full is .TRUE., then all spaces are eliminated.