Cantera  3.1.0b1
Loading...
Searching...
No Matches
Boundary1D.cpp
Go to the documentation of this file.
1//! @file Boundary1D.cpp
2
3// This file is part of Cantera. See License.txt in the top-level directory or
4// at https://cantera.org/license.txt for license and copyright information.
5
10
11using namespace std;
12
13namespace Cantera
14{
15
17{
18}
19
20void Boundary1D::_init(size_t n)
21{
22 if (m_index == npos) {
23 throw CanteraError("Boundary1D::_init",
24 "install in container before calling init.");
25 }
26
27 // A boundary object contains only one grid point
28 resize(n,1);
29
30 m_left_nsp = 0;
31 m_right_nsp = 0;
32
33 // check for left and right flow objects
34 if (m_index > 0) {
36 if (!r.isConnector()) { // multi-point domain
38 if (m_left_nv > c_offset_Y) {
40 } else {
41 m_left_nsp = 0;
42 }
43 m_flow_left = dynamic_cast<Flow1D*>(&r);
44 if (m_flow_left != nullptr) {
46 }
47 } else {
48 throw CanteraError("Boundary1D::_init",
49 "Boundary domains can only be connected on the left to flow "
50 "domains, not '{}' domains.", r.type());
51 }
52 }
53
54 // if this is not the last domain, see what is connected on the right
55 if (m_index + 1 < container().nDomains()) {
57 if (!r.isConnector()) { // multi-point domain
59 if (m_right_nv > c_offset_Y) {
61 } else {
62 m_right_nsp = 0;
63 }
64 m_flow_right = dynamic_cast<Flow1D*>(&r);
65 if (m_flow_right != nullptr) {
66 m_phase_right = &m_flow_right->phase();
67 }
68 } else {
69 throw CanteraError("Boundary1D::_init",
70 "Boundary domains can only be connected on the right to flow "
71 "domains, not '{}' domains.", r.type());
72 }
73 }
74}
75
76void Boundary1D::fromArray(SolutionArray& arr, double* soln)
77{
78 setMeta(arr.meta());
79}
80
81// ---------------- Inlet1D methods ----------------
82
84{
85}
86
87Inlet1D::Inlet1D(shared_ptr<Solution> solution, const string& id)
88 : Inlet1D()
89{
91 m_id = id;
92}
93
94
95//! set spreading rate
97{
98 m_V0 = V0;
100}
101
103{
105 // Adjust flow domain temperature bounds based on inlet temperature
106 if (m_flow != nullptr && m_flow->lowerBound(c_offset_T) >= m_temp) {
108 }
109}
110
111void Inlet1D::show(const double* x)
112{
113 writelog(" Mass Flux: {:10.4g} kg/m^2/s \n", m_mdot);
114 writelog(" Temperature: {:10.4g} K \n", m_temp);
115 if (m_flow) {
116 writelog(" Mass Fractions: \n");
117 for (size_t k = 0; k < m_flow->phase().nSpecies(); k++) {
118 if (m_yin[k] != 0.0) {
119 writelog(" {:>16s} {:10.4g} \n",
120 m_flow->phase().speciesName(k), m_yin[k]);
121 }
122 }
123 }
124 writelog("\n");
125}
126
127void Inlet1D::setMoleFractions(const string& xin)
128{
129 m_xstr = xin;
130 if (m_flow) {
134 }
135}
136
137void Inlet1D::setMoleFractions(const double* xin)
138{
139 if (m_flow) {
143 }
144}
145
147{
148 _init(0);
149
150 // if a flow domain is present on the left, then this must be a right inlet.
151 // Note that an inlet object can only be a terminal object - it cannot have
152 // flows on both the left and right
153 if (m_flow_left && !m_flow_right) {
154 if (!m_flow_left->isStrained()) {
155 throw CanteraError("Inlet1D::init",
156 "Right inlets with right-to-left flow are only supported for "
157 "strained flow configurations.");
158 }
161 } else if (m_flow_right) {
163 m_flow = m_flow_right;
164 } else {
165 throw CanteraError("Inlet1D::init", "Inlet1D is not properly connected.");
166 }
167
168 // components = u, V, T, lambda, + mass fractions
169 m_nsp = m_flow->phase().nSpecies();
170 m_yin.resize(m_nsp, 0.0);
171 if (m_xstr != "") {
173 } else {
174 m_yin[0] = 1.0;
175 }
176
177}
178
179void Inlet1D::eval(size_t jg, double* xg, double* rg,
180 integer* diagg, double rdt)
181{
182 if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
183 return;
184 }
185
186 if (m_ilr == LeftInlet) {
187 // Array elements corresponding to the first point of the flow domain
188 double* xb = xg + m_flow->loc();
189 double* rb = rg + m_flow->loc();
190
191 // The first flow residual is for u. This, however, is not modified by
192 // the inlet, since this is set within the flow domain from the
193 // continuity equation.
194
195 if (m_flow->doEnergy(0)) {
196 // The third flow residual is for T, where it is set to T(0). Subtract
197 // the local temperature to hold the flow T to the inlet T.
198 rb[c_offset_T] -= m_temp;
199 } else {
200 rb[c_offset_T] -= m_flow->T_fixed(0);
201 }
202
203 if (m_flow->isFree()) {
204 // if the flow is a freely-propagating flame, mdot is not specified.
205 // Set mdot equal to rho*u.
206 m_mdot = m_flow->density(0) * xb[c_offset_U];
207 } else if (m_flow->isStrained()) { // axisymmetric flow
209 // When using two-point control, the mass flow rate at the left inlet is
210 // not specified. Instead, the mass flow rate is dictated by the
211 // velocity at the left inlet, which comes from the U variable. The
212 // default boundary condition specified in the Flow1D.cpp file already
213 // handles this case. We only need to update the stored value of m_mdot
214 // so that other equations that use the quantity are consistent.
216 } else {
217 // The flow domain sets this to -rho*u. Add mdot to specify the mass
218 // flow rate
219 rb[c_offset_L] += m_mdot;
220 }
221
222 // spreading rate. The flow domain sets this to V(0),
223 // so for finite spreading rate subtract m_V0.
224 rb[c_offset_V] -= m_V0;
225 } else { // unstrained flow
226 rb[c_offset_U] = m_flow->density(0) * xb[c_offset_U] - m_mdot;
227 }
228
229 // add the convective term to the species residual equations
230 for (size_t k = 0; k < m_nsp; k++) {
231 if (k != m_flow_right->leftExcessSpecies()) {
232 rb[c_offset_Y+k] += m_mdot*m_yin[k];
233 }
234 }
235
236 } else {
237 // right inlet (should only be used for counter-flow flames)
238 // Array elements corresponding to the last point in the flow domain
239 double* rb = rg + loc() - m_flow->nComponents();
240 double* xb = xg + loc() - m_flow->nComponents();
241 size_t last_index = m_flow->nPoints() - 1;
242
243 rb[c_offset_V] -= m_V0;
244 if (m_flow->doEnergy(m_flow->nPoints() - 1)) {
245 rb[c_offset_T] -= m_temp; // T
246 } else {
247 rb[c_offset_T] -= m_flow->T_fixed(m_flow->nPoints() - 1);
248 }
249
250 if (m_flow->twoPointControlEnabled()) { // For point control adjustments
251 // At the right boundary, the mdot is dictated by the velocity at the right
252 // boundary, which comes from the Uo variable. The variable Uo is the
253 // left-moving velocity and has a negative value, so the mass flow has to be
254 // negated to give a positive value when using Uo.
255 m_mdot = -m_flow->density(last_index) * xb[c_offset_Uo];
256 }
257 rb[c_offset_U] += m_mdot;
258
259 for (size_t k = 0; k < m_nsp; k++) {
260 if (k != m_flow_left->rightExcessSpecies()) {
261 rb[c_offset_Y+k] += m_mdot * m_yin[k];
262 }
263 }
264 }
265}
266
267shared_ptr<SolutionArray> Inlet1D::asArray(const double* soln) const
268{
270 meta["mass-flux"] = m_mdot;
271 auto arr = SolutionArray::create(m_solution, 1, meta);
272
273 // set gas state (using pressure from adjacent domain)
274 double pressure = m_flow->phase().pressure();
275 auto phase = m_solution->thermo();
276 phase->setState_TPY(m_temp, pressure, m_yin.data());
277 vector<double> data(phase->stateSize());
278 phase->saveState(data);
279
280 arr->setState(0, data);
281 return arr;
282}
283
284void Inlet1D::fromArray(SolutionArray& arr, double* soln)
285{
287 arr.setLoc(0);
288 auto phase = arr.thermo();
289 auto meta = arr.meta();
290 m_temp = phase->temperature();
291 if (meta.hasKey("mass-flux")) {
292 m_mdot = meta.at("mass-flux").asDouble();
293 } else {
294 // convert data format used by Python h5py export (Cantera < 3.0)
295 auto aux = arr.getAuxiliary(0);
296 m_mdot = phase->density() * aux.at("velocity").as<double>();
297 }
298 phase->getMassFractions(m_yin.data());
299}
300
301// ------------- Empty1D -------------
302
304{
305 _init(0);
306}
307
308void Empty1D::eval(size_t jg, double* xg, double* rg,
309 integer* diagg, double rdt)
310{
311}
312
313shared_ptr<SolutionArray> Empty1D::asArray(const double* soln) const
314{
316 return SolutionArray::create(m_solution, 0, meta);
317}
318
319// -------------- Symm1D --------------
320
322{
323 _init(0);
324}
325
326void Symm1D::eval(size_t jg, double* xg, double* rg, integer* diagg,
327 double rdt)
328{
329 if (jg != npos && (jg + 2< firstPoint() || jg > lastPoint() + 2)) {
330 return;
331 }
332
333 // start of local part of global arrays
334 double* x = xg + loc();
335 double* r = rg + loc();
336 integer* diag = diagg + loc();
337
338 if (m_flow_right) {
339 size_t nc = m_flow_right->nComponents();
340 double* xb = x;
341 double* rb = r;
342 int* db = diag;
343 db[c_offset_V] = 0;
344 db[c_offset_T] = 0;
345 rb[c_offset_V] = xb[c_offset_V] - xb[c_offset_V + nc]; // zero dV/dz
346 if (m_flow_right->doEnergy(0)) {
347 rb[c_offset_T] = xb[c_offset_T] - xb[c_offset_T + nc]; // zero dT/dz
348 }
349 }
350
351 if (m_flow_left) {
352 size_t nc = m_flow_left->nComponents();
353 double* xb = x - nc;
354 double* rb = r - nc;
355 int* db = diag - nc;
356 db[c_offset_V] = 0;
357 db[c_offset_T] = 0;
358 rb[c_offset_V] = xb[c_offset_V] - xb[c_offset_V - nc]; // zero dV/dz
360 rb[c_offset_T] = xb[c_offset_T] - xb[c_offset_T - nc]; // zero dT/dz
361 }
362 }
363}
364
365shared_ptr<SolutionArray> Symm1D::asArray(const double* soln) const
366{
368 return SolutionArray::create(m_solution, 0, meta);
369}
370
371// -------- Outlet1D --------
372
374{
375}
376
377OutletRes1D::OutletRes1D(shared_ptr<Solution> solution, const string& id)
378 : OutletRes1D()
379{
381 m_id = id;
382}
383
385{
386 _init(0);
387
388 if (m_flow_right) {
389 throw CanteraError("Outlet1D::init",
390 "Left outlets with right-to-left flow are not supported.");
391 }
392 if (m_flow_left) {
394 } else {
395 throw CanteraError("Outlet1D::init", "Outlet1D is not connected.");
396 }
397}
398
399void Outlet1D::eval(size_t jg, double* xg, double* rg, integer* diagg,
400 double rdt)
401{
402 if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
403 return;
404 }
405
406 // start of local part of global arrays
407 double* x = xg + loc();
408 double* r = rg + loc();
409 integer* diag = diagg + loc();
410
411 // flow is left-to-right
412 size_t nc = m_flow_left->nComponents();
413 double* xb = x - nc;
414 double* rb = r - nc;
415 int* db = diag - nc;
416
417 size_t last = m_flow_left->nPoints() - 1;
418 if (m_flow_left->doEnergy(last)) {
419 rb[c_offset_T] = xb[c_offset_T] - xb[c_offset_T - nc]; // zero T gradient
420 } else {
421 rb[c_offset_T] = xb[c_offset_T] - m_flow_left->T_fixed(last);
422 }
423 size_t kSkip = c_offset_Y + m_flow_left->rightExcessSpecies();
424 for (size_t k = c_offset_Y; k < nc; k++) {
425 if (k != kSkip) {
426 rb[k] = xb[k] - xb[k - nc]; // zero mass fraction gradient
427 db[k] = 0;
428 }
429 }
430}
431
432shared_ptr<SolutionArray> Outlet1D::asArray(const double* soln) const
433{
435 return SolutionArray::create(m_solution, 0, meta);
436}
437
438// -------- OutletRes1D --------
439
440void OutletRes1D::setMoleFractions(const string& xres)
441{
442 m_xstr = xres;
443 if (m_flow) {
447 }
448}
449
450void OutletRes1D::setMoleFractions(const double* xres)
451{
452 if (m_flow) {
456 }
457}
458
460{
461 _init(0);
462
463 if (m_flow_right) {
464 throw CanteraError("OutletRes1D::init",
465 "Left outlets with right-to-left flow are not supported.");
466 }
467 if (m_flow_left) {
469 } else {
470 throw CanteraError("OutletRes1D::init", "no flow!");
471 }
472
473 m_nsp = m_flow->phase().nSpecies();
474 m_yres.resize(m_nsp, 0.0);
475 if (m_xstr != "") {
477 } else {
478 m_yres[0] = 1.0;
479 }
480}
481
482void OutletRes1D::eval(size_t jg, double* xg, double* rg,
483 integer* diagg, double rdt)
484{
485 if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
486 return;
487 }
488
489 // start of local part of global arrays
490 double* x = xg + loc();
491 double* r = rg + loc();
492 integer* diag = diagg + loc();
493
494 size_t nc = m_flow_left->nComponents();
495 double* xb = x - nc;
496 double* rb = r - nc;
497 int* db = diag - nc;
498
499 size_t last = m_flow_left->nPoints() - 1;
500 if (m_flow_left->doEnergy(last)) {
501 rb[c_offset_T] = xb[c_offset_T] - xb[c_offset_T - nc]; // zero T gradient
502 } else {
503 rb[c_offset_T] = xb[c_offset_T] - m_flow_left->T_fixed(last);
504 }
505 size_t kSkip = m_flow_left->rightExcessSpecies();
506 for (size_t k = c_offset_Y; k < nc; k++) {
507 if (k != kSkip) {
508 rb[k] = xb[k] - m_yres[k-c_offset_Y]; // fixed Y
509 db[k] = 0;
510 }
511 }
512}
513
514shared_ptr<SolutionArray> OutletRes1D::asArray(const double* soln) const
515{
517 meta["temperature"] = m_temp;
518 auto arr = SolutionArray::create(m_solution, 1, meta);
519
520 // set gas state (using pressure from adjacent domain)
521 double pressure = m_flow->phase().pressure();
522 auto phase = m_solution->thermo();
523 phase->setState_TPY(m_temp, pressure, &m_yres[0]);
524 vector<double> data(phase->stateSize());
525 phase->saveState(data);
526
527 arr->setState(0, data);
528 return arr;
529}
530
531void OutletRes1D::fromArray(SolutionArray& arr, double* soln)
532{
534 arr.setLoc(0);
535 auto phase = arr.thermo();
536 m_temp = phase->temperature();
537 auto Y = phase->massFractions();
538 std::copy(Y, Y + m_nsp, &m_yres[0]);
539}
540
541// -------- Surf1D --------
542
544{
545 _init(0);
546}
547
548void Surf1D::eval(size_t jg, double* xg, double* rg,
549 integer* diagg, double rdt)
550{
551 if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
552 return;
553 }
554
555 // start of local part of global arrays
556 double* x = xg + loc();
557 double* r = rg + loc();
558
559 if (m_flow_right) {
560 double* rb = r;
561 double* xb = x;
562 rb[c_offset_T] = xb[c_offset_T] - m_temp; // specified T
563 }
564
565 if (m_flow_left) {
566 size_t nc = m_flow_left->nComponents();
567 double* rb = r - nc;
568 double* xb = x - nc;
569 rb[c_offset_T] = xb[c_offset_T] - m_temp; // specified T
570 }
571}
572
573shared_ptr<SolutionArray> Surf1D::asArray(const double* soln) const
574{
576 meta["temperature"] = m_temp;
577 return SolutionArray::create(m_solution, 0, meta);
578}
579
580void Surf1D::fromArray(SolutionArray& arr, double* soln)
581{
582 auto meta = arr.meta();
583 m_temp = meta["temperature"].asDouble();
584 meta.erase("temperature");
586}
587
588void Surf1D::show(std::ostream& s, const double* x)
589{
590 s << "------------------- Surface " << domainIndex() << " ------------------- " << std::endl;
591 s << " temperature: " << m_temp << " K" << std::endl;
592}
593
594void Surf1D::show(const double* x)
595{
596 writelog(" Temperature: {:10.4g} K \n\n", m_temp);
597}
598
599// -------- ReactingSurf1D --------
600
602 : m_kin(0)
603 , m_nsp(0)
604{
605}
606
607ReactingSurf1D::ReactingSurf1D(shared_ptr<Solution> solution, const string& id)
608{
609 auto phase = std::dynamic_pointer_cast<SurfPhase>(solution->thermo());
610 if (!phase) {
611 throw CanteraError("ReactingSurf1D::ReactingSurf1D",
612 "Detected incompatible ThermoPhase type '{}'", solution->thermo()->type());
613 }
614 auto kin = std::dynamic_pointer_cast<InterfaceKinetics>(solution->kinetics());
615 if (!kin) {
616 throw CanteraError("ReactingSurf1D::ReactingSurf1D",
617 "Detected incompatible kinetics type '{}'",
618 solution->kinetics()->kineticsType());
619 }
621 m_id = id;
622 m_kin = kin.get();
623 m_sphase = phase.get();
625 m_enabled = true;
626}
627
628void ReactingSurf1D::setKinetics(shared_ptr<Kinetics> kin)
629{
630 auto sol = Solution::create();
631 sol->setThermo(kin->reactionPhase());
632 sol->setKinetics(kin);
633 sol->setTransportModel("none");
634 setSolution(sol);
635 m_kin = dynamic_pointer_cast<InterfaceKinetics>(kin).get();
636 m_sphase = dynamic_pointer_cast<SurfPhase>(kin->reactionPhase()).get();
638 m_enabled = true;
639}
640
641string ReactingSurf1D::componentName(size_t n) const
642{
643 if (n < m_nsp) {
644 return m_sphase->speciesName(n);
645 } else {
646 return "<unknown>";
647 }
648}
649
651{
652 m_nv = m_nsp;
653 _init(m_nsp);
654
655 m_fixed_cov.resize(m_nsp, 0.0);
656 m_fixed_cov[0] = 1.0;
657 m_work.resize(m_kin->nTotalSpecies(), 0.0);
658
659 for (size_t n = 0; n < m_nsp; n++) {
660 setBounds(n, -1.0e-5, 2.0);
661 }
662}
663
665 double* x = xg + loc();
668}
669
670void ReactingSurf1D::eval(size_t jg, double* xg, double* rg,
671 integer* diagg, double rdt)
672{
673 if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
674 return;
675 }
676
677 // start of local part of global arrays
678 double* x = xg + loc();
679 double* r = rg + loc();
680 integer* diag = diagg + loc();
681
682 // set the coverages
683 double sum = 0.0;
684 for (size_t k = 0; k < m_nsp; k++) {
685 m_work[k] = x[k];
686 sum += x[k];
687 }
690
691 // set the left gas state to the adjacent point
692
693 size_t leftloc = 0, rightloc = 0;
694 size_t pnt = 0;
695
696 if (m_flow_left) {
697 leftloc = m_flow_left->loc();
698 pnt = m_flow_left->nPoints() - 1;
699 m_flow_left->setGas(xg + leftloc, pnt);
700 }
701
702 if (m_flow_right) {
703 rightloc = m_flow_right->loc();
704 m_flow_right->setGas(xg + rightloc, 0);
705 }
706
708 double rs0 = 1.0/m_sphase->siteDensity();
709
710 if (m_enabled) {
711 for (size_t k = 0; k < m_nsp; k++) {
712 r[k] = m_work[k] * m_sphase->size(k) * rs0;
713 r[k] -= rdt*(x[k] - prevSoln(k,0));
714 diag[k] = 1;
715 }
716 r[0] = 1.0 - sum;
717 diag[0] = 0;
718 } else {
719 for (size_t k = 0; k < m_nsp; k++) {
720 r[k] = x[k] - m_fixed_cov[k];
721 diag[k] = 0;
722 }
723 }
724
725 if (m_flow_right) {
726 double* rb = r + m_nsp;
727 double* xb = x + m_nsp;
728 rb[c_offset_T] = xb[c_offset_T] - m_temp; // specified T
729 }
730 if (m_flow_left) {
731 size_t nc = m_flow_left->nComponents();
732 const vector<double>& mwleft = m_phase_left->molecularWeights();
733 double* rb = r - nc;
734 double* xb = x - nc;
735 rb[c_offset_T] = xb[c_offset_T] - m_temp; // specified T
736 size_t nSkip = m_flow_left->rightExcessSpecies();
737 size_t l_offset = 0;
738 ThermoPhase* left_thermo = &m_flow_left->phase();
739 for (size_t nth = 0; nth < m_kin->nPhases(); nth++) {
740 if (&m_kin->thermo(nth) == left_thermo) {
741 l_offset = m_kin->kineticsSpeciesIndex(0, nth);
742 break;
743 }
744 }
745 for (size_t nl = 0; nl < m_left_nsp; nl++) {
746 if (nl != nSkip) {
747 rb[c_offset_Y+nl] += m_work[nl + l_offset]*mwleft[nl];
748 }
749 }
750 }
751}
752
753shared_ptr<SolutionArray> ReactingSurf1D::asArray(const double* soln) const
754{
756 meta["temperature"] = m_temp;
757 meta["phase"]["name"] = m_sphase->name();
758 AnyValue source = m_sphase->input().getMetadata("filename");
759 meta["phase"]["source"] = source.empty() ? "<unknown>" : source.asString();
760
761 // set state of surface phase
763 m_sphase->setCoverages(soln);
764 vector<double> data(m_sphase->stateSize());
765 m_sphase->saveState(data.size(), &data[0]);
766
767 auto arr = SolutionArray::create(m_solution, 1, meta);
768 arr->setState(0, data);
769 return arr;
770}
771
773{
775 arr.setLoc(0);
776 auto surf = std::dynamic_pointer_cast<SurfPhase>(arr.thermo());
777 if (!surf) {
778 throw CanteraError("ReactingSurf1D::fromArray",
779 "Restoring of coverages requires surface phase");
780 }
781 m_temp = surf->temperature();
782 surf->getCoverages(soln);
783}
784
785void ReactingSurf1D::show(const double* x)
786{
787 writelog(" Temperature: {:10.4g} K \n", m_temp);
788 writelog(" Coverages: \n");
789 for (size_t k = 0; k < m_nsp; k++) {
790 writelog(" {:>20s} {:10.4g} \n", m_sphase->speciesName(k), x[k]);
791 }
792 writelog("\n");
793}
794}
Boundary objects for one-dimensional simulations.
const AnyValue & getMetadata(const string &key) const
Get a value from the metadata applicable to the AnyMap tree containing this node.
Definition AnyMap.cpp:623
A map of string keys to values whose type can vary at runtime.
Definition AnyMap.h:431
A wrapper for a variable whose type is determined at runtime.
Definition AnyMap.h:87
const string & asString() const
Return the held value, if it is a string.
Definition AnyMap.cpp:782
bool empty() const
Return boolean indicating whether AnyValue is empty.
Definition AnyMap.cpp:690
ThermoPhase * m_phase_left
Thermo object used by left flow domain.
Definition Boundary1D.h:125
double m_mdot
Mass flow rate at the boundary.
Definition Boundary1D.h:131
double m_temp
Temperature of the boundary.
Definition Boundary1D.h:129
void _init(size_t n)
Initialize member variables based on the adjacent domains.
Flow1D * m_flow_left
Flow domain to the left of this boundary.
Definition Boundary1D.h:119
ThermoPhase * m_phase_right
Thermo object used by right flow domain.
Definition Boundary1D.h:126
size_t m_right_nsp
Number of species in right flow domain.
Definition Boundary1D.h:124
virtual void setTemperature(double t)
Set the temperature.
Definition Boundary1D.h:61
void fromArray(SolutionArray &arr, double *soln) override
Restore the solution for this domain from a SolutionArray.
size_t m_left_nsp
Number of species in left flow domain.
Definition Boundary1D.h:123
Boundary1D()
Default constructor.
size_t m_right_nv
Number of state vector components in right flow domain.
Definition Boundary1D.h:122
size_t m_left_nv
Flow domain to the right of this boundary.
Definition Boundary1D.h:121
Base class for exceptions thrown by Cantera classes.
Base class for one-dimensional domains.
Definition Domain1D.h:29
size_t lastPoint() const
The index of the last (that is, right-most) grid point belonging to this domain.
Definition Domain1D.h:428
size_t domainIndex()
The left-to-right location of this domain.
Definition Domain1D.h:53
shared_ptr< Solution > m_solution
Composite thermo/kinetics/transport handler.
Definition Domain1D.h:624
size_t nComponents() const
Number of components at each grid point.
Definition Domain1D.h:151
shared_ptr< Solution > solution() const
Return thermo/kinetics/transport manager used in the domain.
Definition Domain1D.h:402
virtual bool isConnector()
True if the domain is a connector domain.
Definition Domain1D.h:58
virtual void setMeta(const AnyMap &meta)
Retrieve meta data.
Definition Domain1D.cpp:173
size_t m_index
Left-to-right location of this domain.
Definition Domain1D.h:600
string id() const
Returns the identifying tag for this domain.
Definition Domain1D.h:479
size_t m_nv
Number of solution components.
Definition Domain1D.h:586
size_t nPoints() const
Number of grid points in this domain.
Definition Domain1D.h:173
double lowerBound(size_t n) const
Lower bound on the nth component.
Definition Domain1D.h:273
virtual void resize(size_t nv, size_t np)
Resize the domain to have nv components and np grid points.
Definition Domain1D.cpp:44
double upperBound(size_t n) const
Upper bound on the nth component.
Definition Domain1D.h:268
void setSolution(shared_ptr< Solution > sol)
Set the solution manager.
Definition Domain1D.cpp:31
const OneDim & container() const
The container holding this domain.
Definition Domain1D.h:79
string m_id
Identity tag for the domain.
Definition Domain1D.h:617
string type() const
String indicating the domain implemented.
Definition Domain1D.h:50
void setBounds(size_t n, double lower, double upper)
Set the upper and lower bounds for a solution component, n.
Definition Domain1D.h:212
double prevSoln(size_t n, size_t j) const
Value of component n at point j in the previous solution.
Definition Domain1D.h:469
size_t firstPoint() const
The index of the first (that is, left-most) grid point belonging to this domain.
Definition Domain1D.h:423
void needJacUpdate()
Set this if something has changed in the governing equations (for example, the value of a constant ha...
Definition Domain1D.cpp:113
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:418
virtual AnyMap getMeta() const
Retrieve meta data.
Definition Domain1D.cpp:121
shared_ptr< SolutionArray > asArray(const double *soln) const override
Save the state of this domain as a SolutionArray.
void eval(size_t jg, double *xg, double *rg, integer *diagg, double rdt) override
Evaluate the residual function at point j.
void init() override
Initialize.
This class represents 1D flow domains that satisfy the one-dimensional similarity solution for chemic...
Definition Flow1D.h:46
double density(size_t j) const
Get the density [kg/m³] at point j
Definition Flow1D.h:350
bool doEnergy(size_t j)
true if the energy equation is solved at point j or false if a fixed temperature condition is imposed...
Definition Flow1D.h:335
ThermoPhase & phase()
Access the phase object used to compute thermodynamic properties for points in this domain.
Definition Flow1D.h:82
bool twoPointControlEnabled() const
Returns the status of the two-point control.
Definition Flow1D.h:328
size_t rightExcessSpecies() const
Index of the species on the right boundary with the largest mass fraction.
Definition Flow1D.h:409
void setGas(const double *x, size_t j)
Set the gas object state to be consistent with the solution at point j.
Definition Flow1D.cpp:238
void setViscosityFlag(bool dovisc)
Specify if the viscosity term should be included in the momentum equation.
Definition Flow1D.h:376
size_t leftExcessSpecies() const
Index of the species on the left boundary with the largest mass fraction.
Definition Flow1D.h:404
bool isFree() const
Retrieve flag indicating whether flow is freely propagating.
Definition Flow1D.h:360
bool isStrained() const
Retrieve flag indicating whether flow uses radial momentum.
Definition Flow1D.h:371
double T_fixed(size_t j) const
The fixed temperature value at point j.
Definition Flow1D.h:170
void setMoleFractions(const string &xin) override
Set the mole fractions by specifying a string.
vector< double > m_yin
inlet mass fractions
Definition Boundary1D.h:187
int m_ilr
A marker that indicates whether this is a left inlet or a right inlet.
Definition Boundary1D.h:181
string m_xstr
inlet mass fractions. Parsing deferred to init()
Definition Boundary1D.h:188
shared_ptr< SolutionArray > asArray(const double *soln) const override
Save the state of this domain as a SolutionArray.
size_t nSpecies() override
Get the number of species.
Definition Boundary1D.h:165
void setTemperature(double T) override
Set the temperature.
void eval(size_t jg, double *xg, double *rg, integer *diagg, double rdt) override
Evaluate the residual function at point j.
size_t m_nsp
Number of species in the adjacent flow domain.
Definition Boundary1D.h:186
void fromArray(SolutionArray &arr, double *soln) override
Restore the solution for this domain from a SolutionArray.
void init() override
Initialize.
Flow1D * m_flow
the adjacent flow domain
Definition Boundary1D.h:189
void setSpreadRate(double V0) override
set spreading rate
void show(const double *x) override
Print the solution.
double m_V0
The spread rate of the inlet [1/s].
Definition Boundary1D.h:184
Inlet1D()
Default constructor.
ThermoPhase & thermo(size_t n=0)
This method returns a reference to the nth ThermoPhase object defined in this kinetics mechanism.
Definition Kinetics.h:242
size_t nPhases() const
The number of phases participating in the reaction mechanism.
Definition Kinetics.h:184
size_t kineticsSpeciesIndex(size_t k, size_t n) const
The location of species k of phase n in species arrays.
Definition Kinetics.h:276
size_t nTotalSpecies() const
The total number of species in all phases participating in the kinetics mechanism.
Definition Kinetics.h:254
virtual void getNetProductionRates(double *wdot)
Species net production rates [kmol/m^3/s or kmol/m^2/s].
Definition Kinetics.cpp:413
Domain1D & domain(size_t i) const
Return a reference to domain i.
Definition OneDim.h:69
shared_ptr< SolutionArray > asArray(const double *soln) const override
Save the state of this domain as a SolutionArray.
void eval(size_t jg, double *xg, double *rg, integer *diagg, double rdt) override
Evaluate the residual function at point j.
void init() override
Initialize.
An outlet with specified composition.
Definition Boundary1D.h:287
void setMoleFractions(const string &xin) override
Set the mole fractions by specifying a string.
OutletRes1D()
Default constructor.
string m_xstr
Mole fractions in the reservoir.
Definition Boundary1D.h:321
shared_ptr< SolutionArray > asArray(const double *soln) const override
Save the state of this domain as a SolutionArray.
vector< double > m_yres
Mass fractions in the reservoir.
Definition Boundary1D.h:320
void eval(size_t jg, double *xg, double *rg, integer *diagg, double rdt) override
Evaluate the residual function at point j.
size_t m_nsp
Number of species in the adjacent flow domain.
Definition Boundary1D.h:319
void fromArray(SolutionArray &arr, double *soln) override
Restore the solution for this domain from a SolutionArray.
void init() override
Initialize.
Flow1D * m_flow
The adjacent flow domain.
Definition Boundary1D.h:322
virtual void setMoleFractions(const double *const x)
Set the mole fractions to the specified values.
Definition Phase.cpp:289
size_t nSpecies() const
Returns the number of species in the phase.
Definition Phase.h:231
void saveState(vector< double > &state) const
Save the current internal state of the phase.
Definition Phase.cpp:236
string speciesName(size_t k) const
Name of the species with index k.
Definition Phase.cpp:142
virtual size_t stateSize() const
Return size of vector defining internal state of the phase.
Definition Phase.cpp:228
void setMoleFractionsByName(const Composition &xMap)
Set the species mole fractions by name.
Definition Phase.cpp:330
const vector< double > & molecularWeights() const
Return a const reference to the internal vector of molecular weights.
Definition Phase.cpp:395
virtual void setTemperature(double temp)
Set the internally stored temperature of the phase (K).
Definition Phase.h:623
void getMassFractions(double *const y) const
Get the species mass fractions.
Definition Phase.cpp:471
virtual double pressure() const
Return the thermodynamic pressure (Pa).
Definition Phase.h:580
string name() const
Return the name of the phase.
Definition Phase.cpp:20
SurfPhase * m_sphase
phase representing the surface species
Definition Boundary1D.h:414
void setKinetics(shared_ptr< Kinetics > kin) override
Set the kinetics manager.
void resetBadValues(double *xg) override
When called, this function should reset "bad" values in the state vector such as negative species con...
InterfaceKinetics * m_kin
surface kinetics mechanism
Definition Boundary1D.h:413
bool m_enabled
True if coverage equations are being solved.
Definition Boundary1D.h:416
vector< double > m_fixed_cov
Fixed values of the coverages used when coverage equations are not being solved.
Definition Boundary1D.h:424
ReactingSurf1D()
Default constructor.
vector< double > m_work
temporary vector used to store coverages and production rates.
Definition Boundary1D.h:420
shared_ptr< SolutionArray > asArray(const double *soln) const override
Save the state of this domain as a SolutionArray.
void eval(size_t jg, double *xg, double *rg, integer *diagg, double rdt) override
Evaluate the residual function at point j.
size_t m_nsp
the number of surface phase species
Definition Boundary1D.h:415
void fromArray(SolutionArray &arr, double *soln) override
Restore the solution for this domain from a SolutionArray.
string componentName(size_t n) const override
Name of component n. May be overloaded.
void init() override
Initialize.
void show(const double *x) override
Print the solution.
A container class holding arrays of state information.
void setLoc(int loc, bool restore=true)
Update the buffered location used to access SolutionArray entries.
AnyMap getAuxiliary(int loc)
Retrieve auxiliary data for a given location.
AnyMap & meta()
SolutionArray meta data.
shared_ptr< ThermoPhase > thermo()
Retrieve associated ThermoPhase object.
static shared_ptr< SolutionArray > create(const shared_ptr< Solution > &sol, int size=0, const AnyMap &meta={})
Instantiate a new SolutionArray reference.
static shared_ptr< Solution > create()
Create an empty Solution object.
Definition Solution.h:54
shared_ptr< SolutionArray > asArray(const double *soln) const override
Save the state of this domain as a SolutionArray.
void eval(size_t jg, double *xg, double *rg, integer *diagg, double rdt) override
Evaluate the residual function at point j.
void fromArray(SolutionArray &arr, double *soln) override
Restore the solution for this domain from a SolutionArray.
void init() override
Initialize.
void show(std::ostream &s, const double *x) override
double pressure() const override
Return the thermodynamic pressure (Pa).
Definition SurfPhase.h:238
double size(size_t k) const
Returns the number of sites occupied by one molecule of species k.
Definition SurfPhase.h:221
void setCoverages(const double *theta)
Set the surface site fractions to a specified state.
double siteDensity() const
Returns the site density.
Definition SurfPhase.h:216
void setCoveragesNoNorm(const double *theta)
Set the surface site fractions to a specified state.
void getCoverages(double *theta) const
Return a vector of surface coverages.
shared_ptr< SolutionArray > asArray(const double *soln) const override
Save the state of this domain as a SolutionArray.
void eval(size_t jg, double *xg, double *rg, integer *diagg, double rdt) override
Evaluate the residual function at point j.
void init() override
Initialize.
Base class for a phase with thermodynamic properties.
virtual void setState_TP(double t, double p)
Set the temperature (K) and pressure (Pa)
const AnyMap & input() const
Access input data associated with the phase description.
void writelog(const string &fmt, const Args &... args)
Write a formatted message to the screen.
Definition global.h:171
Namespace for the Cantera kernel.
Definition AnyMap.cpp:595
const size_t npos
index returned by functions to indicate "no position"
Definition ct_defs.h:180
const int LeftInlet
Unique identifier for the left inlet.
Definition Boundary1D.h:22
const int RightInlet
Unique identifier for the right inlet.
Definition Boundary1D.h:25
@ c_offset_U
axial velocity [m/s]
Definition Flow1D.h:25
@ c_offset_L
(1/r)dP/dr
Definition Flow1D.h:28
@ c_offset_V
strain rate
Definition Flow1D.h:26
@ c_offset_Y
mass fractions
Definition Flow1D.h:31
@ c_offset_Uo
oxidizer axial velocity [m/s]
Definition Flow1D.h:30
@ c_offset_T
temperature [kelvin]
Definition Flow1D.h:27