38#include "./base/base_uses.f90"
49 PRIVATE :: qs_ot_p2m_diag
51 PRIVATE :: qs_ot_ref_poly
52 PRIVATE :: qs_ot_ref_chol
53 PRIVATE :: qs_ot_ref_lwdn
54 PRIVATE :: qs_ot_ref_decide
55 PRIVATE :: qs_ot_ref_update
56 PRIVATE :: qs_ot_refine
57 PRIVATE :: qs_ot_on_the_fly_localize
59 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_ot'
79 qs_ot_env%os_valid = .false.
80 IF (.NOT.
ASSOCIATED(qs_ot_env%matrix_psc0))
THEN
82 CALL dbcsr_copy(qs_ot_env%matrix_psc0, qs_ot_env%matrix_sc0,
'matrix_psc0')
85 IF (.NOT. qs_ot_env%use_dx)
THEN
86 qs_ot_env%use_dx = .true.
88 CALL dbcsr_copy(qs_ot_env%matrix_dx, qs_ot_env%matrix_gx,
'matrix_dx')
89 IF (qs_ot_env%settings%do_rotation)
THEN
91 CALL dbcsr_copy(qs_ot_env%rot_mat_dx, qs_ot_env%rot_mat_gx,
'rot_mat_dx')
93 IF (qs_ot_env%settings%do_ener)
THEN
94 ncoef =
SIZE(qs_ot_env%ener_gx)
95 ALLOCATE (qs_ot_env%ener_dx(ncoef))
96 qs_ot_env%ener_dx = 0.0_dp
110 SUBROUTINE qs_ot_on_the_fly_localize(qs_ot_env, C_NEW, SC, G_OLD, D)
113 TYPE(
dbcsr_type),
POINTER :: c_new, sc, g_old, d
115 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_on_the_fly_localize'
116 INTEGER,
PARAMETER :: taylor_order = 50
117 REAL(kind=
dp),
PARAMETER :: alpha = 0.1_dp, f2_eps = 0.01_dp
119 INTEGER :: col, col_size, handle, i, k, n, p, row, &
121 REAL(
dp),
DIMENSION(:, :),
POINTER :: block
122 REAL(kind=
dp) :: expfactor, f2, norm_fro, norm_gct, tmp
125 TYPE(
dbcsr_type),
POINTER :: c, gp1, gp2, gu, u
128 CALL timeset(routinen, handle)
134 gu => qs_ot_env%buf1_k_k_nosym
135 u => qs_ot_env%buf2_k_k_nosym
136 gp1 => qs_ot_env%buf3_k_k_nosym
137 gp2 => qs_ot_env%buf4_k_k_nosym
138 c => qs_ot_env%buf1_n_k
150 tmp = sqrt(block(i, p)**2 + f2_eps)
152 block(i, p) = block(i, p)/tmp
166 use_distribution=dist, &
167 transpose_distribution=.false.)
168 CALL dbcsr_add(gu, u, alpha_scalar=-0.5_dp, beta_scalar=0.5_dp)
190 DO i = 2, taylor_order
195 expfactor = expfactor/real(i, kind=
dp)
196 CALL dbcsr_add(u, gp1, alpha_scalar=1.0_dp, beta_scalar=expfactor)
199 IF (norm_fro*expfactor < 1.0e-10_dp)
EXIT
215 IF (
ASSOCIATED(g_old))
THEN
220 CALL timestop(handle)
221 END SUBROUTINE qs_ot_on_the_fly_localize
233 SUBROUTINE qs_ot_ref_chol(qs_ot_env, C_OLD, C_TMP, C_NEW, P, SC, update)
236 TYPE(
dbcsr_type) :: c_old, c_tmp, c_new, p, sc
237 LOGICAL,
INTENT(IN) :: update
239 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_ref_chol'
241 INTEGER :: handle, k, n
243 CALL timeset(routinen, handle)
252 transa=
"N", para_env=qs_ot_env%para_env, blacs_env=qs_ot_env%blacs_env)
257 transa=
"N", para_env=qs_ot_env%para_env, blacs_env=qs_ot_env%blacs_env)
261 CALL timestop(handle)
262 END SUBROUTINE qs_ot_ref_chol
274 SUBROUTINE qs_ot_ref_lwdn(qs_ot_env, C_OLD, C_TMP, C_NEW, P, SC, update)
277 TYPE(
dbcsr_type) :: c_old, c_tmp, c_new, p, sc
278 LOGICAL,
INTENT(IN) :: update
280 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_ref_lwdn'
282 INTEGER :: handle, i, k, n
283 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: eig, fun
286 CALL timeset(routinen, handle)
290 v => qs_ot_env%buf1_k_k_nosym
291 w => qs_ot_env%buf2_k_k_nosym
292 ALLOCATE (eig(k), fun(k))
294 CALL cp_dbcsr_syevd(p, v, eig, qs_ot_env%para_env, qs_ot_env%blacs_env)
298 IF (eig(i) <= 0.0_dp)
THEN
299 cpabort(
"P not positive definite")
301 IF (eig(i) < 1.0e-8_dp)
THEN
304 fun(i) = 1.0_dp/sqrt(eig(i))
320 DEALLOCATE (eig, fun)
322 CALL timestop(handle)
323 END SUBROUTINE qs_ot_ref_lwdn
336 SUBROUTINE qs_ot_ref_poly(qs_ot_env, C_OLD, C_TMP, C_NEW, P, SC, norm_in, update)
339 TYPE(
dbcsr_type),
POINTER :: c_old, c_tmp, c_new, p
341 REAL(
dp),
INTENT(IN) :: norm_in
342 LOGICAL,
INTENT(IN) :: update
344 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_ref_poly'
346 INTEGER :: handle, irefine, k, n
347 LOGICAL :: quick_exit
348 REAL(
dp) :: norm, norm_fro, norm_gct, occ_in, &
350 TYPE(
dbcsr_type),
POINTER :: buf1, buf2, buf_nosym, ft, fy
352 CALL timeset(routinen, handle)
356 buf_nosym => qs_ot_env%buf1_k_k_nosym
357 buf1 => qs_ot_env%buf1_k_k_sym
358 buf2 => qs_ot_env%buf2_k_k_sym
359 fy => qs_ot_env%buf3_k_k_sym
360 ft => qs_ot_env%buf4_k_k_sym
367 IF (norm < qs_ot_env%settings%eps_irac_quick_exit) quick_exit = .true.
371 DO irefine = 1, qs_ot_env%settings%max_irac
374 IF (norm > 1.0_dp)
THEN
376 rescale = rescale/sqrt(norm)
380 CALL qs_ot_refine(p, fy, buf1, buf2, qs_ot_env%settings%irac_degree, &
381 qs_ot_env%settings%eps_irac_filter_matrix)
384 IF (irefine == 1)
THEN
388 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
390 CALL dbcsr_filter(buf1, qs_ot_env%settings%eps_irac_filter_matrix)
403 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
405 CALL dbcsr_filter(buf_nosym, qs_ot_env%settings%eps_irac_filter_matrix)
409 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
411 CALL dbcsr_filter(p, qs_ot_env%settings%eps_irac_filter_matrix)
420 norm = min(norm_gct, norm_fro)
425 IF (norm > 1.0e10_dp)
THEN
426 CALL cp_abort(__location__, &
427 "Refinement blows up! "// &
428 "We need you to improve the code, please post your input on "// &
429 "the forum https://www.cp2k.org/")
433 IF (norm < qs_ot_env%settings%eps_irac_quick_exit) quick_exit = .true.
436 IF (norm < qs_ot_env%settings%eps_irac)
EXIT
442 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
444 CALL dbcsr_filter(c_new, qs_ot_env%settings%eps_irac_filter_matrix)
451 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
453 CALL dbcsr_filter(c_tmp, qs_ot_env%settings%eps_irac_filter_matrix)
459 CALL timestop(handle)
460 END SUBROUTINE qs_ot_ref_poly
467 FUNCTION qs_ot_ref_update(qs_ot_env1)
RESULT(update)
473 SELECT CASE (qs_ot_env1%settings%ot_method)
475 SELECT CASE (qs_ot_env1%settings%line_search_method)
477 IF (qs_ot_env1%line_search_count == 2) update = .true.
486 END FUNCTION qs_ot_ref_update
494 SUBROUTINE qs_ot_ref_decide(qs_ot_env1, norm_in, ortho_irac)
497 REAL(
dp),
INTENT(IN) :: norm_in
498 CHARACTER(LEN=*),
INTENT(INOUT) :: ortho_irac
500 ortho_irac = qs_ot_env1%settings%ortho_irac
501 IF (norm_in < qs_ot_env1%settings%eps_irac_switch) ortho_irac =
"POLY"
502 END SUBROUTINE qs_ot_ref_decide
516 matrix_gx_old, matrix_dx, qs_ot_env, qs_ot_env1)
518 TYPE(
dbcsr_type),
POINTER :: matrix_c, matrix_s, matrix_x, matrix_sx, &
519 matrix_gx_old, matrix_dx
522 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_orbitals_ref'
524 CHARACTER(LEN=4) :: ortho_irac
525 INTEGER :: handle, k, n
526 LOGICAL :: on_the_fly_loc, update
527 REAL(
dp) :: norm, norm_fro, norm_gct, occ_in, occ_out
528 TYPE(
dbcsr_type),
POINTER :: c_new, c_old, c_tmp, d, g_old, p, s, sc
530 CALL timeset(routinen, handle)
532 CALL dbcsr_get_info(matrix_c, nfullrows_total=n, nfullcols_total=k)
537 g_old => matrix_gx_old
541 p => qs_ot_env%p_k_k_sym
542 c_tmp => qs_ot_env%buf1_n_k
545 update = qs_ot_ref_update(qs_ot_env1)
551 on_the_fly_loc = qs_ot_env1%settings%on_the_fly_loc
554 IF (
ASSOCIATED(s))
THEN
556 IF (qs_ot_env1%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
558 CALL dbcsr_filter(sc, qs_ot_env1%settings%eps_irac_filter_matrix)
567 IF (qs_ot_env1%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
569 CALL dbcsr_filter(p, qs_ot_env1%settings%eps_irac_filter_matrix)
578 norm = min(norm_gct, norm_fro)
579 CALL qs_ot_ref_decide(qs_ot_env1, norm, ortho_irac)
582 SELECT CASE (ortho_irac)
584 CALL qs_ot_ref_chol(qs_ot_env, c_old, c_tmp, c_new, p, sc, update)
586 CALL qs_ot_ref_lwdn(qs_ot_env, c_old, c_tmp, c_new, p, sc, update)
588 CALL qs_ot_ref_poly(qs_ot_env, c_old, c_tmp, c_new, p, sc, norm, update)
590 cpabort(
"Wrong argument")
595 IF (on_the_fly_loc)
THEN
596 CALL qs_ot_on_the_fly_localize(qs_ot_env, c_new, sc, g_old, d)
601 CALL timestop(handle)
613 SUBROUTINE qs_ot_refine(P, FY, P2, T, irac_degree, eps_irac_filter_matrix)
614 TYPE(
dbcsr_type),
INTENT(inout) :: p, fy, p2, t
615 INTEGER,
INTENT(in) :: irac_degree
616 REAL(
dp),
INTENT(in) :: eps_irac_filter_matrix
618 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_refine'
621 REAL(
dp) :: occ_in, occ_out, r
623 CALL timeset(routinen, handle)
626 SELECT CASE (irac_degree)
631 IF (eps_irac_filter_matrix > 0.0_dp)
THEN
637 CALL dbcsr_add(fy, p, alpha_scalar=1.0_dp, beta_scalar=r)
643 IF (eps_irac_filter_matrix > 0.0_dp)
THEN
650 IF (eps_irac_filter_matrix > 0.0_dp)
THEN
656 CALL dbcsr_add(fy, p2, alpha_scalar=1.0_dp, beta_scalar=r)
658 CALL dbcsr_add(fy, p, alpha_scalar=1.0_dp, beta_scalar=r)
665 IF (eps_irac_filter_matrix > 0.0_dp)
THEN
670 r = -180.0_dp/128.0_dp
671 CALL dbcsr_add(t, p, alpha_scalar=0.0_dp, beta_scalar=r)
673 CALL dbcsr_add(t, p2, alpha_scalar=1.0_dp, beta_scalar=r)
675 IF (eps_irac_filter_matrix > 0.0_dp)
THEN
680 r = 378.0_dp/128.0_dp
681 CALL dbcsr_add(fy, p2, alpha_scalar=1.0_dp, beta_scalar=r)
682 r = -420.0_dp/128.0_dp
683 CALL dbcsr_add(fy, p, alpha_scalar=1.0_dp, beta_scalar=r)
684 r = 315.0_dp/128.0_dp
687 cpabort(
"This irac_order NYI")
689 CALL timestop(handle)
690 END SUBROUTINE qs_ot_refine
702 TYPE(
dbcsr_type),
POINTER :: matrix_hc, matrix_x, matrix_sx, matrix_gx
705 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative_ref'
707 INTEGER :: handle, k, n
708 REAL(
dp) :: occ_in, occ_out
709 TYPE(
dbcsr_type),
POINTER :: c, chc, g, g_dp, hc, sc
711 CALL timeset(routinen, handle)
713 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
719 chc => qs_ot_env%buf1_k_k_sym
720 g_dp => qs_ot_env%buf1_n_k_dp
724 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
726 CALL dbcsr_filter(chc, qs_ot_env%settings%eps_irac_filter_matrix)
731 IF (qs_ot_env%settings%eps_irac_filter_matrix > 0.0_dp)
THEN
733 CALL dbcsr_filter(g, qs_ot_env%settings%eps_irac_filter_matrix)
737 CALL dbcsr_add(g, hc, alpha_scalar=-1.0_dp, beta_scalar=1.0_dp)
739 CALL timestop(handle)
750 TYPE(
dbcsr_type),
POINTER :: matrix_x, matrix_sx
753 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_p'
754 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
756 INTEGER :: handle, k, max_iter, n
758 REAL(kind=
dp) :: max_ev, min_ev, threshold
760 CALL timeset(routinen, handle)
762 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
770 max_iter = 30; threshold = 1.0e-03_dp
771 CALL arnoldi_extremal(qs_ot_env%matrix_p, max_ev, min_ev, converged, threshold, max_iter)
772 qs_ot_env%largest_eval_upper_bound = max(max_ev, abs(min_ev))
775 CALL decide_strategy(qs_ot_env)
776 IF (qs_ot_env%do_taylor)
THEN
777 CALL qs_ot_p2m_taylor(qs_ot_env)
779 CALL qs_ot_p2m_diag(qs_ot_env)
782 IF (qs_ot_env%settings%do_rotation)
THEN
783 CALL qs_ot_generate_rotation(qs_ot_env)
786 CALL timestop(handle)
798 SUBROUTINE qs_ot_generate_rotation(qs_ot_env)
802 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_generate_rotation'
805 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: exp_evals_im, exp_evals_re
808 CALL timeset(routinen, handle)
818 eigenvectors_re=qs_ot_env%rot_mat_evec_re, &
819 eigenvectors_im=qs_ot_env%rot_mat_evec_im, &
820 eigenvalues=qs_ot_env%rot_mat_evals, &
821 para_env=qs_ot_env%para_env, &
822 blacs_env=qs_ot_env%blacs_env)
825 ALLOCATE (exp_evals_re(k), exp_evals_im(k))
826 exp_evals_re(:) = cos(-qs_ot_env%rot_mat_evals(:))
827 exp_evals_im(:) = sin(-qs_ot_env%rot_mat_evals(:))
831 CALL dbcsr_copy(buf_1, qs_ot_env%rot_mat_evec_re, name=
"buf_1")
833 CALL dbcsr_copy(buf_2, qs_ot_env%rot_mat_evec_im, name=
"buf_2")
835 CALL dbcsr_add(buf_1, buf_2, alpha_scalar=+1.0_dp, beta_scalar=-1.0_dp)
836 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, buf_1, qs_ot_env%rot_mat_evec_re, 0.0_dp, qs_ot_env%rot_mat_u)
838 CALL dbcsr_copy(buf_1, qs_ot_env%rot_mat_evec_im)
840 CALL dbcsr_copy(buf_2, qs_ot_env%rot_mat_evec_re)
842 CALL dbcsr_add(buf_1, buf_2, alpha_scalar=+1.0_dp, beta_scalar=+1.0_dp)
843 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, buf_1, qs_ot_env%rot_mat_evec_im, 1.0_dp, qs_ot_env%rot_mat_u)
848 DEALLOCATE (exp_evals_re, exp_evals_im)
851 CALL timestop(handle)
853 END SUBROUTINE qs_ot_generate_rotation
863 SUBROUTINE qs_ot_rot_mat_derivative(qs_ot_env)
866 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_rot_mat_derivative'
868 INTEGER :: handle, i, j, k
869 REAL(kind=
dp) :: e1, e2
870 TYPE(
dbcsr_type) :: outer_deriv_re, outer_deriv_im, mat_buf, &
871 inner_deriv_re, inner_deriv_im
873 INTEGER,
DIMENSION(:),
POINTER :: row_blk_offset, col_blk_offset
874 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_in_re, block_in_im, block_out_re, block_out_im
877 COMPLEX(dp) :: cval_in, cval_out
880 CALL timeset(routinen, handle)
884 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%rot_mat_dedu)
886 CALL dbcsr_copy(mat_buf, qs_ot_env%rot_mat_dedu,
"mat_buf")
889 CALL dbcsr_copy(inner_deriv_re, qs_ot_env%rot_mat_dedu,
"inner_deriv_re")
890 CALL dbcsr_copy(inner_deriv_im, qs_ot_env%rot_mat_dedu,
"inner_deriv_im")
892 CALL dbcsr_multiply(
'T',
'N', +1.0_dp, qs_ot_env%rot_mat_dedu, qs_ot_env%rot_mat_evec_im, 0.0_dp, mat_buf)
893 CALL dbcsr_multiply(
'T',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_im, mat_buf, 0.0_dp, inner_deriv_re)
894 CALL dbcsr_multiply(
'T',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_re, mat_buf, 0.0_dp, inner_deriv_im)
896 CALL dbcsr_multiply(
'T',
'N', +1.0_dp, qs_ot_env%rot_mat_dedu, qs_ot_env%rot_mat_evec_re, 0.0_dp, mat_buf)
897 CALL dbcsr_multiply(
'T',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_re, mat_buf, 1.0_dp, inner_deriv_re)
898 CALL dbcsr_multiply(
'T',
'N', -1.0_dp, qs_ot_env%rot_mat_evec_im, mat_buf, 1.0_dp, inner_deriv_im)
901 CALL dbcsr_copy(outer_deriv_re, qs_ot_env%rot_mat_dedu,
"outer_deriv_re")
902 CALL dbcsr_copy(outer_deriv_im, qs_ot_env%rot_mat_dedu,
"outer_deriv_im")
904 CALL dbcsr_get_info(qs_ot_env%rot_mat_dedu, row_blk_offset=row_blk_offset, col_blk_offset=col_blk_offset)
913 DO i = 1,
SIZE(block_in_re, 1)
914 DO j = 1,
SIZE(block_in_re, 2)
915 e1 = qs_ot_env%rot_mat_evals(row_blk_offset(row) + i - 1)
916 e2 = qs_ot_env%rot_mat_evals(col_blk_offset(col) + j - 1)
917 cval_in = cmplx(block_in_re(i, j), block_in_im(i, j),
dp)
918 cval_out = cval_in*cint(e1, e2)
919 block_out_re(i, j) = real(cval_out)
920 block_out_im(i, j) = aimag(cval_out)
929 CALL dbcsr_multiply(
'N',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_re, outer_deriv_re, 0.0_dp, mat_buf)
930 CALL dbcsr_multiply(
'N',
'N', -1.0_dp, qs_ot_env%rot_mat_evec_im, outer_deriv_im, 1.0_dp, mat_buf)
931 CALL dbcsr_multiply(
'N',
'T', +1.0_dp, mat_buf, qs_ot_env%rot_mat_evec_re, 0.0_dp, qs_ot_env%matrix_buf1)
933 CALL dbcsr_multiply(
'N',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_re, outer_deriv_im, 0.0_dp, mat_buf)
934 CALL dbcsr_multiply(
'N',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_im, outer_deriv_re, 1.0_dp, mat_buf)
935 CALL dbcsr_multiply(
'N',
'T', +1.0_dp, mat_buf, qs_ot_env%rot_mat_evec_im, 1.0_dp, qs_ot_env%matrix_buf1)
940 shallow_data_copy=.false., use_distribution=dist, &
941 transpose_distribution=.false.)
944 CALL dbcsr_add(qs_ot_env%matrix_buf1, qs_ot_env%matrix_buf2, alpha_scalar=-1.0_dp, beta_scalar=+1.0_dp)
945 CALL dbcsr_copy(qs_ot_env%rot_mat_gx, qs_ot_env%matrix_buf1)
951 CALL timestop(handle)
960 FUNCTION cint(e1, e2)
961 REAL(kind=
dp) :: e1, e2
962 COMPLEX(KIND=dp) :: cint
964 COMPLEX(KIND=dp) :: l1, l2, x
967 l1 = (0.0_dp, -1.0_dp)*e1
968 l2 = (0.0_dp, -1.0_dp)*e2
969 IF (abs(l1 - l2) > 0.5_dp)
THEN
970 cint = (exp(l1) - exp(l2))/(l1 - l2)
976 x = x*(l1 - l2)/real(i + 1, kind=
dp)
981 END SUBROUTINE qs_ot_rot_mat_derivative
992 SUBROUTINE decide_strategy(qs_ot_env)
996 REAL(kind=
dp) :: num_error
998 qs_ot_env%do_taylor = .false.
1000 num_error = qs_ot_env%largest_eval_upper_bound/(2.0_dp)
1001 DO WHILE (num_error > qs_ot_env%settings%eps_taylor .AND. n <= qs_ot_env%settings%max_taylor)
1003 num_error = num_error*qs_ot_env%largest_eval_upper_bound/real((2*n + 1)*(2*n + 2), kind=
dp)
1005 qs_ot_env%taylor_order = n
1006 IF (qs_ot_env%taylor_order <= qs_ot_env%settings%max_taylor)
THEN
1007 qs_ot_env%do_taylor = .true.
1010 END SUBROUTINE decide_strategy
1022 TYPE(
dbcsr_type),
POINTER :: matrix_c, matrix_x
1025 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_orbitals'
1026 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1028 INTEGER :: handle, k, n
1031 CALL timeset(routinen, handle)
1033 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
1037 IF (qs_ot_env%settings%do_rotation)
THEN
1038 matrix_kk => qs_ot_env%matrix_buf1
1040 qs_ot_env%rot_mat_u, rzero, matrix_kk)
1042 matrix_kk => qs_ot_env%matrix_cosp
1045 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_c0, matrix_kk, &
1048 IF (qs_ot_env%settings%do_rotation)
THEN
1049 matrix_kk => qs_ot_env%matrix_buf1
1051 qs_ot_env%rot_mat_u, rzero, matrix_kk)
1053 matrix_kk => qs_ot_env%matrix_sinp
1058 CALL timestop(handle)
1075 TYPE(
dbcsr_type),
POINTER :: matrix_hc, matrix_x, matrix_sx, matrix_gx
1078 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative'
1079 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1081 INTEGER :: handle, k, n, ortho_k
1082 TYPE(
dbcsr_type),
POINTER :: matrix_hc_local, matrix_target
1084 CALL timeset(routinen, handle)
1086 NULLIFY (matrix_hc_local)
1088 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
1093 IF (qs_ot_env%settings%do_rotation)
THEN
1096 CALL dbcsr_copy(matrix_hc_local, matrix_hc, name=
'matrix_hc_local')
1098 CALL dbcsr_multiply(
'N',
'T', rone, matrix_gx, qs_ot_env%rot_mat_u, rzero, matrix_hc_local)
1100 matrix_hc_local => matrix_hc
1103 IF (qs_ot_env%do_taylor)
THEN
1104 CALL qs_ot_get_derivative_taylor(matrix_hc_local, matrix_x, matrix_sx, matrix_gx, qs_ot_env)
1106 CALL qs_ot_get_derivative_diag(matrix_hc_local, matrix_x, matrix_sx, matrix_gx, qs_ot_env)
1110 CALL dbcsr_get_info(qs_ot_env%matrix_sc0, nfullcols_total=ortho_k)
1112 IF (
ASSOCIATED(qs_ot_env%preconditioner))
THEN
1113 matrix_target => qs_ot_env%matrix_psc0
1115 matrix_target => qs_ot_env%matrix_sc0
1118 IF (.NOT. qs_ot_env%os_valid)
THEN
1122 IF (
ASSOCIATED(qs_ot_env%preconditioner))
THEN
1124 qs_ot_env%matrix_psc0)
1127 qs_ot_env%matrix_sc0, matrix_target, &
1128 rzero, qs_ot_env%matrix_os)
1130 para_env=qs_ot_env%para_env, blacs_env=qs_ot_env%blacs_env)
1132 para_env=qs_ot_env%para_env, blacs_env=qs_ot_env%blacs_env, &
1133 uplo_to_full=.true.)
1134 qs_ot_env%os_valid = .true.
1137 rzero, qs_ot_env%matrix_buf1_ortho)
1139 qs_ot_env%matrix_buf1_ortho, rzero, qs_ot_env%matrix_buf2_ortho)
1141 qs_ot_env%matrix_buf2_ortho, rone, matrix_gx)
1143 IF (qs_ot_env%settings%do_rotation)
THEN
1144 CALL qs_ot_rot_mat_derivative(qs_ot_env)
1147 IF (qs_ot_env%settings%do_rotation)
THEN
1151 CALL timestop(handle)
1163 SUBROUTINE qs_ot_get_derivative_diag(matrix_hc, matrix_x, matrix_sx, matrix_gx, &
1166 TYPE(
dbcsr_type),
POINTER :: matrix_hc, matrix_x, matrix_sx, matrix_gx
1169 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative_diag'
1170 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1172 INTEGER :: handle, k, n
1175 CALL timeset(routinen, handle)
1177 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
1181 CALL dbcsr_multiply(
'N',
'N', rone, matrix_hc, qs_ot_env%matrix_sinp, rzero, matrix_gx)
1183 CALL dbcsr_multiply(
'T',
'N', rone, matrix_hc, matrix_x, rzero, qs_ot_env%matrix_buf2)
1185 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_buf2, qs_ot_env%matrix_r, &
1186 rzero, qs_ot_env%matrix_buf1)
1187 CALL dbcsr_multiply(
'T',
'N', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
1188 rzero, qs_ot_env%matrix_buf2)
1192 qs_ot_env%matrix_buf3)
1195 CALL dbcsr_multiply(
'T',
'N', rone, matrix_hc, qs_ot_env%matrix_c0, rzero, &
1196 qs_ot_env%matrix_buf2)
1198 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_buf2, qs_ot_env%matrix_r, &
1199 rzero, qs_ot_env%matrix_buf1)
1200 CALL dbcsr_multiply(
'T',
'N', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
1201 rzero, qs_ot_env%matrix_buf2)
1204 qs_ot_env%matrix_buf4)
1207 CALL dbcsr_add(qs_ot_env%matrix_buf3, qs_ot_env%matrix_buf4, &
1208 alpha_scalar=rone, beta_scalar=rone)
1211 CALL dbcsr_multiply(
'N',
'T', rone, qs_ot_env%matrix_buf3, qs_ot_env%matrix_r, &
1212 rzero, qs_ot_env%matrix_buf1)
1213 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
1214 rzero, qs_ot_env%matrix_buf3)
1217 shallow_data_copy=.false., use_distribution=dist, &
1218 transpose_distribution=.false.)
1219 CALL dbcsr_add(qs_ot_env%matrix_buf3, qs_ot_env%matrix_buf1, &
1220 alpha_scalar=rone, beta_scalar=rone)
1223 CALL dbcsr_multiply(
'N',
'N', rone, matrix_sx, qs_ot_env%matrix_buf3, &
1225 CALL timestop(handle)
1227 END SUBROUTINE qs_ot_get_derivative_diag
1237 SUBROUTINE qs_ot_get_derivative_taylor(matrix_hc, matrix_x, matrix_sx, matrix_gx, &
1240 TYPE(
dbcsr_type),
POINTER :: matrix_hc, matrix_x, matrix_sx, matrix_gx
1243 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative_taylor'
1244 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1246 INTEGER :: handle, i, k, n
1247 REAL(kind=
dp) :: cosfactor, sinfactor
1249 TYPE(
dbcsr_type),
POINTER :: matrix_left, matrix_right
1251 CALL timeset(routinen, handle)
1253 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
1257 CALL dbcsr_multiply(
'N',
'N', rone, matrix_hc, qs_ot_env%matrix_sinp, rzero, matrix_gx)
1259 IF (qs_ot_env%taylor_order <= 0)
THEN
1260 CALL timestop(handle)
1265 CALL dbcsr_set(qs_ot_env%matrix_r, rzero)
1268 matrix_left => qs_ot_env%matrix_cosp_b
1269 matrix_right => qs_ot_env%matrix_sinp_b
1272 CALL dbcsr_multiply(
'T',
'N', rone, matrix_hc, matrix_x, rzero, matrix_left)
1275 shallow_data_copy=.false., use_distribution=dist, &
1276 transpose_distribution=.false.)
1277 CALL dbcsr_add(matrix_left, qs_ot_env%matrix_buf1, &
1278 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
1282 sinfactor = -1.0_dp/(2.0_dp*3.0_dp)
1283 CALL dbcsr_add(qs_ot_env%matrix_r, matrix_left, &
1284 alpha_scalar=1.0_dp, beta_scalar=sinfactor)
1290 DO i = 2, qs_ot_env%taylor_order
1291 sinfactor = sinfactor*(-1.0_dp)/real(2*i*(2*i + 1), kind=
dp)
1292 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_p, matrix_left, rzero, qs_ot_env%matrix_buf1)
1293 CALL dbcsr_multiply(
'N',
'N', rone, matrix_right, qs_ot_env%matrix_p, rzero, matrix_left)
1295 CALL dbcsr_add(matrix_left, qs_ot_env%matrix_buf1, &
1297 CALL dbcsr_add(qs_ot_env%matrix_r, matrix_left, &
1298 alpha_scalar=1.0_dp, beta_scalar=sinfactor)
1302 CALL dbcsr_multiply(
'T',
'N', rone, matrix_hc, qs_ot_env%matrix_c0, rzero, matrix_left)
1305 shallow_data_copy=.false., use_distribution=dist, &
1306 transpose_distribution=.false.)
1307 CALL dbcsr_add(matrix_left, qs_ot_env%matrix_buf1, 1.0_dp, 1.0_dp)
1311 cosfactor = -1.0_dp/(1.0_dp*2.0_dp)
1312 CALL dbcsr_add(qs_ot_env%matrix_r, matrix_left, &
1313 alpha_scalar=1.0_dp, beta_scalar=cosfactor)
1319 DO i = 2, qs_ot_env%taylor_order
1320 cosfactor = cosfactor*(-1.0_dp)/real(2*i*(2*i - 1), kind=
dp)
1321 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_p, matrix_left, rzero, qs_ot_env%matrix_buf1)
1322 CALL dbcsr_multiply(
'N',
'N', rone, matrix_right, qs_ot_env%matrix_p, rzero, matrix_left)
1324 CALL dbcsr_add(matrix_left, qs_ot_env%matrix_buf1, 1.0_dp, 1.0_dp)
1325 CALL dbcsr_add(qs_ot_env%matrix_r, matrix_left, &
1326 alpha_scalar=1.0_dp, beta_scalar=cosfactor)
1330 CALL dbcsr_multiply(
'N',
'N', rone, matrix_sx, qs_ot_env%matrix_r, rone, matrix_gx)
1332 CALL timestop(handle)
1334 END SUBROUTINE qs_ot_get_derivative_taylor
1340 SUBROUTINE qs_ot_p2m_taylor(qs_ot_env)
1343 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_p2m_taylor'
1344 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1346 INTEGER :: handle, i, k
1347 REAL(kind=
dp) :: cosfactor, sinfactor
1349 CALL timeset(routinen, handle)
1352 CALL dbcsr_set(qs_ot_env%matrix_cosp, rzero)
1353 CALL dbcsr_set(qs_ot_env%matrix_sinp, rzero)
1357 IF (qs_ot_env%taylor_order <= 0)
THEN
1358 CALL timestop(handle)
1363 cosfactor = -1.0_dp/(1.0_dp*2.0_dp)
1364 sinfactor = -1.0_dp/(2.0_dp*3.0_dp)
1365 CALL dbcsr_add(qs_ot_env%matrix_cosp, qs_ot_env%matrix_p, alpha_scalar=1.0_dp, beta_scalar=cosfactor)
1366 CALL dbcsr_add(qs_ot_env%matrix_sinp, qs_ot_env%matrix_p, alpha_scalar=1.0_dp, beta_scalar=sinfactor)
1367 IF (qs_ot_env%taylor_order <= 1)
THEN
1368 CALL timestop(handle)
1374 CALL dbcsr_copy(qs_ot_env%matrix_r, qs_ot_env%matrix_p)
1376 DO i = 2, qs_ot_env%taylor_order
1378 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_p, qs_ot_env%matrix_r, &
1379 rzero, qs_ot_env%matrix_buf1)
1380 CALL dbcsr_copy(qs_ot_env%matrix_r, qs_ot_env%matrix_buf1)
1382 cosfactor = cosfactor*(-1.0_dp)/real(2*i*(2*i - 1), kind=
dp)
1383 sinfactor = sinfactor*(-1.0_dp)/real(2*i*(2*i + 1), kind=
dp)
1384 CALL dbcsr_add(qs_ot_env%matrix_cosp, qs_ot_env%matrix_r, &
1385 alpha_scalar=1.0_dp, beta_scalar=cosfactor)
1386 CALL dbcsr_add(qs_ot_env%matrix_sinp, qs_ot_env%matrix_r, &
1387 alpha_scalar=1.0_dp, beta_scalar=sinfactor)
1390 CALL timestop(handle)
1392 END SUBROUTINE qs_ot_p2m_taylor
1402 SUBROUTINE qs_ot_p2m_diag(qs_ot_env)
1406 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_p2m_diag'
1407 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1409 INTEGER :: col, col_offset, col_size, handle, i, j, &
1410 k, row, row_offset, row_size
1411 REAL(
dp),
DIMENSION(:, :),
POINTER :: block
1412 REAL(kind=
dp) :: a, b
1415 CALL timeset(routinen, handle)
1418 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_p)
1419 CALL cp_dbcsr_syevd(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r, qs_ot_env%evals, &
1420 qs_ot_env%para_env, qs_ot_env%blacs_env)
1422 qs_ot_env%evals(i) = max(0.0_dp, qs_ot_env%evals(i))
1427 qs_ot_env%dum(i) = cos(sqrt(qs_ot_env%evals(i)))
1429 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r)
1431 CALL dbcsr_multiply(
'N',
'T', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
1432 rzero, qs_ot_env%matrix_cosp)
1436 qs_ot_env%dum(i) = qs_ot_sinc(sqrt(qs_ot_env%evals(i)))
1438 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r)
1440 CALL dbcsr_multiply(
'N',
'T', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
1441 rzero, qs_ot_env%matrix_sinp)
1443 CALL dbcsr_copy(qs_ot_env%matrix_cosp_b, qs_ot_env%matrix_cosp)
1447 row_size=row_size, col_size=col_size, &
1448 row_offset=row_offset, col_offset=col_offset)
1451 a = (sqrt(qs_ot_env%evals(row_offset + i - 1)) &
1452 - sqrt(qs_ot_env%evals(col_offset + j - 1)))/2.0_dp
1453 b = (sqrt(qs_ot_env%evals(row_offset + i - 1)) &
1454 + sqrt(qs_ot_env%evals(col_offset + j - 1)))/2.0_dp
1455 block(i, j) = -0.5_dp*qs_ot_sinc(a)*qs_ot_sinc(b)
1461 CALL dbcsr_copy(qs_ot_env%matrix_sinp_b, qs_ot_env%matrix_sinp)
1465 row_size=row_size, col_size=col_size, &
1466 row_offset=row_offset, col_offset=col_offset)
1469 a = sqrt(qs_ot_env%evals(row_offset + i - 1))
1470 b = sqrt(qs_ot_env%evals(col_offset + j - 1))
1471 block(i, j) = qs_ot_sincf(a, b)
1477 CALL timestop(handle)
1479 END SUBROUTINE qs_ot_p2m_diag
1486 FUNCTION qs_ot_sinc(x)
1488 REAL(kind=
dp),
INTENT(IN) :: x
1489 REAL(kind=
dp) :: qs_ot_sinc
1491 REAL(kind=
dp),
PARAMETER :: q1 = 1.0_dp, q2 = -q1/(2.0_dp*3.0_dp), q3 = -q2/(4.0_dp*5.0_dp), &
1492 q4 = -q3/(6.0_dp*7.0_dp), q5 = -q4/(8.0_dp*9.0_dp), q6 = -q5/(10.0_dp*11.0_dp), &
1493 q7 = -q6/(12.0_dp*13.0_dp), q8 = -q7/(14.0_dp*15.0_dp), q9 = -q8/(16.0_dp*17.0_dp), &
1494 q10 = -q9/(18.0_dp*19.0_dp)
1498 IF (abs(x) > 0.5_dp)
THEN
1499 qs_ot_sinc = sin(x)/x
1502 qs_ot_sinc = q1 + y*(q2 + y*(q3 + y*(q4 + y*(q5 + y*(q6 + y*(q7 + y*(q8 + y*(q9 + y*(q10)))))))))
1504 END FUNCTION qs_ot_sinc
1512 FUNCTION qs_ot_sincf(xa, ya)
1514 REAL(kind=
dp),
INTENT(IN) :: xa, ya
1515 REAL(kind=
dp) :: qs_ot_sincf
1518 REAL(kind=
dp) :: a, b, rs, sf, x, xs, y, ybx, ybxs
1521 IF (xa < 0) cpabort(
"x is negative")
1522 IF (ya < 0) cpabort(
"y is negative")
1532 IF (x < 0.5_dp)
THEN
1534 qs_ot_sincf = 0.0_dp
1535 IF (x > 0.0_dp)
THEN
1541 sf = -1.0_dp/((1.0_dp + ybx)*6.0_dp)
1547 qs_ot_sincf = qs_ot_sincf + sf*rs*xs*(1.0_dp + ybxs)
1548 sf = -sf/(real((2*i + 2),
dp)*real((2*i + 3),
dp))
1555 IF (x - y > 0.1_dp)
THEN
1556 qs_ot_sincf = (qs_ot_sinc(x) - qs_ot_sinc(y))/((x + y)*(x - y))
1561 qs_ot_sincf = (qs_ot_sinc(b)*cos(a) - qs_ot_sinc(a)*cos(b))/(2*x*y)
1565 END FUNCTION qs_ot_sincf
arnoldi iteration using dbcsr
subroutine, public arnoldi_extremal(matrix_a, max_ev, min_ev, converged, threshold, max_iter)
simple wrapper to estimate extremal eigenvalues with arnoldi, using the old lanczos interface this hi...
subroutine, public dbcsr_transposed(transposed, normal, shallow_data_copy, transpose_distribution, use_distribution)
...
subroutine, public dbcsr_release_p(matrix)
...
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
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_get_block_p(matrix, row, col, block, found, row_size, col_size)
...
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_init_p(matrix)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset, transposed)
...
subroutine, public dbcsr_filter(matrix, eps)
...
real(kind=dp) function, public dbcsr_get_occupation(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_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
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_restore(matrix, neig, matrixb, matrixout, op, pos, transa, para_env, blacs_env)
...
subroutine, public cp_dbcsr_cholesky_invert(matrix, n, para_env, blacs_env, uplo_to_full)
used to replace the cholesky decomposition by the inverse
real(dp) function, public dbcsr_gershgorin_norm(matrix)
Compute the gershgorin norm of a dbcsr matrix.
subroutine, public dbcsr_add_on_diag(matrix, alpha)
Adds the given scalar to the diagonal of the matrix. Reserves any missing diagonal blocks.
real(dp) function, public dbcsr_frobenius_norm(matrix)
Compute the frobenius norm of a dbcsr matrix.
subroutine, public dbcsr_hadamard_product(matrix_a, matrix_b, matrix_c)
Hadamard product: C = A . B (C needs to be different from A and B)
subroutine, public dbcsr_scale_by_vector(matrix, alpha, side)
Scales the rows/columns of given matrix.
Interface to (sca)lapack for the Cholesky based procedures.
subroutine, public cp_dbcsr_heevd(matrix_re, matrix_im, eigenvectors_re, eigenvectors_im, eigenvalues, para_env, blacs_env)
...
subroutine, public cp_dbcsr_syevd(matrix, eigenvectors, eigenvalues, para_env, blacs_env)
...
Defines the basic variable types.
integer, parameter, public dp
Interface to the message passing library MPI.
computes preconditioners, and implements methods to apply them currently used in qs_ot
subroutine, public qs_ot_get_p(matrix_x, matrix_sx, qs_ot_env)
computes p=x*S*x and the matrix functionals related matrices
subroutine, public qs_ot_get_derivative_ref(matrix_hc, matrix_x, matrix_sx, matrix_gx, qs_ot_env)
...
subroutine, public qs_ot_get_orbitals(matrix_c, matrix_x, qs_ot_env)
c=(c0*cos(p^0.5)+x*sin(p^0.5)*p^(-0.5)) x rot_mat_u this assumes that x is already ortho to S*C0,...
subroutine, public qs_ot_get_orbitals_ref(matrix_c, matrix_s, matrix_x, matrix_sx, matrix_gx_old, matrix_dx, qs_ot_env, qs_ot_env1)
...
subroutine, public qs_ot_get_derivative(matrix_hc, matrix_x, matrix_sx, matrix_gx, qs_ot_env)
this routines computes dE/dx=dx, with dx ortho to sc0 needs dE/dC=hc,C0,X,SX,p if preconditioned it w...
subroutine, public qs_ot_new_preconditioner(qs_ot_env, preconditioner)
gets ready to use the preconditioner/ or renew the preconditioner only keeps a pointer to the precond...