22 m_newt = make_unique<MultiNewton>(1);
28 m_newt = make_unique<MultiNewton>(1);
29 m_state = make_shared<vector<double>>();
30 for (
auto& dom : domains) {
43 for (
size_t n = 0; n <
m_dom.size(); n++) {
44 if (
domain(n).
id() == name) {
48 throw CanteraError(
"OneDim::domainIndex",
"no domain named >>"+name+
"<<");
69 size_t n =
m_dom.size();
71 m_dom.back()->append(d.get());
84 d->setContainer(
this,
m_dom.size()-1);
91 "Replaced by getJacobian. To be removed after Cantera 3.2.");
92 auto multijac = dynamic_pointer_cast<MultiJac>(
m_jac);
96 throw CanteraError(
"OneDim::jacobian",
"Active Jacobian is not a MultiJac");
127 writelog(
"\nStatistics:\n\n Grid Timesteps Functions Time Jacobians Time\n");
129 for (
size_t i = 0; i < n; i++) {
131 writelog(
"{:5d} {:5d} {:6d} {:9.4f} {:5d} {:9.4f}\n",
135 writelog(
"{:5d} {:5d} {:6d} NA {:5d} NA\n",
144 int nev =
m_jac->nEvals();
182 for (
size_t i = 0; i <
nDomains(); i++) {
183 const auto& d =
m_dom[i];
185 size_t np = d->nPoints();
186 size_t nv = d->nComponents();
187 for (
size_t n = 0; n < np; n++) {
197 size_t bw1 = d->bandwidth();
199 bw1 = std::max<size_t>(2*d->nComponents(), 1) - 1;
206 size_t bw2 =
m_dom[i-1]->bandwidth();
208 bw2 =
m_dom[i-1]->nComponents();
210 bw2 += d->nComponents() - 1;
213 m_size = d->loc() + d->size();
237 return m_newt->solve(x, xnew, *
this, loglevel);
242 double rdt_save =
m_rdt;
261void OneDim::eval(
size_t j,
double* x,
double* r,
double rdt,
int count)
263 clock_t t0 = clock();
276 for (
const auto& d :
m_bulk) {
287 clock_t t1 = clock();
296 clock_t t0 = clock();
298 m_work2.resize(
size());
301 for (
size_t j = 0; j <
points(); j++) {
302 size_t nv =
nVars(j);
303 for (
size_t n = 0; n < nv; n++) {
305 double xsave = x0[ipt];
310 x0[ipt] = xsave + dx;
311 double rdx = 1.0 / (x0[ipt] - xsave);
314 eval(j, x0, m_work2.data(), 0.0, 0);
317 for (
size_t i = j - 1; i != j+2; i++) {
319 size_t mv =
nVars(i);
320 size_t iloc =
loc(i);
321 for (
size_t m = 0; m < mv; m++) {
322 double delta = m_work2[m+iloc] -
m_work1[m+iloc];
324 m_jac->setValue(m + iloc, ipt, delta * rdx);
334 m_jac->updateElapsed(
double(clock() - t0) / CLOCKS_PER_SEC);
335 m_jac->incrementEvals();
343 for (
size_t i = 0; i <
m_size; i++) {
344 ss = std::max(fabs(r[i]),ss);
351 double rdt_old =
m_rdt;
403 int successiveFailures = 0;
407 writelog(
"\n============================");
408 writelog(
"\n{:<5s} {:<11s} {:<7s}\n",
"step",
"dt (s)",
"log(ss)");
409 writelog(
"============================");
414 writelog(
"\n{:<5d} {:<6.4e} {:>7.4f}", n, dt, log10(ss));
415 }
else if (loglevel > 1) {
417 writelog(
"\nTimestep ({}) dt= {:<11.4e} log(ss)= {:<7.4f}", n, dt, log10(ss));
423 int j0 =
m_jac->nEvals();
426 int status =
solve(x, r, loglevel);
432 writelog(
"\nTimestep ({}) succeeded", n);
434 successiveFailures = 0;
439 if (
m_jac->nEvals() == j0) {
445 dt = std::min(dt,
m_tmax);
448 "Took maximum number of timesteps allowed ({}) without "
454 successiveFailures++;
457 }
else if (loglevel > 1) {
458 writelog(
"\nTimestep ({}) failed", n);
460 if (successiveFailures > 2) {
461 debuglog(
"--> Resetting negative species concentrations", loglevel);
463 successiveFailures = 0;
465 debuglog(
"--> Reducing timestep", loglevel);
468 string err_msg = fmt::format(
469 "Time integration failed. Minimum timestep ({}) reached.",
m_tmin);
479 writelog(
"\n{:<5d} {:<6.4e} {:>7.4f}", n, dt, log10(ss));
480 writelog(
"\n============================");
481 }
else if (loglevel > 1) {
483 writelog(
"\nTimestep ({}) dt= {:<11.4e} log10(ss)= {:<7.4f}\n", n, dt, log10(ss));
493 for (
auto dom :
m_dom) {
494 dom->resetBadValues(x);
Base class for exceptions thrown by Cantera classes.
Base class for one-dimensional domains.
size_t nComponents() const
Number of components at each grid point.
Domain1D * left() const
Return a pointer to the left neighbor.
string id() const
Returns the identifying tag for this domain.
Domain1D * right() const
Return a pointer to the right neighbor.
virtual string componentName(size_t n) const
Name of component n. May be overloaded.
virtual void init()
Initialize.
void initTimeInteg(double dt, const double *x0)
Performs the setup required before starting a time-stepping solution.
void setSteadyMode()
Set the internally-stored reciprocal of the time step to 0.0, which is used to indicate that the prob...
virtual size_t loc(size_t j=0) const
Location of the start of the local solution vector in the global solution vector.
virtual double eval(double t) const
Evaluate the function.
Class MultiJac evaluates the Jacobian of a system of equations defined by a residual function supplie...
Newton iterator for multi-domain, one-dimensional problems.
void setOptions(int maxJacAge=5)
Set options.
int solve(double *x0, double *x1, int loglevel)
Solve F(x) = 0, where F(x) is the multi-domain residual function.
size_t start(size_t i) const
The index of the start of domain i in the solution vector.
int m_nsteps
Number of time steps taken in the current call to solve()
void init()
Initialize all domains.
size_t m_size
solution vector size
int m_nsteps_max
Maximum number of timesteps allowed per call to solve()
virtual void resize()
Call after one or more grids has changed size, for example after being refined.
void resetBadValues(double *x)
Reset values such as negative species concentrations in each domain.
void saveStats()
Save statistics on function and Jacobian evaluation, and reset the counters.
unique_ptr< MultiNewton > m_newt
Newton iterator.
double m_jacobianAbsPerturb
Absolute perturbation of each component in finite difference Jacobian.
size_t size() const
Total solution vector length;.
size_t loc(size_t jg)
Location in the solution vector of the first component of global point jg.
void eval(size_t j, double *x, double *r, double rdt=-1.0, int count=1)
Evaluate the multi-domain residual function.
double ssnorm(double *x, double *r)
Steady-state max norm (infinity norm) of the residual evaluated using solution x.
void addDomain(shared_ptr< Domain1D > d)
Add a domain. Domains are added left-to-right.
double rdt() const
Reciprocal of the time step.
void initTimeInteg(double dt, double *x)
Prepare for time stepping beginning with solution x and timestep dt.
size_t nDomains() const
Number of domains.
vector< double > m_jacElapsed
Time [s] spent evaluating Jacobians on this grid.
Domain1D * right()
Pointer to right-most domain (last added).
std::tuple< string, size_t, string > component(size_t i)
Return the domain, local point index, and component name for the i-th component of the global solutio...
size_t bandwidth() const
Jacobian bandwidth.
double m_rdt
reciprocal of time step
double m_jacobianThreshold
Threshold for ignoring small elements in Jacobian.
shared_ptr< SystemJacobian > m_jac
Jacobian evaluator.
shared_ptr< vector< double > > m_state
Solution vector.
vector< double > m_funcElapsed
Time [s] spent on residual function evaluations on this grid (not counting evaluations used to constr...
vector< shared_ptr< Domain1D > > m_connect
All connector and boundary domains.
vector< int > m_mask
Transient mask. See transientMask().
Func1 * m_interrupt
Function called at the start of every call to eval.
vector< shared_ptr< Domain1D > > m_bulk
All bulk/flow domains.
vector< int > m_funcEvals
Number of residual function evaluations on this grid (not counting evaluations used to construct Jaco...
vector< size_t > m_loc
Location in the state vector of the first component of each point, across all domains.
double m_evaltime
Total time [s] spent in eval()
size_t nVars(size_t jg)
Number of solution components at global point jg.
size_t m_bw
Jacobian bandwidth.
double m_tfactor
factor time step is multiplied by if time stepping fails ( < 1 )
bool m_jac_ok
if true, Jacobian is current
int m_ts_jac_age
Maximum age of the Jacobian in time-stepping mode.
size_t domainIndex(const string &name)
Get the index of the domain named name.
double timeStep(int nsteps, double dt, double *x, double *r, int loglevel)
Take time steps using Backward Euler.
Domain1D * pointDomain(size_t i)
Return a pointer to the domain global point i belongs to.
void setJacAge(int ss_age, int ts_age=-1)
Set the maximum number of steps that can be taken using the same Jacobian before it must be re-evalua...
vector< size_t > m_gridpts
Number of grid points in this grid.
void evalSSJacobian(double *x, double *rsd)
Evaluate the steady-state Jacobian, accessible via jacobian()
void evalJacobian(double *x0)
Evaluates the Jacobian at x0 using finite differences.
double m_tmin
minimum timestep size
size_t points()
Total number of points.
double m_tmax
maximum timestep size
int m_ss_jac_age
Maximum age of the Jacobian in steady-state mode.
vector< size_t > m_nvars
Number of variables at each point, across all domains.
int m_nevals
Number of calls to eval()
bool m_init
Indicates whether one-time initialization for each domain has been completed.
void writeStats(int printTime=1)
Write statistics about the number of iterations and Jacobians at each grid level.
void clearStats()
Clear saved statistics.
void setSteadyMode()
Prepare to solve the steady-state problem.
void setLinearSolver(shared_ptr< SystemJacobian > solver)
Set the linear solver used to hold the Jacobian matrix and solve linear systems as part of each Newto...
size_t m_pts
Total number of points.
OneDim()
Default constructor.
vector< int > m_jacEvals
Number of Jacobian evaluations on this grid.
Func1 * m_time_step_callback
User-supplied function called after each successful timestep.
vector< int > m_timeSteps
Number of time steps taken in each call to solve() (for example, for each successive grid refinement)
Domain1D & domain(size_t i) const
Return a reference to domain i.
vector< shared_ptr< Domain1D > > m_dom
All domains comprising the system.
double m_jacobianRelPerturb
Relative perturbation of each component in finite difference Jacobian.
Domain1D * left()
Pointer to left-most domain (first added).
vector< double > m_work1
Work arrays used during Jacobian evaluation.
MultiNewton & newton()
Return a reference to the Newton iterator.
MultiJac & jacobian()
Return a reference to the Jacobian evaluator of an OneDim object.
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 size_t npos
index returned by functions to indicate "no position"
const double Tiny
Small number to compare differences of mole fractions against.
shared_ptr< SystemJacobian > newSystemJacobian(const string &type)
Create a SystemJacobian object of the specified type.
offset
Offsets of solution components in the 1D solution array.
void warn_deprecated(const string &source, const AnyBase &node, const string &message)
A deprecation warning for syntax in an input file.