Cantera  2.4.0
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 http://www.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 and initialize an IonsFromNeutralVPSSTP object directly from
79  //! an ASCII input file
80  /*!
81  * This constructor is a shell around the routine initThermo(), with a
82  * reference to the XML database to get the info for the phase.
83  *
84  * @param inputFile Name of the input file containing the phase XML data
85  * to set up the object
86  * @param id ID of the phase in the input file. Defaults to the
87  * empty string.
88  */
89  IonsFromNeutralVPSSTP(const std::string& inputFile,
90  const std::string& id = "");
91 
92  //! Construct and initialize an IonsFromNeutralVPSSTP object
93  //! directly from an XML database
94  /*!
95  * @param phaseRoot XML phase node containing the description of the phase
96  * @param id id attribute containing the name of the phase.
97  * (default is the empty string)
98  */
99  IonsFromNeutralVPSSTP(XML_Node& phaseRoot, const std::string& id = "");
100 
101  // @}
102  //! @name Utilities
103  //! @{
104 
105  virtual std::string type() const {
106  return "IonsFromNeutral";
107  }
108 
109  //! @}
110  //! @name Molar Thermodynamic Properties
111  //! @{
112 
113  //! Return the Molar enthalpy. Units: J/kmol.
114  /*!
115  * This is calculated from the partial molar enthalpies of the species.
116  */
117  virtual doublereal enthalpy_mole() const;
118 
119  virtual doublereal entropy_mole() const;
120  virtual doublereal gibbs_mole() const;
121  virtual doublereal cp_mole() const;
122  virtual doublereal cv_mole() const;
123 
124  /**
125  * @}
126  * @name Activities, Standard States, and Activity Concentrations
127  *
128  * The activity \f$a_k\f$ of a species in solution is
129  * related to the chemical potential by \f[ \mu_k = \mu_k^0(T)
130  * + \hat R T \log a_k. \f] The quantity \f$\mu_k^0(T,P)\f$ is
131  * the chemical potential at unit activity, which depends only
132  * on temperature and pressure.
133  * @{
134  */
135 
136  virtual void getActivityCoefficients(doublereal* ac) const;
137 
138  //@}
139  /// @name Partial Molar Properties of the Solution
140  //@{
141 
142  virtual void getChemPotentials(doublereal* mu) const;
143 
144  //! Returns an array of partial molar enthalpies for the species in the
145  //! mixture.
146  /*!
147  * Units (J/kmol)
148  *
149  * For this phase, the partial molar enthalpies are equal to the standard
150  * state enthalpies modified by the derivative of the molality-based
151  * activity coefficient wrt temperature
152  *
153  * \f[
154  * \bar h_k(T,P) = h^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT}
155  * \f]
156  *
157  * @param hbar Output vector of species partial molar enthalpies.
158  * Length: m_kk. Units: J/kmol
159  */
160  virtual void getPartialMolarEnthalpies(doublereal* hbar) const;
161 
162  //! Returns an array of partial molar entropies for the species in the
163  //! mixture.
164  /*!
165  * Units (J/kmol)
166  *
167  * For this phase, the partial molar enthalpies are equal to the standard
168  * state enthalpies modified by the derivative of the activity coefficient
169  * wrt temperature
170  *
171  * \f[
172  * \bar s_k(T,P) = s^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT}
173  * - R \ln( \gamma_k X_k)
174  * - R T \frac{d \ln(\gamma_k) }{dT}
175  * \f]
176  *
177  * @param sbar Output vector of species partial molar entropies.
178  * Length: m_kk. Units: J/kmol/K
179  */
180  virtual void getPartialMolarEntropies(doublereal* sbar) const;
181 
182  virtual void getdlnActCoeffds(const doublereal dTds, const doublereal* const dXds,
183  doublereal* dlnActCoeffds) const;
184  virtual void getdlnActCoeffdlnX_diag(doublereal* dlnActCoeffdlnX_diag) const;
185  virtual void getdlnActCoeffdlnN_diag(doublereal* dlnActCoeffdlnN_diag) const;
186  virtual void getdlnActCoeffdlnN(const size_t ld, doublereal* const dlnActCoeffdlnN);
187  //! @}
188 
189  //! Get the Salt Dissociation Coefficients.
190  //! Returns the vector of dissociation coefficients and vector of charges
191  /*!
192  * @param fm_neutralMolec_ions Returns the formula matrix for the
193  * composition of neutral molecules in terms of the ions.
194  * @param charges Returns a vector containing the charges of
195  * all species in this phase
196  * @param neutMolIndex Returns the vector fm_invert_ionForNeutral
197  * This is the mapping between ion species and neutral molecule for
198  * quick invert.
199  */
200  void getDissociationCoeffs(vector_fp& fm_neutralMolec_ions, vector_fp& charges, std::vector<size_t>& neutMolIndex) const;
201 
202  //! Return the current value of the neutral mole fraction vector
203  /*!
204  * @param neutralMoleculeMoleFractions Vector of neutral molecule mole
205  * fractions.
206  */
207  void getNeutralMolecMoleFractions(vector_fp& neutralMoleculeMoleFractions) const {
208  neutralMoleculeMoleFractions = NeutralMolecMoleFractions_;
209  }
210 
211  //! Calculate neutral molecule mole fractions
212  /*!
213  * This routine calculates the neutral molecule mole fraction given the
214  * vector of ion mole fractions, i.e., the mole fractions from this
215  * ThermoPhase. Note, this routine basically assumes that there is charge
216  * neutrality. If there isn't, then it wouldn't make much sense.
217  *
218  * for the case of cIonSolnType_SINGLEANION, some slough in the charge
219  * neutrality is allowed. The cation number is followed, while the
220  * difference in charge neutrality is dumped into the anion mole number to
221  * fix the imbalance.
222  *
223  * @param dx input vector of ion mole fraction gradients
224  * @param dy output Vector of neutral molecule mole fraction gradients
225  */
226  void getNeutralMoleculeMoleGrads(const doublereal* const dx, doublereal* const dy) const;
227 
228  //! Get the list of cations in this object
229  /*!
230  * @param cation List of cations
231  */
232  void getCationList(std::vector<size_t>& cation) const {
233  cation=cationList_;
234  }
235 
236  //! Get the list of anions in this object
237  /*!
238  * @param anion List of anions
239  */
240  void getAnionList(std::vector<size_t>& anion) const {
241  anion=anionList_;
242  }
243 
244  /**
245  * @name Setting the State
246  * These methods set all or part of the thermodynamic state.
247  * @{
248  */
249 
250  virtual void calcDensity();
251 
252  //! Calculate ion mole fractions from neutral molecule mole fractions.
253  /*!
254  * @param mf Dump the mole fractions into this vector.
255  */
256  virtual void calcIonMoleFractions(doublereal* const mf) const;
257 
258  //! Calculate neutral molecule mole fractions
259  /*!
260  * This routine calculates the neutral molecule mole fraction given the
261  * vector of ion mole fractions, i.e., the mole fractions from this
262  * ThermoPhase. Note, this routine basically assumes that there is charge
263  * neutrality. If there isn't, then it wouldn't make much sense.
264  *
265  * for the case of cIonSolnType_SINGLEANION, some slough in the charge
266  * neutrality is allowed. The cation number is followed, while the
267  * difference in charge neutrality is dumped into the anion mole number to
268  * fix the imbalance.
269  */
270  virtual void calcNeutralMoleculeMoleFractions() const;
271 
272  //@}
273 
274  virtual bool addSpecies(shared_ptr<Species> spec);
275  void setNeutralMoleculePhase(shared_ptr<ThermoPhase> neutral);
276  shared_ptr<ThermoPhase> getNeutralMoleculePhase();
277 
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 private:
405  GibbsExcessVPSSTP* geThermo;
406  // Temporary vectors that I don't want to allocate every time the function
407  // is called
408  mutable vector_fp y_;
409  mutable vector_fp dlnActCoeff_NeutralMolecule_;
410  mutable vector_fp dX_NeutralMolecule_;
411  mutable vector_fp m_work; // length m_kk
412 
413  //! Temporary mole fraction vector
415 
416  //! Storage vector for the neutral molecule chemical potentials
417  /*!
418  * This vector is used as a temporary storage area when calculating the ion
419  * chemical potentials.
420  *
421  * - Units = Joules/kmol
422  * - Length = numNeutralMoleculeSpecies_
423  */
425 
426  //! Storage vector for the neutral molecule ln activity coefficients
427  /*!
428  * This vector is used as a temporary storage area when calculating the ion
429  * chemical potentials and activity coefficients
430  *
431  * - Units = none
432  * - Length = numNeutralMoleculeSpecies_
433  */
435 
436  //! Storage vector for the neutral molecule d ln activity coefficients dT
437  /*!
438  * This vector is used as a temporary storage area when calculating the ion
439  * derivatives
440  *
441  * - Units = 1/Kelvin
442  * - Length = numNeutralMoleculeSpecies_
443  */
445 
446  //! Storage vector for the neutral molecule d ln activity coefficients dX -
447  //! diagonal component
448  /*!
449  * This vector is used as a temporary storage area when calculating the ion
450  * derivatives
451  *
452  * - Units = none
453  * - Length = numNeutralMoleculeSpecies_
454  */
456 
457  //! Storage vector for the neutral molecule d ln activity coefficients dlnN
458  //! - diagonal component
459  /*!
460  * This vector is used as a temporary storage area when calculating the ion
461  * derivatives
462  *
463  * - Units = none
464  * - Length = numNeutralMoleculeSpecies_
465  */
467 
468  //! Storage vector for the neutral molecule d ln activity coefficients dlnN
469  /*!
470  * This vector is used as a temporary storage area when calculating the ion
471  * derivatives
472  *
473  * - Units = none
474  * - Length = numNeutralMoleculeSpecies_
475  */
477 };
478 
479 }
480 
481 #endif
vector_fp muNeutralMolecule_
Storage vector for the neutral molecule chemical potentials.
vector_fp NeutralMolecMoleFractions_
Mole fractions using the Neutral Molecule Mole fraction basis.
size_t indexSpecialSpecies_
Index of special species.
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:97
void s_update_dlnActCoeff() const
Update the change in the ln activity coefficients.
virtual std::string type() const
String indicating the thermodynamic model implemented.
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.
void getAnionList(std::vector< size_t > &anion) const
Get the list of anions in this object.
A class for 2D arrays stored in column-major (Fortran-compatible) form.
Definition: Array.h:31
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.
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.
Header for intermediate ThermoPhase object for phases which employ Gibbs excess free energy based for...
virtual doublereal gibbs_mole() const
Molar Gibbs function. Units: J/kmol.
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)
void getNeutralMolecMoleFractions(vector_fp &neutralMoleculeMoleFractions) const
Return the current value of the neutral mole fraction vector.
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.
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
std::vector< size_t > passThroughList_
List of the species in this ThermoPhase which are passed through to the neutralMoleculePhase ThermoPh...
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...
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:157
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 &thermoNode)
Set equation of state parameter values from XML entries.
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
std::vector< size_t > cationList_
List of the species in this ThermoPhase which are cation 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...
void getCationList(std::vector< size_t > &cation) const
Get the list of cations in this object.
void getDissociationCoeffs(vector_fp &fm_neutralMolec_ions, vector_fp &charges, std::vector< size_t > &neutMolIndex) const
Get the Salt Dissociation Coefficients.
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:8
size_t numNeutralMoleculeSpecies_
Number of neutral molecule species.
virtual doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
vector_fp moleFractionsTmp_
Temporary mole fraction vector.
void getNeutralMoleculeMoleGrads(const doublereal *const dx, doublereal *const dy) const
Calculate neutral molecule mole fractions.
void s_update_dlnActCoeff_dlnN_diag() const
Update the derivative of the log of the activity coefficients wrt log(number of moles) - diagonal com...
IonSolnType_enumType
enums for molten salt ion solution types
vector_fp dlnActCoeffdlnX_diag_NeutralMolecule_
Storage vector for the neutral molecule d ln activity coefficients dX - diagonal component.