Cantera 2.6.0
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
10#include "cantera/oneD/StFlow.h"
12#include "cantera/oneD/refine.h"
14#include "cantera/base/xml.h"
17#include <limits>
18#include <fstream>
19
20using namespace std;
21
22namespace Cantera
23{
24
25Sim1D::Sim1D(vector<Domain1D*>& domains) :
26 OneDim(domains),
27 m_steady_callback(0)
28{
29 // resize the internal solution vector and the work array, and perform
30 // domain-specific initialization of the solution vector.
31 resize();
32 for (size_t n = 0; n < nDomains(); n++) {
34 }
35
36 // set some defaults
37 m_tstep = 1.0e-5;
38 m_steps = { 10 };
39}
40
41void Sim1D::setInitialGuess(const std::string& component, vector_fp& locs, vector_fp& vals)
42{
43 for (size_t dom=0; dom<nDomains(); dom++) {
44 Domain1D& d = domain(dom);
45 size_t ncomp = d.nComponents();
46 for (size_t comp=0; comp<ncomp; comp++) {
47 if (d.componentName(comp)==component) {
48 setProfile(dom,comp,locs,vals);
49 }
50 }
51 }
52}
53
54void Sim1D::setValue(size_t dom, size_t comp, size_t localPoint, doublereal value)
55{
56 size_t iloc = domain(dom).loc() + domain(dom).index(comp, localPoint);
57 AssertThrowMsg(iloc < m_x.size(), "Sim1D::setValue",
58 "Index out of bounds: {} > {}", iloc, m_x.size());
59 m_x[iloc] = value;
60}
61
62doublereal Sim1D::value(size_t dom, size_t comp, size_t localPoint) const
63{
64 size_t iloc = domain(dom).loc() + domain(dom).index(comp, localPoint);
65 AssertThrowMsg(iloc < m_x.size(), "Sim1D::value",
66 "Index out of bounds: {} > {}", iloc, m_x.size());
67 return m_x[iloc];
68}
69
70doublereal Sim1D::workValue(size_t dom, size_t comp, size_t localPoint) const
71{
72 size_t iloc = domain(dom).loc() + domain(dom).index(comp, localPoint);
73 AssertThrowMsg(iloc < m_x.size(), "Sim1D::workValue",
74 "Index out of bounds: {} > {}", iloc, m_x.size());
75 return m_xnew[iloc];
76}
77
78void Sim1D::setProfile(size_t dom, size_t comp,
79 const vector_fp& pos, const vector_fp& values)
80{
81 if (pos.front() != 0.0 || pos.back() != 1.0) {
82 throw CanteraError("Sim1D::setProfile",
83 "`pos` vector must span the range [0, 1]. Got a vector spanning "
84 "[{}, {}] instead.", pos.front(), pos.back());
85 }
86 Domain1D& d = domain(dom);
87 doublereal z0 = d.zmin();
88 doublereal z1 = d.zmax();
89 for (size_t n = 0; n < d.nPoints(); n++) {
90 double zpt = d.z(n);
91 double frac = (zpt - z0)/(z1 - z0);
92 double v = linearInterp(frac, pos, values);
93 setValue(dom, comp, n, v);
94 }
95}
96
97void Sim1D::save(const std::string& fname, const std::string& id,
98 const std::string& desc, int loglevel)
99{
100 size_t dot = fname.find_last_of(".");
101 string extension = (dot != npos) ? toLowerCopy(fname.substr(dot+1)) : "";
102 if (extension != "yml" && extension != "yaml") {
103 OneDim::save(fname, id, desc, m_x.data(), loglevel);
104 return;
105 }
106
107 // Check for an existing file and load it if present
108 AnyMap data;
109 if (ifstream(fname).good()) {
110 data = AnyMap::fromYamlFile(fname);
111 }
112 bool preexisting = data.hasKey(id);
113
114 // Add this simulation to the YAML
115 data[id] = serialize(m_x.data());
116
117 // Add metadata
118 data[id]["description"] = desc;
119 data[id]["generator"] = "Cantera Sim1D";
120 data[id]["cantera-version"] = CANTERA_VERSION;
121 data[id]["git-commit"] = gitCommit();
122
123 // Add a timestamp indicating the current time
124 time_t aclock;
125 ::time(&aclock); // Get time in seconds
126 struct tm* newtime = localtime(&aclock); // Convert time to struct tm form
127 data[id]["date"] = stripnonprint(asctime(newtime));
128
129 // Force metadata fields to the top of the file
130 data[id]["description"].setLoc(-6, 0);
131 data[id]["generator"].setLoc(-5, 0);
132 data[id]["cantera-version"].setLoc(-4, 0);
133 data[id]["git-commit"].setLoc(-3, 0);
134 data[id]["date"].setLoc(-2, 0);
135
136 // If this is not replacing an existing solution, put it at the end
137 if (!preexisting) {
138 data[id].setLoc(INT_MAX, 0);
139 }
140
141 // Write the output file and remove the now-outdated cached file
142 std::ofstream out(fname);
143 out << data.toYamlString();
145 if (loglevel > 0) {
146 writelog("Solution saved to file {} as solution '{}'.\n", fname, id);
147 }
148}
149
150void Sim1D::saveResidual(const std::string& fname, const std::string& id,
151 const std::string& desc, int loglevel)
152{
153 vector_fp res(m_x.size(), -999);
154 OneDim::eval(npos, &m_x[0], &res[0], 0.0);
155 // Temporarily put the residual into m_x, since this is the vector that the save()
156 // function reads.
157 std::swap(res, m_x);
158 save(fname, id, desc, loglevel);
159 std::swap(res, m_x);
160}
161
162void Sim1D::restore(const std::string& fname, const std::string& id,
163 int loglevel)
164{
165 size_t dot = fname.find_last_of(".");
166 string extension = (dot != npos) ? toLowerCopy(fname.substr(dot+1)) : "";
167 if (extension == "yml" || extension == "yaml") {
168 AnyMap root = AnyMap::fromYamlFile(fname);
169 if (!root.hasKey(id)) {
170 throw InputFileError("Sim1D::restore", root,
171 "No solution with id '{}'", id);
172 }
173 const auto& state = root[id];
174 for (auto dom : m_dom) {
175 if (!state.hasKey(dom->id())) {
176 throw InputFileError("Sim1D::restore", state,
177 "Saved state '{}' does not contain a domain named '{}'.",
178 id, dom->id());
179 }
180 dom->resize(dom->nComponents(), state[dom->id()]["points"].asInt());
181 }
182 resize();
183 m_xlast_ts.clear();
184 for (auto dom : m_dom) {
185 dom->restore(state[dom->id()].as<AnyMap>(), m_x.data() + dom->loc(),
186 loglevel);
187 }
188 } else {
189 XML_Node root;
190 root.build(fname);
191
192 XML_Node* f = root.findID(id);
193 if (!f) {
194 throw CanteraError("Sim1D::restore","No solution with id = "+id);
195 }
196
197 vector<XML_Node*> xd = f->getChildren("domain");
198 if (xd.size() != nDomains()) {
199 throw CanteraError("Sim1D::restore", "Solution does not contain the "
200 " correct number of domains. Found {} expected {}.\n",
201 xd.size(), nDomains());
202 }
203 for (size_t m = 0; m < nDomains(); m++) {
204 Domain1D& dom = domain(m);
205 if (loglevel > 0 && xd[m]->attrib("id") != dom.id()) {
206 warn_user("Sim1D::restore", "Domain names do not match: "
207 "'{} and '{}'", (*xd[m])["id"], dom.id());
208 }
209 dom.resize(domain(m).nComponents(), intValue((*xd[m])["points"]));
210 }
211 resize();
212 m_xlast_ts.clear();
213 for (size_t m = 0; m < nDomains(); m++) {
214 domain(m).restore(*xd[m], &m_x[start(m)], loglevel);
215 }
216 }
217 finalize();
218}
219
220void Sim1D::setFlatProfile(size_t dom, size_t comp, doublereal v)
221{
222 size_t np = domain(dom).nPoints();
223 for (size_t n = 0; n < np; n++) {
224 setValue(dom, comp, n, v);
225 }
226}
227
228void Sim1D::showSolution(ostream& s)
229{
230 for (size_t n = 0; n < nDomains(); n++) {
231 if (domain(n).domainType() != cEmptyType) {
232 domain(n).showSolution_s(s, &m_x[start(n)]);
233 }
234 }
235}
236
237void Sim1D::showSolution()
238{
239 for (size_t n = 0; n < nDomains(); n++) {
240 if (domain(n).domainType() != cEmptyType) {
241 writelog("\n\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> "+domain(n).id()
242 +" <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n\n");
243 domain(n).showSolution(&m_x[start(n)]);
244 }
245 }
246}
247
249{
250 if (m_xlast_ts.empty()) {
251 throw CanteraError("Sim1D::restoreTimeSteppingSolution",
252 "No successful time steps taken on this grid.");
253 }
254 m_x = m_xlast_ts;
255}
256
258{
259 if (m_xlast_ss.empty()) {
260 throw CanteraError("Sim1D::restoreSteadySolution",
261 "No successful steady state solution");
262 }
263 m_x = m_xlast_ss;
264 for (size_t n = 0; n < nDomains(); n++) {
266 domain(n).setupGrid(z.size(), z.data());
267 }
268}
269
270void Sim1D::getInitialSoln()
271{
272 for (size_t n = 0; n < nDomains(); n++) {
274 }
275}
276
278{
279 for (size_t n = 0; n < nDomains(); n++) {
280 domain(n)._finalize(&m_x[start(n)]);
281 }
282}
283
284void Sim1D::setTimeStep(double stepsize, size_t n, const int* tsteps)
285{
286 m_tstep = stepsize;
287 m_steps.resize(n);
288 for (size_t i = 0; i < n; i++) {
289 m_steps[i] = tsteps[i];
290 }
291}
292
293int Sim1D::newtonSolve(int loglevel)
294{
295 int m = OneDim::solve(m_x.data(), m_xnew.data(), loglevel);
296 if (m >= 0) {
297 m_x = m_xnew;
298 return 0;
299 } else if (m > -10) {
300 return -1;
301 } else {
302 throw CanteraError("Sim1D::newtonSolve",
303 "ERROR: OneDim::solve returned m = {}", m);
304 }
305}
306
307void Sim1D::solve(int loglevel, bool refine_grid)
308{
309 int new_points = 1;
310 doublereal dt = m_tstep;
311 m_nsteps = 0;
312 int soln_number = -1;
313 finalize();
314
315 while (new_points > 0) {
316 size_t istep = 0;
317 int nsteps = m_steps[istep];
318
319 bool ok = false;
320 if (loglevel > 0) {
321 writeline('.', 78, true, true);
322 }
323 while (!ok) {
324 // Attempt to solve the steady problem
326 newton().setOptions(m_ss_jac_age);
327 debuglog("Attempt Newton solution of steady-state problem...", loglevel);
328 int status = newtonSolve(loglevel-1);
329
330 if (status == 0) {
331 if (loglevel > 0) {
332 writelog(" success.\n\n");
333 writelog("Problem solved on [");
334 for (size_t mm = 1; mm < nDomains(); mm+=2) {
335 writelog("{}", domain(mm).nPoints());
336 if (mm + 2 < nDomains()) {
337 writelog(", ");
338 }
339 }
340 writelog("] point grid(s).\n");
341 }
342 if (m_steady_callback) {
344 }
345
346 if (loglevel > 6) {
347 save("debug_sim1d.yaml", "debug",
348 "After successful Newton solve");
349 }
350 if (loglevel > 7) {
351 saveResidual("debug_sim1d.yaml", "residual",
352 "After successful Newton solve");
353 }
354 ok = true;
355 soln_number++;
356 } else {
357 debuglog(" failure. \n", loglevel);
358 if (loglevel > 6) {
359 save("debug_sim1d.yaml", "debug",
360 "After unsuccessful Newton solve");
361 }
362 if (loglevel > 7) {
363 saveResidual("debug_sim1d.yaml", "residual",
364 "After unsuccessful Newton solve");
365 }
366 if (loglevel > 0) {
367 writelog("Take {} timesteps ", nsteps);
368 }
369 dt = timeStep(nsteps, dt, m_x.data(), m_xnew.data(),
370 loglevel-1);
371 m_xlast_ts = m_x;
372 if (loglevel > 6) {
373 save("debug_sim1d.yaml", "debug", "After timestepping");
374 }
375 if (loglevel > 7) {
376 saveResidual("debug_sim1d.yaml", "residual",
377 "After timestepping");
378 }
379
380 if (loglevel == 1) {
381 writelog(" {:10.4g} {:10.4g}\n", dt,
382 log10(ssnorm(m_x.data(), m_xnew.data())));
383 }
384 istep++;
385 if (istep >= m_steps.size()) {
386 nsteps = m_steps.back();
387 } else {
388 nsteps = m_steps[istep];
389 }
390 dt = std::min(dt, m_tmax);
391 }
392 }
393 if (loglevel > 0) {
394 writeline('.', 78, true, true);
395 }
396 if (loglevel > 2) {
397 showSolution();
398 }
399
400 if (refine_grid) {
401 new_points = refine(loglevel);
402 if (new_points) {
403 // If the grid has changed, preemptively reduce the timestep
404 // to avoid multiple successive failed time steps.
405 dt = m_tstep;
406 }
407 if (new_points && loglevel > 6) {
408 save("debug_sim1d.yaml", "debug", "After regridding");
409 }
410 if (new_points && loglevel > 7) {
411 saveResidual("debug_sim1d.yaml", "residual",
412 "After regridding");
413 }
414 } else {
415 debuglog("grid refinement disabled.\n", loglevel);
416 new_points = 0;
417 }
418 }
419}
420
421int Sim1D::refine(int loglevel)
422{
423 int ianalyze, np = 0;
424 vector_fp znew, xnew;
425 std::vector<size_t> dsize;
426
427 m_xlast_ss = m_x;
428 m_grid_last_ss.clear();
429
430 for (size_t n = 0; n < nDomains(); n++) {
431 Domain1D& d = domain(n);
432 Refiner& r = d.refiner();
433
434 // Save the old grid corresponding to the converged solution
435 m_grid_last_ss.push_back(d.grid());
436
437 // determine where new points are needed
438 ianalyze = r.analyze(d.grid().size(), d.grid().data(), &m_x[start(n)]);
439 if (ianalyze < 0) {
440 return ianalyze;
441 }
442
443 if (loglevel > 0) {
444 r.show();
445 }
446
447 np += r.nNewPoints();
448 size_t comp = d.nComponents();
449
450 // loop over points in the current grid
451 size_t npnow = d.nPoints();
452 size_t nstart = znew.size();
453 for (size_t m = 0; m < npnow; m++) {
454 if (r.keepPoint(m)) {
455 // add the current grid point to the new grid
456 znew.push_back(d.grid(m));
457
458 // do the same for the solution at this point
459 for (size_t i = 0; i < comp; i++) {
460 xnew.push_back(value(n, i, m));
461 }
462
463 // now check whether a new point is needed in the interval to
464 // the right of point m, and if so, add entries to znew and xnew
465 // for this new point
466 if (r.newPointNeeded(m) && m + 1 < npnow) {
467 // add new point at midpoint
468 double zmid = 0.5*(d.grid(m) + d.grid(m+1));
469 znew.push_back(zmid);
470 np++;
471
472 // for each component, linearly interpolate
473 // the solution to this point
474 for (size_t i = 0; i < comp; i++) {
475 double xmid = 0.5*(value(n, i, m) + value(n, i, m+1));
476 xnew.push_back(xmid);
477 }
478 }
479 } else {
480 if (loglevel > 0) {
481 writelog("refine: discarding point at {}\n", d.grid(m));
482 }
483 }
484 }
485 dsize.push_back(znew.size() - nstart);
486 }
487
488 // At this point, the new grid znew and the new solution vector xnew have
489 // been constructed, but the domains themselves have not yet been modified.
490 // Now update each domain with the new grid.
491
492 size_t gridstart = 0, gridsize;
493 for (size_t n = 0; n < nDomains(); n++) {
494 Domain1D& d = domain(n);
495 gridsize = dsize[n];
496 d.setupGrid(gridsize, &znew[gridstart]);
497 gridstart += gridsize;
498 }
499
500 // Replace the current solution vector with the new one
501 m_x = xnew;
502 resize();
503 finalize();
504 return np;
505}
506
508{
509 int np = 0;
510 vector_fp znew, xnew;
511 double zfixed = 0.0;
512 double z1 = 0.0, z2 = 0.0;
513 std::vector<size_t> dsize;
514
515 for (size_t n = 0; n < nDomains(); n++) {
516 Domain1D& d = domain(n);
517 size_t comp = d.nComponents();
518 size_t mfixed = npos;
519
520 // loop over current grid to determine where new point is needed
521 StFlow* d_free = dynamic_cast<StFlow*>(&domain(n));
522 size_t npnow = d.nPoints();
523 size_t nstart = znew.size();
524 if (d_free && d_free->domainType() == cFreeFlow) {
525 for (size_t m = 0; m < npnow - 1; m++) {
526 bool fixedpt = false;
527 double t1 = value(n, 2, m);
528 double t2 = value(n, 2, m + 1);
529 // threshold to avoid adding new point too close to existing point
530 double thresh = min(1., 1.e-1 * (t2 - t1));
531 z1 = d.grid(m);
532 z2 = d.grid(m + 1);
533 if (fabs(t - t1) <= thresh) {
534 zfixed = z1;
535 fixedpt = true;
536 } else if (fabs(t2 - t) <= thresh) {
537 zfixed = z2;
538 fixedpt = true;
539 } else if ((t1 < t) && (t < t2)) {
540 mfixed = m;
541 zfixed = (z1 - z2) / (t1 - t2) * (t - t2) + z2;
542 fixedpt = true;
543 }
544
545 if (fixedpt) {
546 d_free->m_zfixed = zfixed;
547 d_free->m_tfixed = t;
548 break;
549 }
550 }
551 }
552
553 // copy solution domain and push back values
554 for (size_t m = 0; m < npnow; m++) {
555 // add the current grid point to the new grid
556 znew.push_back(d.grid(m));
557
558 // do the same for the solution at this point
559 for (size_t i = 0; i < comp; i++) {
560 xnew.push_back(value(n, i, m));
561 }
562 if (m == mfixed) {
563 // add new point at zfixed (mfixed is not npos)
564 znew.push_back(zfixed);
565 np++;
566 double interp_factor = (zfixed - z2) / (z1 - z2);
567 // for each component, linearly interpolate
568 // the solution to this point
569 for (size_t i = 0; i < comp; i++) {
570 double xmid = interp_factor*(value(n, i, m) - value(n, i, m+1)) + value(n,i,m+1);
571 xnew.push_back(xmid);
572 }
573 }
574 }
575 dsize.push_back(znew.size() - nstart);
576 }
577
578 // At this point, the new grid znew and the new solution vector xnew have
579 // been constructed, but the domains themselves have not yet been modified.
580 // Now update each domain with the new grid.
581 size_t gridstart = 0;
582 for (size_t n = 0; n < nDomains(); n++) {
583 Domain1D& d = domain(n);
584 size_t gridsize = dsize[n];
585 d.setupGrid(gridsize, &znew[gridstart]);
586 gridstart += gridsize;
587 }
588
589 // Replace the current solution vector with the new one
590 m_x = xnew;
591
592 resize();
593 finalize();
594 return np;
595}
596
598{
599 double t_fixed = std::numeric_limits<double>::quiet_NaN();
600 for (size_t n = 0; n < nDomains(); n++) {
601 StFlow* d = dynamic_cast<StFlow*>(&domain(n));
602 if (d && d->domainType() == cFreeFlow && d->m_tfixed > 0) {
603 t_fixed = d->m_tfixed;
604 break;
605 }
606 }
607 return t_fixed;
608}
609
611{
612 double z_fixed = std::numeric_limits<double>::quiet_NaN();
613 for (size_t n = 0; n < nDomains(); n++) {
614 StFlow* d = dynamic_cast<StFlow*>(&domain(n));
615 if (d && d->domainType() == cFreeFlow && d->m_tfixed > 0) {
616 z_fixed = d->m_zfixed;
617 break;
618 }
619 }
620 return z_fixed;
621}
622
623void Sim1D::setRefineCriteria(int dom, double ratio,
624 double slope, double curve, double prune)
625{
626 if (dom >= 0) {
627 Refiner& r = domain(dom).refiner();
628 r.setCriteria(ratio, slope, curve, prune);
629 } else {
630 for (size_t n = 0; n < nDomains(); n++) {
631 Refiner& r = domain(n).refiner();
632 r.setCriteria(ratio, slope, curve, prune);
633 }
634 }
635}
636
638{
639 if (dom >= 0) {
640 Refiner& r = domain(dom).refiner();
641 return r.getCriteria();
642 } else {
643 throw CanteraError("Sim1D::getRefineCriteria",
644 "Must specify domain to get criteria from");
645 }
646}
647
648void Sim1D::setGridMin(int dom, double gridmin)
649{
650 if (dom >= 0) {
651 Refiner& r = domain(dom).refiner();
652 r.setGridMin(gridmin);
653 } else {
654 for (size_t n = 0; n < nDomains(); n++) {
655 Refiner& r = domain(n).refiner();
656 r.setGridMin(gridmin);
657 }
658 }
659}
660
661void Sim1D::setMaxGridPoints(int dom, int npoints)
662{
663 if (dom >= 0) {
664 Refiner& r = domain(dom).refiner();
665 r.setMaxPoints(npoints);
666 } else {
667 for (size_t n = 0; n < nDomains(); n++) {
668 Refiner& r = domain(n).refiner();
669 r.setMaxPoints(npoints);
670 }
671 }
672}
673
674size_t Sim1D::maxGridPoints(size_t dom)
675{
676 Refiner& r = domain(dom).refiner();
677 return r.maxPoints();
678}
679
680doublereal Sim1D::jacobian(int i, int j)
681{
682 return OneDim::jacobian().value(i,j);
683}
684
685void Sim1D::evalSSJacobian()
686{
687 OneDim::evalSSJacobian(m_x.data(), m_xnew.data());
688}
689
690void Sim1D::solveAdjoint(const double* b, double* lambda)
691{
692 for (auto& D : m_dom) {
693 D->forceFullUpdate(true);
694 }
695 evalSSJacobian();
696 for (auto& D : m_dom) {
697 D->forceFullUpdate(false);
698 }
699
700 // Form J^T
701 size_t bw = bandwidth();
702 BandMatrix Jt(size(), bw, bw);
703 for (size_t i = 0; i < size(); i++) {
704 size_t j1 = (i > bw) ? i - bw : 0;
705 size_t j2 = (i + bw >= size()) ? size() - 1: i + bw;
706 for (size_t j = j1; j <= j2; j++) {
707 Jt(j,i) = m_jac->value(i,j);
708 }
709 }
710
711 Jt.solve(b, lambda);
712}
713
715{
717 m_x.resize(size(), 0.0);
718 m_xnew.resize(size(), 0.0);
719}
720
721}
A map of string keys to values whose type can vary at runtime.
Definition: AnyMap.h:399
static void clearCachedFile(const std::string &filename)
Remove the specified file from the input cache if it is present.
Definition: AnyMap.cpp:1719
static AnyMap fromYamlFile(const std::string &name, const std::string &parent_name="")
Create an AnyMap from a YAML file.
Definition: AnyMap.cpp:1743
bool hasKey(const std::string &key) const
Returns true if the map contains an item named key.
Definition: AnyMap.cpp:1406
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:267
doublereal & value(size_t i, size_t j)
Return a changeable reference to element (i,j).
Definition: BandMatrix.cpp:168
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
Base class for one-dimensional domains.
Definition: Domain1D.h:38
size_t nComponents() const
Number of components at each grid point.
Definition: Domain1D.h:133
virtual void showSolution(const doublereal *x)
Print the solution.
Definition: Domain1D.cpp:261
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:491
size_t nPoints() const
Number of grid points in this domain.
Definition: Domain1D.h:155
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
Definition: Domain1D.cpp:64
virtual void resize(size_t nv, size_t np)
Definition: Domain1D.cpp:41
Refiner & refiner()
Return a reference to the grid refiner.
Definition: Domain1D.h:128
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
Definition: Domain1D.cpp:131
virtual void _getInitialSoln(doublereal *x)
Writes some or all initial solution values into the global solution array, beginning at the location ...
Definition: Domain1D.cpp:310
int domainType()
Domain type flag.
Definition: Domain1D.h:53
virtual void setupGrid(size_t n, const doublereal *z)
called to set up initial grid, and after grid refinement
Definition: Domain1D.cpp:251
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:373
virtual doublereal eval(doublereal t) const
Evaluate the function.
Definition: Func1.cpp:60
Error thrown for problems processing information contained in an AnyMap or AnyValue.
Definition: AnyMap.h:702
void setOptions(int maxJacAge=5)
Set options.
Definition: MultiNewton.h:68
Container class for multiple-domain 1D problems.
Definition: OneDim.h:27
size_t start(size_t i) const
The index of the start of domain i in the solution vector.
Definition: OneDim.h:86
int m_nsteps
Number of time steps taken in the current call to solve()
Definition: OneDim.h:363
virtual void resize()
Call after one or more grids has changed size, for example after being refined.
Definition: OneDim.cpp:169
std::unique_ptr< MultiJac > m_jac
Jacobian evaluator.
Definition: OneDim.h:337
size_t size() const
Total solution vector length;.
Definition: OneDim.h:97
doublereal ssnorm(doublereal *x, doublereal *r)
Steady-state max norm (infinity norm) of the residual evaluated using solution x.
Definition: OneDim.cpp:291
size_t nDomains() const
Number of domains.
Definition: OneDim.h:55
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:66
size_t bandwidth() const
Jacobian bandwidth.
Definition: OneDim.h:127
double timeStep(int nsteps, double dt, double *x, double *r, int loglevel)
Definition: OneDim.cpp:349
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:259
doublereal m_tmax
maximum timestep size
Definition: OneDim.h:332
MultiJac & jacobian()
Return a reference to the Jacobian evaluator.
Definition: OneDim.cpp:102
void setSteadyMode()
Definition: OneDim.cpp:320
Domain1D & domain(size_t i) const
Return a reference to domain i.
Definition: OneDim.h:60
int solve(doublereal *x0, doublereal *x1, int loglevel)
Solve F(x) = 0, where F(x) is the multi-domain residual function.
Definition: OneDim.cpp:225
MultiNewton & newton()
Return a reference to the Newton iterator.
Definition: OneDim.cpp:106
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:24
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, for example after being refined.
Definition: Sim1D.cpp:714
void restoreTimeSteppingSolution()
Set the current solution vector to the last successful time-stepping solution.
Definition: Sim1D.cpp:248
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:610
void finalize()
Calls method _finalize in each domain.
Definition: Sim1D.cpp:277
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:421
double fixedTemperature()
Return temperature at the point used to fix the flame location.
Definition: Sim1D.cpp:597
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:78
vector_fp getRefineCriteria(int dom)
Get the grid refinement criteria.
Definition: Sim1D.cpp:637
void setMaxGridPoints(int dom, int npoints)
Set the maximum number of grid points in the domain.
Definition: Sim1D.cpp:661
int setFixedTemperature(double t)
Add node for fixed temperature point of freely propagating flame.
Definition: Sim1D.cpp:507
int newtonSolve(int loglevel)
Wrapper around the Newton solver.
Definition: Sim1D.cpp:293
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:162
void solveAdjoint(const double *b, double *lambda)
Solve the equation .
Definition: Sim1D.cpp:690
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:257
size_t maxGridPoints(size_t dom)
Get the maximum number of grid points in this domain.
Definition: Sim1D.cpp:674
void showSolution(std::ostream &s)
Print to stream s the current solution for all domains.
Definition: Sim1D.cpp:228
doublereal value(size_t dom, size_t comp, size_t localPoint) const
Get one entry in the solution vector.
Definition: Sim1D.cpp:62
void setValue(size_t dom, size_t comp, size_t localPoint, doublereal value)
Set a single value in the solution vector.
Definition: Sim1D.cpp:54
Sim1D()
Default constructor.
Definition: Sim1D.h:29
void setGridMin(int dom, double gridmin)
Set the minimum grid spacing in the specified domain(s).
Definition: Sim1D.cpp:648
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:623
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:220
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:41
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:486
double m_zfixed
Location of the point where temperature is fixed.
Definition: StFlow.h:483
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:103
void build(const std::string &filename)
Populate the XML tree from an input file.
Definition: xml.cpp:763
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:646
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:712
Header for a file containing miscellaneous numerical functions.
#define AssertThrowMsg(expr, procedure,...)
Assertion must be true or an error is thrown.
Definition: ctexceptions.h:271
void writelog(const std::string &fmt, const Args &... args)
Write a formatted message to the screen.
Definition: global.h:164
Namespace for the Cantera kernel.
Definition: AnyMap.h:29
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:192
doublereal linearInterp(doublereal x, const vector_fp &xpts, const vector_fp &fpts)
Linearly interpolate a function defined on a discrete grid.
Definition: funcs.cpp:15
int intValue(const std::string &val)
Translate a string into one integer value.
doublereal dot(InputIter x_begin, InputIter x_end, InputIter2 y_begin)
Function that calculates a templated inner product.
Definition: utilities.h:77
void debuglog(const std::string &msg, int loglevel)
Write a message to the log only if loglevel > 0.
Definition: global.h:146
std::string toLowerCopy(const std::string &input)
Convert to lower case.
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:184
std::string gitCommit()
Returns the hash of the git commit from which Cantera was compiled, if known.
Definition: global.cpp:131
void warn_user(const std::string &method, const std::string &msg, const Args &... args)
Print a user warning raised from method as CanteraWarning.
Definition: global.h:245
int solve(DenseMatrix &A, double *b, size_t nrhs=1, size_t ldb=0)
Solve Ax = b. Array b is overwritten on exit with x.
std::string stripnonprint(const std::string &s)
Strip non-printing characters wherever they are.
Definition: stringUtils.cpp:48
Contains declarations for string manipulation functions within Cantera.
Classes providing support for XML data files.