Cantera  2.4.0
StFlow.h
Go to the documentation of this file.
1 //! @file StFlow.h
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 #ifndef CT_STFLOW_H
7 #define CT_STFLOW_H
8 
9 #include "Domain1D.h"
10 #include "cantera/base/Array.h"
13 
14 namespace Cantera
15 {
16 
17 //------------------------------------------
18 // constants
19 //------------------------------------------
20 
21 // Offsets of solution components in the solution array.
22 const size_t c_offset_U = 0; // axial velocity
23 const size_t c_offset_V = 1; // strain rate
24 const size_t c_offset_T = 2; // temperature
25 const size_t c_offset_L = 3; // (1/r)dP/dr
26 const size_t c_offset_E = 4; // electric poisson's equation
27 const size_t c_offset_Y = 5; // mass fractions
28 
29 class Transport;
30 
31 /**
32  * This class represents 1D flow domains that satisfy the one-dimensional
33  * similarity solution for chemically-reacting, axisymmetric flows.
34  * @ingroup onedim
35  */
36 class StFlow : public Domain1D
37 {
38 public:
39  //--------------------------------
40  // construction and destruction
41  //--------------------------------
42 
43  //! Create a new flow domain.
44  //! @param ph Object representing the gas phase. This object will be used
45  //! to evaluate all thermodynamic, kinetic, and transport properties.
46  //! @param nsp Number of species.
47  //! @param points Initial number of grid points
48  StFlow(IdealGasPhase* ph = 0, size_t nsp = 1, size_t points = 1);
49 
50  //! @name Problem Specification
51  //! @{
52 
53  virtual void setupGrid(size_t n, const doublereal* z);
54 
55  virtual void resetBadValues(double* xg);
56 
57 
58  thermo_t& phase() {
59  return *m_thermo;
60  }
61  Kinetics& kinetics() {
62  return *m_kin;
63  }
64 
65  /**
66  * Set the thermo manager. Note that the flow equations assume
67  * the ideal gas equation.
68  */
70  m_thermo = &th;
71  }
72 
73  //! Set the kinetics manager. The kinetics manager must
74  void setKinetics(Kinetics& kin) {
75  m_kin = &kin;
76  }
77 
78  //! set the transport manager
79  void setTransport(Transport& trans);
80 
81  //! Enable thermal diffusion, also known as Soret diffusion.
82  //! Requires that multicomponent transport properties be
83  //! enabled to carry out calculations.
84  void enableSoret(bool withSoret) {
85  m_do_soret = withSoret;
86  }
87  bool withSoret() const {
88  return m_do_soret;
89  }
90 
91  //! Set the pressure. Since the flow equations are for the limit of small
92  //! Mach number, the pressure is very nearly constant throughout the flow.
93  void setPressure(doublereal p) {
94  m_press = p;
95  }
96 
97  //! The current pressure [Pa].
98  doublereal pressure() const {
99  return m_press;
100  }
101 
102  //! Write the initial solution estimate into array x.
103  virtual void _getInitialSoln(double* x);
104 
105  virtual void _finalize(const doublereal* x);
106 
107  //! Sometimes it is desired to carry out the simulation using a specified
108  //! temperature profile, rather than computing it by solving the energy
109  //! equation. This method specifies this profile.
110  void setFixedTempProfile(vector_fp& zfixed, vector_fp& tfixed) {
111  m_zfix = zfixed;
112  m_tfix = tfixed;
113  }
114 
115  /*!
116  * Set the temperature fixed point at grid point j, and disable the energy
117  * equation so that the solution will be held to this value.
118  */
119  void setTemperature(size_t j, doublereal t) {
120  m_fixedtemp[j] = t;
121  m_do_energy[j] = false;
122  }
123 
124  //! The fixed temperature value at point j.
125  doublereal T_fixed(size_t j) const {
126  return m_fixedtemp[j];
127  }
128 
129  // @}
130 
131  virtual std::string componentName(size_t n) const;
132 
133  virtual size_t componentIndex(const std::string& name) const;
134 
135  //! Print the solution.
136  virtual void showSolution(const doublereal* x);
137 
138  //! Save the current solution for this domain into an XML_Node
139  /*!
140  * @param o XML_Node to save the solution to.
141  * @param sol Current value of the solution vector. The object will pick
142  * out which part of the solution vector pertains to this
143  * object.
144  */
145  virtual XML_Node& save(XML_Node& o, const doublereal* const sol);
146 
147  virtual void restore(const XML_Node& dom, doublereal* soln,
148  int loglevel);
149 
150  //! Set flow configuration for freely-propagating flames, using an internal
151  //! point with a fixed temperature as the condition to determine the inlet
152  //! mass flux.
153  void setFreeFlow() {
154  m_type = cFreeFlow;
155  m_dovisc = false;
156  }
157 
158  //! Set flow configuration for axisymmetric counterflow or burner-stabilized
159  //! flames, using specified inlet mass fluxes.
161  m_type = cAxisymmetricStagnationFlow;
162  m_dovisc = true;
163  }
164 
165  //! Return the type of flow domain being represented, either "Free Flame" or
166  //! "Axisymmetric Stagnation".
167  //! @see setFreeFlow setAxisymmetricFlow
168  virtual std::string flowType() {
169  if (m_type == cFreeFlow) {
170  return "Free Flame";
171  } else if (m_type == cAxisymmetricStagnationFlow) {
172  return "Axisymmetric Stagnation";
173  } else {
174  throw CanteraError("StFlow::flowType", "Unknown value for 'm_type'");
175  }
176  }
177 
178  void solveEnergyEqn(size_t j=npos);
179 
180  //! Turn radiation on / off.
181  /*!
182  * The simple radiation model used was established by Y. Liu and B. Rogg
183  * [Y. Liu and B. Rogg, Modelling of thermally radiating diffusion flames
184  * with detailed chemistry and transport, EUROTHERM Seminars, 17:114-127,
185  * 1991]. This model considers the radiation of CO2 and H2O.
186  */
187  void enableRadiation(bool doRadiation) {
188  m_do_radiation = doRadiation;
189  }
190 
191  //! Returns `true` if the radiation term in the energy equation is enabled
192  bool radiationEnabled() const {
193  return m_do_radiation;
194  }
195 
196  //! Set the emissivities for the boundary values
197  /*!
198  * Reads the emissivities for the left and right boundary values in the
199  * radiative term and writes them into the variables, which are used for the
200  * calculation.
201  */
202  void setBoundaryEmissivities(doublereal e_left, doublereal e_right);
203 
204  void fixTemperature(size_t j=npos);
205 
206  bool doEnergy(size_t j) {
207  return m_do_energy[j];
208  }
209 
210  //! Change the grid size. Called after grid refinement.
211  virtual void resize(size_t components, size_t points);
212 
213  virtual void setFixedPoint(int j0, doublereal t0) {}
214 
215  //! Set the gas object state to be consistent with the solution at point j.
216  void setGas(const doublereal* x, size_t j);
217 
218  //! Set the gas state to be consistent with the solution at the midpoint
219  //! between j and j + 1.
220  void setGasAtMidpoint(const doublereal* x, size_t j);
221 
222  doublereal density(size_t j) const {
223  return m_rho[j];
224  }
225 
226  virtual bool fixed_mdot() {
227  return (domainType() != cFreeFlow);
228  }
229  void setViscosityFlag(bool dovisc) {
230  m_dovisc = dovisc;
231  }
232 
233  /*!
234  * Evaluate the residual function for axisymmetric stagnation flow. If
235  * j == npos, the residual function is evaluated at all grid points.
236  * Otherwise, the residual function is only evaluated at grid points
237  * j-1, j, and j+1. This option is used to efficiently evaluate the
238  * Jacobian numerically.
239  */
240  virtual void eval(size_t j, doublereal* x, doublereal* r,
241  integer* mask, doublereal rdt);
242 
243  //! Evaluate all residual components at the right boundary.
244  virtual void evalRightBoundary(double* x, double* res, int* diag,
245  double rdt);
246 
247  //! Evaluate the residual corresponding to the continuity equation at all
248  //! interior grid points.
249  virtual void evalContinuity(size_t j, double* x, double* r,
250  int* diag, double rdt);
251 
252  //! Index of the species on the left boundary with the largest mass fraction
253  size_t leftExcessSpecies() const {
254  return m_kExcessLeft;
255  }
256 
257  //! Index of the species on the right boundary with the largest mass fraction
258  size_t rightExcessSpecies() const {
259  return m_kExcessRight;
260  }
261 
262 protected:
263  doublereal wdot(size_t k, size_t j) const {
264  return m_wdot(k,j);
265  }
266 
267  //! Write the net production rates at point `j` into array `m_wdot`
268  void getWdot(doublereal* x, size_t j) {
269  setGas(x,j);
270  m_kin->getNetProductionRates(&m_wdot(0,j));
271  }
272 
273  //! Update the properties (thermo, transport, and diffusion flux).
274  //! This function is called in eval after the points which need
275  //! to be updated are defined.
276  virtual void updateProperties(size_t jg, double* x, size_t jmin, size_t jmax);
277 
278  //! Evaluate the residual function. This function is called in eval
279  //! after updateProperties is called.
280  virtual void evalResidual(double* x, double* rsd, int* diag,
281  double rdt, size_t jmin, size_t jmax);
282 
283  /**
284  * Update the thermodynamic properties from point j0 to point j1
285  * (inclusive), based on solution x.
286  */
287  void updateThermo(const doublereal* x, size_t j0, size_t j1) {
288  for (size_t j = j0; j <= j1; j++) {
289  setGas(x,j);
290  m_rho[j] = m_thermo->density();
291  m_wtm[j] = m_thermo->meanMolecularWeight();
292  m_cp[j] = m_thermo->cp_mass();
293  }
294  }
295 
296  //! @name Solution components
297  //! @{
298 
299  doublereal T(const doublereal* x, size_t j) const {
300  return x[index(c_offset_T, j)];
301  }
302  doublereal& T(doublereal* x, size_t j) {
303  return x[index(c_offset_T, j)];
304  }
305  doublereal T_prev(size_t j) const {
306  return prevSoln(c_offset_T, j);
307  }
308 
309  doublereal rho_u(const doublereal* x, size_t j) const {
310  return m_rho[j]*x[index(c_offset_U, j)];
311  }
312 
313  doublereal u(const doublereal* x, size_t j) const {
314  return x[index(c_offset_U, j)];
315  }
316 
317  doublereal V(const doublereal* x, size_t j) const {
318  return x[index(c_offset_V, j)];
319  }
320  doublereal V_prev(size_t j) const {
321  return prevSoln(c_offset_V, j);
322  }
323 
324  doublereal lambda(const doublereal* x, size_t j) const {
325  return x[index(c_offset_L, j)];
326  }
327 
328  doublereal Y(const doublereal* x, size_t k, size_t j) const {
329  return x[index(c_offset_Y + k, j)];
330  }
331 
332  doublereal& Y(doublereal* x, size_t k, size_t j) {
333  return x[index(c_offset_Y + k, j)];
334  }
335 
336  doublereal Y_prev(size_t k, size_t j) const {
337  return prevSoln(c_offset_Y + k, j);
338  }
339 
340  doublereal X(const doublereal* x, size_t k, size_t j) const {
341  return m_wtm[j]*Y(x,k,j)/m_wt[k];
342  }
343 
344  doublereal flux(size_t k, size_t j) const {
345  return m_flux(k, j);
346  }
347  //! @}
348 
349  //! @name convective spatial derivatives.
350  //! These use upwind differencing, assuming u(z) is negative
351  //! @{
352  doublereal dVdz(const doublereal* x, size_t j) const {
353  size_t jloc = (u(x,j) > 0.0 ? j : j + 1);
354  return (V(x,jloc) - V(x,jloc-1))/m_dz[jloc-1];
355  }
356 
357  doublereal dYdz(const doublereal* x, size_t k, size_t j) const {
358  size_t jloc = (u(x,j) > 0.0 ? j : j + 1);
359  return (Y(x,k,jloc) - Y(x,k,jloc-1))/m_dz[jloc-1];
360  }
361 
362  doublereal dTdz(const doublereal* x, size_t j) const {
363  size_t jloc = (u(x,j) > 0.0 ? j : j + 1);
364  return (T(x,jloc) - T(x,jloc-1))/m_dz[jloc-1];
365  }
366  //! @}
367 
368  doublereal shear(const doublereal* x, size_t j) const {
369  doublereal c1 = m_visc[j-1]*(V(x,j) - V(x,j-1));
370  doublereal c2 = m_visc[j]*(V(x,j+1) - V(x,j));
371  return 2.0*(c2/(z(j+1) - z(j)) - c1/(z(j) - z(j-1)))/(z(j+1) - z(j-1));
372  }
373 
374  doublereal divHeatFlux(const doublereal* x, size_t j) const {
375  doublereal c1 = m_tcon[j-1]*(T(x,j) - T(x,j-1));
376  doublereal c2 = m_tcon[j]*(T(x,j+1) - T(x,j));
377  return -2.0*(c2/(z(j+1) - z(j)) - c1/(z(j) - z(j-1)))/(z(j+1) - z(j-1));
378  }
379 
380  size_t mindex(size_t k, size_t j, size_t m) {
381  return m*m_nsp*m_nsp + m_nsp*j + k;
382  }
383 
384  //! Update the diffusive mass fluxes.
385  virtual void updateDiffFluxes(const doublereal* x, size_t j0, size_t j1);
386 
387  //---------------------------------------------------------
388  // member data
389  //---------------------------------------------------------
390 
391  doublereal m_press; // pressure
392 
393  // grid parameters
394  vector_fp m_dz;
395 
396  // mixture thermo properties
397  vector_fp m_rho;
398  vector_fp m_wtm;
399 
400  // species thermo properties
401  vector_fp m_wt;
402  vector_fp m_cp;
403 
404  // transport properties
405  vector_fp m_visc;
406  vector_fp m_tcon;
407  vector_fp m_diff;
408  vector_fp m_multidiff;
409  Array2D m_dthermal;
410  Array2D m_flux;
411 
412  // production rates
413  Array2D m_wdot;
414 
415  size_t m_nsp;
416 
417  IdealGasPhase* m_thermo;
418  Kinetics* m_kin;
419  Transport* m_trans;
420 
421  // boundary emissivities for the radiation calculations
422  doublereal m_epsilon_left;
423  doublereal m_epsilon_right;
424 
425  //! Indices within the ThermoPhase of the radiating species. First index is
426  //! for CO2, second is for H2O.
427  std::vector<size_t> m_kRadiating;
428 
429  // flags
430  std::vector<bool> m_do_energy;
431  bool m_do_soret;
432  std::vector<bool> m_do_species;
433  bool m_do_multicomponent;
434 
435  //! flag for the radiative heat loss
437 
438  //! radiative heat loss vector
440 
441  // fixed T and Y values
442  vector_fp m_fixedtemp;
443  vector_fp m_zfix;
444  vector_fp m_tfix;
445 
446  //! Index of species with a large mass fraction at each boundary, for which
447  //! the mass fraction may be calculated as 1 minus the sum of the other mass
448  //! fractions
450  size_t m_kExcessRight;
451 
452  bool m_dovisc;
453 
454  //! Update the transport properties at grid points in the range from `j0`
455  //! to `j1`, based on solution `x`.
456  virtual void updateTransport(doublereal* x, size_t j0, size_t j1);
457 
458 public:
459  //! Location of the point where temperature is fixed
460  double m_zfixed;
461 
462  //! Temperature at the point used to fix the flame location
463  double m_tfixed;
464 
465 private:
466  vector_fp m_ybar;
467 };
468 
469 /**
470  * A class for axisymmetric stagnation flows.
471  *
472  * @deprecated To be removed after Cantera 2.4. Use class StFlow with the
473  * StFlow::setAxisymmetricFlow() method instead.
474  *
475  * @ingroup onedim
476  */
477 class AxiStagnFlow : public StFlow
478 {
479 public:
480  AxiStagnFlow(IdealGasPhase* ph = 0, size_t nsp = 1, size_t points = 1) :
481  StFlow(ph, nsp, points) {
482  m_dovisc = true;
483  m_type = cAxisymmetricStagnationFlow;
484  warn_deprecated("Class AxiStagnFlow is deprecated",
485  "Use StFlow with setAxisymmetricFlow() instead. To be removed after Cantera 2.4.");
486  }
487 };
488 
489 /**
490  * A class for freely-propagating premixed flames.
491  *
492  * @deprecated To be removed after Cantera 2.4. Use class StFlow with the
493  * StFlow::setFreeFlow() method instead.
494  *
495  * @ingroup onedim
496  */
497 class FreeFlame : public StFlow
498 {
499 public:
500  FreeFlame(IdealGasPhase* ph = 0, size_t nsp = 1, size_t points = 1) :
501  StFlow(ph, nsp, points) {
502  m_dovisc = false;
503  m_type = cFreeFlow;
504  warn_deprecated("Class FreeFlame is deprecated",
505  "Use StFlow with setFreeFlow() instead. To be removed after Cantera 2.4.");
506  }
507 };
508 
509 }
510 
511 #endif
virtual std::string componentName(size_t n) const
Name of the nth component. May be overloaded.
Definition: StFlow.cpp:573
void setKinetics(Kinetics &kin)
Set the kinetics manager. The kinetics manager must.
Definition: StFlow.h:74
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
bool m_do_radiation
flag for the radiative heat loss
Definition: StFlow.h:436
size_t leftExcessSpecies() const
Index of the species on the left boundary with the largest mass fraction.
Definition: StFlow.h:253
This class represents 1D flow domains that satisfy the one-dimensional similarity solution for chemic...
Definition: StFlow.h:36
doublereal pressure() const
The current pressure [Pa].
Definition: StFlow.h:98
void setAxisymmetricFlow()
Set flow configuration for axisymmetric counterflow or burner-stabilized flames, using specified inle...
Definition: StFlow.h:160
doublereal cp_mass() const
Specific heat at constant pressure. Units: J/kg/K.
Definition: ThermoPhase.h:734
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
A class for axisymmetric stagnation flows.
Definition: StFlow.h:477
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
virtual void evalRightBoundary(double *x, double *res, int *diag, double rdt)
Evaluate all residual components at the right boundary.
Definition: StFlow.cpp:908
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.
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:54
void setPressure(doublereal p)
Set the pressure.
Definition: StFlow.h:93
virtual doublereal density() const
Density (kg/m^3).
Definition: Phase.h:607
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
A class for freely-propagating premixed flames.
Definition: StFlow.h:497
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
virtual void getNetProductionRates(doublereal *wdot)
Species net production rates [kmol/m^3/s or kmol/m^2/s].
Definition: Kinetics.cpp:418
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:93
Header file for class Cantera::Array2D.
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
void setFreeFlow()
Set flow configuration for freely-propagating flames, using an internal point with a fixed temperatur...
Definition: StFlow.h:153
vector_fp m_qdotRadiation
radiative heat loss vector
Definition: StFlow.h:439
ThermoPhase object for the ideal gas equation of state - workhorse for Cantera (see Thermodynamic Pro...
void setThermo(IdealGasPhase &th)
Set the thermo manager.
Definition: StFlow.h:69
bool radiationEnabled() const
Returns true if the radiation term in the energy equation is enabled.
Definition: StFlow.h:192
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
Public interface for kinetics managers.
Definition: Kinetics.h:110
virtual void resetBadValues(double *xg)
Definition: StFlow.cpp:136
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:65
Base class for kinetics managers and also contains the kineticsmgr module documentation (see Kinetics...
void setTemperature(size_t j, doublereal t)
Definition: StFlow.h:119
std::vector< size_t > m_kRadiating
Indices within the ThermoPhase of the radiating species.
Definition: StFlow.h:427
void getWdot(doublereal *x, size_t j)
Write the net production rates at point j into array m_wdot
Definition: StFlow.h:268
int domainType()
Domain type flag.
Definition: Domain1D.h:54
double prevSoln(size_t n, size_t j) const
Value of component n at point j in the previous solution.
Definition: Domain1D.h:404
virtual std::string flowType()
Return the type of flow domain being represented, either "Free Flame" or "Axisymmetric Stagnation"...
Definition: StFlow.h:168
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
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 setupGrid(size_t n, const doublereal *z)
called to set up initial grid, and after grid refinement
Definition: StFlow.cpp:121
void enableRadiation(bool doRadiation)
Turn radiation on / off.
Definition: StFlow.h:187
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 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
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 _getInitialSoln(double *x)
Write the initial solution estimate into array x.
Definition: StFlow.cpp:158
void enableSoret(bool withSoret)
Enable thermal diffusion, also known as Soret diffusion.
Definition: StFlow.h:84
virtual void resize(size_t components, size_t points)
Change the grid size. Called after grid refinement.
Definition: StFlow.cpp:97
StFlow(IdealGasPhase *ph=0, size_t nsp=1, size_t points=1)
Create a new flow domain.
Definition: StFlow.cpp:16
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:8
double m_zfixed
Location of the point where temperature is fixed.
Definition: StFlow.h:460
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
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