18 Sim1D::Sim1D(vector<Domain1D*>& domains) :
26 for (
size_t n = 0; n <
m_nd; n++) {
40 for (
size_t dom=0; dom<
m_nd; 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:" +
int2str(iloc) +
" > " +
60 doublereal
Sim1D::value(
size_t dom,
size_t comp,
size_t localPoint)
const
64 "Index out of bounds:" +
int2str(iloc) +
" > " +
69 doublereal Sim1D::workValue(
size_t dom,
size_t comp,
size_t localPoint)
const
73 "Index out of bounds:" +
int2str(iloc) +
" > " +
83 doublereal z0 = d.zmin();
84 doublereal z1 = d.zmax();
85 doublereal zpt, frac, v;
86 for (
size_t n = 0; n < d.
nPoints(); n++) {
88 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,
DATA_PTR(
m_x), 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);
111 ifstream s(fname.c_str());
114 "could not open input file "+fname);
122 throw CanteraError(
"Sim1D::restore",
"No solution with id = "+
id);
126 if (xd.size() !=
m_nd) {
127 throw CanteraError(
"Sim1D::restore",
"Solution does not contain the "
128 " correct number of domains. Found " +
129 int2str(xd.size()) +
"expected " +
133 for (
size_t m = 0; m <
m_nd; m++) {
134 if (loglevel > 0 && xd[m]->attrib(
"id") !=
domain(m).id()) {
135 writelog(
"Warning: domain names do not match: '" +
136 (*xd[m])[
"id"] + +
"' and '" +
domain(m).
id() +
"'\n");
142 for (
size_t m = 0; m <
m_nd; m++) {
153 for (n = 0; n < np; n++) {
158 void Sim1D::showSolution(ostream& s)
160 for (
size_t n = 0; n <
m_nd; n++) {
161 if (
domain(n).domainType() != cEmptyType) {
167 void Sim1D::showSolution()
169 for (
size_t n = 0; n <
m_nd; n++) {
170 if (
domain(n).domainType() != cEmptyType) {
172 +
" <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
178 void Sim1D::getInitialSoln()
180 for (
size_t n = 0; n <
m_nd; n++) {
187 for (
size_t n = 0; n <
m_nd; n++) {
192 void Sim1D::setTimeStep(doublereal stepsize,
size_t n, integer* tsteps)
196 for (
size_t i = 0; i < n; i++) {
207 }
else if (m > -10) {
211 "ERROR: OneDim::solve returned m = " +
int2str(m) +
"\n");
215 void Sim1D::solve(
int loglevel,
bool refine_grid)
220 int soln_number = -1;
223 while (new_points > 0) {
229 writeline(
'.', 78,
true,
true);
232 writelog(
"Attempt Newton solution of steady-state problem...", loglevel);
239 for (
size_t mm = 1; mm <
nDomains(); mm+=2) {
248 save(
"debug_sim1d.xml",
"debug",
249 "After successful Newton solve");
252 saveResidual(
"debug_sim1d.xml",
"residual",
253 "After successful Newton solve");
261 save(
"debug_sim1d.xml",
"debug",
262 "After unsuccessful Newton solve");
265 saveResidual(
"debug_sim1d.xml",
"residual",
266 "After unsuccessful Newton solve");
272 save(
"debug_sim1d.xml",
"debug",
"After timestepping");
275 saveResidual(
"debug_sim1d.xml",
"residual",
276 "After timestepping");
280 sprintf(buf,
" %10.4g %10.4g \n", dt,
290 dt = std::min(dt, m_tmax);
294 writeline(
'.', 78,
true,
true);
301 new_points =
refine(loglevel);
307 if (new_points && loglevel > 6) {
308 save(
"debug_sim1d.xml",
"debug",
"After regridding");
310 if (new_points && loglevel > 7) {
311 saveResidual(
"debug_sim1d.xml",
"residual",
314 if (new_points < 0) {
315 writelog(
"Maximum number of grid points reached.");
319 writelog(
"grid refinement disabled.\n", loglevel);
327 int ianalyze, np = 0;
329 doublereal xmid, zmid;
330 std::vector<size_t> dsize;
332 for (
size_t n = 0; n <
m_nd; n++) {
337 ianalyze = r.analyze(d.grid().size(),
347 np += r.nNewPoints();
352 size_t nstart = znew.size();
353 for (
size_t m = 0; m < npnow; m++) {
355 if (r.keepPoint(m)) {
357 znew.push_back(d.grid(m));
360 for (
size_t i = 0; i < comp; i++) {
361 xnew.push_back(
value(n, i, m));
368 if (r.newPointNeeded(m) && m + 1 < npnow) {
371 zmid = 0.5*(d.grid(m) + d.grid(m+1));
372 znew.push_back(zmid);
377 for (
size_t i = 0; i < comp; i++) {
378 xmid = 0.5*(
value(n, i, m) +
value(n, i, m+1));
379 xnew.push_back(xmid);
383 writelog(
"refine: discarding point at "+
fp2str(d.grid(m))+
"\n", loglevel);
386 dsize.push_back(znew.size() - nstart);
394 size_t gridstart = 0, gridsize;
395 for (
size_t n = 0; n <
m_nd; n++) {
399 gridstart += gridsize;
403 m_x.resize(xnew.size());
404 copy(xnew.begin(), xnew.end(),
m_x.begin());
407 m_xnew.resize(xnew.size());
419 doublereal zfixed,interp_factor;
420 doublereal z1 = 0.0, z2 = 0.0, t1,t2;
423 std::vector<size_t> dsize;
426 for (n = 0; n <
m_nd; n++) {
435 size_t nstart = znew.size();
437 for (m = 0; m < npnow-1; m++) {
438 if (
value(n,2,m) == t) {
444 }
else if ((
value(n,2,m)<t) && (
value(n,2,m+1)>t)) {
451 zfixed = (z1-z2)/(t1-t2)*(t-t2)+z2;
461 for (m = 0; m < npnow; m++) {
463 znew.push_back(d.grid(m));
466 for (i = 0; i < comp; i++) {
467 xnew.push_back(
value(n, i, m));
469 if (m==m1 && addnewpt) {
471 znew.push_back(zfixed);
473 interp_factor = (zfixed-z2) / (z1-z2);
476 for (i = 0; i < comp; i++) {
477 xmid = interp_factor*(
value(n, i, m) -
value(n, i, m+1)) +
value(n,i,m+1);
478 xnew.push_back(xmid);
484 dsize.push_back(znew.size() - nstart);
492 size_t gridstart = 0, gridsize;
493 for (n = 0; n <
m_nd; n++) {
497 gridstart += gridsize;
501 m_x.resize(xnew.size());
502 copy(xnew.begin(), xnew.end(),
m_x.begin());
505 m_xnew.resize(xnew.size());
507 copy(xnew.begin(), xnew.end(),
m_xnew.begin());
515 doublereal slope, doublereal curve, doublereal prune)
521 for (
size_t n = 0; n <
m_nd; n++) {
534 for (
size_t n = 0; n <
m_nd; n++) {
541 void Sim1D::setMaxGridPoints(
int dom,
int npoints)
547 for (
size_t n = 0; n <
m_nd; n++) {
559 void Sim1D::evalSSJacobian()
Container class for multiple-domain 1D problems.
size_t m_nd
number of domains
void showSolution(std::ostream &s)
Print to stream s the current solution for all domains.
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
virtual void _getInitialSoln(doublereal *x)
Writes some or all initial solution values into the global solution array, beginning at the location ...
size_t nPoints() const
Number of grid points in this domain.
void restore(const std::string &fname, const std::string &id, int loglevel=2)
Initialize the solution with a previously-saved solution.
double timeStep(int nsteps, double dt, double *x, double *r, int loglevel)
vector_fp m_x
the solution vector
void resize()
Call after one or more grids has been refined.
doublereal value(size_t dom, size_t comp, size_t localPoint) const
Get one entry in the solution vector.
doublereal ssnorm(doublereal *x, doublereal *r)
Steady-state max norm (infinity norm) of the residual evaluated using solution x. ...
void eval(size_t j, double *x, double *r, doublereal rdt=-1.0, int count=1)
Evaluate the multi-domain residual function.
MultiJac & jacobian()
Return a reference to the Jacobian evaluator.
const size_t npos
index returned by functions to indicate "no position"
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
void setValue(size_t dom, size_t comp, size_t localPoint, doublereal value)
Set a single value in the solution vector.
virtual size_t loc(size_t j=0) const
Location of the start of the local solution vector in the global solution vector,.
void setRefineCriteria(int dom=-1, doublereal ratio=10.0, doublereal slope=0.8, doublereal curve=0.8, doublereal prune=-0.1)
Set grid refinement criteria.
int solve(doublereal *x0, doublereal *x1, int loglevel)
Solve F(x) = 0, where F(x) is the multi-domain residual function.
Class XML_Node is a tree-based representation of the contents of an XML file.
void setInitialGuess(const std::string &component, vector_fp &locs, vector_fp &vals)
Set initial guess based on equilibrium.
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
size_t loc(size_t jg)
Location in the solution vector of the first component of global point jg.
vector_int m_steps
array of number of steps to take before re-attempting the steady-state solution
int newtonSolve(int loglevel)
#define AssertThrowMsg(expr, procedure, message)
Assertion must be true or an error is thrown.
A class for freely-propagating premixed flames.
doublereal m_tfixed
Temperature at the point used to fix the flame location.
size_t nComponents() const
Number of components at each grid point.
Base class for one-dimensional domains.
int setFixedTemperature(doublereal t)
Add node for fixed temperature point of freely propagating flame.
void setCriteria(doublereal ratio=10.0, doublereal slope=0.8, doublereal curve=0.8, doublereal prune=-0.1)
Set grid refinement criteria.
size_t start(size_t i) const
The index of the start of domain i in the solution vector.
void setMaxPoints(int npmax)
Set the maximum number of points allowed in the domain.
Domain1D & domain(size_t i) const
Return a reference to domain i.
std::string fp2str(const double x, const std::string &fmt)
Convert a double into a c++ string.
void finalize()
Calls method _finalize in each domain.
virtual void _finalize(const doublereal *x)
In some cases, a domain may need to set parameters that depend on the initial solution estimate...
Classes providing support for XML data files.
virtual void showSolution(const doublereal *x)
Print the solution.
Base class for exceptions thrown by Cantera classes.
doublereal m_tstep
timestep
doublereal & value(size_t i, size_t j)
Return a changeable reference to element (i,j).
doublereal m_zfixed
Location of the point where temperature is fixed.
size_t nDomains() const
Number of domains.
void setGridMin(double gridmin)
Set the minimum allowable spacing between adjacent grid points [m].
void setFlatProfile(size_t dom, size_t comp, doublereal v)
Set component 'comp' of domain 'dom' to value 'v' at all points.
Refiner & refiner()
Return a reference to the grid refiner.
int intValue(const std::string &val)
Translate a string into one integer value.
vector_fp m_xnew
a work array used to hold the residual or the new solution
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
int refine(int loglevel=0)
Refine the grid in all domains.
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...
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.
#define DATA_PTR(vec)
Creates a pointer to the start of the raw data for a vector.
Refine Domain1D grids so that profiles satisfy adaptation tolerances.
void writelog(const std::string &msg)
Write a message to the screen.
size_t size() const
Total solution vector length;.
Header for a file containing miscellaneous numerical functions.
void setGridMin(int dom, double gridmin)
Set the minimum grid spacing in the specified domain(s).
void build(std::istream &f)
Main routine to create an tree-like representation of an XML file.
virtual void setupGrid(size_t n, const doublereal *z)
called to set up initial grid, and after grid refinement
void getChildren(const std::string &name, std::vector< XML_Node * > &children) const
Get a vector of pointers to XML_Node containing all of the children of the current node which matches...
doublereal linearInterp(doublereal x, const vector_fp &xpts, const vector_fp &fpts)
Linearly interpolate a function defined on a discrete grid.