Cantera  2.3.0
StFlow.cpp
Go to the documentation of this file.
1 //! @file StFlow.cpp
2 
3 // This file is part of Cantera. See License.txt in the top-level directory or
4 // at http://www.cantera.org/license.txt for license and copyright information.
5 
6 #include "cantera/oneD/StFlow.h"
7 #include "cantera/base/ctml.h"
10 
11 using namespace std;
12 
13 namespace Cantera
14 {
15 
16 StFlow::StFlow(IdealGasPhase* ph, size_t nsp, size_t points) :
17  Domain1D(nsp+c_offset_Y, points),
18  m_press(-1.0),
19  m_nsp(nsp),
20  m_thermo(0),
21  m_kin(0),
22  m_trans(0),
23  m_epsilon_left(0.0),
24  m_epsilon_right(0.0),
25  m_do_soret(false),
26  m_do_multicomponent(false),
27  m_do_radiation(false),
28  m_kExcessLeft(0),
29  m_kExcessRight(0)
30 {
31  m_type = cFlowType;
32  m_points = points;
33  m_thermo = ph;
34 
35  if (ph == 0) {
36  return; // used to create a dummy object
37  }
38 
39  size_t nsp2 = m_thermo->nSpecies();
40  if (nsp2 != m_nsp) {
41  m_nsp = nsp2;
42  Domain1D::resize(m_nsp+c_offset_Y, points);
43  }
44 
45  // make a local copy of the species molecular weight vector
46  m_wt = m_thermo->molecularWeights();
47 
48  // the species mass fractions are the last components in the solution
49  // vector, so the total number of components is the number of species
50  // plus the offset of the first mass fraction.
51  m_nv = c_offset_Y + m_nsp;
52 
53  // enable all species equations by default
54  m_do_species.resize(m_nsp, true);
55 
56  // but turn off the energy equation at all points
57  m_do_energy.resize(m_points,false);
58 
59  m_diff.resize(m_nsp*m_points);
60  m_multidiff.resize(m_nsp*m_nsp*m_points);
61  m_flux.resize(m_nsp,m_points);
62  m_wdot.resize(m_nsp,m_points, 0.0);
63  m_ybar.resize(m_nsp);
64  m_qdotRadiation.resize(m_points, 0.0);
65 
66  //-------------- default solution bounds --------------------
67  setBounds(0, -1e20, 1e20); // no bounds on u
68  setBounds(1, -1e20, 1e20); // V
69  setBounds(2, 200.0, 1e9); // temperature bounds
70  setBounds(3, -1e20, 1e20); // lambda should be negative
71 
72  // mass fraction bounds
73  for (size_t k = 0; k < m_nsp; k++) {
74  setBounds(c_offset_Y+k, -1.0e-7, 1.0e5);
75  }
76 
77  //-------------------- grid refinement -------------------------
78  m_refiner->setActive(0, false);
79  m_refiner->setActive(1, false);
80  m_refiner->setActive(2, false);
81  m_refiner->setActive(3, false);
82 
83  vector_fp gr;
84  for (size_t ng = 0; ng < m_points; ng++) {
85  gr.push_back(1.0*ng/m_points);
86  }
87  setupGrid(m_points, gr.data());
88  setID("stagnation flow");
89 
90  // Find indices for radiating species
91  m_kRadiating.resize(2, npos);
92  m_kRadiating[0] = m_thermo->speciesIndex("CO2");
93  m_kRadiating[1] = m_thermo->speciesIndex("H2O");
94 }
95 
96 void StFlow::resize(size_t ncomponents, size_t points)
97 {
98  Domain1D::resize(ncomponents, points);
99  m_rho.resize(m_points, 0.0);
100  m_wtm.resize(m_points, 0.0);
101  m_cp.resize(m_points, 0.0);
102  m_visc.resize(m_points, 0.0);
103  m_tcon.resize(m_points, 0.0);
104 
105  m_diff.resize(m_nsp*m_points);
106  if (m_do_multicomponent) {
107  m_multidiff.resize(m_nsp*m_nsp*m_points);
108  m_dthermal.resize(m_nsp, m_points, 0.0);
109  }
110  m_flux.resize(m_nsp,m_points);
111  m_wdot.resize(m_nsp,m_points, 0.0);
112  m_do_energy.resize(m_points,false);
113  m_qdotRadiation.resize(m_points, 0.0);
114  m_fixedtemp.resize(m_points);
115 
116  m_dz.resize(m_points-1);
117  m_z.resize(m_points);
118 }
119 
120 void StFlow::setupGrid(size_t n, const doublereal* z)
121 {
122  resize(m_nv, n);
123 
124  m_z[0] = z[0];
125  for (size_t j = 1; j < m_points; j++) {
126  if (z[j] <= z[j-1]) {
127  throw CanteraError("StFlow::setupGrid",
128  "grid points must be monotonically increasing");
129  }
130  m_z[j] = z[j];
131  m_dz[j-1] = m_z[j] - m_z[j-1];
132  }
133 }
134 
135 void StFlow::resetBadValues(double* xg) {
136  double* x = xg + loc();
137  for (size_t j = 0; j < m_points; j++) {
138  double* Y = x + m_nv*j + c_offset_Y;
139  m_thermo->setMassFractions(Y);
140  m_thermo->getMassFractions(Y);
141  }
142 }
143 
144 void StFlow::setTransport(Transport& trans, bool withSoret)
145 {
146  m_trans = &trans;
147  m_do_soret = withSoret;
148  m_do_multicomponent = (m_trans->transportType() == "Multi");
149 
150  m_diff.resize(m_nsp*m_points);
151  if (m_do_multicomponent) {
152  m_multidiff.resize(m_nsp*m_nsp*m_points);
153  m_dthermal.resize(m_nsp, m_points, 0.0);
154  } else if (withSoret) {
155  throw CanteraError("setTransport",
156  "Thermal diffusion (the Soret effect) "
157  "requires using a multicomponent transport model.");
158  }
159 
160  warn_deprecated("setTransport(Transport& trans, bool withSoret = false)",
161  "The withSoret argument is deprecated and unused. Use "
162  "the form of setTransport with signature setTransport(Transport& trans)."
163  "To be removed after Cantera 2.3.");
164 }
165 
167 {
168  m_trans = &trans;
169  m_do_multicomponent = (m_trans->transportType() == "Multi");
170 
171  m_diff.resize(m_nsp*m_points);
172  if (m_do_multicomponent) {
173  m_multidiff.resize(m_nsp*m_nsp*m_points);
174  m_dthermal.resize(m_nsp, m_points, 0.0);
175  }
176 }
177 
178 void StFlow::enableSoret(bool withSoret)
179 {
180  if (m_do_multicomponent) {
181  m_do_soret = withSoret;
182  } else {
183  throw CanteraError("setTransport",
184  "Thermal diffusion (the Soret effect) "
185  "requires using a multicomponent transport model.");
186  }
187 }
188 
189 void StFlow::_getInitialSoln(double* x)
190 {
191  for (size_t j = 0; j < m_points; j++) {
192  T(x,j) = m_thermo->temperature();
193  m_thermo->getMassFractions(&Y(x, 0, j));
194  }
195 }
196 
197 void StFlow::setGas(const doublereal* x, size_t j)
198 {
199  m_thermo->setTemperature(T(x,j));
200  const doublereal* yy = x + m_nv*j + c_offset_Y;
201  m_thermo->setMassFractions_NoNorm(yy);
202  m_thermo->setPressure(m_press);
203 }
204 
205 void StFlow::setGasAtMidpoint(const doublereal* x, size_t j)
206 {
207  m_thermo->setTemperature(0.5*(T(x,j)+T(x,j+1)));
208  const doublereal* yyj = x + m_nv*j + c_offset_Y;
209  const doublereal* yyjp = x + m_nv*(j+1) + c_offset_Y;
210  for (size_t k = 0; k < m_nsp; k++) {
211  m_ybar[k] = 0.5*(yyj[k] + yyjp[k]);
212  }
213  m_thermo->setMassFractions_NoNorm(m_ybar.data());
214  m_thermo->setPressure(m_press);
215 }
216 
217 void StFlow::_finalize(const doublereal* x)
218 {
219  size_t nz = m_zfix.size();
220  bool e = m_do_energy[0];
221  for (size_t j = 0; j < m_points; j++) {
222  if (e || nz == 0) {
223  m_fixedtemp[j] = T(x, j);
224  } else {
225  double zz = (z(j) - z(0))/(z(m_points - 1) - z(0));
226  double tt = linearInterp(zz, m_zfix, m_tfix);
227  m_fixedtemp[j] = tt;
228  }
229  }
230  if (e) {
231  solveEnergyEqn();
232  }
233 }
234 
235 void StFlow::eval(size_t jg, doublereal* xg,
236  doublereal* rg, integer* diagg, doublereal rdt)
237 {
238  // if evaluating a Jacobian, and the global point is outside the domain of
239  // influence for this domain, then skip evaluating the residual
240  if (jg != npos && (jg + 1 < firstPoint() || jg > lastPoint() + 1)) {
241  return;
242  }
243 
244  // if evaluating a Jacobian, compute the steady-state residual
245  if (jg != npos) {
246  rdt = 0.0;
247  }
248 
249  // start of local part of global arrays
250  doublereal* x = xg + loc();
251  doublereal* rsd = rg + loc();
252  integer* diag = diagg + loc();
253 
254  size_t jmin, jmax;
255  if (jg == npos) { // evaluate all points
256  jmin = 0;
257  jmax = m_points - 1;
258  } else { // evaluate points for Jacobian
259  size_t jpt = (jg == 0) ? 0 : jg - firstPoint();
260  jmin = std::max<size_t>(jpt, 1) - 1;
261  jmax = std::min(jpt+1,m_points-1);
262  }
263 
264  // properties are computed for grid points from j0 to j1
265  size_t j0 = std::max<size_t>(jmin, 1) - 1;
266  size_t j1 = std::min(jmax+1,m_points-1);
267 
268  // ------------ update properties ------------
269 
270  updateThermo(x, j0, j1);
271  if (jg == npos || m_force_full_update) {
272  // update transport properties only if a Jacobian is not being
273  // evaluated, or if specifically requested
274  updateTransport(x, j0, j1);
275  }
276  if (jg == npos) {
277  double* Yleft = x + index(c_offset_Y, jmin);
278  m_kExcessLeft = distance(Yleft, max_element(Yleft, Yleft + m_nsp));
279  double* Yright = x + index(c_offset_Y, jmax);
280  m_kExcessRight = distance(Yright, max_element(Yright, Yright + m_nsp));
281  }
282 
283  // update the species diffusive mass fluxes whether or not a
284  // Jacobian is being evaluated
285  updateDiffFluxes(x, j0, j1);
286 
287  //----------------------------------------------------
288  // evaluate the residual equations at all required
289  // grid points
290  //----------------------------------------------------
291 
292  // calculation of qdotRadiation
293 
294  // The simple radiation model used was established by Y. Liu and B. Rogg [Y.
295  // Liu and B. Rogg, Modelling of thermally radiating diffusion flames with
296  // detailed chemistry and transport, EUROTHERM Seminars, 17:114-127, 1991].
297  // This model uses the optically thin limit and the gray-gas approximation
298  // to simply calculate a volume specified heat flux out of the Planck
299  // absorption coefficients, the boundary emissivities and the temperature.
300  // The model considers only CO2 and H2O as radiating species. Polynomial
301  // lines calculate the species Planck coefficients for H2O and CO2. The data
302  // for the lines is taken from the RADCAL program [Grosshandler, W. L.,
303  // RADCAL: A Narrow-Band Model for Radiation Calculations in a Combustion
304  // Environment, NIST technical note 1402, 1993]. The coefficients for the
305  // polynomials are taken from [http://www.sandia.gov/TNF/radiation.html].
306 
307  if (m_do_radiation) {
308  // variable definitions for the Planck absorption coefficient and the
309  // radiation calculation:
310  doublereal k_P_ref = 1.0*OneAtm;
311 
312  // polynomial coefficients:
313  const doublereal c_H2O[6] = {-0.23093, -1.12390, 9.41530, -2.99880,
314  0.51382, -1.86840e-5};
315  const doublereal c_CO2[6] = {18.741, -121.310, 273.500, -194.050,
316  56.310, -5.8169};
317 
318  // calculation of the two boundary values
319  double boundary_Rad_left = m_epsilon_left * StefanBoltz * pow(T(x, 0), 4);
320  double boundary_Rad_right = m_epsilon_right * StefanBoltz * pow(T(x, m_points - 1), 4);
321 
322  // loop over all grid points
323  for (size_t j = jmin; j < jmax; j++) {
324  // helping variable for the calculation
325  double radiative_heat_loss = 0;
326 
327  // calculation of the mean Planck absorption coefficient
328  double k_P = 0;
329  // absorption coefficient for H2O
330  if (m_kRadiating[1] != npos) {
331  double k_P_H2O = 0;
332  for (size_t n = 0; n <= 5; n++) {
333  k_P_H2O += c_H2O[n] * pow(1000 / T(x, j), (double) n);
334  }
335  k_P_H2O /= k_P_ref;
336  k_P += m_press * X(x, m_kRadiating[1], j) * k_P_H2O;
337  }
338  // absorption coefficient for CO2
339  if (m_kRadiating[0] != npos) {
340  double k_P_CO2 = 0;
341  for (size_t n = 0; n <= 5; n++) {
342  k_P_CO2 += c_CO2[n] * pow(1000 / T(x, j), (double) n);
343  }
344  k_P_CO2 /= k_P_ref;
345  k_P += m_press * X(x, m_kRadiating[0], j) * k_P_CO2;
346  }
347 
348  // calculation of the radiative heat loss term
349  radiative_heat_loss = 2 * k_P *(2 * StefanBoltz * pow(T(x, j), 4)
350  - boundary_Rad_left - boundary_Rad_right);
351 
352  // set the radiative heat loss vector
353  m_qdotRadiation[j] = radiative_heat_loss;
354  }
355  }
356 
357  for (size_t j = jmin; j <= jmax; j++) {
358  //----------------------------------------------
359  // left boundary
360  //----------------------------------------------
361 
362  if (j == 0) {
363  // these may be modified by a boundary object
364 
365  // Continuity. This propagates information right-to-left, since
366  // rho_u at point 0 is dependent on rho_u at point 1, but not on
367  // mdot from the inlet.
368  rsd[index(c_offset_U,0)] =
369  -(rho_u(x,1) - rho_u(x,0))/m_dz[0]
370  -(density(1)*V(x,1) + density(0)*V(x,0));
371 
372  // the inlet (or other) object connected to this one will modify
373  // these equations by subtracting its values for V, T, and mdot. As
374  // a result, these residual equations will force the solution
375  // variables to the values for the boundary object
376  rsd[index(c_offset_V,0)] = V(x,0);
377  rsd[index(c_offset_T,0)] = T(x,0);
378  rsd[index(c_offset_L,0)] = -rho_u(x,0);
379 
380  // The default boundary condition for species is zero flux. However,
381  // the boundary object may modify this.
382  double sum = 0.0;
383  for (size_t k = 0; k < m_nsp; k++) {
384  sum += Y(x,k,0);
385  rsd[index(c_offset_Y + k, 0)] =
386  -(m_flux(k,0) + rho_u(x,0)* Y(x,k,0));
387  }
388  rsd[index(c_offset_Y + leftExcessSpecies(), 0)] = 1.0 - sum;
389  } else if (j == m_points - 1) {
390  evalRightBoundary(x, rsd, diag, rdt);
391  } else { // interior points
392  evalContinuity(j, x, rsd, diag, rdt);
393 
394  //------------------------------------------------
395  // Radial momentum equation
396  //
397  // \rho dV/dt + \rho u dV/dz + \rho V^2
398  // = d(\mu dV/dz)/dz - lambda
399  //-------------------------------------------------
400  rsd[index(c_offset_V,j)]
401  = (shear(x,j) - lambda(x,j) - rho_u(x,j)*dVdz(x,j)
402  - m_rho[j]*V(x,j)*V(x,j))/m_rho[j]
403  - rdt*(V(x,j) - V_prev(j));
404  diag[index(c_offset_V, j)] = 1;
405 
406  //-------------------------------------------------
407  // Species equations
408  //
409  // \rho dY_k/dt + \rho u dY_k/dz + dJ_k/dz
410  // = M_k\omega_k
411  //-------------------------------------------------
412  getWdot(x,j);
413  for (size_t k = 0; k < m_nsp; k++) {
414  double convec = rho_u(x,j)*dYdz(x,k,j);
415  double diffus = 2.0*(m_flux(k,j) - m_flux(k,j-1))
416  / (z(j+1) - z(j-1));
417  rsd[index(c_offset_Y + k, j)]
418  = (m_wt[k]*(wdot(k,j))
419  - convec - diffus)/m_rho[j]
420  - rdt*(Y(x,k,j) - Y_prev(k,j));
421  diag[index(c_offset_Y + k, j)] = 1;
422  }
423 
424  //-----------------------------------------------
425  // energy equation
426  //
427  // \rho c_p dT/dt + \rho c_p u dT/dz
428  // = d(k dT/dz)/dz
429  // - sum_k(\omega_k h_k_ref)
430  // - sum_k(J_k c_p_k / M_k) dT/dz
431  //-----------------------------------------------
432  if (m_do_energy[j]) {
433  setGas(x,j);
434 
435  // heat release term
436  const vector_fp& h_RT = m_thermo->enthalpy_RT_ref();
437  const vector_fp& cp_R = m_thermo->cp_R_ref();
438  double sum = 0.0;
439  double sum2 = 0.0;
440  for (size_t k = 0; k < m_nsp; k++) {
441  double flxk = 0.5*(m_flux(k,j-1) + m_flux(k,j));
442  sum += wdot(k,j)*h_RT[k];
443  sum2 += flxk*cp_R[k]/m_wt[k];
444  }
445  sum *= GasConstant * T(x,j);
446  double dtdzj = dTdz(x,j);
447  sum2 *= GasConstant * dtdzj;
448 
449  rsd[index(c_offset_T, j)] = - m_cp[j]*rho_u(x,j)*dtdzj
450  - divHeatFlux(x,j) - sum - sum2;
451  rsd[index(c_offset_T, j)] /= (m_rho[j]*m_cp[j]);
452  rsd[index(c_offset_T, j)] -= rdt*(T(x,j) - T_prev(j));
453  rsd[index(c_offset_T, j)] -= (m_qdotRadiation[j] / (m_rho[j] * m_cp[j]));
454  diag[index(c_offset_T, j)] = 1;
455  } else {
456  // residual equations if the energy equation is disabled
457  rsd[index(c_offset_T, j)] = T(x,j) - T_fixed(j);
458  diag[index(c_offset_T, j)] = 0;
459  }
460 
461  rsd[index(c_offset_L, j)] = lambda(x,j) - lambda(x,j-1);
462  diag[index(c_offset_L, j)] = 0;
463  }
464  }
465 }
466 
467 void StFlow::updateTransport(doublereal* x, size_t j0, size_t j1)
468 {
469  if (m_do_multicomponent) {
470  for (size_t j = j0; j < j1; j++) {
471  setGasAtMidpoint(x,j);
472  doublereal wtm = m_thermo->meanMolecularWeight();
473  doublereal rho = m_thermo->density();
474  m_visc[j] = (m_dovisc ? m_trans->viscosity() : 0.0);
475  m_trans->getMultiDiffCoeffs(m_nsp, &m_multidiff[mindex(0,0,j)]);
476 
477  // Use m_diff as storage for the factor outside the summation
478  for (size_t k = 0; k < m_nsp; k++) {
479  m_diff[k+j*m_nsp] = m_wt[k] * rho / (wtm*wtm);
480  }
481 
482  m_tcon[j] = m_trans->thermalConductivity();
483  if (m_do_soret) {
484  m_trans->getThermalDiffCoeffs(m_dthermal.ptrColumn(0) + j*m_nsp);
485  }
486  }
487  } else { // mixture averaged transport
488  for (size_t j = j0; j < j1; j++) {
489  setGasAtMidpoint(x,j);
490  m_visc[j] = (m_dovisc ? m_trans->viscosity() : 0.0);
491  m_trans->getMixDiffCoeffs(&m_diff[j*m_nsp]);
492  m_tcon[j] = m_trans->thermalConductivity();
493  }
494  }
495 }
496 
497 void StFlow::showSolution(const doublereal* x)
498 {
499  writelog(" Pressure: {:10.4g} Pa\n", m_press);
500 
502 
503  if (m_do_radiation) {
504  writeline('-', 79, false, true);
505  writelog("\n z radiative heat loss");
506  writeline('-', 79, false, true);
507  for (size_t j = 0; j < m_points; j++) {
508  writelog("\n {:10.4g} {:10.4g}", m_z[j], m_qdotRadiation[j]);
509  }
510  writelog("\n");
511  }
512 }
513 
514 void StFlow::updateDiffFluxes(const doublereal* x, size_t j0, size_t j1)
515 {
516  if (m_do_multicomponent) {
517  for (size_t j = j0; j < j1; j++) {
518  double dz = z(j+1) - z(j);
519  for (size_t k = 0; k < m_nsp; k++) {
520  doublereal sum = 0.0;
521  for (size_t m = 0; m < m_nsp; m++) {
522  sum += m_wt[m] * m_multidiff[mindex(k,m,j)] * (X(x,m,j+1)-X(x,m,j));
523  }
524  m_flux(k,j) = sum * m_diff[k+j*m_nsp] / dz;
525  }
526  }
527  } else {
528  for (size_t j = j0; j < j1; j++) {
529  double sum = 0.0;
530  double wtm = m_wtm[j];
531  double rho = density(j);
532  double dz = z(j+1) - z(j);
533  for (size_t k = 0; k < m_nsp; k++) {
534  m_flux(k,j) = m_wt[k]*(rho*m_diff[k+m_nsp*j]/wtm);
535  m_flux(k,j) *= (X(x,k,j) - X(x,k,j+1))/dz;
536  sum -= m_flux(k,j);
537  }
538  // correction flux to insure that \sum_k Y_k V_k = 0.
539  for (size_t k = 0; k < m_nsp; k++) {
540  m_flux(k,j) += sum*Y(x,k,j);
541  }
542  }
543  }
544 
545  if (m_do_soret) {
546  for (size_t m = j0; m < j1; m++) {
547  double gradlogT = 2.0 * (T(x,m+1) - T(x,m)) /
548  ((T(x,m+1) + T(x,m)) * (z(m+1) - z(m)));
549  for (size_t k = 0; k < m_nsp; k++) {
550  m_flux(k,m) -= m_dthermal(k,m)*gradlogT;
551  }
552  }
553  }
554 }
555 
556 string StFlow::componentName(size_t n) const
557 {
558  switch (n) {
559  case 0:
560  return "u";
561  case 1:
562  return "V";
563  case 2:
564  return "T";
565  case 3:
566  return "lambda";
567  default:
568  if (n >= c_offset_Y && n < (c_offset_Y + m_nsp)) {
569  return m_thermo->speciesName(n - c_offset_Y);
570  } else {
571  return "<unknown>";
572  }
573  }
574 }
575 
576 size_t StFlow::componentIndex(const std::string& name) const
577 {
578  if (name=="u") {
579  return 0;
580  } else if (name=="V") {
581  return 1;
582  } else if (name=="T") {
583  return 2;
584  } else if (name=="lambda") {
585  return 3;
586  } else {
587  for (size_t n=c_offset_Y; n<m_nsp+c_offset_Y; n++) {
588  if (componentName(n)==name) {
589  return n;
590  }
591  }
592  }
593  return npos;
594 }
595 
596 void StFlow::restore(const XML_Node& dom, doublereal* soln, int loglevel)
597 {
598  Domain1D::restore(dom, soln, loglevel);
599  vector<string> ignored;
600  size_t nsp = m_thermo->nSpecies();
601  vector_int did_species(nsp, 0);
602 
603  vector<XML_Node*> str = dom.getChildren("string");
604  for (size_t istr = 0; istr < str.size(); istr++) {
605  const XML_Node& nd = *str[istr];
606  writelog(nd["title"]+": "+nd.value()+"\n");
607  }
608 
609  double pp = getFloat(dom, "pressure", "pressure");
610  setPressure(pp);
611  vector<XML_Node*> d = dom.child("grid_data").getChildren("floatArray");
612  vector_fp x;
613  size_t np = 0;
614  bool readgrid = false, wrote_header = false;
615  for (size_t n = 0; n < d.size(); n++) {
616  const XML_Node& fa = *d[n];
617  string nm = fa["title"];
618  if (nm == "z") {
619  getFloatArray(fa,x,false);
620  np = x.size();
621  if (loglevel >= 2) {
622  writelog("Grid contains {} points.\n", np);
623  }
624  readgrid = true;
625  setupGrid(np, x.data());
626  }
627  }
628  if (!readgrid) {
629  throw CanteraError("StFlow::restore",
630  "domain contains no grid points.");
631  }
632 
633  debuglog("Importing datasets:\n", loglevel >= 2);
634  for (size_t n = 0; n < d.size(); n++) {
635  const XML_Node& fa = *d[n];
636  string nm = fa["title"];
637  getFloatArray(fa,x,false);
638  if (nm == "u") {
639  debuglog("axial velocity ", loglevel >= 2);
640  if (x.size() != np) {
641  throw CanteraError("StFlow::restore",
642  "axial velocity array size error");
643  }
644  for (size_t j = 0; j < np; j++) {
645  soln[index(0,j)] = x[j];
646  }
647  } else if (nm == "z") {
648  ; // already read grid
649  } else if (nm == "V") {
650  debuglog("radial velocity ", loglevel >= 2);
651  if (x.size() != np) {
652  throw CanteraError("StFlow::restore",
653  "radial velocity array size error");
654  }
655  for (size_t j = 0; j < np; j++) {
656  soln[index(1,j)] = x[j];
657  }
658  } else if (nm == "T") {
659  debuglog("temperature ", loglevel >= 2);
660  if (x.size() != np) {
661  throw CanteraError("StFlow::restore",
662  "temperature array size error");
663  }
664  for (size_t j = 0; j < np; j++) {
665  soln[index(2,j)] = x[j];
666  }
667 
668  // For fixed-temperature simulations, use the imported temperature
669  // profile by default. If this is not desired, call
670  // setFixedTempProfile *after* restoring the solution.
671  vector_fp zz(np);
672  for (size_t jj = 0; jj < np; jj++) {
673  zz[jj] = (grid(jj) - zmin())/(zmax() - zmin());
674  }
675  setFixedTempProfile(zz, x);
676  } else if (nm == "L") {
677  debuglog("lambda ", loglevel >= 2);
678  if (x.size() != np) {
679  throw CanteraError("StFlow::restore",
680  "lambda arary size error");
681  }
682  for (size_t j = 0; j < np; j++) {
683  soln[index(3,j)] = x[j];
684  }
685  } else if (m_thermo->speciesIndex(nm) != npos) {
686  debuglog(nm+" ", loglevel >= 2);
687  if (x.size() == np) {
688  size_t k = m_thermo->speciesIndex(nm);
689  did_species[k] = 1;
690  for (size_t j = 0; j < np; j++) {
691  soln[index(k+c_offset_Y,j)] = x[j];
692  }
693  }
694  } else {
695  ignored.push_back(nm);
696  }
697  }
698 
699  if (loglevel >=2 && !ignored.empty()) {
700  writelog("\n\n");
701  writelog("Ignoring datasets:\n");
702  size_t nn = ignored.size();
703  for (size_t n = 0; n < nn; n++) {
704  writelog(ignored[n]+" ");
705  }
706  }
707 
708  if (loglevel >= 1) {
709  for (size_t ks = 0; ks < nsp; ks++) {
710  if (did_species[ks] == 0) {
711  if (!wrote_header) {
712  writelog("Missing data for species:\n");
713  wrote_header = true;
714  }
715  writelog(m_thermo->speciesName(ks)+" ");
716  }
717  }
718  }
719 
720  if (dom.hasChild("energy_enabled")) {
721  getFloatArray(dom, x, false, "", "energy_enabled");
722  if (x.size() == nPoints()) {
723  for (size_t i = 0; i < x.size(); i++) {
724  m_do_energy[i] = (x[i] != 0);
725  }
726  } else if (!x.empty()) {
727  throw CanteraError("StFlow::restore", "energy_enabled is length {}"
728  "but should be length {}", x.size(), nPoints());
729  }
730  }
731 
732  if (dom.hasChild("species_enabled")) {
733  getFloatArray(dom, x, false, "", "species_enabled");
734  if (x.size() == m_nsp) {
735  for (size_t i = 0; i < x.size(); i++) {
736  m_do_species[i] = (x[i] != 0);
737  }
738  } else if (!x.empty()) {
739  // This may occur when restoring from a mechanism with a different
740  // number of species.
741  if (loglevel > 0) {
742  writelog("\nWarning: StFlow::restore: species_enabled is "
743  "length {} but should be length {}. Enabling all species "
744  "equations by default.", x.size(), m_nsp);
745  }
746  m_do_species.assign(m_nsp, true);
747  }
748  }
749 
750  if (dom.hasChild("refine_criteria")) {
751  XML_Node& ref = dom.child("refine_criteria");
752  refiner().setCriteria(getFloat(ref, "ratio"), getFloat(ref, "slope"),
753  getFloat(ref, "curve"), getFloat(ref, "prune"));
754  refiner().setGridMin(getFloat(ref, "grid_min"));
755  }
756 }
757 
758 XML_Node& StFlow::save(XML_Node& o, const doublereal* const sol)
759 {
760  Array2D soln(m_nv, m_points, sol + loc());
761  XML_Node& flow = Domain1D::save(o, sol);
762  flow.addAttribute("type",flowType());
763 
764  if (m_desc != "") {
765  addString(flow,"description",m_desc);
766  }
767  XML_Node& gv = flow.addChild("grid_data");
768  addFloat(flow, "pressure", m_press, "Pa", "pressure");
769 
770  addFloatArray(gv,"z",m_z.size(), m_z.data(),
771  "m","length");
772  vector_fp x(soln.nColumns());
773 
774  soln.getRow(0, x.data());
775  addFloatArray(gv,"u",x.size(),x.data(),"m/s","velocity");
776 
777  soln.getRow(1, x.data());
778  addFloatArray(gv,"V",x.size(),x.data(),"1/s","rate");
779 
780  soln.getRow(2, x.data());
781  addFloatArray(gv,"T",x.size(),x.data(),"K","temperature");
782 
783  soln.getRow(3, x.data());
784  addFloatArray(gv,"L",x.size(),x.data(),"N/m^4");
785 
786  for (size_t k = 0; k < m_nsp; k++) {
787  soln.getRow(c_offset_Y+k, x.data());
788  addFloatArray(gv,m_thermo->speciesName(k),
789  x.size(),x.data(),"","massFraction");
790  }
791  if (m_do_radiation) {
792  addFloatArray(gv, "radiative_heat_loss", m_z.size(),
793  m_qdotRadiation.data(), "W/m^3", "specificPower");
794  }
795  vector_fp values(nPoints());
796  for (size_t i = 0; i < nPoints(); i++) {
797  values[i] = m_do_energy[i];
798  }
799  addNamedFloatArray(flow, "energy_enabled", nPoints(), &values[0]);
800 
801  values.resize(m_nsp);
802  for (size_t i = 0; i < m_nsp; i++) {
803  values[i] = m_do_species[i];
804  }
805  addNamedFloatArray(flow, "species_enabled", m_nsp, &values[0]);
806 
807  XML_Node& ref = flow.addChild("refine_criteria");
808  addFloat(ref, "ratio", refiner().maxRatio());
809  addFloat(ref, "slope", refiner().maxDelta());
810  addFloat(ref, "curve", refiner().maxSlope());
811  addFloat(ref, "prune", refiner().prune());
812  addFloat(ref, "grid_min", refiner().gridMin());
813  return flow;
814 }
815 
816 void StFlow::solveEnergyEqn(size_t j)
817 {
818  bool changed = false;
819  if (j == npos) {
820  for (size_t i = 0; i < m_points; i++) {
821  if (!m_do_energy[i]) {
822  changed = true;
823  }
824  m_do_energy[i] = true;
825  }
826  } else {
827  if (!m_do_energy[j]) {
828  changed = true;
829  }
830  m_do_energy[j] = true;
831  }
832  m_refiner->setActive(0, true);
833  m_refiner->setActive(1, true);
834  m_refiner->setActive(2, true);
835  if (changed) {
836  needJacUpdate();
837  }
838 }
839 
840 void StFlow::setBoundaryEmissivities(doublereal e_left, doublereal e_right)
841 {
842  if (e_left < 0 || e_left > 1) {
843  throw CanteraError("setBoundaryEmissivities",
844  "The left boundary emissivity must be between 0.0 and 1.0!");
845  } else if (e_right < 0 || e_right > 1) {
846  throw CanteraError("setBoundaryEmissivities",
847  "The right boundary emissivity must be between 0.0 and 1.0!");
848  } else {
849  m_epsilon_left = e_left;
850  m_epsilon_right = e_right;
851  }
852 }
853 
854 void StFlow::fixTemperature(size_t j)
855 {
856  bool changed = false;
857  if (j == npos) {
858  for (size_t i = 0; i < m_points; i++) {
859  if (m_do_energy[i]) {
860  changed = true;
861  }
862  m_do_energy[i] = false;
863  }
864  } else {
865  if (m_do_energy[j]) {
866  changed = true;
867  }
868  m_do_energy[j] = false;
869  }
870  m_refiner->setActive(0, false);
871  m_refiner->setActive(1, false);
872  m_refiner->setActive(2, false);
873  if (changed) {
874  needJacUpdate();
875  }
876 }
877 
878 void AxiStagnFlow::evalRightBoundary(doublereal* x, doublereal* rsd,
879  integer* diag, doublereal rdt)
880 {
881  size_t j = m_points - 1;
882  // the boundary object connected to the right of this one may modify or
883  // replace these equations. The default boundary conditions are zero u, V,
884  // and T, and zero diffusive flux for all species.
885  rsd[index(0,j)] = rho_u(x,j);
886  rsd[index(1,j)] = V(x,j);
887  rsd[index(2,j)] = T(x,j);
888  rsd[index(c_offset_L, j)] = lambda(x,j) - lambda(x,j-1);
889  diag[index(c_offset_L, j)] = 0;
890  doublereal sum = 0.0;
891  for (size_t k = 0; k < m_nsp; k++) {
892  sum += Y(x,k,j);
893  rsd[index(k+c_offset_Y,j)] = m_flux(k,j-1) + rho_u(x,j)*Y(x,k,j);
894  }
895  rsd[index(c_offset_Y + rightExcessSpecies(), j)] = 1.0 - sum;
896  diag[index(c_offset_Y + rightExcessSpecies(), j)] = 0;
897 }
898 
899 void AxiStagnFlow::evalContinuity(size_t j, doublereal* x, doublereal* rsd,
900  integer* diag, doublereal rdt)
901 {
902  //----------------------------------------------
903  // Continuity equation
904  //
905  // Note that this propagates the mass flow rate information to the left
906  // (j+1 -> j) from the value specified at the right boundary. The
907  // lambda information propagates in the opposite direction.
908  //
909  // d(\rho u)/dz + 2\rho V = 0
910  //------------------------------------------------
911  rsd[index(c_offset_U,j)] =
912  -(rho_u(x,j+1) - rho_u(x,j))/m_dz[j]
913  -(density(j+1)*V(x,j+1) + density(j)*V(x,j));
914 
915  //algebraic constraint
916  diag[index(c_offset_U, j)] = 0;
917 }
918 
919 FreeFlame::FreeFlame(IdealGasPhase* ph, size_t nsp, size_t points) :
920  StFlow(ph, nsp, points),
921  m_zfixed(Undef),
922  m_tfixed(Undef)
923 {
924  m_dovisc = false;
925  setID("flame");
926 }
927 
928 void FreeFlame::evalRightBoundary(doublereal* x, doublereal* rsd,
929  integer* diag, doublereal rdt)
930 {
931  size_t j = m_points - 1;
932 
933  // the boundary object connected to the right of this one may modify or
934  // replace these equations. The default boundary conditions are zero u, V,
935  // and T, and zero diffusive flux for all species.
936 
937  // zero gradient
938  rsd[index(0,j)] = rho_u(x,j) - rho_u(x,j-1);
939  rsd[index(1,j)] = V(x,j);
940  rsd[index(2,j)] = T(x,j) - T(x,j-1);
941  doublereal sum = 0.0;
942  rsd[index(c_offset_L, j)] = lambda(x,j) - lambda(x,j-1);
943  diag[index(c_offset_L, j)] = 0;
944  for (size_t k = 0; k < m_nsp; k++) {
945  sum += Y(x,k,j);
946  rsd[index(k+c_offset_Y,j)] = m_flux(k,j-1) + rho_u(x,j)*Y(x,k,j);
947  }
948  rsd[index(c_offset_Y + rightExcessSpecies(), j)] = 1.0 - sum;
949  diag[index(c_offset_Y + rightExcessSpecies(), j)] = 0;
950 }
951 
952 void FreeFlame::evalContinuity(size_t j, doublereal* x, doublereal* rsd,
953  integer* diag, doublereal rdt)
954 {
955  //----------------------------------------------
956  // Continuity equation
957  //
958  // d(\rho u)/dz + 2\rho V = 0
959  //----------------------------------------------
960  if (grid(j) > m_zfixed) {
961  rsd[index(c_offset_U,j)] =
962  - (rho_u(x,j) - rho_u(x,j-1))/m_dz[j-1]
963  - (density(j-1)*V(x,j-1) + density(j)*V(x,j));
964  } else if (grid(j) == m_zfixed) {
965  if (m_do_energy[j]) {
966  rsd[index(c_offset_U,j)] = (T(x,j) - m_tfixed);
967  } else {
968  rsd[index(c_offset_U,j)] = (rho_u(x,j)
969  - m_rho[0]*0.3);
970  }
971  } else if (grid(j) < m_zfixed) {
972  rsd[index(c_offset_U,j)] =
973  - (rho_u(x,j+1) - rho_u(x,j))/m_dz[j]
974  - (density(j+1)*V(x,j+1) + density(j)*V(x,j));
975  }
976  //algebraic constraint
977  diag[index(c_offset_U, j)] = 0;
978 }
979 
980 void FreeFlame::_finalize(const doublereal* x)
981 {
983  // If the domain contains the temperature fixed point, make sure that it
984  // is correctly set. This may be necessary when the grid has been modified
985  // externally.
986  if (m_tfixed != Undef) {
987  for (size_t j = 0; j < m_points; j++) {
988  if (z(j) == m_zfixed) {
989  return; // fixed point is already set correctly
990  }
991  }
992 
993  for (size_t j = 0; j < m_points - 1; j++) {
994  // Find where the temperature profile crosses the current
995  // fixed temperature.
996  if ((T(x, j) - m_tfixed) * (T(x, j+1) - m_tfixed) <= 0.0) {
997  m_tfixed = T(x, j+1);
998  m_zfixed = z(j+1);
999  return;
1000  }
1001  }
1002  }
1003 }
1004 
1005 void FreeFlame::restore(const XML_Node& dom, doublereal* soln, int loglevel)
1006 {
1007  StFlow::restore(dom, soln, loglevel);
1008  getOptionalFloat(dom, "t_fixed", m_tfixed);
1009  getOptionalFloat(dom, "z_fixed", m_zfixed);
1010 }
1011 
1012 XML_Node& FreeFlame::save(XML_Node& o, const doublereal* const sol)
1013 {
1014  XML_Node& flow = StFlow::save(o, sol);
1015  if (m_zfixed != Undef) {
1016  addFloat(flow, "z_fixed", m_zfixed, "m");
1017  addFloat(flow, "t_fixed", m_tfixed, "K");
1018  }
1019  return flow;
1020 }
1021 
1022 } // namespace
void addFloatArray(XML_Node &node, const std::string &title, const size_t n, const doublereal *const vals, const std::string &units, const std::string &type, const doublereal minval, const doublereal maxval)
This function adds a child node with the name, "floatArray", with a value consisting of a comma separ...
Definition: ctml.cpp:54
const vector_fp & molecularWeights() const
Return a const reference to the internal vector of molecular weights.
Definition: Phase.cpp:513
std::vector< XML_Node * > getChildren(const std::string &name) const
Get a vector of pointers to XML_Node containing all of the children of the current node which match t...
Definition: xml.cpp:864
size_t getFloatArray(const XML_Node &node, vector_fp &v, const bool convert, const std::string &unitsString, const std::string &nodeName)
This function reads the current node or a child node of the current node with the default name...
Definition: ctml.cpp:299
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
Definition: StFlow.cpp:556
virtual void _finalize(const doublereal *x)
In some cases, a domain may need to set parameters that depend on the initial solution estimate...
Definition: StFlow.cpp:980
void updateThermo(const doublereal *x, size_t j0, size_t j1)
Update the thermodynamic properties from point j0 to point j1 (inclusive), based on solution x...
Definition: StFlow.h:256
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
virtual void evalRightBoundary(doublereal *x, doublereal *res, integer *diag, doublereal rdt)=0
Evaluate all residual components at the right boundary.
bool m_do_radiation
flag for the radiative heat loss
Definition: StFlow.h:405
void getMassFractions(doublereal *const y) const
Get the species mass fractions.
Definition: Phase.cpp:584
const doublereal StefanBoltz
Stefan-Boltzmann constant.
Definition: ct_defs.h:85
const doublereal OneAtm
One atmosphere [Pa].
Definition: ct_defs.h:69
size_t leftExcessSpecies() const
Index of the species on the left boundary with the largest mass fraction.
Definition: StFlow.h:232
This class represents 1D flow domains that satisfy the one-dimensional similarity solution for chemic...
Definition: StFlow.h:35
doublereal temperature() const
Temperature (K).
Definition: Phase.h:601
void resize(size_t n, size_t m, doublereal v=0.0)
Resize the array, and fill the new entries with &#39;v&#39;.
Definition: Array.h:112
void addNamedFloatArray(XML_Node &node, const std::string &name, const size_t n, const doublereal *const vals, const std::string units, const std::string type, const doublereal minval, const doublereal maxval)
This function adds a child node with the name given by the first parameter with a value consisting of...
Definition: ctml.cpp:87
size_t speciesIndex(const std::string &name) const
Returns the index of a species named &#39;name&#39; within the Phase object.
Definition: Phase.cpp:251
virtual void evalRightBoundary(doublereal *x, doublereal *res, integer *diag, doublereal rdt)
Evaluate all residual components at the right boundary.
Definition: StFlow.cpp:928
Class IdealGasPhase represents low-density gases that obey the ideal gas equation of state...
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:165
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
Definition: StFlow.cpp:1005
virtual void _finalize(const doublereal *x)
In some cases, a domain may need to set parameters that depend on the initial solution estimate...
Definition: StFlow.cpp:217
size_t firstPoint() const
The index of the first (i.e., left-most) grid point belonging to this domain.
Definition: Domain1D.h:411
virtual void evalContinuity(size_t j, doublereal *x, doublereal *r, integer *diag, doublereal rdt)
Evaluate the residual corresponding to the continuity equation at all interior grid points...
Definition: StFlow.cpp:899
void addString(XML_Node &node, const std::string &titleString, const std::string &valueString, const std::string &typeString)
This function adds a child node with the name string with a string value to the current node...
Definition: ctml.cpp:125
Headers for the Transport object, which is the virtual base class for all transport property evaluato...
void writelog(const std::string &fmt, const Args &... args)
Write a formatted message to the screen.
Definition: global.h:179
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:97
virtual XML_Node & save(XML_Node &o, const doublereal *const sol)
Save the current solution for this domain into an XML_Node.
Definition: StFlow.cpp:1012
Base class for transport property managers.
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:54
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:262
void setPressure(doublereal p)
Set the pressure.
Definition: StFlow.h:95
STL namespace.
virtual doublereal density() const
Density (kg/m^3).
Definition: Phase.h:607
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
Definition: Domain1D.cpp:173
doublereal * ptrColumn(size_t j)
Return a pointer to the top of column j, columns are contiguous in memory.
Definition: Array.h:314
virtual void evalContinuity(size_t j, doublereal *x, doublereal *r, integer *diag, doublereal rdt)=0
Evaluate the residual corresponding to the continuity equation at all interior grid points...
const vector_fp & cp_R_ref() const
Returns a reference to the dimensionless reference state Heat Capacity vector.
const doublereal Undef
Fairly random number to be used to initialize variables against to see if they are subsequently defin...
Definition: ct_defs.h:134
A class for 2D arrays stored in column-major (Fortran-compatible) form.
Definition: Array.h:31
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:160
doublereal m_tfixed
Temperature at the point used to fix the flame location.
Definition: StFlow.h:481
virtual void restore(const XML_Node &dom, doublereal *soln, int loglevel)
Restore the solution for this domain from an XML_Node.
Definition: StFlow.cpp:596
std::vector< int > vector_int
Vector of ints.
Definition: ct_defs.h:159
Base class for one-dimensional domains.
Definition: Domain1D.h:36
size_t lastPoint() const
The index of the last (i.e., right-most) grid point belonging to this domain.
Definition: Domain1D.h:419
virtual void resize(size_t nv, size_t np)
Definition: Domain1D.cpp:34
void setCriteria(doublereal ratio=10.0, doublereal slope=0.8, doublereal curve=0.8, doublereal prune=-0.1)
Set grid refinement criteria.
Definition: refine.cpp:23
void setID(const std::string &s)
Specify an identifying tag for this domain.
Definition: Domain1D.h:459
vector_fp m_qdotRadiation
radiative heat loss vector
Definition: StFlow.h:408
virtual void evalRightBoundary(doublereal *x, doublereal *res, integer *diag, doublereal rdt)
Evaluate all residual components at the right boundary.
Definition: StFlow.cpp:878
std::string speciesName(size_t k) const
Name of the species with index k.
Definition: Phase.cpp:267
void setFixedTempProfile(vector_fp &zfixed, vector_fp &tfixed)
Sometimes it is desired to carry out the simulation using a specified temperature profile...
Definition: StFlow.h:112
void setTransport(Transport &trans)
set the transport manager
Definition: StFlow.cpp:166
virtual void showSolution(const doublereal *x)
Print the solution.
Definition: Domain1D.cpp:244
virtual void resetBadValues(double *xg)
Definition: StFlow.cpp:135
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:65
std::string value() const
Return the value of an XML node as a string.
Definition: xml.cpp:449
virtual doublereal thermalConductivity()
Returns the mixture thermal conductivity in W/m/K.
virtual doublereal viscosity()
std::vector< size_t > m_kRadiating
Indices within the ThermoPhase of the radiating species.
Definition: StFlow.h:396
doublereal m_zfixed
Location of the point where temperature is fixed.
Definition: StFlow.h:478
void setGridMin(double gridmin)
Set the minimum allowable spacing between adjacent grid points [m].
Definition: refine.h:54
void addAttribute(const std::string &attrib, const std::string &value)
Add or modify an attribute of the current node.
Definition: xml.cpp:474
Refiner & refiner()
Return a reference to the grid refiner.
Definition: Domain1D.h:125
void getWdot(doublereal *x, size_t j)
Write the net production rates at point j into array m_wdot
Definition: StFlow.h:247
virtual void setMassFractions_NoNorm(const doublereal *const y)
Set the mass fractions to the specified values without normalizing.
Definition: Phase.cpp:401
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:536
void debuglog(const std::string &msg, int loglevel)
Write a message to the log only if loglevel > 0.
Definition: global.h:161
XML_Node & child(const size_t n) const
Return a changeable reference to the n&#39;th child of the current node.
Definition: xml.cpp:546
virtual void evalContinuity(size_t j, doublereal *x, doublereal *r, integer *diag, doublereal rdt)
Evaluate the residual corresponding to the continuity equation at all interior grid points...
Definition: StFlow.cpp:952
virtual void getMultiDiffCoeffs(const size_t ld, doublereal *const d)
Return the Multicomponent diffusion coefficients. Units: [m^2/s].
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:197
virtual void showSolution(const doublereal *x)
Print the solution.
Definition: StFlow.cpp:497
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:33
void updateTransport(doublereal *x, size_t j0, size_t j1)
Update the transport properties at grid points in the range from j0 to j1, based on solution x...
Definition: StFlow.cpp:467
virtual void getMixDiffCoeffs(doublereal *const d)
Returns a vector of mixture averaged diffusion coefficients.
virtual void setupGrid(size_t n, const doublereal *z)
called to set up initial grid, and after grid refinement
Definition: StFlow.cpp:120
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:157
void setGasAtMidpoint(const doublereal *x, size_t j)
Set the gas state to be consistent with the solution at the midpoint between j and j + 1...
Definition: StFlow.cpp:205
doublereal meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
Definition: Phase.h:661
virtual void setTemperature(const doublereal temp)
Set the internally stored temperature of the phase (K).
Definition: Phase.h:637
const vector_fp & enthalpy_RT_ref() const
Returns a reference to the dimensionless reference state enthalpy vector.
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Definition: ct_defs.h:64
virtual std::string transportType() const
Identifies the Transport object type.
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:178
void updateDiffFluxes(const doublereal *x, size_t j0, size_t j1)
Update the diffusive mass fluxes.
Definition: StFlow.cpp:514
doublereal T_fixed(size_t j) const
The fixed temperature value at point j.
Definition: StFlow.h:127
size_t rightExcessSpecies() const
Index of the species on the right boundary with the largest mass fraction.
Definition: StFlow.h:237
virtual void setMassFractions(const doublereal *const y)
Set the mass fractions to the specified values and normalize them.
Definition: Phase.cpp:387
size_t m_kExcessLeft
Index of species with a large mass fraction at each boundary, for which the mass fraction may be calc...
Definition: StFlow.h:418
virtual void getThermalDiffCoeffs(doublereal *const dt)
Return a vector of Thermal diffusion coefficients [kg/m/sec].
virtual void _getInitialSoln(double *x)
Write the initial solution estimate into array x.
Definition: StFlow.cpp:189
void getRow(size_t n, doublereal *const rw)
Get the nth row and return it in a vector.
Definition: Array.h:165
void needJacUpdate()
Definition: Domain1D.cpp:104
void resize(size_t components, size_t points)
Change the grid size. Called after grid refinement.
Definition: StFlow.cpp:96
size_t nPoints() const
Number of grid points in this domain.
Definition: Domain1D.h:152
Namespace for the Cantera kernel.
Definition: application.cpp:29
Header for a file containing miscellaneous numerical functions.
void setBoundaryEmissivities(doublereal e_left, doublereal e_right)
Set the emissivities for the boundary values.
Definition: StFlow.cpp:840
virtual void eval(size_t j, doublereal *x, doublereal *r, integer *mask, doublereal rdt)
Definition: StFlow.cpp:235
size_t nColumns() const
Number of columns.
Definition: Array.h:274
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:403
doublereal linearInterp(doublereal x, const vector_fp &xpts, const vector_fp &fpts)
Linearly interpolate a function defined on a discrete grid.
Definition: funcs.cpp:13
virtual XML_Node & save(XML_Node &o, const doublereal *const sol)
Save the current solution for this domain into an XML_Node.
Definition: StFlow.cpp:758
virtual void setPressure(doublereal p)
Set the pressure at constant temperature and composition.
bool getOptionalFloat(const XML_Node &parent, const std::string &name, doublereal &fltRtn, const std::string &type)
Get an optional floating-point value from a child element.
Definition: ctml.cpp:226