33 for (
size_t n = 0; n < r.
size(); n++) {
41 if (jac->info() > 0) {
43 size_t row =
static_cast<size_t>(jac->info() - 1);
45 "Jacobian is singular for matrix row {}:\n{}",
55 const static string separator = fmt::format(
"\n {:=>71}",
"");
57 bool wroteTitle =
false;
59 for (
size_t i = 0; i <
size(); i++) {
64 if (loglevel > 0 && (val > above + 1.0e-12 || val < below - 1.0e-12)) {
65 writelog(
"\nERROR: solution component {} out of bounds.\n", i);
66 writelog(
"{}: value = {:10.3e} (lower = {:10.3e}, upper = {:10.3e})\n",
70 double newval = val + step0[i];
73 fbound = std::max(0.0, std::min(fbound,
74 (above - val)/(newval - val)));
75 }
else if (newval < below) {
76 fbound = std::min(fbound, (val - below)/(val - newval));
79 if (loglevel > 1 && (newval > above || newval < below)) {
81 string header = fmt::format(
" {:=>10}",
"") +
82 " Undamped Newton step takes solution out of bounds " +
83 fmt::format(
"{:=>10}",
"");
88 writelog(
"\n {:<24s} {:<10s} {:<10s} {:<9s} {:<9s}",
89 custom1,
"",
"Value",
"Min",
"Max");
90 writelog(
"\n {:<24s} {:<10s} {:<10s} {:<9s} {:<9s}",
91 custom2,
"Value",
"Change",
"Bound",
"Bound");
96 writelog(
"\n {:<24s} {:>10.3e} {:>10.3e} {:>9.2e} {:>9.2e}",
97 comp_info, val, step0[i], below, above);
100 if (loglevel > 1 && wroteTitle) {
107 span<double> x1, span<double> step1,
double& s1,
111 if (loglevel > 0 && writetitle) {
112 writelog(
"\n\n {:-^70}",
" Damped Newton iteration ");
113 writelog(
"\n {:<4s} {:<10s} {:<10s} {:<7s} {:<7s} {:<7s} {:<5s} {:<3s}\n",
114 "Iter",
"F_damp",
"F_bound",
"log(ss)",
115 "log(s0)",
"log(s1)",
"N_jac",
"Age");
123 double fbound =
boundStep(x0, step0, r, loglevel-1);
128 if (fbound < 1.e-10) {
129 debuglog(
"\n No damped step can be taken without violating solution component bounds.", loglevel);
137 double alpha = fbound*1.0;
143 for (
size_t j = 0; j <
m_n; j++) {
144 x1[j] = x0[j] + alpha*step0[j];
153 step(x1, step1, r, loglevel-1);
156 writelog(
"\n Reducing step size due to evaluation failure on trial step:"
167 double ss = r.
ssnorm(x1, step1);
168 writelog(
"\n {:<4d} {:<9.3e} {:<9.3e} {:>6.3f} {:>6.3f} {:>6.3f} {:<5d} {:d}/{:d}",
171 jac->nEvals(), jac->age(),
m_maxAge);
178 if (s1 < 1.0 || s1 < s0) {
189 debuglog(
"\n Damping coefficient found (solution has not converged yet)", loglevel);
192 debuglog(
"\n Damping coefficient found (solution has converged)", loglevel);
196 debuglog(
"\n No damping coefficient found (max damping iterations reached)", loglevel);
204 clock_t t0 = clock();
206 bool forceNewJac =
false;
207 bool write_header =
true;
210 copy(x0.begin(), x0.end(),
m_x.begin());
212 double rdt = r.
rdt();
233 writelog(
"\n Steady Jacobian factorization failed:"
253 write_header =
false;
258 copy(x1.begin(), x1.end(),
m_x.begin());
259 }
else if (status == 1) {
264 }
else if (status < 0) {
268 if (jac->age() > 1) {
270 if (nJacReeval > 3) {
275 writelog(
"\n Re-evaluating Jacobian (damping coefficient not found"
276 " with this Jacobian)");
289 copy(
m_x.begin(),
m_x.end(), x1.begin());
291 m_elapsed += (clock() - t0)/(1.0*CLOCKS_PER_SEC);
Base class for exceptions thrown by Cantera classes.
virtual string getMessage() const
Method overridden by derived classes to format the error message.
virtual string getMethod() const
Get the name of the method that threw the exception.
double m_dampFactor
Factor by which the damping coefficient is reduced in each iteration.
size_t size()
Get the number of variables in the system.
void resize(size_t points)
Change the problem size.
vector< double > m_x
Work array holding the system state after the last successful step. Size m_n.
int dampStep(span< const double > x0, span< const double > step0, span< double > x1, span< double > step1, double &s1, SteadyStateSystem &r, int loglevel, bool writetitle)
Performs a damped Newton step to solve the system of nonlinear equations.
double m_elapsed
Elapsed CPU time spent computing the Jacobian.
vector< double > m_stp1
Work array holding the damped Newton step. Size m_n.
vector< double > m_stp
Work array holding the undamped Newton step or the system residual. Size m_n.
size_t m_maxDampIter
Maximum number of damping iterations.
int m_maxAge
Maximum allowable Jacobian age before it is recomputed.
MultiNewton(int sz)
Constructor.
double boundStep(span< const double > x0, span< const double > step0, const SteadyStateSystem &r, int loglevel)
Return the factor by which the undamped Newton step 'step0' must be multiplied in order to keep all s...
size_t m_n
number of variables
void step(span< const double > x, span< double > step, SteadyStateSystem &r, int loglevel)
Compute the undamped Newton step.
int solve(span< const double > x0, span< double > x1, SteadyStateSystem &r, int loglevel)
Find the solution to F(x) = 0 by damped Newton iteration.
Base class for representing a system of differential-algebraic equations and solving for its steady-s...
shared_ptr< SystemJacobian > linearSolver() const
Get the the linear solver being used to hold the Jacobian matrix and solve linear systems as part of ...
size_t size() const
Total solution vector length;.
vector< int > & transientMask()
Access the vector indicating which equations contain a transient term.
virtual double upperBound(size_t i) const =0
Get the upper bound for global component i in the state vector.
double rdt() const
Reciprocal of the time step.
virtual string componentName(size_t i) const
Get the name of the i-th component of the state vector.
virtual string componentTableLabel(size_t i) const
Get elements of the component name, aligned with the column headings given by componentTableHeader().
virtual double weightedNorm(span< const double > step) const =0
Compute the weighted norm of step.
virtual void eval(span< const double > x, span< double > r, double rdt=-1.0, int count=1)=0
Evaluate the residual function.
virtual double lowerBound(size_t i) const =0
Get the lower bound for global component i in the state vector.
double ssnorm(span< const double > x, span< double > r)
Steady-state max norm (infinity norm) of the residual evaluated using solution x.
virtual void evalJacobian(span< const double > x0)=0
Evaluates the Jacobian at x0 using finite differences.
virtual pair< string, string > componentTableHeader() const
Get header lines describing the column names included in a component label.
void debuglog(const string &msg, int loglevel)
Write a message to the log only if loglevel > 0.
void writelog(const string &fmt, const Args &... args)
Write a formatted message to the screen.
Namespace for the Cantera kernel.
const double SmallNumber
smallest number to compare to zero.
Various templated functions that carry out common vector and polynomial operations (see Templated Arr...