21 USE dbcsr_api,
ONLY: &
22 dbcsr_add, dbcsr_copy, dbcsr_create, dbcsr_dot, dbcsr_filter, dbcsr_frobenius_norm, &
23 dbcsr_multiply, dbcsr_norm, dbcsr_release, dbcsr_scale, dbcsr_set, dbcsr_transposed, &
24 dbcsr_type, dbcsr_type_no_symmetry
34#include "./base/base_uses.f90"
40 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'dm_ls_scf_curvy'
58 REAL(kind=
dp) :: energy
61 CHARACTER(LEN=*),
PARAMETER :: routinen =
'dm_ls_curvy_optimization'
63 INTEGER :: handle, i, lsstep
65 CALL timeset(routinen, handle)
74 IF (.NOT.
ALLOCATED(ls_scf_env%curvy_data%matrix_dp))
THEN
75 CALL init_curvy(ls_scf_env%curvy_data, ls_scf_env%matrix_s, ls_scf_env%nspins)
76 ls_scf_env%curvy_data%line_search_step = 1
79 DO i = 1, ls_scf_env%nspins
80 CALL dbcsr_copy(ls_scf_env%curvy_data%matrix_psave(i, 1), &
81 ls_scf_env%matrix_p(i))
84 IF (ls_scf_env%nspins == 1)
CALL dbcsr_scale(ls_scf_env%matrix_p(1), 0.5_dp)
85 CALL transform_matrix_orth(ls_scf_env%matrix_p, ls_scf_env%matrix_s_sqrt, &
86 ls_scf_env%eps_filter)
88 DO i = 1, ls_scf_env%nspins
89 CALL dbcsr_copy(ls_scf_env%curvy_data%matrix_p(i), ls_scf_env%matrix_p(i))
93 lsstep = ls_scf_env%curvy_data%line_search_step
97 IF (ls_scf_env%curvy_data%line_search_step == 1) &
98 CALL transform_matrix_orth(ls_scf_env%matrix_ks, ls_scf_env%matrix_s_sqrt_inv, &
99 ls_scf_env%eps_filter)
102 ls_scf_env%curvy_data%energies(lsstep) = energy
103 IF (lsstep .NE. 1) energy = ls_scf_env%curvy_data%energies(1)
106 IF (lsstep .LE. 2)
THEN
107 CALL optimization_step(ls_scf_env%curvy_data, ls_scf_env)
108 ELSE IF (lsstep == ls_scf_env%curvy_data%line_search_type)
THEN
110 CALL optimization_step(ls_scf_env%curvy_data, ls_scf_env)
112 CALL new_p_from_save(ls_scf_env%matrix_p, ls_scf_env%curvy_data%matrix_psave, lsstep, &
113 ls_scf_env%curvy_data%double_step_size)
114 ls_scf_env%curvy_data%line_search_step = ls_scf_env%curvy_data%line_search_step + 1
115 CALL timestop(handle)
118 lsstep = ls_scf_env%curvy_data%line_search_step
122 CALL transform_matrix_orth(ls_scf_env%matrix_p, ls_scf_env%matrix_s_sqrt_inv, &
123 ls_scf_env%eps_filter)
124 IF (ls_scf_env%nspins == 1)
CALL dbcsr_scale(ls_scf_env%matrix_p(1), 2.0_dp)
128 DO i = 1, ls_scf_env%nspins
129 CALL dbcsr_copy(ls_scf_env%curvy_data%matrix_psave(i, lsstep), &
130 ls_scf_env%matrix_p(i))
133 check_conv = lsstep == 1
135 CALL timestop(handle)
150 SUBROUTINE optimization_step(curvy_data, ls_scf_env)
154 CHARACTER(LEN=*),
PARAMETER :: routinen =
'optimization_step'
156 INTEGER :: handle, ispin
157 REAL(kind=
dp) :: filter, step_size(2)
161 CALL timeset(routinen, handle)
163 IF (curvy_data%line_search_step == 1)
THEN
164 curvy_data%step_size = maxval(curvy_data%step_size)
165 curvy_data%step_size = min(max(0.10_dp, 0.5_dp*abs(curvy_data%step_size(1))), 0.5_dp)
167 filter = max(ls_scf_env%eps_filter*curvy_data%min_filter, &
168 ls_scf_env%eps_filter*curvy_data%filter_factor)
169 CALL compute_direction_newton(curvy_data%matrix_p, ls_scf_env%matrix_ks, &
170 curvy_data%matrix_dp, filter, curvy_data%fix_shift, curvy_data%shift, &
171 curvy_data%cg_numer, curvy_data%cg_denom, curvy_data%min_shift)
172 curvy_data%filter_factor = curvy_data%scale_filter*curvy_data%filter_factor
173 step_size = curvy_data%step_size
174 curvy_data%BCH_saved = 0
175 ELSE IF (curvy_data%line_search_step == 2)
THEN
176 step_size = curvy_data%step_size
177 IF (curvy_data%energies(1) - curvy_data%energies(2) .GT. 0.0_dp)
THEN
178 curvy_data%step_size = curvy_data%step_size*2.0_dp
179 curvy_data%double_step_size = .true.
181 curvy_data%step_size = curvy_data%step_size*0.5_dp
182 curvy_data%double_step_size = .false.
184 step_size = curvy_data%step_size
186 CALL line_search_2d(curvy_data%energies, curvy_data%step_size)
187 step_size = curvy_data%step_size
189 CALL line_search_3pnt(curvy_data%energies, curvy_data%step_size)
190 step_size = curvy_data%step_size
193 CALL update_p_exp(curvy_data%matrix_p, ls_scf_env%matrix_p, curvy_data%matrix_dp, &
194 curvy_data%matrix_BCH, ls_scf_env%eps_filter, step_size, curvy_data%BCH_saved, &
195 curvy_data%n_bch_hist)
198 curvy_data%line_search_step = mod(curvy_data%line_search_step, curvy_data%line_search_type) + 1
199 IF (curvy_data%line_search_step == 1)
THEN
200 DO ispin = 1,
SIZE(curvy_data%matrix_p)
201 CALL dbcsr_copy(curvy_data%matrix_p(ispin), ls_scf_env%matrix_p(ispin))
204 CALL timestop(handle)
206 END SUBROUTINE optimization_step
218 SUBROUTINE line_search_2d(energies, step_size)
219 REAL(kind=
dp) :: energies(6), step_size(2)
221 INTEGER :: info, unit_nr
222 REAL(kind=
dp) :: e_pred, param(6), s1, s1sq, s2, s2sq, &
223 sys_lin_eq(6, 6), tmp_e, v1, v2
227 IF (energies(1) - energies(2) .LT. 0._dp)
THEN
228 tmp_e = energies(2); energies(2) = energies(3); energies(3) = tmp_e
229 step_size = step_size*2.0_dp
231 IF (logger%para_env%is_source())
THEN
236 s1 = 0.5_dp*step_size(1); s2 = step_size(1); s1sq = s1**2; s2sq = s2**2
237 sys_lin_eq = 0.0_dp; sys_lin_eq(:, 6) = 1.0_dp
238 sys_lin_eq(2, 1) = s1sq; sys_lin_eq(2, 2) = s1sq; sys_lin_eq(2, 3) = s1sq; sys_lin_eq(2, 4) = s1; sys_lin_eq(2, 5) = s1
239 sys_lin_eq(3, 1) = s2sq; sys_lin_eq(3, 2) = s2sq; sys_lin_eq(3, 3) = s2sq; sys_lin_eq(3, 4) = s2; sys_lin_eq(3, 5) = s2
240 sys_lin_eq(4, 3) = s1sq; sys_lin_eq(4, 5) = s1
241 sys_lin_eq(5, 1) = s1sq; sys_lin_eq(5, 4) = s1
242 sys_lin_eq(6, 3) = s2sq; sys_lin_eq(6, 5) = s2
244 CALL invmat(sys_lin_eq, info)
245 param = matmul(sys_lin_eq, energies)
246 v1 = (param(2)*param(4))/(2.0_dp*param(1)) - param(5)
247 v2 = -(param(2)**2)/(2.0_dp*param(1)) + 2.0_dp*param(3)
249 step_size(1) = (-param(2)*step_size(2) - param(4))/(2.0_dp*param(1))
250 IF (step_size(1) .LT. 0.0_dp) step_size(1) = 1.0_dp
251 IF (step_size(2) .LT. 0.0_dp) step_size(2) = 1.0_dp
254 e_pred = param(1)*step_size(1)**2 + param(2)*step_size(1)*step_size(2) + &
255 param(3)*step_size(2)**2 + param(4)*step_size(1) + param(5)*step_size(2) + param(6)
256 IF (unit_nr .GT. 0)
WRITE (unit_nr,
"(t3,a,F10.5,F10.5,A,F20.9)") &
257 " Line Search: Step Size", step_size,
" Predicted energy", e_pred
258 e_pred = param(1)*s1**2 + param(2)*s2*s1*0.0_dp + &
259 param(3)*s1**2*0.0_dp + param(4)*s1 + param(5)*s1*0.0_dp + param(6)
261 END SUBROUTINE line_search_2d
272 SUBROUTINE line_search_3pnt(energies, step_size)
273 REAL(kind=
dp) :: energies(3), step_size(2)
276 REAL(kind=
dp) :: a, b, c, e_pred, min_val, step1, tmp, &
281 IF (energies(1) - energies(2) .LT. 0._dp)
THEN
282 tmp_e = energies(2); energies(2) = energies(3); energies(3) = tmp_e
283 step_size = step_size*2.0_dp
285 IF (logger%para_env%is_source())
THEN
290 step1 = 0.5_dp*step_size(1)
292 a = (energies(3) + c - 2.0_dp*energies(2))/(2.0_dp*step1**2)
293 b = (energies(2) - c - a*step1**2)/step1
294 IF (a .LT. 1.0e-12_dp) a = -1.0e-12_dp
295 min_val = -b/(2.0_dp*a)
296 e_pred = a*min_val**2 + b*min_val + c
298 IF (e_pred .LT. energies(1) .AND. e_pred .LT. energies(2))
THEN
299 step_size = max(-1.0_dp, &
300 min(min_val, 10_dp*step_size))
304 e_pred = a*(step_size(1))**2 + b*(step_size(1)) + c
305 IF (unit_nr .GT. 0)
THEN
306 WRITE (unit_nr,
"(t3,a,f16.8,a,F20.9)")
"Line Search: Step Size", step_size(1),
" Predicted energy", e_pred
309 END SUBROUTINE line_search_3pnt
328 SUBROUTINE compute_direction_newton(matrix_p, matrix_ks, matrix_dp, eps_filter, fix_shift, &
329 curvy_shift, cg_numer, cg_denom, min_shift)
330 TYPE(dbcsr_type),
DIMENSION(:) :: matrix_p, matrix_ks, matrix_dp
331 REAL(kind=
dp) :: eps_filter
332 LOGICAL :: fix_shift(2)
333 REAL(kind=
dp) :: curvy_shift(2), cg_numer(2), &
334 cg_denom(2), min_shift
336 CHARACTER(LEN=*),
PARAMETER :: routinen =
'compute_direction_newton'
338 INTEGER :: handle, i, ispin, ncyc, nspin, unit_nr
340 REAL(kind=
dp) :: beta, conv_val, maxel, old_conv, shift
342 TYPE(dbcsr_type) :: matrix_ax, matrix_b, matrix_cg, &
343 matrix_dp_old, matrix_pks, matrix_res, &
344 matrix_tmp, matrix_tmp1
348 IF (logger%para_env%is_source())
THEN
353 CALL timeset(routinen, handle)
354 nspin =
SIZE(matrix_p)
356 CALL dbcsr_create(matrix_pks, template=matrix_dp(1), matrix_type=dbcsr_type_no_symmetry)
357 CALL dbcsr_create(matrix_ax, template=matrix_dp(1), matrix_type=dbcsr_type_no_symmetry)
358 CALL dbcsr_create(matrix_tmp, template=matrix_dp(1), matrix_type=dbcsr_type_no_symmetry)
359 CALL dbcsr_create(matrix_tmp1, template=matrix_dp(1), matrix_type=dbcsr_type_no_symmetry)
360 CALL dbcsr_create(matrix_res, template=matrix_dp(1), matrix_type=dbcsr_type_no_symmetry)
361 CALL dbcsr_create(matrix_cg, template=matrix_dp(1), matrix_type=dbcsr_type_no_symmetry)
362 CALL dbcsr_create(matrix_b, template=matrix_dp(1), matrix_type=dbcsr_type_no_symmetry)
363 CALL dbcsr_create(matrix_dp_old, template=matrix_dp(1), matrix_type=dbcsr_type_no_symmetry)
366 CALL dbcsr_copy(matrix_dp_old, matrix_dp(ispin))
369 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_p(ispin), matrix_ks(ispin), &
370 0.0_dp, matrix_pks, filter_eps=eps_filter)
371 CALL dbcsr_transposed(matrix_b, matrix_pks)
372 CALL dbcsr_copy(matrix_cg, matrix_b)
375 CALL dbcsr_add(matrix_cg, matrix_pks, 2.0_dp, -2.0_dp)
378 CALL dbcsr_copy(matrix_res, matrix_cg)
381 CALL dbcsr_add(matrix_b, matrix_pks, -1.0_dp, -1.0_dp)
384 CALL dbcsr_norm(matrix_res, which_norm=2, norm_scalar=old_conv)
385 old_conv = dbcsr_frobenius_norm(matrix_res)
386 shift = min(10.0_dp, max(min_shift, 0.05_dp*old_conv))
387 conv_val = max(0.010_dp*old_conv, 100.0_dp*eps_filter)
389 IF (fix_shift(ispin))
THEN
390 shift = max(min_shift, min(10.0_dp, max(shift, curvy_shift(ispin) - 0.5_dp*curvy_shift(ispin))))
391 curvy_shift(ispin) = shift
395 CALL dbcsr_set(matrix_dp(ispin), 0.0_dp)
400 CALL commutator_symm(matrix_b, matrix_cg, matrix_ax, eps_filter, 1.0_dp)
403 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_cg, matrix_p(ispin), &
404 0.0_dp, matrix_tmp, filter_eps=eps_filter)
405 CALL commutator_symm(matrix_ks(ispin), matrix_tmp, matrix_tmp1, eps_filter, 2.0_dp)
406 CALL dbcsr_add(matrix_ax, matrix_tmp1, 1.0_dp, 1.0_dp)
409 CALL dbcsr_add(matrix_ax, matrix_cg, 1.0_dp, shift)
411 CALL compute_cg_matrices(matrix_ax, matrix_res, matrix_cg, matrix_dp(ispin), &
412 matrix_tmp, eps_filter, at_limit)
413 CALL dbcsr_filter(matrix_cg, eps_filter)
416 maxel = dbcsr_frobenius_norm(matrix_res)
417 IF (unit_nr .GT. 0)
THEN
418 WRITE (unit_nr,
"(T3,A,F12.6)")
"Convergence of Newton iteration ", maxel
421 at_limit = at_limit .OR. (old_conv/maxel .LT. 1.01_dp)
423 IF (i == ncyc .AND. maxel/conv_val .GT. 5.0_dp)
THEN
424 fix_shift(ispin) = .true.
425 curvy_shift(ispin) = 4.0_dp*shift
427 IF (maxel .LT. conv_val .OR. at_limit)
EXIT
431 CALL dbcsr_transposed(matrix_b, matrix_pks)
433 CALL dbcsr_copy(matrix_cg, matrix_b)
434 CALL dbcsr_add(matrix_cg, matrix_pks, 1.0_dp, -1.0_dp)
435 cg_denom(ispin) = cg_numer(ispin)
436 CALL dbcsr_dot(matrix_cg, matrix_dp(ispin), cg_numer(ispin))
437 beta = cg_numer(ispin)/max(cg_denom(ispin), 1.0e-6_dp)
438 IF (beta .LT. 1.0_dp)
THEN
439 beta = max(0.0_dp, beta)
440 CALL dbcsr_add(matrix_dp(ispin), matrix_dp_old, 1.0_dp, beta)
442 IF (unit_nr .GT. 0)
WRITE (unit_nr,
"(A)")
" "
445 CALL dbcsr_release(matrix_pks)
446 CALL dbcsr_release(matrix_dp_old)
447 CALL dbcsr_release(matrix_b)
448 CALL dbcsr_release(matrix_ax)
449 CALL dbcsr_release(matrix_tmp)
450 CALL dbcsr_release(matrix_tmp1)
451 CALL dbcsr_release(matrix_b)
452 CALL dbcsr_release(matrix_res)
453 CALL dbcsr_release(matrix_cg)
455 IF (unit_nr .GT. 0)
CALL m_flush(unit_nr)
456 CALL timestop(handle)
457 END SUBROUTINE compute_direction_newton
474 SUBROUTINE compute_cg_matrices(Ax, res, cg, deltp, tmp, eps_filter, at_limit)
475 TYPE(dbcsr_type) :: ax, res, cg, deltp, tmp
476 REAL(kind=
dp) :: eps_filter
480 REAL(kind=
dp) :: alpha, beta, devi(3),
fac, fac1, &
481 lin_eq(3, 3), new_norm, norm_ca, &
485 CALL dbcsr_dot(res, res, norm_rr)
486 CALL dbcsr_dot(cg, ax, norm_ca)
488 fac = norm_rr/norm_ca
492 CALL dbcsr_copy(tmp, res)
493 CALL dbcsr_add(tmp, ax, 1.0_dp, -
fac)
494 devi(i) = dbcsr_frobenius_norm(tmp)
495 lin_eq(i, :) = (/
fac**2,
fac, 1.0_dp/)
496 fac = fac1 + fac1*((-1)**i)*0.5_dp
499 vec = matmul(lin_eq, devi)
500 alpha = -vec(2)/(2.0_dp*vec(1))
501 fac = sqrt(norm_rr/(norm_ca*alpha))
503 CALL dbcsr_scale(ax,
fac)
504 CALL dbcsr_scale(cg,
fac)
505 norm_ca = norm_ca*
fac**2
508 alpha = norm_rr/norm_ca
509 CALL dbcsr_add(res, ax, 1.0_dp, -alpha)
510 CALL dbcsr_dot(res, res, new_norm)
511 IF (norm_rr .LT. eps_filter*0.001_dp .OR. new_norm .LT. eps_filter*0.001_dp)
THEN
515 beta = new_norm/norm_rr
516 CALL dbcsr_add(deltp, cg, 1.0_dp, alpha)
518 beta = new_norm/norm_rr
519 CALL dbcsr_add(cg, res, beta, 1.0_dp)
521 END SUBROUTINE compute_cg_matrices
536 SUBROUTINE new_p_from_save(matrix_p, matrix_psave, lsstep, DOUBLE)
537 TYPE(dbcsr_type),
DIMENSION(:) :: matrix_p
538 TYPE(dbcsr_type),
DIMENSION(:, :) :: matrix_psave
544 CALL dbcsr_copy(matrix_p(1), matrix_psave(1, 1))
546 CALL dbcsr_copy(matrix_p(2), matrix_psave(2, 2))
548 CALL dbcsr_copy(matrix_p(2), matrix_psave(2, 3))
552 CALL dbcsr_copy(matrix_p(1), matrix_psave(1, 2))
554 CALL dbcsr_copy(matrix_p(1), matrix_psave(1, 3))
556 CALL dbcsr_copy(matrix_p(2), matrix_psave(2, 1))
558 CALL dbcsr_copy(matrix_p(1), matrix_psave(1, 1))
560 CALL dbcsr_copy(matrix_p(2), matrix_psave(2, 3))
562 CALL dbcsr_copy(matrix_p(2), matrix_psave(2, 2))
566 END SUBROUTINE new_p_from_save
580 SUBROUTINE commutator_symm(a, b, res, eps_filter, prefac)
581 TYPE(dbcsr_type) :: a, b, res
582 REAL(kind=
dp) :: eps_filter, prefac
584 CHARACTER(LEN=*),
PARAMETER :: routinen =
'commutator_symm'
587 TYPE(dbcsr_type) :: work
589 CALL timeset(routinen, handle)
591 CALL dbcsr_create(work, template=a, matrix_type=dbcsr_type_no_symmetry)
593 CALL dbcsr_multiply(
"N",
"N", prefac, a, b, 0.0_dp, res, filter_eps=eps_filter)
594 CALL dbcsr_transposed(work, res)
595 CALL dbcsr_add(res, work, 1.0_dp, -1.0_dp)
597 CALL dbcsr_release(work)
599 CALL timestop(handle)
600 END SUBROUTINE commutator_symm
619 SUBROUTINE update_p_exp(matrix_p_in, matrix_p_out, matrix_dp, matrix_BCH, threshold, step_size, &
620 BCH_saved, n_bch_hist)
621 TYPE(dbcsr_type),
DIMENSION(:) :: matrix_p_in, matrix_p_out, matrix_dp
622 TYPE(dbcsr_type),
DIMENSION(:, :) :: matrix_bch
623 REAL(kind=
dp) :: threshold, step_size(2)
624 INTEGER :: bch_saved(2), n_bch_hist
626 CHARACTER(LEN=*),
PARAMETER :: routinen =
'update_p_exp'
628 INTEGER :: handle, i, ispin, nsave, nspin, unit_nr
630 REAL(kind=
dp) :: frob_norm, step_fac
632 TYPE(dbcsr_type) :: matrix, matrix_tmp
634 CALL timeset(routinen, handle)
637 IF (logger%para_env%is_source())
THEN
643 CALL dbcsr_create(matrix, template=matrix_p_in(1), matrix_type=dbcsr_type_no_symmetry)
644 CALL dbcsr_create(matrix_tmp, template=matrix_p_in(1), matrix_type=dbcsr_type_no_symmetry)
645 nspin =
SIZE(matrix_p_in)
652 CALL dbcsr_copy(matrix_tmp, matrix_p_in(ispin))
653 CALL dbcsr_copy(matrix_p_out(ispin), matrix_p_in(ispin))
656 DO i = 1, bch_saved(ispin)
657 step_fac = step_fac*step_size(ispin)
658 CALL dbcsr_copy(matrix_tmp, matrix_p_out(ispin))
659 CALL dbcsr_add(matrix_p_out(ispin), matrix_bch(ispin, i), 1.0_dp,
ifac(i)*step_fac)
660 CALL dbcsr_add(matrix_tmp, matrix_p_out(ispin), 1.0_dp, -1.0_dp)
661 frob_norm = dbcsr_frobenius_norm(matrix_tmp)
662 IF (unit_nr .GT. 0)
WRITE (unit_nr,
"(t3,a,i3,a,f16.8)")
"BCH: step", i,
" Norm of P_old-Pnew:", frob_norm
663 IF (frob_norm .LT. threshold)
EXIT
665 IF (frob_norm .LT. threshold) cycle
668 save_bch = bch_saved(ispin) == 0 .AND. n_bch_hist .GT. 0
669 DO i = bch_saved(ispin) + 1, 20
670 step_fac = step_fac*step_size(ispin)
673 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_tmp, matrix_dp(ispin), &
674 0.0_dp, matrix, filter_eps=threshold)
678 CALL dbcsr_transposed(matrix_tmp, matrix)
679 CALL dbcsr_add(matrix, matrix_tmp, 1.0_dp, 1.0_dp)
682 CALL dbcsr_copy(matrix_tmp, matrix_p_out(ispin))
683 CALL dbcsr_add(matrix_p_out(ispin), matrix, 1.0_dp,
ifac(i)*step_fac)
684 IF (save_bch .AND. i .LE. n_bch_hist)
THEN
685 CALL dbcsr_copy(matrix_bch(ispin, i), matrix)
689 CALL dbcsr_add(matrix_tmp, matrix_p_out(ispin), 1.0_dp, -1.0_dp)
692 frob_norm = dbcsr_frobenius_norm(matrix_tmp)
693 IF (unit_nr .GT. 0)
WRITE (unit_nr,
"(t3,a,i3,a,f16.8)")
"BCH: step", i,
" Norm of P_old-Pnew:", frob_norm
694 IF (frob_norm .LT. threshold)
EXIT
697 CALL dbcsr_copy(matrix_tmp, matrix)
698 CALL dbcsr_filter(matrix_tmp, threshold)
700 bch_saved(ispin) = nsave
701 IF (unit_nr .GT. 0)
WRITE (unit_nr,
"(A)")
" "
705 IF (unit_nr .GT. 0)
CALL m_flush(unit_nr)
706 CALL dbcsr_release(matrix_tmp)
707 CALL dbcsr_release(matrix)
708 CALL timestop(handle)
709 END SUBROUTINE update_p_exp
722 SUBROUTINE transform_matrix_orth(matrix, matrix_trafo, eps_filter)
723 TYPE(dbcsr_type),
DIMENSION(:) :: matrix
724 TYPE(dbcsr_type) :: matrix_trafo
725 REAL(kind=
dp) :: eps_filter
727 CHARACTER(LEN=*),
PARAMETER :: routinen =
'transform_matrix_orth'
729 INTEGER :: handle, ispin
730 TYPE(dbcsr_type) :: matrix_tmp, matrix_work
732 CALL timeset(routinen, handle)
734 CALL dbcsr_create(matrix_work, template=matrix(1), matrix_type=dbcsr_type_no_symmetry)
735 CALL dbcsr_create(matrix_tmp, template=matrix(1), matrix_type=dbcsr_type_no_symmetry)
737 DO ispin = 1,
SIZE(matrix)
738 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix(ispin), matrix_trafo, &
739 0.0_dp, matrix_work, filter_eps=eps_filter)
740 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, matrix_trafo, matrix_work, &
741 0.0_dp, matrix_tmp, filter_eps=eps_filter)
743 CALL dbcsr_transposed(matrix_work, matrix_tmp)
744 CALL dbcsr_add(matrix_tmp, matrix_work, 0.5_dp, 0.5_dp)
745 CALL dbcsr_copy(matrix(ispin), matrix_tmp)
748 CALL dbcsr_release(matrix_tmp)
749 CALL dbcsr_release(matrix_work)
750 CALL timestop(handle)
763 CALL release_dbcsr_array(curvy_data%matrix_dp)
764 CALL release_dbcsr_array(curvy_data%matrix_p)
766 IF (
ALLOCATED(curvy_data%matrix_psave))
THEN
767 DO i = 1,
SIZE(curvy_data%matrix_psave, 1)
769 CALL dbcsr_release(curvy_data%matrix_psave(i, j))
772 DEALLOCATE (curvy_data%matrix_psave)
774 IF (
ALLOCATED(curvy_data%matrix_BCH))
THEN
775 DO i = 1,
SIZE(curvy_data%matrix_BCH, 1)
777 CALL dbcsr_release(curvy_data%matrix_BCH(i, j))
780 DEALLOCATE (curvy_data%matrix_BCH)
788 SUBROUTINE release_dbcsr_array(matrix)
789 TYPE(dbcsr_type),
ALLOCATABLE,
DIMENSION(:) :: matrix
793 IF (
ALLOCATED(matrix))
THEN
794 DO i = 1,
SIZE(matrix)
795 CALL dbcsr_release(matrix(i))
799 END SUBROUTINE release_dbcsr_array
807 SUBROUTINE init_curvy(curvy_data, matrix_s, nspins)
809 TYPE(dbcsr_type) :: matrix_s
814 ALLOCATE (curvy_data%matrix_dp(nspins))
815 ALLOCATE (curvy_data%matrix_p(nspins))
817 CALL dbcsr_create(curvy_data%matrix_dp(ispin), template=matrix_s, &
818 matrix_type=dbcsr_type_no_symmetry)
819 CALL dbcsr_set(curvy_data%matrix_dp(ispin), 0.0_dp)
820 CALL dbcsr_create(curvy_data%matrix_p(ispin), template=matrix_s, &
821 matrix_type=dbcsr_type_no_symmetry)
822 curvy_data%fix_shift = .false.
823 curvy_data%double_step_size = .true.
824 curvy_data%shift = 1.0_dp
825 curvy_data%BCH_saved = 0
826 curvy_data%step_size = 0.60_dp
827 curvy_data%cg_numer = 0.00_dp
828 curvy_data%cg_denom = 0.00_dp
831 ALLOCATE (curvy_data%matrix_psave(nspins, 3))
834 CALL dbcsr_create(curvy_data%matrix_psave(ispin, j), template=matrix_s, &
835 matrix_type=dbcsr_type_no_symmetry)
839 IF (curvy_data%n_bch_hist .GT. 0)
THEN
840 ALLOCATE (curvy_data%matrix_BCH(nspins, curvy_data%n_bch_hist))
842 DO j = 1, curvy_data%n_bch_hist
843 CALL dbcsr_create(curvy_data%matrix_BCH(ispin, j), template=matrix_s, &
844 matrix_type=dbcsr_type_no_symmetry)
849 END SUBROUTINE init_curvy
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public shao2003
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
density matrix optimization using exponential transformations
subroutine, public dm_ls_curvy_optimization(ls_scf_env, energy, check_conv)
driver routine for Head-Gordon curvy step approach
subroutine, public deallocate_curvy_data(curvy_data)
...
Types needed for a linear scaling quickstep SCF run based on the density matrix.
Routines useful for iterative matrix calculations.
Defines the basic variable types.
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
Definition of mathematical constants and functions.
real(kind=dp), dimension(0:maxfac), parameter, public ifac
real(kind=dp), dimension(0:maxfac), parameter, public fac
Collection of simple mathematical functions and subroutines.
subroutine, public invmat(a, info)
returns inverse of matrix using the lapack routines DGETRF and DGETRI
type of a logger, at the moment it contains just a print level starting at which level it should be l...