22 Sim1D::Sim1D(vector<Domain1D*>& domains) :
29 for (
size_t n = 0; n <
nDomains(); n++) {
40 for (
size_t dom=0; dom<
nDomains(); dom++) {
43 for (
size_t comp=0; comp<ncomp; comp++) {
51 void Sim1D::setValue(
size_t dom,
size_t comp,
size_t localPoint, doublereal value)
55 "Index out of bounds: {} > {}", iloc,
m_x.size());
59 doublereal
Sim1D::value(
size_t dom,
size_t comp,
size_t localPoint)
const
63 "Index out of bounds: {} > {}", iloc,
m_x.size());
67 doublereal Sim1D::workValue(
size_t dom,
size_t comp,
size_t localPoint)
const
71 "Index out of bounds: {} > {}", iloc,
m_x.size());
78 if (pos.front() != 0.0 || pos.back() != 1.0) {
80 "`pos` vector must span the range [0, 1]. Got a vector spanning "
81 "[{}, {}] instead.", pos.front(), pos.back());
84 doublereal z0 = d.zmin();
85 doublereal z1 = d.zmax();
86 for (
size_t n = 0; n < d.
nPoints(); n++) {
88 double frac = (zpt - z0)/(z1 - z0);
94 void Sim1D::save(
const std::string& fname,
const std::string&
id,
95 const std::string& desc,
int loglevel)
97 OneDim::save(fname,
id, desc,
m_x.data(), loglevel);
100 void Sim1D::saveResidual(
const std::string& fname,
const std::string&
id,
101 const std::string& desc,
int loglevel)
105 OneDim::save(fname,
id, desc, &res[0], loglevel);
116 throw CanteraError(
"Sim1D::restore",
"No solution with id = "+
id);
121 throw CanteraError(
"Sim1D::restore",
"Solution does not contain the "
122 " correct number of domains. Found {} expected {}.\n",
125 for (
size_t m = 0; m <
nDomains(); m++) {
127 if (loglevel > 0 && xd[m]->attrib(
"id") != dom.id()) {
128 warn_user(
"Sim1D::restore",
"Domain names do not match: "
129 "'{} and '{}'", (*xd[m])[
"id"], dom.id());
135 for (
size_t m = 0; m <
nDomains(); m++) {
144 for (
size_t n = 0; n < np; n++) {
149 void Sim1D::showSolution(ostream& s)
151 for (
size_t n = 0; n <
nDomains(); n++) {
158 void Sim1D::showSolution()
160 for (
size_t n = 0; n <
nDomains(); n++) {
163 +
" <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
172 throw CanteraError(
"Sim1D::restoreTimeSteppingSolution",
173 "No successful time steps taken on this grid.");
182 "No successful steady state solution");
185 for (
size_t n = 0; n <
nDomains(); n++) {
191 void Sim1D::getInitialSoln()
193 for (
size_t n = 0; n <
nDomains(); n++) {
200 for (
size_t n = 0; n <
nDomains(); n++) {
205 void Sim1D::setTimeStep(
double stepsize,
size_t n,
const int* tsteps)
209 for (
size_t i = 0; i < n; i++) {
220 }
else if (m > -10) {
224 "ERROR: OneDim::solve returned m = {}", m);
228 void Sim1D::solve(
int loglevel,
bool refine_grid)
233 int soln_number = -1;
236 while (new_points > 0) {
242 writeline(
'.', 78,
true,
true);
248 debuglog(
"Attempt Newton solution of steady-state problem...", loglevel);
255 for (
size_t mm = 1; mm <
nDomains(); mm+=2) {
268 save(
"debug_sim1d.xml",
"debug",
269 "After successful Newton solve");
272 saveResidual(
"debug_sim1d.xml",
"residual",
273 "After successful Newton solve");
280 save(
"debug_sim1d.xml",
"debug",
281 "After unsuccessful Newton solve");
284 saveResidual(
"debug_sim1d.xml",
"residual",
285 "After unsuccessful Newton solve");
288 writelog(
"Take {} timesteps ", nsteps);
294 save(
"debug_sim1d.xml",
"debug",
"After timestepping");
297 saveResidual(
"debug_sim1d.xml",
"residual",
298 "After timestepping");
302 writelog(
" {:10.4g} {:10.4g}\n", dt,
311 dt = std::min(dt,
m_tmax);
315 writeline(
'.', 78,
true,
true);
322 new_points =
refine(loglevel);
328 if (new_points && loglevel > 6) {
329 save(
"debug_sim1d.xml",
"debug",
"After regridding");
331 if (new_points && loglevel > 7) {
332 saveResidual(
"debug_sim1d.xml",
"residual",
336 debuglog(
"grid refinement disabled.\n", loglevel);
344 int ianalyze, np = 0;
346 std::vector<size_t> dsize;
351 for (
size_t n = 0; n <
nDomains(); n++) {
359 ianalyze = r.analyze(d.grid().size(), d.grid().data(), &
m_x[
start(n)]);
368 np += r.nNewPoints();
373 size_t nstart = znew.size();
374 for (
size_t m = 0; m < npnow; m++) {
375 if (r.keepPoint(m)) {
377 znew.push_back(d.grid(m));
380 for (
size_t i = 0; i < comp; i++) {
381 xnew.push_back(
value(n, i, m));
387 if (r.newPointNeeded(m) && m + 1 < npnow) {
389 double zmid = 0.5*(d.grid(m) + d.grid(m+1));
390 znew.push_back(zmid);
395 for (
size_t i = 0; i < comp; i++) {
396 double xmid = 0.5*(
value(n, i, m) +
value(n, i, m+1));
397 xnew.push_back(xmid);
402 writelog(
"refine: discarding point at {}\n", d.grid(m));
406 dsize.push_back(znew.size() - nstart);
413 size_t gridstart = 0, gridsize;
414 for (
size_t n = 0; n <
nDomains(); n++) {
418 gridstart += gridsize;
433 double z1 = 0.0, z2 = 0.0;
434 std::vector<size_t> dsize;
436 for (
size_t n = 0; n <
nDomains(); n++) {
439 size_t mfixed =
npos;
444 size_t nstart = znew.size();
445 if (d_free && d_free->
domainType() == cFreeFlow) {
446 for (
size_t m = 0; m < npnow - 1; m++) {
447 bool fixedpt =
false;
448 double t1 =
value(n, 2, m);
449 double t2 =
value(n, 2, m + 1);
451 double thresh = min(1., 1.e-1 * (t2 - t1));
454 if (fabs(t - t1) <= thresh) {
457 }
else if (fabs(t2 - t) <= thresh) {
460 }
else if ((t1 < t) && (t < t2)) {
462 zfixed = (z1 - z2) / (t1 - t2) * (t - t2) + z2;
475 for (
size_t m = 0; m < npnow; m++) {
477 znew.push_back(d.grid(m));
480 for (
size_t i = 0; i < comp; i++) {
481 xnew.push_back(
value(n, i, m));
485 znew.push_back(zfixed);
487 double interp_factor = (zfixed - z2) / (z1 - z2);
490 for (
size_t i = 0; i < comp; i++) {
491 double xmid = interp_factor*(
value(n, i, m) -
value(n, i, m+1)) +
value(n,i,m+1);
492 xnew.push_back(xmid);
496 dsize.push_back(znew.size() - nstart);
502 size_t gridstart = 0;
503 for (
size_t n = 0; n <
nDomains(); n++) {
505 size_t gridsize = dsize[n];
507 gridstart += gridsize;
520 double t_fixed = std::numeric_limits<double>::quiet_NaN();
521 for (
size_t n = 0; n <
nDomains(); n++) {
533 double z_fixed = std::numeric_limits<double>::quiet_NaN();
534 for (
size_t n = 0; n <
nDomains(); n++) {
545 double slope,
double curve,
double prune)
551 for (
size_t n = 0; n <
nDomains(); n++) {
565 "Must specify domain to get criteria from");
575 for (
size_t n = 0; n <
nDomains(); n++) {
588 for (
size_t n = 0; n <
nDomains(); n++) {
606 void Sim1D::evalSSJacobian()
608 OneDim::evalSSJacobian(
m_x.data(),
m_xnew.data());
613 for (
auto& D : m_dom) {
614 D->forceFullUpdate(
true);
617 for (
auto& D : m_dom) {
618 D->forceFullUpdate(
false);
624 for (
size_t i = 0; i <
size(); i++) {
625 size_t j1 = (i > bw) ? i - bw : 0;
626 size_t j2 = (i + bw >=
size()) ?
size() - 1: i + bw;
627 for (
size_t j = j1; j <= j2; j++) {
628 Jt(j,i) =
m_jac->value(i,j);
A class for banded matrices, involving matrix inversion processes.
int solve(const doublereal *const b, doublereal *const x)
Solve the matrix problem Ax = b.
doublereal & value(size_t i, size_t j)
Return a changeable reference to element (i,j).
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.
virtual void showSolution(const doublereal *x)
Print the solution.
virtual void _finalize(const doublereal *x)
In some cases, a domain may need to set parameters that depend on the initial solution estimate.
size_t nPoints() const
Number of grid points in this domain.
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
virtual void resize(size_t nv, size_t np)
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
virtual void _getInitialSoln(doublereal *x)
Writes some or all initial solution values into the global solution array, beginning at the location ...
Refiner & refiner()
Return a reference to the grid refiner.
int domainType()
Domain type flag.
virtual void setupGrid(size_t n, const doublereal *z)
called to set up initial grid, and after grid refinement
virtual size_t loc(size_t j=0) const
Location of the start of the local solution vector in the global solution vector,.
virtual doublereal eval(doublereal t) const
Evaluate the function.
void setOptions(int maxJacAge=5)
Set options.
Container class for multiple-domain 1D problems.
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()
virtual void resize()
Call after one or more grids has changed size, e.g. after being refined.
std::unique_ptr< MultiJac > m_jac
Jacobian evaluator.
size_t size() const
Total solution vector length;.
doublereal ssnorm(doublereal *x, doublereal *r)
Steady-state max norm (infinity norm) of the residual evaluated using solution x.
size_t nDomains() const
Number of domains.
std::tuple< std::string, size_t, std::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 timeStep(int nsteps, double dt, double *x, double *r, int loglevel)
void eval(size_t j, double *x, double *r, doublereal rdt=-1.0, int count=1)
Evaluate the multi-domain residual function.
doublereal m_tmax
maximum timestep size
MultiJac & jacobian()
Return a reference to the Jacobian evaluator.
int solve(doublereal *x0, doublereal *x1, int loglevel)
Solve F(x) = 0, where F(x) is the multi-domain residual function.
Domain1D & domain(size_t i) const
Return a reference to domain i.
MultiNewton & newton()
Return a reference to the Newton iterator.
Refine Domain1D grids so that profiles satisfy adaptation tolerances.
size_t maxPoints() const
Returns the maximum number of points allowed in the domain.
vector_fp getCriteria()
Get the grid refinement criteria.
void setMaxPoints(int npmax)
Set the maximum number of points allowed in the domain.
void setCriteria(doublereal ratio=10.0, doublereal slope=0.8, doublereal curve=0.8, doublereal prune=-0.1)
Set grid refinement criteria.
void setGridMin(double gridmin)
Set the minimum allowable spacing between adjacent grid points [m].
vector_fp m_xlast_ss
the solution vector after the last successful steady-state solve (stored before grid refinement)
virtual void resize()
Call after one or more grids has changed size, e.g. after being refined.
void restoreTimeSteppingSolution()
Set the current solution vector to the last successful time-stepping solution.
vector_fp m_x
the solution vector
double fixedTemperatureLocation()
Return location of the point where temperature is fixed.
void finalize()
Calls method _finalize in each domain.
vector_int m_steps
array of number of steps to take before re-attempting the steady-state solution
int refine(int loglevel=0)
Refine the grid in all domains.
double fixedTemperature()
Return temperature at the point used to fix the flame location.
vector_fp m_xlast_ts
the solution vector after the last successful timestepping
vector_fp m_xnew
a work array used to hold the residual or the new solution
void setProfile(size_t dom, size_t comp, const vector_fp &pos, const vector_fp &values)
Specify a profile for one component of one domain.
vector_fp getRefineCriteria(int dom)
Get the grid refinement criteria.
void setMaxGridPoints(int dom, int npoints)
Set the maximum number of grid points in the domain.
int setFixedTemperature(double t)
Add node for fixed temperature point of freely propagating flame.
int newtonSolve(int loglevel)
Wrapper around the Newton solver.
std::vector< vector_fp > m_grid_last_ss
the grids for each domain after the last successful steady-state solve (stored before grid refinement...
void restore(const std::string &fname, const std::string &id, int loglevel=2)
Initialize the solution with a previously-saved solution.
void solveAdjoint(const double *b, double *lambda)
Solve the equation .
Func1 * m_steady_callback
User-supplied function called after a successful steady-state solve.
void restoreSteadySolution()
Set the current solution vector and grid to the last successful steady- state solution.
size_t maxGridPoints(size_t dom)
Get the maximum number of grid points in this domain.
void showSolution(std::ostream &s)
Print to stream s the current solution for all domains.
doublereal value(size_t dom, size_t comp, size_t localPoint) const
Get one entry in the solution vector.
void setValue(size_t dom, size_t comp, size_t localPoint, doublereal value)
Set a single value in the solution vector.
void setGridMin(int dom, double gridmin)
Set the minimum grid spacing in the specified domain(s).
void setRefineCriteria(int dom=-1, double ratio=10.0, double slope=0.8, double curve=0.8, double prune=-0.1)
Set grid refinement criteria.
void setFlatProfile(size_t dom, size_t comp, doublereal v)
Set component 'comp' of domain 'dom' to value 'v' at all points.
doublereal m_tstep
timestep
void setInitialGuess(const std::string &component, vector_fp &locs, vector_fp &vals)
Set initial guess for one component for all domains.
This class represents 1D flow domains that satisfy the one-dimensional similarity solution for chemic...
double m_tfixed
Temperature at the point used to fix the flame location.
double m_zfixed
Location of the point where temperature is fixed.
Class XML_Node is a tree-based representation of the contents of an XML file.
void build(const std::string &filename)
Populate the XML tree from an input file.
XML_Node * findID(const std::string &id, const int depth=100) const
This routine carries out a recursive search for an XML node based on the XML element attribute "id".
std::vector< XML_Node * > getChildren(const std::string &name) const
Get a vector of pointers to XML_Node containing all of the children of the current node which match t...
Header for a file containing miscellaneous numerical functions.
#define AssertThrowMsg(expr, procedure,...)
Assertion must be true or an error is thrown.
const size_t npos
index returned by functions to indicate "no position"
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
void writelog(const std::string &fmt, const Args &... args)
Write a formatted message to the screen.
Namespace for the Cantera kernel.
doublereal linearInterp(doublereal x, const vector_fp &xpts, const vector_fp &fpts)
Linearly interpolate a function defined on a discrete grid.
int intValue(const std::string &val)
Translate a string into one integer value.
Classes providing support for XML data files.