Cantera  2.5.1
Sim1D.cpp
Go to the documentation of this file.
1 /**
2  * @file Sim1D.cpp
3  */
4 
5 // This file is part of Cantera. See License.txt in the top-level directory or
6 // at https://cantera.org/license.txt for license and copyright information.
7 
8 #include "cantera/oneD/Sim1D.h"
10 #include "cantera/oneD/StFlow.h"
12 #include "cantera/numerics/funcs.h"
13 #include "cantera/base/xml.h"
14 #include "cantera/numerics/Func1.h"
15 #include <limits>
16 
17 using namespace std;
18 
19 namespace Cantera
20 {
21 
22 Sim1D::Sim1D(vector<Domain1D*>& domains) :
23  OneDim(domains),
24  m_steady_callback(0)
25 {
26  // resize the internal solution vector and the work array, and perform
27  // domain-specific initialization of the solution vector.
28  resize();
29  for (size_t n = 0; n < nDomains(); n++) {
31  }
32 
33  // set some defaults
34  m_tstep = 1.0e-5;
35  m_steps = { 10 };
36 }
37 
38 void Sim1D::setInitialGuess(const std::string& component, vector_fp& locs, vector_fp& vals)
39 {
40  for (size_t dom=0; dom<nDomains(); dom++) {
41  Domain1D& d = domain(dom);
42  size_t ncomp = d.nComponents();
43  for (size_t comp=0; comp<ncomp; comp++) {
44  if (d.componentName(comp)==component) {
45  setProfile(dom,comp,locs,vals);
46  }
47  }
48  }
49 }
50 
51 void Sim1D::setValue(size_t dom, size_t comp, size_t localPoint, doublereal value)
52 {
53  size_t iloc = domain(dom).loc() + domain(dom).index(comp, localPoint);
54  AssertThrowMsg(iloc < m_x.size(), "Sim1D::setValue",
55  "Index out of bounds: {} > {}", iloc, m_x.size());
56  m_x[iloc] = value;
57 }
58 
59 doublereal Sim1D::value(size_t dom, size_t comp, size_t localPoint) const
60 {
61  size_t iloc = domain(dom).loc() + domain(dom).index(comp, localPoint);
62  AssertThrowMsg(iloc < m_x.size(), "Sim1D::value",
63  "Index out of bounds: {} > {}", iloc, m_x.size());
64  return m_x[iloc];
65 }
66 
67 doublereal Sim1D::workValue(size_t dom, size_t comp, size_t localPoint) const
68 {
69  size_t iloc = domain(dom).loc() + domain(dom).index(comp, localPoint);
70  AssertThrowMsg(iloc < m_x.size(), "Sim1D::workValue",
71  "Index out of bounds: {} > {}", iloc, m_x.size());
72  return m_xnew[iloc];
73 }
74 
75 void Sim1D::setProfile(size_t dom, size_t comp,
76  const vector_fp& pos, const vector_fp& values)
77 {
78  if (pos.front() != 0.0 || pos.back() != 1.0) {
79  throw CanteraError("Sim1D::setProfile",
80  "`pos` vector must span the range [0, 1]. Got a vector spanning "
81  "[{}, {}] instead.", pos.front(), pos.back());
82  }
83  Domain1D& d = domain(dom);
84  doublereal z0 = d.zmin();
85  doublereal z1 = d.zmax();
86  for (size_t n = 0; n < d.nPoints(); n++) {
87  double zpt = d.z(n);
88  double frac = (zpt - z0)/(z1 - z0);
89  double v = linearInterp(frac, pos, values);
90  setValue(dom, comp, n, v);
91  }
92 }
93 
94 void Sim1D::save(const std::string& fname, const std::string& id,
95  const std::string& desc, int loglevel)
96 {
97  OneDim::save(fname, id, desc, m_x.data(), loglevel);
98 }
99 
100 void Sim1D::saveResidual(const std::string& fname, const std::string& id,
101  const std::string& desc, int loglevel)
102 {
103  vector_fp res(m_x.size(), -999);
104  OneDim::eval(npos, &m_x[0], &res[0], 0.0);
105  OneDim::save(fname, id, desc, &res[0], loglevel);
106 }
107 
108 void Sim1D::restore(const std::string& fname, const std::string& id,
109  int loglevel)
110 {
111  XML_Node root;
112  root.build(fname);
113 
114  XML_Node* f = root.findID(id);
115  if (!f) {
116  throw CanteraError("Sim1D::restore","No solution with id = "+id);
117  }
118 
119  vector<XML_Node*> xd = f->getChildren("domain");
120  if (xd.size() != nDomains()) {
121  throw CanteraError("Sim1D::restore", "Solution does not contain the "
122  " correct number of domains. Found {} expected {}.\n",
123  xd.size(), nDomains());
124  }
125  for (size_t m = 0; m < nDomains(); m++) {
126  Domain1D& dom = domain(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());
130  }
131  dom.resize(domain(m).nComponents(), intValue((*xd[m])["points"]));
132  }
133  resize();
134  m_xlast_ts.clear();
135  for (size_t m = 0; m < nDomains(); m++) {
136  domain(m).restore(*xd[m], &m_x[start(m)], loglevel);
137  }
138  finalize();
139 }
140 
141 void Sim1D::setFlatProfile(size_t dom, size_t comp, doublereal v)
142 {
143  size_t np = domain(dom).nPoints();
144  for (size_t n = 0; n < np; n++) {
145  setValue(dom, comp, n, v);
146  }
147 }
148 
149 void Sim1D::showSolution(ostream& s)
150 {
151  for (size_t n = 0; n < nDomains(); n++) {
152  if (domain(n).domainType() != cEmptyType) {
153  domain(n).showSolution_s(s, &m_x[start(n)]);
154  }
155  }
156 }
157 
158 void Sim1D::showSolution()
159 {
160  for (size_t n = 0; n < nDomains(); n++) {
161  if (domain(n).domainType() != cEmptyType) {
162  writelog("\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "+domain(n).id()
163  +" <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
164  domain(n).showSolution(&m_x[start(n)]);
165  }
166  }
167 }
168 
170 {
171  if (m_xlast_ts.empty()) {
172  throw CanteraError("Sim1D::restoreTimeSteppingSolution",
173  "No successful time steps taken on this grid.");
174  }
175  m_x = m_xlast_ts;
176 }
177 
179 {
180  if (m_xlast_ss.empty()) {
181  throw CanteraError("Sim1D::restoreSteadySolution",
182  "No successful steady state solution");
183  }
184  m_x = m_xlast_ss;
185  for (size_t n = 0; n < nDomains(); n++) {
186  vector_fp& z = m_grid_last_ss[n];
187  domain(n).setupGrid(z.size(), z.data());
188  }
189 }
190 
191 void Sim1D::getInitialSoln()
192 {
193  for (size_t n = 0; n < nDomains(); n++) {
194  domain(n)._getInitialSoln(&m_x[start(n)]);
195  }
196 }
197 
199 {
200  for (size_t n = 0; n < nDomains(); n++) {
201  domain(n)._finalize(&m_x[start(n)]);
202  }
203 }
204 
205 void Sim1D::setTimeStep(double stepsize, size_t n, const int* tsteps)
206 {
207  m_tstep = stepsize;
208  m_steps.resize(n);
209  for (size_t i = 0; i < n; i++) {
210  m_steps[i] = tsteps[i];
211  }
212 }
213 
214 int Sim1D::newtonSolve(int loglevel)
215 {
216  int m = OneDim::solve(m_x.data(), m_xnew.data(), loglevel);
217  if (m >= 0) {
218  m_x = m_xnew;
219  return 0;
220  } else if (m > -10) {
221  return -1;
222  } else {
223  throw CanteraError("Sim1D::newtonSolve",
224  "ERROR: OneDim::solve returned m = {}", m);
225  }
226 }
227 
228 void Sim1D::solve(int loglevel, bool refine_grid)
229 {
230  int new_points = 1;
231  doublereal dt = m_tstep;
232  m_nsteps = 0;
233  int soln_number = -1;
234  finalize();
235 
236  while (new_points > 0) {
237  size_t istep = 0;
238  int nsteps = m_steps[istep];
239 
240  bool ok = false;
241  if (loglevel > 0) {
242  writeline('.', 78, true, true);
243  }
244  while (!ok) {
245  // Attempt to solve the steady problem
246  setSteadyMode();
247  newton().setOptions(m_ss_jac_age);
248  debuglog("Attempt Newton solution of steady-state problem...", loglevel);
249  int status = newtonSolve(loglevel-1);
250 
251  if (status == 0) {
252  if (loglevel > 0) {
253  writelog(" success.\n\n");
254  writelog("Problem solved on [");
255  for (size_t mm = 1; mm < nDomains(); mm+=2) {
256  writelog("{}", domain(mm).nPoints());
257  if (mm + 2 < nDomains()) {
258  writelog(", ");
259  }
260  }
261  writelog("] point grid(s).\n");
262  }
263  if (m_steady_callback) {
265  }
266 
267  if (loglevel > 6) {
268  save("debug_sim1d.xml", "debug",
269  "After successful Newton solve");
270  }
271  if (loglevel > 7) {
272  saveResidual("debug_sim1d.xml", "residual",
273  "After successful Newton solve");
274  }
275  ok = true;
276  soln_number++;
277  } else {
278  debuglog(" failure. \n", loglevel);
279  if (loglevel > 6) {
280  save("debug_sim1d.xml", "debug",
281  "After unsuccessful Newton solve");
282  }
283  if (loglevel > 7) {
284  saveResidual("debug_sim1d.xml", "residual",
285  "After unsuccessful Newton solve");
286  }
287  if (loglevel > 0) {
288  writelog("Take {} timesteps ", nsteps);
289  }
290  dt = timeStep(nsteps, dt, m_x.data(), m_xnew.data(),
291  loglevel-1);
292  m_xlast_ts = m_x;
293  if (loglevel > 6) {
294  save("debug_sim1d.xml", "debug", "After timestepping");
295  }
296  if (loglevel > 7) {
297  saveResidual("debug_sim1d.xml", "residual",
298  "After timestepping");
299  }
300 
301  if (loglevel == 1) {
302  writelog(" {:10.4g} {:10.4g}\n", dt,
303  log10(ssnorm(m_x.data(), m_xnew.data())));
304  }
305  istep++;
306  if (istep >= m_steps.size()) {
307  nsteps = m_steps.back();
308  } else {
309  nsteps = m_steps[istep];
310  }
311  dt = std::min(dt, m_tmax);
312  }
313  }
314  if (loglevel > 0) {
315  writeline('.', 78, true, true);
316  }
317  if (loglevel > 2) {
318  showSolution();
319  }
320 
321  if (refine_grid) {
322  new_points = refine(loglevel);
323  if (new_points) {
324  // If the grid has changed, preemptively reduce the timestep
325  // to avoid multiple successive failed time steps.
326  dt = m_tstep;
327  }
328  if (new_points && loglevel > 6) {
329  save("debug_sim1d.xml", "debug", "After regridding");
330  }
331  if (new_points && loglevel > 7) {
332  saveResidual("debug_sim1d.xml", "residual",
333  "After regridding");
334  }
335  } else {
336  debuglog("grid refinement disabled.\n", loglevel);
337  new_points = 0;
338  }
339  }
340 }
341 
342 int Sim1D::refine(int loglevel)
343 {
344  int ianalyze, np = 0;
345  vector_fp znew, xnew;
346  std::vector<size_t> dsize;
347 
348  m_xlast_ss = m_x;
349  m_grid_last_ss.clear();
350 
351  for (size_t n = 0; n < nDomains(); n++) {
352  Domain1D& d = domain(n);
353  Refiner& r = d.refiner();
354 
355  // Save the old grid corresponding to the converged solution
356  m_grid_last_ss.push_back(d.grid());
357 
358  // determine where new points are needed
359  ianalyze = r.analyze(d.grid().size(), d.grid().data(), &m_x[start(n)]);
360  if (ianalyze < 0) {
361  return ianalyze;
362  }
363 
364  if (loglevel > 0) {
365  r.show();
366  }
367 
368  np += r.nNewPoints();
369  size_t comp = d.nComponents();
370 
371  // loop over points in the current grid
372  size_t npnow = d.nPoints();
373  size_t nstart = znew.size();
374  for (size_t m = 0; m < npnow; m++) {
375  if (r.keepPoint(m)) {
376  // add the current grid point to the new grid
377  znew.push_back(d.grid(m));
378 
379  // do the same for the solution at this point
380  for (size_t i = 0; i < comp; i++) {
381  xnew.push_back(value(n, i, m));
382  }
383 
384  // now check whether a new point is needed in the interval to
385  // the right of point m, and if so, add entries to znew and xnew
386  // for this new point
387  if (r.newPointNeeded(m) && m + 1 < npnow) {
388  // add new point at midpoint
389  double zmid = 0.5*(d.grid(m) + d.grid(m+1));
390  znew.push_back(zmid);
391  np++;
392 
393  // for each component, linearly interpolate
394  // the solution to this point
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);
398  }
399  }
400  } else {
401  if (loglevel > 0) {
402  writelog("refine: discarding point at {}\n", d.grid(m));
403  }
404  }
405  }
406  dsize.push_back(znew.size() - nstart);
407  }
408 
409  // At this point, the new grid znew and the new solution vector xnew have
410  // been constructed, but the domains themselves have not yet been modified.
411  // Now update each domain with the new grid.
412 
413  size_t gridstart = 0, gridsize;
414  for (size_t n = 0; n < nDomains(); n++) {
415  Domain1D& d = domain(n);
416  gridsize = dsize[n];
417  d.setupGrid(gridsize, &znew[gridstart]);
418  gridstart += gridsize;
419  }
420 
421  // Replace the current solution vector with the new one
422  m_x = xnew;
423  resize();
424  finalize();
425  return np;
426 }
427 
429 {
430  int np = 0;
431  vector_fp znew, xnew;
432  double zfixed = 0.0;
433  double z1 = 0.0, z2 = 0.0;
434  std::vector<size_t> dsize;
435 
436  for (size_t n = 0; n < nDomains(); n++) {
437  Domain1D& d = domain(n);
438  size_t comp = d.nComponents();
439  size_t mfixed = npos;
440 
441  // loop over current grid to determine where new point is needed
442  StFlow* d_free = dynamic_cast<StFlow*>(&domain(n));
443  size_t npnow = d.nPoints();
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);
450  // threshold to avoid adding new point too close to existing point
451  double thresh = min(1., 1.e-1 * (t2 - t1));
452  z1 = d.grid(m);
453  z2 = d.grid(m + 1);
454  if (fabs(t - t1) <= thresh) {
455  zfixed = z1;
456  fixedpt = true;
457  } else if (fabs(t2 - t) <= thresh) {
458  zfixed = z2;
459  fixedpt = true;
460  } else if ((t1 < t) && (t < t2)) {
461  mfixed = m;
462  zfixed = (z1 - z2) / (t1 - t2) * (t - t2) + z2;
463  fixedpt = true;
464  }
465 
466  if (fixedpt) {
467  d_free->m_zfixed = zfixed;
468  d_free->m_tfixed = t;
469  break;
470  }
471  }
472  }
473 
474  // copy solution domain and push back values
475  for (size_t m = 0; m < npnow; m++) {
476  // add the current grid point to the new grid
477  znew.push_back(d.grid(m));
478 
479  // do the same for the solution at this point
480  for (size_t i = 0; i < comp; i++) {
481  xnew.push_back(value(n, i, m));
482  }
483  if (m == mfixed) {
484  // add new point at zfixed (mfixed is not npos)
485  znew.push_back(zfixed);
486  np++;
487  double interp_factor = (zfixed - z2) / (z1 - z2);
488  // for each component, linearly interpolate
489  // the solution to this point
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);
493  }
494  }
495  }
496  dsize.push_back(znew.size() - nstart);
497  }
498 
499  // At this point, the new grid znew and the new solution vector xnew have
500  // been constructed, but the domains themselves have not yet been modified.
501  // Now update each domain with the new grid.
502  size_t gridstart = 0;
503  for (size_t n = 0; n < nDomains(); n++) {
504  Domain1D& d = domain(n);
505  size_t gridsize = dsize[n];
506  d.setupGrid(gridsize, &znew[gridstart]);
507  gridstart += gridsize;
508  }
509 
510  // Replace the current solution vector with the new one
511  m_x = xnew;
512 
513  resize();
514  finalize();
515  return np;
516 }
517 
519 {
520  double t_fixed = std::numeric_limits<double>::quiet_NaN();
521  for (size_t n = 0; n < nDomains(); n++) {
522  StFlow* d = dynamic_cast<StFlow*>(&domain(n));
523  if (d && d->domainType() == cFreeFlow && d->m_tfixed > 0) {
524  t_fixed = d->m_tfixed;
525  break;
526  }
527  }
528  return t_fixed;
529 }
530 
532 {
533  double z_fixed = std::numeric_limits<double>::quiet_NaN();
534  for (size_t n = 0; n < nDomains(); n++) {
535  StFlow* d = dynamic_cast<StFlow*>(&domain(n));
536  if (d && d->domainType() == cFreeFlow && d->m_tfixed > 0) {
537  z_fixed = d->m_zfixed;
538  break;
539  }
540  }
541  return z_fixed;
542 }
543 
544 void Sim1D::setRefineCriteria(int dom, double ratio,
545  double slope, double curve, double prune)
546 {
547  if (dom >= 0) {
548  Refiner& r = domain(dom).refiner();
549  r.setCriteria(ratio, slope, curve, prune);
550  } else {
551  for (size_t n = 0; n < nDomains(); n++) {
552  Refiner& r = domain(n).refiner();
553  r.setCriteria(ratio, slope, curve, prune);
554  }
555  }
556 }
557 
559 {
560  if (dom >= 0) {
561  Refiner& r = domain(dom).refiner();
562  return r.getCriteria();
563  } else {
564  throw CanteraError("Sim1D::getRefineCriteria",
565  "Must specify domain to get criteria from");
566  }
567 }
568 
569 void Sim1D::setGridMin(int dom, double gridmin)
570 {
571  if (dom >= 0) {
572  Refiner& r = domain(dom).refiner();
573  r.setGridMin(gridmin);
574  } else {
575  for (size_t n = 0; n < nDomains(); n++) {
576  Refiner& r = domain(n).refiner();
577  r.setGridMin(gridmin);
578  }
579  }
580 }
581 
582 void Sim1D::setMaxGridPoints(int dom, int npoints)
583 {
584  if (dom >= 0) {
585  Refiner& r = domain(dom).refiner();
586  r.setMaxPoints(npoints);
587  } else {
588  for (size_t n = 0; n < nDomains(); n++) {
589  Refiner& r = domain(n).refiner();
590  r.setMaxPoints(npoints);
591  }
592  }
593 }
594 
595 size_t Sim1D::maxGridPoints(size_t dom)
596 {
597  Refiner& r = domain(dom).refiner();
598  return r.maxPoints();
599 }
600 
601 doublereal Sim1D::jacobian(int i, int j)
602 {
603  return OneDim::jacobian().value(i,j);
604 }
605 
606 void Sim1D::evalSSJacobian()
607 {
608  OneDim::evalSSJacobian(m_x.data(), m_xnew.data());
609 }
610 
611 void Sim1D::solveAdjoint(const double* b, double* lambda)
612 {
613  for (auto& D : m_dom) {
614  D->forceFullUpdate(true);
615  }
616  evalSSJacobian();
617  for (auto& D : m_dom) {
618  D->forceFullUpdate(false);
619  }
620 
621  // Form J^T
622  size_t bw = bandwidth();
623  BandMatrix Jt(size(), bw, bw);
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);
629  }
630  }
631 
632  Jt.solve(b, lambda);
633 }
634 
636 {
637  OneDim::resize();
638  m_x.resize(size(), 0.0);
639  m_xnew.resize(size(), 0.0);
640 }
641 
642 }
A class for banded matrices, involving matrix inversion processes.
Definition: BandMatrix.h:35
int solve(const doublereal *const b, doublereal *const x)
Solve the matrix problem Ax = b.
Definition: BandMatrix.cpp:275
doublereal & value(size_t i, size_t j)
Return a changeable reference to element (i,j).
Definition: BandMatrix.cpp:176
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
Base class for one-dimensional domains.
Definition: Domain1D.h:39
size_t nComponents() const
Number of components at each grid point.
Definition: Domain1D.h:134
virtual void showSolution(const doublereal *x)
Print the solution.
Definition: Domain1D.cpp:194
virtual void _finalize(const doublereal *x)
In some cases, a domain may need to set parameters that depend on the initial solution estimate.
Definition: Domain1D.h:477
size_t nPoints() const
Number of grid points in this domain.
Definition: Domain1D.h:156
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
Definition: Domain1D.cpp:56
virtual void resize(size_t nv, size_t np)
Definition: Domain1D.cpp:33
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
Definition: Domain1D.cpp:123
virtual void _getInitialSoln(doublereal *x)
Writes some or all initial solution values into the global solution array, beginning at the location ...
Definition: Domain1D.cpp:243
Refiner & refiner()
Return a reference to the grid refiner.
Definition: Domain1D.h:129
int domainType()
Domain type flag.
Definition: Domain1D.h:54
virtual void setupGrid(size_t n, const doublereal *z)
called to set up initial grid, and after grid refinement
Definition: Domain1D.cpp:184
virtual size_t loc(size_t j=0) const
Location of the start of the local solution vector in the global solution vector,.
Definition: Domain1D.h:359
virtual doublereal eval(doublereal t) const
Evaluate the function.
Definition: Func1.cpp:60
void setOptions(int maxJacAge=5)
Set options.
Definition: MultiNewton.h:68
Container class for multiple-domain 1D problems.
Definition: OneDim.h:26
size_t start(size_t i) const
The index of the start of domain i in the solution vector.
Definition: OneDim.h:85
int m_nsteps
Number of time steps taken in the current call to solve()
Definition: OneDim.h:361
virtual void resize()
Call after one or more grids has changed size, e.g. after being refined.
Definition: OneDim.cpp:168
std::unique_ptr< MultiJac > m_jac
Jacobian evaluator.
Definition: OneDim.h:334
size_t size() const
Total solution vector length;.
Definition: OneDim.h:96
doublereal ssnorm(doublereal *x, doublereal *r)
Steady-state max norm (infinity norm) of the residual evaluated using solution x.
Definition: OneDim.cpp:290
size_t nDomains() const
Number of domains.
Definition: OneDim.h:54
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...
Definition: OneDim.cpp:65
size_t bandwidth() const
Jacobian bandwidth.
Definition: OneDim.h:126
double timeStep(int nsteps, double dt, double *x, double *r, int loglevel)
Definition: OneDim.cpp:348
void eval(size_t j, double *x, double *r, doublereal rdt=-1.0, int count=1)
Evaluate the multi-domain residual function.
Definition: OneDim.cpp:258
doublereal m_tmax
maximum timestep size
Definition: OneDim.h:329
MultiJac & jacobian()
Return a reference to the Jacobian evaluator.
Definition: OneDim.cpp:101
void setSteadyMode()
Definition: OneDim.cpp:319
int solve(doublereal *x0, doublereal *x1, int loglevel)
Solve F(x) = 0, where F(x) is the multi-domain residual function.
Definition: OneDim.cpp:224
Domain1D & domain(size_t i) const
Return a reference to domain i.
Definition: OneDim.h:59
MultiNewton & newton()
Return a reference to the Newton iterator.
Definition: OneDim.cpp:105
Refine Domain1D grids so that profiles satisfy adaptation tolerances.
Definition: refine.h:17
size_t maxPoints() const
Returns the maximum number of points allowed in the domain.
Definition: refine.h:57
vector_fp getCriteria()
Get the grid refinement criteria.
Definition: refine.h:42
void setMaxPoints(int npmax)
Set the maximum number of points allowed in the domain.
Definition: refine.h:52
void setCriteria(doublereal ratio=10.0, doublereal slope=0.8, doublereal curve=0.8, doublereal prune=-0.1)
Set grid refinement criteria.
Definition: refine.cpp:23
void setGridMin(double gridmin)
Set the minimum allowable spacing between adjacent grid points [m].
Definition: refine.h:62
vector_fp m_xlast_ss
the solution vector after the last successful steady-state solve (stored before grid refinement)
Definition: Sim1D.h:238
virtual void resize()
Call after one or more grids has changed size, e.g. after being refined.
Definition: Sim1D.cpp:635
void restoreTimeSteppingSolution()
Set the current solution vector to the last successful time-stepping solution.
Definition: Sim1D.cpp:169
vector_fp m_x
the solution vector
Definition: Sim1D.h:231
double fixedTemperatureLocation()
Return location of the point where temperature is fixed.
Definition: Sim1D.cpp:531
void finalize()
Calls method _finalize in each domain.
Definition: Sim1D.cpp:198
vector_int m_steps
array of number of steps to take before re-attempting the steady-state solution
Definition: Sim1D.h:252
int refine(int loglevel=0)
Refine the grid in all domains.
Definition: Sim1D.cpp:342
double fixedTemperature()
Return temperature at the point used to fix the flame location.
Definition: Sim1D.cpp:518
vector_fp m_xlast_ts
the solution vector after the last successful timestepping
Definition: Sim1D.h:234
vector_fp m_xnew
a work array used to hold the residual or the new solution
Definition: Sim1D.h:245
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.
Definition: Sim1D.cpp:75
vector_fp getRefineCriteria(int dom)
Get the grid refinement criteria.
Definition: Sim1D.cpp:558
void setMaxGridPoints(int dom, int npoints)
Set the maximum number of grid points in the domain.
Definition: Sim1D.cpp:582
int setFixedTemperature(double t)
Add node for fixed temperature point of freely propagating flame.
Definition: Sim1D.cpp:428
int newtonSolve(int loglevel)
Wrapper around the Newton solver.
Definition: Sim1D.cpp:214
std::vector< vector_fp > m_grid_last_ss
the grids for each domain after the last successful steady-state solve (stored before grid refinement...
Definition: Sim1D.h:242
void restore(const std::string &fname, const std::string &id, int loglevel=2)
Initialize the solution with a previously-saved solution.
Definition: Sim1D.cpp:108
void solveAdjoint(const double *b, double *lambda)
Solve the equation .
Definition: Sim1D.cpp:611
Func1 * m_steady_callback
User-supplied function called after a successful steady-state solve.
Definition: Sim1D.h:255
void restoreSteadySolution()
Set the current solution vector and grid to the last successful steady- state solution.
Definition: Sim1D.cpp:178
size_t maxGridPoints(size_t dom)
Get the maximum number of grid points in this domain.
Definition: Sim1D.cpp:595
void showSolution(std::ostream &s)
Print to stream s the current solution for all domains.
Definition: Sim1D.cpp:149
doublereal value(size_t dom, size_t comp, size_t localPoint) const
Get one entry in the solution vector.
Definition: Sim1D.cpp:59
void setValue(size_t dom, size_t comp, size_t localPoint, doublereal value)
Set a single value in the solution vector.
Definition: Sim1D.cpp:51
void setGridMin(int dom, double gridmin)
Set the minimum grid spacing in the specified domain(s).
Definition: Sim1D.cpp:569
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.
Definition: Sim1D.cpp:544
void setFlatProfile(size_t dom, size_t comp, doublereal v)
Set component 'comp' of domain 'dom' to value 'v' at all points.
Definition: Sim1D.cpp:141
doublereal m_tstep
timestep
Definition: Sim1D.h:248
void setInitialGuess(const std::string &component, vector_fp &locs, vector_fp &vals)
Set initial guess for one component for all domains.
Definition: Sim1D.cpp:38
This class represents 1D flow domains that satisfy the one-dimensional similarity solution for chemic...
Definition: StFlow.h:37
double m_tfixed
Temperature at the point used to fix the flame location.
Definition: StFlow.h:489
double m_zfixed
Location of the point where temperature is fixed.
Definition: StFlow.h:486
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:104
void build(const std::string &filename)
Populate the XML tree from an input file.
Definition: xml.cpp:762
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".
Definition: xml.cpp:645
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...
Definition: xml.cpp:711
Header for a file containing miscellaneous numerical functions.
#define AssertThrowMsg(expr, procedure,...)
Assertion must be true or an error is thrown.
Definition: ctexceptions.h:265
void debuglog(const std::string &msg, int loglevel)
Write a message to the log only if loglevel > 0.
Definition: global.h:140
void warn_user(const std::string &method, const std::string &msg, const Args &... args)
Definition: global.h:206
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:188
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:180
void writelog(const std::string &fmt, const Args &... args)
Write a formatted message to the screen.
Definition: global.h:158
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:264
doublereal linearInterp(doublereal x, const vector_fp &xpts, const vector_fp &fpts)
Linearly interpolate a function defined on a discrete grid.
Definition: funcs.cpp:13
int intValue(const std::string &val)
Translate a string into one integer value.
Classes providing support for XML data files.