votca 2026-dev
Loading...
Searching...
No Matches
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#ifndef VOTCA_XTP_CONVERGENCEACC_H
22#define VOTCA_XTP_CONVERGENCEACC_H
23
24// VOTCA includes
25#include <votca/tools/linalg.h>
26
27// Local VOTCA includes
28#include "adiis.h"
29#include "aomatrix.h"
30#include "diis.h"
31#include "logger.h"
32
33namespace votca {
34namespace xtp {
35
44 public:
47
50 struct options {
52 bool usediis;
53 bool noisy = false;
55 bool maxout;
57 double diis_start;
58 double levelshift;
60 // Independent from adiis_start deliberately -- see
61 // UKSConvergenceAcc::Iterate's own comment on where this is used
62 // for the full reasoning: ORCA's own DampErr is kept fully
63 // separate from its own DIISStart, and their own guidance for
64 // difficult systems is to make DampErr much SMALLER than default
65 // (keeping damping active LONGER), independent of when DIIS
66 // itself engages. Reusing adiis_start for both purposes could not
67 // represent that independently.
68 double mixingend;
71 // Ceiling mixingparameter can adaptively ramp up toward as the SCF
72 // struggles, rather than staying fixed at mixingparameter (the
73 // BASE/starting value) for the whole run -- matches ORCA's own
74 // static-damping design directly (confirmed from a real ORCA log's
75 // own resolved SCF settings, not the manual's generic defaults):
76 // DampFac (the base, 0.7 by default) and DampMax (the ceiling, 0.98
77 // by default) are two separate parameters there, not one fixed
78 // value. Notably, 0.98 is exactly the value this session's own
79 // hand-tuning independently landed on for a difficult water dimer
80 // case -- this adaptive design is a more principled way to obtain
81 // that same benefit only when actually needed, rather than paying
82 // its cost (slower convergence on easy iterations) for an entire
83 // run regardless of whether the system is struggling at all.
84 double mixingmax;
85 double Econverged;
89 // Maximum iterations for the Davidson eigensolver used by
90 // CoupledAugmentedHessianStep's own direct-minimization fallback --
91 // NOT CDFT-specific, since that fallback can engage for any
92 // sufficiently difficult UKS SCF (see this field's own XML help
93 // text, dftpackage.xml, for the real case that motivated exposing
94 // this at all: a strong CDFT constraint over a large fragment left
95 // the solver still short of its own convergence tolerance at the
96 // previous, hardcoded default of 50).
98 };
99
101 struct SpinDensity {
102 Eigen::MatrixXd alpha;
103 Eigen::MatrixXd beta;
104
106 Eigen::MatrixXd total() const { return alpha + beta; }
107
109 Eigen::MatrixXd spin() const { return alpha - beta; }
110 };
111
115 opt_ = opt;
116 if (opt_.mode == KSmode::closed) {
117 nocclevels_ = opt_.numberofelectrons / 2;
118 } else if (opt_.mode == KSmode::open) {
119 nocclevels_ = opt_.numberofelectrons;
120 } else if (opt_.mode == KSmode::fractional) {
121 nocclevels_ = 0;
122 } else if (opt_.mode == KSmode::restricted_open) {
124 std::max(opt_.number_alpha_electrons, opt_.number_beta_electrons);
125 }
126 diis_.setHistLength(opt_.histlength);
127 }
128
129 void setLogger(Logger* log) { log_ = log; }
130
132 void PrintConfigOptions() const;
133
136 bool isConverged() const {
137 if (totE_.size() < 2) {
138 return false;
139 } else {
140 return std::abs(getDeltaE()) < opt_.Econverged &&
141 getDIIsError() < opt_.error_converged;
142 }
143 }
144
146 double getDeltaE() const {
147 if (totE_.size() < 2) {
148 return 0;
149 } else {
150 return totE_.back() - totE_[totE_.size() - 2];
151 }
152 }
153
154 void setOverlap(AOOverlap& S, double etol);
155
157 double getDIIsError() const { return diiserror_; }
158
161 bool getUseMixing() const { return usedmixing_; }
162
165 Eigen::MatrixXd Iterate(const Eigen::MatrixXd& dmat, Eigen::MatrixXd& H,
166 tools::EigenSystem& MOs, double totE);
168 tools::EigenSystem SolveFockmatrix(const Eigen::MatrixXd& H) const;
170 void Levelshift(Eigen::MatrixXd& H, const Eigen::MatrixXd& MOs_old) const;
171
174 Eigen::MatrixXd DensityMatrix(const tools::EigenSystem& MOs) const;
175
178 SpinDensity DensityMatrixSpinResolved(const tools::EigenSystem& MOs) const;
179
180 private:
182
185 Eigen::MatrixXd DensityMatrixGroundState(const Eigen::MatrixXd& MOs) const;
188 Eigen::MatrixXd DensityMatrixGroundState_unres(
189 const Eigen::MatrixXd& MOs) const;
191 Eigen::MatrixXd DensityMatrixGroundState_frac(
192 const tools::EigenSystem& MOs) const;
193
197 const Eigen::MatrixXd& MOs) const;
198
199 bool usedmixing_ = true;
200 double diiserror_ = std::numeric_limits<double>::max();
202 const AOOverlap* S_;
203
204 Eigen::MatrixXd Sminusahalf;
205 std::vector<Eigen::MatrixXd> mathist_;
206 std::vector<Eigen::MatrixXd> dmatHist_;
207 std::vector<double> totE_;
208
211 double maxerror_ = 0.0;
214};
215
216} // namespace xtp
217} // namespace votca
218
219#endif // VOTCA_XTP_CONVERGENCEACC_H
Eigen::MatrixXd DensityMatrix(const tools::EigenSystem &MOs) const
void Configure(const ConvergenceAcc::options &opt)
Eigen::MatrixXd DensityMatrixGroundState_unres(const Eigen::MatrixXd &MOs) const
std::vector< Eigen::MatrixXd > mathist_
void setLogger(Logger *log)
Attach the logger used for convergence diagnostics.
Eigen::MatrixXd Iterate(const Eigen::MatrixXd &dmat, Eigen::MatrixXd &H, tools::EigenSystem &MOs, double totE)
double getDIIsError() const
Return the DIIS commutator norm from the latest iteration.
tools::EigenSystem SolveFockmatrix(const Eigen::MatrixXd &H) const
Solve the generalized eigenvalue problem for the current Fock matrix.
void PrintConfigOptions() const
Print the active convergence-acceleration settings to the logger.
void Levelshift(Eigen::MatrixXd &H, const Eigen::MatrixXd &MOs_old) const
Apply a virtual-space level shift in the molecular-orbital basis.
double getDeltaE() const
Return the total-energy change between the two most recent SCF iterations.
Eigen::MatrixXd DensityMatrixGroundState_frac(const tools::EigenSystem &MOs) const
Construct a fractional-occupation density matrix from orbital occupations.
std::vector< double > totE_
void setOverlap(AOOverlap &S, double etol)
Precompute overlap-dependent quantities used when solving the Fock matrix.
Eigen::MatrixXd DensityMatrixGroundState(const Eigen::MatrixXd &MOs) const
std::vector< Eigen::MatrixXd > dmatHist_
KSmode
Occupation model used when constructing density matrices.
SpinDensity DensityMatrixSpinResolved(const tools::EigenSystem &MOs) const
SpinDensity DensityMatrixGroundState_restricted_open(const Eigen::MatrixXd &MOs) const
Logger is used for thread-safe output of messages.
Definition logger.h:164
Provides a means for comparing floating point numbers.
Definition basebead.h:33
Eigen::Index Index
Definition types.h:26
Spin-resolved density matrices returned for open-shell SCF updates.
Eigen::MatrixXd total() const
Return the total density P = P^alpha + P^beta.
Eigen::MatrixXd spin() const
Return the spin density P^alpha - P^beta.