Cantera  2.0
StoichSubstanceSSTP.cpp
Go to the documentation of this file.
1 /**
2  * @file StoichSubstanceSSTP.cpp
3  * Definition file for the StoichSubstanceSSTP class, which represents a fixed-composition
4  * incompressible substance (see \ref thermoprops and
5  * class \link Cantera::StoichSubstanceSSTP StoichSubstanceSSTP\endlink)
6  */
7 
8 /*
9  * Copyright (2005) Sandia Corporation. Under the terms of
10  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
11  * U.S. Government retains certain rights in this software.
12  *
13  * Copyright 2001 California Institute of Technology
14  */
15 #include "cantera/base/ct_defs.h"
16 #include "cantera/thermo/mix_defs.h"
20 
21 #include <string>
22 
23 namespace Cantera
24 {
25 
26 /*
27  * ---- Constructors -------
28  */
29 
30 /*
31  * Default Constructor for the StoichSubstanceSSTP class
32  */
35 {
36 }
37 
38 // Create and initialize a StoichSubstanceSSTP ThermoPhase object
39 // from an ASCII input file
40 /*
41  * @param infile name of the input file
42  * @param id name of the phase id in the file.
43  * If this is blank, the first phase in the file is used.
44  */
45 StoichSubstanceSSTP::StoichSubstanceSSTP(std::string infile, std::string id) :
47 {
48  XML_Node* root = get_XML_File(infile);
49  if (id == "-") {
50  id = "";
51  }
52  XML_Node* xphase = get_XML_NameID("phase", std::string("#")+id, root);
53  if (!xphase) {
54  throw CanteraError("StoichSubstanceSSTP::StoichSubstanceSSTP",
55  "Couldn't find phase name in file:" + id);
56  }
57  // Check the model name to ensure we have compatibility
58  const XML_Node& th = xphase->child("thermo");
59  std::string model = th["model"];
60  if (model != "StoichSubstance" && model != "StoichSubstanceSSTP") {
61  throw CanteraError("StoichSubstanceSSTP::StoichSubstanceSSTP",
62  "thermo model attribute must be StoichSubstance");
63  }
64  importPhase(*xphase, this);
65 }
66 
67 // Full Constructor.
68 /*
69  * @param phaseRef XML node pointing to a StoichSubstanceSSTP description
70  * @param id Id of the phase.
71  */
74 {
75  if (id != "") {
76  std::string idxml = xmlphase["id"];
77  if (id != idxml) {
78  throw CanteraError("StoichSubstanceSSTP::StoichSubstanceSSTP",
79  "id's don't match");
80  }
81  }
82  const XML_Node& th = xmlphase.child("thermo");
83  std::string model = th["model"];
84  if (model != "StoichSubstance" && model != "StoichSubstanceSSTP") {
85  throw CanteraError("StoichSubstanceSSTP::StoichSubstanceSSTP",
86  "thermo model attribute must be StoichSubstance");
87  }
88  importPhase(xmlphase, this);
89 }
90 
91 //! Copy constructor
92 /*!
93  * @param right Object to be copied
94  */
97 {
98  *this = operator=(right);
99 }
100 
101 //! Assignment operator
102 /*!
103  * @param right Object to be copied
104  */
107 {
108  if (&right != this) {
110  }
111  return *this;
112 }
113 
114 /*
115  * Destructor for the routine (virtual)
116  *
117  */
119 {
120 }
121 
122 // Duplication function
123 /*
124  * This virtual function is used to create a duplicate of the
125  * current phase. It's used to duplicate the phase when given
126  * a ThermoPhase pointer to the phase.
127  *
128  * @return It returns a ThermoPhase pointer.
129  */
131 {
132  StoichSubstanceSSTP* stp = new StoichSubstanceSSTP(*this);
133  return (ThermoPhase*) stp;
134 }
135 
136 
137 /*
138  * ---- Utilities -----
139  */
140 
141 /*
142  * Equation of state flag. Returns the value cStoichSubstance,
143  * defined in mix_defs.h.
144  */
146 {
147  return cStoichSubstance;
148 }
149 
150 /*
151  * ---- Molar Thermodynamic properties of the solution ----
152  */
153 
154 /**
155  * ----- Mechanical Equation of State ------
156  */
157 
158 /*
159  * Pressure. Units: Pa.
160  * For an incompressible substance, the density is independent
161  * of pressure. This method simply returns the stored
162  * pressure value.
163  */
165 {
166  return m_press;
167 }
168 
169 /*
170  * Set the pressure at constant temperature. Units: Pa.
171  * For an incompressible substance, the density is
172  * independent of pressure. Therefore, this method only
173  * stores the specified pressure value. It does not
174  * modify the density.
175  */
177 {
178  m_press = p;
179 }
180 
181 /*
182  * The isothermal compressibility. Units: 1/Pa.
183  * The isothermal compressibility is defined as
184  * \f[
185  * \kappa_T = -\frac{1}{v}\left(\frac{\partial v}{\partial P}\right)_T
186  * \f]
187  *
188  * It's equal to zero for this model, since the molar volume
189  * doesn't change with pressure or temperature.
190  */
192 {
193  return 0.0;
194 }
195 
196 /*
197  * The thermal expansion coefficient. Units: 1/K.
198  * The thermal expansion coefficient is defined as
199  *
200  * \f[
201  * \beta = \frac{1}{v}\left(\frac{\partial v}{\partial T}\right)_P
202  * \f]
203  *
204  * It's equal to zero for this model, since the molar volume
205  * doesn't change with pressure or temperature.
206  */
208 {
209  return 0.0;
210 }
211 
212 /*
213  * ---- Chemical Potentials and Activities ----
214  */
215 
216 /*
217  * This method returns the array of generalized
218  * concentrations. For a stoichiometric substance, there is
219  * only one species, and the generalized concentration is 1.0.
220  */
222 getActivityConcentrations(doublereal* c) const
223 {
224  c[0] = 1.0;
225 }
226 
227 /*
228  * The standard concentration. This is defined as the concentration
229  * by which the generalized concentration is normalized to produce
230  * the activity.
231  */
233 {
234  return 1.0;
235 }
236 
237 /*
238  * Returns the natural logarithm of the standard
239  * concentration of the kth species
240  */
241 doublereal StoichSubstanceSSTP::logStandardConc(size_t k) const
242 {
243  return 0.0;
244 }
245 
246 /*
247  * Returns the units of the standard and generalized
248  * concentrations Note they have the same units, as their
249  * ratio is defined to be equal to the activity of the kth
250  * species in the solution, which is unitless.
251  *
252  * This routine is used in print out applications where the
253  * units are needed. Usually, MKS units are assumed throughout
254  * the program and in the XML input files.
255  *
256  * uA[0] = kmol units - default = 1
257  * uA[1] = m units - default = -nDim(), the number of spatial
258  * dimensions in the Phase class.
259  * uA[2] = kg units - default = 0;
260  * uA[3] = Pa(pressure) units - default = 0;
261  * uA[4] = Temperature units - default = 0;
262  * uA[5] = time units - default = 0
263  */
265 getUnitsStandardConc(doublereal* uA, int k, int sizeUA) const
266 {
267  for (int i = 0; i < 6; i++) {
268  uA[i] = 0;
269  }
270 }
271 
272 /*
273  * ---- Partial Molar Properties of the Solution ----
274  */
275 
276 
277 
278 /*
279  * ---- Properties of the Standard State of the Species in the Solution
280  * ----
281  */
282 
283 /*
284  * Get the array of chemical potentials at unit activity
285  * \f$ \mu^0_k \f$.
286  *
287  * For a stoichiometric substance, there is no activity term in
288  * the chemical potential expression, and therefore the
289  * standard chemical potential and the chemical potential
290  * are both equal to the molar Gibbs function.
291  */
293 getStandardChemPotentials(doublereal* mu0) const
294 {
295  getGibbs_RT(mu0);
296  mu0[0] *= GasConstant * temperature();
297 }
298 
299 /*
300  * Get the nondimensional Enthalpy functions for the species
301  * at their standard states at the current
302  * <I>T</I> and <I>P</I> of the solution.
303  * Molar enthalpy. Units: J/kmol. For an incompressible,
304  * stoichiometric substance, the internal energy is
305  * independent of pressure, and therefore the molar enthalpy
306  * is \f[ \hat h(T, P) = \hat u(T) + P \hat v \f], where the
307  * molar specific volume is constant.
308  */
309 void StoichSubstanceSSTP::getEnthalpy_RT(doublereal* hrt) const
310 {
311  getEnthalpy_RT_ref(hrt);
312  doublereal RT = GasConstant * temperature();
313  doublereal presCorrect = (m_press - m_p0) / molarDensity();
314  hrt[0] += presCorrect / RT;
315 }
316 
317 /*
318  * Get the array of nondimensional Entropy functions for the
319  * standard state species
320  * at the current <I>T</I> and <I>P</I> of the solution.
321  */
322 void StoichSubstanceSSTP::getEntropy_R(doublereal* sr) const
323 {
324  getEntropy_R_ref(sr);
325 }
326 
327 /*
328  * Get the nondimensional Gibbs functions for the species
329  * at their standard states of solution at the current T and P
330  * of the solution
331  */
332 void StoichSubstanceSSTP::getGibbs_RT(doublereal* grt) const
333 {
334  getEnthalpy_RT(grt);
335  grt[0] -= m_s0_R[0];
336 }
337 
338 /*
339  * Get the nondimensional Gibbs functions for the standard
340  * state of the species at the current T and P.
341  */
342 void StoichSubstanceSSTP::getCp_R(doublereal* cpr) const
343 {
344  _updateThermo();
345  cpr[0] = m_cp0_R[0];
346 }
347 
348 /*
349  * Molar internal energy (J/kmol).
350  * For an incompressible,
351  * stoichiometric substance, the molar internal energy is
352  * independent of pressure. Since the thermodynamic properties
353  * are specified by giving the standard-state enthalpy, the
354  * term \f$ P_0 \hat v\f$ is subtracted from the specified molar
355  * enthalpy to compute the molar internal energy.
356  */
357 void StoichSubstanceSSTP::getIntEnergy_RT(doublereal* urt) const
358 {
359  _updateThermo();
360  doublereal RT = GasConstant * temperature();
361  doublereal PV = m_p0 / molarDensity();
362  urt[0] = m_h0_RT[0] - PV / RT;
363 }
364 
365 /*
366  * ---- Thermodynamic Values for the Species Reference States ----
367  */
368 /*
369  * Molar internal energy or the reference state at the current
370  * temperature, T (J/kmol).
371  * For an incompressible,
372  * stoichiometric substance, the molar internal energy is
373  * independent of pressure. Since the thermodynamic properties
374  * are specified by giving the standard-state enthalpy, the
375  * term \f$ P_0 \hat v\f$ is subtracted from the specified molar
376  * enthalpy to compute the molar internal energy.
377  *
378  * Note, this is equal to the standard state internal energy
379  * evaluated at the reference pressure.
380  */
381 void StoichSubstanceSSTP::getIntEnergy_RT_ref(doublereal* urt) const
382 {
383  _updateThermo();
384  doublereal RT = GasConstant * temperature();
385  doublereal PV = m_p0 / molarDensity();
386  urt[0] = m_h0_RT[0] - PV / RT;
387 }
388 
389 /*
390  * ---- Saturation Properties
391  */
392 
393 
394 
395 /*
396  * ---- Initialization and Internal functions
397  */
398 
399 /**
400  * @internal Initialize. This method is provided to allow
401  * subclasses to perform any initialization required after all
402  * species have been added. For example, it might be used to
403  * resize internal work arrays that must have an entry for
404  * each species. The base class implementation does nothing,
405  * and subclasses that do not require initialization do not
406  * need to overload this method. When importing a CTML phase
407  * description, this method is called just prior to returning
408  * from function importPhase.
409  *
410  * @see importCTML.cpp
411  */
413 {
414  /*
415  * Make sure there is one and only one species in this phase.
416  */
417  m_kk = nSpecies();
418  if (m_kk != 1) {
419  throw CanteraError("initThermo",
420  "stoichiometric substances may only contain one species.");
421  }
422  doublereal tmin = m_spthermo->minTemp();
423  doublereal tmax = m_spthermo->maxTemp();
424  if (tmin > 0.0) {
425  m_tmin = tmin;
426  }
427  if (tmax > 0.0) {
428  m_tmax = tmax;
429  }
430  /*
431  * Store the reference pressure in the variables for the class.
432  */
433  m_p0 = refPressure();
434 
435  /*
436  * Resize temporary arrays.
437  */
438  int leng = 1;
439  m_h0_RT.resize(leng);
440  m_cp0_R.resize(leng);
441  m_s0_R.resize(leng);
442  /*
443  * Call the base class thermo initializer
444  */
446 }
447 
448 
449 void StoichSubstanceSSTP::initThermoXML(XML_Node& phaseNode, std::string id)
450 {
451  /*
452  * Find the Thermo XML node
453  */
454  if (!phaseNode.hasChild("thermo")) {
455  throw CanteraError("StoichSubstanceSSTP::initThermoXML",
456  "no thermo XML node");
457  }
458  XML_Node& tnode = phaseNode.child("thermo");
459  double dens = ctml::getFloatDefaultUnits(tnode, "density", "kg/m3");
460  setDensity(dens);
461  SingleSpeciesTP::initThermoXML(phaseNode, id);
462 }
463 
464 /**
465  * setParameters:
466  *
467  * Generic routine that is used to set the parameters used
468  * by this model.
469  * C[0] = density of phase [ kg/m3 ]
470  */
471 void StoichSubstanceSSTP::setParameters(int n, doublereal* const c)
472 {
473  doublereal rho = c[0];
474  setDensity(rho);
475 }
476 
477 /**
478  * getParameters:
479  *
480  * Generic routine that is used to get the parameters used
481  * by this model.
482  * n = 1
483  * C[0] = density of phase [ kg/m3 ]
484  */
485 void StoichSubstanceSSTP::getParameters(int& n, doublereal* const c) const
486 {
487  doublereal rho = density();
488  n = 1;
489  c[0] = rho;
490 }
491 
492 /*
493  * Reads an xml data block for the parameters needed by this
494  * routine. eosdata is a reference to the xml thermo block, and looks
495  * like this:
496  *
497  * <phase id="stoichsolid" >
498  * <thermo model="StoichSubstance">
499  * <density units="g/cm3">3.52</density>
500  * </thermo>
501  * </phase>
502  */
504 {
505  std::string model = eosdata["model"];
506  if (model != "StoichSubstance" && model != "StoichSubstanceSSTP") {
507  throw CanteraError("StoichSubstanceSSTP::setParametersFromXML",
508  "thermo model attribute must be StoichSubstance");
509  }
510  doublereal rho = ctml::getFloat(eosdata, "density", "toSI");
511  setDensity(rho);
512 }
513 
514 
515 
516 
517 
518 /*
519  * Default Constructor for the electrodeElectron class
520  */
523 {
524 }
525 
526 // Create and initialize a electrodeElectron ThermoPhase object
527 // from an ASCII input file
528 /*
529  * @param infile name of the input file
530  * @param id name of the phase id in the file.
531  * If this is blank, the first phase in the file is used.
532  */
533 electrodeElectron::electrodeElectron(std::string infile, std::string id) :
535 {
536  XML_Node* root = get_XML_File(infile);
537  if (id == "-") {
538  id = "";
539  }
540  XML_Node* xphase = get_XML_NameID("phase", std::string("#")+id, root);
541  if (!xphase) {
542  throw CanteraError("electrodeElectron::electrodeElectron",
543  "Couldn't find phase name in file:" + id);
544  }
545  // Check the model name to ensure we have compatibility
546  const XML_Node& th = xphase->child("thermo");
547  std::string model = th["model"];
548  if (model != "electrodeElectron") {
549  throw CanteraError("electrodeElectron::electrodeElectron",
550  "thermo model attribute must be electrodeElectron");
551  }
552  importPhase(*xphase, this);
553 }
554 
555 // Full Constructor.
556 /*
557  * @param phaseRef XML node pointing to a electrodeElectron description
558  * @param id Id of the phase.
559  */
560 electrodeElectron::electrodeElectron(XML_Node& xmlphase, std::string id) :
562 {
563  if (id != "") {
564  std::string idxml = xmlphase["id"];
565  if (id != idxml) {
566  throw CanteraError("electrodeElectron::electrodeElectron",
567  "id's don't match");
568  }
569  }
570  const XML_Node& th = xmlphase.child("thermo");
571  std::string model = th["model"];
572  if (model != "electrodeElectron") {
573  throw CanteraError("electrodeElectron::electrodeElectron",
574  "thermo model attribute must be electrodeElectron");
575  }
576  importPhase(xmlphase, this);
577 }
578 
579 //! Copy constructor
580 /*!
581  * @param right Object to be copied
582  */
585 {
586  *this = operator=(right);
587 }
588 
589 //! Assignment operator
590 /*!
591  * @param right Object to be copied
592  */
595 {
596  if (&right != this) {
598  }
599  return *this;
600 }
601 
602 /*
603  * Destructor for the routine (virtual)
604  *
605  */
607 {
608 }
609 
611 {
612  std::string model = eosdata["model"];
613  if (model != "electrodeElectron") {
614  throw CanteraError("electrodeElectron::setParametersFromXML",
615  "thermo model attribute must be electrodeElectron");
616  }
617 }
618 
619 void electrodeElectron::initThermoXML(XML_Node& phaseNode, std::string id)
620 {
621  doublereal rho = 10.0;
622  setDensity(rho);
623  SingleSpeciesTP::initThermoXML(phaseNode, id);
624 }
625 
626 void electrodeElectron::setParameters(int n, doublereal* const c)
627 {
628  doublereal rho = 10.0;
629  setDensity(rho);
630 }
631 
632 }
633 
634