29 IonsFromNeutralVPSSTP::IonsFromNeutralVPSSTP() :
30 ionSolnType_(cIonSolnType_SINGLEANION),
31 numNeutralMoleculeSpecies_(0),
32 indexSpecialSpecies_(
npos),
33 neutralMoleculePhase_(0),
39 const std::string& id_) :
40 ionSolnType_(cIonSolnType_SINGLEANION),
41 numNeutralMoleculeSpecies_(0),
42 indexSpecialSpecies_(
npos)
48 const std::string& id_) :
49 ionSolnType_(cIonSolnType_SINGLEANION),
50 numNeutralMoleculeSpecies_(0),
51 indexSpecialSpecies_(
npos)
92 vector_fp& charges, std::vector<size_t>& neutMolIndex)
const 105 for (
size_t k = 0; k <
m_kk; k++) {
115 doublereal xx, fact2;
121 case cIonSolnType_PASSTHROUGH:
124 case cIonSolnType_SINGLEANION:
126 fact2 = 2.0 *
RT() * log(2.0);
141 mu[icat] =
RT() * log(xx);
152 case cIonSolnType_SINGLECATION:
155 case cIonSolnType_MULTICATIONANION:
170 for (
size_t k = 0; k <
m_kk; k++) {
178 for (
size_t k = 0; k <
m_kk; k++) {
193 for (
size_t k = 0; k <
m_kk; k++) {
199 for (
size_t k = 0; k <
m_kk; k++) {
209 for (
size_t k = 0; k <
m_kk; k++) {
219 for (
size_t k = 0; k <
m_kk; k++) {
229 for (
size_t k = 0; k <
m_kk; k++) {
230 for (
size_t m = 0; m <
m_kk; m++) {
231 dlnActCoeffdlnN[ld * k + m] = data[
m_kk * k + m];
253 for (
size_t k = 0; k <
m_kk; k++) {
259 for (
size_t k = 0; k <
m_kk; k++) {
266 doublereal sum = 0.0;
267 for (
size_t k = 0; k <
m_kk; k++) {
270 for (
size_t k = 0; k <
m_kk; k++) {
279 doublereal sum = 0.0;
286 for (
size_t k = 0; k <
m_kk; k++) {
289 if (fabs(sum) > 1.0E-11) {
290 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
291 "molefracts don't sum to one: {}", sum);
295 case cIonSolnType_PASSTHROUGH:
296 for (
size_t k = 0; k <
m_kk; k++) {
301 case cIonSolnType_SINGLEANION:
324 for (
size_t k = 0; k <
m_kk; k++) {
328 for (
size_t k = 0; k <
m_kk; k++) {
333 for (
size_t k = 0; k <
m_kk; k++) {
337 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
338 "neutral molecule calc error");
342 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
343 "neutral molecule calc error - anion");
359 case cIonSolnType_SINGLECATION:
360 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
"Unknown type");
362 case cIonSolnType_MULTICATIONANION:
363 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
"Unknown type");
366 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
"Unknown type");
373 doublereal sumy, sumdy;
384 case cIonSolnType_PASSTHROUGH:
385 for (
size_t k = 0; k <
m_kk; k++) {
390 case cIonSolnType_SINGLEANION:
398 const doublereal temp = 1.0/fmij;
399 dy[jNeut] += dx[icat] * temp;
408 const doublereal temp = 1.0/fmij;
409 dy[jNeut] += dx[icat] * temp;
421 dy[k] = dy[k] * sumy - y_[k]*sumdy*sumy*sumy;
426 case cIonSolnType_SINGLECATION:
427 throw CanteraError(
"IonsFromNeutralVPSSTP::getNeutralMoleculeMoleGrads",
430 case cIonSolnType_MULTICATIONANION:
431 throw CanteraError(
"IonsFromNeutralVPSSTP::getNeutralMoleculeMoleGrads",
435 throw CanteraError(
"IonsFromNeutralVPSSTP::getNeutralMoleculeMoleGrads",
461 const size_t nElementsN,
462 const std::vector<std::string>& elnamesVI ,
464 const size_t nElementsI)
466 double fMax = 1.0E100;
467 for (
size_t mi = 0; mi < nElementsI; mi++) {
468 if (elnamesVI[mi] !=
"E" && elemVectorI[mi] > 1.0E-13) {
469 double eiNum = elemVectorI[mi];
470 for (
size_t mn = 0; mn < nElementsN; mn++) {
471 if (elnamesVI[mi] == elnamesVN[mn]) {
472 if (elemVectorN[mn] <= 1.0E-13) {
475 fMax = std::min(fMax, elemVectorN[mn]/eiNum);
490 const std::vector<std::string>& elnamesVI =
elementNames();
494 for (
size_t m = 0; m < nElementsN; m++) {
498 for (
size_t m = 0; m < nElementsI; m++) {
501 double fac =
factorOverlap(elnamesVN, elemVectorN, nElementsN,
502 elnamesVI ,elemVectorI, nElementsI);
504 for (
size_t m = 0; m < nElementsN; m++) {
505 for (
size_t mi = 0; mi < nElementsI; mi++) {
506 if (elnamesVN[m] == elnamesVI[mi]) {
507 elemVectorN[m] -= fac * elemVectorI[mi];
515 for (
size_t k = 0; k <
m_kk; k++) {
516 for (
size_t m = 0; m < nElementsI; m++) {
517 elemVectorI[m] =
nAtoms(k, m);
520 elnamesVI ,elemVectorI, nElementsI);
522 for (
size_t m = 0; m < nElementsN; m++) {
523 for (
size_t mi = 0; mi < nElementsI; mi++) {
524 if (elnamesVN[m] == elnamesVI[mi]) {
525 elemVectorN[m] -= fac * elemVectorI[mi];
529 bool notTaken =
true;
530 for (
size_t iNeut = 0; iNeut < jNeut; iNeut++) {
539 "Simple formula matrix generation failed, one cation is shared between two salts");
546 for (
size_t m = 0; m < nElementsN; m++) {
547 if (fabs(elemVectorN[m]) > 1.0E-13) {
549 "Simple formula matrix generation failed");
557 void IonsFromNeutralVPSSTP::setNeutralMoleculePhase(shared_ptr<ThermoPhase> neutral)
575 shared_ptr<ThermoPhase> IonsFromNeutralVPSSTP::getNeutralMoleculePhase()
586 m_work.push_back(0.0);
590 if (spec->charge > 0) {
592 }
else if (spec->charge < 0) {
598 if (spec->extra.hasKey(
"special_species")
599 && spec->extra[
"special_species"].asBool()) {
610 if (!thermoNode.
hasChild(
"neutralMoleculePhase")) {
611 throw CanteraError(
"IonsFromNeutralVPSSTP::initThermoXML",
612 "no neutralMoleculePhase XML node");
614 XML_Node& neutralMoleculeNode = thermoNode.
child(
"neutralMoleculePhase");
618 throw CanteraError(
"IonsFromNeutralVPSSTP::initThermoXML",
622 setNeutralMoleculePhase(shared_ptr<ThermoPhase>(
newPhase(*neut_ptr)));
632 case cIonSolnType_PASSTHROUGH:
634 case cIonSolnType_SINGLEANION:
657 case cIonSolnType_SINGLECATION:
658 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff",
"Unimplemented type");
660 case cIonSolnType_MULTICATIONANION:
661 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff",
"Unimplemented type");
664 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff",
"Unimplemented type");
670 doublereal* dlnActCoeffds)
const 675 for (
size_t k = 0; k <
m_kk; k++) {
684 geThermo->
getdlnActCoeffds(dTds, dX_NeutralMolecule_.data(), dlnActCoeff_NeutralMolecule_.data());
687 case cIonSolnType_PASSTHROUGH:
689 case cIonSolnType_SINGLEANION:
696 dlnActCoeffds[icat] = dlnActCoeff_NeutralMolecule_[jNeut]/fmij;
702 dlnActCoeffds[icat]= 0.0;
708 dlnActCoeffds[icat] = dlnActCoeff_NeutralMolecule_[jNeut];
712 case cIonSolnType_SINGLECATION:
713 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeffds",
"Unimplemented type");
715 case cIonSolnType_MULTICATIONANION:
716 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeffds",
"Unimplemented type");
719 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeffds",
"Unimplemented type");
737 case cIonSolnType_PASSTHROUGH:
739 case cIonSolnType_SINGLEANION:
762 case cIonSolnType_SINGLECATION:
763 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeffdT",
"Unimplemented type");
765 case cIonSolnType_MULTICATIONANION:
766 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeffdT",
"Unimplemented type");
769 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeffdT",
"Unimplemented type");
787 case cIonSolnType_PASSTHROUGH:
789 case cIonSolnType_SINGLEANION:
812 case cIonSolnType_SINGLECATION:
813 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff_dlnX_diag()",
"Unimplemented type");
815 case cIonSolnType_MULTICATIONANION:
816 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff_dlnX_diag()",
"Unimplemented type");
819 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff_dlnX_diag()",
"Unimplemented type");
837 case cIonSolnType_PASSTHROUGH:
839 case cIonSolnType_SINGLEANION:
862 case cIonSolnType_SINGLECATION:
863 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff_dlnN_diag()",
"Unimplemented type");
865 case cIonSolnType_MULTICATIONANION:
866 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff_dlnN_diag()",
"Unimplemented type");
869 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff_dlnN_diag()",
"Unimplemented type");
876 size_t kcat = 0, kNeut = 0, mcat = 0, mNeut = 0;
877 doublereal fmij = 0.0;
881 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnN()",
"dynamic cast failed");
883 size_t nsp_ge = geThermo->
nSpecies();
887 case cIonSolnType_PASSTHROUGH:
889 case cIonSolnType_SINGLEANION:
916 for (
size_t k = 0; k <
m_kk; k++) {
927 for (
size_t m = 0; m <
m_kk; m++) {
941 case cIonSolnType_SINGLECATION:
942 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff_dlnN",
"Unimplemented type");
944 case cIonSolnType_MULTICATIONANION:
945 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff_dlnN",
"Unimplemented type");
948 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff_dlnN",
"Unimplemented type");
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 ...
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 ...
vector_fp muNeutralMolecule_
Storage vector for the neutral molecule chemical potentials.
size_t nElements() const
Number of elements.
vector_fp NeutralMolecMoleFractions_
Mole fractions using the Neutral Molecule Mole fraction basis.
vector_fp dlnActCoeffdlnX_diag_
Storage for the current derivative values of the gradients with respect to logarithm of the mole frac...
doublereal temperature() const
Temperature (K).
void resize(size_t n, size_t m, doublereal v=0.0)
Resize the array, and fill the new entries with 'v'.
Header for intermediate ThermoPhase object for phases which consist of ions whose thermodynamics is c...
const size_t npos
index returned by functions to indicate "no position"
vector_fp m_speciesCharge
Vector of species charges. length m_kk.
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
size_t indexSpecialSpecies_
Index of special species.
Class XML_Node is a tree-based representation of the contents of an XML file.
size_t nSpecies() const
Returns the number of species in the phase.
virtual void compositionChanged()
Apply changes to the state which are needed after the composition changes.
virtual void initThermo()
doublereal mean_X(const doublereal *const Q) const
Evaluate the mole-fraction-weighted mean of an array Q.
vector_fp lnActCoeff_NeutralMolecule_
Storage vector for the neutral molecule ln activity coefficients.
vector_fp dlnActCoeffdT_NeutralMolecule_
Storage vector for the neutral molecule d ln activity coefficients dT.
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
void s_update_dlnActCoeff_dlnX_diag() const
Update the derivative of the log of the activity coefficients wrt log(mole fraction) ...
vector_fp dlnActCoeffdlnN_diag_NeutralMolecule_
Storage vector for the neutral molecule d ln activity coefficients dlnN.
virtual void calcNeutralMoleculeMoleFractions() const
Calculate neutral molecule mole fractions.
virtual void initThermo()
vector_fp dlnActCoeffdlnN_diag_
Storage for the current derivative values of the gradients with respect to logarithm of the mole frac...
shared_ptr< ThermoPhase > neutralMoleculePhase_
This is a pointer to the neutral Molecule Phase.
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
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, etc) along a line in parameter space or along a line in physical space.
void s_update_dlnActCoeffdT() const
Update the temperature derivative of the ln activity coefficients.
IonSolnType_enumType ionSolnType_
Ion solution type.
virtual void getdlnActCoeffdlnN_diag(doublereal *dlnActCoeffdlnN_diag) const
Get the array of log species mole number derivatives of the log activity coefficients.
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 compositionChanged()
Apply changes to the state which are needed after the composition changes.
void s_update_lnActCoeff() const
Update the activity coefficients.
Array2D dlnActCoeffdlnN_NeutralMolecule_
Storage vector for the neutral molecule d ln activity coefficients dlnN.
virtual doublereal gibbs_mole() const
Molar Gibbs function. Units: J/kmol.
virtual bool addSpecies(shared_ptr< Species > spec)
Base class for exceptions thrown by Cantera classes.
virtual void calcDensity()
Calculate the density of the mixture using the partial molar volumes and mole fractions as input...
virtual bool addSpecies(shared_ptr< Species > spec)
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies for the species in the mixture.
void s_update_dlnActCoeff_dlnN() const
Update the derivative of the log of the activity coefficients wrt log(number of moles) - diagonal com...
std::vector< size_t > anionList_
List of the species in this ThermoPhase which are anion species.
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
vector_fp lnActCoeff_Scaled_
Storage for the current values of the activity coefficients of the species.
virtual doublereal pressure() const
Returns the current pressure of the phase.
std::vector< size_t > passThroughList_
List of the species in this ThermoPhase which are passed through to the neutralMoleculePhase ThermoPh...
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.
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
virtual void calcIonMoleFractions(doublereal *const mf) const
Calculate ion mole fractions from neutral molecule mole fractions.
virtual void getdlnActCoeffdlnX_diag(doublereal *dlnActCoeffdlnX_diag) const
Get the array of ln mole fraction derivatives of the log activity coefficients - diagonal component o...
const doublereal 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.
virtual void getdlnActCoeffdlnN_diag(doublereal *dlnActCoeffdlnN_diag) const
Get the array of log species mole number derivatives of the log activity coefficients.
std::vector< size_t > fm_invert_ionForNeutral
Mapping between ion species and neutral molecule for quick invert.
virtual doublereal enthalpy_mole() const
Return the Molar enthalpy. Units: J/kmol.
virtual void setParametersFromXML(const XML_Node &eosdata)
Set equation of state parameter values from XML entries.
virtual void setParametersFromXML(const XML_Node &thermoNode)
Set equation of state parameter values from XML entries.
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
Contains declarations for string manipulation functions within Cantera.
std::vector< size_t > cationList_
List of the species in this ThermoPhase which are cation species.
vector_fp moleFractions_
Storage for the current values of the mole fractions of the species.
virtual void getActivityCoefficients(doublereal *ac) const
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
vector_fp fm_neutralMolec_ions_
Formula Matrix for composition of neutral molecules in terms of the molecules in this ThermoPhase...
size_t m_kk
Number of species in the phase.
Array2D dlnActCoeffdlnN_
Storage for the current derivative values of the gradients with respect to logarithm of the species m...
virtual void getEntropy_R(doublereal *sr) const
Get the array of nondimensional Entropy functions for the standard state species at the current T and...
void zero()
Set all of the entries to zero.
virtual void initThermoFile(const std::string &inputFile, const std::string &id)
void getDissociationCoeffs(vector_fp &fm_neutralMolec_ions, vector_fp &charges, std::vector< size_t > &neutMolIndex) const
Get the Salt Dissociation Coefficients.
virtual void getPartialMolarCp(doublereal *cpbar) const
Return an array of partial molar heat capacities for the species in the mixture.
Namespace for the Cantera kernel.
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.
Declarations for the class PDSS_IonsFromNeutral ( which handles calculations for a single ion in a fl...
doublereal nAtoms(size_t k, size_t m) const
Number of atoms of element m in species k.
size_t numNeutralMoleculeSpecies_
Number of neutral molecule species.
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 doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
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, etc) along a line in parameter space or along a line in physical space.
const std::vector< std::string > & elementNames() const
Return a read-only reference to the vector of element names.
vector_fp moleFractionsTmp_
Temporary mole fraction vector.
void getNeutralMoleculeMoleGrads(const doublereal *const dx, doublereal *const dy) const
Calculate neutral molecule mole fractions.
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 getdlnActCoeffdT(doublereal *dlnActCoeffdT) const
Get the array of temperature derivatives of the log activity coefficients.
virtual void setDensity(const doublereal density_)
Set the internally stored density (kg/m^3) of the phase.
vector_fp dlnActCoeffdT_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
void s_update_dlnActCoeff_dlnN_diag() const
Update the derivative of the log of the activity coefficients wrt log(number of moles) - diagonal com...
vector_fp dlnActCoeffdlnX_diag_NeutralMolecule_
Storage vector for the neutral molecule d ln activity coefficients dX - diagonal component.