Cantera  2.5.1
IonsFromNeutralVPSSTP.h
Go to the documentation of this file.
1 /**
2  * @file IonsFromNeutralVPSSTP.h Header for intermediate ThermoPhase object for
3  * phases which consist of ions whose thermodynamics is calculated from
4  * neutral molecule thermodynamics. (see \ref thermoprops and class \link
5  * Cantera::IonsFromNeutralVPSSTP IonsFromNeutralVPSSTP\endlink).
6  */
7 
8 // This file is part of Cantera. See License.txt in the top-level directory or
9 // at https://cantera.org/license.txt for license and copyright information.
10 
11 #ifndef CT_IONSFROMNEUTRALVPSSTP_H
12 #define CT_IONSFROMNEUTRALVPSSTP_H
13 
14 #include "GibbsExcessVPSSTP.h"
15 
16 namespace Cantera
17 {
18 
19 //! enums for molten salt ion solution types
20 /*!
21  * Types identify how complicated the solution is. If there is just mixing on
22  * one of the sublattices but not the other, then the math is considerably
23  * simpler.
24  */
26  cIonSolnType_PASSTHROUGH = 2000 ,
27  cIonSolnType_SINGLEANION ,
28  cIonSolnType_SINGLECATION ,
29  cIonSolnType_MULTICATIONANION
30 };
31 
32 /*!
33  * The IonsFromNeutralVPSSTP is a derived class of ThermoPhase that handles the
34  * specification of the chemical potentials for ionic species, given a
35  * specification of the chemical potentials for the same phase expressed in
36  * terms of combinations of the ionic species that represent neutral molecules.
37  * It's expected that the neutral molecules will be represented in terms of an
38  * excess Gibbs free energy approximation that is a derivative of the
39  * GibbsExcessVPSSTP object. All of the excess Gibbs free energy formulations in
40  * this area employ symmetrical formulations.
41  *
42  * @attention This class currently does not have any test cases or examples. Its
43  * implementation may be incomplete, and future changes to Cantera may
44  * unexpectedly cause this class to stop working. If you use this class,
45  * please consider contributing examples or test cases. In the absence of
46  * new tests or examples, this class may be deprecated and removed in a
47  * future version of Cantera. See
48  * https://github.com/Cantera/cantera/issues/267 for additional information.
49  *
50  * This class is used for molten salts.
51  *
52  * This object actually employs 4 different mole fraction types.
53  *
54  * 1. There is a mole fraction associated the the cations and anions and
55  * neutrals from this ThermoPhase object. This is the normal mole fraction
56  * vector for this object. Note, however, it isn't the appropriate mole
57  * fraction vector to use even for obtaining the correct ideal free energies
58  * of mixing.
59  * 2. There is a mole fraction vector associated with the neutral molecule
60  * ThermoPhase object.
61  * 3. There is a mole fraction vector associated with the cation lattice.
62  * 4. There is a mole fraction vector associated with the anion lattice
63  *
64  * This object can translate between any of the four mole fraction
65  * representations.
66  */
68 {
69 public:
70  //! @name Constructors
71  //! @{
72 
73  /*!
74  * Default constructor
75  */
77 
78  //! Construct an IonsFromNeutralVPSSTP object from an input file
79  /*!
80  * @param inputFile Name of the input file containing the phase definition
81  * @param id name (ID) of the phase in the input file. If empty, the
82  * first phase definition in the input file will be used.
83  */
84  IonsFromNeutralVPSSTP(const std::string& inputFile,
85  const std::string& id = "");
86 
87  //! Construct and initialize an IonsFromNeutralVPSSTP object
88  //! directly from an XML database
89  /*!
90  * @param phaseRoot XML phase node containing the description of the phase
91  * @param id id attribute containing the name of the phase.
92  * (default is the empty string)
93  *
94  * @deprecated The XML input format is deprecated and will be removed in
95  * Cantera 3.0.
96  */
97  IonsFromNeutralVPSSTP(XML_Node& phaseRoot, const std::string& id = "");
98 
99  // @}
100  //! @name Utilities
101  //! @{
102 
103  virtual std::string type() const {
104  return "IonsFromNeutral";
105  }
106 
107  //! @}
108  //! @name Molar Thermodynamic Properties
109  //! @{
110 
111  //! Return the Molar enthalpy. Units: J/kmol.
112  /*!
113  * This is calculated from the partial molar enthalpies of the species.
114  */
115  virtual doublereal enthalpy_mole() const;
116 
117  virtual doublereal entropy_mole() const;
118  virtual doublereal gibbs_mole() const;
119  virtual doublereal cp_mole() const;
120  virtual doublereal cv_mole() const;
121 
122  /**
123  * @}
124  * @name Activities, Standard States, and Activity Concentrations
125  *
126  * The activity \f$a_k\f$ of a species in solution is
127  * related to the chemical potential by \f[ \mu_k = \mu_k^0(T)
128  * + \hat R T \log a_k. \f] The quantity \f$\mu_k^0(T,P)\f$ is
129  * the chemical potential at unit activity, which depends only
130  * on temperature and pressure.
131  * @{
132  */
133 
134  virtual void getActivityCoefficients(doublereal* ac) const;
135 
136  //@}
137  /// @name Partial Molar Properties of the Solution
138  //@{
139 
140  virtual void getChemPotentials(doublereal* mu) const;
141 
142  //! Returns an array of partial molar enthalpies for the species in the
143  //! mixture.
144  /*!
145  * Units (J/kmol)
146  *
147  * For this phase, the partial molar enthalpies are equal to the standard
148  * state enthalpies modified by the derivative of the molality-based
149  * activity coefficient wrt temperature
150  *
151  * \f[
152  * \bar h_k(T,P) = h^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT}
153  * \f]
154  *
155  * @param hbar Output vector of species partial molar enthalpies.
156  * Length: m_kk. Units: J/kmol
157  */
158  virtual void getPartialMolarEnthalpies(doublereal* hbar) const;
159 
160  //! Returns an array of partial molar entropies for the species in the
161  //! mixture.
162  /*!
163  * Units (J/kmol)
164  *
165  * For this phase, the partial molar enthalpies are equal to the standard
166  * state enthalpies modified by the derivative of the activity coefficient
167  * wrt temperature
168  *
169  * \f[
170  * \bar s_k(T,P) = s^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT}
171  * - R \ln( \gamma_k X_k)
172  * - R T \frac{d \ln(\gamma_k) }{dT}
173  * \f]
174  *
175  * @param sbar Output vector of species partial molar entropies.
176  * Length: m_kk. Units: J/kmol/K
177  */
178  virtual void getPartialMolarEntropies(doublereal* sbar) const;
179 
180  virtual void getdlnActCoeffds(const doublereal dTds, const doublereal* const dXds,
181  doublereal* dlnActCoeffds) const;
182  virtual void getdlnActCoeffdlnX_diag(doublereal* dlnActCoeffdlnX_diag) const;
183  virtual void getdlnActCoeffdlnN_diag(doublereal* dlnActCoeffdlnN_diag) const;
184  virtual void getdlnActCoeffdlnN(const size_t ld, doublereal* const dlnActCoeffdlnN);
185  //! @}
186 
187  //! Get the Salt Dissociation Coefficients.
188  //! Returns the vector of dissociation coefficients and vector of charges
189  /*!
190  * @param fm_neutralMolec_ions Returns the formula matrix for the
191  * composition of neutral molecules in terms of the ions.
192  * @param charges Returns a vector containing the charges of
193  * all species in this phase
194  * @param neutMolIndex Returns the vector fm_invert_ionForNeutral
195  * This is the mapping between ion species and neutral molecule for
196  * quick invert.
197  */
198  void getDissociationCoeffs(vector_fp& fm_neutralMolec_ions, vector_fp& charges, std::vector<size_t>& neutMolIndex) const;
199 
200  //! Return the current value of the neutral mole fraction vector
201  /*!
202  * @param neutralMoleculeMoleFractions Vector of neutral molecule mole
203  * fractions.
204  */
205  void getNeutralMolecMoleFractions(vector_fp& neutralMoleculeMoleFractions) const {
206  neutralMoleculeMoleFractions = NeutralMolecMoleFractions_;
207  }
208 
209  //! Calculate neutral molecule mole fractions
210  /*!
211  * This routine calculates the neutral molecule mole fraction given the
212  * vector of ion mole fractions, i.e., the mole fractions from this
213  * ThermoPhase. Note, this routine basically assumes that there is charge
214  * neutrality. If there isn't, then it wouldn't make much sense.
215  *
216  * for the case of cIonSolnType_SINGLEANION, some slough in the charge
217  * neutrality is allowed. The cation number is followed, while the
218  * difference in charge neutrality is dumped into the anion mole number to
219  * fix the imbalance.
220  *
221  * @param dx input vector of ion mole fraction gradients
222  * @param dy output Vector of neutral molecule mole fraction gradients
223  */
224  void getNeutralMoleculeMoleGrads(const doublereal* const dx, doublereal* const dy) const;
225 
226  //! Get the list of cations in this object
227  /*!
228  * @param cation List of cations
229  */
230  void getCationList(std::vector<size_t>& cation) const {
231  cation=cationList_;
232  }
233 
234  //! Get the list of anions in this object
235  /*!
236  * @param anion List of anions
237  */
238  void getAnionList(std::vector<size_t>& anion) const {
239  anion=anionList_;
240  }
241 
242  /**
243  * @name Setting the State
244  * These methods set all or part of the thermodynamic state.
245  * @{
246  */
247 
248  virtual void calcDensity();
249 
250  //! Calculate ion mole fractions from neutral molecule mole fractions.
251  /*!
252  * @param mf Dump the mole fractions into this vector.
253  */
254  virtual void calcIonMoleFractions(doublereal* const mf) const;
255 
256  //! Calculate neutral molecule mole fractions
257  /*!
258  * This routine calculates the neutral molecule mole fraction given the
259  * vector of ion mole fractions, i.e., the mole fractions from this
260  * ThermoPhase. Note, this routine basically assumes that there is charge
261  * neutrality. If there isn't, then it wouldn't make much sense.
262  *
263  * for the case of cIonSolnType_SINGLEANION, some slough in the charge
264  * neutrality is allowed. The cation number is followed, while the
265  * difference in charge neutrality is dumped into the anion mole number to
266  * fix the imbalance.
267  */
268  virtual void calcNeutralMoleculeMoleFractions() const;
269 
270  //@}
271 
272  virtual bool addSpecies(shared_ptr<Species> spec);
273  void setNeutralMoleculePhase(shared_ptr<ThermoPhase> neutral);
274  shared_ptr<ThermoPhase> getNeutralMoleculePhase();
275 
276  virtual void setParameters(const AnyMap& phaseNode,
277  const AnyMap& rootNode=AnyMap());
278  virtual void initThermo();
279  virtual void setParametersFromXML(const XML_Node& thermoNode);
280 
281 private:
282  //! Update the activity coefficients
283  /*!
284  * This function will be called to update the internally stored natural
285  * logarithm of the activity coefficients
286  */
287  void s_update_lnActCoeff() const;
288 
289  //! Update the temperature derivative of the ln activity coefficients
290  /*!
291  * This function will be called to update the internally stored temperature
292  * derivative of the natural logarithm of the activity coefficients
293  */
294  void s_update_dlnActCoeffdT() const;
295 
296  //! Update the change in the ln activity coefficients
297  /*!
298  * This function will be called to update the internally stored change of
299  * the natural logarithm of the activity coefficients w.r.t a change in
300  * state (temp, mole fraction, etc)
301  */
302  void s_update_dlnActCoeff() const;
303 
304  //! Update the derivative of the log of the activity coefficients wrt
305  //! log(mole fraction)
306  /*!
307  * This function will be called to update the internally stored
308  * derivative of the natural logarithm of the activity coefficients
309  * wrt logarithm of the mole fractions.
310  */
311  void s_update_dlnActCoeff_dlnX_diag() const;
312 
313  //! Update the derivative of the log of the activity coefficients wrt
314  //! log(number of moles) - diagonal components
315  /*!
316  * This function will be called to update the internally stored derivative
317  * of the natural logarithm of the activity coefficients wrt logarithm of
318  * the number of moles of given species.
319  */
320  void s_update_dlnActCoeff_dlnN_diag() const;
321 
322  //! Update the derivative of the log of the activity coefficients
323  //! wrt log(number of moles) - diagonal components
324  /*!
325  * This function will be called to update the internally stored derivative
326  * of the natural logarithm of the activity coefficients wrt logarithm of
327  * the number of moles of given species.
328  */
329  void s_update_dlnActCoeff_dlnN() const;
330 
331 protected:
332  virtual void compositionChanged();
333 
334  //! Ion solution type
335  /*!
336  * There is either mixing on the anion, cation, or both lattices.
337  * There is also a passthrough option
338  *
339  * Defaults to cIonSolnType_SINGLEANION, so that LiKCl can be hardwired
340  */
342 
343  //! Number of neutral molecule species
344  /*!
345  * This is equal to the number of species in the neutralMoleculePhase_
346  * ThermoPhase.
347  */
349 
350  //! Index of special species
352 
353  //! Formula Matrix for composition of neutral molecules
354  //! in terms of the molecules in this ThermoPhase
355  /*!
356  * fm_neutralMolec_ions[ i + jNeut * m_kk ]
357  *
358  * This is the number of ions of type i in the neutral molecule jNeut.
359  */
361 
362  //! Mapping between ion species and neutral molecule for quick invert.
363  /*!
364  * fm_invert_ionForNeutral returns vector of int. Each element represents an
365  * ionic species and stores the value of the corresponding neutral molecule
366  *
367  * For the case of fm_invert_simple_ = true, we assume that there is a quick
368  * way to invert the formula matrix so that we can quickly calculate the
369  * neutral molecule mole fraction given the ion mole fraction vector.
370  *
371  * We assume that for a selected set of ion species, that that ion is only
372  * in the neutral molecule, jNeut.
373  *
374  * therefore,
375  *
376  * NeutralMolecMoleFractions_[jNeut] += moleFractions_[i_ion] / fmij;
377  *
378  * where fmij is the number of ions in neutral molecule jNeut.
379  *
380  * Thus, we formulate the neutral molecule mole fraction
381  * NeutralMolecMoleFractions_[] vector from this association. We further
382  * assume that there are no other associations. If fm_invert_simple_ is not
383  * true, then we need to do a formal inversion which takes a great deal of
384  * time and is not currently implemented.
385  */
386  std::vector<size_t> fm_invert_ionForNeutral;
387 
388  //! Mole fractions using the Neutral Molecule Mole fraction basis
390 
391  //! List of the species in this ThermoPhase which are cation species
392  std::vector<size_t> cationList_;
393 
394  //! List of the species in this ThermoPhase which are anion species
395  std::vector<size_t> anionList_;
396 
397  //! List of the species in this ThermoPhase which are passed through to the
398  //! neutralMoleculePhase ThermoPhase. These have neutral charges.
399  std::vector<size_t> passThroughList_;
400 
401  //! This is a pointer to the neutral Molecule Phase
402  shared_ptr<ThermoPhase> neutralMoleculePhase_;
403 
404  //! Root node of the AnyMap which contains this phase definition.
405  //! Used to look up the phase definition for the embedded neutral phase.
407 
408 private:
409  GibbsExcessVPSSTP* geThermo;
410  // Temporary vectors that I don't want to allocate every time the function
411  // is called
412  mutable vector_fp y_;
413  mutable vector_fp dlnActCoeff_NeutralMolecule_;
414  mutable vector_fp dX_NeutralMolecule_;
415  mutable vector_fp m_work; // length m_kk
416 
417  //! Temporary mole fraction vector
419 
420  //! Storage vector for the neutral molecule chemical potentials
421  /*!
422  * This vector is used as a temporary storage area when calculating the ion
423  * chemical potentials.
424  *
425  * - Units = Joules/kmol
426  * - Length = numNeutralMoleculeSpecies_
427  */
429 
430  //! Storage vector for the neutral molecule ln activity coefficients
431  /*!
432  * This vector is used as a temporary storage area when calculating the ion
433  * chemical potentials and activity coefficients
434  *
435  * - Units = none
436  * - Length = numNeutralMoleculeSpecies_
437  */
439 
440  //! Storage vector for the neutral molecule d ln activity coefficients dT
441  /*!
442  * This vector is used as a temporary storage area when calculating the ion
443  * derivatives
444  *
445  * - Units = 1/Kelvin
446  * - Length = numNeutralMoleculeSpecies_
447  */
449 
450  //! Storage vector for the neutral molecule d ln activity coefficients dX -
451  //! diagonal component
452  /*!
453  * This vector is used as a temporary storage area when calculating the ion
454  * derivatives
455  *
456  * - Units = none
457  * - Length = numNeutralMoleculeSpecies_
458  */
460 
461  //! Storage vector for the neutral molecule d ln activity coefficients dlnN
462  //! - diagonal component
463  /*!
464  * This vector is used as a temporary storage area when calculating the ion
465  * derivatives
466  *
467  * - Units = none
468  * - Length = numNeutralMoleculeSpecies_
469  */
471 
472  //! Storage vector for the neutral molecule d ln activity coefficients dlnN
473  /*!
474  * This vector is used as a temporary storage area when calculating the ion
475  * derivatives
476  *
477  * - Units = none
478  * - Length = numNeutralMoleculeSpecies_
479  */
481 };
482 
483 }
484 
485 #endif
Header for intermediate ThermoPhase object for phases which employ Gibbs excess free energy based for...
A map of string keys to values whose type can vary at runtime.
Definition: AnyMap.h:360
A class for 2D arrays stored in column-major (Fortran-compatible) form.
Definition: Array.h:32
AnyMap m_rootNode
Root node of the AnyMap which contains this phase definition.
virtual void setParameters(const AnyMap &phaseNode, const AnyMap &rootNode=AnyMap())
Set equation of state parameters from an AnyMap phase description.
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...
void getAnionList(std::vector< size_t > &anion) const
Get the list of anions in this object.
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...
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.
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.
virtual std::string type() const
String indicating the thermodynamic model implemented.
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.
void getCationList(std::vector< size_t > &cation) const
Get the list of cations in this object.
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.
void s_update_dlnActCoeff() const
Update the change in the ln activity coefficients.
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.
void getNeutralMolecMoleFractions(vector_fp &neutralMoleculeMoleFractions) const
Return the current value of the neutral mole fraction vector.
std::vector< size_t > anionList_
List of the species in this ThermoPhase which are anion species.
virtual bool addSpecies(shared_ptr< Species > spec)
Add a Species to this Phase.
Definition: Phase.cpp:833
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:104
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:180
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:264
IonSolnType_enumType
enums for molten salt ion solution types