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)))
THEN
1624 cpabort(
"PARA and BLACS env are necessary for cholesky algorithm")
1627 use_sigma_inv_guess = .false.
1628 IF (
PRESENT(use_guess))
THEN
1629 use_sigma_inv_guess = use_guess
1632 IF (.NOT.
PRESENT(smear))
THEN
1639 IF (
PRESENT(inverse_accelerator)) my_accelerator = inverse_accelerator
1641 my_inv_eps_factor = 10.0_dp
1642 IF (
PRESENT(inv_eps_factor)) my_inv_eps_factor = inv_eps_factor
1644 IF (orthog_orbs)
THEN
1647 0.0_dp, p, filter_eps=eps_filter)
1655 filter_eps=eps_filter)
1659 filter_eps=eps_filter)
1669 ALLOCATE (diag_correction(dim0))
1670 diag_correction = 1.0_dp
1672 DEALLOCATE (diag_correction)
1676 CALL set_zero_electron_blocks_in_mo_mo_matrix(sigma, nocc_of_domain, 1.0_dp)
1677 SELECT CASE (my_algorithm)
1681 matrix_inverse=sigma_inv, &
1683 use_inv_as_guess=use_sigma_inv_guess, &
1684 threshold=eps_filter*my_inv_eps_factor, &
1685 filter_eps=eps_filter, &
1694 matrix_inverse=sigma_inv, &
1696 use_inv_as_guess=use_sigma_inv_guess, &
1697 threshold=eps_filter*my_inv_eps_factor, &
1698 filter_eps=eps_filter, &
1699 accelerator_order=my_accelerator, &
1700 eps_lanczos=eps_lanczos, &
1701 max_iter_lanczos=max_iter_lanczos, &
1709 para_env=para_env, &
1710 blacs_env=blacs_env)
1712 para_env=para_env, &
1713 blacs_env=blacs_env, &
1714 uplo_to_full=.true.)
1717 cpabort(
"Illegal MO overalp inversion algorithm")
1719 CALL set_zero_electron_blocks_in_mo_mo_matrix(sigma, nocc_of_domain, 0.0_dp)
1720 CALL set_zero_electron_blocks_in_mo_mo_matrix(sigma_inv, nocc_of_domain, 0.0_dp)
1723 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, t, sigma_inv, 0.0_dp, t_tmp, &
1724 filter_eps=eps_filter)
1728 filter_eps=eps_filter)
1734 CALL timestop(handle)
1748 SUBROUTINE set_zero_electron_blocks_in_mo_mo_matrix(matrix, nocc_of_domain, value)
1751 INTEGER,
DIMENSION(:),
INTENT(IN) :: nocc_of_domain
1752 REAL(kind=
dp),
INTENT(IN) ::
value
1755 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: block
1763 IF (row == col .AND. nocc_of_domain(row) == 0)
THEN
1769 END SUBROUTINE set_zero_electron_blocks_in_mo_mo_matrix
1790 psi_projector_orthogonal, proj_in_template, eps_filter, sig_inv_projector, &
1795 TYPE(
dbcsr_type),
INTENT(IN) :: psi_projector, metric
1796 LOGICAL,
INTENT(IN) :: project_out, psi_projector_orthogonal
1797 TYPE(
dbcsr_type),
INTENT(IN) :: proj_in_template
1798 REAL(kind=
dp),
INTENT(IN) :: eps_filter
1799 TYPE(
dbcsr_type),
INTENT(IN),
OPTIONAL :: sig_inv_projector, sig_inv_template
1801 CHARACTER(LEN=*),
PARAMETER :: routinen =
'apply_projector'
1804 TYPE(
dbcsr_type) :: tmp_no, tmp_ov, tmp_ov2, tmp_sig, &
1807 CALL timeset(routinen, handle)
1812 metric, psi_projector, &
1814 filter_eps=eps_filter)
1821 filter_eps=eps_filter)
1823 IF (.NOT. psi_projector_orthogonal)
THEN
1826 template=proj_in_template)
1827 IF (
PRESENT(sig_inv_projector))
THEN
1829 template=sig_inv_projector)
1830 CALL dbcsr_copy(tmp_sig_inv, sig_inv_projector)
1832 IF (.NOT.
PRESENT(sig_inv_template))
THEN
1833 cpabort(
"PROGRAMMING ERROR: provide either template or sig_inv")
1837 template=sig_inv_template, &
1838 matrix_type=dbcsr_type_no_symmetry)
1840 psi_projector, tmp_no, 0.0_dp, tmp_sig, &
1841 filter_eps=eps_filter)
1843 template=sig_inv_template, &
1844 matrix_type=dbcsr_type_no_symmetry)
1846 threshold=eps_filter)
1850 tmp_sig_inv, tmp_ov, 0.0_dp, tmp_ov2, &
1851 filter_eps=eps_filter)
1860 psi_projector, tmp_ov, 0.0_dp, psi_out, &
1861 filter_eps=eps_filter)
1865 IF (project_out)
THEN
1866 CALL dbcsr_add(psi_out, psi_in, -1.0_dp, +1.0_dp)
1869 CALL timestop(handle)
1951 REAL(kind=
dp),
INTENT(IN) :: eps_filter
1953 CHARACTER(LEN=*),
PARAMETER :: routinen =
'generator_to_unitary'
1955 INTEGER :: handle, unit_nr
1956 LOGICAL :: safe_mode
1957 REAL(kind=
dp) :: frob_matrix, frob_matrix_base
1961 CALL timeset(routinen, handle)
1967 IF (logger%para_env%is_source())
THEN
1974 matrix_type=dbcsr_type_no_symmetry)
1976 matrix_type=dbcsr_type_no_symmetry)
1980 matrix_type=dbcsr_type_no_symmetry)
1983 CALL dbcsr_add(delta, x, 1.0_dp, -1.0_dp)
1987 CALL dbcsr_add(t1, delta, 1.0_dp, -1.0_dp)
1993 matrix_type=dbcsr_type_no_symmetry)
1995 filter_eps=eps_filter)
1999 IF (unit_nr > 0)
WRITE (unit_nr, *)
"Error for (inv(A)*A-I)", frob_matrix/frob_matrix_base
2004 filter_eps=eps_filter)
2010 matrix_type=dbcsr_type_no_symmetry)
2012 filter_eps=eps_filter)
2016 IF (unit_nr > 0)
WRITE (unit_nr, *)
"Error for (trn(U)*U-I)", frob_matrix/frob_matrix_base
2020 CALL timestop(handle)
2044 dpattern, map, node_of_domain, my_action, filter_eps, matrix_trimmer, use_trimmer)
2046 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix_in, matrix_out
2048 INTENT(IN) :: operator1
2050 INTENT(IN),
OPTIONAL :: operator2
2053 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2054 INTEGER,
INTENT(IN) :: my_action
2055 REAL(kind=
dp) :: filter_eps
2056 TYPE(
dbcsr_type),
INTENT(IN),
OPTIONAL :: matrix_trimmer
2057 LOGICAL,
INTENT(IN),
OPTIONAL :: use_trimmer
2059 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_domain_operators'
2061 INTEGER :: handle, ndomains
2062 LOGICAL :: matrix_trimmer_required, my_use_trimmer, &
2065 DIMENSION(:) :: subm_in, subm_out, subm_temp
2067 CALL timeset(routinen, handle)
2069 my_use_trimmer = .false.
2070 IF (
PRESENT(use_trimmer))
THEN
2071 my_use_trimmer = use_trimmer
2074 operator2_required = .false.
2075 matrix_trimmer_required = .false.
2077 IF (my_action == 1) operator2_required = .true.
2079 IF (my_use_trimmer)
THEN
2080 matrix_trimmer_required = .true.
2081 cpabort(
"TRIMMED PROJECTOR DISABLED!")
2084 IF (.NOT.
PRESENT(operator2) .AND. operator2_required)
THEN
2085 cpabort(
"SECOND OPERATOR IS REQUIRED")
2087 IF (.NOT.
PRESENT(matrix_trimmer) .AND. matrix_trimmer_required)
THEN
2088 cpabort(
"TRIMMER MATRIX IS REQUIRED")
2093 ALLOCATE (subm_in(ndomains))
2094 ALLOCATE (subm_temp(ndomains))
2095 ALLOCATE (subm_out(ndomains))
2103 IF (my_action == 0)
THEN
2106 subm_in, 0.0_dp, subm_out)
2107 ELSE IF (my_action == 1)
THEN
2111 subm_in, 0.0_dp, subm_temp)
2113 subm_temp, 1.0_dp, subm_out)
2115 cpabort(
"ILLEGAL ACTION")
2125 DEALLOCATE (subm_out)
2126 DEALLOCATE (subm_temp)
2127 DEALLOCATE (subm_in)
2129 CALL timestop(handle)
2157 subm_s_inv_half, subm_s_half, &
2158 subm_r_down, matrix_trimmer, &
2159 dpattern, map, node_of_domain, &
2161 bad_modes_projector_down, &
2163 eps_zero_eigenvalues, &
2164 my_action, skip_inversion)
2166 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix_main
2168 INTENT(IN),
OPTIONAL :: subm_s_inv, subm_s_inv_half, &
2169 subm_s_half, subm_r_down
2170 TYPE(
dbcsr_type),
INTENT(IN),
OPTIONAL :: matrix_trimmer
2173 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2177 INTENT(INOUT),
OPTIONAL :: bad_modes_projector_down
2178 LOGICAL,
INTENT(IN),
OPTIONAL :: use_trimmer
2179 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: eps_zero_eigenvalues
2180 INTEGER,
INTENT(IN) :: my_action
2181 LOGICAL,
INTENT(IN),
OPTIONAL :: skip_inversion
2183 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_preconditioner'
2185 INTEGER :: handle, idomain, index1_end, &
2186 index1_start, n_domain_mos, naos, &
2187 nblkrows_tot, ndomains, neighbor, row
2188 INTEGER,
DIMENSION(:),
POINTER :: nmos
2189 LOGICAL :: eps_zero_eigenvalues_required, matrix_r_required, matrix_s_half_required, &
2190 matrix_s_inv_half_required, matrix_s_inv_required, matrix_trimmer_required, &
2191 my_skip_inversion, my_use_trimmer
2192 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: minv, proj_array
2194 DIMENSION(:) :: subm_main, subm_tmp, subm_tmp2
2196 CALL timeset(routinen, handle)
2198 my_use_trimmer = .false.
2199 IF (
PRESENT(use_trimmer))
THEN
2200 my_use_trimmer = use_trimmer
2203 my_skip_inversion = .false.
2204 IF (
PRESENT(skip_inversion))
THEN
2205 my_skip_inversion = skip_inversion
2208 matrix_s_inv_half_required = .false.
2209 matrix_s_half_required = .false.
2210 eps_zero_eigenvalues_required = .false.
2211 matrix_s_inv_required = .false.
2212 matrix_trimmer_required = .false.
2213 matrix_r_required = .false.
2215 IF (my_action == -1) matrix_s_inv_required = .true.
2216 IF (my_action == -1) matrix_r_required = .true.
2217 IF (my_use_trimmer)
THEN
2218 matrix_trimmer_required = .true.
2219 cpabort(
"TRIMMED PRECONDITIONER DISABLED!")
2222 IF (
PRESENT(bad_modes_projector_down))
THEN
2223 matrix_s_inv_half_required = .true.
2224 matrix_s_half_required = .true.
2225 eps_zero_eigenvalues_required = .true.
2229 IF (.NOT.
PRESENT(subm_s_inv_half) .AND. matrix_s_inv_half_required)
THEN
2230 cpabort(
"S_inv_half SUBMATRICES ARE REQUIRED")
2232 IF (.NOT.
PRESENT(subm_s_half) .AND. matrix_s_half_required)
THEN
2233 cpabort(
"S_half SUBMATRICES ARE REQUIRED")
2235 IF (.NOT.
PRESENT(eps_zero_eigenvalues) .AND. eps_zero_eigenvalues_required)
THEN
2236 cpabort(
"EPS_ZERO_EIGENVALUES IS REQUIRED")
2238 IF (.NOT.
PRESENT(subm_s_inv) .AND. matrix_s_inv_required)
THEN
2239 cpabort(
"S_inv SUBMATRICES ARE REQUIRED")
2241 IF (.NOT.
PRESENT(subm_r_down) .AND. matrix_r_required)
THEN
2242 cpabort(
"R SUBMATRICES ARE REQUIRED")
2244 IF (.NOT.
PRESENT(matrix_trimmer) .AND. matrix_trimmer_required)
THEN
2245 cpabort(
"TRIMMER MATRIX IS REQUIRED")
2249 nblkcols_total=ndomains, &
2250 nblkrows_total=nblkrows_tot, &
2253 ALLOCATE (subm_main(ndomains))
2259 IF (my_action == -1)
THEN
2265 ALLOCATE (subm_tmp(ndomains))
2266 ALLOCATE (subm_tmp2(ndomains))
2270 subm_s_inv, 0.0_dp, subm_tmp)
2272 subm_main, 0.0_dp, subm_tmp2)
2276 subm_tmp, 1.0_dp, subm_main)
2279 DEALLOCATE (subm_tmp2)
2280 DEALLOCATE (subm_tmp)
2283 IF (my_skip_inversion)
THEN
2287 DO idomain = 1, ndomains
2290 IF (subm_main(idomain)%domain > 0)
THEN
2293 IF (idomain == 1)
THEN
2296 index1_start = map%index1(idomain - 1)
2298 index1_end = map%index1(idomain) - 1
2301 DO row = index1_start, index1_end
2302 neighbor = map%pairs(row, 1)
2303 n_domain_mos = n_domain_mos + nmos(neighbor)
2306 naos = subm_main(idomain)%nrows
2308 ALLOCATE (minv(naos, naos))
2310 IF (
PRESENT(bad_modes_projector_down))
THEN
2311 ALLOCATE (proj_array(naos, naos))
2312 CALL pseudo_invert_matrix(a=subm_main(idomain)%mdata, ainv=minv, n=naos, method=1, &
2313 range1=nmos(idomain), range2=n_domain_mos, &
2314 range1_thr=eps_zero_eigenvalues, &
2315 bad_modes_projector_down=proj_array, &
2316 s_inv_half=subm_s_inv_half(idomain)%mdata, &
2317 s_half=subm_s_half(idomain)%mdata &
2320 CALL pseudo_invert_matrix(a=subm_main(idomain)%mdata, ainv=minv, n=naos, method=1, &
2321 range1=nmos(idomain), range2=n_domain_mos)
2328 IF (
PRESENT(bad_modes_projector_down))
THEN
2329 CALL copy_submatrices(subm_main(idomain), bad_modes_projector_down(idomain), .false.)
2331 DEALLOCATE (proj_array)
2341 DEALLOCATE (subm_main)
2351 CALL timestop(handle)
2368 dpattern, map, node_of_domain)
2372 INTENT(INOUT) :: subm_s_sqrt, subm_s_sqrt_inv
2375 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2377 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_s_sqrt'
2379 INTEGER :: handle, idomain, naos, ndomains
2380 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: ssqrt, ssqrtinv
2382 DIMENSION(:) :: subm_s
2384 CALL timeset(routinen, handle)
2387 cpassert(
SIZE(subm_s_sqrt) == ndomains)
2388 cpassert(
SIZE(subm_s_sqrt_inv) == ndomains)
2389 ALLOCATE (subm_s(ndomains))
2396 DO idomain = 1, ndomains
2399 IF (subm_s(idomain)%domain > 0)
THEN
2401 naos = subm_s(idomain)%nrows
2403 ALLOCATE (ssqrt(naos, naos))
2404 ALLOCATE (ssqrtinv(naos, naos))
2406 CALL matrix_sqrt(a=subm_s(idomain)%mdata, asqrt=ssqrt, asqrtinv=ssqrtinv, &
2415 DEALLOCATE (ssqrtinv)
2425 CALL timestop(handle)
2444 INTENT(INOUT) :: subm_s_inv
2447 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2449 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_s_inv'
2451 INTEGER :: handle, idomain, naos, ndomains
2452 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: sinv
2454 DIMENSION(:) :: subm_s
2456 CALL timeset(routinen, handle)
2460 cpassert(
SIZE(subm_s_inv) == ndomains)
2461 ALLOCATE (subm_s(ndomains))
2468 DO idomain = 1, ndomains
2471 IF (subm_s(idomain)%domain > 0)
THEN
2473 naos = subm_s(idomain)%nrows
2475 ALLOCATE (sinv(naos, naos))
2477 CALL pseudo_invert_matrix(a=subm_s(idomain)%mdata, ainv=sinv, n=naos, &
2492 CALL timestop(handle)
2511 subm_r_down, dpattern, map, node_of_domain, filter_eps)
2513 TYPE(
dbcsr_type),
INTENT(IN) :: matrix_t, matrix_sigma_inv, matrix_s
2515 INTENT(INOUT) :: subm_r_down
2518 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2519 REAL(kind=
dp) :: filter_eps
2521 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_r_down'
2523 INTEGER :: handle, ndomains
2524 TYPE(
dbcsr_type) :: m_tmp_no_1, m_tmp_no_2, matrix_r
2526 CALL timeset(routinen, handle)
2530 template=matrix_s, &
2531 matrix_type=dbcsr_type_symmetric)
2533 template=matrix_t, &
2534 matrix_type=dbcsr_type_no_symmetry)
2536 template=matrix_t, &
2537 matrix_type=dbcsr_type_no_symmetry)
2540 0.0_dp, m_tmp_no_1, filter_eps=filter_eps)
2541 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, m_tmp_no_1, matrix_sigma_inv, &
2542 0.0_dp, m_tmp_no_2, filter_eps=filter_eps)
2544 0.0_dp, matrix_r, filter_eps=filter_eps)
2550 cpassert(
SIZE(subm_r_down) == ndomains)
2557 CALL timestop(handle)
2571 SUBROUTINE matrix_sqrt(A, Asqrt, Asqrtinv, N)
2573 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a
2574 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: asqrt, asqrtinv
2575 INTEGER,
INTENT(IN) :: n
2577 CHARACTER(len=*),
PARAMETER :: routinen =
'matrix_sqrt'
2579 INTEGER :: handle, info, jj, lwork, unit_nr
2580 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
2581 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: test, testn
2584 CALL timeset(routinen, handle)
2591 IF (logger%para_env%is_source())
THEN
2598 ALLOCATE (eigenvalues(n))
2601 ALLOCATE (work(max(1, lwork)))
2602 CALL dsyev(
'V',
'L', n, asqrtinv, n, eigenvalues, work, lwork, info)
2603 lwork = int(work(1))
2606 ALLOCATE (work(max(1, lwork)))
2607 CALL dsyev(
'V',
'L', n, asqrtinv, n, eigenvalues, work, lwork, info)
2609 IF (unit_nr > 0)
WRITE (unit_nr, *)
'DSYEV ERROR MESSAGE: ', info
2610 cpabort(
"DSYEV failed")
2616 ALLOCATE (test(n, n))
2618 test(jj, :) = asqrtinv(:, jj)*sqrt(eigenvalues(jj))
2620 ALLOCATE (testn(n, n))
2621 testn(:, :) = matmul(asqrtinv, test)
2625 test(jj, :) = asqrtinv(:, jj)/sqrt(eigenvalues(jj))
2627 testn(:, :) = matmul(asqrtinv, test)
2629 DEALLOCATE (test, testn)
2631 DEALLOCATE (eigenvalues)
2633 CALL timestop(handle)
2635 END SUBROUTINE matrix_sqrt
2656 SUBROUTINE pseudo_invert_matrix(A, Ainv, N, method, range1, range2, range1_thr, &
2657 shift, bad_modes_projector_down, s_inv_half, s_half)
2659 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a
2660 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: ainv
2661 INTEGER,
INTENT(IN) :: n, method
2662 INTEGER,
INTENT(IN),
OPTIONAL :: range1, range2
2663 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: range1_thr, shift
2664 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT), &
2665 OPTIONAL :: bad_modes_projector_down
2666 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
2667 OPTIONAL :: s_inv_half, s_half
2669 CHARACTER(len=*),
PARAMETER :: routinen =
'pseudo_invert_matrix'
2671 INTEGER :: handle, info, jj, lwork, range1_eiv, &
2672 range2_eiv, range3_eiv, unit_nr
2673 LOGICAL :: use_both, use_ranges_only, use_thr_only
2674 REAL(kind=
dp) :: my_shift
2675 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
2676 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: temp1, temp2, temp3, temp4
2679 CALL timeset(routinen, handle)
2683 IF (logger%para_env%is_source())
THEN
2689 IF (method == 1)
THEN
2691 IF ((
PRESENT(range1) .AND. (.NOT.
PRESENT(range2))) .OR. (
PRESENT(range2) .AND. (.NOT.
PRESENT(range1))))
THEN
2692 cpabort(
"range1 and range2 must be provided together")
2695 IF (
PRESENT(range1) .AND.
PRESENT(range1_thr))
THEN
2697 use_thr_only = .false.
2698 use_ranges_only = .false.
2702 IF (
PRESENT(range1))
THEN
2703 use_ranges_only = .true.
2705 use_ranges_only = .false.
2708 IF (
PRESENT(range1_thr))
THEN
2709 use_thr_only = .true.
2711 use_thr_only = .false.
2716 IF ((
PRESENT(s_half) .AND. (.NOT.
PRESENT(s_inv_half))) .OR. (
PRESENT(s_inv_half) .AND. (.NOT.
PRESENT(s_half))))
THEN
2717 cpabort(
"Domain overlap matrix missing")
2722 IF (
PRESENT(shift))
THEN
2729 SELECT CASE (method)
2735 ALLOCATE (eigenvalues(n))
2736 ALLOCATE (temp1(n, n))
2737 ALLOCATE (temp4(n, n))
2738 IF (
PRESENT(s_inv_half))
THEN
2739 CALL dsymm(
'L',
'U', n, n, 1.0_dp, s_inv_half, n, a, n, 0.0_dp, temp1, n)
2740 CALL dsymm(
'R',
'U', n, n, 1.0_dp, s_inv_half, n, temp1, n, 0.0_dp, ainv, n)
2744 ALLOCATE (work(max(1, lwork)))
2745 CALL dsyev(
'V',
'L', n, ainv, n, eigenvalues, work, lwork, info)
2747 lwork = int(work(1))
2750 ALLOCATE (work(max(1, lwork)))
2751 CALL dsyev(
'V',
'L', n, ainv, n, eigenvalues, work, lwork, info)
2754 IF (unit_nr > 0)
WRITE (unit_nr, *)
'EIGENSYSTEM ERROR MESSAGE: ', info
2755 cpabort(
"Eigenproblem routine failed")
2764 ALLOCATE (temp2(n, n))
2765 IF (
PRESENT(bad_modes_projector_down))
ALLOCATE (temp3(n, n))
2766 temp2(1:n, 1:n) = ainv(1:n, 1:n)
2774 IF ((jj <= range2) .AND. (eigenvalues(jj) < range1_thr))
THEN
2775 temp1(jj, :) = temp2(:, jj)*0.0_dp
2776 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2777 range1_eiv = range1_eiv + 1
2779 temp1(jj, :) = temp2(:, jj)/(eigenvalues(jj) + my_shift)
2780 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*0.0_dp
2781 range2_eiv = range2_eiv + 1
2785 IF (use_ranges_only)
THEN
2787 IF (jj <= range1)
THEN
2788 temp1(jj, :) = temp2(:, jj)*0.0_dp
2789 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2790 range1_eiv = range1_eiv + 1
2791 ELSE IF (jj <= range2)
THEN
2792 temp1(jj, :) = temp2(:, jj)*1.0_dp
2793 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2794 range2_eiv = range2_eiv + 1
2796 temp1(jj, :) = temp2(:, jj)/(eigenvalues(jj) + my_shift)
2797 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*0.0_dp
2798 range3_eiv = range3_eiv + 1
2801 ELSE IF (use_thr_only)
THEN
2803 IF (eigenvalues(jj) < range1_thr)
THEN
2804 temp1(jj, :) = temp2(:, jj)*0.0_dp
2805 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2806 range1_eiv = range1_eiv + 1
2808 temp1(jj, :) = temp2(:, jj)/(eigenvalues(jj) + my_shift)
2809 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*0.0_dp
2810 range2_eiv = range2_eiv + 1
2814 cpabort(
"Invert using Cholesky. It would be faster.")
2818 IF (
PRESENT(bad_modes_projector_down))
THEN
2819 IF (
PRESENT(s_half))
THEN
2820 CALL dsymm(
'L',
'U', n, n, 1.0_dp, s_half, n, temp2, n, 0.0_dp, ainv, n)
2821 CALL dsymm(
'R',
'U', n, n, 1.0_dp, s_half, n, temp3, n, 0.0_dp, temp4, n)
2822 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, ainv, n, temp4, n, 0.0_dp, bad_modes_projector_down, n)
2824 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, temp2, n, temp3, n, 0.0_dp, bad_modes_projector_down, n)
2828 IF (
PRESENT(s_inv_half))
THEN
2829 CALL dsymm(
'L',
'U', n, n, 1.0_dp, s_inv_half, n, temp2, n, 0.0_dp, temp4, n)
2830 CALL dsymm(
'R',
'U', n, n, 1.0_dp, s_inv_half, n, temp1, n, 0.0_dp, temp2, n)
2831 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, temp4, n, temp2, n, 0.0_dp, ainv, n)
2833 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, temp2, n, temp1, n, 0.0_dp, ainv, n)
2835 DEALLOCATE (temp1, temp2, temp4)
2836 IF (
PRESENT(bad_modes_projector_down))
DEALLOCATE (temp3)
2837 DEALLOCATE (eigenvalues)
2841 cpabort(
"Illegal method selected for matrix inversion")
2845 CALL timestop(handle)
2847 END SUBROUTINE pseudo_invert_matrix
2862 SUBROUTINE pseudo_matrix_power(A, Apow, power, N, range1, range1_thr, shift)
2864 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a
2865 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: apow
2866 REAL(kind=
dp),
INTENT(IN) :: power
2867 INTEGER,
INTENT(IN) :: n
2868 INTEGER,
INTENT(IN),
OPTIONAL :: range1
2869 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: range1_thr, shift
2871 CHARACTER(len=*),
PARAMETER :: routinen =
'pseudo_matrix_power'
2873 INTEGER :: handle, info, jj, lwork, range1_eiv, &
2875 LOGICAL :: use_both, use_ranges, use_thr
2876 REAL(kind=
dp) :: my_shift
2877 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
2878 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: temp1, temp2
2881 CALL timeset(routinen, handle)
2885 IF (logger%para_env%is_source())
THEN
2891 IF (
PRESENT(range1) .AND.
PRESENT(range1_thr))
THEN
2895 IF (
PRESENT(range1))
THEN
2898 use_ranges = .false.
2899 IF (
PRESENT(range1_thr))
THEN
2908 IF (
PRESENT(shift))
THEN
2916 ALLOCATE (eigenvalues(n))
2917 ALLOCATE (temp1(n, n))
2921 ALLOCATE (work(max(1, lwork)))
2922 CALL dsyev(
'V',
'L', n, apow, n, eigenvalues, work, lwork, info)
2924 lwork = int(work(1))
2927 ALLOCATE (work(max(1, lwork)))
2928 CALL dsyev(
'V',
'L', n, apow, n, eigenvalues, work, lwork, info)
2931 IF (unit_nr > 0)
WRITE (unit_nr, *)
'EIGENSYSTEM ERROR MESSAGE: ', info
2932 cpabort(
"Eigenproblem routine failed")
2941 ALLOCATE (temp2(n, n))
2943 temp2(1:n, 1:n) = apow(1:n, 1:n)
2950 IF ((jj <= range1) .AND. (eigenvalues(jj) < range1_thr))
THEN
2951 temp1(jj, :) = temp2(:, jj)*0.0_dp
2952 range1_eiv = range1_eiv + 1
2954 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
2958 IF (use_ranges)
THEN
2960 IF (jj <= range1)
THEN
2961 temp1(jj, :) = temp2(:, jj)*0.0_dp
2962 range1_eiv = range1_eiv + 1
2964 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
2970 IF (eigenvalues(jj) < range1_thr)
THEN
2971 temp1(jj, :) = temp2(:, jj)*0.0_dp
2973 range1_eiv = range1_eiv + 1
2975 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
2980 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
2986 apow = matmul(temp2, temp1)
2987 DEALLOCATE (temp1, temp2)
2988 DEALLOCATE (eigenvalues)
2990 CALL timestop(handle)
2992 END SUBROUTINE pseudo_matrix_power
3005 CHARACTER(len=*),
PARAMETER :: routinen =
'distribute_domains'
3007 INTEGER :: handle, idomain, least_loaded, nao, &
3009 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: index0
3010 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cpu_load, domain_load
3013 CALL timeset(routinen, handle)
3015 ndomains = almo_scf_env%ndomains
3019 ALLOCATE (domain_load(ndomains))
3020 DO idomain = 1, ndomains
3021 nao = almo_scf_env%nbasis_of_domain(idomain)
3022 domain_load(idomain) = (nao*nao*nao)*1.0_dp
3025 ALLOCATE (index0(ndomains))
3027 CALL sort(domain_load, ndomains, index0)
3029 ALLOCATE (cpu_load(ncpus))
3030 cpu_load(:) = 0.0_dp
3032 DO idomain = 1, ndomains
3033 least_loaded = minloc(cpu_load, 1)
3034 cpu_load(least_loaded) = cpu_load(least_loaded) + domain_load(idomain)
3035 almo_scf_env%cpu_of_domain(index0(idomain)) = least_loaded - 1
3038 DEALLOCATE (cpu_load)
3040 DEALLOCATE (domain_load)
3042 CALL timestop(handle)
3058 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix_no, dpattern
3060 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
3062 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_test'
3064 INTEGER :: handle, ndomains
3067 DIMENSION(:) :: subm_nn, subm_no
3070 CALL timeset(routinen, handle)
3072 CALL dbcsr_get_info(dpattern, group=group, nblkcols_total=ndomains)
3074 ALLOCATE (subm_no(ndomains), subm_nn(ndomains))
3095 DEALLOCATE (subm_no, subm_nn)
3097 CALL timestop(handle)
3124 m_overlap, m_sigma_tmpl, nspins, xalmo_history, assume_t0_q0x, &
3125 optimize_theta, envelope_amplitude, eps_filter, order_lanczos, eps_lanczos, &
3126 max_iter_lanczos, nocc_of_domain)
3128 TYPE(
dbcsr_type),
DIMENSION(:),
INTENT(INOUT) :: m_guess
3129 TYPE(
dbcsr_type),
DIMENSION(:),
INTENT(IN) :: m_t_in, m_t0, m_quench_t
3131 TYPE(
dbcsr_type),
DIMENSION(:),
INTENT(IN) :: m_sigma_tmpl
3132 INTEGER,
INTENT(IN) :: nspins
3134 LOGICAL,
INTENT(IN) :: assume_t0_q0x, optimize_theta
3135 REAL(kind=
dp),
INTENT(IN) :: envelope_amplitude, eps_filter
3136 INTEGER,
INTENT(IN) :: order_lanczos
3137 REAL(kind=
dp),
INTENT(IN) :: eps_lanczos
3138 INTEGER,
INTENT(IN) :: max_iter_lanczos
3139 INTEGER,
DIMENSION(:, :),
INTENT(IN) :: nocc_of_domain
3141 CHARACTER(len=*),
PARAMETER :: routinen =
'xalmo_initial_guess'
3143 INTEGER :: handle, iaspc, ispin, istore, naspc, &
3145 LOGICAL :: aspc_guess
3146 REAL(kind=
dp) :: alpha
3148 TYPE(
dbcsr_type) :: m_extrapolated, m_sigma_tmp
3150 CALL timeset(routinen, handle)
3154 IF (logger%para_env%is_source())
THEN
3160 IF (optimize_theta)
THEN
3161 cpwarn(
"unused option")
3163 alpha = envelope_amplitude
3168 IF (xalmo_history%istore == 0)
THEN
3169 aspc_guess = .false.
3175 IF (.NOT. aspc_guess)
THEN
3177 DO ispin = 1, nspins
3181 IF (assume_t0_q0x)
THEN
3185 CALL dbcsr_copy(m_guess(ispin), m_t_in(ispin))
3195 naspc = min(xalmo_history%istore, xalmo_history%nstore)
3196 IF (unit_nr > 0)
THEN
3197 WRITE (unit_nr, fmt=
"(/,T2,A,/,/,T3,A,I0)") &
3198 "Parameters for the always stable predictor-corrector (ASPC) method:", &
3199 "ASPC order: ", naspc
3202 DO ispin = 1, nspins
3205 template=m_quench_t(ispin), matrix_type=dbcsr_type_no_symmetry)
3207 template=m_sigma_tmpl(ispin), matrix_type=dbcsr_type_no_symmetry)
3215 istore = mod(xalmo_history%istore - iaspc, xalmo_history%nstore) + 1
3216 alpha = (-1.0_dp)**(iaspc + 1)*real(iaspc, kind=
dp)* &
3218 IF (unit_nr > 0)
THEN
3219 WRITE (unit_nr, fmt=
"(T3,A2,I0,A4,F10.6)") &
3220 "B(", iaspc,
") = ", alpha
3225 CALL dbcsr_copy(m_extrapolated, m_quench_t(ispin))
3234 xalmo_history%matrix_p_up_down(ispin, istore), &
3236 0.0_dp, m_extrapolated, &
3237 retain_sparsity=.true.)
3240 overlap=m_sigma_tmp, &
3242 retain_locality=.true., &
3243 only_normalize=.false., &
3244 nocc_of_domain=nocc_of_domain(:, ispin), &
3245 eps_filter=eps_filter, &
3246 order_lanczos=order_lanczos, &
3247 eps_lanczos=eps_lanczos, &
3248 max_iter_lanczos=max_iter_lanczos)
3251 CALL dbcsr_add(m_guess(ispin), m_extrapolated, &
3252 1.0_dp, (1.0_dp*alpha)/naspc)
3260 overlap=m_sigma_tmp, &
3262 retain_locality=.true., &
3263 only_normalize=.false., &
3264 nocc_of_domain=nocc_of_domain(:, ispin), &
3265 eps_filter=eps_filter, &
3266 order_lanczos=order_lanczos, &
3267 eps_lanczos=eps_lanczos, &
3268 max_iter_lanczos=max_iter_lanczos)
3274 IF (assume_t0_q0x)
THEN
3275 CALL dbcsr_add(m_guess(ispin), m_t0(ispin), &
3283 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)
...
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_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset, transposed)
...
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.