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 .EQ.
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 .GT. 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 .NE. 0) cpabort(
"DSYEV failed")
824 IF (almo_scf_env%domain_t(idomain, ispin)%ncols .NE. &
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 .NE. iblock_col)
THEN
944 cpabort(
"off-diagonal block found")
947 block_needed = .true.
948 IF (almo_scf_env%nocc_of_domain(iblock_col, ispin) .EQ. 0 .AND. &
949 almo_scf_env%nvirt_of_domain(iblock_col, ispin) .EQ. 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 .NE. 0) cpabort(
"DSYEV failed")
979 nocc_of_block = almo_scf_env%nocc_of_domain(iblock_col, ispin)
980 IF (nocc_of_block .GT. 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 .GT. 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)
1204 IF (info .NE. 0)
THEN
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
1322 CALL fermifixed(occupation_numbers(1 + neigenval_used:nocc_of_domain(idomain) + neigenval_used), &
1323 mu_of_domain(idomain), &
1325 mo_energies(1 + neigenval_used:nocc_of_domain(idomain) + neigenval_used), &
1326 real_ne_of_domain(idomain), &
1329 spin_kts = spin_kts + kts
1330 neigenval_used = neigenval_used + nocc_of_domain(idomain)
1332 rescaling_factors(:) = sqrt(occupation_numbers)
1357 DEALLOCATE (occupation_numbers)
1358 DEALLOCATE (rescaling_factors)
1360 CALL timestop(handle)
1378 SUBROUTINE get_overlap(bra, ket, overlap, metric, retain_overlap_sparsity, &
1384 LOGICAL,
INTENT(IN),
OPTIONAL :: retain_overlap_sparsity
1385 REAL(kind=
dp) :: eps_filter
1386 LOGICAL,
INTENT(IN),
OPTIONAL :: smear
1388 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_overlap'
1390 INTEGER :: dim0, handle
1391 LOGICAL :: local_retain_sparsity, smearing
1392 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: diag_correction
1395 CALL timeset(routinen, handle)
1397 IF (.NOT.
PRESENT(retain_overlap_sparsity))
THEN
1398 local_retain_sparsity = .false.
1400 local_retain_sparsity = retain_overlap_sparsity
1403 IF (.NOT.
PRESENT(smear))
THEN
1410 matrix_type=dbcsr_type_no_symmetry)
1414 metric, ket, 0.0_dp, tmp, &
1415 filter_eps=eps_filter)
1419 bra, tmp, 0.0_dp, overlap, &
1420 retain_sparsity=local_retain_sparsity, &
1421 filter_eps=eps_filter)
1433 ALLOCATE (diag_correction(dim0))
1434 diag_correction = 1.0_dp
1436 DEALLOCATE (diag_correction)
1439 CALL timestop(handle)
1463 nocc_of_domain, eps_filter, order_lanczos, eps_lanczos, &
1464 max_iter_lanczos, overlap_sqrti, smear)
1466 TYPE(
dbcsr_type),
INTENT(INOUT) :: ket, overlap
1468 LOGICAL,
INTENT(IN) :: retain_locality, only_normalize
1469 INTEGER,
DIMENSION(:),
INTENT(IN) :: nocc_of_domain
1470 REAL(kind=
dp) :: eps_filter
1471 INTEGER,
INTENT(IN) :: order_lanczos
1472 REAL(kind=
dp),
INTENT(IN) :: eps_lanczos
1473 INTEGER,
INTENT(IN) :: max_iter_lanczos
1474 TYPE(
dbcsr_type),
INTENT(INOUT),
OPTIONAL :: overlap_sqrti
1475 LOGICAL,
INTENT(IN),
OPTIONAL :: smear
1477 CHARACTER(LEN=*),
PARAMETER :: routinen =
'orthogonalize_mos'
1479 INTEGER :: dim0, handle
1481 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: diagonal
1483 matrix_sigma_blk_sqrt_inv, &
1486 CALL timeset(routinen, handle)
1488 IF (.NOT.
PRESENT(smear))
THEN
1501 CALL get_overlap(ket, ket, overlap, metric, retain_locality, &
1502 eps_filter, smear=smearing)
1504 IF (only_normalize)
THEN
1507 ALLOCATE (diagonal(dim0))
1511 DEALLOCATE (diagonal)
1516 CALL dbcsr_create(matrix_sigma_blk_sqrt, template=overlap, &
1517 matrix_type=dbcsr_type_no_symmetry)
1518 CALL dbcsr_create(matrix_sigma_blk_sqrt_inv, template=overlap, &
1519 matrix_type=dbcsr_type_no_symmetry)
1522 CALL set_zero_electron_blocks_in_mo_mo_matrix(overlap, nocc_of_domain, 1.0_dp)
1524 overlap, threshold=eps_filter, &
1525 order=order_lanczos, &
1526 eps_lanczos=eps_lanczos, &
1527 max_iter_lanczos=max_iter_lanczos)
1528 CALL set_zero_electron_blocks_in_mo_mo_matrix(overlap, nocc_of_domain, 0.0_dp)
1530 CALL set_zero_electron_blocks_in_mo_mo_matrix(matrix_sigma_blk_sqrt_inv, nocc_of_domain, 0.0_dp)
1534 matrix_type=dbcsr_type_no_symmetry)
1538 matrix_sigma_blk_sqrt_inv, &
1539 0.0_dp, matrix_t_blk_tmp, &
1540 filter_eps=eps_filter)
1546 IF (
PRESENT(overlap_sqrti))
THEN
1548 matrix_sigma_blk_sqrt_inv)
1555 CALL timestop(handle)
1585 use_guess, smear, algorithm, para_env, blacs_env, eps_lanczos, &
1586 max_iter_lanczos, inverse_accelerator, inv_eps_factor)
1590 REAL(kind=
dp),
INTENT(IN) :: eps_filter
1591 LOGICAL,
INTENT(IN) :: orthog_orbs
1592 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: nocc_of_domain
1594 TYPE(
dbcsr_type),
INTENT(INOUT),
OPTIONAL :: sigma, sigma_inv
1595 LOGICAL,
INTENT(IN),
OPTIONAL :: use_guess, smear
1596 INTEGER,
INTENT(IN),
OPTIONAL :: algorithm
1599 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: eps_lanczos
1600 INTEGER,
INTENT(IN),
OPTIONAL :: max_iter_lanczos, inverse_accelerator
1601 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: inv_eps_factor
1603 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_t_to_proj'
1605 INTEGER :: dim0, handle, my_accelerator, &
1607 LOGICAL :: smearing, use_sigma_inv_guess
1608 REAL(kind=
dp) :: my_inv_eps_factor
1609 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: diag_correction
1612 CALL timeset(routinen, handle)
1615 IF (.NOT. orthog_orbs)
THEN
1616 IF ((.NOT.
PRESENT(s)) .OR. (.NOT.
PRESENT(sigma)) .OR. &
1617 (.NOT.
PRESENT(sigma_inv)) .OR. (.NOT.
PRESENT(nocc_of_domain)))
THEN
1618 cpabort(
"Nonorthogonal orbitals need more input")
1623 IF (
PRESENT(algorithm)) my_algorithm = algorithm
1625 IF (my_algorithm == 1 .AND. (.NOT.
PRESENT(para_env) .OR. .NOT.
PRESENT(blacs_env))) &
1626 cpabort(
"PARA and BLACS env are necessary for cholesky algorithm")
1628 use_sigma_inv_guess = .false.
1629 IF (
PRESENT(use_guess))
THEN
1630 use_sigma_inv_guess = use_guess
1633 IF (.NOT.
PRESENT(smear))
THEN
1640 IF (
PRESENT(inverse_accelerator)) my_accelerator = inverse_accelerator
1642 my_inv_eps_factor = 10.0_dp
1643 IF (
PRESENT(inv_eps_factor)) my_inv_eps_factor = inv_eps_factor
1645 IF (orthog_orbs)
THEN
1648 0.0_dp, p, filter_eps=eps_filter)
1656 filter_eps=eps_filter)
1660 filter_eps=eps_filter)
1670 ALLOCATE (diag_correction(dim0))
1671 diag_correction = 1.0_dp
1673 DEALLOCATE (diag_correction)
1677 CALL set_zero_electron_blocks_in_mo_mo_matrix(sigma, nocc_of_domain, 1.0_dp)
1678 SELECT CASE (my_algorithm)
1682 matrix_inverse=sigma_inv, &
1684 use_inv_as_guess=use_sigma_inv_guess, &
1685 threshold=eps_filter*my_inv_eps_factor, &
1686 filter_eps=eps_filter, &
1695 matrix_inverse=sigma_inv, &
1697 use_inv_as_guess=use_sigma_inv_guess, &
1698 threshold=eps_filter*my_inv_eps_factor, &
1699 filter_eps=eps_filter, &
1700 accelerator_order=my_accelerator, &
1701 eps_lanczos=eps_lanczos, &
1702 max_iter_lanczos=max_iter_lanczos, &
1710 para_env=para_env, &
1711 blacs_env=blacs_env)
1713 para_env=para_env, &
1714 blacs_env=blacs_env, &
1715 uplo_to_full=.true.)
1718 cpabort(
"Illegal MO overalp inversion algorithm")
1720 CALL set_zero_electron_blocks_in_mo_mo_matrix(sigma, nocc_of_domain, 0.0_dp)
1721 CALL set_zero_electron_blocks_in_mo_mo_matrix(sigma_inv, nocc_of_domain, 0.0_dp)
1724 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, t, sigma_inv, 0.0_dp, t_tmp, &
1725 filter_eps=eps_filter)
1729 filter_eps=eps_filter)
1735 CALL timestop(handle)
1749 SUBROUTINE set_zero_electron_blocks_in_mo_mo_matrix(matrix, nocc_of_domain, value)
1752 INTEGER,
DIMENSION(:),
INTENT(IN) :: nocc_of_domain
1753 REAL(kind=
dp),
INTENT(IN) ::
value
1756 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: block
1764 IF (row == col .AND. nocc_of_domain(row) == 0)
THEN
1770 END SUBROUTINE set_zero_electron_blocks_in_mo_mo_matrix
1791 psi_projector_orthogonal, proj_in_template, eps_filter, sig_inv_projector, &
1796 TYPE(
dbcsr_type),
INTENT(IN) :: psi_projector, metric
1797 LOGICAL,
INTENT(IN) :: project_out, psi_projector_orthogonal
1798 TYPE(
dbcsr_type),
INTENT(IN) :: proj_in_template
1799 REAL(kind=
dp),
INTENT(IN) :: eps_filter
1800 TYPE(
dbcsr_type),
INTENT(IN),
OPTIONAL :: sig_inv_projector, sig_inv_template
1802 CHARACTER(LEN=*),
PARAMETER :: routinen =
'apply_projector'
1805 TYPE(
dbcsr_type) :: tmp_no, tmp_ov, tmp_ov2, tmp_sig, &
1808 CALL timeset(routinen, handle)
1813 metric, psi_projector, &
1815 filter_eps=eps_filter)
1822 filter_eps=eps_filter)
1824 IF (.NOT. psi_projector_orthogonal)
THEN
1827 template=proj_in_template)
1828 IF (
PRESENT(sig_inv_projector))
THEN
1830 template=sig_inv_projector)
1831 CALL dbcsr_copy(tmp_sig_inv, sig_inv_projector)
1833 IF (.NOT.
PRESENT(sig_inv_template))
THEN
1834 cpabort(
"PROGRAMMING ERROR: provide either template or sig_inv")
1838 template=sig_inv_template, &
1839 matrix_type=dbcsr_type_no_symmetry)
1841 psi_projector, tmp_no, 0.0_dp, tmp_sig, &
1842 filter_eps=eps_filter)
1844 template=sig_inv_template, &
1845 matrix_type=dbcsr_type_no_symmetry)
1847 threshold=eps_filter)
1851 tmp_sig_inv, tmp_ov, 0.0_dp, tmp_ov2, &
1852 filter_eps=eps_filter)
1861 psi_projector, tmp_ov, 0.0_dp, psi_out, &
1862 filter_eps=eps_filter)
1866 IF (project_out)
THEN
1867 CALL dbcsr_add(psi_out, psi_in, -1.0_dp, +1.0_dp)
1870 CALL timestop(handle)
1952 REAL(kind=
dp),
INTENT(IN) :: eps_filter
1954 CHARACTER(LEN=*),
PARAMETER :: routinen =
'generator_to_unitary'
1956 INTEGER :: handle, unit_nr
1957 LOGICAL :: safe_mode
1958 REAL(kind=
dp) :: frob_matrix, frob_matrix_base
1962 CALL timeset(routinen, handle)
1968 IF (logger%para_env%is_source())
THEN
1975 matrix_type=dbcsr_type_no_symmetry)
1977 matrix_type=dbcsr_type_no_symmetry)
1981 matrix_type=dbcsr_type_no_symmetry)
1984 CALL dbcsr_add(delta, x, 1.0_dp, -1.0_dp)
1988 CALL dbcsr_add(t1, delta, 1.0_dp, -1.0_dp)
1994 matrix_type=dbcsr_type_no_symmetry)
1996 filter_eps=eps_filter)
2000 IF (unit_nr > 0)
WRITE (unit_nr, *)
"Error for (inv(A)*A-I)", frob_matrix/frob_matrix_base
2005 filter_eps=eps_filter)
2011 matrix_type=dbcsr_type_no_symmetry)
2013 filter_eps=eps_filter)
2017 IF (unit_nr > 0)
WRITE (unit_nr, *)
"Error for (trn(U)*U-I)", frob_matrix/frob_matrix_base
2021 CALL timestop(handle)
2045 dpattern, map, node_of_domain, my_action, filter_eps, matrix_trimmer, use_trimmer)
2047 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix_in, matrix_out
2049 INTENT(IN) :: operator1
2051 INTENT(IN),
OPTIONAL :: operator2
2054 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2055 INTEGER,
INTENT(IN) :: my_action
2056 REAL(kind=
dp) :: filter_eps
2057 TYPE(
dbcsr_type),
INTENT(IN),
OPTIONAL :: matrix_trimmer
2058 LOGICAL,
INTENT(IN),
OPTIONAL :: use_trimmer
2060 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_domain_operators'
2062 INTEGER :: handle, ndomains
2063 LOGICAL :: matrix_trimmer_required, my_use_trimmer, &
2066 DIMENSION(:) :: subm_in, subm_out, subm_temp
2068 CALL timeset(routinen, handle)
2070 my_use_trimmer = .false.
2071 IF (
PRESENT(use_trimmer))
THEN
2072 my_use_trimmer = use_trimmer
2075 operator2_required = .false.
2076 matrix_trimmer_required = .false.
2078 IF (my_action .EQ. 1) operator2_required = .true.
2080 IF (my_use_trimmer)
THEN
2081 matrix_trimmer_required = .true.
2082 cpabort(
"TRIMMED PROJECTOR DISABLED!")
2085 IF (.NOT.
PRESENT(operator2) .AND. operator2_required)
THEN
2086 cpabort(
"SECOND OPERATOR IS REQUIRED")
2088 IF (.NOT.
PRESENT(matrix_trimmer) .AND. matrix_trimmer_required)
THEN
2089 cpabort(
"TRIMMER MATRIX IS REQUIRED")
2094 ALLOCATE (subm_in(ndomains))
2095 ALLOCATE (subm_temp(ndomains))
2096 ALLOCATE (subm_out(ndomains))
2110 IF (my_action .EQ. 0)
THEN
2113 subm_in, 0.0_dp, subm_out)
2114 ELSE IF (my_action .EQ. 1)
THEN
2118 subm_in, 0.0_dp, subm_temp)
2120 subm_temp, 1.0_dp, subm_out)
2122 cpabort(
"ILLEGAL ACTION")
2132 DEALLOCATE (subm_out)
2133 DEALLOCATE (subm_temp)
2134 DEALLOCATE (subm_in)
2136 CALL timestop(handle)
2164 subm_s_inv_half, subm_s_half, &
2165 subm_r_down, matrix_trimmer, &
2166 dpattern, map, node_of_domain, &
2168 bad_modes_projector_down, &
2170 eps_zero_eigenvalues, &
2171 my_action, skip_inversion)
2173 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix_main
2175 INTENT(IN),
OPTIONAL :: subm_s_inv, subm_s_inv_half, &
2176 subm_s_half, subm_r_down
2177 TYPE(
dbcsr_type),
INTENT(IN),
OPTIONAL :: matrix_trimmer
2180 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2184 INTENT(INOUT),
OPTIONAL :: bad_modes_projector_down
2185 LOGICAL,
INTENT(IN),
OPTIONAL :: use_trimmer
2186 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: eps_zero_eigenvalues
2187 INTEGER,
INTENT(IN) :: my_action
2188 LOGICAL,
INTENT(IN),
OPTIONAL :: skip_inversion
2190 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_preconditioner'
2192 INTEGER :: handle, idomain, index1_end, &
2193 index1_start, n_domain_mos, naos, &
2194 nblkrows_tot, ndomains, neighbor, row
2195 INTEGER,
DIMENSION(:),
POINTER :: nmos
2196 LOGICAL :: eps_zero_eigenvalues_required, matrix_r_required, matrix_s_half_required, &
2197 matrix_s_inv_half_required, matrix_s_inv_required, matrix_trimmer_required, &
2198 my_skip_inversion, my_use_trimmer
2199 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: minv, proj_array
2201 DIMENSION(:) :: subm_main, subm_tmp, subm_tmp2
2203 CALL timeset(routinen, handle)
2205 my_use_trimmer = .false.
2206 IF (
PRESENT(use_trimmer))
THEN
2207 my_use_trimmer = use_trimmer
2210 my_skip_inversion = .false.
2211 IF (
PRESENT(skip_inversion))
THEN
2212 my_skip_inversion = skip_inversion
2215 matrix_s_inv_half_required = .false.
2216 matrix_s_half_required = .false.
2217 eps_zero_eigenvalues_required = .false.
2218 matrix_s_inv_required = .false.
2219 matrix_trimmer_required = .false.
2220 matrix_r_required = .false.
2222 IF (my_action .EQ. -1) matrix_s_inv_required = .true.
2223 IF (my_action .EQ. -1) matrix_r_required = .true.
2224 IF (my_use_trimmer)
THEN
2225 matrix_trimmer_required = .true.
2226 cpabort(
"TRIMMED PRECONDITIONER DISABLED!")
2229 IF (
PRESENT(bad_modes_projector_down))
THEN
2230 matrix_s_inv_half_required = .true.
2231 matrix_s_half_required = .true.
2232 eps_zero_eigenvalues_required = .true.
2236 IF (.NOT.
PRESENT(subm_s_inv_half) .AND. matrix_s_inv_half_required)
THEN
2237 cpabort(
"S_inv_half SUBMATRICES ARE REQUIRED")
2239 IF (.NOT.
PRESENT(subm_s_half) .AND. matrix_s_half_required)
THEN
2240 cpabort(
"S_half SUBMATRICES ARE REQUIRED")
2242 IF (.NOT.
PRESENT(eps_zero_eigenvalues) .AND. eps_zero_eigenvalues_required)
THEN
2243 cpabort(
"EPS_ZERO_EIGENVALUES IS REQUIRED")
2245 IF (.NOT.
PRESENT(subm_s_inv) .AND. matrix_s_inv_required)
THEN
2246 cpabort(
"S_inv SUBMATRICES ARE REQUIRED")
2248 IF (.NOT.
PRESENT(subm_r_down) .AND. matrix_r_required)
THEN
2249 cpabort(
"R SUBMATRICES ARE REQUIRED")
2251 IF (.NOT.
PRESENT(matrix_trimmer) .AND. matrix_trimmer_required)
THEN
2252 cpabort(
"TRIMMER MATRIX IS REQUIRED")
2256 nblkcols_total=ndomains, &
2257 nblkrows_total=nblkrows_tot, &
2260 ALLOCATE (subm_main(ndomains))
2272 IF (my_action .EQ. -1)
THEN
2278 ALLOCATE (subm_tmp(ndomains))
2279 ALLOCATE (subm_tmp2(ndomains))
2283 subm_s_inv, 0.0_dp, subm_tmp)
2285 subm_main, 0.0_dp, subm_tmp2)
2289 subm_tmp, 1.0_dp, subm_main)
2292 DEALLOCATE (subm_tmp2)
2293 DEALLOCATE (subm_tmp)
2296 IF (my_skip_inversion)
THEN
2300 DO idomain = 1, ndomains
2303 IF (subm_main(idomain)%domain .GT. 0)
THEN
2306 IF (idomain .EQ. 1)
THEN
2309 index1_start = map%index1(idomain - 1)
2311 index1_end = map%index1(idomain) - 1
2314 DO row = index1_start, index1_end
2315 neighbor = map%pairs(row, 1)
2316 n_domain_mos = n_domain_mos + nmos(neighbor)
2319 naos = subm_main(idomain)%nrows
2322 ALLOCATE (minv(naos, naos))
2352 IF (
PRESENT(bad_modes_projector_down))
THEN
2353 ALLOCATE (proj_array(naos, naos))
2354 CALL pseudo_invert_matrix(a=subm_main(idomain)%mdata, ainv=minv, n=naos, method=1, &
2355 range1=nmos(idomain), range2=n_domain_mos, &
2356 range1_thr=eps_zero_eigenvalues, &
2357 bad_modes_projector_down=proj_array, &
2358 s_inv_half=subm_s_inv_half(idomain)%mdata, &
2359 s_half=subm_s_half(idomain)%mdata &
2362 CALL pseudo_invert_matrix(a=subm_main(idomain)%mdata, ainv=minv, n=naos, method=1, &
2363 range1=nmos(idomain), range2=n_domain_mos)
2371 IF (
PRESENT(bad_modes_projector_down))
THEN
2372 CALL copy_submatrices(subm_main(idomain), bad_modes_projector_down(idomain), .false.)
2374 DEALLOCATE (proj_array)
2384 DEALLOCATE (subm_main)
2394 CALL timestop(handle)
2411 dpattern, map, node_of_domain)
2415 INTENT(INOUT) :: subm_s_sqrt, subm_s_sqrt_inv
2418 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2420 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_s_sqrt'
2422 INTEGER :: handle, idomain, naos, ndomains
2423 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: ssqrt, ssqrtinv
2425 DIMENSION(:) :: subm_s
2427 CALL timeset(routinen, handle)
2430 cpassert(
SIZE(subm_s_sqrt) .EQ. ndomains)
2431 cpassert(
SIZE(subm_s_sqrt_inv) .EQ. ndomains)
2432 ALLOCATE (subm_s(ndomains))
2439 DO idomain = 1, ndomains
2442 IF (subm_s(idomain)%domain .GT. 0)
THEN
2444 naos = subm_s(idomain)%nrows
2446 ALLOCATE (ssqrt(naos, naos))
2447 ALLOCATE (ssqrtinv(naos, naos))
2449 CALL matrix_sqrt(a=subm_s(idomain)%mdata, asqrt=ssqrt, asqrtinv=ssqrtinv, &
2458 DEALLOCATE (ssqrtinv)
2468 CALL timestop(handle)
2487 INTENT(INOUT) :: subm_s_inv
2490 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2492 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_s_inv'
2494 INTEGER :: handle, idomain, naos, ndomains
2495 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: sinv
2497 DIMENSION(:) :: subm_s
2499 CALL timeset(routinen, handle)
2503 cpassert(
SIZE(subm_s_inv) .EQ. ndomains)
2504 ALLOCATE (subm_s(ndomains))
2511 DO idomain = 1, ndomains
2514 IF (subm_s(idomain)%domain .GT. 0)
THEN
2516 naos = subm_s(idomain)%nrows
2518 ALLOCATE (sinv(naos, naos))
2520 CALL pseudo_invert_matrix(a=subm_s(idomain)%mdata, ainv=sinv, n=naos, &
2535 CALL timestop(handle)
2554 subm_r_down, dpattern, map, node_of_domain, filter_eps)
2556 TYPE(
dbcsr_type),
INTENT(IN) :: matrix_t, matrix_sigma_inv, matrix_s
2558 INTENT(INOUT) :: subm_r_down
2561 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2562 REAL(kind=
dp) :: filter_eps
2564 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_r_down'
2566 INTEGER :: handle, ndomains
2567 TYPE(
dbcsr_type) :: m_tmp_no_1, m_tmp_no_2, matrix_r
2569 CALL timeset(routinen, handle)
2573 template=matrix_s, &
2574 matrix_type=dbcsr_type_symmetric)
2576 template=matrix_t, &
2577 matrix_type=dbcsr_type_no_symmetry)
2579 template=matrix_t, &
2580 matrix_type=dbcsr_type_no_symmetry)
2583 0.0_dp, m_tmp_no_1, filter_eps=filter_eps)
2584 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, m_tmp_no_1, matrix_sigma_inv, &
2585 0.0_dp, m_tmp_no_2, filter_eps=filter_eps)
2587 0.0_dp, matrix_r, filter_eps=filter_eps)
2593 cpassert(
SIZE(subm_r_down) .EQ. ndomains)
2600 CALL timestop(handle)
2614 SUBROUTINE matrix_sqrt(A, Asqrt, Asqrtinv, N)
2616 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a
2617 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: asqrt, asqrtinv
2618 INTEGER,
INTENT(IN) :: n
2620 CHARACTER(len=*),
PARAMETER :: routinen =
'matrix_sqrt'
2622 INTEGER :: handle, info, jj, lwork, unit_nr
2623 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
2624 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: test, testn
2627 CALL timeset(routinen, handle)
2634 IF (logger%para_env%is_source())
THEN
2659 ALLOCATE (eigenvalues(n))
2662 ALLOCATE (work(max(1, lwork)))
2663 CALL dsyev(
'V',
'L', n, asqrtinv, n, eigenvalues, work, lwork, info)
2664 lwork = int(work(1))
2667 ALLOCATE (work(max(1, lwork)))
2668 CALL dsyev(
'V',
'L', n, asqrtinv, n, eigenvalues, work, lwork, info)
2669 IF (info .NE. 0)
THEN
2670 IF (unit_nr > 0)
WRITE (unit_nr, *)
'DSYEV ERROR MESSAGE: ', info
2671 cpabort(
"DSYEV failed")
2677 ALLOCATE (test(n, n))
2679 test(jj, :) = asqrtinv(:, jj)*sqrt(eigenvalues(jj))
2681 ALLOCATE (testn(n, n))
2682 testn(:, :) = matmul(asqrtinv, test)
2686 test(jj, :) = asqrtinv(:, jj)/sqrt(eigenvalues(jj))
2688 testn(:, :) = matmul(asqrtinv, test)
2690 DEALLOCATE (test, testn)
2692 DEALLOCATE (eigenvalues)
2709 CALL timestop(handle)
2711 END SUBROUTINE matrix_sqrt
2732 SUBROUTINE pseudo_invert_matrix(A, Ainv, N, method, range1, range2, range1_thr, &
2733 shift, bad_modes_projector_down, s_inv_half, s_half)
2735 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a
2736 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: ainv
2737 INTEGER,
INTENT(IN) :: n, method
2738 INTEGER,
INTENT(IN),
OPTIONAL :: range1, range2
2739 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: range1_thr, shift
2740 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT), &
2741 OPTIONAL :: bad_modes_projector_down
2742 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
2743 OPTIONAL :: s_inv_half, s_half
2745 CHARACTER(len=*),
PARAMETER :: routinen =
'pseudo_invert_matrix'
2747 INTEGER :: handle, info, jj, lwork, range1_eiv, &
2748 range2_eiv, range3_eiv, unit_nr
2749 LOGICAL :: use_both, use_ranges_only, use_thr_only
2750 REAL(kind=
dp) :: my_shift
2751 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
2752 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: temp1, temp2, temp3, temp4
2755 CALL timeset(routinen, handle)
2759 IF (logger%para_env%is_source())
THEN
2765 IF (method .EQ. 1)
THEN
2767 IF ((
PRESENT(range1) .AND. (.NOT.
PRESENT(range2))) .OR. (
PRESENT(range2) .AND. (.NOT.
PRESENT(range1))))
THEN
2768 cpabort(
"range1 and range2 must be provided together")
2771 IF (
PRESENT(range1) .AND.
PRESENT(range1_thr))
THEN
2773 use_thr_only = .false.
2774 use_ranges_only = .false.
2778 IF (
PRESENT(range1))
THEN
2779 use_ranges_only = .true.
2781 use_ranges_only = .false.
2784 IF (
PRESENT(range1_thr))
THEN
2785 use_thr_only = .true.
2787 use_thr_only = .false.
2792 IF ((
PRESENT(s_half) .AND. (.NOT.
PRESENT(s_inv_half))) .OR. (
PRESENT(s_inv_half) .AND. (.NOT.
PRESENT(s_half))))
THEN
2793 cpabort(
"Domain overlap matrix missing")
2798 IF (
PRESENT(shift))
THEN
2805 SELECT CASE (method)
2811 ALLOCATE (eigenvalues(n))
2812 ALLOCATE (temp1(n, n))
2813 ALLOCATE (temp4(n, n))
2814 IF (
PRESENT(s_inv_half))
THEN
2815 CALL dsymm(
'L',
'U', n, n, 1.0_dp, s_inv_half, n, a, n, 0.0_dp, temp1, n)
2816 CALL dsymm(
'R',
'U', n, n, 1.0_dp, s_inv_half, n, temp1, n, 0.0_dp, ainv, n)
2820 ALLOCATE (work(max(1, lwork)))
2821 CALL dsyev(
'V',
'L', n, ainv, n, eigenvalues, work, lwork, info)
2823 lwork = int(work(1))
2826 ALLOCATE (work(max(1, lwork)))
2827 CALL dsyev(
'V',
'L', n, ainv, n, eigenvalues, work, lwork, info)
2829 IF (info .NE. 0)
THEN
2830 IF (unit_nr > 0)
WRITE (unit_nr, *)
'EIGENSYSTEM ERROR MESSAGE: ', info
2831 cpabort(
"Eigenproblem routine failed")
2840 ALLOCATE (temp2(n, n))
2841 IF (
PRESENT(bad_modes_projector_down))
ALLOCATE (temp3(n, n))
2842 temp2(1:n, 1:n) = ainv(1:n, 1:n)
2850 IF ((jj .LE. range2) .AND. (eigenvalues(jj) .LT. range1_thr))
THEN
2851 temp1(jj, :) = temp2(:, jj)*0.0_dp
2852 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2853 range1_eiv = range1_eiv + 1
2855 temp1(jj, :) = temp2(:, jj)/(eigenvalues(jj) + my_shift)
2856 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*0.0_dp
2857 range2_eiv = range2_eiv + 1
2861 IF (use_ranges_only)
THEN
2863 IF (jj .LE. range1)
THEN
2864 temp1(jj, :) = temp2(:, jj)*0.0_dp
2865 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2866 range1_eiv = range1_eiv + 1
2867 ELSE IF (jj .LE. range2)
THEN
2868 temp1(jj, :) = temp2(:, jj)*1.0_dp
2869 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2870 range2_eiv = range2_eiv + 1
2872 temp1(jj, :) = temp2(:, jj)/(eigenvalues(jj) + my_shift)
2873 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*0.0_dp
2874 range3_eiv = range3_eiv + 1
2877 ELSE IF (use_thr_only)
THEN
2879 IF (eigenvalues(jj) .LT. range1_thr)
THEN
2880 temp1(jj, :) = temp2(:, jj)*0.0_dp
2881 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2882 range1_eiv = range1_eiv + 1
2884 temp1(jj, :) = temp2(:, jj)/(eigenvalues(jj) + my_shift)
2885 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*0.0_dp
2886 range2_eiv = range2_eiv + 1
2890 cpabort(
"Invert using Cholesky. It would be faster.")
2894 IF (
PRESENT(bad_modes_projector_down))
THEN
2895 IF (
PRESENT(s_half))
THEN
2896 CALL dsymm(
'L',
'U', n, n, 1.0_dp, s_half, n, temp2, n, 0.0_dp, ainv, n)
2897 CALL dsymm(
'R',
'U', n, n, 1.0_dp, s_half, n, temp3, n, 0.0_dp, temp4, n)
2898 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, ainv, n, temp4, n, 0.0_dp, bad_modes_projector_down, n)
2900 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, temp2, n, temp3, n, 0.0_dp, bad_modes_projector_down, n)
2904 IF (
PRESENT(s_inv_half))
THEN
2905 CALL dsymm(
'L',
'U', n, n, 1.0_dp, s_inv_half, n, temp2, n, 0.0_dp, temp4, n)
2906 CALL dsymm(
'R',
'U', n, n, 1.0_dp, s_inv_half, n, temp1, n, 0.0_dp, temp2, n)
2907 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, temp4, n, temp2, n, 0.0_dp, ainv, n)
2909 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, temp2, n, temp1, n, 0.0_dp, ainv, n)
2911 DEALLOCATE (temp1, temp2, temp4)
2912 IF (
PRESENT(bad_modes_projector_down))
DEALLOCATE (temp3)
2913 DEALLOCATE (eigenvalues)
2917 cpabort(
"Illegal method selected for matrix inversion")
2936 CALL timestop(handle)
2938 END SUBROUTINE pseudo_invert_matrix
2953 SUBROUTINE pseudo_matrix_power(A, Apow, power, N, range1, range1_thr, shift)
2955 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a
2956 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: apow
2957 REAL(kind=
dp),
INTENT(IN) :: power
2958 INTEGER,
INTENT(IN) :: n
2959 INTEGER,
INTENT(IN),
OPTIONAL :: range1
2960 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: range1_thr, shift
2962 CHARACTER(len=*),
PARAMETER :: routinen =
'pseudo_matrix_power'
2964 INTEGER :: handle, info, jj, lwork, range1_eiv, &
2966 LOGICAL :: use_both, use_ranges, use_thr
2967 REAL(kind=
dp) :: my_shift
2968 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
2969 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: temp1, temp2
2972 CALL timeset(routinen, handle)
2976 IF (logger%para_env%is_source())
THEN
2982 IF (
PRESENT(range1) .AND.
PRESENT(range1_thr))
THEN
2986 IF (
PRESENT(range1))
THEN
2989 use_ranges = .false.
2990 IF (
PRESENT(range1_thr))
THEN
2999 IF (
PRESENT(shift))
THEN
3007 ALLOCATE (eigenvalues(n))
3008 ALLOCATE (temp1(n, n))
3012 ALLOCATE (work(max(1, lwork)))
3013 CALL dsyev(
'V',
'L', n, apow, n, eigenvalues, work, lwork, info)
3015 lwork = int(work(1))
3018 ALLOCATE (work(max(1, lwork)))
3019 CALL dsyev(
'V',
'L', n, apow, n, eigenvalues, work, lwork, info)
3021 IF (info .NE. 0)
THEN
3022 IF (unit_nr > 0)
WRITE (unit_nr, *)
'EIGENSYSTEM ERROR MESSAGE: ', info
3023 cpabort(
"Eigenproblem routine failed")
3032 ALLOCATE (temp2(n, n))
3034 temp2(1:n, 1:n) = apow(1:n, 1:n)
3041 IF ((jj .LE. range1) .AND. (eigenvalues(jj) .LT. range1_thr))
THEN
3042 temp1(jj, :) = temp2(:, jj)*0.0_dp
3043 range1_eiv = range1_eiv + 1
3045 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
3049 IF (use_ranges)
THEN
3051 IF (jj .LE. range1)
THEN
3052 temp1(jj, :) = temp2(:, jj)*0.0_dp
3053 range1_eiv = range1_eiv + 1
3055 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
3061 IF (eigenvalues(jj) .LT. range1_thr)
THEN
3062 temp1(jj, :) = temp2(:, jj)*0.0_dp
3064 range1_eiv = range1_eiv + 1
3066 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
3071 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
3077 apow = matmul(temp2, temp1)
3078 DEALLOCATE (temp1, temp2)
3079 DEALLOCATE (eigenvalues)
3081 CALL timestop(handle)
3083 END SUBROUTINE pseudo_matrix_power
3096 CHARACTER(len=*),
PARAMETER :: routinen =
'distribute_domains'
3098 INTEGER :: handle, idomain, least_loaded, nao, &
3100 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: index0
3101 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cpu_load, domain_load
3104 CALL timeset(routinen, handle)
3106 ndomains = almo_scf_env%ndomains
3110 ALLOCATE (domain_load(ndomains))
3111 DO idomain = 1, ndomains
3112 nao = almo_scf_env%nbasis_of_domain(idomain)
3113 domain_load(idomain) = (nao*nao*nao)*1.0_dp
3116 ALLOCATE (index0(ndomains))
3118 CALL sort(domain_load, ndomains, index0)
3120 ALLOCATE (cpu_load(ncpus))
3121 cpu_load(:) = 0.0_dp
3123 DO idomain = 1, ndomains
3124 least_loaded = minloc(cpu_load, 1)
3125 cpu_load(least_loaded) = cpu_load(least_loaded) + domain_load(idomain)
3126 almo_scf_env%cpu_of_domain(index0(idomain)) = least_loaded - 1
3129 DEALLOCATE (cpu_load)
3131 DEALLOCATE (domain_load)
3133 CALL timestop(handle)
3149 TYPE(
dbcsr_type),
INTENT(INOUT) :: matrix_no, dpattern
3151 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
3153 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_test'
3155 INTEGER :: handle, ndomains
3158 DIMENSION(:) :: subm_nn, subm_no
3161 CALL timeset(routinen, handle)
3163 CALL dbcsr_get_info(dpattern, group=group, nblkcols_total=ndomains)
3165 ALLOCATE (subm_no(ndomains), subm_nn(ndomains))
3186 DEALLOCATE (subm_no, subm_nn)
3188 CALL timestop(handle)
3215 m_overlap, m_sigma_tmpl, nspins, xalmo_history, assume_t0_q0x, &
3216 optimize_theta, envelope_amplitude, eps_filter, order_lanczos, eps_lanczos, &
3217 max_iter_lanczos, nocc_of_domain)
3219 TYPE(
dbcsr_type),
DIMENSION(:),
INTENT(INOUT) :: m_guess
3220 TYPE(
dbcsr_type),
DIMENSION(:),
INTENT(IN) :: m_t_in, m_t0, m_quench_t
3222 TYPE(
dbcsr_type),
DIMENSION(:),
INTENT(IN) :: m_sigma_tmpl
3223 INTEGER,
INTENT(IN) :: nspins
3225 LOGICAL,
INTENT(IN) :: assume_t0_q0x, optimize_theta
3226 REAL(kind=
dp),
INTENT(IN) :: envelope_amplitude, eps_filter
3227 INTEGER,
INTENT(IN) :: order_lanczos
3228 REAL(kind=
dp),
INTENT(IN) :: eps_lanczos
3229 INTEGER,
INTENT(IN) :: max_iter_lanczos
3230 INTEGER,
DIMENSION(:, :),
INTENT(IN) :: nocc_of_domain
3232 CHARACTER(len=*),
PARAMETER :: routinen =
'xalmo_initial_guess'
3234 INTEGER :: handle, iaspc, ispin, istore, naspc, &
3236 LOGICAL :: aspc_guess
3237 REAL(kind=
dp) :: alpha
3239 TYPE(
dbcsr_type) :: m_extrapolated, m_sigma_tmp
3241 CALL timeset(routinen, handle)
3245 IF (logger%para_env%is_source())
THEN
3251 IF (optimize_theta)
THEN
3252 cpwarn(
"unused option")
3254 alpha = envelope_amplitude
3259 IF (xalmo_history%istore == 0)
THEN
3260 aspc_guess = .false.
3266 IF (.NOT. aspc_guess)
THEN
3268 DO ispin = 1, nspins
3272 IF (assume_t0_q0x)
THEN
3276 CALL dbcsr_copy(m_guess(ispin), m_t_in(ispin))
3286 naspc = min(xalmo_history%istore, xalmo_history%nstore)
3287 IF (unit_nr > 0)
THEN
3288 WRITE (unit_nr, fmt=
"(/,T2,A,/,/,T3,A,I0)") &
3289 "Parameters for the always stable predictor-corrector (ASPC) method:", &
3290 "ASPC order: ", naspc
3293 DO ispin = 1, nspins
3296 template=m_quench_t(ispin), matrix_type=dbcsr_type_no_symmetry)
3298 template=m_sigma_tmpl(ispin), matrix_type=dbcsr_type_no_symmetry)
3306 istore = mod(xalmo_history%istore - iaspc, xalmo_history%nstore) + 1
3307 alpha = (-1.0_dp)**(iaspc + 1)*real(iaspc, kind=
dp)* &
3309 IF (unit_nr > 0)
THEN
3310 WRITE (unit_nr, fmt=
"(T3,A2,I0,A4,F10.6)") &
3311 "B(", iaspc,
") = ", alpha
3316 CALL dbcsr_copy(m_extrapolated, m_quench_t(ispin))
3325 xalmo_history%matrix_p_up_down(ispin, istore), &
3327 0.0_dp, m_extrapolated, &
3328 retain_sparsity=.true.)
3331 overlap=m_sigma_tmp, &
3333 retain_locality=.true., &
3334 only_normalize=.false., &
3335 nocc_of_domain=nocc_of_domain(:, ispin), &
3336 eps_filter=eps_filter, &
3337 order_lanczos=order_lanczos, &
3338 eps_lanczos=eps_lanczos, &
3339 max_iter_lanczos=max_iter_lanczos)
3342 CALL dbcsr_add(m_guess(ispin), m_extrapolated, &
3343 1.0_dp, (1.0_dp*alpha)/naspc)
3351 overlap=m_sigma_tmp, &
3353 retain_locality=.true., &
3354 only_normalize=.false., &
3355 nocc_of_domain=nocc_of_domain(:, ispin), &
3356 eps_filter=eps_filter, &
3357 order_lanczos=order_lanczos, &
3358 eps_lanczos=eps_lanczos, &
3359 max_iter_lanczos=max_iter_lanczos)
3365 IF (assume_t0_q0x)
THEN
3366 CALL dbcsr_add(m_guess(ispin), m_t0(ispin), &
3374 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
deal with the Fermi distribution, compute it, fix mu, get derivs
subroutine, public fermifixed(f, mu, kts, e, n, t, maxocc, estate, festate)
returns occupations according to Fermi-Dirac statistics for a given set of energies and number of ele...
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
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.