67#include "./base/base_uses.f90"
73 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_diis'
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, &
143 INTEGER,
INTENT(IN) :: nspin
146 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_check_i_alloc'
148 INTEGER :: handle, ibuffer, ispin, nbuffer, &
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("// &
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("// &
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)
230 TYPE(
mo_set_type),
DIMENSION(:),
INTENT(IN) :: mo_array
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
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, traces
253 REAL(kind=
dp),
DIMENSION(:),
POINTER :: occa, occb
254 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b
256 TYPE(
cp_fm_type),
POINTER :: c, new_errors, parameters
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, 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)
299 IF (
PRESENT(s_matrix))
THEN
300 IF (.NOT.
ALLOCATED(diis_buffer%overlap_copy_plan))
ALLOCATE (diis_buffer%overlap_copy_plan)
310 occupation_numbers=occa, &
313 new_errors => diis_buffer%error(ib, ispin)
314 parameters => diis_buffer%param(ib, ispin)
325 occupation_numbers=occb)
328 occ(imo) = sqrt(occa(imo) + occb(imo))
335 CALL cp_fm_symm(
"L",
"U", nao, homo, 1.0_dp, parameters, sc, 0.0_dp, kc(ispin))
337 IF (
PRESENT(s_matrix))
THEN
338 CALL copy_dbcsr_to_fm(s_matrix(1)%matrix, new_errors, diis_buffer%overlap_copy_plan, check_plan=.true.)
340 CALL cp_fm_symm(
"L",
"U", nao, homo, 1.0_dp, new_errors, c, 0.0_dp, sc)
347 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, sc, kc(ispin), 0.0_dp, new_errors)
348 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, kc(ispin), sc, -1.0_dp, new_errors)
355 CALL cp_fm_symm(
"L",
"U", nao, homo, maxocc, parameters, c, 0.0_dp, kc(ispin))
357 IF (
PRESENT(s_matrix))
THEN
359 CALL copy_dbcsr_to_fm(s_matrix(1)%matrix, new_errors, diis_buffer%overlap_copy_plan, check_plan=.true.)
361 CALL cp_fm_symm(
"L",
"U", nao, homo, 2.0_dp, new_errors, c, 0.0_dp, sc)
363 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, sc, kc(ispin), 0.0_dp, new_errors)
364 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, kc(ispin), sc, -1.0_dp, new_errors)
367 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, c, kc(ispin), 0.0_dp, new_errors)
368 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, kc(ispin), c, -1.0_dp, new_errors)
374 error_max = max(error_max, tmp)
380 diis_step = ((diis_buffer%ncall >= my_nmixing) .AND. (delta < eps_diis))
384 IF (output_unit > 0)
THEN
385 WRITE (unit=output_unit, fmt=
"(/,T9,A,I4,/,(T9,A,ES12.3))") &
386 "DIIS | Current SCF DIIS buffer size: ", nb, &
387 "DIIS | Maximum SCF DIIS error vector element:", error_max, &
388 "DIIS | Current SCF convergence: ", delta, &
389 "DIIS | Threshold value for a DIIS step: ", eps_diis
390 IF (error_max < eps_diis)
THEN
391 WRITE (unit=output_unit, fmt=
"(T9,A)") &
392 "DIIS | => The SCF DIIS buffer will be updated"
394 WRITE (unit=output_unit, fmt=
"(T9,A)") &
395 "DIIS | => No update of the SCF DIIS buffer"
397 IF (diis_step .AND. (error_max < eps_diis))
THEN
398 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
399 "DIIS | => A SCF DIIS step will be performed"
401 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
402 "DIIS | => No SCF DIIS step will be performed"
408 IF (error_max < eps_diis)
THEN
410 b => diis_buffer%b_matrix
412 ALLOCATE (traces(nb))
417 CALL cp_fm_trace(diis_buffer%error(1, ispin), diis_buffer%error(ib, ispin), traces(1))
419 CALL cp_fm_trace(diis_buffer%error(1:nb, ispin), diis_buffer%error(ib, ispin), traces)
421 b(1:nb, ib) = b(1:nb, ib) + traces(:)
426 b(ib, jb) = b(jb, ib)
441 ALLOCATE (a(nb1, nb1))
442 ALLOCATE (b(nb1, nb1))
447 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
449 b(1:nb, nb1) = -1.0_dp
450 b(nb1, 1:nb) = -1.0_dp
458 a(1:nb1, 1:nb1) = b(1:nb1, 1:nb1)
460 eigenvectors_discarded = .false.
463 IF (abs(ev(jb)) < eigenvalue_threshold)
THEN
464 IF (output_unit > 0)
THEN
465 IF (.NOT. eigenvectors_discarded)
THEN
466 WRITE (unit=output_unit, fmt=
"(T9,A)") &
467 "DIIS | Checking eigenvalues of the DIIS error matrix"
469 WRITE (unit=message, fmt=
"(T9,A,I6,A,ES10.1,A,ES10.1)") &
470 "DIIS | Eigenvalue ", jb,
" = ", ev(jb),
" is smaller than "// &
471 "threshold ", eigenvalue_threshold
473 WRITE (unit=output_unit, fmt=
"(T9,A)") trim(message)
474 eigenvectors_discarded = .true.
476 a(1:nb1, jb) = 0.0_dp
478 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
482 IF ((output_unit > 0) .AND. eigenvectors_discarded)
THEN
483 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
484 "DIIS | The corresponding eigenvectors were discarded"
487 ev(1:nb) = matmul(a(1:nb, 1:nb1), b(nb1, 1:nb1))
494 parameters => diis_buffer%param(jb, ispin)
506 parameters => diis_buffer%param(ib, ispin)
515 CALL timestop(handle)
530 diis_buffer%ncall = 0
553 diis_step, eps_diis, nmixing, s_matrix, threshold)
560 INTEGER,
INTENT(IN) :: unit_nr, iscf
561 LOGICAL,
INTENT(OUT) :: diis_step
562 REAL(kind=
dp),
INTENT(IN) :: eps_diis
563 INTEGER,
INTENT(IN),
OPTIONAL :: nmixing
565 REAL(kind=
dp),
INTENT(IN) :: threshold
567 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_step_4lscf'
568 REAL(kind=
dp),
PARAMETER :: eigenvalue_threshold = 1.0e-12_dp
570 INTEGER :: handle, ib, ispin, jb, my_nmixing, nb, &
572 REAL(kind=
dp) :: error_max, tmp
573 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: ev
574 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b
577 TYPE(
dbcsr_type) :: matrix_kserr_t, matrix_tmp
578 TYPE(
dbcsr_type),
POINTER :: new_errors, old_errors, parameters
581 CALL timeset(routinen, handle)
582 IF (ls_scf_env%do_pao)
THEN
583 cpabort(
"LS_SCF%LS_DIIS not compatible with PAO")
585 nspin = ls_scf_env%nspins
588 IF (
PRESENT(nmixing)) my_nmixing = nmixing
589 NULLIFY (new_errors, old_errors, parameters, a, b)
592 IF (diis_buffer%nbuffer < 1)
THEN
593 CALL timestop(handle)
601 CALL qs_diis_b_check_i_alloc_sparse( &
607 ib =
modulo(diis_buffer%ncall, diis_buffer%nbuffer) + 1
608 diis_buffer%ncall = diis_buffer%ncall + 1
609 nb = min(diis_buffer%ncall, diis_buffer%nbuffer)
612 template=ls_scf_env%matrix_ks(1), &
616 template=ls_scf_env%matrix_ks(1), &
622 new_errors => diis_buffer%error(ib, ispin)%matrix
623 parameters => diis_buffer%param(ib, ispin)%matrix
626 matrix_ks(ispin)%matrix)
628 IF (
PRESENT(s_matrix))
THEN
632 1.0_dp, ls_scf_env%matrix_p(ispin), &
634 0.0_dp, matrix_tmp, &
635 filter_eps=threshold)
638 1.0_dp, matrix_ks(ispin)%matrix, &
640 0.0_dp, new_errors, &
641 filter_eps=threshold)
653 1.0_dp, matrix_ks(ispin)%matrix, &
654 ls_scf_env%matrix_p(ispin), &
655 0.0_dp, new_errors, &
656 filter_eps=threshold)
667 error_max = max(error_max, tmp)
673 diis_step = (diis_buffer%ncall >= my_nmixing)
675 IF (unit_nr > 0)
THEN
676 WRITE (unit_nr,
'(A29,I3,A3,4(I3,A1))') &
677 "DIIS: (ncall,nbuffer,ib,nb)=(", iscf,
")=(", &
678 diis_buffer%ncall,
",", diis_buffer%nbuffer,
",", ib,
",", nb,
")"
679 WRITE (unit_nr,
'(A57,I3,A3,L1,A1,F10.8,A1,F4.2,A1,L1,A1)') &
680 "DIIS: (diis_step,error_max,eps_diis,error_max<eps_diis)=(", &
681 iscf,
")=(", diis_step,
",", error_max,
",", eps_diis,
",", &
682 (error_max < eps_diis),
")"
683 WRITE (unit_nr,
'(A75)') &
684 "DIIS: diis_step=T : Perform DIIS error_max<eps_diis=T : Update DIIS buffer"
688 IF (error_max < eps_diis)
THEN
689 b => diis_buffer%b_matrix
693 old_errors => diis_buffer%error(jb, ispin)%matrix
694 new_errors => diis_buffer%error(ib, ispin)%matrix
698 b(jb, ib) = b(jb, ib) + tmp
700 b(ib, jb) = b(jb, ib)
709 ALLOCATE (a(nb1, nb1))
710 ALLOCATE (b(nb1, nb1))
713 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
714 b(1:nb, nb1) = -1.0_dp
715 b(nb1, 1:nb) = -1.0_dp
719 a(1:nb1, 1:nb1) = b(1:nb1, 1:nb1)
721 IF (abs(ev(jb)) < eigenvalue_threshold)
THEN
722 a(1:nb1, jb) = 0.0_dp
724 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
728 ev(1:nb) = matmul(a(1:nb, 1:nb1), b(nb1, 1:nb1))
731 IF (iscf >= ls_scf_env%iter_ini_diis)
THEN
733 IF (unit_nr > 0)
THEN
734 WRITE (unit_nr,
'(A40,I3)')
'DIIS: Updating Kohn-Sham matrix at iscf=', iscf
738 CALL dbcsr_set(matrix_ks(ispin)%matrix, &
741 parameters => diis_buffer%param(jb, ispin)%matrix
742 CALL dbcsr_add(matrix_ks(ispin)%matrix, parameters, &
754 parameters => diis_buffer%param(ib, ispin)%matrix
756 matrix_ks(ispin)%matrix)
761 CALL timestop(handle)
778 SUBROUTINE qs_diis_b_check_i_alloc_sparse(diis_buffer, ls_scf_env, &
783 INTEGER,
INTENT(IN) :: nspin
785 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_check_i_alloc_sparse'
787 INTEGER :: handle, ibuffer, ispin, nbuffer
792 CALL timeset(routinen, handle)
796 nbuffer = diis_buffer%nbuffer
798 IF (.NOT.
ASSOCIATED(diis_buffer%error))
THEN
799 ALLOCATE (diis_buffer%error(nbuffer, nspin))
802 DO ibuffer = 1, nbuffer
803 ALLOCATE (diis_buffer%error(ibuffer, ispin)%matrix)
805 CALL dbcsr_create(diis_buffer%error(ibuffer, ispin)%matrix, &
806 template=ls_scf_env%matrix_ks(1), &
812 IF (.NOT.
ASSOCIATED(diis_buffer%param))
THEN
813 ALLOCATE (diis_buffer%param(nbuffer, nspin))
816 DO ibuffer = 1, nbuffer
817 ALLOCATE (diis_buffer%param(ibuffer, ispin)%matrix)
818 CALL dbcsr_create(diis_buffer%param(ibuffer, ispin)%matrix, &
819 template=ls_scf_env%matrix_ks(1), &
825 IF (.NOT.
ASSOCIATED(diis_buffer%b_matrix))
THEN
826 ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
828 diis_buffer%b_matrix = 0.0_dp
831 CALL timestop(handle)
833 END SUBROUTINE qs_diis_b_check_i_alloc_sparse
847 diis_buffer%ncall = 0
862 INTEGER,
INTENT(in) :: nbuffer
864 NULLIFY (diis_buffer%b_matrix)
865 NULLIFY (diis_buffer%error)
866 NULLIFY (diis_buffer%param)
867 diis_buffer%nbuffer = nbuffer
868 diis_buffer%ncall = 0
880 INTEGER,
INTENT(in) :: nbuffer
882 NULLIFY (diis_buffer%b_matrix)
883 NULLIFY (diis_buffer%error)
884 NULLIFY (diis_buffer%param)
885 NULLIFY (diis_buffer%smat)
886 diis_buffer%nbuffer = nbuffer
887 diis_buffer%ncall = 0
904 INTEGER,
INTENT(IN) :: nspin, nkp
907 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_check_i_alloc_kp'
909 INTEGER :: handle, ibuffer, ikp, ispin, nbuffer, &
915 CALL timeset(routinen, handle)
919 nbuffer = diis_buffer%nbuffer
921 IF (.NOT.
ASSOCIATED(diis_buffer%error))
THEN
922 ALLOCATE (diis_buffer%error(nbuffer, nspin, nkp))
926 DO ibuffer = 1, nbuffer
928 name=
"qs_diis_b%error("// &
931 matrix_struct=matrix_struct)
937 IF (.NOT.
ASSOCIATED(diis_buffer%param))
THEN
938 ALLOCATE (diis_buffer%param(nbuffer, nspin, nkp))
942 DO ibuffer = 1, nbuffer
944 name=
"qs_diis_b%param("// &
947 matrix_struct=matrix_struct)
953 IF (.NOT.
ASSOCIATED(diis_buffer%smat))
THEN
954 ALLOCATE (diis_buffer%smat(nkp))
958 matrix_struct=matrix_struct)
962 IF (.NOT.
ASSOCIATED(diis_buffer%b_matrix))
THEN
963 ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
964 diis_buffer%b_matrix = 0.0_dp
967 IF (output_unit > 0)
THEN
968 WRITE (unit=output_unit, fmt=
"(/,T9,A)") &
969 "DIIS | The SCF DIIS buffer was allocated and initialized"
975 CALL timestop(handle)
987 diis_buffer%ncall = 0
999 INTEGER,
INTENT(OUT) :: ib, nb
1001 ib =
modulo(diis_buffer%ncall, diis_buffer%nbuffer) + 1
1002 diis_buffer%ncall = diis_buffer%ncall + 1
1003 nb = min(diis_buffer%ncall, diis_buffer%nbuffer)
1023 SUBROUTINE qs_diis_b_calc_err_kp(diis_buffer, ib, mos, kc, sc, ispin, ikp, cmos, real_wfn, local, gemm_ctx)
1025 INTEGER,
INTENT(IN) :: ib
1028 INTEGER,
INTENT(IN) :: ispin, ikp
1030 LOGICAL,
INTENT(IN),
OPTIONAL :: real_wfn, local
1033 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_calc_err_kp'
1035 INTEGER :: handle, homo, nao
1036 LOGICAL :: my_real_wfn
1038 TYPE(
cp_cfm_type),
POINTER :: new_errors, parameters, smat
1041 NULLIFY (rmos, parameters, new_errors, smat)
1043 CALL timeset(routinen, handle)
1044 my_real_wfn = .false.
1045 IF (
PRESENT(real_wfn)) my_real_wfn = real_wfn
1051 IF (diis_buffer%nbuffer < 1)
THEN
1052 CALL timestop(handle)
1055 CALL get_mo_set(mos(ispin), nao=nao, homo=homo, maxocc=maxocc)
1057 IF (my_real_wfn)
THEN
1060 cmplx(1.0_dp, kind=
dp), rmos)
1065 new_errors => diis_buffer%error(ib, ispin, ikp)
1066 parameters => diis_buffer%param(ib, ispin, ikp)
1067 smat => diis_buffer%smat(ikp)
1076 cpassert(product(parameters%matrix_struct%context%num_pe) == 1)
1077 cpassert(product(cmos%matrix_struct%context%num_pe) == 1)
1078 cpassert(product(kc%matrix_struct%context%num_pe) == 1)
1079 cpassert(product(smat%matrix_struct%context%num_pe) == 1)
1080 cpassert(product(sc%matrix_struct%context%num_pe) == 1)
1081 cpassert(product(new_errors%matrix_struct%context%num_pe) == 1)
1082 CALL gemm_ctx%gemm(
"N",
"N", nao, homo, nao, cmplx(maxocc, kind=
dp), &
1083 parameters%local_data,
SIZE(parameters%local_data, 1), &
1084 cmos%local_data,
SIZE(cmos%local_data, 1), (0.0_dp, 0.0_dp), &
1085 kc%local_data,
SIZE(kc%local_data, 1))
1086 CALL gemm_ctx%gemm(
"N",
"N", nao, homo, nao, (2.0_dp, 0.0_dp), &
1087 smat%local_data,
SIZE(smat%local_data, 1), &
1088 cmos%local_data,
SIZE(cmos%local_data, 1), (0.0_dp, 0.0_dp), &
1089 sc%local_data,
SIZE(sc%local_data, 1))
1090 CALL gemm_ctx%gemm(
"N",
"C", nao, nao, homo, (1.0_dp, 0.0_dp), &
1091 sc%local_data,
SIZE(sc%local_data, 1), &
1092 kc%local_data,
SIZE(kc%local_data, 1), (0.0_dp, 0.0_dp), &
1093 new_errors%local_data,
SIZE(new_errors%local_data, 1))
1094 CALL gemm_ctx%gemm(
"N",
"C", nao, nao, homo, (1.0_dp, 0.0_dp), &
1095 kc%local_data,
SIZE(kc%local_data, 1), &
1096 sc%local_data,
SIZE(sc%local_data, 1), (-1.0_dp, 0.0_dp), &
1097 new_errors%local_data,
SIZE(new_errors%local_data, 1))
1099 CALL parallel_gemm(
"N",
"N", nao, homo, nao, cmplx(maxocc, kind=
dp), parameters, cmos, (0.0_dp, 0.0_dp), kc)
1100 CALL parallel_gemm(
"N",
"N", nao, homo, nao, (2.0_dp, 0.0_dp), smat, cmos, (0.0_dp, 0.0_dp), sc)
1101 CALL parallel_gemm(
"N",
"C", nao, nao, homo, (1.0_dp, 0.0_dp), sc, kc, (0.0_dp, 0.0_dp), new_errors)
1102 CALL parallel_gemm(
"N",
"C", nao, nao, homo, (1.0_dp, 0.0_dp), kc, sc, (-1.0_dp, 0.0_dp), new_errors)
1105 CALL timestop(handle)
1127 nspin, nkp, nkp_local, nmixing, scf_section, para_env_inter_kp)
1130 COMPLEX(KIND=dp),
DIMENSION(:),
INTENT(INOUT) :: coeffs
1131 INTEGER,
INTENT(IN) :: ib, nb
1132 REAL(kind=
dp),
INTENT(IN) :: delta
1133 REAL(kind=
dp),
INTENT(OUT) :: error_max
1134 LOGICAL,
INTENT(OUT) :: diis_step
1135 REAL(kind=
dp),
INTENT(IN) :: eps_diis
1136 INTEGER,
INTENT(IN) :: nspin, nkp, nkp_local
1137 INTEGER,
INTENT(IN),
OPTIONAL :: nmixing
1141 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_step_kp'
1142 REAL(kind=
dp),
PARAMETER :: eigenvalue_threshold = 1.0e-12_dp
1144 CHARACTER(LEN=2*default_string_length) :: message
1145 COMPLEX(KIND=dp) :: tmp
1146 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: a, b
1147 INTEGER :: handle, ikp, ispin, jb, my_nmixing, nb1, &
1149 LOGICAL :: eigenvectors_discarded
1150 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: ev
1155 NULLIFY (matrix_struct, new_errors, logger)
1157 CALL timeset(routinen, handle)
1162 IF (
PRESENT(nmixing)) my_nmixing = nmixing
1167 IF (diis_buffer%nbuffer < 1)
THEN
1168 CALL timestop(handle)
1173 diis_step = ((diis_buffer%ncall >= my_nmixing) .AND. (delta < eps_diis))
1176 CALL cp_cfm_get_info(diis_buffer%error(ib, 1, 1), matrix_struct=matrix_struct)
1177 ALLOCATE (b(nb, nb))
1180 DO ikp = 1, nkp_local
1182 new_errors => diis_buffer%error(ib, ispin, ikp)
1183 CALL cp_cfm_trace(diis_buffer%error(jb, ispin, ikp), new_errors, tmp, &
1184 conjugate_a=.true., local=.true.)
1185 b(jb, ib) = b(jb, ib) + 1.0_dp/real(nkp,
dp)*tmp
1191 CALL matrix_struct%para_env%sum(b(:, ib))
1192 CALL para_env_inter_kp%sum(b(:, ib))
1194 b(ib, jb) = conjg(b(jb, ib))
1197 error_max = sqrt(real(b(ib, ib))**2 + aimag(b(ib, ib))**2)
1200 extension=
".scfLog")
1201 IF (output_unit > 0)
THEN
1202 WRITE (unit=output_unit, fmt=
"(/,T9,A,I4,/,(T9,A,ES12.3))") &
1203 "DIIS | Current SCF DIIS buffer size: ", nb, &
1204 "DIIS | Maximum SCF DIIS error at last step: ", error_max, &
1205 "DIIS | Current SCF convergence: ", delta, &
1206 "DIIS | Threshold value for a DIIS step: ", eps_diis
1207 IF (error_max < eps_diis)
THEN
1208 WRITE (unit=output_unit, fmt=
"(T9,A)") &
1209 "DIIS | => The SCF DIIS buffer will be updated"
1211 WRITE (unit=output_unit, fmt=
"(T9,A)") &
1212 "DIIS | => No update of the SCF DIIS buffer"
1214 IF (diis_step .AND. (error_max < eps_diis))
THEN
1215 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
1216 "DIIS | => A SCF DIIS step will be performed"
1218 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
1219 "DIIS | => No SCF DIIS step will be performed"
1224 IF (error_max < eps_diis)
THEN
1226 diis_buffer%b_matrix(ib, jb) = b(ib, jb)
1227 diis_buffer%b_matrix(jb, ib) = b(jb, ib)
1240 ALLOCATE (a(nb1, nb1))
1241 ALLOCATE (b(nb1, nb1))
1245 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
1247 b(1:nb, nb1) = -1.0_dp
1248 b(nb1, 1:nb) = -1.0_dp
1249 b(nb1, nb1) = 0.0_dp
1253 a(1:nb1, 1:nb1) = 0.0_dp
1254 CALL diag_complex(b(1:nb1, 1:nb1), a(1:nb1, 1:nb1), ev(1:nb1))
1255 b(1:nb1, 1:nb1) = a(1:nb1, 1:nb1)
1257 eigenvectors_discarded = .false.
1260 IF (abs(ev(jb)) < eigenvalue_threshold)
THEN
1261 IF (output_unit > 0)
THEN
1262 IF (.NOT. eigenvectors_discarded)
THEN
1263 WRITE (unit=output_unit, fmt=
"(T9,A)") &
1264 "DIIS | Checking eigenvalues of the DIIS error matrix"
1266 WRITE (unit=message, fmt=
"(T9,A,I6,A,ES10.1,A,ES10.1)") &
1267 "DIIS | Eigenvalue ", jb,
" = ", ev(jb),
" is smaller than "// &
1268 "threshold ", eigenvalue_threshold
1270 WRITE (unit=output_unit, fmt=
"(T9,A)") trim(message)
1271 eigenvectors_discarded = .true.
1273 a(1:nb1, jb) = 0.0_dp
1275 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
1279 IF ((output_unit > 0) .AND. eigenvectors_discarded)
THEN
1280 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
1281 "DIIS | The corresponding eigenvectors were discarded"
1284 coeffs(1:nb) = -matmul(a(1:nb, 1:nb1), conjg(b(nb1, 1:nb1)))
1294 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_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_trace(matrix_a, matrix_b, trace, conjugate_a, local)
By default, returns the trace of matrix_a^T matrix_b, i.e sum_{i,j}(matrix_a(i,j)*matrix_b(i,...
Represents a complex full matrix distributed on many processors.
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_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 dbcsr_transposed(transposed, normal, shallow_data_copy, transpose_distribution, use_distribution)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
real(dp) function, public dbcsr_maxabs(matrix)
Compute the maxabs norm of a dbcsr matrix.
subroutine, public dbcsr_dot(matrix_a, matrix_b, trace)
Computes the dot product of two matrices, also known as the trace of their matrix product.
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm, plan, check_plan)
Copy a DBCSR matrix to a BLACS matrix.
Basic linear algebra operations for full matrices.
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_column_scale(matrixa, scaling, first_col, source)
Scales columns of the full matrix by corresponding factors.
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, nrow, ncol, set_zero)
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...
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,...
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, file_access)
...
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 diag_complex(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.
subroutine, public qs_diis_b_calc_err_kp(diis_buffer, ib, mos, kc, sc, ispin, ikp, cmos, real_wfn, local, gemm_ctx)
Calculate and store the error for a given k-point.
pure subroutine, public qs_diis_b_clear(diis_buffer)
clears the buffer
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_inter_kp)
Update the SCF DIIS buffer, and if appropriate does a diis step, for k-points.
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_create_kp(diis_buffer, nbuffer)
Allocates an SCF DIIS buffer 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 qs_diis_b_check_i_alloc_kp(diis_buffer, matrix_struct, nspin, nkp, scf_section)
Allocate and initialize a DIIS buffer for nao*nao parameter variables and with a buffer size of nbuff...
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, matrix_vhxc, 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.
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, cmo_coeff)
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.
Represent a complex full matrix.
keeps the information about the structure of a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment
build arrau of pointers to diis buffers in the k-point (complex full matrices) case
build array of pointers to diis buffers for sparse matrix case
keeps a buffer with the previous values of s,p,k