18 : m_tmin(1.0e-16), m_tmax(10.0), m_tfactor(0.5),
20 m_rdt(0.0), m_jac_ok(false),
21 m_nd(0), m_bw(0), m_size(0),
23 m_ss_jac_age(10), m_ts_jac_age(20),
24 m_interrupt(0), m_nevals(0), m_evaltime(0.0)
27 m_newt =
new MultiNewton(1);
31 OneDim::OneDim(vector<Domain1D*> domains) :
32 m_tmin(1.0e-16), m_tmax(10.0), m_tfactor(0.5),
34 m_rdt(0.0), m_jac_ok(false),
35 m_nd(0), m_bw(0), m_size(0),
37 m_ss_jac_age(10), m_ts_jac_age(20),
38 m_interrupt(0), m_nevals(0), m_evaltime(0.0)
44 int nd =
static_cast<int>(domains.size());
46 for (i = 0; i < nd; i++) {
53 size_t OneDim::domainIndex(
const std::string& name)
55 for (
size_t n = 0; n <
m_nd; n++) {
56 if (
domain(n).
id() == name) {
60 throw CanteraError(
"OneDim::domainIndex",
"no domain named >>"+name+
"<<");
68 int n =
static_cast<int>(m_dom.size());
70 m_dom.back()->append(d);
75 m_connect.push_back(d);
107 sprintf(buf,
"\nStatistics:\n\n Grid Functions Time Jacobians Time \n");
109 size_t n = m_gridpts.size();
110 for (
size_t i = 0; i < n; i++) {
112 sprintf(buf,
"%5s %5i %9.4f %5i %9.4f \n",
113 int2str(m_gridpts[i]).c_str(), m_funcEvals[i], m_funcElapsed[i],
114 m_jacEvals[i], m_jacElapsed[i]);
116 sprintf(buf,
"%5s %5i NA %5i NA \n",
117 int2str(m_gridpts[i]).c_str(), m_funcEvals[i], m_jacEvals[i]);
126 int nev = m_jac->
nEvals();
127 if (nev > 0 && m_nevals > 0) {
128 m_gridpts.push_back(m_pts);
129 m_jacEvals.push_back(m_jac->
nEvals());
131 m_funcEvals.push_back(m_nevals);
133 m_funcElapsed.push_back(m_evaltime);
142 std::vector<size_t> nvars,
loc;
148 for (
size_t i = 0; i <
m_nd; i++) {
153 for (
size_t n = 0; n < np; n++) {
172 bw2 = m_dom[i-1]->bandwidth();
174 bw2 = m_dom[i-1]->nComponents();
185 m_size = d->
loc() + d->size();
191 m_mask.resize(
size());
198 for (
size_t i = 0; i <
m_nd; i++) {
199 m_dom[i]->setJac(m_jac);
207 m_jac->
eval(x, xnew, 0.0);
208 m_jac->updateTransient(m_rdt,
DATA_PTR(m_mask));
211 return m_newt->
solve(x, xnew, *
this, *m_jac, loglevel);
214 void OneDim::evalSSJacobian(doublereal* x, doublereal* xnew)
216 doublereal rdt_save = m_rdt;
220 m_jac->
eval(x, xnew, 0.0);
236 void OneDim::eval(
size_t j,
double* x,
double* r, doublereal rdt,
int count)
238 clock_t t0 = clock();
242 fill(r, r + m_size, 0.0);
243 fill(m_mask.begin(), m_mask.end(), 0);
248 vector<Domain1D*>::iterator d;
251 for (d = m_bulk.begin(); d != m_bulk.end(); ++d) {
252 (*d)->eval(j, x, r,
DATA_PTR(m_mask), rdt);
256 for (d = m_connect.begin(); d != m_connect.end(); ++d) {
257 (*d)->eval(j, x, r,
DATA_PTR(m_mask), rdt);
262 clock_t t1 = clock();
263 m_evaltime += double(t1 - t0)/CLOCKS_PER_SEC;
272 for (
size_t i = 0; i < m_size; i++) {
273 ss = std::max(fabs(r[i]),ss);
280 doublereal rdt_old = m_rdt;
285 if (fabs(rdt_old - m_rdt) >
Tiny) {
286 m_jac->updateTransient(m_rdt,
DATA_PTR(m_mask));
301 m_jac->updateTransient(m_rdt,
DATA_PTR(m_mask));
332 doublereal* r,
int loglevel)
337 writelog(
"\n\n step size (s) log10(ss) \n", loglevel);
338 writelog(
"===============================\n", loglevel);
346 sprintf(str,
" %4d %10.4g %10.4g" , n,dt,log10(ss));
354 m =
solve(x, r, loglevel-1);
361 copy(r, r + m_size, x);
374 writelog(
"...failure.\n", loglevel);
378 "Time integration failed.");
391 void OneDim::save(
const std::string& fname, std::string
id,
392 const std::string& desc, doublereal* sol,
398 newtime = localtime(&aclock);
401 ifstream fin(fname.c_str());
408 while (same_ID != 0) {
409 idnew =
id +
"_" +
int2str(jid);
411 same_ID = root.
findID(idnew);
415 ct = &root.
child(
"ctml");
417 ct = &root.addChild(
"ctml");
419 XML_Node& sim = (XML_Node&)ct->addChild(
"simulation");
421 addString(sim,
"timestamp",asctime(newtime));
426 Domain1D* d =
left();
431 ofstream s(fname.c_str());
433 throw CanteraError(
"save",
"could not open file "+fname);
437 writelog(
"Solution saved to file "+fname+
" as solution "+
id+
".\n", loglevel);
440 void Domain1D::setGrid(
size_t n,
const doublereal* z)
444 for (
size_t j = 0; j < m_points; j++) {
size_t m_nd
number of domains
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
Domain1D * left()
Pointer to left-most domain (first added).
void addDomain(Domain1D *d)
Add a domain. Domains are added left-to-right.
size_t nPoints() const
Number of grid points in this domain.
Domain1D * left() const
Return a pointer to the left neighbor.
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
int nEvals() const
Number of Jacobian evaluations.
double timeStep(int nsteps, double dt, double *x, double *r, int loglevel)
void resize()
Call after one or more grids has been refined.
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 size_t loc(size_t j=0) const
Location of the start of the local solution vector in the global solution vector,.
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 setContainer(OneDim *c, size_t index)
size_t loc(size_t jg)
Location in the solution vector of the first component of global point jg.
void addString(Cantera::XML_Node &node, const std::string &titleString, const std::string &valueString, const std::string &typeString)
This function adds a child node with the name string with a string value to the current node...
MultiNewton & newton()
Return a reference to the Newton iterator.
virtual doublereal eval(doublereal t) const
Evaluate the function.
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
size_t nComponents() const
Number of components at each grid point.
Base class for one-dimensional domains.
void setAge(int age)
Set the Jacobian age.
int solve(doublereal *x0, doublereal *x1, OneDim &r, MultiJac &jac, int loglevel)
Find the solution to F(X) = 0 by damped Newton iteration.
size_t bandwidth()
Set the Jacobian bandwidth for this domain.
Domain1D & domain(size_t i) const
Return a reference to domain i.
Base class for exceptions thrown by Cantera classes.
void resize(size_t points)
Change the problem size.
void saveStats()
Save statistics on function and Jacobian evaluation, and reset the counters.
Domain1D * right() const
Return a pointer to the right neighbor.
void eval(doublereal *x0, doublereal *resid0, double rdt)
Evaluate the Jacobian at x0.
void writeStats(int printTime=1)
Write statistics about the number of iterations and Jacobians at each grid level. ...
void addAttribute(const std::string &attrib, const std::string &value)
Add or modify an attribute of the current node.
Class MultiJac evaluates the Jacobian of a system of equations defined by a residual function supplie...
void initTimeInteg(doublereal dt, doublereal *x)
Prepare for time stepping beginning with solution x and timestep dt.
const doublereal Tiny
Small number to compare differences of mole fractions against.
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...
doublereal elapsedTime() const
Elapsed CPU time spent computing the Jacobian.
#define DATA_PTR(vec)
Creates a pointer to the start of the raw data for a vector.
Func1 * m_interrupt
Function called at the start of every call to eval.
Newton iterator for multi-domain, one-dimensional problems.
void writelog(const std::string &msg)
Write a message to the screen.
Domain1D * right()
Pointer to right-most domain (last added).
size_t size() const
Total solution vector length;.
Domain1D * pointDomain(size_t i)
Return a pointer to the domain global point i belongs to.
void build(std::istream &f)
Main routine to create an tree-like representation of an XML file.
void setOptions(int maxJacAge=5)
Set options.
void initTimeInteg(doublereal dt, const doublereal *x0)