19 USE dbcsr_api,
ONLY: &
20 dbcsr_add, dbcsr_add_on_diag, dbcsr_copy, dbcsr_create, dbcsr_desymmetrize, dbcsr_dot, &
21 dbcsr_filter, dbcsr_finalize, dbcsr_frobenius_norm, dbcsr_get_data_type, &
22 dbcsr_get_occupation, dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, &
23 dbcsr_iterator_start, dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_multiply, &
24 dbcsr_put_block, dbcsr_release, dbcsr_scale, dbcsr_set, dbcsr_trace, dbcsr_type, &
25 dbcsr_type_no_symmetry
47 #include "./base/base_uses.f90"
53 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'dm_ls_scf_methods'
72 TYPE(dbcsr_type) :: matrix_s
73 TYPE(ls_scf_env_type) :: ls_scf_env
75 CHARACTER(len=*),
PARAMETER :: routinen =
'ls_scf_init_matrix_S'
77 INTEGER :: handle, unit_nr
78 REAL(kind=
dp) :: frob_matrix, frob_matrix_base
79 TYPE(cp_logger_type),
POINTER :: logger
80 TYPE(dbcsr_type) :: matrix_tmp1, matrix_tmp2
82 CALL timeset(routinen, handle)
86 IF (logger%para_env%is_source())
THEN
93 IF (ls_scf_env%has_unit_metric)
THEN
94 CALL dbcsr_set(ls_scf_env%matrix_s, 0.0_dp)
95 CALL dbcsr_add_on_diag(ls_scf_env%matrix_s, 1.0_dp)
97 CALL matrix_qs_to_ls(ls_scf_env%matrix_s, matrix_s, ls_scf_env%ls_mstruct, covariant=.true.)
100 CALL dbcsr_filter(ls_scf_env%matrix_s, ls_scf_env%eps_filter)
103 IF (ls_scf_env%has_s_preconditioner)
THEN
104 CALL dbcsr_create(ls_scf_env%matrix_bs_sqrt, template=ls_scf_env%matrix_s, &
105 matrix_type=dbcsr_type_no_symmetry)
106 CALL dbcsr_create(ls_scf_env%matrix_bs_sqrt_inv, template=ls_scf_env%matrix_s, &
107 matrix_type=dbcsr_type_no_symmetry)
109 ls_scf_env%s_preconditioner_type, ls_scf_env%ls_mstruct, &
110 ls_scf_env%matrix_bs_sqrt, ls_scf_env%matrix_bs_sqrt_inv, &
111 ls_scf_env%eps_filter, ls_scf_env%s_sqrt_order, &
112 ls_scf_env%eps_lanczos, ls_scf_env%max_iter_lanczos)
116 IF (ls_scf_env%has_s_preconditioner)
THEN
118 ls_scf_env%matrix_bs_sqrt, ls_scf_env%matrix_bs_sqrt_inv)
122 IF (ls_scf_env%use_s_sqrt)
THEN
124 CALL dbcsr_create(ls_scf_env%matrix_s_sqrt, template=ls_scf_env%matrix_s, &
125 matrix_type=dbcsr_type_no_symmetry)
126 CALL dbcsr_create(ls_scf_env%matrix_s_sqrt_inv, template=ls_scf_env%matrix_s, &
127 matrix_type=dbcsr_type_no_symmetry)
129 SELECT CASE (ls_scf_env%s_sqrt_method)
132 ls_scf_env%matrix_s, ls_scf_env%eps_filter, &
133 ls_scf_env%s_sqrt_order, &
134 ls_scf_env%eps_lanczos, ls_scf_env%max_iter_lanczos, &
138 ls_scf_env%matrix_s, ls_scf_env%eps_filter, &
139 ls_scf_env%s_sqrt_order, &
140 ls_scf_env%eps_lanczos, ls_scf_env%max_iter_lanczos)
142 cpabort(
"Unknown sqrt method.")
145 IF (ls_scf_env%check_s_inv)
THEN
146 CALL dbcsr_create(matrix_tmp1, template=ls_scf_env%matrix_s, &
147 matrix_type=dbcsr_type_no_symmetry)
148 CALL dbcsr_create(matrix_tmp2, template=ls_scf_env%matrix_s, &
149 matrix_type=dbcsr_type_no_symmetry)
151 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, ls_scf_env%matrix_s_sqrt_inv, ls_scf_env%matrix_s, &
152 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
154 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_tmp1, ls_scf_env%matrix_s_sqrt_inv, &
155 0.0_dp, matrix_tmp2, filter_eps=ls_scf_env%eps_filter)
157 frob_matrix_base = dbcsr_frobenius_norm(matrix_tmp2)
158 CALL dbcsr_add_on_diag(matrix_tmp2, -1.0_dp)
159 frob_matrix = dbcsr_frobenius_norm(matrix_tmp2)
160 IF (unit_nr > 0)
THEN
161 WRITE (unit_nr, *)
"Error for (inv(sqrt(S))*S*inv(sqrt(S))-I)", frob_matrix/frob_matrix_base
164 CALL dbcsr_release(matrix_tmp1)
165 CALL dbcsr_release(matrix_tmp2)
170 IF (ls_scf_env%needs_s_inv)
THEN
171 CALL dbcsr_create(ls_scf_env%matrix_s_inv, template=ls_scf_env%matrix_s, &
172 matrix_type=dbcsr_type_no_symmetry)
173 IF (.NOT. ls_scf_env%use_s_sqrt)
THEN
174 CALL invert_hotelling(ls_scf_env%matrix_s_inv, ls_scf_env%matrix_s, ls_scf_env%eps_filter)
176 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, ls_scf_env%matrix_s_sqrt_inv, ls_scf_env%matrix_s_sqrt_inv, &
177 0.0_dp, ls_scf_env%matrix_s_inv, filter_eps=ls_scf_env%eps_filter)
179 IF (ls_scf_env%check_s_inv)
THEN
180 CALL dbcsr_create(matrix_tmp1, template=ls_scf_env%matrix_s, &
181 matrix_type=dbcsr_type_no_symmetry)
182 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, ls_scf_env%matrix_s_inv, ls_scf_env%matrix_s, &
183 0.0_dp, matrix_tmp1, filter_eps=ls_scf_env%eps_filter)
184 frob_matrix_base = dbcsr_frobenius_norm(matrix_tmp1)
185 CALL dbcsr_add_on_diag(matrix_tmp1, -1.0_dp)
186 frob_matrix = dbcsr_frobenius_norm(matrix_tmp1)
187 IF (unit_nr > 0)
THEN
188 WRITE (unit_nr, *)
"Error for (inv(S)*S-I)", frob_matrix/frob_matrix_base
190 CALL dbcsr_release(matrix_tmp1)
194 CALL timestop(handle)
214 matrix_bs_sqrt, matrix_bs_sqrt_inv, threshold, order, eps_lanczos, max_iter_lanczos)
216 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_s
217 INTEGER :: preconditioner_type
218 TYPE(ls_mstruct_type) :: ls_mstruct
219 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_bs_sqrt, matrix_bs_sqrt_inv
220 REAL(kind=
dp) :: threshold
222 REAL(kind=
dp) :: eps_lanczos
223 INTEGER :: max_iter_lanczos
225 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_matrix_preconditioner'
227 INTEGER :: datatype, handle, iblock_col, iblock_row
228 LOGICAL :: block_needed
229 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_dp
230 TYPE(dbcsr_iterator_type) :: iter
231 TYPE(dbcsr_type) :: matrix_bs
233 CALL timeset(routinen, handle)
235 datatype = dbcsr_get_data_type(matrix_s)
238 CALL dbcsr_create(matrix_bs, template=matrix_s)
240 SELECT CASE (preconditioner_type)
243 CALL dbcsr_iterator_start(iter, matrix_s)
244 DO WHILE (dbcsr_iterator_blocks_left(iter))
245 CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, block_dp)
252 block_needed = .false.
254 IF (iblock_row == iblock_col)
THEN
255 block_needed = .true.
259 IF (ls_mstruct%atom_to_molecule(iblock_row) == ls_mstruct%atom_to_molecule(iblock_col)) block_needed = .true.
264 IF (block_needed)
THEN
265 CALL dbcsr_put_block(matrix=matrix_bs, row=iblock_row, col=iblock_col, block=block_dp)
269 CALL dbcsr_iterator_stop(iter)
272 CALL dbcsr_finalize(matrix_bs)
274 SELECT CASE (preconditioner_type)
277 CALL dbcsr_copy(matrix_bs_sqrt, matrix_bs)
278 CALL dbcsr_set(matrix_bs_sqrt, 0.0_dp)
279 CALL dbcsr_add_on_diag(matrix_bs_sqrt, 1.0_dp)
282 CALL dbcsr_copy(matrix_bs_sqrt_inv, matrix_bs)
283 CALL dbcsr_set(matrix_bs_sqrt_inv, 0.0_dp)
284 CALL dbcsr_add_on_diag(matrix_bs_sqrt_inv, 1.0_dp)
286 CALL dbcsr_copy(matrix_bs_sqrt, matrix_bs)
287 CALL dbcsr_copy(matrix_bs_sqrt_inv, matrix_bs)
293 threshold=min(threshold, 1.0e-10_dp), order=order, &
294 eps_lanczos=eps_lanczos, max_iter_lanczos=max_iter_lanczos)
297 CALL dbcsr_release(matrix_bs)
299 CALL timestop(handle)
317 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix
318 CHARACTER(LEN=*) :: direction
319 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_bs_sqrt, matrix_bs_sqrt_inv
321 CHARACTER(LEN=*),
PARAMETER :: routinen =
'apply_matrix_preconditioner'
324 TYPE(dbcsr_type) :: matrix_tmp
326 CALL timeset(routinen, handle)
327 CALL dbcsr_create(matrix_tmp, template=matrix, matrix_type=dbcsr_type_no_symmetry)
329 SELECT CASE (direction)
331 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix, matrix_bs_sqrt_inv, &
333 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_bs_sqrt_inv, matrix_tmp, &
336 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix, matrix_bs_sqrt, &
338 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_bs_sqrt, matrix_tmp, &
344 CALL dbcsr_release(matrix_tmp)
346 CALL timestop(handle)
372 matrix_s, matrix_s_inv, nelectron, threshold, sign_symmetric, submatrix_sign_method, &
375 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_p
376 REAL(kind=
dp),
INTENT(INOUT) :: mu
378 INTEGER :: sign_method, sign_order
379 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_ks, matrix_s, matrix_s_inv
380 INTEGER,
INTENT(IN) :: nelectron
381 REAL(kind=
dp),
INTENT(IN) :: threshold
382 LOGICAL,
OPTIONAL :: sign_symmetric
383 INTEGER,
OPTIONAL :: submatrix_sign_method
384 TYPE(dbcsr_type),
INTENT(IN),
OPTIONAL :: matrix_s_sqrt_inv
386 CHARACTER(LEN=*),
PARAMETER :: routinen =
'density_matrix_sign'
387 REAL(kind=
dp),
PARAMETER :: initial_increment = 0.01_dp
389 INTEGER :: handle, iter, unit_nr, &
390 used_submatrix_sign_method
391 LOGICAL :: do_sign_symmetric, has_mu_high, &
392 has_mu_low, internal_mu_adjust
393 REAL(kind=
dp) :: increment, mu_high, mu_low, trace
394 TYPE(cp_logger_type),
POINTER :: logger
396 CALL timeset(routinen, handle)
399 IF (logger%para_env%is_source())
THEN
405 do_sign_symmetric = .false.
406 IF (
PRESENT(sign_symmetric)) do_sign_symmetric = sign_symmetric
409 IF (
PRESENT(submatrix_sign_method)) used_submatrix_sign_method = submatrix_sign_method
415 IF (internal_mu_adjust)
THEN
416 CALL density_matrix_sign_internal_mu(matrix_p, trace, mu, sign_method, &
417 matrix_ks, matrix_s, threshold, &
418 used_submatrix_sign_method, &
419 nelectron, matrix_s_sqrt_inv)
421 increment = initial_increment
424 has_mu_high = .false.
428 IF (has_mu_low .AND. has_mu_high)
THEN
429 mu = (mu_low + mu_high)/2
430 IF (abs(mu_high - mu_low) < threshold)
EXIT
434 matrix_ks, matrix_s, matrix_s_inv, threshold, &
435 do_sign_symmetric, used_submatrix_sign_method, &
437 IF (unit_nr > 0)
WRITE (unit_nr,
'(T2,A,I2,1X,F13.9,1X,F15.9)') &
438 "Density matrix: iter, mu, trace error: ", iter, mu, trace - nelectron
442 IF (abs(trace - nelectron) < 0.5_dp .OR. fixed_mu)
EXIT
444 IF (trace < nelectron)
THEN
448 increment = increment*2
453 increment = increment*2
459 CALL timestop(handle)
482 matrix_s, matrix_s_inv, threshold, sign_symmetric, submatrix_sign_method, &
485 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_p
486 REAL(kind=
dp),
INTENT(OUT) :: trace
487 REAL(kind=
dp),
INTENT(INOUT) :: mu
488 INTEGER :: sign_method, sign_order
489 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_ks, matrix_s, matrix_s_inv
490 REAL(kind=
dp),
INTENT(IN) :: threshold
491 LOGICAL :: sign_symmetric
492 INTEGER :: submatrix_sign_method
493 TYPE(dbcsr_type),
INTENT(IN),
OPTIONAL :: matrix_s_sqrt_inv
495 CHARACTER(LEN=*),
PARAMETER :: routinen =
'density_matrix_sign_fixed_mu'
497 INTEGER :: handle, unit_nr
498 REAL(kind=
dp) :: frob_matrix
499 TYPE(cp_logger_type),
POINTER :: logger
500 TYPE(dbcsr_type) :: matrix_p_ud, matrix_sign, matrix_sinv_ks, matrix_ssqrtinv_ks_ssqrtinv, &
501 matrix_ssqrtinv_ks_ssqrtinv2, matrix_tmp
503 CALL timeset(routinen, handle)
506 IF (logger%para_env%is_source())
THEN
512 CALL dbcsr_create(matrix_sign, template=matrix_s, matrix_type=dbcsr_type_no_symmetry)
514 IF (sign_symmetric)
THEN
516 IF (.NOT.
PRESENT(matrix_s_sqrt_inv)) &
517 cpabort(
"Argument matrix_s_sqrt_inv required if sign_symmetric is set")
519 CALL dbcsr_create(matrix_ssqrtinv_ks_ssqrtinv, template=matrix_s, matrix_type=dbcsr_type_no_symmetry)
520 CALL dbcsr_create(matrix_ssqrtinv_ks_ssqrtinv2, template=matrix_s, matrix_type=dbcsr_type_no_symmetry)
521 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_s_sqrt_inv, matrix_ks, &
522 0.0_dp, matrix_ssqrtinv_ks_ssqrtinv2, filter_eps=threshold)
523 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_ssqrtinv_ks_ssqrtinv2, matrix_s_sqrt_inv, &
524 0.0_dp, matrix_ssqrtinv_ks_ssqrtinv, filter_eps=threshold)
525 CALL dbcsr_add_on_diag(matrix_ssqrtinv_ks_ssqrtinv, -mu)
527 SELECT CASE (sign_method)
531 CALL matrix_sign_proot(matrix_sign, matrix_ssqrtinv_ks_ssqrtinv, threshold, sign_order)
533 CALL matrix_sign_submatrix(matrix_sign, matrix_ssqrtinv_ks_ssqrtinv, threshold, sign_order, submatrix_sign_method)
535 cpabort(
"Unkown sign method.")
537 CALL dbcsr_release(matrix_ssqrtinv_ks_ssqrtinv)
538 CALL dbcsr_release(matrix_ssqrtinv_ks_ssqrtinv2)
542 CALL dbcsr_create(matrix_sinv_ks, template=matrix_s, matrix_type=dbcsr_type_no_symmetry)
543 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_s_inv, matrix_ks, &
544 0.0_dp, matrix_sinv_ks, filter_eps=threshold)
545 CALL dbcsr_add_on_diag(matrix_sinv_ks, -mu)
548 SELECT CASE (sign_method)
554 CALL matrix_sign_submatrix(matrix_sign, matrix_sinv_ks, threshold, sign_order, submatrix_sign_method)
556 cpabort(
"Unkown sign method.")
558 CALL dbcsr_release(matrix_sinv_ks)
562 CALL dbcsr_create(matrix_p_ud, template=matrix_s, matrix_type=dbcsr_type_no_symmetry)
563 CALL dbcsr_copy(matrix_p_ud, matrix_sign)
564 CALL dbcsr_scale(matrix_p_ud, -0.5_dp)
565 CALL dbcsr_add_on_diag(matrix_p_ud, 0.5_dp)
566 CALL dbcsr_release(matrix_sign)
569 CALL dbcsr_trace(matrix_p_ud, trace)
572 CALL dbcsr_create(matrix_tmp, template=matrix_s, matrix_type=dbcsr_type_no_symmetry)
573 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_p_ud, matrix_p_ud, &
574 0.0_dp, matrix_tmp, filter_eps=threshold)
575 CALL dbcsr_add(matrix_tmp, matrix_p_ud, 1.0_dp, -1.0_dp)
576 frob_matrix = dbcsr_frobenius_norm(matrix_tmp)
577 IF (unit_nr > 0)
WRITE (unit_nr,
'(T2,A,F20.12)')
"Deviation from idempotency: ", frob_matrix
579 IF (sign_symmetric)
THEN
580 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_s_sqrt_inv, matrix_p_ud, &
581 0.0_dp, matrix_tmp, filter_eps=threshold)
582 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_tmp, matrix_s_sqrt_inv, &
583 0.0_dp, matrix_p, filter_eps=threshold)
587 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_p_ud, matrix_s_inv, &
588 0.0_dp, matrix_p, filter_eps=threshold)
590 CALL dbcsr_release(matrix_p_ud)
591 CALL dbcsr_release(matrix_tmp)
593 CALL timestop(handle)
613 SUBROUTINE density_matrix_sign_internal_mu(matrix_p, trace, mu, sign_method, matrix_ks, &
614 matrix_s, threshold, submatrix_sign_method, &
615 nelectron, matrix_s_sqrt_inv)
617 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_p
618 REAL(kind=
dp),
INTENT(OUT) :: trace
619 REAL(kind=
dp),
INTENT(INOUT) :: mu
620 INTEGER :: sign_method
621 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_ks, matrix_s
622 REAL(kind=
dp),
INTENT(IN) :: threshold
623 INTEGER :: submatrix_sign_method
624 INTEGER,
INTENT(IN) :: nelectron
625 TYPE(dbcsr_type),
INTENT(IN) :: matrix_s_sqrt_inv
627 CHARACTER(LEN=*),
PARAMETER :: routinen =
'density_matrix_sign_internal_mu'
629 INTEGER :: handle, unit_nr
630 REAL(kind=
dp) :: frob_matrix
631 TYPE(cp_logger_type),
POINTER :: logger
632 TYPE(dbcsr_type) :: matrix_p_ud, matrix_sign, &
633 matrix_ssqrtinv_ks_ssqrtinv, &
634 matrix_ssqrtinv_ks_ssqrtinv2, &
637 CALL timeset(routinen, handle)
640 IF (logger%para_env%is_source())
THEN
646 CALL dbcsr_create(matrix_sign, template=matrix_s, matrix_type=dbcsr_type_no_symmetry)
648 CALL dbcsr_create(matrix_ssqrtinv_ks_ssqrtinv, template=matrix_s, matrix_type=dbcsr_type_no_symmetry)
649 CALL dbcsr_create(matrix_ssqrtinv_ks_ssqrtinv2, template=matrix_s, matrix_type=dbcsr_type_no_symmetry)
650 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_s_sqrt_inv, matrix_ks, &
651 0.0_dp, matrix_ssqrtinv_ks_ssqrtinv2, filter_eps=threshold)
652 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_ssqrtinv_ks_ssqrtinv2, matrix_s_sqrt_inv, &
653 0.0_dp, matrix_ssqrtinv_ks_ssqrtinv, filter_eps=threshold)
654 CALL dbcsr_add_on_diag(matrix_ssqrtinv_ks_ssqrtinv, -mu)
656 SELECT CASE (sign_method)
658 SELECT CASE (submatrix_sign_method)
661 submatrix_sign_method)
663 cpabort(
"density_matrix_sign_internal_mu called with invalid submatrix sign method")
666 cpabort(
"density_matrix_sign_internal_mu called with invalid sign method.")
668 CALL dbcsr_release(matrix_ssqrtinv_ks_ssqrtinv)
669 CALL dbcsr_release(matrix_ssqrtinv_ks_ssqrtinv2)
672 CALL dbcsr_create(matrix_p_ud, template=matrix_s, matrix_type=dbcsr_type_no_symmetry)
673 CALL dbcsr_copy(matrix_p_ud, matrix_sign)
674 CALL dbcsr_scale(matrix_p_ud, -0.5_dp)
675 CALL dbcsr_add_on_diag(matrix_p_ud, 0.5_dp)
676 CALL dbcsr_release(matrix_sign)
679 CALL dbcsr_trace(matrix_p_ud, trace)
682 CALL dbcsr_create(matrix_tmp, template=matrix_s, matrix_type=dbcsr_type_no_symmetry)
683 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_p_ud, matrix_p_ud, &
684 0.0_dp, matrix_tmp, filter_eps=threshold)
685 CALL dbcsr_add(matrix_tmp, matrix_p_ud, 1.0_dp, -1.0_dp)
686 frob_matrix = dbcsr_frobenius_norm(matrix_tmp)
687 IF (unit_nr > 0)
WRITE (unit_nr,
'(T2,A,F20.12)')
"Deviation from idempotency: ", frob_matrix
689 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_s_sqrt_inv, matrix_p_ud, &
690 0.0_dp, matrix_tmp, filter_eps=threshold)
691 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_tmp, matrix_s_sqrt_inv, &
692 0.0_dp, matrix_p, filter_eps=threshold)
693 CALL dbcsr_release(matrix_p_ud)
694 CALL dbcsr_release(matrix_tmp)
696 CALL timestop(handle)
698 END SUBROUTINE density_matrix_sign_internal_mu
720 nelectron, threshold, e_homo, e_lumo, e_mu, &
721 dynamic_threshold, matrix_ks_deviation, &
722 max_iter_lanczos, eps_lanczos, converged)
724 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_p
725 TYPE(dbcsr_type),
INTENT(IN) :: matrix_ks, matrix_s_sqrt_inv
726 INTEGER,
INTENT(IN) :: nelectron
727 REAL(kind=
dp),
INTENT(IN) :: threshold
728 REAL(kind=
dp),
INTENT(INOUT) :: e_homo, e_lumo, e_mu
729 LOGICAL,
INTENT(IN),
OPTIONAL :: dynamic_threshold
730 TYPE(dbcsr_type),
INTENT(INOUT),
OPTIONAL :: matrix_ks_deviation
731 INTEGER,
INTENT(IN) :: max_iter_lanczos
732 REAL(kind=
dp),
INTENT(IN) :: eps_lanczos
733 LOGICAL,
INTENT(OUT),
OPTIONAL :: converged
735 CHARACTER(LEN=*),
PARAMETER :: routinen =
'density_matrix_trs4'
736 INTEGER,
PARAMETER :: max_iter = 100
737 REAL(kind=
dp),
PARAMETER :: gamma_max = 6.0_dp, gamma_min = 0.0_dp
739 INTEGER :: branch, estimated_steps, handle, i, j, &
741 INTEGER(kind=int_8) :: flop1, flop2
742 LOGICAL :: arnoldi_converged, do_dyn_threshold
743 REAL(kind=
dp) :: current_threshold, delta_n, eps_max, eps_min, est_threshold, frob_id, &
744 frob_x, gam, homo, lumo, max_eig, max_threshold, maxdev, maxev, min_eig, minev, mmin, mu, &
745 mu_a, mu_b, mu_c, mu_fa, mu_fc, occ_matrix, scaled_homo_bound, scaled_lumo_bound, t1, t2, &
746 trace_fx, trace_gx, xi
747 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: gamma_values
748 TYPE(cp_logger_type),
POINTER :: logger
749 TYPE(dbcsr_type) :: matrix_k0, matrix_x, matrix_x_nosym, &
750 matrix_xidsq, matrix_xsq, tmp_gx
752 IF (nelectron == 0)
THEN
753 CALL dbcsr_set(matrix_p, 0.0_dp)
757 CALL timeset(routinen, handle)
760 IF (logger%para_env%is_source())
THEN
766 do_dyn_threshold = .false.
767 IF (
PRESENT(dynamic_threshold)) do_dyn_threshold = dynamic_threshold
769 IF (
PRESENT(converged)) converged = .false.
772 CALL dbcsr_create(matrix_x, template=matrix_ks, matrix_type=
"S")
775 CALL dbcsr_create(matrix_x_nosym, template=matrix_ks, matrix_type=dbcsr_type_no_symmetry)
777 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_s_sqrt_inv, matrix_ks, &
778 0.0_dp, matrix_x_nosym, filter_eps=threshold)
779 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_x_nosym, matrix_s_sqrt_inv, &
780 0.0_dp, matrix_x, filter_eps=threshold)
781 CALL dbcsr_desymmetrize(matrix_x, matrix_x_nosym)
783 CALL dbcsr_create(matrix_k0, template=matrix_ks, matrix_type=dbcsr_type_no_symmetry)
784 CALL dbcsr_copy(matrix_k0, matrix_x_nosym)
787 IF (do_dyn_threshold)
THEN
788 cpassert(
PRESENT(matrix_ks_deviation))
789 CALL dbcsr_add(matrix_ks_deviation, matrix_x_nosym, -1.0_dp, 1.0_dp)
790 CALL arnoldi_extremal(matrix_ks_deviation, maxev, minev, max_iter=max_iter_lanczos, threshold=eps_lanczos, &
791 converged=arnoldi_converged)
792 maxdev = max(abs(maxev), abs(minev))
793 IF (unit_nr > 0)
THEN
794 WRITE (unit_nr,
'(T6,A,1X,L12)')
"Lanczos converged: ", arnoldi_converged
795 WRITE (unit_nr,
'(T6,A,1X,F12.5)')
"change in mixed matrix: ", maxdev
796 WRITE (unit_nr,
'(T6,A,1X,F12.5)')
"HOMO upper bound: ", e_homo + maxdev
797 WRITE (unit_nr,
'(T6,A,1X,F12.5)')
"LUMO lower bound: ", e_lumo - maxdev
798 WRITE (unit_nr,
'(T6,A,1X,L12)')
"Predicts a gap ? ", ((e_lumo - maxdev) - (e_homo + maxdev)) > 0
801 CALL dbcsr_copy(matrix_ks_deviation, matrix_x_nosym)
806 CALL arnoldi_extremal(matrix_x_nosym, max_eig, min_eig, max_iter=max_iter_lanczos, threshold=eps_lanczos, &
807 converged=arnoldi_converged)
808 IF (unit_nr > 0)
WRITE (unit_nr,
'(T6,A,1X,2F12.5,1X,A,1X,L1)')
"Est. extremal eigenvalues", &
809 min_eig, max_eig,
" converged: ", arnoldi_converged
814 IF (eps_max == eps_min)
THEN
815 CALL dbcsr_scale(matrix_x, 1.0_dp/eps_max)
817 CALL dbcsr_add_on_diag(matrix_x, -eps_max)
818 CALL dbcsr_scale(matrix_x, -1.0_dp/(eps_max - eps_min))
821 current_threshold = threshold
822 IF (do_dyn_threshold)
THEN
824 scaled_homo_bound = (eps_max - (e_homo + maxdev))/(eps_max - eps_min)
825 scaled_lumo_bound = (eps_max - (e_lumo - maxdev))/(eps_max - eps_min)
828 CALL dbcsr_create(matrix_xsq, template=matrix_ks, matrix_type=
"S")
830 CALL dbcsr_create(matrix_xidsq, template=matrix_ks, matrix_type=
"S")
832 CALL dbcsr_create(tmp_gx, template=matrix_ks, matrix_type=
"S")
834 ALLOCATE (gamma_values(max_iter))
841 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_x, matrix_x, &
842 0.0_dp, matrix_xsq, &
843 filter_eps=current_threshold, flop=flop1)
846 CALL dbcsr_copy(matrix_xidsq, matrix_x)
847 CALL dbcsr_add(matrix_xidsq, matrix_xsq, -1.0_dp, 1.0_dp)
848 frob_id = dbcsr_frobenius_norm(matrix_xidsq)
849 frob_x = dbcsr_frobenius_norm(matrix_x)
853 CALL dbcsr_copy(matrix_xidsq, matrix_x)
854 CALL dbcsr_add(matrix_xidsq, matrix_xsq, -2.0_dp, 1.0_dp)
855 CALL dbcsr_add_on_diag(matrix_xidsq, 1.0_dp)
858 CALL dbcsr_copy(tmp_gx, matrix_x)
859 CALL dbcsr_add(tmp_gx, matrix_xsq, 4.0_dp, -3.0_dp)
863 CALL dbcsr_dot(matrix_xsq, matrix_xidsq, trace_gx)
864 CALL dbcsr_dot(matrix_xsq, tmp_gx, trace_fx)
869 delta_n = nelectron - trace_fx
871 IF (((frob_id*frob_id) < (threshold*frob_x*frob_x)) .AND. (abs(delta_n) < 0.5_dp))
THEN
873 ELSE IF (abs(delta_n) < 1e-14_dp)
THEN
877 gam = delta_n/max(trace_gx, abs(delta_n)/100)
879 gamma_values(i) = gam
881 IF (unit_nr > 0 .AND. .false.)
THEN
882 WRITE (unit_nr, *)
"trace_fx", trace_fx,
"trace_gx", trace_gx,
"gam", gam, &
883 "frob_id", frob_id,
"conv", abs(frob_id/frob_x)
886 IF (do_dyn_threshold)
THEN
888 xi = (scaled_homo_bound - scaled_lumo_bound)
889 IF (xi > 0.0_dp)
THEN
890 mmin = 0.5*(scaled_homo_bound + scaled_lumo_bound)
891 max_threshold = abs(1 - 2*mmin)*xi
893 scaled_homo_bound = evaluate_trs4_polynomial(scaled_homo_bound, gamma_values(i:), 1)
894 scaled_lumo_bound = evaluate_trs4_polynomial(scaled_lumo_bound, gamma_values(i:), 1)
895 estimated_steps = estimate_steps(scaled_homo_bound, scaled_lumo_bound, threshold)
897 est_threshold = (threshold/(estimated_steps + i + 1))*xi/(1 + threshold/(estimated_steps + i + 1))
898 est_threshold = min(max_threshold, est_threshold)
899 IF (i > 1) est_threshold = max(est_threshold, 0.1_dp*current_threshold)
900 current_threshold = est_threshold
902 current_threshold = threshold
906 IF (gam > gamma_max)
THEN
908 CALL dbcsr_add(matrix_x, matrix_xsq, 2.0_dp, -1.0_dp)
909 CALL dbcsr_filter(matrix_x, current_threshold)
911 ELSE IF (gam < gamma_min)
THEN
913 CALL dbcsr_copy(matrix_x, matrix_xsq)
917 CALL dbcsr_add(tmp_gx, matrix_xidsq, 1.0_dp, gam)
918 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_xsq, tmp_gx, &
920 flop=flop2, filter_eps=current_threshold)
924 occ_matrix = dbcsr_get_occupation(matrix_x)
926 IF (unit_nr > 0)
THEN
928 '(T6,A,I3,1X,F10.8,E12.3,F12.3,F13.3,E12.3)')
"TRS4 it ", &
929 i, occ_matrix, abs(trace_gx), t2 - t1, &
930 (flop1 + flop2)/(1.0e6_dp*max(t2 - t1, 0.001_dp)), current_threshold
935 cpabort(
"trace_gx is an abnormal value (NaN/Inf).")
940 IF ((frob_id*frob_id) < (threshold*frob_x*frob_x) .AND. branch == 3 .AND. (abs(delta_n) < 0.5_dp))
THEN
941 IF (
PRESENT(converged)) converged = .true.
947 occ_matrix = dbcsr_get_occupation(matrix_x)
948 IF (unit_nr > 0)
WRITE (unit_nr,
'(T6,A,I3,1X,F10.8,E12.3)')
'Final TRS4 iteration ', i, occ_matrix, abs(trace_gx)
951 CALL dbcsr_release(tmp_gx)
952 CALL dbcsr_release(matrix_xsq)
953 CALL dbcsr_release(matrix_xidsq)
956 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_x, matrix_s_sqrt_inv, &
957 0.0_dp, matrix_x_nosym, filter_eps=threshold)
958 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_s_sqrt_inv, matrix_x_nosym, &
959 0.0_dp, matrix_p, filter_eps=threshold)
963 mu_a = 0.0_dp; mu_b = 1.0_dp;
964 mu_fa = evaluate_trs4_polynomial(mu_a, gamma_values, i - 1) - 0.5_dp
966 mu_c = 0.5*(mu_a + mu_b)
967 mu_fc = evaluate_trs4_polynomial(mu_c, gamma_values, i - 1) - 0.5_dp
968 IF (abs(mu_fc) < 1.0e-6_dp .OR. (mu_b - mu_a)/2 < 1.0e-6_dp)
EXIT
970 IF (mu_fc*mu_fa > 0)
THEN
977 mu = (eps_min - eps_max)*mu_c + eps_max
978 DEALLOCATE (gamma_values)
979 IF (unit_nr > 0)
THEN
980 WRITE (unit_nr,
'(T6,A,1X,F12.5)')
'Chemical potential (mu): ', mu
984 IF (do_dyn_threshold)
THEN
985 CALL dbcsr_desymmetrize(matrix_x, matrix_x_nosym)
987 threshold, max_iter_lanczos, eps_lanczos, homo, lumo, unit_nr)
992 CALL dbcsr_release(matrix_x)
993 CALL dbcsr_release(matrix_x_nosym)
994 CALL dbcsr_release(matrix_k0)
995 CALL timestop(handle)
1016 nelectron, threshold, e_homo, e_lumo, &
1017 non_monotonic, eps_lanczos, max_iter_lanczos)
1019 TYPE(dbcsr_type),
INTENT(INOUT) :: matrix_p
1020 TYPE(dbcsr_type),
INTENT(IN) :: matrix_ks, matrix_s_sqrt_inv
1021 INTEGER,
INTENT(IN) :: nelectron
1022 REAL(kind=
dp),
INTENT(IN) :: threshold
1023 REAL(kind=
dp),
INTENT(INOUT) :: e_homo, e_lumo
1024 LOGICAL,
INTENT(IN),
OPTIONAL :: non_monotonic
1025 REAL(kind=
dp),
INTENT(IN) :: eps_lanczos
1026 INTEGER,
INTENT(IN) :: max_iter_lanczos
1028 CHARACTER(LEN=*),
PARAMETER :: routinen =
'density_matrix_tc2'
1029 INTEGER,
PARAMETER :: max_iter = 100
1031 INTEGER :: handle, i, j, k, unit_nr
1032 INTEGER(kind=int_8) :: flop1, flop2
1033 LOGICAL :: converged, do_non_monotonic
1034 REAL(kind=
dp) :: beta, betab, eps_max, eps_min, gama, &
1035 max_eig, min_eig, occ_matrix, t1, t2, &
1037 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: alpha, lambda, nu, poly, wu, x, y
1038 TYPE(cp_logger_type),
POINTER :: logger
1039 TYPE(dbcsr_type) :: matrix_tmp, matrix_x, matrix_xsq
1041 CALL timeset(routinen, handle)
1044 IF (logger%para_env%is_source())
THEN
1050 do_non_monotonic = .false.
1051 IF (
PRESENT(non_monotonic)) do_non_monotonic = non_monotonic
1054 CALL dbcsr_create(matrix_x, template=matrix_ks, matrix_type=dbcsr_type_no_symmetry)
1055 CALL dbcsr_create(matrix_xsq, template=matrix_ks, matrix_type=dbcsr_type_no_symmetry)
1057 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_s_sqrt_inv, matrix_ks, &
1058 0.0_dp, matrix_xsq, filter_eps=threshold)
1059 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_xsq, matrix_s_sqrt_inv, &
1060 0.0_dp, matrix_x, filter_eps=threshold)
1062 IF (unit_nr > 0)
THEN
1063 WRITE (unit_nr,
'(T6,A,1X,F12.5)')
"HOMO upper bound: ", e_homo
1064 WRITE (unit_nr,
'(T6,A,1X,F12.5)')
"LUMO lower bound: ", e_lumo
1065 WRITE (unit_nr,
'(T6,A,1X,L12)')
"Predicts a gap ? ", ((e_lumo) - (e_homo)) > 0
1069 CALL arnoldi_extremal(matrix_x, max_eig, min_eig, max_iter=max_iter_lanczos, threshold=eps_lanczos, &
1070 converged=converged)
1071 IF (unit_nr > 0)
WRITE (unit_nr,
'(T6,A,1X,2F12.5,1X,A,1X,L1)')
"Est. extremal eigenvalues", &
1072 min_eig, max_eig,
" converged: ", converged
1078 CALL dbcsr_scale(matrix_x, -1.0_dp)
1079 CALL dbcsr_add_on_diag(matrix_x, eps_max)
1080 CALL dbcsr_scale(matrix_x, 1/(eps_max - eps_min))
1082 CALL dbcsr_copy(matrix_xsq, matrix_x)
1084 CALL dbcsr_create(matrix_tmp, template=matrix_ks, matrix_type=dbcsr_type_no_symmetry)
1086 ALLOCATE (poly(max_iter))
1087 ALLOCATE (nu(max_iter))
1088 ALLOCATE (wu(max_iter))
1089 ALLOCATE (alpha(max_iter))
1092 ALLOCATE (lambda(4))
1095 beta = (eps_max - abs(e_lumo))/(eps_max - eps_min)
1096 betab = (eps_max + abs(e_homo))/(eps_max - eps_min)
1098 IF ((beta - betab) < 0.005_dp)
THEN
1099 beta = beta - 0.002_dp
1100 betab = betab + 0.002_dp
1103 IF (.NOT. do_non_monotonic)
THEN
1108 IF (e_homo == 0.0_dp)
THEN
1114 trace_fx = nelectron
1119 flop1 = 0; flop2 = 0
1121 IF (abs(trace_fx - nelectron) <= abs(trace_gx - nelectron))
THEN
1124 alpha(i) = 2.0_dp/(2.0_dp - beta)
1126 CALL dbcsr_scale(matrix_x, alpha(i))
1127 CALL dbcsr_add_on_diag(matrix_x, 1.0_dp - alpha(i))
1128 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_x, matrix_x, &
1129 0.0_dp, matrix_xsq, &
1130 filter_eps=threshold, flop=flop1)
1133 CALL dbcsr_copy(matrix_tmp, matrix_x)
1135 CALL dbcsr_copy(matrix_x, matrix_xsq)
1137 beta = (1.0_dp - alpha(i)) + alpha(i)*beta
1139 betab = (1.0_dp - alpha(i)) + alpha(i)*betab
1144 alpha(i) = 2.0_dp/(1.0_dp + betab)
1146 CALL dbcsr_scale(matrix_x, alpha(i))
1147 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_x, matrix_x, &
1148 0.0_dp, matrix_xsq, &
1149 filter_eps=threshold, flop=flop1)
1152 CALL dbcsr_copy(matrix_tmp, matrix_x)
1154 CALL dbcsr_add(matrix_x, matrix_xsq, 2.0_dp, -1.0_dp)
1156 beta = alpha(i)*beta
1157 beta = 2.0_dp*beta - beta*beta
1158 betab = alpha(i)*betab
1159 betab = 2.0_dp*betab - betab*betab
1162 occ_matrix = dbcsr_get_occupation(matrix_x)
1164 IF (unit_nr > 0)
THEN
1166 '(T6,A,I3,1X,F10.8,E12.3,F12.3,F13.3,E12.3)')
"TC2 it ", &
1167 i, occ_matrix, t2 - t1, &
1168 (flop1 + flop2)/(1.0e6_dp*(t2 - t1)), threshold
1173 CALL dbcsr_trace(matrix_xsq, trace_fx)
1176 CALL dbcsr_add(matrix_xsq, matrix_tmp, -1.0_dp, 1.0_dp)
1177 CALL dbcsr_trace(matrix_xsq, trace_gx)
1178 nu(i) = dbcsr_frobenius_norm(matrix_xsq)
1182 CALL dbcsr_add(matrix_xsq, matrix_tmp, 1.0_dp, 1.0_dp)
1183 CALL dbcsr_trace(matrix_xsq, trace_gx)
1185 IF (abs(nu(i)) < (threshold))
EXIT
1188 occ_matrix = dbcsr_get_occupation(matrix_x)
1189 IF (unit_nr > 0)
WRITE (unit_nr,
'(T6,A,I3,1X,1F10.8,1X,1F10.8)')
'Final TC2 iteration ', i, occ_matrix, abs(nu(i))
1192 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_x, matrix_s_sqrt_inv, &
1193 0.0_dp, matrix_tmp, filter_eps=threshold)
1194 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_s_sqrt_inv, matrix_tmp, &
1195 0.0_dp, matrix_p, filter_eps=threshold)
1197 CALL dbcsr_release(matrix_xsq)
1198 CALL dbcsr_release(matrix_tmp)
1205 gama = 6.0_dp - 4.0_dp*(sqrt(2.0_dp))
1206 gama = gama - gama*gama
1207 DO WHILE (nu(i) < gama)
1209 IF (wu(i) < 1.0e-14_dp)
THEN
1213 IF ((1.0_dp - 4.0_dp*nu(i)*nu(i)/wu(i)) < 0.0_dp)
THEN
1217 y(1) = 0.5_dp*(1.0_dp - sqrt(1.0_dp - 4.0_dp*nu(i)*nu(i)/wu(i)))
1218 y(2) = 0.5_dp*(1.0_dp - sqrt(1.0_dp - 4.0_dp*nu(i)))
1219 y(3) = 0.5_dp*(1.0_dp + sqrt(1.0_dp - 4.0_dp*nu(i)))
1220 y(4) = 0.5_dp*(1.0_dp + sqrt(1.0_dp - 4.0_dp*nu(i)*nu(i)/wu(i)))
1221 y(:) = min(1.0_dp, max(0.0_dp, y(:)))
1223 IF (poly(j) == 1.0_dp)
THEN
1226 y(k) = (y(k) - 1.0_dp + alpha(j))/alpha(j)
1230 y(k) = 1.0_dp - sqrt(1.0_dp - y(k))
1231 y(k) = y(k)/alpha(j)
1235 x(1) = min(x(1), y(1))
1236 x(2) = min(x(2), y(2))
1237 x(3) = max(x(3), y(3))
1238 x(4) = max(x(4), y(4))
1243 lambda(k) = eps_max - (eps_max - eps_min)*x(k)
1248 IF (unit_nr > 0)
WRITE (unit_nr,
'(T6,A,3E12.4)')
"outer homo/lumo/gap", e_homo, e_lumo, (e_lumo - e_homo)
1249 IF (unit_nr > 0)
WRITE (unit_nr,
'(T6,A,3E12.4)')
"inner homo/lumo/gap", lambda(3), lambda(2), (lambda(2) - lambda(3))
1259 CALL dbcsr_release(matrix_x)
1260 CALL timestop(handle)
1281 SUBROUTINE compute_homo_lumo(matrix_k, matrix_p, eps_min, eps_max, threshold, max_iter_lanczos, eps_lanczos, homo, lumo, unit_nr)
1282 TYPE(dbcsr_type) :: matrix_k, matrix_p
1283 REAL(kind=
dp) :: eps_min, eps_max, threshold
1284 INTEGER,
INTENT(IN) :: max_iter_lanczos
1285 REAL(kind=
dp),
INTENT(IN) :: eps_lanczos
1286 REAL(kind=
dp) :: homo, lumo
1289 LOGICAL :: converged
1290 REAL(kind=
dp) :: max_eig, min_eig, shift1, shift2
1291 TYPE(dbcsr_type) :: tmp1, tmp2, tmp3
1295 CALL dbcsr_create(tmp1, template=matrix_k, matrix_type=dbcsr_type_no_symmetry)
1297 CALL dbcsr_create(tmp2, template=matrix_k, matrix_type=dbcsr_type_no_symmetry)
1299 CALL dbcsr_create(tmp3, template=matrix_k, matrix_type=dbcsr_type_no_symmetry)
1305 CALL dbcsr_copy(tmp2, matrix_k)
1306 CALL dbcsr_add_on_diag(tmp2, shift1)
1307 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_p, tmp2, &
1308 0.0_dp, tmp1, filter_eps=threshold)
1310 threshold=eps_lanczos, max_iter=max_iter_lanczos)
1311 homo = max_eig - shift1
1312 IF (unit_nr > 0)
THEN
1313 WRITE (unit_nr,
'(T6,A,1X,L12)')
"Lanczos converged: ", converged
1317 CALL dbcsr_copy(tmp3, matrix_p)
1318 CALL dbcsr_scale(tmp3, -1.0_dp)
1319 CALL dbcsr_add_on_diag(tmp3, 1.0_dp)
1320 CALL dbcsr_copy(tmp2, matrix_k)
1321 CALL dbcsr_add_on_diag(tmp2, -shift2)
1322 CALL dbcsr_multiply(
"N",
"N", -1.0_dp, tmp3, tmp2, &
1323 0.0_dp, tmp1, filter_eps=threshold)
1325 threshold=eps_lanczos, max_iter=max_iter_lanczos)
1326 lumo = -max_eig + shift2
1328 IF (unit_nr > 0)
THEN
1329 WRITE (unit_nr,
'(T6,A,1X,L12)')
"Lanczos converged: ", converged
1330 WRITE (unit_nr,
'(T6,A,1X,3F12.5)')
'HOMO/LUMO/gap', homo, lumo, lumo - homo
1332 CALL dbcsr_release(tmp1)
1333 CALL dbcsr_release(tmp2)
1334 CALL dbcsr_release(tmp3)
1345 FUNCTION evaluate_trs4_polynomial(x, gamma_values, i)
RESULT(xr)
1347 REAL(kind=
dp),
DIMENSION(:) :: gamma_values
1351 REAL(kind=
dp),
PARAMETER :: gam_max = 6.0_dp, gam_min = 0.0_dp
1357 IF (gamma_values(k) > gam_max)
THEN
1359 ELSE IF (gamma_values(k) < gam_min)
THEN
1362 xr = (xr*xr)*(4*xr - 3*xr*xr) + gamma_values(k)*xr*xr*((1 - xr)**2)
1365 END FUNCTION evaluate_trs4_polynomial
1374 FUNCTION estimate_steps(homo, lumo, threshold)
RESULT(steps)
1375 REAL(kind=
dp) :: homo, lumo, threshold
1379 REAL(kind=
dp) :: h, l, m
1385 IF (abs(l) < threshold .AND. abs(1 - h) < threshold)
EXIT
1387 IF (m > 0.5_dp)
THEN
1396 END FUNCTION estimate_steps
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...
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
lower level routines for linear scaling SCF
subroutine, public ls_scf_init_matrix_s(matrix_s, ls_scf_env)
initialize S matrix related properties (sqrt, inverse...) Might be factored-out since this seems comm...
subroutine, public density_matrix_sign_fixed_mu(matrix_p, trace, mu, sign_method, sign_order, matrix_ks, matrix_s, matrix_s_inv, threshold, sign_symmetric, submatrix_sign_method, matrix_s_sqrt_inv)
for a fixed mu, compute the corresponding density matrix and its trace
subroutine, public apply_matrix_preconditioner(matrix, direction, matrix_bs_sqrt, matrix_bs_sqrt_inv)
apply a preconditioner either forward (precondition) inv(sqrt(bs)) * A * inv(sqrt(bs)) backward (rest...
subroutine, public density_matrix_sign(matrix_p, mu, fixed_mu, sign_method, sign_order, matrix_ks, matrix_s, matrix_s_inv, nelectron, threshold, sign_symmetric, submatrix_sign_method, matrix_s_sqrt_inv)
compute the density matrix with a trace that is close to nelectron. take a mu as input,...
subroutine, public compute_matrix_preconditioner(matrix_s, preconditioner_type, ls_mstruct, matrix_bs_sqrt, matrix_bs_sqrt_inv, threshold, order, eps_lanczos, max_iter_lanczos)
compute for a block positive definite matrix s (bs) the sqrt(bs) and inv(sqrt(bs))
subroutine, public compute_homo_lumo(matrix_k, matrix_p, eps_min, eps_max, threshold, max_iter_lanczos, eps_lanczos, homo, lumo, unit_nr)
compute the homo and lumo given a KS matrix and a density matrix in the orthonormalized basis and the...
subroutine, public density_matrix_trs4(matrix_p, matrix_ks, matrix_s_sqrt_inv, nelectron, threshold, e_homo, e_lumo, e_mu, dynamic_threshold, matrix_ks_deviation, max_iter_lanczos, eps_lanczos, converged)
compute the density matrix using a trace-resetting algorithm
subroutine, public density_matrix_tc2(matrix_p, matrix_ks, matrix_s_sqrt_inv, nelectron, threshold, e_homo, e_lumo, non_monotonic, eps_lanczos, max_iter_lanczos)
compute the density matrix using a non monotonic trace conserving algorithm based on SIAM DOI....
Routines for a linear scaling quickstep SCF run based on the density matrix, with a focus on the inte...
subroutine, public matrix_qs_to_ls(matrix_ls, matrix_qs, ls_mstruct, covariant)
first link to QS, copy a QS matrix to LS matrix used to isolate QS style matrices from LS style will ...
Types needed for a linear scaling quickstep SCF run based on the density matrix.
Routines useful for iterative matrix calculations.
subroutine, public matrix_sqrt_newton_schulz(matrix_sqrt, matrix_sqrt_inv, matrix, threshold, order, eps_lanczos, max_iter_lanczos, symmetrize, converged)
compute the sqrt of a matrix via the sign function and the corresponding Newton-Schulz iterations the...
subroutine, public matrix_sign_submatrix(matrix_sign, matrix, threshold, sign_order, submatrix_sign_method)
Submatrix method.
subroutine, public matrix_sign_submatrix_mu_adjust(matrix_sign, matrix, mu, nelectron, threshold, variant)
Submatrix method with internal adjustment of chemical potential.
subroutine, public invert_hotelling(matrix_inverse, matrix, threshold, use_inv_as_guess, norm_convergence, filter_eps, accelerator_order, max_iter_lanczos, eps_lanczos, silent)
invert a symmetric positive definite matrix by Hotelling's method explicit symmetrization makes this ...
subroutine, public matrix_sign_proot(matrix_sign, matrix, threshold, sign_order)
compute the sign a matrix using the general algorithm for the p-th root of Richters et al....
subroutine, public matrix_sign_newton_schulz(matrix_sign, matrix, threshold, sign_order)
compute the sign a matrix using Newton-Schulz iterations
subroutine, public matrix_sqrt_proot(matrix_sqrt, matrix_sqrt_inv, matrix, threshold, order, eps_lanczos, max_iter_lanczos, symmetrize, converged)
compute the sqrt of a matrix via the general algorithm for the p-th root of Richters et al....
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Collection of simple mathematical functions and subroutines.
logical function, public abnormal_value(a)
determines if a value is not normal (e.g. for Inf and Nan) based on IO to work also under optimizatio...