Cantera  2.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
boundaries1D.cpp
Go to the documentation of this file.
1 /**
2  * @file boundaries1D.cpp
3  */
4 // Copyright 2002-3 California Institute of Technology
5 
6 #include "cantera/oneD/Inlet1D.h"
7 #include "cantera/oneD/OneDim.h"
8 #include "cantera/base/ctml.h"
9 
10 using namespace std;
11 
12 namespace Cantera
13 {
14 
15 Bdry1D::Bdry1D() : Domain1D(1, 1, 0.0),
16  m_flow_left(0), m_flow_right(0),
17  m_ilr(0), m_left_nv(0), m_right_nv(0),
18  m_left_loc(0), m_right_loc(0),
19  m_left_points(0), m_nv(0),
20  m_left_nsp(0), m_right_nsp(0),
21  m_sp_left(0), m_sp_right(0),
22  m_start_left(0), m_start_right(0),
23  m_phase_left(0), m_phase_right(0), m_temp(0.0), m_mdot(0.0)
24 {
25  m_type = cConnectorType;
26 }
27 
28 void Bdry1D::_init(size_t n)
29 {
30  if (m_index == npos) {
31  throw CanteraError("Bdry1D::_init",
32  "install in container before calling init.");
33  }
34 
35  // A boundary object contains only one grid point
36  resize(n,1);
37 
38  m_left_nsp = 0;
39  m_right_nsp = 0;
40 
41  // check for left and right flow objects
42  if (m_index > 0) {
43  Domain1D& r = container().domain(m_index-1);
44  if (r.domainType() == cFlowType) {
45  m_flow_left = (StFlow*)&r;
46  m_left_nv = m_flow_left->nComponents();
47  m_left_points = m_flow_left->nPoints();
48  m_left_loc = container().start(m_index-1);
49  m_left_nsp = m_left_nv - 4;
50  m_phase_left = &m_flow_left->phase();
51  } else
52  throw CanteraError("Bdry1D::_init",
53  "Boundary domains can only be "
54  "connected on the left to flow domains, not type "+int2str(r.domainType())
55  + " domains.");
56  }
57 
58  // if this is not the last domain, see what is connected on
59  // the right
60  if (m_index + 1 < container().nDomains()) {
61  Domain1D& r = container().domain(m_index+1);
62  if (r.domainType() == cFlowType) {
63  m_flow_right = (StFlow*)&r;
64  m_right_nv = m_flow_right->nComponents();
65  m_right_loc = container().start(m_index+1);
66  m_right_nsp = m_right_nv - 4;
67  m_phase_right = &m_flow_right->phase();
68  } else
69  throw CanteraError("Bdry1D::_init",
70  "Boundary domains can only be "
71  "connected on the right to flow domains, not type "+int2str(r.domainType())
72  + " domains.");
73  }
74 }
75 
76 //----------------------------------------------------------
77 // Inlet1D methods
78 //----------------------------------------------------------
79 
80 void Inlet1D::setMoleFractions(const std::string& xin)
81 {
82  m_xstr = xin;
83  if (m_flow) {
84  m_flow->phase().setMoleFractionsByName(xin);
85  m_flow->phase().getMassFractions(DATA_PTR(m_yin));
86  needJacUpdate();
87  }
88 }
89 
90 void Inlet1D::setMoleFractions(const doublereal* xin)
91 {
92  if (m_flow) {
93  m_flow->phase().setMoleFractions(xin);
94  m_flow->phase().getMassFractions(DATA_PTR(m_yin));
95  needJacUpdate();
96  }
97 }
98 
99 string Inlet1D::componentName(size_t n) const
100 {
101  switch (n) {
102  case 0:
103  return "mdot";
104  case 1:
105  return "temperature";
106  default:
107  break;
108  }
109  return "unknown";
110 }
111 
113 {
114  _init(2);
115 
116  setBounds(0, -1e5, 1e5); // mdot
117  setBounds(1, 200.0, 1e5); // T
118 
119  // set tolerances
120  setSteadyTolerances(1e-4, 1e-5);
121  setTransientTolerances(1e-4, 1e-5);
122 
123  // if a flow domain is present on the left, then this must be
124  // a right inlet. Note that an inlet object can only be a
125  // terminal object - it cannot have flows on both the left and
126  // right
127  if (m_flow_left) {
128  m_ilr = RightInlet;
129  m_flow = m_flow_left;
130  } else if (m_flow_right) {
131  m_ilr = LeftInlet;
132  m_flow = m_flow_right;
133  } else {
134  throw CanteraError("Inlet1D::init","no flow!");
135  }
136 
137  // components = u, V, T, lambda, + mass fractions
138  m_nsp = m_flow->nComponents() - 4;
139  m_yin.resize(m_nsp, 0.0);
140  if (m_xstr != "") {
141  setMoleFractions(m_xstr);
142  } else {
143  m_yin[0] = 1.0;
144  }
145 }
146 
147 void Inlet1D::eval(size_t jg, doublereal* xg, doublereal* rg,
148  integer* diagg, doublereal rdt)
149 {
150  if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
151  return;
152  }
153 
154  // start of local part of global arrays
155  doublereal* x = xg + loc();
156  doublereal* r = rg + loc();
157  integer* diag = diagg + loc();
158  doublereal* xb, *rb;
159 
160  // residual equations for the two local variables
161 
162  r[0] = m_mdot - x[0];
163 
164  // Temperature
165  r[1] = m_temp - x[1];
166 
167  // both are algebraic constraints
168  diag[0] = 0;
169  diag[1] = 0;
170 
171 
172  // if it is a left inlet, then the flow solution vector
173  // starts 2 to the right in the global solution vector
174  if (m_ilr == LeftInlet) {
175  xb = x + 2;
176  rb = r + 2;
177 
178  // The first flow residual is for u. This, however, is not
179  // modified by the inlet, since this is set within the flow
180  // domain from the continuity equation.
181 
182  // spreading rate. The flow domain sets this to V(0),
183  // so for finite spreading rate subtract m_V0.
184  rb[1] -= m_V0;
185 
186  // The third flow residual is for T, where it is set to
187  // T(0). Subtract the local temperature to hold the flow
188  // T to the inlet T.
189  rb[2] -= x[1];
190 
191  // The flow domain sets this to -rho*u. Add mdot to
192  // specify the mass flow rate.
193  rb[3] += x[0];
194 
195  // add the convective term to the species residual equations
196  for (size_t k = 1; k < m_nsp; k++) {
197  rb[4+k] += x[0]*m_yin[k];
198  }
199 
200  // if the flow is a freely-propagating flame, mdot is not
201  // specified. Set mdot equal to rho*u, and also set
202  // lambda to zero.
203  if (!m_flow->fixed_mdot()) {
204  m_mdot = m_flow->density(0)*xb[0];
205  r[0] = m_mdot - x[0];
206  rb[3] = xb[3];
207  }
208  }
209 
210  // right inlet.
211  else {
212  size_t boffset = m_flow->nComponents();
213  xb = x - boffset;
214  rb = r - boffset;
215  rb[1] -= m_V0;
216  rb[2] -= x[1]; // T
217  rb[0] += x[0]; // u
218  for (size_t k = 1; k < m_nsp; k++) {
219  rb[4+k] += x[0]*(m_yin[k]);
220  }
221  }
222 }
223 
224 XML_Node& Inlet1D::save(XML_Node& o, const doublereal* const soln)
225 {
226  const doublereal* s = soln + loc();
227  XML_Node& inlt = Domain1D::save(o, soln);
228  inlt.addAttribute("type","inlet");
229  for (size_t k = 0; k < nComponents(); k++) {
230  addFloat(inlt, componentName(k), s[k]);
231  }
232  for (size_t k=0; k < m_nsp; k++) {
233  addFloat(inlt, "massFraction", m_yin[k], "",
234  m_flow->phase().speciesName(k));
235  }
236  return inlt;
237 }
238 
239 void Inlet1D::restore(const XML_Node& dom, doublereal* soln, int loglevel)
240 {
241  Domain1D::restore(dom, soln, loglevel);
242  soln[0] = m_mdot = getFloat(dom, "mdot", "massflowrate");
243  soln[1] = m_temp = getFloat(dom, "temperature", "temperature");
244 
245  m_yin.assign(m_nsp, 0.0);
246 
247  for (size_t i = 0; i < dom.nChildren(); i++) {
248  const XML_Node& node = dom.child(i);
249  if (node.name() == "massFraction") {
250  size_t k = m_flow->phase().speciesIndex(node.attrib("type"));
251  if (k != npos) {
252  m_yin[k] = node.fp_value();
253  }
254  }
255  }
256  resize(2,1);
257 }
258 
259 //--------------------------------------------------
260 // Empty1D
261 //--------------------------------------------------
262 
263 string Empty1D::componentName(size_t n) const
264 {
265  switch (n) {
266  case 0:
267  return "dummy";
268  default:
269  break;
270  }
271  return "<unknown>";
272 }
273 
275 {
276  setBounds(0, -1.0, 1.0);
277 
278  // set tolerances
279  setSteadyTolerances(1e-4, 1e-4);
280  setTransientTolerances(1e-4, 1e-4);
281 }
282 
283 void Empty1D::eval(size_t jg, doublereal* xg, doublereal* rg,
284  integer* diagg, doublereal rdt)
285 {
286  if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
287  return;
288  }
289 
290  // start of local part of global arrays
291  doublereal* x = xg + loc();
292  doublereal* r = rg + loc();
293  integer* diag = diagg + loc();
294  // integer *db;
295 
296  r[0] = x[0];
297  diag[0] = 0;
298 }
299 
300 XML_Node& Empty1D::save(XML_Node& o, const doublereal* const soln)
301 {
302  XML_Node& symm = Domain1D::save(o, soln);
303  symm.addAttribute("type","empty");
304  return symm;
305 }
306 
307 void Empty1D::restore(const XML_Node& dom, doublereal* soln, int loglevel)
308 {
309  Domain1D::restore(dom, soln, loglevel);
310  resize(1,1);
311 }
312 
313 //--------------------------------------------------
314 // Symm1D
315 //--------------------------------------------------
316 
317 string Symm1D::componentName(size_t n) const
318 {
319  switch (n) {
320  case 0:
321  return "dummy";
322  default:
323  break;
324  }
325  return "<unknown>";
326 }
327 
329 {
330  _init(1);
331  setBounds(0, -1.0, 1.0);
332 
333  // set tolerances
334  setSteadyTolerances(1e-4, 1e-4);
335  setTransientTolerances(1e-4, 1e-4);
336 }
337 
338 void Symm1D::eval(size_t jg, doublereal* xg, doublereal* rg, integer* diagg,
339  doublereal rdt)
340 {
341  if (jg != npos && (jg + 2< firstPoint() || jg > lastPoint() + 2)) {
342  return;
343  }
344 
345  // start of local part of global arrays
346  doublereal* x = xg + loc();
347  doublereal* r = rg + loc();
348  integer* diag = diagg + loc();
349  doublereal* xb, *rb;
350  integer* db;
351 
352  r[0] = x[0];
353  diag[0] = 0;
354  size_t nc;
355 
356  if (m_flow_right) {
357  nc = m_flow_right->nComponents();
358  xb = x + 1;
359  rb = r + 1;
360  db = diag + 1;
361  db[1] = 0;
362  db[2] = 0;
363  rb[1] = xb[1] - xb[1 + nc]; // zero dV/dz
364  rb[2] = xb[2] - xb[2 + nc]; // zero dT/dz
365  }
366 
367  if (m_flow_left) {
368  nc = m_flow_left->nComponents();
369  xb = x - nc;
370  rb = r - nc;
371  db = diag - nc;
372  db[1] = 0;
373  db[2] = 0;
374  rb[1] = xb[1] - xb[1 - nc]; // zero dV/dz
375  rb[2] = xb[2] - xb[2 - nc]; // zero dT/dz
376  }
377 }
378 
379 XML_Node& Symm1D::save(XML_Node& o, const doublereal* const soln)
380 {
381  XML_Node& symm = Domain1D::save(o, soln);
382  symm.addAttribute("type","symmetry");
383  return symm;
384 }
385 
386 void Symm1D::restore(const XML_Node& dom, doublereal* soln, int loglevel)
387 {
388  Domain1D::restore(dom, soln, loglevel);
389  resize(1,1);
390 }
391 
392 //--------------------------------------------------
393 // Outlet1D
394 //--------------------------------------------------
395 
396 string Outlet1D::componentName(size_t n) const
397 {
398  switch (n) {
399  case 0:
400  return "outlet dummy";
401  default:
402  break;
403  }
404  return "<unknown>";
405 }
406 
408 {
409  _init(1);
410  setBounds(0, -1.0, 1.0);
411 
412  // set tolerances
413  setSteadyTolerances(1e-4, 1e-4);
414  setTransientTolerances(1e-4, 1e-4);
415  if (m_flow_right) {
416  m_flow_right->setViscosityFlag(false);
417  }
418  if (m_flow_left) {
419  m_flow_left->setViscosityFlag(false);
420  }
421 }
422 
423 void Outlet1D::eval(size_t jg, doublereal* xg, doublereal* rg, integer* diagg,
424  doublereal rdt)
425 {
426  if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
427  return;
428  }
429 
430  // start of local part of global arrays
431  doublereal* x = xg + loc();
432  doublereal* r = rg + loc();
433  integer* diag = diagg + loc();
434  doublereal* xb, *rb;
435  integer* db;
436 
437  r[0] = x[0];
438  diag[0] = 0;
439  size_t nc, k;
440 
441  if (m_flow_right) {
442  nc = m_flow_right->nComponents();
443  xb = x + 1;
444  rb = r + 1;
445  db = diag + 1;
446  rb[0] = xb[3];
447  rb[2] = xb[2] - xb[2 + nc];
448  for (k = 4; k < nc; k++) {
449  rb[k] = xb[k] - xb[k + nc];
450  }
451  }
452 
453  if (m_flow_left) {
454  nc = m_flow_left->nComponents();
455  xb = x - nc;
456  rb = r - nc;
457  db = diag - nc;
458 
459  // zero Lambda
460  if (m_flow_left->fixed_mdot()) {
461  rb[0] = xb[3];
462  }
463 
464  rb[2] = xb[2] - xb[2 - nc]; // zero T gradient
465  for (k = 5; k < nc; k++) {
466  rb[k] = xb[k] - xb[k - nc]; // zero mass fraction gradient
467  db[k] = 0;
468  }
469  }
470 }
471 
472 XML_Node& Outlet1D::save(XML_Node& o, const doublereal* const soln)
473 {
474  XML_Node& outlt = Domain1D::save(o, soln);
475  outlt.addAttribute("type","outlet");
476  return outlt;
477 }
478 
479 void Outlet1D::restore(const XML_Node& dom, doublereal* soln, int loglevel)
480 {
481  Domain1D::restore(dom, soln, loglevel);
482  resize(1,1);
483 }
484 
485 //--------------------------------------------------
486 // OutletRes1D
487 //--------------------------------------------------
488 
489 void OutletRes1D::setMoleFractions(const std::string& xres)
490 {
491  m_xstr = xres;
492  if (m_flow) {
493  m_flow->phase().setMoleFractionsByName(xres);
494  m_flow->phase().getMassFractions(DATA_PTR(m_yres));
495  needJacUpdate();
496  }
497 }
498 
499 void OutletRes1D::setMoleFractions(const doublereal* xres)
500 {
501  if (m_flow) {
502  m_flow->phase().setMoleFractions(xres);
503  m_flow->phase().getMassFractions(DATA_PTR(m_yres));
504  needJacUpdate();
505  }
506 }
507 
508 string OutletRes1D::componentName(size_t n) const
509 {
510  switch (n) {
511  case 0:
512  return "dummy";
513  default:
514  break;
515  }
516  return "<unknown>";
517 }
518 
520 {
521  _init(1);
522  // set bounds (dummy)
523  setBounds(0, -1.0, 1.0);
524 
525  // set tolerances
526  setSteadyTolerances(1e-4, 1e-4);
527  setTransientTolerances(1e-4, 1e-4);
528 
529  if (m_flow_left) {
530  m_flow = m_flow_left;
531  } else if (m_flow_right) {
532  m_flow = m_flow_right;
533  } else {
534  throw CanteraError("OutletRes1D::init","no flow!");
535  }
536 
537  m_nsp = m_flow->nComponents() - 4;
538  m_yres.resize(m_nsp, 0.0);
539  if (m_xstr != "") {
540  setMoleFractions(m_xstr);
541  } else {
542  m_yres[0] = 1.0;
543  }
544 }
545 
546 void OutletRes1D::eval(size_t jg, doublereal* xg, doublereal* rg,
547  integer* diagg, doublereal rdt)
548 {
549 
550  if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
551  return;
552  }
553 
554  // start of local part of global arrays
555  doublereal* x = xg + loc();
556  doublereal* r = rg + loc();
557  integer* diag = diagg + loc();
558  doublereal* xb, *rb;
559  integer* db;
560 
561  // drive dummy component to zero
562  r[0] = x[0];
563  diag[0] = 0;
564  size_t nc, k;
565 
566  if (m_flow_right) {
567  nc = m_flow_right->nComponents();
568  xb = x + 1;
569  rb = r + 1;
570  db = diag + 1;
571 
572  // this seems wrong...
573  // zero Lambda
574  rb[0] = xb[3];
575 
576  // zero gradient for T
577  rb[2] = xb[2] - xb[2 + nc];
578 
579  // specified mass fractions
580  for (k = 4; k < nc; k++) {
581  rb[k] = xb[k] - m_yres[k-4];
582  }
583  }
584 
585  if (m_flow_left) {
586 
587  nc = m_flow_left->nComponents();
588  xb = x - nc;
589  rb = r - nc;
590  db = diag - nc;
591 
592  if (!m_flow_left->fixed_mdot()) {
593  ;
594  } else {
595  rb[0] = xb[3]; // zero Lambda
596  }
597  rb[2] = xb[2] - m_temp; // zero dT/dz
598  for (k = 5; k < nc; k++) {
599  rb[k] = xb[k] - m_yres[k-4]; // fixed Y
600  db[k] = 0;
601  }
602  }
603 }
604 
605 XML_Node& OutletRes1D::save(XML_Node& o, const doublereal* const soln)
606 {
607  XML_Node& outlt = Domain1D::save(o, soln);
608  outlt.addAttribute("type","outletres");
609  addFloat(outlt, "temperature", m_temp, "K");
610  for (size_t k=0; k < m_nsp; k++) {
611  addFloat(outlt, "massFraction", m_yres[k], "",
612  m_flow->phase().speciesName(k));
613  }
614  return outlt;
615 }
616 
617 void OutletRes1D::restore(const XML_Node& dom, doublereal* soln, int loglevel)
618 {
619  Domain1D::restore(dom, soln, loglevel);
620  m_temp = getFloat(dom, "temperature");
621 
622  m_yres.assign(m_nsp, 0.0);
623  for (size_t i = 0; i < dom.nChildren(); i++) {
624  const XML_Node& node = dom.child(i);
625  if (node.name() == "massFraction") {
626  size_t k = m_flow->phase().speciesIndex(node.attrib("type"));
627  if (k != npos) {
628  m_yres[k] = node.fp_value();
629  }
630  }
631  }
632 
633  resize(1,1);
634 }
635 
636 //-----------------------------------------------------------
637 // Surf1D
638 //-----------------------------------------------------------
639 
640 string Surf1D::componentName(size_t n) const
641 {
642  switch (n) {
643  case 0:
644  return "temperature";
645  default:
646  break;
647  }
648  return "<unknown>";
649 }
650 
652 {
653  _init(1);
654  // set bounds (T)
655  setBounds(0, 200.0, 1e5);
656 
657  // set tolerances
658  setSteadyTolerances(1e-4, 1e-4);
659  setTransientTolerances(1e-4, 1e-4);
660 }
661 
662 void Surf1D::eval(size_t jg, doublereal* xg, doublereal* rg,
663  integer* diagg, doublereal 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  doublereal* x = xg + loc();
671  doublereal* r = rg + loc();
672  integer* diag = diagg + loc();
673  doublereal* xb, *rb;
674 
675  r[0] = x[0] - m_temp;
676  diag[0] = 0;
677  size_t nc;
678 
679  if (m_flow_right) {
680  rb = r + 1;
681  xb = x + 1;
682  rb[2] = xb[2] - x[0]; // specified T
683  }
684 
685  if (m_flow_left) {
686  nc = m_flow_left->nComponents();
687  rb = r - nc;
688  xb = x - nc;
689  rb[2] = xb[2] - x[0]; // specified T
690  }
691 }
692 
693 XML_Node& Surf1D::save(XML_Node& o, const doublereal* const soln)
694 {
695  const doublereal* s = soln + loc();
696  XML_Node& inlt = Domain1D::save(o, soln);
697  inlt.addAttribute("type","surface");
698  for (size_t k = 0; k < nComponents(); k++) {
699  addFloat(inlt, componentName(k), s[k]);
700  }
701  return inlt;
702 }
703 
704 void Surf1D::restore(const XML_Node& dom, doublereal* soln, int loglevel)
705 {
706  Domain1D::restore(dom, soln, loglevel);
707  soln[0] = m_temp = getFloat(dom, "temperature", "temperature");
708  resize(1,1);
709 }
710 
711 //-----------------------------------------------------------
712 // ReactingSurf1D
713 //-----------------------------------------------------------
714 
715 string ReactingSurf1D::componentName(size_t n) const
716 {
717  if (n == 0) {
718  return "temperature";
719  } else if (n < m_nsp + 1) {
720  return m_sphase->speciesName(n-1);
721  } else {
722  return "<unknown>";
723  }
724 }
725 
727 {
728  m_nv = m_nsp + 1;
729  _init(m_nsp+1);
730  m_fixed_cov.resize(m_nsp, 0.0);
731  m_fixed_cov[0] = 1.0;
732  m_work.resize(m_kin->nTotalSpecies(), 0.0);
733 
734  setBounds(0, 200.0, 1e5);
735  for (size_t n = 0; n < m_nsp; n++) {
736  setBounds(n+1, -1.0e-5, 2.0);
737  }
738  setSteadyTolerances(1.0e-5, 1.0e-9);
739  setTransientTolerances(1.0e-5, 1.0e-9);
740  setSteadyTolerances(1.0e-5, 1.0e-4, 0);
741  setTransientTolerances(1.0e-5, 1.0e-4, 0);
742 }
743 
744 void ReactingSurf1D::eval(size_t jg, doublereal* xg, doublereal* rg,
745  integer* diagg, doublereal rdt)
746 {
747  if (jg != npos && (jg + 2 < firstPoint() || jg > lastPoint() + 2)) {
748  return;
749  }
750 
751  // start of local part of global arrays
752  doublereal* x = xg + loc();
753  doublereal* r = rg + loc();
754  integer* diag = diagg + loc();
755  doublereal* xb, *rb;
756 
757  // specified surface temp
758  r[0] = x[0] - m_temp;
759 
760  // set the coverages
761  doublereal sum = 0.0;
762  for (size_t k = 0; k < m_nsp; k++) {
763  m_work[k] = x[k+1];
764  sum += x[k+1];
765  }
766  m_sphase->setTemperature(x[0]);
767  m_sphase->setCoverages(DATA_PTR(m_work));
768 
769  // set the left gas state to the adjacent point
770 
771  size_t leftloc = 0, rightloc = 0;
772  size_t pnt = 0;
773 
774  if (m_flow_left) {
775  leftloc = m_flow_left->loc();
776  pnt = m_flow_left->nPoints() - 1;
777  m_flow_left->setGas(xg + leftloc, pnt);
778  }
779 
780  if (m_flow_right) {
781  rightloc = m_flow_right->loc();
782  m_flow_right->setGas(xg + rightloc, 0);
783  }
784 
785  m_kin->getNetProductionRates(DATA_PTR(m_work));
786  doublereal rs0 = 1.0/m_sphase->siteDensity();
787  size_t ioffset = m_kin->kineticsSpeciesIndex(0, m_surfindex);
788 
789  if (m_enabled) {
790  doublereal maxx = -1.0;
791  for (size_t k = 0; k < m_nsp; k++) {
792  r[k+1] = m_work[k + ioffset] * m_sphase->size(k) * rs0;
793  r[k+1] -= rdt*(x[k+1] - prevSoln(k+1,0));
794  diag[k+1] = 1;
795  maxx = std::max(x[k+1], maxx);
796  }
797  r[1] = 1.0 - sum;
798  diag[1] = 0;
799  } else {
800  for (size_t k = 0; k < m_nsp; k++) {
801  r[k+1] = x[k+1] - m_fixed_cov[k];
802  diag[k+1] = 0;
803  }
804  }
805 
806  if (m_flow_right) {
807  rb = r + 1;
808  xb = x + 1;
809  rb[2] = xb[2] - x[0]; // specified T
810  }
811  size_t nc;
812  if (m_flow_left) {
813  nc = m_flow_left->nComponents();
814  const doublereal* mwleft = DATA_PTR(m_phase_left->molecularWeights());
815  rb =r - nc;
816  xb = x - nc;
817  rb[2] = xb[2] - x[0]; // specified T
818  for (size_t nl = 1; nl < m_left_nsp; nl++) {
819  rb[4+nl] += m_work[nl]*mwleft[nl];
820  }
821  }
822 }
823 
824 XML_Node& ReactingSurf1D::save(XML_Node& o, const doublereal* const soln)
825 {
826  const doublereal* s = soln + loc();
827  XML_Node& dom = Domain1D::save(o, soln);
828  dom.addAttribute("type","surface");
829  addFloat(dom, "temperature", s[0], "K");
830  for (size_t k=0; k < m_nsp; k++) {
831  addFloat(dom, "coverage", s[k+1], "",
832  m_sphase->speciesName(k));
833  }
834  return dom;
835 }
836 
837 void ReactingSurf1D::restore(const XML_Node& dom, doublereal* soln,
838  int loglevel)
839 {
840  Domain1D::restore(dom, soln, loglevel);
841  soln[0] = m_temp = getFloat(dom, "temperature");
842 
843  m_fixed_cov.assign(m_nsp, 0.0);
844  for (size_t i = 0; i < dom.nChildren(); i++) {
845  const XML_Node& node = dom.child(i);
846  if (node.name() == "coverage") {
847  size_t k = m_sphase->speciesIndex(node.attrib("type"));
848  if (k != npos) {
849  m_fixed_cov[k] = soln[k+1] = node.fp_value();
850  }
851  }
852  }
853  m_sphase->setCoverages(&m_fixed_cov[0]);
854 
855  resize(m_nsp+1,1);
856 }
857 }
virtual void eval(size_t jg, doublereal *xg, doublereal *rg, integer *diagg, doublereal rdt)
Evaluate the residual function at point j.
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
Definition: stringUtils.cpp:39
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
size_t nPoints() const
Number of grid points in this domain.
Definition: Domain1D.h:186
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:527
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
void getMassFractions(doublereal *const y) const
Get the species mass fractions.
Definition: Phase.cpp:598
virtual void setMoleFractions(const std::string &xin)
Set the mole fractions by specifying a std::string.
virtual void eval(size_t jg, doublereal *xg, doublereal *rg, integer *diagg, doublereal rdt)
Evaluate the residual function at point j.
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:165
size_t firstPoint() const
The index of the first (i.e., left-most) grid point belonging to this domain.
Definition: Domain1D.h:435
virtual XML_Node & save(XML_Node &o, const doublereal *const soln)
Save the current solution for this domain into an XML_Node.
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
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:427
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
void setCoverages(const doublereal *theta)
Set the surface site fractions to a specified state.
Definition: SurfPhase.cpp:284
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:100
doublereal size(size_t k) const
This routine returns the size of species k.
Definition: Phase.h:411
virtual void init()
size_t nTotalSpecies() const
The total number of species in all phases participating in the kinetics mechanism.
Definition: Kinetics.h:297
virtual void eval(size_t jg, doublereal *xg, doublereal *rg, integer *diagg, doublereal rdt)
Evaluate the residual function at point j.
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
Definition: Domain1D.cpp:108
virtual void eval(size_t jg, doublereal *xg, doublereal *rg, integer *diagg, doublereal rdt)
Evaluate the residual function at point j.
virtual XML_Node & save(XML_Node &o, const doublereal *const soln)
Save the current solution for this domain into an XML_Node.
virtual void init()
virtual XML_Node & save(XML_Node &o, const doublereal *const soln)
Save the current solution for this domain into an XML_Node.
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
Definition: xml.cpp:573
virtual XML_Node & save(XML_Node &o, const doublereal *const sol)
Save the current solution for this domain into an XML_Node.
Definition: Domain1D.cpp:95
virtual void getNetProductionRates(doublereal *wdot)
Species net production rates [kmol/m^3/s or kmol/m^2/s].
Definition: Kinetics.cpp:501
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
size_t nComponents() const
Number of components at each grid point.
Definition: Domain1D.h:164
virtual XML_Node & save(XML_Node &o, const doublereal *const soln)
Save the current solution for this domain into an XML_Node.
size_t speciesIndex(const std::string &name) const
Returns the index of a species named 'name' within the Phase object.
Definition: Phase.cpp:257
virtual void eval(size_t jg, doublereal *xg, doublereal *rg, integer *diagg, doublereal rdt)
Evaluate the residual function at point j.
Boundary objects for one-dimensional simulations.
size_t start(size_t i) const
The index of the start of domain i in the solution vector.
Definition: OneDim.h:77
size_t lastPoint() const
The index of the last (i.e., right-most) grid point belonging to this domain.
Definition: Domain1D.h:443
Domain1D & domain(size_t i) const
Return a reference to domain i.
Definition: OneDim.h:53
virtual void init()
virtual XML_Node & save(XML_Node &o, const doublereal *const soln)
Save the current solution for this domain into an XML_Node.
std::string name() const
Returns the name of the XML node.
Definition: xml.h:394
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
void setMoleFractionsByName(const compositionMap &xMap)
Set the species mole fractions by name.
Definition: Phase.cpp:376
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:99
virtual void setMoleFractions(const doublereal *const x)
Set the mole fractions to the specified values There is no restriction on the sum of the mole fractio...
Definition: Phase.cpp:331
virtual void resize(size_t nv, size_t np)
Definition: Domain1D.h:135
virtual XML_Node & save(XML_Node &o, const doublereal *const soln)
Save the current solution for this domain into an XML_Node.
virtual void setMoleFractions(const std::string &xin)
Set the mole fractions by specifying a std::string.
void addAttribute(const std::string &attrib, const std::string &value)
Add or modify an attribute of the current node.
Definition: xml.cpp:501
size_t kineticsSpeciesIndex(size_t k, size_t n) const
The location of species k of phase n in species arrays.
Definition: Kinetics.h:323
virtual void eval(size_t jg, doublereal *xg, doublereal *rg, integer *diagg, doublereal rdt)
Evaluate the residual function at point j.
virtual void init()
void setGas(const doublereal *x, size_t j)
Set the gas object state to be consistent with the solution at point j.
Definition: StFlow.cpp:184
Domain1D(size_t nv=1, size_t points=1, doublereal time=0.0)
Constructor.
Definition: Domain1D.h:46
const vector_fp & molecularWeights() const
Return a const reference to the internal vector of molecular weights.
Definition: Phase.cpp:515
void addFloat(XML_Node &node, const std::string &title, const doublereal val, const std::string &units, const std::string &type, const doublereal minval, const doublereal maxval)
This function adds a child node with the name, "float", with a value consisting of a single floating ...
Definition: ctml.cpp:30
void setSteadyTolerances(doublereal rtol, doublereal atol, size_t n=npos)
Set tolerances for steady-state mode.
Definition: Domain1D.cpp:29
virtual void eval(size_t jg, doublereal *xg, doublereal *rg, integer *diagg, doublereal rdt)
Evaluate the residual function at point j.
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
virtual void setTemperature(const doublereal temp)
Set the internally stored temperature of the phase (K).
Definition: Phase.h:638
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
doublereal getFloat(const XML_Node &parent, const std::string &name, const std::string &type)
Get a floating-point value from a child element.
Definition: ctml.cpp:194
#define DATA_PTR(vec)
Creates a pointer to the start of the raw data for a vector.
Definition: ct_defs.h:36
virtual void init()
const OneDim & container() const
The container holding this domain.
Definition: Domain1D.h:83
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
void needJacUpdate()
Definition: Domain1D.cpp:42
doublereal fp_value() const
Return the value of an XML node as a single double.
Definition: xml.cpp:481
virtual XML_Node & save(XML_Node &o, const doublereal *const soln)
Save the current solution for this domain into an XML_Node.
double prevSoln(size_t n, size_t j) const
Value of component n at point j in the previous solution.
Definition: Domain1D.h:478
void setTransientTolerances(doublereal rtol, doublereal atol, size_t n=npos)
Set tolerances for time-stepping mode.
Definition: Domain1D.cpp:16
virtual void init()
std::string speciesName(size_t k) const
Name of the species with index k.
Definition: Phase.cpp:272
size_t nChildren(bool discardComments=false) const
Return the number of children.
Definition: xml.cpp:583
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
doublereal siteDensity()
Returns the site density.
Definition: SurfPhase.h:410