Cantera  2.0
VPSSMgr_Water_HKFT.cpp
Go to the documentation of this file.
1 /**
2  * @file VPSSMgr_Water_HKFT.cpp
3  * Definition file for a derived class that handles the calculation
4  * of standard state thermo properties for pure water and
5  * a set of species which obey the HKFT standard state
6  * dependence
7  * (see \ref thermoprops and class
8  * \link Cantera::VPSSMgr_Water_HKFT VPSSMgr_Water_HKFT\endlink).
9  */
10 
11 /*
12  * Copyright (2005) Sandia Corporation. Under the terms of
13  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
14  * U.S. Government retains certain rights in this software.
15  */
16 
21 
22 using namespace std;
23 
24 namespace Cantera
25 {
26 
27 VPSSMgr_Water_HKFT::VPSSMgr_Water_HKFT(VPStandardStateTP* vp_ptr,
28  SpeciesThermo* spth) :
29  VPSSMgr(vp_ptr, spth),
30  m_waterSS(0),
31  m_tlastRef(-1.0)
32 {
35 }
36 
37 
39 {
40  // m_waterSS is owned by VPStandardState
41 }
42 
44  VPSSMgr(right.m_vptp_ptr, right.m_spthermo),
45  m_waterSS(0),
46  m_tlastRef(-1.0)
47 {
50  *this = right;
51 }
52 
53 
56 {
57  if (&b == this) {
58  return *this;
59  }
61  m_waterSS = (PDSS_Water*) m_vptp_ptr->providePDSS(0);
62  m_tlastRef = -1.0;
63  return *this;
64 }
65 
66 VPSSMgr*
68 {
69  VPSSMgr_Water_HKFT* vpm = new VPSSMgr_Water_HKFT(*this);
70  return (VPSSMgr*) vpm;
71 }
72 
73 void
75 {
77  copy(m_h0_RT.begin(), m_h0_RT.end(), hrt);
78 }
79 
80 void
82 {
84  copy(m_g0_RT.begin(), m_g0_RT.end(), grt);
85 }
86 
87 void
89 {
90  getGibbs_RT_ref(g);
91  doublereal RT = GasConstant * m_tlast;
92  for (size_t k = 0; k < m_kk; k++) {
93  g[k] *= RT;
94  }
95 }
96 
97 void
99 {
101  copy(m_s0_R.begin(), m_s0_R.end(), sr);
102 }
103 
104 void
105 VPSSMgr_Water_HKFT::getCp_R_ref(doublereal* cpr) const
106 {
108  copy(m_cp0_R.begin(), m_cp0_R.end(), cpr);
109 }
110 
111 void
113 {
115  copy(m_V0.begin(), m_V0.end(), vol);
116 }
117 
118 void VPSSMgr_Water_HKFT::setState_P(doublereal pres)
119 {
120  if (m_plast != pres) {
121  m_plast = pres;
123  }
124 }
125 
126 void VPSSMgr_Water_HKFT::setState_T(doublereal temp)
127 {
128  if (m_tlast != temp) {
129  m_tlast = temp;
131  }
132 }
133 
134 void VPSSMgr_Water_HKFT::setState_TP(doublereal temp, doublereal pres)
135 {
136  if (m_tlast != temp) {
137  m_tlast = temp;
138  m_plast = pres;
140  } else if (m_plast != pres) {
141  m_plast = pres;
143  }
144 }
145 
147 {
148  if (m_tlastRef != m_tlast) {
151  }
152 }
153 
155 {
157  doublereal RT = GasConstant * m_tlast;
158  m_waterSS->setState_TP(m_tlast, m_p0);
159  m_h0_RT[0] = (m_waterSS->enthalpy_mole())/ RT;
161  m_cp0_R[0] = (m_waterSS->cp_mole()) / GasConstant;
162  m_g0_RT[0] = (m_hss_RT[0] - m_sss_R[0]);
164  PDSS_HKFT* ps;
165  for (size_t k = 1; k < m_kk; k++) {
166  ps = (PDSS_HKFT*) m_vptp_ptr->providePDSS(k);
167  ps->setState_TP(m_tlast, m_p0);
168  m_cp0_R[k] = ps->cp_R();
169  m_s0_R[k] = ps->entropy_mole() / GasConstant;
170  m_g0_RT[k] = ps->gibbs_RT();
171  m_h0_RT[k] = m_g0_RT[k] + m_s0_R[k];
172 #ifdef DEBUG_MODE_NOT
173  double h = ps->enthalpy_RT();
174  if (fabs(m_h0_RT[k] - h) > 1.0E-4) {
175  printf(" VPSSMgr_Water_HKFT::_updateRefStateThermo:: we have a discrepancy\n");
176  }
177 #endif
178  m_V0[k] = ps->molarVolume();
179 
180  }
181  m_waterSS->setState_TP(m_tlast, m_plast);
182  for (size_t k = 1; k < m_kk; k++) {
183  ps = (PDSS_HKFT*) m_vptp_ptr->providePDSS(k);
184  ps->setState_TP(m_tlast, m_plast);
185  }
186 }
187 
189 {
190  doublereal RT = GasConstant * m_tlast;
191  // Do the water
192  m_waterSS->setState_TP(m_tlast, m_plast);
193  m_hss_RT[0] = (m_waterSS->enthalpy_mole())/ RT;
196  m_gss_RT[0] = (m_hss_RT[0] - m_sss_R[0]);
198 
199  for (size_t k = 1; k < m_kk; k++) {
200  PDSS_HKFT* ps = (PDSS_HKFT*) m_vptp_ptr->providePDSS(k);
201  ps->setState_TP(m_tlast, m_plast);
202  m_cpss_R[k] = ps->cp_R();
203  m_sss_R[k] = ps->entropy_R();
204  m_gss_RT[k] = ps->gibbs_RT();
205  m_hss_RT[k] = m_gss_RT[k] + m_sss_R[k];
206  m_Vss[k] = ps->molarVolume();
207  }
208 }
209 
211 {
213 }
214 
215 
216 void
217 VPSSMgr_Water_HKFT::initThermoXML(XML_Node& phaseNode, std::string id)
218 {
219  VPSSMgr::initThermoXML(phaseNode, id);
220 
221  XML_Node& speciesList = phaseNode.child("speciesArray");
222  XML_Node* speciesDB = get_XML_NameID("speciesData", speciesList["datasrc"],
223  &phaseNode.root());
224  const vector<string> &sss = m_vptp_ptr->speciesNames();
225 
226  m_waterSS->setState_TP(300., OneAtm);
228 
229  for (size_t k = 1; k < m_kk; k++) {
230  const XML_Node* s = speciesDB->findByAttr("name", sss[k]);
231  if (!s) {
232  throw CanteraError("VPSSMgr_Water_HKFT::initThermoXML",
233  "No species Node for species " + sss[k]);
234  }
235  const XML_Node* ss = s->findByName("standardState");
236  if (!ss) {
237  throw CanteraError("VPSSMgr_Water_HKFT::initThermoXML",
238  "No standardState Node for species " + sss[k]);
239  }
240  std::string model = lowercase((*ss)["model"]);
241  if (model != "hkft") {
242  throw CanteraError("VPSSMgr_Water_HKFT::initThermoXML",
243  "Standard state model for a solute species isn't "
244  "the HKFT standard state model: " + sss[k]);
245  }
246  }
247 }
248 
249 PDSS*
250 VPSSMgr_Water_HKFT::createInstallPDSS(size_t k, const XML_Node& speciesNode,
251  const XML_Node* const phaseNode_ptr)
252 {
253  PDSS* kPDSS = 0;
254 
255  const XML_Node* ss = speciesNode.findByName("standardState");
256  if (!ss) {
257  std::string sName = speciesNode["name"];
258  throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
259  "No standardState Node for species " + sName);
260  }
261  // Will have to do something for water
262  // -> make sure it's species 0
263  // -> make sure it's designated as a real water EOS
264  if (k == 0) {
265  string xn = speciesNode["name"];
266  if (xn != "H2O(L)") {
267  throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
268  "h2o wrong name: " + xn);
269  }
270 
271  std::string model = (*ss)["model"];
272  if (model != "waterIAPWS" && model != "waterPDSS") {
273  throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
274  "wrong SS mode: " + model);
275  }
276  //VPSSMgr::installSTSpecies(k, speciesNode, phaseNode_ptr);
277  if (m_waterSS) {
278  delete m_waterSS;
279  }
280  m_waterSS = new PDSS_Water(m_vptp_ptr, 0);
281 
282  GeneralSpeciesThermo* genSpthermo = dynamic_cast<GeneralSpeciesThermo*>(m_spthermo);
283  if (!genSpthermo) {
284  throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
285  "failed dynamic cast");
286  }
287  genSpthermo->installPDSShandler(k, m_waterSS, this);
288 
289  kPDSS = m_waterSS;
290  } else {
291  std::string model = (*ss)["model"];
292  if (model != "HKFT") {
293  std::string sName = speciesNode["name"];
294  throw CanteraError("VPSSMgr_Water_HKFT::initThermoXML",
295  "standardState model for species isn't "
296  "HKFT: " + sName);
297  }
298 
299  kPDSS = new PDSS_HKFT(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
300 
301  GeneralSpeciesThermo* genSpthermo = dynamic_cast<GeneralSpeciesThermo*>(m_spthermo);
302  if (!genSpthermo) {
303  throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
304  "failed dynamic cast");
305  }
306  genSpthermo->installPDSShandler(k, kPDSS, this);
307  }
308  return kPDSS;
309 }
310 
312 {
313  return cPDSS_UNDEF;
314 }
315 
317 {
318  return cVPSSMGR_WATER_HKFT;
319 }
320 }
321 
322