| Cantera 3.0.0

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