31 const std::string& id_) :
32 ionSolnType_(cIonSolnType_SINGLEANION),
33 numNeutralMoleculeSpecies_(0),
34 indexSpecialSpecies_(
npos)
40 const std::string& id_) :
41 ionSolnType_(cIonSolnType_SINGLEANION),
42 numNeutralMoleculeSpecies_(0),
43 indexSpecialSpecies_(
npos)
84 vector_fp& charges, std::vector<size_t>& neutMolIndex)
const
97 for (
size_t k = 0; k <
m_kk; k++) {
107 doublereal xx, fact2;
113 case cIonSolnType_PASSTHROUGH:
116 case cIonSolnType_SINGLEANION:
118 fact2 = 2.0 *
RT() * log(2.0);
133 mu[icat] =
RT() * log(xx);
144 case cIonSolnType_SINGLECATION:
145 throw CanteraError(
"IonsFromNeutralVPSSTP::getChemPotentials",
"Unknown type");
146 case cIonSolnType_MULTICATIONANION:
147 throw CanteraError(
"IonsFromNeutralVPSSTP::getChemPotentials",
"Unknown type");
149 throw CanteraError(
"IonsFromNeutralVPSSTP::getChemPotentials",
"Unknown type");
159 for (
size_t k = 0; k <
m_kk; k++) {
167 for (
size_t k = 0; k <
m_kk; k++) {
182 for (
size_t k = 0; k <
m_kk; k++) {
188 for (
size_t k = 0; k <
m_kk; k++) {
198 for (
size_t k = 0; k <
m_kk; k++) {
208 for (
size_t k = 0; k <
m_kk; k++) {
218 for (
size_t k = 0; k <
m_kk; k++) {
219 for (
size_t m = 0; m <
m_kk; m++) {
220 dlnActCoeffdlnN[ld * k + m] = data[
m_kk * k + m];
242 for (
size_t k = 0; k <
m_kk; k++) {
248 for (
size_t k = 0; k <
m_kk; k++) {
255 doublereal sum = 0.0;
256 for (
size_t k = 0; k <
m_kk; k++) {
259 for (
size_t k = 0; k <
m_kk; k++) {
268 doublereal sum = 0.0;
275 for (
size_t k = 0; k <
m_kk; k++) {
278 if (fabs(sum) > 1.0E-11) {
279 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
280 "molefracts don't sum to one: {}", sum);
284 case cIonSolnType_PASSTHROUGH:
285 for (
size_t k = 0; k <
m_kk; k++) {
290 case cIonSolnType_SINGLEANION:
313 for (
size_t k = 0; k <
m_kk; k++) {
317 for (
size_t k = 0; k <
m_kk; k++) {
322 for (
size_t k = 0; k <
m_kk; k++) {
326 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
327 "neutral molecule calc error");
331 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
332 "neutral molecule calc error - anion");
348 case cIonSolnType_SINGLECATION:
349 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
"Unknown type");
351 case cIonSolnType_MULTICATIONANION:
352 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
"Unknown type");
355 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
"Unknown type");
362 doublereal sumy, sumdy;
373 case cIonSolnType_PASSTHROUGH:
374 for (
size_t k = 0; k <
m_kk; k++) {
379 case cIonSolnType_SINGLEANION:
387 const doublereal temp = 1.0/fmij;
388 dy[jNeut] += dx[icat] * temp;
397 const doublereal temp = 1.0/fmij;
398 dy[jNeut] += dx[icat] * temp;
410 dy[k] = dy[k] * sumy - y_[k]*sumdy*sumy*sumy;
415 case cIonSolnType_SINGLECATION:
416 throw CanteraError(
"IonsFromNeutralVPSSTP::getNeutralMoleculeMoleGrads",
419 case cIonSolnType_MULTICATIONANION:
420 throw CanteraError(
"IonsFromNeutralVPSSTP::getNeutralMoleculeMoleGrads",
424 throw CanteraError(
"IonsFromNeutralVPSSTP::getNeutralMoleculeMoleGrads",
450 const size_t nElementsN,
451 const std::vector<std::string>& elnamesVI ,
453 const size_t nElementsI)
455 double fMax = 1.0E100;
456 for (
size_t mi = 0; mi < nElementsI; mi++) {
457 if (elnamesVI[mi] !=
"E" && elemVectorI[mi] > 1.0E-13) {
458 double eiNum = elemVectorI[mi];
459 for (
size_t mn = 0; mn < nElementsN; mn++) {
460 if (elnamesVI[mi] == elnamesVN[mn]) {
461 if (elemVectorN[mn] <= 1.0E-13) {
464 fMax = std::min(fMax, elemVectorN[mn]/eiNum);
482 string neutralName =
m_input[
"neutral-phase"].asString();
483 const auto& slash = boost::ifind_last(neutralName,
"/");
485 string fileName(neutralName.begin(), slash.begin());
486 neutralName = string(slash.end(), neutralName.end());
489 AnyMap& phaseNode = infile[
"phases"].getMapWhere(
"name", neutralName);
490 setNeutralMoleculePhase(
newPhase(phaseNode, infile));
499 "IonsFromNeutralVPSSTP::initThermo",
500 "The neutral phase has not been initialized. Are you missing the "
501 "'neutral-phase' key?"
510 const std::vector<std::string>& elnamesVI =
elementNames();
515 "IonsFromNeutralVPSSTP::initThermo",
516 "No special-species were specified in the phase."
519 for (
size_t m = 0; m < nElementsI; m++) {
524 for (
size_t m = 0; m < nElementsN; m++) {
528 double fac =
factorOverlap(elnamesVN, elemVectorN, nElementsN,
529 elnamesVI ,elemVectorI, nElementsI);
531 for (
size_t m = 0; m < nElementsN; m++) {
532 for (
size_t mi = 0; mi < nElementsI; mi++) {
533 if (elnamesVN[m] == elnamesVI[mi]) {
534 elemVectorN[m] -= fac * elemVectorI[mi];
542 for (
size_t k = 0; k <
m_kk; k++) {
543 for (
size_t m = 0; m < nElementsI; m++) {
544 elemVectorI[m] =
nAtoms(k, m);
547 elnamesVI ,elemVectorI, nElementsI);
549 for (
size_t m = 0; m < nElementsN; m++) {
550 for (
size_t mi = 0; mi < nElementsI; mi++) {
551 if (elnamesVN[m] == elnamesVI[mi]) {
552 elemVectorN[m] -= fac * elemVectorI[mi];
556 bool notTaken =
true;
557 for (
size_t iNeut = 0; iNeut < jNeut; iNeut++) {
566 "Simple formula matrix generation failed, one cation is shared between two salts");
573 for (
size_t m = 0; m < nElementsN; m++) {
574 if (fabs(elemVectorN[m]) > 1.0E-13) {
576 "Simple formula matrix generation failed");
592void IonsFromNeutralVPSSTP::setNeutralMoleculePhase(shared_ptr<ThermoPhase> neutral)
608 for (
size_t k = 0; k <
nSpecies(); k++) {
613shared_ptr<ThermoPhase> IonsFromNeutralVPSSTP::getNeutralMoleculePhase()
624 m_work.push_back(0.0);
628 if (spec->charge > 0) {
630 }
else if (spec->charge < 0) {
636 if (spec->input.hasKey(
"equation-of-state")) {
637 auto& ss = spec->input[
"equation-of-state"].getMapWhere(
638 "model",
"ions-from-neutral-molecule");
639 if (ss.getBool(
"special-species",
false)) {
651 if (!thermoNode.
hasChild(
"neutralMoleculePhase")) {
652 throw CanteraError(
"IonsFromNeutralVPSSTP::setParametersFromXML",
653 "no neutralMoleculePhase XML node");
655 XML_Node& neutralMoleculeNode = thermoNode.
child(
"neutralMoleculePhase");
659 throw CanteraError(
"IonsFromNeutralVPSSTP::setParametersFromXML",
663 setNeutralMoleculePhase(shared_ptr<ThermoPhase>(
newPhase(*neut_ptr)));
673 case cIonSolnType_PASSTHROUGH:
675 case cIonSolnType_SINGLEANION:
698 case cIonSolnType_SINGLECATION:
699 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff",
"Unimplemented type");
701 case cIonSolnType_MULTICATIONANION:
702 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff",
"Unimplemented type");
705 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff",
"Unimplemented type");
711 doublereal* dlnActCoeffds)
const
716 for (
size_t k = 0; k <
m_kk; k++) {
725 geThermo->
getdlnActCoeffds(dTds, dX_NeutralMolecule_.data(), dlnActCoeff_NeutralMolecule_.data());
728 case cIonSolnType_PASSTHROUGH:
730 case cIonSolnType_SINGLEANION:
737 dlnActCoeffds[icat] = dlnActCoeff_NeutralMolecule_[jNeut]/fmij;
743 dlnActCoeffds[icat]= 0.0;
749 dlnActCoeffds[icat] = dlnActCoeff_NeutralMolecule_[jNeut];
753 case cIonSolnType_SINGLECATION:
754 throw CanteraError(
"IonsFromNeutralVPSSTP::getdlnActCoeffds",
"Unimplemented type");
756 case cIonSolnType_MULTICATIONANION:
757 throw CanteraError(
"IonsFromNeutralVPSSTP::getdlnActCoeffds",
"Unimplemented type");
760 throw CanteraError(
"IonsFromNeutralVPSSTP::getdlnActCoeffds",
"Unimplemented type");
778 case cIonSolnType_PASSTHROUGH:
780 case cIonSolnType_SINGLEANION:
803 case cIonSolnType_SINGLECATION:
804 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeffdT",
"Unimplemented type");
806 case cIonSolnType_MULTICATIONANION:
807 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeffdT",
"Unimplemented type");
810 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeffdT",
"Unimplemented type");
828 case cIonSolnType_PASSTHROUGH:
830 case cIonSolnType_SINGLEANION:
853 case cIonSolnType_SINGLECATION:
854 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnX_diag",
"Unimplemented type");
856 case cIonSolnType_MULTICATIONANION:
857 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnX_diag",
"Unimplemented type");
860 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnX_diag",
"Unimplemented type");
878 case cIonSolnType_PASSTHROUGH:
880 case cIonSolnType_SINGLEANION:
903 case cIonSolnType_SINGLECATION:
904 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnN_diag",
"Unimplemented type");
906 case cIonSolnType_MULTICATIONANION:
907 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnN_diag",
"Unimplemented type");
910 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnN_diag",
"Unimplemented type");
917 size_t kcat = 0, kNeut = 0, mcat = 0, mNeut = 0;
918 doublereal fmij = 0.0;
922 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnN",
"dynamic cast failed");
924 size_t nsp_ge = geThermo->
nSpecies();
928 case cIonSolnType_PASSTHROUGH:
930 case cIonSolnType_SINGLEANION:
957 for (
size_t k = 0; k <
m_kk; k++) {
968 for (
size_t m = 0; m <
m_kk; m++) {
982 case cIonSolnType_SINGLECATION:
983 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnN",
"Unimplemented type");
985 case cIonSolnType_MULTICATIONANION:
986 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnN",
"Unimplemented type");
989 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnN",
"Unimplemented type");
Header for intermediate ThermoPhase object for phases which consist of ions whose thermodynamics is c...
Declarations for the class PDSS_IonsFromNeutral ( which handles calculations for a single ion in a fl...
Declaration for class Cantera::Species.
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.
const std::string & getString(const std::string &key, const std::string &default_) const
If key exists, return it as a string, otherwise return default_.
static AnyMap fromYamlFile(const std::string &name, const std::string &parent_name="")
Create an AnyMap from a YAML file.
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.
virtual bool addSpecies(shared_ptr< Species > spec)
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 ...
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 moleFractions_
Storage for the current values of the mole fractions of the species.
vector_fp dlnActCoeffdlnN_diag_
Storage for the current derivative values of the gradients with respect to logarithm of the mole frac...
virtual void compositionChanged()
Apply changes to the state which are needed after the composition changes.
virtual void getdlnActCoeffdT(doublereal *dlnActCoeffdT) const
Get the array of temperature derivatives of the log activity coefficients.
vector_fp dlnActCoeffdT_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
AnyMap m_rootNode
Root node of the AnyMap which contains this phase definition.
virtual bool addSpecies(shared_ptr< Species > spec)
virtual void setParameters(const AnyMap &phaseNode, const AnyMap &rootNode=AnyMap())
Set equation of state parameters from an AnyMap phase description.
virtual void getParameters(AnyMap &phaseNode) const
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
vector_fp dlnActCoeffdT_NeutralMolecule_
Storage vector for the neutral molecule d ln activity coefficients dT.
virtual void getActivityCoefficients(doublereal *ac) const
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
vector_fp lnActCoeff_NeutralMolecule_
Storage vector for the neutral molecule ln activity coefficients.
virtual void calcNeutralMoleculeMoleFractions() const
Calculate neutral molecule mole fractions.
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.
void getNeutralMoleculeMoleGrads(const doublereal *const dx, doublereal *const dy) const
Calculate neutral molecule mole fractions.
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies for the species in the mixture.
vector_fp moleFractionsTmp_
Temporary mole fraction vector.
std::vector< size_t > passThroughList_
List of the species in this ThermoPhase which are passed through to the neutralMoleculePhase ThermoPh...
virtual doublereal enthalpy_mole() const
Return the Molar enthalpy. Units: J/kmol.
void s_update_dlnActCoeff_dlnN_diag() const
Update the derivative of the log of the activity coefficients wrt log(number of moles) - diagonal com...
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 ...
vector_fp muNeutralMolecule_
Storage vector for the neutral molecule chemical potentials.
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...
IonsFromNeutralVPSSTP(const std::string &inputFile="", const std::string &id="")
Construct an IonsFromNeutralVPSSTP object from an input file.
virtual void calcIonMoleFractions(doublereal *const mf) const
Calculate ion mole fractions from neutral molecule mole fractions.
size_t indexSpecialSpecies_
Index of special species.
vector_fp NeutralMolecMoleFractions_
Mole fractions using the Neutral Molecule Mole fraction basis.
vector_fp fm_neutralMolec_ions_
Formula Matrix for composition of neutral molecules in terms of the molecules in this ThermoPhase.
void getDissociationCoeffs(vector_fp &fm_neutralMolec_ions, vector_fp &charges, std::vector< size_t > &neutMolIndex) const
Get the Salt Dissociation Coefficients.
vector_fp dlnActCoeffdlnN_diag_NeutralMolecule_
Storage vector for the neutral molecule d ln activity coefficients dlnN.
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
std::vector< size_t > cationList_
List of the species in this ThermoPhase which are cation species.
Array2D dlnActCoeffdlnN_NeutralMolecule_
Storage vector for the neutral molecule d ln activity coefficients dlnN.
virtual void initThermo()
void s_update_dlnActCoeff_dlnN() const
Update the derivative of the log of the activity coefficients wrt log(number of moles) - diagonal com...
shared_ptr< ThermoPhase > neutralMoleculePhase_
This is a pointer to the neutral Molecule Phase.
size_t numNeutralMoleculeSpecies_
Number of neutral molecule species.
virtual doublereal gibbs_mole() const
Molar Gibbs function. Units: J/kmol.
std::vector< size_t > fm_invert_ionForNeutral
Mapping between ion species and neutral molecule for quick invert.
vector_fp dlnActCoeffdlnX_diag_NeutralMolecule_
Storage vector for the neutral molecule d ln activity coefficients dX - diagonal component.
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,...
virtual void compositionChanged()
Apply changes to the state which are needed after the composition changes.
void s_update_dlnActCoeff_dlnX_diag() const
Update the derivative of the log of the activity coefficients wrt log(mole fraction)
void s_update_lnActCoeff() const
Update the activity coefficients.
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
void s_update_dlnActCoeffdT() const
Update the temperature derivative of the ln activity coefficients.
IonSolnType_enumType ionSolnType_
Ion solution type.
virtual void setParametersFromXML(const XML_Node &thermoNode)
Set equation of state parameter values from XML entries.
virtual void calcDensity()
Calculate the density of the mixture using the partial molar volumes and mole fractions as input.
std::vector< size_t > anionList_
List of the species in this ThermoPhase which are anion species.
virtual void setParent(VPStandardStateTP *phase, size_t k)
Set the parent VPStandardStateTP object of this PDSS object.
void assignDensity(const double density_)
Set the internally stored constant density (kg/m^3) of the phase.
doublereal mean_X(const doublereal *const Q) const
Evaluate the mole-fraction-weighted mean of an array Q.
vector_fp m_speciesCharge
Vector of species charges. length m_kk.
size_t nSpecies() const
Returns the number of species in the phase.
size_t m_kk
Number of species in the phase.
doublereal nAtoms(size_t k, size_t m) const
Number of atoms of element m in species k.
const std::vector< std::string > & elementNames() const
Return a read-only reference to the vector of element names.
doublereal temperature() const
Temperature (K).
size_t nElements() const
Number of elements.
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
void initThermoFile(const std::string &inputFile, const std::string &id)
virtual void getPartialMolarCp(doublereal *cpbar) const
Return an array of partial molar heat capacities for the species in the mixture.
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 getdlnActCoeffds(const doublereal dTds, const doublereal *const dXds, doublereal *dlnActCoeffds) const
Get the change in activity coefficients wrt changes in state (temp, mole fraction,...
AnyMap m_input
Data supplied via setParameters.
virtual void setParameters(int n, doublereal *const c)
Set the equation of state parameters.
virtual void setParametersFromXML(const XML_Node &eosdata)
Set equation of state parameter values from XML entries.
virtual void getParameters(int &n, doublereal *const c) const
Get the equation of state parameters in a vector.
virtual void getdlnActCoeffdlnN_diag(doublereal *dlnActCoeffdlnN_diag) const
Get the array of log species mole number derivatives of the log activity coefficients.
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 doublereal pressure() const
Returns the current pressure of the phase.
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.
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
#define AssertTrace(expr)
Assertion must be true or an error is thrown.
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"
XML_Node * get_XML_Node(const std::string &file_ID, XML_Node *root)
This routine will locate an XML node in either the input XML tree or in another input file specified ...
const double SmallNumber
smallest number to compare to zero.
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].
static double factorOverlap(const std::vector< std::string > &elnamesVN, const vector_fp &elemVectorN, const size_t nElementsN, const std::vector< std::string > &elnamesVI, const vector_fp &elemVectorI, const size_t nElementsI)
Return the factor overlap.
Contains declarations for string manipulation functions within Cantera.