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 .LT. 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) .LE. 0.0_dp) &
299 cpabort(
"P not positive definite")
300 IF (eig(i) .LT. 1.0e-8_dp)
THEN
303 fun(i) = 1.0_dp/sqrt(eig(i))
319 DEALLOCATE (eig, fun)
321 CALL timestop(handle)
322 END SUBROUTINE qs_ot_ref_lwdn
335 SUBROUTINE qs_ot_ref_poly(qs_ot_env, C_OLD, C_TMP, C_NEW, P, SC, norm_in, update)
338 TYPE(
dbcsr_type),
POINTER :: c_old, c_tmp, c_new, p
340 REAL(
dp),
INTENT(IN) :: norm_in
341 LOGICAL,
INTENT(IN) :: update
343 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_ref_poly'
345 INTEGER :: handle, irefine, k, n
346 LOGICAL :: quick_exit
347 REAL(
dp) :: norm, norm_fro, norm_gct, occ_in, &
349 TYPE(
dbcsr_type),
POINTER :: buf1, buf2, buf_nosym, ft, fy
351 CALL timeset(routinen, handle)
355 buf_nosym => qs_ot_env%buf1_k_k_nosym
356 buf1 => qs_ot_env%buf1_k_k_sym
357 buf2 => qs_ot_env%buf2_k_k_sym
358 fy => qs_ot_env%buf3_k_k_sym
359 ft => qs_ot_env%buf4_k_k_sym
366 IF (norm .LT. qs_ot_env%settings%eps_irac_quick_exit) quick_exit = .true.
370 DO irefine = 1, qs_ot_env%settings%max_irac
373 IF (norm .GT. 1.0_dp)
THEN
375 rescale = rescale/sqrt(norm)
379 CALL qs_ot_refine(p, fy, buf1, buf2, qs_ot_env%settings%irac_degree, &
380 qs_ot_env%settings%eps_irac_filter_matrix)
383 IF (irefine .EQ. 1)
THEN
387 IF (qs_ot_env%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
389 CALL dbcsr_filter(buf1, qs_ot_env%settings%eps_irac_filter_matrix)
402 IF (qs_ot_env%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
404 CALL dbcsr_filter(buf_nosym, qs_ot_env%settings%eps_irac_filter_matrix)
408 IF (qs_ot_env%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
410 CALL dbcsr_filter(p, qs_ot_env%settings%eps_irac_filter_matrix)
419 norm = min(norm_gct, norm_fro)
424 IF (norm > 1.0e10_dp)
THEN
425 CALL cp_abort(__location__, &
426 "Refinement blows up! "// &
427 "We need you to improve the code, please post your input on "// &
428 "the forum https://www.cp2k.org/")
432 IF (norm .LT. qs_ot_env%settings%eps_irac_quick_exit) quick_exit = .true.
435 IF (norm .LT. qs_ot_env%settings%eps_irac)
EXIT
441 IF (qs_ot_env%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
443 CALL dbcsr_filter(c_new, qs_ot_env%settings%eps_irac_filter_matrix)
450 IF (qs_ot_env%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
452 CALL dbcsr_filter(c_tmp, qs_ot_env%settings%eps_irac_filter_matrix)
458 CALL timestop(handle)
459 END SUBROUTINE qs_ot_ref_poly
466 FUNCTION qs_ot_ref_update(qs_ot_env1)
RESULT(update)
472 SELECT CASE (qs_ot_env1%settings%ot_method)
474 SELECT CASE (qs_ot_env1%settings%line_search_method)
476 IF (qs_ot_env1%line_search_count .EQ. 2) update = .true.
485 END FUNCTION qs_ot_ref_update
493 SUBROUTINE qs_ot_ref_decide(qs_ot_env1, norm_in, ortho_irac)
496 REAL(
dp),
INTENT(IN) :: norm_in
497 CHARACTER(LEN=*),
INTENT(INOUT) :: ortho_irac
499 ortho_irac = qs_ot_env1%settings%ortho_irac
500 IF (norm_in .LT. qs_ot_env1%settings%eps_irac_switch) ortho_irac =
"POLY"
501 END SUBROUTINE qs_ot_ref_decide
515 matrix_gx_old, matrix_dx, qs_ot_env, qs_ot_env1)
517 TYPE(
dbcsr_type),
POINTER :: matrix_c, matrix_s, matrix_x, matrix_sx, &
518 matrix_gx_old, matrix_dx
521 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_orbitals_ref'
523 CHARACTER(LEN=4) :: ortho_irac
524 INTEGER :: handle, k, n
525 LOGICAL :: on_the_fly_loc, update
526 REAL(
dp) :: norm, norm_fro, norm_gct, occ_in, occ_out
527 TYPE(
dbcsr_type),
POINTER :: c_new, c_old, c_tmp, d, g_old, p, s, sc
529 CALL timeset(routinen, handle)
531 CALL dbcsr_get_info(matrix_c, nfullrows_total=n, nfullcols_total=k)
536 g_old => matrix_gx_old
540 p => qs_ot_env%p_k_k_sym
541 c_tmp => qs_ot_env%buf1_n_k
544 update = qs_ot_ref_update(qs_ot_env1)
550 on_the_fly_loc = qs_ot_env1%settings%on_the_fly_loc
553 IF (
ASSOCIATED(s))
THEN
555 IF (qs_ot_env1%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
557 CALL dbcsr_filter(sc, qs_ot_env1%settings%eps_irac_filter_matrix)
566 IF (qs_ot_env1%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
568 CALL dbcsr_filter(p, qs_ot_env1%settings%eps_irac_filter_matrix)
577 norm = min(norm_gct, norm_fro)
578 CALL qs_ot_ref_decide(qs_ot_env1, norm, ortho_irac)
581 SELECT CASE (ortho_irac)
583 CALL qs_ot_ref_chol(qs_ot_env, c_old, c_tmp, c_new, p, sc, update)
585 CALL qs_ot_ref_lwdn(qs_ot_env, c_old, c_tmp, c_new, p, sc, update)
587 CALL qs_ot_ref_poly(qs_ot_env, c_old, c_tmp, c_new, p, sc, norm, update)
589 cpabort(
"Wrong argument")
594 IF (on_the_fly_loc)
THEN
595 CALL qs_ot_on_the_fly_localize(qs_ot_env, c_new, sc, g_old, d)
600 CALL timestop(handle)
612 SUBROUTINE qs_ot_refine(P, FY, P2, T, irac_degree, eps_irac_filter_matrix)
613 TYPE(
dbcsr_type),
INTENT(inout) :: p, fy, p2, t
614 INTEGER,
INTENT(in) :: irac_degree
615 REAL(
dp),
INTENT(in) :: eps_irac_filter_matrix
617 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_refine'
620 REAL(
dp) :: occ_in, occ_out, r
622 CALL timeset(routinen, handle)
625 SELECT CASE (irac_degree)
630 IF (eps_irac_filter_matrix .GT. 0.0_dp)
THEN
636 CALL dbcsr_add(fy, p, alpha_scalar=1.0_dp, beta_scalar=r)
642 IF (eps_irac_filter_matrix .GT. 0.0_dp)
THEN
649 IF (eps_irac_filter_matrix .GT. 0.0_dp)
THEN
655 CALL dbcsr_add(fy, p2, alpha_scalar=1.0_dp, beta_scalar=r)
657 CALL dbcsr_add(fy, p, alpha_scalar=1.0_dp, beta_scalar=r)
664 IF (eps_irac_filter_matrix .GT. 0.0_dp)
THEN
669 r = -180.0_dp/128.0_dp
670 CALL dbcsr_add(t, p, alpha_scalar=0.0_dp, beta_scalar=r)
672 CALL dbcsr_add(t, p2, alpha_scalar=1.0_dp, beta_scalar=r)
674 IF (eps_irac_filter_matrix .GT. 0.0_dp)
THEN
679 r = 378.0_dp/128.0_dp
680 CALL dbcsr_add(fy, p2, alpha_scalar=1.0_dp, beta_scalar=r)
681 r = -420.0_dp/128.0_dp
682 CALL dbcsr_add(fy, p, alpha_scalar=1.0_dp, beta_scalar=r)
683 r = 315.0_dp/128.0_dp
686 cpabort(
"This irac_order NYI")
688 CALL timestop(handle)
689 END SUBROUTINE qs_ot_refine
701 TYPE(
dbcsr_type),
POINTER :: matrix_hc, matrix_x, matrix_sx, matrix_gx
704 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative_ref'
706 INTEGER :: handle, k, n
707 REAL(
dp) :: occ_in, occ_out
708 TYPE(
dbcsr_type),
POINTER :: c, chc, g, g_dp, hc, sc
710 CALL timeset(routinen, handle)
712 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
718 chc => qs_ot_env%buf1_k_k_sym
719 g_dp => qs_ot_env%buf1_n_k_dp
723 IF (qs_ot_env%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
725 CALL dbcsr_filter(chc, qs_ot_env%settings%eps_irac_filter_matrix)
730 IF (qs_ot_env%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
732 CALL dbcsr_filter(g, qs_ot_env%settings%eps_irac_filter_matrix)
736 CALL dbcsr_add(g, hc, alpha_scalar=-1.0_dp, beta_scalar=1.0_dp)
738 CALL timestop(handle)
749 TYPE(
dbcsr_type),
POINTER :: matrix_x, matrix_sx
752 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_p'
753 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
755 INTEGER :: handle, k, max_iter, n
757 REAL(kind=
dp) :: max_ev, min_ev, threshold
759 CALL timeset(routinen, handle)
761 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
769 max_iter = 30; threshold = 1.0e-03_dp
770 CALL arnoldi_extremal(qs_ot_env%matrix_p, max_ev, min_ev, converged, threshold, max_iter)
771 qs_ot_env%largest_eval_upper_bound = max(max_ev, abs(min_ev))
774 CALL decide_strategy(qs_ot_env)
775 IF (qs_ot_env%do_taylor)
THEN
776 CALL qs_ot_p2m_taylor(qs_ot_env)
778 CALL qs_ot_p2m_diag(qs_ot_env)
781 IF (qs_ot_env%settings%do_rotation)
THEN
782 CALL qs_ot_generate_rotation(qs_ot_env)
785 CALL timestop(handle)
797 SUBROUTINE qs_ot_generate_rotation(qs_ot_env)
801 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_generate_rotation'
804 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: exp_evals_im, exp_evals_re
807 CALL timeset(routinen, handle)
817 eigenvectors_re=qs_ot_env%rot_mat_evec_re, &
818 eigenvectors_im=qs_ot_env%rot_mat_evec_im, &
819 eigenvalues=qs_ot_env%rot_mat_evals, &
820 para_env=qs_ot_env%para_env, &
821 blacs_env=qs_ot_env%blacs_env)
824 ALLOCATE (exp_evals_re(k), exp_evals_im(k))
825 exp_evals_re(:) = cos(-qs_ot_env%rot_mat_evals(:))
826 exp_evals_im(:) = sin(-qs_ot_env%rot_mat_evals(:))
830 CALL dbcsr_copy(buf_1, qs_ot_env%rot_mat_evec_re, name=
"buf_1")
832 CALL dbcsr_copy(buf_2, qs_ot_env%rot_mat_evec_im, name=
"buf_2")
834 CALL dbcsr_add(buf_1, buf_2, alpha_scalar=+1.0_dp, beta_scalar=-1.0_dp)
835 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)
837 CALL dbcsr_copy(buf_1, qs_ot_env%rot_mat_evec_im)
839 CALL dbcsr_copy(buf_2, qs_ot_env%rot_mat_evec_re)
841 CALL dbcsr_add(buf_1, buf_2, alpha_scalar=+1.0_dp, beta_scalar=+1.0_dp)
842 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)
847 DEALLOCATE (exp_evals_re, exp_evals_im)
850 CALL timestop(handle)
852 END SUBROUTINE qs_ot_generate_rotation
862 SUBROUTINE qs_ot_rot_mat_derivative(qs_ot_env)
865 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_rot_mat_derivative'
867 INTEGER :: handle, i, j, k
868 REAL(kind=
dp) :: e1, e2
869 TYPE(
dbcsr_type) :: outer_deriv_re, outer_deriv_im, mat_buf, &
870 inner_deriv_re, inner_deriv_im
872 INTEGER,
DIMENSION(:),
POINTER :: row_blk_offset, col_blk_offset
873 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_in_re, block_in_im, block_out_re, block_out_im
876 COMPLEX(dp) :: cval_in, cval_out
879 CALL timeset(routinen, handle)
883 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%rot_mat_dedu)
885 CALL dbcsr_copy(mat_buf, qs_ot_env%rot_mat_dedu,
"mat_buf")
888 CALL dbcsr_copy(inner_deriv_re, qs_ot_env%rot_mat_dedu,
"inner_deriv_re")
889 CALL dbcsr_copy(inner_deriv_im, qs_ot_env%rot_mat_dedu,
"inner_deriv_im")
891 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)
892 CALL dbcsr_multiply(
'T',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_im, mat_buf, 0.0_dp, inner_deriv_re)
893 CALL dbcsr_multiply(
'T',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_re, mat_buf, 0.0_dp, inner_deriv_im)
895 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)
896 CALL dbcsr_multiply(
'T',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_re, mat_buf, 1.0_dp, inner_deriv_re)
897 CALL dbcsr_multiply(
'T',
'N', -1.0_dp, qs_ot_env%rot_mat_evec_im, mat_buf, 1.0_dp, inner_deriv_im)
900 CALL dbcsr_copy(outer_deriv_re, qs_ot_env%rot_mat_dedu,
"outer_deriv_re")
901 CALL dbcsr_copy(outer_deriv_im, qs_ot_env%rot_mat_dedu,
"outer_deriv_im")
903 CALL dbcsr_get_info(qs_ot_env%rot_mat_dedu, row_blk_offset=row_blk_offset, col_blk_offset=col_blk_offset)
912 DO i = 1,
SIZE(block_in_re, 1)
913 DO j = 1,
SIZE(block_in_re, 2)
914 e1 = qs_ot_env%rot_mat_evals(row_blk_offset(row) + i - 1)
915 e2 = qs_ot_env%rot_mat_evals(col_blk_offset(col) + j - 1)
916 cval_in = cmplx(block_in_re(i, j), block_in_im(i, j),
dp)
917 cval_out = cval_in*cint(e1, e2)
918 block_out_re(i, j) = real(cval_out)
919 block_out_im(i, j) = aimag(cval_out)
928 CALL dbcsr_multiply(
'N',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_re, outer_deriv_re, 0.0_dp, mat_buf)
929 CALL dbcsr_multiply(
'N',
'N', -1.0_dp, qs_ot_env%rot_mat_evec_im, outer_deriv_im, 1.0_dp, mat_buf)
930 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)
932 CALL dbcsr_multiply(
'N',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_re, outer_deriv_im, 0.0_dp, mat_buf)
933 CALL dbcsr_multiply(
'N',
'N', +1.0_dp, qs_ot_env%rot_mat_evec_im, outer_deriv_re, 1.0_dp, mat_buf)
934 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)
939 shallow_data_copy=.false., use_distribution=dist, &
940 transpose_distribution=.false.)
943 CALL dbcsr_add(qs_ot_env%matrix_buf1, qs_ot_env%matrix_buf2, alpha_scalar=-1.0_dp, beta_scalar=+1.0_dp)
944 CALL dbcsr_copy(qs_ot_env%rot_mat_gx, qs_ot_env%matrix_buf1)
950 CALL timestop(handle)
959 FUNCTION cint(e1, e2)
960 REAL(kind=
dp) :: e1, e2
961 COMPLEX(KIND=dp) :: cint
963 COMPLEX(KIND=dp) :: l1, l2, x
966 l1 = (0.0_dp, -1.0_dp)*e1
967 l2 = (0.0_dp, -1.0_dp)*e2
968 IF (abs(l1 - l2) .GT. 0.5_dp)
THEN
969 cint = (exp(l1) - exp(l2))/(l1 - l2)
975 x = x*(l1 - l2)/real(i + 1, kind=
dp)
980 END SUBROUTINE qs_ot_rot_mat_derivative
991 SUBROUTINE decide_strategy(qs_ot_env)
995 REAL(kind=
dp) :: num_error
997 qs_ot_env%do_taylor = .false.
999 num_error = qs_ot_env%largest_eval_upper_bound/(2.0_dp)
1000 DO WHILE (num_error > qs_ot_env%settings%eps_taylor .AND. n <= qs_ot_env%settings%max_taylor)
1002 num_error = num_error*qs_ot_env%largest_eval_upper_bound/real((2*n + 1)*(2*n + 2), kind=
dp)
1004 qs_ot_env%taylor_order = n
1005 IF (qs_ot_env%taylor_order <= qs_ot_env%settings%max_taylor)
THEN
1006 qs_ot_env%do_taylor = .true.
1009 END SUBROUTINE decide_strategy
1021 TYPE(
dbcsr_type),
POINTER :: matrix_c, matrix_x
1024 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_orbitals'
1025 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1027 INTEGER :: handle, k, n
1030 CALL timeset(routinen, handle)
1032 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
1036 IF (qs_ot_env%settings%do_rotation)
THEN
1037 matrix_kk => qs_ot_env%matrix_buf1
1039 qs_ot_env%rot_mat_u, rzero, matrix_kk)
1041 matrix_kk => qs_ot_env%matrix_cosp
1044 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_c0, matrix_kk, &
1047 IF (qs_ot_env%settings%do_rotation)
THEN
1048 matrix_kk => qs_ot_env%matrix_buf1
1050 qs_ot_env%rot_mat_u, rzero, matrix_kk)
1052 matrix_kk => qs_ot_env%matrix_sinp
1057 CALL timestop(handle)
1074 TYPE(
dbcsr_type),
POINTER :: matrix_hc, matrix_x, matrix_sx, matrix_gx
1077 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative'
1078 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1080 INTEGER :: handle, k, n, ortho_k
1081 TYPE(
dbcsr_type),
POINTER :: matrix_hc_local, matrix_target
1083 CALL timeset(routinen, handle)
1085 NULLIFY (matrix_hc_local)
1087 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
1092 IF (qs_ot_env%settings%do_rotation)
THEN
1095 CALL dbcsr_copy(matrix_hc_local, matrix_hc, name=
'matrix_hc_local')
1097 CALL dbcsr_multiply(
'N',
'T', rone, matrix_gx, qs_ot_env%rot_mat_u, rzero, matrix_hc_local)
1099 matrix_hc_local => matrix_hc
1102 IF (qs_ot_env%do_taylor)
THEN
1103 CALL qs_ot_get_derivative_taylor(matrix_hc_local, matrix_x, matrix_sx, matrix_gx, qs_ot_env)
1105 CALL qs_ot_get_derivative_diag(matrix_hc_local, matrix_x, matrix_sx, matrix_gx, qs_ot_env)
1109 CALL dbcsr_get_info(qs_ot_env%matrix_sc0, nfullcols_total=ortho_k)
1111 IF (
ASSOCIATED(qs_ot_env%preconditioner))
THEN
1112 matrix_target => qs_ot_env%matrix_psc0
1114 matrix_target => qs_ot_env%matrix_sc0
1117 IF (.NOT. qs_ot_env%os_valid)
THEN
1121 IF (
ASSOCIATED(qs_ot_env%preconditioner))
THEN
1123 qs_ot_env%matrix_psc0)
1126 qs_ot_env%matrix_sc0, matrix_target, &
1127 rzero, qs_ot_env%matrix_os)
1129 para_env=qs_ot_env%para_env, blacs_env=qs_ot_env%blacs_env)
1131 para_env=qs_ot_env%para_env, blacs_env=qs_ot_env%blacs_env, &
1132 uplo_to_full=.true.)
1133 qs_ot_env%os_valid = .true.
1136 rzero, qs_ot_env%matrix_buf1_ortho)
1138 qs_ot_env%matrix_buf1_ortho, rzero, qs_ot_env%matrix_buf2_ortho)
1140 qs_ot_env%matrix_buf2_ortho, rone, matrix_gx)
1142 IF (qs_ot_env%settings%do_rotation)
THEN
1143 CALL qs_ot_rot_mat_derivative(qs_ot_env)
1146 IF (qs_ot_env%settings%do_rotation)
THEN
1150 CALL timestop(handle)
1162 SUBROUTINE qs_ot_get_derivative_diag(matrix_hc, matrix_x, matrix_sx, matrix_gx, &
1165 TYPE(
dbcsr_type),
POINTER :: matrix_hc, matrix_x, matrix_sx, matrix_gx
1168 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative_diag'
1169 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1171 INTEGER :: handle, k, n
1174 CALL timeset(routinen, handle)
1176 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
1180 CALL dbcsr_multiply(
'N',
'N', rone, matrix_hc, qs_ot_env%matrix_sinp, rzero, matrix_gx)
1182 CALL dbcsr_multiply(
'T',
'N', rone, matrix_hc, matrix_x, rzero, qs_ot_env%matrix_buf2)
1184 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_buf2, qs_ot_env%matrix_r, &
1185 rzero, qs_ot_env%matrix_buf1)
1186 CALL dbcsr_multiply(
'T',
'N', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
1187 rzero, qs_ot_env%matrix_buf2)
1191 qs_ot_env%matrix_buf3)
1194 CALL dbcsr_multiply(
'T',
'N', rone, matrix_hc, qs_ot_env%matrix_c0, rzero, &
1195 qs_ot_env%matrix_buf2)
1197 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_buf2, qs_ot_env%matrix_r, &
1198 rzero, qs_ot_env%matrix_buf1)
1199 CALL dbcsr_multiply(
'T',
'N', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
1200 rzero, qs_ot_env%matrix_buf2)
1203 qs_ot_env%matrix_buf4)
1206 CALL dbcsr_add(qs_ot_env%matrix_buf3, qs_ot_env%matrix_buf4, &
1207 alpha_scalar=rone, beta_scalar=rone)
1210 CALL dbcsr_multiply(
'N',
'T', rone, qs_ot_env%matrix_buf3, qs_ot_env%matrix_r, &
1211 rzero, qs_ot_env%matrix_buf1)
1212 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
1213 rzero, qs_ot_env%matrix_buf3)
1216 shallow_data_copy=.false., use_distribution=dist, &
1217 transpose_distribution=.false.)
1218 CALL dbcsr_add(qs_ot_env%matrix_buf3, qs_ot_env%matrix_buf1, &
1219 alpha_scalar=rone, beta_scalar=rone)
1222 CALL dbcsr_multiply(
'N',
'N', rone, matrix_sx, qs_ot_env%matrix_buf3, &
1224 CALL timestop(handle)
1226 END SUBROUTINE qs_ot_get_derivative_diag
1236 SUBROUTINE qs_ot_get_derivative_taylor(matrix_hc, matrix_x, matrix_sx, matrix_gx, &
1239 TYPE(
dbcsr_type),
POINTER :: matrix_hc, matrix_x, matrix_sx, matrix_gx
1242 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative_taylor'
1243 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1245 INTEGER :: handle, i, k, n
1246 REAL(kind=
dp) :: cosfactor, sinfactor
1248 TYPE(
dbcsr_type),
POINTER :: matrix_left, matrix_right
1250 CALL timeset(routinen, handle)
1252 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
1256 CALL dbcsr_multiply(
'N',
'N', rone, matrix_hc, qs_ot_env%matrix_sinp, rzero, matrix_gx)
1258 IF (qs_ot_env%taylor_order .LE. 0)
THEN
1259 CALL timestop(handle)
1264 CALL dbcsr_set(qs_ot_env%matrix_r, rzero)
1267 matrix_left => qs_ot_env%matrix_cosp_b
1268 matrix_right => qs_ot_env%matrix_sinp_b
1271 CALL dbcsr_multiply(
'T',
'N', rone, matrix_hc, matrix_x, rzero, matrix_left)
1274 shallow_data_copy=.false., use_distribution=dist, &
1275 transpose_distribution=.false.)
1276 CALL dbcsr_add(matrix_left, qs_ot_env%matrix_buf1, &
1277 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
1281 sinfactor = -1.0_dp/(2.0_dp*3.0_dp)
1282 CALL dbcsr_add(qs_ot_env%matrix_r, matrix_left, &
1283 alpha_scalar=1.0_dp, beta_scalar=sinfactor)
1289 DO i = 2, qs_ot_env%taylor_order
1290 sinfactor = sinfactor*(-1.0_dp)/real(2*i*(2*i + 1), kind=
dp)
1291 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_p, matrix_left, rzero, qs_ot_env%matrix_buf1)
1292 CALL dbcsr_multiply(
'N',
'N', rone, matrix_right, qs_ot_env%matrix_p, rzero, matrix_left)
1294 CALL dbcsr_add(matrix_left, qs_ot_env%matrix_buf1, &
1296 CALL dbcsr_add(qs_ot_env%matrix_r, matrix_left, &
1297 alpha_scalar=1.0_dp, beta_scalar=sinfactor)
1301 CALL dbcsr_multiply(
'T',
'N', rone, matrix_hc, qs_ot_env%matrix_c0, rzero, matrix_left)
1304 shallow_data_copy=.false., use_distribution=dist, &
1305 transpose_distribution=.false.)
1306 CALL dbcsr_add(matrix_left, qs_ot_env%matrix_buf1, 1.0_dp, 1.0_dp)
1310 cosfactor = -1.0_dp/(1.0_dp*2.0_dp)
1311 CALL dbcsr_add(qs_ot_env%matrix_r, matrix_left, &
1312 alpha_scalar=1.0_dp, beta_scalar=cosfactor)
1318 DO i = 2, qs_ot_env%taylor_order
1319 cosfactor = cosfactor*(-1.0_dp)/real(2*i*(2*i - 1), kind=
dp)
1320 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_p, matrix_left, rzero, qs_ot_env%matrix_buf1)
1321 CALL dbcsr_multiply(
'N',
'N', rone, matrix_right, qs_ot_env%matrix_p, rzero, matrix_left)
1323 CALL dbcsr_add(matrix_left, qs_ot_env%matrix_buf1, 1.0_dp, 1.0_dp)
1324 CALL dbcsr_add(qs_ot_env%matrix_r, matrix_left, &
1325 alpha_scalar=1.0_dp, beta_scalar=cosfactor)
1329 CALL dbcsr_multiply(
'N',
'N', rone, matrix_sx, qs_ot_env%matrix_r, rone, matrix_gx)
1331 CALL timestop(handle)
1333 END SUBROUTINE qs_ot_get_derivative_taylor
1339 SUBROUTINE qs_ot_p2m_taylor(qs_ot_env)
1342 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_p2m_taylor'
1343 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1345 INTEGER :: handle, i, k
1346 REAL(kind=
dp) :: cosfactor, sinfactor
1348 CALL timeset(routinen, handle)
1351 CALL dbcsr_set(qs_ot_env%matrix_cosp, rzero)
1352 CALL dbcsr_set(qs_ot_env%matrix_sinp, rzero)
1356 IF (qs_ot_env%taylor_order .LE. 0)
THEN
1357 CALL timestop(handle)
1362 cosfactor = -1.0_dp/(1.0_dp*2.0_dp)
1363 sinfactor = -1.0_dp/(2.0_dp*3.0_dp)
1364 CALL dbcsr_add(qs_ot_env%matrix_cosp, qs_ot_env%matrix_p, alpha_scalar=1.0_dp, beta_scalar=cosfactor)
1365 CALL dbcsr_add(qs_ot_env%matrix_sinp, qs_ot_env%matrix_p, alpha_scalar=1.0_dp, beta_scalar=sinfactor)
1366 IF (qs_ot_env%taylor_order .LE. 1)
THEN
1367 CALL timestop(handle)
1373 CALL dbcsr_copy(qs_ot_env%matrix_r, qs_ot_env%matrix_p)
1375 DO i = 2, qs_ot_env%taylor_order
1377 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_p, qs_ot_env%matrix_r, &
1378 rzero, qs_ot_env%matrix_buf1)
1379 CALL dbcsr_copy(qs_ot_env%matrix_r, qs_ot_env%matrix_buf1)
1381 cosfactor = cosfactor*(-1.0_dp)/real(2*i*(2*i - 1), kind=
dp)
1382 sinfactor = sinfactor*(-1.0_dp)/real(2*i*(2*i + 1), kind=
dp)
1383 CALL dbcsr_add(qs_ot_env%matrix_cosp, qs_ot_env%matrix_r, &
1384 alpha_scalar=1.0_dp, beta_scalar=cosfactor)
1385 CALL dbcsr_add(qs_ot_env%matrix_sinp, qs_ot_env%matrix_r, &
1386 alpha_scalar=1.0_dp, beta_scalar=sinfactor)
1389 CALL timestop(handle)
1391 END SUBROUTINE qs_ot_p2m_taylor
1401 SUBROUTINE qs_ot_p2m_diag(qs_ot_env)
1405 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_p2m_diag'
1406 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1408 INTEGER :: col, col_offset, col_size, handle, i, j, &
1409 k, row, row_offset, row_size
1410 REAL(
dp),
DIMENSION(:, :),
POINTER :: block
1411 REAL(kind=
dp) :: a, b
1414 CALL timeset(routinen, handle)
1417 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_p)
1418 CALL cp_dbcsr_syevd(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r, qs_ot_env%evals, &
1419 qs_ot_env%para_env, qs_ot_env%blacs_env)
1421 qs_ot_env%evals(i) = max(0.0_dp, qs_ot_env%evals(i))
1426 qs_ot_env%dum(i) = cos(sqrt(qs_ot_env%evals(i)))
1428 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r)
1430 CALL dbcsr_multiply(
'N',
'T', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
1431 rzero, qs_ot_env%matrix_cosp)
1435 qs_ot_env%dum(i) = qs_ot_sinc(sqrt(qs_ot_env%evals(i)))
1437 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r)
1439 CALL dbcsr_multiply(
'N',
'T', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
1440 rzero, qs_ot_env%matrix_sinp)
1442 CALL dbcsr_copy(qs_ot_env%matrix_cosp_b, qs_ot_env%matrix_cosp)
1446 row_size=row_size, col_size=col_size, &
1447 row_offset=row_offset, col_offset=col_offset)
1450 a = (sqrt(qs_ot_env%evals(row_offset + i - 1)) &
1451 - sqrt(qs_ot_env%evals(col_offset + j - 1)))/2.0_dp
1452 b = (sqrt(qs_ot_env%evals(row_offset + i - 1)) &
1453 + sqrt(qs_ot_env%evals(col_offset + j - 1)))/2.0_dp
1454 block(i, j) = -0.5_dp*qs_ot_sinc(a)*qs_ot_sinc(b)
1460 CALL dbcsr_copy(qs_ot_env%matrix_sinp_b, qs_ot_env%matrix_sinp)
1464 row_size=row_size, col_size=col_size, &
1465 row_offset=row_offset, col_offset=col_offset)
1468 a = sqrt(qs_ot_env%evals(row_offset + i - 1))
1469 b = sqrt(qs_ot_env%evals(col_offset + j - 1))
1470 block(i, j) = qs_ot_sincf(a, b)
1476 CALL timestop(handle)
1478 END SUBROUTINE qs_ot_p2m_diag
1485 FUNCTION qs_ot_sinc(x)
1487 REAL(kind=
dp),
INTENT(IN) :: x
1488 REAL(kind=
dp) :: qs_ot_sinc
1490 REAL(kind=
dp),
PARAMETER :: q1 = 1.0_dp, q2 = -q1/(2.0_dp*3.0_dp), q3 = -q2/(4.0_dp*5.0_dp), &
1491 q4 = -q3/(6.0_dp*7.0_dp), q5 = -q4/(8.0_dp*9.0_dp), q6 = -q5/(10.0_dp*11.0_dp), &
1492 q7 = -q6/(12.0_dp*13.0_dp), q8 = -q7/(14.0_dp*15.0_dp), q9 = -q8/(16.0_dp*17.0_dp), &
1493 q10 = -q9/(18.0_dp*19.0_dp)
1497 IF (abs(x) > 0.5_dp)
THEN
1498 qs_ot_sinc = sin(x)/x
1501 qs_ot_sinc = q1 + y*(q2 + y*(q3 + y*(q4 + y*(q5 + y*(q6 + y*(q7 + y*(q8 + y*(q9 + y*(q10)))))))))
1503 END FUNCTION qs_ot_sinc
1511 FUNCTION qs_ot_sincf(xa, ya)
1513 REAL(kind=
dp),
INTENT(IN) :: xa, ya
1514 REAL(kind=
dp) :: qs_ot_sincf
1517 REAL(kind=
dp) :: a, b, rs, sf, x, xs, y, ybx, ybxs
1520 IF (xa .LT. 0) cpabort(
"x is negative")
1521 IF (ya .LT. 0) cpabort(
"y is negative")
1523 IF (xa .LT. ya)
THEN
1531 IF (x .LT. 0.5_dp)
THEN
1533 qs_ot_sincf = 0.0_dp
1534 IF (x .GT. 0.0_dp)
THEN
1540 sf = -1.0_dp/((1.0_dp + ybx)*6.0_dp)
1546 qs_ot_sincf = qs_ot_sincf + sf*rs*xs*(1.0_dp + ybxs)
1547 sf = -sf/(real((2*i + 2),
dp)*real((2*i + 3),
dp))
1554 IF (x - y .GT. 0.1_dp)
THEN
1555 qs_ot_sincf = (qs_ot_sinc(x) - qs_ot_sinc(y))/((x + y)*(x - y))
1560 qs_ot_sincf = (qs_ot_sinc(b)*cos(a) - qs_ot_sinc(a)*cos(b))/(2*x*y)
1564 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)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_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_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...