72#include "./base/base_uses.f90"
78 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_diis'
108 INTEGER,
INTENT(in) :: nbuffer
110 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_diis_b_create'
116 CALL timeset(routinen, handle)
118 NULLIFY (diis_buffer%b_matrix)
119 NULLIFY (diis_buffer%error)
120 NULLIFY (diis_buffer%param)
121 diis_buffer%nbuffer = nbuffer
122 diis_buffer%ncall = 0
124 CALL timestop(handle)
143 SUBROUTINE qs_diis_b_check_i_alloc(diis_buffer, matrix_struct, nspin, &
148 INTEGER,
INTENT(IN) :: nspin
151 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_check_i_alloc'
153 INTEGER :: handle, ibuffer, ispin, nbuffer, &
159 CALL timeset(routinen, handle)
163 nbuffer = diis_buffer%nbuffer
165 IF (.NOT.
ASSOCIATED(diis_buffer%error))
THEN
166 ALLOCATE (diis_buffer%error(nbuffer, nspin))
169 DO ibuffer = 1, nbuffer
171 name=
"qs_diis_b%error("// &
174 matrix_struct=matrix_struct)
179 IF (.NOT.
ASSOCIATED(diis_buffer%param))
THEN
180 ALLOCATE (diis_buffer%param(nbuffer, nspin))
183 DO ibuffer = 1, nbuffer
185 name=
"qs_diis_b%param("// &
188 matrix_struct=matrix_struct)
193 IF (.NOT.
ASSOCIATED(diis_buffer%b_matrix))
THEN
194 ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
195 diis_buffer%b_matrix = 0.0_dp
198 IF (output_unit > 0)
THEN
199 WRITE (unit=output_unit, fmt=
"(/,T9,A)") &
200 "DIIS | The SCF DIIS buffer was allocated and initialized"
206 CALL timestop(handle)
208 END SUBROUTINE qs_diis_b_check_i_alloc
232 diis_step, eps_diis, nmixing, s_matrix, scf_section, roks)
235 TYPE(
mo_set_type),
DIMENSION(:),
INTENT(IN) :: mo_array
238 REAL(kind=
dp),
INTENT(IN) :: delta
239 REAL(kind=
dp),
INTENT(OUT) :: error_max
240 LOGICAL,
INTENT(OUT) :: diis_step
241 REAL(kind=
dp),
INTENT(IN) :: eps_diis
242 INTEGER,
INTENT(IN),
OPTIONAL :: nmixing
246 LOGICAL,
INTENT(IN),
OPTIONAL :: roks
248 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_step'
249 REAL(kind=
dp),
PARAMETER :: eigenvalue_threshold = 1.0e-12_dp
251 CHARACTER(LEN=2*default_string_length) :: message
252 INTEGER :: handle, homo, ib, imo, ispin, jb, &
253 my_nmixing, nao, nb, nb1, nmo, nspin, &
255 LOGICAL :: eigenvectors_discarded, my_roks
256 REAL(kind=
dp) :: maxocc, tmp
257 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: ev, occ, traces
258 REAL(kind=
dp),
DIMENSION(:),
POINTER :: occa, occb
259 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b
261 TYPE(
cp_fm_type),
POINTER :: c, new_errors, parameters
266 CALL timeset(routinen, handle)
268 nspin =
SIZE(mo_array)
271 IF (
PRESENT(roks))
THEN
279 IF (
PRESENT(nmixing)) my_nmixing = nmixing
281 NULLIFY (c, new_errors, parameters, matrix_struct, a, b, occa, occb)
286 IF (diis_buffer%nbuffer < 1)
THEN
287 CALL timestop(handle)
292 matrix_struct=matrix_struct)
293 CALL qs_diis_b_check_i_alloc(diis_buffer, &
294 matrix_struct=matrix_struct, &
296 scf_section=scf_section)
300 ib =
modulo(diis_buffer%ncall, diis_buffer%nbuffer) + 1
301 diis_buffer%ncall = diis_buffer%ncall + 1
302 nb = min(diis_buffer%ncall, diis_buffer%nbuffer)
304 IF (
PRESENT(s_matrix))
THEN
305 IF (.NOT.
ALLOCATED(diis_buffer%overlap_copy_plan))
ALLOCATE (diis_buffer%overlap_copy_plan)
315 occupation_numbers=occa, &
318 new_errors => diis_buffer%error(ib, ispin)
319 parameters => diis_buffer%param(ib, ispin)
330 occupation_numbers=occb)
333 occ(imo) = sqrt(occa(imo) + occb(imo))
340 CALL cp_fm_symm(
"L",
"U", nao, homo, 1.0_dp, parameters, sc, 0.0_dp, kc(ispin))
342 IF (
PRESENT(s_matrix))
THEN
343 CALL copy_dbcsr_to_fm(s_matrix(1)%matrix, new_errors, diis_buffer%overlap_copy_plan, check_plan=.true.)
345 CALL cp_fm_symm(
"L",
"U", nao, homo, 1.0_dp, new_errors, c, 0.0_dp, sc)
352 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, sc, kc(ispin), 0.0_dp, new_errors)
353 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, kc(ispin), sc, -1.0_dp, new_errors)
360 CALL cp_fm_symm(
"L",
"U", nao, homo, maxocc, parameters, c, 0.0_dp, kc(ispin))
362 IF (
PRESENT(s_matrix))
THEN
364 CALL copy_dbcsr_to_fm(s_matrix(1)%matrix, new_errors, diis_buffer%overlap_copy_plan, check_plan=.true.)
366 CALL cp_fm_symm(
"L",
"U", nao, homo, 2.0_dp, new_errors, c, 0.0_dp, sc)
368 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, sc, kc(ispin), 0.0_dp, new_errors)
369 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, kc(ispin), sc, -1.0_dp, new_errors)
372 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, c, kc(ispin), 0.0_dp, new_errors)
373 CALL parallel_gemm(
"N",
"T", nao, nao, homo, 1.0_dp, kc(ispin), c, -1.0_dp, new_errors)
379 error_max = max(error_max, tmp)
385 diis_step = ((diis_buffer%ncall >= my_nmixing) .AND. (delta < eps_diis))
389 IF (output_unit > 0)
THEN
390 WRITE (unit=output_unit, fmt=
"(/,T9,A,I4,/,(T9,A,ES12.3))") &
391 "DIIS | Current SCF DIIS buffer size: ", nb, &
392 "DIIS | Maximum SCF DIIS error vector element:", error_max, &
393 "DIIS | Current SCF convergence: ", delta, &
394 "DIIS | Threshold value for a DIIS step: ", eps_diis
395 IF (error_max < eps_diis)
THEN
396 WRITE (unit=output_unit, fmt=
"(T9,A)") &
397 "DIIS | => The SCF DIIS buffer will be updated"
399 WRITE (unit=output_unit, fmt=
"(T9,A)") &
400 "DIIS | => No update of the SCF DIIS buffer"
402 IF (diis_step .AND. (error_max < eps_diis))
THEN
403 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
404 "DIIS | => A SCF DIIS step will be performed"
406 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
407 "DIIS | => No SCF DIIS step will be performed"
413 IF (error_max < eps_diis)
THEN
415 b => diis_buffer%b_matrix
417 ALLOCATE (traces(nb))
422 CALL cp_fm_trace(diis_buffer%error(1, ispin), diis_buffer%error(ib, ispin), traces(1))
424 CALL cp_fm_trace(diis_buffer%error(1:nb, ispin), diis_buffer%error(ib, ispin), traces)
426 b(1:nb, ib) = b(1:nb, ib) + traces(:)
431 b(ib, jb) = b(jb, ib)
446 ALLOCATE (a(nb1, nb1))
447 ALLOCATE (b(nb1, nb1))
452 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
454 b(1:nb, nb1) = -1.0_dp
455 b(nb1, 1:nb) = -1.0_dp
463 a(1:nb1, 1:nb1) = b(1:nb1, 1:nb1)
465 eigenvectors_discarded = .false.
468 IF (abs(ev(jb)) < eigenvalue_threshold)
THEN
469 IF (output_unit > 0)
THEN
470 IF (.NOT. eigenvectors_discarded)
THEN
471 WRITE (unit=output_unit, fmt=
"(T9,A)") &
472 "DIIS | Checking eigenvalues of the DIIS error matrix"
474 WRITE (unit=message, fmt=
"(T9,A,I6,A,ES10.1,A,ES10.1)") &
475 "DIIS | Eigenvalue ", jb,
" = ", ev(jb),
" is smaller than "// &
476 "threshold ", eigenvalue_threshold
478 WRITE (unit=output_unit, fmt=
"(T9,A)") trim(message)
479 eigenvectors_discarded = .true.
481 a(1:nb1, jb) = 0.0_dp
483 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
487 IF ((output_unit > 0) .AND. eigenvectors_discarded)
THEN
488 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
489 "DIIS | The corresponding eigenvectors were discarded"
492 ev(1:nb) = matmul(a(1:nb, 1:nb1), b(nb1, 1:nb1))
499 parameters => diis_buffer%param(jb, ispin)
511 parameters => diis_buffer%param(ib, ispin)
520 CALL timestop(handle)
535 diis_buffer%ncall = 0
558 diis_step, eps_diis, nmixing, s_matrix, threshold)
565 INTEGER,
INTENT(IN) :: unit_nr, iscf
566 LOGICAL,
INTENT(OUT) :: diis_step
567 REAL(kind=
dp),
INTENT(IN) :: eps_diis
568 INTEGER,
INTENT(IN),
OPTIONAL :: nmixing
570 REAL(kind=
dp),
INTENT(IN) :: threshold
572 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_step_4lscf'
573 REAL(kind=
dp),
PARAMETER :: eigenvalue_threshold = 1.0e-12_dp
575 INTEGER :: handle, ib, ispin, jb, my_nmixing, nb, &
577 REAL(kind=
dp) :: error_max, tmp
578 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: ev
579 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: a, b
582 TYPE(
dbcsr_type) :: matrix_kserr_t, matrix_tmp
583 TYPE(
dbcsr_type),
POINTER :: new_errors, old_errors, parameters
586 CALL timeset(routinen, handle)
587 IF (ls_scf_env%do_pao)
THEN
588 cpabort(
"LS_SCF%LS_DIIS not compatible with PAO")
590 nspin = ls_scf_env%nspins
593 IF (
PRESENT(nmixing)) my_nmixing = nmixing
594 NULLIFY (new_errors, old_errors, parameters, a, b)
597 IF (diis_buffer%nbuffer < 1)
THEN
598 CALL timestop(handle)
606 CALL qs_diis_b_check_i_alloc_sparse( &
612 ib =
modulo(diis_buffer%ncall, diis_buffer%nbuffer) + 1
613 diis_buffer%ncall = diis_buffer%ncall + 1
614 nb = min(diis_buffer%ncall, diis_buffer%nbuffer)
617 template=ls_scf_env%matrix_ks(1), &
621 template=ls_scf_env%matrix_ks(1), &
627 new_errors => diis_buffer%error(ib, ispin)%matrix
628 parameters => diis_buffer%param(ib, ispin)%matrix
631 matrix_ks(ispin)%matrix)
633 IF (
PRESENT(s_matrix))
THEN
637 1.0_dp, ls_scf_env%matrix_p(ispin), &
639 0.0_dp, matrix_tmp, &
640 filter_eps=threshold)
643 1.0_dp, matrix_ks(ispin)%matrix, &
645 0.0_dp, new_errors, &
646 filter_eps=threshold)
658 1.0_dp, matrix_ks(ispin)%matrix, &
659 ls_scf_env%matrix_p(ispin), &
660 0.0_dp, new_errors, &
661 filter_eps=threshold)
672 error_max = max(error_max, tmp)
678 diis_step = (diis_buffer%ncall >= my_nmixing)
680 IF (unit_nr > 0)
THEN
681 WRITE (unit_nr,
'(A29,I3,A3,4(I3,A1))') &
682 "DIIS: (ncall,nbuffer,ib,nb)=(", iscf,
")=(", &
683 diis_buffer%ncall,
",", diis_buffer%nbuffer,
",", ib,
",", nb,
")"
684 WRITE (unit_nr,
'(A57,I3,A3,L1,A1,F10.8,A1,F4.2,A1,L1,A1)') &
685 "DIIS: (diis_step,error_max,eps_diis,error_max<eps_diis)=(", &
686 iscf,
")=(", diis_step,
",", error_max,
",", eps_diis,
",", &
687 (error_max < eps_diis),
")"
688 WRITE (unit_nr,
'(A75)') &
689 "DIIS: diis_step=T : Perform DIIS error_max<eps_diis=T : Update DIIS buffer"
693 IF (error_max < eps_diis)
THEN
694 b => diis_buffer%b_matrix
698 old_errors => diis_buffer%error(jb, ispin)%matrix
699 new_errors => diis_buffer%error(ib, ispin)%matrix
703 b(jb, ib) = b(jb, ib) + tmp
705 b(ib, jb) = b(jb, ib)
714 ALLOCATE (a(nb1, nb1))
715 ALLOCATE (b(nb1, nb1))
718 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
719 b(1:nb, nb1) = -1.0_dp
720 b(nb1, 1:nb) = -1.0_dp
724 a(1:nb1, 1:nb1) = b(1:nb1, 1:nb1)
726 IF (abs(ev(jb)) < eigenvalue_threshold)
THEN
727 a(1:nb1, jb) = 0.0_dp
729 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
733 ev(1:nb) = matmul(a(1:nb, 1:nb1), b(nb1, 1:nb1))
736 IF (iscf >= ls_scf_env%iter_ini_diis)
THEN
738 IF (unit_nr > 0)
THEN
739 WRITE (unit_nr,
'(A40,I3)')
'DIIS: Updating Kohn-Sham matrix at iscf=', iscf
743 CALL dbcsr_set(matrix_ks(ispin)%matrix, &
746 parameters => diis_buffer%param(jb, ispin)%matrix
747 CALL dbcsr_add(matrix_ks(ispin)%matrix, parameters, &
759 parameters => diis_buffer%param(ib, ispin)%matrix
761 matrix_ks(ispin)%matrix)
766 CALL timestop(handle)
783 SUBROUTINE qs_diis_b_check_i_alloc_sparse(diis_buffer, ls_scf_env, &
788 INTEGER,
INTENT(IN) :: nspin
790 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_check_i_alloc_sparse'
792 INTEGER :: handle, ibuffer, ispin, nbuffer
797 CALL timeset(routinen, handle)
801 nbuffer = diis_buffer%nbuffer
803 IF (.NOT.
ASSOCIATED(diis_buffer%error))
THEN
804 ALLOCATE (diis_buffer%error(nbuffer, nspin))
807 DO ibuffer = 1, nbuffer
808 ALLOCATE (diis_buffer%error(ibuffer, ispin)%matrix)
810 CALL dbcsr_create(diis_buffer%error(ibuffer, ispin)%matrix, &
811 template=ls_scf_env%matrix_ks(1), &
817 IF (.NOT.
ASSOCIATED(diis_buffer%param))
THEN
818 ALLOCATE (diis_buffer%param(nbuffer, nspin))
821 DO ibuffer = 1, nbuffer
822 ALLOCATE (diis_buffer%param(ibuffer, ispin)%matrix)
823 CALL dbcsr_create(diis_buffer%param(ibuffer, ispin)%matrix, &
824 template=ls_scf_env%matrix_ks(1), &
830 IF (.NOT.
ASSOCIATED(diis_buffer%b_matrix))
THEN
831 ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
833 diis_buffer%b_matrix = 0.0_dp
836 CALL timestop(handle)
838 END SUBROUTINE qs_diis_b_check_i_alloc_sparse
852 diis_buffer%ncall = 0
867 INTEGER,
INTENT(in) :: nbuffer
869 NULLIFY (diis_buffer%b_matrix)
870 NULLIFY (diis_buffer%error)
871 NULLIFY (diis_buffer%param)
872 diis_buffer%nbuffer = nbuffer
873 diis_buffer%ncall = 0
885 INTEGER,
INTENT(in) :: nbuffer
887 NULLIFY (diis_buffer%b_matrix)
888 NULLIFY (diis_buffer%error)
889 NULLIFY (diis_buffer%param)
890 NULLIFY (diis_buffer%smat)
891 diis_buffer%nbuffer = nbuffer
892 diis_buffer%ncall = 0
909 INTEGER,
INTENT(IN) :: nspin, nkp
912 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_check_i_alloc_kp'
914 INTEGER :: handle, ibuffer, ikp, ispin, nbuffer, &
920 CALL timeset(routinen, handle)
924 nbuffer = diis_buffer%nbuffer
926 IF (.NOT.
ASSOCIATED(diis_buffer%error))
THEN
927 ALLOCATE (diis_buffer%error(nbuffer, nspin, nkp))
931 DO ibuffer = 1, nbuffer
933 name=
"qs_diis_b%error("// &
936 matrix_struct=matrix_struct)
942 IF (.NOT.
ASSOCIATED(diis_buffer%param))
THEN
943 ALLOCATE (diis_buffer%param(nbuffer, nspin, nkp))
947 DO ibuffer = 1, nbuffer
949 name=
"qs_diis_b%param("// &
952 matrix_struct=matrix_struct)
958 IF (.NOT.
ASSOCIATED(diis_buffer%smat))
THEN
959 ALLOCATE (diis_buffer%smat(nkp))
963 matrix_struct=matrix_struct)
967 IF (.NOT.
ASSOCIATED(diis_buffer%b_matrix))
THEN
968 ALLOCATE (diis_buffer%b_matrix(nbuffer + 1, nbuffer + 1))
969 diis_buffer%b_matrix = 0.0_dp
972 IF (output_unit > 0)
THEN
973 WRITE (unit=output_unit, fmt=
"(/,T9,A)") &
974 "DIIS | The SCF DIIS buffer was allocated and initialized"
980 CALL timestop(handle)
992 diis_buffer%ncall = 0
1004 INTEGER,
INTENT(OUT) :: ib, nb
1006 ib =
modulo(diis_buffer%ncall, diis_buffer%nbuffer) + 1
1007 diis_buffer%ncall = diis_buffer%ncall + 1
1008 nb = min(diis_buffer%ncall, diis_buffer%nbuffer)
1028 SUBROUTINE qs_diis_b_calc_err_kp(diis_buffer, ib, mos, kc, sc, ispin, ikp, cmos, real_wfn, local, gemm_ctx)
1030 INTEGER,
INTENT(IN) :: ib
1033 INTEGER,
INTENT(IN) :: ispin, ikp
1035 LOGICAL,
INTENT(IN),
OPTIONAL :: real_wfn, local
1038 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_calc_err_kp'
1040 INTEGER :: handle, homo, nao
1041 LOGICAL :: my_real_wfn
1043 TYPE(
cp_cfm_type),
POINTER :: new_errors, parameters, smat
1046 NULLIFY (rmos, parameters, new_errors, smat)
1048 CALL timeset(routinen, handle)
1049 my_real_wfn = .false.
1050 IF (
PRESENT(real_wfn)) my_real_wfn = real_wfn
1056 IF (diis_buffer%nbuffer < 1)
THEN
1057 CALL timestop(handle)
1060 CALL get_mo_set(mos(ispin), nao=nao, homo=homo, maxocc=maxocc)
1062 IF (my_real_wfn)
THEN
1065 cmplx(1.0_dp, kind=
dp), rmos)
1070 new_errors => diis_buffer%error(ib, ispin, ikp)
1071 parameters => diis_buffer%param(ib, ispin, ikp)
1072 smat => diis_buffer%smat(ikp)
1081 cpassert(product(parameters%matrix_struct%context%num_pe) == 1)
1082 cpassert(product(cmos%matrix_struct%context%num_pe) == 1)
1083 cpassert(product(kc%matrix_struct%context%num_pe) == 1)
1084 cpassert(product(smat%matrix_struct%context%num_pe) == 1)
1085 cpassert(product(sc%matrix_struct%context%num_pe) == 1)
1086 cpassert(product(new_errors%matrix_struct%context%num_pe) == 1)
1087 CALL gemm_ctx%gemm(
"N",
"N", nao, homo, nao, cmplx(maxocc, kind=
dp), &
1088 parameters%local_data,
SIZE(parameters%local_data, 1), &
1089 cmos%local_data,
SIZE(cmos%local_data, 1), (0.0_dp, 0.0_dp), &
1090 kc%local_data,
SIZE(kc%local_data, 1))
1091 CALL gemm_ctx%gemm(
"N",
"N", nao, homo, nao, (2.0_dp, 0.0_dp), &
1092 smat%local_data,
SIZE(smat%local_data, 1), &
1093 cmos%local_data,
SIZE(cmos%local_data, 1), (0.0_dp, 0.0_dp), &
1094 sc%local_data,
SIZE(sc%local_data, 1))
1095 CALL gemm_ctx%gemm(
"N",
"C", nao, nao, homo, (1.0_dp, 0.0_dp), &
1096 sc%local_data,
SIZE(sc%local_data, 1), &
1097 kc%local_data,
SIZE(kc%local_data, 1), (0.0_dp, 0.0_dp), &
1098 new_errors%local_data,
SIZE(new_errors%local_data, 1))
1099 CALL gemm_ctx%gemm(
"N",
"C", nao, nao, homo, (1.0_dp, 0.0_dp), &
1100 kc%local_data,
SIZE(kc%local_data, 1), &
1101 sc%local_data,
SIZE(sc%local_data, 1), (-1.0_dp, 0.0_dp), &
1102 new_errors%local_data,
SIZE(new_errors%local_data, 1))
1104 CALL parallel_gemm(
"N",
"N", nao, homo, nao, cmplx(maxocc, kind=
dp), parameters, cmos, (0.0_dp, 0.0_dp), kc)
1105 CALL parallel_gemm(
"N",
"N", nao, homo, nao, (2.0_dp, 0.0_dp), smat, cmos, (0.0_dp, 0.0_dp), sc)
1106 CALL parallel_gemm(
"N",
"C", nao, nao, homo, (1.0_dp, 0.0_dp), sc, kc, (0.0_dp, 0.0_dp), new_errors)
1107 CALL parallel_gemm(
"N",
"C", nao, nao, homo, (1.0_dp, 0.0_dp), kc, sc, (-1.0_dp, 0.0_dp), new_errors)
1110 CALL timestop(handle)
1132 nspin, nkp, nkp_local, nmixing, scf_section, para_env_inter_kp)
1135 COMPLEX(KIND=dp),
DIMENSION(:),
INTENT(INOUT) :: coeffs
1136 INTEGER,
INTENT(IN) :: ib, nb
1137 REAL(kind=
dp),
INTENT(IN) :: delta
1138 REAL(kind=
dp),
INTENT(OUT) :: error_max
1139 LOGICAL,
INTENT(OUT) :: diis_step
1140 REAL(kind=
dp),
INTENT(IN) :: eps_diis
1141 INTEGER,
INTENT(IN) :: nspin, nkp, nkp_local
1142 INTEGER,
INTENT(IN),
OPTIONAL :: nmixing
1146 CHARACTER(LEN=*),
PARAMETER :: routinen =
'qs_diis_b_step_kp'
1147 REAL(kind=
dp),
PARAMETER :: eigenvalue_threshold = 1.0e-12_dp
1149 CHARACTER(LEN=2*default_string_length) :: message
1150 COMPLEX(KIND=dp) :: tmp
1151 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :) :: a, b
1152 INTEGER :: handle, ikp, ispin, jb, my_nmixing, nb1, &
1154 LOGICAL :: eigenvectors_discarded
1155 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: ev
1162 NULLIFY (matrix_struct, new_errors, logger)
1164 CALL timeset(routinen, handle)
1169 IF (
PRESENT(nmixing)) my_nmixing = nmixing
1174 IF (diis_buffer%nbuffer < 1)
THEN
1175 CALL timestop(handle)
1180 diis_step = ((diis_buffer%ncall >= my_nmixing) .AND. (delta < eps_diis))
1183 CALL cp_cfm_get_info(diis_buffer%error(ib, 1, 1), matrix_struct=matrix_struct)
1187 ALLOCATE (b(nb, nb))
1190 DO ikp = 1, nkp_local
1192 new_errors => diis_buffer%error(ib, ispin, ikp)
1193 CALL cp_cfm_to_fm(diis_buffer%error(jb, ispin, ikp), rerr, ierr)
1197 b(jb, ib) = b(jb, ib) + 1.0_dp/real(nkp,
dp)*tmp
1200 b(ib, jb) = conjg(b(jb, ib))
1208 CALL para_env_inter_kp%sum(b)
1210 error_max = sqrt(real(b(ib, ib))**2 + aimag(b(ib, ib))**2)
1213 extension=
".scfLog")
1214 IF (output_unit > 0)
THEN
1215 WRITE (unit=output_unit, fmt=
"(/,T9,A,I4,/,(T9,A,ES12.3))") &
1216 "DIIS | Current SCF DIIS buffer size: ", nb, &
1217 "DIIS | Maximum SCF DIIS error at last step: ", error_max, &
1218 "DIIS | Current SCF convergence: ", delta, &
1219 "DIIS | Threshold value for a DIIS step: ", eps_diis
1220 IF (error_max < eps_diis)
THEN
1221 WRITE (unit=output_unit, fmt=
"(T9,A)") &
1222 "DIIS | => The SCF DIIS buffer will be updated"
1224 WRITE (unit=output_unit, fmt=
"(T9,A)") &
1225 "DIIS | => No update of the SCF DIIS buffer"
1227 IF (diis_step .AND. (error_max < eps_diis))
THEN
1228 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
1229 "DIIS | => A SCF DIIS step will be performed"
1231 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
1232 "DIIS | => No SCF DIIS step will be performed"
1237 IF (error_max < eps_diis)
THEN
1239 diis_buffer%b_matrix(ib, jb) = b(ib, jb)
1240 diis_buffer%b_matrix(jb, ib) = b(jb, ib)
1253 ALLOCATE (a(nb1, nb1))
1254 ALLOCATE (b(nb1, nb1))
1258 b(1:nb, 1:nb) = diis_buffer%b_matrix(1:nb, 1:nb)
1260 b(1:nb, nb1) = -1.0_dp
1261 b(nb1, 1:nb) = -1.0_dp
1262 b(nb1, nb1) = 0.0_dp
1266 a(1:nb1, 1:nb1) = 0.0_dp
1267 CALL diag_complex(b(1:nb1, 1:nb1), a(1:nb1, 1:nb1), ev(1:nb1))
1268 b(1:nb1, 1:nb1) = a(1:nb1, 1:nb1)
1270 eigenvectors_discarded = .false.
1273 IF (abs(ev(jb)) < eigenvalue_threshold)
THEN
1274 IF (output_unit > 0)
THEN
1275 IF (.NOT. eigenvectors_discarded)
THEN
1276 WRITE (unit=output_unit, fmt=
"(T9,A)") &
1277 "DIIS | Checking eigenvalues of the DIIS error matrix"
1279 WRITE (unit=message, fmt=
"(T9,A,I6,A,ES10.1,A,ES10.1)") &
1280 "DIIS | Eigenvalue ", jb,
" = ", ev(jb),
" is smaller than "// &
1281 "threshold ", eigenvalue_threshold
1283 WRITE (unit=output_unit, fmt=
"(T9,A)") trim(message)
1284 eigenvectors_discarded = .true.
1286 a(1:nb1, jb) = 0.0_dp
1288 a(1:nb1, jb) = a(1:nb1, jb)/ev(jb)
1292 IF ((output_unit > 0) .AND. eigenvectors_discarded)
THEN
1293 WRITE (unit=output_unit, fmt=
"(T9,A,/)") &
1294 "DIIS | The corresponding eigenvectors were discarded"
1297 coeffs(1:nb) = -matmul(a(1:nb, 1:nb1), conjg(b(nb1, 1:nb1)))
1307 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)
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_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_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 cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
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_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, 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...
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 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