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