62#include "./base/base_uses.f90"
68 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'almo_scf_methods'
115 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_ks_to_ks_xx'
117 INTEGER :: handle, ispin, ndomains
118 REAL(kind=
dp) :: eps_multiply
119 TYPE(
dbcsr_type) :: matrix_tmp1, matrix_tmp2, matrix_tmp3, matrix_tmp4, matrix_tmp5, &
120 matrix_tmp6, matrix_tmp7, matrix_tmp8, matrix_tmp9
122 DIMENSION(:) :: subm_tmp1, subm_tmp2, subm_tmp3
124 CALL timeset(routinen, handle)
126 eps_multiply = almo_scf_env%eps_filter
128 DO ispin = 1, almo_scf_env%nspins
130 CALL dbcsr_get_info(almo_scf_env%quench_t(ispin), nblkcols_total=ndomains)
134 almo_scf_env%matrix_ks(ispin), &
135 almo_scf_env%domain_ks_xx(:, ispin), &
136 almo_scf_env%quench_t(ispin), &
137 almo_scf_env%domain_map(ispin), &
138 almo_scf_env%cpu_of_domain, &
148 template=almo_scf_env%matrix_t(ispin))
149 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_ks(ispin), &
150 almo_scf_env%matrix_t(ispin), &
151 0.0_dp, matrix_tmp1, &
152 filter_eps=eps_multiply)
158 template=almo_scf_env%matrix_t(ispin))
160 almo_scf_env%matrix_sigma_inv(ispin), &
161 0.0_dp, matrix_tmp2, &
162 filter_eps=eps_multiply)
167 almo_scf_env%matrix_t(ispin), &
168 0.0_dp, matrix_tmp1, &
169 filter_eps=eps_multiply)
175 template=almo_scf_env%matrix_s(1), &
176 matrix_type=dbcsr_type_no_symmetry)
179 0.0_dp, matrix_tmp4, &
180 filter_eps=eps_multiply)
183 ALLOCATE (subm_tmp1(ndomains))
188 almo_scf_env%quench_t(ispin), &
189 almo_scf_env%domain_map(ispin), &
190 almo_scf_env%cpu_of_domain, &
193 -1.0_dp, subm_tmp1,
'N')
195 -1.0_dp, subm_tmp1,
'T')
201 template=almo_scf_env%matrix_t(ispin), &
202 matrix_type=dbcsr_type_no_symmetry)
205 almo_scf_env%matrix_t(ispin), &
206 0.0_dp, matrix_tmp3, &
207 filter_eps=eps_multiply)
214 template=almo_scf_env%matrix_t(ispin), &
215 matrix_type=dbcsr_type_no_symmetry)
218 almo_scf_env%matrix_sigma_inv(ispin), &
219 0.0_dp, matrix_tmp6, &
220 filter_eps=eps_multiply)
225 CALL dbcsr_copy(almo_scf_env%matrix_err_xx(ispin), &
226 almo_scf_env%quench_t(ispin))
227 CALL dbcsr_copy(almo_scf_env%matrix_err_xx(ispin), &
228 matrix_tmp2, keep_sparsity=.true.)
230 template=almo_scf_env%matrix_t(ispin), &
231 matrix_type=dbcsr_type_no_symmetry)
233 almo_scf_env%quench_t(ispin))
235 matrix_tmp6, keep_sparsity=.true.)
236 CALL dbcsr_add(almo_scf_env%matrix_err_xx(ispin), &
237 matrix_tmp4, 1.0_dp, -1.0_dp)
247 matrix_tmp6, 1.0_dp, -1.0_dp)
249 template=almo_scf_env%matrix_s(1), &
250 matrix_type=dbcsr_type_no_symmetry)
253 almo_scf_env%matrix_t(ispin), &
254 0.0_dp, matrix_tmp4, &
255 filter_eps=eps_multiply)
258 almo_scf_env%domain_err(:, ispin), &
259 almo_scf_env%quench_t(ispin), &
260 almo_scf_env%domain_map(ispin), &
261 almo_scf_env%cpu_of_domain, &
266 ALLOCATE (subm_tmp2(ndomains))
269 almo_scf_env%domain_err(:, ispin), &
270 almo_scf_env%domain_s_sqrt(:, ispin), 0.0_dp, subm_tmp2)
272 almo_scf_env%domain_s_sqrt_inv(:, ispin), &
273 subm_tmp2, 0.0_dp, almo_scf_env%domain_err(:, ispin))
282 template=almo_scf_env%matrix_s(1), &
283 matrix_type=dbcsr_type_no_symmetry)
287 0.0_dp, matrix_tmp5, &
288 filter_eps=eps_multiply)
294 almo_scf_env%quench_t(ispin), &
295 almo_scf_env%domain_map(ispin), &
296 almo_scf_env%cpu_of_domain, &
300 1.0_dp, subm_tmp1,
'N')
303 ALLOCATE (subm_tmp3(ndomains))
308 almo_scf_env%quench_t(ispin), &
309 almo_scf_env%domain_map(ispin), &
310 almo_scf_env%cpu_of_domain, &
315 almo_scf_env%quench_t(ispin), &
316 almo_scf_env%domain_map(ispin), &
317 almo_scf_env%cpu_of_domain, &
321 -1.0_dp, subm_tmp3,
'N')
325 almo_scf_env%quench_t(ispin), &
326 almo_scf_env%domain_map(ispin), &
327 almo_scf_env%cpu_of_domain, &
330 subm_tmp3, 0.0_dp, subm_tmp1)
332 1.0_dp, subm_tmp1,
'N')
334 1.0_dp, subm_tmp1,
'T')
338 template=almo_scf_env%matrix_sigma_blk(ispin), &
339 matrix_type=dbcsr_type_no_symmetry)
341 almo_scf_env%matrix_t(ispin), &
343 0.0_dp, matrix_tmp7, &
344 filter_eps=eps_multiply)
348 template=almo_scf_env%matrix_sigma_blk(ispin), &
349 matrix_type=dbcsr_type_symmetric)
350 CALL dbcsr_copy(matrix_tmp8, almo_scf_env%matrix_sigma_blk(ispin))
352 almo_scf_env%matrix_sigma_inv(ispin), &
354 0.0_dp, matrix_tmp8, &
355 retain_sparsity=.true., &
356 filter_eps=eps_multiply)
361 template=almo_scf_env%matrix_t(ispin), &
362 matrix_type=dbcsr_type_no_symmetry)
363 CALL dbcsr_copy(matrix_tmp9, almo_scf_env%quench_t(ispin))
364 CALL dbcsr_copy(matrix_tmp9, matrix_tmp1, keep_sparsity=.true.)
370 0.0_dp, matrix_tmp3, &
371 filter_eps=eps_multiply)
379 almo_scf_env%quench_t(ispin), &
380 almo_scf_env%domain_map(ispin), &
381 almo_scf_env%cpu_of_domain, &
384 subm_tmp3, 0.0_dp, subm_tmp1)
386 1.0_dp, subm_tmp1,
'N')
435 DEALLOCATE (subm_tmp3)
436 DEALLOCATE (subm_tmp2)
437 DEALLOCATE (subm_tmp1)
444 CALL timestop(handle)
460 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_ks_to_ks_blk'
462 INTEGER :: handle, ispin
463 REAL(kind=
dp) :: eps_multiply
464 TYPE(
dbcsr_type) :: matrix_tmp1, matrix_tmp2, matrix_tmp3, matrix_tmp4, matrix_tmp5, &
465 matrix_tmp6, matrix_tmp7, matrix_tmp8, matrix_tmp9, matrix_tmp_err
467 CALL timeset(routinen, handle)
469 eps_multiply = almo_scf_env%eps_filter
471 DO ispin = 1, almo_scf_env%nspins
477 template=almo_scf_env%matrix_t(ispin))
478 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_ks(ispin), &
479 almo_scf_env%matrix_t_blk(ispin), &
480 0.0_dp, matrix_tmp1, &
481 filter_eps=eps_multiply)
486 template=almo_scf_env%matrix_t(ispin))
488 almo_scf_env%matrix_sigma_inv(ispin), &
489 0.0_dp, matrix_tmp2, &
490 filter_eps=eps_multiply)
503 almo_scf_env%matrix_t_blk(ispin), &
504 0.0_dp, matrix_tmp1, &
505 filter_eps=eps_multiply)
511 template=almo_scf_env%matrix_s_blk(1), &
512 matrix_type=dbcsr_type_no_symmetry)
513 CALL dbcsr_copy(matrix_tmp4, almo_scf_env%matrix_s_blk(1))
516 0.0_dp, matrix_tmp4, &
517 retain_sparsity=.true., &
518 filter_eps=eps_multiply)
521 CALL dbcsr_copy(almo_scf_env%matrix_ks_blk(ispin), &
522 almo_scf_env%matrix_ks(ispin), keep_sparsity=.true.)
523 CALL dbcsr_add(almo_scf_env%matrix_ks_blk(ispin), &
531 template=almo_scf_env%matrix_s_blk(1), &
532 matrix_type=dbcsr_type_no_symmetry)
534 CALL dbcsr_add(almo_scf_env%matrix_ks_blk(ispin), matrix_tmp5, &
541 template=almo_scf_env%matrix_sigma_inv(ispin), &
542 matrix_type=dbcsr_type_no_symmetry)
544 almo_scf_env%matrix_t_blk(ispin), &
546 0.0_dp, matrix_tmp3, &
547 filter_eps=eps_multiply)
553 template=almo_scf_env%matrix_sigma_inv(ispin), &
554 matrix_type=dbcsr_type_no_symmetry)
556 almo_scf_env%matrix_sigma_inv(ispin), &
558 0.0_dp, matrix_tmp6, &
559 filter_eps=eps_multiply)
566 template=almo_scf_env%matrix_t(ispin))
569 0.0_dp, matrix_tmp3, &
570 filter_eps=eps_multiply)
587 cpassert(almo_scf_env%almo_update_algorithm ==
almo_scf_diag)
590 template=almo_scf_env%matrix_t_blk(ispin))
593 CALL dbcsr_add(matrix_tmp_err, matrix_tmp3, &
596 CALL dbcsr_copy(almo_scf_env%matrix_err_blk(ispin), &
597 almo_scf_env%matrix_s_blk_sqrt(1))
599 almo_scf_env%matrix_t_blk(ispin), &
600 0.0_dp, almo_scf_env%matrix_err_blk(ispin), &
601 retain_sparsity=.true., &
602 filter_eps=eps_multiply)
607 template=almo_scf_env%matrix_err_blk(ispin))
609 almo_scf_env%matrix_err_blk(ispin), &
610 almo_scf_env%matrix_s_blk_sqrt(1), &
611 0.0_dp, matrix_tmp_err, &
612 filter_eps=eps_multiply)
614 almo_scf_env%matrix_s_blk_sqrt_inv(1), &
616 0.0_dp, almo_scf_env%matrix_err_blk(ispin), &
617 filter_eps=eps_multiply)
621 almo_scf_env%matrix_err_blk(ispin))
622 CALL dbcsr_add(almo_scf_env%matrix_err_blk(ispin), &
634 template=almo_scf_env%matrix_sigma_blk(ispin), &
635 matrix_type=dbcsr_type_no_symmetry)
636 CALL dbcsr_copy(matrix_tmp9, almo_scf_env%matrix_sigma_blk(ispin))
637 CALL dbcsr_copy(matrix_tmp9, matrix_tmp6, keep_sparsity=.true.)
645 1.0_dp, almo_scf_env%matrix_ks_blk(ispin), &
646 retain_sparsity=.true., &
647 filter_eps=eps_multiply)
658 template=almo_scf_env%matrix_t_blk(ispin))
662 CALL dbcsr_copy(matrix_tmp7, almo_scf_env%matrix_t_blk(ispin))
663 CALL dbcsr_copy(matrix_tmp7, matrix_tmp3, keep_sparsity=.true.)
667 template=almo_scf_env%matrix_t_blk(ispin))
668 CALL dbcsr_copy(matrix_tmp8, almo_scf_env%matrix_t_blk(ispin))
669 CALL dbcsr_copy(matrix_tmp8, matrix_tmp1, keep_sparsity=.true.)
673 0.0_dp, matrix_tmp4, &
674 filter_eps=eps_multiply, &
675 retain_sparsity=.true.)
678 CALL dbcsr_add(almo_scf_env%matrix_ks_blk(ispin), matrix_tmp4, &
684 CALL dbcsr_add(almo_scf_env%matrix_ks_blk(ispin), matrix_tmp5, &
689 CALL dbcsr_copy(matrix_tmp7, matrix_tmp2, keep_sparsity=.true.)
693 0.0_dp, matrix_tmp4, &
694 retain_sparsity=.true., &
695 filter_eps=eps_multiply)
697 CALL dbcsr_add(almo_scf_env%matrix_ks_blk(ispin), matrix_tmp4, &
703 CALL dbcsr_add(almo_scf_env%matrix_ks_blk(ispin), matrix_tmp5, &
711 0.0_dp, matrix_tmp7, &
712 retain_sparsity=.true., &
713 filter_eps=eps_multiply)
720 1.0_dp, almo_scf_env%matrix_ks_blk(ispin), &
721 retain_sparsity=.true., &
722 filter_eps=eps_multiply)
728 CALL timestop(handle)
745 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_ks_xx_to_tv_xx'
747 INTEGER :: handle, iblock_size, idomain, info, &
748 ispin, lwork, ndomains
749 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
750 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: data_copy
752 DIMENSION(:) :: subm_ks_xx_orthog, subm_t, subm_tmp
754 CALL timeset(routinen, handle)
758 cpabort(
"a domain must be located entirely on a CPU")
761 ndomains = almo_scf_env%ndomains
762 ALLOCATE (subm_tmp(ndomains))
763 ALLOCATE (subm_ks_xx_orthog(ndomains))
764 ALLOCATE (subm_t(ndomains))
766 DO ispin = 1, almo_scf_env%nspins
789 almo_scf_env%domain_s_sqrt_inv(:, ispin), 0.0_dp, subm_tmp)
791 subm_tmp, 0.0_dp, subm_ks_xx_orthog)
799 DO idomain = 1, ndomains
802 IF (subm_ks_xx_orthog(idomain)%domain > 0)
THEN
804 iblock_size = subm_ks_xx_orthog(idomain)%nrows
807 ALLOCATE (eigenvalues(iblock_size))
808 ALLOCATE (data_copy(iblock_size, iblock_size))
809 data_copy(:, :) = subm_ks_xx_orthog(idomain)%mdata(:, :)
813 ALLOCATE (work(max(1, lwork)))
814 CALL dsyev(
'V',
'L', iblock_size, data_copy, iblock_size, eigenvalues, work, lwork, info)
819 ALLOCATE (work(max(1, lwork)))
820 CALL dsyev(
'V',
'L', iblock_size, data_copy, iblock_size, eigenvalues, work, lwork, info)
821 IF (info /= 0) cpabort(
"DSYEV failed")
824 IF (almo_scf_env%domain_t(idomain, ispin)%ncols /= &
825 almo_scf_env%nocc_of_domain(idomain, ispin))
THEN
826 cpabort(
"wrong domain structure")
829 subm_t(idomain), .false.)
833 IF (almo_scf_env%smear)
THEN
834 almo_scf_env%mo_energies(1 + sum(almo_scf_env%nocc_of_domain(:idomain - 1, ispin)) &
835 :sum(almo_scf_env%nocc_of_domain(:idomain, ispin)), ispin) &
836 = eigenvalues(1:almo_scf_env%nocc_of_domain(idomain, ispin))
840 DEALLOCATE (data_copy)
841 DEALLOCATE (eigenvalues)
851 subm_t, 0.0_dp, almo_scf_env%domain_t(:, ispin))
856 almo_scf_env%matrix_t(ispin), &
857 almo_scf_env%domain_t(:, ispin), &
858 almo_scf_env%quench_t(ispin))
860 almo_scf_env%eps_filter)
868 DEALLOCATE (subm_tmp)
869 DEALLOCATE (subm_ks_xx_orthog)
872 CALL timestop(handle)
890 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_ks_blk_to_tv_blk'
892 INTEGER :: handle, iblock_col, iblock_row, &
893 iblock_size, info, ispin, lwork, &
894 nocc_of_block, nvirt_of_block,
orbital
895 LOGICAL :: block_needed
896 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
897 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: data_copy, new_block
898 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: data_p
901 matrix_t_blk_orthog, matrix_tmp, &
904 CALL timeset(routinen, handle)
908 cpabort(
"a domain must be located entirely on a CPU")
911 DO ispin = 1, almo_scf_env%nspins
913 CALL dbcsr_create(matrix_tmp, template=almo_scf_env%matrix_ks_blk(ispin), &
914 matrix_type=dbcsr_type_no_symmetry)
915 CALL dbcsr_create(matrix_ks_blk_orthog, template=almo_scf_env%matrix_ks_blk(ispin), &
916 matrix_type=dbcsr_type_no_symmetry)
919 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_ks_blk(ispin), &
920 almo_scf_env%matrix_s_blk_sqrt_inv(1), 0.0_dp, matrix_tmp, &
921 filter_eps=almo_scf_env%eps_filter)
922 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_s_blk_sqrt_inv(1), &
923 matrix_tmp, 0.0_dp, matrix_ks_blk_orthog, &
924 filter_eps=almo_scf_env%eps_filter)
930 CALL dbcsr_create(matrix_t_blk_orthog, template=almo_scf_env%matrix_t_blk(ispin))
931 CALL dbcsr_create(matrix_v_blk_orthog, template=almo_scf_env%matrix_v_full_blk(ispin))
943 IF (iblock_row /= iblock_col)
THEN
944 cpabort(
"off-diagonal block found")
947 block_needed = .true.
948 IF (almo_scf_env%nocc_of_domain(iblock_col, ispin) == 0 .AND. &
949 almo_scf_env%nvirt_of_domain(iblock_col, ispin) == 0)
THEN
950 block_needed = .false.
953 IF (block_needed)
THEN
956 ALLOCATE (eigenvalues(iblock_size))
957 ALLOCATE (data_copy(iblock_size, iblock_size))
958 data_copy(:, :) = data_p(:, :)
962 ALLOCATE (work(max(1, lwork)))
963 CALL dsyev(
'V',
'L', iblock_size, data_copy, iblock_size, eigenvalues, work, lwork, info)
968 ALLOCATE (work(max(1, lwork)))
969 CALL dsyev(
'V',
'L', iblock_size, data_copy, iblock_size, eigenvalues, work, lwork, info)
970 IF (info /= 0) cpabort(
"DSYEV failed")
979 nocc_of_block = almo_scf_env%nocc_of_domain(iblock_col, ispin)
980 IF (nocc_of_block > 0)
THEN
982 block=data_copy(:, 1:nocc_of_block))
984 ALLOCATE (new_block(nocc_of_block, nocc_of_block))
985 new_block(:, :) = 0.0_dp
989 CALL dbcsr_put_block(almo_scf_env%matrix_eoo(ispin), iblock_row, iblock_col, new_block)
990 DEALLOCATE (new_block)
998 IF (almo_scf_env%smear)
THEN
1000 almo_scf_env%mo_energies(sum(almo_scf_env%nocc_of_domain(:iblock_row - 1, ispin)) +
orbital, &
1007 nvirt_of_block = almo_scf_env%nvirt_of_domain(iblock_col, ispin)
1008 IF (nvirt_of_block > 0)
THEN
1010 block=data_copy(:, (nocc_of_block + 1):(nocc_of_block + nvirt_of_block)))
1012 ALLOCATE (new_block(nvirt_of_block, nvirt_of_block))
1013 new_block(:, :) = 0.0_dp
1014 DO orbital = 1, nvirt_of_block
1017 CALL dbcsr_put_block(almo_scf_env%matrix_evv_full(ispin), iblock_row, iblock_col, new_block)
1018 DEALLOCATE (new_block)
1022 DEALLOCATE (data_copy)
1023 DEALLOCATE (eigenvalues)
1042 CALL dbcsr_filter(matrix_t_blk_orthog, almo_scf_env%eps_filter)
1043 CALL dbcsr_filter(matrix_v_blk_orthog, almo_scf_env%eps_filter)
1048 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_s_blk_sqrt_inv(1), &
1049 matrix_t_blk_orthog, 0.0_dp, almo_scf_env%matrix_t_blk(ispin), &
1050 filter_eps=almo_scf_env%eps_filter)
1051 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_s_blk_sqrt_inv(1), &
1052 matrix_v_blk_orthog, 0.0_dp, almo_scf_env%matrix_v_full_blk(ispin), &
1053 filter_eps=almo_scf_env%eps_filter)
1060 CALL timestop(handle)
1076 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix_out
1077 INTEGER,
DIMENSION(:) :: nocc
1079 CHARACTER(LEN=*),
PARAMETER :: routinen =
'pseudo_invert_diagonal_blk'
1081 INTEGER :: handle, iblock_col, iblock_row, &
1082 iblock_size, methodid
1083 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: data_copy
1084 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: data_p
1087 CALL timeset(routinen, handle)
1098 IF (iblock_row == iblock_col)
THEN
1101 ALLOCATE (data_copy(iblock_size, iblock_size))
1107 CALL pseudo_invert_matrix(data_p, data_copy, iblock_size, &
1109 range1=nocc(iblock_row), range2=nocc(iblock_row), &
1116 DEALLOCATE (data_copy)
1124 CALL timestop(handle)
1139 LOGICAL,
INTENT(IN) :: ionic
1141 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_p_blk_to_t_blk'
1143 INTEGER :: handle, iblock_col, iblock_row, &
1144 iblock_size, info, ispin, lwork, &
1145 nocc_of_block, unit_nr
1146 LOGICAL :: block_needed
1147 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
1148 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: data_copy
1149 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: data_p
1154 CALL timeset(routinen, handle)
1158 IF (logger%para_env%is_source())
THEN
1164 DO ispin = 1, almo_scf_env%nspins
1170 template=almo_scf_env%matrix_t_blk(ispin))
1172 work_mutable=.true.)
1178 block_needed = .false.
1180 IF (iblock_row == iblock_col)
THEN
1181 block_needed = .true.
1184 IF (.NOT. block_needed)
THEN
1185 cpabort(
"off-diag block found")
1189 ALLOCATE (eigenvalues(iblock_size))
1190 ALLOCATE (data_copy(iblock_size, iblock_size))
1191 data_copy(:, :) = data_p(:, :)
1195 ALLOCATE (work(max(1, lwork)))
1196 CALL dsyev(
'V',
'L', iblock_size, data_copy, iblock_size, eigenvalues, &
1198 lwork = int(work(1))
1202 ALLOCATE (work(max(1, lwork)))
1203 CALL dsyev(
'V',
'L', iblock_size, data_copy, iblock_size, eigenvalues, work, lwork, info)
1205 IF (unit_nr > 0)
THEN
1206 WRITE (unit_nr, *)
'BLOCK = ', iblock_row
1207 WRITE (unit_nr, *)
'INFO =', info
1208 WRITE (unit_nr, *) data_p(:, :)
1210 cpabort(
"DSYEV failed")
1217 nocc_of_block = almo_scf_env%nocc_of_domain(iblock_col, ispin)
1218 cpassert(nocc_of_block > 0)
1220 block=data_copy(:, iblock_size - nocc_of_block + 1:))
1222 DEALLOCATE (data_copy)
1223 DEALLOCATE (eigenvalues)
1230 almo_scf_env%eps_filter)
1231 CALL dbcsr_copy(almo_scf_env%matrix_t_blk(ispin), &
1240 keep_sparsity=.true.)
1243 template=almo_scf_env%matrix_t_blk(ispin), &
1244 matrix_type=dbcsr_type_no_symmetry)
1248 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_s_blk(1), &
1249 almo_scf_env%matrix_t_blk(ispin), &
1250 0.0_dp, matrix_t_blk_tmp, &
1251 filter_eps=almo_scf_env%eps_filter)
1254 almo_scf_env%matrix_p_blk(ispin), matrix_t_blk_tmp, &
1255 0.0_dp, almo_scf_env%matrix_t_blk(ispin), &
1256 filter_eps=almo_scf_env%eps_filter)
1264 CALL timestop(handle)
1285 spin_kTS, smear_e_temp, ndomains, nocc_of_domain)
1288 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: mo_energies
1289 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: mu_of_domain, real_ne_of_domain
1290 REAL(kind=
dp),
INTENT(INOUT) :: spin_kts
1291 REAL(kind=
dp),
INTENT(IN) :: smear_e_temp
1292 INTEGER,
INTENT(IN) :: ndomains
1293 INTEGER,
DIMENSION(:),
INTENT(IN) :: nocc_of_domain
1295 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_t_rescaling'
1297 INTEGER :: handle, idomain, neigenval_used, nmo
1298 REAL(kind=
dp) :: kts
1299 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: occupation_numbers, rescaling_factors
1301 CALL timeset(routinen, handle)
1306 nmo =
SIZE(mo_energies)
1307 ALLOCATE (occupation_numbers(nmo))
1308 ALLOCATE (rescaling_factors(nmo))
1321 DO idomain = 1, ndomains
1323 CALL smearfixed(occupation_numbers(1 + neigenval_used:nocc_of_domain(idomain) + neigenval_used), &
1324 mu_of_domain(idomain), kts, &
1325 mo_energies(1 + neigenval_used:nocc_of_domain(idomain) + neigenval_used), &
1327 spin_kts = spin_kts + kts
1328 neigenval_used = neigenval_used + nocc_of_domain(idomain)
1330 rescaling_factors(:) = sqrt(occupation_numbers)
1355 DEALLOCATE (occupation_numbers)
1356 DEALLOCATE (rescaling_factors)
1358 CALL timestop(handle)
1376 SUBROUTINE get_overlap(bra, ket, overlap, metric, retain_overlap_sparsity, &
1382 LOGICAL,
INTENT(IN),
OPTIONAL :: retain_overlap_sparsity
1383 REAL(kind=
dp) :: eps_filter
1384 LOGICAL,
INTENT(IN),
OPTIONAL :: smear
1386 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_overlap'
1388 INTEGER :: dim0, handle
1389 LOGICAL :: local_retain_sparsity, smearing
1390 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: diag_correction
1393 CALL timeset(routinen, handle)
1395 IF (.NOT.
PRESENT(retain_overlap_sparsity))
THEN
1396 local_retain_sparsity = .false.
1398 local_retain_sparsity = retain_overlap_sparsity
1401 IF (.NOT.
PRESENT(smear))
THEN
1408 matrix_type=dbcsr_type_no_symmetry)
1412 metric, ket, 0.0_dp, tmp, &
1413 filter_eps=eps_filter)
1417 bra, tmp, 0.0_dp, overlap, &
1418 retain_sparsity=local_retain_sparsity, &
1419 filter_eps=eps_filter)
1431 ALLOCATE (diag_correction(dim0))
1432 diag_correction = 1.0_dp
1434 DEALLOCATE (diag_correction)
1437 CALL timestop(handle)
1461 nocc_of_domain, eps_filter, order_lanczos, eps_lanczos, &
1462 max_iter_lanczos, overlap_sqrti, smear)
1464 TYPE(
dbcsr_type),
INTENT(INOUT) :: ket, overlap
1466 LOGICAL,
INTENT(IN) :: retain_locality, only_normalize
1467 INTEGER,
DIMENSION(:),
INTENT(IN) :: nocc_of_domain
1468 REAL(kind=
dp) :: eps_filter
1469 INTEGER,
INTENT(IN) :: order_lanczos
1470 REAL(kind=
dp),
INTENT(IN) :: eps_lanczos
1471 INTEGER,
INTENT(IN) :: max_iter_lanczos
1472 TYPE(
dbcsr_type),
INTENT(INOUT),
OPTIONAL :: overlap_sqrti
1473 LOGICAL,
INTENT(IN),
OPTIONAL :: smear
1475 CHARACTER(LEN=*),
PARAMETER :: routinen =
'orthogonalize_mos'
1477 INTEGER :: dim0, handle
1479 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: diagonal
1481 matrix_sigma_blk_sqrt_inv, &
1484 CALL timeset(routinen, handle)
1486 IF (.NOT.
PRESENT(smear))
THEN
1499 CALL get_overlap(ket, ket, overlap, metric, retain_locality, &
1500 eps_filter, smear=smearing)
1502 IF (only_normalize)
THEN
1505 ALLOCATE (diagonal(dim0))
1509 DEALLOCATE (diagonal)
1514 CALL dbcsr_create(matrix_sigma_blk_sqrt, template=overlap, &
1515 matrix_type=dbcsr_type_no_symmetry)
1516 CALL dbcsr_create(matrix_sigma_blk_sqrt_inv, template=overlap, &
1517 matrix_type=dbcsr_type_no_symmetry)
1520 CALL set_zero_electron_blocks_in_mo_mo_matrix(overlap, nocc_of_domain, 1.0_dp)
1522 overlap, threshold=eps_filter, &
1523 order=order_lanczos, &
1524 eps_lanczos=eps_lanczos, &
1525 max_iter_lanczos=max_iter_lanczos)
1526 CALL set_zero_electron_blocks_in_mo_mo_matrix(overlap, nocc_of_domain, 0.0_dp)
1528 CALL set_zero_electron_blocks_in_mo_mo_matrix(matrix_sigma_blk_sqrt_inv, nocc_of_domain, 0.0_dp)
1532 matrix_type=dbcsr_type_no_symmetry)
1536 matrix_sigma_blk_sqrt_inv, &
1537 0.0_dp, matrix_t_blk_tmp, &
1538 filter_eps=eps_filter)
1544 IF (
PRESENT(overlap_sqrti))
THEN
1546 matrix_sigma_blk_sqrt_inv)
1553 CALL timestop(handle)
1583 use_guess, smear, algorithm, para_env, blacs_env, eps_lanczos, &
1584 max_iter_lanczos, inverse_accelerator, inv_eps_factor)
1588 REAL(kind=
dp),
INTENT(IN) :: eps_filter
1589 LOGICAL,
INTENT(IN) :: orthog_orbs
1590 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: nocc_of_domain
1592 TYPE(
dbcsr_type),
INTENT(INOUT),
OPTIONAL :: sigma, sigma_inv
1593 LOGICAL,
INTENT(IN),
OPTIONAL :: use_guess, smear
1594 INTEGER,
INTENT(IN),
OPTIONAL :: algorithm
1597 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: eps_lanczos
1598 INTEGER,
INTENT(IN),
OPTIONAL :: max_iter_lanczos, inverse_accelerator
1599 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: inv_eps_factor
1601 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_t_to_proj'
1603 INTEGER :: dim0, handle, my_accelerator, &
1605 LOGICAL :: smearing, use_sigma_inv_guess
1606 REAL(kind=
dp) :: my_inv_eps_factor
1607 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: diag_correction
1610 CALL timeset(routinen, handle)
1613 IF (.NOT. orthog_orbs)
THEN
1614 IF ((.NOT.
PRESENT(s)) .OR. (.NOT.
PRESENT(sigma)) .OR. &
1615 (.NOT.
PRESENT(sigma_inv)) .OR. (.NOT.
PRESENT(nocc_of_domain)))
THEN
1616 cpabort(
"Nonorthogonal orbitals need more input")
1621 IF (
PRESENT(algorithm)) my_algorithm = algorithm
1623 IF (my_algorithm == 1 .AND. (.NOT.
PRESENT(para_env) .OR. .NOT.
PRESENT(blacs_env))) &
1624 cpabort(
"PARA and BLACS env are necessary for cholesky algorithm")
1626 use_sigma_inv_guess = .false.
1627 IF (
PRESENT(use_guess))
THEN
1628 use_sigma_inv_guess = use_guess
1631 IF (.NOT.
PRESENT(smear))
THEN
1638 IF (
PRESENT(inverse_accelerator)) my_accelerator = inverse_accelerator
1640 my_inv_eps_factor = 10.0_dp
1641 IF (
PRESENT(inv_eps_factor)) my_inv_eps_factor = inv_eps_factor
1643 IF (orthog_orbs)
THEN
1646 0.0_dp, p, filter_eps=eps_filter)
1654 filter_eps=eps_filter)
1658 filter_eps=eps_filter)
1668 ALLOCATE (diag_correction(dim0))
1669 diag_correction = 1.0_dp
1671 DEALLOCATE (diag_correction)
1675 CALL set_zero_electron_blocks_in_mo_mo_matrix(sigma, nocc_of_domain, 1.0_dp)
1676 SELECT CASE (my_algorithm)
1680 matrix_inverse=sigma_inv, &
1682 use_inv_as_guess=use_sigma_inv_guess, &
1683 threshold=eps_filter*my_inv_eps_factor, &
1684 filter_eps=eps_filter, &
1693 matrix_inverse=sigma_inv, &
1695 use_inv_as_guess=use_sigma_inv_guess, &
1696 threshold=eps_filter*my_inv_eps_factor, &
1697 filter_eps=eps_filter, &
1698 accelerator_order=my_accelerator, &
1699 eps_lanczos=eps_lanczos, &
1700 max_iter_lanczos=max_iter_lanczos, &
1708 para_env=para_env, &
1709 blacs_env=blacs_env)
1711 para_env=para_env, &
1712 blacs_env=blacs_env, &
1713 uplo_to_full=.true.)
1716 cpabort(
"Illegal MO overalp inversion algorithm")
1718 CALL set_zero_electron_blocks_in_mo_mo_matrix(sigma, nocc_of_domain, 0.0_dp)
1719 CALL set_zero_electron_blocks_in_mo_mo_matrix(sigma_inv, nocc_of_domain, 0.0_dp)
1722 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, t, sigma_inv, 0.0_dp, t_tmp, &
1723 filter_eps=eps_filter)
1727 filter_eps=eps_filter)
1733 CALL timestop(handle)
1747 SUBROUTINE set_zero_electron_blocks_in_mo_mo_matrix(matrix, nocc_of_domain, value)
1750 INTEGER,
DIMENSION(:),
INTENT(IN) :: nocc_of_domain
1751 REAL(kind=
dp),
INTENT(IN) ::
value
1754 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: block
1762 IF (row == col .AND. nocc_of_domain(row) == 0)
THEN
1768 END SUBROUTINE set_zero_electron_blocks_in_mo_mo_matrix
1789 psi_projector_orthogonal, proj_in_template, eps_filter, sig_inv_projector, &
1794 TYPE(
dbcsr_type),
INTENT(IN) :: psi_projector, metric
1795 LOGICAL,
INTENT(IN) :: project_out, psi_projector_orthogonal
1796 TYPE(
dbcsr_type),
INTENT(IN) :: proj_in_template
1797 REAL(kind=
dp),
INTENT(IN) :: eps_filter
1798 TYPE(
dbcsr_type),
INTENT(IN),
OPTIONAL :: sig_inv_projector, sig_inv_template
1800 CHARACTER(LEN=*),
PARAMETER :: routinen =
'apply_projector'
1803 TYPE(
dbcsr_type) :: tmp_no, tmp_ov, tmp_ov2, tmp_sig, &
1806 CALL timeset(routinen, handle)
1811 metric, psi_projector, &
1813 filter_eps=eps_filter)
1820 filter_eps=eps_filter)
1822 IF (.NOT. psi_projector_orthogonal)
THEN
1825 template=proj_in_template)
1826 IF (
PRESENT(sig_inv_projector))
THEN
1828 template=sig_inv_projector)
1829 CALL dbcsr_copy(tmp_sig_inv, sig_inv_projector)
1831 IF (.NOT.
PRESENT(sig_inv_template))
THEN
1832 cpabort(
"PROGRAMMING ERROR: provide either template or sig_inv")
1836 template=sig_inv_template, &
1837 matrix_type=dbcsr_type_no_symmetry)
1839 psi_projector, tmp_no, 0.0_dp, tmp_sig, &
1840 filter_eps=eps_filter)
1842 template=sig_inv_template, &
1843 matrix_type=dbcsr_type_no_symmetry)
1845 threshold=eps_filter)
1849 tmp_sig_inv, tmp_ov, 0.0_dp, tmp_ov2, &
1850 filter_eps=eps_filter)
1859 psi_projector, tmp_ov, 0.0_dp, psi_out, &
1860 filter_eps=eps_filter)
1864 IF (project_out)
THEN
1865 CALL dbcsr_add(psi_out, psi_in, -1.0_dp, +1.0_dp)
1868 CALL timestop(handle)
1950 REAL(kind=
dp),
INTENT(IN) :: eps_filter
1952 CHARACTER(LEN=*),
PARAMETER :: routinen =
'generator_to_unitary'
1954 INTEGER :: handle, unit_nr
1955 LOGICAL :: safe_mode
1956 REAL(kind=
dp) :: frob_matrix, frob_matrix_base
1960 CALL timeset(routinen, handle)
1966 IF (logger%para_env%is_source())
THEN
1973 matrix_type=dbcsr_type_no_symmetry)
1975 matrix_type=dbcsr_type_no_symmetry)
1979 matrix_type=dbcsr_type_no_symmetry)
1982 CALL dbcsr_add(delta, x, 1.0_dp, -1.0_dp)
1986 CALL dbcsr_add(t1, delta, 1.0_dp, -1.0_dp)
1992 matrix_type=dbcsr_type_no_symmetry)
1994 filter_eps=eps_filter)
1998 IF (unit_nr > 0)
WRITE (unit_nr, *)
"Error for (inv(A)*A-I)", frob_matrix/frob_matrix_base
2003 filter_eps=eps_filter)
2009 matrix_type=dbcsr_type_no_symmetry)
2011 filter_eps=eps_filter)
2015 IF (unit_nr > 0)
WRITE (unit_nr, *)
"Error for (trn(U)*U-I)", frob_matrix/frob_matrix_base
2019 CALL timestop(handle)
2043 dpattern, map, node_of_domain, my_action, filter_eps, matrix_trimmer, use_trimmer)
2045 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix_in, matrix_out
2047 INTENT(IN) :: operator1
2049 INTENT(IN),
OPTIONAL :: operator2
2052 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2053 INTEGER,
INTENT(IN) :: my_action
2054 REAL(kind=
dp) :: filter_eps
2055 TYPE(
dbcsr_type),
INTENT(IN),
OPTIONAL :: matrix_trimmer
2056 LOGICAL,
INTENT(IN),
OPTIONAL :: use_trimmer
2058 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_domain_operators'
2060 INTEGER :: handle, ndomains
2061 LOGICAL :: matrix_trimmer_required, my_use_trimmer, &
2064 DIMENSION(:) :: subm_in, subm_out, subm_temp
2066 CALL timeset(routinen, handle)
2068 my_use_trimmer = .false.
2069 IF (
PRESENT(use_trimmer))
THEN
2070 my_use_trimmer = use_trimmer
2073 operator2_required = .false.
2074 matrix_trimmer_required = .false.
2076 IF (my_action == 1) operator2_required = .true.
2078 IF (my_use_trimmer)
THEN
2079 matrix_trimmer_required = .true.
2080 cpabort(
"TRIMMED PROJECTOR DISABLED!")
2083 IF (.NOT.
PRESENT(operator2) .AND. operator2_required)
THEN
2084 cpabort(
"SECOND OPERATOR IS REQUIRED")
2086 IF (.NOT.
PRESENT(matrix_trimmer) .AND. matrix_trimmer_required)
THEN
2087 cpabort(
"TRIMMER MATRIX IS REQUIRED")
2092 ALLOCATE (subm_in(ndomains))
2093 ALLOCATE (subm_temp(ndomains))
2094 ALLOCATE (subm_out(ndomains))
2108 IF (my_action == 0)
THEN
2111 subm_in, 0.0_dp, subm_out)
2112 ELSE IF (my_action == 1)
THEN
2116 subm_in, 0.0_dp, subm_temp)
2118 subm_temp, 1.0_dp, subm_out)
2120 cpabort(
"ILLEGAL ACTION")
2130 DEALLOCATE (subm_out)
2131 DEALLOCATE (subm_temp)
2132 DEALLOCATE (subm_in)
2134 CALL timestop(handle)
2162 subm_s_inv_half, subm_s_half, &
2163 subm_r_down, matrix_trimmer, &
2164 dpattern, map, node_of_domain, &
2166 bad_modes_projector_down, &
2168 eps_zero_eigenvalues, &
2169 my_action, skip_inversion)
2171 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix_main
2173 INTENT(IN),
OPTIONAL :: subm_s_inv, subm_s_inv_half, &
2174 subm_s_half, subm_r_down
2175 TYPE(
dbcsr_type),
INTENT(IN),
OPTIONAL :: matrix_trimmer
2178 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2182 INTENT(INOUT),
OPTIONAL :: bad_modes_projector_down
2183 LOGICAL,
INTENT(IN),
OPTIONAL :: use_trimmer
2184 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: eps_zero_eigenvalues
2185 INTEGER,
INTENT(IN) :: my_action
2186 LOGICAL,
INTENT(IN),
OPTIONAL :: skip_inversion
2188 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_preconditioner'
2190 INTEGER :: handle, idomain, index1_end, &
2191 index1_start, n_domain_mos, naos, &
2192 nblkrows_tot, ndomains, neighbor, row
2193 INTEGER,
DIMENSION(:),
POINTER :: nmos
2194 LOGICAL :: eps_zero_eigenvalues_required, matrix_r_required, matrix_s_half_required, &
2195 matrix_s_inv_half_required, matrix_s_inv_required, matrix_trimmer_required, &
2196 my_skip_inversion, my_use_trimmer
2197 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: minv, proj_array
2199 DIMENSION(:) :: subm_main, subm_tmp, subm_tmp2
2201 CALL timeset(routinen, handle)
2203 my_use_trimmer = .false.
2204 IF (
PRESENT(use_trimmer))
THEN
2205 my_use_trimmer = use_trimmer
2208 my_skip_inversion = .false.
2209 IF (
PRESENT(skip_inversion))
THEN
2210 my_skip_inversion = skip_inversion
2213 matrix_s_inv_half_required = .false.
2214 matrix_s_half_required = .false.
2215 eps_zero_eigenvalues_required = .false.
2216 matrix_s_inv_required = .false.
2217 matrix_trimmer_required = .false.
2218 matrix_r_required = .false.
2220 IF (my_action == -1) matrix_s_inv_required = .true.
2221 IF (my_action == -1) matrix_r_required = .true.
2222 IF (my_use_trimmer)
THEN
2223 matrix_trimmer_required = .true.
2224 cpabort(
"TRIMMED PRECONDITIONER DISABLED!")
2227 IF (
PRESENT(bad_modes_projector_down))
THEN
2228 matrix_s_inv_half_required = .true.
2229 matrix_s_half_required = .true.
2230 eps_zero_eigenvalues_required = .true.
2234 IF (.NOT.
PRESENT(subm_s_inv_half) .AND. matrix_s_inv_half_required)
THEN
2235 cpabort(
"S_inv_half SUBMATRICES ARE REQUIRED")
2237 IF (.NOT.
PRESENT(subm_s_half) .AND. matrix_s_half_required)
THEN
2238 cpabort(
"S_half SUBMATRICES ARE REQUIRED")
2240 IF (.NOT.
PRESENT(eps_zero_eigenvalues) .AND. eps_zero_eigenvalues_required)
THEN
2241 cpabort(
"EPS_ZERO_EIGENVALUES IS REQUIRED")
2243 IF (.NOT.
PRESENT(subm_s_inv) .AND. matrix_s_inv_required)
THEN
2244 cpabort(
"S_inv SUBMATRICES ARE REQUIRED")
2246 IF (.NOT.
PRESENT(subm_r_down) .AND. matrix_r_required)
THEN
2247 cpabort(
"R SUBMATRICES ARE REQUIRED")
2249 IF (.NOT.
PRESENT(matrix_trimmer) .AND. matrix_trimmer_required)
THEN
2250 cpabort(
"TRIMMER MATRIX IS REQUIRED")
2254 nblkcols_total=ndomains, &
2255 nblkrows_total=nblkrows_tot, &
2258 ALLOCATE (subm_main(ndomains))
2270 IF (my_action == -1)
THEN
2276 ALLOCATE (subm_tmp(ndomains))
2277 ALLOCATE (subm_tmp2(ndomains))
2281 subm_s_inv, 0.0_dp, subm_tmp)
2283 subm_main, 0.0_dp, subm_tmp2)
2287 subm_tmp, 1.0_dp, subm_main)
2290 DEALLOCATE (subm_tmp2)
2291 DEALLOCATE (subm_tmp)
2294 IF (my_skip_inversion)
THEN
2298 DO idomain = 1, ndomains
2301 IF (subm_main(idomain)%domain > 0)
THEN
2304 IF (idomain == 1)
THEN
2307 index1_start = map%index1(idomain - 1)
2309 index1_end = map%index1(idomain) - 1
2312 DO row = index1_start, index1_end
2313 neighbor = map%pairs(row, 1)
2314 n_domain_mos = n_domain_mos + nmos(neighbor)
2317 naos = subm_main(idomain)%nrows
2320 ALLOCATE (minv(naos, naos))
2350 IF (
PRESENT(bad_modes_projector_down))
THEN
2351 ALLOCATE (proj_array(naos, naos))
2352 CALL pseudo_invert_matrix(a=subm_main(idomain)%mdata, ainv=minv, n=naos, method=1, &
2353 range1=nmos(idomain), range2=n_domain_mos, &
2354 range1_thr=eps_zero_eigenvalues, &
2355 bad_modes_projector_down=proj_array, &
2356 s_inv_half=subm_s_inv_half(idomain)%mdata, &
2357 s_half=subm_s_half(idomain)%mdata &
2360 CALL pseudo_invert_matrix(a=subm_main(idomain)%mdata, ainv=minv, n=naos, method=1, &
2361 range1=nmos(idomain), range2=n_domain_mos)
2369 IF (
PRESENT(bad_modes_projector_down))
THEN
2370 CALL copy_submatrices(subm_main(idomain), bad_modes_projector_down(idomain), .false.)
2372 DEALLOCATE (proj_array)
2382 DEALLOCATE (subm_main)
2392 CALL timestop(handle)
2409 dpattern, map, node_of_domain)
2413 INTENT(INOUT) :: subm_s_sqrt, subm_s_sqrt_inv
2416 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2418 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_s_sqrt'
2420 INTEGER :: handle, idomain, naos, ndomains
2421 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: ssqrt, ssqrtinv
2423 DIMENSION(:) :: subm_s
2425 CALL timeset(routinen, handle)
2428 cpassert(
SIZE(subm_s_sqrt) == ndomains)
2429 cpassert(
SIZE(subm_s_sqrt_inv) == ndomains)
2430 ALLOCATE (subm_s(ndomains))
2437 DO idomain = 1, ndomains
2440 IF (subm_s(idomain)%domain > 0)
THEN
2442 naos = subm_s(idomain)%nrows
2444 ALLOCATE (ssqrt(naos, naos))
2445 ALLOCATE (ssqrtinv(naos, naos))
2447 CALL matrix_sqrt(a=subm_s(idomain)%mdata, asqrt=ssqrt, asqrtinv=ssqrtinv, &
2456 DEALLOCATE (ssqrtinv)
2466 CALL timestop(handle)
2485 INTENT(INOUT) :: subm_s_inv
2488 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2490 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_s_inv'
2492 INTEGER :: handle, idomain, naos, ndomains
2493 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: sinv
2495 DIMENSION(:) :: subm_s
2497 CALL timeset(routinen, handle)
2501 cpassert(
SIZE(subm_s_inv) == ndomains)
2502 ALLOCATE (subm_s(ndomains))
2509 DO idomain = 1, ndomains
2512 IF (subm_s(idomain)%domain > 0)
THEN
2514 naos = subm_s(idomain)%nrows
2516 ALLOCATE (sinv(naos, naos))
2518 CALL pseudo_invert_matrix(a=subm_s(idomain)%mdata, ainv=sinv, n=naos, &
2533 CALL timestop(handle)
2552 subm_r_down, dpattern, map, node_of_domain, filter_eps)
2554 TYPE(
dbcsr_type),
INTENT(IN) :: matrix_t, matrix_sigma_inv, matrix_s
2556 INTENT(INOUT) :: subm_r_down
2559 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2560 REAL(kind=
dp) :: filter_eps
2562 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_r_down'
2564 INTEGER :: handle, ndomains
2565 TYPE(
dbcsr_type) :: m_tmp_no_1, m_tmp_no_2, matrix_r
2567 CALL timeset(routinen, handle)
2571 template=matrix_s, &
2572 matrix_type=dbcsr_type_symmetric)
2574 template=matrix_t, &
2575 matrix_type=dbcsr_type_no_symmetry)
2577 template=matrix_t, &
2578 matrix_type=dbcsr_type_no_symmetry)
2581 0.0_dp, m_tmp_no_1, filter_eps=filter_eps)
2582 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, m_tmp_no_1, matrix_sigma_inv, &
2583 0.0_dp, m_tmp_no_2, filter_eps=filter_eps)
2585 0.0_dp, matrix_r, filter_eps=filter_eps)
2591 cpassert(
SIZE(subm_r_down) == ndomains)
2598 CALL timestop(handle)
2612 SUBROUTINE matrix_sqrt(A, Asqrt, Asqrtinv, N)
2614 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a
2615 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: asqrt, asqrtinv
2616 INTEGER,
INTENT(IN) :: n
2618 CHARACTER(len=*),
PARAMETER :: routinen =
'matrix_sqrt'
2620 INTEGER :: handle, info, jj, lwork, unit_nr
2621 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
2622 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: test, testn
2625 CALL timeset(routinen, handle)
2632 IF (logger%para_env%is_source())
THEN
2657 ALLOCATE (eigenvalues(n))
2660 ALLOCATE (work(max(1, lwork)))
2661 CALL dsyev(
'V',
'L', n, asqrtinv, n, eigenvalues, work, lwork, info)
2662 lwork = int(work(1))
2665 ALLOCATE (work(max(1, lwork)))
2666 CALL dsyev(
'V',
'L', n, asqrtinv, n, eigenvalues, work, lwork, info)
2668 IF (unit_nr > 0)
WRITE (unit_nr, *)
'DSYEV ERROR MESSAGE: ', info
2669 cpabort(
"DSYEV failed")
2675 ALLOCATE (test(n, n))
2677 test(jj, :) = asqrtinv(:, jj)*sqrt(eigenvalues(jj))
2679 ALLOCATE (testn(n, n))
2680 testn(:, :) = matmul(asqrtinv, test)
2684 test(jj, :) = asqrtinv(:, jj)/sqrt(eigenvalues(jj))
2686 testn(:, :) = matmul(asqrtinv, test)
2688 DEALLOCATE (test, testn)
2690 DEALLOCATE (eigenvalues)
2707 CALL timestop(handle)
2709 END SUBROUTINE matrix_sqrt
2730 SUBROUTINE pseudo_invert_matrix(A, Ainv, N, method, range1, range2, range1_thr, &
2731 shift, bad_modes_projector_down, s_inv_half, s_half)
2733 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a
2734 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: ainv
2735 INTEGER,
INTENT(IN) :: n, method
2736 INTEGER,
INTENT(IN),
OPTIONAL :: range1, range2
2737 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: range1_thr, shift
2738 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT), &
2739 OPTIONAL :: bad_modes_projector_down
2740 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
2741 OPTIONAL :: s_inv_half, s_half
2743 CHARACTER(len=*),
PARAMETER :: routinen =
'pseudo_invert_matrix'
2745 INTEGER :: handle, info, jj, lwork, range1_eiv, &
2746 range2_eiv, range3_eiv, unit_nr
2747 LOGICAL :: use_both, use_ranges_only, use_thr_only
2748 REAL(kind=
dp) :: my_shift
2749 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
2750 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: temp1, temp2, temp3, temp4
2753 CALL timeset(routinen, handle)
2757 IF (logger%para_env%is_source())
THEN
2763 IF (method == 1)
THEN
2765 IF ((
PRESENT(range1) .AND. (.NOT.
PRESENT(range2))) .OR. (
PRESENT(range2) .AND. (.NOT.
PRESENT(range1))))
THEN
2766 cpabort(
"range1 and range2 must be provided together")
2769 IF (
PRESENT(range1) .AND.
PRESENT(range1_thr))
THEN
2771 use_thr_only = .false.
2772 use_ranges_only = .false.
2776 IF (
PRESENT(range1))
THEN
2777 use_ranges_only = .true.
2779 use_ranges_only = .false.
2782 IF (
PRESENT(range1_thr))
THEN
2783 use_thr_only = .true.
2785 use_thr_only = .false.
2790 IF ((
PRESENT(s_half) .AND. (.NOT.
PRESENT(s_inv_half))) .OR. (
PRESENT(s_inv_half) .AND. (.NOT.
PRESENT(s_half))))
THEN
2791 cpabort(
"Domain overlap matrix missing")
2796 IF (
PRESENT(shift))
THEN
2803 SELECT CASE (method)
2809 ALLOCATE (eigenvalues(n))
2810 ALLOCATE (temp1(n, n))
2811 ALLOCATE (temp4(n, n))
2812 IF (
PRESENT(s_inv_half))
THEN
2813 CALL dsymm(
'L',
'U', n, n, 1.0_dp, s_inv_half, n, a, n, 0.0_dp, temp1, n)
2814 CALL dsymm(
'R',
'U', n, n, 1.0_dp, s_inv_half, n, temp1, n, 0.0_dp, ainv, n)
2818 ALLOCATE (work(max(1, lwork)))
2819 CALL dsyev(
'V',
'L', n, ainv, n, eigenvalues, work, lwork, info)
2821 lwork = int(work(1))
2824 ALLOCATE (work(max(1, lwork)))
2825 CALL dsyev(
'V',
'L', n, ainv, n, eigenvalues, work, lwork, info)
2828 IF (unit_nr > 0)
WRITE (unit_nr, *)
'EIGENSYSTEM ERROR MESSAGE: ', info
2829 cpabort(
"Eigenproblem routine failed")
2838 ALLOCATE (temp2(n, n))
2839 IF (
PRESENT(bad_modes_projector_down))
ALLOCATE (temp3(n, n))
2840 temp2(1:n, 1:n) = ainv(1:n, 1:n)
2848 IF ((jj <= range2) .AND. (eigenvalues(jj) < range1_thr))
THEN
2849 temp1(jj, :) = temp2(:, jj)*0.0_dp
2850 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2851 range1_eiv = range1_eiv + 1
2853 temp1(jj, :) = temp2(:, jj)/(eigenvalues(jj) + my_shift)
2854 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*0.0_dp
2855 range2_eiv = range2_eiv + 1
2859 IF (use_ranges_only)
THEN
2861 IF (jj <= range1)
THEN
2862 temp1(jj, :) = temp2(:, jj)*0.0_dp
2863 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2864 range1_eiv = range1_eiv + 1
2865 ELSE IF (jj <= range2)
THEN
2866 temp1(jj, :) = temp2(:, jj)*1.0_dp
2867 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2868 range2_eiv = range2_eiv + 1
2870 temp1(jj, :) = temp2(:, jj)/(eigenvalues(jj) + my_shift)
2871 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*0.0_dp
2872 range3_eiv = range3_eiv + 1
2875 ELSE IF (use_thr_only)
THEN
2877 IF (eigenvalues(jj) < range1_thr)
THEN
2878 temp1(jj, :) = temp2(:, jj)*0.0_dp
2879 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2880 range1_eiv = range1_eiv + 1
2882 temp1(jj, :) = temp2(:, jj)/(eigenvalues(jj) + my_shift)
2883 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*0.0_dp
2884 range2_eiv = range2_eiv + 1
2888 cpabort(
"Invert using Cholesky. It would be faster.")
2892 IF (
PRESENT(bad_modes_projector_down))
THEN
2893 IF (
PRESENT(s_half))
THEN
2894 CALL dsymm(
'L',
'U', n, n, 1.0_dp, s_half, n, temp2, n, 0.0_dp, ainv, n)
2895 CALL dsymm(
'R',
'U', n, n, 1.0_dp, s_half, n, temp3, n, 0.0_dp, temp4, n)
2896 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, ainv, n, temp4, n, 0.0_dp, bad_modes_projector_down, n)
2898 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, temp2, n, temp3, n, 0.0_dp, bad_modes_projector_down, n)
2902 IF (
PRESENT(s_inv_half))
THEN
2903 CALL dsymm(
'L',
'U', n, n, 1.0_dp, s_inv_half, n, temp2, n, 0.0_dp, temp4, n)
2904 CALL dsymm(
'R',
'U', n, n, 1.0_dp, s_inv_half, n, temp1, n, 0.0_dp, temp2, n)
2905 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, temp4, n, temp2, n, 0.0_dp, ainv, n)
2907 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, temp2, n, temp1, n, 0.0_dp, ainv, n)
2909 DEALLOCATE (temp1, temp2, temp4)
2910 IF (
PRESENT(bad_modes_projector_down))
DEALLOCATE (temp3)
2911 DEALLOCATE (eigenvalues)
2915 cpabort(
"Illegal method selected for matrix inversion")
2934 CALL timestop(handle)
2936 END SUBROUTINE pseudo_invert_matrix
2951 SUBROUTINE pseudo_matrix_power(A, Apow, power, N, range1, range1_thr, shift)
2953 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a
2954 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: apow
2955 REAL(kind=
dp),
INTENT(IN) :: power
2956 INTEGER,
INTENT(IN) :: n
2957 INTEGER,
INTENT(IN),
OPTIONAL :: range1
2958 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: range1_thr, shift
2960 CHARACTER(len=*),
PARAMETER :: routinen =
'pseudo_matrix_power'
2962 INTEGER :: handle, info, jj, lwork, range1_eiv, &
2964 LOGICAL :: use_both, use_ranges, use_thr
2965 REAL(kind=
dp) :: my_shift
2966 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
2967 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: temp1, temp2
2970 CALL timeset(routinen, handle)
2974 IF (logger%para_env%is_source())
THEN
2980 IF (
PRESENT(range1) .AND.
PRESENT(range1_thr))
THEN
2984 IF (
PRESENT(range1))
THEN
2987 use_ranges = .false.
2988 IF (
PRESENT(range1_thr))
THEN
2997 IF (
PRESENT(shift))
THEN
3005 ALLOCATE (eigenvalues(n))
3006 ALLOCATE (temp1(n, n))
3010 ALLOCATE (work(max(1, lwork)))
3011 CALL dsyev(
'V',
'L', n, apow, n, eigenvalues, work, lwork, info)
3013 lwork = int(work(1))
3016 ALLOCATE (work(max(1, lwork)))
3017 CALL dsyev(
'V',
'L', n, apow, n, eigenvalues, work, lwork, info)
3020 IF (unit_nr > 0)
WRITE (unit_nr, *)
'EIGENSYSTEM ERROR MESSAGE: ', info
3021 cpabort(
"Eigenproblem routine failed")
3030 ALLOCATE (temp2(n, n))
3032 temp2(1:n, 1:n) = apow(1:n, 1:n)
3039 IF ((jj <= range1) .AND. (eigenvalues(jj) < range1_thr))
THEN
3040 temp1(jj, :) = temp2(:, jj)*0.0_dp
3041 range1_eiv = range1_eiv + 1
3043 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
3047 IF (use_ranges)
THEN
3049 IF (jj <= range1)
THEN
3050 temp1(jj, :) = temp2(:, jj)*0.0_dp
3051 range1_eiv = range1_eiv + 1
3053 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
3059 IF (eigenvalues(jj) < range1_thr)
THEN
3060 temp1(jj, :) = temp2(:, jj)*0.0_dp
3062 range1_eiv = range1_eiv + 1
3064 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
3069 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
3075 apow = matmul(temp2, temp1)
3076 DEALLOCATE (temp1, temp2)
3077 DEALLOCATE (eigenvalues)
3079 CALL timestop(handle)
3081 END SUBROUTINE pseudo_matrix_power
3094 CHARACTER(len=*),
PARAMETER :: routinen =
'distribute_domains'
3096 INTEGER :: handle, idomain, least_loaded, nao, &
3098 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: index0
3099 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cpu_load, domain_load
3102 CALL timeset(routinen, handle)
3104 ndomains = almo_scf_env%ndomains
3108 ALLOCATE (domain_load(ndomains))
3109 DO idomain = 1, ndomains
3110 nao = almo_scf_env%nbasis_of_domain(idomain)
3111 domain_load(idomain) = (nao*nao*nao)*1.0_dp
3114 ALLOCATE (index0(ndomains))
3116 CALL sort(domain_load, ndomains, index0)
3118 ALLOCATE (cpu_load(ncpus))
3119 cpu_load(:) = 0.0_dp
3121 DO idomain = 1, ndomains
3122 least_loaded = minloc(cpu_load, 1)
3123 cpu_load(least_loaded) = cpu_load(least_loaded) + domain_load(idomain)
3124 almo_scf_env%cpu_of_domain(index0(idomain)) = least_loaded - 1
3127 DEALLOCATE (cpu_load)
3129 DEALLOCATE (domain_load)
3131 CALL timestop(handle)
3147 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix_no, dpattern
3149 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
3151 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_test'
3153 INTEGER :: handle, ndomains
3156 DIMENSION(:) :: subm_nn, subm_no
3159 CALL timeset(routinen, handle)
3161 CALL dbcsr_get_info(dpattern, group=group, nblkcols_total=ndomains)
3163 ALLOCATE (subm_no(ndomains), subm_nn(ndomains))
3184 DEALLOCATE (subm_no, subm_nn)
3186 CALL timestop(handle)
3213 m_overlap, m_sigma_tmpl, nspins, xalmo_history, assume_t0_q0x, &
3214 optimize_theta, envelope_amplitude, eps_filter, order_lanczos, eps_lanczos, &
3215 max_iter_lanczos, nocc_of_domain)
3217 TYPE(
dbcsr_type),
DIMENSION(:),
INTENT(INOUT) :: m_guess
3218 TYPE(
dbcsr_type),
DIMENSION(:),
INTENT(IN) :: m_t_in, m_t0, m_quench_t
3220 TYPE(
dbcsr_type),
DIMENSION(:),
INTENT(IN) :: m_sigma_tmpl
3221 INTEGER,
INTENT(IN) :: nspins
3223 LOGICAL,
INTENT(IN) :: assume_t0_q0x, optimize_theta
3224 REAL(kind=
dp),
INTENT(IN) :: envelope_amplitude, eps_filter
3225 INTEGER,
INTENT(IN) :: order_lanczos
3226 REAL(kind=
dp),
INTENT(IN) :: eps_lanczos
3227 INTEGER,
INTENT(IN) :: max_iter_lanczos
3228 INTEGER,
DIMENSION(:, :),
INTENT(IN) :: nocc_of_domain
3230 CHARACTER(len=*),
PARAMETER :: routinen =
'xalmo_initial_guess'
3232 INTEGER :: handle, iaspc, ispin, istore, naspc, &
3234 LOGICAL :: aspc_guess
3235 REAL(kind=
dp) :: alpha
3237 TYPE(
dbcsr_type) :: m_extrapolated, m_sigma_tmp
3239 CALL timeset(routinen, handle)
3243 IF (logger%para_env%is_source())
THEN
3249 IF (optimize_theta)
THEN
3250 cpwarn(
"unused option")
3252 alpha = envelope_amplitude
3257 IF (xalmo_history%istore == 0)
THEN
3258 aspc_guess = .false.
3264 IF (.NOT. aspc_guess)
THEN
3266 DO ispin = 1, nspins
3270 IF (assume_t0_q0x)
THEN
3274 CALL dbcsr_copy(m_guess(ispin), m_t_in(ispin))
3284 naspc = min(xalmo_history%istore, xalmo_history%nstore)
3285 IF (unit_nr > 0)
THEN
3286 WRITE (unit_nr, fmt=
"(/,T2,A,/,/,T3,A,I0)") &
3287 "Parameters for the always stable predictor-corrector (ASPC) method:", &
3288 "ASPC order: ", naspc
3291 DO ispin = 1, nspins
3294 template=m_quench_t(ispin), matrix_type=dbcsr_type_no_symmetry)
3296 template=m_sigma_tmpl(ispin), matrix_type=dbcsr_type_no_symmetry)
3304 istore = mod(xalmo_history%istore - iaspc, xalmo_history%nstore) + 1
3305 alpha = (-1.0_dp)**(iaspc + 1)*real(iaspc, kind=
dp)* &
3307 IF (unit_nr > 0)
THEN
3308 WRITE (unit_nr, fmt=
"(T3,A2,I0,A4,F10.6)") &
3309 "B(", iaspc,
") = ", alpha
3314 CALL dbcsr_copy(m_extrapolated, m_quench_t(ispin))
3323 xalmo_history%matrix_p_up_down(ispin, istore), &
3325 0.0_dp, m_extrapolated, &
3326 retain_sparsity=.true.)
3329 overlap=m_sigma_tmp, &
3331 retain_locality=.true., &
3332 only_normalize=.false., &
3333 nocc_of_domain=nocc_of_domain(:, ispin), &
3334 eps_filter=eps_filter, &
3335 order_lanczos=order_lanczos, &
3336 eps_lanczos=eps_lanczos, &
3337 max_iter_lanczos=max_iter_lanczos)
3340 CALL dbcsr_add(m_guess(ispin), m_extrapolated, &
3341 1.0_dp, (1.0_dp*alpha)/naspc)
3349 overlap=m_sigma_tmp, &
3351 retain_locality=.true., &
3352 only_normalize=.false., &
3353 nocc_of_domain=nocc_of_domain(:, ispin), &
3354 eps_filter=eps_filter, &
3355 order_lanczos=order_lanczos, &
3356 eps_lanczos=eps_lanczos, &
3357 max_iter_lanczos=max_iter_lanczos)
3363 IF (assume_t0_q0x)
THEN
3364 CALL dbcsr_add(m_guess(ispin), m_t0(ispin), &
3372 CALL timestop(handle)
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
Subroutines for ALMO SCF.
subroutine, public construct_domain_preconditioner(matrix_main, subm_s_inv, subm_s_inv_half, subm_s_half, subm_r_down, matrix_trimmer, dpattern, map, node_of_domain, preconditioner, bad_modes_projector_down, use_trimmer, eps_zero_eigenvalues, my_action, skip_inversion)
Constructs preconditioners for each domain -1. projected preconditioner 0. simple preconditioner.
subroutine, public almo_scf_ks_xx_to_tv_xx(almo_scf_env)
ALMOs by diagonalizing the KS domain submatrices computes both the occupied and virtual orbitals.
subroutine, public xalmo_initial_guess(m_guess, m_t_in, m_t0, m_quench_t, m_overlap, m_sigma_tmpl, nspins, xalmo_history, assume_t0_q0x, optimize_theta, envelope_amplitude, eps_filter, order_lanczos, eps_lanczos, max_iter_lanczos, nocc_of_domain)
create the initial guess for XALMOs
subroutine, public construct_test(matrix_no, dpattern, map, node_of_domain)
Tests construction and release of domain submatrices.
subroutine, public distribute_domains(almo_scf_env)
Load balancing of the submatrix computations.
subroutine, public almo_scf_p_blk_to_t_blk(almo_scf_env, ionic)
computes occupied ALMOs from the superimposed atomic density blocks
subroutine, public generator_to_unitary(x, u, eps_filter)
computes a unitary matrix from an arbitrary "generator" matrix U = ( 1 - X + tr(X) ) ( 1 + X - tr(X) ...
subroutine, public pseudo_invert_diagonal_blk(matrix_in, matrix_out, nocc)
inverts block-diagonal blocks of a dbcsr_matrix
subroutine, public almo_scf_ks_blk_to_tv_blk(almo_scf_env)
computes ALMOs by diagonalizing the projected blocked KS matrix uses the diagonalization code for blo...
subroutine, public apply_domain_operators(matrix_in, matrix_out, operator1, operator2, dpattern, map, node_of_domain, my_action, filter_eps, matrix_trimmer, use_trimmer)
Parallel code for domain specific operations (my_action) 0. out = op1 * in.
subroutine, public construct_domain_r_down(matrix_t, matrix_sigma_inv, matrix_s, subm_r_down, dpattern, map, node_of_domain, filter_eps)
Constructs subblocks of the covariant-covariant projectors (i.e. DM without spin factor)
subroutine, public almo_scf_t_to_proj(t, p, eps_filter, orthog_orbs, nocc_of_domain, s, sigma, sigma_inv, use_guess, smear, algorithm, para_env, blacs_env, eps_lanczos, max_iter_lanczos, inverse_accelerator, inv_eps_factor)
computes the idempotent density matrix from MOs MOs can be either orthogonal or non-orthogonal
subroutine, public construct_domain_s_inv(matrix_s, subm_s_inv, dpattern, map, node_of_domain)
Constructs S_inv block for each domain.
subroutine, public almo_scf_ks_to_ks_blk(almo_scf_env)
computes the projected KS from the total KS matrix also computes the DIIS error vector as a by-produc...
subroutine, public get_overlap(bra, ket, overlap, metric, retain_overlap_sparsity, eps_filter, smear)
Computes the overlap matrix of MO orbitals.
subroutine, public fill_matrix_with_ones(matrix)
Fill all matrix blocks with 1.0_dp.
subroutine, public apply_projector(psi_in, psi_out, psi_projector, metric, project_out, psi_projector_orthogonal, proj_in_template, eps_filter, sig_inv_projector, sig_inv_template)
applies projector to the orbitals |psi_out> = P |psi_in> OR |psi_out> = (1-P) |psi_in>,...
subroutine, public construct_domain_s_sqrt(matrix_s, subm_s_sqrt, subm_s_sqrt_inv, dpattern, map, node_of_domain)
Constructs S^(+1/2) and S^(-1/2) submatrices for each domain.
subroutine, public orthogonalize_mos(ket, overlap, metric, retain_locality, only_normalize, nocc_of_domain, eps_filter, order_lanczos, eps_lanczos, max_iter_lanczos, overlap_sqrti, smear)
orthogonalize MOs
subroutine, public almo_scf_ks_to_ks_xx(almo_scf_env)
builds projected KS matrices for the overlapping domains also computes the DIIS error vector as a by-...
subroutine, public almo_scf_t_rescaling(matrix_t, mo_energies, mu_of_domain, real_ne_of_domain, spin_kts, smear_e_temp, ndomains, nocc_of_domain)
Apply an occupation-rescaling trick to ALMOs for smearing. Partially occupied orbitals are considered...
Types for all ALMO-based methods.
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public kuhne2007
integer, save, public kolafa2004
methods related to the blacs parallel environment
subroutine, public dbcsr_transposed(transposed, normal, shallow_data_copy, transpose_distribution, use_distribution)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
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_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_work_create(matrix, nblks_guess, sizedata_guess, n, work_mutable)
...
subroutine, public dbcsr_filter(matrix, eps)
...
subroutine, public dbcsr_finalize(matrix)
...
subroutine, public dbcsr_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_iterator_readonly_start(iterator, matrix, shared, dynamic, dynamic_byrows)
Like dbcsr_iterator_start() but with matrix being INTENT(IN). When invoking this routine,...
subroutine, public dbcsr_put_block(matrix, row, col, block, summation)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
subroutine, public dbcsr_distribution_get(dist, row_dist, col_dist, nrows, ncols, has_threads, group, mynode, numnodes, nprows, npcols, myprow, mypcol, pgrid, subgroups_defined, prow_group, pcol_group)
...
Interface to (sca)lapack for the Cholesky based procedures.
subroutine, public cp_dbcsr_cholesky_decompose(matrix, n, para_env, blacs_env)
used to replace a symmetric positive def. matrix M with its cholesky decomposition U: M = U^T * U,...
subroutine, public cp_dbcsr_cholesky_invert(matrix, n, para_env, blacs_env, uplo_to_full)
used to replace the cholesky decomposition by the inverse
subroutine, public dbcsr_set_diag(matrix, diag)
Copies the diagonal elements from the given array into the given matrix.
subroutine, public dbcsr_get_diag(matrix, diag)
Copies the diagonal elements from the given matrix into the given array.
subroutine, public dbcsr_add_on_diag(matrix, alpha)
Adds the given scalar to the diagonal of the matrix. Reserves any missing diagonal blocks.
subroutine, public dbcsr_print(matrix, variable_name, unit_nr)
Prints given matrix in matlab format (only present blocks).
subroutine, public dbcsr_reserve_all_blocks(matrix)
Reserves all blocks.
subroutine, public dbcsr_init_random(matrix, keep_sparsity)
Fills the given matrix with random numbers.
real(dp) function, public dbcsr_frobenius_norm(matrix)
Compute the frobenius norm of a dbcsr matrix.
subroutine, public dbcsr_reserve_diag_blocks(matrix)
Reserves all diagonal blocks.
subroutine, public dbcsr_scale_by_vector(matrix, alpha, side)
Scales the rows/columns of given matrix.
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
Subroutines to handle submatrices.
subroutine, public copy_submatrix_data(array, copy)
...
subroutine, public print_submatrices(submatrices, mpgroup)
...
subroutine, public construct_dbcsr_from_submatrices(matrix, submatrix, distr_pattern)
Constructs a DBCSR matrix from submatrices.
subroutine, public construct_submatrices(matrix, submatrix, distr_pattern, domain_map, node_of_domain, job_type)
Constructs submatrices for each ALMO domain by collecting distributed DBCSR blocks to local arrays.
Types to handle submatrices.
integer, parameter, public select_row
integer, parameter, public select_row_col
Routines useful for iterative matrix calculations.
subroutine, public invert_taylor(matrix_inverse, matrix, threshold, use_inv_as_guess, norm_convergence, filter_eps, accelerator_order, max_iter_lanczos, eps_lanczos, silent)
invert a symmetric positive definite diagonally dominant matrix
subroutine, public invert_hotelling(matrix_inverse, matrix, threshold, use_inv_as_guess, norm_convergence, filter_eps, accelerator_order, max_iter_lanczos, eps_lanczos, silent)
invert a symmetric positive definite matrix by Hotelling's method explicit symmetrization makes this ...
subroutine, public matrix_sqrt_newton_schulz(matrix_sqrt, matrix_sqrt_inv, matrix, threshold, order, eps_lanczos, max_iter_lanczos, symmetrize, converged, iounit)
compute the sqrt of a matrix via the sign function and the corresponding Newton-Schulz iterations the...
Defines the basic variable types.
integer, parameter, public dp
Collection of simple mathematical functions and subroutines.
elemental real(kind=dp) function, public binomial(n, k)
The binomial coefficient n over k for 0 <= k <= n is calculated, otherwise zero is returned.
subroutine, public invmat_symm(a, potrf, uplo)
returns inverse of real symmetric, positive definite matrix
Interface to the message passing library MPI.
computes preconditioners, and implements methods to apply them currently used in qs_ot
Unified smearing module supporting four methods: smear_fermi_dirac — Fermi-Dirac distribution smear_g...
subroutine, public smearfixed(f, mu, kts, e, n, sigma, maxocc, method, estate, festate)
Bisection search for the chemical potential mu such that the total electron count equals N,...
All kind of helpful little routines.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
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
Orbital angular momentum.