22 USE dbcsr_api,
ONLY: &
23 dbcsr_add, dbcsr_add_on_diag, dbcsr_copy, dbcsr_distribution_type, dbcsr_filter, &
24 dbcsr_frobenius_norm, dbcsr_gershgorin_norm, dbcsr_get_block_p, dbcsr_get_info, &
25 dbcsr_get_occupation, dbcsr_hadamard_product, dbcsr_init_p, dbcsr_iterator_blocks_left, &
26 dbcsr_iterator_next_block, dbcsr_iterator_start, dbcsr_iterator_stop, dbcsr_iterator_type, &
27 dbcsr_multiply, dbcsr_release, dbcsr_release_p, dbcsr_scale, dbcsr_scale_by_vector, &
28 dbcsr_set, dbcsr_transposed, dbcsr_type
34 #include "./base/base_uses.f90"
45 PRIVATE :: qs_ot_p2m_diag
47 PRIVATE :: qs_ot_ref_poly
48 PRIVATE :: qs_ot_ref_chol
49 PRIVATE :: qs_ot_ref_lwdn
50 PRIVATE :: qs_ot_ref_decide
51 PRIVATE :: qs_ot_ref_update
52 PRIVATE :: qs_ot_refine
53 PRIVATE :: qs_ot_on_the_fly_localize
55 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_ot'
70 TYPE(qs_ot_type) :: qs_ot_env
76 qs_ot_env%os_valid = .false.
77 IF (.NOT.
ASSOCIATED(qs_ot_env%matrix_psc0))
THEN
78 CALL dbcsr_init_p(qs_ot_env%matrix_psc0)
79 CALL dbcsr_copy(qs_ot_env%matrix_psc0, qs_ot_env%matrix_sc0,
'matrix_psc0')
82 IF (.NOT. qs_ot_env%use_dx)
THEN
83 qs_ot_env%use_dx = .true.
84 CALL dbcsr_init_p(qs_ot_env%matrix_dx)
85 CALL dbcsr_copy(qs_ot_env%matrix_dx, qs_ot_env%matrix_gx,
'matrix_dx')
86 IF (qs_ot_env%settings%do_rotation)
THEN
87 CALL dbcsr_init_p(qs_ot_env%rot_mat_dx)
88 CALL dbcsr_copy(qs_ot_env%rot_mat_dx, qs_ot_env%rot_mat_gx,
'rot_mat_dx')
90 IF (qs_ot_env%settings%do_ener)
THEN
91 ncoef =
SIZE(qs_ot_env%ener_gx)
92 ALLOCATE (qs_ot_env%ener_dx(ncoef))
93 qs_ot_env%ener_dx = 0.0_dp
107 SUBROUTINE qs_ot_on_the_fly_localize(qs_ot_env, C_NEW, SC, G_OLD, D)
109 TYPE(qs_ot_type) :: qs_ot_env
110 TYPE(dbcsr_type),
POINTER :: c_new, sc, g_old, d
112 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_on_the_fly_localize'
113 INTEGER,
PARAMETER :: taylor_order = 50
114 REAL(kind=
dp),
PARAMETER :: alpha = 0.1_dp, f2_eps = 0.01_dp
116 INTEGER :: blk, col, col_size, group_handle, &
117 handle, i, k, n, p, row, row_size
118 REAL(
dp),
DIMENSION(:, :),
POINTER :: data
119 REAL(kind=
dp) :: expfactor, f2, norm_fro, norm_gct, tmp
120 TYPE(dbcsr_distribution_type) :: dist
121 TYPE(dbcsr_iterator_type) :: iter
122 TYPE(dbcsr_type),
POINTER :: c, gp1, gp2, gu, u
123 TYPE(mp_comm_type) :: group
125 CALL timeset(routinen, handle)
128 CALL dbcsr_get_info(c_new, nfullrows_total=n, nfullcols_total=k)
131 gu => qs_ot_env%buf1_k_k_nosym
132 u => qs_ot_env%buf2_k_k_nosym
133 gp1 => qs_ot_env%buf3_k_k_nosym
134 gp2 => qs_ot_env%buf4_k_k_nosym
135 c => qs_ot_env%buf1_n_k
141 CALL dbcsr_copy(c, c_new)
142 CALL dbcsr_iterator_start(iter, c)
143 DO WHILE (dbcsr_iterator_blocks_left(iter))
144 CALL dbcsr_iterator_next_block(iter, row, col,
DATA, blk, &
145 row_size=row_size, col_size=col_size)
148 tmp = sqrt(
DATA(i, p)**2 + f2_eps)
150 DATA(i, p) =
DATA(i, p)/tmp
154 CALL dbcsr_iterator_stop(iter)
155 CALL dbcsr_get_info(c, group=group_handle)
156 CALL group%set_handle(group_handle)
160 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, c, c_new, 0.0_dp, gu)
163 CALL dbcsr_get_info(gu, distribution=dist)
164 CALL dbcsr_transposed(u, gu, shallow_data_copy=.false., &
165 use_distribution=dist, &
166 transpose_distribution=.false.)
167 CALL dbcsr_add(gu, u, alpha_scalar=-0.5_dp, beta_scalar=0.5_dp)
170 norm_fro = dbcsr_frobenius_norm(gu)
171 norm_gct = dbcsr_gershgorin_norm(gu)
179 CALL dbcsr_scale(gu, -alpha)
184 CALL dbcsr_copy(u, gu)
185 CALL dbcsr_scale(u, expfactor)
186 CALL dbcsr_add_on_diag(u, 1.0_dp)
188 CALL dbcsr_copy(gp1, gu)
189 DO i = 2, taylor_order
191 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, gu, gp1, 0.0_dp, gp2)
192 CALL dbcsr_copy(gp1, gp2)
194 expfactor = expfactor/real(i, kind=
dp)
195 CALL dbcsr_add(u, gp1, alpha_scalar=1.0_dp, beta_scalar=expfactor)
196 norm_fro = dbcsr_frobenius_norm(gp1)
198 IF (norm_fro*expfactor .LT. 1.0e-10_dp)
EXIT
202 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, c_new, u, 0.0_dp, c)
203 CALL dbcsr_copy(c_new, c)
206 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, sc, u, 0.0_dp, c)
207 CALL dbcsr_copy(sc, c)
210 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, d, u, 0.0_dp, c)
211 CALL dbcsr_copy(d, c)
214 IF (
ASSOCIATED(g_old))
THEN
215 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, g_old, u, 0.0_dp, c)
216 CALL dbcsr_copy(g_old, c)
219 CALL timestop(handle)
220 END SUBROUTINE qs_ot_on_the_fly_localize
232 SUBROUTINE qs_ot_ref_chol(qs_ot_env, C_OLD, C_TMP, C_NEW, P, SC, update)
234 TYPE(qs_ot_type) :: qs_ot_env
235 TYPE(dbcsr_type) :: c_old, c_tmp, c_new, p, sc
236 LOGICAL,
INTENT(IN) :: update
238 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_ref_chol'
240 INTEGER :: handle, k, n
242 CALL timeset(routinen, handle)
244 CALL dbcsr_get_info(c_new, nfullrows_total=n, nfullcols_total=k)
251 transa=
"N", para_env=qs_ot_env%para_env, blacs_env=qs_ot_env%blacs_env)
256 transa=
"N", para_env=qs_ot_env%para_env, blacs_env=qs_ot_env%blacs_env)
257 CALL dbcsr_copy(sc, c_tmp)
260 CALL timestop(handle)
261 END SUBROUTINE qs_ot_ref_chol
273 SUBROUTINE qs_ot_ref_lwdn(qs_ot_env, C_OLD, C_TMP, C_NEW, P, SC, update)
275 TYPE(qs_ot_type) :: qs_ot_env
276 TYPE(dbcsr_type) :: c_old, c_tmp, c_new, p, sc
277 LOGICAL,
INTENT(IN) :: update
279 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_ref_lwdn'
281 INTEGER :: handle, i, k, n
282 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: eig, fun
283 TYPE(dbcsr_type),
POINTER :: v, w
285 CALL timeset(routinen, handle)
287 CALL dbcsr_get_info(c_new, nfullrows_total=n, nfullcols_total=k)
289 v => qs_ot_env%buf1_k_k_nosym
290 w => qs_ot_env%buf2_k_k_nosym
291 ALLOCATE (eig(k), fun(k))
293 CALL cp_dbcsr_syevd(p, v, eig, qs_ot_env%para_env, qs_ot_env%blacs_env)
297 IF (eig(i) .LE. 0.0_dp) &
298 cpabort(
"P not positive definite")
299 IF (eig(i) .LT. 1.0e-8_dp)
THEN
302 fun(i) = 1.0_dp/sqrt(eig(i))
305 CALL dbcsr_copy(w, v)
306 CALL dbcsr_scale_by_vector(v, alpha=fun, side=
'right')
307 CALL dbcsr_multiply(
'N',
'T', 1.0_dp, w, v, 0.0_dp, p)
310 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, c_old, p, 0.0_dp, c_new)
314 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, sc, p, 0.0_dp, c_tmp)
315 CALL dbcsr_copy(sc, c_tmp)
318 DEALLOCATE (eig, fun)
320 CALL timestop(handle)
321 END SUBROUTINE qs_ot_ref_lwdn
334 SUBROUTINE qs_ot_ref_poly(qs_ot_env, C_OLD, C_TMP, C_NEW, P, SC, norm_in, update)
336 TYPE(qs_ot_type) :: qs_ot_env
337 TYPE(dbcsr_type),
POINTER :: c_old, c_tmp, c_new, p
338 TYPE(dbcsr_type) :: sc
339 REAL(
dp),
INTENT(IN) :: norm_in
340 LOGICAL,
INTENT(IN) :: update
342 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_ref_poly'
344 INTEGER :: handle, irefine, k, n
345 LOGICAL :: quick_exit
346 REAL(
dp) :: norm, norm_fro, norm_gct, occ_in, &
348 TYPE(dbcsr_type),
POINTER :: buf1, buf2, buf_nosym, ft, fy
350 CALL timeset(routinen, handle)
352 CALL dbcsr_get_info(c_new, nfullrows_total=n, nfullcols_total=k)
354 buf_nosym => qs_ot_env%buf1_k_k_nosym
355 buf1 => qs_ot_env%buf1_k_k_sym
356 buf2 => qs_ot_env%buf2_k_k_sym
357 fy => qs_ot_env%buf3_k_k_sym
358 ft => qs_ot_env%buf4_k_k_sym
365 IF (norm .LT. qs_ot_env%settings%eps_irac_quick_exit) quick_exit = .true.
369 DO irefine = 1, qs_ot_env%settings%max_irac
372 IF (norm .GT. 1.0_dp)
THEN
373 CALL dbcsr_scale(p, 1.0_dp/norm)
374 rescale = rescale/sqrt(norm)
378 CALL qs_ot_refine(p, fy, buf1, buf2, qs_ot_env%settings%irac_degree, &
379 qs_ot_env%settings%eps_irac_filter_matrix)
382 IF (irefine .EQ. 1)
THEN
383 CALL dbcsr_copy(ft, fy, name=
'FT')
385 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, ft, fy, 0.0_dp, buf1)
386 IF (qs_ot_env%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
387 occ_in = dbcsr_get_occupation(buf1)
388 CALL dbcsr_filter(buf1, qs_ot_env%settings%eps_irac_filter_matrix)
389 occ_out = dbcsr_get_occupation(buf1)
391 CALL dbcsr_copy(ft, buf1, name=
'FT')
400 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, p, fy, 0.0_dp, buf_nosym)
401 IF (qs_ot_env%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
402 occ_in = dbcsr_get_occupation(buf_nosym)
403 CALL dbcsr_filter(buf_nosym, qs_ot_env%settings%eps_irac_filter_matrix)
404 occ_out = dbcsr_get_occupation(buf_nosym)
406 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, fy, buf_nosym, 0.0_dp, p)
407 IF (qs_ot_env%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
408 occ_in = dbcsr_get_occupation(p)
409 CALL dbcsr_filter(p, qs_ot_env%settings%eps_irac_filter_matrix)
410 occ_out = dbcsr_get_occupation(p)
414 CALL dbcsr_add_on_diag(p, -1.0_dp)
415 norm_fro = dbcsr_frobenius_norm(p)
416 norm_gct = dbcsr_gershgorin_norm(p)
417 CALL dbcsr_add_on_diag(p, 1.0_dp)
418 norm = min(norm_gct, norm_fro)
423 IF (norm > 1.0e10_dp)
THEN
424 CALL cp_abort(__location__, &
425 "Refinement blows up! "// &
426 "We need you to improve the code, please post your input on "// &
427 "the forum https://www.cp2k.org/")
431 IF (norm .LT. qs_ot_env%settings%eps_irac_quick_exit) quick_exit = .true.
434 IF (norm .LT. qs_ot_env%settings%eps_irac)
EXIT
439 CALL dbcsr_multiply(
'N',
'N', rescale, c_old, ft, 0.0_dp, c_new)
440 IF (qs_ot_env%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
441 occ_in = dbcsr_get_occupation(c_new)
442 CALL dbcsr_filter(c_new, qs_ot_env%settings%eps_irac_filter_matrix)
443 occ_out = dbcsr_get_occupation(c_new)
448 CALL dbcsr_multiply(
'N',
'N', rescale, sc, ft, 0.0_dp, c_tmp)
449 IF (qs_ot_env%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
450 occ_in = dbcsr_get_occupation(c_tmp)
451 CALL dbcsr_filter(c_tmp, qs_ot_env%settings%eps_irac_filter_matrix)
452 occ_out = dbcsr_get_occupation(c_tmp)
454 CALL dbcsr_copy(sc, c_tmp)
457 CALL timestop(handle)
458 END SUBROUTINE qs_ot_ref_poly
465 FUNCTION qs_ot_ref_update(qs_ot_env1)
RESULT(update)
467 TYPE(qs_ot_type) :: qs_ot_env1
471 SELECT CASE (qs_ot_env1%settings%ot_method)
473 SELECT CASE (qs_ot_env1%settings%line_search_method)
475 IF (qs_ot_env1%line_search_count .EQ. 2) update = .true.
484 END FUNCTION qs_ot_ref_update
492 SUBROUTINE qs_ot_ref_decide(qs_ot_env1, norm_in, ortho_irac)
494 TYPE(qs_ot_type) :: qs_ot_env1
495 REAL(
dp),
INTENT(IN) :: norm_in
496 CHARACTER(LEN=*),
INTENT(INOUT) :: ortho_irac
498 ortho_irac = qs_ot_env1%settings%ortho_irac
499 IF (norm_in .LT. qs_ot_env1%settings%eps_irac_switch) ortho_irac =
"POLY"
500 END SUBROUTINE qs_ot_ref_decide
514 matrix_gx_old, matrix_dx, qs_ot_env, qs_ot_env1)
516 TYPE(dbcsr_type),
POINTER :: matrix_c, matrix_s, matrix_x, matrix_sx, &
517 matrix_gx_old, matrix_dx
518 TYPE(qs_ot_type) :: qs_ot_env, qs_ot_env1
520 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_orbitals_ref'
522 CHARACTER(LEN=4) :: ortho_irac
523 INTEGER :: handle, k, n
524 LOGICAL :: on_the_fly_loc, update
525 REAL(
dp) :: norm, norm_fro, norm_gct, occ_in, occ_out
526 TYPE(dbcsr_type),
POINTER :: c_new, c_old, c_tmp, d, g_old, p, s, sc
528 CALL timeset(routinen, handle)
530 CALL dbcsr_get_info(matrix_c, nfullrows_total=n, nfullcols_total=k)
535 g_old => matrix_gx_old
539 p => qs_ot_env%p_k_k_sym
540 c_tmp => qs_ot_env%buf1_n_k
543 update = qs_ot_ref_update(qs_ot_env1)
549 on_the_fly_loc = qs_ot_env1%settings%on_the_fly_loc
552 IF (
ASSOCIATED(s))
THEN
553 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, s, c_old, 0.0_dp, sc)
554 IF (qs_ot_env1%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
555 occ_in = dbcsr_get_occupation(sc)
556 CALL dbcsr_filter(sc, qs_ot_env1%settings%eps_irac_filter_matrix)
557 occ_out = dbcsr_get_occupation(sc)
560 CALL dbcsr_copy(sc, c_old)
564 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, c_old, sc, 0.0_dp, p)
565 IF (qs_ot_env1%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
566 occ_in = dbcsr_get_occupation(p)
567 CALL dbcsr_filter(p, qs_ot_env1%settings%eps_irac_filter_matrix)
568 occ_out = dbcsr_get_occupation(p)
572 CALL dbcsr_add_on_diag(p, -1.0_dp)
573 norm_fro = dbcsr_frobenius_norm(p)
574 norm_gct = dbcsr_gershgorin_norm(p)
575 CALL dbcsr_add_on_diag(p, 1.0_dp)
576 norm = min(norm_gct, norm_fro)
577 CALL qs_ot_ref_decide(qs_ot_env1, norm, ortho_irac)
580 SELECT CASE (ortho_irac)
582 CALL qs_ot_ref_chol(qs_ot_env, c_old, c_tmp, c_new, p, sc, update)
584 CALL qs_ot_ref_lwdn(qs_ot_env, c_old, c_tmp, c_new, p, sc, update)
586 CALL qs_ot_ref_poly(qs_ot_env, c_old, c_tmp, c_new, p, sc, norm, update)
588 cpabort(
"Wrong argument")
593 IF (on_the_fly_loc)
THEN
594 CALL qs_ot_on_the_fly_localize(qs_ot_env, c_new, sc, g_old, d)
596 CALL dbcsr_copy(c_old, c_new)
599 CALL timestop(handle)
611 SUBROUTINE qs_ot_refine(P, FY, P2, T, irac_degree, eps_irac_filter_matrix)
616 TYPE(dbcsr_type),
INTENT(inout) :: p, fy, p2, t
617 INTEGER,
INTENT(in) :: irac_degree
618 REAL(
dp),
INTENT(in) :: eps_irac_filter_matrix
620 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_refine'
623 REAL(
dp) :: occ_in, occ_out, r
625 CALL timeset(routinen, handle)
627 CALL dbcsr_get_info(p, nfullcols_total=k)
628 SELECT CASE (irac_degree)
632 CALL dbcsr_multiply(
'N',
'N', r, p, p, 0.0_dp, fy)
633 IF (eps_irac_filter_matrix .GT. 0.0_dp)
THEN
634 occ_in = dbcsr_get_occupation(fy)
635 CALL dbcsr_filter(fy, eps_irac_filter_matrix)
636 occ_out = dbcsr_get_occupation(fy)
639 CALL dbcsr_add(fy, p, alpha_scalar=1.0_dp, beta_scalar=r)
641 CALL dbcsr_add_on_diag(fy, alpha_scalar=r)
644 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, p, p, 0.0_dp, p2)
645 IF (eps_irac_filter_matrix .GT. 0.0_dp)
THEN
646 occ_in = dbcsr_get_occupation(p2)
647 CALL dbcsr_filter(p2, eps_irac_filter_matrix)
648 occ_out = dbcsr_get_occupation(p2)
651 CALL dbcsr_multiply(
'N',
'N', r, p2, p, 0.0_dp, fy)
652 IF (eps_irac_filter_matrix .GT. 0.0_dp)
THEN
653 occ_in = dbcsr_get_occupation(fy)
654 CALL dbcsr_filter(fy, eps_irac_filter_matrix)
655 occ_out = dbcsr_get_occupation(fy)
658 CALL dbcsr_add(fy, p2, alpha_scalar=1.0_dp, beta_scalar=r)
660 CALL dbcsr_add(fy, p, alpha_scalar=1.0_dp, beta_scalar=r)
662 CALL dbcsr_add_on_diag(fy, alpha_scalar=r)
666 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, p, p, 0.0_dp, p2)
667 IF (eps_irac_filter_matrix .GT. 0.0_dp)
THEN
668 occ_in = dbcsr_get_occupation(p2)
669 CALL dbcsr_filter(p2, eps_irac_filter_matrix)
670 occ_out = dbcsr_get_occupation(p2)
672 r = -180.0_dp/128.0_dp
673 CALL dbcsr_add(t, p, alpha_scalar=0.0_dp, beta_scalar=r)
675 CALL dbcsr_add(t, p2, alpha_scalar=1.0_dp, beta_scalar=r)
676 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, t, p2, 0.0_dp, fy)
677 IF (eps_irac_filter_matrix .GT. 0.0_dp)
THEN
678 occ_in = dbcsr_get_occupation(fy)
679 CALL dbcsr_filter(fy, eps_irac_filter_matrix)
680 occ_out = dbcsr_get_occupation(fy)
682 r = 378.0_dp/128.0_dp
683 CALL dbcsr_add(fy, p2, alpha_scalar=1.0_dp, beta_scalar=r)
684 r = -420.0_dp/128.0_dp
685 CALL dbcsr_add(fy, p, alpha_scalar=1.0_dp, beta_scalar=r)
686 r = 315.0_dp/128.0_dp
687 CALL dbcsr_add_on_diag(fy, alpha_scalar=r)
689 cpabort(
"This irac_order NYI")
691 CALL timestop(handle)
692 END SUBROUTINE qs_ot_refine
704 TYPE(dbcsr_type),
POINTER :: matrix_hc, matrix_x, matrix_sx, matrix_gx
705 TYPE(qs_ot_type) :: qs_ot_env
707 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_derivative_ref'
709 INTEGER :: handle, k, n
710 REAL(
dp) :: occ_in, occ_out
711 TYPE(dbcsr_type),
POINTER :: c, chc, g, g_dp, hc, sc
713 CALL timeset(routinen, handle)
715 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
721 chc => qs_ot_env%buf1_k_k_sym
722 g_dp => qs_ot_env%buf1_n_k_dp
725 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, c, hc, 0.0_dp, chc)
726 IF (qs_ot_env%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
727 occ_in = dbcsr_get_occupation(chc)
728 CALL dbcsr_filter(chc, qs_ot_env%settings%eps_irac_filter_matrix)
729 occ_out = dbcsr_get_occupation(chc)
732 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, sc, chc, 0.0_dp, g)
733 IF (qs_ot_env%settings%eps_irac_filter_matrix .GT. 0.0_dp)
THEN
734 occ_in = dbcsr_get_occupation(g)
735 CALL dbcsr_filter(g, qs_ot_env%settings%eps_irac_filter_matrix)
736 occ_out = dbcsr_get_occupation(g)
739 CALL dbcsr_add(g, hc, alpha_scalar=-1.0_dp, beta_scalar=1.0_dp)
741 CALL timestop(handle)
753 TYPE(dbcsr_type),
POINTER :: matrix_x, matrix_sx
754 TYPE(qs_ot_type) :: qs_ot_env
756 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_p'
757 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
759 INTEGER :: handle, k, max_iter, n
761 REAL(kind=
dp) :: max_ev, min_ev, threshold
763 CALL timeset(routinen, handle)
765 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
768 CALL dbcsr_multiply(
'T',
'N', rone, matrix_x, matrix_sx, rzero, &
773 max_iter = 30; threshold = 1.0e-03_dp
774 CALL arnoldi_extremal(qs_ot_env%matrix_p, max_ev, min_ev, converged, threshold, max_iter)
775 qs_ot_env%largest_eval_upper_bound = max(max_ev, abs(min_ev))
777 IF (.NOT. converged) qs_ot_env%largest_eval_upper_bound = dbcsr_gershgorin_norm(qs_ot_env%matrix_p)
778 CALL decide_strategy(qs_ot_env)
779 IF (qs_ot_env%do_taylor)
THEN
780 CALL qs_ot_p2m_taylor(qs_ot_env)
782 CALL qs_ot_p2m_diag(qs_ot_env)
785 IF (qs_ot_env%settings%do_rotation)
THEN
786 CALL qs_ot_generate_rotation(qs_ot_env)
789 CALL timestop(handle)
800 SUBROUTINE qs_ot_generate_rotation(qs_ot_env)
802 TYPE(qs_ot_type) :: qs_ot_env
804 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_generate_rotation'
805 COMPLEX(KIND=dp),
PARAMETER :: cone = (1.0_dp, 0.0_dp), &
806 czero = (0.0_dp, 0.0_dp)
808 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:) :: evals_exp
809 COMPLEX(KIND=dp),
DIMENSION(:),
POINTER :: data_z
810 INTEGER :: blk, col, handle, k, row
812 REAL(kind=
dp),
DIMENSION(:),
POINTER :: data_d
813 TYPE(dbcsr_iterator_type) :: iter
814 TYPE(dbcsr_type) :: cmat_u, cmat_x
816 CALL timeset(routinen, handle)
818 CALL dbcsr_get_info(qs_ot_env%rot_mat_x, nfullrows_total=k)
821 CALL dbcsr_copy(cmat_x, qs_ot_env%rot_mat_evec, name=
'cmat_x')
822 CALL dbcsr_copy(cmat_u, qs_ot_env%rot_mat_evec, name=
'cmat_u')
823 ALLOCATE (evals_exp(k))
830 CALL dbcsr_iterator_start(iter, cmat_x)
831 DO WHILE (dbcsr_iterator_blocks_left(iter))
832 CALL dbcsr_iterator_next_block(iter, row, col, data_z, blk)
833 CALL dbcsr_get_block_p(qs_ot_env%rot_mat_x, row, col, data_d, found)
834 IF (.NOT. found)
THEN
835 WRITE (*, *) routinen//.NOT.
' found'
838 data_z = cmplx(0.0_dp, data_d, kind=
dp)
841 CALL dbcsr_iterator_stop(iter)
843 CALL cp_dbcsr_heevd(cmat_x, qs_ot_env%rot_mat_evec, qs_ot_env%rot_mat_evals, &
844 qs_ot_env%para_env, qs_ot_env%blacs_env)
845 evals_exp(:) = exp((0.0_dp, -1.0_dp)*qs_ot_env%rot_mat_evals(:))
846 CALL dbcsr_copy(cmat_x, qs_ot_env%rot_mat_evec)
847 CALL dbcsr_scale_by_vector(cmat_x, alpha=evals_exp, side=
'right')
848 CALL dbcsr_multiply(
'N',
'C', cone, cmat_x, qs_ot_env%rot_mat_evec, czero, cmat_u)
849 CALL dbcsr_copy(qs_ot_env%rot_mat_u, cmat_u, keep_imaginary=.false.)
850 CALL dbcsr_release(cmat_x)
851 CALL dbcsr_release(cmat_u)
852 DEALLOCATE (evals_exp)
855 CALL timestop(handle)
857 END SUBROUTINE qs_ot_generate_rotation
866 SUBROUTINE qs_ot_rot_mat_derivative(qs_ot_env)
867 TYPE(qs_ot_type) :: qs_ot_env
869 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_rot_mat_derivative'
871 COMPLEX(KIND=dp),
PARAMETER :: cone = (1.0_dp, 0.0_dp), &
872 czero = (0.0_dp, 0.0_dp)
874 INTEGER :: handle, i, j, k
875 REAL(kind=
dp) :: e1, e2
876 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: data_d
877 TYPE(dbcsr_type) :: cmat_buf1, cmat_buf2
878 TYPE(dbcsr_iterator_type) :: iter
879 COMPLEX(dp),
DIMENSION(:, :),
POINTER :: data_z
880 INTEGER::row, col, blk, row_offset, col_offset, row_size, col_size
882 TYPE(dbcsr_distribution_type) :: dist
884 CALL timeset(routinen, handle)
886 CALL dbcsr_get_info(qs_ot_env%rot_mat_u, nfullrows_total=k)
888 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%rot_mat_dedu)
890 CALL dbcsr_copy(cmat_buf1, qs_ot_env%rot_mat_evec,
"cmat_buf1")
891 CALL dbcsr_copy(cmat_buf2, qs_ot_env%rot_mat_evec,
"cmat_buf2")
900 CALL dbcsr_iterator_start(iter, cmat_buf1)
901 DO WHILE (dbcsr_iterator_blocks_left(iter))
902 CALL dbcsr_iterator_next_block(iter, row, col, data_z, blk)
903 CALL dbcsr_get_block_p(qs_ot_env%matrix_buf1, row, col, data_d, found)
906 CALL dbcsr_iterator_stop(iter)
908 CALL dbcsr_multiply(
'T',
'N', cone, cmat_buf1, qs_ot_env%rot_mat_evec, &
910 CALL dbcsr_multiply(
'C',
'N', cone, qs_ot_env%rot_mat_evec, cmat_buf2, &
913 CALL dbcsr_iterator_start(iter, cmat_buf1)
914 DO WHILE (dbcsr_iterator_blocks_left(iter))
915 CALL dbcsr_iterator_next_block(iter, row, col, data_z, blk, &
916 row_size=row_size, col_size=col_size, &
917 row_offset=row_offset, col_offset=col_offset)
920 e1 = qs_ot_env%rot_mat_evals(row_offset + i - 1)
921 e2 = qs_ot_env%rot_mat_evals(col_offset + j - 1)
922 data_z(i, j) = data_z(i, j)*cint(e1, e2)
926 CALL dbcsr_iterator_stop(iter)
928 CALL dbcsr_multiply(
'N',
'N', cone, qs_ot_env%rot_mat_evec, cmat_buf1, &
930 CALL dbcsr_multiply(
'N',
'C', cone, cmat_buf2, qs_ot_env%rot_mat_evec, &
933 CALL dbcsr_copy(qs_ot_env%matrix_buf1, cmat_buf1)
935 CALL dbcsr_get_info(qs_ot_env%matrix_buf3, distribution=dist)
936 CALL dbcsr_transposed(qs_ot_env%matrix_buf2, qs_ot_env%matrix_buf1, &
937 shallow_data_copy=.false., use_distribution=dist, &
938 transpose_distribution=.false.)
939 CALL dbcsr_add(qs_ot_env%matrix_buf1, qs_ot_env%matrix_buf2, &
940 alpha_scalar=-1.0_dp, beta_scalar=+1.0_dp)
941 CALL dbcsr_copy(qs_ot_env%rot_mat_gx, qs_ot_env%matrix_buf1)
942 CALL dbcsr_release(cmat_buf1)
943 CALL dbcsr_release(cmat_buf2)
945 CALL timestop(handle)
953 FUNCTION cint(e1, e2)
954 REAL(kind=
dp) :: e1, e2
955 COMPLEX(KIND=dp) :: cint
957 COMPLEX(KIND=dp) :: l1, l2, x
960 l1 = (0.0_dp, -1.0_dp)*e1
961 l2 = (0.0_dp, -1.0_dp)*e2
962 IF (abs(l1 - l2) .GT. 0.5_dp)
THEN
963 cint = (exp(l1) - exp(l2))/(l1 - l2)
969 x = x*(l1 - l2)/real(i + 1, kind=
dp)
974 END SUBROUTINE qs_ot_rot_mat_derivative
988 SUBROUTINE decide_strategy(qs_ot_env)
989 TYPE(qs_ot_type) :: qs_ot_env
992 REAL(kind=
dp) :: num_error
994 qs_ot_env%do_taylor = .false.
996 num_error = qs_ot_env%largest_eval_upper_bound/(2.0_dp)
997 DO WHILE (num_error > qs_ot_env%settings%eps_taylor .AND. n <= qs_ot_env%settings%max_taylor)
999 num_error = num_error*qs_ot_env%largest_eval_upper_bound/real((2*n + 1)*(2*n + 2), kind=
dp)
1001 qs_ot_env%taylor_order = n
1002 IF (qs_ot_env%taylor_order <= qs_ot_env%settings%max_taylor)
THEN
1003 qs_ot_env%do_taylor = .true.
1006 END SUBROUTINE decide_strategy
1019 TYPE(dbcsr_type),
POINTER :: matrix_c, matrix_x
1020 TYPE(qs_ot_type) :: qs_ot_env
1022 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_get_orbitals'
1023 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1025 INTEGER :: handle, k, n
1026 TYPE(dbcsr_type),
POINTER :: matrix_kk
1028 CALL timeset(routinen, handle)
1030 CALL dbcsr_get_info(matrix_x, nfullrows_total=n, nfullcols_total=k)
1034 IF (qs_ot_env%settings%do_rotation)
THEN
1035 matrix_kk => qs_ot_env%matrix_buf1
1036 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_cosp, &
1037 qs_ot_env%rot_mat_u, rzero, matrix_kk)
1039 matrix_kk => qs_ot_env%matrix_cosp
1042 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_c0, matrix_kk, &
1045 IF (qs_ot_env%settings%do_rotation)
THEN
1046 matrix_kk => qs_ot_env%matrix_buf1
1047 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_sinp, &
1048 qs_ot_env%rot_mat_u, rzero, matrix_kk)
1050 matrix_kk => qs_ot_env%matrix_sinp
1052 CALL dbcsr_multiply(
'N',
'N', rone, matrix_x, matrix_kk, &
1055 CALL timestop(handle)
1074 TYPE(dbcsr_type),
POINTER :: matrix_hc, matrix_x, matrix_sx, matrix_gx
1075 TYPE(qs_ot_type) :: qs_ot_env
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
1093 CALL dbcsr_copy(matrix_gx, matrix_hc)
1094 CALL dbcsr_init_p(matrix_hc_local)
1095 CALL dbcsr_copy(matrix_hc_local, matrix_hc, name=
'matrix_hc_local')
1096 CALL dbcsr_set(matrix_hc_local, 0.0_dp)
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
1122 CALL apply_preconditioner(qs_ot_env%preconditioner, qs_ot_env%matrix_sc0, &
1123 qs_ot_env%matrix_psc0)
1125 CALL dbcsr_multiply(
'T',
'N', rone, &
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 upper_to_full=.true.)
1133 qs_ot_env%os_valid = .true.
1135 CALL dbcsr_multiply(
'T',
'N', rone, matrix_target, matrix_gx, &
1136 rzero, qs_ot_env%matrix_buf1_ortho)
1137 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_os, &
1138 qs_ot_env%matrix_buf1_ortho, rzero, qs_ot_env%matrix_buf2_ortho)
1139 CALL dbcsr_multiply(
'N',
'N', -rone, qs_ot_env%matrix_sc0, &
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
1147 CALL dbcsr_release_p(matrix_hc_local)
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
1166 TYPE(qs_ot_type) :: qs_ot_env
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
1172 TYPE(dbcsr_distribution_type) :: dist
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)
1190 CALL dbcsr_hadamard_product(qs_ot_env%matrix_buf2, qs_ot_env%matrix_sinp_b, &
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)
1202 CALL dbcsr_hadamard_product(qs_ot_env%matrix_buf2, qs_ot_env%matrix_cosp_b, &
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)
1214 CALL dbcsr_get_info(qs_ot_env%matrix_buf3, distribution=dist)
1215 CALL dbcsr_transposed(qs_ot_env%matrix_buf1, 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
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
1241 TYPE(qs_ot_type) :: qs_ot_env
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
1248 TYPE(dbcsr_distribution_type) :: dist
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 .LE. 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)
1273 CALL dbcsr_get_info(matrix_left, distribution=dist)
1274 CALL dbcsr_transposed(qs_ot_env%matrix_buf1, 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)
1279 CALL dbcsr_copy(matrix_right, matrix_left)
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)
1294 CALL dbcsr_copy(matrix_right, 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)
1303 CALL dbcsr_get_info(matrix_left, distribution=dist)
1304 CALL dbcsr_transposed(qs_ot_env%matrix_buf1, 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)
1308 CALL dbcsr_copy(matrix_right, matrix_left)
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)
1323 CALL dbcsr_copy(matrix_right, 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
1341 SUBROUTINE qs_ot_p2m_taylor(qs_ot_env)
1342 TYPE(qs_ot_type) :: qs_ot_env
1344 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_p2m_taylor'
1345 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1347 INTEGER :: handle, i, k
1348 REAL(kind=
dp) :: cosfactor, sinfactor
1350 CALL timeset(routinen, handle)
1353 CALL dbcsr_set(qs_ot_env%matrix_cosp, rzero)
1354 CALL dbcsr_set(qs_ot_env%matrix_sinp, rzero)
1355 CALL dbcsr_add_on_diag(qs_ot_env%matrix_cosp, rone)
1356 CALL dbcsr_add_on_diag(qs_ot_env%matrix_sinp, rone)
1358 IF (qs_ot_env%taylor_order .LE. 0)
THEN
1359 CALL timestop(handle)
1364 cosfactor = -1.0_dp/(1.0_dp*2.0_dp)
1365 sinfactor = -1.0_dp/(2.0_dp*3.0_dp)
1366 CALL dbcsr_add(qs_ot_env%matrix_cosp, qs_ot_env%matrix_p, alpha_scalar=1.0_dp, beta_scalar=cosfactor)
1367 CALL dbcsr_add(qs_ot_env%matrix_sinp, qs_ot_env%matrix_p, alpha_scalar=1.0_dp, beta_scalar=sinfactor)
1368 IF (qs_ot_env%taylor_order .LE. 1)
THEN
1369 CALL timestop(handle)
1374 CALL dbcsr_get_info(qs_ot_env%matrix_p, nfullrows_total=k)
1375 CALL dbcsr_copy(qs_ot_env%matrix_r, qs_ot_env%matrix_p)
1377 DO i = 2, qs_ot_env%taylor_order
1379 CALL dbcsr_multiply(
'N',
'N', rone, qs_ot_env%matrix_p, qs_ot_env%matrix_r, &
1380 rzero, qs_ot_env%matrix_buf1)
1381 CALL dbcsr_copy(qs_ot_env%matrix_r, qs_ot_env%matrix_buf1)
1383 cosfactor = cosfactor*(-1.0_dp)/real(2*i*(2*i - 1), kind=
dp)
1384 sinfactor = sinfactor*(-1.0_dp)/real(2*i*(2*i + 1), kind=
dp)
1385 CALL dbcsr_add(qs_ot_env%matrix_cosp, qs_ot_env%matrix_r, &
1386 alpha_scalar=1.0_dp, beta_scalar=cosfactor)
1387 CALL dbcsr_add(qs_ot_env%matrix_sinp, qs_ot_env%matrix_r, &
1388 alpha_scalar=1.0_dp, beta_scalar=sinfactor)
1391 CALL timestop(handle)
1393 END SUBROUTINE qs_ot_p2m_taylor
1404 SUBROUTINE qs_ot_p2m_diag(qs_ot_env)
1406 TYPE(qs_ot_type) :: qs_ot_env
1408 CHARACTER(len=*),
PARAMETER :: routinen =
'qs_ot_p2m_diag'
1409 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
1411 INTEGER :: blk, col, col_offset, col_size, handle, &
1412 i, j, k, row, row_offset, row_size
1413 REAL(
dp),
DIMENSION(:, :),
POINTER :: data
1414 REAL(kind=
dp) :: a, b
1415 TYPE(dbcsr_iterator_type) :: iter
1417 CALL timeset(routinen, handle)
1419 CALL dbcsr_get_info(qs_ot_env%matrix_p, nfullrows_total=k)
1420 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_p)
1421 CALL cp_dbcsr_syevd(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r, qs_ot_env%evals, &
1422 qs_ot_env%para_env, qs_ot_env%blacs_env)
1424 qs_ot_env%evals(i) = max(0.0_dp, qs_ot_env%evals(i))
1429 qs_ot_env%dum(i) = cos(sqrt(qs_ot_env%evals(i)))
1431 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r)
1432 CALL dbcsr_scale_by_vector(qs_ot_env%matrix_buf1, alpha=qs_ot_env%dum, side=
'right')
1433 CALL dbcsr_multiply(
'N',
'T', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
1434 rzero, qs_ot_env%matrix_cosp)
1438 qs_ot_env%dum(i) = qs_ot_sinc(sqrt(qs_ot_env%evals(i)))
1440 CALL dbcsr_copy(qs_ot_env%matrix_buf1, qs_ot_env%matrix_r)
1441 CALL dbcsr_scale_by_vector(qs_ot_env%matrix_buf1, alpha=qs_ot_env%dum, side=
'right')
1442 CALL dbcsr_multiply(
'N',
'T', rone, qs_ot_env%matrix_r, qs_ot_env%matrix_buf1, &
1443 rzero, qs_ot_env%matrix_sinp)
1445 CALL dbcsr_copy(qs_ot_env%matrix_cosp_b, qs_ot_env%matrix_cosp)
1446 CALL dbcsr_iterator_start(iter, qs_ot_env%matrix_cosp_b)
1447 DO WHILE (dbcsr_iterator_blocks_left(iter))
1448 CALL dbcsr_iterator_next_block(iter, row, col,
DATA, &
1449 block_number=blk, row_size=row_size, col_size=col_size, &
1450 row_offset=row_offset, col_offset=col_offset)
1453 a = (sqrt(qs_ot_env%evals(row_offset + i - 1)) &
1454 - sqrt(qs_ot_env%evals(col_offset + j - 1)))/2.0_dp
1455 b = (sqrt(qs_ot_env%evals(row_offset + i - 1)) &
1456 + sqrt(qs_ot_env%evals(col_offset + j - 1)))/2.0_dp
1457 DATA(i, j) = -0.5_dp*qs_ot_sinc(a)*qs_ot_sinc(b)
1461 CALL dbcsr_iterator_stop(iter)
1463 CALL dbcsr_copy(qs_ot_env%matrix_sinp_b, qs_ot_env%matrix_sinp)
1464 CALL dbcsr_iterator_start(iter, qs_ot_env%matrix_sinp_b)
1465 DO WHILE (dbcsr_iterator_blocks_left(iter))
1466 CALL dbcsr_iterator_next_block(iter, row, col,
DATA, &
1467 block_number=blk, row_size=row_size, col_size=col_size, &
1468 row_offset=row_offset, col_offset=col_offset)
1471 a = sqrt(qs_ot_env%evals(row_offset + i - 1))
1472 b = sqrt(qs_ot_env%evals(col_offset + j - 1))
1473 DATA(i, j) = qs_ot_sincf(a, b)
1477 CALL dbcsr_iterator_stop(iter)
1479 CALL timestop(handle)
1481 END SUBROUTINE qs_ot_p2m_diag
1489 FUNCTION qs_ot_sinc(x)
1491 REAL(kind=
dp),
INTENT(IN) :: x
1492 REAL(kind=
dp) :: qs_ot_sinc
1494 REAL(kind=
dp),
PARAMETER :: q1 = 1.0_dp, q2 = -q1/(2.0_dp*3.0_dp), q3 = -q2/(4.0_dp*5.0_dp), &
1495 q4 = -q3/(6.0_dp*7.0_dp), q5 = -q4/(8.0_dp*9.0_dp), q6 = -q5/(10.0_dp*11.0_dp), &
1496 q7 = -q6/(12.0_dp*13.0_dp), q8 = -q7/(14.0_dp*15.0_dp), q9 = -q8/(16.0_dp*17.0_dp), &
1497 q10 = -q9/(18.0_dp*19.0_dp)
1501 IF (abs(x) > 0.5_dp)
THEN
1502 qs_ot_sinc = sin(x)/x
1505 qs_ot_sinc = q1 + y*(q2 + y*(q3 + y*(q4 + y*(q5 + y*(q6 + y*(q7 + y*(q8 + y*(q9 + y*(q10)))))))))
1507 END FUNCTION qs_ot_sinc
1515 FUNCTION qs_ot_sincf(xa, ya)
1517 REAL(kind=
dp),
INTENT(IN) :: xa, ya
1518 REAL(kind=
dp) :: qs_ot_sincf
1521 REAL(kind=
dp) :: a, b, rs, sf, x, xs, y, ybx, ybxs
1525 IF (xa .LT. 0) cpabort(
"x is negative")
1526 IF (ya .LT. 0) cpabort(
"y is negative")
1528 IF (xa .LT. ya)
THEN
1536 IF (x .LT. 0.5_dp)
THEN
1538 qs_ot_sincf = 0.0_dp
1539 IF (x .GT. 0.0_dp)
THEN
1545 sf = -1.0_dp/((1.0_dp + ybx)*6.0_dp)
1551 qs_ot_sincf = qs_ot_sincf + sf*rs*xs*(1.0_dp + ybxs)
1552 sf = -sf/(real((2*i + 2),
dp)*real((2*i + 3),
dp))
1559 IF (x - y .GT. 0.1_dp)
THEN
1560 qs_ot_sincf = (qs_ot_sinc(x) - qs_ot_sinc(y))/((x + y)*(x - y))
1565 qs_ot_sincf = (qs_ot_sinc(b)*cos(a) - qs_ot_sinc(a)*cos(b))/(2*x*y)
1569 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...
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, upper_to_full)
used to replace the cholesky decomposition by the inverse
Interface to (sca)lapack for the Cholesky based procedures.
subroutine, public cp_dbcsr_heevd(matrix, eigenvectors, 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)
...
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)
...
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)
...
subroutine, public qs_ot_new_preconditioner(qs_ot_env, preconditioner)
...