20 MixtureFugacityTP::MixtureFugacityTP() :
22 forcedState_(FLUID_UNDEFINED),
52 for (
size_t k = 0; k <
m_kk; k++) {
53 muRT[k] *= 1.0 /
RT();
64 for (
size_t k = 0; k <
m_kk; k++) {
65 g[k] =
RT() * (g[k] + tmp);
79 for (
size_t k = 0; k <
m_kk; k++) {
89 for (
size_t k = 0; k <
m_kk; k++) {
99 for (
size_t k = 0; k <
m_kk; k++) {
108 for (
size_t i = 0; i <
m_kk; i++) {
122 for (
size_t i = 0; i <
m_kk; i++) {
144 scale(gibbsrt.begin(), gibbsrt.end(), g,
RT());
168 for (
size_t i = 0; i <
m_kk; i++) {
190 if (state.
hasChild(
"temperature")) {
191 t =
getFloat(state,
"temperature",
"temperature");
195 double p =
getFloat(state,
"pressure",
"pressure");
197 }
else if (state.
hasChild(
"density")) {
198 double rho =
getFloat(state,
"density",
"density");
240 void MixtureFugacityTP::setMoleFractions_NoState(
const doublereal*
const x)
244 updateMixingExpressions();
264 updateMixingExpressions();
274 rho =
densityCalc(t, pres, FLUID_UNDEFINED , rhoNow);
279 throw CanteraError(
"MixtureFugacityTP::setState_TP",
"neg rho");
282 throw CanteraError(
"MixtureFugacityTP::setState_TP",
"neg rho");
287 if (
iState_ < FLUID_LIQUID_0) {
293 if (
iState_ >= FLUID_LIQUID_0) {
294 throw CanteraError(
"MixtureFugacityTP::setState_TP",
"wrong state");
297 throw CanteraError(
"MixtureFugacityTP::setState_TP",
"neg rho");
301 if (
iState_ >= FLUID_LIQUID_0) {
308 throw CanteraError(
"MixtureFugacityTP::setState_TP",
"wrong state");
311 throw CanteraError(
"MixtureFugacityTP::setState_TP",
"neg rho");
317 void MixtureFugacityTP::setState_TR(doublereal T, doublereal rho)
324 updateMixingExpressions();
330 setMoleFractions_NoState(x);
356 doublereal lpr = -0.8734*tt*tt - 3.4522*tt + 4.2918;
357 return pcrit*exp(lpr);
366 int phase, doublereal rhoguess)
370 if (rhoguess == -1.0) {
372 if (TKelvin > tcrit) {
375 if (phase == FLUID_GAS || phase == FLUID_SUPERCRIT) {
377 }
else if (phase >= FLUID_LIQUID_0) {
379 rhoguess = mmw / lqvol;
389 double molarVolBase = mmw / rhoguess;
390 double molarVolLast = molarVolBase;
395 double molarVolSpinodal = vc;
399 bool gasSide = molarVolBase > vc;
408 for (
int n = 0; n < 200; n++) {
413 double dpdVBase =
dpdVCalc(TKelvin, molarVolBase, presBase);
418 if (dpdVBase >= 0.0) {
419 if (TKelvin > tcrit) {
421 "T > tcrit unexpectedly");
428 if (molarVolBase >= vc) {
429 molarVolSpinodal = molarVolBase;
430 molarVolBase = 0.5 * (molarVolLast + molarVolSpinodal);
432 molarVolBase = 0.5 * (molarVolLast + molarVolSpinodal);
435 if (molarVolBase <= vc) {
436 molarVolSpinodal = molarVolBase;
437 molarVolBase = 0.5 * (molarVolLast + molarVolSpinodal);
439 molarVolBase = 0.5 * (molarVolLast + molarVolSpinodal);
446 if (fabs(presBase-presPa) < 1.0E-30 + 1.0E-8 * presPa) {
452 doublereal dpdV = dpdVBase;
454 dpdV = dpdVBase * 1.5;
459 double delMV = - (presBase - presPa) / dpdV;
460 if ((!gasSide || delMV < 0.0) && fabs(delMV) > 0.2 * molarVolBase) {
461 delMV = delMV / fabs(delMV) * 0.2 * molarVolBase;
464 if (TKelvin < tcrit) {
466 if (delMV < 0.0 && -delMV > 0.5 * (molarVolBase - molarVolSpinodal)) {
467 delMV = - 0.5 * (molarVolBase - molarVolSpinodal);
470 if (delMV > 0.0 && delMV > 0.5 * (molarVolSpinodal - molarVolBase)) {
471 delMV = 0.5 * (molarVolSpinodal - molarVolBase);
476 molarVolLast = molarVolBase;
477 molarVolBase += delMV;
479 if (fabs(delMV/molarVolBase) < 1.0E-14) {
485 if (molarVolBase <= 0.0) {
486 molarVolBase = std::min(1.0E-30, fabs(delMV*1.0E-4));
491 double densBase = 0.0;
494 throw CanteraError(
"MixtureFugacityTP::densityCalc",
"Process did not converge");
496 densBase = mmw / molarVolBase;
501 void MixtureFugacityTP::updateMixingExpressions()
506 doublereal& densGasGuess, doublereal& liqGRT, doublereal& gasGRT)
509 doublereal densLiq =
densityCalc(TKelvin, pres, FLUID_LIQUID_0, densLiqGuess);
510 if (densLiq <= 0.0) {
513 densLiqGuess = densLiq;
514 setState_TR(TKelvin, densLiq);
518 doublereal densGas =
densityCalc(TKelvin, pres, FLUID_GAS, densGasGuess);
519 if (densGas <= 0.0) {
522 "Error occurred trying to find gas density at (T,P) = {} {}",
527 densGasGuess = densGas;
528 setState_TR(TKelvin, densGas);
542 return FLUID_SUPERCRIT;
544 double tmid = tcrit - 100.;
552 double densLiqTmid = mmw / molVolLiqTmid;
553 double densGasTmid = mmw / molVolGasTmid;
554 double densMidTmid = 0.5 * (densLiqTmid + densGasTmid);
555 doublereal rhoMid = rhocrit + (t - tcrit) * (rhocrit - densMidTmid) / (tcrit - tmid);
558 int iStateGuess = FLUID_LIQUID_0;
560 iStateGuess = FLUID_GAS;
562 double molarVol = mmw / rho;
565 double dpdv =
dpdVCalc(t, molarVol, presCalc);
587 doublereal molarVolGas;
588 doublereal molarVolLiquid;
593 doublereal& molarVolLiquid)
623 double RhoLiquidGood = mw / volLiquid;
624 double RhoGasGood = pres * mw / (
GasConstant * TKelvin);
625 doublereal delGRT = 1.0E6;
626 doublereal liqGRT, gasGRT;
630 doublereal presLiquid = 0.;
632 doublereal presBase = pres;
633 bool foundLiquid =
false;
634 bool foundGas =
false;
636 doublereal densLiquid =
densityCalc(TKelvin, presBase, FLUID_LIQUID_0, RhoLiquidGood);
637 if (densLiquid > 0.0) {
640 RhoLiquidGood = densLiquid;
643 for (
int i = 0; i < 50; i++) {
645 densLiquid =
densityCalc(TKelvin, pres, FLUID_LIQUID_0, RhoLiquidGood);
646 if (densLiquid > 0.0) {
649 RhoLiquidGood = densLiquid;
656 doublereal densGas =
densityCalc(TKelvin, pres, FLUID_GAS, RhoGasGood);
657 if (densGas <= 0.0) {
662 RhoGasGood = densGas;
665 for (
int i = 0; i < 50; i++) {
667 densGas =
densityCalc(TKelvin, pres, FLUID_GAS, RhoGasGood);
671 RhoGasGood = densGas;
677 if (foundGas && foundLiquid && presGas != presLiquid) {
678 pres = 0.5 * (presLiquid + presGas);
681 for (
int i = 0; i < 50; i++) {
682 densLiquid =
densityCalc(TKelvin, pres, FLUID_LIQUID_0, RhoLiquidGood);
683 if (densLiquid <= 0.0) {
687 RhoLiquidGood = densLiquid;
690 densGas =
densityCalc(TKelvin, pres, FLUID_GAS, RhoGasGood);
691 if (densGas <= 0.0) {
695 RhoGasGood = densGas;
698 if (goodGas && goodLiq) {
701 if (!goodLiq && !goodGas) {
702 pres = 0.5 * (pres + presLiquid);
704 if (goodLiq || goodGas) {
705 pres = 0.5 * (presLiquid + presGas);
709 if (!foundGas || !foundLiquid) {
710 warn_user(
"MixtureFugacityTP::calculatePsat",
711 "could not find a starting pressure; exiting.");
714 if (presGas != presLiquid) {
715 warn_user(
"MixtureFugacityTP::calculatePsat",
716 "could not find a starting pressure; exiting");
721 double presLast = pres;
722 double RhoGas = RhoGasGood;
723 double RhoLiquid = RhoLiquidGood;
726 for (
int i = 0; i < 20; i++) {
727 int stab =
corr0(TKelvin, pres, RhoLiquid, RhoGas, liqGRT, gasGRT);
730 delGRT = liqGRT - gasGRT;
731 doublereal delV = mw * (1.0/RhoLiquid - 1.0/RhoGas);
732 doublereal dp = - delGRT *
GasConstant * TKelvin / delV;
734 if (fabs(dp) > 0.1 * pres) {
742 }
else if (stab == -1) {
744 if (presLast > pres) {
745 pres = 0.5 * (presLast + pres);
750 }
else if (stab == -2) {
751 if (presLast < pres) {
752 pres = 0.5 * (presLast + pres);
758 molarVolGas = mw / RhoGas;
759 molarVolLiquid = mw / RhoLiquid;
761 if (fabs(delGRT) < 1.0E-8) {
767 molarVolGas = mw / RhoGas;
768 molarVolLiquid = mw / RhoLiquid;
770 setState_TR(tempSave, densSave);
776 molarVolLiquid = molarVolGas;
777 setState_TR(tempSave, densSave);
803 for (
size_t k = 0; k <
m_kk; k++) {
808 throw CanteraError(
"MixtureFugacityTP::_updateReferenceStateThermo",
"neg ref pressure");
Header file for a derived class of ThermoPhase that handles non-ideal mixtures based on the fugacity ...
#define FLUID_UNSTABLE
Various states of the Fugacity object.
Base class for exceptions thrown by Cantera classes.
virtual void setStateFromXML(const XML_Node &state)
Set the initial state of the phase to the conditions specified in the state XML element.
int iState_
Current state of the fluid.
vector_fp m_g0_RT
Temporary storage for dimensionless reference state Gibbs energies.
virtual int reportSolnBranchActual() const
Report the solution branch which the solution is actually on.
vector_fp m_cp0_R
Temporary storage for dimensionless reference state heat capacities.
virtual bool addSpecies(shared_ptr< Species > spec)
virtual void getGibbs_RT_ref(doublereal *grt) const
Returns the vector of nondimensional Gibbs Free Energies of the reference state at the current temper...
virtual void getGibbs_RT(doublereal *grt) const
Get the nondimensional Gibbs functions for the species at their standard states of solution at the cu...
virtual doublereal hresid() const
Calculate the deviation terms for the total enthalpy of the mixture from the ideal gas mixture.
doublereal z() const
Calculate the value of z.
vector_fp m_h0_RT
Temporary storage for dimensionless reference state enthalpies.
virtual doublereal satPressure(doublereal TKelvin)
Calculate the saturation pressure at the current mixture content for the given temperature.
virtual void setState_TP(doublereal T, doublereal pres)
Set the temperature (K) and pressure (Pa)
virtual void _updateReferenceStateThermo() const
Updates the reference state thermodynamic functions at the current T of the solution.
virtual void getStandardVolumes(doublereal *vol) const
Get the molar volumes of each species in their standard states at the current T and P of the solution...
vector_fp m_s0_R
Temporary storage for dimensionless reference state entropies.
virtual void setState_TPX(doublereal t, doublereal p, const doublereal *x)
Set the temperature (K), pressure (Pa), and mole fractions.
virtual doublereal dpdVCalc(doublereal TKelvin, doublereal molarVol, doublereal &presCalc) const
Calculate the pressure and the pressure derivative given the temperature and the molar volume.
virtual doublereal sresid() const
Calculate the deviation terms for the total entropy of the mixture from the ideal gas mixture.
virtual void getCp_R(doublereal *cpr) const
Get the nondimensional Heat Capacities at constant pressure for the standard state of the species at ...
virtual void getEntropy_R(doublereal *sr) const
Get the array of nondimensional Enthalpy functions for the standard state species at the current T an...
virtual void setPressure(doublereal p)
Set the internally stored pressure (Pa) at constant temperature and composition.
virtual doublereal densityCalc(doublereal TKelvin, doublereal pressure, int phaseRequested, doublereal rhoguess)
Calculates the density given the temperature and the pressure and a guess at the density.
virtual doublereal psatEst(doublereal TKelvin) const
Estimate for the saturation pressure.
virtual doublereal liquidVolEst(doublereal TKelvin, doublereal &pres) const
Estimate for the molar volume of the liquid.
const vector_fp & gibbs_RT_ref() const
Returns the vector of nondimensional Gibbs free energies of the reference state at the current temper...
virtual int standardStateConvention() const
This method returns the convention used in specification of the standard state, of which there are cu...
virtual void getEntropy_R_ref(doublereal *er) const
Returns the vector of nondimensional entropies of the reference state at the current temperature of t...
virtual doublereal densSpinodalGas() const
Return the value of the density at the gas spinodal point (on the gas side) for the current temperatu...
virtual void getIntEnergy_RT(doublereal *urt) const
Returns the vector of nondimensional internal Energies of the standard state at the current temperatu...
virtual void setTemperature(const doublereal temp)
Set the temperature of the phase.
virtual void getCp_R_ref(doublereal *cprt) const
Returns the vector of nondimensional constant pressure heat capacities of the reference state at the ...
virtual doublereal pressureCalc(doublereal TKelvin, doublereal molarVol) const
Calculate the pressure given the temperature and the molar volume.
vector_fp moleFractions_
Storage for the current values of the mole fractions of the species.
doublereal m_Tlast_ref
The last temperature at which the reference state thermodynamic properties were calculated at.
doublereal calculatePsat(doublereal TKelvin, doublereal &molarVolGas, doublereal &molarVolLiquid)
Calculate the saturation pressure at the current mixture content for the given temperature.
virtual void getStandardChemPotentials(doublereal *mu) const
Get the array of chemical potentials at unit activity.
virtual void getStandardVolumes_ref(doublereal *vol) const
Get the molar volumes of the species reference states at the current T and P_ref of the solution.
int forcedState_
Force the system to be on a particular side of the spinodal curve.
virtual int forcedSolutionBranch() const
Report the solution branch which the solution is restricted to.
virtual void compositionChanged()
Apply changes to the state which are needed after the composition changes.
virtual void getChemPotentials_RT(doublereal *mu) const
Get the array of non-dimensional species chemical potentials These are partial molar Gibbs free energ...
virtual void setForcedSolutionBranch(int solnBranch)
Set the solution branch to force the ThermoPhase to exist on one branch or another.
int corr0(doublereal TKelvin, doublereal pres, doublereal &densLiq, doublereal &densGas, doublereal &liqGRT, doublereal &gasGRT)
Utility routine in the calculation of the saturation pressure.
virtual doublereal densSpinodalLiquid() const
Return the value of the density at the liquid spinodal point (on the liquid side) for the current tem...
virtual void getGibbs_ref(doublereal *g) const
Returns the vector of the Gibbs function of the reference state at the current temperature of the sol...
virtual void invalidateCache()
Invalidate any cached values which are normally updated only when a change in state is detected.
virtual void getEnthalpy_RT(doublereal *hrt) const
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
virtual void getPureGibbs(doublereal *gpure) const
Get the pure Gibbs free energies of each species.
int phaseState(bool checkState=false) const
Returns the Phase State flag for the current state of the object.
virtual void getEnthalpy_RT_ref(doublereal *hrt) const
virtual void calcDensity()
Calculate the density of the mixture using the partial molar volumes and mole fractions as input.
virtual void update(doublereal T, doublereal *cp_R, doublereal *h_RT, doublereal *s_R) const
Compute the reference-state properties for all species.
An error indicating that an unimplemented function has been called.
virtual void setMoleFractions(const double *const x)
Set the mole fractions to the specified values.
void setMoleFractionsByName(const compositionMap &xMap)
Set the species mole fractions by name.
size_t m_kk
Number of species in the phase.
virtual void setDensity(const double density_)
Set the internally stored density (kg/m^3) of the phase.
doublereal meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
void getMoleFractions(double *const x) const
Get the species mole fraction vector.
virtual double density() const
Density (kg/m^3).
virtual void compositionChanged()
Apply changes to the state which are needed after the composition changes.
doublereal temperature() const
Temperature (K).
virtual void setTemperature(const doublereal temp)
Set the internally stored temperature of the phase (K).
void setMassFractionsByName(const compositionMap &yMap)
Set the species mass fractions by name.
virtual double pressure() const
Return the thermodynamic pressure (Pa).
virtual doublereal gibbs_mole() const
Molar Gibbs function. Units: J/kmol.
virtual bool addSpecies(shared_ptr< Species > spec)
virtual doublereal critPressure() const
Critical pressure (Pa).
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
virtual doublereal critTemperature() const
Critical temperature (K).
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
virtual doublereal critDensity() const
Critical density (kg/m3).
virtual doublereal refPressure() const
Returns the reference pressure in Pa.
MultiSpeciesThermo m_spthermo
Pointer to the calculation manager for species reference-state thermodynamic properties.
virtual void invalidateCache()
Invalidate any cached values which are normally updated only when a change in state is detected.
Class XML_Node is a tree-based representation of the contents of an XML file.
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data.
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
const double GasConstant
Universal Gas Constant [J/kmol/K].
Namespace for the Cantera kernel.
doublereal getFloat(const XML_Node &parent, const std::string &name, const std::string &type)
Get a floating-point value from a child element.
std::string getChildValue(const XML_Node &parent, const std::string &nameString)
This function reads a child node with the name, nameString, and returns its XML value as the return s...
void scale(InputIter begin, InputIter end, OutputIter out, S scale_factor)
Multiply elements of an array by a scale factor.
const int cSS_CONVENTION_TEMPERATURE
Standard state uses the molar convention.
Contains declarations for string manipulation functions within Cantera.