23#include <boost/algorithm/string.hpp>
31 warn_deprecated(
"class IonsFromNeutralVPSSTP",
"To be removed after Cantera 3.0");
71 vector<double>& charges, vector<size_t>& neutMolIndex)
const
84 for (
size_t k = 0; k <
m_kk; k++) {
100 case cIonSolnType_PASSTHROUGH:
103 case cIonSolnType_SINGLEANION:
105 fact2 = 2.0 *
RT() * log(2.0);
120 mu[icat] =
RT() * log(xx);
131 case cIonSolnType_SINGLECATION:
132 throw CanteraError(
"IonsFromNeutralVPSSTP::getChemPotentials",
"Unknown type");
133 case cIonSolnType_MULTICATIONANION:
134 throw CanteraError(
"IonsFromNeutralVPSSTP::getChemPotentials",
"Unknown type");
136 throw CanteraError(
"IonsFromNeutralVPSSTP::getChemPotentials",
"Unknown type");
146 for (
size_t k = 0; k <
m_kk; k++) {
154 for (
size_t k = 0; k <
m_kk; k++) {
169 for (
size_t k = 0; k <
m_kk; k++) {
175 for (
size_t k = 0; k <
m_kk; k++) {
185 for (
size_t k = 0; k <
m_kk; k++) {
195 for (
size_t k = 0; k <
m_kk; k++) {
205 for (
size_t k = 0; k <
m_kk; k++) {
206 for (
size_t m = 0; m <
m_kk; m++) {
207 dlnActCoeffdlnN[ld * k + m] = data[
m_kk * k + m];
229 for (
size_t k = 0; k <
m_kk; k++) {
235 for (
size_t k = 0; k <
m_kk; k++) {
243 for (
size_t k = 0; k <
m_kk; k++) {
246 for (
size_t k = 0; k <
m_kk; k++) {
262 for (
size_t k = 0; k <
m_kk; k++) {
265 if (fabs(sum) > 1.0E-11) {
266 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
267 "molefracts don't sum to one: {}", sum);
271 case cIonSolnType_PASSTHROUGH:
272 for (
size_t k = 0; k <
m_kk; k++) {
277 case cIonSolnType_SINGLEANION:
300 for (
size_t k = 0; k <
m_kk; k++) {
304 for (
size_t k = 0; k <
m_kk; k++) {
309 for (
size_t k = 0; k <
m_kk; k++) {
313 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
314 "neutral molecule calc error");
318 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
319 "neutral molecule calc error - anion");
335 case cIonSolnType_SINGLECATION:
336 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
"Unknown type");
338 case cIonSolnType_MULTICATIONANION:
339 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
"Unknown type");
342 throw CanteraError(
"IonsFromNeutralVPSSTP::calcNeutralMoleculeMoleFractions",
"Unknown type");
360 case cIonSolnType_PASSTHROUGH:
361 for (
size_t k = 0; k <
m_kk; k++) {
366 case cIonSolnType_SINGLEANION:
374 const double temp = 1.0/fmij;
375 dy[jNeut] += dx[icat] * temp;
384 const double temp = 1.0/fmij;
385 dy[jNeut] += dx[icat] * temp;
397 dy[k] = dy[k] * sumy - y_[k]*sumdy*sumy*sumy;
402 case cIonSolnType_SINGLECATION:
403 throw CanteraError(
"IonsFromNeutralVPSSTP::getNeutralMoleculeMoleGrads",
406 case cIonSolnType_MULTICATIONANION:
407 throw CanteraError(
"IonsFromNeutralVPSSTP::getNeutralMoleculeMoleGrads",
411 throw CanteraError(
"IonsFromNeutralVPSSTP::getNeutralMoleculeMoleGrads",
436 const vector<double>& elemVectorN,
437 const size_t nElementsN,
438 const vector<string>& elnamesVI ,
439 const vector<double>& elemVectorI,
440 const size_t nElementsI)
442 double fMax = 1.0E100;
443 for (
size_t mi = 0; mi < nElementsI; mi++) {
444 if (elnamesVI[mi] !=
"E" && elemVectorI[mi] > 1.0E-13) {
445 double eiNum = elemVectorI[mi];
446 for (
size_t mn = 0; mn < nElementsN; mn++) {
447 if (elnamesVI[mi] == elnamesVN[mn]) {
448 if (elemVectorN[mn] <= 1.0E-13) {
451 fMax = std::min(fMax, elemVectorN[mn]/eiNum);
469 string neutralName =
m_input[
"neutral-phase"].asString();
470 const auto& slash = boost::ifind_last(neutralName,
"/");
472 string fileName(neutralName.begin(), slash.begin());
473 neutralName = string(slash.end(), neutralName.end());
476 AnyMap& phaseNode = infile[
"phases"].getMapWhere(
"name", neutralName);
477 setNeutralMoleculePhase(
newThermo(phaseNode, infile));
486 "IonsFromNeutralVPSSTP::initThermo",
487 "The neutral phase has not been initialized. Are you missing the "
488 "'neutral-phase' key?"
494 vector<double> elemVectorN(nElementsN);
498 vector<double> elemVectorI(nElementsI);
502 "IonsFromNeutralVPSSTP::initThermo",
503 "No special-species were specified in the phase."
506 for (
size_t m = 0; m < nElementsI; m++) {
511 for (
size_t m = 0; m < nElementsN; m++) {
515 double fac =
factorOverlap(elnamesVN, elemVectorN, nElementsN,
516 elnamesVI ,elemVectorI, nElementsI);
518 for (
size_t m = 0; m < nElementsN; m++) {
519 for (
size_t mi = 0; mi < nElementsI; mi++) {
520 if (elnamesVN[m] == elnamesVI[mi]) {
521 elemVectorN[m] -= fac * elemVectorI[mi];
529 for (
size_t k = 0; k <
m_kk; k++) {
530 for (
size_t m = 0; m < nElementsI; m++) {
531 elemVectorI[m] =
nAtoms(k, m);
534 elnamesVI ,elemVectorI, nElementsI);
536 for (
size_t m = 0; m < nElementsN; m++) {
537 for (
size_t mi = 0; mi < nElementsI; mi++) {
538 if (elnamesVN[m] == elnamesVI[mi]) {
539 elemVectorN[m] -= fac * elemVectorI[mi];
543 bool notTaken =
true;
544 for (
size_t iNeut = 0; iNeut < jNeut; iNeut++) {
553 "Simple formula matrix generation failed, one cation is shared between two salts");
560 for (
size_t m = 0; m < nElementsN; m++) {
561 if (fabs(elemVectorN[m]) > 1.0E-13) {
563 "Simple formula matrix generation failed");
579void IonsFromNeutralVPSSTP::setNeutralMoleculePhase(shared_ptr<ThermoPhase> neutral)
595 for (
size_t k = 0; k <
nSpecies(); k++) {
600shared_ptr<ThermoPhase> IonsFromNeutralVPSSTP::getNeutralMoleculePhase()
611 m_work.push_back(0.0);
615 if (spec->charge > 0) {
617 }
else if (spec->charge < 0) {
623 if (spec->input.hasKey(
"equation-of-state")) {
624 auto& ss = spec->input[
"equation-of-state"].getMapWhere(
625 "model",
"ions-from-neutral-molecule");
626 if (ss.getBool(
"special-species",
false)) {
641 case cIonSolnType_PASSTHROUGH:
643 case cIonSolnType_SINGLEANION:
666 case cIonSolnType_SINGLECATION:
667 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff",
"Unimplemented type");
669 case cIonSolnType_MULTICATIONANION:
670 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff",
"Unimplemented type");
673 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_lnActCoeff",
"Unimplemented type");
679 double* dlnActCoeffds)
const
684 for (
size_t k = 0; k <
m_kk; k++) {
693 geThermo->
getdlnActCoeffds(dTds, dX_NeutralMolecule_.data(), dlnActCoeff_NeutralMolecule_.data());
696 case cIonSolnType_PASSTHROUGH:
698 case cIonSolnType_SINGLEANION:
705 dlnActCoeffds[icat] = dlnActCoeff_NeutralMolecule_[jNeut]/fmij;
711 dlnActCoeffds[icat]= 0.0;
717 dlnActCoeffds[icat] = dlnActCoeff_NeutralMolecule_[jNeut];
721 case cIonSolnType_SINGLECATION:
722 throw CanteraError(
"IonsFromNeutralVPSSTP::getdlnActCoeffds",
"Unimplemented type");
724 case cIonSolnType_MULTICATIONANION:
725 throw CanteraError(
"IonsFromNeutralVPSSTP::getdlnActCoeffds",
"Unimplemented type");
728 throw CanteraError(
"IonsFromNeutralVPSSTP::getdlnActCoeffds",
"Unimplemented type");
746 case cIonSolnType_PASSTHROUGH:
748 case cIonSolnType_SINGLEANION:
771 case cIonSolnType_SINGLECATION:
772 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeffdT",
"Unimplemented type");
774 case cIonSolnType_MULTICATIONANION:
775 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeffdT",
"Unimplemented type");
778 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeffdT",
"Unimplemented type");
796 case cIonSolnType_PASSTHROUGH:
798 case cIonSolnType_SINGLEANION:
821 case cIonSolnType_SINGLECATION:
822 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnX_diag",
"Unimplemented type");
824 case cIonSolnType_MULTICATIONANION:
825 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnX_diag",
"Unimplemented type");
828 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnX_diag",
"Unimplemented type");
846 case cIonSolnType_PASSTHROUGH:
848 case cIonSolnType_SINGLEANION:
871 case cIonSolnType_SINGLECATION:
872 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnN_diag",
"Unimplemented type");
874 case cIonSolnType_MULTICATIONANION:
875 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnN_diag",
"Unimplemented type");
878 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnN_diag",
"Unimplemented type");
885 size_t kcat = 0, kNeut = 0, mcat = 0, mNeut = 0;
890 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnN",
"dynamic cast failed");
892 size_t nsp_ge = geThermo->
nSpecies();
896 case cIonSolnType_PASSTHROUGH:
898 case cIonSolnType_SINGLEANION:
925 for (
size_t k = 0; k <
m_kk; k++) {
936 for (
size_t m = 0; m <
m_kk; m++) {
950 case cIonSolnType_SINGLECATION:
951 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnN",
"Unimplemented type");
953 case cIonSolnType_MULTICATIONANION:
954 throw CanteraError(
"IonsFromNeutralVPSSTP::s_update_dlnActCoeff_dlnN",
"Unimplemented type");
957 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.
bool hasKey(const string &key) const
Returns true if the map contains an item named key.
const string & getString(const string &key, const string &default_) const
If key exists, return it as a string, otherwise return default_.
static AnyMap fromYamlFile(const string &name, const string &parent_name="")
Create an AnyMap from a YAML file.
void zero()
Set all of the entries to zero.
virtual 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.
GibbsExcessVPSSTP is a derived class of ThermoPhase that handles variable pressure standard state met...
Array2D dlnActCoeffdlnN_
Storage for the current derivative values of the gradients with respect to logarithm of the species m...
vector< double > lnActCoeff_Scaled_
Storage for the current values of the activity coefficients of the species.
vector< double > dlnActCoeffdlnX_diag_
Storage for the current derivative values of the gradients with respect to logarithm of the mole frac...
vector< double > moleFractions_
Storage for the current values of the mole fractions of the species.
vector< double > dlnActCoeffdT_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
virtual void getdlnActCoeffdT(double *dlnActCoeffdT) const
Get the array of temperature derivatives of the log activity coefficients.
void compositionChanged() override
Apply changes to the state which are needed after the composition changes.
bool addSpecies(shared_ptr< Species > spec) override
Add a Species to this Phase.
vector< double > dlnActCoeffdlnN_diag_
Storage for the current derivative values of the gradients with respect to logarithm of the mole frac...
void getdlnActCoeffdlnN(const size_t ld, double *const dlnActCoeffdlnN) override
Get the array of derivatives of the log activity coefficients with respect to the log of the species ...
vector< double > lnActCoeff_NeutralMolecule_
Storage vector for the neutral molecule ln activity coefficients.
vector< size_t > anionList_
List of the species in this ThermoPhase which are anion species.
void getdlnActCoeffds(const double dTds, const double *const dXds, double *dlnActCoeffds) const override
Get the change in activity coefficients wrt changes in state (temp, mole fraction,...
double enthalpy_mole() const override
Return the Molar enthalpy. Units: J/kmol.
AnyMap m_rootNode
Root node of the AnyMap which contains this phase definition.
vector< double > dlnActCoeffdlnX_diag_NeutralMolecule_
Storage vector for the neutral molecule d ln activity coefficients dX - diagonal component.
void getPartialMolarEnthalpies(double *hbar) const override
Returns an array of partial molar enthalpies for the species in the mixture.
void getChemPotentials(double *mu) const override
Get the species chemical potentials. Units: J/kmol.
void getDissociationCoeffs(vector< double > &fm_neutralMolec_ions, vector< double > &charges, vector< size_t > &neutMolIndex) const
Get the Salt Dissociation Coefficients.
virtual void calcNeutralMoleculeMoleFractions() const
Calculate neutral molecule mole fractions.
virtual void calcIonMoleFractions(double *const mf) const
Calculate ion mole fractions from neutral molecule mole fractions.
vector< size_t > fm_invert_ionForNeutral
Mapping between ion species and neutral molecule for quick invert.
vector< double > muNeutralMolecule_
Storage vector for the neutral molecule chemical potentials.
void s_update_dlnActCoeff_dlnN_diag() const
Update the derivative of the log of the activity coefficients wrt log(number of moles) - diagonal com...
void getParameters(AnyMap &phaseNode) const override
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
void initThermo() override
Initialize the ThermoPhase object after all species have been set up.
vector< double > fm_neutralMolec_ions_
Formula Matrix for composition of neutral molecules in terms of the molecules in this ThermoPhase.
size_t indexSpecialSpecies_
Index of special species.
IonsFromNeutralVPSSTP(const string &inputFile="", const string &id="")
Construct an IonsFromNeutralVPSSTP object from an input file.
double cv_mole() const override
Molar heat capacity at constant volume. Units: J/kmol/K.
vector< double > dlnActCoeffdlnN_diag_NeutralMolecule_
Storage vector for the neutral molecule d ln activity coefficients dlnN.
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.
void s_update_dlnActCoeff_dlnN() const
Update the derivative of the log of the activity coefficients wrt log(number of moles) - diagonal com...
double entropy_mole() const override
Molar entropy. Units: J/kmol/K.
void calcDensity() override
Calculate the density of the mixture using the partial molar volumes and mole fractions as input.
shared_ptr< ThermoPhase > neutralMoleculePhase_
This is a pointer to the neutral Molecule Phase.
vector< double > dlnActCoeffdT_NeutralMolecule_
Storage vector for the neutral molecule d ln activity coefficients dT.
size_t numNeutralMoleculeSpecies_
Number of neutral molecule species.
double cp_mole() const override
Molar heat capacity at constant pressure. Units: J/kmol/K.
void compositionChanged() override
Apply changes to the state which are needed after the composition changes.
vector< double > moleFractionsTmp_
Temporary mole fraction vector.
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.
double gibbs_mole() const override
Molar Gibbs function. Units: J/kmol.
vector< size_t > passThroughList_
List of the species in this ThermoPhase which are passed through to the neutralMoleculePhase ThermoPh...
void getdlnActCoeffdlnX_diag(double *dlnActCoeffdlnX_diag) const override
Get the array of ln mole fraction derivatives of the log activity coefficients - diagonal component o...
bool addSpecies(shared_ptr< Species > spec) override
Add a Species to this Phase.
void getdlnActCoeffdlnN_diag(double *dlnActCoeffdlnN_diag) const override
Get the array of log species mole number derivatives of the log activity coefficients.
void getActivityCoefficients(double *ac) const override
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
void s_update_dlnActCoeffdT() const
Update the temperature derivative of the ln activity coefficients.
void setParameters(const AnyMap &phaseNode, const AnyMap &rootNode=AnyMap()) override
Set equation of state parameters from an AnyMap phase description.
vector< double > NeutralMolecMoleFractions_
Mole fractions using the Neutral Molecule Mole fraction basis.
void getNeutralMoleculeMoleGrads(const double *const dx, double *const dy) const
Calculate neutral molecule mole fractions.
IonSolnType_enumType ionSolnType_
Ion solution type.
void getPartialMolarEntropies(double *sbar) const override
Returns an array of partial molar entropies for the species in the mixture.
void getdlnActCoeffdlnN(const size_t ld, double *const dlnActCoeffdlnN) override
Get the array of derivatives of the log activity coefficients with respect to the log of the 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.
size_t nSpecies() const
Returns the number of species in the phase.
size_t m_kk
Number of species in the phase.
double temperature() const
Temperature (K).
double nAtoms(size_t k, size_t m) const
Number of atoms of element m in species k.
size_t nElements() const
Number of elements.
double mean_X(const double *const Q) const
Evaluate the mole-fraction-weighted mean of an array Q.
vector< double > m_speciesCharge
Vector of species charges. length m_kk.
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 ...
virtual void getdlnActCoeffdlnN_diag(double *dlnActCoeffdlnN_diag) const
Get the array of log species mole number derivatives of the log activity coefficients.
double RT() const
Return the Gas Constant multiplied by the current temperature.
virtual void getPartialMolarCp(double *cpbar) const
Return an array of partial molar heat capacities for the species in the mixture.
virtual void getdlnActCoeffds(const double dTds, const double *const dXds, double *dlnActCoeffds) const
Get the change in activity coefficients wrt changes in state (temp, mole fraction,...
virtual void initThermo()
Initialize the ThermoPhase object after all species have been set up.
void initThermoFile(const string &inputFile, const string &id)
Initialize a ThermoPhase object using an input file.
virtual void getdlnActCoeffdlnX_diag(double *dlnActCoeffdlnX_diag) const
Get the array of ln mole fraction derivatives of the log activity coefficients - diagonal component o...
AnyMap m_input
Data supplied via setParameters.
double pressure() const override
Returns the current pressure of the phase.
void getEntropy_R(double *sr) const override
Get the array of nondimensional Entropy functions for the standard state species at the current T and...
void getEnthalpy_RT(double *hrt) const override
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
#define AssertTrace(expr)
Assertion must be true or an error is thrown.
const double GasConstant
Universal Gas Constant [J/kmol/K].
shared_ptr< ThermoPhase > newThermo(const AnyMap &phaseNode, const AnyMap &rootNode)
Create a new ThermoPhase object and initialize it.
Namespace for the Cantera kernel.
const size_t npos
index returned by functions to indicate "no position"
const vector< string > & elementNames()
Get a vector of the names of the elements defined in Cantera.
const double SmallNumber
smallest number to compare to zero.
static double factorOverlap(const vector< string > &elnamesVN, const vector< double > &elemVectorN, const size_t nElementsN, const vector< string > &elnamesVI, const vector< double > &elemVectorI, const size_t nElementsI)
Return the factor overlap.
void warn_deprecated(const string &source, const AnyBase &node, const string &message)
A deprecation warning for syntax in an input file.
Contains declarations for string manipulation functions within Cantera.