Cantera  2.0
VPSSMgr_General.cpp
Go to the documentation of this file.
1 /**
2  * @file VPSSMgr_General.cpp
3  * Definition file for a derived class that handles the calculation
4  * of standard state thermo properties for
5  * a set of species belonging to a single phase in a completely general
6  * but slow way (see \ref thermoprops and
7  * class \link Cantera::VPSSMgr_General VPSSMgr_General\endlink).
8  */
9 /*
10  * Copyright (2005) Sandia Corporation. Under the terms of
11  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
12  * U.S. Government retains certain rights in this software.
13  */
14 
16 #include "cantera/thermo/PDSS.h"
17 #include "cantera/base/xml.h"
18 #include "cantera/base/ctml.h"
26 
27 using namespace std;
28 
29 namespace Cantera
30 {
31 
32 VPSSMgr_General::VPSSMgr_General(VPStandardStateTP* vp_ptr,
33  SpeciesThermo* spth) :
34  VPSSMgr(vp_ptr, spth)
35 {
36  // Might want to do something other than holding this true.
37  // However, for the sake of getting this all up and running,
38  // will not go there for now.
41 }
42 
44 {
45 }
46 
48  VPSSMgr(right.m_vptp_ptr, right.m_spthermo)
49 {
52  *this = right;
53 }
54 //====================================================================================================================
56 {
57  if (&b == this) {
58  return *this;
59  }
61  /*
62  * Must fill in the shallow pointers. These must have already been transfered
63  * and stored in the owning VPStandardStateTP class. Note we are aware that at this point
64  * m_vptr_ptr may refer back to the wrong ThermoPhase object. However, the shallow copy
65  * performed here is consistent with the assignment operator's general functionality.
66  */
67  m_PDSS_ptrs.resize(m_kk);
68  for (size_t k = 0; k < m_kk; k++) {
69  m_PDSS_ptrs[k] = m_vptp_ptr->providePDSS(k);
70  }
71  return *this;
72 }
73 
75 {
76  VPSSMgr_General* vpm = new VPSSMgr_General(*this);
77  return (VPSSMgr*) vpm;
78 }
79 //====================================================================================================================
80 // Initialize the internal shallow pointers in this object
81 /*
82  * There are a bunch of internal shallow pointers that point to the owning
83  * VPStandardStateTP and SpeciesThermo objects. This function reinitializes
84  * them. This function is called like an onion.
85  *
86  * @param vp_ptr Pointer to the VPStandardStateTP standard state
87  * @param sp_ptr Pointer to the SpeciesThermo standard state
88  */
90 {
91  VPSSMgr::initAllPtrs(vp_ptr, sp_ptr);
92  /*
93  * Must fill in the shallow pointers. These must have already been transfered
94  * and stored in the owning VPStandardStateTP class.
95  */
96  m_PDSS_ptrs.resize(m_kk);
97  for (size_t k = 0; k < m_kk; k++) {
98  m_PDSS_ptrs[k] = m_vptp_ptr->providePDSS(k);
99  }
100 }
101 //====================================================================================================================
103 {
105  for (size_t k = 0; k < m_kk; k++) {
106  PDSS* kPDSS = m_PDSS_ptrs[k];
107  kPDSS->setState_TP(m_tlast, m_plast);
108  m_h0_RT[k] = kPDSS->enthalpy_RT_ref();
109  m_s0_R[k] = kPDSS->entropy_R_ref();
110  m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
111  m_cp0_R[k] = kPDSS->cp_R_ref();
112  m_V0[k] = kPDSS->molarVolume_ref();
113  }
114  }
115 }
116 
118 {
119  for (size_t k = 0; k < m_kk; k++) {
120  PDSS* kPDSS = m_PDSS_ptrs[k];
121  kPDSS->setState_TP(m_tlast, m_plast);
122  m_hss_RT[k] = kPDSS->enthalpy_RT();
123  m_sss_R[k] = kPDSS->entropy_R();
124  m_gss_RT[k] = m_hss_RT[k] - m_sss_R[k];
125  m_cpss_R[k] = kPDSS->cp_R();
126  m_Vss[k] = kPDSS->molarVolume();
127  }
128 }
129 
130 
132 {
133  initLengths();
134 }
135 
136 /*!
137  * Returns the vector of the
138  * gibbs function of the reference state at the current temperature
139  * of the solution and the reference pressure for the species.
140  * units = J/kmol
141  *
142  * @param g Output vector contain the Gibbs free energies
143  * of the reference state of the species
144  * length = m_kk, units = J/kmol.
145  */
146 void VPSSMgr_General::getGibbs_ref(doublereal* g) const
147 {
148  doublereal _rt = GasConstant * m_tlast;
150  std::copy(m_g0_RT.begin(), m_g0_RT.end(), g);
151  scale(g, g+m_kk, g, _rt);
152  } else {
153  for (size_t k = 0; k < m_kk; k++) {
154  PDSS* kPDSS = m_PDSS_ptrs[k];
155  kPDSS->setState_TP(m_tlast, m_plast);
156  double h0_RT = kPDSS->enthalpy_RT_ref();
157  double s0_R = kPDSS->entropy_R_ref();
158  g[k] = _rt * (h0_RT - s0_R);
159  }
160  }
161 }
162 
163 void
164 VPSSMgr_General::initThermoXML(XML_Node& phaseNode, std::string id)
165 {
166  VPSSMgr::initThermoXML(phaseNode, id);
167 }
168 
169 PDSS*
170 VPSSMgr_General::returnPDSS_ptr(size_t k, const XML_Node& speciesNode,
171  const XML_Node* const phaseNode_ptr, bool& doST)
172 {
173  PDSS* kPDSS = 0;
174  doST = true;
175  GeneralSpeciesThermo* genSpthermo = dynamic_cast<GeneralSpeciesThermo*>(m_spthermo);
176 
177 
178  const XML_Node* const ss = speciesNode.findByName("standardState");
179  if (!ss) {
180  VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
181  kPDSS = new PDSS_IdealGas(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
182  return kPDSS;
183  }
184  std::string model = (*ss)["model"];
185  if (model == "constant_incompressible") {
186  VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
187  kPDSS = new PDSS_ConstVol(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
188  if (!kPDSS) {
189  throw CanteraError("VPSSMgr_General::returnPDSS_ptr", "new PDSS_ConstVol failed");
190  }
191  } else if (model == "waterIAPWS" || model == "waterPDSS") {
192  // VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
193  kPDSS = new PDSS_Water(m_vptp_ptr, 0);
194  if (!genSpthermo) {
195  throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
196  "failed dynamic cast");
197  }
198  genSpthermo->installPDSShandler(k, kPDSS, this);
199  m_useTmpRefStateStorage = false;
200  } else if (model == "HKFT") {
201  doST = false;
202  kPDSS = new PDSS_HKFT(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
203  if (!genSpthermo) {
204  throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
205  "failed dynamic cast");
206  }
207  genSpthermo->installPDSShandler(k, kPDSS, this);
208 
209  } else if (model == "IonFromNeutral") {
210  if (!genSpthermo) {
211  throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
212  "failed dynamic cast");
213  }
214  doST = false;
215  kPDSS = new PDSS_IonsFromNeutral(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
216  if (!kPDSS) {
217  throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
218  "new PDSS_IonsFromNeutral failed");
219  }
220  genSpthermo->installPDSShandler(k, kPDSS, this);
221 
222  } else if (model == "constant" || model == "temperature_polynomial" || model == "density_temperature_polynomial") {
223  VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
224  kPDSS = new PDSS_SSVol(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
225  if (!kPDSS) {
226  throw CanteraError("VPSSMgr_General::returnPDSS_ptr", "new PDSS_SSVol failed");
227  }
228  } else {
229  throw CanteraError("VPSSMgr_General::returnPDSS_ptr",
230  "unknown standard state formulation: " + model);
231  }
232  return kPDSS;
233 }
234 
235 PDSS*
236 VPSSMgr_General::createInstallPDSS(size_t k, const XML_Node& speciesNode,
237  const XML_Node* const phaseNode_ptr)
238 {
239  bool doST;
240  PDSS* kPDSS = returnPDSS_ptr(k, speciesNode, phaseNode_ptr, doST);
241  // VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
242  if (m_PDSS_ptrs.size() < k+1) {
243  m_PDSS_ptrs.resize(k+1, 0);
244  }
245  m_PDSS_ptrs[k] = kPDSS;
246  if ((k+1) >= m_kk) {
247  m_kk = k+1;
248  }
249 
250  doublereal minTemp = kPDSS->minTemp();
251  if (minTemp > m_minTemp) {
252  m_minTemp = minTemp;
253  }
254 
255  doublereal maxTemp = kPDSS->maxTemp();
256  if (maxTemp < m_maxTemp) {
257  m_maxTemp = maxTemp;
258  }
259 
260  doublereal p0 = kPDSS->refPressure();
261  if (k == 0) {
262  m_p0 = p0;
263  }
264  return kPDSS;
265 }
266 
268 {
269  PDSS* kPDSS = m_PDSS_ptrs[k];
270  return kPDSS->reportPDSSType();
271 }
272 
273 
275 {
276  return cVPSSMGR_GENERAL;
277 }
278 }
279 
280