23 ThermoPhase::ThermoPhase() :
25 m_spthermo(0), m_speciesData(0),
27 m_hasElementPotentials(false),
28 m_chargeNeutralityNecessary(false),
46 m_hasElementPotentials(false),
47 m_chargeNeutralityNecessary(false),
77 (void)Phase::operator=(right);
89 for (
size_t k = 0; k <
m_kk; k++) {
124 for (
size_t k = 0; k <
nSpecies(); k++) {
132 for (
size_t k = 0; k <
m_kk; k++) {
133 lnac[k] = std::log(lnac[k]);
171 const std::string& y)
217 doublereal dTtol,
bool doUV)
220 doublereal Hmax = 0.0, Hmin = 0.0;
228 "Input specific volume is too small or negative. v = " +
fp2str(v));
234 "Input pressure is too small or negative. p = " +
fp2str(p));
247 }
else if (Tnew < Tmin) {
263 bool ignoreBounds =
false;
267 bool unstablePhase =
false;
270 double Tunstable = -1.0;
271 bool unstablePhaseNew =
false;
274 for (
int n = 0; n < 500; n++) {
279 unstablePhase =
true;
283 dt =
clip((Htarget - Hold)/cpd, -100.0, 100.0);
291 if ((dt > 0.0 && unstablePhase) || (dt <= 0.0 && !unstablePhase)) {
292 if (Hbot < Htarget && Tnew < (0.75 * Tbot + 0.25 * Told)) {
293 dt = 0.75 * (Tbot - Told);
296 }
else if (Htop > Htarget && Tnew > (0.75 * Ttop + 0.25 * Told)) {
297 dt = 0.75 * (Ttop - Told);
302 if (Tnew > Tmax && !ignoreBounds) {
305 if (Hmax >= Htarget) {
306 if (Htop < Htarget) {
315 if (Tnew < Tmin && !ignoreBounds) {
318 if (Hmin <= Htarget) {
319 if (Hbot > Htarget) {
332 for (
int its = 0; its < 10; its++) {
334 if (Tnew < Told / 3.0) {
336 dt = -2.0 * Told / 3.0;
347 unstablePhaseNew =
true;
350 unstablePhaseNew =
false;
353 if (unstablePhase ==
false && unstablePhaseNew ==
true) {
358 if (Hnew == Htarget) {
360 }
else if (Hnew > Htarget && (Htop < Htarget || Hnew < Htop)) {
363 }
else if (Hnew < Htarget && (Hbot > Htarget || Hnew > Hbot)) {
368 double Herr = Htarget - Hnew;
369 double acpd = std::max(fabs(cpd), 1.0E-5);
370 double denom = std::max(fabs(Htarget), acpd * dTtol);
371 double HConvErr = fabs((Herr)/denom);
372 if (HConvErr < 0.00001 *dTtol || fabs(dt) < dTtol) {
381 string ErrString =
"No convergence in 500 iterations\n";
383 ErrString +=
"\tTarget Internal Energy = " +
fp2str(Htarget) +
"\n";
384 ErrString +=
"\tCurrent Specific Volume = " +
fp2str(v) +
"\n";
385 ErrString +=
"\tStarting Temperature = " +
fp2str(Tinit) +
"\n";
386 ErrString +=
"\tCurrent Temperature = " +
fp2str(Tnew) +
"\n";
387 ErrString +=
"\tCurrent Internal Energy = " +
fp2str(Hnew) +
"\n";
388 ErrString +=
"\tCurrent Delta T = " +
fp2str(dt) +
"\n";
390 ErrString +=
"\tTarget Enthalpy = " +
fp2str(Htarget) +
"\n";
391 ErrString +=
"\tCurrent Pressure = " +
fp2str(p) +
"\n";
392 ErrString +=
"\tStarting Temperature = " +
fp2str(Tinit) +
"\n";
393 ErrString +=
"\tCurrent Temperature = " +
fp2str(Tnew) +
"\n";
394 ErrString +=
"\tCurrent Enthalpy = " +
fp2str(Hnew) +
"\n";
395 ErrString +=
"\tCurrent Delta T = " +
fp2str(dt) +
"\n";
398 ErrString +=
"\t - The phase became unstable (Cp < 0) T_unstable_last = "
399 +
fp2str(Tunstable) +
"\n";
421 doublereal dTtol,
bool doSV)
429 "Input specific volume is too small or negative. v = " +
fp2str(v));
435 "Input pressure is too small or negative. p = " +
fp2str(p));
448 }
else if (Tnew < Tmin) {
465 bool ignoreBounds =
false;
469 bool unstablePhase =
false;
470 double Tunstable = -1.0;
471 bool unstablePhaseNew =
false;
474 for (
int n = 0; n < 500; n++) {
479 unstablePhase =
true;
483 dt =
clip((Starget - Sold)*Told/cpd, -100.0, 100.0);
487 if ((dt > 0.0 && unstablePhase) || (dt <= 0.0 && !unstablePhase)) {
488 if (Sbot < Starget && Tnew < Tbot) {
489 dt = 0.75 * (Tbot - Told);
492 }
else if (Stop > Starget && Tnew > Ttop) {
493 dt = 0.75 * (Ttop - Told);
498 if (Tnew > Tmax && !ignoreBounds) {
501 if (Smax >= Starget) {
502 if (Stop < Starget) {
510 }
else if (Tnew < Tmin && !ignoreBounds) {
513 if (Smin <= Starget) {
514 if (Sbot > Starget) {
527 for (
int its = 0; its < 10; its++) {
533 unstablePhaseNew =
true;
536 unstablePhaseNew =
false;
539 if (unstablePhase ==
false && unstablePhaseNew ==
true) {
544 if (Snew == Starget) {
546 }
else if (Snew > Starget && (Stop < Starget || Snew < Stop)) {
549 }
else if (Snew < Starget && (Sbot > Starget || Snew > Sbot)) {
554 double Serr = Starget - Snew;
555 double acpd = std::max(fabs(cpd), 1.0E-5);
556 double denom = std::max(fabs(Starget), acpd * dTtol);
557 double SConvErr = fabs((Serr * Tnew)/denom);
558 if (SConvErr < 0.00001 *dTtol || fabs(dt) < dTtol) {
567 string ErrString =
"No convergence in 500 iterations\n";
569 ErrString +=
"\tTarget Entropy = " +
fp2str(Starget) +
"\n";
570 ErrString +=
"\tCurrent Specific Volume = " +
fp2str(v) +
"\n";
571 ErrString +=
"\tStarting Temperature = " +
fp2str(Tinit) +
"\n";
572 ErrString +=
"\tCurrent Temperature = " +
fp2str(Tnew) +
"\n";
573 ErrString +=
"\tCurrent Entropy = " +
fp2str(Snew) +
"\n";
574 ErrString +=
"\tCurrent Delta T = " +
fp2str(dt) +
"\n";
576 ErrString +=
"\tTarget Entropy = " +
fp2str(Starget) +
"\n";
577 ErrString +=
"\tCurrent Pressure = " +
fp2str(p) +
"\n";
578 ErrString +=
"\tStarting Temperature = " +
fp2str(Tinit) +
"\n";
579 ErrString +=
"\tCurrent Temperature = " +
fp2str(Tnew) +
"\n";
580 ErrString +=
"\tCurrent Entropy = " +
fp2str(Snew) +
"\n";
581 ErrString +=
"\tCurrent Delta T = " +
fp2str(dt) +
"\n";
584 ErrString +=
"\t - The phase became unstable (Cp < 0) T_unstable_last = "
585 +
fp2str(Tunstable) +
"\n";
603 for (
int i = 0; i < sizeUA; i++) {
608 uA[1] = -int(
nDim());
639 "species reference state thermo manager was not set");
645 const std::string&
id)
648 if (inputFile.size() == 0) {
650 "input file is null");
653 ifstream fin(path.c_str());
656 +path+
" for reading.");
668 "ERROR: Can not find phase named " +
669 id +
" in file named " + inputFile);
675 throw CanteraError(
"ThermoPhase::initThermoFile",
"importPhase failed ");
697 for (
size_t k = 0; k <
m_kk; k++) {
704 for (
size_t k = 0; k <
m_kk; k++) {
707 if (fabs(sum) > 1.0E-11) {
708 throw CanteraError(
"ThermoPhase::setReferenceComposition",
709 "input mole fractions don't sum to 1.0");
716 for (
size_t k = 0; k <
m_kk; k++) {
726 "Number of species is equal to zero");
746 "m_speciesData is the wrong size");
762 if (state.
hasChild(
"temperature")) {
763 double t =
getFloat(state,
"temperature",
"temperature");
767 double p =
getFloat(state,
"pressure",
"pressure");
771 double rho =
getFloat(state,
"density",
"density");
780 if (lambda.size() < mm) {
781 throw CanteraError(
"setElementPotentials",
"lambda too small");
786 for (
size_t m = 0; m < mm; m++) {
796 for (
size_t m = 0; m <
nElements(); m++) {
805 for (
size_t m = 0; m <
m_kk; m++) {
806 for (
size_t k = 0; k <
m_kk; k++) {
807 dlnActCoeffdlnN[ld * k + m] = 0.0;
813 void ThermoPhase::getdlnActCoeffdlnN_numderiv(
const size_t ld, doublereal*
const dlnActCoeffdlnN)
815 double deltaMoles_j = 0.0;
821 std::vector<double> ActCoeff_Base(
m_kk);
823 std::vector<double> Xmol_Base(
m_kk);
827 std::vector<double> ActCoeff(
m_kk);
828 std::vector<double> Xmol(
m_kk);
829 double v_totalMoles = 1.0;
830 double TMoles_base = v_totalMoles;
835 for (
size_t j = 0; j <
m_kk; j++) {
843 double moles_j_base = v_totalMoles * Xmol_Base[j];
844 deltaMoles_j = 1.0E-7 * moles_j_base + v_totalMoles * 1.0E-13 + 1.0E-150;
849 v_totalMoles = TMoles_base + deltaMoles_j;
850 for (
size_t k = 0; k <
m_kk; k++) {
851 Xmol[k] = Xmol_Base[k] * TMoles_base / v_totalMoles;
853 Xmol[j] = (moles_j_base + deltaMoles_j) / v_totalMoles;
865 double*
const lnActCoeffCol = dlnActCoeffdlnN + ld * j;
866 for (
size_t k = 0; k <
m_kk; k++) {
867 lnActCoeffCol[k] = (2*moles_j_base + deltaMoles_j) *(ActCoeff[k] - ActCoeff_Base[k]) /
868 ((ActCoeff[k] + ActCoeff_Base[k]) * deltaMoles_j);
873 v_totalMoles = TMoles_base;
891 sprintf(p,
" \n %s:\n",
name().c_str());
894 sprintf(p,
" \n temperature %12.6g K\n",
temperature());
896 sprintf(p,
" pressure %12.6g Pa\n",
pressure());
898 sprintf(p,
" density %12.6g kg/m^3\n",
density());
905 sprintf(p,
" potential %12.6g V\n", phi);
911 sprintf(p,
" 1 kg 1 kmol\n");
913 sprintf(p,
" ----------- ------------\n");
915 sprintf(p,
" enthalpy %12.6g %12.4g J\n",
918 sprintf(p,
" internal energy %12.6g %12.4g J\n",
921 sprintf(p,
" entropy %12.6g %12.4g J/K\n",
924 sprintf(p,
" Gibbs function %12.6g %12.4g J\n",
927 sprintf(p,
" heat capacity c_p %12.6g %12.4g J/K\n",
931 sprintf(p,
" heat capacity c_v %12.6g %12.4g J/K\n",
936 sprintf(p,
" heat capacity c_v <not implemented> \n");
953 " Y Chem. Pot. / RT \n");
955 sprintf(p,
" ------------- "
956 "------------ ------------\n");
958 for (
size_t k = 0; k < kk; k++) {
960 sprintf(p,
"%18s %12.6g %12.6g %12.6g\n",
963 sprintf(p,
"%18s %12.6g %12.6g \n",
972 sprintf(p,
" -------------"
975 for (
size_t k = 0; k < kk; k++) {
976 sprintf(p,
"%18s %12.6g %12.6g\n",
993 csvFile.precision(8);
998 std::vector<std::string> pNames;
999 std::vector<vector_fp> data;
1002 csvFile << setw(tabS) <<
"Species,";
1003 for (
size_t i = 0; i < pNames.size(); i++) {
1004 csvFile << setw(tabM) << pNames[i] <<
",";
1007 for (
size_t k = 0; k <
nSpecies(); k++) {
1010 for (
size_t i = 0; i < pNames.size(); i++) {
1011 csvFile << setw(tabM) << data[i][k] <<
",";
1015 for (
size_t i = 0; i < pNames.size(); i++) {
1016 csvFile << setw(tabM) << 0 <<
",";
1024 std::vector<vector_fp>& data)
const
1029 names.push_back(
"X");
1032 names.push_back(
"Y");
1035 names.push_back(
"Chem. Pot (J/kmol)");
1038 names.push_back(
"Activity");
1041 names.push_back(
"Act. Coeff.");
1044 names.push_back(
"Part. Mol Enthalpy (J/kmol)");
1047 names.push_back(
"Part. Mol. Entropy (J/K/kmol)");
1050 names.push_back(
"Part. Mol. Energy (J/kmol)");
1053 names.push_back(
"Part. Mol. Cp (J/K/kmol");
1056 names.push_back(
"Part. Mol. Cv (J/K/kmol)");
std::map< std::string, doublereal > compositionMap
Map connecting a string name with a double.
virtual void setState_HP(doublereal h, doublereal p, doublereal tol=1.e-4)
Set the internally stored specific enthalpy (J/kg) and pressure (Pa) of the phase.
ThermoPhase()
Constructor.
virtual doublereal density() const
Density (kg/m^3).
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
doublereal electricPotential() const
Returns the electric potential of this phase (V).
doublereal err(const std::string &msg) const
Error function that gets called for unhandled cases.
virtual doublereal gibbs_mole() const
Molar Gibbs function. Units: J/kmol.
XML_Node * findXMLPhase(XML_Node *root, const std::string &idtarget)
Search an XML_Node tree for a named phase XML_Node.
size_t nElements() const
Number of elements.
std::vector< const XML_Node * > m_speciesData
Vector of pointers to the species databases.
void getMassFractions(doublereal *const y) const
Get the species mass fractions.
virtual void setState_TPX(doublereal t, doublereal p, const doublereal *x)
Set the temperature (K), pressure (Pa), and mole fractions.
virtual void initThermo()
Initialize the ThermoPhase object after all species have been set up.
ThermoPhase & operator=(const ThermoPhase &right)
Assignment operator.
const int cAC_CONVENTION_MOLAR
Standard state uses the molar convention.
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
void setState_HPorUV(doublereal h, doublereal p, doublereal tol=1.e-4, bool doUV=false)
Carry out work in HP and UV calculations.
virtual void reportCSV(std::ofstream &csvFile) const
returns a summary of the state of the phase to a comma separated file.
const int cSS_CONVENTION_TEMPERATURE
Standard state uses the molar convention.
Class XML_Node is a tree-based representation of the contents of an XML file.
void setState_conditional_TP(doublereal t, doublereal p, bool set_p)
Helper function used by setState_HPorUV and setState_SPorSV.
T clip(const T &value, const T &lower, const T &upper)
Clip value such that lower <= value <= upper.
doublereal getFloat(const Cantera::XML_Node &parent, const std::string &name, const std::string &type)
Get a floating-point value from a child element.
Base class for phases of matter.
vector_fp m_lambdaRRT
Vector of element potentials.
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
void getMoleFractions(doublereal *const x) const
Get the species mole fraction vector.
void saveSpeciesData(const size_t k, const XML_Node *const data)
Store a reference pointer to the XML tree containing the species data for this phase.
std::string name() const
Return the name of the phase.
Pure Virtual base class for the species thermo manager classes.
virtual void setState_PY(doublereal p, doublereal *y)
Set the internally stored pressure (Pa) and mass fractions.
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
virtual doublereal standardConcentration(size_t k=0) const
Return the standard concentration for the kth species.
doublereal intEnergy_mass() const
Specific internal energy.
Base class for a phase with thermodynamic properties.
virtual void setReferenceComposition(const doublereal *const x)
Sets the reference composition.
bool getElementPotentials(doublereal *lambda) const
Returns the element potentials stored in the ThermoPhase object.
void setMassFractionsByName(compositionMap &yMap)
Set the species mass fractions by name.
bool m_chargeNeutralityNecessary
Boolean indicating whether a charge neutrality condition is a necessity.
virtual void setStateFromXML(const XML_Node &state)
Set the initial state of the phase to the conditions specified in the state XML element.
bool importPhase(XML_Node &phase, ThermoPhase *th, SpeciesThermoFactory *spfactory)
Import a phase information into an empty thermophase object.
virtual doublereal intEnergy_mole() const
Molar internal energy. Units: J/kmol.
virtual void getActivities(doublereal *a) const
Get the array of non-dimensional activities at the current solution temperature, pressure, and solution concentration.
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
doublereal gibbs_mass() const
Specific Gibbs function.
doublereal entropy_mass() const
Specific entropy.
doublereal m_phi
Stored value of the electric potential for this phase.
virtual void getUnitsStandardConc(double *uA, int k=0, int sizeUA=6) const
Returns the units of the standard and generalized concentrations.
virtual ThermoPhase * duplMyselfAsThermoPhase() const
Duplication routine for objects which inherit from ThermoPhase.
virtual doublereal maxTemp(size_t k=npos) const
Maximum temperature for which the thermodynamic data for the species are valid.
std::string fp2str(const double x, const std::string &fmt)
Convert a double into a c++ string.
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
doublereal cp_mass() const
Specific heat at constant pressure.
virtual void setState_SP(doublereal s, doublereal p, doublereal tol=1.e-4)
Set the specific entropy (J/kg/K) and pressure (Pa).
virtual void setState_TPY(doublereal t, doublereal p, const doublereal *y)
Set the internally stored temperature (K), pressure (Pa), and mass fractions of the phase...
virtual void getCsvReportData(std::vector< std::string > &names, std::vector< vector_fp > &data) const
Fills names and data with the column names and species thermo properties to be included in the output...
int m_ssConvention
Contains the standard state convention.
virtual void getReferenceComposition(doublereal *const x) const
Gets the reference composition.
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies of the species in the solution.
Base class for exceptions thrown by Cantera classes.
void setMoleFractionsByName(compositionMap &xMap)
Set the species mole fractions by name.
compositionMap parseCompString(const std::string &ss, const std::vector< std::string > &names)
Parse a composition string into a map consisting of individual key:composition pairs.
doublereal cv_mass() const
Specific heat at constant volume.
void setElementPotentials(const vector_fp &lambda)
Stores the element potentials in the ThermoPhase object.
virtual void setMoleFractions(const doublereal *const x)
Set the mole fractions to the specified values There is no restriction on the sum of the mole fractio...
virtual void setState_UV(doublereal u, doublereal v, doublereal tol=1.e-4)
Set the specific internal energy (J/kg) and specific volume (m^3/kg).
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
virtual std::string report(bool show_thermo=true) const
returns a summary of the state of the phase as a string
virtual void getPartialMolarIntEnergies(doublereal *ubar) const
Return an array of partial molar internal energies for the species in the mixture.
virtual void setState_TP(doublereal t, doublereal p)
Set the temperature (K) and pressure (Pa)
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
size_t nSpecies() const
Returns the number of species in the phase.
virtual doublereal pressure() const
Return the thermodynamic pressure (Pa).
virtual void installSlavePhases(Cantera::XML_Node *phaseNode)
Add in species from Slave phases.
const std::vector< std::string > & speciesNames() const
Return a const reference to the vector of species names.
virtual void setState_SV(doublereal s, doublereal v, doublereal tol=1.e-4)
Set the specific entropy (J/kg/K) and specific volume (m^3/kg).
doublereal temperature() const
Temperature (K).
size_t nDim() const
Returns the number of spatial dimensions (1, 2, or 3)
virtual void getActivityConcentrations(doublereal *c) const
This method returns an array of generalized concentrations.
virtual void setPressure(doublereal p)
Set the internally stored pressure (Pa) at constant temperature and composition.
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
const doublereal SmallNumber
smallest number to compare to zero.
virtual int standardStateConvention() const
This method returns the convention used in specification of the standard state, of which there are cu...
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
void setState_SPorSV(doublereal s, doublereal p, doublereal tol=1.e-4, bool doSV=false)
Carry out work in SP and SV calculations.
virtual void getLnActivityCoefficients(doublereal *lnac) const
Get the array of non-dimensional molar-based ln activity coefficients at the current solution tempera...
virtual int eosType() const
Equation of state type flag.
virtual void setTemperature(const doublereal temp)
Set the internally stored temperature of the phase (K).
doublereal enthalpy_mass() const
Specific enthalpy.
doublereal meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
virtual void getActivityCoefficients(doublereal *ac) const
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
virtual void setState_PX(doublereal p, doublereal *x)
Set the pressure (Pa) and mole fractions.
virtual int activityConvention() const
This method returns the convention used in specification of the activities, of which there are curren...
const std::vector< const XML_Node * > & speciesData() const
Return a pointer to the vector of XML nodes containing the species data for this phase.
Contains declarations for string manipulation functions within Cantera.
std::vector< doublereal > xMol_Ref
Reference Mole Fraction Composition.
#define DATA_PTR(vec)
Creates a pointer to the start of the raw data for a vector.
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
virtual doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
virtual void setMassFractions(const doublereal *const y)
Set the mass fractions to the specified values and normalize them.
virtual SpeciesThermo & speciesThermo(int k=-1)
Return a changeable reference to the calculation manager for species reference-state thermodynamic pr...
virtual doublereal logStandardConc(size_t k=0) const
Natural logarithm of the standard concentration of the kth species.
size_t m_kk
Number of species in the phase.
virtual void getdlnActCoeffdlnN(const size_t ld, doublereal *const dlnActCoeffdlnN)
Get the array of derivatives of the log activity coefficients with respect to the log of the species ...
virtual void getPartialMolarCp(doublereal *cpbar) const
Return an array of partial molar heat capacities for the species in the mixture.
void setSpeciesThermo(SpeciesThermo *spthermo)
Install a species thermodynamic property manager.
virtual void initThermoFile(const std::string &inputFile, const std::string &id)
virtual ~ThermoPhase()
Destructor. Deletes the species thermo manager.
bool m_hasElementPotentials
Boolean indicating whether there is a valid set of saved element potentials for this phase...
std::string getChildValue(const Cantera::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...
Header file for class ThermoPhase, the base class for phases with thermodynamic properties, and the text for the Module thermoprops (see Thermodynamic Properties and class ThermoPhase).
SpeciesThermo * m_spthermo
Pointer to the calculation manager for species reference-state thermodynamic properties.
void build(std::istream &f)
Main routine to create an tree-like representation of an XML file.
std::string speciesName(size_t k) const
Name of the species with index k.
virtual void setDensity(const doublereal density_)
Set the internally stored density (kg/m^3) of the phase Note the density of a phase is an independent...
virtual doublereal minTemp(size_t k=npos) const
Minimum temperature for which the thermodynamic data for the species or phase are valid...
void save()
Function to put this error onto Cantera's error stack.