Cantera  2.3.0
HMWSoln.h
Go to the documentation of this file.
1 /**
2  * @file HMWSoln.h
3  * Headers for the HMWSoln ThermoPhase object, which models concentrated
4  * electrolyte solutions
5  * (see \ref thermoprops and \link Cantera::HMWSoln HMWSoln \endlink) .
6  *
7  * Class HMWSoln represents a concentrated liquid electrolyte phase which
8  * obeys the Pitzer formulation for nonideality using molality-based
9  * standard states.
10  */
11 
12 // This file is part of Cantera. See License.txt in the top-level directory or
13 // at http://www.cantera.org/license.txt for license and copyright information.
14 
15 #ifndef CT_HMWSOLN_H
16 #define CT_HMWSOLN_H
17 
18 #include "MolalityVPSSTP.h"
19 #include "cantera/base/Array.h"
20 
21 namespace Cantera
22 {
23 
24 /**
25  * Major Parameters:
26  * The form of the Pitzer expression refers to the form of the Gibbs free
27  * energy expression. The temperature dependence of the Pitzer coefficients
28  * are handled by another parameter.
29  *
30  * m_formPitzer = Form of the Pitzer expression
31  *
32  * PITZERFORM_BASE = 0
33  *
34  * Only one form is supported atm. This parameter is included for
35  * future expansion.
36  */
37 #define PITZERFORM_BASE 0
38 
39 /*!
40  * @name Temperature Dependence of the Pitzer Coefficients
41  *
42  * Note, the temperature dependence of the Gibbs free energy also depends on the
43  * temperature dependence of the standard state and the temperature dependence
44  * of the Debye-Huckel constant, which includes the dielectric constant and the
45  * density. Therefore, this expression defines only part of the temperature
46  * dependence for the mixture thermodynamic functions.
47  *
48  * PITZER_TEMP_CONSTANT
49  * All coefficients are considered constant wrt temperature
50  * PITZER_TEMP_LINEAR
51  * All coefficients are assumed to have a linear dependence
52  * wrt to temperature.
53  * PITZER_TEMP_COMPLEX1
54  * All coefficients are assumed to have a complex functional
55  * based dependence wrt temperature; See:
56  * (Silvester, Pitzer, J. Phys. Chem. 81, 19 1822 (1977)).
57  *
58  * beta0 = q0 + q3(1/T - 1/Tr) + q4(ln(T/Tr)) +
59  * q1(T - Tr) + q2(T**2 - Tr**2)
60  */
61 //@{
62 #define PITZER_TEMP_CONSTANT 0
63 #define PITZER_TEMP_LINEAR 1
64 #define PITZER_TEMP_COMPLEX1 2
65 //@}
66 
67 /*
68  * @name ways to calculate the value of A_Debye
69  *
70  * These defines determine the way A_Debye is calculated
71  */
72 //@{
73 #define A_DEBYE_CONST 0
74 #define A_DEBYE_WATER 1
75 //@}
76 
77 class WaterProps;
78 
79 /**
80  * Class HMWSoln represents a dilute or concentrated liquid electrolyte
81  * phase which obeys the Pitzer formulation for nonideality.
82  *
83  * As a prerequisite to the specification of thermodynamic quantities,
84  * The concentrations of the ionic species are assumed to obey the
85  * electroneutrality condition.
86  *
87  * ## Specification of Species Standard State Properties
88  *
89  * The solvent is assumed to be liquid water. A real model for liquid water
90  * (IAPWS 1995 formulation) is used as its standard state. All standard state
91  * properties for the solvent are based on this real model for water, and
92  * involve function calls to the object that handles the real water model,
93  * #Cantera::WaterPropsIAPWS.
94  *
95  * The standard states for solutes are on the unit molality basis. Therefore, in
96  * the documentation below, the normal \f$ o \f$ superscript is replaced with
97  * the \f$ \triangle \f$ symbol. The reference state symbol is now
98  * \f$ \triangle, ref \f$.
99  *
100  * It is assumed that the reference state thermodynamics may be obtained by a
101  * pointer to a populated species thermodynamic property manager class (see
102  * ThermoPhase::m_spthermo). How to relate pressure changes to the reference
103  * state thermodynamics is resolved at this level.
104  *
105  * For solutes that rely on ThermoPhase::m_spthermo, are assumed to have an
106  * incompressible standard state mechanical property. In other words, the molar
107  * volumes are independent of temperature and pressure.
108  *
109  * For these incompressible, standard states, the molar internal energy is
110  * independent of pressure. Since the thermodynamic properties are specified by
111  * giving the standard-state enthalpy, the term \f$ P_0 \hat v\f$ is subtracted
112  * from the specified molar enthalpy to compute the molar internal energy. The
113  * entropy is assumed to be independent of the pressure.
114  *
115  * The enthalpy function is given by the following relation.
116  *
117  * \f[
118  * h^\triangle_k(T,P) = h^{\triangle,ref}_k(T)
119  * + \tilde{v}_k \left( P - P_{ref} \right)
120  * \f]
121  *
122  * For an incompressible, stoichiometric substance, the molar internal energy is
123  * independent of pressure. Since the thermodynamic properties are specified by
124  * giving the standard-state enthalpy, the term \f$ P_{ref} \tilde v\f$ is
125  * subtracted from the specified reference molar enthalpy to compute the molar
126  * internal energy.
127  *
128  * \f[
129  * u^\triangle_k(T,P) = h^{\triangle,ref}_k(T) - P_{ref} \tilde{v}_k
130  * \f]
131  *
132  * The solute standard state heat capacity and entropy are independent of
133  * pressure. The solute standard state Gibbs free energy is obtained from the
134  * enthalpy and entropy functions.
135  *
136  * The vector Phase::m_speciesSize[] is used to hold the base values of species
137  * sizes. These are defined as the molar volumes of species at infinite dilution
138  * at 300 K and 1 atm of water. m_speciesSize are calculated during the
139  * initialization of the HMWSoln object and are then not touched.
140  *
141  * The current model assumes that an incompressible molar volume for all
142  * solutes. The molar volume for the water solvent, however, is obtained from a
143  * pure water equation of state, waterSS. Therefore, the water standard state
144  * varies with both T and P. It is an error to request standard state water
145  * properties at a T and P where the water phase is not a stable phase, i.e.,
146  * beyond its spinodal curve.
147  *
148  * ## Specification of Solution Thermodynamic Properties
149  *
150  * Chemical potentials of the solutes, \f$ \mu_k \f$, and the solvent, \f$ \mu_o
151  * \f$, which are based on the molality form, have the following general format:
152  *
153  * \f[
154  * \mu_k = \mu^{\triangle}_k(T,P) + R T ln(\gamma_k^{\triangle} \frac{m_k}{m^\triangle})
155  * \f]
156  * \f[
157  * \mu_o = \mu^o_o(T,P) + RT ln(a_o)
158  * \f]
159  *
160  * where \f$ \gamma_k^{\triangle} \f$ is the molality based activity coefficient
161  * for species \f$k\f$.
162  *
163  * Individual activity coefficients of ions can not be independently measured.
164  * Instead, only binary pairs forming electroneutral solutions can be measured.
165  * This problem leads to a redundancy in the evaluation of species standard
166  * state properties. The redundancy issue is resolved by setting the standard
167  * state chemical potential enthalpy, entropy, and volume for the hydrogen ion,
168  * H+, to zero, for every temperature and pressure. After this convention is
169  * applied, all other standard state properties of ionic species contain
170  * meaningful information.
171  *
172  * ### Ionic Strength
173  *
174  * Most of the parameterizations within the model use the ionic strength as a
175  * key variable. The ionic strength, \f$ I\f$ is defined as follows
176  *
177  * \f[
178  * I = \frac{1}{2} \sum_k{m_k z_k^2}
179  * \f]
180  *
181  * \f$ m_k \f$ is the molality of the kth species. \f$ z_k \f$ is the charge of
182  * the kth species. Note, the ionic strength is a defined units quantity. The
183  * molality has defined units of gmol kg-1, and therefore the ionic strength has
184  * units of sqrt(gmol/kg).
185  *
186  * In some instances, from some authors, a different formulation is used for the
187  * ionic strength in the equations below. The different formulation is due to
188  * the possibility of the existence of weak acids and how association wrt to the
189  * weak acid equilibrium relation affects the calculation of the activity
190  * coefficients via the assumed value of the ionic strength.
191  *
192  * If we are to assume that the association reaction doesn't have an effect on
193  * the ionic strength, then we will want to consider the associated weak acid as
194  * in effect being fully dissociated, when we calculate an effective value for
195  * the ionic strength. We will call this calculated value, the stoichiometric
196  * ionic strength, \f$ I_s \f$, putting a subscript s to denote it from the more
197  * straightforward calculation of \f$ I \f$.
198  *
199  * \f[
200  * I_s = \frac{1}{2} \sum_k{m_k^s z_k^2}
201  * \f]
202  *
203  * Here, \f$ m_k^s \f$ is the value of the molalities calculated assuming that
204  * all weak acid-base pairs are in their fully dissociated states. This
205  * calculation may be simplified by considering that the weakly associated acid
206  * may be made up of two charged species, k1 and k2, each with their own
207  * charges, obeying the following relationship:
208  *
209  * \f[
210  * z_k = z_{k1} + z_{k2}
211  * \f]
212  * Then, we may only need to specify one charge value, say, \f$ z_{k1}\f$, the
213  * cation charge number, in order to get both numbers, since we have already
214  * specified \f$ z_k \f$ in the definition of original species. Then, the
215  * stoichiometric ionic strength may be calculated via the following formula.
216  *
217  * \f[
218  * I_s = \frac{1}{2} \left(\sum_{k,ions}{m_k z_k^2}+
219  * \sum_{k,weak_assoc}(m_k z_{k1}^2 + m_k z_{k2}^2) \right)
220  * \f]
221  *
222  * The specification of which species are weakly associated acids is made in the
223  * input file via the `stoichIsMods` XML block, where the charge for k1 is also
224  * specified. An example is given below:
225  *
226  * @code
227  * <stoichIsMods>
228  * NaCl(aq):-1.0
229  * </stoichIsMods>
230  * @endcode
231  *
232  * Because we need the concept of a weakly associated acid in order to calculated
233  * \f$ I_s \f$ we need to catalog all species in the phase. This is done using
234  * the following categories:
235  *
236  * - `cEST_solvent` Solvent species (neutral)
237  * - `cEST_chargedSpecies` Charged species (charged)
238  * - `cEST_weakAcidAssociated` Species which can break apart into charged species.
239  * It may or may not be charged. These may or
240  * may not be be included in the
241  * species solution vector.
242  * - `cEST_strongAcidAssociated` Species which always breaks apart into charged species.
243  * It may or may not be charged. Normally, these
244  * aren't included in the speciation vector.
245  * - `cEST_polarNeutral` Polar neutral species
246  * - `cEST_nonpolarNeutral` Non polar neutral species
247  *
248  * Polar and non-polar neutral species are differentiated, because some
249  * additions to the activity coefficient expressions distinguish between these
250  * two types of solutes. This is the so-called salt-out effect.
251  *
252  * The type of species is specified in the `electrolyteSpeciesType` XML block.
253  * Note, this is not considered a part of the specification of the standard
254  * state for the species, at this time. Therefore, this information is put under
255  * the `activityCoefficient` XML block. An example is given below
256  *
257  * @code
258  * <electrolyteSpeciesType>
259  * H2L(L):solvent
260  * H+:chargedSpecies
261  * NaOH(aq):weakAcidAssociated
262  * NaCl(aq):strongAcidAssociated
263  * NH3(aq):polarNeutral
264  * O2(aq):nonpolarNeutral
265  * </electrolyteSpeciesType>
266  * @endcode
267  *
268  * Much of the species electrolyte type information is inferred from other
269  * information in the input file. For example, as species which is charged is
270  * given the "chargedSpecies" default category. A neutral solute species is put
271  * into the "nonpolarNeutral" category by default.
272  *
273  * ### Specification of the Excess Gibbs Free Energy
274  *
275  * Pitzer's formulation may best be represented as a specification of the excess
276  * Gibbs free energy, \f$ G^{ex} \f$, defined as the deviation of the total
277  * Gibbs free energy from that of an ideal molal solution.
278  * \f[
279  * G = G^{id} + G^{ex}
280  * \f]
281  *
282  * The ideal molal solution contribution, not equal to an ideal solution
283  * contribution and in fact containing a singularity at the zero solvent mole
284  * fraction limit, is given below.
285  * \f[
286  * G^{id} = n_o \mu^o_o + \sum_{k\ne o} n_k \mu_k^{\triangle}
287  * + \tilde{M}_o n_o ( RT (\sum{m_i(\ln(m_i)-1)}))
288  * \f]
289  *
290  * From the excess Gibbs free energy formulation, the activity coefficient
291  * expression and the osmotic coefficient expression for the solvent may be
292  * defined, by taking the appropriate derivatives. Using this approach
293  * guarantees that the entire system will obey the Gibbs-Duhem relations.
294  *
295  * Pitzer employs the following general expression for the excess Gibbs free
296  * energy
297  *
298  * \f[
299  * \begin{array}{cclc}
300  * \frac{G^{ex}}{\tilde{M}_o n_o RT} &= &
301  * \left( \frac{4A_{Debye}I}{3b} \right) \ln(1 + b \sqrt{I})
302  * + 2 \sum_c \sum_a m_c m_a B_{ca}
303  * + \sum_c \sum_a m_c m_a Z C_{ca}
304  * \\&&
305  * + \sum_{c < c'} \sum m_c m_{c'} \left[ 2 \Phi_{c{c'}} + \sum_a m_a \Psi_{c{c'}a} \right]
306  * + \sum_{a < a'} \sum m_a m_{a'} \left[ 2 \Phi_{a{a'}} + \sum_c m_c \Psi_{a{a'}c} \right]
307  * \\&&
308  * + 2 \sum_n \sum_c m_n m_c \lambda_{nc} + 2 \sum_n \sum_a m_n m_a \lambda_{na}
309  * + 2 \sum_{n < n'} \sum m_n m_{n'} \lambda_{n{n'}}
310  * + \sum_n m^2_n \lambda_{nn}
311  * \end{array}
312  * \f]
313  *
314  * *a* is a subscript over all anions, *c* is a subscript extending over all
315  * cations, and *i* is a subscript that extends over all anions and cations.
316  * *n* is a subscript that extends only over neutral solute molecules. The
317  * second line contains cross terms where cations affect cations and/or
318  * cation/anion pairs, and anions affect anions or cation/anion pairs. Note part
319  * of the coefficients, \f$ \Phi_{c{c'}} \f$ and \f$ \Phi_{a{a'}} \f$ stem from
320  * the theory of unsymmetrical mixing of electrolytes with different charges.
321  * This theory depends on the total ionic strength of the solution, and
322  * therefore, \f$ \Phi_{c{c'}} \f$ and \f$ \Phi_{a{a'}} \f$ will depend on
323  * *I*, the ionic strength. \f$ B_{ca}\f$ is a strong function of the
324  * total ionic strength, *I*, of the electrolyte. The rest of the coefficients
325  * are assumed to be independent of the molalities or ionic strengths. However,
326  * all coefficients are potentially functions of the temperature and pressure
327  * of the solution.
328  *
329  * *A* is the Debye-Huckel constant. Its specification is described in its
330  * own section below.
331  *
332  * \f$ I\f$ is the ionic strength of the solution, and is given by:
333  *
334  * \f[
335  * I = \frac{1}{2} \sum_k{m_k z_k^2}
336  * \f]
337  *
338  * In contrast to several other Debye-Huckel implementations (see \ref
339  * DebyeHuckel), the parameter \f$ b\f$ in the above equation is a constant that
340  * does not vary with respect to ion identity. This is an important
341  * simplification as it avoids troubles with satisfaction of the Gibbs-Duhem
342  * analysis.
343  *
344  * The function \f$ Z \f$ is given by
345  *
346  * \f[
347  * Z = \sum_i m_i \left| z_i \right|
348  * \f]
349  *
350  * The value of \f$ B_{ca}\f$ is given by the following function
351  *
352  * \f[
353  * B_{ca} = \beta^{(0)}_{ca} + \beta^{(1)}_{ca} g(\alpha^{(1)}_{ca} \sqrt{I})
354  * + \beta^{(2)}_{ca} g(\alpha^{(2)}_{ca} \sqrt{I})
355  * \f]
356  *
357  * where
358  *
359  * \f[
360  * g(x) = 2 \frac{(1 - (1 + x)\exp[-x])}{x^2}
361  * \f]
362  *
363  * The formulation for \f$ B_{ca}\f$ combined with the formulation of the Debye-
364  * Huckel term in the eqn. for the excess Gibbs free energy stems essentially
365  * from an empirical fit to the ionic strength dependent data based over a wide
366  * sampling of binary electrolyte systems. \f$ C_{ca} \f$, \f$ \lambda_{nc} \f$,
367  * \f$ \lambda_{na} \f$, \f$ \lambda_{nn} \f$, \f$ \Psi_{c{c'}a} \f$, \f$
368  * \Psi_{a{a'}c} \f$ are experimentally derived coefficients that may have
369  * pressure and/or temperature dependencies.
370  *
371  * The \f$ \Phi_{c{c'}} \f$ and \f$ \Phi_{a{a'}} \f$ formulations are slightly
372  * more complicated. \f$ b \f$ is a universal constant defined to be equal to
373  * \f$ 1.2\ kg^{1/2}\ gmol^{-1/2} \f$. The exponential coefficient \f$
374  * \alpha^{(1)}_{ca} \f$ is usually fixed at \f$ \alpha^{(1)}_{ca} = 2.0\
375  * kg^{1/2} gmol^{-1/2}\f$ except for 2-2 electrolytes, while other parameters
376  * were fit to experimental data. For 2-2 electrolytes, \f$ \alpha^{(1)}_{ca} =
377  * 1.4\ kg^{1/2}\ gmol^{-1/2}\f$ is used in combination with either \f$
378  * \alpha^{(2)}_{ca} = 12\ kg^{1/2}\ gmol^{-1/2}\f$ or \f$ \alpha^{(2)}_{ca} = k
379  * A_\psi \f$, where *k* is a constant. For electrolytes other than 2-2
380  * electrolytes the \f$ \beta^{(2)}_{ca} g(\alpha^{(2)}_{ca} \sqrt{I}) \f$ term
381  * is not used in the fitting procedure; it is only used for divalent metal
382  * solfates and other high-valence electrolytes which exhibit significant
383  * association at low ionic strengths.
384  *
385  * The \f$ \beta^{(0)}_{ca} \f$, \f$ \beta^{(1)}_{ca}\f$, \f$ \beta^{(2)}_{ca}
386  * \f$, and \f$ C_{ca} \f$ binary coefficients are referred to as ion-
387  * interaction or Pitzer parameters. These Pitzer parameters may vary with
388  * temperature and pressure but they do not depend on the ionic strength. Their
389  * values and temperature derivatives of their values have been tabulated for a
390  * range of electrolytes
391  *
392  * The \f$ \Phi_{c{c'}} \f$ and \f$ \Phi_{a{a'}} \f$ contributions, which
393  * capture cation-cation and anion-anion interactions, also have an ionic
394  * strength dependence.
395  *
396  * Ternary contributions \f$ \Psi_{c{c'}a} \f$ and \f$ \Psi_{a{a'}c} \f$ have
397  * been measured also for some systems. The success of the Pitzer method lies in
398  * its ability to model nonlinear activity coefficients of complex
399  * multicomponent systems with just binary and minor ternary contributions,
400  * which can be independently measured in binary or ternary subsystems.
401  *
402  * ### Multicomponent Activity Coefficients for Solutes
403  *
404  * The formulas for activity coefficients of solutes may be obtained by taking
405  * the following derivative of the excess Gibbs Free Energy formulation
406  * described above:
407  *
408  * \f[
409  * \ln(\gamma_k^\triangle) = \frac{d\left( \frac{G^{ex}}{M_o n_o RT} \right)}{d(m_k)}\Bigg|_{n_i}
410  * \f]
411  *
412  * In the formulas below the following conventions are used. The subscript *M*
413  * refers to a particular cation. The subscript X refers to a particular anion,
414  * whose activity is being currently evaluated. the subscript *a* refers to a
415  * summation over all anions in the solution, while the subscript *c* refers to
416  * a summation over all cations in the solutions.
417  *
418  * The activity coefficient for a particular cation *M* is given by
419  *
420  * \f[
421  * \ln(\gamma_M^\triangle) = -z_M^2(F) + \sum_a m_a \left( 2 B_{Ma} + Z C_{Ma} \right)
422  * + z_M \left( \sum_a \sum_c m_a m_c C_{ca} \right)
423  * + \sum_c m_c \left[ 2 \Phi_{Mc} + \sum_a m_a \Psi_{Mca} \right]
424  * + \sum_{a < a'} \sum m_a m_{a'} \Psi_{Ma{a'}}
425  * + 2 \sum_n m_n \lambda_{nM}
426  * \f]
427  *
428  * The activity coefficient for a particular anion *X* is given by
429  *
430  * \f[
431  * \ln(\gamma_X^\triangle) = -z_X^2(F) + \sum_a m_c \left( 2 B_{cX} + Z C_{cX} \right)
432  * + \left|z_X \right| \left( \sum_a \sum_c m_a m_c C_{ca} \right)
433  * + \sum_a m_a \left[ 2 \Phi_{Xa} + \sum_c m_c \Psi_{cXa} \right]
434  * + \sum_{c < c'} \sum m_c m_{c'} \Psi_{c{c'}X}
435  * + 2 \sum_n m_n \lambda_{nM}
436  * \f]
437  * where the function \f$ F \f$ is given by
438  *
439  * \f[
440  * F = - A_{\phi} \left[ \frac{\sqrt{I}}{1 + b \sqrt{I}}
441  * + \frac{2}{b} \ln{\left(1 + b\sqrt{I}\right)} \right]
442  * + \sum_a \sum_c m_a m_c B'_{ca}
443  * + \sum_{c < c'} \sum m_c m_{c'} \Phi'_{c{c'}}
444  * + \sum_{a < a'} \sum m_a m_{a'} \Phi'_{a{a'}}
445  * \f]
446  *
447  * We have employed the definition of \f$ A_{\phi} \f$, also used by Pitzer
448  * which is equal to
449  *
450  * \f[
451  * A_{\phi} = \frac{A_{Debye}}{3}
452  * \f]
453  *
454  * In the above formulas, \f$ \Phi'_{c{c'}} \f$ and \f$ \Phi'_{a{a'}} \f$ are the
455  * ionic strength derivatives of \f$ \Phi_{c{c'}} \f$ and \f$ \Phi_{a{a'}} \f$,
456  * respectively.
457  *
458  * The function \f$ B'_{MX} \f$ is defined as:
459  *
460  * \f[
461  * B'_{MX} = \left( \frac{\beta^{(1)}_{MX} h(\alpha^{(1)}_{MX} \sqrt{I})}{I} \right)
462  * \left( \frac{\beta^{(2)}_{MX} h(\alpha^{(2)}_{MX} \sqrt{I})}{I} \right)
463  * \f]
464  *
465  * where \f$ h(x) \f$ is defined as
466  *
467  * \f[
468  * h(x) = g'(x) \frac{x}{2} =
469  * \frac{2\left(1 - \left(1 + x + \frac{x^2}{2} \right)\exp(-x) \right)}{x^2}
470  * \f]
471  *
472  * The activity coefficient for neutral species *N* is given by
473  *
474  * \f[
475  * \ln(\gamma_N^\triangle) = 2 \left( \sum_i m_i \lambda_{iN}\right)
476  * \f]
477  *
478  * ### Activity of the Water Solvent
479  *
480  * The activity for the solvent water,\f$ a_o \f$, is not independent and must
481  * be determined either from the Gibbs-Duhem relation or from taking the
482  * appropriate derivative of the same excess Gibbs free energy function as was
483  * used to formulate the solvent activity coefficients. Pitzer's description
484  * follows the later approach to derive a formula for the osmotic coefficient,
485  * \f$ \phi \f$.
486  *
487  * \f[
488  * \phi - 1 = - \left( \frac{d\left(\frac{G^{ex}}{RT} \right)}{d(\tilde{M}_o n_o)} \right)
489  * \frac{1}{\sum_{i \ne 0} m_i}
490  * \f]
491  *
492  * The osmotic coefficient may be related to the water activity by the following relation:
493  *
494  * \f[
495  * \phi = - \frac{1}{\tilde{M}_o \sum_{i \neq o} m_i} \ln(a_o)
496  * = - \frac{n_o}{\sum_{i \neq o}n_i} \ln(a_o)
497  * \f]
498  *
499  * The result is the following
500  *
501  * \f[
502  * \begin{array}{ccclc}
503  * \phi - 1 &= &
504  * \frac{2}{\sum_{i \ne 0} m_i}
505  * \bigg[ &
506  * - A_{\phi} \frac{I^{3/2}}{1 + b \sqrt{I}}
507  * + \sum_c \sum_a m_c m_a \left( B^{\phi}_{ca} + Z C_{ca}\right)
508  * \\&&&
509  * + \sum_{c < c'} \sum m_c m_{c'} \left[ \Phi^{\phi}_{c{c'}} + \sum_a m_a \Psi_{c{c'}a} \right]
510  * + \sum_{a < a'} \sum m_a m_{a'} \left[ \Phi^{\phi}_{a{a'}} + \sum_c m_c \Psi_{a{a'}c} \right]
511  * \\&&&
512  * + \sum_n \sum_c m_n m_c \lambda_{nc} + \sum_n \sum_a m_n m_a \lambda_{na}
513  * + \sum_{n < n'} \sum m_n m_{n'} \lambda_{n{n'}}
514  * + \frac{1}{2} \left( \sum_n m^2_n \lambda_{nn}\right)
515  * \bigg]
516  * \end{array}
517  * \f]
518  *
519  * It can be shown that the expression
520  *
521  * \f[
522  * B^{\phi}_{ca} = \beta^{(0)}_{ca} + \beta^{(1)}_{ca} \exp{(- \alpha^{(1)}_{ca} \sqrt{I})}
523  * + \beta^{(2)}_{ca} \exp{(- \alpha^{(2)}_{ca} \sqrt{I} )}
524  * \f]
525  *
526  * is consistent with the expression \f$ B_{ca} \f$ in the \f$ G^{ex} \f$
527  * expression after carrying out the derivative wrt \f$ m_M \f$.
528  *
529  * Also taking into account that \f$ {\Phi}_{c{c'}} \f$ and
530  * \f$ {\Phi}_{a{a'}} \f$ has an ionic strength dependence.
531  *
532  * \f[
533  * \Phi^{\phi}_{c{c'}} = {\Phi}_{c{c'}} + I \frac{d{\Phi}_{c{c'}}}{dI}
534  * \f]
535  *
536  * \f[
537  * \Phi^{\phi}_{a{a'}} = \Phi_{a{a'}} + I \frac{d\Phi_{a{a'}}}{dI}
538  * \f]
539  *
540  * ### Temperature and Pressure Dependence of the Pitzer Parameters
541  *
542  * In general most of the coefficients introduced in the previous section may
543  * have a temperature and pressure dependence. The temperature and pressure
544  * dependence of these coefficients strongly influence the value of the excess
545  * Enthalpy and excess Volumes of Pitzer solutions. Therefore, these are readily
546  * measurable quantities. HMWSoln provides several different methods for putting
547  * these dependencies into the coefficients. HMWSoln has an implementation
548  * described by Silverter and Pitzer (1977), which was used to fit experimental
549  * data for NaCl over an extensive range, below the critical temperature of
550  * water. They found a temperature functional form for fitting the 3 following
551  * coefficients that describe the Pitzer parameterization for a single salt to
552  * be adequate to describe how the excess Gibbs free energy values for the
553  * binary salt changes with respect to temperature. The following functional
554  * form was used to fit the temperature dependence of the Pitzer Coefficients
555  * for each cation - anion pair, M X.
556  *
557  * \f[
558  * \beta^{(0)}_{MX} = q^{b0}_0
559  * + q^{b0}_1 \left( T - T_r \right)
560  * + q^{b0}_2 \left( T^2 - T_r^2 \right)
561  * + q^{b0}_3 \left( \frac{1}{T} - \frac{1}{T_r}\right)
562  * + q^{b0}_4 \ln \left( \frac{T}{T_r} \right)
563  * \f]
564  * \f[
565  * \beta^{(1)}_{MX} = q^{b1}_0 + q^{b1}_1 \left( T - T_r \right)
566  * + q^{b1}_{2} \left( T^2 - T_r^2 \right)
567  * \f]
568  * \f[
569  * C^{\phi}_{MX} = q^{Cphi}_0
570  * + q^{Cphi}_1 \left( T - T_r \right)
571  * + q^{Cphi}_2 \left( T^2 - T_r^2 \right)
572  * + q^{Cphi}_3 \left( \frac{1}{T} - \frac{1}{T_r}\right)
573  * + q^{Cphi}_4 \ln \left( \frac{T}{T_r} \right)
574  * \f]
575  *
576  * where
577  *
578  * \f[
579  * C^{\phi}_{MX} = 2 {\left| z_M z_X \right|}^{1/2} C_{MX}
580  * \f]
581  *
582  * In later papers, Pitzer has added additional temperature dependencies to all
583  * of the other remaining second and third order virial coefficients. Some of
584  * these dependencies are justified and motivated by theory. Therefore, a
585  * formalism wherein all of the coefficients in the base theory have temperature
586  * dependencies associated with them has been implemented within the HMWSoln
587  * object. Much of the formalism, however, has been unexercised.
588  *
589  * In the HMWSoln object, the temperature dependence of the Pitzer parameters
590  * are specified in the following way.
591  *
592  * - PIZTER_TEMP_CONSTANT - string name "CONSTANT"
593  * - Assumes that all coefficients are independent of temperature
594  * and pressure
595  * - PIZTER_TEMP_COMPLEX1 - string name "COMPLEX" or "COMPLEX1"
596  * - Uses the full temperature dependence for the
597  * \f$\beta^{(0)}_{MX} \f$ (5 coeffs),
598  * the \f$\beta^{(1)}_{MX} \f$ (3 coeffs),
599  * and \f$ C^{\phi}_{MX} \f$ (5 coeffs) parameters described above.
600  * - PITZER_TEMP_LINEAR - string name "LINEAR"
601  * - Uses just the temperature dependence for the
602  * \f$\beta^{(0)}_{MX} \f$, the \f$\beta^{(1)}_{MX} \f$,
603  * and \f$ C^{\phi}_{MX} \f$ coefficients described above.
604  * There are 2 coefficients for each term.
605  *
606  * The temperature dependence is specified in an attributes field in the
607  * `activityCoefficients` XML block, called `TempModel`. Permissible values for
608  * that attribute are `CONSTANT`, `COMPLEX1`, and `LINEAR`.
609  *
610  * The specification of the binary interaction between a cation and an anion is
611  * given by the coefficients, \f$ B_{MX}\f$ and \f$ C_{MX}\f$ The specification
612  * of \f$ B_{MX}\f$ is a function of \f$\beta^{(0)}_{MX} \f$,
613  * \f$\beta^{(1)}_{MX} \f$, \f$\beta^{(2)}_{MX} \f$, \f$\alpha^{(1)}_{MX} \f$,
614  * and \f$\alpha^{(2)}_{MX} \f$. \f$ C_{MX}\f$ is calculated from
615  * \f$C^{\phi}_{MX} \f$ from the formula above. All of the underlying
616  * coefficients are specified in the XML element block `binarySaltParameters`,
617  * which has the attribute `cation` and `anion` to identify the interaction. XML
618  * elements named `beta0, beta1, beta2, Cphi, Alpha1, Alpha2` within each
619  * `binarySaltParameters` block specify the parameters. Within each of these
620  * blocks multiple parameters describing temperature or pressure dependence are
621  * serially listed in the order that they appear in the equation in this
622  * document. An example of the `beta0` block that fits the `COMPLEX1`
623  * temperature dependence given above is
624  *
625  * @code
626  * <binarySaltParameters cation="Na+" anion="OH-">
627  * <beta0> q0, q1, q2, q3, q4 </beta0>
628  * </binarySaltParameters>
629  * @endcode
630  *
631  * The parameters for \f$ \beta^{(0)}\f$ fit the following equation:
632  *
633  * \f[
634  * \beta^{(0)} = q_0^{{\beta}0} + q_1^{{\beta}0} \left( T - T_r \right)
635  * + q_2^{{\beta}0} \left( T^2 - T_r^2 \right)
636  * + q_3^{{\beta}0} \left( \frac{1}{T} - \frac{1}{T_r} \right)
637  * + q_4^{{\beta}0} \ln \left( \frac{T}{T_r} \right)
638  * \f]
639  *
640  * This same `COMPLEX1` temperature dependence given above is used for the
641  * following parameters:
642  * \f$ \beta^{(0)}_{MX} \f$, \f$ \beta^{(1)}_{MX} \f$,
643  * \f$ \beta^{(2)}_{MX} \f$, \f$ \Theta_{cc'} \f$, \f$\Theta_{aa'} \f$,
644  * \f$ \Psi_{c{c'}a} \f$ and \f$ \Psi_{ca{a'}} \f$.
645  *
646  * ### Like-Charged Binary Ion Parameters and the Mixing Parameters
647  *
648  * The previous section contained the functions, \f$ \Phi_{c{c'}} \f$,
649  * \f$ \Phi_{a{a'}} \f$ and their derivatives wrt the ionic strength, \f$
650  * \Phi'_{c{c'}} \f$ and \f$ \Phi'_{a{a'}} \f$. Part of these terms come from
651  * theory.
652  *
653  * Since like charged ions repel each other and are generally not near each
654  * other, the virial coefficients for same-charged ions are small. However,
655  * Pitzer doesn't ignore these in his formulation. Relatively larger and longer
656  * range terms between like-charged ions exist however, which appear only for
657  * unsymmetrical mixing of same-sign charged ions with different charges. \f$
658  * \Phi_{ij} \f$, where \f$ ij \f$ is either \f$ a{a'} \f$ or \f$ c{c'} \f$ is
659  * given by
660  *
661  * \f[
662  * {\Phi}_{ij} = \Theta_{ij} + \,^E \Theta_{ij}(I)
663  * \f]
664  *
665  * \f$ \Theta_{ij} \f$ is the small virial coefficient expansion term. Dependent
666  * in general on temperature and pressure, its ionic strength dependence is
667  * ignored in Pitzer's approach. \f$ \,^E\Theta_{ij}(I) \f$ accounts for the
668  * electrostatic unsymmetrical mixing effects and is dependent only on the
669  * charges of the ions i, j, the total ionic strength and on the dielectric
670  * constant and density of the solvent. This seems to be a relatively well-
671  * documented part of the theory. They theory below comes from Pitzer summation
672  * (Pitzer) in the appendix. It's also mentioned in Bethke's book (Bethke), and
673  * the equations are summarized in Harvie & Weare (1980). Within the code, \f$
674  * \,^E\Theta_{ij}(I) \f$ is evaluated according to the algorithm described in
675  * Appendix B [Pitzer] as
676  *
677  * \f[
678  * \,^E\Theta_{ij}(I) = \left( \frac{z_i z_j}{4I} \right)
679  * \left( J(x_{ij}) - \frac{1}{2} J(x_{ii})
680  * - \frac{1}{2} J(x_{jj}) \right)
681  * \f]
682  *
683  * where \f$ x_{ij} = 6 z_i z_j A_{\phi} \sqrt{I} \f$ and
684  *
685  * \f[
686  * J(x) = \frac{1}{x} \int_0^{\infty}{\left( 1 + q +
687  * \frac{1}{2} q^2 - e^q \right) y^2 dy}
688  * \f]
689  *
690  * and \f$ q = - (\frac{x}{y}) e^{-y} \f$. \f$ J(x) \f$ is evaluated by
691  * numerical integration.
692  *
693  * The \f$ \Theta_{ij} \f$ term is a constant that is specified by the XML
694  * element `thetaCation` and `thetaAnion`, which has the attribute `cation1`,
695  * `cation2` and `anion1`, `anion2` respectively to identify the interaction. No
696  * temperature or pressure dependence of this parameter is currently allowed. An
697  * example of the block is presented below.
698  *
699  * @code
700  * <thetaCation cation1="Na+" cation2="H+">
701  * <Theta> 0.036 </Theta>
702  * </thetaCation>
703  * @endcode
704  *
705  * ### Ternary Pitzer Parameters
706  *
707  * The \f$ \Psi_{c{c'}a} \f$ and \f$ \Psi_{ca{a'}} \f$ terms represent ternary
708  * interactions between two cations and an anion and two anions and a cation,
709  * respectively. In Pitzer's implementation these terms are usually small in
710  * absolute size. Currently these parameters do not have any dependence on
711  * temperature, pressure, or ionic strength.
712  *
713  * Their values are input using the XML element `psiCommonCation` and
714  * `psiCommonAnion`. The species id's are specified in attribute fields in the
715  * XML element. The fields `cation`, `anion1`, and `anion2` are used for
716  * `psiCommonCation`. The fields `anion`, `cation1` and `cation2` are used for
717  * `psiCommonAnion`. An example block is given below. The `Theta` field below is
718  * a duplicate of the `thetaAnion` field mentioned above. The two fields are
719  * input into the same block for convenience, and because their data are highly
720  * correlated, in practice. It is an error for the two blocks to specify
721  * different information about thetaAnion (or thetaCation) in different blocks.
722  * It's ok to specify duplicate but consistent information in multiple blocks.
723  *
724  * @code
725  * <psiCommonCation cation="Na+" anion1="Cl-" anion2="OH-">
726  * <Theta> -0.05 </Theta>
727  * <Psi> -0.006 </Psi>
728  * </psiCommonCation>
729  * @endcode
730  *
731  * ### Treatment of Neutral Species
732  *
733  * Binary virial-coefficient-like interactions between two neutral species may
734  * be specified in the \f$ \lambda_{mn} \f$ terms that appear in the formulas
735  * above. Currently these interactions are independent of temperature, pressure,
736  * and ionic strength. Also, currently, the neutrality of the species are not
737  * checked. Therefore, this interaction may involve charged species in the
738  * solution as well. The identity of the species is specified by the `species1`
739  * and `species2` attributes to the XML `lambdaNeutral` node. These terms are
740  * symmetrical; `species1` and `species2` may be reversed and the term will be
741  * the same. An example is given below.
742  *
743  * @code
744  * <lambdaNeutral species1="CO2" species2="CH4">
745  * <lambda> 0.05 </lambda>
746  * </lambdaNeutral>
747  * @endcode
748  *
749  * ## Example of the Specification of Parameters for the Activity Coefficients
750  *
751  * An example is given below.
752  *
753  * An example `activityCoefficients` XML block for this formulation is supplied
754  * below
755  *
756  * @code
757  * <activityCoefficients model="Pitzer" TempModel="complex1">
758  * <!-- Pitzer Coefficients
759  * These coefficients are from Pitzer's main
760  * paper, in his book.
761  * -->
762  * <A_Debye model="water" />
763  * <ionicRadius default="3.042843" units="Angstroms">
764  * </ionicRadius>
765  * <binarySaltParameters cation="Na+" anion="Cl-">
766  * <beta0> 0.0765, 0.008946, -3.3158E-6,
767  * -777.03, -4.4706
768  * </beta0>
769  * <beta1> 0.2664, 6.1608E-5, 1.0715E-6, 0.0, 0.0 </beta1>
770  * <beta2> 0.0, 0.0, 0.0, 0.0, 0.0 </beta2>
771  * <Cphi> 0.00127, -4.655E-5, 0.0,
772  * 33.317, 0.09421
773  * </Cphi>
774  * <Alpha1> 2.0 </Alpha1>
775  * </binarySaltParameters>
776  *
777  * <binarySaltParameters cation="H+" anion="Cl-">
778  * <beta0> 0.1775, 0.0, 0.0, 0.0, 0.0 </beta0>
779  * <beta1> 0.2945, 0.0, 0.0, 0.0, 0.0 </beta1>
780  * <beta2> 0.0, 0.0, 0.0, 0.0, 0.0 </beta2>
781  * <Cphi> 0.0008, 0.0, 0.0, 0.0, 0.0 </Cphi>
782  * <Alpha1> 2.0 </Alpha1>
783  * </binarySaltParameters>
784  *
785  * <binarySaltParameters cation="Na+" anion="OH-">
786  * <beta0> 0.0864, 0.0, 0.0, 0.0, 0.0 </beta0>
787  * <beta1> 0.253, 0.0, 0.0 0.0, 0.0 </beta1>
788  * <beta2> 0.0 0.0, 0.0, 0.0, 0.0 </beta2>
789  * <Cphi> 0.0044, 0.0, 0.0, 0.0, 0.0 </Cphi>
790  * <Alpha1> 2.0 </Alpha1>
791  * </binarySaltParameters>
792  *
793  * <thetaAnion anion1="Cl-" anion2="OH-">
794  * <Theta> -0.05, 0.0, 0.0, 0.0, 0.0 </Theta>
795  * </thetaAnion>
796  *
797  * <psiCommonCation cation="Na+" anion1="Cl-" anion2="OH-">
798  * <Theta> -0.05, 0.0, 0.0, 0.0, 0.0 </Theta>
799  * <Psi> -0.006 </Psi>
800  * </psiCommonCation>
801  *
802  * <thetaCation cation1="Na+" cation2="H+">
803  * <Theta> 0.036, 0.0, 0.0, 0.0, 0.0 </Theta>
804  * </thetaCation>
805  *
806  * <psiCommonAnion anion="Cl-" cation1="Na+" cation2="H+">
807  * <Theta> 0.036, 0.0, 0.0, 0.0, 0.0 </Theta>
808  * <Psi> -0.004 </Psi>
809  * </psiCommonAnion>
810  * </activityCoefficients>
811  * @endcode
812  *
813  * ### Specification of the Debye-Huckel Constant
814  *
815  * In the equations above, the formula for \f$ A_{Debye} \f$ is needed. The
816  * HMWSoln object uses two methods for specifying these quantities. The default
817  * method is to assume that \f$ A_{Debye} \f$ is a constant, given in the
818  * initialization process, and stored in the member double, m_A_Debye.
819  * Optionally, a full water treatment may be employed that makes
820  * \f$ A_{Debye} \f$ a full function of *T* and *P* and creates nontrivial
821  * entries for the excess heat capacity, enthalpy, and excess volumes of
822  * solution.
823  *
824  * \f[
825  * A_{Debye} = \frac{F e B_{Debye}}{8 \pi \epsilon R T} {\left( C_o \tilde{M}_o \right)}^{1/2}
826  * \f]
827  * where
828  *
829  * \f[
830  * B_{Debye} = \frac{F} {{(\frac{\epsilon R T}{2})}^{1/2}}
831  * \f]
832  * Therefore:
833  * \f[
834  * A_{Debye} = \frac{1}{8 \pi}
835  * {\left(\frac{2 N_a \rho_o}{1000}\right)}^{1/2}
836  * {\left(\frac{N_a e^2}{\epsilon R T }\right)}^{3/2}
837  * \f]
838  *
839  * Units = sqrt(kg/gmol)
840  *
841  * where
842  * - \f$ N_a \f$ is Avogadro's number
843  * - \f$ \rho_w \f$ is the density of water
844  * - \f$ e \f$ is the electronic charge
845  * - \f$ \epsilon = K \epsilon_o \f$ is the permittivity of water
846  * - \f$ K \f$ is the dielectric constant of water,
847  * - \f$ \epsilon_o \f$ is the permittivity of free space.
848  * - \f$ \rho_o \f$ is the density of the solvent in its standard state.
849  *
850  * Nominal value at 298 K and 1 atm = 1.172576 (kg/gmol)^(1/2)
851  * based on:
852  * - \f$ \epsilon / \epsilon_0 \f$ = 78.54 (water at 25C)
853  * - T = 298.15 K
854  * - B_Debye = 3.28640E9 (kg/gmol)^(1/2) / m
855  *
856  * An example of a fixed value implementation is given below.
857  * @code
858  * <activityCoefficients model="Pitzer">
859  * <!-- A_Debye units = sqrt(kg/gmol) -->
860  * <A_Debye> 1.172576 </A_Debye>
861  * <!-- object description continues -->
862  * </activityCoefficients>
863  * @endcode
864  *
865  * An example of a variable value implementation within the HMWSoln object is
866  * given below. The model attribute, "water", triggers the full implementation.
867  *
868  * @code
869  * <activityCoefficients model="Pitzer">
870  * <!-- A_Debye units = sqrt(kg/gmol) -->
871  * <A_Debye model="water" />
872  * <!-- object description continues -->
873  * </activityCoefficients>
874  * @endcode
875  *
876  * ### Temperature and Pressure Dependence of the Activity Coefficients
877  *
878  * Temperature dependence of the activity coefficients leads to nonzero terms
879  * for the excess enthalpy and entropy of solution. This means that the partial
880  * molar enthalpies, entropies, and heat capacities are all non-trivial to
881  * compute. The following formulas are used.
882  *
883  * The partial molar enthalpy, \f$ \bar s_k(T,P) \f$:
884  *
885  * \f[
886  * \bar h_k(T,P) = h^{\triangle}_k(T,P)
887  * - R T^2 \frac{d \ln(\gamma_k^\triangle)}{dT}
888  * \f]
889  * The solvent partial molar enthalpy is equal to
890  * \f[
891  * \bar h_o(T,P) = h^{o}_o(T,P) - R T^2 \frac{d \ln(a_o)}{dT}
892  * = h^{o}_o(T,P)
893  * + R T^2 (\sum_{k \neq o} m_k) \tilde{M_o} (\frac{d \phi}{dT})
894  * \f]
895  *
896  * The partial molar entropy, \f$ \bar s_k(T,P) \f$:
897  *
898  * \f[
899  * \bar s_k(T,P) = s^{\triangle}_k(T,P)
900  * - R \ln( \gamma^{\triangle}_k \frac{m_k}{m^{\triangle}}))
901  * - R T \frac{d \ln(\gamma^{\triangle}_k) }{dT}
902  * \f]
903  * \f[
904  * \bar s_o(T,P) = s^o_o(T,P) - R \ln(a_o)
905  * - R T \frac{d \ln(a_o)}{dT}
906  * \f]
907  *
908  * The partial molar heat capacity, \f$ C_{p,k}(T,P)\f$:
909  *
910  * \f[
911  * \bar C_{p,k}(T,P) = C^{\triangle}_{p,k}(T,P)
912  * - 2 R T \frac{d \ln( \gamma^{\triangle}_k)}{dT}
913  * - R T^2 \frac{d^2 \ln(\gamma^{\triangle}_k) }{{dT}^2}
914  * \f]
915  * \f[
916  * \bar C_{p,o}(T,P) = C^o_{p,o}(T,P)
917  * - 2 R T \frac{d \ln(a_o)}{dT}
918  * - R T^2 \frac{d^2 \ln(a_o)}{{dT}^2}
919  * \f]
920  *
921  * The pressure dependence of the activity coefficients leads to non-zero terms
922  * for the excess Volume of the solution. Therefore, the partial molar volumes
923  * are functions of the pressure derivatives of the activity coefficients.
924  * \f[
925  * \bar V_k(T,P) = V^{\triangle}_k(T,P)
926  * + R T \frac{d \ln(\gamma^{\triangle}_k) }{dP}
927  * \f]
928  * \f[
929  * \bar V_o(T,P) = V^o_o(T,P)
930  * + R T \frac{d \ln(a_o)}{dP}
931  * \f]
932  *
933  * The majority of work for these functions take place in the internal routines
934  * that calculate the first and second derivatives of the log of the activity
935  * coefficients wrt temperature, s_update_dlnMolalityActCoeff_dT(),
936  * s_update_d2lnMolalityActCoeff_dT2(), and the first derivative of the log
937  * activity coefficients wrt pressure, s_update_dlnMolalityActCoeff_dP().
938  *
939  * ## %Application within Kinetics Managers
940  *
941  * For the time being, we have set the standard concentration for all solute
942  * species in this phase equal to the default concentration of the solvent at
943  * the system temperature and pressure multiplied by Mnaught (kg solvent / gmol
944  * solvent). The solvent standard concentration is just equal to its standard
945  * state concentration.
946  *
947  * This means that the kinetics operator essentially works on an generalized
948  * concentration basis (kmol / m3), with units for the kinetic rate constant
949  * specified as if all reactants (solvent or solute) are on a concentration
950  * basis (kmol /m3). The concentration will be modified by the activity
951  * coefficients.
952  *
953  * For example, a bulk-phase binary reaction between liquid solute species *j*
954  * and *k*, producing a new liquid solute species *l* would have the following
955  * equation for its rate of progress variable, \f$ R^1 \f$, which has units of
956  * kmol m-3 s-1.
957  *
958  * \f[
959  * R^1 = k^1 C_j^a C_k^a = k^1 (C^o_o \tilde{M}_o a_j) (C^o_o \tilde{M}_o a_k)
960  * \f]
961  *
962  * where
963  *
964  * \f[
965  * C_j^a = C^o_o \tilde{M}_o a_j \quad and \quad C_k^a = C^o_o \tilde{M}_o a_k
966  * \f]
967  *
968  * \f$ C_j^a \f$ is the activity concentration of species *j*, and
969  * \f$ C_k^a \f$ is the activity concentration of species *k*. \f$ C^o_o \f$ is
970  * the concentration of water at 298 K and 1 atm. \f$ \tilde{M}_o \f$ has units
971  * of kg solvent per gmol solvent and is equal to
972  *
973  * \f[
974  * \tilde{M}_o = \frac{M_o}{1000}
975  * \f]
976  *
977  * \f$ a_j \f$ is the activity of species *j* at the current temperature and
978  * pressure and concentration of the liquid phase is given by the molality based
979  * activity coefficient multiplied by the molality of the jth species.
980  *
981  * \f[
982  * a_j = \gamma_j^\triangle m_j = \gamma_j^\triangle \frac{n_j}{\tilde{M}_o n_o}
983  * \f]
984  *
985  * \f$k^1 \f$ has units of m^3/kmol/s.
986  *
987  * Therefore the generalized activity concentration of a solute species has the following form
988  *
989  * \f[
990  * C_j^a = C^o_o \frac{\gamma_j^\triangle n_j}{n_o}
991  * \f]
992  *
993  * The generalized activity concentration of the solvent has the same units, but it's a simpler form
994  *
995  * \f[
996  * C_o^a = C^o_o a_o
997  * \f]
998  *
999  * The reverse rate constant can then be obtained from the law of microscopic reversibility
1000  * and the equilibrium expression for the system.
1001  *
1002  * \f[
1003  * \frac{a_j a_k}{ a_l} = K^{o,1} = \exp(\frac{\mu^o_l - \mu^o_j - \mu^o_k}{R T} )
1004  * \f]
1005  *
1006  * \f$ K^{o,1} \f$ is the dimensionless form of the equilibrium constant.
1007  *
1008  * \f[
1009  * R^{-1} = k^{-1} C_l^a = k^{-1} (C_o \tilde{M}_o a_l)
1010  * \f]
1011  *
1012  * where
1013  *
1014  * \f[
1015  * k^{-1} = k^1 K^{o,1} C_o \tilde{M}_o
1016  * \f]
1017  *
1018  * \f$ k^{-1} \f$ has units of 1/s.
1019  *
1020  * Note, this treatment may be modified in the future, as events dictate.
1021  *
1022  * ## Instantiation of the Class
1023  *
1024  * The constructor for this phase is now located in the default ThermoFactory
1025  * for %Cantera. The following code snippet may be used to initialize the phase
1026  * using the default construction technique within %Cantera.
1027  *
1028  * @code
1029  * ThermoPhase *HMW = newPhase("HMW_NaCl.xml", "NaCl_electrolyte");
1030  * @endcode
1031  *
1032  * A new HMWSoln object may be created by the following code snippets:
1033  *
1034  * @code
1035  * HMWSoln *HMW = new HMWSoln("HMW_NaCl.xml", "NaCl_electrolyte");
1036  * @endcode
1037  *
1038  * or
1039  *
1040  * @code
1041  * XML_Node *xm = get_XML_NameID("phase", "HMW_NaCl.xml#NaCl_electrolyte", 0);
1042  * HMWSoln *dh = new HMWSoln(*xm);
1043  * @endcode
1044  *
1045  * or by the following call to importPhase():
1046  *
1047  * @code
1048  * XML_Node *xm = get_XML_NameID("phase", "HMW_NaCl.xml#NaCl_electrolyte", 0);
1049  * HMWSoln dhphase;
1050  * importPhase(*xm, &dhphase);
1051  * @endcode
1052  *
1053  * ## XML Example
1054  *
1055  * The phase model name for this is called StoichSubstance. It must be supplied
1056  * as the model attribute of the thermo XML element entry. Within the phase XML
1057  * block, the density of the phase must be specified. An example of an XML file
1058  * this phase is given below.
1059  *
1060  * @code
1061  * <phase id="NaCl_electrolyte" dim="3">
1062  * <speciesArray datasrc="#species_waterSolution">
1063  * H2O(L) Na+ Cl- H+ OH-
1064  * </speciesArray>
1065  * <state>
1066  * <temperature units="K"> 300 </temperature>
1067  * <pressure units="Pa">101325.0</pressure>
1068  * <soluteMolalities>
1069  * Na+:3.0
1070  * Cl-:3.0
1071  * H+:1.0499E-8
1072  * OH-:1.3765E-6
1073  * </soluteMolalities>
1074  * </state>
1075  * <!-- thermo model identifies the inherited class
1076  * from ThermoPhase that will handle the thermodynamics.
1077  * -->
1078  * <thermo model="HMW">
1079  * <standardConc model="solvent_volume" />
1080  * <activityCoefficients model="Pitzer" TempModel="complex1">
1081  * <!-- Pitzer Coefficients
1082  * These coefficients are from Pitzer's main
1083  * paper, in his book.
1084  * -->
1085  * <A_Debye model="water" />
1086  * <ionicRadius default="3.042843" units="Angstroms">
1087  * </ionicRadius>
1088  * <binarySaltParameters cation="Na+" anion="Cl-">
1089  * <beta0> 0.0765, 0.008946, -3.3158E-6,
1090  * -777.03, -4.4706
1091  * </beta0>
1092  * <beta1> 0.2664, 6.1608E-5, 1.0715E-6 </beta1>
1093  * <beta2> 0.0 </beta2>
1094  * <Cphi> 0.00127, -4.655E-5, 0.0,
1095  * 33.317, 0.09421
1096  * </Cphi>
1097  * <Alpha1> 2.0 </Alpha1>
1098  * </binarySaltParameters>
1099  *
1100  * <binarySaltParameters cation="H+" anion="Cl-">
1101  * <beta0> 0.1775, 0.0, 0.0, 0.0, 0.0</beta0>
1102  * <beta1> 0.2945, 0.0, 0.0 </beta1>
1103  * <beta2> 0.0 </beta2>
1104  * <Cphi> 0.0008, 0.0, 0.0, 0.0, 0.0 </Cphi>
1105  * <Alpha1> 2.0 </Alpha1>
1106  * </binarySaltParameters>
1107  *
1108  * <binarySaltParameters cation="Na+" anion="OH-">
1109  * <beta0> 0.0864, 0.0, 0.0, 0.0, 0.0 </beta0>
1110  * <beta1> 0.253, 0.0, 0.0 </beta1>
1111  * <beta2> 0.0 </beta2>
1112  * <Cphi> 0.0044, 0.0, 0.0, 0.0, 0.0 </Cphi>
1113  * <Alpha1> 2.0 </Alpha1>
1114  * </binarySaltParameters>
1115  *
1116  * <thetaAnion anion1="Cl-" anion2="OH-">
1117  * <Theta> -0.05 </Theta>
1118  * </thetaAnion>
1119  *
1120  * <psiCommonCation cation="Na+" anion1="Cl-" anion2="OH-">
1121  * <Theta> -0.05 </Theta>
1122  * <Psi> -0.006 </Psi>
1123  * </psiCommonCation>
1124  *
1125  * <thetaCation cation1="Na+" cation2="H+">
1126  * <Theta> 0.036 </Theta>
1127  * </thetaCation>
1128  *
1129  * <psiCommonAnion anion="Cl-" cation1="Na+" cation2="H+">
1130  * <Theta> 0.036 </Theta>
1131  * <Psi> -0.004 </Psi>
1132  * </psiCommonAnion>
1133  *
1134  * </activityCoefficients>
1135  *
1136  * <solvent> H2O(L) </solvent>
1137  * </thermo>
1138  * <elementArray datasrc="elements.xml"> O H Na Cl </elementArray>
1139  * <kinetics model="none" >
1140  * </kinetics>
1141  * </phase>
1142  * @endcode
1143  * @ingroup thermoprops
1144  */
1145 class HMWSoln : public MolalityVPSSTP
1146 {
1147 public:
1148  //! Default Constructor
1149  HMWSoln();
1150 
1151  //! Construct and initialize an HMWSoln ThermoPhase object
1152  //! directly from an ASCII input file
1153  /*!
1154  * This constructor is a shell that calls the routine initThermo(), with
1155  * a reference to the XML database to get the info for the phase.
1156  *
1157  * @param inputFile Name of the input file containing the phase XML data
1158  * to set up the object
1159  * @param id ID of the phase in the input file. Defaults to the
1160  * empty string.
1161  */
1162  HMWSoln(const std::string& inputFile, const std::string& id = "");
1163 
1164  //! Construct and initialize an HMWSoln ThermoPhase object
1165  //! directly from an XML database
1166  /*!
1167  * @param phaseRef XML phase node containing the description of the phase
1168  * @param id id attribute containing the name of the phase.
1169  * (default is the empty string)
1170  */
1171  HMWSoln(XML_Node& phaseRef, const std::string& id = "");
1172 
1173  HMWSoln(const HMWSoln& right);
1174  HMWSoln& operator=(const HMWSoln& right);
1175  virtual ~HMWSoln();
1176  virtual ThermoPhase* duplMyselfAsThermoPhase() const;
1177 
1178  //! Import, construct, and initialize a HMWSoln phase
1179  //! specification from an XML tree into the current object.
1180  /*
1181  * This routine is a precursor to constructPhaseXML(XML_Node*)
1182  * routine, which does most of the work.
1183  *
1184  * @param inputfile XML file containing the description of the phase
1185  * @param id Optional parameter identifying the name of the
1186  * phase. If none is given, the first XML
1187  * phase element will be used.
1188  * @deprecated Use initThermoFile() instead. To be removed after Cantera 2.3.
1189  */
1190  void constructPhaseFile(std::string inputFile, std::string id);
1191 
1192  //! Import and initialize a HMWSoln phase specification in an XML tree
1193  //! into the current object.
1194  /*!
1195  * Here we read an XML description of the phase. We import descriptions of
1196  * the elements that make up the species in a phase. We import information
1197  * about the species, including their reference state thermodynamic
1198  * polynomials. We then freeze the state of the species.
1199  *
1200  * Then, we read the species molar volumes from the XML tree to finish the
1201  * initialization.
1202  *
1203  * @param phaseNode This object must be the phase node of a complete XML
1204  * tree description of the phase, including all of the species
1205  * data. In other words while "phase" must point to an XML phase
1206  * object, it must have sibling nodes "speciesData" that
1207  * describe the species in the phase.
1208  * @param id ID of the phase. If nonnull, a check is done to see if
1209  * phaseNode is pointing to the phase with the correct id.
1210  * @deprecated Use importPhase() instead. To be removed after Cantera 2.3.
1211  */
1212  void constructPhaseXML(XML_Node& phaseNode, std::string id);
1213 
1214  //! @name Utilities
1215  //! @{
1216 
1217  virtual int eosType() const;
1218  virtual std::string type() const {
1219  return "HMWSoln";
1220  }
1221 
1222  //! @}
1223  //! @name Molar Thermodynamic Properties of the Solution
1224  //! @{
1225 
1226  /// Molar enthalpy. Units: J/kmol.
1227  /**
1228  * Molar enthalpy of the solution. Units: J/kmol.
1229  * (HKM -> Bump up to Parent object)
1230  */
1231  virtual doublereal enthalpy_mole() const;
1232 
1233  /**
1234  * Excess molar enthalpy of the solution from
1235  * the mixing process. Units: J/ kmol.
1236  *
1237  * Note this is kmol of the total solution.
1238  */
1239  virtual doublereal relative_enthalpy() const;
1240 
1241  /**
1242  * Excess molar enthalpy of the solution from
1243  * the mixing process on a molality basis.
1244  * Units: J/ (kmol add salt).
1245  *
1246  * Note this is kmol of the guessed at salt composition
1247  */
1248  virtual doublereal relative_molal_enthalpy() const;
1249 
1250  /// Molar entropy. Units: J/kmol/K.
1251  /**
1252  * Molar entropy of the solution. Units: J/kmol/K. For an ideal, constant
1253  * partial molar volume solution mixture with pure species phases which
1254  * exhibit zero volume expansivity:
1255  * \f[
1256  * \hat s(T, P, X_k) = \sum_k X_k \hat s^0_k(T)
1257  * - \hat R \sum_k X_k log(X_k)
1258  * \f]
1259  * The reference-state pure-species entropies \f$ \hat s^0_k(T,p_{ref}) \f$
1260  * are computed by the species thermodynamic property manager. The pure
1261  * species entropies are independent of temperature since the volume
1262  * expansivities are equal to zero.
1263  * @see MultiSpeciesThermo
1264  *
1265  * (HKM -> Bump up to Parent object)
1266  */
1267  virtual doublereal entropy_mole() const;
1268 
1269  /// Molar Gibbs function. Units: J/kmol.
1270  /*!
1271  * (HKM -> Bump up to Parent object)
1272  */
1273  virtual doublereal gibbs_mole() const;
1274 
1275  virtual doublereal cp_mole() const;
1276 
1277  /// Molar heat capacity at constant volume. Units: J/kmol/K.
1278  /*!
1279  * (HKM -> Bump up to Parent object)
1280  */
1281  virtual doublereal cv_mole() const;
1282 
1283  //!@}
1284  //! @name Mechanical Equation of State Properties
1285  /*!
1286  * In this equation of state implementation, the density is a function
1287  * only of the mole fractions. Therefore, it can't be an independent
1288  * variable. Instead, the pressure is used as the independent variable.
1289  * Functions which try to set the thermodynamic state by calling
1290  * setDensity() may cause an exception to be thrown.
1291  */
1292  //!@{
1293 
1294 protected:
1295  /**
1296  * Calculate the density of the mixture using the partial
1297  * molar volumes and mole fractions as input
1298  *
1299  * The formula for this is
1300  *
1301  * \f[
1302  * \rho = \frac{\sum_k{X_k W_k}}{\sum_k{X_k V_k}}
1303  * \f]
1304  *
1305  * where \f$X_k\f$ are the mole fractions, \f$W_k\f$ are the molecular
1306  * weights, and \f$V_k\f$ are the pure species molar volumes.
1307  *
1308  * Note, the basis behind this formula is that in an ideal solution the
1309  * partial molar volumes are equal to the pure species molar volumes. We
1310  * have additionally specified in this class that the pure species molar
1311  * volumes are independent of temperature and pressure.
1312  *
1313  * NOTE: This is a non-virtual function, which is not a member of the
1314  * ThermoPhase base class.
1315  */
1316  void calcDensity();
1317 
1318 public:
1319  //! Set the internally stored density (kg/m^3) of the phase.
1320  /*!
1321  * Overridden setDensity() function is necessary because the density is not
1322  * an independent variable.
1323  *
1324  * This function will now throw an error condition.
1325  *
1326  * Note, in general, setting the phase density is now a nonlinear
1327  * calculation. P and T are the fundamental variables. This routine should
1328  * be revamped to do the nonlinear problem.
1329  *
1330  * @todo May have to adjust the strategy here to make the eos for these
1331  * materials slightly compressible, in order to create a condition where
1332  * the density is a function of the pressure.
1333  * @todo Now have a compressible ss equation for liquid water. Therefore,
1334  * this phase is compressible. May still want to change the
1335  * independent variable however.
1336  *
1337  * @param rho Input density (kg/m^3).
1338  */
1339  virtual void setDensity(const doublereal rho);
1340 
1341  //! Set the internally stored molar density (kmol/m^3) for the phase.
1342  /**
1343  * Overridden setMolarDensity() function is necessary because of the
1344  * underlying water model.
1345  *
1346  * This function will now throw an error condition if the input isn't
1347  * exactly equal to the current molar density.
1348  *
1349  * @param conc Input molar density (kmol/m^3).
1350  */
1351  virtual void setMolarDensity(const doublereal conc);
1352 
1353  /**
1354  * @}
1355  * @name Activities, Standard States, and Activity Concentrations
1356  *
1357  * The activity \f$a_k\f$ of a species in solution is related to the
1358  * chemical potential by \f[ \mu_k = \mu_k^0(T) + \hat R T \log a_k. \f] The
1359  * quantity \f$\mu_k^0(T,P)\f$ is the chemical potential at unit activity,
1360  * which depends only on temperature and the pressure. Activity is assumed
1361  * to be molality-based here.
1362  * @{
1363  */
1364 
1365  //! This method returns an array of generalized activity concentrations
1366  /*!
1367  * The generalized activity concentrations, \f$ C_k^a\f$, are defined such
1368  * that \f$ a_k = C^a_k / C^0_k, \f$ where \f$ C^0_k \f$ is a standard
1369  * concentration defined below. These generalized concentrations are used
1370  * by kinetics manager classes to compute the forward and reverse rates of
1371  * elementary reactions.
1372  *
1373  * The generalized activity concentration of a solute species has the
1374  * following form
1375  *
1376  * \f[
1377  * C_j^a = C^o_o \frac{\gamma_j^\triangle n_j}{n_o}
1378  * \f]
1379  *
1380  * The generalized activity concentration of the solvent has the same units,
1381  * but it's a simpler form
1382  *
1383  * \f[
1384  * C_o^a = C^o_o a_o
1385  * \f]
1386  *
1387  * @param c Array of generalized concentrations. The
1388  * units are kmol m-3 for both the solvent and the solute species
1389  */
1390  virtual void getActivityConcentrations(doublereal* c) const;
1391 
1392  //! Return the standard concentration for the kth species
1393  /*!
1394  * The standard concentration \f$ C^0_k \f$ used to normalize the activity
1395  * (i.e., generalized) concentration for use
1396  *
1397  * We have set the standard concentration for all solute species in this
1398  * phase equal to the default concentration of the solvent at the system
1399  * temperature and pressure multiplied by Mnaught (kg solvent / gmol
1400  * solvent). The solvent standard concentration is just equal to its
1401  * standard state concentration.
1402  *
1403  * \f[
1404  * C_j^0 = C^o_o \tilde{M}_o \quad and C_o^0 = C^o_o
1405  * \f]
1406  *
1407  * The consequence of this is that the standard concentrations have unequal
1408  * units between the solvent and the solute. However, both the solvent and
1409  * the solute activity concentrations will have the same units of kmol/kg^3.
1410  *
1411  * This means that the kinetics operator essentially works on an generalized
1412  * concentration basis (kmol / m3), with units for the kinetic rate constant
1413  * specified as if all reactants (solvent or solute) are on a concentration
1414  * basis (kmol /m3). The concentration will be modified by the activity
1415  * coefficients.
1416  *
1417  * For example, a bulk-phase binary reaction between liquid solute species
1418  * *j* and *k*, producing a new liquid solute species *l* would have the
1419  * following equation for its rate of progress variable, \f$ R^1 \f$, which
1420  * has units of kmol m-3 s-1.
1421  *
1422  * \f[
1423  * R^1 = k^1 C_j^a C_k^a = k^1 (C^o_o \tilde{M}_o a_j) (C^o_o \tilde{M}_o a_k)
1424  * \f]
1425  *
1426  * where
1427  *
1428  * \f[
1429  * C_j^a = C^o_o \tilde{M}_o a_j \quad and \quad C_k^a = C^o_o \tilde{M}_o a_k
1430  * \f]
1431  *
1432  * \f$ C_j^a \f$ is the activity concentration of species *j*, and
1433  * \f$ C_k^a \f$ is the activity concentration of species *k*. \f$ C^o_o \f$
1434  * is the concentration of water at 298 K and 1 atm. \f$ \tilde{M}_o \f$ has
1435  * units of kg solvent per gmol solvent and is equal to
1436  *
1437  * \f[
1438  * \tilde{M}_o = \frac{M_o}{1000}
1439  * \f]
1440  *
1441  * \f$ a_j \f$ is
1442  * the activity of species *j* at the current temperature and pressure
1443  * and concentration of the liquid phase is given by the molality based
1444  * activity coefficient multiplied by the molality of the jth species.
1445  *
1446  * \f[
1447  * a_j = \gamma_j^\triangle m_j = \gamma_j^\triangle \frac{n_j}{\tilde{M}_o n_o}
1448  * \f]
1449  *
1450  * \f$k^1 \f$ has units of m^3/kmol/s.
1451  *
1452  * Therefore the generalized activity concentration of a solute species has
1453  * the following form
1454  *
1455  * \f[
1456  * C_j^a = C^o_o \frac{\gamma_j^\triangle n_j}{n_o}
1457  * \f]
1458  *
1459  * The generalized activity concentration of the solvent has the same units,
1460  * but it's a simpler form
1461  *
1462  * \f[
1463  * C_o^a = C^o_o a_o
1464  * \f]
1465  *
1466  * @param k Optional parameter indicating the species. The default is to
1467  * assume this refers to species 0.
1468  * @returns the standard Concentration in units of m^3/kmol.
1469  *
1470  * @param k Species index
1471  */
1472  virtual doublereal standardConcentration(size_t k=0) const;
1473 
1474  //! Get the array of non-dimensional activities at the current solution
1475  //! temperature, pressure, and solution concentration.
1476  /*!
1477  *
1478  * We resolve this function at this level by calling on the
1479  * activityConcentration function. However, derived classes may want to
1480  * override this default implementation.
1481  *
1482  * (note solvent is on molar scale).
1483  *
1484  * @param ac Output vector of activities. Length: m_kk.
1485  */
1486  virtual void getActivities(doublereal* ac) const;
1487 
1488  //! @}
1489  //! @name Partial Molar Properties of the Solution
1490  //! @{
1491 
1492  //! Get the species chemical potentials. Units: J/kmol.
1493  /*!
1494  *
1495  * This function returns a vector of chemical potentials of the
1496  * species in solution.
1497  *
1498  * \f[
1499  * \mu_k = \mu^{\triangle}_k(T,P) + R T ln(\gamma_k^{\triangle} m_k)
1500  * \f]
1501  *
1502  * @param mu Output vector of species chemical
1503  * potentials. Length: m_kk. Units: J/kmol
1504  */
1505  virtual void getChemPotentials(doublereal* mu) const;
1506 
1507  //! Returns an array of partial molar enthalpies for the species
1508  //! in the mixture. Units (J/kmol)
1509  /*!
1510  * For this phase, the partial molar enthalpies are equal to the standard
1511  * state enthalpies modified by the derivative of the molality-based
1512  * activity coefficient wrt temperature
1513  *
1514  * \f[
1515  * \bar h_k(T,P) = h^{\triangle}_k(T,P)
1516  * - R T^2 \frac{d \ln(\gamma_k^\triangle)}{dT}
1517  * \f]
1518  * The solvent partial molar enthalpy is equal to
1519  * \f[
1520  * \bar h_o(T,P) = h^{o}_o(T,P) - R T^2 \frac{d \ln(a_o)}{dT}
1521  * = h^{o}_o(T,P)
1522  * + R T^2 (\sum_{k \neq o} m_k) \tilde{M_o} (\frac{d \phi}{dT})
1523  * \f]
1524  *
1525  * @param hbar Output vector of species partial molar enthalpies.
1526  * Length: m_kk. units are J/kmol.
1527  */
1528  virtual void getPartialMolarEnthalpies(doublereal* hbar) const;
1529 
1530  //! Returns an array of partial molar entropies of the species in the
1531  //! solution. Units: J/kmol/K.
1532  /*!
1533  * Maxwell's equations provide an answer for how calculate this
1534  * (p.215 Smith and Van Ness)
1535  *
1536  * d(chemPot_i)/dT = -sbar_i
1537  *
1538  * For this phase, the partial molar entropies are equal to the SS species
1539  * entropies plus the ideal solution contribution plus complicated functions
1540  * of the temperature derivative of the activity coefficients.
1541  *
1542  * \f[
1543  * \bar s_k(T,P) = s^{\triangle}_k(T,P)
1544  * - R \ln( \gamma^{\triangle}_k \frac{m_k}{m^{\triangle}}))
1545  * - R T \frac{d \ln(\gamma^{\triangle}_k) }{dT}
1546  * \f]
1547  * \f[
1548  * \bar s_o(T,P) = s^o_o(T,P) - R \ln(a_o)
1549  * - R T \frac{d \ln(a_o)}{dT}
1550  * \f]
1551  *
1552  * @param sbar Output vector of species partial molar entropies.
1553  * Length = m_kk. units are J/kmol/K.
1554  */
1555  virtual void getPartialMolarEntropies(doublereal* sbar) const;
1556 
1557  //! Return an array of partial molar volumes for the species in the mixture.
1558  //! Units: m^3/kmol.
1559  /*!
1560  * For this solution, the partial molar volumes are functions of the
1561  * pressure derivatives of the activity coefficients.
1562  *
1563  * \f[
1564  * \bar V_k(T,P) = V^{\triangle}_k(T,P)
1565  * + R T \frac{d \ln(\gamma^{\triangle}_k) }{dP}
1566  * \f]
1567  * \f[
1568  * \bar V_o(T,P) = V^o_o(T,P)
1569  * + R T \frac{d \ln(a_o)}{dP}
1570  * \f]
1571  *
1572  * @param vbar Output vector of species partial molar volumes.
1573  * Length = m_kk. units are m^3/kmol.
1574  */
1575  virtual void getPartialMolarVolumes(doublereal* vbar) const;
1576 
1577  //! Return an array of partial molar heat capacities for the species in the
1578  //! mixture. Units: J/kmol/K
1579  /*!
1580  * The following formulas are implemented within the code.
1581  *
1582  * \f[
1583  * \bar C_{p,k}(T,P) = C^{\triangle}_{p,k}(T,P)
1584  * - 2 R T \frac{d \ln( \gamma^{\triangle}_k)}{dT}
1585  * - R T^2 \frac{d^2 \ln(\gamma^{\triangle}_k) }{{dT}^2}
1586  * \f]
1587  * \f[
1588  * \bar C_{p,o}(T,P) = C^o_{p,o}(T,P)
1589  * - 2 R T \frac{d \ln(a_o)}{dT}
1590  * - R T^2 \frac{d^2 \ln(a_o)}{{dT}^2}
1591  * \f]
1592  *
1593  * @param cpbar Output vector of species partial molar heat capacities at
1594  * constant pressure. Length = m_kk. units are J/kmol/K.
1595  */
1596  virtual void getPartialMolarCp(doublereal* cpbar) const;
1597 
1598 public:
1599  //@}
1600 
1601  //! Get the saturation pressure for a given temperature.
1602  /*!
1603  * Note the limitations of this function. Stability considerations
1604  * concerning multiphase equilibrium are ignored in this calculation.
1605  * Therefore, the call is made directly to the SS of water underneath. The
1606  * object is put back into its original state at the end of the call.
1607  *
1608  * @todo This is probably not implemented correctly. The stability of the
1609  * salt should be added into this calculation. The underlying water
1610  * model may be called to get the stability of the pure water
1611  * solution, if needed.
1612  *
1613  * @param T Temperature (kelvin)
1614  */
1615  virtual doublereal satPressure(doublereal T);
1616 
1617  /*
1618  * -------------- Utilities -------------------------------
1619  */
1620 
1621  virtual void initThermo();
1622 
1623  //! Initialize the phase parameters from an XML file.
1624  /*!
1625  * This gets called from importPhase(). It processes the XML file after the
1626  * species are set up. This is the main routine for reading in activity
1627  * coefficient parameters.
1628  *
1629  * @param phaseNode This object must be the phase node of a complete XML
1630  * tree description of the phase, including all of the species
1631  * data. In other words while "phase" must point to an XML phase
1632  * object, it must have sibling nodes "speciesData" that
1633  * describe the species in the phase.
1634  * @param id ID of the phase. If nonnull, a check is done to see if
1635  * phaseNode is pointing to the phase with the correct id.
1636  */
1637  virtual void initThermoXML(XML_Node& phaseNode, const std::string& id);
1638 
1639  //! Value of the Debye Huckel constant as a function of temperature
1640  //! and pressure.
1641  /*!
1642  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
1643  *
1644  * Units = sqrt(kg/gmol)
1645  *
1646  * @param temperature Temperature of the derivative calculation
1647  * or -1 to indicate the current temperature
1648  * @param pressure Pressure of the derivative calculation
1649  * or -1 to indicate the current pressure
1650  */
1651  virtual double A_Debye_TP(double temperature = -1.0,
1652  double pressure = -1.0) const;
1653 
1654  //! Value of the derivative of the Debye Huckel constant with respect to
1655  //! temperature as a function of temperature and pressure.
1656  /*!
1657  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
1658  *
1659  * Units = sqrt(kg/gmol)
1660  *
1661  * @param temperature Temperature of the derivative calculation
1662  * or -1 to indicate the current temperature
1663  * @param pressure Pressure of the derivative calculation
1664  * or -1 to indicate the current pressure
1665  */
1666  virtual double dA_DebyedT_TP(double temperature = -1.0,
1667  double pressure = -1.0) const;
1668 
1669  /**
1670  * Value of the derivative of the Debye Huckel constant with respect to
1671  * pressure, as a function of temperature and pressure.
1672  *
1673  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
1674  *
1675  * Units = sqrt(kg/gmol)
1676  *
1677  * @param temperature Temperature of the derivative calculation
1678  * or -1 to indicate the current temperature
1679  * @param pressure Pressure of the derivative calculation
1680  * or -1 to indicate the current pressure
1681  */
1682  virtual double dA_DebyedP_TP(double temperature = -1.0,
1683  double pressure = -1.0) const;
1684 
1685  /**
1686  * Return Pitzer's definition of A_L. This is basically the
1687  * derivative of the A_phi multiplied by 4 R T**2
1688  *
1689  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
1690  * dA_phidT = d(A_Debye)/dT / 3.0
1691  * A_L = dA_phidT * (4 * R * T * T)
1692  *
1693  * Units = sqrt(kg/gmol) (RT)
1694  *
1695  * @param temperature Temperature of the derivative calculation
1696  * or -1 to indicate the current temperature
1697  * @param pressure Pressure of the derivative calculation
1698  * or -1 to indicate the current pressure
1699  */
1700  double ADebye_L(double temperature = -1.0,
1701  double pressure = -1.0) const;
1702 
1703  /**
1704  * Return Pitzer's definition of A_J. This is basically the temperature
1705  * derivative of A_L, and the second derivative of A_phi
1706  *
1707  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
1708  * dA_phidT = d(A_Debye)/dT / 3.0
1709  * A_J = 2 A_L/T + 4 * R * T * T * d2(A_phi)/dT2
1710  *
1711  * Units = sqrt(kg/gmol) (R)
1712  *
1713  * @param temperature Temperature of the derivative calculation
1714  * or -1 to indicate the current temperature
1715  * @param pressure Pressure of the derivative calculation
1716  * or -1 to indicate the current pressure
1717  */
1718  double ADebye_J(double temperature = -1.0,
1719  double pressure = -1.0) const;
1720 
1721  /**
1722  * Return Pitzer's definition of A_V. This is the derivative wrt pressure of
1723  * A_phi multiplied by - 4 R T
1724  *
1725  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
1726  * dA_phidT = d(A_Debye)/dP / 3.0
1727  * A_V = - dA_phidP * (4 * R * T)
1728  *
1729  * Units = sqrt(kg/gmol) (RT) / Pascal
1730  *
1731  * @param temperature Temperature of the derivative calculation
1732  * or -1 to indicate the current temperature
1733  * @param pressure Pressure of the derivative calculation
1734  * or -1 to indicate the current pressure
1735  */
1736  double ADebye_V(double temperature = -1.0,
1737  double pressure = -1.0) const;
1738 
1739  //! Value of the 2nd derivative of the Debye Huckel constant with respect to
1740  //! temperature as a function of temperature and pressure.
1741  /*!
1742  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
1743  *
1744  * Units = sqrt(kg/gmol)
1745  *
1746  * @param temperature Temperature of the derivative calculation
1747  * or -1 to indicate the current temperature
1748  * @param pressure Pressure of the derivative calculation
1749  * or -1 to indicate the current pressure
1750  */
1751  virtual double d2A_DebyedT2_TP(double temperature = -1.0,
1752  double pressure = -1.0) const;
1753 
1754  //! Reports the ionic radius of the kth species
1755  /*!
1756  * @param k Species index
1757  */
1758  double AionicRadius(int k = 0) const;
1759 
1760  /**
1761  * formPitzer():
1762  *
1763  * Returns the form of the Pitzer parameterization used
1764  */
1765  int formPitzer() const {
1766  return m_formPitzer;
1767  }
1768 
1769  //! Print out all of the input Pitzer coefficients.
1770  void printCoeffs() const;
1771 
1772  //! Get the array of unscaled non-dimensional molality based
1773  //! activity coefficients at the current solution temperature,
1774  //! pressure, and solution concentration.
1775  /*!
1776  * See Denbigh p. 278 for a thorough discussion. This class must be
1777  * overridden in classes which derive from MolalityVPSSTP. This function
1778  * takes over from the molar-based activity coefficient calculation,
1779  * getActivityCoefficients(), in derived classes.
1780  *
1781  * @param acMolality Output vector containing the molality based activity coefficients.
1782  * length: m_kk.
1783  */
1784  void getUnscaledMolalityActivityCoefficients(doublereal* acMolality) const;
1785 
1786 private:
1787  //! Apply the current phScale to a set of activity Coefficients
1788  /*!
1789  * See the Eq3/6 Manual for a thorough discussion.
1790  */
1791  void s_updateScaling_pHScaling() const;
1792 
1793  //! Apply the current phScale to a set of derivatives of the activity
1794  //! Coefficients wrt temperature
1795  /*!
1796  * See the Eq3/6 Manual for a thorough discussion of the need
1797  */
1798  void s_updateScaling_pHScaling_dT() const;
1799 
1800  //! Apply the current phScale to a set of 2nd derivatives of the activity
1801  //! Coefficients wrt temperature
1802  /*!
1803  * See the Eq3/6 Manual for a thorough discussion of the need
1804  */
1805  void s_updateScaling_pHScaling_dT2() const;
1806 
1807  //! Apply the current phScale to a set of derivatives of the activity
1808  //! Coefficients wrt pressure
1809  /*!
1810  * See the Eq3/6 Manual for a thorough discussion of the need
1811  */
1812  void s_updateScaling_pHScaling_dP() const;
1813 
1814  //! Calculate the Chlorine activity coefficient on the NBS scale
1815  /*!
1816  * We assume here that the m_IionicMolality variable is up to date.
1817  */
1818  doublereal s_NBS_CLM_lnMolalityActCoeff() const;
1819 
1820  //! Calculate the temperature derivative of the Chlorine activity
1821  //! coefficient on the NBS scale
1822  /*!
1823  * We assume here that the m_IionicMolality variable is up to date.
1824  */
1825  doublereal s_NBS_CLM_dlnMolalityActCoeff_dT() const;
1826 
1827  //! Calculate the second temperature derivative of the Chlorine activity
1828  //! coefficient on the NBS scale
1829  /*!
1830  * We assume here that the m_IionicMolality variable is up to date.
1831  */
1832  doublereal s_NBS_CLM_d2lnMolalityActCoeff_dT2() const;
1833 
1834  //! Calculate the pressure derivative of the Chlorine activity coefficient
1835  /*!
1836  * We assume here that the m_IionicMolality variable is up to date.
1837  */
1838  doublereal s_NBS_CLM_dlnMolalityActCoeff_dP() const;
1839 
1840  //@}
1841 
1842 private:
1843  /**
1844  * This is the form of the Pitzer parameterization used in this model. The
1845  * options are described at the top of this document, and in the general
1846  * documentation. The list is repeated here:
1847  *
1848  * PITZERFORM_BASE = 0 (only one supported atm)
1849  */
1851 
1852  /**
1853  * This is the form of the temperature dependence of Pitzer parameterization
1854  * used in the model.
1855  *
1856  * PITZER_TEMP_CONSTANT 0
1857  * PITZER_TEMP_LINEAR 1
1858  * PITZER_TEMP_COMPLEX1 2
1859  */
1861 
1862  /**
1863  * Format for the generalized concentration:
1864  *
1865  * 0 = unity
1866  * 1 = molar_volume
1867  * 2 = solvent_volume (default)
1868  *
1869  * The generalized concentrations can have three different forms
1870  * depending on the value of the member attribute m_formGC, which
1871  * is supplied in the constructor.
1872  *
1873  * | m_formGC | GeneralizedConc | StandardConc |
1874  * | -------- | --------------- | ------------ |
1875  * | 0 | X_k | 1.0 |
1876  * | 1 | X_k / V_k | 1.0 / V_k |
1877  * | 2 | X_k / V_N | 1.0 / V_N |
1878  *
1879  * The value and form of the generalized concentration will affect reaction
1880  * rate constants involving species in this phase.
1881  *
1882  * (HKM Note: Using option #1 may lead to spurious results and has been
1883  * included only with warnings. The reason is that it molar volumes of
1884  * electrolytes may often be negative. The molar volume of H+ is defined to
1885  * be zero too. Either options 0 or 2 are the appropriate choice. Option 0
1886  * leads to bulk reaction rate constants which have units of s-1. Option 2
1887  * leads to bulk reaction rate constants for bimolecular rxns which have
1888  * units of m-3 kmol-1 s-1.)
1889  */
1891 
1892  //! Vector containing the electrolyte species type
1893  /*!
1894  * The possible types are:
1895  * - solvent
1896  * - Charged Species
1897  * - weakAcidAssociated
1898  * - strongAcidAssociated
1899  * - polarNeutral
1900  * - nonpolarNeutral
1901  */
1903 
1904  //! a_k = Size of the ionic species in the DH formulation. units = meters
1906 
1907  //! Current value of the ionic strength on the molality scale Associated
1908  //! Salts, if present in the mechanism, don't contribute to the value of the
1909  //! ionic strength in this version of the Ionic strength.
1910  mutable double m_IionicMolality;
1911 
1912  //! Maximum value of the ionic strength allowed in the calculation of the
1913  //! activity coefficients.
1915 
1916  //! Reference Temperature for the Pitzer formulations.
1918 
1919  //! Stoichiometric ionic strength on the molality scale. This differs from
1920  //! m_IionicMolality in the sense that associated salts are treated as
1921  //! unassociated salts, when calculating the Ionic strength by this method.
1922  mutable double m_IionicMolalityStoich;
1923 
1924 public:
1925  /**
1926  * Form of the constant outside the Debye-Huckel term called A. It's
1927  * normally a function of temperature and pressure. However, it can be set
1928  * from the input file in order to aid in numerical comparisons. Acceptable
1929  * forms:
1930  *
1931  * A_DEBYE_CONST 0
1932  * A_DEBYE_WATER 1
1933  *
1934  * The A_DEBYE_WATER form may be used for water solvents with needs to cover
1935  * varying temperatures and pressures. Note, the dielectric constant of
1936  * water is a relatively strong function of T, and its variability must be
1937  * accounted for,
1938  */
1940 
1941 private:
1942  /**
1943  * A_Debye: this expression appears on the top of the ln actCoeff term in
1944  * the general Debye-Huckel expression It depends on temperature.
1945  * And, therefore, most be recalculated whenever T or P changes.
1946  * This variable is a local copy of the calculation.
1947  *
1948  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
1949  *
1950  * where B_Debye = F / sqrt(epsilon R T/2)
1951  * (dw/1000)^(1/2)
1952  *
1953  * A_Debye = (1/ (8 Pi)) (2 Na * dw/1000)^(1/2)
1954  * (e * e / (epsilon * kb * T))^(3/2)
1955  *
1956  * Units = sqrt(kg/gmol)
1957  *
1958  * Nominal value = 1.172576 sqrt(kg/gmol)
1959  * based on:
1960  * epsilon/epsilon_0 = 78.54
1961  * (water at 25C)
1962  * epsilon_0 = 8.854187817E-12 C2 N-1 m-2
1963  * e = 1.60217653 E-19 C
1964  * F = 9.6485309E7 C kmol-1
1965  * R = 8.314472E3 kg m2 s-2 kmol-1 K-1
1966  * T = 298.15 K
1967  * B_Debye = 3.28640E9 sqrt(kg/gmol)/m
1968  * dw = C_0 * M_0 (density of water) (kg/m3)
1969  * = 1.0E3 at 25C
1970  */
1971  mutable double m_A_Debye;
1972 
1973  //! Water standard state calculator
1974  /*!
1975  * derived from the equation of state for water.
1976  */
1978 
1979  //! density of standard-state water
1980  /*!
1981  * internal temporary variable
1982  */
1984 
1985  //! Pointer to the water property calculator
1986  std::unique_ptr<WaterProps> m_waterProps;
1987 
1988  //! vector of size m_kk, used as a temporary holding area.
1990 
1991  /**
1992  * Stoichiometric species charge -> This is for calculations of the ionic
1993  * strength which ignore ion-ion pairing into neutral molecules. The
1994  * Stoichiometric species charge is the charge of one of the ion that would
1995  * occur if the species broke into two charged ion pairs.
1996  *
1997  * NaCl -> m_speciesCharge_Stoich = -1;
1998  * HSO4- -> H+ + SO42- = -2
1999  * -> The other charge is calculated.
2000  *
2001  * For species that aren't ion pairs, its equal to the m_speciesCharge[]
2002  * value.
2003  */
2005 
2006  /**
2007  * Array of 2D data used in the Pitzer/HMW formulation. Beta0_ij[i][j] is
2008  * the value of the Beta0 coefficient for the ij salt. It will be nonzero
2009  * iff i and j are both charged and have opposite sign. The array is also
2010  * symmetric. counterIJ where counterIJ = m_counterIJ[i][j] is used to
2011  * access this array.
2012  */
2014 
2015  //! Derivative of Beta0_ij[i][j] wrt T. Vector index is counterIJ
2017 
2018  //! Derivative of Beta0_ij[i][j] wrt TT. Vector index is counterIJ
2020 
2021  //! Derivative of Beta0_ij[i][j] wrt P. Vector index is counterIJ
2023 
2024  //! Array of coefficients for Beta0, a variable in Pitzer's papers
2025  /*!
2026  * Column index is counterIJ. m_Beta0MX_ij_coeff.ptrColumn(counterIJ) is a
2027  * double* containing the vector of coefficients for the counterIJ
2028  * interaction.
2029  */
2031 
2032  //! Array of 2D data used in the Pitzer/HMW formulation. Beta1_ij[i][j] is
2033  //! the value of the Beta1 coefficient for the ij salt. It will be nonzero
2034  //! iff i and j are both charged and have opposite sign. The array is also
2035  //! symmetric. counterIJ where counterIJ = m_counterIJ[i][j] is used to
2036  //! access this array.
2038 
2039  //! Derivative of Beta1_ij[i][j] wrt T. Vector index is counterIJ
2041 
2042  //! Derivative of Beta1_ij[i][j] wrt TT. Vector index is counterIJ
2044 
2045  //! Derivative of Beta1_ij[i][j] wrt P. Vector index is counterIJ
2047 
2048  //! Array of coefficients for Beta1, a variable in Pitzer's papers
2049  /*!
2050  * Column index is counterIJ. m_Beta1MX_ij_coeff.ptrColumn(counterIJ) is a
2051  * double* containing the vector of coefficients for the counterIJ
2052  * interaction.
2053  */
2055 
2056  //! Array of 2D data used in the Pitzer/HMW formulation. Beta2_ij[i][j] is
2057  //! the value of the Beta2 coefficient for the ij salt. It will be nonzero
2058  //! iff i and j are both charged and have opposite sign, and i and j both
2059  //! have charges of 2 or more. The array is also symmetric. counterIJ where
2060  //! counterIJ = m_counterIJ[i][j] is used to access this array.
2062 
2063  //! Derivative of Beta2_ij[i][j] wrt T. Vector index is counterIJ
2065 
2066  //! Derivative of Beta2_ij[i][j] wrt TT. Vector index is counterIJ
2068 
2069  //! Derivative of Beta2_ij[i][j] wrt P. Vector index is counterIJ
2071 
2072  //! Array of coefficients for Beta2, a variable in Pitzer's papers
2073  /*!
2074  * column index is counterIJ. m_Beta2MX_ij_coeff.ptrColumn(counterIJ) is a
2075  * double* containing the vector of coefficients for the counterIJ
2076  * interaction. This was added for the YMP database version of the code
2077  * since it contains temperature-dependent parameters for some 2-2
2078  * electrolytes.
2079  */
2081 
2082  // Array of 2D data used in the Pitzer/HMW formulation. Alpha1MX_ij[i][j] is
2083  // the value of the alpha1 coefficient for the ij interaction. It will be
2084  // nonzero iff i and j are both charged and have opposite sign. It is
2085  // symmetric wrt i, j. counterIJ where counterIJ = m_counterIJ[i][j] is used
2086  // to access this array.
2087  vector_fp m_Alpha1MX_ij;
2088 
2089  //! Array of 2D data used in the Pitzer/HMW formulation. Alpha2MX_ij[i][j]
2090  //! is the value of the alpha2 coefficient for the ij interaction. It will
2091  //! be nonzero iff i and j are both charged and have opposite sign, and i
2092  //! and j both have charges of 2 or more, usually. It is symmetric wrt i, j.
2093  //! counterIJ, where counterIJ = m_counterIJ[i][j], is used to access this
2094  //! array.
2096 
2097  //! Array of 2D data used in the Pitzer/HMW formulation. CphiMX_ij[i][j] is
2098  //! the value of the Cphi coefficient for the ij interaction. It will be
2099  //! nonzero iff i and j are both charged and have opposite sign, and i and j
2100  //! both have charges of 2 or more. The array is also symmetric. counterIJ
2101  //! where counterIJ = m_counterIJ[i][j] is used to access this array.
2103 
2104  //! Derivative of Cphi_ij[i][j] wrt T. Vector index is counterIJ
2106 
2107  //! Derivative of Cphi_ij[i][j] wrt TT. Vector index is counterIJ
2109 
2110  //! Derivative of Cphi_ij[i][j] wrt P. Vector index is counterIJ
2112 
2113  //! Array of coefficients for CphiMX, a parameter in the activity
2114  //! coefficient formulation
2115  /*!
2116  * Column index is counterIJ. m_CphiMX_ij_coeff.ptrColumn(counterIJ) is a
2117  * double* containing the vector of coefficients for the counterIJ
2118  * interaction.
2119  */
2121 
2122  //! Array of 2D data for Theta_ij[i][j] in the Pitzer/HMW formulation.
2123  /*!
2124  * Array of 2D data used in the Pitzer/HMW formulation. Theta_ij[i][j] is
2125  * the value of the theta coefficient for the ij interaction. It will be
2126  * nonzero for charged ions with the same sign. It is symmetric. counterIJ
2127  * where counterIJ = m_counterIJ[i][j] is used to access this array.
2128  *
2129  * HKM Recent Pitzer papers have used a functional form for Theta_ij, which
2130  * depends on the ionic strength.
2131  */
2133 
2134  //! Derivative of Theta_ij[i][j] wrt T. Vector index is counterIJ
2136 
2137  //! Derivative of Theta_ij[i][j] wrt TT. Vector index is counterIJ
2139 
2140  //! Derivative of Theta_ij[i][j] wrt P. Vector index is counterIJ
2142 
2143  //! Array of coefficients for Theta_ij[i][j] in the Pitzer/HMW formulation.
2144  /*!
2145  * Theta_ij[i][j] is the value of the theta coefficient for the ij
2146  * interaction. It will be nonzero for charged ions with the same sign. It
2147  * is symmetric. Column index is counterIJ. counterIJ where counterIJ =
2148  * m_counterIJ[i][j] is used to access this array.
2149  *
2150  * m_Theta_ij_coeff.ptrColumn(counterIJ) is a double* containing
2151  * the vector of coefficients for the counterIJ interaction.
2152  */
2154 
2155  //! Array of 3D data used in the Pitzer/HMW formulation.
2156  /*!
2157  * Psi_ijk[n] is the value of the psi coefficient for the
2158  * ijk interaction where
2159  *
2160  * n = k + j * m_kk + i * m_kk * m_kk;
2161  *
2162  * It is potentially nonzero everywhere. The first two coordinates are
2163  * symmetric wrt cations, and the last two coordinates are symmetric wrt
2164  * anions.
2165  */
2167 
2168  //! Derivative of Psi_ijk[n] wrt T. See m_Psi_ijk for reference on the
2169  //! indexing into this variable.
2171 
2172  //! Derivative of Psi_ijk[n] wrt TT. See m_Psi_ijk for reference on the
2173  //! indexing into this variable.
2175 
2176  //! Derivative of Psi_ijk[n] wrt P. See m_Psi_ijk for reference on the
2177  //! indexing into this variable.
2179 
2180  //! Array of coefficients for Psi_ijk[n] in the Pitzer/HMW formulation.
2181  /*!
2182  * Psi_ijk[n] is the value of the psi coefficient for the
2183  * ijk interaction where
2184  *
2185  * n = k + j * m_kk + i * m_kk * m_kk;
2186  *
2187  * It is potentially nonzero everywhere. The first two coordinates are
2188  * symmetric wrt cations, and the last two coordinates are symmetric wrt
2189  * anions.
2190  *
2191  * m_Psi_ijk_coeff.ptrColumn(n) is a double* containing the vector of
2192  * coefficients for the n interaction.
2193  */
2195 
2196  //! Lambda coefficient for the ij interaction
2197  /*!
2198  * Array of 2D data used in the Pitzer/HMW formulation. Lambda_nj[n][j]
2199  * represents the lambda coefficient for the ij interaction. This is a
2200  * general interaction representing neutral species. The neutral species
2201  * occupy the first index, i.e., n. The charged species occupy the j
2202  * coordinate. neutral, neutral interactions are also included here.
2203  */
2205 
2206  //! Derivative of Lambda_nj[i][j] wrt T. see m_Lambda_ij
2208 
2209  //! Derivative of Lambda_nj[i][j] wrt TT
2211 
2212  //! Derivative of Lambda_nj[i][j] wrt P
2214 
2215  //! Array of coefficients for Lambda_nj[i][j] in the Pitzer/HMW formulation.
2216  /*!
2217  * Array of 2D data used in the Pitzer/HMW formulation. Lambda_ij[i][j]
2218  * represents the lambda coefficient for the ij interaction. This is a
2219  * general interaction representing neutral species. The neutral species
2220  * occupy the first index, i.e., i. The charged species occupy the j
2221  * coordinate. Neutral, neutral interactions are also included here.
2222  *
2223  * n = j + m_kk * i
2224  *
2225  * m_Lambda_ij_coeff.ptrColumn(n) is a double* containing the vector of
2226  * coefficients for the (i,j) interaction.
2227  */
2229 
2230  //! Mu coefficient for the self-ternary neutral coefficient
2231  /*!
2232  * Array of 2D data used in the Pitzer/HMW formulation. Mu_nnn[i] represents
2233  * the Mu coefficient for the nnn interaction. This is a general interaction
2234  * representing neutral species interacting with itself.
2235  */
2237 
2238  //! Mu coefficient temperature derivative for the self-ternary neutral
2239  //! coefficient
2240  /*!
2241  * Array of 2D data used in the Pitzer/HMW formulation. Mu_nnn_L[i]
2242  * represents the Mu coefficient temperature derivative for the nnn
2243  * interaction. This is a general interaction representing neutral species
2244  * interacting with itself.
2245  */
2247 
2248  //! Mu coefficient 2nd temperature derivative for the self-ternary neutral
2249  //! coefficient
2250  /*!
2251  * Array of 2D data used in the Pitzer/HMW formulation. Mu_nnn_L[i]
2252  * represents the Mu coefficient 2nd temperature derivative for the nnn
2253  * interaction. This is a general interaction representing neutral species
2254  * interacting with itself.
2255  */
2257 
2258  //! Mu coefficient pressure derivative for the self-ternary neutral
2259  //! coefficient
2260  /*!
2261  * Array of 2D data used in the Pitzer/HMW formulation. Mu_nnn_L[i]
2262  * represents the Mu coefficient pressure derivative for the nnn
2263  * interaction. This is a general interaction representing neutral species
2264  * interacting with itself.
2265  */
2267 
2268  //! Array of coefficients form_Mu_nnn term
2270 
2271  //! Logarithm of the activity coefficients on the molality scale.
2272  /*!
2273  * mutable because we change this if the composition or temperature or
2274  * pressure changes. Index is the species index
2275  */
2277 
2278  //! Logarithm of the activity coefficients on the molality scale.
2279  /*!
2280  * mutable because we change this if the composition or temperature or
2281  * pressure changes. Index is the species index
2282  */
2284 
2285  //! Derivative of the Logarithm of the activity coefficients on the molality
2286  //! scale wrt T. Index is the species index
2288 
2289  //! Derivative of the Logarithm of the activity coefficients on the molality
2290  //! scale wrt T. Index is the species index
2292 
2293  //! Derivative of the Logarithm of the activity coefficients on the molality
2294  //! scale wrt TT. Index is the species index.
2296 
2297  //! Derivative of the Logarithm of the activity coefficients on the molality
2298  //! scale wrt TT. Index is the species index
2300 
2301  //! Derivative of the Logarithm of the activity coefficients on the
2302  //! molality scale wrt P. Index is the species index
2304 
2305  //! Derivative of the Logarithm of the activity coefficients on the
2306  //! molality scale wrt P. Index is the species index
2308 
2309  // -------- Temporary Variables Used in the Activity Coeff Calc
2310 
2311  //! Cropped and modified values of the molalities used in activity
2312  //! coefficient calculations
2314 
2315  //! Boolean indicating whether the molalities are cropped or are modified
2317 
2318  //! a counter variable for keeping track of symmetric binary
2319  //! interactions amongst the solute species.
2320  /*!
2321  * n = m_kk*i + j
2322  * m_CounterIJ[n] = counterIJ
2323  */
2325 
2326  //! This is elambda, MEC
2327  mutable double elambda[17];
2328 
2329  //! This is elambda1, MEC
2330  mutable double elambda1[17];
2331 
2332  /**
2333  * Various temporary arrays used in the calculation of the Pitzer activity
2334  * coefficients. The subscript, L, denotes the same quantity's derivative
2335  * wrt temperature
2336  */
2337 
2338  //! This is the value of g(x) in Pitzer's papers. Vector index is counterIJ
2340 
2341  //! This is the value of g2(x2) in Pitzer's papers. Vector index is counterIJ
2343 
2344  //! hfunc, was called gprime in Pitzer's paper. However, it's not the
2345  //! derivative of gfunc(x), so I renamed it. Vector index is counterIJ
2347 
2348  //! hfunc2, was called gprime in Pitzer's paper. However, it's not the
2349  //! derivative of gfunc(x), so I renamed it. Vector index is counterIJ
2351 
2352  //! Intermediate variable called BMX in Pitzer's paper. This is the basic
2353  //! cation - anion interaction. Vector index is counterIJ
2355 
2356  //! Derivative of BMX_IJ wrt T. Vector index is counterIJ
2358 
2359  //! Derivative of BMX_IJ wrt TT. Vector index is counterIJ
2361 
2362  //! Derivative of BMX_IJ wrt P. Vector index is counterIJ
2364 
2365  //! Intermediate variable called BprimeMX in Pitzer's paper. Vector index is
2366  //! counterIJ
2368 
2369  //! Derivative of BprimeMX wrt T. Vector index is counterIJ
2371 
2372  //! Derivative of BprimeMX wrt TT. Vector index is counterIJ
2374 
2375  //! Derivative of BprimeMX wrt P. Vector index is counterIJ
2377 
2378  //! Intermediate variable called BphiMX in Pitzer's paper. Vector index is
2379  //! counterIJ
2381 
2382  //! Derivative of BphiMX_IJ wrt T. Vector index is counterIJ
2384 
2385  //! Derivative of BphiMX_IJ wrt TT. Vector index is counterIJ
2387 
2388  //! Derivative of BphiMX_IJ wrt P. Vector index is counterIJ
2390 
2391  //! Intermediate variable called Phi in Pitzer's paper. Vector index is
2392  //! counterIJ
2394 
2395  //! Derivative of m_Phi_IJ wrt T. Vector index is counterIJ
2397 
2398  //! Derivative of m_Phi_IJ wrt TT. Vector index is counterIJ
2400 
2401  //! Derivative of m_Phi_IJ wrt P. Vector index is counterIJ
2403 
2404  //! Intermediate variable called Phiprime in Pitzer's paper. Vector index is
2405  //! counterIJ
2407 
2408  //! Intermediate variable called PhiPhi in Pitzer's paper. Vector index is
2409  //! counterIJ
2411 
2412  //! Derivative of m_PhiPhi_IJ wrt T. Vector index is counterIJ
2414 
2415  //! Derivative of m_PhiPhi_IJ wrt TT. Vector index is counterIJ
2417 
2418  //! Derivative of m_PhiPhi_IJ wrt P. Vector index is counterIJ
2420 
2421  //! Intermediate variable called CMX in Pitzer's paper. Vector index is
2422  //! counterIJ
2424 
2425  //! Derivative of m_CMX_IJ wrt T. Vector index is counterIJ
2427 
2428  //! Derivative of m_CMX_IJ wrt TT. Vector index is counterIJ
2430 
2431  //! Derivative of m_CMX_IJ wrt P. Vector index is counterIJ
2433 
2434  //! Intermediate storage of the activity coefficient itself. Vector index is
2435  //! the species index
2437 
2438  //! Logarithm of the molal activity coefficients. Normally these are all
2439  //! one. However, stability schemes will change that
2441 
2442  //! IMS Cutoff type
2444 
2445  //! value of the solute mole fraction that centers the cutoff polynomials
2446  //! for the cutoff =1 process;
2447  doublereal IMS_X_o_cutoff_;
2448 
2449  //! gamma_o value for the cutoff process at the zero solvent point
2450  doublereal IMS_gamma_o_min_;
2451 
2452  //! gamma_k minimum for the cutoff process at the zero solvent point
2453  doublereal IMS_gamma_k_min_;
2454 
2455  //! Parameter in the polyExp cutoff treatment having to do with rate of exp decay
2456  doublereal IMS_cCut_;
2457 
2458  //! Parameter in the polyExp cutoff treatment
2459  /*!
2460  * This is the slope of the f function at the zero solvent point
2461  * Default value is 0.6
2462  */
2463  doublereal IMS_slopefCut_;
2464 
2465  //! Parameter in the polyExp cutoff treatment
2466  /*!
2467  * This is the slope of the g function at the zero solvent point
2468  * Default value is 0.0
2469  */
2470  doublereal IMS_slopegCut_;
2471 
2472  //! @name Parameters in the polyExp cutoff treatment having to do with rate of exp decay
2473  //! @{
2474  doublereal IMS_dfCut_;
2475  doublereal IMS_efCut_;
2476  doublereal IMS_afCut_;
2477  doublereal IMS_bfCut_;
2478  doublereal IMS_dgCut_;
2479  doublereal IMS_egCut_;
2480  doublereal IMS_agCut_;
2481  doublereal IMS_bgCut_;
2482  //! @}
2483 
2484  //! value of the solvent mole fraction that centers the cutoff polynomials
2485  //! for the cutoff =1 process;
2486  doublereal MC_X_o_cutoff_;
2487 
2488  //! gamma_o value for the cutoff process at the zero solvent point
2489  doublereal MC_X_o_min_;
2490 
2491  //! Parameter in the Molality Exp cutoff treatment
2492  /*!
2493  * This is the slope of the p function at the zero solvent point
2494  * Default value is 0.0
2495  */
2496  doublereal MC_slopepCut_;
2497 
2498  //! @name Parameters in the Molality Exp cutoff treatment
2499  //! @{
2500  doublereal MC_dpCut_;
2501  doublereal MC_epCut_;
2502  doublereal MC_apCut_;
2503  doublereal MC_bpCut_;
2504  doublereal MC_cpCut_;
2505  doublereal CROP_ln_gamma_o_min;
2506  doublereal CROP_ln_gamma_o_max;
2507  doublereal CROP_ln_gamma_k_min;
2508  doublereal CROP_ln_gamma_k_max;
2509 
2510  //! This is a boolean-type vector indicating whether
2511  //! a species's activity coefficient is in the cropped regime
2512  /*!
2513  * * 0 = Not in cropped regime
2514  * * 1 = In a transition regime where it is altered but there
2515  * still may be a temperature or pressure dependence
2516  * * 2 = In a cropped regime where there is no temperature
2517  * or pressure dependence
2518  */
2520  //! @}
2521 
2522  //! Initialize all of the species-dependent lengths in the object
2523  void initLengths();
2524 
2525  //! Apply the current phScale to a set of activity Coefficients or
2526  //! activities
2527  /*!
2528  * See the Eq3/6 Manual for a thorough discussion.
2529  *
2530  * @param acMolality input/Output vector containing the molality based
2531  * activity coefficients. length: m_kk.
2532  */
2533  virtual void applyphScale(doublereal* acMolality) const;
2534 
2535 private:
2536  /*
2537  * This function will be called to update the internally stored
2538  * natural logarithm of the molality activity coefficients
2539  */
2540  void s_update_lnMolalityActCoeff() const;
2541 
2542  //! This function calculates the temperature derivative of the
2543  //! natural logarithm of the molality activity coefficients.
2544  /*!
2545  * This function does all of the direct work. The solvent activity
2546  * coefficient is on the molality scale. It's derivative is too.
2547  */
2548  void s_update_dlnMolalityActCoeff_dT() const;
2549 
2550  /**
2551  * This function calculates the temperature second derivative of the natural
2552  * logarithm of the molality activity coefficients.
2553  */
2554  void s_update_d2lnMolalityActCoeff_dT2() const;
2555 
2556  /**
2557  * This function calculates the pressure derivative of the
2558  * natural logarithm of the molality activity coefficients.
2559  *
2560  * Assumes that the activity coefficients are current.
2561  */
2562  void s_update_dlnMolalityActCoeff_dP() const;
2563 
2564  //! This function will be called to update the internally stored
2565  //! natural logarithm of the molality activity coefficients
2566  /*
2567  * Normally they are all one. However, sometimes they are not,
2568  * due to stability schemes
2569  *
2570  * gamma_k_molar = gamma_k_molal / Xmol_solvent
2571  *
2572  * gamma_o_molar = gamma_o_molal
2573  */
2574  void s_updateIMS_lnMolalityActCoeff() const;
2575 
2576 private:
2577  //! Calculate the Pitzer portion of the activity coefficients.
2578  /**
2579  * This is the main routine in the whole module. It calculates the molality
2580  * based activity coefficients for the solutes, and the activity of water.
2581  */
2582  void s_updatePitzer_lnMolalityActCoeff() const;
2583 
2584  //! Calculates the temperature derivative of the natural logarithm of the
2585  //! molality activity coefficients.
2586  /*!
2587  * Public function makes sure that all dependent data is
2588  * up to date, before calling a private function
2589  */
2591 
2592  /**
2593  * This function calculates the temperature second derivative of the
2594  * natural logarithm of the molality activity coefficients.
2595  *
2596  * It is assumed that the Pitzer activity coefficient and first derivative
2597  * routine are called immediately preceding the call to this routine.
2598  */
2600 
2601  //! Calculates the Pressure derivative of the natural logarithm of the
2602  //! molality activity coefficients.
2603  /*!
2604  * It is assumed that the Pitzer activity coefficient and first derivative
2605  * routine are called immediately preceding the calling of this routine.
2606  */
2608 
2609  //! Calculates the Pitzer coefficients' dependence on the temperature.
2610  /*!
2611  * It will also calculate the temperature derivatives of the coefficients,
2612  * as they are important in the calculation of the latent heats and the heat
2613  * capacities of the mixtures.
2614  *
2615  * @param doDerivs If >= 1, then the routine will calculate the first
2616  * derivative. If >= 2, the routine will calculate the first
2617  * and second temperature derivative. default = 2
2618  */
2619  void s_updatePitzer_CoeffWRTemp(int doDerivs = 2) const;
2620 
2621  //! Calculate the lambda interactions.
2622  /*!
2623  * Calculate E-lambda terms for charge combinations of like sign, using
2624  * method of Pitzer (1975). This implementation is based on Bethke,
2625  * Appendix 2.
2626  *
2627  * @param is Ionic strength
2628  */
2629  void calc_lambdas(double is) const;
2630  mutable doublereal m_last_is;
2631 
2632  /**
2633  * Calculate etheta and etheta_prime
2634  *
2635  * This interaction accounts for the mixing effects of like-signed ions with
2636  * different charges. This interaction will be nonzero for species with the
2637  * same charge. this routine is not to be called for neutral species; it
2638  * core dumps or error exits.
2639  *
2640  * MEC implementation routine.
2641  *
2642  * @param z1 charge of the first molecule
2643  * @param z2 charge of the second molecule
2644  * @param etheta return pointer containing etheta
2645  * @param etheta_prime Return pointer containing etheta_prime.
2646  *
2647  * This routine uses the internal variables, elambda[] and elambda1[].
2648  */
2649  void calc_thetas(int z1, int z2,
2650  double* etheta, double* etheta_prime) const;
2651 
2652  //! Set up a counter variable for keeping track of symmetric binary
2653  //! interactions amongst the solute species.
2654  /*!
2655  * The purpose of this is to squeeze the ij parameters into a
2656  * compressed single counter.
2657  *
2658  * n = m_kk*i + j
2659  * m_Counter[n] = counter
2660  */
2661  void counterIJ_setup() const;
2662 
2663  //! Calculate the cropped molalities
2664  /*!
2665  * This is an internal routine that calculates values of m_molalitiesCropped
2666  * from m_molalities
2667  */
2668  void calcMolalitiesCropped() const;
2669 
2670  //! Process an XML node called "binarySaltParameters"
2671  /*!
2672  * This node contains all of the parameters necessary to describe the Pitzer
2673  * model for that particular binary salt. This function reads the XML file
2674  * and writes the coefficients it finds to an internal data structures.
2675  *
2676  * @param BinSalt reference to the XML_Node named binarySaltParameters
2677  * containing the anion - cation interaction
2678  */
2679  void readXMLBinarySalt(XML_Node& BinSalt);
2680 
2681  //! Process an XML node called "thetaAnion"
2682  /*!
2683  * This node contains all of the parameters necessary to describe the binary
2684  * interactions between two anions.
2685  *
2686  * @param BinSalt reference to the XML_Node named thetaAnion containing the
2687  * anion - anion interaction
2688  */
2689  void readXMLThetaAnion(XML_Node& BinSalt);
2690 
2691  //! Process an XML node called "thetaCation"
2692  /*!
2693  * This node contains all of the parameters necessary to describe the binary
2694  * interactions between two cations.
2695  *
2696  * @param BinSalt reference to the XML_Node named thetaCation containing
2697  * the cation - cation interaction
2698  */
2699  void readXMLThetaCation(XML_Node& BinSalt);
2700 
2701  //! Process an XML node called "psiCommonAnion"
2702  /*!
2703  * This node contains all of the parameters necessary to describe
2704  * the ternary interactions between one anion and two cations.
2705  *
2706  * @param BinSalt reference to the XML_Node named psiCommonAnion containing
2707  * the anion - cation1 - cation2 interaction
2708  */
2709  void readXMLPsiCommonAnion(XML_Node& BinSalt);
2710 
2711  //! Process an XML node called "psiCommonCation"
2712  /*!
2713  * This node contains all of the parameters necessary to describe
2714  * the ternary interactions between one cation and two anions.
2715  *
2716  * @param BinSalt reference to the XML_Node named psiCommonCation
2717  * containing the cation - anion1 - anion2 interaction
2718  */
2719  void readXMLPsiCommonCation(XML_Node& BinSalt);
2720 
2721  //! Process an XML node called "lambdaNeutral"
2722  /*!
2723  * This node contains all of the parameters necessary to describe the binary
2724  * interactions between one neutral species and any other species (neutral
2725  * or otherwise) in the mechanism.
2726  *
2727  * @param BinSalt reference to the XML_Node named lambdaNeutral containing
2728  * multiple Neutral - species interactions
2729  */
2730  void readXMLLambdaNeutral(XML_Node& BinSalt);
2731 
2732  //! Process an XML node called "MunnnNeutral"
2733  /*!
2734  * This node contains all of the parameters necessary to describe
2735  * the self-ternary interactions for one neutral species.
2736  *
2737  * @param BinSalt reference to the XML_Node named Munnn containing the
2738  * self-ternary interaction
2739  */
2740  void readXMLMunnnNeutral(XML_Node& BinSalt);
2741 
2742  //! Process an XML node called "zetaCation"
2743  /*!
2744  * This node contains all of the parameters necessary to describe
2745  * the ternary interactions between one neutral, one cation, and one anion.
2746  *
2747  * @param BinSalt reference to the XML_Node named psiCommonCation
2748  * containing the neutral - cation - anion interaction
2749  */
2750  void readXMLZetaCation(const XML_Node& BinSalt);
2751 
2752  //! Process an XML node called "croppingCoefficients" for the cropping
2753  //! coefficients values
2754  /*!
2755  * @param acNode Activity Coefficient XML Node
2756  */
2757  void readXMLCroppingCoefficients(const XML_Node& acNode);
2758 
2759  //! Precalculate the IMS Cutoff parameters for typeCutoff = 2
2760  void calcIMSCutoffParams_();
2761 
2762  //! Calculate molality cut-off parameters
2763  void calcMCCutoffParams_();
2764 
2765  //! Utility function to assign an integer value from a string for the
2766  //! ElectrolyteSpeciesType field.
2767  /*!
2768  * @param estString string name of the electrolyte species type
2769  */
2770  static int interp_est(const std::string& estString);
2771 
2772 public:
2773  //! Turn on copious debug printing when this is true
2774  mutable int m_debugCalc;
2775 
2776  //! Return int specifying the amount of debug printing
2777  int debugPrinting();
2778 };
2779 
2780 }
2781 
2782 #endif
vector_fp m_Theta_ij_P
Derivative of Theta_ij[i][j] wrt P. Vector index is counterIJ.
Definition: HMWSoln.h:2141
vector_fp m_BMX_IJ_L
Derivative of BMX_IJ wrt T. Vector index is counterIJ.
Definition: HMWSoln.h:2357
vector_fp m_PhiPhi_IJ_P
Derivative of m_PhiPhi_IJ wrt P. Vector index is counterIJ.
Definition: HMWSoln.h:2419
void calcMolalitiesCropped() const
Calculate the cropped molalities.
Definition: HMWSoln.cpp:1047
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
Definition: HMWSoln.cpp:574
void s_updateScaling_pHScaling() const
Apply the current phScale to a set of activity Coefficients.
Definition: HMWSoln.cpp:4213
vector_fp m_CphiMX_ij_LL
Derivative of Cphi_ij[i][j] wrt TT. Vector index is counterIJ.
Definition: HMWSoln.h:2108
void s_update_dlnMolalityActCoeff_dT() const
This function calculates the temperature derivative of the natural logarithm of the molality activity...
Definition: HMWSoln.cpp:2153
vector_fp m_Theta_ij_L
Derivative of Theta_ij[i][j] wrt T. Vector index is counterIJ.
Definition: HMWSoln.h:2135
vector_fp m_speciesCharge_Stoich
Stoichiometric species charge -> This is for calculations of the ionic strength which ignore ion-ion ...
Definition: HMWSoln.h:2004
void readXMLBinarySalt(XML_Node &BinSalt)
Process an XML node called "binarySaltParameters".
vector_fp m_CMX_IJ_P
Derivative of m_CMX_IJ wrt P. Vector index is counterIJ.
Definition: HMWSoln.h:2432
vector_fp m_gfunc_IJ
Various temporary arrays used in the calculation of the Pitzer activity coefficients.
Definition: HMWSoln.h:2339
virtual doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
Definition: HMWSoln.cpp:465
vector_fp m_Beta2MX_ij_L
Derivative of Beta2_ij[i][j] wrt T. Vector index is counterIJ.
Definition: HMWSoln.h:2064
vector_fp m_d2lnActCoeffMolaldT2_Unscaled
Derivative of the Logarithm of the activity coefficients on the molality scale wrt TT...
Definition: HMWSoln.h:2299
doublereal MC_X_o_cutoff_
value of the solvent mole fraction that centers the cutoff polynomials for the cutoff =1 process; ...
Definition: HMWSoln.h:2486
virtual void applyphScale(doublereal *acMolality) const
Apply the current phScale to a set of activity Coefficients or activities.
Definition: HMWSoln.cpp:4199
vector_fp IMS_lnActCoeffMolal_
Logarithm of the molal activity coefficients.
Definition: HMWSoln.h:2440
doublereal temperature() const
Temperature (K).
Definition: Phase.h:601
Array2D m_Lambda_nj_coeff
Array of coefficients for Lambda_nj[i][j] in the Pitzer/HMW formulation.
Definition: HMWSoln.h:2228
double m_maxIionicStrength
Maximum value of the ionic strength allowed in the calculation of the activity coefficients.
Definition: HMWSoln.h:1914
void readXMLLambdaNeutral(XML_Node &BinSalt)
Process an XML node called "lambdaNeutral".
void readXMLThetaAnion(XML_Node &BinSalt)
Process an XML node called "thetaAnion".
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
Definition: HMWSoln.cpp:453
vector_fp m_Beta1MX_ij_LL
Derivative of Beta1_ij[i][j] wrt TT. Vector index is counterIJ.
Definition: HMWSoln.h:2043
doublereal s_NBS_CLM_dlnMolalityActCoeff_dP() const
Calculate the pressure derivative of the Chlorine activity coefficient.
Definition: HMWSoln.cpp:4295
vector_fp m_Mu_nnn_L
Mu coefficient temperature derivative for the self-ternary neutral coefficient.
Definition: HMWSoln.h:2246
vector_fp m_dlnActCoeffMolaldP_Unscaled
Derivative of the Logarithm of the activity coefficients on the molality scale wrt P...
Definition: HMWSoln.h:2307
Array2D m_Beta0MX_ij_coeff
Array of coefficients for Beta0, a variable in Pitzer&#39;s papers.
Definition: HMWSoln.h:2030
vector_fp m_Beta2MX_ij_P
Derivative of Beta2_ij[i][j] wrt P. Vector index is counterIJ.
Definition: HMWSoln.h:2070
double AionicRadius(int k=0) const
Reports the ionic radius of the kth species.
Definition: HMWSoln.cpp:844
vector_fp m_Beta2MX_ij
Array of 2D data used in the Pitzer/HMW formulation.
Definition: HMWSoln.h:2061
Array2D m_Lambda_nj_P
Derivative of Lambda_nj[i][j] wrt P.
Definition: HMWSoln.h:2213
void readXMLMunnnNeutral(XML_Node &BinSalt)
Process an XML node called "MunnnNeutral".
virtual int eosType() const
Equation of state type flag.
Definition: HMWSoln.cpp:372
vector_fp m_PhiPhi_IJ
Intermediate variable called PhiPhi in Pitzer&#39;s paper.
Definition: HMWSoln.h:2410
vector_fp m_Phi_IJ_L
Derivative of m_Phi_IJ wrt T. Vector index is counterIJ.
Definition: HMWSoln.h:2396
int IMS_typeCutoff_
IMS Cutoff type.
Definition: HMWSoln.h:2443
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies of the species in the solution.
Definition: HMWSoln.cpp:616
vector_fp m_dlnActCoeffMolaldT_Scaled
Derivative of the Logarithm of the activity coefficients on the molality scale wrt T...
Definition: HMWSoln.h:2287
virtual void setMolarDensity(const doublereal conc)
Set the internally stored molar density (kmol/m^3) for the phase.
Definition: HMWSoln.cpp:511
void counterIJ_setup() const
Set up a counter variable for keeping track of symmetric binary interactions amongst the solute speci...
Definition: HMWSoln.cpp:1188
vector_fp m_BMX_IJ_P
Derivative of BMX_IJ wrt P. Vector index is counterIJ.
Definition: HMWSoln.h:2363
void s_updateIMS_lnMolalityActCoeff() const
This function will be called to update the internally stored natural logarithm of the molality activi...
Definition: HMWSoln.cpp:4053
vector_fp m_Beta0MX_ij_L
Derivative of Beta0_ij[i][j] wrt T. Vector index is counterIJ.
Definition: HMWSoln.h:2016
double elambda[17]
This is elambda, MEC.
Definition: HMWSoln.h:2327
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:97
vector_fp m_dlnActCoeffMolaldP_Scaled
Derivative of the Logarithm of the activity coefficients on the molality scale wrt P...
Definition: HMWSoln.h:2303
int debugPrinting()
Return int specifying the amount of debug printing.
Definition: HMWSoln.cpp:4302
vector_fp m_Mu_nnn_P
Mu coefficient pressure derivative for the self-ternary neutral coefficient.
Definition: HMWSoln.h:2266
doublereal s_NBS_CLM_dlnMolalityActCoeff_dT() const
Calculate the temperature derivative of the Chlorine activity coefficient on the NBS scale...
Definition: HMWSoln.cpp:4281
void readXMLPsiCommonAnion(XML_Node &BinSalt)
Process an XML node called "psiCommonAnion".
Array2D m_Lambda_nj_L
Derivative of Lambda_nj[i][j] wrt T. see m_Lambda_ij.
Definition: HMWSoln.h:2207
virtual void setDensity(const doublereal rho)
Set the internally stored density (kg/m^3) of the phase.
Definition: HMWSoln.cpp:502
vector_fp m_BprimeMX_IJ_P
Derivative of BprimeMX wrt P. Vector index is counterIJ.
Definition: HMWSoln.h:2376
void calcMCCutoffParams_()
Calculate molality cut-off parameters.
vector_fp m_CphiMX_ij_P
Derivative of Cphi_ij[i][j] wrt P. Vector index is counterIJ.
Definition: HMWSoln.h:2111
void calcIMSCutoffParams_()
Precalculate the IMS Cutoff parameters for typeCutoff = 2.
vector_fp m_Psi_ijk_L
Derivative of Psi_ijk[n] wrt T.
Definition: HMWSoln.h:2170
void readXMLZetaCation(const XML_Node &BinSalt)
Process an XML node called "zetaCation".
int formPitzer() const
formPitzer():
Definition: HMWSoln.h:1765
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Initialize the phase parameters from an XML file.
vector_fp m_lnActCoeffMolal_Unscaled
Logarithm of the activity coefficients on the molality scale.
Definition: HMWSoln.h:2283
void s_updatePitzer_d2lnMolalityActCoeff_dT2() const
This function calculates the temperature second derivative of the natural logarithm of the molality a...
Definition: HMWSoln.cpp:2795
vector_fp m_Theta_ij
Array of 2D data for Theta_ij[i][j] in the Pitzer/HMW formulation.
Definition: HMWSoln.h:2132
vector_fp m_hfunc_IJ
hfunc, was called gprime in Pitzer&#39;s paper.
Definition: HMWSoln.h:2346
double elambda1[17]
This is elambda1, MEC.
Definition: HMWSoln.h:2330
vector_fp m_Beta1MX_ij_P
Derivative of Beta1_ij[i][j] wrt P. Vector index is counterIJ.
Definition: HMWSoln.h:2046
vector_fp m_BprimeMX_IJ_LL
Derivative of BprimeMX wrt TT. Vector index is counterIJ.
Definition: HMWSoln.h:2373
double ADebye_V(double temperature=-1.0, double pressure=-1.0) const
Return Pitzer&#39;s definition of A_V.
Definition: HMWSoln.cpp:795
vector_fp m_PhiPhi_IJ_LL
Derivative of m_PhiPhi_IJ wrt TT. Vector index is counterIJ.
Definition: HMWSoln.h:2416
void readXMLPsiCommonCation(XML_Node &BinSalt)
Process an XML node called "psiCommonCation".
doublereal IMS_cCut_
Parameter in the polyExp cutoff treatment having to do with rate of exp decay.
Definition: HMWSoln.h:2456
vector_fp m_Psi_ijk_LL
Derivative of Psi_ijk[n] wrt TT.
Definition: HMWSoln.h:2174
double m_IionicMolality
Current value of the ionic strength on the molality scale Associated Salts, if present in the mechani...
Definition: HMWSoln.h:1910
virtual ThermoPhase * duplMyselfAsThermoPhase() const
Duplication routine for objects which inherit from ThermoPhase.
Definition: HMWSoln.cpp:367
vector_fp m_Phi_IJ
Intermediate variable called Phi in Pitzer&#39;s paper.
Definition: HMWSoln.h:2393
vector_fp m_BphiMX_IJ
Intermediate variable called BphiMX in Pitzer&#39;s paper.
Definition: HMWSoln.h:2380
Array2D m_CphiMX_ij_coeff
Array of coefficients for CphiMX, a parameter in the activity coefficient formulation.
Definition: HMWSoln.h:2120
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
Definition: HMWSoln.cpp:653
void s_updateScaling_pHScaling_dP() const
Apply the current phScale to a set of derivatives of the activity Coefficients wrt pressure...
Definition: HMWSoln.cpp:4258
vector_fp m_Beta1MX_ij
Array of 2D data used in the Pitzer/HMW formulation.
Definition: HMWSoln.h:2037
vector_fp m_tmpV
vector of size m_kk, used as a temporary holding area.
Definition: HMWSoln.h:1989
A class for 2D arrays stored in column-major (Fortran-compatible) form.
Definition: Array.h:31
Header for intermediate ThermoPhase object for phases which employ molality based activity coefficien...
virtual void getPartialMolarCp(doublereal *cpbar) const
Return an array of partial molar heat capacities for the species in the mixture.
Definition: HMWSoln.cpp:666
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:93
HMWSoln()
Default Constructor.
Definition: HMWSoln.cpp:27
vector_fp m_lnActCoeffMolal_Scaled
Logarithm of the activity coefficients on the molality scale.
Definition: HMWSoln.h:2276
Header file for class Cantera::Array2D.
std::vector< int > vector_int
Vector of ints.
Definition: ct_defs.h:159
doublereal MC_X_o_min_
gamma_o value for the cutoff process at the zero solvent point
Definition: HMWSoln.h:2489
vector_fp m_Phi_IJ_P
Derivative of m_Phi_IJ wrt P. Vector index is counterIJ.
Definition: HMWSoln.h:2402
PDSS * m_waterSS
Water standard state calculator.
Definition: HMWSoln.h:1977
vector_fp m_Phiprime_IJ
Intermediate variable called Phiprime in Pitzer&#39;s paper.
Definition: HMWSoln.h:2406
vector_fp m_h2func_IJ
hfunc2, was called gprime in Pitzer&#39;s paper.
Definition: HMWSoln.h:2350
void readXMLCroppingCoefficients(const XML_Node &acNode)
Process an XML node called "croppingCoefficients" for the cropping coefficients values.
void printCoeffs() const
Print out all of the input Pitzer coefficients.
Definition: HMWSoln.cpp:4155
vector_fp m_Psi_ijk_P
Derivative of Psi_ijk[n] wrt P.
Definition: HMWSoln.h:2178
vector_fp m_CMX_IJ_L
Derivative of m_CMX_IJ wrt T. Vector index is counterIJ.
Definition: HMWSoln.h:2426
bool m_molalitiesAreCropped
Boolean indicating whether the molalities are cropped or are modified.
Definition: HMWSoln.h:2316
vector_fp m_dlnActCoeffMolaldT_Unscaled
Derivative of the Logarithm of the activity coefficients on the molality scale wrt T...
Definition: HMWSoln.h:2291
Array2D m_Psi_ijk_coeff
Array of coefficients for Psi_ijk[n] in the Pitzer/HMW formulation.
Definition: HMWSoln.h:2194
doublereal s_NBS_CLM_lnMolalityActCoeff() const
Calculate the Chlorine activity coefficient on the NBS scale.
Definition: HMWSoln.cpp:4273
std::unique_ptr< WaterProps > m_waterProps
Pointer to the water property calculator.
Definition: HMWSoln.h:1986
virtual doublereal relative_enthalpy() const
Excess molar enthalpy of the solution from the mixing process.
Definition: HMWSoln.cpp:401
void calc_thetas(int z1, int z2, double *etheta, double *etheta_prime) const
Calculate etheta and etheta_prime.
Definition: HMWSoln.cpp:4027
virtual void initThermo()
vector_fp m_Mu_nnn
Mu coefficient for the self-ternary neutral coefficient.
Definition: HMWSoln.h:2236
vector_fp m_molalitiesCropped
Cropped and modified values of the molalities used in activity coefficient calculations.
Definition: HMWSoln.h:2313
vector_fp m_Beta2MX_ij_LL
Derivative of Beta2_ij[i][j] wrt TT. Vector index is counterIJ.
Definition: HMWSoln.h:2067
void s_updatePitzer_dlnMolalityActCoeff_dT() const
Calculates the temperature derivative of the natural logarithm of the molality activity coefficients...
Definition: HMWSoln.cpp:2181
vector_int CROP_speciesCropped_
This is a boolean-type vector indicating whether a species&#39;s activity coefficient is in the cropped r...
Definition: HMWSoln.h:2519
vector_fp m_CMX_IJ_LL
Derivative of m_CMX_IJ wrt TT. Vector index is counterIJ.
Definition: HMWSoln.h:2429
Array2D m_Beta2MX_ij_coeff
Array of coefficients for Beta2, a variable in Pitzer&#39;s papers.
Definition: HMWSoln.h:2080
Array2D m_Lambda_nj_LL
Derivative of Lambda_nj[i][j] wrt TT.
Definition: HMWSoln.h:2210
void getUnscaledMolalityActivityCoefficients(doublereal *acMolality) const
Get the array of unscaled non-dimensional molality based activity coefficients at the current solutio...
Definition: HMWSoln.cpp:561
doublereal IMS_slopegCut_
Parameter in the polyExp cutoff treatment.
Definition: HMWSoln.h:2470
doublereal IMS_slopefCut_
Parameter in the polyExp cutoff treatment.
Definition: HMWSoln.h:2463
vector_fp m_Beta0MX_ij_LL
Derivative of Beta0_ij[i][j] wrt TT. Vector index is counterIJ.
Definition: HMWSoln.h:2019
void s_updatePitzer_CoeffWRTemp(int doDerivs=2) const
Calculates the Pitzer coefficients&#39; dependence on the temperature.
Definition: HMWSoln.cpp:1211
int m_form_A_Debye
Form of the constant outside the Debye-Huckel term called A.
Definition: HMWSoln.h:1939
doublereal s_NBS_CLM_d2lnMolalityActCoeff_dT2() const
Calculate the second temperature derivative of the Chlorine activity coefficient on the NBS scale...
Definition: HMWSoln.cpp:4288
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
Definition: HMWSoln.cpp:395
vector_int m_CounterIJ
a counter variable for keeping track of symmetric binary interactions amongst the solute species...
Definition: HMWSoln.h:2324
doublereal MC_slopepCut_
Parameter in the Molality Exp cutoff treatment.
Definition: HMWSoln.h:2496
vector_fp m_CMX_IJ
Intermediate variable called CMX in Pitzer&#39;s paper.
Definition: HMWSoln.h:2423
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
Definition: HMWSoln.cpp:597
double m_TempPitzerRef
Reference Temperature for the Pitzer formulations.
Definition: HMWSoln.h:1917
vector_fp m_CphiMX_ij_L
Derivative of Cphi_ij[i][j] wrt T. Vector index is counterIJ.
Definition: HMWSoln.h:2105
static int interp_est(const std::string &estString)
Utility function to assign an integer value from a string for the ElectrolyteSpeciesType field...
void constructPhaseXML(XML_Node &phaseNode, std::string id)
Import and initialize a HMWSoln phase specification in an XML tree into the current object...
vector_fp m_BphiMX_IJ_L
Derivative of BphiMX_IJ wrt T. Vector index is counterIJ.
Definition: HMWSoln.h:2383
vector_fp m_g2func_IJ
This is the value of g2(x2) in Pitzer&#39;s papers. Vector index is counterIJ.
Definition: HMWSoln.h:2342
virtual double d2A_DebyedT2_TP(double temperature=-1.0, double pressure=-1.0) const
Value of the 2nd derivative of the Debye Huckel constant with respect to temperature as a function of...
Definition: HMWSoln.cpp:818
void constructPhaseFile(std::string inputFile, std::string id)
Import, construct, and initialize a HMWSoln phase specification from an XML tree into the current obj...
void readXMLThetaCation(XML_Node &BinSalt)
Process an XML node called "thetaCation".
double m_densWaterSS
density of standard-state water
Definition: HMWSoln.h:1983
Array2D m_Lambda_nj
Lambda coefficient for the ij interaction.
Definition: HMWSoln.h:2204
void s_update_d2lnMolalityActCoeff_dT2() const
This function calculates the temperature second derivative of the natural logarithm of the molality a...
Definition: HMWSoln.cpp:2767
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
Definition: HMWSoln.cpp:471
vector_fp m_Phi_IJ_LL
Derivative of m_Phi_IJ wrt TT. Vector index is counterIJ.
Definition: HMWSoln.h:2399
int m_formPitzer
This is the form of the Pitzer parameterization used in this model.
Definition: HMWSoln.h:1850
virtual doublereal pressure() const
Returns the current pressure of the phase.
virtual std::string type() const
String indicating the thermodynamic model implemented.
Definition: HMWSoln.h:1218
doublereal IMS_gamma_k_min_
gamma_k minimum for the cutoff process at the zero solvent point
Definition: HMWSoln.h:2453
virtual void getActivityConcentrations(doublereal *c) const
This method returns an array of generalized activity concentrations.
Definition: HMWSoln.cpp:519
vector_fp m_Alpha2MX_ij
Array of 2D data used in the Pitzer/HMW formulation.
Definition: HMWSoln.h:2095
vector_int m_electrolyteSpeciesType
Vector containing the electrolyte species type.
Definition: HMWSoln.h:1902
vector_fp m_Beta0MX_ij
Array of 2D data used in the Pitzer/HMW formulation.
Definition: HMWSoln.h:2013
vector_fp m_BprimeMX_IJ_L
Derivative of BprimeMX wrt T. Vector index is counterIJ.
Definition: HMWSoln.h:2370
doublereal IMS_gamma_o_min_
gamma_o value for the cutoff process at the zero solvent point
Definition: HMWSoln.h:2450
vector_fp m_BMX_IJ_LL
Derivative of BMX_IJ wrt TT. Vector index is counterIJ.
Definition: HMWSoln.h:2360
int m_formGC
Format for the generalized concentration:
Definition: HMWSoln.h:1890
double m_A_Debye
A_Debye: this expression appears on the top of the ln actCoeff term in the general Debye-Huckel expre...
Definition: HMWSoln.h:1971
virtual doublereal standardConcentration(size_t k=0) const
Return the standard concentration for the kth species.
Definition: HMWSoln.cpp:532
void initLengths()
Initialize all of the species-dependent lengths in the object.
Definition: HMWSoln.cpp:851
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
Virtual base class for a species with a pressure dependent standard state.
Definition: PDSS.h:176
virtual doublereal relative_molal_enthalpy() const
Excess molar enthalpy of the solution from the mixing process on a molality basis.
Definition: HMWSoln.cpp:413
void calcDensity()
Calculate the density of the mixture using the partial molar volumes and mole fractions as input...
Definition: HMWSoln.cpp:483
vector_fp m_gamma_tmp
Intermediate storage of the activity coefficient itself.
Definition: HMWSoln.h:2436
void s_update_dlnMolalityActCoeff_dP() const
This function calculates the pressure derivative of the natural logarithm of the molality activity co...
Definition: HMWSoln.cpp:3373
virtual void getActivities(doublereal *ac) const
Get the array of non-dimensional activities at the current solution temperature, pressure, and solution concentration.
Definition: HMWSoln.cpp:542
doublereal IMS_X_o_cutoff_
value of the solute mole fraction that centers the cutoff polynomials for the cutoff =1 process; ...
Definition: HMWSoln.h:2447
vector_fp m_Psi_ijk
Array of 3D data used in the Pitzer/HMW formulation.
Definition: HMWSoln.h:2166
Class HMWSoln represents a dilute or concentrated liquid electrolyte phase which obeys the Pitzer for...
Definition: HMWSoln.h:1145
void s_updatePitzer_dlnMolalityActCoeff_dP() const
Calculates the Pressure derivative of the natural logarithm of the molality activity coefficients...
Definition: HMWSoln.cpp:3397
vector_fp m_BMX_IJ
Intermediate variable called BMX in Pitzer&#39;s paper.
Definition: HMWSoln.h:2354
void s_updateScaling_pHScaling_dT() const
Apply the current phScale to a set of derivatives of the activity Coefficients wrt temperature...
Definition: HMWSoln.cpp:4228
virtual double dA_DebyedP_TP(double temperature=-1.0, double pressure=-1.0) const
Value of the derivative of the Debye Huckel constant with respect to pressure, as a function of tempe...
Definition: HMWSoln.cpp:752
virtual double dA_DebyedT_TP(double temperature=-1.0, double pressure=-1.0) const
Value of the derivative of the Debye Huckel constant with respect to temperature as a function of tem...
Definition: HMWSoln.cpp:728
double m_IionicMolalityStoich
Stoichiometric ionic strength on the molality scale.
Definition: HMWSoln.h:1922
void s_updateScaling_pHScaling_dT2() const
Apply the current phScale to a set of 2nd derivatives of the activity Coefficients wrt temperature...
Definition: HMWSoln.cpp:4243
int m_debugCalc
Turn on copious debug printing when this is true.
Definition: HMWSoln.h:2774
vector_fp m_BprimeMX_IJ
Intermediate variable called BprimeMX in Pitzer&#39;s paper.
Definition: HMWSoln.h:2367
vector_fp m_d2lnActCoeffMolaldT2_Scaled
Derivative of the Logarithm of the activity coefficients on the molality scale wrt TT...
Definition: HMWSoln.h:2295
Namespace for the Cantera kernel.
Definition: application.cpp:29
vector_fp m_CphiMX_ij
Array of 2D data used in the Pitzer/HMW formulation.
Definition: HMWSoln.h:2102
int m_formPitzerTemp
This is the form of the temperature dependence of Pitzer parameterization used in the model...
Definition: HMWSoln.h:1860
void calc_lambdas(double is) const
Calculate the lambda interactions.
Definition: HMWSoln.cpp:3976
vector_fp m_Beta1MX_ij_L
Derivative of Beta1_ij[i][j] wrt T. Vector index is counterIJ.
Definition: HMWSoln.h:2040
double ADebye_J(double temperature=-1.0, double pressure=-1.0) const
Return Pitzer&#39;s definition of A_J.
Definition: HMWSoln.cpp:806
vector_fp m_Theta_ij_LL
Derivative of Theta_ij[i][j] wrt TT. Vector index is counterIJ.
Definition: HMWSoln.h:2138
Array2D m_Theta_ij_coeff
Array of coefficients for Theta_ij[i][j] in the Pitzer/HMW formulation.
Definition: HMWSoln.h:2153
virtual doublereal satPressure(doublereal T)
Get the saturation pressure for a given temperature.
Definition: HMWSoln.cpp:686
Array2D m_Mu_nnn_coeff
Array of coefficients form_Mu_nnn term.
Definition: HMWSoln.h:2269
vector_fp m_Mu_nnn_LL
Mu coefficient 2nd temperature derivative for the self-ternary neutral coefficient.
Definition: HMWSoln.h:2256
void s_updatePitzer_lnMolalityActCoeff() const
Calculate the Pitzer portion of the activity coefficients.
Definition: HMWSoln.cpp:1457
vector_fp m_Aionic
a_k = Size of the ionic species in the DH formulation. units = meters
Definition: HMWSoln.h:1905
vector_fp m_BphiMX_IJ_P
Derivative of BphiMX_IJ wrt P. Vector index is counterIJ.
Definition: HMWSoln.h:2389
virtual double A_Debye_TP(double temperature=-1.0, double pressure=-1.0) const
Value of the Debye Huckel constant as a function of temperature and pressure.
Definition: HMWSoln.cpp:696
Array2D m_Beta1MX_ij_coeff
Array of coefficients for Beta1, a variable in Pitzer&#39;s papers.
Definition: HMWSoln.h:2054
vector_fp m_PhiPhi_IJ_L
Derivative of m_PhiPhi_IJ wrt T. Vector index is counterIJ.
Definition: HMWSoln.h:2413
double ADebye_L(double temperature=-1.0, double pressure=-1.0) const
Return Pitzer&#39;s definition of A_L.
Definition: HMWSoln.cpp:784
vector_fp m_Beta0MX_ij_P
Derivative of Beta0_ij[i][j] wrt P. Vector index is counterIJ.
Definition: HMWSoln.h:2022
vector_fp m_BphiMX_IJ_LL
Derivative of BphiMX_IJ wrt TT. Vector index is counterIJ.
Definition: HMWSoln.h:2386
virtual doublereal gibbs_mole() const
Molar Gibbs function. Units: J/kmol.
Definition: HMWSoln.cpp:459