MADNESS 0.10.1
SCFProtocol.h
Go to the documentation of this file.
1/*
2 This file is part of MADNESS.
3
4 Copyright (C) 2007,2010 Oak Ridge National Laboratory
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 For more information please contact:
21
22 Robert J. Harrison
23 Oak Ridge National Laboratory
24 One Bethel Valley Road
25 P.O. Box 2008, MS-6367
26
27 email: harrisonrj@ornl.gov
28 tel: 865-241-3937
29 fax: 865-572-0680
30
31
32 $Id$
33*/
34
35/// \file SCFProtocol.h
36/// \brief solution protocol for SCF calculations
37
38
39#ifndef MADNESS_CHEM_SCFPROTOCOL_H__INCLUDED
40#define MADNESS_CHEM_SCFPROTOCOL_H__INCLUDED
41
43
44namespace madness {
45
46/// struct for running a protocol of subsequently tightening precision
47
48/// The ladder is `CalculationParameters::protocol()` and nothing else -- the
49/// same list moldft walks, so both engines refine through identical steps and
50/// `k` follows from `SCF::set_protocol`'s thresh->k table. `econv` and `dconv`
51/// are convergence criteria applied at each rung, relaxed to the rung's own
52/// threshold the way `SCF::solve` already relaxes dconv: you cannot converge a
53/// quantity tighter than the basis represents it.
55public:
65
67
68 bool converged; ///< flag if protocol has converged
69
70 double start_prec; ///< starting precision, typically 1.e-4
71 double current_prec; ///< current precision
72 double end_prec; ///< final precision
73
74 double thresh; ///< numerical precision of representing functions
75 double econv; ///< energy convergence of SCF calculations
76 double dconv; ///< density convergence of SCF calculations
77
78 /// number of rungs in the ladder
79 std::size_t size() const {return protocol.size();}
80
81 /// index of the rung this protocol will start at
82 std::size_t start_index() const {return index;}
83
84 /// start at a given rung rather than at the first
85
86 /// used to skip rungs a restart has already converged through
87 void set_start_index(const std::size_t i) {
88 MADNESS_CHECK_THROW(i<protocol.size(), "start index beyond the protocol");
89 index=i;
93 }
94
95 /// drop the last rung, i.e. stop one step short of the full precision
96
97 /// used for cheap pre-iterations; never empties the ladder
99 if (protocol.size()<2) return;
100 protocol.pop_back();
101 end_prec=protocol.back();
102 if (index>=protocol.size()) set_start_index(protocol.size()-1);
103 }
104
105 void initialize() {
106
107 // don't do anything if this protocol is already converged
108 if (converged) return;
109
112
113 if (world.rank()==0) {
114 std::stringstream ss;
115 ss <<"\nstarting protocol at time" << std::setw(8) << std::setprecision(2)
116 << wall_time() << "s";
117 print(ss.str());
118 print("precision steps ",current_prec," --> ",end_prec,
119 " (rung",index,"of",protocol.size(),")");
120 print("protocol: thresh",thresh,"econv ",econv,"dconv",dconv);
121 }
122 }
123
124 bool finished() const {return converged;}
125
126 /// go to the next rung of the ladder
128 if (index+1<protocol.size()) {
129 ++index;
132 } else {
133 converged=true;
134 }
135
136 return *this;
137 }
138
139 /// true if the current rung is the last one
140 bool on_last_rung() const {return index+1==protocol.size();}
141
142 /// infer thresholds for a given rung of the ladder
143
144 /// The rung sets the representation threshold. econv and dconv are the
145 /// user's, but never tighter than the rung can support.
146 ///
147 /// dconv needs care. The BSH residual cannot fall much below the threshold
148 /// the orbitals are represented at, and nemo tests `bsh_norm < dconv`
149 /// strictly, so a dconv equal to the rung's threshold is unreachable and the
150 /// rung burns maxiter without converging. Intermediate rungs therefore use
151 /// the long-standing 0.1*sqrt(thresh) relaxation -- 1e-3 at thresh 1e-4,
152 /// 1e-4 at thresh 1e-6 -- which is comfortably looser than the rung; they
153 /// are only a stepping stone, so there is nothing to gain from converging
154 /// them tightly. The last rung is the answer, so it honours the user's dconv
155 /// (never demanding tighter than the representation supports).
156 void infer_thresholds(const double prec) {
157 thresh=prec;
158 econv=std::max(prec,user_econv);
159 if (on_last_rung()) dconv=std::max(prec,user_dconv);
160 else dconv=std::max(user_dconv,std::min(1.e-3,sqrt(prec)*0.1));
161 }
162
163 /// compare two positive doubles to be equal
164 bool approx(const double a, const double b) const {
165 return (std::abs(a/b-1.0)<1.e-12);
166 }
167
168private:
169 std::vector<double> protocol; ///< the ladder, from CalculationParameters
170 std::size_t index; ///< current rung
171 double user_econv; ///< energy convergence provided by user
172 double user_dconv; ///< density convergence provided by user
173};
174
175
176
177} // namespace madness
178
179
180#endif /* SRC_APPS_CHEM_SCFPROTOCOL_H_ */
double w(double t, double eps)
Definition DKops.h:22
struct for running a protocol of subsequently tightening precision
Definition SCFProtocol.h:54
double user_dconv
density convergence provided by user
Definition SCFProtocol.h:172
double user_econv
energy convergence provided by user
Definition SCFProtocol.h:171
double end_prec
final precision
Definition SCFProtocol.h:72
World & world
Definition SCFProtocol.h:66
bool finished() const
Definition SCFProtocol.h:124
void initialize()
Definition SCFProtocol.h:105
std::vector< double > protocol
the ladder, from CalculationParameters
Definition SCFProtocol.h:169
void drop_last_rung()
drop the last rung, i.e. stop one step short of the full precision
Definition SCFProtocol.h:98
SCFProtocol & operator++()
go to the next rung of the ladder
Definition SCFProtocol.h:127
bool converged
flag if protocol has converged
Definition SCFProtocol.h:68
std::size_t start_index() const
index of the rung this protocol will start at
Definition SCFProtocol.h:82
std::size_t index
current rung
Definition SCFProtocol.h:170
double dconv
density convergence of SCF calculations
Definition SCFProtocol.h:76
double current_prec
current precision
Definition SCFProtocol.h:71
double thresh
numerical precision of representing functions
Definition SCFProtocol.h:74
void set_start_index(const std::size_t i)
start at a given rung rather than at the first
Definition SCFProtocol.h:87
double start_prec
starting precision, typically 1.e-4
Definition SCFProtocol.h:70
std::size_t size() const
number of rungs in the ladder
Definition SCFProtocol.h:79
bool on_last_rung() const
true if the current rung is the last one
Definition SCFProtocol.h:140
void infer_thresholds(const double prec)
infer thresholds for a given rung of the ladder
Definition SCFProtocol.h:156
bool approx(const double a, const double b) const
compare two positive doubles to be equal
Definition SCFProtocol.h:164
SCFProtocol(World &w, const CalculationParameters &param)
Definition SCFProtocol.h:56
double econv
energy convergence of SCF calculations
Definition SCFProtocol.h:75
A parallel world class.
Definition world.h:134
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition world.h:344
#define MADNESS_CHECK_THROW(condition, msg)
Check a condition — even in a release build the condition is always evaluated so it can have side eff...
Definition madness_exception.h:207
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
void print(const T &t, const Ts &... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition print.h:227
double wall_time()
Returns the wall time in seconds relative to an arbitrary origin.
Definition timers.cc:48
static XNonlinearSolver< std::vector< Function< T, NDIM > >, T, vector_function_allocator< T, NDIM > > nonlinear_vector_solver(World &world, const long nvec)
Definition nonlinsol.h:371
static long abs(long a)
Definition tensor.h:219
static const double b
Definition nonlinschro.cc:119
static const double a
Definition nonlinschro.cc:118
Definition CalculationParameters.h:51
InputParameters param
Definition tdse.cc:203