Cantera  2.0
SimpleThermo.h
Go to the documentation of this file.
1 /**
2  * @file SimpleThermo.h
3  * Header for the SimpleThermo (constant heat capacity) species reference-state model
4  * for multiple species in a phase, derived from the
7  */
8 #ifndef CT_SIMPLETHERMO_H
9 #define CT_SIMPLETHERMO_H
10
11 #include "SpeciesThermoMgr.h"
12 #include "speciesThermoTypes.h"
13
14 namespace Cantera
15 {
16
17 /*!
18  * A constant-heat capacity species thermodynamic property manager class.
19  * This makes the
20  * assumption that the heat capacity is a constant. Then, the following
21  * relations are used to complete the specification of the thermodynamic
22  * functions for each species in the phase.
23  *
24  * \f[
25  * \frac{c_p(T)}{R} = Cp0\_R
26  * \f]
27  * \f[
28  * \frac{h^0(T)}{RT} = \frac{1}{T} * (h0\_R + (T - T_0) * Cp0\_R)
29  * \f]
30  * \f[
31  * \frac{s^0(T)}{R} = (s0\_R + (log(T) - log(T_0)) * Cp0\_R)
32  * \f]
33  *
34  * This parameterization takes 4 input values. These are:
35  * - c[0] = \f$T_0 \f$(Kelvin)
36  * - c[1] = \f$H_k^o(T_0, p_{ref}) \f$ (J/kmol)
37  * - c[2] = \f$S_k^o(T_0, p_{ref}) \f$ (J/kmol K)
38  * - c[3] = \f${Cp}_k^o(T_0, p_{ref}) \f$ (J(kmol K)
39  *
40  * All species must have the same reference pressure.
41  * The single-species standard-state property Manager ConstCpPoly has the same
42  * parameterization as the SimpleThermo class does.
43  *
44  * @see ConstCpPoly
45  *
46  * @ingroup mgrsrefcalc
47  */
49 {
50
51 public:
52
53  //! Initialized to the type of parameterization
54  /*!A
55  * Note, this value is used in some template functions. For this object the
56  * value is SIMPLE.
57  */
58  const int ID;
59
60  //! Constructor
62  ID(SIMPLE),
63  m_tlow_max(0.0),
64  m_thigh_min(1.e30),
65  m_p0(-1.0),
66  m_nspData(0) {}
67
68  //! Destructor
69  virtual ~SimpleThermo() {}
70
71  //! Copy constructor
72  /*!
73  * @param right Object to be copied
74  */
75  SimpleThermo(const SimpleThermo& right) :
76  ID(SIMPLE),
77  m_tlow_max(0.0),
78  m_thigh_min(1.e30),
79  m_p0(-1.0),
80  m_nspData(0) {
81  /*
82  * Call the assignment operator
83  */
84  *this = operator=(right);
85  }
86
87  //! Assignment operator
88  /*!
89  * @param right Object to be copied
90  */
92  /*
93  * Check for self assignment.
94  */
95  if (this == &right) {
96  return *this;
97  }
98
99  m_loc = right.m_loc;
100  m_index = right.m_index;
101  m_tlow_max = right.m_tlow_max;
102  m_thigh_min = right.m_thigh_min;
103  m_tlow = right.m_tlow;
104  m_thigh = right.m_thigh;
105  m_t0 = right.m_t0;
106  m_logt0 = right.m_logt0;
107  m_h0_R = right.m_h0_R;
108  m_s0_R = right.m_s0_R;
109  m_cp0_R = right.m_cp0_R;
110  m_p0 = right.m_p0;
111  m_nspData = right.m_nspData;
112
113  return *this;
114  }
115
116  //! Duplication routine for objects which inherit from
117  //! %SpeciesThermo
118  /*!
119  * This virtual routine can be used to duplicate %SpeciesThermo objects
120  * inherited from %SpeciesThermo even if the application only has
121  * a pointer to %SpeciesThermo to work with.
122  * ->commented out because we first need to add copy constructors
123  * and assignment operators to all of the derived classes.
124  */
126  SimpleThermo* nt = new SimpleThermo(*this);
127  return (SpeciesThermo*) nt;
128  }
129
130  //! Install a new species thermodynamic property
131  //! parameterization for one species.
132  /*!
133  *
134  * @param name String name of the species
135  * @param index Species index, k
136  * @param type int flag specifying the type of parameterization to be
137  * installed.
138  * @param c Vector of coefficients for the parameterization.
139  * There are 4 coefficients. The values (and units) are the following
140  * - c[0] = \f$T_0 \f$(Kelvin)
141  * - c[1] = \f$H_k^o(T_0, p_{ref}) \f$ (J/kmol)
142  * - c[2] = \f$S_k^o(T_0, p_{ref}) \f$ (J/kmol K)
143  * - c[3] = \f${Cp}_k^o(T_0, p_{ref}) \f$ (J(kmol K)
144  *
145  * @param minTemp minimum temperature for which this parameterization
146  * is valid.
147  * @param maxTemp maximum temperature for which this parameterization
148  * is valid.
149  * @param refPressure standard-state pressure for this
150  * parameterization.
151  *
152  * @see ConstCpPoly
153  */
154  virtual void install(std::string name, size_t index, int type, const doublereal* c,
155  doublereal minTemp, doublereal maxTemp, doublereal refPressure) {
156
157  m_logt0.push_back(log(c[0]));
158  m_t0.push_back(c[0]);
159  m_h0_R.push_back(c[1]/GasConstant);
160  m_s0_R.push_back(c[2]/GasConstant);
161  m_cp0_R.push_back(c[3]/GasConstant);
162  m_index.push_back(index);
163  m_loc[index] = m_nspData;
164  m_nspData++;
165  doublereal tlow = minTemp;
166  doublereal thigh = maxTemp;
167
168  if (tlow > m_tlow_max) {
169  m_tlow_max = tlow;
170  }
171  if (thigh < m_thigh_min) {
172  m_thigh_min = thigh;
173  }
174
175  if (m_tlow.size() < index + 1) {
176  m_tlow.resize(index + 1, tlow);
177  m_thigh.resize(index + 1, thigh);
178  }
179  m_tlow[index] = tlow;
180  m_thigh[index] = thigh;
181
182  if (m_p0 < 0.0) {
183  m_p0 = refPressure;
184  } else if (fabs(m_p0 - refPressure) > 0.1) {
185  std::string logmsg = " WARNING SimpleThermo: New Species, " + name +
186  ", has a different reference pressure, "
187  + fp2str(refPressure) + ", than existing reference pressure, " + fp2str(m_p0) + "\n";
188  writelog(logmsg);
189  logmsg = " This is now a fatal error\n";
190  writelog(logmsg);
191  throw CanteraError("install()", "Species have different reference pressures");
192  }
193  m_p0 = refPressure;
194  }
195
196  //! Install a new species thermodynamic property
197  //! parameterization for one species.
198  /*!
199  * @param stit_ptr Pointer to the SpeciesThermoInterpType object
200  * This will set up the thermo for one species
201  */
202  virtual void install_STIT(SpeciesThermoInterpType* stit_ptr) {
203  throw CanteraError("install_STIT", "not implemented");
204  }
205
206  //! Compute the reference-state properties for all species.
207  /*!
208  * Given temperature T in K, this method updates the values of
209  * the non-dimensional heat capacity at constant pressure,
210  * enthalpy, and entropy, at the reference pressure, Pref
211  * of each of the standard states.
212  *
213  * @param t Temperature (Kelvin)
214  * @param cp_R Vector of Dimensionless heat capacities.
215  * (length m_kk).
216  * @param h_RT Vector of Dimensionless enthalpies.
217  * (length m_kk).
218  * @param s_R Vector of Dimensionless entropies.
219  * (length m_kk).
220  */
221  virtual void update(doublereal t, doublereal* cp_R,
222  doublereal* h_RT, doublereal* s_R) const {
223  size_t k, ki;
224  doublereal logt = log(t);
225  doublereal rt = 1.0/t;
226  for (k = 0; k < m_nspData; k++) {
227  ki = m_index[k];
228  cp_R[ki] = m_cp0_R[k];
229  h_RT[ki] = rt*(m_h0_R[k] + (t - m_t0[k]) * m_cp0_R[k]);
230  s_R[ki] = m_s0_R[k] + m_cp0_R[k] * (logt - m_logt0[k]);
231  }
232  }
233
234  //! Like update(), but only updates the single species k.
235  /*!
236  * @param k species index
237  * @param t Temperature (Kelvin)
238  * @param cp_R Vector of Dimensionless heat capacities.
239  * (length m_kk).
240  * @param h_RT Vector of Dimensionless enthalpies.
241  * (length m_kk).
242  * @param s_R Vector of Dimensionless entropies.
243  * (length m_kk).
244  */
245  virtual void update_one(size_t k, doublereal t, doublereal* cp_R,
246  doublereal* h_RT, doublereal* s_R) const {
247  doublereal logt = log(t);
248  doublereal rt = 1.0/t;
249  size_t loc = m_loc[k];
250  cp_R[k] = m_cp0_R[loc];
251  h_RT[k] = rt*(m_h0_R[loc] + (t - m_t0[loc]) * m_cp0_R[loc]);
252  s_R[k] = m_s0_R[loc] + m_cp0_R[loc] * (logt - m_logt0[loc]);
253  }
254
255  //! Minimum temperature.
256  /*!
257  * If no argument is supplied, this
258  * method returns the minimum temperature for which \e all
259  * parameterizations are valid. If an integer index k is
260  * supplied, then the value returned is the minimum
261  * temperature for species k in the phase.
262  *
263  * @param k Species index
264  */
265  virtual doublereal minTemp(size_t k=npos) const {
266  if (k == npos) {
267  return m_tlow_max;
268  } else {
269  return m_tlow[m_loc[k]];
270  }
271  }
272
273  //! Maximum temperature.
274  /*!
275  * If no argument is supplied, this
276  * method returns the maximum temperature for which \e all
277  * parameterizations are valid. If an integer index k is
278  * supplied, then the value returned is the maximum
279  * temperature for parameterization k.
280  *
281  * @param k Species Index
282  */
283  virtual doublereal maxTemp(size_t k=npos) const {
284  if (k == npos) {
285  return m_thigh_min;
286  } else {
287  return m_thigh[m_loc[k]];
288  }
289  }
290
291  //! The reference-state pressure for species k.
292  /*!
293  *
294  * returns the reference state pressure in Pascals for
295  * species k. If k is left out of the argument list,
296  * it returns the reference state pressure for the first
297  * species.
298  * Note that some SpeciesThermo implementations, such
299  * as those for ideal gases, require that all species
300  * in the same phase have the same reference state pressures.
301  *
302  * @param k Species Index
303  */
304  virtual doublereal refPressure(size_t k=npos) const {
305  return m_p0;
306  }
307
308  //! This utility function reports the type of parameterization
309  //! used for the species with index number index.
310  /*!
311  *
312  * @param index Species index
313  */
314  virtual int reportType(size_t index) const {
315  return SIMPLE;
316  }
317
318  /*!
319  * This utility function reports back the type of
320  * parameterization and all of the parameters for the
321  * species, index.
322  *
323  * @param index Species index
324  * @param type Integer type of the standard type
325  * @param c Vector of coefficients used to set the
326  * parameters for the standard state.
327  * For the SimpleThermo object, there are 4 coefficients.
328  * @param minTemp output - Minimum temperature
329  * @param maxTemp output - Maximum temperature
330  * @param refPressure output - reference pressure (Pa).
331  *
332  */
333  virtual void reportParams(size_t index, int& type,
334  doublereal* const c,
335  doublereal& minTemp,
336  doublereal& maxTemp,
337  doublereal& refPressure) const {
338  type = reportType(index);
339  size_t loc = m_loc[index];
340  if (type == SIMPLE) {
341  c[0] = m_t0[loc];
342  c[1] = m_h0_R[loc] * GasConstant;
343  c[2] = m_s0_R[loc] * GasConstant;
344  c[3] = m_cp0_R[loc] * GasConstant;
345  minTemp = m_tlow[loc];
346  maxTemp = m_thigh[loc];
347  refPressure = m_p0;
348  }
349  }
350
351  //! Modify parameters for the standard state
352  /*!
353  * The thermo parameterization for a single species is overwritten.
354  *
355  * @param index Species index
356  * @param c Vector of coefficients used to set the
357  * parameters for the standard state.
358  * Must be length >= 4.
359  * @deprecated
360  */
361  DEPRECATED(virtual void modifyParams(size_t index, doublereal* c)) {
362  size_t loc = m_loc[index];
363  if (loc == npos) {
364  throw CanteraError("SimpleThermo::modifyParams",
365  "modifying parameters for species which hasn't been set yet");
366  }
367  /*
368  * Change the data
369  */
370  m_t0[loc] = c[0];
371  m_h0_R[loc] = c[1] / GasConstant;
372  m_s0_R[loc] = c[2] / GasConstant;
373  m_cp0_R[loc] = c[3] / GasConstant;
374  }
375
376 #ifdef H298MODIFY_CAPABILITY
377
378  virtual doublereal reportOneHf298(int k) const {
379  throw CanteraError("reportHF298", "unimplemented");
380  }
381
382  virtual void modifyOneHf298(const int k, const doublereal Hf298New) {
383  throw CanteraError("reportHF298", "unimplemented");
384  }
385
386
387 #endif
388 protected:
389
390  //! Mapping between the species index and the vector index where the coefficients are kept
391  /*!
392  * This object doesn't have a one-to one correspondence between the species index, kspec,
393  * and the data location index,indexData, m_cp0_R[indexData].
394  * This index keeps track of it.
395  * indexData = m_loc[kspec]
396  */
397  mutable std::map<size_t, size_t> m_loc;
398
399  //! Map between the vector index where the coefficients are kept and the species index
400  /*!
401  * Length is equal to the number of dataPoints.
402  * kspec = m_index[indexData]
403  */
404  std::vector<size_t> m_index;
405
406  //! Maximum value of the low temperature limit
407  doublereal m_tlow_max;
408
409  //! Minimum value of the high temperature limit
410  doublereal m_thigh_min;
411
412  //! Vector of low temperature limits (species index)
413  /*!
414  * Length is equal to number of data points
415  */
417
418  //! Vector of low temperature limits (species index)
419  /*!
420  * Length is equal to number of data points
421  */
423
424  //! Vector of base temperatures (kelvin)
425  /*!
426  * Length is equal to the number of species data points
427  */
429
430  //! Vector of base log temperatures (kelvin)
431  /*!
432  * Length is equal to the number of species data points
433  */
435
436  //! Vector of base dimensionless Enthalpies
437  /*!
438  * Length is equal to the number of species data points
439  */
441
442  //! Vector of base dimensionless Entropies
443  /*!
444  * Length is equal to the number of species data points
445  */
447
448  //! Vector of base dimensionless heat capacities
449  /*!
450  * Length is equal to the number of species data points
451  */
453
454  //! Reference pressure (Pa)
455  /*!
456  * all species must have the same reference pressure.
457  */
458  doublereal m_p0;
459
460  //! Number of species data points in the object.
461  /*!
462  * This is less than or equal to the number of species in the phase.
463  */
464  size_t m_nspData;
465
466 };
467
468 }
469
470 #endif