Cantera  3.2.0a5
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(const shared_ptr<SolutionArray>& arr)
77{
78 setMeta(arr->meta());
79}
80
81// ---------------- Inlet1D methods ----------------
82
84{
85}
86
87Inlet1D::Inlet1D(shared_ptr<Solution> phase, const string& id)
88 : Inlet1D()
89{
91 m_solution->thermo()->addSpeciesLock();
92 m_id = id;
93}
94
95
96//! set spreading rate
98{
99 m_V0 = V0;
101}
102
104{
106 // Adjust flow domain temperature bounds based on inlet temperature
107 if (m_flow != nullptr && m_flow->lowerBound(c_offset_T) >= m_temp) {
109 }
110}
111
112void Inlet1D::show(const double* x)
113{
114 writelog(" Mass Flux: {:10.4g} kg/m^2/s \n", m_mdot);
115 writelog(" Temperature: {:10.4g} K \n", m_temp);
116 if (m_flow) {
117 writelog(" Mass Fractions: \n");
118 for (size_t k = 0; k < m_flow->phase().nSpecies(); k++) {
119 if (m_yin[k] != 0.0) {
120 writelog(" {:>16s} {:10.4g} \n",
121 m_flow->phase().speciesName(k), m_yin[k]);
122 }
123 }
124 }
125 writelog("\n");
126}
127
128void Inlet1D::setMoleFractions(const string& xin)
129{
130 m_xstr = xin;
131 if (m_flow) {
135 }
136}
137
138void Inlet1D::setMoleFractions(const double* xin)
139{
140 if (m_flow) {
144 }
145}
146
148{
149 _init(0);
150
151 // if a flow domain is present on the left, then this must be a right inlet.
152 // Note that an inlet object can only be a terminal object - it cannot have
153 // flows on both the left and right
154 if (m_flow_left && !m_flow_right) {
155 if (!m_flow_left->isStrained()) {
156 throw CanteraError("Inlet1D::init",
157 "Right inlets with right-to-left flow are only supported for "
158 "strained flow configurations.");
159 }
162 } else if (m_flow_right) {
164 m_flow = m_flow_right;
165 } else {
166 throw CanteraError("Inlet1D::init", "Inlet1D is not properly connected.");
167 }
168
169 // components = u, V, T, Lambda, + mass fractions
170 m_nsp = m_flow->phase().nSpecies();
171 m_yin.resize(m_nsp, 0.0);
172 if (m_xstr != "") {
174 } else {
175 m_yin[0] = 1.0;
176 }
177
178}
179
180void Inlet1D::eval(size_t jg, double* xg, double* rg,
181 integer* diagg, double rdt)
182{
183 if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
184 return;
185 }
186
187 if (m_ilr == LeftInlet) {
188 // Array elements corresponding to the first point of the flow domain
189 double* xb = xg + m_flow->loc();
190 double* rb = rg + m_flow->loc();
191
192 // The first flow residual is for u. This, however, is not modified by
193 // the inlet, since this is set within the flow domain from the
194 // continuity equation.
195
196 if (m_flow->doEnergy(0)) {
197 // The third flow residual is for T, where it is set to T(0). Subtract
198 // the local temperature to hold the flow T to the inlet T.
199 rb[c_offset_T] -= m_temp;
200 } else {
201 rb[c_offset_T] -= m_flow->T_fixed(0);
202 }
203
204 if (m_flow->isFree()) {
205 // if the flow is a freely-propagating flame, mdot is not specified.
206 // Set mdot equal to rho*u.
207 m_mdot = m_flow->density(0) * xb[c_offset_U];
208 } else if (m_flow->isStrained()) { // axisymmetric flow
210 // When using two-point control, the mass flow rate at the left inlet is
211 // not specified. Instead, the mass flow rate is dictated by the
212 // velocity at the left inlet, which comes from the U variable. The
213 // default boundary condition specified in the Flow1D.cpp file already
214 // handles this case. We only need to update the stored value of m_mdot
215 // so that other equations that use the quantity are consistent.
217 } else {
218 // The flow domain sets this to -rho*u. Add mdot to specify the mass
219 // flow rate
220 rb[c_offset_L] += m_mdot;
221 }
222
223 // spreading rate. The flow domain sets this to V(0),
224 // so for finite spreading rate subtract m_V0.
225 rb[c_offset_V] -= m_V0;
226 } else { // unstrained flow
227 rb[c_offset_U] = m_flow->density(0) * xb[c_offset_U] - m_mdot;
228 }
229
230 // add the convective term to the species residual equations
231 for (size_t k = 0; k < m_nsp; k++) {
232 if (k != m_flow_right->leftExcessSpecies()) {
233 rb[c_offset_Y+k] += m_mdot*m_yin[k];
234 }
235 }
236
237 } else {
238 // right inlet (should only be used for counter-flow flames)
239 // Array elements corresponding to the last point in the flow domain
240 double* rb = rg + loc() - m_flow->nComponents();
241 double* xb = xg + loc() - m_flow->nComponents();
242 size_t last_index = m_flow->nPoints() - 1;
243
244 rb[c_offset_V] -= m_V0;
245 if (m_flow->doEnergy(m_flow->nPoints() - 1)) {
246 rb[c_offset_T] -= m_temp; // T
247 } else {
248 rb[c_offset_T] -= m_flow->T_fixed(m_flow->nPoints() - 1);
249 }
250
251 if (m_flow->twoPointControlEnabled()) { // For point control adjustments
252 // At the right boundary, the mdot is dictated by the velocity at the right
253 // boundary, which comes from the Uo variable. The variable Uo is the
254 // left-moving velocity and has a negative value, so the mass flow has to be
255 // negated to give a positive value when using Uo.
256 m_mdot = -m_flow->density(last_index) * xb[c_offset_Uo];
257 }
258 rb[c_offset_U] += m_mdot;
259
260 for (size_t k = 0; k < m_nsp; k++) {
261 if (k != m_flow_left->rightExcessSpecies()) {
262 rb[c_offset_Y+k] += m_mdot * m_yin[k];
263 }
264 }
265 }
266}
267
268shared_ptr<SolutionArray> Inlet1D::toArray(bool normalize)
269{
271 meta["mass-flux"] = m_mdot;
272 auto arr = SolutionArray::create(m_solution, 1, meta);
273
274 // set gas state (using pressure from adjacent domain)
275 double pressure = m_flow->phase().pressure();
276 auto thermo = m_solution->thermo();
277 thermo->setState_TPY(m_temp, pressure, m_yin.data());
278 vector<double> data(thermo->stateSize());
279 thermo->saveState(data);
280
281 arr->setState(0, data);
282 if (normalize) {
283 arr->normalize();
284 }
285 return arr;
286}
287
288void Inlet1D::fromArray(const shared_ptr<SolutionArray>& arr)
289{
290 Boundary1D::setMeta(arr->meta());
291 arr->setLoc(0);
292 auto thermo = arr->thermo();
293 auto meta = arr->meta();
294 m_temp = thermo->temperature();
295 if (meta.hasKey("mass-flux")) {
296 m_mdot = meta.at("mass-flux").asDouble();
297 } else {
298 // convert data format used by Python h5py export (Cantera < 3.0)
299 auto aux = arr->getAuxiliary(0);
300 m_mdot = thermo->density() * aux.at("velocity").as<double>();
301 }
302 thermo->getMassFractions(m_yin.data());
303}
304
305// ------------- Empty1D -------------
306
308{
309 _init(0);
310}
311
312void Empty1D::eval(size_t jg, double* xg, double* rg,
313 integer* diagg, double rdt)
314{
315}
316
317shared_ptr<SolutionArray> Empty1D::toArray(bool normalize)
318{
320 return SolutionArray::create(m_solution, 0, meta);
321}
322
323// -------------- Symm1D --------------
324
326{
327 _init(0);
328}
329
330void Symm1D::eval(size_t jg, double* xg, double* rg, integer* diagg,
331 double rdt)
332{
333 if (jg != npos && (jg + 2< firstPoint() || jg > lastPoint() + 2)) {
334 return;
335 }
336
337 // start of local part of global arrays
338 double* x = xg + loc();
339 double* r = rg + loc();
340 integer* diag = diagg + loc();
341
342 if (m_flow_right) {
343 size_t nc = m_flow_right->nComponents();
344 double* xb = x;
345 double* rb = r;
346 int* db = diag;
347 db[c_offset_V] = 0;
348 db[c_offset_T] = 0;
349 rb[c_offset_V] = xb[c_offset_V] - xb[c_offset_V + nc]; // zero dV/dz
350 if (m_flow_right->doEnergy(0)) {
351 rb[c_offset_T] = xb[c_offset_T] - xb[c_offset_T + nc]; // zero dT/dz
352 }
353 }
354
355 if (m_flow_left) {
356 size_t nc = m_flow_left->nComponents();
357 double* xb = x - nc;
358 double* rb = r - nc;
359 int* db = diag - nc;
360 db[c_offset_V] = 0;
361 db[c_offset_T] = 0;
362 rb[c_offset_V] = xb[c_offset_V] - xb[c_offset_V - nc]; // zero dV/dz
364 rb[c_offset_T] = xb[c_offset_T] - xb[c_offset_T - nc]; // zero dT/dz
365 }
366 }
367}
368
369shared_ptr<SolutionArray> Symm1D::toArray(bool normalize)
370{
372 return SolutionArray::create(m_solution, 0, meta);
373}
374
375// -------- Outlet1D --------
376
378{
379}
380
381OutletRes1D::OutletRes1D(shared_ptr<Solution> phase, const string& id)
382 : OutletRes1D()
383{
385 m_solution->thermo()->addSpeciesLock();
386 m_id = id;
387}
388
390{
391 _init(0);
392
393 if (m_flow_right) {
394 throw CanteraError("Outlet1D::init",
395 "Left outlets with right-to-left flow are not supported.");
396 }
397 if (m_flow_left) {
399 } else {
400 throw CanteraError("Outlet1D::init", "Outlet1D is not connected.");
401 }
402}
403
404void Outlet1D::eval(size_t jg, double* xg, double* rg, integer* diagg,
405 double rdt)
406{
407 if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
408 return;
409 }
410
411 // start of local part of global arrays
412 double* x = xg + loc();
413 double* r = rg + loc();
414 integer* diag = diagg + loc();
415
416 // flow is left-to-right
417 size_t nc = m_flow_left->nComponents();
418 double* xb = x - nc;
419 double* rb = r - nc;
420 int* db = diag - nc;
421
422 size_t last = m_flow_left->nPoints() - 1;
423 if (m_flow_left->doEnergy(last)) {
424 rb[c_offset_T] = xb[c_offset_T] - xb[c_offset_T - nc]; // zero T gradient
425 } else {
426 rb[c_offset_T] = xb[c_offset_T] - m_flow_left->T_fixed(last);
427 }
428 size_t kSkip = c_offset_Y + m_flow_left->rightExcessSpecies();
429 for (size_t k = c_offset_Y; k < nc; k++) {
430 if (k != kSkip) {
431 rb[k] = xb[k] - xb[k - nc]; // zero mass fraction gradient
432 db[k] = 0;
433 }
434 }
435}
436
437shared_ptr<SolutionArray> Outlet1D::toArray(bool normalize)
438{
440 return SolutionArray::create(m_solution, 0, meta);
441}
442
443// -------- OutletRes1D --------
444
445void OutletRes1D::setMoleFractions(const string& xres)
446{
447 m_xstr = xres;
448 if (m_flow) {
452 }
453}
454
455void OutletRes1D::setMoleFractions(const double* xres)
456{
457 if (m_flow) {
461 }
462}
463
465{
466 _init(0);
467
468 if (m_flow_right) {
469 throw CanteraError("OutletRes1D::init",
470 "Left outlets with right-to-left flow are not supported.");
471 }
472 if (m_flow_left) {
474 } else {
475 throw CanteraError("OutletRes1D::init", "no flow!");
476 }
477
478 m_nsp = m_flow->phase().nSpecies();
479 m_yres.resize(m_nsp, 0.0);
480 if (m_xstr != "") {
482 } else {
483 m_yres[0] = 1.0;
484 }
485}
486
487void OutletRes1D::eval(size_t jg, double* xg, double* rg,
488 integer* diagg, double rdt)
489{
490 if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
491 return;
492 }
493
494 // start of local part of global arrays
495 double* x = xg + loc();
496 double* r = rg + loc();
497 integer* diag = diagg + loc();
498
499 size_t nc = m_flow_left->nComponents();
500 double* xb = x - nc;
501 double* rb = r - nc;
502 int* db = diag - nc;
503
504 size_t last = m_flow_left->nPoints() - 1;
505 if (m_flow_left->doEnergy(last)) {
506 rb[c_offset_T] = xb[c_offset_T] - xb[c_offset_T - nc]; // zero T gradient
507 } else {
508 rb[c_offset_T] = xb[c_offset_T] - m_flow_left->T_fixed(last);
509 }
510 size_t kSkip = m_flow_left->rightExcessSpecies();
511 for (size_t k = c_offset_Y; k < nc; k++) {
512 if (k != kSkip) {
513 rb[k] = xb[k] - m_yres[k-c_offset_Y]; // fixed Y
514 db[k] = 0;
515 }
516 }
517}
518
519shared_ptr<SolutionArray> OutletRes1D::toArray(bool normalize)
520{
522 meta["temperature"] = m_temp;
523 auto arr = SolutionArray::create(m_solution, 1, meta);
524
525 // set gas state (using pressure from adjacent domain)
526 double pressure = m_flow->phase().pressure();
527 auto thermo = m_solution->thermo();
528 thermo->setState_TPY(m_temp, pressure, &m_yres[0]);
529 vector<double> data(thermo->stateSize());
530 thermo->saveState(data);
531
532 arr->setState(0, data);
533 if (normalize) {
534 arr->normalize();
535 }
536 return arr;
537}
538
539void OutletRes1D::fromArray(const shared_ptr<SolutionArray>& arr)
540{
541 Boundary1D::setMeta(arr->meta());
542 arr->setLoc(0);
543 auto thermo = arr->thermo();
544 m_temp = thermo->temperature();
545 auto Y = thermo->massFractions();
546 std::copy(Y, Y + m_nsp, &m_yres[0]);
547}
548
549// -------- Surf1D --------
550
552{
553 _init(0);
554}
555
556void Surf1D::eval(size_t jg, double* xg, double* rg,
557 integer* diagg, double rdt)
558{
559 if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
560 return;
561 }
562
563 // start of local part of global arrays
564 double* x = xg + loc();
565 double* r = rg + loc();
566
567 if (m_flow_right) {
568 double* rb = r;
569 double* xb = x;
570 rb[c_offset_T] = xb[c_offset_T] - m_temp; // specified T
571 }
572
573 if (m_flow_left) {
574 size_t nc = m_flow_left->nComponents();
575 double* rb = r - nc;
576 double* xb = x - nc;
577 rb[c_offset_T] = xb[c_offset_T] - m_temp; // specified T
578 }
579}
580
581shared_ptr<SolutionArray> Surf1D::toArray(bool normalize)
582{
584 meta["temperature"] = m_temp;
585 return SolutionArray::create(m_solution, 0, meta);
586}
587
588void Surf1D::fromArray(const shared_ptr<SolutionArray>& arr)
589{
590 auto meta = arr->meta();
591 m_temp = meta["temperature"].asDouble();
592 meta.erase("temperature");
594}
595
596void Surf1D::show(const double* x)
597{
598 writelog(" Temperature: {:10.4g} K \n\n", m_temp);
599}
600
601// -------- ReactingSurf1D --------
602
604 : m_kin(0)
605 , m_nsp(0)
606{
607}
608
609ReactingSurf1D::ReactingSurf1D(shared_ptr<Solution> phase, const string& id)
610{
611 auto thermo = std::dynamic_pointer_cast<SurfPhase>(phase->thermo());
612 if (!thermo) {
613 throw CanteraError("ReactingSurf1D::ReactingSurf1D",
614 "Detected incompatible ThermoPhase type '{}'", phase->thermo()->type());
615 }
616 auto kin = std::dynamic_pointer_cast<InterfaceKinetics>(phase->kinetics());
617 if (!kin) {
618 throw CanteraError("ReactingSurf1D::ReactingSurf1D",
619 "Detected incompatible kinetics type '{}'",
620 phase->kinetics()->kineticsType());
621 }
623 m_solution->thermo()->addSpeciesLock();
624 m_id = id;
625 m_kin = kin.get();
626 m_sphase = thermo.get();
628 m_enabled = true;
629}
630
631void ReactingSurf1D::setKinetics(shared_ptr<Kinetics> kin)
632{
633 warn_deprecated("ReactingSurf1D::setKinetics",
634 "After Cantera 3.2, a change of domain contents after instantiation "
635 "will be disabled.");
636 auto sol = Solution::create();
637 sol->setThermo(kin->reactionPhase());
638 sol->setKinetics(kin);
639 sol->setTransportModel("none");
640 m_solution = sol;
641 m_solution->thermo()->addSpeciesLock();
642 m_kin = dynamic_pointer_cast<InterfaceKinetics>(kin).get();
643 m_sphase = dynamic_pointer_cast<SurfPhase>(kin->reactionPhase()).get();
645 m_enabled = true;
646}
647
648string ReactingSurf1D::componentName(size_t n) const
649{
650 if (n < m_nsp) {
651 return m_sphase->speciesName(n);
652 }
653 throw IndexError("ReactingSurf1D::componentName", "component", n, m_nsp);
654}
655
656size_t ReactingSurf1D::componentIndex(const string& name, bool checkAlias) const
657{
658 return m_sphase->speciesIndex(name, true);
659}
660
662{
663 m_nv = m_nsp;
664 _init(m_nsp);
665
666 m_fixed_cov.resize(m_nsp, 0.0);
667 m_fixed_cov[0] = 1.0;
668 m_work.resize(m_kin->nTotalSpecies(), 0.0);
669
670 for (size_t n = 0; n < m_nsp; n++) {
671 setBounds(n, -1.0e-5, 2.0);
672 }
673}
674
676 double* x = xg + loc();
679}
680
681void ReactingSurf1D::eval(size_t jg, double* xg, double* rg,
682 integer* diagg, double rdt)
683{
684 if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
685 return;
686 }
687
688 // start of local part of global arrays
689 double* x = xg + loc();
690 double* r = rg + loc();
691 integer* diag = diagg + loc();
692
693 // set the coverages
694 double sum = 0.0;
695 for (size_t k = 0; k < m_nsp; k++) {
696 m_work[k] = x[k];
697 sum += x[k];
698 }
701
702 // set the left gas state to the adjacent point
703
704 size_t leftloc = 0, rightloc = 0;
705 size_t pnt = 0;
706
707 if (m_flow_left) {
708 leftloc = m_flow_left->loc();
709 pnt = m_flow_left->nPoints() - 1;
710 m_flow_left->setGas(xg + leftloc, pnt);
711 }
712
713 if (m_flow_right) {
714 rightloc = m_flow_right->loc();
715 m_flow_right->setGas(xg + rightloc, 0);
716 }
717
719 double rs0 = 1.0/m_sphase->siteDensity();
720
721 if (m_enabled) {
722 for (size_t k = 0; k < m_nsp; k++) {
723 r[k] = m_work[k] * m_sphase->size(k) * rs0;
724 r[k] -= rdt*(x[k] - prevSoln(k,0));
725 diag[k] = 1;
726 }
727 r[0] = 1.0 - sum;
728 diag[0] = 0;
729 } else {
730 for (size_t k = 0; k < m_nsp; k++) {
731 r[k] = x[k] - m_fixed_cov[k];
732 diag[k] = 0;
733 }
734 }
735
736 if (m_flow_right) {
737 double* rb = r + m_nsp;
738 double* xb = x + m_nsp;
739 rb[c_offset_T] = xb[c_offset_T] - m_temp; // specified T
740 }
741 if (m_flow_left) {
742 size_t nc = m_flow_left->nComponents();
743 const vector<double>& mwleft = m_phase_left->molecularWeights();
744 double* rb = r - nc;
745 double* xb = x - nc;
746 rb[c_offset_T] = xb[c_offset_T] - m_temp; // specified T
747 size_t nSkip = m_flow_left->rightExcessSpecies();
748 size_t l_offset = 0;
749 ThermoPhase* left_thermo = &m_flow_left->phase();
750 for (size_t nth = 0; nth < m_kin->nPhases(); nth++) {
751 if (&m_kin->thermo(nth) == left_thermo) {
752 l_offset = m_kin->kineticsSpeciesIndex(0, nth);
753 break;
754 }
755 }
756 for (size_t nl = 0; nl < m_left_nsp; nl++) {
757 if (nl != nSkip) {
758 rb[c_offset_Y+nl] += m_work[nl + l_offset]*mwleft[nl];
759 }
760 }
761 }
762}
763
764double ReactingSurf1D::value(const string& component) const
765{
766 if (!m_state) {
767 throw CanteraError("ReactingSurf1D::value",
768 "Domain needs to be installed in a container.");
769 }
770 auto i = componentIndex(component);
771 const double* soln = m_state->data() + m_iloc;
772 return soln[index(i, 0)];
773}
774
775shared_ptr<SolutionArray> ReactingSurf1D::toArray(bool normalize)
776{
777 if (!m_state) {
778 throw CanteraError("ReactingSurf1D::toArray",
779 "Domain needs to be installed in a container before calling toArray.");
780 }
781 double* soln = m_state->data() + m_iloc;
783 meta["temperature"] = m_temp;
784 meta["phase"]["name"] = m_sphase->name();
785 AnyValue source = m_sphase->input().getMetadata("filename");
786 meta["phase"]["source"] = source.empty() ? "<unknown>" : source.asString();
787
788 // set state of surface phase
790 m_sphase->setCoverages(soln);
791 vector<double> data(m_sphase->stateSize());
792 m_sphase->saveState(data.size(), &data[0]);
793
794 auto arr = SolutionArray::create(m_solution, 1, meta);
795 arr->setState(0, data);
796 if (normalize) {
797 arr->normalize();
798 }
799 return arr;
800}
801
802void ReactingSurf1D::fromArray(const shared_ptr<SolutionArray>& arr)
803{
804 if (!m_state) {
805 throw CanteraError("Domain1D::fromArray",
806 "Domain needs to be installed in a container before calling fromArray.");
807 }
808 resize(nComponents(), arr->size());
810 double* soln = m_state->data() + m_iloc;
811
812 Boundary1D::setMeta(arr->meta());
813 arr->setLoc(0);
814 auto surf = std::dynamic_pointer_cast<SurfPhase>(arr->thermo());
815 if (!surf) {
816 throw CanteraError("ReactingSurf1D::fromArray",
817 "Restoring of coverages requires surface phase");
818 }
819 m_temp = surf->temperature();
820 surf->getCoverages(soln);
821 _finalize(soln);
822}
823
824void ReactingSurf1D::show(const double* x)
825{
826 writelog(" Temperature: {:10.4g} K \n", m_temp);
827 writelog(" Coverages: \n");
828 for (size_t k = 0; k < m_nsp; k++) {
829 writelog(" {:>20s} {:10.4g} \n", m_sphase->speciesName(k), x[k]);
830 }
831 writelog("\n");
832}
833}
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:88
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
void fromArray(const shared_ptr< SolutionArray > &arr) override
Restore the solution for this domain from a SolutionArray.
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
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:667
size_t m_iloc
Starting location within the solution vector for unknowns that correspond to this domain.
Definition Domain1D.h:845
shared_ptr< Solution > m_solution
Composite thermo/kinetics/transport handler.
Definition Domain1D.h:862
OneDim * m_container
Parent OneDim simulation containing this and adjacent domains.
Definition Domain1D.h:836
size_t nComponents() const
Number of components at each grid point.
Definition Domain1D.h:174
virtual bool isConnector()
True if the domain is a connector domain.
Definition Domain1D.h:59
virtual void setMeta(const AnyMap &meta)
Retrieve meta data.
Definition Domain1D.cpp:171
size_t m_index
Left-to-right location of this domain.
Definition Domain1D.h:838
string id() const
Returns the identifying tag for this domain.
Definition Domain1D.h:718
shared_ptr< Solution > phase() const
Return thermo/kinetics/transport manager used in the domain.
Definition Domain1D.h:641
size_t m_nv
Number of solution components.
Definition Domain1D.h:824
size_t nPoints() const
Number of grid points in this domain.
Definition Domain1D.h:202
double lowerBound(size_t n) const
Lower bound on the nth component.
Definition Domain1D.h:329
shared_ptr< vector< double > > m_state
data pointer shared from OneDim
Definition Domain1D.h:821
virtual void resize(size_t nv, size_t np)
Resize the domain to have nv components and np grid points.
Definition Domain1D.cpp:52
double upperBound(size_t n) const
Upper bound on the nth component.
Definition Domain1D.h:324
const OneDim & container() const
The container holding this domain.
Definition Domain1D.h:112
string m_id
Identity tag for the domain.
Definition Domain1D.h:855
string type() const
String indicating the domain implemented.
Definition Domain1D.h:51
void setBounds(size_t n, double lower, double upper)
Set the upper and lower bounds for a solution component, n.
Definition Domain1D.h:268
double prevSoln(size_t n, size_t j) const
Value of component n at point j in the previous solution.
Definition Domain1D.h:708
size_t firstPoint() const
The index of the first (that is, left-most) grid point belonging to this domain.
Definition Domain1D.h:662
void needJacUpdate()
Set this if something has changed in the governing equations (for example, the value of a constant ha...
Definition Domain1D.cpp:135
size_t index(size_t n, size_t j) const
Returns the index of the solution vector, which corresponds to component n at grid point j.
Definition Domain1D.h:408
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:657
virtual AnyMap getMeta() const
Retrieve meta data.
Definition Domain1D.cpp:143
shared_ptr< SolutionArray > toArray(bool normalize=false) override
Save the state of this domain to 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:47
double density(size_t j) const
Get the density [kg/m³] at point j
Definition Flow1D.h:425
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:410
ThermoPhase & phase()
Access the phase object used to compute thermodynamic properties for points in this domain.
Definition Flow1D.h:93
bool twoPointControlEnabled() const
Returns the status of the two-point control.
Definition Flow1D.h:403
size_t rightExcessSpecies() const
Index of the species on the right boundary with the largest mass fraction.
Definition Flow1D.h:484
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:289
void setViscosityFlag(bool dovisc)
Specify if the viscosity term should be included in the momentum equation.
Definition Flow1D.h:451
size_t leftExcessSpecies() const
Index of the species on the left boundary with the largest mass fraction.
Definition Flow1D.h:479
bool isFree() const
Retrieve flag indicating whether flow is freely propagating.
Definition Flow1D.h:435
bool isStrained() const
Retrieve flag indicating whether flow uses radial momentum.
Definition Flow1D.h:446
double T_fixed(size_t j) const
The fixed temperature value at point j.
Definition Flow1D.h:193
An array index is out of range.
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
shared_ptr< SolutionArray > toArray(bool normalize=false) override
Save the state of this domain to a SolutionArray.
string m_xstr
inlet mass fractions.
Definition Boundary1D.h:188
size_t nSpecies() override
Get the number of species.
Definition Boundary1D.h:165
void fromArray(const shared_ptr< SolutionArray > &arr) override
Restore the solution for this domain from a SolutionArray.
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 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:270
size_t nPhases() const
The number of phases participating in the reaction mechanism.
Definition Kinetics.h:201
size_t kineticsSpeciesIndex(size_t k, size_t n) const
The location of species k of phase n in species arrays.
Definition Kinetics.h:304
size_t nTotalSpecies() const
The total number of species in all phases participating in the kinetics mechanism.
Definition Kinetics.h:282
virtual void getNetProductionRates(double *wdot)
Species net production rates [kmol/m^3/s or kmol/m^2/s].
Definition Kinetics.cpp:489
void resize() override
Call to set the size of internal data structures after first defining the system or if the problem si...
Definition OneDim.cpp:189
Domain1D & domain(size_t i) const
Return a reference to domain i.
Definition OneDim.h:78
shared_ptr< SolutionArray > toArray(bool normalize=false) override
Save the state of this domain to 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:290
void setMoleFractions(const string &xin) override
Set the mole fractions by specifying a string.
shared_ptr< SolutionArray > toArray(bool normalize=false) override
Save the state of this domain to a SolutionArray.
OutletRes1D()
Default constructor.
string m_xstr
Mole fractions in the reservoir.
Definition Boundary1D.h:324
vector< double > m_yres
Mass fractions in the reservoir.
Definition Boundary1D.h:323
void fromArray(const shared_ptr< SolutionArray > &arr) override
Restore the solution for this domain from 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
Number of species in the adjacent flow domain.
Definition Boundary1D.h:322
void init() override
Initialize.
Flow1D * m_flow
The adjacent flow domain.
Definition Boundary1D.h:325
virtual void setMoleFractions(const double *const x)
Set the mole fractions to the specified values.
Definition Phase.cpp:347
size_t nSpecies() const
Returns the number of species in the phase.
Definition Phase.h:270
void saveState(vector< double > &state) const
Save the current internal state of the phase.
Definition Phase.cpp:303
string speciesName(size_t k) const
Name of the species with index k.
Definition Phase.cpp:174
virtual size_t stateSize() const
Return size of vector defining internal state of the phase.
Definition Phase.cpp:295
void setMoleFractionsByName(const Composition &xMap)
Set the species mole fractions by name.
Definition Phase.cpp:388
const vector< double > & molecularWeights() const
Return a const reference to the internal vector of molecular weights.
Definition Phase.cpp:460
size_t speciesIndex(const string &name) const
Returns the index of a species named 'name' within the Phase object.
Definition Phase.cpp:147
virtual void setTemperature(double temp)
Set the internally stored temperature of the phase (K).
Definition Phase.h:690
void getMassFractions(double *const y) const
Get the species mass fractions.
Definition Phase.cpp:536
virtual double pressure() const
Return the thermodynamic pressure (Pa).
Definition Phase.h:647
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...
size_t componentIndex(const string &name, bool checkAlias=true) const override
Index of component with name name.
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 > toArray(bool normalize=false) override
Save the state of this domain to a SolutionArray.
double value(const string &component) const override
Set a single component value at a boundary.
void fromArray(const shared_ptr< SolutionArray > &arr) override
Restore the solution for this domain from a SolutionArray.
void eval(size_t jg, double *xg, double *rg, integer *diagg, double rdt) override
Evaluate the residual function at point j.
void _finalize(const double *x) override
In some cases, a domain may need to set parameters that depend on the initial solution estimate.
Definition Boundary1D.h:406
size_t m_nsp
the number of surface phase species
Definition Boundary1D.h:415
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.
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 > toArray(bool normalize=false) override
Save the state of this domain to a SolutionArray.
void fromArray(const shared_ptr< SolutionArray > &arr) override
Restore the solution for this domain from 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.
void show(const double *x) override
Print the solution.
double pressure() const override
Return the thermodynamic pressure (Pa).
Definition SurfPhase.h:254
double size(size_t k) const
Returns the number of sites occupied by one molecule of species k.
Definition SurfPhase.h:237
void setCoverages(const double *theta)
Set the surface site fractions to a specified state.
double siteDensity() const
Returns the site density.
Definition SurfPhase.h:232
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 > toArray(bool normalize=false) override
Save the state of this domain to 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:176
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:26
@ c_offset_L
(1/r)dP/dr
Definition Flow1D.h:29
@ c_offset_V
strain rate
Definition Flow1D.h:27
@ c_offset_Y
mass fractions
Definition Flow1D.h:32
@ c_offset_Uo
oxidizer axial velocity [m/s]
Definition Flow1D.h:31
@ c_offset_T
temperature [kelvin]
Definition Flow1D.h:28
void warn_deprecated(const string &source, const AnyBase &node, const string &message)
A deprecation warning for syntax in an input file.
Definition AnyMap.cpp:1997