00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef WIN32
00024 #pragma warning(disable:4786)
00025 #pragma warning(disable:4503)
00026 #endif
00027
00028 #include "VPSSMgr_Water_HKFT.h"
00029 #include "PDSS_Water.h"
00030 #include "PDSS_HKFT.h"
00031 #include "GeneralSpeciesThermo.h"
00032
00033 using namespace std;
00034
00035 namespace Cantera {
00036
00037 VPSSMgr_Water_HKFT::VPSSMgr_Water_HKFT(VPStandardStateTP *vp_ptr,
00038 SpeciesThermo *spth) :
00039 VPSSMgr(vp_ptr, spth),
00040 m_waterSS(0),
00041 m_tlastRef(-1.0)
00042 {
00043 m_useTmpRefStateStorage = true;
00044 m_useTmpStandardStateStorage = true;
00045 }
00046
00047
00048 VPSSMgr_Water_HKFT::~VPSSMgr_Water_HKFT()
00049 {
00050
00051 }
00052
00053 VPSSMgr_Water_HKFT::VPSSMgr_Water_HKFT(const VPSSMgr_Water_HKFT &right) :
00054 VPSSMgr(right.m_vptp_ptr, right.m_spthermo),
00055 m_waterSS(0),
00056 m_tlastRef(-1.0)
00057 {
00058 m_useTmpRefStateStorage = true;
00059 m_useTmpStandardStateStorage = true;
00060 *this = right;
00061 }
00062
00063
00064 VPSSMgr_Water_HKFT&
00065 VPSSMgr_Water_HKFT::operator=(const VPSSMgr_Water_HKFT &b)
00066 {
00067 if (&b == this) return *this;
00068 VPSSMgr::operator=(b);
00069 m_waterSS = (PDSS_Water *) m_vptp_ptr->providePDSS(0);
00070 m_tlastRef = -1.0;
00071 return *this;
00072 }
00073
00074 VPSSMgr *
00075 VPSSMgr_Water_HKFT::duplMyselfAsVPSSMgr() const {
00076 VPSSMgr_Water_HKFT *vpm = new VPSSMgr_Water_HKFT(*this);
00077 return (VPSSMgr *) vpm;
00078 }
00079
00080 void
00081 VPSSMgr_Water_HKFT::getEnthalpy_RT_ref(doublereal *hrt) const{
00082 updateRefStateThermo();
00083 copy(m_h0_RT.begin(), m_h0_RT.end(), hrt);
00084 }
00085
00086 void
00087 VPSSMgr_Water_HKFT::getGibbs_RT_ref(doublereal *grt) const{
00088 updateRefStateThermo();
00089 copy(m_g0_RT.begin(), m_g0_RT.end(), grt);
00090 }
00091
00092 void
00093 VPSSMgr_Water_HKFT::getGibbs_ref(doublereal *g) const{
00094 getGibbs_RT_ref(g);
00095 doublereal RT = GasConstant * m_tlast;
00096 for (int k = 0; k < m_kk; k++) {
00097 g[k] *= RT;
00098 }
00099 }
00100
00101 void
00102 VPSSMgr_Water_HKFT::getEntropy_R_ref(doublereal *sr) const{
00103 updateRefStateThermo();
00104 copy(m_s0_R.begin(), m_s0_R.end(), sr);
00105 }
00106
00107 void
00108 VPSSMgr_Water_HKFT::getCp_R_ref(doublereal *cpr) const{
00109 updateRefStateThermo();
00110 copy(m_cp0_R.begin(), m_cp0_R.end(), cpr);
00111 }
00112
00113 void
00114 VPSSMgr_Water_HKFT::getStandardVolumes_ref(doublereal *vol) const{
00115 updateRefStateThermo();
00116 copy(m_V0.begin(), m_V0.end(), vol);
00117 }
00118
00119 void VPSSMgr_Water_HKFT::setState_P(doublereal pres) {
00120 if (m_plast != pres) {
00121 m_plast = pres;
00122 _updateStandardStateThermo();
00123 }
00124 }
00125
00126 void VPSSMgr_Water_HKFT::setState_T(doublereal temp) {
00127 if (m_tlast != temp) {
00128 m_tlast = temp;
00129 _updateStandardStateThermo();
00130 }
00131 }
00132
00133 void VPSSMgr_Water_HKFT::setState_TP(doublereal temp, doublereal pres) {
00134 if (m_tlast != temp) {
00135 m_tlast = temp;
00136 m_plast = pres;
00137 _updateStandardStateThermo();
00138 } else if (m_plast != pres) {
00139 m_plast = pres;
00140 _updateStandardStateThermo();
00141 }
00142 }
00143
00144 void VPSSMgr_Water_HKFT::updateRefStateThermo() const {
00145 if (m_tlastRef != m_tlast) {
00146 m_tlastRef = m_tlast;
00147 _updateRefStateThermo();
00148 }
00149 }
00150
00151 void VPSSMgr_Water_HKFT::_updateRefStateThermo() const {
00152 m_p0 = m_waterSS->pref_safe(m_tlast);
00153 doublereal RT = GasConstant * m_tlast;
00154 m_waterSS->setState_TP(m_tlast, m_p0);
00155 m_h0_RT[0] = (m_waterSS->enthalpy_mole())/ RT;
00156 m_s0_R[0] = (m_waterSS->entropy_mole()) / GasConstant;
00157 m_cp0_R[0] = (m_waterSS->cp_mole()) / GasConstant;
00158 m_g0_RT[0] = (m_hss_RT[0] - m_sss_R[0]);
00159 m_V0[0] = (m_waterSS->density()) / m_vptp_ptr->molecularWeight(0);
00160 PDSS_HKFT *ps;
00161 for (int k = 1; k < m_kk; k++) {
00162 ps = (PDSS_HKFT *) m_vptp_ptr->providePDSS(k);
00163 ps->setState_TP(m_tlast, m_p0);
00164 m_cp0_R[k] = ps->cp_R();
00165 m_s0_R[k] = ps->entropy_mole() / GasConstant;
00166 m_g0_RT[k] = ps->gibbs_RT();
00167 m_h0_RT[k] = m_g0_RT[k] + m_s0_R[k];
00168 #ifdef DEBUG_MODE_NOT
00169 double h = ps->enthalpy_RT();
00170 if (fabs( m_h0_RT[k] - h) > 1.0E-4) {
00171 printf(" VPSSMgr_Water_HKFT::_updateRefStateThermo:: we have a discrepancy\n");
00172 }
00173 #endif
00174 m_V0[k] = ps->molarVolume();
00175
00176 }
00177 m_waterSS->setState_TP(m_tlast, m_plast);
00178 for (int k = 1; k < m_kk; k++) {
00179 ps = (PDSS_HKFT *) m_vptp_ptr->providePDSS(k);
00180 ps->setState_TP(m_tlast, m_plast);
00181 }
00182 }
00183
00184 void VPSSMgr_Water_HKFT::_updateStandardStateThermo() {
00185 doublereal RT = GasConstant * m_tlast;
00186
00187 m_waterSS->setState_TP(m_tlast, m_plast);
00188 m_hss_RT[0] = (m_waterSS->enthalpy_mole())/ RT;
00189 m_sss_R[0] = (m_waterSS->entropy_mole()) / GasConstant;
00190 m_cpss_R[0] = (m_waterSS->cp_mole()) / GasConstant;
00191 m_gss_RT[0] = (m_hss_RT[0] - m_sss_R[0]);
00192 m_Vss[0] = (m_vptp_ptr->molecularWeight(0)) / (m_waterSS->density());
00193
00194 for (int k = 1; k < m_kk; k++) {
00195 PDSS_HKFT *ps = (PDSS_HKFT *) m_vptp_ptr->providePDSS(k);
00196 ps->setState_TP(m_tlast, m_plast);
00197 m_cpss_R[k] = ps->cp_R();
00198 m_sss_R[k] = ps->entropy_R();
00199 m_gss_RT[k] = ps->gibbs_RT();;
00200 m_hss_RT[k] = m_gss_RT[k] + m_sss_R[k];
00201 m_Vss[k] = ps->molarVolume();
00202 }
00203 }
00204
00205 void VPSSMgr_Water_HKFT::initThermo() {
00206 VPSSMgr::initThermo();
00207 }
00208
00209
00210 void
00211 VPSSMgr_Water_HKFT::initThermoXML(XML_Node& phaseNode, std::string id) {
00212 VPSSMgr::initThermoXML(phaseNode, id);
00213
00214 XML_Node& speciesList = phaseNode.child("speciesArray");
00215 XML_Node* speciesDB = get_XML_NameID("speciesData", speciesList["datasrc"],
00216 &phaseNode.root());
00217 const vector<string> &sss = m_vptp_ptr->speciesNames();
00218
00219 m_waterSS->setState_TP(300., OneAtm);
00220 m_Vss[0] = (m_waterSS->density()) / m_vptp_ptr->molecularWeight(0);
00221
00222 for (int k = 1; k < m_kk; k++) {
00223 const XML_Node* s = speciesDB->findByAttr("name", sss[k]);
00224 if (!s) {
00225 throw CanteraError("VPSSMgr_Water_HKFT::initThermoXML",
00226 "No species Node for species " + sss[k]);
00227 }
00228 const XML_Node *ss = s->findByName("standardState");
00229 if (!ss) {
00230 throw CanteraError("VPSSMgr_Water_HKFT::initThermoXML",
00231 "No standardState Node for species " + sss[k]);
00232 }
00233 std::string model = lowercase((*ss)["model"]);
00234 if (model != "hkft") {
00235 throw CanteraError("VPSSMgr_Water_HKFT::initThermoXML",
00236 "Standard state model for a solute species isn't "
00237 "the HKFT standard state model: " + sss[k]);
00238 }
00239 }
00240 }
00241
00242 PDSS *
00243 VPSSMgr_Water_HKFT::createInstallPDSS(int k, const XML_Node& speciesNode,
00244 const XML_Node * const phaseNode_ptr) {
00245 PDSS *kPDSS = 0;
00246
00247 const XML_Node *ss = speciesNode.findByName("standardState");
00248 if (!ss) {
00249 std::string sName = speciesNode["name"];
00250 throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
00251 "No standardState Node for species " + sName);
00252 }
00253
00254
00255
00256 if (k == 0) {
00257 string xn = speciesNode["name"];
00258 if (xn != "H2O(L)") {
00259 throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
00260 "h2o wrong name: " + xn);
00261 }
00262
00263 std::string model = (*ss)["model"];
00264 if (model != "waterIAPWS" && model != "waterPDSS") {
00265 throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
00266 "wrong SS mode: " + model);
00267 }
00268
00269 if (m_waterSS) delete m_waterSS;
00270 m_waterSS = new PDSS_Water(m_vptp_ptr, 0);
00271
00272 GeneralSpeciesThermo *genSpthermo = dynamic_cast<GeneralSpeciesThermo *>(m_spthermo);
00273 if (!genSpthermo) {
00274 throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
00275 "failed dynamic cast");
00276 }
00277 genSpthermo->installPDSShandler(k, m_waterSS, this);
00278
00279 kPDSS = m_waterSS;
00280 } else {
00281 std::string model = (*ss)["model"];
00282 if (model != "HKFT") {
00283 std::string sName = speciesNode["name"];
00284 throw CanteraError("VPSSMgr_Water_HKFT::initThermoXML",
00285 "standardState model for species isn't "
00286 "HKFT: " + sName);
00287 }
00288
00289 kPDSS = new PDSS_HKFT(m_vptp_ptr, k, speciesNode, *phaseNode_ptr, true);
00290
00291 GeneralSpeciesThermo *genSpthermo = dynamic_cast<GeneralSpeciesThermo *>(m_spthermo);
00292 if (!genSpthermo) {
00293 throw CanteraError("VPSSMgr_Water_HKFT::installSpecies",
00294 "failed dynamic cast");
00295 }
00296 genSpthermo->installPDSShandler(k, kPDSS, this);
00297 }
00298 return kPDSS;
00299 }
00300
00301 PDSS_enumType VPSSMgr_Water_HKFT::reportPDSSType(int k) const {
00302 return cPDSS_UNDEF;
00303 }
00304
00305 VPSSMgr_enumType VPSSMgr_Water_HKFT::reportVPSSMgrType() const {
00306 return cVPSSMGR_WATER_HKFT;
00307 }
00308 }
00309
00310