27 USE dbcsr_api,
ONLY: &
28 dbcsr_add, dbcsr_add_on_diag, dbcsr_copy, dbcsr_create, dbcsr_distribution_get, &
29 dbcsr_distribution_type, dbcsr_filter, dbcsr_finalize, dbcsr_frobenius_norm, &
30 dbcsr_get_block_p, dbcsr_get_diag, dbcsr_get_info, dbcsr_get_stored_coordinates, &
31 dbcsr_init_random, dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, &
32 dbcsr_iterator_start, dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_multiply, &
33 dbcsr_nblkcols_total, dbcsr_nblkrows_total, dbcsr_print, dbcsr_release, &
34 dbcsr_reserve_block2d, dbcsr_scale_by_vector, dbcsr_set, dbcsr_set_diag, dbcsr_transposed, &
35 dbcsr_type, dbcsr_type_no_symmetry, dbcsr_type_symmetric, dbcsr_work_create
41 domain_submatrix_type,&
60 #include "./base/base_uses.f90"
66 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'almo_scf_methods'
96 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix
98 INTEGER :: col, hold, iblock_col, iblock_row, &
99 mynode, nblkcols_tot, nblkrows_tot, row
101 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: p_new_block
102 TYPE(dbcsr_distribution_type) :: dist
104 CALL dbcsr_get_info(matrix, distribution=dist)
105 CALL dbcsr_distribution_get(dist, mynode=mynode)
106 CALL dbcsr_work_create(matrix, work_mutable=.true.)
107 nblkrows_tot = dbcsr_nblkrows_total(matrix)
108 nblkcols_tot = dbcsr_nblkcols_total(matrix)
109 DO row = 1, nblkrows_tot
110 DO col = 1, nblkcols_tot
114 CALL dbcsr_get_stored_coordinates(matrix, &
115 iblock_row, iblock_col, hold)
116 IF (hold .EQ. mynode)
THEN
117 NULLIFY (p_new_block)
118 CALL dbcsr_reserve_block2d(matrix, &
119 iblock_row, iblock_col, p_new_block)
120 cpassert(
ASSOCIATED(p_new_block))
121 p_new_block(:, :) = 1.0_dp
125 CALL dbcsr_finalize(matrix)
139 TYPE(almo_scf_env_type),
INTENT(INOUT) :: almo_scf_env
141 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_ks_to_ks_xx'
143 INTEGER :: handle, ispin, ndomains
144 REAL(kind=
dp) :: eps_multiply
145 TYPE(dbcsr_type) :: matrix_tmp1, matrix_tmp2, matrix_tmp3, matrix_tmp4, matrix_tmp5, &
146 matrix_tmp6, matrix_tmp7, matrix_tmp8, matrix_tmp9
147 TYPE(domain_submatrix_type),
ALLOCATABLE, &
148 DIMENSION(:) :: subm_tmp1, subm_tmp2, subm_tmp3
150 CALL timeset(routinen, handle)
152 eps_multiply = almo_scf_env%eps_filter
154 DO ispin = 1, almo_scf_env%nspins
156 ndomains = dbcsr_nblkcols_total(almo_scf_env%quench_t(ispin))
160 almo_scf_env%matrix_ks(ispin), &
161 almo_scf_env%domain_ks_xx(:, ispin), &
162 almo_scf_env%quench_t(ispin), &
163 almo_scf_env%domain_map(ispin), &
164 almo_scf_env%cpu_of_domain, &
173 CALL dbcsr_create(matrix_tmp1, &
174 template=almo_scf_env%matrix_t(ispin))
175 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_ks(ispin), &
176 almo_scf_env%matrix_t(ispin), &
177 0.0_dp, matrix_tmp1, &
178 filter_eps=eps_multiply)
183 CALL dbcsr_create(matrix_tmp2, &
184 template=almo_scf_env%matrix_t(ispin))
185 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_tmp1, &
186 almo_scf_env%matrix_sigma_inv(ispin), &
187 0.0_dp, matrix_tmp2, &
188 filter_eps=eps_multiply)
192 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_s(1), &
193 almo_scf_env%matrix_t(ispin), &
194 0.0_dp, matrix_tmp1, &
195 filter_eps=eps_multiply)
200 CALL dbcsr_create(matrix_tmp4, &
201 template=almo_scf_env%matrix_s(1), &
202 matrix_type=dbcsr_type_no_symmetry)
203 CALL dbcsr_multiply(
"N",
"T", 1.0_dp, matrix_tmp2, &
205 0.0_dp, matrix_tmp4, &
206 filter_eps=eps_multiply)
209 ALLOCATE (subm_tmp1(ndomains))
210 CALL init_submatrices(subm_tmp1)
214 almo_scf_env%quench_t(ispin), &
215 almo_scf_env%domain_map(ispin), &
216 almo_scf_env%cpu_of_domain, &
218 CALL add_submatrices(1.0_dp, almo_scf_env%domain_ks_xx(:, ispin), &
219 -1.0_dp, subm_tmp1,
'N')
220 CALL add_submatrices(1.0_dp, almo_scf_env%domain_ks_xx(:, ispin), &
221 -1.0_dp, subm_tmp1,
'T')
226 CALL dbcsr_create(matrix_tmp3, &
227 template=almo_scf_env%matrix_t(ispin), &
228 matrix_type=dbcsr_type_no_symmetry)
229 CALL dbcsr_multiply(
"T",
"N", 1.0_dp, &
231 almo_scf_env%matrix_t(ispin), &
232 0.0_dp, matrix_tmp3, &
233 filter_eps=eps_multiply)
234 CALL dbcsr_release(matrix_tmp4)
239 CALL dbcsr_create(matrix_tmp6, &
240 template=almo_scf_env%matrix_t(ispin), &
241 matrix_type=dbcsr_type_no_symmetry)
242 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, &
244 almo_scf_env%matrix_sigma_inv(ispin), &
245 0.0_dp, matrix_tmp6, &
246 filter_eps=eps_multiply)
251 CALL dbcsr_copy(almo_scf_env%matrix_err_xx(ispin), &
252 almo_scf_env%quench_t(ispin))
253 CALL dbcsr_copy(almo_scf_env%matrix_err_xx(ispin), &
254 matrix_tmp2, keep_sparsity=.true.)
255 CALL dbcsr_create(matrix_tmp4, &
256 template=almo_scf_env%matrix_t(ispin), &
257 matrix_type=dbcsr_type_no_symmetry)
258 CALL dbcsr_copy(matrix_tmp4, &
259 almo_scf_env%quench_t(ispin))
260 CALL dbcsr_copy(matrix_tmp4, &
261 matrix_tmp6, keep_sparsity=.true.)
262 CALL dbcsr_add(almo_scf_env%matrix_err_xx(ispin), &
263 matrix_tmp4, 1.0_dp, -1.0_dp)
264 CALL dbcsr_release(matrix_tmp4)
270 CALL dbcsr_copy(matrix_tmp3, &
272 CALL dbcsr_add(matrix_tmp3, &
273 matrix_tmp6, 1.0_dp, -1.0_dp)
274 CALL dbcsr_create(matrix_tmp4, &
275 template=almo_scf_env%matrix_s(1), &
276 matrix_type=dbcsr_type_no_symmetry)
277 CALL dbcsr_multiply(
"N",
"T", 1.0_dp, &
279 almo_scf_env%matrix_t(ispin), &
280 0.0_dp, matrix_tmp4, &
281 filter_eps=eps_multiply)
284 almo_scf_env%domain_err(:, ispin), &
285 almo_scf_env%quench_t(ispin), &
286 almo_scf_env%domain_map(ispin), &
287 almo_scf_env%cpu_of_domain, &
289 CALL dbcsr_release(matrix_tmp4)
292 ALLOCATE (subm_tmp2(ndomains))
293 CALL init_submatrices(subm_tmp2)
294 CALL multiply_submatrices(
'N',
'N', 1.0_dp, &
295 almo_scf_env%domain_err(:, ispin), &
296 almo_scf_env%domain_s_sqrt(:, ispin), 0.0_dp, subm_tmp2)
297 CALL multiply_submatrices(
'N',
'N', 1.0_dp, &
298 almo_scf_env%domain_s_sqrt_inv(:, ispin), &
299 subm_tmp2, 0.0_dp, almo_scf_env%domain_err(:, ispin))
307 CALL dbcsr_create(matrix_tmp5, &
308 template=almo_scf_env%matrix_s(1), &
309 matrix_type=dbcsr_type_no_symmetry)
310 CALL dbcsr_multiply(
"N",
"T", 1.0_dp, &
313 0.0_dp, matrix_tmp5, &
314 filter_eps=eps_multiply)
320 almo_scf_env%quench_t(ispin), &
321 almo_scf_env%domain_map(ispin), &
322 almo_scf_env%cpu_of_domain, &
324 CALL dbcsr_release(matrix_tmp5)
325 CALL add_submatrices(1.0_dp, almo_scf_env%domain_ks_xx(:, ispin), &
326 1.0_dp, subm_tmp1,
'N')
329 ALLOCATE (subm_tmp3(ndomains))
330 CALL init_submatrices(subm_tmp3)
334 almo_scf_env%quench_t(ispin), &
335 almo_scf_env%domain_map(ispin), &
336 almo_scf_env%cpu_of_domain, &
341 almo_scf_env%quench_t(ispin), &
342 almo_scf_env%domain_map(ispin), &
343 almo_scf_env%cpu_of_domain, &
345 CALL dbcsr_release(matrix_tmp6)
346 CALL add_submatrices(1.0_dp, subm_tmp2, &
347 -1.0_dp, subm_tmp3,
'N')
351 almo_scf_env%quench_t(ispin), &
352 almo_scf_env%domain_map(ispin), &
353 almo_scf_env%cpu_of_domain, &
355 CALL multiply_submatrices(
'N',
'T', 1.0_dp, subm_tmp2, &
356 subm_tmp3, 0.0_dp, subm_tmp1)
357 CALL add_submatrices(1.0_dp, almo_scf_env%domain_ks_xx(:, ispin), &
358 1.0_dp, subm_tmp1,
'N')
359 CALL add_submatrices(1.0_dp, almo_scf_env%domain_ks_xx(:, ispin), &
360 1.0_dp, subm_tmp1,
'T')
363 CALL dbcsr_create(matrix_tmp7, &
364 template=almo_scf_env%matrix_sigma_blk(ispin), &
365 matrix_type=dbcsr_type_no_symmetry)
366 CALL dbcsr_multiply(
"T",
"N", 1.0_dp, &
367 almo_scf_env%matrix_t(ispin), &
369 0.0_dp, matrix_tmp7, &
370 filter_eps=eps_multiply)
373 CALL dbcsr_create(matrix_tmp8, &
374 template=almo_scf_env%matrix_sigma_blk(ispin), &
375 matrix_type=dbcsr_type_symmetric)
376 CALL dbcsr_copy(matrix_tmp8, almo_scf_env%matrix_sigma_blk(ispin))
377 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, &
378 almo_scf_env%matrix_sigma_inv(ispin), &
380 0.0_dp, matrix_tmp8, &
381 retain_sparsity=.true., &
382 filter_eps=eps_multiply)
383 CALL dbcsr_release(matrix_tmp7)
386 CALL dbcsr_create(matrix_tmp9, &
387 template=almo_scf_env%matrix_t(ispin), &
388 matrix_type=dbcsr_type_no_symmetry)
389 CALL dbcsr_copy(matrix_tmp9, almo_scf_env%quench_t(ispin))
390 CALL dbcsr_copy(matrix_tmp9, matrix_tmp1, keep_sparsity=.true.)
393 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, &
396 0.0_dp, matrix_tmp3, &
397 filter_eps=eps_multiply)
398 CALL dbcsr_release(matrix_tmp8)
399 CALL dbcsr_release(matrix_tmp9)
405 almo_scf_env%quench_t(ispin), &
406 almo_scf_env%domain_map(ispin), &
407 almo_scf_env%cpu_of_domain, &
409 CALL multiply_submatrices(
'N',
'T', 1.0_dp, subm_tmp2, &
410 subm_tmp3, 0.0_dp, subm_tmp1)
411 CALL add_submatrices(1.0_dp, almo_scf_env%domain_ks_xx(:, ispin), &
412 1.0_dp, subm_tmp1,
'N')
458 CALL release_submatrices(subm_tmp3)
459 CALL release_submatrices(subm_tmp2)
460 CALL release_submatrices(subm_tmp1)
461 DEALLOCATE (subm_tmp3)
462 DEALLOCATE (subm_tmp2)
463 DEALLOCATE (subm_tmp1)
464 CALL dbcsr_release(matrix_tmp3)
465 CALL dbcsr_release(matrix_tmp2)
466 CALL dbcsr_release(matrix_tmp1)
470 CALL timestop(handle)
484 TYPE(almo_scf_env_type),
INTENT(INOUT) :: almo_scf_env
486 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_ks_to_ks_blk'
488 INTEGER :: handle, ispin
489 REAL(kind=
dp) :: eps_multiply
490 TYPE(dbcsr_type) :: matrix_tmp1, matrix_tmp2, matrix_tmp3, matrix_tmp4, matrix_tmp5, &
491 matrix_tmp6, matrix_tmp7, matrix_tmp8, matrix_tmp9, matrix_tmp_err
493 CALL timeset(routinen, handle)
495 eps_multiply = almo_scf_env%eps_filter
497 DO ispin = 1, almo_scf_env%nspins
502 CALL dbcsr_create(matrix_tmp1, &
503 template=almo_scf_env%matrix_t(ispin))
504 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_ks(ispin), &
505 almo_scf_env%matrix_t_blk(ispin), &
506 0.0_dp, matrix_tmp1, &
507 filter_eps=eps_multiply)
511 CALL dbcsr_create(matrix_tmp2, &
512 template=almo_scf_env%matrix_t(ispin))
513 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_tmp1, &
514 almo_scf_env%matrix_sigma_inv(ispin), &
515 0.0_dp, matrix_tmp2, &
516 filter_eps=eps_multiply)
528 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_s(1), &
529 almo_scf_env%matrix_t_blk(ispin), &
530 0.0_dp, matrix_tmp1, &
531 filter_eps=eps_multiply)
536 CALL dbcsr_create(matrix_tmp4, &
537 template=almo_scf_env%matrix_s_blk(1), &
538 matrix_type=dbcsr_type_no_symmetry)
539 CALL dbcsr_copy(matrix_tmp4, almo_scf_env%matrix_s_blk(1))
540 CALL dbcsr_multiply(
"N",
"T", 1.0_dp, matrix_tmp2, &
542 0.0_dp, matrix_tmp4, &
543 retain_sparsity=.true., &
544 filter_eps=eps_multiply)
547 CALL dbcsr_copy(almo_scf_env%matrix_ks_blk(ispin), &
548 almo_scf_env%matrix_ks(ispin), keep_sparsity=.true.)
549 CALL dbcsr_add(almo_scf_env%matrix_ks_blk(ispin), &
556 CALL dbcsr_create(matrix_tmp5, &
557 template=almo_scf_env%matrix_s_blk(1), &
558 matrix_type=dbcsr_type_no_symmetry)
559 CALL dbcsr_transposed(matrix_tmp5, matrix_tmp4)
560 CALL dbcsr_add(almo_scf_env%matrix_ks_blk(ispin), matrix_tmp5, &
566 CALL dbcsr_create(matrix_tmp3, &
567 template=almo_scf_env%matrix_sigma_inv(ispin), &
568 matrix_type=dbcsr_type_no_symmetry)
569 CALL dbcsr_multiply(
"T",
"N", 1.0_dp, &
570 almo_scf_env%matrix_t_blk(ispin), &
572 0.0_dp, matrix_tmp3, &
573 filter_eps=eps_multiply)
578 CALL dbcsr_create(matrix_tmp6, &
579 template=almo_scf_env%matrix_sigma_inv(ispin), &
580 matrix_type=dbcsr_type_no_symmetry)
581 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, &
582 almo_scf_env%matrix_sigma_inv(ispin), &
584 0.0_dp, matrix_tmp6, &
585 filter_eps=eps_multiply)
590 CALL dbcsr_release(matrix_tmp3)
591 CALL dbcsr_create(matrix_tmp3, &
592 template=almo_scf_env%matrix_t(ispin))
593 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_tmp1, &
595 0.0_dp, matrix_tmp3, &
596 filter_eps=eps_multiply)
613 cpassert(almo_scf_env%almo_update_algorithm .EQ.
almo_scf_diag)
615 CALL dbcsr_create(matrix_tmp_err, &
616 template=almo_scf_env%matrix_t_blk(ispin))
617 CALL dbcsr_copy(matrix_tmp_err, &
619 CALL dbcsr_add(matrix_tmp_err, matrix_tmp3, &
622 CALL dbcsr_copy(almo_scf_env%matrix_err_blk(ispin), &
623 almo_scf_env%matrix_s_blk_sqrt(1))
624 CALL dbcsr_multiply(
"N",
"T", 1.0_dp, matrix_tmp_err, &
625 almo_scf_env%matrix_t_blk(ispin), &
626 0.0_dp, almo_scf_env%matrix_err_blk(ispin), &
627 retain_sparsity=.true., &
628 filter_eps=eps_multiply)
629 CALL dbcsr_release(matrix_tmp_err)
632 CALL dbcsr_create(matrix_tmp_err, &
633 template=almo_scf_env%matrix_err_blk(ispin))
634 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, &
635 almo_scf_env%matrix_err_blk(ispin), &
636 almo_scf_env%matrix_s_blk_sqrt(1), &
637 0.0_dp, matrix_tmp_err, &
638 filter_eps=eps_multiply)
639 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, &
640 almo_scf_env%matrix_s_blk_sqrt_inv(1), &
642 0.0_dp, almo_scf_env%matrix_err_blk(ispin), &
643 filter_eps=eps_multiply)
646 CALL dbcsr_transposed(matrix_tmp_err, &
647 almo_scf_env%matrix_err_blk(ispin))
648 CALL dbcsr_add(almo_scf_env%matrix_err_blk(ispin), &
651 CALL dbcsr_release(matrix_tmp_err)
659 CALL dbcsr_create(matrix_tmp9, &
660 template=almo_scf_env%matrix_sigma_blk(ispin), &
661 matrix_type=dbcsr_type_no_symmetry)
662 CALL dbcsr_copy(matrix_tmp9, almo_scf_env%matrix_sigma_blk(ispin))
663 CALL dbcsr_copy(matrix_tmp9, matrix_tmp6, keep_sparsity=.true.)
664 CALL dbcsr_release(matrix_tmp6)
669 CALL dbcsr_multiply(
"N",
"T", 1.0_dp, matrix_tmp3, &
671 1.0_dp, almo_scf_env%matrix_ks_blk(ispin), &
672 retain_sparsity=.true., &
673 filter_eps=eps_multiply)
683 CALL dbcsr_create(matrix_tmp7, &
684 template=almo_scf_env%matrix_t_blk(ispin))
688 CALL dbcsr_copy(matrix_tmp7, almo_scf_env%matrix_t_blk(ispin))
689 CALL dbcsr_copy(matrix_tmp7, matrix_tmp3, keep_sparsity=.true.)
690 CALL dbcsr_release(matrix_tmp3)
692 CALL dbcsr_create(matrix_tmp8, &
693 template=almo_scf_env%matrix_t_blk(ispin))
694 CALL dbcsr_copy(matrix_tmp8, almo_scf_env%matrix_t_blk(ispin))
695 CALL dbcsr_copy(matrix_tmp8, matrix_tmp1, keep_sparsity=.true.)
696 CALL dbcsr_release(matrix_tmp1)
697 CALL dbcsr_multiply(
"N",
"T", 1.0_dp, matrix_tmp7, &
699 0.0_dp, matrix_tmp4, &
700 filter_eps=eps_multiply, &
701 retain_sparsity=.true.)
704 CALL dbcsr_add(almo_scf_env%matrix_ks_blk(ispin), matrix_tmp4, &
709 CALL dbcsr_transposed(matrix_tmp5, matrix_tmp4)
710 CALL dbcsr_add(almo_scf_env%matrix_ks_blk(ispin), matrix_tmp5, &
715 CALL dbcsr_copy(matrix_tmp7, matrix_tmp2, keep_sparsity=.true.)
716 CALL dbcsr_release(matrix_tmp2)
717 CALL dbcsr_multiply(
"N",
"T", 1.0_dp, matrix_tmp7, &
719 0.0_dp, matrix_tmp4, &
720 retain_sparsity=.true., &
721 filter_eps=eps_multiply)
723 CALL dbcsr_add(almo_scf_env%matrix_ks_blk(ispin), matrix_tmp4, &
727 CALL dbcsr_transposed(matrix_tmp5, matrix_tmp4)
728 CALL dbcsr_release(matrix_tmp4)
729 CALL dbcsr_add(almo_scf_env%matrix_ks_blk(ispin), matrix_tmp5, &
731 CALL dbcsr_release(matrix_tmp5)
735 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_tmp8, &
737 0.0_dp, matrix_tmp7, &
738 retain_sparsity=.true., &
739 filter_eps=eps_multiply)
740 CALL dbcsr_release(matrix_tmp9)
744 CALL dbcsr_multiply(
"N",
"T", 1.0_dp, matrix_tmp7, &
746 1.0_dp, almo_scf_env%matrix_ks_blk(ispin), &
747 retain_sparsity=.true., &
748 filter_eps=eps_multiply)
749 CALL dbcsr_release(matrix_tmp7)
750 CALL dbcsr_release(matrix_tmp8)
754 CALL timestop(handle)
769 TYPE(almo_scf_env_type),
INTENT(INOUT) :: almo_scf_env
771 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_ks_xx_to_tv_xx'
773 INTEGER :: handle, iblock_size, idomain, info, &
774 ispin, lwork, ndomains
775 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
776 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: data_copy
777 TYPE(domain_submatrix_type),
ALLOCATABLE, &
778 DIMENSION(:) :: subm_ks_xx_orthog, subm_t, subm_tmp
780 CALL timeset(routinen, handle)
784 cpabort(
"a domain must be located entirely on a CPU")
787 ndomains = almo_scf_env%ndomains
788 ALLOCATE (subm_tmp(ndomains))
789 ALLOCATE (subm_ks_xx_orthog(ndomains))
790 ALLOCATE (subm_t(ndomains))
792 DO ispin = 1, almo_scf_env%nspins
794 CALL init_submatrices(subm_tmp)
795 CALL init_submatrices(subm_ks_xx_orthog)
814 CALL multiply_submatrices(
'N',
'N', 1.0_dp, almo_scf_env%domain_ks_xx(:, ispin), &
815 almo_scf_env%domain_s_sqrt_inv(:, ispin), 0.0_dp, subm_tmp)
816 CALL multiply_submatrices(
'N',
'N', 1.0_dp, almo_scf_env%domain_s_sqrt_inv(:, ispin), &
817 subm_tmp, 0.0_dp, subm_ks_xx_orthog)
818 CALL release_submatrices(subm_tmp)
822 CALL init_submatrices(subm_t)
825 DO idomain = 1, ndomains
828 IF (subm_ks_xx_orthog(idomain)%domain .GT. 0)
THEN
830 iblock_size = subm_ks_xx_orthog(idomain)%nrows
833 ALLOCATE (eigenvalues(iblock_size))
834 ALLOCATE (data_copy(iblock_size, iblock_size))
835 data_copy(:, :) = subm_ks_xx_orthog(idomain)%mdata(:, :)
839 ALLOCATE (work(max(1, lwork)))
840 CALL dsyev(
'V',
'L', iblock_size, data_copy, iblock_size, eigenvalues, work, lwork, info)
845 ALLOCATE (work(max(1, lwork)))
846 CALL dsyev(
'V',
'L', iblock_size, data_copy, iblock_size, eigenvalues, work, lwork, info)
847 IF (info .NE. 0)
THEN
848 cpabort(
"DSYEV failed")
852 IF (almo_scf_env%domain_t(idomain, ispin)%ncols .NE. &
853 almo_scf_env%nocc_of_domain(idomain, ispin))
THEN
854 cpabort(
"wrong domain structure")
856 CALL copy_submatrices(almo_scf_env%domain_t(idomain, ispin), &
857 subm_t(idomain), .false.)
861 IF (almo_scf_env%smear)
THEN
862 almo_scf_env%mo_energies(1 + sum(almo_scf_env%nocc_of_domain(:idomain - 1, ispin)) &
863 :sum(almo_scf_env%nocc_of_domain(:idomain, ispin)), ispin) &
864 = eigenvalues(1:almo_scf_env%nocc_of_domain(idomain, ispin))
868 DEALLOCATE (data_copy)
869 DEALLOCATE (eigenvalues)
875 CALL release_submatrices(subm_ks_xx_orthog)
878 CALL multiply_submatrices(
'N',
'N', 1.0_dp, almo_scf_env%domain_s_sqrt_inv(:, ispin), &
879 subm_t, 0.0_dp, almo_scf_env%domain_t(:, ispin))
880 CALL release_submatrices(subm_t)
884 almo_scf_env%matrix_t(ispin), &
885 almo_scf_env%domain_t(:, ispin), &
886 almo_scf_env%quench_t(ispin))
887 CALL dbcsr_filter(almo_scf_env%matrix_t(ispin), &
888 almo_scf_env%eps_filter)
896 DEALLOCATE (subm_tmp)
897 DEALLOCATE (subm_ks_xx_orthog)
900 CALL timestop(handle)
916 TYPE(almo_scf_env_type),
INTENT(INOUT) :: almo_scf_env
918 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_ks_blk_to_tv_blk'
920 INTEGER :: handle, iblock_col, iblock_row, &
921 iblock_size, info, ispin, lwork, &
922 nocc_of_block, nvirt_of_block,
orbital
923 LOGICAL :: block_needed
924 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
925 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: data_copy
926 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: data_p, p_new_block
927 TYPE(dbcsr_iterator_type) :: iter
928 TYPE(dbcsr_type) :: matrix_ks_blk_orthog, &
929 matrix_t_blk_orthog, matrix_tmp, &
932 CALL timeset(routinen, handle)
936 cpabort(
"a domain must be located entirely on a CPU")
939 DO ispin = 1, almo_scf_env%nspins
941 CALL dbcsr_create(matrix_tmp, template=almo_scf_env%matrix_ks_blk(ispin), &
942 matrix_type=dbcsr_type_no_symmetry)
943 CALL dbcsr_create(matrix_ks_blk_orthog, template=almo_scf_env%matrix_ks_blk(ispin), &
944 matrix_type=dbcsr_type_no_symmetry)
947 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_ks_blk(ispin), &
948 almo_scf_env%matrix_s_blk_sqrt_inv(1), 0.0_dp, matrix_tmp, &
949 filter_eps=almo_scf_env%eps_filter)
950 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_s_blk_sqrt_inv(1), &
951 matrix_tmp, 0.0_dp, matrix_ks_blk_orthog, &
952 filter_eps=almo_scf_env%eps_filter)
954 CALL dbcsr_release(matrix_tmp)
958 CALL dbcsr_create(matrix_t_blk_orthog, template=almo_scf_env%matrix_t_blk(ispin))
959 CALL dbcsr_create(matrix_v_blk_orthog, template=almo_scf_env%matrix_v_full_blk(ispin))
960 CALL dbcsr_work_create(matrix_t_blk_orthog, work_mutable=.true.)
961 CALL dbcsr_work_create(matrix_v_blk_orthog, work_mutable=.true.)
963 CALL dbcsr_work_create(almo_scf_env%matrix_eoo(ispin), work_mutable=.true.)
964 CALL dbcsr_work_create(almo_scf_env%matrix_evv_full(ispin), work_mutable=.true.)
966 CALL dbcsr_iterator_start(iter, matrix_ks_blk_orthog)
968 DO WHILE (dbcsr_iterator_blocks_left(iter))
969 CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, data_p, row_size=iblock_size)
971 IF (iblock_row .NE. iblock_col)
THEN
972 cpabort(
"off-diagonal block found")
975 block_needed = .true.
976 IF (almo_scf_env%nocc_of_domain(iblock_col, ispin) .EQ. 0 .AND. &
977 almo_scf_env%nvirt_of_domain(iblock_col, ispin) .EQ. 0)
THEN
978 block_needed = .false.
981 IF (block_needed)
THEN
984 ALLOCATE (eigenvalues(iblock_size))
985 ALLOCATE (data_copy(iblock_size, iblock_size))
986 data_copy(:, :) = data_p(:, :)
990 ALLOCATE (work(max(1, lwork)))
991 CALL dsyev(
'V',
'L', iblock_size, data_copy, iblock_size, eigenvalues, work, lwork, info)
996 ALLOCATE (work(max(1, lwork)))
997 CALL dsyev(
'V',
'L', iblock_size, data_copy, iblock_size, eigenvalues, work, lwork, info)
998 IF (info .NE. 0)
THEN
999 cpabort(
"DSYEV failed")
1009 nocc_of_block = almo_scf_env%nocc_of_domain(iblock_col, ispin)
1010 IF (nocc_of_block .GT. 0)
THEN
1011 NULLIFY (p_new_block)
1012 CALL dbcsr_reserve_block2d(matrix_t_blk_orthog, iblock_row, iblock_col, p_new_block)
1013 cpassert(
ASSOCIATED(p_new_block))
1014 p_new_block(:, :) = data_copy(:, 1:nocc_of_block)
1016 NULLIFY (p_new_block)
1017 CALL dbcsr_reserve_block2d(almo_scf_env%matrix_eoo(ispin), iblock_row, iblock_col, p_new_block)
1018 cpassert(
ASSOCIATED(p_new_block))
1019 p_new_block(:, :) = 0.0_dp
1030 IF (almo_scf_env%smear)
THEN
1032 almo_scf_env%mo_energies(sum(almo_scf_env%nocc_of_domain(:iblock_row - 1, ispin)) +
orbital, &
1039 nvirt_of_block = almo_scf_env%nvirt_of_domain(iblock_col, ispin)
1040 IF (nvirt_of_block .GT. 0)
THEN
1041 NULLIFY (p_new_block)
1042 CALL dbcsr_reserve_block2d(matrix_v_blk_orthog, iblock_row, iblock_col, p_new_block)
1043 cpassert(
ASSOCIATED(p_new_block))
1044 p_new_block(:, :) = data_copy(:, (nocc_of_block + 1):(nocc_of_block + nvirt_of_block))
1046 NULLIFY (p_new_block)
1047 CALL dbcsr_reserve_block2d(almo_scf_env%matrix_evv_full(ispin), iblock_row, iblock_col, p_new_block)
1048 cpassert(
ASSOCIATED(p_new_block))
1049 p_new_block(:, :) = 0.0_dp
1050 DO orbital = 1, nvirt_of_block
1056 DEALLOCATE (data_copy)
1057 DEALLOCATE (eigenvalues)
1062 CALL dbcsr_iterator_stop(iter)
1064 CALL dbcsr_finalize(matrix_t_blk_orthog)
1065 CALL dbcsr_finalize(matrix_v_blk_orthog)
1066 CALL dbcsr_finalize(almo_scf_env%matrix_eoo(ispin))
1067 CALL dbcsr_finalize(almo_scf_env%matrix_evv_full(ispin))
1076 CALL dbcsr_filter(matrix_t_blk_orthog, almo_scf_env%eps_filter)
1077 CALL dbcsr_filter(matrix_v_blk_orthog, almo_scf_env%eps_filter)
1079 CALL dbcsr_release(matrix_ks_blk_orthog)
1082 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_s_blk_sqrt_inv(1), &
1083 matrix_t_blk_orthog, 0.0_dp, almo_scf_env%matrix_t_blk(ispin), &
1084 filter_eps=almo_scf_env%eps_filter)
1085 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_s_blk_sqrt_inv(1), &
1086 matrix_v_blk_orthog, 0.0_dp, almo_scf_env%matrix_v_full_blk(ispin), &
1087 filter_eps=almo_scf_env%eps_filter)
1089 CALL dbcsr_release(matrix_t_blk_orthog)
1090 CALL dbcsr_release(matrix_v_blk_orthog)
1094 CALL timestop(handle)
1109 TYPE(dbcsr_type),
INTENT(IN) :: matrix_in
1110 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_out
1111 INTEGER,
DIMENSION(:) :: nocc
1113 CHARACTER(LEN=*),
PARAMETER :: routinen =
'pseudo_invert_diagonal_blk'
1115 INTEGER :: handle, iblock_col, iblock_row, &
1116 iblock_size, methodid
1117 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: data_copy
1118 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: data_p, p_new_block
1119 TYPE(dbcsr_iterator_type) :: iter
1121 CALL timeset(routinen, handle)
1123 CALL dbcsr_create(matrix_out, template=matrix_in)
1124 CALL dbcsr_work_create(matrix_out, work_mutable=.true.)
1126 CALL dbcsr_iterator_start(iter, matrix_in)
1128 DO WHILE (dbcsr_iterator_blocks_left(iter))
1130 CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, data_p, row_size=iblock_size)
1132 IF (iblock_row == iblock_col)
THEN
1135 ALLOCATE (data_copy(iblock_size, iblock_size))
1141 CALL pseudo_invert_matrix(data_p, data_copy, iblock_size, &
1143 range1=nocc(iblock_row), range2=nocc(iblock_row), &
1149 NULLIFY (p_new_block)
1150 CALL dbcsr_reserve_block2d(matrix_out, iblock_row, iblock_col, p_new_block)
1151 cpassert(
ASSOCIATED(p_new_block))
1152 p_new_block(:, :) = data_copy(:, :)
1154 DEALLOCATE (data_copy)
1159 CALL dbcsr_iterator_stop(iter)
1161 CALL dbcsr_finalize(matrix_out)
1163 CALL timestop(handle)
1177 TYPE(almo_scf_env_type),
INTENT(INOUT) :: almo_scf_env
1178 LOGICAL,
INTENT(IN) :: ionic
1180 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_p_blk_to_t_blk'
1182 INTEGER :: handle, iblock_col, iblock_row, &
1183 iblock_size, info, ispin, lwork, &
1184 nocc_of_block, unit_nr
1185 LOGICAL :: block_needed
1186 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
1187 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: data_copy
1188 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: data_p, p_new_block
1189 TYPE(cp_logger_type),
POINTER :: logger
1190 TYPE(dbcsr_iterator_type) :: iter
1191 TYPE(dbcsr_type) :: matrix_t_blk_tmp
1193 CALL timeset(routinen, handle)
1197 IF (logger%para_env%is_source())
THEN
1203 DO ispin = 1, almo_scf_env%nspins
1208 CALL dbcsr_create(matrix_t_blk_tmp, &
1209 template=almo_scf_env%matrix_t_blk(ispin))
1210 CALL dbcsr_work_create(matrix_t_blk_tmp, &
1211 work_mutable=.true.)
1213 CALL dbcsr_iterator_start(iter, almo_scf_env%matrix_p_blk(ispin))
1214 DO WHILE (dbcsr_iterator_blocks_left(iter))
1215 CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, data_p, row_size=iblock_size)
1217 block_needed = .false.
1219 IF (iblock_row == iblock_col)
THEN
1220 block_needed = .true.
1223 IF (.NOT. block_needed)
THEN
1224 cpabort(
"off-diag block found")
1228 ALLOCATE (eigenvalues(iblock_size))
1229 ALLOCATE (data_copy(iblock_size, iblock_size))
1230 data_copy(:, :) = data_p(:, :)
1234 ALLOCATE (work(max(1, lwork)))
1235 CALL dsyev(
'V',
'L', iblock_size, data_copy, iblock_size, eigenvalues, &
1237 lwork = int(work(1))
1241 ALLOCATE (work(max(1, lwork)))
1242 CALL dsyev(
'V',
'L', iblock_size, data_copy, iblock_size, eigenvalues, work, lwork, info)
1243 IF (info .NE. 0)
THEN
1244 IF (unit_nr > 0)
THEN
1245 WRITE (unit_nr, *)
'BLOCK = ', iblock_row
1246 WRITE (unit_nr, *)
'INFO =', info
1247 WRITE (unit_nr, *) data_p(:, :)
1249 cpabort(
"DSYEV failed")
1256 NULLIFY (p_new_block)
1257 CALL dbcsr_reserve_block2d(matrix_t_blk_tmp, &
1258 iblock_row, iblock_col, p_new_block)
1259 nocc_of_block =
SIZE(p_new_block, 2)
1260 cpassert(
ASSOCIATED(p_new_block))
1261 cpassert(nocc_of_block .GT. 0)
1262 p_new_block(:, :) = data_copy(:, iblock_size - nocc_of_block + 1:)
1265 DEALLOCATE (data_copy)
1266 DEALLOCATE (eigenvalues)
1269 CALL dbcsr_iterator_stop(iter)
1271 CALL dbcsr_finalize(matrix_t_blk_tmp)
1272 CALL dbcsr_filter(matrix_t_blk_tmp, &
1273 almo_scf_env%eps_filter)
1274 CALL dbcsr_copy(almo_scf_env%matrix_t_blk(ispin), &
1276 CALL dbcsr_release(matrix_t_blk_tmp)
1282 CALL dbcsr_init_random(almo_scf_env%matrix_t_blk(ispin), &
1283 keep_sparsity=.true.)
1285 CALL dbcsr_create(matrix_t_blk_tmp, &
1286 template=almo_scf_env%matrix_t_blk(ispin), &
1287 matrix_type=dbcsr_type_no_symmetry)
1291 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, almo_scf_env%matrix_s_blk(1), &
1292 almo_scf_env%matrix_t_blk(ispin), &
1293 0.0_dp, matrix_t_blk_tmp, &
1294 filter_eps=almo_scf_env%eps_filter)
1296 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, &
1297 almo_scf_env%matrix_p_blk(ispin), matrix_t_blk_tmp, &
1298 0.0_dp, almo_scf_env%matrix_t_blk(ispin), &
1299 filter_eps=almo_scf_env%eps_filter)
1301 CALL dbcsr_release(matrix_t_blk_tmp)
1307 CALL timestop(handle)
1328 spin_kTS, smear_e_temp, ndomains, nocc_of_domain)
1330 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_t
1331 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: mo_energies
1332 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: mu_of_domain, real_ne_of_domain
1333 REAL(kind=
dp),
INTENT(INOUT) :: spin_kts
1334 REAL(kind=
dp),
INTENT(IN) :: smear_e_temp
1335 INTEGER,
INTENT(IN) :: ndomains
1336 INTEGER,
DIMENSION(:),
INTENT(IN) :: nocc_of_domain
1338 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_t_rescaling'
1340 INTEGER :: handle, idomain, neigenval_used, nmo
1341 REAL(kind=
dp) :: kts
1342 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: occupation_numbers, rescaling_factors
1344 CALL timeset(routinen, handle)
1349 nmo =
SIZE(mo_energies)
1350 ALLOCATE (occupation_numbers(nmo))
1351 ALLOCATE (rescaling_factors(nmo))
1364 DO idomain = 1, ndomains
1365 CALL fermifixed(occupation_numbers(1 + neigenval_used:nocc_of_domain(idomain) + neigenval_used), &
1366 mu_of_domain(idomain), &
1368 mo_energies(1 + neigenval_used:nocc_of_domain(idomain) + neigenval_used), &
1369 real_ne_of_domain(idomain), &
1372 spin_kts = spin_kts + kts
1373 neigenval_used = neigenval_used + nocc_of_domain(idomain)
1375 rescaling_factors(:) = sqrt(occupation_numbers)
1388 CALL dbcsr_scale_by_vector(matrix_t, rescaling_factors, side=
'right')
1400 DEALLOCATE (occupation_numbers)
1401 DEALLOCATE (rescaling_factors)
1403 CALL timestop(handle)
1421 SUBROUTINE get_overlap(bra, ket, overlap, metric, retain_overlap_sparsity, &
1424 TYPE(dbcsr_type),
INTENT(IN) :: bra, ket
1425 TYPE(dbcsr_type),
INTENT(INOUT) :: overlap
1426 TYPE(dbcsr_type),
INTENT(IN) :: metric
1427 LOGICAL,
INTENT(IN),
OPTIONAL :: retain_overlap_sparsity
1428 REAL(kind=
dp) :: eps_filter
1429 LOGICAL,
INTENT(IN),
OPTIONAL :: smear
1431 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_overlap'
1433 INTEGER :: dim0, handle
1434 LOGICAL :: local_retain_sparsity, smearing
1435 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: diag_correction
1436 TYPE(dbcsr_type) :: tmp
1438 CALL timeset(routinen, handle)
1440 IF (.NOT.
PRESENT(retain_overlap_sparsity))
THEN
1441 local_retain_sparsity = .false.
1443 local_retain_sparsity = retain_overlap_sparsity
1446 IF (.NOT.
PRESENT(smear))
THEN
1452 CALL dbcsr_create(tmp, template=ket, &
1453 matrix_type=dbcsr_type_no_symmetry)
1456 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, &
1457 metric, ket, 0.0_dp, tmp, &
1458 filter_eps=eps_filter)
1461 CALL dbcsr_multiply(
"T",
"N", 1.0_dp, &
1462 bra, tmp, 0.0_dp, overlap, &
1463 retain_sparsity=local_retain_sparsity, &
1464 filter_eps=eps_filter)
1466 CALL dbcsr_release(tmp)
1475 CALL dbcsr_get_info(overlap, nfullrows_total=dim0)
1476 ALLOCATE (diag_correction(dim0))
1477 diag_correction = 1.0_dp
1478 CALL dbcsr_set_diag(overlap, diag_correction)
1479 DEALLOCATE (diag_correction)
1482 CALL timestop(handle)
1506 nocc_of_domain, eps_filter, order_lanczos, eps_lanczos, &
1507 max_iter_lanczos, overlap_sqrti, smear)
1509 TYPE(dbcsr_type),
INTENT(INOUT) :: ket, overlap
1510 TYPE(dbcsr_type),
INTENT(IN) :: metric
1511 LOGICAL,
INTENT(IN) :: retain_locality, only_normalize
1512 INTEGER,
DIMENSION(:),
INTENT(IN) :: nocc_of_domain
1513 REAL(kind=
dp) :: eps_filter
1514 INTEGER,
INTENT(IN) :: order_lanczos
1515 REAL(kind=
dp),
INTENT(IN) :: eps_lanczos
1516 INTEGER,
INTENT(IN) :: max_iter_lanczos
1517 TYPE(dbcsr_type),
INTENT(INOUT),
OPTIONAL :: overlap_sqrti
1518 LOGICAL,
INTENT(IN),
OPTIONAL :: smear
1520 CHARACTER(LEN=*),
PARAMETER :: routinen =
'orthogonalize_mos'
1522 INTEGER :: dim0, handle
1524 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: diagonal
1525 TYPE(dbcsr_type) :: matrix_sigma_blk_sqrt, &
1526 matrix_sigma_blk_sqrt_inv, &
1529 CALL timeset(routinen, handle)
1531 IF (.NOT.
PRESENT(smear))
THEN
1540 CALL dbcsr_set(overlap, 0.0_dp)
1541 CALL dbcsr_add_on_diag(overlap, 1.0_dp)
1542 CALL dbcsr_filter(overlap, eps_filter)
1544 CALL get_overlap(ket, ket, overlap, metric, retain_locality, &
1545 eps_filter, smear=smearing)
1547 IF (only_normalize)
THEN
1549 CALL dbcsr_get_info(overlap, nfullrows_total=dim0)
1550 ALLOCATE (diagonal(dim0))
1551 CALL dbcsr_get_diag(overlap, diagonal)
1552 CALL dbcsr_set(overlap, 0.0_dp)
1553 CALL dbcsr_set_diag(overlap, diagonal)
1554 DEALLOCATE (diagonal)
1555 CALL dbcsr_filter(overlap, eps_filter)
1559 CALL dbcsr_create(matrix_sigma_blk_sqrt, template=overlap, &
1560 matrix_type=dbcsr_type_no_symmetry)
1561 CALL dbcsr_create(matrix_sigma_blk_sqrt_inv, template=overlap, &
1562 matrix_type=dbcsr_type_no_symmetry)
1565 CALL set_zero_electron_blocks_in_mo_mo_matrix(overlap, nocc_of_domain, 1.0_dp)
1567 overlap, threshold=eps_filter, &
1568 order=order_lanczos, &
1569 eps_lanczos=eps_lanczos, &
1570 max_iter_lanczos=max_iter_lanczos)
1571 CALL set_zero_electron_blocks_in_mo_mo_matrix(overlap, nocc_of_domain, 0.0_dp)
1573 CALL set_zero_electron_blocks_in_mo_mo_matrix(matrix_sigma_blk_sqrt_inv, nocc_of_domain, 0.0_dp)
1575 CALL dbcsr_create(matrix_t_blk_tmp, &
1577 matrix_type=dbcsr_type_no_symmetry)
1579 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, &
1581 matrix_sigma_blk_sqrt_inv, &
1582 0.0_dp, matrix_t_blk_tmp, &
1583 filter_eps=eps_filter)
1586 CALL dbcsr_copy(ket, matrix_t_blk_tmp)
1589 IF (
PRESENT(overlap_sqrti))
THEN
1590 CALL dbcsr_copy(overlap_sqrti, &
1591 matrix_sigma_blk_sqrt_inv)
1594 CALL dbcsr_release(matrix_t_blk_tmp)
1595 CALL dbcsr_release(matrix_sigma_blk_sqrt)
1596 CALL dbcsr_release(matrix_sigma_blk_sqrt_inv)
1598 CALL timestop(handle)
1628 use_guess, smear, algorithm, para_env, blacs_env, eps_lanczos, &
1629 max_iter_lanczos, inverse_accelerator, inv_eps_factor)
1631 TYPE(dbcsr_type),
INTENT(IN) :: t
1632 TYPE(dbcsr_type),
INTENT(INOUT) :: p
1633 REAL(kind=
dp),
INTENT(IN) :: eps_filter
1634 LOGICAL,
INTENT(IN) :: orthog_orbs
1635 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: nocc_of_domain
1636 TYPE(dbcsr_type),
INTENT(IN),
OPTIONAL :: s
1637 TYPE(dbcsr_type),
INTENT(INOUT),
OPTIONAL :: sigma, sigma_inv
1638 LOGICAL,
INTENT(IN),
OPTIONAL :: use_guess, smear
1639 INTEGER,
INTENT(IN),
OPTIONAL :: algorithm
1640 TYPE(mp_para_env_type),
OPTIONAL,
POINTER :: para_env
1641 TYPE(cp_blacs_env_type),
OPTIONAL,
POINTER :: blacs_env
1642 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: eps_lanczos
1643 INTEGER,
INTENT(IN),
OPTIONAL :: max_iter_lanczos, inverse_accelerator
1644 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: inv_eps_factor
1646 CHARACTER(LEN=*),
PARAMETER :: routinen =
'almo_scf_t_to_proj'
1648 INTEGER :: dim0, handle, my_accelerator, &
1650 LOGICAL :: smearing, use_sigma_inv_guess
1651 REAL(kind=
dp) :: my_inv_eps_factor
1652 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: diag_correction
1653 TYPE(dbcsr_type) :: t_tmp
1655 CALL timeset(routinen, handle)
1658 IF (.NOT. orthog_orbs)
THEN
1659 IF ((.NOT.
PRESENT(s)) .OR. (.NOT.
PRESENT(sigma)) .OR. &
1660 (.NOT.
PRESENT(sigma_inv)) .OR. (.NOT.
PRESENT(nocc_of_domain)))
THEN
1661 cpabort(
"Nonorthogonal orbitals need more input")
1666 IF (
PRESENT(algorithm)) my_algorithm = algorithm
1668 IF (my_algorithm == 1 .AND. (.NOT.
PRESENT(para_env) .OR. .NOT.
PRESENT(blacs_env))) &
1669 cpabort(
"PARA and BLACS env are necessary for cholesky algorithm")
1671 use_sigma_inv_guess = .false.
1672 IF (
PRESENT(use_guess))
THEN
1673 use_sigma_inv_guess = use_guess
1676 IF (.NOT.
PRESENT(smear))
THEN
1683 IF (
PRESENT(inverse_accelerator)) my_accelerator = inverse_accelerator
1685 my_inv_eps_factor = 10.0_dp
1686 IF (
PRESENT(inv_eps_factor)) my_inv_eps_factor = inv_eps_factor
1688 IF (orthog_orbs)
THEN
1690 CALL dbcsr_multiply(
"N",
"T", 1.0_dp, t, t, &
1691 0.0_dp, p, filter_eps=eps_filter)
1695 CALL dbcsr_create(t_tmp, template=t)
1698 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, s, t, 0.0_dp, t_tmp, &
1699 filter_eps=eps_filter)
1702 CALL dbcsr_multiply(
"T",
"N", 1.0_dp, t, t_tmp, 0.0_dp, sigma, &
1703 filter_eps=eps_filter)
1712 CALL dbcsr_get_info(sigma, nfullrows_total=dim0)
1713 ALLOCATE (diag_correction(dim0))
1714 diag_correction = 1.0_dp
1715 CALL dbcsr_set_diag(sigma, diag_correction)
1716 DEALLOCATE (diag_correction)
1720 CALL set_zero_electron_blocks_in_mo_mo_matrix(sigma, nocc_of_domain, 1.0_dp)
1721 SELECT CASE (my_algorithm)
1725 matrix_inverse=sigma_inv, &
1727 use_inv_as_guess=use_sigma_inv_guess, &
1728 threshold=eps_filter*my_inv_eps_factor, &
1729 filter_eps=eps_filter, &
1738 matrix_inverse=sigma_inv, &
1740 use_inv_as_guess=use_sigma_inv_guess, &
1741 threshold=eps_filter*my_inv_eps_factor, &
1742 filter_eps=eps_filter, &
1743 accelerator_order=my_accelerator, &
1744 eps_lanczos=eps_lanczos, &
1745 max_iter_lanczos=max_iter_lanczos, &
1751 CALL dbcsr_copy(sigma_inv, sigma)
1753 para_env=para_env, &
1754 blacs_env=blacs_env)
1756 para_env=para_env, &
1757 blacs_env=blacs_env, &
1758 upper_to_full=.true.)
1759 CALL dbcsr_filter(sigma_inv, eps_filter)
1761 cpabort(
"Illegal MO overalp inversion algorithm")
1763 CALL set_zero_electron_blocks_in_mo_mo_matrix(sigma, nocc_of_domain, 0.0_dp)
1764 CALL set_zero_electron_blocks_in_mo_mo_matrix(sigma_inv, nocc_of_domain, 0.0_dp)
1767 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, t, sigma_inv, 0.0_dp, t_tmp, &
1768 filter_eps=eps_filter)
1771 CALL dbcsr_multiply(
"N",
"T", 1.0_dp, t_tmp, t, 0.0_dp, p, &
1772 filter_eps=eps_filter)
1774 CALL dbcsr_release(t_tmp)
1778 CALL timestop(handle)
1792 SUBROUTINE set_zero_electron_blocks_in_mo_mo_matrix(matrix, nocc_of_domain, value)
1794 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix
1795 INTEGER,
DIMENSION(:),
INTENT(IN) :: nocc_of_domain
1796 REAL(kind=
dp),
INTENT(IN) ::
value
1798 INTEGER :: hold, iblock_col, iblock_row, mynode, &
1800 LOGICAL :: found, tr
1801 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: p_new_block
1802 TYPE(dbcsr_distribution_type) :: dist
1804 CALL dbcsr_get_info(matrix, distribution=dist)
1805 CALL dbcsr_distribution_get(dist, mynode=mynode)
1807 CALL dbcsr_work_create(matrix, work_mutable=.true.)
1809 nblkrows_tot = dbcsr_nblkrows_total(matrix)
1811 DO row = 1, nblkrows_tot
1812 IF (nocc_of_domain(row) == 0)
THEN
1816 CALL dbcsr_get_stored_coordinates(matrix, iblock_row, iblock_col, hold)
1817 IF (hold .EQ. mynode)
THEN
1818 NULLIFY (p_new_block)
1819 CALL dbcsr_get_block_p(matrix, iblock_row, iblock_col, p_new_block, found)
1821 p_new_block(1, 1) =
value
1823 CALL dbcsr_reserve_block2d(matrix, iblock_row, iblock_col, p_new_block)
1824 cpassert(
ASSOCIATED(p_new_block))
1825 p_new_block(1, 1) =
value
1831 CALL dbcsr_finalize(matrix)
1833 END SUBROUTINE set_zero_electron_blocks_in_mo_mo_matrix
1854 psi_projector_orthogonal, proj_in_template, eps_filter, sig_inv_projector, &
1857 TYPE(dbcsr_type),
INTENT(IN) :: psi_in
1858 TYPE(dbcsr_type),
INTENT(INOUT) :: psi_out
1859 TYPE(dbcsr_type),
INTENT(IN) :: psi_projector, metric
1860 LOGICAL,
INTENT(IN) :: project_out, psi_projector_orthogonal
1861 TYPE(dbcsr_type),
INTENT(IN) :: proj_in_template
1862 REAL(kind=
dp),
INTENT(IN) :: eps_filter
1863 TYPE(dbcsr_type),
INTENT(IN),
OPTIONAL :: sig_inv_projector, sig_inv_template
1865 CHARACTER(LEN=*),
PARAMETER :: routinen =
'apply_projector'
1868 TYPE(dbcsr_type) :: tmp_no, tmp_ov, tmp_ov2, tmp_sig, &
1871 CALL timeset(routinen, handle)
1874 CALL dbcsr_create(tmp_no, template=psi_projector)
1875 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, &
1876 metric, psi_projector, &
1878 filter_eps=eps_filter)
1881 CALL dbcsr_create(tmp_ov, template=proj_in_template)
1882 CALL dbcsr_multiply(
"T",
"N", 1.0_dp, &
1885 filter_eps=eps_filter)
1887 IF (.NOT. psi_projector_orthogonal)
THEN
1889 CALL dbcsr_create(tmp_ov2, &
1890 template=proj_in_template)
1891 IF (
PRESENT(sig_inv_projector))
THEN
1892 CALL dbcsr_create(tmp_sig_inv, &
1893 template=sig_inv_projector)
1894 CALL dbcsr_copy(tmp_sig_inv, sig_inv_projector)
1896 IF (.NOT.
PRESENT(sig_inv_template))
THEN
1897 cpabort(
"PROGRAMMING ERROR: provide either template or sig_inv")
1900 CALL dbcsr_create(tmp_sig, &
1901 template=sig_inv_template, &
1902 matrix_type=dbcsr_type_no_symmetry)
1903 CALL dbcsr_multiply(
"T",
"N", 1.0_dp, &
1904 psi_projector, tmp_no, 0.0_dp, tmp_sig, &
1905 filter_eps=eps_filter)
1906 CALL dbcsr_create(tmp_sig_inv, &
1907 template=sig_inv_template, &
1908 matrix_type=dbcsr_type_no_symmetry)
1910 threshold=eps_filter)
1911 CALL dbcsr_release(tmp_sig)
1913 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, &
1914 tmp_sig_inv, tmp_ov, 0.0_dp, tmp_ov2, &
1915 filter_eps=eps_filter)
1916 CALL dbcsr_release(tmp_sig_inv)
1917 CALL dbcsr_copy(tmp_ov, tmp_ov2)
1918 CALL dbcsr_release(tmp_ov2)
1920 CALL dbcsr_release(tmp_no)
1923 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, &
1924 psi_projector, tmp_ov, 0.0_dp, psi_out, &
1925 filter_eps=eps_filter)
1926 CALL dbcsr_release(tmp_ov)
1929 IF (project_out)
THEN
1930 CALL dbcsr_add(psi_out, psi_in, -1.0_dp, +1.0_dp)
1933 CALL timestop(handle)
2013 TYPE(dbcsr_type),
INTENT(IN) :: x
2014 TYPE(dbcsr_type),
INTENT(INOUT) :: u
2015 REAL(kind=
dp),
INTENT(IN) :: eps_filter
2017 CHARACTER(LEN=*),
PARAMETER :: routinen =
'generator_to_unitary'
2019 INTEGER :: handle, unit_nr
2020 LOGICAL :: safe_mode
2021 REAL(kind=
dp) :: frob_matrix, frob_matrix_base
2022 TYPE(cp_logger_type),
POINTER :: logger
2023 TYPE(dbcsr_type) :: delta, t1, t2, tmp1
2025 CALL timeset(routinen, handle)
2031 IF (logger%para_env%is_source())
THEN
2037 CALL dbcsr_create(t1, template=x, &
2038 matrix_type=dbcsr_type_no_symmetry)
2039 CALL dbcsr_create(t2, template=x, &
2040 matrix_type=dbcsr_type_no_symmetry)
2043 CALL dbcsr_create(delta, template=x, &
2044 matrix_type=dbcsr_type_no_symmetry)
2045 CALL dbcsr_transposed(delta, x)
2047 CALL dbcsr_add(delta, x, 1.0_dp, -1.0_dp)
2050 CALL dbcsr_add_on_diag(t1, 1.0_dp)
2051 CALL dbcsr_add(t1, delta, 1.0_dp, -1.0_dp)
2056 CALL dbcsr_create(tmp1, template=x, &
2057 matrix_type=dbcsr_type_no_symmetry)
2058 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, t2, t1, 0.0_dp, tmp1, &
2059 filter_eps=eps_filter)
2060 frob_matrix_base = dbcsr_frobenius_norm(tmp1)
2061 CALL dbcsr_add_on_diag(tmp1, -1.0_dp)
2062 frob_matrix = dbcsr_frobenius_norm(tmp1)
2063 IF (unit_nr > 0)
WRITE (unit_nr, *)
"Error for (inv(A)*A-I)", frob_matrix/frob_matrix_base
2064 CALL dbcsr_release(tmp1)
2067 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, delta, t2, 0.0_dp, u, &
2068 filter_eps=eps_filter)
2069 CALL dbcsr_add(u, t2, 1.0_dp, 1.0_dp)
2073 CALL dbcsr_create(tmp1, template=x, &
2074 matrix_type=dbcsr_type_no_symmetry)
2075 CALL dbcsr_multiply(
"T",
"N", 1.0_dp, u, u, 0.0_dp, tmp1, &
2076 filter_eps=eps_filter)
2077 frob_matrix_base = dbcsr_frobenius_norm(tmp1)
2078 CALL dbcsr_add_on_diag(tmp1, -1.0_dp)
2079 frob_matrix = dbcsr_frobenius_norm(tmp1)
2080 IF (unit_nr > 0)
WRITE (unit_nr, *)
"Error for (trn(U)*U-I)", frob_matrix/frob_matrix_base
2081 CALL dbcsr_release(tmp1)
2084 CALL timestop(handle)
2108 dpattern, map, node_of_domain, my_action, filter_eps, matrix_trimmer, use_trimmer)
2110 TYPE(dbcsr_type),
INTENT(IN) :: matrix_in
2111 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_out
2112 TYPE(domain_submatrix_type),
DIMENSION(:), &
2113 INTENT(IN) :: operator1
2114 TYPE(domain_submatrix_type),
DIMENSION(:), &
2115 INTENT(IN),
OPTIONAL :: operator2
2116 TYPE(dbcsr_type),
INTENT(IN) :: dpattern
2117 TYPE(domain_map_type),
INTENT(IN) :: map
2118 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2119 INTEGER,
INTENT(IN) :: my_action
2120 REAL(kind=
dp) :: filter_eps
2121 TYPE(dbcsr_type),
INTENT(IN),
OPTIONAL :: matrix_trimmer
2122 LOGICAL,
INTENT(IN),
OPTIONAL :: use_trimmer
2124 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_domain_operators'
2126 INTEGER :: handle, ndomains
2127 LOGICAL :: matrix_trimmer_required, my_use_trimmer, &
2129 TYPE(domain_submatrix_type),
ALLOCATABLE, &
2130 DIMENSION(:) :: subm_in, subm_out, subm_temp
2132 CALL timeset(routinen, handle)
2134 my_use_trimmer = .false.
2135 IF (
PRESENT(use_trimmer))
THEN
2136 my_use_trimmer = use_trimmer
2139 operator2_required = .false.
2140 matrix_trimmer_required = .false.
2142 IF (my_action .EQ. 1) operator2_required = .true.
2144 IF (my_use_trimmer)
THEN
2145 matrix_trimmer_required = .true.
2146 cpabort(
"TRIMMED PROJECTOR DISABLED!")
2149 IF (.NOT.
PRESENT(operator2) .AND. operator2_required)
THEN
2150 cpabort(
"SECOND OPERATOR IS REQUIRED")
2152 IF (.NOT.
PRESENT(matrix_trimmer) .AND. matrix_trimmer_required)
THEN
2153 cpabort(
"TRIMMER MATRIX IS REQUIRED")
2156 ndomains = dbcsr_nblkcols_total(dpattern)
2158 ALLOCATE (subm_in(ndomains))
2159 ALLOCATE (subm_temp(ndomains))
2160 ALLOCATE (subm_out(ndomains))
2162 CALL init_submatrices(subm_in)
2163 CALL init_submatrices(subm_temp)
2164 CALL init_submatrices(subm_out)
2174 IF (my_action .EQ. 0)
THEN
2176 CALL multiply_submatrices(
'N',
'N', 1.0_dp, operator1, &
2177 subm_in, 0.0_dp, subm_out)
2178 ELSE IF (my_action .EQ. 1)
THEN
2180 CALL copy_submatrices(subm_in, subm_out, .true.)
2181 CALL multiply_submatrices(
'N',
'N', 1.0_dp, operator1, &
2182 subm_in, 0.0_dp, subm_temp)
2183 CALL multiply_submatrices(
'N',
'N', -1.0_dp, operator2, &
2184 subm_temp, 1.0_dp, subm_out)
2186 cpabort(
"ILLEGAL ACTION")
2190 CALL dbcsr_filter(matrix_out, filter_eps)
2192 CALL release_submatrices(subm_out)
2193 CALL release_submatrices(subm_temp)
2194 CALL release_submatrices(subm_in)
2196 DEALLOCATE (subm_out)
2197 DEALLOCATE (subm_temp)
2198 DEALLOCATE (subm_in)
2200 CALL timestop(handle)
2228 subm_s_inv_half, subm_s_half, &
2229 subm_r_down, matrix_trimmer, &
2230 dpattern, map, node_of_domain, &
2232 bad_modes_projector_down, &
2234 eps_zero_eigenvalues, &
2235 my_action, skip_inversion)
2237 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_main
2238 TYPE(domain_submatrix_type),
DIMENSION(:), &
2239 INTENT(IN),
OPTIONAL :: subm_s_inv, subm_s_inv_half, &
2240 subm_s_half, subm_r_down
2241 TYPE(dbcsr_type),
INTENT(IN),
OPTIONAL :: matrix_trimmer
2242 TYPE(dbcsr_type),
INTENT(IN) :: dpattern
2243 TYPE(domain_map_type),
INTENT(IN) :: map
2244 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2245 TYPE(domain_submatrix_type),
DIMENSION(:), &
2247 TYPE(domain_submatrix_type),
DIMENSION(:), &
2248 INTENT(INOUT),
OPTIONAL :: bad_modes_projector_down
2249 LOGICAL,
INTENT(IN),
OPTIONAL :: use_trimmer
2250 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: eps_zero_eigenvalues
2251 INTEGER,
INTENT(IN) :: my_action
2252 LOGICAL,
INTENT(IN),
OPTIONAL :: skip_inversion
2254 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_preconditioner'
2256 INTEGER :: handle, idomain, index1_end, &
2257 index1_start, n_domain_mos, naos, &
2258 nblkrows_tot, ndomains, neighbor, row
2259 INTEGER,
DIMENSION(:),
POINTER :: nmos
2260 LOGICAL :: eps_zero_eigenvalues_required, matrix_r_required, matrix_s_half_required, &
2261 matrix_s_inv_half_required, matrix_s_inv_required, matrix_trimmer_required, &
2262 my_skip_inversion, my_use_trimmer
2263 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: minv, proj_array
2264 TYPE(domain_submatrix_type),
ALLOCATABLE, &
2265 DIMENSION(:) :: subm_main, subm_tmp, subm_tmp2
2267 CALL timeset(routinen, handle)
2269 my_use_trimmer = .false.
2270 IF (
PRESENT(use_trimmer))
THEN
2271 my_use_trimmer = use_trimmer
2274 my_skip_inversion = .false.
2275 IF (
PRESENT(skip_inversion))
THEN
2276 my_skip_inversion = skip_inversion
2279 matrix_s_inv_half_required = .false.
2280 matrix_s_half_required = .false.
2281 eps_zero_eigenvalues_required = .false.
2282 matrix_s_inv_required = .false.
2283 matrix_trimmer_required = .false.
2284 matrix_r_required = .false.
2286 IF (my_action .EQ. -1) matrix_s_inv_required = .true.
2287 IF (my_action .EQ. -1) matrix_r_required = .true.
2288 IF (my_use_trimmer)
THEN
2289 matrix_trimmer_required = .true.
2290 cpabort(
"TRIMMED PRECONDITIONER DISABLED!")
2293 IF (
PRESENT(bad_modes_projector_down))
THEN
2294 matrix_s_inv_half_required = .true.
2295 matrix_s_half_required = .true.
2296 eps_zero_eigenvalues_required = .true.
2300 IF (.NOT.
PRESENT(subm_s_inv_half) .AND. matrix_s_inv_half_required)
THEN
2301 cpabort(
"S_inv_half SUBMATRICES ARE REQUIRED")
2303 IF (.NOT.
PRESENT(subm_s_half) .AND. matrix_s_half_required)
THEN
2304 cpabort(
"S_half SUBMATRICES ARE REQUIRED")
2306 IF (.NOT.
PRESENT(eps_zero_eigenvalues) .AND. eps_zero_eigenvalues_required)
THEN
2307 cpabort(
"EPS_ZERO_EIGENVALUES IS REQUIRED")
2309 IF (.NOT.
PRESENT(subm_s_inv) .AND. matrix_s_inv_required)
THEN
2310 cpabort(
"S_inv SUBMATRICES ARE REQUIRED")
2312 IF (.NOT.
PRESENT(subm_r_down) .AND. matrix_r_required)
THEN
2313 cpabort(
"R SUBMATRICES ARE REQUIRED")
2315 IF (.NOT.
PRESENT(matrix_trimmer) .AND. matrix_trimmer_required)
THEN
2316 cpabort(
"TRIMMER MATRIX IS REQUIRED")
2319 CALL dbcsr_get_info(dpattern, &
2320 nblkcols_total=ndomains, &
2321 nblkrows_total=nblkrows_tot, &
2324 ALLOCATE (subm_main(ndomains))
2325 CALL init_submatrices(subm_main)
2336 IF (my_action .EQ. -1)
THEN
2342 ALLOCATE (subm_tmp(ndomains))
2343 ALLOCATE (subm_tmp2(ndomains))
2344 CALL init_submatrices(subm_tmp)
2345 CALL init_submatrices(subm_tmp2)
2346 CALL multiply_submatrices(
'N',
'N', 1.0_dp, subm_r_down, &
2347 subm_s_inv, 0.0_dp, subm_tmp)
2348 CALL multiply_submatrices(
'N',
'N', 1.0_dp, subm_tmp, &
2349 subm_main, 0.0_dp, subm_tmp2)
2350 CALL add_submatrices(1.0_dp, subm_main, -1.0_dp, subm_tmp2,
'N')
2351 CALL add_submatrices(1.0_dp, subm_main, -1.0_dp, subm_tmp2,
'T')
2352 CALL multiply_submatrices(
'N',
'T', 1.0_dp, subm_tmp2, &
2353 subm_tmp, 1.0_dp, subm_main)
2354 CALL release_submatrices(subm_tmp)
2355 CALL release_submatrices(subm_tmp2)
2356 DEALLOCATE (subm_tmp2)
2357 DEALLOCATE (subm_tmp)
2360 IF (my_skip_inversion)
THEN
2364 DO idomain = 1, ndomains
2367 IF (subm_main(idomain)%domain .GT. 0)
THEN
2370 IF (idomain .EQ. 1)
THEN
2373 index1_start = map%index1(idomain - 1)
2375 index1_end = map%index1(idomain) - 1
2378 DO row = index1_start, index1_end
2379 neighbor = map%pairs(row, 1)
2380 n_domain_mos = n_domain_mos + nmos(neighbor)
2383 naos = subm_main(idomain)%nrows
2386 ALLOCATE (minv(naos, naos))
2416 IF (
PRESENT(bad_modes_projector_down))
THEN
2417 ALLOCATE (proj_array(naos, naos))
2418 CALL pseudo_invert_matrix(a=subm_main(idomain)%mdata, ainv=minv, n=naos, method=1, &
2419 range1=nmos(idomain), range2=n_domain_mos, &
2420 range1_thr=eps_zero_eigenvalues, &
2421 bad_modes_projector_down=proj_array, &
2422 s_inv_half=subm_s_inv_half(idomain)%mdata, &
2423 s_half=subm_s_half(idomain)%mdata &
2426 CALL pseudo_invert_matrix(a=subm_main(idomain)%mdata, ainv=minv, n=naos, method=1, &
2427 range1=nmos(idomain), range2=n_domain_mos)
2431 CALL copy_submatrices(subm_main(idomain),
preconditioner(idomain), .false.)
2435 IF (
PRESENT(bad_modes_projector_down))
THEN
2436 CALL copy_submatrices(subm_main(idomain), bad_modes_projector_down(idomain), .false.)
2438 DEALLOCATE (proj_array)
2447 CALL release_submatrices(subm_main)
2448 DEALLOCATE (subm_main)
2458 CALL timestop(handle)
2475 dpattern, map, node_of_domain)
2477 TYPE(dbcsr_type),
INTENT(IN) :: matrix_s
2478 TYPE(domain_submatrix_type),
DIMENSION(:), &
2479 INTENT(INOUT) :: subm_s_sqrt, subm_s_sqrt_inv
2480 TYPE(dbcsr_type),
INTENT(IN) :: dpattern
2481 TYPE(domain_map_type),
INTENT(IN) :: map
2482 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2484 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_s_sqrt'
2486 INTEGER :: handle, idomain, naos, ndomains
2487 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: ssqrt, ssqrtinv
2488 TYPE(domain_submatrix_type),
ALLOCATABLE, &
2489 DIMENSION(:) :: subm_s
2491 CALL timeset(routinen, handle)
2493 ndomains = dbcsr_nblkcols_total(dpattern)
2494 cpassert(
SIZE(subm_s_sqrt) .EQ. ndomains)
2495 cpassert(
SIZE(subm_s_sqrt_inv) .EQ. ndomains)
2496 ALLOCATE (subm_s(ndomains))
2497 CALL init_submatrices(subm_s)
2503 DO idomain = 1, ndomains
2506 IF (subm_s(idomain)%domain .GT. 0)
THEN
2508 naos = subm_s(idomain)%nrows
2510 ALLOCATE (ssqrt(naos, naos))
2511 ALLOCATE (ssqrtinv(naos, naos))
2513 CALL matrix_sqrt(a=subm_s(idomain)%mdata, asqrt=ssqrt, asqrtinv=ssqrtinv, &
2516 CALL copy_submatrices(subm_s(idomain), subm_s_sqrt(idomain), .false.)
2519 CALL copy_submatrices(subm_s(idomain), subm_s_sqrt_inv(idomain), .false.)
2522 DEALLOCATE (ssqrtinv)
2529 CALL release_submatrices(subm_s)
2532 CALL timestop(handle)
2549 TYPE(dbcsr_type),
INTENT(IN) :: matrix_s
2550 TYPE(domain_submatrix_type),
DIMENSION(:), &
2551 INTENT(INOUT) :: subm_s_inv
2552 TYPE(dbcsr_type),
INTENT(IN) :: dpattern
2553 TYPE(domain_map_type),
INTENT(IN) :: map
2554 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2556 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_s_inv'
2558 INTEGER :: handle, idomain, naos, ndomains
2559 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: sinv
2560 TYPE(domain_submatrix_type),
ALLOCATABLE, &
2561 DIMENSION(:) :: subm_s
2563 CALL timeset(routinen, handle)
2565 ndomains = dbcsr_nblkcols_total(dpattern)
2567 cpassert(
SIZE(subm_s_inv) .EQ. ndomains)
2568 ALLOCATE (subm_s(ndomains))
2569 CALL init_submatrices(subm_s)
2575 DO idomain = 1, ndomains
2578 IF (subm_s(idomain)%domain .GT. 0)
THEN
2580 naos = subm_s(idomain)%nrows
2582 ALLOCATE (sinv(naos, naos))
2584 CALL pseudo_invert_matrix(a=subm_s(idomain)%mdata, ainv=sinv, n=naos, &
2587 CALL copy_submatrices(subm_s(idomain), subm_s_inv(idomain), .false.)
2596 CALL release_submatrices(subm_s)
2599 CALL timestop(handle)
2618 subm_r_down, dpattern, map, node_of_domain, filter_eps)
2620 TYPE(dbcsr_type),
INTENT(IN) :: matrix_t, matrix_sigma_inv, matrix_s
2621 TYPE(domain_submatrix_type),
DIMENSION(:), &
2622 INTENT(INOUT) :: subm_r_down
2623 TYPE(dbcsr_type),
INTENT(IN) :: dpattern
2624 TYPE(domain_map_type),
INTENT(IN) :: map
2625 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
2626 REAL(kind=
dp) :: filter_eps
2628 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_domain_r_down'
2630 INTEGER :: handle, ndomains
2631 TYPE(dbcsr_type) :: m_tmp_no_1, m_tmp_no_2, matrix_r
2633 CALL timeset(routinen, handle)
2636 CALL dbcsr_create(matrix_r, &
2637 template=matrix_s, &
2638 matrix_type=dbcsr_type_symmetric)
2639 CALL dbcsr_create(m_tmp_no_1, &
2640 template=matrix_t, &
2641 matrix_type=dbcsr_type_no_symmetry)
2642 CALL dbcsr_create(m_tmp_no_2, &
2643 template=matrix_t, &
2644 matrix_type=dbcsr_type_no_symmetry)
2646 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_s, matrix_t, &
2647 0.0_dp, m_tmp_no_1, filter_eps=filter_eps)
2648 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, m_tmp_no_1, matrix_sigma_inv, &
2649 0.0_dp, m_tmp_no_2, filter_eps=filter_eps)
2650 CALL dbcsr_multiply(
"N",
"T", 1.0_dp, m_tmp_no_2, m_tmp_no_1, &
2651 0.0_dp, matrix_r, filter_eps=filter_eps)
2653 CALL dbcsr_release(m_tmp_no_1)
2654 CALL dbcsr_release(m_tmp_no_2)
2656 ndomains = dbcsr_nblkcols_total(dpattern)
2657 cpassert(
SIZE(subm_r_down) .EQ. ndomains)
2662 CALL dbcsr_release(matrix_r)
2664 CALL timestop(handle)
2678 SUBROUTINE matrix_sqrt(A, Asqrt, Asqrtinv, N)
2680 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a
2681 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: asqrt, asqrtinv
2682 INTEGER,
INTENT(IN) :: n
2684 CHARACTER(len=*),
PARAMETER :: routinen =
'matrix_sqrt'
2686 INTEGER :: handle, info, jj, lwork, unit_nr
2687 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
2688 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: test, testn
2689 TYPE(cp_logger_type),
POINTER :: logger
2691 CALL timeset(routinen, handle)
2698 IF (logger%para_env%is_source())
THEN
2723 ALLOCATE (eigenvalues(n))
2726 ALLOCATE (work(max(1, lwork)))
2727 CALL dsyev(
'V',
'L', n, asqrtinv, n, eigenvalues, work, lwork, info)
2728 lwork = int(work(1))
2731 ALLOCATE (work(max(1, lwork)))
2732 CALL dsyev(
'V',
'L', n, asqrtinv, n, eigenvalues, work, lwork, info)
2733 IF (info .NE. 0)
THEN
2734 IF (unit_nr > 0)
WRITE (unit_nr, *)
'DSYEV ERROR MESSAGE: ', info
2735 cpabort(
"DSYEV failed")
2741 ALLOCATE (test(n, n))
2743 test(jj, :) = asqrtinv(:, jj)*sqrt(eigenvalues(jj))
2745 ALLOCATE (testn(n, n))
2746 testn(:, :) = matmul(asqrtinv, test)
2750 test(jj, :) = asqrtinv(:, jj)/sqrt(eigenvalues(jj))
2752 testn(:, :) = matmul(asqrtinv, test)
2754 DEALLOCATE (test, testn)
2756 DEALLOCATE (eigenvalues)
2773 CALL timestop(handle)
2775 END SUBROUTINE matrix_sqrt
2796 SUBROUTINE pseudo_invert_matrix(A, Ainv, N, method, range1, range2, range1_thr, &
2797 shift, bad_modes_projector_down, s_inv_half, s_half)
2799 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a
2800 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: ainv
2801 INTEGER,
INTENT(IN) :: n, method
2802 INTEGER,
INTENT(IN),
OPTIONAL :: range1, range2
2803 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: range1_thr, shift
2804 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT), &
2805 OPTIONAL :: bad_modes_projector_down
2806 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
2807 OPTIONAL :: s_inv_half, s_half
2809 CHARACTER(len=*),
PARAMETER :: routinen =
'pseudo_invert_matrix'
2811 INTEGER :: handle, ii, info, jj, lwork, range1_eiv, &
2812 range2_eiv, range3_eiv, unit_nr
2813 LOGICAL :: use_both, use_ranges_only, use_thr_only
2814 REAL(kind=
dp) :: my_shift
2815 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
2816 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: temp1, temp2, temp3, temp4
2817 TYPE(cp_logger_type),
POINTER :: logger
2819 CALL timeset(routinen, handle)
2823 IF (logger%para_env%is_source())
THEN
2829 IF (method .EQ. 1)
THEN
2831 IF ((
PRESENT(range1) .AND. (.NOT.
PRESENT(range2))) .OR. (
PRESENT(range2) .AND. (.NOT.
PRESENT(range1))))
THEN
2832 cpabort(
"range1 and range2 must be provided together")
2835 IF (
PRESENT(range1) .AND.
PRESENT(range1_thr))
THEN
2837 use_thr_only = .false.
2838 use_ranges_only = .false.
2842 IF (
PRESENT(range1))
THEN
2843 use_ranges_only = .true.
2845 use_ranges_only = .false.
2848 IF (
PRESENT(range1_thr))
THEN
2849 use_thr_only = .true.
2851 use_thr_only = .false.
2856 IF ((
PRESENT(s_half) .AND. (.NOT.
PRESENT(s_inv_half))) .OR. (
PRESENT(s_inv_half) .AND. (.NOT.
PRESENT(s_half))))
THEN
2857 cpabort(
"Domain overlap matrix missing")
2862 IF (
PRESENT(shift))
THEN
2869 SELECT CASE (method)
2872 CALL dpotrf(
'L', n, ainv, n, info)
2873 IF (info .NE. 0)
THEN
2874 cpabort(
"DPOTRF failed")
2876 CALL dpotri(
'L', n, ainv, n, info)
2877 IF (info .NE. 0)
THEN
2878 cpabort(
"DPOTRI failed")
2883 ainv(ii, jj) = ainv(jj, ii)
2891 ALLOCATE (eigenvalues(n))
2892 ALLOCATE (temp1(n, n))
2893 ALLOCATE (temp4(n, n))
2894 IF (
PRESENT(s_inv_half))
THEN
2895 CALL dsymm(
'L',
'U', n, n, 1.0_dp, s_inv_half, n, a, n, 0.0_dp, temp1, n)
2896 CALL dsymm(
'R',
'U', n, n, 1.0_dp, s_inv_half, n, temp1, n, 0.0_dp, ainv, n)
2900 ALLOCATE (work(max(1, lwork)))
2901 CALL dsyev(
'V',
'L', n, ainv, n, eigenvalues, work, lwork, info)
2903 lwork = int(work(1))
2906 ALLOCATE (work(max(1, lwork)))
2907 CALL dsyev(
'V',
'L', n, ainv, n, eigenvalues, work, lwork, info)
2909 IF (info .NE. 0)
THEN
2910 IF (unit_nr > 0)
WRITE (unit_nr, *)
'EIGENSYSTEM ERROR MESSAGE: ', info
2911 cpabort(
"Eigenproblem routine failed")
2920 ALLOCATE (temp2(n, n))
2921 IF (
PRESENT(bad_modes_projector_down))
ALLOCATE (temp3(n, n))
2922 temp2(1:n, 1:n) = ainv(1:n, 1:n)
2930 IF ((jj .LE. range2) .AND. (eigenvalues(jj) .LT. range1_thr))
THEN
2931 temp1(jj, :) = temp2(:, jj)*0.0_dp
2932 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2933 range1_eiv = range1_eiv + 1
2935 temp1(jj, :) = temp2(:, jj)/(eigenvalues(jj) + my_shift)
2936 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*0.0_dp
2937 range2_eiv = range2_eiv + 1
2941 IF (use_ranges_only)
THEN
2943 IF (jj .LE. range1)
THEN
2944 temp1(jj, :) = temp2(:, jj)*0.0_dp
2945 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2946 range1_eiv = range1_eiv + 1
2947 ELSE IF (jj .LE. range2)
THEN
2948 temp1(jj, :) = temp2(:, jj)*1.0_dp
2949 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2950 range2_eiv = range2_eiv + 1
2952 temp1(jj, :) = temp2(:, jj)/(eigenvalues(jj) + my_shift)
2953 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*0.0_dp
2954 range3_eiv = range3_eiv + 1
2957 ELSE IF (use_thr_only)
THEN
2959 IF (eigenvalues(jj) .LT. range1_thr)
THEN
2960 temp1(jj, :) = temp2(:, jj)*0.0_dp
2961 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*1.0_dp
2962 range1_eiv = range1_eiv + 1
2964 temp1(jj, :) = temp2(:, jj)/(eigenvalues(jj) + my_shift)
2965 IF (
PRESENT(bad_modes_projector_down)) temp3(jj, :) = ainv(:, jj)*0.0_dp
2966 range2_eiv = range2_eiv + 1
2970 cpabort(
"Invert using Cholesky. It would be faster.")
2974 IF (
PRESENT(bad_modes_projector_down))
THEN
2975 IF (
PRESENT(s_half))
THEN
2976 CALL dsymm(
'L',
'U', n, n, 1.0_dp, s_half, n, temp2, n, 0.0_dp, ainv, n)
2977 CALL dsymm(
'R',
'U', n, n, 1.0_dp, s_half, n, temp3, n, 0.0_dp, temp4, n)
2978 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, ainv, n, temp4, n, 0.0_dp, bad_modes_projector_down, n)
2980 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, temp2, n, temp3, n, 0.0_dp, bad_modes_projector_down, n)
2984 IF (
PRESENT(s_inv_half))
THEN
2985 CALL dsymm(
'L',
'U', n, n, 1.0_dp, s_inv_half, n, temp2, n, 0.0_dp, temp4, n)
2986 CALL dsymm(
'R',
'U', n, n, 1.0_dp, s_inv_half, n, temp1, n, 0.0_dp, temp2, n)
2987 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, temp4, n, temp2, n, 0.0_dp, ainv, n)
2989 CALL dgemm(
'N',
'N', n, n, n, 1.0_dp, temp2, n, temp1, n, 0.0_dp, ainv, n)
2991 DEALLOCATE (temp1, temp2, temp4)
2992 IF (
PRESENT(bad_modes_projector_down))
DEALLOCATE (temp3)
2993 DEALLOCATE (eigenvalues)
2997 cpabort(
"Illegal method selected for matrix inversion")
3016 CALL timestop(handle)
3018 END SUBROUTINE pseudo_invert_matrix
3034 SUBROUTINE pseudo_matrix_power(A, Apow, power, N, range1, range1_thr, shift)
3036 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: a
3037 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: apow
3038 REAL(kind=
dp),
INTENT(IN) :: power
3039 INTEGER,
INTENT(IN) :: n
3040 INTEGER,
INTENT(IN),
OPTIONAL :: range1
3041 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: range1_thr, shift
3043 CHARACTER(len=*),
PARAMETER :: routinen =
'pseudo_matrix_power'
3045 INTEGER :: handle, info, jj, lwork, range1_eiv, &
3047 LOGICAL :: use_both, use_ranges, use_thr
3048 REAL(kind=
dp) :: my_shift
3049 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues, work
3050 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: temp1, temp2
3051 TYPE(cp_logger_type),
POINTER :: logger
3053 CALL timeset(routinen, handle)
3057 IF (logger%para_env%is_source())
THEN
3063 IF (
PRESENT(range1) .AND.
PRESENT(range1_thr))
THEN
3067 IF (
PRESENT(range1))
THEN
3070 use_ranges = .false.
3071 IF (
PRESENT(range1_thr))
THEN
3080 IF (
PRESENT(shift))
THEN
3088 ALLOCATE (eigenvalues(n))
3089 ALLOCATE (temp1(n, n))
3093 ALLOCATE (work(max(1, lwork)))
3094 CALL dsyev(
'V',
'L', n, apow, n, eigenvalues, work, lwork, info)
3096 lwork = int(work(1))
3099 ALLOCATE (work(max(1, lwork)))
3101 CALL dsyev(
'V',
'L', n, apow, n, eigenvalues, work, lwork, info)
3103 IF (info .NE. 0)
THEN
3104 IF (unit_nr > 0)
WRITE (unit_nr, *)
'EIGENSYSTEM ERROR MESSAGE: ', info
3105 cpabort(
"Eigenproblem routine failed")
3114 ALLOCATE (temp2(n, n))
3116 temp2(1:n, 1:n) = apow(1:n, 1:n)
3123 IF ((jj .LE. range1) .AND. (eigenvalues(jj) .LT. range1_thr))
THEN
3124 temp1(jj, :) = temp2(:, jj)*0.0_dp
3125 range1_eiv = range1_eiv + 1
3127 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
3131 IF (use_ranges)
THEN
3133 IF (jj .LE. range1)
THEN
3134 temp1(jj, :) = temp2(:, jj)*0.0_dp
3135 range1_eiv = range1_eiv + 1
3137 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
3143 IF (eigenvalues(jj) .LT. range1_thr)
THEN
3144 temp1(jj, :) = temp2(:, jj)*0.0_dp
3146 range1_eiv = range1_eiv + 1
3148 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
3153 temp1(jj, :) = temp2(:, jj)*((eigenvalues(jj) + my_shift)**power)
3159 apow = matmul(temp2, temp1)
3160 DEALLOCATE (temp1, temp2)
3161 DEALLOCATE (eigenvalues)
3163 CALL timestop(handle)
3165 END SUBROUTINE pseudo_matrix_power
3176 TYPE(almo_scf_env_type),
INTENT(INOUT) :: almo_scf_env
3178 CHARACTER(len=*),
PARAMETER :: routinen =
'distribute_domains'
3180 INTEGER :: handle, idomain, least_loaded, nao, &
3182 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: index0
3183 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cpu_load, domain_load
3184 TYPE(dbcsr_distribution_type) :: dist
3186 CALL timeset(routinen, handle)
3188 ndomains = almo_scf_env%ndomains
3189 CALL dbcsr_get_info(almo_scf_env%matrix_s(1), distribution=dist)
3190 CALL dbcsr_distribution_get(dist, numnodes=ncpus)
3192 ALLOCATE (domain_load(ndomains))
3193 DO idomain = 1, ndomains
3194 nao = almo_scf_env%nbasis_of_domain(idomain)
3195 domain_load(idomain) = (nao*nao*nao)*1.0_dp
3198 ALLOCATE (index0(ndomains))
3200 CALL sort(domain_load, ndomains, index0)
3202 ALLOCATE (cpu_load(ncpus))
3203 cpu_load(:) = 0.0_dp
3205 DO idomain = 1, ndomains
3206 least_loaded = minloc(cpu_load, 1)
3207 cpu_load(least_loaded) = cpu_load(least_loaded) + domain_load(idomain)
3208 almo_scf_env%cpu_of_domain(index0(idomain)) = least_loaded - 1
3211 DEALLOCATE (cpu_load)
3213 DEALLOCATE (domain_load)
3215 CALL timestop(handle)
3231 TYPE(dbcsr_type),
INTENT(IN) :: matrix_no, dpattern
3232 TYPE(domain_map_type),
INTENT(IN) :: map
3233 INTEGER,
DIMENSION(:),
INTENT(IN) :: node_of_domain
3235 CHARACTER(len=*),
PARAMETER :: routinen =
'construct_test'
3237 INTEGER :: groupid, handle, ndomains
3238 TYPE(dbcsr_type) :: copy1
3239 TYPE(domain_submatrix_type),
ALLOCATABLE, &
3240 DIMENSION(:) :: subm_nn, subm_no
3241 TYPE(mp_comm_type) :: group
3243 CALL timeset(routinen, handle)
3245 ndomains = dbcsr_nblkcols_total(dpattern)
3246 CALL dbcsr_get_info(dpattern, group=groupid)
3247 CALL group%set_handle(groupid)
3249 ALLOCATE (subm_no(ndomains), subm_nn(ndomains))
3250 CALL init_submatrices(subm_no)
3251 CALL init_submatrices(subm_nn)
3261 CALL dbcsr_create(copy1, template=matrix_no)
3262 CALL dbcsr_copy(copy1, matrix_no)
3263 CALL dbcsr_print(copy1)
3265 CALL dbcsr_print(copy1)
3266 CALL dbcsr_release(copy1)
3268 CALL release_submatrices(subm_no)
3269 CALL release_submatrices(subm_nn)
3270 DEALLOCATE (subm_no, subm_nn)
3272 CALL timestop(handle)
3299 m_overlap, m_sigma_tmpl, nspins, xalmo_history, assume_t0_q0x, &
3300 optimize_theta, envelope_amplitude, eps_filter, order_lanczos, eps_lanczos, &
3301 max_iter_lanczos, nocc_of_domain)
3303 TYPE(dbcsr_type),
DIMENSION(:),
INTENT(INOUT) :: m_guess
3304 TYPE(dbcsr_type),
DIMENSION(:),
INTENT(IN) :: m_t_in, m_t0, m_quench_t
3305 TYPE(dbcsr_type),
INTENT(IN) :: m_overlap
3306 TYPE(dbcsr_type),
DIMENSION(:),
INTENT(IN) :: m_sigma_tmpl
3307 INTEGER,
INTENT(IN) :: nspins
3308 TYPE(almo_scf_history_type),
INTENT(IN) :: xalmo_history
3309 LOGICAL,
INTENT(IN) :: assume_t0_q0x, optimize_theta
3310 REAL(kind=
dp),
INTENT(IN) :: envelope_amplitude, eps_filter
3311 INTEGER,
INTENT(IN) :: order_lanczos
3312 REAL(kind=
dp),
INTENT(IN) :: eps_lanczos
3313 INTEGER,
INTENT(IN) :: max_iter_lanczos
3314 INTEGER,
DIMENSION(:, :),
INTENT(IN) :: nocc_of_domain
3316 CHARACTER(len=*),
PARAMETER :: routinen =
'xalmo_initial_guess'
3318 INTEGER :: handle, iaspc, ispin, istore, naspc, &
3320 LOGICAL :: aspc_guess
3321 REAL(kind=
dp) :: alpha
3322 TYPE(cp_logger_type),
POINTER :: logger
3323 TYPE(dbcsr_type) :: m_extrapolated, m_sigma_tmp
3325 CALL timeset(routinen, handle)
3329 IF (logger%para_env%is_source())
THEN
3335 IF (optimize_theta)
THEN
3336 cpwarn(
"unused option")
3338 alpha = envelope_amplitude
3343 IF (xalmo_history%istore == 0)
THEN
3344 aspc_guess = .false.
3350 IF (.NOT. aspc_guess)
THEN
3352 DO ispin = 1, nspins
3356 IF (assume_t0_q0x)
THEN
3357 CALL dbcsr_set(m_guess(ispin), 0.0_dp)
3360 CALL dbcsr_copy(m_guess(ispin), m_t_in(ispin))
3370 naspc = min(xalmo_history%istore, xalmo_history%nstore)
3371 IF (unit_nr > 0)
THEN
3372 WRITE (unit_nr, fmt=
"(/,T2,A,/,/,T3,A,I0)") &
3373 "Parameters for the always stable predictor-corrector (ASPC) method:", &
3374 "ASPC order: ", naspc
3377 DO ispin = 1, nspins
3379 CALL dbcsr_create(m_extrapolated, &
3380 template=m_quench_t(ispin), matrix_type=dbcsr_type_no_symmetry)
3381 CALL dbcsr_create(m_sigma_tmp, &
3382 template=m_sigma_tmpl(ispin), matrix_type=dbcsr_type_no_symmetry)
3385 CALL dbcsr_set(m_guess(ispin), 0.0_dp)
3390 istore = mod(xalmo_history%istore - iaspc, xalmo_history%nstore) + 1
3391 alpha = (-1.0_dp)**(iaspc + 1)*real(iaspc, kind=
dp)* &
3393 IF (unit_nr > 0)
THEN
3394 WRITE (unit_nr, fmt=
"(T3,A2,I0,A4,F10.6)") &
3395 "B(", iaspc,
") = ", alpha
3400 CALL dbcsr_copy(m_extrapolated, m_quench_t(ispin))
3408 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, &
3409 xalmo_history%matrix_p_up_down(ispin, istore), &
3411 0.0_dp, m_extrapolated, &
3412 retain_sparsity=.true.)
3415 overlap=m_sigma_tmp, &
3417 retain_locality=.true., &
3418 only_normalize=.false., &
3419 nocc_of_domain=nocc_of_domain(:, ispin), &
3420 eps_filter=eps_filter, &
3421 order_lanczos=order_lanczos, &
3422 eps_lanczos=eps_lanczos, &
3423 max_iter_lanczos=max_iter_lanczos)
3426 CALL dbcsr_add(m_guess(ispin), m_extrapolated, &
3427 1.0_dp, (1.0_dp*alpha)/naspc)
3431 CALL dbcsr_release(m_extrapolated)
3435 overlap=m_sigma_tmp, &
3437 retain_locality=.true., &
3438 only_normalize=.false., &
3439 nocc_of_domain=nocc_of_domain(:, ispin), &
3440 eps_filter=eps_filter, &
3441 order_lanczos=order_lanczos, &
3442 eps_lanczos=eps_lanczos, &
3443 max_iter_lanczos=max_iter_lanczos)
3445 CALL dbcsr_release(m_sigma_tmp)
3449 IF (assume_t0_q0x)
THEN
3450 CALL dbcsr_add(m_guess(ispin), m_t0(ispin), &
3458 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 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 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 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...
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-...
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
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, upper_to_full)
used to replace the cholesky decomposition by the inverse
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 matrix_sqrt_newton_schulz(matrix_sqrt, matrix_sqrt_inv, matrix, threshold, order, eps_lanczos, max_iter_lanczos, symmetrize, converged)
compute the sqrt of a matrix via the sign function and the corresponding Newton-Schulz iterations the...
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 ...
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.
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.
Orbital angular momentum.