86 TYPE(
dbcsr_type),
POINTER :: matrix_h, matrix_s
87 INTEGER,
INTENT(IN) :: output_unit
90 CHARACTER(len=*),
PARAMETER :: routinen =
'generate_extended_space'
92 INTEGER :: handle, homo, i_first, i_last, imo, iter, j, jj, max_iter, n, nao, nmat, nmat2, &
93 nmo, nmo_converged, nmo_not_converged, nset, nset_conv, nset_not_conv
94 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: iconv, inotconv
95 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: iconv_set, inotconv_set
96 LOGICAL :: converged, do_apply_preconditioner
97 REAL(
dp) :: lambda, max_norm, min_norm, t1, t2
98 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: ritz_coeff, vnorm
99 REAL(
dp),
DIMENSION(:),
POINTER :: eig_not_conv, eigenvalues, evals
101 TYPE(
cp_fm_type) :: c_conv, c_notconv, c_out, h_block, h_fm, &
102 m_hc, m_sc, m_tmp, mt_tmp, s_block, &
103 s_fm, v_block, w_block
104 TYPE(
cp_fm_type),
POINTER :: c_pz, c_z, mo_coeff
107 CALL timeset(routinen, handle)
109 NULLIFY (mo_coeff, mo_coeff_b, eigenvalues)
111 do_apply_preconditioner = .false.
113 CALL get_mo_set(mo_set=mo_set, mo_coeff=mo_coeff, mo_coeff_b=mo_coeff_b, eigenvalues=eigenvalues, &
114 nao=nao, nmo=nmo, homo=homo)
115 IF (do_apply_preconditioner)
THEN
116 max_iter = bdav_env%max_iter
122 NULLIFY (evals, eig_not_conv)
124 IF (output_unit > 0)
THEN
125 WRITE (output_unit,
"(T15,A,T23,A,T36,A,T49,A,T60,A,/,T8,A)") &
126 " Cycle ",
" conv. MOS ",
" B2MAX ",
" B2MIN ",
" Time", repeat(
"-", 60)
129 ALLOCATE (iconv(nmo))
130 ALLOCATE (inotconv(nmo))
131 ALLOCATE (ritz_coeff(nmo))
132 ALLOCATE (vnorm(nmo))
135 DO iter = 1, max_iter
139 CALL cp_fm_create(m_hc, mo_coeff%matrix_struct, name=
"hc")
141 CALL cp_fm_create(m_sc, mo_coeff%matrix_struct, name=
"sc")
145 context=mo_coeff%matrix_struct%context, &
146 para_env=mo_coeff%matrix_struct%para_env)
147 CALL cp_fm_create(m_tmp, fm_struct_tmp, name=
"matrix_tmp")
150 CALL parallel_gemm(
'T',
'N', nmo, nmo, nao, 1.0_dp, mo_coeff, m_hc, 0.0_dp, m_tmp)
155 c_z => bdav_env%matrix_z
156 c_pz => bdav_env%matrix_pz
163 nmo_not_converged = 0
167 max_norm = max(max_norm, vnorm(imo))
168 min_norm = min(min_norm, vnorm(imo))
173 IF (vnorm(imo) <= bdav_env%eps_iter)
THEN
174 nmo_converged = nmo_converged + 1
175 iconv(nmo_converged) = imo
177 nmo_not_converged = nmo_not_converged + 1
178 inotconv(nmo_not_converged) = imo
182 IF (nmo_converged > 0)
THEN
183 ALLOCATE (iconv_set(nmo_converged, 2))
184 ALLOCATE (inotconv_set(nmo_not_converged, 2))
187 DO j = 1, nmo_converged
190 IF (imo == i_last + 1)
THEN
192 iconv_set(nset, 2) = imo
196 iconv_set(nset, 1) = imo
197 iconv_set(nset, 2) = imo
204 DO j = 1, nmo_not_converged
207 IF (imo == i_last + 1)
THEN
209 inotconv_set(nset, 2) = imo
213 inotconv_set(nset, 1) = imo
214 inotconv_set(nset, 2) = imo
223 IF (real(nmo_converged,
dp)/real(nmo,
dp) > bdav_env%conv_percent)
THEN
225 DEALLOCATE (iconv_set)
226 DEALLOCATE (inotconv_set)
228 IF (output_unit > 0)
THEN
229 WRITE (output_unit,
'(T16,I5,T24,I6,T33,E12.4,2x,E12.4,T60,F8.3)') &
230 iter, nmo_converged, max_norm, min_norm, t2 - t1
232 WRITE (output_unit, *)
" Reached convergence in ", iter, &
233 " Davidson iterations"
239 IF (nmo_converged > 0)
THEN
241 context=mo_coeff%matrix_struct%context, &
242 para_env=mo_coeff%matrix_struct%para_env)
244 CALL cp_fm_create(h_fm, fm_struct_tmp, name=
"matrix_tmp")
246 CALL cp_fm_create(s_fm, fm_struct_tmp, name=
"matrix_tmp")
256 CALL cp_fm_create(c_out, fm_struct_tmp, name=
"matrix_tmp")
263 context=mo_coeff%matrix_struct%context, &
264 para_env=mo_coeff%matrix_struct%para_env)
268 CALL cp_fm_create(m_tmp, fm_struct_tmp, name=
"m_tmp_nxmc")
274 context=mo_coeff%matrix_struct%context, &
275 para_env=mo_coeff%matrix_struct%para_env)
276 CALL cp_fm_create(c_notconv, fm_struct_tmp, name=
"c_notconv")
278 IF (nmo_converged > 0)
THEN
290 i_first = iconv_set(j, 1)
291 i_last = iconv_set(j, 2)
292 n = i_last - i_first + 1
296 CALL cp_fm_symm(
'L',
'U', nao, nmo_converged, 1.0_dp, s_fm, c_conv, 0.0_dp, m_tmp)
297 CALL parallel_gemm(
'N',
'T', nao, nao, nmo_converged, 1.0_dp, m_tmp, m_tmp, 0.0_dp, c_out)
300 lambda = 100.0_dp*abs(eigenvalues(homo))
308 CALL cp_fm_create(m_tmp, fm_struct_tmp, name=
"m_tmp_nxm")
310 IF (nmo_converged > 0)
THEN
311 ALLOCATE (eig_not_conv(nmo_not_converged))
313 DO j = 1, nset_not_conv
314 i_first = inotconv_set(j, 1)
315 i_last = inotconv_set(j, 2)
316 n = i_last - i_first + 1
318 eig_not_conv(jj:jj + n - 1) = ritz_coeff(i_first:i_last)
321 CALL parallel_gemm(
'N',
'N', nao, nmo_not_converged, nao, 1.0_dp, c_out, c_notconv, 0.0_dp, m_hc)
322 CALL cp_fm_symm(
'L',
'U', nao, nmo_not_converged, 1.0_dp, s_fm, c_notconv, 0.0_dp, m_sc)
327 DEALLOCATE (eig_not_conv)
334 IF (do_apply_preconditioner)
THEN
345 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nmo_not_converged, ncol_global=nmo_not_converged, &
346 context=mo_coeff%matrix_struct%context, &
347 para_env=mo_coeff%matrix_struct%para_env)
349 CALL cp_fm_create(m_tmp, fm_struct_tmp, name=
"m_tmp_mxm")
350 CALL cp_fm_create(mt_tmp, fm_struct_tmp, name=
"mt_tmp_mxm")
353 nmat = nmo_not_converged
354 nmat2 = 2*nmo_not_converged
356 context=mo_coeff%matrix_struct%context, &
357 para_env=mo_coeff%matrix_struct%para_env)
363 ALLOCATE (evals(nmat2))
371 CALL parallel_gemm(
'T',
'N', nmat, nmat, nao, 1.0_dp, c_notconv, m_hc, 0.0_dp, m_tmp)
375 CALL parallel_gemm(
'T',
'N', nmat, nmat, nao, 1.0_dp, c_pz, m_sc, 0.0_dp, m_tmp)
380 CALL parallel_gemm(
'T',
'N', nmat, nmat, nao, 1.0_dp, c_pz, m_hc, 0.0_dp, m_tmp)
388 IF (nmo_converged > 0)
THEN
389 CALL parallel_gemm(
'N',
'N', nao, nmat, nao, 1.0_dp, c_out, c_pz, 0.0_dp, m_hc)
390 CALL cp_fm_symm(
'L',
'U', nao, nmo_not_converged, 1.0_dp, s_fm, c_pz, 0.0_dp, m_sc)
401 CALL parallel_gemm(
'T',
'N', nmat, nmat, nao, 1.0_dp, c_pz, m_sc, 0.0_dp, m_tmp)
404 CALL parallel_gemm(
'T',
'N', nmat, nmat, nao, 1.0_dp, c_pz, m_hc, 0.0_dp, m_tmp)
410 CALL reduce_extended_space(s_block, h_block, v_block, w_block, evals, nmat2)
414 CALL parallel_gemm(
'N',
'N', nao, nmat, nmat, 1.0_dp, c_notconv, m_tmp, 0.0_dp, m_hc)
416 CALL parallel_gemm(
'N',
'N', nao, nmat, nmat, 1.0_dp, c_pz, m_tmp, 1.0_dp, m_hc)
426 IF (nmo_converged > 0)
THEN
429 DEALLOCATE (c_z, c_pz)
431 DO j = 1, nset_not_conv
432 i_first = inotconv_set(j, 1)
433 i_last = inotconv_set(j, 2)
434 n = i_last - i_first + 1
436 eigenvalues(i_first:i_last) = evals(jj:jj + n - 1)
439 DEALLOCATE (iconv_set)
440 DEALLOCATE (inotconv_set)
443 eigenvalues(1:nmo) = evals(1:nmo)
452 IF (output_unit > 0)
THEN
453 WRITE (output_unit,
'(T16,I5,T24,I6,T33,E12.4,2x,E12.4,T60,F8.3)') &
454 iter, nmo_converged, max_norm, min_norm, t2 - t1
461 DEALLOCATE (inotconv)
462 DEALLOCATE (ritz_coeff)
465 CALL timestop(handle)
482 TYPE(
dbcsr_type),
POINTER :: matrix_h, matrix_s
483 INTEGER,
INTENT(IN) :: output_unit
486 CHARACTER(len=*),
PARAMETER :: routinen =
'generate_extended_space_sparse'
488 INTEGER :: col_offset, handle, homo, i_first, i_last, imo, iteration, j, jj, k, max_iter, n, &
489 nao, nmat, nmat2, nmo, nmo_converged, nmo_not_converged, nset, nset_conv, nset_not_conv
490 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: iconv, inotconv
491 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: iconv_set, inotconv_set
492 LOGICAL :: converged, do_apply_preconditioner
493 REAL(
dp) :: lambda, max_norm, min_norm, t1, t2
494 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: eig_not_conv, evals, ritz_coeff, vnorm
495 REAL(
dp),
DIMENSION(:),
POINTER :: eigenvalues
496 REAL(
dp),
DIMENSION(:, :),
POINTER :: block
498 TYPE(
cp_fm_type) :: h_block, matrix_mm_fm, matrix_mmt_fm, &
499 matrix_nm_fm, matrix_z_fm, mo_conv_fm, &
500 s_block, v_block, w_block
501 TYPE(
cp_fm_type),
POINTER :: mo_coeff, mo_notconv_fm
503 TYPE(
dbcsr_type),
POINTER :: c_out, matrix_hc, matrix_mm, matrix_pz, &
504 matrix_sc, matrix_z, mo_coeff_b, &
505 mo_conv, mo_notconv, smo_conv
508 CALL timeset(routinen, handle)
510 do_apply_preconditioner = .false.
513 NULLIFY (mo_coeff, mo_coeff_b, matrix_hc, matrix_sc, matrix_z, matrix_pz, matrix_mm)
514 NULLIFY (mo_notconv_fm, mo_conv, mo_notconv, smo_conv, c_out)
515 NULLIFY (fm_struct_tmp)
516 CALL get_mo_set(mo_set=mo_set, mo_coeff=mo_coeff, mo_coeff_b=mo_coeff_b, &
517 eigenvalues=eigenvalues, homo=homo, nao=nao, nmo=nmo)
518 IF (do_apply_preconditioner)
THEN
519 max_iter = bdav_env%max_iter
525 IF (output_unit > 0)
THEN
526 WRITE (output_unit,
"(T15,A,T23,A,T36,A,T49,A,T60,A,/,T8,A)") &
527 " Cycle ",
" conv. MOS ",
" B2MAX ",
" B2MIN ",
" Time", repeat(
"-", 60)
531 ALLOCATE (ritz_coeff(nmo))
532 ALLOCATE (iconv(nmo))
533 ALLOCATE (inotconv(nmo))
534 ALLOCATE (vnorm(nmo))
537 DO iteration = 1, max_iter
538 NULLIFY (c_out, mo_conv, mo_notconv_fm, mo_notconv)
543 matrix_type=dbcsr_type_no_symmetry)
547 matrix_type=dbcsr_type_no_symmetry)
549 CALL dbcsr_get_info(mo_coeff_b, nfullrows_total=n, nfullcols_total=k, group=group)
550 CALL dbcsr_multiply(
'n',
'n', 1.0_dp, matrix_h, mo_coeff_b, 0.0_dp, matrix_hc, last_column=k)
551 CALL dbcsr_multiply(
'n',
'n', 1.0_dp, matrix_s, mo_coeff_b, 0.0_dp, matrix_sc, last_column=k)
560 sym=dbcsr_type_no_symmetry)
562 CALL dbcsr_multiply(
't',
'n', 1.0_dp, mo_coeff_b, matrix_hc, 0.0_dp, matrix_mm, last_column=k)
564 CALL mo_coeff%matrix_struct%para_env%sum(ritz_coeff)
570 matrix_type=dbcsr_type_no_symmetry)
573 CALL dbcsr_add(matrix_z, matrix_hc, -1.0_dp, 1.0_dp)
580 DO j = 1,
SIZE(block, 2)
581 vnorm(col_offset + j - 1) = vnorm(col_offset + j - 1) + sum(block(:, j)**2)
585 CALL group%sum(vnorm)
590 nmo_not_converged = 0
594 max_norm = max(max_norm, vnorm(imo))
595 min_norm = min(min_norm, vnorm(imo))
601 IF (vnorm(imo) <= bdav_env%eps_iter)
THEN
602 nmo_converged = nmo_converged + 1
603 iconv(nmo_converged) = imo
605 nmo_not_converged = nmo_not_converged + 1
606 inotconv(nmo_not_converged) = imo
610 IF (nmo_converged > 0)
THEN
611 ALLOCATE (iconv_set(nmo_converged, 2))
612 ALLOCATE (inotconv_set(nmo_not_converged, 2))
615 DO j = 1, nmo_converged
618 IF (imo == i_last + 1)
THEN
620 iconv_set(nset, 2) = imo
624 iconv_set(nset, 1) = imo
625 iconv_set(nset, 2) = imo
632 DO j = 1, nmo_not_converged
635 IF (imo == i_last + 1)
THEN
637 inotconv_set(nset, 2) = imo
641 inotconv_set(nset, 1) = imo
642 inotconv_set(nset, 2) = imo
653 IF (real(nmo_converged,
dp)/real(nmo,
dp) > bdav_env%conv_percent)
THEN
654 DEALLOCATE (iconv_set)
656 DEALLOCATE (inotconv_set)
660 IF (output_unit > 0)
THEN
661 WRITE (output_unit,
'(T16,I5,T24,I6,T33,E12.4,2x,E12.4,T60,F8.3)') &
662 iteration, nmo_converged, max_norm, min_norm, t2 - t1
664 WRITE (output_unit, *)
" Reached convergence in ", iteration, &
665 " Davidson iterations"
671 IF (nmo_converged > 0)
THEN
675 context=mo_coeff%matrix_struct%context, &
676 para_env=mo_coeff%matrix_struct%para_env)
677 CALL cp_fm_create(mo_conv_fm, fm_struct_tmp, name=
"mo_conv_fm")
684 i_first = iconv_set(j, 1)
685 i_last = iconv_set(j, 2)
686 n = i_last - i_first + 1
695 matrix_type=dbcsr_type_symmetric)
700 sym=dbcsr_type_no_symmetry)
704 sym=dbcsr_type_no_symmetry)
708 CALL dbcsr_multiply(
'n',
'n', 1.0_dp, matrix_s, mo_conv, 0.0_dp, smo_conv, last_column=nmo_converged)
709 CALL dbcsr_multiply(
'n',
't', 1.0_dp, smo_conv, smo_conv, 0.0_dp, c_out, last_column=nao)
711 lambda = 100.0_dp*abs(eigenvalues(homo))
712 CALL dbcsr_add(c_out, matrix_h, lambda, 1.0_dp)
720 context=mo_coeff%matrix_struct%context, &
721 para_env=mo_coeff%matrix_struct%para_env)
722 ALLOCATE (mo_notconv_fm)
723 CALL cp_fm_create(mo_notconv_fm, fm_struct_tmp, name=
"mo_notconv_fm")
727 ALLOCATE (eig_not_conv(nmo_not_converged))
730 DO j = 1, nset_not_conv
731 i_first = inotconv_set(j, 1)
732 i_last = inotconv_set(j, 2)
733 n = i_last - i_first + 1
735 eig_not_conv(jj:jj + n - 1) = ritz_coeff(i_first:i_last)
742 sym=dbcsr_type_no_symmetry)
746 sym=dbcsr_type_no_symmetry)
750 sym=dbcsr_type_no_symmetry)
754 sym=dbcsr_type_no_symmetry)
758 CALL dbcsr_multiply(
'n',
'n', 1.0_dp, c_out, mo_notconv, 0.0_dp, matrix_hc, &
759 last_column=nmo_not_converged)
760 CALL dbcsr_multiply(
'n',
'n', 1.0_dp, matrix_s, mo_notconv, 0.0_dp, matrix_sc, &
761 last_column=nmo_not_converged)
765 CALL dbcsr_add(matrix_z, matrix_hc, -1.0_dp, 1.0_dp)
767 DEALLOCATE (eig_not_conv)
772 sym=dbcsr_type_no_symmetry)
774 CALL dbcsr_multiply(
't',
'n', 1.0_dp, mo_notconv, matrix_hc, 0.0_dp, matrix_mm, &
775 last_column=nmo_not_converged)
778 mo_notconv => mo_coeff_b
779 mo_notconv_fm => mo_coeff
787 matrix_type=dbcsr_type_no_symmetry)
789 IF (do_apply_preconditioner)
THEN
800 nmat = nmo_not_converged
802 context=mo_coeff%matrix_struct%context, &
803 para_env=mo_coeff%matrix_struct%para_env)
804 CALL cp_fm_create(matrix_mm_fm, fm_struct_tmp, name=
"m_tmp_mxm")
805 CALL cp_fm_create(matrix_mmt_fm, fm_struct_tmp, name=
"mt_tmp_mxm")
809 nmat2 = 2*nmo_not_converged
811 context=mo_coeff%matrix_struct%context, &
812 para_env=mo_coeff%matrix_struct%para_env)
818 ALLOCATE (evals(nmat2))
828 CALL dbcsr_multiply(
't',
'n', 1.0_dp, matrix_pz, matrix_sc, 0.0_dp, matrix_mm, last_column=nmat)
837 CALL dbcsr_multiply(
't',
'n', 1.0_dp, matrix_pz, matrix_hc, 0.0_dp, matrix_mm, last_column=nmat)
847 CALL dbcsr_get_info(matrix_pz, nfullrows_total=n, nfullcols_total=k)
848 CALL dbcsr_multiply(
'n',
'n', 1.0_dp, c_out, matrix_pz, 0.0_dp, matrix_hc, last_column=k)
849 CALL dbcsr_multiply(
'n',
'n', 1.0_dp, matrix_s, matrix_pz, 0.0_dp, matrix_sc, last_column=k)
852 CALL dbcsr_multiply(
't',
'n', 1.0_dp, matrix_pz, matrix_sc, 0.0_dp, matrix_mm, last_column=k)
858 CALL dbcsr_multiply(
't',
'n', 1.0_dp, matrix_pz, matrix_hc, 0.0_dp, matrix_mm, last_column=k)
867 CALL reduce_extended_space(s_block, h_block, v_block, w_block, evals, nmat2)
871 context=mo_coeff%matrix_struct%context, &
872 para_env=mo_coeff%matrix_struct%para_env)
873 CALL cp_fm_create(matrix_nm_fm, fm_struct_tmp, name=
"m_nxm")
874 CALL cp_fm_create(matrix_z_fm, fm_struct_tmp, name=
"m_nxm")
880 CALL parallel_gemm(
'N',
'N', nao, nmat, nmat, 1.0_dp, mo_notconv_fm, matrix_mm_fm, 0.0_dp, matrix_nm_fm)
882 CALL parallel_gemm(
'N',
'N', nao, nmat, nmat, 1.0_dp, matrix_z_fm, matrix_mm_fm, 1.0_dp, matrix_nm_fm)
894 IF (nmo_converged > 0)
THEN
896 DO j = 1, nset_not_conv
897 i_first = inotconv_set(j, 1)
898 i_last = inotconv_set(j, 2)
899 n = i_last - i_first + 1
901 eigenvalues(i_first:i_last) = evals(jj:jj + n - 1)
904 DEALLOCATE (iconv_set)
905 DEALLOCATE (inotconv_set)
910 DEALLOCATE (mo_notconv_fm)
913 eigenvalues(1:nmo) = evals(1:nmo)
921 IF (output_unit > 0)
THEN
922 WRITE (output_unit,
'(T16,I5,T24,I6,T33,E12.4,2x,E12.4,T60,F8.3)') &
923 iteration, nmo_converged, max_norm, min_norm, t2 - t1
929 DEALLOCATE (ritz_coeff)
931 DEALLOCATE (inotconv)
934 CALL timestop(handle)