void MixtureFugacityTP::setStateFromXML(const XML_Node& state) { int doTP = 0; string comp = ctml::getChildValue(state,"moleFractions"); if (comp != "") { // not overloaded in current object -> phase state is not calculated. setMoleFractionsByName(comp); doTP = 1; } else { comp = ctml::getChildValue(state,"massFractions"); if (comp != "") { // not overloaded in current object -> phase state is not calculated. setMassFractionsByName(comp); doTP = 1; } } double t = temperature(); if (state.hasChild("temperature")) { t = ctml::getFloat(state, "temperature", "temperature"); doTP = 1; } if (state.hasChild("pressure")) { double p = ctml::getFloat(state, "pressure", "pressure"); setState_TP(t, p); } else if (state.hasChild("density")) { double rho = ctml::getFloat(state, "density", "density"); setState_TR(t, rho); } else if (doTP) { double rho = Phase::density(); setState_TR(t, rho); } }
void SingleSpeciesTP::setState_SP(doublereal s, doublereal p, doublereal tol) { doublereal dt; setPressure(p); for (int n = 0; n < 50; n++) { dt = clip((s - entropy_mass())*temperature()/cp_mass(), -100.0, 100.0); setState_TP(temperature() + dt, p); if (fabs(dt) < tol) { return; } } throw CanteraError("setState_SP","no convergence. dt = " + fp2str(dt)); }
void SingleSpeciesTP::setState_HP(doublereal h, doublereal p, doublereal tol) { doublereal dt; setPressure(p); for (int n = 0; n < 50; n++) { dt = (h - enthalpy_mass())/cp_mass(); if (dt > 100.0) dt = 100.0; else if (dt < -100.0) dt = -100.0; setState_TP(temperature() + dt, p); if (fabs(dt) < tol) { return; } } throw CanteraError("setState_HP","no convergence. dt = " + fp2str(dt)); }
void vcs_VolPhase::setPtrThermoPhase(ThermoPhase* tp_ptr) { TP_ptr = tp_ptr; Temp_ = TP_ptr->temperature(); Pres_ = TP_ptr->pressure(); setState_TP(Temp_, Pres_); p_VCS_UnitsFormat = VCS_UNITS_MKS; m_phi = TP_ptr->electricPotential(); size_t nsp = TP_ptr->nSpecies(); size_t nelem = TP_ptr->nElements(); if (nsp != m_numSpecies) { if (m_numSpecies != 0) { plogf("Warning Nsp != NVolSpeces: %d %d \n", nsp, m_numSpecies); } resize(VP_ID_, nsp, nelem, PhaseName.c_str()); } TP_ptr->getMoleFractions(VCS_DATA_PTR(Xmol_)); creationMoleNumbers_ = Xmol_; _updateMoleFractionDependencies(); /* * figure out ideal solution tag */ if (nsp == 1) { m_isIdealSoln = true; } else { int eos = TP_ptr->eosType(); switch (eos) { case cIdealGas: case cIncompressible: case cSurf: case cMetal: case cStoichSubstance: case cSemiconductor: case cLatticeSolid: case cLattice: case cEdge: case cIdealSolidSolnPhase: m_isIdealSoln = true; break; default: m_isIdealSoln = false; }; } }
void StoichSubstance::initThermo() { ThermoPhase::initThermo(); if (m_kk > 1) { throw CanteraError("initThermo", "stoichiometric substances may only contain one species."); } doublereal tmin = m_spthermo->minTemp(); doublereal tmax = m_spthermo->maxTemp(); m_p0 = refPressure(); m_h0_RT.resize(m_kk); m_cp0_R.resize(m_kk); m_s0_R.resize(m_kk); // Put the object on a valid temperature point. double tnow = 300.; if (tnow > tmin && tnow < tmax) { } else { tnow = 0.1 * (9 * tmin + tmax); } setState_TP(tnow, m_p0); }
void ThermoPhase::setState_TPX(doublereal t, doublereal p, const compositionMap& x) { setMoleFractionsByName(x); setState_TP(t,p); }
void ThermoPhase::setState_TPX(doublereal t, doublereal p, const doublereal* x) { setMoleFractions(x); setState_TP(t,p); }
/* * Set the temperature (K), pressure (Pa), and molalities. */ void MolalityVPSSTP::setState_TPM(doublereal t, doublereal p, compositionMap& m) { setMolalitiesByName(m); setState_TP(t, p); }
void ThermoPhase::setState_TPY(doublereal t, doublereal p, const compositionMap& y) { setMassFractionsByName(y); setState_TP(t,p); }
void GibbsExcessVPSSTP::setState_TPX(doublereal t, doublereal p, const doublereal* x) { State::setMoleFractions(x); getMoleFractions(DATA_PTR(moleFractions_)); setState_TP(t, p); }
/* * Set the pressure at constant temperature. Units: Pa. * This method sets a constant within the object. * The mass density is not a function of pressure. */ void GibbsExcessVPSSTP::setPressure(doublereal p) { setState_TP(temperature(), p); }
doublereal MixtureFugacityTP::calculatePsat(doublereal TKelvin, doublereal& molarVolGas, doublereal& molarVolLiquid) { /* * The algorithm for this routine has undergone quite a bit of work. It probably needs more work. * However, it seems now to be fairly robust. * The key requirement is to find an initial pressure where both the liquid and the gas exist. This * is not as easy as it sounds, and it gets exceedingly hard as the critical temperature is approached * from below. * Once we have this initial state, then we seek to equilibrate the gibbs free energies of the * gas and liquid and use the formula * * dp = VdG * * to create an update condition for deltaP using * * - (Gliq - Ggas) = (Vliq - Vgas) (deltaP) * * @TODO Suggestions for the future would be to switch it to an algorithm that uses the gas molar volume * and the liquid molar volumes as the fundamental unknowns. */ // we need this because this is a non-const routine that is public setTemperature(TKelvin); double densSave = density(); double tempSave = temperature(); double pres; doublereal mw = meanMolecularWeight(); if (TKelvin < critTemperature()) { pres = psatEst(TKelvin); // trial value = Psat from correlation doublereal volLiquid = liquidVolEst(TKelvin, pres); double RhoLiquidGood = mw / volLiquid; double RhoGasGood = pres * mw / (GasConstant * TKelvin); doublereal delGRT = 1.0E6; doublereal liqGRT, gasGRT; /* * First part of the calculation involves finding a pressure at which the * gas and the liquid state coexists. */ doublereal presLiquid = 0.; doublereal presGas; doublereal presBase = pres; bool foundLiquid = false; bool foundGas = false; doublereal densLiquid = densityCalc(TKelvin, presBase, FLUID_LIQUID_0, RhoLiquidGood); if (densLiquid > 0.0) { foundLiquid = true; presLiquid = pres; RhoLiquidGood = densLiquid; } if (!foundLiquid) { for (int i = 0; i < 50; i++) { pres = 1.1 * pres; densLiquid = densityCalc(TKelvin, pres, FLUID_LIQUID_0, RhoLiquidGood); if (densLiquid > 0.0) { foundLiquid = true; presLiquid = pres; RhoLiquidGood = densLiquid; break; } } } pres = presBase; doublereal densGas = densityCalc(TKelvin, pres, FLUID_GAS, RhoGasGood); if (densGas <= 0.0) { foundGas = false; } else { foundGas = true; presGas = pres; RhoGasGood = densGas; } if (!foundGas) { for (int i = 0; i < 50; i++) { pres = 0.9 * pres; densGas = densityCalc(TKelvin, pres, FLUID_GAS, RhoGasGood); if (densGas > 0.0) { foundGas = true; presGas = pres; RhoGasGood = densGas; break; } } } if (foundGas && foundLiquid) { if (presGas != presLiquid) { pres = 0.5 * (presLiquid + presGas); bool goodLiq; bool goodGas; for (int i = 0; i < 50; i++) { densLiquid = densityCalc(TKelvin, pres, FLUID_LIQUID_0, RhoLiquidGood); if (densLiquid <= 0.0) { goodLiq = false; } else { goodLiq = true; RhoLiquidGood = densLiquid; presLiquid = pres; } densGas = densityCalc(TKelvin, pres, FLUID_GAS, RhoGasGood); if (densGas <= 0.0) { goodGas = false; } else { goodGas = true; RhoGasGood = densGas; presGas = pres; } if (goodGas && goodLiq) { break; } if (!goodLiq && !goodGas) { pres = 0.5 * (pres + presLiquid); } if (goodLiq || goodGas) { pres = 0.5 * (presLiquid + presGas); } } } } if (!foundGas || !foundLiquid) { printf("error coundn't find a starting pressure\n"); return 0.0; } if (presGas != presLiquid) { printf("error coundn't find a starting pressure\n"); return 0.0; } pres = presGas; double presLast = pres; double RhoGas = RhoGasGood; double RhoLiquid = RhoLiquidGood; /* * Now that we have found a good pressure we can proceed with the algorithm. */ for (int i = 0; i < 20; i++) { int stab = corr0(TKelvin, pres, RhoLiquid, RhoGas, liqGRT, gasGRT); if (stab == 0) { presLast = pres; delGRT = liqGRT - gasGRT; doublereal delV = mw * (1.0/RhoLiquid - 1.0/RhoGas); doublereal dp = - delGRT * GasConstant * TKelvin / delV; if (fabs(dp) > 0.1 * pres) { if (dp > 0.0) { dp = 0.1 * pres; } else { dp = -0.1 * pres; } } pres += dp; } else if (stab == -1) { delGRT = 1.0E6; if (presLast > pres) { pres = 0.5 * (presLast + pres); } else { // we are stuck here - try this pres = 1.1 * pres; } } else if (stab == -2) { if (presLast < pres) { pres = 0.5 * (presLast + pres); } else { // we are stuck here - try this pres = 0.9 * pres; } } molarVolGas = mw / RhoGas; molarVolLiquid = mw / RhoLiquid; if (fabs(delGRT) < 1.0E-8) { // converged break; } } molarVolGas = mw / RhoGas; molarVolLiquid = mw / RhoLiquid; // Put the fluid in the desired end condition setState_TR(tempSave, densSave); return pres; } else { pres = critPressure(); setState_TP(TKelvin, pres); molarVolGas = mw / density(); molarVolLiquid = molarVolGas; setState_TR(tempSave, densSave); } return pres; }
void MixtureFugacityTP::setState_TPX(doublereal t, doublereal p, const doublereal* x) { setMoleFractions_NoState(x); setState_TP(t,p); }
void MixtureFugacityTP::setPressure(doublereal p) { setState_TP(temperature(), p); }
void ThermoPhase::setState_TPX(doublereal t, doublereal p, const std::string& x) { setMoleFractionsByName(x); setState_TP(t,p); }
void ThermoPhase::setState_TPY(doublereal t, doublereal p, const doublereal* y) { setMassFractions(y); setState_TP(t,p); }
void VPStandardStateTP::setTemperature(const doublereal temp) { setState_TP(temp, m_Pcurrent); updateStandardStateThermo(); }
void ThermoPhase::setState_TPY(doublereal t, doublereal p, const std::string& y) { setMassFractionsByName(y); setState_TP(t,p); }
void VPStandardStateTP::setPressure(doublereal p) { setState_TP(temperature(), p); updateStandardStateThermo(); }
/* * Set the temperature (K), pressure (Pa), and molalities * (gmol kg-1) of the solutes */ void MolalityVPSSTP::setState_TPM(doublereal t, doublereal p, const doublereal* const molalities) { setMolalities(molalities); setState_TP(t, p); }
vcs_VolPhase& vcs_VolPhase::operator=(const vcs_VolPhase& b) { if (&b != this) { size_t old_num = m_numSpecies; // Note: we comment this out for the assignment operator // specifically, because it isn't true for the assignment // operator but is true for a copy constructor // m_owningSolverObject = b.m_owningSolverObject; VP_ID_ = b.VP_ID_; m_singleSpecies = b.m_singleSpecies; m_gasPhase = b.m_gasPhase; m_eqnState = b.m_eqnState; ChargeNeutralityElement = b.ChargeNeutralityElement; p_VCS_UnitsFormat = b.p_VCS_UnitsFormat; p_activityConvention= b.p_activityConvention; m_numSpecies = b.m_numSpecies; m_numElemConstraints = b.m_numElemConstraints; m_elementNames.resize(b.m_numElemConstraints); for (size_t e = 0; e < b.m_numElemConstraints; e++) { m_elementNames[e] = b.m_elementNames[e]; } m_elementActive = b.m_elementActive; m_elementType = b.m_elementType; m_formulaMatrix = b.m_formulaMatrix; m_speciesUnknownType = b.m_speciesUnknownType; m_elemGlobalIndex = b.m_elemGlobalIndex; PhaseName = b.PhaseName; m_totalMolesInert = b.m_totalMolesInert; m_isIdealSoln = b.m_isIdealSoln; m_existence = b.m_existence; m_MFStartIndex = b.m_MFStartIndex; /* * Do a shallow copy because we haven' figured this out. */ IndSpecies = b.IndSpecies; for (size_t k = 0; k < old_num; k++) { if (ListSpeciesPtr[k]) { delete ListSpeciesPtr[k]; ListSpeciesPtr[k] = 0; } } ListSpeciesPtr.resize(m_numSpecies, 0); for (size_t k = 0; k < m_numSpecies; k++) { ListSpeciesPtr[k] = new vcs_SpeciesProperties(*(b.ListSpeciesPtr[k])); } /* * Do a shallow copy of the ThermoPhase object pointer. * We don't duplicate the object. * Um, there is no reason we couldn't do a * duplicateMyselfAsThermoPhase() call here. This will * have to be looked into. */ TP_ptr = b.TP_ptr; v_totalMoles = b.v_totalMoles; Xmol_ = b.Xmol_; creationMoleNumbers_ = b.creationMoleNumbers_; creationGlobalRxnNumbers_ = b.creationGlobalRxnNumbers_; m_phiVarIndex = b.m_phiVarIndex; m_totalVol = b.m_totalVol; SS0ChemicalPotential = b.SS0ChemicalPotential; StarChemicalPotential = b.StarChemicalPotential; StarMolarVol = b.StarMolarVol; PartialMolarVol = b.PartialMolarVol; ActCoeff = b.ActCoeff; np_dLnActCoeffdMolNumber = b.np_dLnActCoeffdMolNumber; m_vcsStateStatus = b.m_vcsStateStatus; m_phi = b.m_phi; m_UpToDate = false; m_UpToDate_AC = false; m_UpToDate_VolStar = false; m_UpToDate_VolPM = false; m_UpToDate_GStar = false; m_UpToDate_G0 = false; Temp_ = b.Temp_; Pres_ = b.Pres_; setState_TP(Temp_, Pres_); _updateMoleFractionDependencies(); } return *this; }
/* * Set the temperature (K), pressure (Pa), and molality. */ void MolalityVPSSTP::setState_TPM(doublereal t, doublereal p, const std::string& m) { setMolalitiesByName(m); setState_TP(t, p); }
void vcs_VolPhase::setState_T(const double temp) { setState_TP(temp, Pres_); }