22 const std::string& id_) :
23 numBinaryInteractions_(0),
24 formRedlichKister_(0),
31 const std::string& id_) :
32 numBinaryInteractions_(0),
33 formRedlichKister_(0),
46 for (
size_t k = 0; k <
m_kk; k++) {
61 for (
size_t k = 0; k <
m_kk; k++) {
72 for (
size_t i = 0; i <
m_kk; i++) {
83 for (
size_t i = 0; i <
m_kk; i++) {
94 for (
size_t i = 0; i <
m_kk; i++) {
111 for (
size_t k = 0; k <
m_kk; k++) {
119 for (
size_t k = 0; k <
m_kk; k++) {
134 for (
size_t k = 0; k <
m_kk; k++) {
138 for (
size_t k = 0; k <
m_kk; k++) {
154 for (
size_t k = 0; k <
m_kk; k++) {
159 for (
size_t k = 0; k <
m_kk; k++) {
168 for (
size_t iK = 0; iK <
m_kk; iK++) {
176 for (
const auto& item :
m_input[
"interactions"].asVector<AnyMap>()) {
177 auto&
species = item[
"species"].asVector<
string>(2);
178 vector_fp h_excess = item.convertVector(
"excess-enthalpy",
"J/kmol");
179 vector_fp s_excess = item.convertVector(
"excess-entropy",
"J/kmol/K");
181 h_excess.data(), h_excess.size(),
182 s_excess.data(), s_excess.size());
192 vector<AnyMap> interactions;
195 interaction[
"species"] = vector<std::string>{
199 while (h.size() > 1 && h.back() == 0) {
202 while (s.size() > 1 && s.back() == 0) {
205 interaction[
"excess-enthalpy"].setQuantity(std::move(h),
"J/kmol");
206 interaction[
"excess-entropy"].setQuantity(std::move(s),
"J/kmol/K");
207 interactions.push_back(std::move(interaction));
209 phaseNode[
"interactions"] = std::move(interactions);
219 if ((
int) id_.size() > 0 && phaseNode.
id() != id_) {
220 throw CanteraError(
"RedlichKisterVPSSTP::initThermoXML",
221 "phasenode and Id are incompatible");
226 if (!phaseNode.
hasChild(
"thermo")) {
227 throw CanteraError(
"RedlichKisterVPSSTP::initThermoXML",
228 "no thermo XML node");
232 throw CanteraError(
"RedlichKisterVPSSTP::initThermoXML",
233 "Unknown thermo model: " + thermoNode[
"model"]
234 +
" - This object only knows \"Redlich-Kister\" ");
239 if (thermoNode.
hasChild(
"activityCoefficients")) {
242 throw CanteraError(
"RedlichKisterVPSSTP::initThermoXML",
243 "Unknown activity coefficient model: " + acNode[
"model"]);
245 for (
size_t i = 0; i < acNode.
nChildren(); i++) {
274 doublereal deltaX = XA - XB;
278 doublereal poly = 1.0;
279 doublereal polyMm1 = 1.0;
280 doublereal sum = 0.0;
281 doublereal sumMm1 = 0.0;
282 doublereal sum2 = 0.0;
283 for (
size_t m = 0; m < N; m++) {
284 doublereal A_ge = (he_vec[m] - T * se_vec[m]) / (
GasConstant * T);
286 sum2 += A_ge * (m + 1) * poly;
289 sumMm1 += (A_ge * polyMm1 * m);
293 doublereal oneMXA = 1.0 - XA;
294 doublereal oneMXB = 1.0 - XB;
295 for (
size_t k = 0; k <
m_kk; k++) {
298 }
else if (iB == k) {
318 doublereal deltaX = XA - XB;
320 doublereal poly = 1.0;
321 doublereal sum = 0.0;
323 doublereal sumMm1 = 0.0;
324 doublereal polyMm1 = 1.0;
325 doublereal sum2 = 0.0;
326 for (
size_t m = 0; m < N; m++) {
327 doublereal A_ge = - se_vec[m];
329 sum2 += A_ge * (m + 1) * poly;
332 sumMm1 += (A_ge * polyMm1 * m);
336 doublereal oneMXA = 1.0 - XA;
337 doublereal oneMXB = 1.0 - XB;
338 for (
size_t k = 0; k <
m_kk; k++) {
341 }
else if (iB == k) {
353 for (
size_t k = 0; k <
m_kk; k++) {
361 for (
size_t k = 0; k <
m_kk; k++) {
376 double deltaX = XA - XB;
383 double polyMm1 = 1.0;
384 double polyMm2 = 1.0;
386 for (
size_t m = 0; m < N; m++) {
387 double A_ge = (he_vec[m] - T * se_vec[m]) / (
GasConstant * T);;
391 sumMm1 += (A_ge * polyMm1 * m);
395 sumMm2 += (A_ge * polyMm2 * m * (m - 1.0));
400 for (
size_t k = 0; k <
m_kk; k++) {
403 XA * (- (1-XA+XB) * sum + 2*(1.0 - XA) * XB * sumMm1
404 + sumMm1 * (XB * (1 - 2*XA + XB) - XA * (1 - XA + 2*XB))
405 + 2 * XA * XB * sumMm2 * (1.0 - XA + XB));
406 }
else if (iB == k) {
408 XB * (- (1-XB+XA) * sum - 2*(1.0 - XB) * XA * sumMm1
409 + sumMm1 * (XA * (2*XB - XA - 1) - XB * (-2*XA + XB - 1))
410 - 2 * XA * XB * sumMm2 * (-XA - 1 + XB));
426 doublereal deltaX = XA - XB;
428 doublereal poly = 1.0;
429 doublereal sum = 0.0;
432 doublereal sumMm1 = 0.0;
433 doublereal polyMm1 = 1.0;
434 doublereal polyMm2 = 1.0;
435 doublereal sum2 = 0.0;
436 doublereal sum2Mm1 = 0.0;
437 doublereal sumMm2 = 0.0;
438 for (
size_t m = 0; m < N; m++) {
439 doublereal A_ge = he_vec[m] - T * se_vec[m];
441 sum2 += A_ge * (m + 1) * poly;
444 sumMm1 += (A_ge * polyMm1 * m);
445 sum2Mm1 += (A_ge * polyMm1 * m * (1.0 + m));
449 sumMm2 += (A_ge * polyMm2 * m * (m - 1.0));
454 for (
size_t k = 0; k <
m_kk; k++) {
457 + XB * sumMm1 * (1.0 - 2.0 * XA + XB)
458 + XA * XB * sumMm2 * (1.0 - XA + XB));
461 + XA * sumMm1 * (1.0 + 2.0 * XB - XA)
462 - XA * XB * sumMm2 * (1.0 - XA + XB));
463 }
else if (iB == k) {
465 + XB * sumMm1 * (1.0 - 2.0 * XA + XB)
466 + XA * XB * sumMm2 * (1.0 - XA + XB));
469 + XA * sumMm1 * (XB - XA - (1.0 - XB))
470 - XA * XB * sumMm2 * (-XA - (1.0 - XB)));
480 doublereal* dlnActCoeffds)
const
484 for (
size_t k = 0; k <
m_kk; k++) {
486 for (
size_t j = 0; j <
m_kk; j++) {
495 for (
size_t j = 0; j <
m_kk; j++) {
497 for (
size_t k = 0; k <
m_kk; k++) {
506 for (
size_t k = 0; k <
m_kk; k++) {
515 for (
size_t k = 0; k <
m_kk; k++) {
516 for (
size_t m = 0; m <
m_kk; m++) {
517 dlnActCoeffdlnN[ld * k + m] = data[
m_kk * k + m];
524 std::string xname = xmLBinarySpecies.
name();
525 if (xname !=
"binaryNeutralSpeciesParameters") {
526 throw CanteraError(
"RedlichKisterVPSSTP::readXMLBinarySpecies",
527 "Incorrect name for processing this routine: " + xname);
530 std::string iName = xmLBinarySpecies.
attrib(
"speciesA");
532 throw CanteraError(
"RedlichKisterVPSSTP::readXMLBinarySpecies",
"no speciesA attrib");
534 std::string jName = xmLBinarySpecies.
attrib(
"speciesB");
536 throw CanteraError(
"RedlichKisterVPSSTP::readXMLBinarySpecies",
"no speciesB attrib");
543 if (iSpecies ==
npos) {
547 if (jSpecies ==
npos) {
552 for (
size_t iChild = 0; iChild < xmLBinarySpecies.
nChildren(); iChild++) {
557 if (nodeName ==
"excessenthalpy") {
558 getFloatArray(xmlChild, hParams,
true,
"toSI",
"excessEnthalpy");
559 }
else if (nodeName ==
"excessentropy") {
560 getFloatArray(xmlChild, sParams,
true,
"toSI",
"excessEntropy");
564 sParams.data(), sParams.size());
568 const std::string& speciesA,
const std::string& speciesB,
569 const double* excess_enthalpy,
size_t n_enthalpy,
570 const double* excess_entropy,
size_t n_entropy)
575 throw CanteraError(
"RedlichKisterVPSSTP::addBinaryInteraction",
576 "Species '{}' not present in phase", speciesA);
577 }
else if (kB ==
npos) {
578 throw CanteraError(
"RedlichKisterVPSSTP::addBinaryInteraction",
579 "Species '{}' not present in phase", speciesB);
582 throw CanteraError(
"RedlichKisterVPSSTP::addBinaryInteraction",
583 "Species '{}' should be neutral", speciesA);
584 }
else if (
charge(kB) != 0) {
585 throw CanteraError(
"RedlichKisterVPSSTP::addBinaryInteraction",
586 "Species '{}' should be neutral", speciesB);
591 m_HE_m_ij.emplace_back(excess_enthalpy, excess_enthalpy + n_enthalpy);
592 m_SE_m_ij.emplace_back(excess_entropy, excess_entropy + n_entropy);
593 size_t N = max(n_enthalpy, n_entropy);
(see Thermodynamic Properties and class RedlichKisterVPSSTP).
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
A map of string keys to values whose type can vary at runtime.
bool hasKey(const std::string &key) const
Returns true if the map contains an item named key.
void zero()
Set all of the entries to zero.
void resize(size_t n, size_t m, double v=0.0)
Resize the array, and fill the new entries with 'v'.
Base class for exceptions thrown by Cantera classes.
Array2D dlnActCoeffdlnN_
Storage for the current derivative values of the gradients with respect to logarithm of the species m...
vector_fp dlnActCoeffdlnX_diag_
Storage for the current derivative values of the gradients with respect to logarithm of the mole frac...
vector_fp lnActCoeff_Scaled_
Storage for the current values of the activity coefficients of the species.
vector_fp d2lnActCoeffdT2_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
vector_fp moleFractions_
Storage for the current values of the mole fractions of the species.
vector_fp dlnActCoeffdT_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
doublereal charge(size_t k) const
Dimensionless electrical charge of a single molecule of species k The charge is normalized by the the...
size_t m_kk
Number of species in the phase.
std::string speciesName(size_t k) const
Name of the species with index k.
doublereal temperature() const
Temperature (K).
size_t speciesIndex(const std::string &name) const
Returns the index of a species named 'name' within the Phase object.
shared_ptr< Species > species(const std::string &name) const
Return the Species object for the named species.
void s_update_dlnActCoeff_dX_() const
Internal routine that calculates the derivative of the activity coefficients wrt the mole fractions.
virtual void getParameters(AnyMap &phaseNode) const
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
Array2D dlnActCoeff_dX_
Two dimensional array of derivatives of activity coefficients wrt mole fractions.
virtual void getd2lnActCoeffdT2(doublereal *d2lnActCoeffdT2) const
Get the array of temperature second derivatives of the log activity coefficients.
virtual void getLnActivityCoefficients(doublereal *lnac) const
Get the array of non-dimensional molar-based ln activity coefficients at the current solution tempera...
virtual doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies for the species in the mixture.
RedlichKisterVPSSTP(const std::string &inputFile="", const std::string &id="")
Construct a RedlichKisterVPSSTP object from an input file.
virtual void getdlnActCoeffdT(doublereal *dlnActCoeffdT) const
Get the array of temperature derivatives of the log activity coefficients.
size_t numBinaryInteractions_
number of binary interaction expressions
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
std::vector< vector_fp > m_HE_m_ij
Enthalpy term for the binary mole fraction interaction of the excess Gibbs free energy expression.
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 ...
void readXMLBinarySpecies(XML_Node &xmlBinarySpecies)
Process an XML node called "binaryNeutralSpeciesParameters".
std::vector< size_t > m_N_ij
Vector of the length of the polynomial for the interaction.
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
virtual void getdlnActCoeffdlnX_diag(doublereal *dlnActCoeffdlnX_diag) const
Get the array of ln mole fraction derivatives of the log activity coefficients - diagonal component o...
virtual void getPartialMolarCp(doublereal *cpbar) const
Returns an array of partial molar entropies for the species in the mixture.
std::vector< size_t > m_pSpecies_A_ij
vector of species indices representing species A in the interaction
void s_update_dlnActCoeff_dT() const
Update the derivative of the log of the activity coefficients wrt T.
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
virtual void initThermo()
virtual void getdlnActCoeffdlnN_diag(doublereal *dlnActCoeffdlnN_diag) const
Get the array of log species mole number derivatives of the log activity coefficients.
virtual void getdlnActCoeffds(const doublereal dTds, const doublereal *const dXds, doublereal *dlnActCoeffds) const
Get the change in activity coefficients wrt changes in state (temp, mole fraction,...
std::vector< size_t > m_pSpecies_B_ij
vector of species indices representing species B in the interaction
void initLengths()
Initialize lengths of local variables after all species have been identified.
void s_update_dlnActCoeff_dlnX_diag() const
Internal routine that calculates the total derivative of the activity coefficients with respect to th...
void s_update_lnActCoeff() const
Update the activity coefficients.
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
std::vector< vector_fp > m_SE_m_ij
Entropy term for the binary mole fraction interaction of the excess Gibbs free energy expression.
void addBinaryInteraction(const std::string &speciesA, const std::string &speciesB, const double *excess_enthalpy, size_t n_enthalpy, const double *excess_entropy, size_t n_entropy)
Add a binary species interaction with the specified parameters.
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
void initThermoFile(const std::string &inputFile, const std::string &id)
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
AnyMap m_input
Data supplied via setParameters.
virtual void getParameters(int &n, doublereal *const c) const
Get the equation of state parameters in a vector.
virtual void getStandardVolumes(doublereal *vol) const
Get the molar volumes of the species standard states at the current T and P of the solution.
virtual void getCp_R(doublereal *cpr) const
Get the nondimensional Heat Capacities at constant pressure for the species standard states at the cu...
virtual void getEntropy_R(doublereal *sr) const
Get the array of nondimensional Entropy functions for the standard state species at the current T and...
virtual void initThermo()
virtual void getStandardChemPotentials(doublereal *mu) const
Get the array of chemical potentials at unit activity for the species at their standard states at the...
virtual void getEnthalpy_RT(doublereal *hrt) const
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
Class XML_Node is a tree-based representation of the contents of an XML file.
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
std::string name() const
Returns the name of the XML node.
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
std::string id() const
Return the id attribute, if present.
size_t nChildren(bool discardComments=false) const
Return the number of children.
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data.
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
Namespace for the Cantera kernel.
const size_t npos
index returned by functions to indicate "no position"
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
const double SmallNumber
smallest number to compare to zero.
std::string toLowerCopy(const std::string &input)
Convert to lower case.
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].
size_t getFloatArray(const XML_Node &node, vector_fp &v, const bool convert=true, const std::string &unitsString="", const std::string &nodeName="floatArray")
This function reads the current node or a child node of the current node with the default name,...
Contains declarations for string manipulation functions within Cantera.