votca 2026-dev
Loading...
Searching...
No Matches
uks_convergenceacc.h
Go to the documentation of this file.
1/*
2 * Copyright 2009-2020 The VOTCA Development Team
3 * (http://www.votca.org)
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License")
6 *
7 * You may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 */
19
20#pragma once
21
22#ifndef VOTCA_XTP_UKS_CONVERGENCEACC_H
23#define VOTCA_XTP_UKS_CONVERGENCEACC_H
24
25// Standard includes
26#include <functional>
27#include <utility>
28
29// VOTCA includes
30#include <votca/tools/linalg.h>
31
32#include "votca/xtp/adiis.h"
33#include "votca/xtp/aomatrix.h"
36#include "votca/xtp/diis.h"
37#include "votca/xtp/logger.h"
38
39namespace votca {
40namespace xtp {
41
43 public:
46
47 struct SpinDensity {
48 Eigen::MatrixXd alpha;
49 Eigen::MatrixXd beta;
50
51 Eigen::MatrixXd total() const { return alpha + beta; }
52 };
53
54 struct SpinFock {
55 Eigen::MatrixXd alpha;
56 Eigen::MatrixXd beta;
57 };
58
77 std::function<SpinFock(const Eigen::MatrixXd& /*Dalpha_new*/,
78 const Eigen::MatrixXd& /*Dbeta_new*/)>;
79
80 void Configure(const options& opt_alpha, const options& opt_beta);
81 void setLogger(Logger* log);
82 void setOverlap(AOOverlap& S, double etol);
84 coupled_fock_builder_ = builder;
85 }
86
87 SpinDensity DensityMatrix(const tools::EigenSystem& MOs_alpha,
88 const tools::EigenSystem& MOs_beta) const;
89
90 SpinDensity Iterate(const SpinDensity& dmat, SpinFock& H,
91 tools::EigenSystem& MOs_alpha,
92 tools::EigenSystem& MOs_beta, double totE);
93
94 tools::EigenSystem SolveFockmatrix(const Eigen::MatrixXd& H) const;
95
106 Eigen::MatrixXd UnflattenRotation(const Eigen::VectorXd& v_ov, Index nao,
107 Index nocclevels) const;
108
115 std::pair<Eigen::MatrixXd, Eigen::MatrixXd> UnflattenCoupledRotation(
116 const Eigen::VectorXd& v, Index nao_alpha, Index nocclevels_alpha,
117 Index nao_beta, Index nocclevels_beta) const;
118
131 Eigen::VectorXd BuildCoupledSigmaVector(
132 const Eigen::VectorXd& v, const Eigen::MatrixXd& C_alpha,
133 Index nocclevels_alpha, const Eigen::MatrixXd& C_beta,
134 Index nocclevels_beta, const CoupledFockBuilder& coupled_fock_builder,
135 double finite_diff_step = 1e-3) const;
136
146 std::pair<Eigen::MatrixXd, Eigen::MatrixXd> CoupledAugmentedHessianStep(
147 const Eigen::MatrixXd& H_AO_alpha, const tools::EigenSystem& MOs_alpha,
148 Index nocclevels_alpha, const Eigen::MatrixXd& H_AO_beta,
149 const tools::EigenSystem& MOs_beta, Index nocclevels_beta,
150 const CoupledFockBuilder& coupled_fock_builder, double trust_radius,
151 double& predicted_energy_change) const;
152
153 bool isConverged() const;
154 double getDIIsError() const { return diiserror_; }
155 double getDeltaE() const;
156 bool getUseMixing() const { return usedmixing_; }
157
158 private:
159 Eigen::MatrixXd DensityMatrixGroundState_unres(const Eigen::MatrixXd& MOs,
160 Index nocclevels) const;
161
162 void Levelshift(Eigen::MatrixXd& H, const Eigen::MatrixXd& MOs_old,
163 const options& opt, Index nocclevels) const;
164
165 Eigen::MatrixXd BuildErrorMatrix(const Eigen::MatrixXd& dmat,
166 const Eigen::MatrixXd& H) const;
167
168 double CombinedError(const Eigen::MatrixXd& err_alpha,
169 const Eigen::MatrixXd& err_beta) const;
170
205 Eigen::MatrixXd DirectMinimizationRotation(
206 const Eigen::MatrixXd& H_AO, const tools::EigenSystem& MOs,
207 Index nocclevels, double& predicted_energy_change) const;
208
211
212 AOOverlap* S_ = nullptr;
213 Logger* log_ = nullptr;
214 Eigen::MatrixXd Sminusahalf;
215
217
220
221 std::vector<Eigen::MatrixXd> mathist_alpha_;
222 std::vector<Eigen::MatrixXd> mathist_beta_;
223 std::vector<Eigen::MatrixXd> dmatHist_alpha_;
224 std::vector<Eigen::MatrixXd> dmatHist_beta_;
225 std::vector<double> totE_;
226
229
230 double diiserror_ = 1.0;
231 double maxerror_ = -1.0;
233 bool usedmixing_ = true;
234
235 // Direct-minimization fallback bookkeeping. consecutive_adiis_failures_
236 // tracks how many (A)DIIS attempts in a row have failed -- switching
237 // to DirectMinimizationRotation/CoupledAugmentedHessianStep after
238 // kMaxConsecutiveADIISFailures deliberately mirrors ORCA's own
239 // auto-TRAH trigger (switching away from DIIS-family methods after
240 // they visibly struggle), rather than falling back to plain mixing
241 // indefinitely the way this class already did before this addition.
244
245 // Trailing-average trigger for direct-minimization, ADDITIONAL to
246 // (not replacing) the consecutive-failures count above -- matches
247 // ORCA's own AutoTRAH design (confirmed directly from a real ORCA
248 // log's own resolved SCF settings: "Auto Start start iteration 50",
249 // "Auto Start num. interpolation iter. 10", "Auto Start mean grad.
250 // ratio tolernc. 1.125"). Rather than only reacting to N CONSECUTIVE
251 // ADIIS failures (which says nothing about whether progress is
252 // merely slow but real, or genuinely stalled), this tracks whether
253 // diiserror_ itself is failing to shrink fast enough ON AVERAGE over
254 // a trailing window, regardless of whether any individual ADIIS
255 // attempt in that window happened to "succeed" by its own tail-
256 // coefficient criterion. diiserror_history_ holds the trailing
257 // window (capped at kTrailingWindowSize entries, oldest dropped as
258 // new ones are added); the trigger itself only becomes eligible
259 // after kAutoStartIteration total iterations, matching ORCA's own
260 // deliberate delay before considering this criterion at all.
261 std::vector<double> diiserror_history_;
263 static constexpr Index kTrailingWindowSize = 10;
264 static constexpr Index kAutoStartIteration = 50;
265 static constexpr double kMeanRatioTolerance = 1.125;
266
267 // Fletcher's trust-radius update (Helmich-Paris, J. Chem. Phys. 154,
268 // 164104 (2021), Sec. II D -- ORCA's own TRAH-SCF paper, confirmed
269 // directly by reading it rather than reconstructed from memory): the
270 // trust radius is no longer a fixed constant. direct_min_pending_
271 // marks that the MOs/density just returned came from a direct-
272 // minimization step (either DirectMinimizationRotation or
273 // CoupledAugmentedHessianStep) whose actual effect on the energy has
274 // not yet been verified -- checked at the START of the NEXT Iterate()
275 // call (see this class's own header comment on
276 // DirectMinimizationRotation for why it can only be checked then,
277 // not within the same call that took the step).
286
287 // Trust-radius floor tied to BuildSigmaVector's own finite-
288 // difference step size (kFiniteDiffStep = 1e-3, defined there): a
289 // real run showed trust_radius_current_ shrinking past 1e-6 with
290 // an IDENTICAL step/predicted-change/actual-change every single
291 // time, since the bisection's own alpha_min=1 floor means the
292 // gentlest achievable step cannot shrink any further -- the reject
293 // loop could never resolve on its own and only ended when the
294 // outer SCF's own iteration budget ran out. A trust radius below
295 // the sigma vector's own probing resolution is also asking for
296 // precision the underlying finite-difference model was never built
297 // to provide. direct_min_floor_hit_ marks that this floor has been
298 // reached without an accepted step, at which point Iterate() stops
299 // retriggering CoupledAugmentedHessianStep/DirectMinimizationRotation
300 // and falls back to plain mixing instead -- reset naturally each time a
301 // new UKSConvergenceAcc is constructed (a fresh instance per
302 // DFTEngine::EvaluateUKS call, i.e. per outer CDFT lambda trial or
303 // per geometry step), not explicitly reset within one instance's
304 // own lifetime.
306 // Lowered from 1e-2 to 3e-3 -- still 3x above BuildSigmaVector's own
307 // finite-difference resolution (kFiniteDiffStep = 1e-3), so the
308 // original justification for having a floor at all still holds, but
309 // a real run (He2+, the coupled alpha-beta path) showed
310 // actual_dE shrinking monotonically and r steadily climbing back
311 // toward the accept range (r=0) right up until it hit the OLD
312 // 1e-2 floor and fell back to mixing -- which then settled into a
313 // 2-period oscillation rather than converging. Giving that
314 // trajectory more room, rather than cutting it off exactly where it
315 // was still improving, is a direct, testable next step.
316 static constexpr double kMinTrustRadius = 3e-3;
317};
318
319} // namespace xtp
320} // namespace votca
321
322#endif // VOTCA_XTP_UKS_CONVERGENCEACC_H
KSmode
Occupation model used when constructing density matrices.
Logger is used for thread-safe output of messages.
Definition logger.h:164
double CombinedError(const Eigen::MatrixXd &err_alpha, const Eigen::MatrixXd &err_beta) const
tools::EigenSystem SolveFockmatrix(const Eigen::MatrixXd &H) const
ConvergenceAcc::KSmode KSmode
std::pair< Eigen::MatrixXd, Eigen::MatrixXd > UnflattenCoupledRotation(const Eigen::VectorXd &v, Index nao_alpha, Index nocclevels_alpha, Index nao_beta, Index nocclevels_beta) const
static constexpr Index kAutoStartIteration
SpinDensity DensityMatrix(const tools::EigenSystem &MOs_alpha, const tools::EigenSystem &MOs_beta) const
void Levelshift(Eigen::MatrixXd &H, const Eigen::MatrixXd &MOs_old, const options &opt, Index nocclevels) const
std::vector< Eigen::MatrixXd > mathist_beta_
static constexpr double kMinTrustRadius
static constexpr Index kMaxConsecutiveADIISFailures
void setOverlap(AOOverlap &S, double etol)
void Configure(const options &opt_alpha, const options &opt_beta)
Eigen::VectorXd BuildCoupledSigmaVector(const Eigen::VectorXd &v, const Eigen::MatrixXd &C_alpha, Index nocclevels_alpha, const Eigen::MatrixXd &C_beta, Index nocclevels_beta, const CoupledFockBuilder &coupled_fock_builder, double finite_diff_step=1e-3) const
Eigen::MatrixXd BuildErrorMatrix(const Eigen::MatrixXd &dmat, const Eigen::MatrixXd &H) const
ConvergenceAcc::options options
SpinDensity Iterate(const SpinDensity &dmat, SpinFock &H, tools::EigenSystem &MOs_alpha, tools::EigenSystem &MOs_beta, double totE)
std::vector< Eigen::MatrixXd > dmatHist_alpha_
Eigen::MatrixXd DirectMinimizationRotation(const Eigen::MatrixXd &H_AO, const tools::EigenSystem &MOs, Index nocclevels, double &predicted_energy_change) const
Eigen::MatrixXd UnflattenRotation(const Eigen::VectorXd &v_ov, Index nao, Index nocclevels) const
Eigen::VectorXd direct_min_pre_MOs_beta_energies_
std::vector< double > diiserror_history_
std::vector< Eigen::MatrixXd > dmatHist_beta_
CoupledFockBuilder coupled_fock_builder_
Eigen::VectorXd direct_min_pre_MOs_alpha_energies_
Eigen::MatrixXd DensityMatrixGroundState_unres(const Eigen::MatrixXd &MOs, Index nocclevels) const
static constexpr Index kTrailingWindowSize
static constexpr double kMeanRatioTolerance
std::function< SpinFock(const Eigen::MatrixXd &, const Eigen::MatrixXd &)> CoupledFockBuilder
std::vector< Eigen::MatrixXd > mathist_alpha_
void setCoupledFockBuilder(const CoupledFockBuilder &builder)
std::pair< Eigen::MatrixXd, Eigen::MatrixXd > CoupledAugmentedHessianStep(const Eigen::MatrixXd &H_AO_alpha, const tools::EigenSystem &MOs_alpha, Index nocclevels_alpha, const Eigen::MatrixXd &H_AO_beta, const tools::EigenSystem &MOs_beta, Index nocclevels_beta, const CoupledFockBuilder &coupled_fock_builder, double trust_radius, double &predicted_energy_change) const
Provides a means for comparing floating point numbers.
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26