29 USE ieee_arithmetic,
ONLY: ieee_is_finite
41#include "./base/base_uses.f90"
63 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_ot_minimizer'
75 non_descent, forget_history, do_ener)
76 LOGICAL,
INTENT(IN) :: non_descent, forget_history, do_ener
94 occupation_preconditioned, current_energy, reference_energy)
95 LOGICAL,
INTENT(IN) :: occupation_preconditioned
96 REAL(kind=
dp),
INTENT(IN) :: current_energy, reference_energy
98 REAL(kind=
dp) :: energy_scale
100 energy_scale = max(1.0_dp, abs(current_energy), abs(reference_energy))
102 abs(current_energy - reference_energy) <= &
103 64.0_dp*epsilon(1.0_dp)*energy_scale
130 SUBROUTINE ot_mini(qs_ot_env, matrix_hc, matrix_hc_im, &
131 matrix_hc_physical, matrix_hc_physical_im, para_env_inter_kp, &
132 gradient_only, gradient_prepared)
133 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
136 POINTER :: matrix_hc_im, matrix_hc_physical, &
137 matrix_hc_physical_im
139 LOGICAL,
INTENT(IN),
OPTIONAL :: gradient_only, gradient_prepared
141 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_mini'
143 INTEGER :: handle, ispin, nspin
144 LOGICAL :: do_ener, do_ks, evaluate_gradient_only, &
146 separate_occupation_gradient
149 CALL timeset(routinen, handle)
151 evaluate_gradient_only = .false.
152 reuse_gradient = .false.
153 IF (
PRESENT(gradient_only)) evaluate_gradient_only = gradient_only
154 IF (
PRESENT(gradient_prepared)) reuse_gradient = gradient_prepared
155 cpassert(.NOT. (evaluate_gradient_only .AND. reuse_gradient))
157 nspin =
SIZE(qs_ot_env)
159 do_ks = qs_ot_env(1)%settings%ks
160 do_ener = qs_ot_env(1)%settings%do_ener
161 separate_occupation_gradient =
PRESENT(matrix_hc_physical)
162 IF (separate_occupation_gradient)
THEN
163 cpassert(qs_ot_env(1)%settings%occupation_preconditioner)
164 cpassert(
SIZE(matrix_hc_physical) == nspin)
167 qs_ot_env(1)%OT_METHOD_FULL =
""
170 IF (.NOT. reuse_gradient .AND. .NOT. qs_ot_env(1)%energy_only)
THEN
171 qs_ot_env(1)%gradient = 0.0_dp
174 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
175 IF (.NOT.
PRESENT(matrix_hc_im))
THEN
176 cpabort(
"Complex k-point OT derivative requires imaginary H(k)*C(k).")
178 SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
180 IF (separate_occupation_gradient)
THEN
181 cpassert(
PRESENT(matrix_hc_physical_im))
183 matrix_hc_im(ispin)%matrix, &
185 matrix_hc_physical(ispin)%matrix, &
186 matrix_hc_physical_im(ispin)%matrix)
187 cpassert(
ASSOCIATED(qs_ot_env(ispin)%matrix_preconditioned_gx))
188 cpassert(
ASSOCIATED(qs_ot_env(ispin)%matrix_preconditioned_gx_im))
189 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_preconditioned_gx, &
190 qs_ot_env(ispin)%matrix_gx)
191 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_preconditioned_gx_im, &
192 qs_ot_env(ispin)%matrix_gx_im)
194 matrix_hc_physical_im(ispin)%matrix, &
198 matrix_hc_im(ispin)%matrix, &
202 IF (separate_occupation_gradient)
THEN
203 cpassert(
PRESENT(matrix_hc_physical_im))
205 matrix_hc_im(ispin)%matrix, &
207 matrix_hc_physical(ispin)%matrix, &
208 matrix_hc_physical_im(ispin)%matrix)
209 cpassert(
ASSOCIATED(qs_ot_env(ispin)%matrix_preconditioned_gx))
210 cpassert(
ASSOCIATED(qs_ot_env(ispin)%matrix_preconditioned_gx_im))
211 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_preconditioned_gx, &
212 qs_ot_env(ispin)%matrix_gx)
213 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_preconditioned_gx_im, &
214 qs_ot_env(ispin)%matrix_gx_im)
216 matrix_hc_physical_im(ispin)%matrix, &
220 matrix_hc_im(ispin)%matrix, &
224 cpabort(
"Complex k-point OT derivative requires ALGORITHM STRICT or IRAC")
227 SELECT CASE (qs_ot_env(1)%settings%ot_algorithm)
230 qs_ot_env(ispin)%matrix_sx, &
231 qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin))
232 IF (separate_occupation_gradient)
THEN
233 cpassert(
ASSOCIATED(qs_ot_env(ispin)%matrix_preconditioned_gx))
234 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_preconditioned_gx, &
235 qs_ot_env(ispin)%matrix_gx)
237 qs_ot_env(ispin)%matrix_x, &
238 qs_ot_env(ispin)%matrix_sx, &
239 qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin))
243 qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_sx, &
244 qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin))
245 IF (separate_occupation_gradient)
THEN
246 cpassert(
ASSOCIATED(qs_ot_env(ispin)%matrix_preconditioned_gx))
247 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_preconditioned_gx, &
248 qs_ot_env(ispin)%matrix_gx)
250 qs_ot_env(ispin)%matrix_x, &
251 qs_ot_env(ispin)%matrix_sx, &
252 qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin))
255 cpabort(
"ALGORITHM NYI")
260 IF (qs_ot_env(1)%use_dx)
THEN
262 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_dx, tmp)
263 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient + tmp
264 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
265 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, qs_ot_env(ispin)%matrix_dx_im, tmp)
266 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient + tmp
268 IF (qs_ot_env(1)%settings%do_rotation)
THEN
269 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_dx, tmp)
270 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient + 0.5_dp*tmp
271 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
272 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
273 qs_ot_env(ispin)%rot_mat_dx_im, tmp)
274 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient + 0.5_dp*tmp
279 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_dx)
280 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient + tmp
284 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx, tmp)
285 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient - tmp
286 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
287 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, qs_ot_env(ispin)%matrix_gx_im, tmp)
288 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient - tmp
290 IF (qs_ot_env(1)%settings%do_rotation)
THEN
291 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_gx, tmp)
292 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient - 0.5_dp*tmp
293 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
294 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
295 qs_ot_env(ispin)%rot_mat_gx_im, tmp)
296 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient - 0.5_dp*tmp
301 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_gx)
302 qs_ot_env(1)%gradient = qs_ot_env(1)%gradient - tmp
306 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, qs_ot_env(1)%gradient)
309 IF (evaluate_gradient_only)
THEN
310 CALL timestop(handle)
314 SELECT CASE (qs_ot_env(1)%settings%OT_METHOD)
316 IF (current_point_is_fine(qs_ot_env))
THEN
317 qs_ot_env(1)%OT_METHOD_FULL =
"OT CG"
318 CALL ot_new_cg_direction(qs_ot_env, para_env_inter_kp)
319 qs_ot_env(1)%line_search_count = 0
321 qs_ot_env(1)%OT_METHOD_FULL =
"OT LS"
323 CALL do_line_search(qs_ot_env)
325 IF (current_point_is_fine(qs_ot_env))
THEN
326 qs_ot_env(1)%OT_METHOD_FULL =
"OT SD"
327 CALL ot_new_sd_direction(qs_ot_env, para_env_inter_kp)
328 qs_ot_env(1)%line_search_count = 0
330 qs_ot_env(1)%OT_METHOD_FULL =
"OT LS"
332 CALL do_line_search(qs_ot_env)
334 qs_ot_env(1)%OT_METHOD_FULL =
"OT DIIS"
335 CALL ot_diis_step(qs_ot_env, para_env_inter_kp)
337 qs_ot_env(1)%OT_METHOD_FULL =
"OT BROY"
338 CALL ot_broyden_step(qs_ot_env, para_env_inter_kp)
340 IF (current_point_is_fine(qs_ot_env))
THEN
341 qs_ot_env(1)%OT_METHOD_FULL =
"OT LBFGS"
342 CALL ot_new_lbfgs_direction(qs_ot_env, para_env_inter_kp)
343 qs_ot_env(1)%line_search_count = 0
345 qs_ot_env(1)%OT_METHOD_FULL =
"OT LS"
347 CALL do_line_search(qs_ot_env)
349 cpabort(
"OT_METHOD NYI")
352 CALL timestop(handle)
366 matrix_hc_physical, matrix_hc_physical_im, para_env_inter_kp)
367 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
370 POINTER :: matrix_hc_im, matrix_hc_physical, &
371 matrix_hc_physical_im
374 CALL ot_mini(qs_ot_env, matrix_hc, matrix_hc_im=matrix_hc_im, &
375 matrix_hc_physical=matrix_hc_physical, &
376 matrix_hc_physical_im=matrix_hc_physical_im, &
377 para_env_inter_kp=para_env_inter_kp, gradient_only=.true.)
386 SUBROUTINE ot_mini_sum_kpoint_scalar(para_env_inter_kp, value)
388 REAL(kind=
dp),
INTENT(INOUT) ::
value
390 IF (
PRESENT(para_env_inter_kp))
THEN
391 IF (
ASSOCIATED(para_env_inter_kp))
CALL para_env_inter_kp%sum(
value)
394 END SUBROUTINE ot_mini_sum_kpoint_scalar
413 reference_energy, current_energy, reference_residual, current_residual, &
414 predicted_slope, predicted_curvature, position, default_step, &
415 predicted_drop, measured_drop, quality, residual_ratio, good)
416 REAL(kind=
dp),
INTENT(IN) :: reference_energy, current_energy, reference_residual, &
417 current_residual, predicted_slope, predicted_curvature, position, default_step
418 REAL(kind=
dp),
INTENT(OUT) :: predicted_drop, measured_drop, quality, &
420 LOGICAL,
INTENT(OUT) :: good
422 REAL(kind=
dp) :: accepted_position, resolution, scale
424 predicted_drop = 0.0_dp
425 measured_drop = 0.0_dp
427 residual_ratio = huge(1.0_dp)
429 IF (.NOT. ieee_is_finite(reference_energy) .OR. .NOT. ieee_is_finite(current_energy) .OR. &
430 .NOT. ieee_is_finite(reference_residual) .OR. .NOT. ieee_is_finite(current_residual) .OR. &
431 .NOT. ieee_is_finite(predicted_slope) .OR. .NOT. ieee_is_finite(predicted_curvature) .OR. &
432 .NOT. ieee_is_finite(position) .OR. .NOT. ieee_is_finite(default_step))
RETURN
434 accepted_position = abs(position)
435 measured_drop = reference_energy - current_energy
436 predicted_drop = accepted_position*predicted_slope - &
437 0.5_dp*accepted_position**2*predicted_curvature
438 scale = max(1.0_dp, abs(reference_energy), abs(current_energy), &
439 abs(predicted_drop), abs(measured_drop))
440 resolution = 256.0_dp*epsilon(1.0_dp)*scale
441 IF (reference_residual > tiny(reference_residual))
THEN
442 residual_ratio = max(0.0_dp, current_residual)/reference_residual
444 IF (predicted_drop > resolution) quality = measured_drop/predicted_drop
446 good = predicted_drop > resolution .AND. measured_drop > resolution .AND. &
447 accepted_position >= 1.0e-6_dp*max(abs(default_step), tiny(default_step)) .AND. &
448 quality >= 0.05_dp .AND. quality <= 5.0_dp .AND. residual_ratio <= 1.0_dp
465 reference_energy, current_energy, predicted_slope, position, curvature, valid)
466 REAL(kind=
dp),
INTENT(IN) :: reference_energy, current_energy, &
467 predicted_slope, position
468 REAL(kind=
dp),
INTENT(OUT) :: curvature
469 LOGICAL,
INTENT(OUT) :: valid
471 REAL(kind=
dp) :: accepted_position, measured_drop
475 IF (.NOT. ieee_is_finite(reference_energy) .OR. .NOT. ieee_is_finite(current_energy) .OR. &
476 .NOT. ieee_is_finite(predicted_slope) .OR. .NOT. ieee_is_finite(position))
RETURN
477 accepted_position = abs(position)
478 IF (accepted_position <= sqrt(epsilon(1.0_dp)))
RETURN
480 measured_drop = reference_energy - current_energy
481 curvature = 2.0_dp*(accepted_position*predicted_slope - measured_drop)/accepted_position**2
482 valid = ieee_is_finite(curvature)
483 IF (.NOT. valid) curvature = 0.0_dp
501 reference_energy, current_energy, reference_residual, current_residual, &
502 predicted_slope, shadow_curvature, position, advantage, residual_ratio, good)
503 REAL(kind=
dp),
INTENT(IN) :: reference_energy, current_energy, reference_residual, &
504 current_residual, predicted_slope, shadow_curvature, position
505 REAL(kind=
dp),
INTENT(OUT) :: advantage, residual_ratio
506 LOGICAL,
INTENT(OUT) :: good
508 REAL(kind=
dp) :: accepted_position, baseline_drop, baseline_error, candidate_drop, &
509 candidate_error, measured_drop, resolution, scale
512 residual_ratio = huge(1.0_dp)
514 IF (.NOT. ieee_is_finite(reference_energy) .OR. .NOT. ieee_is_finite(current_energy) .OR. &
515 .NOT. ieee_is_finite(reference_residual) .OR. .NOT. ieee_is_finite(current_residual) .OR. &
516 .NOT. ieee_is_finite(predicted_slope) .OR. .NOT. ieee_is_finite(shadow_curvature) .OR. &
517 .NOT. ieee_is_finite(position))
RETURN
519 accepted_position = abs(position)
520 measured_drop = reference_energy - current_energy
521 baseline_drop = accepted_position*predicted_slope
522 candidate_drop = baseline_drop - 0.5_dp*accepted_position**2*shadow_curvature
523 scale = max(1.0_dp, abs(reference_energy), abs(current_energy), abs(measured_drop), &
524 abs(baseline_drop), abs(candidate_drop))
525 resolution = 256.0_dp*epsilon(1.0_dp)*scale
526 IF (reference_residual > tiny(reference_residual))
THEN
527 residual_ratio = max(0.0_dp, current_residual)/reference_residual
529 IF (measured_drop <= resolution .OR. baseline_drop <= resolution .OR. &
530 candidate_drop <= resolution)
RETURN
532 baseline_error = abs(measured_drop - baseline_drop)/scale
533 candidate_error = abs(measured_drop - candidate_drop)/scale
534 advantage = baseline_error - candidate_error
535 good = advantage > 64.0_dp*epsilon(1.0_dp)*scale .AND. residual_ratio <= 1.05_dp
558 baseline_slope, response_slope, response_curvature, accepted_slope, accepted_curvature, &
559 position, baseline_drop, response_drop, relative_gain, preferred)
560 REAL(kind=
dp),
INTENT(IN) :: baseline_slope, response_slope, &
561 response_curvature, accepted_slope, &
562 accepted_curvature, position
563 REAL(kind=
dp),
INTENT(OUT) :: baseline_drop, response_drop, &
565 LOGICAL,
INTENT(OUT) :: preferred
567 REAL(kind=
dp) :: alpha, baseline_curvature, &
568 curvature_ratio, resolution, scale
570 baseline_drop = 0.0_dp
571 response_drop = 0.0_dp
572 relative_gain = 0.0_dp
574 IF (.NOT. ieee_is_finite(baseline_slope) .OR. .NOT. ieee_is_finite(response_slope) .OR. &
575 .NOT. ieee_is_finite(response_curvature) .OR. .NOT. ieee_is_finite(accepted_slope) .OR. &
576 .NOT. ieee_is_finite(accepted_curvature) .OR. .NOT. ieee_is_finite(position))
RETURN
578 alpha = abs(position)
579 scale = max(1.0_dp, abs(baseline_slope), abs(response_slope), &
580 abs(response_curvature), abs(accepted_slope), abs(accepted_curvature))
581 resolution = 256.0_dp*epsilon(1.0_dp)*scale
582 IF (alpha <= sqrt(epsilon(1.0_dp)) .OR. baseline_slope <= resolution .OR. &
583 response_slope <= resolution .OR. accepted_slope <= resolution)
RETURN
585 curvature_ratio = accepted_curvature/accepted_slope
586 baseline_curvature = curvature_ratio*baseline_slope
587 baseline_drop = alpha*baseline_slope - 0.5_dp*alpha**2*baseline_curvature
588 response_drop = alpha*response_slope - 0.5_dp*alpha**2*response_curvature
589 scale = max(abs(baseline_drop), abs(response_drop), resolution)
590 relative_gain = (response_drop - baseline_drop)/scale
591 preferred = response_drop > resolution .AND. response_drop > baseline_drop + resolution
606 available, residual, directions, shadow_good_samples, good_samples, cooldown)
RESULT(probe)
607 LOGICAL,
INTENT(IN) :: available
608 REAL(kind=
dp),
INTENT(IN) :: residual
609 INTEGER,
INTENT(IN) :: directions, shadow_good_samples, &
610 good_samples, cooldown
613 INTEGER :: interval, phase
616 IF (.NOT. available .OR. .NOT. ieee_is_finite(residual))
RETURN
617 IF (residual <= 0.0_dp .OR. residual > 2.0e-3_dp .OR. cooldown > 0)
RETURN
618 IF (shadow_good_samples < 3)
RETURN
620 IF (good_samples >= 3) interval = 4
621 IF (directions < interval)
RETURN
622 phase = mod(directions, interval)
623 probe = phase == 0 .OR. phase == 1
643 residual, directions, shadow_good_samples, good_samples, cooldown, shadow_pending)
RESULT(prepare)
644 REAL(kind=
dp),
INTENT(IN) :: residual
645 INTEGER,
INTENT(IN) :: directions, shadow_good_samples, &
646 good_samples, cooldown
647 LOGICAL,
INTENT(IN) :: shadow_pending
650 INTEGER :: interval, next_direction, phase
652 prepare = shadow_pending
654 IF (.NOT. ieee_is_finite(residual) .OR. residual <= 0.0_dp .OR. residual > 4.0e-3_dp)
RETURN
655 IF (cooldown > 1)
RETURN
656 IF (shadow_good_samples < 3)
THEN
662 IF (good_samples >= 3) interval = 4
663 next_direction = min(huge(directions) - 1, max(0, directions) + 1)
664 phase = mod(next_direction, interval)
665 prepare = phase == interval - 1
679 residual, directions, shadow_good_samples, good_samples, cooldown)
RESULT(followup)
680 REAL(kind=
dp),
INTENT(IN) :: residual
681 INTEGER,
INTENT(IN) :: directions, shadow_good_samples, &
682 good_samples, cooldown
685 INTEGER :: interval, phase
688 IF (.NOT. ieee_is_finite(residual) .OR. residual <= 0.0_dp .OR. residual > 4.0e-3_dp)
RETURN
689 IF (cooldown > 1)
RETURN
690 IF (shadow_good_samples < 3)
THEN
696 IF (good_samples >= 3) interval = 4
697 phase = mod(max(0, directions), interval)
698 followup = phase == interval - 1 .OR. phase == 0
715 SUBROUTINE ot_try_mermin_response_direction( &
716 qs_ot_env, para_env_inter_kp, baseline_delta, test_down, use_response_candidate)
717 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
719 REAL(kind=
dp),
INTENT(IN) :: baseline_delta
720 REAL(kind=
dp),
INTENT(INOUT) :: test_down
721 LOGICAL,
INTENT(OUT) :: use_response_candidate
723 INTEGER :: ispin, nspin
724 LOGICAL :: active_candidate_available, candidate_available, candidate_good, do_ener, do_ks, &
725 probe_response_candidate, shadow_good
726 REAL(kind=
dp) :: baseline_model_drop, measured_drop, predicted_drop, response_advantage, &
727 response_model_drop, response_quality, response_relative_gain, response_residual_ratio, &
728 response_test_down, tmp
731 nspin =
SIZE(qs_ot_env)
732 do_ks = qs_ot_env(1)%settings%ks
733 do_ener = qs_ot_env(1)%settings%do_ener
735 shadow_good = .false.
736 candidate_good = .false.
738 IF (qs_ot_env(1)%response_shadow_pending)
THEN
740 qs_ot_env(1)%response_reference_energy, qs_ot_env(1)%etotal, &
741 qs_ot_env(1)%response_reference_residual, baseline_delta, &
742 qs_ot_env(1)%response_predicted_slope, qs_ot_env(1)%response_shadow_curvature, &
743 qs_ot_env(1)%ds_min, response_advantage, response_residual_ratio, shadow_good)
744 IF (shadow_good)
THEN
745 qs_ot_env(1)%response_shadow_good_samples = &
746 min(huge(qs_ot_env(1)%response_shadow_good_samples) - 1, &
747 qs_ot_env(1)%response_shadow_good_samples + 1)
749 qs_ot_env(1)%response_shadow_good_samples = &
750 max(0, qs_ot_env(1)%response_shadow_good_samples - 1)
752 IF (logger%iter_info%print_level >=
high_print_level .AND. logger%para_env%is_source())
THEN
754 '(A,1X,I5,2(1X,L1),4(1X,ES16.8))') &
755 " OT Mermin response shadow good hxc-dir advantage residual model shadow:", &
756 qs_ot_env(1)%response_shadow_good_samples, shadow_good, &
757 qs_ot_env(1)%response_hxc_direction_valid, response_advantage, &
758 response_residual_ratio, qs_ot_env(1)%response_model_curvature, &
759 qs_ot_env(1)%response_shadow_curvature
761 qs_ot_env(1)%response_shadow_pending = .false.
764 IF (qs_ot_env(1)%response_candidate_pending)
THEN
766 qs_ot_env(1)%response_reference_energy, qs_ot_env(1)%etotal, &
767 qs_ot_env(1)%response_reference_residual, baseline_delta, &
768 qs_ot_env(1)%response_predicted_slope, qs_ot_env(1)%response_predicted_curvature, &
769 qs_ot_env(1)%ds_min, qs_ot_env(1)%settings%ds_min, predicted_drop, measured_drop, &
770 response_quality, response_residual_ratio, candidate_good)
771 IF (candidate_good)
THEN
772 qs_ot_env(1)%response_candidate_good_samples = &
773 min(huge(qs_ot_env(1)%response_candidate_good_samples) - 1, &
774 qs_ot_env(1)%response_candidate_good_samples + 1)
776 qs_ot_env(1)%response_candidate_good_samples = &
777 max(0, qs_ot_env(1)%response_candidate_good_samples - 2)
778 qs_ot_env(1)%response_candidate_cooldown = 6
780 IF (logger%iter_info%print_level >=
high_print_level .AND. logger%para_env%is_source())
THEN
782 " OT Mermin response candidate good quality residual predicted measured:", &
783 qs_ot_env(1)%response_candidate_good_samples, candidate_good, response_quality, &
784 response_residual_ratio, predicted_drop, measured_drop
786 qs_ot_env(1)%response_candidate_pending = .false.
789 qs_ot_env(1)%response_candidate_directions = &
790 min(huge(qs_ot_env(1)%response_candidate_directions) - 1, &
791 qs_ot_env(1)%response_candidate_directions + 1)
792 IF (qs_ot_env(1)%response_candidate_cooldown > 0)
THEN
793 qs_ot_env(1)%response_candidate_cooldown = qs_ot_env(1)%response_candidate_cooldown - 1
796 candidate_available = qs_ot_env(1)%settings%occupation_preconditioner .AND. &
797 qs_ot_env(1)%settings%do_rotation .AND. do_ener
799 candidate_available = candidate_available .AND. &
800 qs_ot_env(ispin)%rotation_response_valid .AND. &
801 ASSOCIATED(qs_ot_env(ispin)%matrix_response_gx) .AND. &
802 ASSOCIATED(qs_ot_env(ispin)%matrix_response_gx_im) .AND. &
803 ASSOCIATED(qs_ot_env(ispin)%rot_mat_response_gx) .AND. &
804 ASSOCIATED(qs_ot_env(ispin)%rot_mat_response_gx_im) .AND. &
805 ASSOCIATED(qs_ot_env(ispin)%ener_response_gx)
807 active_candidate_available = candidate_available .AND. shadow_good .AND. &
808 qs_ot_env(1)%response_hxc_direction_valid
810 active_candidate_available, baseline_delta, &
811 qs_ot_env(1)%response_candidate_directions, &
812 qs_ot_env(1)%response_shadow_good_samples, &
813 qs_ot_env(1)%response_candidate_good_samples, &
814 qs_ot_env(1)%response_candidate_cooldown)
815 use_response_candidate = .false.
817 IF (probe_response_candidate)
THEN
818 response_test_down = 0.0_dp
819 baseline_model_drop = 0.0_dp
820 response_model_drop = 0.0_dp
821 response_relative_gain = 0.0_dp
824 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, &
825 qs_ot_env(ispin)%matrix_response_gx, tmp)
826 response_test_down = response_test_down - tmp
827 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
828 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, &
829 qs_ot_env(ispin)%matrix_response_gx_im, tmp)
830 response_test_down = response_test_down - tmp
832 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, &
833 qs_ot_env(ispin)%rot_mat_response_gx, tmp)
834 response_test_down = response_test_down - 0.5_dp*tmp
835 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
836 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
837 qs_ot_env(ispin)%rot_mat_response_gx_im, tmp)
838 response_test_down = response_test_down - 0.5_dp*tmp
844 response_test_down = response_test_down - &
845 dot_product(qs_ot_env(ispin)%ener_gx, &
846 qs_ot_env(ispin)%ener_response_gx)
849 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, response_test_down)
850 IF (response_test_down < 0.0_dp)
THEN
852 -test_down, -response_test_down, qs_ot_env(1)%response_model_curvature, &
853 qs_ot_env(1)%response_predicted_slope, qs_ot_env(1)%response_shadow_curvature, &
854 qs_ot_env(1)%ds_min, baseline_model_drop, response_model_drop, &
855 response_relative_gain, use_response_candidate)
857 IF (logger%iter_info%print_level >=
high_print_level .AND. logger%para_env%is_source())
THEN
859 " OT Mermin response candidate comparison directions shadow active cooldown residual "// &
860 "curvature baseline response gain probe use:", &
861 qs_ot_env(1)%response_candidate_directions, &
862 qs_ot_env(1)%response_shadow_good_samples, &
863 qs_ot_env(1)%response_candidate_good_samples, &
864 qs_ot_env(1)%response_candidate_cooldown, baseline_delta, &
865 qs_ot_env(1)%response_model_curvature, baseline_model_drop, response_model_drop, &
866 response_relative_gain, probe_response_candidate, use_response_candidate
868 IF (use_response_candidate)
THEN
871 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin)%matrix_response_gx)
872 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_dx, -1.0_dp)
873 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
874 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_dx_im, &
875 qs_ot_env(ispin)%matrix_response_gx_im)
876 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_dx_im, -1.0_dp)
878 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx, &
879 qs_ot_env(ispin)%rot_mat_response_gx)
880 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_dx, -1.0_dp)
881 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
882 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx_im, &
883 qs_ot_env(ispin)%rot_mat_response_gx_im)
884 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_dx_im, -1.0_dp)
887 IF (do_ener) qs_ot_env(ispin)%ener_dx = -qs_ot_env(ispin)%ener_response_gx
889 test_down = response_test_down
893 qs_ot_env(1)%response_reference_energy = qs_ot_env(1)%etotal
894 qs_ot_env(1)%response_reference_residual = baseline_delta
895 IF (test_down < 0.0_dp)
THEN
896 qs_ot_env(1)%response_predicted_slope = -test_down
898 qs_ot_env(1)%response_predicted_slope = qs_ot_env(1)%gnorm
900 IF (use_response_candidate)
THEN
901 qs_ot_env(1)%response_candidate_pending = .true.
902 qs_ot_env(1)%response_shadow_pending = .false.
903 qs_ot_env(1)%response_predicted_curvature = qs_ot_env(1)%response_model_curvature
905 qs_ot_env(1)%response_candidate_pending = .false.
906 qs_ot_env(1)%response_shadow_pending = candidate_available .AND. &
909 qs_ot_env(1)%response_candidate_directions, &
910 qs_ot_env(1)%response_shadow_good_samples, &
911 qs_ot_env(1)%response_candidate_good_samples, &
912 qs_ot_env(1)%response_candidate_cooldown)
915 END SUBROUTINE ot_try_mermin_response_direction
926 FUNCTION current_point_is_fine(qs_ot_env)
RESULT(res)
927 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
933 IF (.NOT. qs_ot_env(1)%energy_only)
THEN
936 IF (qs_ot_env(1)%line_search_count == 0)
THEN
941 IF (qs_ot_env(1)%line_search_might_be_done)
THEN
949 END FUNCTION current_point_is_fine
958 SUBROUTINE do_line_search(qs_ot_env)
959 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
961 SELECT CASE (qs_ot_env(1)%settings%line_search_method)
963 CALL do_line_search_gold(qs_ot_env)
965 CALL do_line_search_3pnt(qs_ot_env)
967 IF (use_three_point_mermin_search(qs_ot_env))
THEN
968 CALL do_line_search_3pnt(qs_ot_env)
970 CALL do_line_search_2pnt(qs_ot_env)
973 CALL do_line_search_adapt(qs_ot_env)
975 CALL do_line_search_none(qs_ot_env)
979 END SUBROUTINE do_line_search
986 FUNCTION use_three_point_mermin_search(qs_ot_env)
RESULT(res)
987 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
993 IF (.NOT. qs_ot_env(1)%settings%occupation_preconditioner)
RETURN
995 DO ispin = 1,
SIZE(qs_ot_env)
996 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1001 END FUNCTION use_three_point_mermin_search
1010 SUBROUTINE take_step(ds, qs_ot_env)
1012 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
1014 CHARACTER(len=*),
PARAMETER :: routinen =
'take_step'
1016 INTEGER :: handle, ispin, nspin
1017 LOGICAL :: do_ener, do_ks
1019 CALL timeset(routinen, handle)
1021 nspin =
SIZE(qs_ot_env)
1023 do_ks = qs_ot_env(1)%settings%ks
1024 do_ener = qs_ot_env(1)%settings%do_ener
1028 IF (qs_ot_env(1)%use_dx)
THEN
1031 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_dx, &
1032 alpha_scalar=1.0_dp, beta_scalar=ds)
1033 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1034 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x_im, qs_ot_env(ispin)%matrix_dx_im, &
1035 alpha_scalar=1.0_dp, beta_scalar=ds)
1037 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
1038 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x, qs_ot_env(ispin)%rot_mat_dx, &
1039 alpha_scalar=1.0_dp, beta_scalar=ds)
1040 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1041 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x_im, qs_ot_env(ispin)%rot_mat_dx_im, &
1042 alpha_scalar=1.0_dp, beta_scalar=ds)
1049 qs_ot_env(ispin)%ener_x = qs_ot_env(ispin)%ener_x + ds*qs_ot_env(ispin)%ener_dx
1055 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, qs_ot_env(ispin)%matrix_gx, &
1056 alpha_scalar=1.0_dp, beta_scalar=-ds)
1057 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1058 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x_im, qs_ot_env(ispin)%matrix_gx_im, &
1059 alpha_scalar=1.0_dp, beta_scalar=-ds)
1061 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
1062 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x, qs_ot_env(ispin)%rot_mat_gx, &
1063 alpha_scalar=1.0_dp, beta_scalar=-ds)
1064 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1065 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x_im, qs_ot_env(ispin)%rot_mat_gx_im, &
1066 alpha_scalar=1.0_dp, beta_scalar=-ds)
1073 qs_ot_env(ispin)%ener_x = qs_ot_env(ispin)%ener_x - ds*qs_ot_env(ispin)%ener_gx
1077 CALL timestop(handle)
1078 END SUBROUTINE take_step
1085 SUBROUTINE do_line_search_gold(qs_ot_env)
1087 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
1089 CHARACTER(len=*),
PARAMETER :: routinen =
'do_line_search_gold'
1090 REAL(kind=
dp),
PARAMETER :: gold_sec = 0.3819_dp
1092 INTEGER :: count, handle
1095 CALL timeset(routinen, handle)
1097 qs_ot_env(1)%line_search_count = qs_ot_env(1)%line_search_count + 1
1098 count = qs_ot_env(1)%line_search_count
1099 qs_ot_env(1)%line_search_might_be_done = .false.
1100 qs_ot_env(1)%energy_only = .true.
1102 IF (count + 1 >
SIZE(qs_ot_env(1)%OT_pos))
THEN
1105 cpabort(
"MAX ITER EXCEEDED : FATAL")
1108 IF (qs_ot_env(1)%line_search_count == 1)
THEN
1109 qs_ot_env(1)%line_search_left = 1
1110 qs_ot_env(1)%line_search_right = 0
1111 qs_ot_env(1)%line_search_mid = 1
1112 qs_ot_env(1)%ot_pos(1) = 0.0_dp
1113 qs_ot_env(1)%ot_energy(1) = qs_ot_env(1)%etotal
1114 qs_ot_env(1)%ot_pos(2) = qs_ot_env(1)%ds_min/gold_sec
1116 qs_ot_env(1)%ot_energy(count) = qs_ot_env(1)%etotal
1120 IF (qs_ot_env(1)%line_search_right == 0)
THEN
1121 IF (qs_ot_env(1)%ot_energy(count - 1) < qs_ot_env(1)%ot_energy(count))
THEN
1122 qs_ot_env(1)%line_search_right = count
1123 qs_ot_env(1)%ot_pos(count + 1) = qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid) + &
1124 (qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_right) - &
1125 qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid))*gold_sec
1127 qs_ot_env(1)%line_search_left = qs_ot_env(1)%line_search_mid
1128 qs_ot_env(1)%line_search_mid = count
1129 qs_ot_env(1)%ot_pos(count + 1) = qs_ot_env(1)%ot_pos(count)/gold_sec
1133 IF (qs_ot_env(1)%ot_pos(count) < qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid))
THEN
1134 IF (qs_ot_env(1)%ot_energy(count) < qs_ot_env(1)%ot_energy(qs_ot_env(1)%line_search_mid))
THEN
1135 qs_ot_env(1)%line_search_right = qs_ot_env(1)%line_search_mid
1136 qs_ot_env(1)%line_search_mid = count
1138 qs_ot_env(1)%line_search_left = count
1141 IF (qs_ot_env(1)%ot_energy(count) < qs_ot_env(1)%ot_energy(qs_ot_env(1)%line_search_mid))
THEN
1142 qs_ot_env(1)%line_search_left = qs_ot_env(1)%line_search_mid
1143 qs_ot_env(1)%line_search_mid = count
1145 qs_ot_env(1)%line_search_right = count
1149 IF ((qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_right) &
1150 - qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid)) > &
1151 (qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid) &
1152 - qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_left)))
THEN
1153 qs_ot_env(1)%ot_pos(count + 1) = &
1154 qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid) + &
1155 gold_sec*(qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_right) &
1156 - qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid))
1158 qs_ot_env(1)%ot_pos(count + 1) = &
1159 qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_left) + &
1160 gold_sec*(qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid) &
1161 - qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_left))
1164 IF (((qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_right) &
1165 - qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid)) < &
1166 qs_ot_env(1)%ds_min*qs_ot_env(1)%settings%gold_target) .AND. &
1167 ((qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid) &
1168 - qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_left)) < &
1169 qs_ot_env(1)%ds_min*qs_ot_env(1)%settings%gold_target))
THEN
1170 qs_ot_env(1)%energy_only = .false.
1171 qs_ot_env(1)%line_search_might_be_done = .true.
1175 ds = qs_ot_env(1)%OT_pos(count + 1) - qs_ot_env(1)%OT_pos(count)
1176 qs_ot_env(1)%ds_min = qs_ot_env(1)%OT_pos(count + 1)
1178 CALL take_step(ds, qs_ot_env)
1180 CALL timestop(handle)
1182 END SUBROUTINE do_line_search_gold
1188 SUBROUTINE do_line_search_3pnt(qs_ot_env)
1190 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
1192 CHARACTER(len=*),
PARAMETER :: routinen =
'do_line_search_3pnt'
1194 INTEGER :: best_index, count, handle, i
1195 REAL(kind=
dp) :: best_energy, denom, ds, fa, fb, fc, nom, &
1196 pos, tol, val, xa, xb,
xc
1198 CALL timeset(routinen, handle)
1200 qs_ot_env(1)%line_search_might_be_done = .false.
1201 qs_ot_env(1)%energy_only = .true.
1204 qs_ot_env(1)%line_search_count = qs_ot_env(1)%line_search_count + 1
1205 count = qs_ot_env(1)%line_search_count
1206 qs_ot_env(1)%ot_energy(count) = qs_ot_env(1)%etotal
1209 qs_ot_env(1)%ot_pos(count) = 0.0_dp
1210 qs_ot_env(1)%ot_pos(count + 1) = qs_ot_env(1)%ds_min*0.8_dp
1212 IF (qs_ot_env(1)%OT_energy(count) > qs_ot_env(1)%OT_energy(count - 1))
THEN
1213 qs_ot_env(1)%OT_pos(count + 1) = qs_ot_env(1)%ds_min*0.5_dp
1215 qs_ot_env(1)%OT_pos(count + 1) = qs_ot_env(1)%ds_min*1.4_dp
1218 xa = qs_ot_env(1)%OT_pos(1)
1219 xb = qs_ot_env(1)%OT_pos(2)
1220 xc = qs_ot_env(1)%OT_pos(3)
1221 fa = qs_ot_env(1)%OT_energy(1)
1222 fb = qs_ot_env(1)%OT_energy(2)
1223 fc = qs_ot_env(1)%OT_energy(3)
1224 nom = (xb - xa)**2*(fb - fc) - (xb -
xc)**2*(fb - fa)
1225 denom = (xb - xa)*(fb - fc) - (xb -
xc)*(fb - fa)
1226 IF (abs(denom) <= 1.0e-18_dp*max(abs(fb - fc), abs(fb - fa)))
THEN
1229 pos = xb - 0.5_dp*nom/denom
1231 val = (pos - xa)*(pos - xb)*fc/((
xc - xa)*(
xc - xb)) + &
1232 (pos - xb)*(pos -
xc)*fa/((xa - xb)*(xa -
xc)) + &
1233 (pos -
xc)*(pos - xa)*fb/((xb -
xc)*(xb - xa))
1236 IF (qs_ot_env(1)%OT_energy(i) < qs_ot_env(1)%OT_energy(best_index)) best_index = i
1238 best_energy = qs_ot_env(1)%OT_energy(best_index)
1239 tol = 10.0_dp*epsilon(1.0_dp)*max(1.0_dp, abs(best_energy))
1240 IF (use_three_point_mermin_search(qs_ot_env) .AND. best_index /= 1 .AND. &
1241 val >= best_energy - tol)
THEN
1242 qs_ot_env(1)%OT_pos(count + 1) = qs_ot_env(1)%OT_pos(best_index)
1243 ELSE IF (val < fa .AND. val <= fb .AND. val <= fc)
THEN
1245 qs_ot_env(1)%OT_pos(count + 1) = max(maxval(qs_ot_env(1)%OT_pos(1:3))*0.01_dp, &
1246 min(pos, maxval(qs_ot_env(1)%OT_pos(1:3))*4.0_dp))
1248 qs_ot_env(1)%OT_pos(count + 1) = maxval(qs_ot_env(1)%OT_pos(1:3))*2.0_dp
1250 qs_ot_env(1)%energy_only = .false.
1251 qs_ot_env(1)%line_search_might_be_done = .true.
1255 ds = qs_ot_env(1)%OT_pos(count + 1) - qs_ot_env(1)%OT_pos(count)
1256 qs_ot_env(1)%ds_min = qs_ot_env(1)%OT_pos(count + 1)
1258 CALL take_step(ds, qs_ot_env)
1260 CALL timestop(handle)
1262 END SUBROUTINE do_line_search_3pnt
1268 SUBROUTINE do_line_search_2pnt(qs_ot_env)
1270 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
1272 CHARACTER(len=*),
PARAMETER :: routinen =
'do_line_search_2pnt'
1274 INTEGER :: count, handle
1275 REAL(kind=
dp) :: a, b, c, ds, pos, val, x0, x1
1277 CALL timeset(routinen, handle)
1279 qs_ot_env(1)%line_search_might_be_done = .false.
1280 qs_ot_env(1)%energy_only = .true.
1283 qs_ot_env(1)%line_search_count = qs_ot_env(1)%line_search_count + 1
1284 count = qs_ot_env(1)%line_search_count
1285 qs_ot_env(1)%ot_energy(count) = qs_ot_env(1)%etotal
1288 qs_ot_env(1)%ot_pos(count) = 0.0_dp
1289 qs_ot_env(1)%ot_grad(count) = qs_ot_env(1)%gradient
1290 qs_ot_env(1)%ot_pos(count + 1) = qs_ot_env(1)%ds_min*1.0_dp
1293 c = qs_ot_env(1)%ot_energy(1)
1294 b = qs_ot_env(1)%ot_grad(1)
1295 x1 = qs_ot_env(1)%ot_pos(2)
1296 a = (qs_ot_env(1)%ot_energy(2) - b*x1 - c)/(x1**2)
1297 IF (a <= 0.0_dp) a = 1.0e-15_dp
1299 val = a*pos**2 + b*pos + c
1300 qs_ot_env(1)%energy_only = .false.
1301 qs_ot_env(1)%line_search_might_be_done = .true.
1302 IF (val < qs_ot_env(1)%ot_energy(1) .AND. val <= qs_ot_env(1)%ot_energy(2))
THEN
1305 qs_ot_env(1)%OT_pos(count + 1) = max(maxval(qs_ot_env(1)%OT_pos(1:2))*0.01_dp, &
1306 min(pos, maxval(qs_ot_env(1)%OT_pos(1:2))*4.0_dp))
1308 qs_ot_env(1)%OT_pos(count + 1) = maxval(qs_ot_env(1)%OT_pos(1:2))*2.0_dp
1313 ds = qs_ot_env(1)%OT_pos(count + 1) - qs_ot_env(1)%OT_pos(count)
1314 qs_ot_env(1)%ds_min = qs_ot_env(1)%OT_pos(count + 1)
1316 CALL take_step(ds, qs_ot_env)
1318 CALL timestop(handle)
1320 END SUBROUTINE do_line_search_2pnt
1326 SUBROUTINE do_line_search_adapt(qs_ot_env)
1328 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
1330 CHARACTER(len=*),
PARAMETER :: routinen =
'do_line_search_adapt'
1331 REAL(kind=
dp),
PARAMETER :: grow_factor = 2.0_dp, &
1332 shrink_factor = 0.5_dp
1334 INTEGER :: count, handle, il, im, ir
1335 REAL(kind=
dp) :: a, b, c, denom, ds, el, em, er, &
1336 step_size, xl, xm, xr
1338 CALL timeset(routinen, handle)
1340 qs_ot_env(1)%line_search_count = qs_ot_env(1)%line_search_count + 1
1341 count = qs_ot_env(1)%line_search_count
1342 qs_ot_env(1)%line_search_might_be_done = .false.
1343 qs_ot_env(1)%energy_only = .true.
1345 IF (count + 1 >
SIZE(qs_ot_env(1)%OT_pos))
THEN
1348 cpabort(
"MAX ITER EXCEEDED : FATAL")
1352 IF (qs_ot_env(1)%line_search_count == 1)
THEN
1353 qs_ot_env(1)%line_search_left = 1
1354 qs_ot_env(1)%line_search_right = 0
1355 qs_ot_env(1)%line_search_mid = 1
1356 qs_ot_env(1)%ot_Pos(1) = 0.0_dp
1357 qs_ot_env(1)%ot_energy(1) = qs_ot_env(1)%etotal
1358 qs_ot_env(1)%ot_Pos(2) = qs_ot_env(1)%ds_min*grow_factor
1360 qs_ot_env(1)%ot_energy(count) = qs_ot_env(1)%etotal
1364 IF (qs_ot_env(1)%line_search_right == 0)
THEN
1365 IF (qs_ot_env(1)%ot_energy(count - 1) < qs_ot_env(1)%ot_energy(count))
THEN
1366 qs_ot_env(1)%line_search_right = count
1367 qs_ot_env(1)%ot_Pos(count + 1) = qs_ot_env(1)%ot_Pos(qs_ot_env(1)%line_search_mid) + &
1368 (qs_ot_env(1)%ot_Pos(qs_ot_env(1)%line_search_right) - &
1369 qs_ot_env(1)%ot_Pos(qs_ot_env(1)%line_search_mid))*shrink_factor
1372 qs_ot_env(1)%line_search_left = qs_ot_env(1)%line_search_mid
1373 qs_ot_env(1)%line_search_mid = count
1374 qs_ot_env(1)%ot_Pos(count + 1) = qs_ot_env(1)%ot_Pos(count)*grow_factor
1378 IF (qs_ot_env(1)%ot_pos(count) < qs_ot_env(1)%ot_pos(qs_ot_env(1)%line_search_mid))
THEN
1379 IF (qs_ot_env(1)%ot_energy(count) < qs_ot_env(1)%ot_energy(qs_ot_env(1)%line_search_mid))
THEN
1380 qs_ot_env(1)%line_search_right = qs_ot_env(1)%line_search_mid
1381 qs_ot_env(1)%line_search_mid = count
1383 qs_ot_env(1)%line_search_left = count
1386 IF (qs_ot_env(1)%ot_energy(count) < qs_ot_env(1)%ot_energy(qs_ot_env(1)%line_search_mid))
THEN
1387 qs_ot_env(1)%line_search_left = qs_ot_env(1)%line_search_mid
1388 qs_ot_env(1)%line_search_mid = count
1390 qs_ot_env(1)%line_search_right = count
1393 il = qs_ot_env(1)%line_search_left
1394 im = qs_ot_env(1)%line_search_mid
1395 ir = qs_ot_env(1)%line_search_right
1396 xl = qs_ot_env(1)%OT_pos(il)
1397 xm = qs_ot_env(1)%OT_pos(im)
1398 xr = qs_ot_env(1)%OT_pos(ir)
1399 el = qs_ot_env(1)%ot_energy(il)
1400 em = qs_ot_env(1)%ot_energy(im)
1401 er = qs_ot_env(1)%ot_energy(ir)
1405 qs_ot_env(1)%ot_Pos(count + 1) = qs_ot_env(1)%ot_Pos(ir)*grow_factor
1408 denom = (xl - xm)*(xl - xr)*(xm - xr)
1409 a = (xr*(em - el) + xm*(el - er) + xl*(er - em))/denom
1410 b = (xr**2*(el - em) + xm**2*(er - el) + xl**2*(em - er))/denom
1411 c = (xm*xr*(xm - xr)*el + xr*xl*(xr - xl)*em + xr*xm*(xr - xm)*er)/denom
1413 IF (abs(a) /= 0.0_dp)
THEN
1414 step_size = -b/(2.0_dp*a)
1418 cpassert(step_size >= 0.0_dp)
1419 qs_ot_env(1)%ot_Pos(count + 1) = step_size
1420 qs_ot_env(1)%line_search_might_be_done = .true.
1421 qs_ot_env(1)%energy_only = .false.
1425 qs_ot_env(1)%ot_Pos(count + 1) = qs_ot_env(1)%ot_Pos(im) + &
1426 (qs_ot_env(1)%ot_Pos(ir) - qs_ot_env(1)%ot_Pos(im))*shrink_factor
1431 ds = qs_ot_env(1)%OT_pos(count + 1) - qs_ot_env(1)%OT_pos(count)
1432 qs_ot_env(1)%ds_min = qs_ot_env(1)%OT_pos(count + 1)
1434 CALL take_step(ds, qs_ot_env)
1436 CALL timestop(handle)
1438 END SUBROUTINE do_line_search_adapt
1444 SUBROUTINE do_line_search_none(qs_ot_env)
1445 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
1447 CALL take_step(qs_ot_env(1)%ds_min, qs_ot_env)
1449 END SUBROUTINE do_line_search_none
1461 SUBROUTINE ot_new_sd_direction(qs_ot_env, para_env_inter_kp)
1462 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
1465 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_new_sd_direction'
1467 INTEGER :: handle, ispin, itmp, k, n, nener, nspin
1468 LOGICAL :: do_ener, do_ks
1469 REAL(kind=
dp) :: channel_gnorm, nvariables, tmp
1472 CALL timeset(routinen, handle)
1476 nspin =
SIZE(qs_ot_env)
1478 do_ks = qs_ot_env(1)%settings%ks
1479 do_ener = qs_ot_env(1)%settings%do_ener
1481 IF (
ASSOCIATED(qs_ot_env(1)%preconditioner))
THEN
1482 IF (.NOT. qs_ot_env(1)%use_dx) cpabort(
"use dx")
1483 qs_ot_env(1)%gnorm = 0.0_dp
1486 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1487 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1489 qs_ot_env(ispin)%matrix_preconditioned_gx, &
1490 qs_ot_env(ispin)%matrix_preconditioned_gx_im, &
1491 qs_ot_env(ispin)%matrix_dx, &
1492 qs_ot_env(ispin)%matrix_dx_im)
1495 qs_ot_env(ispin)%matrix_gx, &
1496 qs_ot_env(ispin)%matrix_gx_im, &
1497 qs_ot_env(ispin)%matrix_dx, &
1498 qs_ot_env(ispin)%matrix_dx_im)
1500 cpassert(qs_ot_env(ispin)%kpoint_weight > 0.0_dp)
1506 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1508 qs_ot_env(ispin)%matrix_preconditioned_gx, &
1509 qs_ot_env(ispin)%matrix_dx)
1512 qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_dx)
1515 channel_gnorm = 0.0_dp
1516 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_dx, tmp)
1517 channel_gnorm = channel_gnorm + tmp
1518 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1519 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, qs_ot_env(ispin)%matrix_dx_im, tmp)
1520 channel_gnorm = channel_gnorm + tmp
1522 IF (qs_ot_env(ispin)%settings%occupation_preconditioner .AND. &
1523 channel_gnorm <= 0.0_dp)
THEN
1524 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1526 qs_ot_env(ispin)%matrix_gx, &
1527 qs_ot_env(ispin)%matrix_gx_im, &
1528 qs_ot_env(ispin)%matrix_dx, &
1529 qs_ot_env(ispin)%matrix_dx_im)
1536 qs_ot_env(ispin)%matrix_gx, &
1537 qs_ot_env(ispin)%matrix_dx)
1539 channel_gnorm = 0.0_dp
1540 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_dx, tmp)
1541 channel_gnorm = channel_gnorm + tmp
1542 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1543 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, &
1544 qs_ot_env(ispin)%matrix_dx_im, tmp)
1545 channel_gnorm = channel_gnorm + tmp
1548 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + channel_gnorm
1550 IF (qs_ot_env(1)%gnorm < 0.0_dp)
THEN
1555 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_dx, -1.0_dp)
1556 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1557 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_dx_im, -1.0_dp)
1560 IF (qs_ot_env(1)%settings%do_rotation)
THEN
1563 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx, qs_ot_env(ispin)%rot_mat_gx)
1564 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_dx, tmp)
1566 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
1567 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1568 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx_im, qs_ot_env(ispin)%rot_mat_gx_im)
1569 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
1570 qs_ot_env(ispin)%rot_mat_dx_im, tmp)
1571 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
1575 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_dx, -1.0_dp)
1576 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1577 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_dx_im, -1.0_dp)
1584 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1585 qs_ot_env(ispin)%ener_dx = qs_ot_env(ispin)%ener_preconditioned_gx
1587 qs_ot_env(ispin)%ener_dx = qs_ot_env(ispin)%ener_gx
1589 tmp = dot_product(qs_ot_env(ispin)%ener_dx, qs_ot_env(ispin)%ener_gx)
1590 IF (qs_ot_env(ispin)%settings%occupation_preconditioner .AND. tmp <= 0.0_dp)
THEN
1591 qs_ot_env(ispin)%ener_dx = qs_ot_env(ispin)%ener_gx
1592 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_gx)
1594 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1595 qs_ot_env(ispin)%ener_dx = -qs_ot_env(ispin)%ener_dx
1599 qs_ot_env(1)%gnorm = 0.0_dp
1602 channel_gnorm = 0.0_dp
1603 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1604 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, &
1605 qs_ot_env(ispin)%matrix_preconditioned_gx, tmp)
1607 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx, tmp)
1609 channel_gnorm = channel_gnorm + tmp
1610 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1611 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1612 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, &
1613 qs_ot_env(ispin)%matrix_preconditioned_gx_im, tmp)
1615 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, qs_ot_env(ispin)%matrix_gx_im, tmp)
1617 channel_gnorm = channel_gnorm + tmp
1619 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1620 IF (channel_gnorm <= 0.0_dp)
THEN
1621 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_preconditioned_gx, &
1622 qs_ot_env(ispin)%matrix_gx)
1623 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1624 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_preconditioned_gx_im, &
1625 qs_ot_env(ispin)%matrix_gx_im)
1627 channel_gnorm = 0.0_dp
1628 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, &
1629 qs_ot_env(ispin)%matrix_preconditioned_gx, tmp)
1630 channel_gnorm = channel_gnorm + tmp
1631 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1632 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, &
1633 qs_ot_env(ispin)%matrix_preconditioned_gx_im, tmp)
1634 channel_gnorm = channel_gnorm + tmp
1637 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx, &
1638 qs_ot_env(ispin)%matrix_preconditioned_gx)
1639 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1640 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_im, &
1641 qs_ot_env(ispin)%matrix_preconditioned_gx_im)
1644 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + channel_gnorm
1646 IF (qs_ot_env(1)%settings%do_rotation)
THEN
1648 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_gx, tmp)
1650 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
1651 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1652 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
1653 qs_ot_env(ispin)%rot_mat_gx_im, tmp)
1654 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
1661 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1662 tmp = dot_product(qs_ot_env(ispin)%ener_gx, &
1663 qs_ot_env(ispin)%ener_preconditioned_gx)
1664 IF (tmp <= 0.0_dp)
THEN
1665 qs_ot_env(ispin)%ener_preconditioned_gx = qs_ot_env(ispin)%ener_gx
1666 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_gx)
1668 qs_ot_env(ispin)%ener_gx = qs_ot_env(ispin)%ener_preconditioned_gx
1670 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_gx)
1672 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1683 CALL dbcsr_get_info(qs_ot_env(ispin)%matrix_x, nfullcols_total=itmp)
1685 IF (qs_ot_env(ispin)%has_complex_kpoint_state) k = k + itmp
1690 nener = nener +
SIZE(qs_ot_env(ispin)%ener_x)
1693 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, qs_ot_env(1)%gnorm)
1694 nvariables = real(int(n, kind=
int_8)*int(k, kind=
int_8) + nener, kind=
dp)
1695 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, nvariables)
1697 IF (nvariables > 0.0_dp)
THEN
1698 qs_ot_env(1)%delta = sqrt(abs(qs_ot_env(1)%gnorm)/nvariables)
1699 qs_ot_env(1)%gradient = -qs_ot_env(1)%gnorm
1701 qs_ot_env(1)%delta = 0.0_dp
1702 qs_ot_env(1)%gradient = 0.0_dp
1705 CALL timestop(handle)
1707 END SUBROUTINE ot_new_sd_direction
1719 SUBROUTINE ot_new_cg_direction(qs_ot_env, para_env_inter_kp)
1720 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
1723 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_new_cg_direction'
1725 INTEGER :: handle, ispin, itmp, k, n, nener, nspin
1726 LOGICAL :: do_ener, do_ks, &
1727 preceding_response_candidate, &
1728 use_response_candidate
1729 REAL(kind=
dp) :: baseline_delta, baseline_gnorm, beta_pr, &
1730 gnorm_cross, nvariables, test_down, tmp
1736 CALL timeset(routinen, handle)
1738 nspin =
SIZE(qs_ot_env)
1740 preceding_response_candidate = qs_ot_env(1)%response_candidate_pending
1742 do_ks = qs_ot_env(1)%settings%ks
1743 do_ener = qs_ot_env(1)%settings%do_ener
1744 gnorm_cross = 0.0_dp
1747 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx_old, tmp)
1748 gnorm_cross = gnorm_cross + tmp
1749 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1750 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, qs_ot_env(ispin)%matrix_gx_old_im, tmp)
1751 gnorm_cross = gnorm_cross + tmp
1754 IF (qs_ot_env(1)%settings%do_rotation)
THEN
1756 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_gx_old, tmp)
1758 gnorm_cross = gnorm_cross + 0.5_dp*tmp
1759 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1760 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
1761 qs_ot_env(ispin)%rot_mat_gx_old_im, tmp)
1762 gnorm_cross = gnorm_cross + 0.5_dp*tmp
1769 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_gx_old)
1770 gnorm_cross = gnorm_cross + tmp
1773 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, gnorm_cross)
1775 IF (
ASSOCIATED(qs_ot_env(1)%preconditioner))
THEN
1778 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1779 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1781 qs_ot_env(ispin)%matrix_preconditioned_gx, &
1782 qs_ot_env(ispin)%matrix_preconditioned_gx_im, &
1783 qs_ot_env(ispin)%matrix_gx_old, &
1784 qs_ot_env(ispin)%matrix_gx_old_im)
1787 qs_ot_env(ispin)%matrix_gx, &
1788 qs_ot_env(ispin)%matrix_gx_im, &
1789 qs_ot_env(ispin)%matrix_gx_old, &
1790 qs_ot_env(ispin)%matrix_gx_old_im)
1792 cpassert(qs_ot_env(ispin)%kpoint_weight > 0.0_dp)
1793 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_gx_old, &
1795 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_gx_old_im, &
1798 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1800 qs_ot_env(ispin)%matrix_preconditioned_gx, &
1801 qs_ot_env(ispin)%matrix_gx_old)
1804 qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx_old)
1808 qs_ot_env(1)%gnorm = 0.0_dp
1811 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx_old, tmp)
1812 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1813 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1814 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, qs_ot_env(ispin)%matrix_gx_old_im, tmp)
1815 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1818 IF (.NOT. qs_ot_env(1)%settings%occupation_preconditioner)
THEN
1820 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx_old)
1821 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1822 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_im, &
1823 qs_ot_env(ispin)%matrix_gx_old_im)
1827 IF (qs_ot_env(1)%settings%do_rotation)
THEN
1829 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx_old, qs_ot_env(ispin)%rot_mat_gx)
1830 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_gx_old, tmp)
1832 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
1833 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1834 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx_old_im, &
1835 qs_ot_env(ispin)%rot_mat_gx_im)
1836 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
1837 qs_ot_env(ispin)%rot_mat_gx_old_im, tmp)
1838 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
1845 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1846 qs_ot_env(ispin)%ener_gx_old = qs_ot_env(ispin)%ener_preconditioned_gx
1848 qs_ot_env(ispin)%ener_gx_old = qs_ot_env(ispin)%ener_gx
1850 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_gx_old)
1851 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1856 qs_ot_env(1)%gnorm = 0.0_dp
1858 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1859 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, &
1860 qs_ot_env(ispin)%matrix_preconditioned_gx, tmp)
1862 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx, tmp)
1864 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1865 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1866 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_old, &
1867 qs_ot_env(ispin)%matrix_preconditioned_gx)
1869 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_old, qs_ot_env(ispin)%matrix_gx)
1871 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1872 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1873 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, &
1874 qs_ot_env(ispin)%matrix_preconditioned_gx_im, tmp)
1876 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, qs_ot_env(ispin)%matrix_gx_im, tmp)
1878 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1879 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1880 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_old_im, &
1881 qs_ot_env(ispin)%matrix_preconditioned_gx_im)
1883 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_old_im, qs_ot_env(ispin)%matrix_gx_im)
1887 IF (qs_ot_env(1)%settings%do_rotation)
THEN
1889 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_gx, tmp)
1891 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
1892 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx_old, qs_ot_env(ispin)%rot_mat_gx)
1893 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1894 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
1895 qs_ot_env(ispin)%rot_mat_gx_im, tmp)
1896 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
1897 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx_old_im, &
1898 qs_ot_env(ispin)%rot_mat_gx_im)
1905 IF (qs_ot_env(ispin)%settings%occupation_preconditioner)
THEN
1906 tmp = dot_product(qs_ot_env(ispin)%ener_gx, &
1907 qs_ot_env(ispin)%ener_preconditioned_gx)
1908 qs_ot_env(ispin)%ener_gx_old = qs_ot_env(ispin)%ener_preconditioned_gx
1910 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_gx)
1911 qs_ot_env(ispin)%ener_gx_old = qs_ot_env(ispin)%ener_gx
1913 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1918 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, qs_ot_env(1)%gnorm)
1919 IF (
ASSOCIATED(qs_ot_env(1)%preconditioner) .AND. &
1920 .NOT. qs_ot_env(1)%settings%occupation_preconditioner .AND. &
1921 qs_ot_env(1)%gnorm < 0.0_dp)
THEN
1928 IF (qs_ot_env(1)%settings%occupation_preconditioner .AND. qs_ot_env(1)%gnorm <= 0.0_dp)
THEN
1929 qs_ot_env(1)%gnorm = 0.0_dp
1932 IF (
ASSOCIATED(qs_ot_env(1)%preconditioner))
THEN
1933 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1935 qs_ot_env(ispin)%matrix_gx, &
1936 qs_ot_env(ispin)%matrix_gx_im, &
1937 qs_ot_env(ispin)%matrix_gx_old, &
1938 qs_ot_env(ispin)%matrix_gx_old_im)
1939 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_gx_old, &
1941 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_gx_old_im, &
1945 qs_ot_env(ispin)%matrix_gx, &
1946 qs_ot_env(ispin)%matrix_gx_old)
1949 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_old, qs_ot_env(ispin)%matrix_gx)
1950 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1951 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_old_im, &
1952 qs_ot_env(ispin)%matrix_gx_im)
1955 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx_old, tmp)
1956 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1957 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1958 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, &
1959 qs_ot_env(ispin)%matrix_gx_old_im, tmp)
1960 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + tmp
1962 IF (qs_ot_env(1)%settings%do_rotation)
THEN
1963 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx_old, qs_ot_env(ispin)%rot_mat_gx)
1964 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_gx_old, tmp)
1965 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
1966 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
1967 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx_old_im, &
1968 qs_ot_env(ispin)%rot_mat_gx_im)
1969 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
1970 qs_ot_env(ispin)%rot_mat_gx_old_im, tmp)
1971 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + 0.5_dp*tmp
1978 qs_ot_env(ispin)%ener_gx_old = qs_ot_env(ispin)%ener_gx
1979 qs_ot_env(1)%gnorm = qs_ot_env(1)%gnorm + &
1980 dot_product(qs_ot_env(ispin)%ener_gx, &
1981 qs_ot_env(ispin)%ener_gx_old)
1984 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, qs_ot_env(1)%gnorm)
1986 baseline_gnorm = qs_ot_env(1)%gnorm
1994 CALL dbcsr_get_info(qs_ot_env(ispin)%matrix_x, nfullcols_total=itmp)
1996 IF (qs_ot_env(ispin)%has_complex_kpoint_state) k = k + itmp
2001 nener = nener +
SIZE(qs_ot_env(ispin)%ener_x)
2004 nvariables = real(int(n, kind=
int_8)*int(k, kind=
int_8) + nener, kind=
dp)
2005 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, nvariables)
2007 baseline_delta = 0.0_dp
2008 IF (nvariables > 0.0_dp)
THEN
2009 baseline_delta = sqrt(abs(baseline_gnorm)/nvariables)
2014 qs_ot_env(1)%delta = baseline_delta
2015 IF (nvariables > 0.0_dp)
THEN
2016 beta_pr = (qs_ot_env(1)%gnorm - gnorm_cross)/qs_ot_env(1)%gnorm_old
2020 IF (preceding_response_candidate) beta_pr = 0.0_dp
2022 qs_ot_env(1)%settings%occupation_preconditioner, qs_ot_env(1)%etotal, &
2023 qs_ot_env(1)%response_reference_energy)) beta_pr = 0.0_dp
2024 beta_pr = max(beta_pr, 0.0_dp)
2029 CALL dbcsr_add(qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin)%matrix_gx_old, &
2030 alpha_scalar=beta_pr, beta_scalar=-1.0_dp)
2031 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_dx, tmp)
2032 test_down = test_down + tmp
2033 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2034 CALL dbcsr_add(qs_ot_env(ispin)%matrix_dx_im, qs_ot_env(ispin)%matrix_gx_old_im, &
2035 alpha_scalar=beta_pr, beta_scalar=-1.0_dp)
2036 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, qs_ot_env(ispin)%matrix_dx_im, tmp)
2037 test_down = test_down + tmp
2039 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2040 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_dx, qs_ot_env(ispin)%rot_mat_gx_old, &
2041 alpha_scalar=beta_pr, beta_scalar=-1.0_dp)
2042 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_dx, tmp)
2043 test_down = test_down + 0.5_dp*tmp
2044 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2045 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_dx_im, &
2046 qs_ot_env(ispin)%rot_mat_gx_old_im, &
2047 alpha_scalar=beta_pr, beta_scalar=-1.0_dp)
2048 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
2049 qs_ot_env(ispin)%rot_mat_dx_im, tmp)
2050 test_down = test_down + 0.5_dp*tmp
2057 qs_ot_env(ispin)%ener_dx = beta_pr*qs_ot_env(ispin)%ener_dx - &
2058 qs_ot_env(ispin)%ener_gx_old
2059 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_dx)
2060 test_down = test_down + tmp
2063 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, test_down)
2065 IF (test_down >= 0.0_dp)
THEN
2069 CALL dbcsr_add(qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin)%matrix_gx_old, &
2070 alpha_scalar=beta_pr, beta_scalar=-1.0_dp)
2071 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2072 CALL dbcsr_add(qs_ot_env(ispin)%matrix_dx_im, qs_ot_env(ispin)%matrix_gx_old_im, &
2073 alpha_scalar=beta_pr, beta_scalar=-1.0_dp)
2075 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2076 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_dx, &
2077 qs_ot_env(ispin)%rot_mat_gx_old, &
2078 alpha_scalar=beta_pr, beta_scalar=-1.0_dp)
2079 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2080 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_dx_im, &
2081 qs_ot_env(ispin)%rot_mat_gx_old_im, &
2082 alpha_scalar=beta_pr, beta_scalar=-1.0_dp)
2089 qs_ot_env(ispin)%ener_dx = beta_pr*qs_ot_env(ispin)%ener_dx - &
2090 qs_ot_env(ispin)%ener_gx_old
2095 CALL ot_try_mermin_response_direction( &
2096 qs_ot_env, para_env_inter_kp, baseline_delta, test_down, use_response_candidate)
2098 IF (use_response_candidate)
THEN
2099 qs_ot_env(1)%OT_METHOD_FULL =
"OT CG-R"
2100 qs_ot_env(1)%gradient = test_down
2102 qs_ot_env(1)%gradient = beta_pr*qs_ot_env(1)%gradient - qs_ot_env(1)%gnorm
2104 qs_ot_env(1)%gnorm_old = qs_ot_env(1)%gnorm
2106 CALL timestop(handle)
2108 END SUBROUTINE ot_new_cg_direction
2119 REAL(kind=
dp),
INTENT(IN) :: sy, ss, yy, curvature_tol
2120 REAL(kind=
dp) :: damping_shift
2122 REAL(kind=
dp) :: curvature_discriminant, target_sy
2124 damping_shift = 0.0_dp
2125 IF (.NOT. ieee_is_finite(sy) .OR. .NOT. ieee_is_finite(ss) .OR. &
2126 .NOT. ieee_is_finite(yy) .OR. ss <= 0.0_dp .OR. yy <= 0.0_dp .OR. &
2127 curvature_tol < 0.0_dp .OR. curvature_tol >= 1.0_dp)
RETURN
2129 curvature_discriminant = max(0.0_dp, ss*yy - sy*sy)
2130 target_sy = curvature_tol/sqrt(max(tiny(1.0_dp), 1.0_dp - curvature_tol**2))* &
2131 sqrt(curvature_discriminant)
2132 IF (sy <= target_sy)
THEN
2133 target_sy = target_sy*(1.0_dp + sqrt(epsilon(1.0_dp)))
2134 damping_shift = max(0.0_dp, (target_sy - sy)/ss)
2135 IF (.NOT. ieee_is_finite(damping_shift)) damping_shift = 0.0_dp
2146 previous_gradient_norm_sq)
RESULT(restart_history)
2147 REAL(kind=
dp),
INTENT(IN) :: current_gradient_norm_sq, &
2148 previous_gradient_norm_sq
2149 LOGICAL :: restart_history
2151 REAL(kind=
dp),
PARAMETER :: gradient_restart_factor = 10.0_dp
2153 restart_history = ieee_is_finite(current_gradient_norm_sq) .AND. &
2154 ieee_is_finite(previous_gradient_norm_sq) .AND. &
2155 previous_gradient_norm_sq > tiny(1.0_dp) .AND. &
2156 current_gradient_norm_sq > gradient_restart_factor**2* &
2157 previous_gradient_norm_sq
2167 REAL(kind=
dp),
INTENT(IN) :: accepted_step, reference_step
2168 LOGICAL :: restart_step
2170 REAL(kind=
dp),
PARAMETER :: step_restart_factor = 1.0e-6_dp
2172 restart_step = ieee_is_finite(accepted_step) .AND. &
2173 ieee_is_finite(reference_step) .AND. &
2174 reference_step > 0.0_dp .AND. &
2175 abs(accepted_step) < step_restart_factor*reference_step
2194 g_dot_response, response_norm_sq, g_dot_h0_g, h0_g_norm_sq, &
2195 response_scale, response_weight, valid)
2196 REAL(kind=
dp),
INTENT(IN) :: g_dot_response, response_norm_sq, &
2197 g_dot_h0_g, h0_g_norm_sq
2198 REAL(kind=
dp),
INTENT(OUT) :: response_scale, response_weight
2199 LOGICAL,
INTENT(OUT) :: valid
2201 REAL(kind=
dp),
PARAMETER :: powell_fraction = 0.2_dp
2203 REAL(kind=
dp) :: scaled_curvature
2205 response_scale = 1.0_dp
2206 response_weight = 0.0_dp
2207 valid = ieee_is_finite(g_dot_response) .AND. &
2208 ieee_is_finite(response_norm_sq) .AND. &
2209 ieee_is_finite(g_dot_h0_g) .AND. &
2210 ieee_is_finite(h0_g_norm_sq) .AND. &
2211 g_dot_response > 0.0_dp .AND. &
2212 response_norm_sq > tiny(1.0_dp) .AND. &
2213 g_dot_h0_g > 0.0_dp .AND. &
2214 h0_g_norm_sq > tiny(1.0_dp)
2215 IF (.NOT. valid)
RETURN
2217 response_scale = sqrt(h0_g_norm_sq/response_norm_sq)
2218 scaled_curvature = response_scale*g_dot_response
2219 IF (.NOT. ieee_is_finite(response_scale) .OR. &
2220 .NOT. ieee_is_finite(scaled_curvature) .OR. scaled_curvature <= 0.0_dp)
THEN
2221 response_scale = 1.0_dp
2226 response_weight = 1.0_dp
2227 IF (scaled_curvature < powell_fraction*g_dot_h0_g)
THEN
2228 response_weight = (1.0_dp - powell_fraction)*g_dot_h0_g/ &
2229 (g_dot_h0_g - scaled_curvature)
2251 SUBROUTINE ot_apply_lbfgs_initial_inverse( &
2252 qs_ot_env, gamma, gamma_rotation, scratch_index, para_env_inter_kp)
2253 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
2254 REAL(kind=
dp),
INTENT(IN) ::
gamma, gamma_rotation
2255 INTEGER,
INTENT(IN) :: scratch_index
2259 LOGICAL :: valid_response
2260 REAL(kind=
dp) :: coeff_p, coeff_v, g_dot_h0_g, g_dot_h0_q, g_dot_p, h0_g_norm_sq, &
2261 kpoint_scale, p_dot_q, p_norm_sq, response_scale, response_weight, rho, tmp
2264 DO ispin = 1,
SIZE(qs_ot_env)
2265 IF (
ASSOCIATED(qs_ot_env(1)%preconditioner))
THEN
2266 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2268 qs_ot_env(ispin)%matrix_gx_old, &
2269 qs_ot_env(ispin)%matrix_gx_old_im, &
2270 qs_ot_env(ispin)%matrix_dx, &
2271 qs_ot_env(ispin)%matrix_dx_im)
2272 cpassert(qs_ot_env(ispin)%kpoint_weight > 0.0_dp)
2274 qs_ot_env(ispin)%kpoint_weight)
2275 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_dx, kpoint_scale)
2276 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_dx_im, kpoint_scale)
2279 qs_ot_env(ispin)%matrix_gx_old, &
2280 qs_ot_env(ispin)%matrix_dx)
2283 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin)%matrix_gx_old)
2285 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2286 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_dx_im, &
2287 qs_ot_env(ispin)%matrix_gx_old_im)
2291 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2292 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx, qs_ot_env(ispin)%rot_mat_gx_old)
2293 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_dx, gamma_rotation)
2294 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2295 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx_im, &
2296 qs_ot_env(ispin)%rot_mat_gx_old_im)
2297 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_dx_im, gamma_rotation)
2300 IF (qs_ot_env(1)%settings%do_ener)
THEN
2301 qs_ot_env(ispin)%ener_dx =
gamma*qs_ot_env(ispin)%ener_gx_old
2304 IF (.NOT. qs_ot_env(1)%settings%occupation_preconditioner)
RETURN
2307 DO ispin = 1,
SIZE(qs_ot_env)
2308 cpassert(
ASSOCIATED(qs_ot_env(ispin)%matrix_preconditioned_gx))
2309 IF (
ASSOCIATED(qs_ot_env(1)%preconditioner))
THEN
2310 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2311 cpassert(
ASSOCIATED(qs_ot_env(ispin)%matrix_preconditioned_gx_im))
2313 qs_ot_env(ispin)%matrix_preconditioned_gx, &
2314 qs_ot_env(ispin)%matrix_preconditioned_gx_im, &
2315 qs_ot_env(ispin)%matrix_h_e(scratch_index)%matrix, &
2316 qs_ot_env(ispin)%matrix_h_e_im(scratch_index)%matrix)
2318 qs_ot_env(ispin)%kpoint_weight)
2319 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_h_e(scratch_index)%matrix, &
2321 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_h_e_im(scratch_index)%matrix, &
2325 qs_ot_env(ispin)%matrix_preconditioned_gx, &
2326 qs_ot_env(ispin)%matrix_h_e(scratch_index)%matrix)
2329 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_e(scratch_index)%matrix, &
2330 qs_ot_env(ispin)%matrix_preconditioned_gx)
2331 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2332 cpassert(
ASSOCIATED(qs_ot_env(ispin)%matrix_preconditioned_gx_im))
2333 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_e_im(scratch_index)%matrix, &
2334 qs_ot_env(ispin)%matrix_preconditioned_gx_im)
2337 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2338 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_e(scratch_index)%matrix, &
2339 qs_ot_env(ispin)%rot_mat_gx)
2340 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_h_e(scratch_index)%matrix, &
2342 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2343 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_e_im(scratch_index)%matrix, &
2344 qs_ot_env(ispin)%rot_mat_gx_im)
2345 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_h_e_im(scratch_index)%matrix, &
2349 IF (qs_ot_env(1)%settings%do_ener)
THEN
2350 cpassert(
ASSOCIATED(qs_ot_env(ispin)%ener_preconditioned_gx))
2351 qs_ot_env(ispin)%ener_h_e(scratch_index, :) = &
2352 qs_ot_env(ispin)%ener_preconditioned_gx
2360 DO ispin = 1,
SIZE(qs_ot_env)
2361 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_dx, tmp)
2362 g_dot_h0_q = g_dot_h0_q + tmp
2363 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, &
2364 qs_ot_env(ispin)%matrix_h_e(scratch_index)%matrix, tmp)
2365 g_dot_p = g_dot_p + tmp
2366 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_e(scratch_index)%matrix, &
2367 qs_ot_env(ispin)%matrix_gx_old, tmp)
2368 p_dot_q = p_dot_q + tmp
2369 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_e(scratch_index)%matrix, &
2370 qs_ot_env(ispin)%matrix_h_e(scratch_index)%matrix, tmp)
2371 p_norm_sq = p_norm_sq + tmp
2372 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2373 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, &
2374 qs_ot_env(ispin)%matrix_dx_im, tmp)
2375 g_dot_h0_q = g_dot_h0_q + tmp
2376 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, &
2377 qs_ot_env(ispin)%matrix_h_e_im(scratch_index)%matrix, tmp)
2378 g_dot_p = g_dot_p + tmp
2379 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_e_im(scratch_index)%matrix, &
2380 qs_ot_env(ispin)%matrix_gx_old_im, tmp)
2381 p_dot_q = p_dot_q + tmp
2382 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_e_im(scratch_index)%matrix, &
2383 qs_ot_env(ispin)%matrix_h_e_im(scratch_index)%matrix, tmp)
2384 p_norm_sq = p_norm_sq + tmp
2386 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2387 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, &
2388 qs_ot_env(ispin)%rot_mat_dx, tmp)
2389 g_dot_h0_q = g_dot_h0_q + 0.5_dp*tmp
2390 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, &
2391 qs_ot_env(ispin)%rot_mat_h_e(scratch_index)%matrix, tmp)
2392 g_dot_p = g_dot_p + 0.5_dp*tmp
2393 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_e(scratch_index)%matrix, &
2394 qs_ot_env(ispin)%rot_mat_gx_old, tmp)
2395 p_dot_q = p_dot_q + 0.5_dp*tmp
2396 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_e(scratch_index)%matrix, &
2397 qs_ot_env(ispin)%rot_mat_h_e(scratch_index)%matrix, tmp)
2398 p_norm_sq = p_norm_sq + 0.5_dp*tmp
2399 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2400 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
2401 qs_ot_env(ispin)%rot_mat_dx_im, tmp)
2402 g_dot_h0_q = g_dot_h0_q + 0.5_dp*tmp
2403 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
2404 qs_ot_env(ispin)%rot_mat_h_e_im(scratch_index)%matrix, tmp)
2405 g_dot_p = g_dot_p + 0.5_dp*tmp
2406 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_e_im(scratch_index)%matrix, &
2407 qs_ot_env(ispin)%rot_mat_gx_old_im, tmp)
2408 p_dot_q = p_dot_q + 0.5_dp*tmp
2409 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_e_im(scratch_index)%matrix, &
2410 qs_ot_env(ispin)%rot_mat_h_e_im(scratch_index)%matrix, tmp)
2411 p_norm_sq = p_norm_sq + 0.5_dp*tmp
2414 IF (qs_ot_env(1)%settings%do_ener)
THEN
2415 g_dot_h0_q = g_dot_h0_q + &
2416 dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_dx)
2417 g_dot_p = g_dot_p + dot_product(qs_ot_env(ispin)%ener_gx, &
2418 qs_ot_env(ispin)%ener_h_e(scratch_index, :))
2419 p_dot_q = p_dot_q + dot_product(qs_ot_env(ispin)%ener_h_e(scratch_index, :), &
2420 qs_ot_env(ispin)%ener_gx_old)
2421 p_norm_sq = p_norm_sq + dot_product( &
2422 qs_ot_env(ispin)%ener_h_e(scratch_index, :), &
2423 qs_ot_env(ispin)%ener_h_e(scratch_index, :))
2426 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, g_dot_h0_q)
2427 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, g_dot_p)
2428 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, p_dot_q)
2429 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, p_norm_sq)
2433 h0_g_norm_sq = 0.0_dp
2434 DO ispin = 1,
SIZE(qs_ot_env)
2435 IF (
ASSOCIATED(qs_ot_env(1)%preconditioner))
THEN
2436 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2438 qs_ot_env(ispin)%matrix_gx, &
2439 qs_ot_env(ispin)%matrix_gx_im, &
2440 qs_ot_env(ispin)%matrix_gx_old, &
2441 qs_ot_env(ispin)%matrix_gx_old_im)
2443 qs_ot_env(ispin)%kpoint_weight)
2444 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_gx_old, kpoint_scale)
2445 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_gx_old_im, kpoint_scale)
2448 qs_ot_env(ispin)%matrix_gx, &
2449 qs_ot_env(ispin)%matrix_gx_old)
2452 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_old, qs_ot_env(ispin)%matrix_gx)
2454 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2455 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_old_im, qs_ot_env(ispin)%matrix_gx_im)
2459 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx_old, tmp)
2460 g_dot_h0_g = g_dot_h0_g + tmp
2461 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_old, &
2462 qs_ot_env(ispin)%matrix_gx_old, tmp)
2463 h0_g_norm_sq = h0_g_norm_sq + tmp
2464 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2465 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, &
2466 qs_ot_env(ispin)%matrix_gx_old_im, tmp)
2467 g_dot_h0_g = g_dot_h0_g + tmp
2468 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_old_im, &
2469 qs_ot_env(ispin)%matrix_gx_old_im, tmp)
2470 h0_g_norm_sq = h0_g_norm_sq + tmp
2472 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2473 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx_old, qs_ot_env(ispin)%rot_mat_gx)
2474 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_gx_old, gamma_rotation)
2475 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, &
2476 qs_ot_env(ispin)%rot_mat_gx_old, tmp)
2477 g_dot_h0_g = g_dot_h0_g + 0.5_dp*tmp
2478 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_old, &
2479 qs_ot_env(ispin)%rot_mat_gx_old, tmp)
2480 h0_g_norm_sq = h0_g_norm_sq + 0.5_dp*tmp
2481 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2482 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx_old_im, &
2483 qs_ot_env(ispin)%rot_mat_gx_im)
2484 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_gx_old_im, gamma_rotation)
2485 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
2486 qs_ot_env(ispin)%rot_mat_gx_old_im, tmp)
2487 g_dot_h0_g = g_dot_h0_g + 0.5_dp*tmp
2488 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_old_im, &
2489 qs_ot_env(ispin)%rot_mat_gx_old_im, tmp)
2490 h0_g_norm_sq = h0_g_norm_sq + 0.5_dp*tmp
2493 IF (qs_ot_env(1)%settings%do_ener)
THEN
2494 qs_ot_env(ispin)%ener_gx_old =
gamma*qs_ot_env(ispin)%ener_gx
2495 g_dot_h0_g = g_dot_h0_g + &
2496 dot_product(qs_ot_env(ispin)%ener_gx, &
2497 qs_ot_env(ispin)%ener_gx_old)
2498 h0_g_norm_sq = h0_g_norm_sq + &
2499 dot_product(qs_ot_env(ispin)%ener_gx_old, &
2500 qs_ot_env(ispin)%ener_gx_old)
2503 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, g_dot_h0_g)
2504 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, h0_g_norm_sq)
2507 g_dot_p, p_norm_sq, g_dot_h0_g, h0_g_norm_sq, &
2508 response_scale, response_weight, valid_response)
2509 IF (.NOT. valid_response)
RETURN
2512 DO ispin = 1,
SIZE(qs_ot_env)
2513 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_h_e(scratch_index)%matrix, &
2514 response_weight*response_scale)
2515 CALL dbcsr_add(qs_ot_env(ispin)%matrix_h_e(scratch_index)%matrix, &
2516 qs_ot_env(ispin)%matrix_gx_old, &
2517 alpha_scalar=1.0_dp, beta_scalar=1.0_dp - response_weight)
2518 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2519 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_h_e_im(scratch_index)%matrix, &
2520 response_weight*response_scale)
2521 CALL dbcsr_add(qs_ot_env(ispin)%matrix_h_e_im(scratch_index)%matrix, &
2522 qs_ot_env(ispin)%matrix_gx_old_im, &
2523 alpha_scalar=1.0_dp, beta_scalar=1.0_dp - response_weight)
2525 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2526 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_h_e(scratch_index)%matrix, &
2527 response_weight*response_scale)
2528 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_h_e(scratch_index)%matrix, &
2529 qs_ot_env(ispin)%rot_mat_gx_old, &
2530 alpha_scalar=1.0_dp, beta_scalar=1.0_dp - response_weight)
2531 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2532 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_h_e_im(scratch_index)%matrix, &
2533 response_weight*response_scale)
2534 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_h_e_im(scratch_index)%matrix, &
2535 qs_ot_env(ispin)%rot_mat_gx_old_im, &
2536 alpha_scalar=1.0_dp, beta_scalar=1.0_dp - response_weight)
2539 IF (qs_ot_env(1)%settings%do_ener)
THEN
2540 qs_ot_env(ispin)%ener_h_e(scratch_index, :) = &
2541 response_weight*response_scale*qs_ot_env(ispin)%ener_h_e(scratch_index, :) + &
2542 (1.0_dp - response_weight)*qs_ot_env(ispin)%ener_gx_old
2545 g_dot_p = response_weight*response_scale*g_dot_p + &
2546 (1.0_dp - response_weight)*g_dot_h0_g
2547 p_dot_q = response_weight*response_scale*p_dot_q + &
2548 (1.0_dp - response_weight)*g_dot_h0_q
2550 rho = 1.0_dp/g_dot_p
2551 coeff_p = -rho*g_dot_h0_q + p_dot_q*(rho + rho*rho*g_dot_h0_g)
2552 coeff_v = -rho*p_dot_q
2553 DO ispin = 1,
SIZE(qs_ot_env)
2554 CALL dbcsr_add(qs_ot_env(ispin)%matrix_dx, &
2555 qs_ot_env(ispin)%matrix_h_e(scratch_index)%matrix, &
2556 alpha_scalar=1.0_dp, beta_scalar=coeff_p)
2557 CALL dbcsr_add(qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin)%matrix_gx_old, &
2558 alpha_scalar=1.0_dp, beta_scalar=coeff_v)
2559 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2560 CALL dbcsr_add(qs_ot_env(ispin)%matrix_dx_im, &
2561 qs_ot_env(ispin)%matrix_h_e_im(scratch_index)%matrix, &
2562 alpha_scalar=1.0_dp, beta_scalar=coeff_p)
2563 CALL dbcsr_add(qs_ot_env(ispin)%matrix_dx_im, &
2564 qs_ot_env(ispin)%matrix_gx_old_im, &
2565 alpha_scalar=1.0_dp, beta_scalar=coeff_v)
2567 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2568 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_dx, &
2569 qs_ot_env(ispin)%rot_mat_h_e(scratch_index)%matrix, &
2570 alpha_scalar=1.0_dp, beta_scalar=coeff_p)
2571 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_dx, qs_ot_env(ispin)%rot_mat_gx_old, &
2572 alpha_scalar=1.0_dp, beta_scalar=coeff_v)
2573 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2574 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_dx_im, &
2575 qs_ot_env(ispin)%rot_mat_h_e_im(scratch_index)%matrix, &
2576 alpha_scalar=1.0_dp, beta_scalar=coeff_p)
2577 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_dx_im, &
2578 qs_ot_env(ispin)%rot_mat_gx_old_im, &
2579 alpha_scalar=1.0_dp, beta_scalar=coeff_v)
2582 IF (qs_ot_env(1)%settings%do_ener)
THEN
2583 qs_ot_env(ispin)%ener_dx = qs_ot_env(ispin)%ener_dx + &
2584 coeff_p*qs_ot_env(ispin)%ener_h_e(scratch_index, :) + &
2585 coeff_v*qs_ot_env(ispin)%ener_gx_old
2588 END SUBROUTINE ot_apply_lbfgs_initial_inverse
2602 SUBROUTINE ot_new_lbfgs_direction(qs_ot_env, para_env_inter_kp)
2603 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
2606 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_new_lbfgs_direction'
2607 REAL(kind=
dp),
PARAMETER :: rotation_scale_max = 1.0e3_dp, &
2608 rotation_scale_min = 1.0e-3_dp
2610 INTEGER :: handle, i, ispin, itmp, j, k, m_history, &
2611 n, nener, newest, nhistory, nspin
2612 INTEGER(KIND=int_8) :: nrotation, nvariables
2613 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: history_index
2614 LOGICAL :: do_ener, preceding_response_candidate, &
2615 restart_history, restart_step, &
2616 use_response_candidate
2617 REAL(kind=
dp) :: beta, current_gradient_norm_sq, curvature_tol, damping_shift, g_dot_z, &
2618 gamma, gamma_rotation, nvariables_global, previous_gradient_norm_sq, ss, ss_rotation, &
2619 stq, sy, sy_rotation, test_down, tmp, yy, yy_newest, yy_rotation
2620 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: alpha, rho
2622 CALL timeset(routinen, handle)
2624 IF (.NOT. qs_ot_env(1)%settings%ks)
THEN
2625 cpabort(
"MINIMIZER LBFGS currently requires OT orbital variables")
2627 nspin =
SIZE(qs_ot_env)
2628 do_ener = qs_ot_env(1)%settings%do_ener
2629 m_history = qs_ot_env(1)%settings%diis_m
2630 curvature_tol = qs_ot_env(1)%settings%lbfgs_curvature_tol
2631 restart_history = .false.
2632 restart_step = .false.
2633 preceding_response_candidate = qs_ot_env(1)%response_candidate_pending
2641 IF (qs_ot_env(1)%diis_iter > 0)
THEN
2642 current_gradient_norm_sq = 0.0_dp
2643 previous_gradient_norm_sq = 0.0_dp
2645 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_gx, tmp)
2646 current_gradient_norm_sq = current_gradient_norm_sq + tmp
2647 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_e(m_history + 1)%matrix, &
2648 qs_ot_env(ispin)%matrix_h_e(m_history + 1)%matrix, tmp)
2649 previous_gradient_norm_sq = previous_gradient_norm_sq + tmp
2650 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2651 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, &
2652 qs_ot_env(ispin)%matrix_gx_im, tmp)
2653 current_gradient_norm_sq = current_gradient_norm_sq + tmp
2654 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_e_im(m_history + 1)%matrix, &
2655 qs_ot_env(ispin)%matrix_h_e_im(m_history + 1)%matrix, tmp)
2656 previous_gradient_norm_sq = previous_gradient_norm_sq + tmp
2658 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2659 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_gx, tmp)
2660 current_gradient_norm_sq = current_gradient_norm_sq + 0.5_dp*tmp
2661 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_e(m_history + 1)%matrix, &
2662 qs_ot_env(ispin)%rot_mat_h_e(m_history + 1)%matrix, tmp)
2663 previous_gradient_norm_sq = previous_gradient_norm_sq + 0.5_dp*tmp
2664 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2665 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
2666 qs_ot_env(ispin)%rot_mat_gx_im, tmp)
2667 current_gradient_norm_sq = current_gradient_norm_sq + 0.5_dp*tmp
2668 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_e_im(m_history + 1)%matrix, &
2669 qs_ot_env(ispin)%rot_mat_h_e_im(m_history + 1)%matrix, tmp)
2670 previous_gradient_norm_sq = previous_gradient_norm_sq + 0.5_dp*tmp
2674 tmp = dot_product(qs_ot_env(ispin)%ener_gx, qs_ot_env(ispin)%ener_gx)
2675 current_gradient_norm_sq = current_gradient_norm_sq + tmp
2676 tmp = dot_product(qs_ot_env(ispin)%ener_h_e(m_history + 1, :), &
2677 qs_ot_env(ispin)%ener_h_e(m_history + 1, :))
2678 previous_gradient_norm_sq = previous_gradient_norm_sq + tmp
2681 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, current_gradient_norm_sq)
2682 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, previous_gradient_norm_sq)
2684 qs_ot_env(1)%settings%ds_min)
2686 previous_gradient_norm_sq) .OR. &
2687 restart_step .OR. preceding_response_candidate
2688 IF (restart_history)
THEN
2689 qs_ot_env(1)%diis_iter = 1
2690 IF (restart_step) qs_ot_env(1)%ds_min = qs_ot_env(1)%settings%ds_min
2691 qs_ot_env(1)%OT_METHOD_FULL =
"OT L-RST"
2698 IF (qs_ot_env(1)%diis_iter > 0 .AND. .NOT. restart_history)
THEN
2699 j = mod(qs_ot_env(1)%diis_iter - 1, m_history) + 1
2702 sy_rotation = 0.0_dp
2703 ss_rotation = 0.0_dp
2705 yy_rotation = 0.0_dp
2707 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin)%matrix_x)
2708 CALL dbcsr_add(qs_ot_env(ispin)%matrix_dx, &
2709 qs_ot_env(ispin)%matrix_h_x(m_history + 1)%matrix, &
2710 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2711 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_old, qs_ot_env(ispin)%matrix_gx)
2712 CALL dbcsr_add(qs_ot_env(ispin)%matrix_gx_old, &
2713 qs_ot_env(ispin)%matrix_h_e(m_history + 1)%matrix, &
2714 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2715 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin)%matrix_dx, tmp)
2717 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin)%matrix_gx_old, tmp)
2719 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_old, qs_ot_env(ispin)%matrix_gx_old, tmp)
2721 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2722 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_dx_im, qs_ot_env(ispin)%matrix_x_im)
2723 CALL dbcsr_add(qs_ot_env(ispin)%matrix_dx_im, &
2724 qs_ot_env(ispin)%matrix_h_x_im(m_history + 1)%matrix, &
2725 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2726 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_old_im, qs_ot_env(ispin)%matrix_gx_im)
2727 CALL dbcsr_add(qs_ot_env(ispin)%matrix_gx_old_im, &
2728 qs_ot_env(ispin)%matrix_h_e_im(m_history + 1)%matrix, &
2729 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2730 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_dx_im, &
2731 qs_ot_env(ispin)%matrix_dx_im, tmp)
2733 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_dx_im, &
2734 qs_ot_env(ispin)%matrix_gx_old_im, tmp)
2736 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_old_im, &
2737 qs_ot_env(ispin)%matrix_gx_old_im, tmp)
2740 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2741 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx, qs_ot_env(ispin)%rot_mat_x)
2742 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_dx, &
2743 qs_ot_env(ispin)%rot_mat_h_x(m_history + 1)%matrix, &
2744 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2745 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx_old, qs_ot_env(ispin)%rot_mat_gx)
2746 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_gx_old, &
2747 qs_ot_env(ispin)%rot_mat_h_e(m_history + 1)%matrix, &
2748 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2749 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_dx, qs_ot_env(ispin)%rot_mat_dx, tmp)
2750 ss = ss + 0.5_dp*tmp
2751 ss_rotation = ss_rotation + 0.5_dp*tmp
2752 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_dx, qs_ot_env(ispin)%rot_mat_gx_old, tmp)
2753 sy = sy + 0.5_dp*tmp
2754 sy_rotation = sy_rotation + 0.5_dp*tmp
2755 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_old, qs_ot_env(ispin)%rot_mat_gx_old, tmp)
2756 yy = yy + 0.5_dp*tmp
2757 yy_rotation = yy_rotation + 0.5_dp*tmp
2758 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2759 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx_im, qs_ot_env(ispin)%rot_mat_x_im)
2760 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_dx_im, &
2761 qs_ot_env(ispin)%rot_mat_h_x_im(m_history + 1)%matrix, &
2762 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2763 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx_old_im, &
2764 qs_ot_env(ispin)%rot_mat_gx_im)
2765 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_gx_old_im, &
2766 qs_ot_env(ispin)%rot_mat_h_e_im(m_history + 1)%matrix, &
2767 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
2768 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_dx_im, &
2769 qs_ot_env(ispin)%rot_mat_dx_im, tmp)
2770 ss = ss + 0.5_dp*tmp
2771 ss_rotation = ss_rotation + 0.5_dp*tmp
2772 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_dx_im, &
2773 qs_ot_env(ispin)%rot_mat_gx_old_im, tmp)
2774 sy = sy + 0.5_dp*tmp
2775 sy_rotation = sy_rotation + 0.5_dp*tmp
2776 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_old_im, &
2777 qs_ot_env(ispin)%rot_mat_gx_old_im, tmp)
2778 yy = yy + 0.5_dp*tmp
2779 yy_rotation = yy_rotation + 0.5_dp*tmp
2783 qs_ot_env(ispin)%ener_dx = qs_ot_env(ispin)%ener_x - &
2784 qs_ot_env(ispin)%ener_h_x(m_history + 1, :)
2785 qs_ot_env(ispin)%ener_gx_old = qs_ot_env(ispin)%ener_gx - &
2786 qs_ot_env(ispin)%ener_h_e(m_history + 1, :)
2787 ss = ss + dot_product(qs_ot_env(ispin)%ener_dx, qs_ot_env(ispin)%ener_dx)
2788 sy = sy + dot_product(qs_ot_env(ispin)%ener_dx, qs_ot_env(ispin)%ener_gx_old)
2789 yy = yy + dot_product(qs_ot_env(ispin)%ener_gx_old, qs_ot_env(ispin)%ener_gx_old)
2792 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, ss)
2793 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, sy)
2794 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, yy)
2795 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, ss_rotation)
2796 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, sy_rotation)
2797 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, yy_rotation)
2802 damping_shift = 0.0_dp
2803 IF (qs_ot_env(1)%settings%lbfgs_damping)
THEN
2806 IF (damping_shift > 0.0_dp)
THEN
2808 CALL dbcsr_add(qs_ot_env(ispin)%matrix_gx_old, &
2809 qs_ot_env(ispin)%matrix_dx, &
2810 alpha_scalar=1.0_dp, beta_scalar=damping_shift)
2811 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2812 CALL dbcsr_add(qs_ot_env(ispin)%matrix_gx_old_im, &
2813 qs_ot_env(ispin)%matrix_dx_im, &
2814 alpha_scalar=1.0_dp, beta_scalar=damping_shift)
2816 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2817 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_gx_old, &
2818 qs_ot_env(ispin)%rot_mat_dx, &
2819 alpha_scalar=1.0_dp, beta_scalar=damping_shift)
2820 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2821 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_gx_old_im, &
2822 qs_ot_env(ispin)%rot_mat_dx_im, &
2823 alpha_scalar=1.0_dp, beta_scalar=damping_shift)
2827 qs_ot_env(ispin)%ener_gx_old = qs_ot_env(ispin)%ener_gx_old + &
2828 damping_shift*qs_ot_env(ispin)%ener_dx
2831 yy = yy + 2.0_dp*damping_shift*sy + damping_shift**2*ss
2832 yy_rotation = yy_rotation + 2.0_dp*damping_shift*sy_rotation + &
2833 damping_shift**2*ss_rotation
2834 sy = sy + damping_shift*ss
2835 sy_rotation = sy_rotation + damping_shift*ss_rotation
2837 IF (ieee_is_finite(sy) .AND. ieee_is_finite(ss) .AND. ieee_is_finite(yy) .AND. &
2838 ss > 0.0_dp .AND. yy > 0.0_dp .AND. sy > curvature_tol*sqrt(ss*yy))
THEN
2840 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_x(j)%matrix, &
2841 qs_ot_env(ispin)%matrix_dx)
2842 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_e(j)%matrix, &
2843 qs_ot_env(ispin)%matrix_gx_old)
2844 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2845 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_x_im(j)%matrix, &
2846 qs_ot_env(ispin)%matrix_dx_im)
2847 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_e_im(j)%matrix, &
2848 qs_ot_env(ispin)%matrix_gx_old_im)
2850 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2851 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_x(j)%matrix, &
2852 qs_ot_env(ispin)%rot_mat_dx)
2853 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_e(j)%matrix, &
2854 qs_ot_env(ispin)%rot_mat_gx_old)
2855 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2856 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_x_im(j)%matrix, &
2857 qs_ot_env(ispin)%rot_mat_dx_im)
2858 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_e_im(j)%matrix, &
2859 qs_ot_env(ispin)%rot_mat_gx_old_im)
2863 qs_ot_env(ispin)%ener_h_x(j, :) = qs_ot_env(ispin)%ener_dx
2864 qs_ot_env(ispin)%ener_h_e(j, :) = qs_ot_env(ispin)%ener_gx_old
2867 qs_ot_env(1)%lbfgs_rho(j) = 1.0_dp/sy
2868 qs_ot_env(1)%lbfgs_yy(j) = yy
2869 qs_ot_env(1)%lbfgs_sy_rotation(j) = sy_rotation
2870 qs_ot_env(1)%lbfgs_yy_rotation(j) = yy_rotation
2871 qs_ot_env(1)%diis_iter = qs_ot_env(1)%diis_iter + 1
2875 qs_ot_env(1)%OT_METHOD_FULL =
"OT LSKIP"
2877 ELSE IF (qs_ot_env(1)%diis_iter <= 0)
THEN
2878 qs_ot_env(1)%diis_iter = 1
2882 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_old, qs_ot_env(ispin)%matrix_gx)
2883 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2884 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_gx_old_im, qs_ot_env(ispin)%matrix_gx_im)
2886 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2887 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx_old, qs_ot_env(ispin)%rot_mat_gx)
2888 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2889 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_gx_old_im, &
2890 qs_ot_env(ispin)%rot_mat_gx_im)
2893 IF (do_ener) qs_ot_env(ispin)%ener_gx_old = qs_ot_env(ispin)%ener_gx
2896 nhistory = min(qs_ot_env(1)%diis_iter - 1, m_history)
2897 ALLOCATE (alpha(max(1, nhistory)), rho(max(1, nhistory)), &
2898 history_index(max(1, nhistory)))
2899 gamma_rotation = 1.0_dp
2903 IF (nhistory > 0)
THEN
2904 newest = mod(qs_ot_env(1)%diis_iter - 2, m_history) + 1
2905 yy_newest = qs_ot_env(1)%lbfgs_yy(newest)
2906 IF (qs_ot_env(1)%settings%do_rotation .AND. &
2907 ieee_is_finite(qs_ot_env(1)%lbfgs_sy_rotation(newest)) .AND. &
2908 ieee_is_finite(qs_ot_env(1)%lbfgs_yy_rotation(newest)) .AND. &
2909 qs_ot_env(1)%lbfgs_sy_rotation(newest) > 0.0_dp .AND. &
2910 qs_ot_env(1)%lbfgs_yy_rotation(newest) > 0.0_dp)
THEN
2911 gamma_rotation = max(rotation_scale_min, min(rotation_scale_max, &
2912 qs_ot_env(1)%lbfgs_sy_rotation(newest)/ &
2913 qs_ot_env(1)%lbfgs_yy_rotation(newest)))
2916 history_index(i) =
modulo(newest - i, m_history) + 1
2919 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_x(history_index(i))%matrix, &
2920 qs_ot_env(ispin)%matrix_gx_old, tmp)
2922 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2923 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_x_im(history_index(i))%matrix, &
2924 qs_ot_env(ispin)%matrix_gx_old_im, tmp)
2927 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2928 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_x(history_index(i))%matrix, &
2929 qs_ot_env(ispin)%rot_mat_gx_old, tmp)
2930 stq = stq + 0.5_dp*tmp
2931 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2932 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_x_im(history_index(i))%matrix, &
2933 qs_ot_env(ispin)%rot_mat_gx_old_im, tmp)
2934 stq = stq + 0.5_dp*tmp
2938 stq = stq + dot_product(qs_ot_env(ispin)%ener_h_x(history_index(i), :), &
2939 qs_ot_env(ispin)%ener_gx_old)
2942 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, stq)
2943 rho(i) = qs_ot_env(1)%lbfgs_rho(history_index(i))
2944 alpha(i) = rho(i)*stq
2946 CALL dbcsr_add(qs_ot_env(ispin)%matrix_gx_old, &
2947 qs_ot_env(ispin)%matrix_h_e(history_index(i))%matrix, &
2948 alpha_scalar=1.0_dp, beta_scalar=-alpha(i))
2949 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2950 CALL dbcsr_add(qs_ot_env(ispin)%matrix_gx_old_im, &
2951 qs_ot_env(ispin)%matrix_h_e_im(history_index(i))%matrix, &
2952 alpha_scalar=1.0_dp, beta_scalar=-alpha(i))
2954 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2955 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_gx_old, &
2956 qs_ot_env(ispin)%rot_mat_h_e(history_index(i))%matrix, &
2957 alpha_scalar=1.0_dp, beta_scalar=-alpha(i))
2958 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2959 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_gx_old_im, &
2960 qs_ot_env(ispin)%rot_mat_h_e_im(history_index(i))%matrix, &
2961 alpha_scalar=1.0_dp, beta_scalar=-alpha(i))
2965 qs_ot_env(ispin)%ener_gx_old = qs_ot_env(ispin)%ener_gx_old - &
2966 alpha(i)*qs_ot_env(ispin)%ener_h_e(history_index(i), :)
2975 IF (nhistory > 0 .AND. yy_newest > 0.0_dp)
gamma = 1.0_dp/(rho(1)*yy_newest)
2976 CALL ot_apply_lbfgs_initial_inverse( &
2977 qs_ot_env,
gamma, gamma_rotation, m_history + 1, para_env_inter_kp)
2982 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_x(m_history + 1)%matrix, &
2983 qs_ot_env(ispin)%matrix_x)
2984 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_e(m_history + 1)%matrix, &
2985 qs_ot_env(ispin)%matrix_gx)
2986 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2987 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_x_im(m_history + 1)%matrix, &
2988 qs_ot_env(ispin)%matrix_x_im)
2989 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_e_im(m_history + 1)%matrix, &
2990 qs_ot_env(ispin)%matrix_gx_im)
2992 IF (qs_ot_env(1)%settings%do_rotation)
THEN
2993 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_x(m_history + 1)%matrix, &
2994 qs_ot_env(ispin)%rot_mat_x)
2995 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_e(m_history + 1)%matrix, &
2996 qs_ot_env(ispin)%rot_mat_gx)
2997 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
2998 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_x_im(m_history + 1)%matrix, &
2999 qs_ot_env(ispin)%rot_mat_x_im)
3000 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_e_im(m_history + 1)%matrix, &
3001 qs_ot_env(ispin)%rot_mat_gx_im)
3005 qs_ot_env(ispin)%ener_h_x(m_history + 1, :) = qs_ot_env(ispin)%ener_x
3006 qs_ot_env(ispin)%ener_h_e(m_history + 1, :) = qs_ot_env(ispin)%ener_gx
3011 DO i = nhistory, 1, -1
3014 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_e(history_index(i))%matrix, &
3015 qs_ot_env(ispin)%matrix_dx, tmp)
3017 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3018 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_e_im(history_index(i))%matrix, &
3019 qs_ot_env(ispin)%matrix_dx_im, tmp)
3022 IF (qs_ot_env(1)%settings%do_rotation)
THEN
3023 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_e(history_index(i))%matrix, &
3024 qs_ot_env(ispin)%rot_mat_dx, tmp)
3025 beta = beta + 0.5_dp*tmp
3026 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3027 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_e_im(history_index(i))%matrix, &
3028 qs_ot_env(ispin)%rot_mat_dx_im, tmp)
3029 beta = beta + 0.5_dp*tmp
3033 beta = beta + dot_product(qs_ot_env(ispin)%ener_h_e(history_index(i), :), &
3034 qs_ot_env(ispin)%ener_dx)
3037 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, beta)
3040 CALL dbcsr_add(qs_ot_env(ispin)%matrix_dx, &
3041 qs_ot_env(ispin)%matrix_h_x(history_index(i))%matrix, &
3042 alpha_scalar=1.0_dp, beta_scalar=alpha(i) - beta)
3043 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3044 CALL dbcsr_add(qs_ot_env(ispin)%matrix_dx_im, &
3045 qs_ot_env(ispin)%matrix_h_x_im(history_index(i))%matrix, &
3046 alpha_scalar=1.0_dp, beta_scalar=alpha(i) - beta)
3048 IF (qs_ot_env(1)%settings%do_rotation)
THEN
3049 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_dx, &
3050 qs_ot_env(ispin)%rot_mat_h_x(history_index(i))%matrix, &
3051 alpha_scalar=1.0_dp, beta_scalar=alpha(i) - beta)
3052 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3053 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_dx_im, &
3054 qs_ot_env(ispin)%rot_mat_h_x_im(history_index(i))%matrix, &
3055 alpha_scalar=1.0_dp, beta_scalar=alpha(i) - beta)
3059 qs_ot_env(ispin)%ener_dx = qs_ot_env(ispin)%ener_dx + &
3060 (alpha(i) - beta)* &
3061 qs_ot_env(ispin)%ener_h_x(history_index(i), :)
3068 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_dx, tmp)
3069 g_dot_z = g_dot_z + tmp
3070 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3071 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, qs_ot_env(ispin)%matrix_dx_im, tmp)
3072 g_dot_z = g_dot_z + tmp
3074 IF (qs_ot_env(1)%settings%do_rotation)
THEN
3075 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_dx, tmp)
3076 g_dot_z = g_dot_z + 0.5_dp*tmp
3077 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3078 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
3079 qs_ot_env(ispin)%rot_mat_dx_im, tmp)
3080 g_dot_z = g_dot_z + 0.5_dp*tmp
3084 g_dot_z = g_dot_z + dot_product(qs_ot_env(ispin)%ener_gx, &
3085 qs_ot_env(ispin)%ener_dx)
3088 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, g_dot_z)
3092 IF (.NOT. ieee_is_finite(g_dot_z) .OR. g_dot_z <= 0.0_dp)
THEN
3093 qs_ot_env(1)%diis_iter = 1
3094 qs_ot_env(1)%OT_METHOD_FULL =
"OT L-SD"
3095 IF (
ASSOCIATED(qs_ot_env(1)%preconditioner))
THEN
3097 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3099 qs_ot_env(ispin)%matrix_gx, &
3100 qs_ot_env(ispin)%matrix_gx_im, &
3101 qs_ot_env(ispin)%matrix_dx, &
3102 qs_ot_env(ispin)%matrix_dx_im)
3103 cpassert(qs_ot_env(ispin)%kpoint_weight > 0.0_dp)
3106 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_dx_im, tmp)
3109 qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_dx)
3111 IF (qs_ot_env(1)%settings%do_rotation)
THEN
3112 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx, qs_ot_env(ispin)%rot_mat_gx)
3113 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3114 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx_im, &
3115 qs_ot_env(ispin)%rot_mat_gx_im)
3118 IF (do_ener) qs_ot_env(ispin)%ener_dx = qs_ot_env(ispin)%ener_gx
3122 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin)%matrix_gx)
3123 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3124 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_dx_im, qs_ot_env(ispin)%matrix_gx_im)
3126 IF (qs_ot_env(1)%settings%do_rotation)
THEN
3127 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx, qs_ot_env(ispin)%rot_mat_gx)
3128 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3129 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx_im, &
3130 qs_ot_env(ispin)%rot_mat_gx_im)
3133 IF (do_ener) qs_ot_env(ispin)%ener_dx = qs_ot_env(ispin)%ener_gx
3138 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_dx, tmp)
3139 g_dot_z = g_dot_z + tmp
3140 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3141 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, qs_ot_env(ispin)%matrix_dx_im, tmp)
3142 g_dot_z = g_dot_z + tmp
3144 IF (qs_ot_env(1)%settings%do_rotation)
THEN
3145 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_dx, tmp)
3146 g_dot_z = g_dot_z + 0.5_dp*tmp
3147 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3148 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
3149 qs_ot_env(ispin)%rot_mat_dx_im, tmp)
3150 g_dot_z = g_dot_z + 0.5_dp*tmp
3154 g_dot_z = g_dot_z + dot_product(qs_ot_env(ispin)%ener_gx, &
3155 qs_ot_env(ispin)%ener_dx)
3158 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, g_dot_z)
3159 IF (.NOT. ieee_is_finite(g_dot_z) .OR. g_dot_z <= 0.0_dp)
THEN
3162 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_dx, qs_ot_env(ispin)%matrix_gx)
3163 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, qs_ot_env(ispin)%matrix_dx, tmp)
3164 g_dot_z = g_dot_z + tmp
3165 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3166 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_dx_im, qs_ot_env(ispin)%matrix_gx_im)
3167 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, &
3168 qs_ot_env(ispin)%matrix_dx_im, tmp)
3169 g_dot_z = g_dot_z + tmp
3171 IF (qs_ot_env(1)%settings%do_rotation)
THEN
3172 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx, qs_ot_env(ispin)%rot_mat_gx)
3173 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, qs_ot_env(ispin)%rot_mat_dx, tmp)
3174 g_dot_z = g_dot_z + 0.5_dp*tmp
3175 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3176 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_dx_im, &
3177 qs_ot_env(ispin)%rot_mat_gx_im)
3178 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
3179 qs_ot_env(ispin)%rot_mat_dx_im, tmp)
3180 g_dot_z = g_dot_z + 0.5_dp*tmp
3184 qs_ot_env(ispin)%ener_dx = qs_ot_env(ispin)%ener_gx
3185 g_dot_z = g_dot_z + dot_product(qs_ot_env(ispin)%ener_gx, &
3186 qs_ot_env(ispin)%ener_dx)
3189 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, g_dot_z)
3194 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_dx, -1.0_dp)
3195 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3196 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_dx_im, -1.0_dp)
3198 IF (qs_ot_env(1)%settings%do_rotation)
THEN
3199 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_dx, -1.0_dp)
3200 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3201 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_dx_im, -1.0_dp)
3204 IF (do_ener) qs_ot_env(ispin)%ener_dx = -qs_ot_env(ispin)%ener_dx
3206 qs_ot_env(1)%gnorm = g_dot_z
3207 qs_ot_env(1)%gradient = -g_dot_z
3215 CALL dbcsr_get_info(qs_ot_env(ispin)%matrix_x, nfullcols_total=itmp)
3217 IF (qs_ot_env(ispin)%has_complex_kpoint_state) k = k + itmp
3218 IF (qs_ot_env(1)%settings%do_rotation)
THEN
3219 nrotation = nrotation + int(itmp, kind=
int_8)*int(itmp - 1, kind=
int_8)/2_int_8
3220 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3221 nrotation = nrotation + int(itmp, kind=
int_8)*int(itmp + 1, kind=
int_8)/2_int_8
3224 IF (do_ener) nener = nener +
SIZE(qs_ot_env(ispin)%ener_x)
3226 nvariables = int(n, kind=
int_8)*int(k, kind=
int_8) + nrotation + &
3227 int(nener, kind=
int_8)
3228 nvariables_global = real(nvariables, kind=
dp)
3229 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, nvariables_global)
3230 IF (nvariables_global > 0.0_dp)
THEN
3231 qs_ot_env(1)%delta = sqrt(abs(g_dot_z)/nvariables_global)
3233 qs_ot_env(1)%delta = 0.0_dp
3234 qs_ot_env(1)%gradient = 0.0_dp
3237 test_down = -g_dot_z
3238 CALL ot_try_mermin_response_direction( &
3239 qs_ot_env, para_env_inter_kp, qs_ot_env(1)%delta, test_down, use_response_candidate)
3240 IF (use_response_candidate)
THEN
3244 qs_ot_env(1)%diis_iter = 1
3245 qs_ot_env(1)%OT_METHOD_FULL =
"OT L-R"
3246 qs_ot_env(1)%gnorm = -test_down
3247 qs_ot_env(1)%gradient = test_down
3250 DEALLOCATE (alpha, rho, history_index)
3251 CALL timestop(handle)
3253 END SUBROUTINE ot_new_lbfgs_direction
3263 SUBROUTINE ot_build_history_residual(qs_ot_env, history_index, step_scale, &
3264 para_env_inter_kp, gnorm)
3265 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
3266 INTEGER,
INTENT(IN) :: history_index
3267 REAL(kind=
dp),
INTENT(IN) :: step_scale
3269 REAL(kind=
dp),
INTENT(OUT) :: gnorm
3271 LOGICAL :: use_occupation_response
3274 use_occupation_response = qs_ot_env(1)%settings%occupation_preconditioner
3275 CALL ot_build_history_residual_once(qs_ot_env, history_index, step_scale, &
3276 use_occupation_response, gnorm)
3277 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, gnorm)
3281 IF (use_occupation_response .AND. gnorm <= 0.0_dp)
THEN
3282 CALL ot_build_history_residual_once(qs_ot_env, history_index, step_scale, .false., gnorm)
3283 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, gnorm)
3285 IF (gnorm < 0.0_dp)
THEN
3289 END SUBROUTINE ot_build_history_residual
3299 SUBROUTINE ot_build_history_residual_once(qs_ot_env, history_index, step_scale, &
3300 use_occupation_response, gnorm)
3301 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
3302 INTEGER,
INTENT(IN) :: history_index
3303 REAL(kind=
dp),
INTENT(IN) :: step_scale
3304 LOGICAL,
INTENT(IN) :: use_occupation_response
3305 REAL(kind=
dp),
INTENT(OUT) :: gnorm
3308 LOGICAL :: do_ener, do_ks
3309 REAL(kind=
dp) :: kpoint_scale, tmp
3310 TYPE(
dbcsr_type),
POINTER :: orbital_residual, orbital_residual_im
3312 do_ks = qs_ot_env(1)%settings%ks
3313 do_ener = qs_ot_env(1)%settings%do_ener
3317 DO ispin = 1,
SIZE(qs_ot_env)
3318 IF (use_occupation_response)
THEN
3319 cpassert(
ASSOCIATED(qs_ot_env(ispin)%matrix_preconditioned_gx))
3320 orbital_residual => qs_ot_env(ispin)%matrix_preconditioned_gx
3321 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3322 cpassert(
ASSOCIATED(qs_ot_env(ispin)%matrix_preconditioned_gx_im))
3323 orbital_residual_im => qs_ot_env(ispin)%matrix_preconditioned_gx_im
3326 orbital_residual => qs_ot_env(ispin)%matrix_gx
3327 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3328 orbital_residual_im => qs_ot_env(ispin)%matrix_gx_im
3332 IF (
ASSOCIATED(qs_ot_env(1)%preconditioner))
THEN
3333 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3335 orbital_residual, orbital_residual_im, &
3336 qs_ot_env(ispin)%matrix_h_e(history_index)%matrix, &
3337 qs_ot_env(ispin)%matrix_h_e_im(history_index)%matrix)
3338 cpassert(qs_ot_env(ispin)%kpoint_weight > 0.0_dp)
3340 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_h_e(history_index)%matrix, kpoint_scale)
3341 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_h_e_im(history_index)%matrix, kpoint_scale)
3344 qs_ot_env(ispin)%matrix_h_e(history_index)%matrix)
3347 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_e(history_index)%matrix, orbital_residual)
3348 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3349 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_e_im(history_index)%matrix, &
3350 orbital_residual_im)
3354 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, &
3355 qs_ot_env(ispin)%matrix_h_e(history_index)%matrix, tmp)
3357 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_h_e(history_index)%matrix, step_scale)
3358 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3359 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, &
3360 qs_ot_env(ispin)%matrix_h_e_im(history_index)%matrix, tmp)
3362 CALL dbcsr_scale(qs_ot_env(ispin)%matrix_h_e_im(history_index)%matrix, step_scale)
3365 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
3366 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_e(history_index)%matrix, &
3367 qs_ot_env(ispin)%rot_mat_gx)
3368 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, &
3369 qs_ot_env(ispin)%rot_mat_h_e(history_index)%matrix, tmp)
3370 gnorm = gnorm + 0.5_dp*tmp
3371 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_h_e(history_index)%matrix, step_scale)
3372 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3373 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_e_im(history_index)%matrix, &
3374 qs_ot_env(ispin)%rot_mat_gx_im)
3375 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
3376 qs_ot_env(ispin)%rot_mat_h_e_im(history_index)%matrix, tmp)
3377 gnorm = gnorm + 0.5_dp*tmp
3378 CALL dbcsr_scale(qs_ot_env(ispin)%rot_mat_h_e_im(history_index)%matrix, step_scale)
3385 DO ispin = 1,
SIZE(qs_ot_env)
3386 IF (use_occupation_response)
THEN
3387 cpassert(
ASSOCIATED(qs_ot_env(ispin)%ener_preconditioned_gx))
3388 qs_ot_env(ispin)%ener_h_e(history_index, :) = &
3389 qs_ot_env(ispin)%ener_preconditioned_gx
3391 qs_ot_env(ispin)%ener_h_e(history_index, :) = qs_ot_env(ispin)%ener_gx
3393 gnorm = gnorm + dot_product(qs_ot_env(ispin)%ener_gx, &
3394 qs_ot_env(ispin)%ener_h_e(history_index, :))
3395 qs_ot_env(ispin)%ener_h_e(history_index, :) = &
3396 step_scale*qs_ot_env(ispin)%ener_h_e(history_index, :)
3399 END SUBROUTINE ot_build_history_residual_once
3406 SUBROUTINE ot_diis_step(qs_ot_env, para_env_inter_kp)
3407 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
3410 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_diis_step'
3412 INTEGER :: diis_bound, diis_m, handle, i, info, &
3413 ispin, itmp, j, k, n, nener, nspin
3414 LOGICAL :: do_ener, do_ks, do_ot_sd
3415 REAL(kind=
dp) :: nvariables, overlap, tmp, tr_xnew_gx, &
3419 CALL timeset(routinen, handle)
3423 do_ks = qs_ot_env(1)%settings%ks
3424 do_ener = qs_ot_env(1)%settings%do_ener
3425 nspin =
SIZE(qs_ot_env)
3427 diis_m = qs_ot_env(1)%settings%diis_m
3429 IF (qs_ot_env(1)%diis_iter < diis_m)
THEN
3430 diis_bound = qs_ot_env(1)%diis_iter + 1
3435 j = mod(qs_ot_env(1)%diis_iter, diis_m) + 1
3441 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_x(j)%matrix, qs_ot_env(ispin)%matrix_x)
3442 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3443 CALL dbcsr_copy(qs_ot_env(ispin)%matrix_h_x_im(j)%matrix, &
3444 qs_ot_env(ispin)%matrix_x_im)
3446 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
3447 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_x(j)%matrix, qs_ot_env(ispin)%rot_mat_x)
3448 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3449 CALL dbcsr_copy(qs_ot_env(ispin)%rot_mat_h_x_im(j)%matrix, &
3450 qs_ot_env(ispin)%rot_mat_x_im)
3457 qs_ot_env(ispin)%ener_h_x(j, :) = qs_ot_env(ispin)%ener_x(:)
3460 CALL ot_build_history_residual(qs_ot_env, j, -qs_ot_env(1)%ds_min, &
3461 para_env_inter_kp, qs_ot_env(1)%gnorm)
3468 CALL dbcsr_get_info(qs_ot_env(ispin)%matrix_x, nfullcols_total=itmp)
3470 IF (qs_ot_env(ispin)%has_complex_kpoint_state) k = k + itmp
3475 nener = nener +
SIZE(qs_ot_env(ispin)%ener_x)
3478 nvariables = real(int(n, kind=
int_8)*int(k, kind=
int_8) + nener, kind=
dp)
3479 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, nvariables)
3481 IF (nvariables > 0.0_dp)
THEN
3482 qs_ot_env(1)%delta = sqrt(abs(qs_ot_env(1)%gnorm)/nvariables)
3483 qs_ot_env(1)%gradient = -qs_ot_env(1)%gnorm
3485 qs_ot_env(1)%delta = 0.0_dp
3486 qs_ot_env(1)%gradient = 0.0_dp
3490 DO i = 1, diis_bound
3496 qs_ot_env(1)%ls_diis(i, j) = 0.0_dp
3499 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_e(j)%matrix, &
3500 qs_ot_env(ispin)%matrix_h_e(i)%matrix, &
3502 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) + tmp
3503 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3504 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_e_im(j)%matrix, &
3505 qs_ot_env(ispin)%matrix_h_e_im(i)%matrix, tmp)
3506 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) + tmp
3508 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
3509 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_e(j)%matrix, &
3510 qs_ot_env(ispin)%rot_mat_h_e(i)%matrix, &
3512 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) + 0.5_dp*tmp
3513 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3514 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_e_im(j)%matrix, &
3515 qs_ot_env(ispin)%rot_mat_h_e_im(i)%matrix, tmp)
3516 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) + 0.5_dp*tmp
3523 tmp = dot_product(qs_ot_env(ispin)%ener_h_e(j, :), qs_ot_env(ispin)%ener_h_e(i, :))
3524 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) + tmp
3528 qs_ot_env(1)%ls_diis(i, j) = 0.0_dp
3531 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx, &
3532 qs_ot_env(ispin)%matrix_h_e(i)%matrix, &
3534 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) - qs_ot_env(1)%ds_min*tmp
3535 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3536 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_gx_im, &
3537 qs_ot_env(ispin)%matrix_h_e_im(i)%matrix, tmp)
3538 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) - qs_ot_env(1)%ds_min*tmp
3540 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
3541 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx, &
3542 qs_ot_env(ispin)%rot_mat_h_e(i)%matrix, &
3544 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) - qs_ot_env(1)%ds_min*0.5_dp*tmp
3545 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3546 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_gx_im, &
3547 qs_ot_env(ispin)%rot_mat_h_e_im(i)%matrix, tmp)
3548 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) - &
3549 qs_ot_env(1)%ds_min*0.5_dp*tmp
3556 tmp = dot_product(qs_ot_env(ispin)%ener_gx(:), qs_ot_env(ispin)%ener_h_e(i, :))
3557 qs_ot_env(1)%ls_diis(i, j) = qs_ot_env(1)%ls_diis(i, j) - qs_ot_env(1)%ds_min*tmp
3561 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, qs_ot_env(1)%ls_diis(i, j))
3562 qs_ot_env(1)%ls_diis(j, i) = qs_ot_env(1)%ls_diis(i, j)
3563 qs_ot_env(1)%ls_diis(i, diis_bound + 1) = 1.0_dp
3564 qs_ot_env(1)%ls_diis(diis_bound + 1, i) = 1.0_dp
3565 qs_ot_env(1)%c_diis(i) = 0.0_dp
3567 qs_ot_env(1)%ls_diis(diis_bound + 1, diis_bound + 1) = 0.0_dp
3568 qs_ot_env(1)%c_diis(diis_bound + 1) = 1.0_dp
3570 qs_ot_env(1)%lss_diis = qs_ot_env(1)%ls_diis
3572 CALL dgesv(diis_bound + 1, 1, qs_ot_env(1)%lss_diis, diis_m + 1, qs_ot_env(1)%ipivot, &
3573 qs_ot_env(1)%c_diis, diis_m + 1, info)
3583 CALL dbcsr_set(qs_ot_env(ispin)%matrix_x, 0.0_dp)
3584 DO i = 1, diis_bound
3585 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, &
3586 qs_ot_env(ispin)%matrix_h_e(i)%matrix, &
3587 alpha_scalar=1.0_dp, beta_scalar=qs_ot_env(1)%c_diis(i))
3589 DO i = 1, diis_bound
3590 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, &
3591 qs_ot_env(ispin)%matrix_h_x(i)%matrix, &
3592 alpha_scalar=1.0_dp, beta_scalar=qs_ot_env(1)%c_diis(i))
3594 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3595 CALL dbcsr_set(qs_ot_env(ispin)%matrix_x_im, 0.0_dp)
3596 DO i = 1, diis_bound
3597 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x_im, &
3598 qs_ot_env(ispin)%matrix_h_e_im(i)%matrix, &
3599 alpha_scalar=1.0_dp, beta_scalar=qs_ot_env(1)%c_diis(i))
3601 DO i = 1, diis_bound
3602 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x_im, &
3603 qs_ot_env(ispin)%matrix_h_x_im(i)%matrix, &
3604 alpha_scalar=1.0_dp, beta_scalar=qs_ot_env(1)%c_diis(i))
3607 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
3608 CALL dbcsr_set(qs_ot_env(ispin)%rot_mat_x, 0.0_dp)
3609 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3610 CALL dbcsr_set(qs_ot_env(ispin)%rot_mat_x_im, 0.0_dp)
3612 DO i = 1, diis_bound
3613 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x, &
3614 qs_ot_env(ispin)%rot_mat_h_e(i)%matrix, &
3615 alpha_scalar=1.0_dp, beta_scalar=qs_ot_env(1)%c_diis(i))
3616 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3617 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x_im, &
3618 qs_ot_env(ispin)%rot_mat_h_e_im(i)%matrix, &
3619 alpha_scalar=1.0_dp, beta_scalar=qs_ot_env(1)%c_diis(i))
3622 DO i = 1, diis_bound
3623 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x, &
3624 qs_ot_env(ispin)%rot_mat_h_x(i)%matrix, &
3625 alpha_scalar=1.0_dp, beta_scalar=qs_ot_env(1)%c_diis(i))
3626 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3627 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x_im, &
3628 qs_ot_env(ispin)%rot_mat_h_x_im(i)%matrix, &
3629 alpha_scalar=1.0_dp, beta_scalar=qs_ot_env(1)%c_diis(i))
3637 qs_ot_env(ispin)%ener_x(:) = 0.0_dp
3638 DO i = 1, diis_bound
3639 qs_ot_env(ispin)%ener_x(:) = qs_ot_env(ispin)%ener_x(:) &
3640 + qs_ot_env(1)%c_diis(i)*qs_ot_env(ispin)%ener_h_e(i, :)
3642 DO i = 1, diis_bound
3643 qs_ot_env(ispin)%ener_x(:) = qs_ot_env(ispin)%ener_x(:) &
3644 + qs_ot_env(1)%c_diis(i)*qs_ot_env(ispin)%ener_h_x(i, :)
3648 qs_ot_env(1)%diis_iter = qs_ot_env(1)%diis_iter + 1
3649 IF (qs_ot_env(1)%settings%safer_diis)
THEN
3657 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_x(j)%matrix, &
3658 qs_ot_env(ispin)%matrix_gx, tmp)
3659 tr_xold_gx = tr_xold_gx + tmp
3660 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_x, &
3661 qs_ot_env(ispin)%matrix_gx, tmp)
3662 tr_xnew_gx = tr_xnew_gx + tmp
3663 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3664 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_h_x_im(j)%matrix, &
3665 qs_ot_env(ispin)%matrix_gx_im, tmp)
3666 tr_xold_gx = tr_xold_gx + tmp
3667 CALL dbcsr_dot(qs_ot_env(ispin)%matrix_x_im, &
3668 qs_ot_env(ispin)%matrix_gx_im, tmp)
3669 tr_xnew_gx = tr_xnew_gx + tmp
3671 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
3672 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_x(j)%matrix, &
3673 qs_ot_env(ispin)%rot_mat_gx, tmp)
3674 tr_xold_gx = tr_xold_gx + 0.5_dp*tmp
3675 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_x, &
3676 qs_ot_env(ispin)%rot_mat_gx, tmp)
3677 tr_xnew_gx = tr_xnew_gx + 0.5_dp*tmp
3678 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3679 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_h_x_im(j)%matrix, &
3680 qs_ot_env(ispin)%rot_mat_gx_im, tmp)
3681 tr_xold_gx = tr_xold_gx + 0.5_dp*tmp
3682 CALL dbcsr_dot(qs_ot_env(ispin)%rot_mat_x_im, &
3683 qs_ot_env(ispin)%rot_mat_gx_im, tmp)
3684 tr_xnew_gx = tr_xnew_gx + 0.5_dp*tmp
3691 tmp = dot_product(qs_ot_env(ispin)%ener_h_x(j, :), qs_ot_env(ispin)%ener_gx(:))
3692 tr_xold_gx = tr_xold_gx + tmp
3693 tmp = dot_product(qs_ot_env(ispin)%ener_x(:), qs_ot_env(ispin)%ener_gx(:))
3694 tr_xnew_gx = tr_xnew_gx + tmp
3697 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, tr_xold_gx)
3698 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, tr_xnew_gx)
3699 overlap = (tr_xnew_gx - tr_xold_gx)
3701 IF (overlap > 0.0_dp)
THEN
3708 qs_ot_env(1)%OT_METHOD_FULL =
"OT SD"
3711 CALL dbcsr_set(qs_ot_env(ispin)%matrix_x, 0.0_dp)
3712 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, &
3713 qs_ot_env(ispin)%matrix_h_e(j)%matrix, &
3715 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x, &
3716 qs_ot_env(ispin)%matrix_h_x(j)%matrix, &
3718 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3719 CALL dbcsr_set(qs_ot_env(ispin)%matrix_x_im, 0.0_dp)
3720 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x_im, &
3721 qs_ot_env(ispin)%matrix_h_e_im(j)%matrix, &
3723 CALL dbcsr_add(qs_ot_env(ispin)%matrix_x_im, &
3724 qs_ot_env(ispin)%matrix_h_x_im(j)%matrix, &
3727 IF (qs_ot_env(ispin)%settings%do_rotation)
THEN
3728 CALL dbcsr_set(qs_ot_env(ispin)%rot_mat_x, 0.0_dp)
3729 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3730 CALL dbcsr_set(qs_ot_env(ispin)%rot_mat_x_im, 0.0_dp)
3732 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x, &
3733 qs_ot_env(ispin)%rot_mat_h_e(j)%matrix, &
3735 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3736 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x_im, &
3737 qs_ot_env(ispin)%rot_mat_h_e_im(j)%matrix, &
3740 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x, &
3741 qs_ot_env(ispin)%rot_mat_h_x(j)%matrix, &
3743 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3744 CALL dbcsr_add(qs_ot_env(ispin)%rot_mat_x_im, &
3745 qs_ot_env(ispin)%rot_mat_h_x_im(j)%matrix, &
3753 qs_ot_env(ispin)%ener_x(:) = 0._dp
3754 qs_ot_env(ispin)%ener_x(:) = qs_ot_env(ispin)%ener_x(:) + qs_ot_env(ispin)%ener_h_e(j, :)
3755 qs_ot_env(ispin)%ener_x(:) = qs_ot_env(ispin)%ener_x(:) + qs_ot_env(ispin)%ener_h_x(j, :)
3760 CALL timestop(handle)
3762 END SUBROUTINE ot_diis_step
3770 SUBROUTINE ot_broyden_step(qs_ot_env, para_env_inter_kp)
3771 TYPE(
qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
3774 INTEGER,
PARAMETER :: broyden_gradient = 4, &
3775 broyden_position = 1, &
3776 broyden_random = 3, &
3777 broyden_residual = 2
3778 INTEGER :: diis_bound, diis_m, i, ispin, itmp, j, &
3780 INTEGER(KIND=int_8) :: nrotation, nvariables
3781 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: circ_index
3782 LOGICAL :: adaptive_sigma, do_ener, do_ks, &
3783 do_rotation, enable_flip, forget_history
3784 REAL(kind=
dp) :: beta, eta,
gamma, omega, sigma, &
3785 sigma_dec, sigma_min, tmp, tmp2, &
3787 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: f, x
3788 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: g, s
3789 eta = qs_ot_env(1)%settings%broyden_eta
3790 omega = qs_ot_env(1)%settings%broyden_omega
3791 sigma_dec = qs_ot_env(1)%settings%broyden_sigma_decrease
3792 sigma_min = qs_ot_env(1)%settings%broyden_sigma_min
3793 forget_history = qs_ot_env(1)%settings%broyden_forget_history
3794 adaptive_sigma = qs_ot_env(1)%settings%broyden_adaptive_sigma
3795 enable_flip = qs_ot_env(1)%settings%broyden_enable_flip
3796 do_ks = qs_ot_env(1)%settings%ks
3797 do_ener = qs_ot_env(1)%settings%do_ener
3798 do_rotation = qs_ot_env(1)%settings%do_rotation
3800 beta = qs_ot_env(1)%settings%broyden_beta
3801 gamma = qs_ot_env(1)%settings%broyden_gamma
3802 IF (adaptive_sigma)
THEN
3803 IF (qs_ot_env(1)%broyden_adaptive_sigma < 0.0_dp)
THEN
3804 sigma = qs_ot_env(1)%settings%broyden_sigma
3806 sigma = qs_ot_env(1)%broyden_adaptive_sigma
3809 sigma = qs_ot_env(1)%settings%broyden_sigma
3812 IF (.NOT. do_ks) cpabort(
"BROYDEN currently requires OT orbital variables")
3814 nspin =
SIZE(qs_ot_env)
3816 diis_m = qs_ot_env(1)%settings%diis_m
3818 IF (qs_ot_env(1)%diis_iter < diis_m)
THEN
3819 diis_bound = qs_ot_env(1)%diis_iter + 1
3825 k = 2*diis_bound + 1
3830 ALLOCATE (circ_index(diis_bound))
3837 j = mod(qs_ot_env(1)%diis_iter, diis_m) + 1
3839 CALL broyden_copy_current_to_history(j)
3840 CALL ot_build_history_residual(qs_ot_env, j, -1.0_dp, para_env_inter_kp, &
3842 IF (qs_ot_env(1)%settings%occupation_preconditioner)
THEN
3843 CALL broyden_bound_occupation_response(j, qs_ot_env(1)%gnorm)
3852 CALL dbcsr_get_info(qs_ot_env(ispin)%matrix_x, nfullcols_total=itmp)
3854 IF (qs_ot_env(ispin)%has_complex_kpoint_state) k = k + itmp
3855 IF (do_rotation)
THEN
3856 nrotation = nrotation + int(itmp, kind=
int_8)*int(itmp - 1, kind=
int_8)/2_int_8
3857 IF (qs_ot_env(ispin)%has_complex_kpoint_state)
THEN
3858 nrotation = nrotation + int(itmp, kind=
int_8)*int(itmp + 1, kind=
int_8)/2_int_8
3861 IF (do_ener) nener = nener +
SIZE(qs_ot_env(ispin)%ener_x)
3863 nvariables = int(n, kind=
int_8)*int(k, kind=
int_8) + nrotation + &
3864 int(nener, kind=
int_8)
3865 nvariables_global = real(nvariables, kind=
dp)
3866 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp, nvariables_global)
3869 IF (nvariables_global > 0.0_dp)
THEN
3870 qs_ot_env(1)%delta = sqrt(abs(qs_ot_env(1)%gnorm)/nvariables_global)
3871 qs_ot_env(1)%gradient = -qs_ot_env(1)%gnorm
3873 qs_ot_env(1)%delta = 0.0_dp
3874 qs_ot_env(1)%gradient = 0.0_dp
3877 IF (diis_bound == diis_m)
THEN
3878 DO i = 1, diis_bound
3879 circ_index(i) = mod(j + i - 1, diis_m) + 1
3882 DO i = 1, diis_bound
3888 CALL broyden_randomize_current()
3889 DO i = 1, diis_bound
3890 CALL broyden_product_dot(broyden_position, circ_index(i), &
3891 broyden_position, circ_index(i), s(i, i))
3892 CALL broyden_product_dot(broyden_residual, circ_index(i), &
3893 broyden_residual, circ_index(i), &
3894 s(i + diis_bound, i + diis_bound))
3896 s(i, 2*diis_bound + 1) = 0.0_dp
3897 s(2*diis_bound + 1, i) = 0.0_dp
3898 s(i + diis_bound, 2*diis_bound + 1) = 0.0_dp
3899 s(2*diis_bound + 1, i + diis_bound) = 0.0_dp
3900 DO k = i + 1, diis_bound
3901 CALL broyden_product_dot(broyden_position, circ_index(i), &
3902 broyden_position, circ_index(k), s(i, k))
3904 CALL broyden_product_dot(broyden_residual, circ_index(i), &
3905 broyden_residual, circ_index(k), &
3906 s(diis_bound + i, diis_bound + k))
3907 s(diis_bound + k, diis_bound + i) = s(diis_bound + i, diis_bound + k)
3909 DO k = 1, diis_bound
3910 CALL broyden_product_dot(broyden_position, circ_index(i), &
3911 broyden_residual, circ_index(k), &
3912 s(i, k + diis_bound))
3913 s(k + diis_bound, i) = s(i, k + diis_bound)
3916 CALL broyden_product_dot(broyden_random, 0, broyden_random, 0, &
3917 s(2*diis_bound + 1, 2*diis_bound + 1))
3920 k = 2*diis_bound + 1
3922 s(k, :) = s(k, :)/tmp
3923 s(:, k) = s(:, k)/tmp
3925 IF (diis_bound > 1)
THEN
3928 CALL broyden_product_dot(broyden_position, circ_index(i), &
3929 broyden_residual, circ_index(i), tmp)
3931 CALL broyden_product_dot(broyden_position, circ_index(i - 1), &
3932 broyden_residual, circ_index(i), tmp)
3934 CALL broyden_product_dot(broyden_position, circ_index(i), &
3935 broyden_residual, circ_index(i - 1), tmp)
3937 CALL broyden_product_dot(broyden_position, circ_index(i - 1), &
3938 broyden_residual, circ_index(i - 1), tmp)
3940 qs_ot_env(1)%c_broy(i - 1) = tmp2
3943 qs_ot_env(1)%energy_h(j) = qs_ot_env(1)%etotal
3946 i = minloc(qs_ot_env(1)%energy_h(1:diis_bound), dim=1)
3948 sigma = sigma_dec*sigma
3949 qs_ot_env(1)%OT_METHOD_FULL =
"OT BTRK"
3950 CALL broyden_set_current_zero()
3951 CALL broyden_add_history(broyden_position, i, 1.0_dp, 1.0_dp -
gamma)
3952 CALL broyden_add_history(broyden_position, circ_index(diis_bound), 1.0_dp,
gamma)
3955 DO i = 2, diis_bound
3962 f(diis_bound + i) = 1.0_dp
3963 f(diis_bound + i - 1) = -1.0_dp
3966 IF (enable_flip)
THEN
3967 IF (qs_ot_env(1)%c_broy(i - 1) > 0)
THEN
3974 x(:) = tmp*x - matmul(g, f)
3977 tmp = dot_product(f, matmul(s, f))
3979 f(:) = matmul(s, f)/tmp
3981 g(:, :) = g + spread(x, dim=2, ncopies=
SIZE(f))*spread(f, dim=1, ncopies=
SIZE(x))
3984 f(2*diis_bound) = 1.0_dp
3985 x(:) = -beta*matmul(g, f)
3988 CALL broyden_set_current_zero()
3989 DO i = 1, diis_bound
3990 CALL broyden_add_history(broyden_residual, circ_index(i), 1.0_dp, &
3993 DO i = 1, diis_bound
3994 CALL broyden_add_history(broyden_position, circ_index(i), 1.0_dp, x(i))
3997 IF (adaptive_sigma)
THEN
3998 tmp = new_sigma(g, s, diis_bound)
4001 sigma = min(omega*sigma, tmp)
4005 CALL broyden_product_dot(broyden_gradient, 0, broyden_random, 0, tmp)
4008 IF (tmp >= 0.0_dp)
THEN
4009 qs_ot_env(1)%OT_METHOD_FULL =
"OT TURN"
4014 qs_ot_env(1)%diis_iter = 0
4016 sigma = sigma*sigma_dec
4017 CALL broyden_add_history(broyden_position, circ_index(diis_bound), -1.0_dp, 1.0_dp)
4019 CALL broyden_add_history(broyden_position, circ_index(diis_bound), 1.0_dp, 1.0_dp)
4024 DEALLOCATE (s, g, f, x, circ_index)
4027 qs_ot_env(1)%diis_iter = qs_ot_env(1)%diis_iter + 1
4028 qs_ot_env(1)%broyden_adaptive_sigma = max(sigma, sigma_min)
4037 SUBROUTINE broyden_bound_occupation_response(history_index, gnorm)
4038 INTEGER,
INTENT(IN) :: history_index
4039 REAL(kind=
dp),
INTENT(INOUT) :: gnorm
4042 LOGICAL :: valid_response
4043 REAL(kind=
dp) :: g_dot_h0_g, h0_g_norm_sq, p_dot_h0, response_delta_norm_sq, &
4044 response_norm_sq, response_scale, response_weight
4046 CALL broyden_build_h0_current()
4047 CALL broyden_product_dot(broyden_gradient, 0, broyden_random, 0, g_dot_h0_g)
4048 CALL broyden_product_dot(broyden_random, 0, broyden_random, 0, h0_g_norm_sq)
4049 CALL broyden_product_dot(broyden_residual, history_index, &
4050 broyden_residual, history_index, response_norm_sq)
4051 CALL broyden_product_dot(broyden_residual, history_index, &
4052 broyden_random, 0, p_dot_h0)
4053 p_dot_h0 = -p_dot_h0
4054 response_delta_norm_sq = response_norm_sq + h0_g_norm_sq - 2.0_dp*p_dot_h0
4055 valid_response = ieee_is_finite(gnorm) .AND. ieee_is_finite(response_norm_sq) .AND. &
4056 ieee_is_finite(g_dot_h0_g) .AND. ieee_is_finite(h0_g_norm_sq) .AND. &
4057 ieee_is_finite(response_delta_norm_sq) .AND. gnorm > 0.0_dp .AND. &
4058 g_dot_h0_g > 0.0_dp .AND. h0_g_norm_sq > tiny(1.0_dp) .AND. &
4059 response_delta_norm_sq >= 0.0_dp
4060 response_scale = 1.0_dp
4061 response_weight = 0.0_dp
4062 IF (valid_response)
THEN
4064 response_weight = min(1.0_dp, sqrt(h0_g_norm_sq/ &
4065 max(response_delta_norm_sq, tiny(1.0_dp))))
4069 IF (qs_ot_env(1)%diis_iter > 0) response_weight = 0.0_dp
4070 IF (.NOT. valid_response)
THEN
4071 response_scale = 0.0_dp
4072 response_weight = 0.0_dp
4075 DO ichannel = 1, nspin
4076 CALL dbcsr_scale(qs_ot_env(ichannel)%matrix_h_e(history_index)%matrix, &
4077 response_weight*response_scale)
4078 CALL dbcsr_add(qs_ot_env(ichannel)%matrix_h_e(history_index)%matrix, &
4079 qs_ot_env(ichannel)%matrix_x, 1.0_dp, -(1.0_dp - response_weight))
4080 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4081 CALL dbcsr_scale(qs_ot_env(ichannel)%matrix_h_e_im(history_index)%matrix, &
4082 response_weight*response_scale)
4083 CALL dbcsr_add(qs_ot_env(ichannel)%matrix_h_e_im(history_index)%matrix, &
4084 qs_ot_env(ichannel)%matrix_x_im, 1.0_dp, &
4085 -(1.0_dp - response_weight))
4087 IF (do_rotation)
THEN
4088 CALL dbcsr_scale(qs_ot_env(ichannel)%rot_mat_h_e(history_index)%matrix, &
4089 response_weight*response_scale)
4090 CALL dbcsr_add(qs_ot_env(ichannel)%rot_mat_h_e(history_index)%matrix, &
4091 qs_ot_env(ichannel)%rot_mat_x, 1.0_dp, &
4092 -(1.0_dp - response_weight))
4093 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4094 CALL dbcsr_scale(qs_ot_env(ichannel)%rot_mat_h_e_im(history_index)%matrix, &
4095 response_weight*response_scale)
4096 CALL dbcsr_add(qs_ot_env(ichannel)%rot_mat_h_e_im(history_index)%matrix, &
4097 qs_ot_env(ichannel)%rot_mat_x_im, 1.0_dp, &
4098 -(1.0_dp - response_weight))
4102 qs_ot_env(ichannel)%ener_h_e(history_index, :) = &
4103 response_weight*response_scale*qs_ot_env(ichannel)%ener_h_e(history_index, :) - &
4104 (1.0_dp - response_weight)*qs_ot_env(ichannel)%ener_x
4107 IF (valid_response)
THEN
4108 gnorm = response_weight*response_scale*gnorm + &
4109 (1.0_dp - response_weight)*g_dot_h0_g
4113 END SUBROUTINE broyden_bound_occupation_response
4118 SUBROUTINE broyden_build_h0_current()
4120 REAL(kind=
dp) :: kpoint_scale
4122 DO ichannel = 1, nspin
4123 IF (
ASSOCIATED(qs_ot_env(1)%preconditioner))
THEN
4124 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4126 qs_ot_env(ichannel)%matrix_gx, &
4127 qs_ot_env(ichannel)%matrix_gx_im, &
4128 qs_ot_env(ichannel)%matrix_x, &
4129 qs_ot_env(ichannel)%matrix_x_im)
4130 cpassert(qs_ot_env(ichannel)%kpoint_weight > 0.0_dp)
4132 qs_ot_env(ichannel)%kpoint_weight)
4133 CALL dbcsr_scale(qs_ot_env(ichannel)%matrix_x, kpoint_scale)
4134 CALL dbcsr_scale(qs_ot_env(ichannel)%matrix_x_im, kpoint_scale)
4137 qs_ot_env(ichannel)%matrix_gx, &
4138 qs_ot_env(ichannel)%matrix_x)
4141 CALL dbcsr_copy(qs_ot_env(ichannel)%matrix_x, qs_ot_env(ichannel)%matrix_gx)
4142 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4143 CALL dbcsr_copy(qs_ot_env(ichannel)%matrix_x_im, &
4144 qs_ot_env(ichannel)%matrix_gx_im)
4147 IF (do_rotation)
THEN
4148 CALL dbcsr_copy(qs_ot_env(ichannel)%rot_mat_x, qs_ot_env(ichannel)%rot_mat_gx)
4149 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4150 CALL dbcsr_copy(qs_ot_env(ichannel)%rot_mat_x_im, &
4151 qs_ot_env(ichannel)%rot_mat_gx_im)
4154 IF (do_ener) qs_ot_env(ichannel)%ener_x = qs_ot_env(ichannel)%ener_gx
4156 END SUBROUTINE broyden_build_h0_current
4162 SUBROUTINE broyden_copy_current_to_history(history_index)
4163 INTEGER,
INTENT(IN) :: history_index
4167 DO ichannel = 1, nspin
4168 CALL dbcsr_copy(qs_ot_env(ichannel)%matrix_h_x(history_index)%matrix, &
4169 qs_ot_env(ichannel)%matrix_x)
4170 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4171 CALL dbcsr_copy(qs_ot_env(ichannel)%matrix_h_x_im(history_index)%matrix, &
4172 qs_ot_env(ichannel)%matrix_x_im)
4174 IF (do_rotation)
THEN
4175 CALL dbcsr_copy(qs_ot_env(ichannel)%rot_mat_h_x(history_index)%matrix, &
4176 qs_ot_env(ichannel)%rot_mat_x)
4177 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4178 CALL dbcsr_copy(qs_ot_env(ichannel)%rot_mat_h_x_im(history_index)%matrix, &
4179 qs_ot_env(ichannel)%rot_mat_x_im)
4183 qs_ot_env(ichannel)%ener_h_x(history_index, :) = qs_ot_env(ichannel)%ener_x
4186 END SUBROUTINE broyden_copy_current_to_history
4191 SUBROUTINE broyden_randomize_current()
4192 INTEGER :: ichannel, icoef
4194 DO ichannel = 1, nspin
4196 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4199 IF (do_rotation)
THEN
4201 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4206 DO icoef = 1,
SIZE(qs_ot_env(ichannel)%ener_x)
4207 qs_ot_env(ichannel)%ener_x(icoef) = sin(real(icoef + &
4208 37*qs_ot_env(ichannel)%spin_index + &
4209 101*qs_ot_env(ichannel)%kpoint_index, kind=
dp))
4213 END SUBROUTINE broyden_randomize_current
4218 SUBROUTINE broyden_set_current_zero()
4221 DO ichannel = 1, nspin
4222 CALL dbcsr_set(qs_ot_env(ichannel)%matrix_x, 0.0_dp)
4223 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4224 CALL dbcsr_set(qs_ot_env(ichannel)%matrix_x_im, 0.0_dp)
4226 IF (do_rotation)
THEN
4227 CALL dbcsr_set(qs_ot_env(ichannel)%rot_mat_x, 0.0_dp)
4228 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4229 CALL dbcsr_set(qs_ot_env(ichannel)%rot_mat_x_im, 0.0_dp)
4232 IF (do_ener) qs_ot_env(ichannel)%ener_x = 0.0_dp
4234 END SUBROUTINE broyden_set_current_zero
4243 SUBROUTINE broyden_add_history(vector_kind, history_index, alpha_current, beta_history)
4244 INTEGER,
INTENT(IN) :: vector_kind, history_index
4245 REAL(kind=
dp),
INTENT(IN) :: alpha_current, beta_history
4250 DO ichannel = 1, nspin
4251 CALL broyden_matrix_pointer(vector_kind, history_index, ichannel, .false., .false., source)
4252 CALL dbcsr_add(qs_ot_env(ichannel)%matrix_x, source, alpha_current, beta_history)
4253 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4254 CALL broyden_matrix_pointer(vector_kind, history_index, ichannel, .true., .false., source)
4255 CALL dbcsr_add(qs_ot_env(ichannel)%matrix_x_im, source, alpha_current, beta_history)
4257 IF (do_rotation)
THEN
4258 CALL broyden_matrix_pointer(vector_kind, history_index, ichannel, .false., .true., source)
4259 CALL dbcsr_add(qs_ot_env(ichannel)%rot_mat_x, source, alpha_current, beta_history)
4260 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4261 CALL broyden_matrix_pointer(vector_kind, history_index, ichannel, .true., .true., source)
4262 CALL dbcsr_add(qs_ot_env(ichannel)%rot_mat_x_im, source, alpha_current, beta_history)
4266 SELECT CASE (vector_kind)
4267 CASE (broyden_position)
4268 qs_ot_env(ichannel)%ener_x = alpha_current*qs_ot_env(ichannel)%ener_x + &
4269 beta_history*qs_ot_env(ichannel)%ener_h_x(history_index, :)
4270 CASE (broyden_residual)
4271 qs_ot_env(ichannel)%ener_x = alpha_current*qs_ot_env(ichannel)%ener_x + &
4272 beta_history*qs_ot_env(ichannel)%ener_h_e(history_index, :)
4274 cpabort(
"Invalid Broyden history vector kind")
4278 END SUBROUTINE broyden_add_history
4288 SUBROUTINE broyden_product_dot(kind_a, index_a, kind_b, index_b, value)
4289 INTEGER,
INTENT(IN) :: kind_a, index_a, kind_b, index_b
4290 REAL(kind=
dp),
INTENT(OUT) ::
value
4293 REAL(kind=
dp) :: dot_value
4294 REAL(kind=
dp),
DIMENSION(:),
POINTER :: energy_a, energy_b
4295 TYPE(
dbcsr_type),
POINTER :: matrix_a, matrix_b
4298 DO ichannel = 1, nspin
4299 CALL broyden_matrix_pointer(kind_a, index_a, ichannel, .false., .false., matrix_a)
4300 CALL broyden_matrix_pointer(kind_b, index_b, ichannel, .false., .false., matrix_b)
4301 CALL dbcsr_dot(matrix_a, matrix_b, dot_value)
4302 value =
value + dot_value
4303 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4304 CALL broyden_matrix_pointer(kind_a, index_a, ichannel, .true., .false., matrix_a)
4305 CALL broyden_matrix_pointer(kind_b, index_b, ichannel, .true., .false., matrix_b)
4306 CALL dbcsr_dot(matrix_a, matrix_b, dot_value)
4307 value =
value + dot_value
4309 IF (do_rotation)
THEN
4310 CALL broyden_matrix_pointer(kind_a, index_a, ichannel, .false., .true., matrix_a)
4311 CALL broyden_matrix_pointer(kind_b, index_b, ichannel, .false., .true., matrix_b)
4312 CALL dbcsr_dot(matrix_a, matrix_b, dot_value)
4313 value =
value + 0.5_dp*dot_value
4314 IF (qs_ot_env(ichannel)%has_complex_kpoint_state)
THEN
4315 CALL broyden_matrix_pointer(kind_a, index_a, ichannel, .true., .true., matrix_a)
4316 CALL broyden_matrix_pointer(kind_b, index_b, ichannel, .true., .true., matrix_b)
4317 CALL dbcsr_dot(matrix_a, matrix_b, dot_value)
4318 value =
value + 0.5_dp*dot_value
4322 CALL broyden_energy_pointer(kind_a, index_a, ichannel, energy_a)
4323 CALL broyden_energy_pointer(kind_b, index_b, ichannel, energy_b)
4324 value =
value + dot_product(energy_a, energy_b)
4327 CALL ot_mini_sum_kpoint_scalar(para_env_inter_kp,
value)
4328 END SUBROUTINE broyden_product_dot
4339 SUBROUTINE broyden_matrix_pointer(vector_kind, history_index, channel, imaginary, rotation, matrix)
4340 INTEGER,
INTENT(IN) :: vector_kind, history_index, channel
4341 LOGICAL,
INTENT(IN) :: imaginary, rotation
4345 cpassert(qs_ot_env(channel)%has_complex_kpoint_state)
4347 SELECT CASE (vector_kind)
4348 CASE (broyden_position)
4349 cpassert(history_index > 0)
4352 matrix => qs_ot_env(channel)%rot_mat_h_x_im(history_index)%matrix
4354 matrix => qs_ot_env(channel)%rot_mat_h_x(history_index)%matrix
4358 matrix => qs_ot_env(channel)%matrix_h_x_im(history_index)%matrix
4360 matrix => qs_ot_env(channel)%matrix_h_x(history_index)%matrix
4363 CASE (broyden_residual)
4364 cpassert(history_index > 0)
4367 matrix => qs_ot_env(channel)%rot_mat_h_e_im(history_index)%matrix
4369 matrix => qs_ot_env(channel)%rot_mat_h_e(history_index)%matrix
4373 matrix => qs_ot_env(channel)%matrix_h_e_im(history_index)%matrix
4375 matrix => qs_ot_env(channel)%matrix_h_e(history_index)%matrix
4378 CASE (broyden_random)
4381 matrix => qs_ot_env(channel)%rot_mat_x_im
4383 matrix => qs_ot_env(channel)%rot_mat_x
4387 matrix => qs_ot_env(channel)%matrix_x_im
4389 matrix => qs_ot_env(channel)%matrix_x
4392 CASE (broyden_gradient)
4395 matrix => qs_ot_env(channel)%rot_mat_gx_im
4397 matrix => qs_ot_env(channel)%rot_mat_gx
4401 matrix => qs_ot_env(channel)%matrix_gx_im
4403 matrix => qs_ot_env(channel)%matrix_gx
4407 cpabort(
"Invalid Broyden product vector kind")
4409 END SUBROUTINE broyden_matrix_pointer
4418 SUBROUTINE broyden_energy_pointer(vector_kind, history_index, channel, energy)
4419 INTEGER,
INTENT(IN) :: vector_kind, history_index, channel
4420 REAL(kind=
dp),
DIMENSION(:),
POINTER :: energy
4422 SELECT CASE (vector_kind)
4423 CASE (broyden_position)
4424 cpassert(history_index > 0)
4425 energy => qs_ot_env(channel)%ener_h_x(history_index, :)
4426 CASE (broyden_residual)
4427 cpassert(history_index > 0)
4428 energy => qs_ot_env(channel)%ener_h_e(history_index, :)
4429 CASE (broyden_random)
4430 energy => qs_ot_env(channel)%ener_x
4431 CASE (broyden_gradient)
4432 energy => qs_ot_env(channel)%ener_gx
4434 cpabort(
"Invalid Broyden energy vector kind")
4436 END SUBROUTINE broyden_energy_pointer
4438 END SUBROUTINE ot_broyden_step
4447 FUNCTION new_sigma(G, S, n)
RESULT(sigma)
4453 REAL(kind=
dp),
DIMENSION(:, :) :: g, s
4455 REAL(kind=
dp) :: sigma
4457 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigv
4458 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: h
4461 CALL hess_g(g, s, h, n)
4468 sigma = sum(abs(eigv**2))/sum(abs(eigv))
4471 sigma = sum(abs(eigv))/max(1,
SIZE(eigv))
4474 sigma = (maxval(abs(eigv)) + minval(abs(eigv)))*0.5_dp
4477 DEALLOCATE (h, eigv)
4478 END FUNCTION new_sigma
4487 SUBROUTINE hess_g(G, S, H, n)
4494 REAL(kind=
dp),
DIMENSION(:, :) :: g, s, h
4498 REAL(kind=
dp) :: tmp
4499 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: v
4500 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: q
4510 tmp = sqrt(dot_product(q(:, 1), matmul(s, q(:, 1))))
4511 q(:, :) = q(:, :)/tmp
4514 v(:) = matmul(g, q(:, i))
4516 h(j, i) = dot_product(q(:, j), matmul(s, v))
4517 v(:) = v - h(j, i)*q(:, j)
4520 tmp = dot_product(v, matmul(s, v))
4521 IF (tmp <= 0.0_dp)
THEN
4527 IF (abs(tmp) < 1e-9_dp)
THEN
4532 q(:, i + 1) = v/h(i + 1, i)
4537 END SUBROUTINE hess_g
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
subroutine, public dbcsr_scale(matrix, alpha_scalar)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
subroutine, public dbcsr_init_random(matrix, keep_sparsity)
Fills the given matrix with random numbers.
subroutine, public dbcsr_dot(matrix_a, matrix_b, trace)
Computes the dot product of two matrices, also known as the trace of their matrix product.
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
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer, parameter, public high_print_level
Calculation of the incomplete Gamma function F_n(t) for multi-center integrals over Cartesian Gaussia...
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
Collection of simple mathematical functions and subroutines.
subroutine, public diamat_all(a, eigval, dac)
Diagonalize the symmetric n by n matrix a using the LAPACK library. Only the upper triangle of matrix...
Interface to the message passing library MPI.
computes preconditioners, and implements methods to apply them currently used in qs_ot
pure subroutine, public lbfgs_response_secant_parameters(g_dot_response, response_norm_sq, g_dot_h0_g, h0_g_norm_sq, response_scale, response_weight, valid)
Normalize and damp an occupation-response secant against the conventional H0 direction.
pure logical function, public ot_mermin_response_preparation_needed(residual, directions, shadow_good_samples, good_samples, cooldown, shadow_pending)
Decide whether the next accepted state needs the dense finite Mermin response.
pure logical function, public ot_mermin_response_probe(available, residual, directions, shadow_good_samples, good_samples, cooldown)
Select a sparse coupled-response probe from accepted-history evidence.
pure subroutine, public ot_mermin_response_assess(reference_energy, current_energy, reference_residual, current_residual, predicted_slope, predicted_curvature, position, default_step, predicted_drop, measured_drop, quality, residual_ratio, good)
Assess a finite-response candidate at its accepted Mermin endpoint.
pure logical function, public ot_mermin_response_shadow_followup(residual, directions, shadow_good_samples, good_samples, cooldown)
Decide whether a prepared conventional direction needs a shadow at its endpoint.
pure elemental logical function, public broyden_history_restart_required(non_descent, forget_history, do_ener)
Decide whether a non-descent Broyden step invalidates its secant history.
pure real(kind=dp) function, public lbfgs_curvature_damping_shift(sy, ss, yy, curvature_tol)
Returns the smallest shift y <- y + shift*s that meets relative L-BFGS curvature.
pure subroutine, public ot_mermin_response_candidate_preferred(baseline_slope, response_slope, response_curvature, accepted_slope, accepted_curvature, position, baseline_drop, response_drop, relative_gain, preferred)
Compare response and conventional directions in one accepted Mermin model.
pure logical function, public lbfgs_history_restart_required(current_gradient_norm_sq, previous_gradient_norm_sq)
Decides whether an L-BFGS history must be discarded after excessive gradient growth.
pure elemental logical function, public cg_history_restart_required(occupation_preconditioned, current_energy, reference_energy)
Decide whether an unresolved accepted energy change invalidates CG conjugacy.
subroutine, public ot_mini_prepare_gradient(qs_ot_env, matrix_hc, matrix_hc_im, matrix_hc_physical, matrix_hc_physical_im, para_env_inter_kp)
Evaluate the current OT derivative without advancing the minimizer.
pure subroutine, public ot_mermin_secant_curvature(reference_energy, current_energy, predicted_slope, position, curvature, valid)
Recover the total finite Mermin curvature of an accepted line-search secant.
pure subroutine, public ot_mermin_response_compare(reference_energy, current_energy, reference_residual, current_residual, predicted_slope, shadow_curvature, position, advantage, residual_ratio, good)
Compare an endpoint response shadow with the linear accepted-step model.
subroutine, public ot_mini(qs_ot_env, matrix_hc, matrix_hc_im, matrix_hc_physical, matrix_hc_physical_im, para_env_inter_kp, gradient_only, gradient_prepared)
...
pure logical function, public lbfgs_step_restart_required(accepted_step, reference_step)
Decides whether L-BFGS must recover from a collapsed accepted line-search step.
pure elemental real(kind=dp) function, public qs_ot_kpoint_preconditioner_scale(kpoint_weight)
Scale an inverse k-point Hessian block consistently with its irreducible weight.
subroutine, public qs_ot_get_derivative_ref_complex(matrix_hc, matrix_hc_im, qs_ot_env, matrix_hc_rotation, matrix_hc_rotation_im)
complex k-point REF derivative dE/dX from H(k)C(k), S(k)C(k), and C(k)
subroutine, public qs_ot_get_derivative_complex(matrix_hc, matrix_hc_im, qs_ot_env, matrix_hc_rotation, matrix_hc_rotation_im)
finite complex STRICT derivative, projected onto C0^H*S*X=0
subroutine, public qs_ot_get_derivative_ref(matrix_hc, matrix_x, matrix_sx, matrix_gx, qs_ot_env)
...
subroutine, public qs_ot_get_derivative(matrix_hc, matrix_x, matrix_sx, matrix_gx, qs_ot_env)
this routines computes dE/dx=dx, with dx ortho to sc0 needs dE/dC=hc,C0,X,SX,p if preconditioned it w...
Exchange and Correlation functional calculations.
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment