Cantera  2.0
FixedChemPotSSTP.cpp
Go to the documentation of this file.
1 /**
2  * @file FixedChemPotSSTP.cpp
3  * Definition file for the FixedChemPotSSTP class, which represents a fixed-composition
4  * incompressible substance with a constant chemical potential (see \ref thermoprops and
5  * class \link Cantera::FixedChemPotSSTP FixedChemPotSSTP\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  */
14 
15 #include "cantera/base/ct_defs.h"
16 #include "cantera/thermo/mix_defs.h"
20 
21 
22 #include <string>
24 namespace Cantera
25 {
26 //====================================================================================================================
27 /*
28  * ---- Constructors -------
29  */
30 //====================================================================================================================
31 /*
32  * Default Constructor for the FixedChemPotSSTP class
33  */
36  chemPot_(0.0)
37 {
38 }
39 //====================================================================================================================
40 // Create and initialize a FixedChemPotSSTP ThermoPhase object
41 // from an ASCII input file
42 /*
43  * @param infile name of the input file
44  * @param id name of the phase id in the file.
45  * If this is blank, the first phase in the file is used.
46  */
47 FixedChemPotSSTP::FixedChemPotSSTP(std::string infile, std::string id) :
49  chemPot_(0.0)
50 {
51  XML_Node* root = get_XML_File(infile);
52  if (id == "-") {
53  id = "";
54  }
55  XML_Node* xphase = get_XML_NameID("phase", std::string("#")+id, root);
56  if (!xphase) {
57  throw CanteraError("FixedChemPotSSTP::FixedChemPotSSTP",
58  "Couldn't find phase name in file:" + id);
59  }
60  // Check the model name to ensure we have compatibility
61  const XML_Node& th = xphase->child("thermo");
62  std::string model = th["model"];
63  if (model != "StoichSubstance" && model != "StoichSubstanceSSTP" && model != "FixedChemPot") {
64  throw CanteraError("FixedChemPotSSTP::FixedChemPotSSTP",
65  "thermo model attribute must be FixedChemPot or StoichSubstance");
66  }
67  importPhase(*xphase, this);
68 }
69 //====================================================================================================================
70 // Full Constructor.
71 /*
72  * @param phaseRef XML node pointing to a FixedChemPotSSTP description
73  * @param id Id of the phase.
74  */
75 FixedChemPotSSTP::FixedChemPotSSTP(XML_Node& xmlphase, std::string id) :
77  chemPot_(0.0)
78 {
79  if (id != "") {
80  std::string idxml = xmlphase["id"];
81  if (id != idxml) {
82  throw CanteraError("FixedChemPotSSTP::FixedChemPotSSTP",
83  "id's don't match");
84  }
85  }
86  const XML_Node& th = xmlphase.child("thermo");
87  std::string model = th["model"];
88  if (model != "StoichSubstance" && model != "StoichSubstanceSSTP" && model != "FixedChemPotSSTP") {
89  throw CanteraError("FixedChemPotSSTP::FixedChemPotSSTP",
90  "thermo model attribute must be StoichSubstance or FixedChemPot");
91  }
92  importPhase(xmlphase, this);
93 
94  if (model == "StoichSubstance" || model == "StoichSubstanceSSTP") {
95  _updateThermo();
96  chemPot_ = (m_h0_RT[0] - m_s0_R[0]) * GasConstant * temperature();
97  }
98 }
99 //====================================================================================================================
100 FixedChemPotSSTP::FixedChemPotSSTP(std::string Ename, doublereal val) :
101  SingleSpeciesTP(),
102  chemPot_(0.0)
103 {
104 
105  std::string pname = Ename + "Fixed";
106  setID(pname);
107  setName(pname);
108  setNDim(3);
109  addUniqueElement(Ename, -12345.);
110  freezeElements();
111  vector_fp ecomp(nElements(), 0.0);
112  ecomp[0] = 1.0;
113  double chrg = 0.0;
114  SpeciesThermo* spth = new SimpleThermo();
115  setSpeciesThermo(spth);
116  addUniqueSpecies(pname, &ecomp[0], chrg, 0.0);
117  double c[4];
118  c[0] = 298.15;
119  c[1] = val;
120  c[2] = 0.0;
121  c[3] = 0.0;
122  m_spthermo->install(pname, 0, SIMPLE, c, 0.0, 1.0E30, OneAtm);
123  freezeSpecies();
124  initThermo();
125  m_p0 = OneAtm;
126  m_tlast = 298.15;
128 
129  // Create an XML_Node entry for this species
130  XML_Node* s = new XML_Node("species", 0);
131  s->addAttribute("name", pname);
132  std::string aaS = Ename + ":1";
133  s->addChild("atomArray", aaS);
134  XML_Node& tt = s->addChild("thermo");
135  XML_Node& ss = tt.addChild("Simple");
136  ss.addAttribute("Pref", "1 bar");
137  ss.addAttribute("Tmax", "5000.");
138  ss.addAttribute("Tmin", "100.");
139  ss.addChild("t0", "298.15");
140  ss.addChild("cp0", "0.0");
141  std::string sval = fp2str(val);
142  ss.addChild("h", sval);
143  ss.addChild("s", "0.0");
144  saveSpeciesData(0, s);
145  delete s;
146  s = 0;
147 }
148 
149 //====================================================================================================================
150 // Copy constructor
151 /*
152  * @param right Object to be copied
153  */
156 {
157  *this = operator=(right);
158 }
159 //====================================================================================================================
160 // Assignment operator
161 /*
162  * @param right Object to be copied
163  */
166 {
167  if (&right != this) {
169 
170  chemPot_ = right.chemPot_;
171  }
172  return *this;
173 }
174 //====================================================================================================================
175 /*
176  * Destructor for the routine (virtual)
177  *
178  */
180 {
181 }
182 //====================================================================================================================
183 // Duplication function
184 /*
185  * This virtual function is used to create a duplicate of the
186  * current phase. It's used to duplicate the phase when given
187  * a ThermoPhase pointer to the phase.
188  *
189  * @return It returns a ThermoPhase pointer.
190  */
192 {
193  FixedChemPotSSTP* stp = new FixedChemPotSSTP(*this);
194  return (ThermoPhase*) stp;
195 }
196 //====================================================================================================================
197 
198 /*
199  * ---- Utilities -----
200  */
201 
202 /*
203  * Equation of state flag. Returns the value cStoichSubstance,
204  * defined in mix_defs.h.
205  */
207 {
208  return cFixedChemPot;
209 }
210 
211 /*
212  * ---- Molar Thermodynamic properties of the solution ----
213  */
214 
215 /*
216  * ----- Mechanical Equation of State ------
217  */
218 //====================================================================================================================
219 /*
220  * Pressure. Units: Pa.
221  * For an incompressible substance, the density is independent
222  * of pressure. This method simply returns the stored
223  * pressure value.
224  */
225 doublereal FixedChemPotSSTP::pressure() const
226 {
227  return m_press;
228 }
229 //====================================================================================================================
230 /*
231  * Set the pressure at constant temperature. Units: Pa.
232  * For an incompressible substance, the density is
233  * independent of pressure. Therefore, this method only
234  * stores the specified pressure value. It does not
235  * modify the density.
236  */
238 {
239  m_press = p;
240 }
241 //====================================================================================================================
242 /*
243  * The isothermal compressibility. Units: 1/Pa.
244  * The isothermal compressibility is defined as
245  * \f[
246  * \kappa_T = -\frac{1}{v}\left(\frac{\partial v}{\partial P}\right)_T
247  * \f]
248  *
249  * It's equal to zero for this model, since the molar volume
250  * doesn't change with pressure or temperature.
251  */
253 {
254  return 0.0;
255 }
256 //====================================================================================================================
257 /*
258  * The thermal expansion coefficient. Units: 1/K.
259  * The thermal expansion coefficient is defined as
260  *
261  * \f[
262  * \beta = \frac{1}{v}\left(\frac{\partial v}{\partial T}\right)_P
263  * \f]
264  *
265  * It's equal to zero for this model, since the molar volume
266  * doesn't change with pressure or temperature.
267  */
269 {
270  return 0.0;
271 }
272 //====================================================================================================================
273 /*
274  * ---- Chemical Potentials and Activities ----
275  */
276 //====================================================================================================================
277 /*
278  * This method returns the array of generalized
279  * concentrations. For a stoichiometric substance, there is
280  * only one species, and the generalized concentration is 1.0.
281  */
283 getActivityConcentrations(doublereal* c) const
284 {
285  c[0] = 1.0;
286 }
287 //====================================================================================================================
288 /*
289  * The standard concentration. This is defined as the concentration
290  * by which the generalized concentration is normalized to produce
291  * the activity.
292  */
293 doublereal FixedChemPotSSTP::standardConcentration(size_t k) const
294 {
295  return 1.0;
296 }
297 //====================================================================================================================
298 /*
299  * Returns the natural logarithm of the standard
300  * concentration of the kth species
301  */
302 doublereal FixedChemPotSSTP::logStandardConc(size_t k) const
303 {
304  return 0.0;
305 }
306 //====================================================================================================================
307 /*
308  * Returns the units of the standard and generalized
309  * concentrations Note they have the same units, as their
310  * ratio is defined to be equal to the activity of the kth
311  * species in the solution, which is unitless.
312  *
313  * This routine is used in print out applications where the
314  * units are needed. Usually, MKS units are assumed throughout
315  * the program and in the XML input files.
316  *
317  * uA[0] = kmol units - default = 1
318  * uA[1] = m units - default = -nDim(), the number of spatial
319  * dimensions in the Phase class.
320  * uA[2] = kg units - default = 0;
321  * uA[3] = Pa(pressure) units - default = 0;
322  * uA[4] = Temperature units - default = 0;
323  * uA[5] = time units - default = 0
324  */
326 getUnitsStandardConc(doublereal* uA, int k, int sizeUA) const
327 {
328  for (int i = 0; i < 6; i++) {
329  uA[i] = 0;
330  }
331 }
332 //====================================================================================================================
333 /*
334  * ---- Partial Molar Properties of the Solution ----
335  */
336 void FixedChemPotSSTP::getPartialMolarVolumes(doublereal* vbar) const
337 {
338  vbar[0] = 0.0;
339 }
340 //====================================================================================================================
341 /*
342  * ---- Properties of the Standard State of the Species in the Solution
343  * ----
344  */
345 //====================================================================================================================
346 /*
347  * Get the array of chemical potentials at unit activity
348  * \f$ \mu^0_k \f$.
349  *
350  * For a stoichiometric substance, there is no activity term in
351  * the chemical potential expression, and therefore the
352  * standard chemical potential and the chemical potential
353  * are both equal to the molar Gibbs function.
354  */
356 getStandardChemPotentials(doublereal* mu0) const
357 {
358  mu0[0] = chemPot_;
359 }
360 //====================================================================================================================
361 /*
362  * Get the nondimensional Enthalpy functions for the species
363  * at their standard states at the current
364  * <I>T</I> and <I>P</I> of the solution.
365  * Molar enthalpy. Units: J/kmol. For an incompressible,
366  * stoichiometric substance, the internal energy is
367  * independent of pressure, and therefore the molar enthalpy
368  * is \f[ \hat h(T, P) = \hat u(T) + P \hat v \f], where the
369  * molar specific volume is constant.
370  */
371 void FixedChemPotSSTP::getEnthalpy_RT(doublereal* hrt) const
372 {
373  double rt = _RT();
374  hrt[0] = chemPot_ / rt;
375 }
376 //====================================================================================================================
377 /*
378  * Get the array of nondimensional Entropy functions for the
379  * standard state species
380  * at the current <I>T</I> and <I>P</I> of the solution.
381  */
382 void FixedChemPotSSTP::getEntropy_R(doublereal* sr) const
383 {
384  sr[0] = 0.0;
385 }
386 //====================================================================================================================
387 /*
388  * Get the nondimensional Gibbs functions for the species
389  * at their standard states of solution at the current T and P
390  * of the solution
391  */
392 void FixedChemPotSSTP::getGibbs_RT(doublereal* grt) const
393 {
394  double rt = _RT();
395  grt[0] = chemPot_ / rt;
396 }
397 //====================================================================================================================
398 /*
399  * Get the nondimensional Gibbs functions for the standard
400  * state of the species at the current T and P.
401  */
402 void FixedChemPotSSTP::getCp_R(doublereal* cpr) const
403 {
404  cpr[0] = 0.0;
405 }
406 //====================================================================================================================
407 /*
408  * Molar internal energy (J/kmol).
409  * For an incompressible,
410  * stoichiometric substance, the molar internal energy is
411  * independent of pressure. Since the thermodynamic properties
412  * are specified by giving the standard-state enthalpy, the
413  * term \f$ P_0 \hat v\f$ is subtracted from the specified molar
414  * enthalpy to compute the molar internal energy.
415  */
416 void FixedChemPotSSTP::getIntEnergy_RT(doublereal* urt) const
417 {
418  urt[0] = chemPot_;
419 }
420 //====================================================================================================================
421 // Get the molar volumes of each species in their standard
422 // states at the current <I>T</I> and <I>P</I> of the solution.
423 /*
424  * units = m^3 / kmol
425  *
426  * We set this to zero
427  *
428  * @param vbar On output this contains the standard volume of the species
429  * and phase (m^3/kmol). Vector of length 1
430  */
431 void FixedChemPotSSTP::getStandardVolumes(doublereal* vbar) const
432 {
433  vbar[0] = 0.0;
434 }
435 //====================================================================================================================
436 /*
437  * ---- Thermodynamic Values for the Species Reference States ----
438  */
439 //====================================================================================================================
440 void FixedChemPotSSTP::getIntEnergy_RT_ref(doublereal* urt) const
441 {
442  urt[0] = chemPot_;
443 }
444 //====================================================================================================================
445 void FixedChemPotSSTP::getEnthalpy_RT_ref(doublereal* hrt) const
446 {
447  double rt = _RT();
448  hrt[0] = chemPot_ / rt;
449 }
450 //====================================================================================================================
451 void FixedChemPotSSTP::getEntropy_R_ref(doublereal* sr) const
452 {
453  sr[0] = 0.0;
454 }
455 //====================================================================================================================
456 void FixedChemPotSSTP::getGibbs_RT_ref(doublereal* grt) const
457 {
458  double rt = _RT();
459  grt[0] = chemPot_ / rt;
460 }
461 //====================================================================================================================
462 void FixedChemPotSSTP::getGibbs_ref(doublereal* g) const
463 {
464  g[0] = chemPot_;
465 }
466 //====================================================================================================================
467 void FixedChemPotSSTP::getCp_R_ref(doublereal* cpr) const
468 {
469  cpr[0] = 0.0;
470 }
471 //====================================================================================================================
472 /*
473  * ---- Saturation Properties
474  */
475 //====================================================================================================================
476 /*
477  * ---- Initialization and Internal functions
478  */
479 //====================================================================================================================
480 /*
481  * @internal Initialize. This method is provided to allow
482  * subclasses to perform any initialization required after all
483  * species have been added. For example, it might be used to
484  * resize internal work arrays that must have an entry for
485  * each species. The base class implementation does nothing,
486  * and subclasses that do not require initialization do not
487  * need to overload this method. When importing a CTML phase
488  * description, this method is called just prior to returning
489  * from function importPhase.
490  *
491  * @see importCTML.cpp
492  */
494 {
495  /*
496  * Call the base class thermo initializer
497  */
499 }
500 //====================================================================================================================
501 
502 void FixedChemPotSSTP::initThermoXML(XML_Node& phaseNode, std::string id)
503 {
504  /*
505  * Find the Thermo XML node
506  */
507  if (!phaseNode.hasChild("thermo")) {
508  throw CanteraError("FixedChemPotSSTP::initThermoXML", "no thermo XML node");
509  }
510  XML_Node& tnode = phaseNode.child("thermo");
511  std::string model = tnode["model"];
512  if (model != "StoichSubstance" && model != "FixedChemPot" && model != "StoichSubstanceSSTP") {
513  throw CanteraError("FixedChemPotSSTP::initThermoXML()",
514  "thermo model attribute must be FixedChemPot or StoichSubstance or StoichSubstanceSSTP");
515  }
516  if (model == "FixedChemPot") {
517  double val = ctml::getFloatDefaultUnits(tnode, "chemicalPotential", "J/kmol");
518  chemPot_ = val;
519  }
520  SingleSpeciesTP::initThermoXML(phaseNode, id);
521 
522 
523 }
524 //====================================================================================================================
525 /*
526  * setParameters:
527  *
528  * Generic routine that is used to set the parameters used
529  * by this model.
530  * C[0] = density of phase [ kg/m3 ]
531  */
532 void FixedChemPotSSTP::setParameters(int n, doublereal* const c)
533 {
534  chemPot_ = c[0];
535 }
536 //====================================================================================================================
537 /*
538  * getParameters:
539  *
540  * Generic routine that is used to get the parameters used
541  * by this model.
542  * n = 1
543  * C[0] = density of phase [ kg/m3 ]
544  */
545 void FixedChemPotSSTP::getParameters(int& n, doublereal* const c) const
546 {
547  n = 1;
548  c[0] = chemPot_;
549 }
550 //====================================================================================================================
552 {
553  std::string model = eosdata["model"];
554  if (model != "StoichSubstance" && model != "FixedChemPot" && model != "StoichSubstanceSSTP") {
555  throw CanteraError("FixedChemPotSSTP::setParametersFromXML",
556  "thermo model attribute must be FixedChemPot or StoichSubstance or StoichSubstanceSSTP");
557  }
558  if (model == "FixedChemPotSSTP") {
559  doublereal val = ctml::getFloatDefaultUnits(eosdata, "chemicalPotential", "J/kmol");
560  chemPot_ = val;
561  }
562 }
563 //====================================================================================================================
564 // Function to set the chemical potential directly
565 /*
566  * @param chemPot Value of the chemical potential (units J/kmol)
567  */
569 {
570  chemPot_ = chemPot;
571 }
572 //====================================================================================================================
573 }