Cantera  3.1.0a1
BinarySolutionTabulatedThermo.h
Go to the documentation of this file.
1 /**
2  * @file BinarySolutionTabulatedThermo.h
3  * Header file for an binary solution model with tabulated standard state
4  * thermodynamic data (see @ref thermoprops and class
5  * @link Cantera::BinarySolutionTabulatedThermo BinarySolutionTabulatedThermo@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_BINARYSOLUTIONTABULATEDTHERMO_H
12 #define CT_BINARYSOLUTIONTABULATEDTHERMO_H
13 
14 #include "IdealSolidSolnPhase.h"
15 #include "cantera/base/utilities.h"
16 
17 namespace Cantera
18 {
19 
20 //! Overloads the virtual methods of class IdealSolidSolnPhase to implement
21 //! tabulated standard state thermodynamics for one species in a binary
22 //! solution.
23 /**
24  *
25  * BinarySolutionTabulatedThermo is derived from IdealSolidSolnPhase, but
26  * overwrites the standard state thermodynamic data using tabulated data,
27  * as provided by the user in the input file. This ends up being useful for
28  * certain non-ideal / non-dilute species where the interaction potentials, as
29  * a function of composition / solute mole fraction, are not easily represented
30  * by any closed-form equation of state.
31  *
32  * A good example of this type of phase is intercalation-based lithium storage
33  * materials used for lithium-ion battery electrodes. Measuring the open
34  * circuit voltage @f$ E_eq @f$, relative to a reference electrode, as a
35  * function of lithium mole fraction and as a function of temperature, provides
36  * a means to evaluate the gibbs free energy of reaction:
37  *
38  * @f[
39  * \Delta g_{\rm rxn} = -\frac{E_eq}{nF}
40  * @f]
41  *
42  * where @f$ n @f$ is the charge number transferred to the phase, via the
43  * reaction, and @f$ F @f$ is Faraday's constant. The gibbs energy of
44  * reaction, in turn, can be separated into enthalpy and entropy of reaction
45  * components:
46  *
47  * @f[
48  * \Delta g_{\rm rxn} = \Delta h_{\rm rxn} - T\Delta s_{\rm rxn}
49  * @f]
50  * @f[
51  * \frac{d\Delta g_{\rm rxn}}{dT} = - \Delta s_{\rm rxn}
52  * @f]
53  *
54  * For the tabulated binary phase, the user identifies a 'tabulated' species,
55  * while the other is considered the 'reference' species. The standard state
56  * thermo variables for the tabulated species therefore incorporate any and all
57  * excess energy contributions, and are calculated according to the reaction
58  * energy terms:
59  *
60  * @f[
61  * \Delta h_{\rm rxn} = \sum_k \nu_k h^{\rm o}_k
62  * @f]
63  * @f[
64  * \Delta s_{\rm rxn} = \sum_k \nu_k s^{\rm o}_k + RT\ln\left(\prod_k\left(\frac{c_k}{c^{\rm o}_k} \right)^{\nu_k}\right)
65  * @f]
66  *
67  * Where the 'reference' species is automatically assigned standard state
68  * thermo variables @f$ h^{\rm o} = 0 @f$ and @f$ s^{\rm o} = 0 @f$, and standard
69  * state thermo variables for species in any other phases are calculated
70  * according to the rules specified in that phase definition.
71  *
72  * The present model is intended for modeling non-ideal, tabulated
73  * thermodynamics for binary solutions where the tabulated species is
74  * incorporated via an electrochemical reaction, such that the open circuit
75  * voltage can be measured, relative to a counter electrode species with
76  * standard state thermo properties @f$ h^{\rm o} = 0 @f$.
77  * It is possible that this can be generalized such that this assumption about
78  * the counter-electrode is not required. At present, this is left as future
79  * work.
80  *
81  * The user therefore provides a table of three equally-sized vectors of
82  * tabulated data:
83  *
84  * - @f$ x_{\rm tab} @f$ = array of mole fractions for the tabulated species
85  * at which measurements were conducted and thermo
86  * data are provided.
87  * - @f$ h_{\rm tab} @f$ = @f$ F\left(-E_{\rm eq}\left(x,T^{\rm o} \right) + T^{\rm o} \frac{dE_{\rm eq}\left(x,T^{\rm o} \right)}{dT}\right) @f$
88  * - @f$ s_{\rm tab} @f$ = @f$ F \left(\frac{dE_{\rm eq}\left(x,T^{\rm o} \right)}{dT} + s_{\rm counter}^{\rm o} \right) @f$
89  *
90  * where @f$ E_{\rm eq}\left(x,T^{\rm o} \right) @f$ and @f$ \frac{dE_{\rm eq}\left(x,T^{\rm o} \right)}{dT} @f$
91  * are the experimentally-measured open circuit voltage and derivative in
92  * open circuit voltage with respect to temperature, respectively, both
93  * measured as a mole fraction of @f$ x @f$ for the tabulated species and at a
94  * temperature of @f$ T^{\rm o} @f$. The arrays @f$ h_{\rm tab} @f$ and
95  * @f$ s_{\rm tab} @f$ must be the same length as the @f$ x_{\rm tab} @f$ array.
96  *
97  * From these tabulated inputs, the standard state thermodynamic properties
98  * for the tabulated species (subscript @f$ k @f$, tab) are calculated as:
99  *
100  * @f[
101  * h^{\rm o}_{k,\,{\rm tab}} = h_{\rm tab}
102  * @f]
103  * @f[
104  * s^{\rm o}_{k,\,{\rm tab}} = s_{\rm tab} + R\ln\frac{x_{k,\,{\rm tab}}}{1-x_{k,\,{\rm tab}}} + \frac{R}{F} \ln\left(\frac{c^{\rm o}_{k,\,{\rm ref}}}{c^{\rm o}_{k,\,{\rm tab}}}\right)
105  * @f]
106  *
107  * Now, whenever the composition has changed, the lookup/interpolation of the
108  * tabulated thermo data is performed to update the standard state
109  * thermodynamic data for the tabulated species.
110  *
111  * Furthermore, there is an optional feature to include non-ideal effects regarding
112  * partial molar volumes of the species, @f$ \bar V_k @f$. Being derived from
113  * IdealSolidSolnPhase, the default assumption in BinarySolutionTabulatedThermo
114  * is that the species comprising the binary solution have constant partial molar
115  * volumes equal to their pure species molar volumes. However, this assumption only
116  * holds true if there is no or only weak interactions between the two species in the
117  * binary mixture. In non-ideal solid materials, for example intercalation-based
118  * lithium storage materials, the partial molar volumes of the species typically show a
119  * strong non-linear dependency on the composition of the mixture. These dependencies
120  * can most often only be determined experimentally, for example via X-ray diffraction
121  * (XRD) measurements of the unit cell volume. Therefore, the user can provide an optional fourth vector of
122  * tabulated molar volume data with the same size as the other tabulated data:
123  *
124  * - @f$ V_{\mathrm{m,tab}} @f$ = array of the molar volume of the binary solution phase at
125  * the tabulated mole fractions.
126  *
127  * The partial molar volumes @f$ \bar V_1 @f$ of the tabulated species and
128  * @f$ \bar V_2 @f$ of the 'reference' species, respectively, can then be derived from
129  * the provided molar volume:
130  *
131  * @f[
132  * \bar V_1 = V_{\mathrm{m,tab}} + \left(1-x_{\mathrm {tab}}\right) \cdot
133  * \frac{\mathrm{d}V_{\mathrm{m,tab}}}{\mathrm{d}x_{\mathrm {tab}}} \\
134  * \bar V_2 = V_{\mathrm{m,tab}} - x_{\mathrm {tab}} \cdot
135  * \frac{\mathrm{d}V_{\mathrm{m,tab}}}{\mathrm{d}x_{\mathrm {tab}}}
136  * @f]
137  *
138  * The derivation is implemented using forward differences at the boundaries of the
139  * input vector and a central differencing scheme at interior points. As the
140  * derivative is determined numerically, the input data should be relatively smooth
141  * (recommended is one data point for every mole fraction per cent). The calculated
142  * partial molar volumes are accessible to the user via getPartialMolarVolumes().
143  *
144  * The calculation of the mass density incorporates the non-ideal behavior by using
145  * the provided molar volume in the equation:
146  *
147  * @f[
148  * \rho = \frac{\sum_k{x_k W_k}}{V_\mathrm{m}}
149  * @f]
150  *
151  * where @f$ x_k @f$ are the mole fractions, @f$ W_k @f$ are the molecular weights, and
152  * @f$ V_\mathrm{m} @f$ is the molar volume interpolated from @f$ V_{\mathrm{m,tab}} @f$.
153  *
154  * If the optional fourth input vector is not specified, the molar volume is calculated
155  * by using the pure species molar volumes, as in IdealSolidSolnPhase. Regardless if the
156  * molarVolume key is provided or not, the equation-of-state field in the pure species
157  * entries has to be defined.
158  *
159  * @ingroup thermoprops
160  */
162 {
163 public:
164  //! Construct and initialize an BinarySolutionTabulatedThermo ThermoPhase object
165  //! directly from an input file
166  /*!
167  * This constructor will also fully initialize the object.
168  *
169  * @param infile File name for the input file containing information
170  * for this phase. If not specified, an empty phase will be created.
171  * @param id The name of this phase. This is used to look up
172  * the phase in the input file.
173  */
174  explicit BinarySolutionTabulatedThermo(const string& infile="", const string& id="");
175 
176  string type() const override {
177  return "binary-solution-tabulated";
178  }
179 
180  bool addSpecies(shared_ptr<Species> spec) override;
181  void initThermo() override;
182  bool ready() const override;
183  void getParameters(AnyMap& phaseNode) const override;
184 
185  /**
186  * returns an array of partial molar volumes of the species
187  * in the solution. Units: m^3 kmol-1.
188  *
189  * The partial molar volumes are derived as shown in the equations in the detailed
190  * description section.
191  *
192  * @param vbar Output vector of partial molar volumes. Length: m_kk.
193  */
194  void getPartialMolarVolumes(double* vbar) const override;
195 
196  /**
197  * Overloads the calcDensity() method of IdealSolidSoln to also consider non-ideal
198  * behavior.
199  *
200  * The formula for this is
201  *
202  * @f[
203  * \rho = \frac{\sum_k{X_k W_k}}{V_\mathrm{m}}
204  * @f]
205  *
206  * where @f$ X_k @f$ are the mole fractions, @f$ W_k @f$ are the molecular weights, and
207  * @f$ V_\mathrm{m} @f$ is the molar volume interpolated from @f$ V_{\mathrm{m,tab}} @f$.
208  */
209  void calcDensity() override;
210 
211 protected:
212  //! If the compositions have changed, update the tabulated thermo lookup
213  void compositionChanged() override;
214 
215  //! Species thermodynamics linear interpolation function
216  /*!
217  * Tabulated values are only interpolated within the limits of the provided mole
218  * fraction. If these limits are exceeded, the values are capped at the lower or
219  * the upper limit.
220  *
221  * @param x Current mole fraction at which to interpolate.
222  * @param inputData Input vector of the data to be interpolated.
223  * @returns Linear interpolation of tabulated data at the current
224  * mole fraction x.
225  */
226  double interpolate(const double x, const vector<double>& inputData) const;
227 
228  //! Numerical derivative of the molar volume table
229  /*!
230  * Tabulated values are only interpolated within the limits of the provided mole
231  * fraction. If these limits are exceeded, the values are capped at the lower or
232  * the upper limit.
233  *
234  * @param inputData Input vector of tabulated data to be derived.
235  * @param derivedData Output vector of tabulated data that is numerically
236  * derived with respect to the mole fraction.
237  */
238  void diff(const vector<double>& inputData, vector<double>& derivedData) const;
239 
240  //! Current tabulated species index
241  size_t m_kk_tab = npos;
242 
243  //! Tabulated contribution to h0[m_kk_tab] at the current composition
244  mutable double m_h0_tab;
245 
246  //! Tabulated contribution to s0[m_kk_tab] at the current composition
247  mutable double m_s0_tab;
248 
249  //! Vector for storing tabulated thermo
250  vector<double> m_molefrac_tab;
251  vector<double> m_enthalpy_tab;
252  vector<double> m_entropy_tab;
253  vector<double> m_molar_volume_tab;
254  vector<double> m_derived_molar_volume_tab;
255 
256 private:
257  void _updateThermo() const override;
258 };
259 }
260 
261 #endif
Header file for an ideal solid solution model with incompressible thermodynamics (see Thermodynamic P...
A map of string keys to values whose type can vary at runtime.
Definition: AnyMap.h:427
Overloads the virtual methods of class IdealSolidSolnPhase to implement tabulated standard state ther...
vector< double > m_molefrac_tab
Vector for storing tabulated thermo.
double m_s0_tab
Tabulated contribution to s0[m_kk_tab] at the current composition.
void getParameters(AnyMap &phaseNode) const override
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
string type() const override
String indicating the thermodynamic model implemented.
void initThermo() override
Initialize the ThermoPhase object after all species have been set up.
void getPartialMolarVolumes(double *vbar) const override
returns an array of partial molar volumes of the species in the solution.
double interpolate(const double x, const vector< double > &inputData) const
Species thermodynamics linear interpolation function.
size_t m_kk_tab
Current tabulated species index.
void diff(const vector< double > &inputData, vector< double > &derivedData) const
Numerical derivative of the molar volume table.
void calcDensity() override
Overloads the calcDensity() method of IdealSolidSoln to also consider non-ideal behavior.
BinarySolutionTabulatedThermo(const string &infile="", const string &id="")
Construct and initialize an BinarySolutionTabulatedThermo ThermoPhase object directly from an input f...
double m_h0_tab
Tabulated contribution to h0[m_kk_tab] at the current composition.
void compositionChanged() override
If the compositions have changed, update the tabulated thermo lookup.
bool ready() const override
Returns a bool indicating whether the object is ready for use.
bool addSpecies(shared_ptr< Species > spec) override
Add a Species to this Phase.
void _updateThermo() const override
This function gets called for every call to functions in this class.
Class IdealSolidSolnPhase represents a condensed phase ideal solution compound.
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:564
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:180
Various templated functions that carry out common vector and polynomial operations (see Templated Arr...