17 : m_tmin(1.0e-16), m_tmax(10.0), m_tfactor(0.5),
19 m_rdt(0.0), m_jac_ok(false),
20 m_nd(0), m_bw(0), m_size(0),
21 m_init(false), m_pts(0), m_solve_time(0.0),
22 m_ss_jac_age(10), m_ts_jac_age(20),
23 m_interrupt(0), m_nevals(0), m_evaltime(0.0)
25 m_newt =
new MultiNewton(1);
28 OneDim::OneDim(vector<Domain1D*> domains) :
29 m_tmin(1.0e-16), m_tmax(10.0), m_tfactor(0.5),
31 m_rdt(0.0), m_jac_ok(false),
32 m_nd(0), m_bw(0), m_size(0),
33 m_init(false), m_solve_time(0.0),
34 m_ss_jac_age(10), m_ts_jac_age(20),
35 m_interrupt(0), m_nevals(0), m_evaltime(0.0)
39 for (
size_t i = 0; i < domains.size(); i++) {
46 size_t OneDim::domainIndex(
const std::string& name)
48 for (
size_t n = 0; n <
m_nd; n++) {
49 if (
domain(n).
id() == name) {
53 throw CanteraError(
"OneDim::domainIndex",
"no domain named >>"+name+
"<<");
60 size_t n = m_dom.size();
62 m_dom.back()->append(d);
67 m_connect.push_back(d);
99 sprintf(buf,
"\nStatistics:\n\n Grid Functions Time Jacobians Time \n");
101 size_t n = m_gridpts.size();
102 for (
size_t i = 0; i < n; i++) {
104 sprintf(buf,
"%5s %5i %9.4f %5i %9.4f \n",
105 int2str(m_gridpts[i]).c_str(), m_funcEvals[i], m_funcElapsed[i],
106 m_jacEvals[i], m_jacElapsed[i]);
108 sprintf(buf,
"%5s %5i NA %5i NA \n",
109 int2str(m_gridpts[i]).c_str(), m_funcEvals[i], m_jacEvals[i]);
118 int nev = m_jac->
nEvals();
119 if (nev > 0 && m_nevals > 0) {
120 m_gridpts.push_back(m_pts);
121 m_jacEvals.push_back(m_jac->
nEvals());
123 m_funcEvals.push_back(m_nevals);
125 m_funcElapsed.push_back(m_evaltime);
135 m_jacElapsed.clear();
137 m_funcElapsed.clear();
152 for (
size_t i = 0; i <
m_nd; i++) {
157 for (
size_t n = 0; n < np; n++) {
158 m_nvars.push_back(nv);
171 m_bw = std::max(m_bw, bw1);
176 size_t bw2 = m_dom[i-1]->bandwidth();
178 bw2 = m_dom[i-1]->nComponents();
181 m_bw = std::max(m_bw, bw2);
183 m_size = d->
loc() + d->size();
187 m_mask.resize(
size());
194 for (
size_t i = 0; i <
m_nd; i++) {
195 m_dom[i]->setJac(m_jac);
203 m_jac->
eval(x, xnew, 0.0);
204 m_jac->updateTransient(m_rdt,
DATA_PTR(m_mask));
207 return m_newt->
solve(x, xnew, *
this, *m_jac, loglevel);
210 void OneDim::evalSSJacobian(doublereal* x, doublereal* xnew)
212 doublereal rdt_save = m_rdt;
216 m_jac->
eval(x, xnew, 0.0);
232 void OneDim::eval(
size_t j,
double* x,
double* r, doublereal rdt,
int count)
234 clock_t t0 = clock();
238 fill(r, r + m_size, 0.0);
239 fill(m_mask.begin(), m_mask.end(), 0);
243 vector<Domain1D*>::iterator d;
246 for (d = m_bulk.begin(); d != m_bulk.end(); ++d) {
247 (*d)->eval(j, x, r,
DATA_PTR(m_mask), rdt);
251 for (d = m_connect.begin(); d != m_connect.end(); ++d) {
252 (*d)->eval(j, x, r,
DATA_PTR(m_mask), rdt);
257 clock_t t1 = clock();
258 m_evaltime += double(t1 - t0)/CLOCKS_PER_SEC;
267 for (
size_t i = 0; i < m_size; i++) {
268 ss = std::max(fabs(r[i]),ss);
275 doublereal rdt_old = m_rdt;
280 if (fabs(rdt_old - m_rdt) >
Tiny) {
281 m_jac->updateTransient(m_rdt,
DATA_PTR(m_mask));
296 m_jac->updateTransient(m_rdt,
DATA_PTR(m_mask));
319 doublereal* r,
int loglevel)
324 writelog(
"\n\n step size (s) log10(ss) \n", loglevel);
325 writelog(
"===============================\n", loglevel);
331 doublereal ss =
ssnorm(x, r);
332 sprintf(str,
" %4d %10.4g %10.4g" , n,dt,log10(ss));
340 int m =
solve(x, r, loglevel-1);
347 copy(r, r + m_size, x);
351 dt = std::min(dt, m_tmax);
357 writelog(
"...failure.\n", loglevel);
361 "Time integration failed.");
374 void OneDim::save(
const std::string& fname, std::string
id,
375 const std::string& desc, doublereal* sol,
380 struct tm* newtime = localtime(&aclock);
383 ifstream fin(fname.c_str());
393 XML_Node& sim = root.addChild(
"simulation");
394 sim.addAttribute(
"id",
id);
395 addString(sim,
"timestamp",asctime(newtime));
400 Domain1D* d =
left();
405 ofstream s(fname.c_str());
407 throw CanteraError(
"OneDim::save",
"could not open file "+fname);
411 writelog(
"Solution saved to file "+fname+
" as solution "+
id+
".\n", loglevel);
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"
void addString(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...
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)
MultiNewton & newton()
Return a reference to the Newton iterator.
virtual doublereal eval(doublereal t) const
Evaluate the function.
size_t nComponents() const
Number of components at each grid point.
Base class for one-dimensional domains.
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 clearStats()
Clear saved statistics.
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. ...
Class MultiJac evaluates the Jacobian of a system of equations defined by a residual function supplie...
void removeChild(const XML_Node *const node)
Remove a child from this node's list of children.
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.
XML_Node * parent() const
Returns a pointer to the parent node of the current node.
void setOptions(int maxJacAge=5)
Set options.
void initTimeInteg(doublereal dt, const doublereal *x0)