Cantera  2.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  * Copyright (2006) Sandia Corporation. Under the terms of
13  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
14  * U.S. Government retains certain rights in this software.
15  */
16 #ifndef CT_HMWSOLN_H
17 #define CT_HMWSOLN_H
18 
19 #include "MolalityVPSSTP.h"
20 #include "electrolytes.h"
21 
22 namespace Cantera
23 {
24 
25 
26 /**
27  * Major Parameters:
28  * The form of the Pitzer expression refers to the
29  * form of the Gibbs free energy expression. The temperature
30  * dependence of the Pitzer coefficients are handled by
31  * another parameter.
32  *
33  * m_formPitzer = Form of the Pitzer expression
34  *
35  * PITZERFORM_BASE = 0
36  *
37  * Only one form is supported atm. This parameter is included for
38  * future expansion.
39  *
40  */
41 #define PITZERFORM_BASE 0
42 
43 
44 /*!
45  * @name Temperature Dependence of the Pitzer Coefficients
46  *
47  * Note, the temperature dependence of the
48  * Gibbs free energy also depends on the temperature dependence
49  * of the standard state and the temperature dependence of the
50  * Debye-Huckel constant, which includes the dielectric constant
51  * and the density. Therefore, this expression defines only part
52  * of the temperature dependence for the mixture thermodynamic
53  * functions.
54  *
55  * PITZER_TEMP_CONSTANT
56  * All coefficients are considered constant wrt temperature
57  * PITZER_TEMP_LINEAR
58  * All coefficients are assumed to have a linear dependence
59  * wrt to temperature.
60  * PITZER_TEMP_COMPLEX1
61  * All coefficients are assumed to have a complex functional
62  * based dependence wrt temperature; See:
63  * (Silvester, Pitzer, J. Phys. Chem. 81, 19 1822 (1977)).
64  *
65  * beta0 = q0 + q3(1/T - 1/Tr) + q4(ln(T/Tr)) +
66  * q1(T - Tr) + q2(T**2 - Tr**2)
67  *
68  */
69 //@{
70 #define PITZER_TEMP_CONSTANT 0
71 #define PITZER_TEMP_LINEAR 1
72 #define PITZER_TEMP_COMPLEX1 2
73 //@}
74 
75 /*
76  * @name ways to calculate the value of A_Debye
77  *
78  * These defines determine the way A_Debye is calculated
79  */
80 //@{
81 #define A_DEBYE_CONST 0
82 #define A_DEBYE_WATER 1
83 //@}
84 
85 class WaterProps;
86 class PDSS_Water;
87 
88 /**
89  * Class %HMWSoln represents a dilute or concentrated liquid electrolyte
90  * phase which obeys the Pitzer formulation for nonideality.
91  *
92  * As a prerequisite to the specification of thermodynamic quantities,
93  * The concentrations of the ionic species are assumed to obey the
94  * electroneutrality condition.
95  *
96  * <HR>
97  * <H2> Specification of Species Standard %State Properties </H2>
98  * <HR>
99  *
100  * The solvent is assumed to be liquid water. A real model for liquid
101  * water (IAPWS 1995 formulation) is used as its standard state.
102  * All standard state properties for the solvent are based on
103  * this real model for water, and involve function calls
104  * to the object that handles the real water model, #Cantera::WaterPropsIAPWS.
105  *
106  * The standard states for solutes are on the unit molality basis.
107  * Therefore, in the documentation below, the normal \f$ o \f$
108  * superscript is replaced with
109  * the \f$ \triangle \f$ symbol. The reference state symbol is now
110  * \f$ \triangle, ref \f$.
111  *
112  *
113  * It is assumed that the reference state thermodynamics may be
114  * obtained by a pointer to a populated species thermodynamic property
115  * manager class (see ThermoPhase::m_spthermo). How to relate pressure
116  * changes to the reference state thermodynamics is resolved at this level.
117  *
118  * For solutes that rely on ThermoPhase::m_spthermo, are assumed to
119  * have an incompressible standard state mechanical property.
120  * In other words, the molar volumes are independent of temperature
121  * and pressure.
122  *
123  * For these incompressible,
124  * standard states, the molar internal energy is
125  * independent of pressure. Since the thermodynamic properties
126  * are specified by giving the standard-state enthalpy, the
127  * term \f$ P_0 \hat v\f$ is subtracted from the specified molar
128  * enthalpy to compute the molar internal energy. The entropy is
129  * assumed to be independent of the pressure.
130  *
131  * The enthalpy function is given by the following relation.
132  *
133  * \f[
134  * \raggedright h^\triangle_k(T,P) = h^{\triangle,ref}_k(T)
135  * + \tilde{v}_k \left( P - P_{ref} \right)
136  * \f]
137  *
138  * For an incompressible,
139  * stoichiometric substance, the molar internal energy is
140  * independent of pressure. Since the thermodynamic properties
141  * are specified by giving the standard-state enthalpy, the
142  * term \f$ P_{ref} \tilde v\f$ is subtracted from the specified reference molar
143  * enthalpy to compute the molar internal energy.
144  *
145  * \f[
146  * u^\triangle_k(T,P) = h^{\triangle,ref}_k(T) - P_{ref} \tilde{v}_k
147  * \f]
148  *
149  *
150  * The solute standard state heat capacity and entropy are independent
151  * of pressure. The solute standard state gibbs free energy is obtained
152  * from the enthalpy and entropy functions.
153  *
154  * The vector Phase::m_speciesSize[] is used to hold the
155  * base values of species sizes. These are defined as the
156  * molar volumes of species at infinite dilution at 300 K and 1 atm
157  * of water. m_speciesSize are calculated during the initialization of the
158  * %HMWSoln object and are then not touched.
159  *
160  * The current model assumes that an incompressible molar volume for
161  * all solutes. The molar volume for the water solvent, however,
162  * is obtained from a pure water equation of state, waterSS.
163  * Therefore, the water standard state varies with both T and P.
164  * It is an error to request standard state water properties at a T and P
165  * where the water phase is not a stable phase, i.e., beyond its
166  * spinodal curve.
167  *
168  * <HR>
169  * <H2> Specification of Solution Thermodynamic Properties </H2>
170  * <HR>
171  *
172  * Chemical potentials
173  * of the solutes, \f$ \mu_k \f$, and the solvent, \f$ \mu_o \f$, which are based
174  * on the molality form, have the following general format:
175  *
176  * \f[
177  * \mu_k = \mu^{\triangle}_k(T,P) + R T ln(\gamma_k^{\triangle} \frac{m_k}{m^\triangle})
178  * \f]
179  * \f[
180  * \mu_o = \mu^o_o(T,P) + RT ln(a_o)
181  * \f]
182  *
183  * where \f$ \gamma_k^{\triangle} \f$ is the molality based activity coefficient for species
184  * \f$k\f$.
185  *
186  * Individual activity coefficients of ions can not be independently measured. Instead,
187  * only binary pairs forming electroneutral solutions can be measured. This problem
188  * leads to a redundancy in the evaluation of species standard state properties.
189  * The redundancy issue is resolved by setting the standard state chemical potential
190  * enthalpy, entropy, and volume for the hydrogen ion, H+, to zero, for every temperature
191  * and pressure. After this convention is applied, all other standard state
192  * properties of ionic species contain meaningful information.
193  *
194  *
195  * <H3> Ionic Strength </H3>
196  *
197  * Most of the parameterizations within the model use the ionic strength
198  * as a key variable. The ionic strength, \f$ I\f$ is defined as follows
199  *
200  * \f[
201  * I = \frac{1}{2} \sum_k{m_k z_k^2}
202  * \f]
203  *
204  *
205  * \f$ m_k \f$ is the molality of the kth species. \f$ z_k \f$ is the charge
206  * of the kth species. Note, the ionic strength is a defined units quantity.
207  * The molality has defined units of gmol kg-1, and therefore the ionic
208  * strength has units of sqrt( gmol kg<SUP>-1</SUP>).
209  *
210  * In some instances, from some authors, a different
211  * formulation is used for the ionic strength in the equations below. The different
212  * formulation is due to the possibility of the existence of weak acids and how
213  * association wrt to the weak acid equilibrium relation affects the calculation
214  * of the activity coefficients via the assumed value of the ionic strength.
215  *
216  * If we are to assume that the association reaction doesn't have an effect
217  * on the ionic strength, then we will want to consider the associated weak
218  * acid as in effect being fully dissociated, when we calculate an effective
219  * value for the ionic strength. We will call this calculated value, the
220  * stoichiometric ionic strength, \f$ I_s \f$, putting a subscript s to denote
221  * it from the more straightforward calculation of \f$ I \f$.
222  *
223  * \f[
224  * I_s = \frac{1}{2} \sum_k{m_k^s z_k^2}
225  * \f]
226  *
227  * Here, \f$ m_k^s \f$ is the value of the molalities calculated assuming that
228  * all weak acid-base pairs are in their fully dissociated states. This calculation may
229  * be simplified by considering that the weakly associated acid may be made up of two
230  * charged species, k1 and k2, each with their own charges, obeying the following relationship:
231  *
232  * \f[
233  * z_k = z_{k1} + z_{k2}
234  * \f]
235  * Then, we may only need to specify one charge value, say, \f$ z_{k1}\f$,
236  * the cation charge number,
237  * in order to get both numbers, since we have already specified \f$ z_k \f$
238  * in the definition of original species.
239  * Then, the stoichiometric ionic strength may be calculated via the following formula.
240  *
241  * \f[
242  * I_s = \frac{1}{2} \left(\sum_{k,ions}{m_k z_k^2}+
243  * \sum_{k,weak_assoc}(m_k z_{k1}^2 + m_k z_{k2}^2) \right)
244  * \f]
245  *
246  * The specification of which species are weakly associated acids is made in the input
247  * file via the
248  * <TT> stoichIsMods </TT> XML block, where the charge for k1 is also specified.
249  * An example is given below:
250  *
251  * @code
252  * <stoichIsMods>
253  * NaCl(aq):-1.0
254  * </stoichIsMods>
255  * @endcode
256  *
257  *
258  * Because we need the concept of a weakly associated acid in order to calculated
259  * \f$ I_s \f$ we need to
260  * catalog all species in the phase. This is done using the following categories:
261  *
262  * - <B>cEST_solvent</B> : Solvent species (neutral)
263  * - <B>cEST_chargedSpecies</B> Charged species (charged)
264  * - <B>cEST_weakAcidAssociated</B> Species which can break apart into charged species.
265  * It may or may not be charged. These may or
266  * may not be be included in the
267  * species solution vector.
268  * - <B>cEST_strongAcidAssociated</B> Species which always breaks apart into charged species.
269  * It may or may not be charged. Normally, these
270  * aren't included in the speciation vector.
271  * - <B>cEST_polarNeutral </B> Polar neutral species
272  * - <B>cEST_nonpolarNeutral</B> Non polar neutral species
273  *
274  * Polar and non-polar neutral species are differentiated, because some additions
275  * to the activity
276  * coefficient expressions distinguish between these two types of solutes.
277  * This is the so-called salt-out effect.
278  *
279  * The type of species is specified in the <TT>electrolyteSpeciesType</TT> XML block.
280  * Note, this is not
281  * considered a part of the specification of the standard state for the species,
282  * at this time. Therefore,
283  * this information is put under the <TT>activityCoefficient</TT> XML block. An example
284  * is given below
285  *
286  * @code
287  * <electrolyteSpeciesType>
288  * H2L(L):solvent
289  * H+:chargedSpecies
290  * NaOH(aq):weakAcidAssociated
291  * NaCl(aq):strongAcidAssociated
292  * NH3(aq):polarNeutral
293  * O2(aq):nonpolarNeutral
294  * </electrolyteSpeciesType>
295  * @endcode
296  *
297  *
298  * Much of the species electrolyte type information is inferred from other information in the
299  * input file. For example, as species which is charged is given the "chargedSpecies" default
300  * category. A neutral solute species is put into the "nonpolarNeutral" category by default.
301  *
302  *
303  * <H3> Specification of the Excess Gibbs Free Energy </H3>
304  *
305  * Pitzer's formulation may best be represented as a specification of the excess gibbs
306  * free energy, \f$ G^{ex} \f$, defined as the deviation of the total gibbs free energy from
307  * that of an ideal molal solution.
308  * \f[
309  * G = G^{id} + G^{ex}
310  * \f]
311  *
312  * The ideal molal solution contribution, not equal to an ideal solution contribution
313  * and in fact containing a singularity at the zero solvent mole fraction limit, is
314  * given below.
315  * \f[
316  * G^{id} = n_o \mu^o_o + \sum_{k\ne o} n_k \mu_k^{\triangle}
317  * + \tilde{M}_o n_o ( RT (\sum{m_i(\ln(m_i)-1)}))
318  * \f]
319  *
320  * From the excess Gibbs free energy formulation, the activity coefficient expression
321  * and the osmotic coefficient expression for the solvent may be defined, by
322  * taking the appropriate derivatives. Using this approach guarantees that the
323  * entire system will obey the Gibbs-Duhem relations.
324  *
325  * Pitzer employs the following general expression for the excess Gibbs free energy
326  *
327  * \f[
328  * \begin{array}{cclc}
329  * \frac{G^{ex}}{\tilde{M}_o n_o RT} &= &
330  * \left( \frac{4A_{Debye}I}{3b} \right) \ln(1 + b \sqrt{I})
331  * + 2 \sum_c \sum_a m_c m_a B_{ca}
332  * + \sum_c \sum_a m_c m_a Z C_{ca}
333  * \\&&
334  * + \sum_{c < c'} \sum m_c m_{c'} \left[ 2 \Phi_{c{c'}} + \sum_a m_a \Psi_{c{c'}a} \right]
335  * + \sum_{a < a'} \sum m_a m_{a'} \left[ 2 \Phi_{a{a'}} + \sum_c m_c \Psi_{a{a'}c} \right]
336  * \\&&
337  * + 2 \sum_n \sum_c m_n m_c \lambda_{nc} + 2 \sum_n \sum_a m_n m_a \lambda_{na}
338  * + 2 \sum_{n < n'} \sum m_n m_{n'} \lambda_{n{n'}}
339  * + \sum_n m^2_n \lambda_{nn}
340  * \end{array}
341  * \f]
342  *
343  * <I>a</I> is a subscript over all anions, <I>c</I> is a subscript extending over all
344  * cations, and <I>i</I> is a subscript that extends over all anions and cations.
345  * <I>n</I> is a subscript that extends only over neutral solute molecules.
346  * The second line contains cross terms where cations affect
347  * cations and/or cation/anion pairs,
348  * and anions affect anions or cation/anion pairs. Note part of the coefficients,
349  * \f$ \Phi_{c{c'}} \f$ and \f$ \Phi_{a{a'}} \f$ stem from the theory
350  * of unsymmetrical mixing of electrolytes with different charges. This
351  * theory depends on the total ionic strength of the solution, and therefore,
352  * \f$ \Phi_{c{c'}} \f$ and \f$ \Phi_{a{a'}} \f$ will depend on <I>I</I>, the
353  * ionic strength. \f$ B_{ca}\f$ is a strong function of the
354  * total ionic strength, <I>I</I>,
355  * of the electrolyte. The rest of the coefficients are assumed to be independent of the
356  * molalities or ionic strengths. However, all coefficients are potentially functions
357  * of the temperature and pressure of the solution.
358  *
359  * <I>A</I> is the Debye-Huckel constant. Its specification is described in its own
360  * section below.
361  *
362  * \f$ I\f$ is the ionic strength of the solution, and is given by:
363  *
364  * \f[
365  * I = \frac{1}{2} \sum_k{m_k z_k^2}
366  * \f]
367  *
368  * In contrast to several other Debye-Huckel implementations (see \ref DebyeHuckel), the
369  * parameter \f$ b\f$ in the above equation is a constant that
370  * does not vary with respect to ion identity. This is an important simplification
371  * as it avoids troubles with satisfaction of the Gibbs-Duhem analysis.
372  *
373  * The function \f$ Z \f$ is given by
374  *
375  * \f[
376  * Z = \sum_i m_i \left| z_i \right|
377  * \f]
378  *
379  * The value of \f$ B_{ca}\f$ is given by the following function
380  *
381  * \f[
382  * B_{ca} = \beta^{(0)}_{ca} + \beta^{(1)}_{ca} g(\alpha^{(1)}_{ca} \sqrt{I})
383  * + \beta^{(2)}_{ca} g(\alpha^{(2)}_{ca} \sqrt{I})
384  * \f]
385  *
386  * where
387  *
388  * \f[
389  * g(x) = 2 \frac{(1 - (1 + x)\exp[-x])}{x^2}
390  * \f]
391  *
392  * The formulation for \f$ B_{ca}\f$ combined with the formulation of the
393  * Debye-Huckel term in the eqn. for the excess Gibbs free energy stems
394  * essentially from an empirical fit to the ionic strength dependent data
395  * based over a wide sampling of binary electrolyte systems. \f$ C_{ca} \f$,
396  * \f$ \lambda_{nc} \f$, \f$ \lambda_{na} \f$, \f$ \lambda_{nn} \f$,
397  * \f$ \Psi_{c{c'}a} \f$, \f$ \Psi_{a{a'}c} \f$ are experimentally derived
398  * coefficients that may have pressure and/or temperature dependencies.
399  * The \f$ \Phi_{c{c'}} \f$ and \f$ \Phi_{a{a'}} \f$ formulations are
400  * slightly more complicated. \f$ b \f$ is a universal
401  * constant defined to be equal to \f$ 1.2\ kg^{1/2}\ gmol^{-1/2} \f$. The exponential
402  * coefficient \f$ \alpha^{(1)}_{ca} \f$ is usually
403  * fixed at \f$ \alpha^{(1)}_{ca} = 2.0\ kg^{1/2} gmol^{-1/2}\f$
404  * except for 2-2 electrolytes, while other parameters were fit to experimental
405  * data. For 2-2 electrolytes, \f$ \alpha^{(1)}_{ca} = 1.4\ kg^{1/2}\ gmol^{-1/2}\f$
406  * is used in combination with either \f$ \alpha^{(2)}_{ca} = 12\ kg^{1/2}\ gmol^{-1/2}\f$
407  * or \f$ \alpha^{(2)}_{ca} = k A_\psi \f$, where <I>k</I> is a constant. For electrolytes other
408  * than 2-2 electrolytes the \f$ \beta^{(2)}_{ca} g(\alpha^{(2)}_{ca} \sqrt{I}) \f$ term
409  * is not used in the fitting procedure; it is only used for divalent metal
410  * solfates and other high-valence electrolytes which exhibit significant
411  * association at low ionic strengths.
412  *
413  * The \f$ \beta^{(0)}_{ca} \f$, \f$ \beta^{(1)}_{ca}\f$, \f$ \beta^{(2)}_{ca} \f$,
414  * and \f$ C_{ca} \f$ binary coefficients are referred to as ion-interaction or
415  * Pitzer parameters. These Pitzer parameters may vary with temperature and pressure
416  * but they do not depend on the ionic strength. Their values and temperature
417  * derivatives of their values have been tabulated for a range of electrolytes
418  *
419  * The \f$ \Phi_{c{c'}} \f$ and \f$ \Phi_{a{a'}} \f$ contributions, which
420  * capture cation-cation and anion-anion interactions, also have an
421  * ionic strength dependence.
422  *
423  * Ternary contributions \f$ \Psi_{c{c'}a} \f$ and \f$ \Psi_{a{a'}c} \f$
424  * have been measured also for some systems. The success of the Pitzer
425  * method lies in its ability to model nonlinear activity coefficients
426  * of complex multicomponent systems with just binary and minor
427  * ternary contributions, which can be independently measured in
428  * binary or ternary subsystems.
429  *
430  *
431  * <H3> Multicomponent Activity Coefficients for Solutes </H3>
432  *
433  * The formulas for activity coefficients of solutes may be obtained by taking the
434  * following derivative of the excess Gibbs Free Energy formulation described above:
435  *
436  * \f[
437  * \ln(\gamma_k^\triangle) = \frac{d\left( \frac{G^{ex}}{M_o n_o RT} \right)}{d(m_k)}\Bigg|_{n_i}
438  * \f]
439  *
440  * In the formulas below the following conventions are used. The subscript <I>M</I> refers
441  * to a particular cation. The subscript X refers to a particular anion, whose
442  * activity is being currently evaluated. the subscript <I>a</I> refers to a summation
443  * over all anions in the solution, while the subscript <I>c</I> refers to a summation
444  * over all cations in the solutions.
445  *
446  * The activity coefficient for a particular cation <I>M</I> is given by
447  *
448  * \f[
449  * \ln(\gamma_M^\triangle) = -z_M^2(F) + \sum_a m_a \left( 2 B_{Ma} + Z C_{Ma} \right)
450  * + z_M \left( \sum_a \sum_c m_a m_c C_{ca} \right)
451  * + \sum_c m_c \left[ 2 \Phi_{Mc} + \sum_a m_a \Psi_{Mca} \right]
452  * + \sum_{a < a'} \sum m_a m_{a'} \Psi_{Ma{a'}}
453  * + 2 \sum_n m_n \lambda_{nM}
454  * \f]
455  *
456  * The activity coefficient for a particular anion <I>X</I> is given by
457  *
458  * \f[
459  * \ln(\gamma_X^\triangle) = -z_X^2(F) + \sum_a m_c \left( 2 B_{cX} + Z C_{cX} \right)
460  * + \left|z_X \right| \left( \sum_a \sum_c m_a m_c C_{ca} \right)
461  * + \sum_a m_a \left[ 2 \Phi_{Xa} + \sum_c m_c \Psi_{cXa} \right]
462  * + \sum_{c < c'} \sum m_c m_{c'} \Psi_{c{c'}X}
463  * + 2 \sum_n m_n \lambda_{nM}
464  * \f]
465  * where the function \f$ F \f$ is given by
466  *
467  * \f[
468  * F = - A_{\phi} \left[ \frac{\sqrt{I}}{1 + b \sqrt{I}}
469  * + \frac{2}{b} \ln{\left(1 + b\sqrt{I}\right)} \right]
470  * + \sum_a \sum_c m_a m_c B'_{ca}
471  * + \sum_{c < c'} \sum m_c m_{c'} \Phi'_{c{c'}}
472  * + \sum_{a < a'} \sum m_a m_{a'} \Phi'_{a{a'}}
473  * \f]
474  *
475  * We have employed the definition of \f$ A_{\phi} \f$, also used by Pitzer
476  * which is equal to
477  *
478  * \f[
479  * A_{\phi} = \frac{A_{Debye}}{3}
480  * \f]
481  *
482  * In the above formulas, \f$ \Phi'_{c{c'}} \f$ and \f$ \Phi'_{a{a'}} \f$ are the
483  * ionic strength derivatives of \f$ \Phi_{c{c'}} \f$ and \f$ \Phi_{a{a'}} \f$,
484  * respectively.
485  *
486  * The function \f$ B'_{MX} \f$ is defined as:
487  *
488  * \f[
489  * B'_{MX} = \left( \frac{\beta^{(1)}_{MX} h(\alpha^{(1)}_{MX} \sqrt{I})}{I} \right)
490  * \left( \frac{\beta^{(2)}_{MX} h(\alpha^{(2)}_{MX} \sqrt{I})}{I} \right)
491  * \f]
492  *
493  * where \f$ h(x) \f$ is defined as
494  *
495  * \f[
496  * h(x) = g'(x) \frac{x}{2} =
497  * \frac{2\left(1 - \left(1 + x + \frac{x^2}{2} \right)\exp(-x) \right)}{x^2}
498  * \f]
499  *
500  * The activity coefficient for neutral species <I>N</I> is given by
501  *
502  * \f[
503  * \ln(\gamma_N^\triangle) = 2 \left( \sum_i m_i \lambda_{iN}\right)
504  * \f]
505  *
506  *
507  * <H3> Activity of the Water Solvent </H3>
508  *
509  * The activity for the solvent water,\f$ a_o \f$, is not independent and must be
510  * determined either from the Gibbs-Duhem relation or from taking the appropriate derivative
511  * of the same excess Gibbs free energy function as was used to formulate
512  * the solvent activity coefficients. Pitzer's description follows the later approach to
513  * derive a formula for the osmotic coefficient, \f$ \phi \f$.
514  *
515  * \f[
516  * \phi - 1 = - \left( \frac{d\left(\frac{G^{ex}}{RT} \right)}{d(\tilde{M}_o n_o)} \right)
517  * \frac{1}{\sum_{i \ne 0} m_i}
518  * \f]
519  *
520  * The osmotic coefficient may be related to the water activity by the following relation:
521  *
522  * \f[
523  * \phi = - \frac{1}{\tilde{M}_o \sum_{i \neq o} m_i} \ln(a_o)
524  * = - \frac{n_o}{\sum_{i \neq o}n_i} \ln(a_o)
525  * \f]
526  *
527  *
528  * The result is the following
529  *
530  * \f[
531  * \begin{array}{ccclc}
532  * \phi - 1 &= &
533  * \frac{2}{\sum_{i \ne 0} m_i}
534  * \bigg[ &
535  * - A_{\phi} \frac{I^{3/2}}{1 + b \sqrt{I}}
536  * + \sum_c \sum_a m_c m_a \left( B^{\phi}_{ca} + Z C_{ca}\right)
537  * \\&&&
538  * + \sum_{c < c'} \sum m_c m_{c'} \left[ \Phi^{\phi}_{c{c'}} + \sum_a m_a \Psi_{c{c'}a} \right]
539  * + \sum_{a < a'} \sum m_a m_{a'} \left[ \Phi^{\phi}_{a{a'}} + \sum_c m_c \Psi_{a{a'}c} \right]
540  * \\&&&
541  * + \sum_n \sum_c m_n m_c \lambda_{nc} + \sum_n \sum_a m_n m_a \lambda_{na}
542  * + \sum_{n < n'} \sum m_n m_{n'} \lambda_{n{n'}}
543  * + \frac{1}{2} \left( \sum_n m^2_n \lambda_{nn}\right)
544  * \bigg]
545  * \end{array}
546  * \f]
547  *
548  * It can be shown that the expression
549  *
550  *
551  * \f[
552  * B^{\phi}_{ca} = \beta^{(0)}_{ca} + \beta^{(1)}_{ca} \exp{(- \alpha^{(1)}_{ca} \sqrt{I})}
553  * + \beta^{(2)}_{ca} \exp{(- \alpha^{(2)}_{ca} \sqrt{I} )}
554  * \f]
555  *
556  * is consistent with the expression \f$ B_{ca} \f$ in the \f$ G^{ex} \f$ expression
557  * after carrying out the derivative wrt \f$ m_M \f$.
558  *
559  * Also taking into account that \f$ {\Phi}_{c{c'}} \f$ and
560  * \f$ {\Phi}_{a{a'}} \f$ has an ionic strength dependence.
561  *
562  * \f[
563  * \Phi^{\phi}_{c{c'}} = {\Phi}_{c{c'}} + I \frac{d{\Phi}_{c{c'}}}{dI}
564  * \f]
565  *
566  * \f[
567  * \Phi^{\phi}_{a{a'}} = \Phi_{a{a'}} + I \frac{d\Phi_{a{a'}}}{dI}
568  * \f]
569  *
570  *
571  * <H3> Temperature and Pressure Dependence of the Pitzer Parameters </H3>
572  *
573  * In general most of the coefficients introduced in the previous section may
574  * have a temperature and pressure dependence. The temperature and pressure
575  * dependence of these coefficients strongly influence the value of the
576  * excess Enthalpy and excess Volumes of Pitzer solutions. Therefore, these
577  * are readily measurable quantities.
578  * HMWSoln provides several
579  * different methods for putting these dependencies into the coefficients.
580  * HMWSoln has an implementation described by Silverter and Pitzer (1977),
581  * which was used to fit experimental data for NaCl over an extensive range,
582  * below the critical temperature of water.
583  * They found a temperature functional form for fitting the 3 following
584  * coefficients that describe the Pitzer parameterization for a single salt
585  * to be adequate to describe how the excess gibbs free energy values for
586  * the binary salt changes with respect to temperature.
587  * The following functional form
588  * was used to fit the temperature dependence of the Pitzer Coefficients
589  * for each cation - anion pair, M X.
590  *
591  * \f[
592  * \beta^{(0)}_{MX} = q^{b0}_0
593  * + q^{b0}_1 \left( T - T_r \right)
594  * + q^{b0}_2 \left( T^2 - T_r^2 \right)
595  * + q^{b0}_3 \left( \frac{1}{T} - \frac{1}{T_r}\right)
596  * + q^{b0}_4 \ln \left( \frac{T}{T_r} \right)
597  * \f]
598  * \f[
599  * \beta^{(1)}_{MX} = q^{b1}_0 + q^{b1}_1 \left( T - T_r \right)
600  * + q^{b1}_{2} \left( T^2 - T_r^2 \right)
601  * \f]
602  * \f[
603  * C^{\phi}_{MX} = q^{Cphi}_0
604  * + q^{Cphi}_1 \left( T - T_r \right)
605  * + q^{Cphi}_2 \left( T^2 - T_r^2 \right)
606  * + q^{Cphi}_3 \left( \frac{1}{T} - \frac{1}{T_r}\right)
607  * + q^{Cphi}_4 \ln \left( \frac{T}{T_r} \right)
608  * \f]
609  *
610  * where
611  *
612  * \f[
613  * C^{\phi}_{MX} = 2 {\left| z_M z_X \right|}^{1/2} C_{MX}
614  * \f]
615  *
616  * In later papers, Pitzer has added additional temperature dependencies
617  * to all of the other remaining second and third order virial coefficients.
618  * Some of these dependencies are justified and motivated by theory.
619  * Therefore,
620  * a formalism wherein all of the coefficients in the base theory have
621  * temperature dependencies associated with them has been implemented
622  * within the %HMWSoln object. Much of the formalism, however,
623  * has been unexercised.
624  *
625  * In the %HMWSoln object, the temperature dependence of the Pitzer
626  * parameters are specified in the following way.
627  *
628  * - PIZTER_TEMP_CONSTANT - string name "CONSTANT"
629  * - Assumes that all coefficients are independent of temperature
630  * and pressure
631  * - PIZTER_TEMP_COMPLEX1 - string name "COMPLEX" or "COMPLEX1"
632  * - Uses the full temperature dependence for the
633  * \f$\beta^{(0)}_{MX} \f$ (5 coeffs),
634  * the \f$\beta^{(1)}_{MX} \f$ (3 coeffs),
635  * and \f$ C^{\phi}_{MX} \f$ (5 coeffs) parameters described above.
636  * - PITZER_TEMP_LINEAR - string name "LINEAR"
637  * - Uses just the temperature dependence for the
638  * \f$\beta^{(0)}_{MX} \f$, the \f$\beta^{(1)}_{MX} \f$,
639  * and \f$ C^{\phi}_{MX} \f$ coefficients described above.
640  * There are 2 coefficients for each term.
641  *
642  * The temperature dependence is specified in an attributes field
643  * in the <TT> activityCoefficients </TT> XML block,
644  * called <TT> TempModel </TT>. Permissible values for that
645  * attribute are <TT> CONSTANT, COMPLEX1</TT>, and <TT> LINEAR.</TT>
646  *
647  * The specification of the binary interaction between a cation and
648  * an anion is given by the coefficients, \f$ B_{MX}\f$ and
649  * \f$ C_{MX}\f$
650  * The specification of \f$ B_{MX}\f$ is a function of
651  * \f$\beta^{(0)}_{MX} \f$, \f$\beta^{(1)}_{MX} \f$,
652  * \f$\beta^{(2)}_{MX} \f$, \f$\alpha^{(1)}_{MX} \f$, and
653  * \f$\alpha^{(2)}_{MX} \f$.
654  * \f$ C_{MX}\f$ is calculated from \f$C^{\phi}_{MX} \f$
655  * from the formula above.
656  * All of the underlying coefficients are specified in the
657  * XML element block <TT> binarySaltParameters </TT>, which
658  * has the attribute <TT> cation </TT> and <TT> anion </TT>
659  * to identify the interaction. XML elements named
660  * <TT> beta0, beta1, beta2, Cphi, Alpha1, Alpha2 </TT>
661  * within each <TT> binarySaltParameters </TT> block
662  * specify the parameters. Within each of these blocks
663  * multiple parameters describing temperature or pressure
664  * dependence are serially listed in the order that they
665  * appear in the equation in this document. An example of
666  * the <TT> beta0 </TT> block that fits the <TT> COMPLEX1 </TT> temperature
667  * dependence given above is
668  *
669  * @code
670  <binarySaltParameters cation="Na+" anion="OH-">
671  <beta0> q0, q1, q2, q3, q4 </beta0>
672  </binarySaltParameters>
673  @endcode
674  *
675  * The parameters for \f$ \beta^{(0)}\f$ fit the following equation:
676  *
677  * \f[
678  * \beta^{(0)} = q_0^{{\beta}0} + q_1^{{\beta}0} \left( T - T_r \right)
679  * + q_2^{{\beta}0} \left( T^2 - T_r^2 \right)
680  * + q_3^{{\beta}0} \left( \frac{1}{T} - \frac{1}{T_r} \right)
681  * + q_4^{{\beta}0} \ln \left( \frac{T}{T_r} \right)
682  * \f]
683  *
684  * This same COMPLEX1 </TT> temperature
685  * dependence given above is used for the following parameters:
686  * \f$ \beta^{(0)}_{MX} \f$, \f$ \beta^{(1)}_{MX} \f$,
687  * \f$ \beta^{(2)}_{MX} \f$, \f$ \Theta_{cc'} \f$, \f$\Theta_{aa'} \f$,
688  * \f$ \Psi_{c{c'}a} \f$ and \f$ \Psi_{ca{a'}} \f$.
689  *
690  *
691  * <H3> Like-Charged Binary Ion Parameters and the Mixing Parameters </H3>
692  *
693  * The previous section contained the functions, \f$ \Phi_{c{c'}} \f$,
694  * \f$ \Phi_{a{a'}} \f$ and their derivatives wrt the
695  * ionic strength, \f$ \Phi'_{c{c'}} \f$ and \f$ \Phi'_{a{a'}} \f$.
696  * Part of these terms come from theory.
697  *
698  * Since like charged ions repel each other and are generally
699  * not near each other, the virial coefficients for same-charged ions
700  * are small. However, Pitzer doesn't ignore these in his
701  * formulation. Relatively larger and longer range terms between
702  * like-charged ions exist however, which appear only for
703  * unsymmetrical mixing of same-sign charged ions with different
704  * charges. \f$ \Phi_{ij} \f$, where \f$ ij \f$ is either \f$ a{a'} \f$
705  * or \f$ c{c'} \f$ is given by
706  *
707  *
708  *
709  * \f[
710  * {\Phi}_{ij} = \Theta_{ij} + \,^E \Theta_{ij}(I)
711  * \f]
712  *
713  *
714  * \f$ \Theta_{ij} \f$ is the small virial coefficient expansion term.
715  * Dependent in general on temperature and pressure, its ionic
716  * strength dependence is ignored in Pitzer's approach.
717  * \f$ \,^E\Theta_{ij}(I) \f$ accounts for the electrostatic
718  * unsymmetrical mixing effects and is dependent only on the
719  * charges of the ions i, j, the total ionic strength and on
720  * the dielectric constant and density of the solvent.
721  * This seems to be a relatively well-documented part of the theory.
722  * They theory below comes from Pitzer summation (Pitzer) in the
723  * appendix. It's also mentioned in Bethke's book (Bethke), and
724  * the equations are summarized in Harvie & Weare (1980).
725  * Within the code, \f$ \,^E\Theta_{ij}(I) \f$ is evaluated according
726  * to the algorithm described in Appendix B [Pitzer] as
727  *
728  * \f[
729  * \,^E\Theta_{ij}(I) = \left( \frac{z_i z_j}{4I} \right)
730  * \left( J(x_{ij}) - \frac{1}{2} J(x_{ii})
731  * - \frac{1}{2} J(x_{jj}) \right)
732  * \f]
733  *
734  * where \f$ x_{ij} = 6 z_i z_j A_{\phi} \sqrt{I} \f$ and
735  *
736  * \f[
737  * J(x) = \frac{1}{x} \int_0^{\infty}{\left( 1 + q +
738  * \frac{1}{2} q^2 - e^q \right) y^2 dy}
739  * \f]
740  *
741  * and \f$ q = - (\frac{x}{y}) e^{-y} \f$. \f$ J(x) \f$ is evaluated by
742  * numerical integration.
743  *
744  * The \f$ \Theta_{ij} \f$ term is a constant that is specified
745  * by the XML element <TT> thetaCation </TT> and
746  * <TT> thetaAnion </TT>, which
747  * has the attribute <TT> cation1 </TT>, <TT> cation2 </TT> and
748  * <TT> anion1 </TT>, <TT> anion2 </TT> respectively
749  * to identify the interaction. No temperature or
750  * pressure dependence of this parameter is currently allowed.
751  * An example of the block is presented below.
752  *
753  * @code
754  <thetaCation cation1="Na+" cation2="H+">
755  <Theta> 0.036 </Theta>
756  </thetaCation>
757  @endcode
758  *
759  *
760  * <H3> Ternary Pitzer Parameters </H3>
761  *
762  * The \f$ \Psi_{c{c'}a} \f$ and \f$ \Psi_{ca{a'}} \f$ terms
763  * represent ternary interactions between two cations and
764  * an anion and two anions and a cation, respectively.
765  * In Pitzer's implementation these terms are usually small
766  * in absolute size. Currently these parameters do not have
767  * any dependence on temperature, pressure, or ionic strength.
768  *
769  * Their values are input using the XML element
770  * <TT> psiCommonCation </TT> and <TT> psiCommonAnion </TT>.
771  * The species id's are specified in attribute fields in
772  * the XML element. The fields <TT>cation</TT>,
773  * <TT> anion1</TT>, and <TT> anion2</TT>
774  * are used for <TT>psiCommonCation</TT>. The fields <TT> anion</TT>,
775  * <TT>cation1</TT> and <TT>cation2</TT> are used for
776  * <TT> psiCommonAnion</TT>. An example block is given below.
777  * The <TT> Theta </TT> field below is a duplicate of the
778  * <TT> thetaAnion </TT> field mentioned above. The two fields
779  * are input into the same block for convenience, and because
780  * their data are highly correlated, in practice.
781  * It is an error for the
782  * two blocks to specify different information about
783  * thetaAnion (or thetaCation) in different blocks. It's
784  * ok to specify duplicate but consistent information
785  * in multiple blocks.
786  *
787  * @code
788  <psiCommonCation cation="Na+" anion1="Cl-" anion2="OH-">
789  <Theta> -0.05 </Theta>
790  <Psi> -0.006 </Psi>
791  </psiCommonCation>
792  @endcode
793  *
794  * <H3> Treatment of Neutral Species </H3>
795  *
796  * Binary virial-coefficient-like interactions between two neutral
797  * species may be specified in the \f$ \lambda_{mn} \f$ terms
798  * that appear in the formulas above.
799  * Currently these interactions are independent of temperature,
800  * pressure, and ionic strength. Also, currently, the neutrality
801  * of the species are not checked. Therefore, this interaction
802  * may involve charged species in the solution as well.
803  * The identity of the species is specified by the
804  * <TT>species1</TT> and <TT>species2</TT> attributes to the XML
805  * <TT>lambdaNeutral</TT> node. These terms are symmetrical;
806  * <TT>species1</TT> and <TT>species2</TT> may be reversed and
807  * the term will be the same. An example is given below.
808  *
809  * @code
810  <lambdaNeutral species1="CO2" species2="CH4">
811  <lambda> 0.05 </lambda>
812  </lambdaNeutral>
813  @endcode
814  *
815  * <H3> Example of the Specification of Parameters for the Activity
816  * Coefficients </H3>
817  *
818  * An example is given below.
819  *
820  * An example <TT> activityCoefficients </TT> XML block for this
821  * formulation is supplied below
822  *
823  * @verbatim
824  <activityCoefficients model="Pitzer" TempModel="complex1">
825  <!-- Pitzer Coefficients
826  These coefficients are from Pitzer's main
827  paper, in his book.
828  -->
829  <A_Debye model="water" />
830  <ionicRadius default="3.042843" units="Angstroms">
831  </ionicRadius>
832  <binarySaltParameters cation="Na+" anion="Cl-">
833  <beta0> 0.0765, 0.008946, -3.3158E-6,
834  -777.03, -4.4706
835  </beta0>
836  <beta1> 0.2664, 6.1608E-5, 1.0715E-6, 0.0, 0.0 </beta1>
837  <beta2> 0.0, 0.0, 0.0, 0.0, 0.0 </beta2>
838  <Cphi> 0.00127, -4.655E-5, 0.0,
839  33.317, 0.09421
840  </Cphi>
841  <Alpha1> 2.0 </Alpha1>
842  </binarySaltParameters>
843 
844  <binarySaltParameters cation="H+" anion="Cl-">
845  <beta0> 0.1775, 0.0, 0.0, 0.0, 0.0 </beta0>
846  <beta1> 0.2945, 0.0, 0.0, 0.0, 0.0 </beta1>
847  <beta2> 0.0, 0.0, 0.0, 0.0, 0.0 </beta2>
848  <Cphi> 0.0008, 0.0, 0.0, 0.0, 0.0 </Cphi>
849  <Alpha1> 2.0 </Alpha1>
850  </binarySaltParameters>
851 
852  <binarySaltParameters cation="Na+" anion="OH-">
853  <beta0> 0.0864, 0.0, 0.0, 0.0, 0.0 </beta0>
854  <beta1> 0.253, 0.0, 0.0 0.0, 0.0 </beta1>
855  <beta2> 0.0 0.0, 0.0, 0.0, 0.0 </beta2>
856  <Cphi> 0.0044, 0.0, 0.0, 0.0, 0.0 </Cphi>
857  <Alpha1> 2.0 </Alpha1>
858  </binarySaltParameters>
859 
860  <thetaAnion anion1="Cl-" anion2="OH-">
861  <Theta> -0.05, 0.0, 0.0, 0.0, 0.0 </Theta>
862  </thetaAnion>
863 
864  <psiCommonCation cation="Na+" anion1="Cl-" anion2="OH-">
865  <Theta> -0.05, 0.0, 0.0, 0.0, 0.0 </Theta>
866  <Psi> -0.006 </Psi>
867  </psiCommonCation>
868 
869  <thetaCation cation1="Na+" cation2="H+">
870  <Theta> 0.036, 0.0, 0.0, 0.0, 0.0 </Theta>
871  </thetaCation>
872 
873  <psiCommonAnion anion="Cl-" cation1="Na+" cation2="H+">
874  <Theta> 0.036, 0.0, 0.0, 0.0, 0.0 </Theta>
875  <Psi> -0.004 </Psi>
876  </psiCommonAnion>
877 
878  </activityCoefficients>
879  @endverbatim
880  *
881  *
882  * <H3> Specification of the Debye-Huckel Constant </H3>
883  *
884  * In the equations above, the formula for \f$ A_{Debye} \f$
885  * is needed. The %HMWSoln object uses two methods for specifying these quantities.
886  * The default method is to assume that \f$ A_{Debye} \f$ is a constant, given
887  * in the initialization process, and stored in the
888  * member double, m_A_Debye. Optionally, a full water treatment may be employed that makes
889  * \f$ A_{Debye} \f$ a full function of <I>T</I> and <I>P</I> and creates nontrivial entries for
890  * the excess heat capacity, enthalpy, and excess volumes of solution.
891  *
892  * \f[
893  * A_{Debye} = \frac{F e B_{Debye}}{8 \pi \epsilon R T} {\left( C_o \tilde{M}_o \right)}^{1/2}
894  * \f]
895  * where
896  *
897  * \f[
898  * B_{Debye} = \frac{F} {{(\frac{\epsilon R T}{2})}^{1/2}}
899  * \f]
900  * Therefore:
901  * \f[
902  * A_{Debye} = \frac{1}{8 \pi}
903  * {\left(\frac{2 N_a \rho_o}{1000}\right)}^{1/2}
904  * {\left(\frac{N_a e^2}{\epsilon R T }\right)}^{3/2}
905  * \f]
906  *
907  * Units = sqrt(kg/gmol)
908  *
909  * where
910  * - \f$ N_a \f$ is Avogadro's number
911  * - \f$ \rho_w \f$ is the density of water
912  * - \f$ e \f$ is the electronic charge
913  * - \f$ \epsilon = K \epsilon_o \f$ is the permittivity of water
914  * where \f$ K \f$ is the dielectric constant of water,
915  * and \f$ \epsilon_o \f$ is the permittivity of free space.
916  * - \f$ \rho_o \f$ is the density of the solvent in its standard state.
917  *
918  * Nominal value at 298 K and 1 atm = 1.172576 (kg/gmol)<SUP>1/2</SUP>
919  * based on:
920  * - \f$ \epsilon / \epsilon_0 \f$ = 78.54
921  * (water at 25C)
922  * - T = 298.15 K
923  * - B_Debye = 3.28640E9 (kg/gmol)<SUP>1/2</SUP> m<SUP>-1</SUP>
924  *
925  * An example of a fixed value implementation is given below.
926  * @code
927  * <activityCoefficients model="Pitzer">
928  * <!-- A_Debye units = sqrt(kg/gmol) -->
929  * <A_Debye> 1.172576 </A_Debye>
930  * <!-- object description continues -->
931  * </activityCoefficients>
932  * @endcode
933  *
934  * An example of a variable value implementation within the %HMWSoln object is given below.
935  * The model attribute, "water", triggers the full implementation.
936  *
937  * @code
938  * <activityCoefficients model="Pitzer">
939  * <!-- A_Debye units = sqrt(kg/gmol) -->
940  * <A_Debye model="water" />
941  * <!-- object description continues -->
942  * </activityCoefficients>
943  * @endcode
944  *
945  *
946  * <H3> Temperature and Pressure Dependence of the Activity Coefficients </H3>
947  *
948  * Temperature dependence of the activity coefficients leads to nonzero terms
949  * for the excess enthalpy and entropy of solution. This means that the
950  * partial molar enthalpies, entropies, and heat capacities are all
951  * non-trivial to compute. The following formulas are used.
952  *
953  * The partial molar enthalpy, \f$ \bar s_k(T,P) \f$:
954  *
955  * \f[
956  * \bar h_k(T,P) = h^{\triangle}_k(T,P)
957  * - R T^2 \frac{d \ln(\gamma_k^\triangle)}{dT}
958  * \f]
959  * The solvent partial molar enthalpy is equal to
960  * \f[
961  * \bar h_o(T,P) = h^{o}_o(T,P) - R T^2 \frac{d \ln(a_o)}{dT}
962  * = h^{o}_o(T,P)
963  * + R T^2 (\sum_{k \neq o} m_k) \tilde{M_o} (\frac{d \phi}{dT})
964  * \f]
965  *
966  * The partial molar entropy, \f$ \bar s_k(T,P) \f$:
967  *
968  * \f[
969  * \bar s_k(T,P) = s^{\triangle}_k(T,P)
970  * - R \ln( \gamma^{\triangle}_k \frac{m_k}{m^{\triangle}}))
971  * - R T \frac{d \ln(\gamma^{\triangle}_k) }{dT}
972  * \f]
973  * \f[
974  * \bar s_o(T,P) = s^o_o(T,P) - R \ln(a_o)
975  * - R T \frac{d \ln(a_o)}{dT}
976  * \f]
977  *
978  * The partial molar heat capacity, \f$ C_{p,k}(T,P)\f$:
979  *
980  * \f[
981  * \bar C_{p,k}(T,P) = C^{\triangle}_{p,k}(T,P)
982  * - 2 R T \frac{d \ln( \gamma^{\triangle}_k)}{dT}
983  * - R T^2 \frac{d^2 \ln(\gamma^{\triangle}_k) }{{dT}^2}
984  * \f]
985  * \f[
986  * \bar C_{p,o}(T,P) = C^o_{p,o}(T,P)
987  * - 2 R T \frac{d \ln(a_o)}{dT}
988  * - R T^2 \frac{d^2 \ln(a_o)}{{dT}^2}
989  * \f]
990  *
991  * The pressure dependence of the activity coefficients leads to non-zero terms
992  * for the excess Volume of the solution.
993  * Therefore, the partial molar volumes are functions
994  * of the pressure derivatives of the activity coefficients.
995  * \f[
996  * \bar V_k(T,P) = V^{\triangle}_k(T,P)
997  * + R T \frac{d \ln(\gamma^{\triangle}_k) }{dP}
998  * \f]
999  * \f[
1000  * \bar V_o(T,P) = V^o_o(T,P)
1001  * + R T \frac{d \ln(a_o)}{dP}
1002  * \f]
1003  *
1004  * The majority of work for these functions take place in the internal
1005  * routines that calculate the first and second derivatives of the log
1006  * of the activity coefficients wrt temperature,
1007  * s_update_dlnMolalityActCoeff_dT(), s_update_d2lnMolalityActCoeff_dT2(),
1008  * and the first
1009  * derivative of the log activity coefficients wrt pressure,
1010  * s_update_dlnMolalityActCoeff_dP().
1011  *
1012  * <HR>
1013  * <H2> %Application within %Kinetics Managers </H2>
1014  * <HR>
1015  *
1016  * For the time being, we have set the standard concentration for all solute
1017  * species in
1018  * this phase equal to the default concentration of the solvent at the system temperature
1019  * and pressure multiplied by Mnaught (kg solvent / gmol solvent). The solvent
1020  * standard concentration is just equal to its standard state concentration.
1021  *
1022  *
1023  * This means that the
1024  * kinetics operator essentially works on an generalized concentration basis (kmol / m3),
1025  * with units for the kinetic rate constant specified
1026  * as if all reactants (solvent or solute) are on a concentration basis (kmol /m3).
1027  * The concentration will be modified by the activity coefficients.
1028  *
1029  * For example, a bulk-phase binary reaction between liquid solute species
1030  * <I>j</I> and <I>k</I>, producing
1031  * a new liquid solute species <I>l</I> would have the
1032  * following equation for its rate of progress variable, \f$ R^1 \f$, which has
1033  * units of kmol m-3 s-1.
1034  *
1035  * \f[
1036  * 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)
1037  * \f]
1038  *
1039  * where
1040  *
1041  * \f[
1042  * 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
1043  * \f]
1044  *
1045  * \f$ C_j^a \f$ is the activity concentration of species <I>j</I>, and
1046  * \f$ C_k^a \f$ is the activity concentration of species <I>k</I>. \f$ C^o_o \f$
1047  * is the concentration of water at 298 K and 1 atm. \f$ \tilde{M}_o \f$
1048  * has units of kg solvent per gmol solvent and is equal to
1049  *
1050  * \f[
1051  * \tilde{M}_o = \frac{M_o}{1000}
1052  * \f]
1053  *
1054  * \f$ a_j \f$ is
1055  * the activity of species <I>j</I> at the current temperature and pressure
1056  * and concentration of the liquid phase is given by the molality based
1057  * activity coefficient multiplied by the molality of the jth species.
1058  *
1059  * \f[
1060  * a_j = \gamma_j^\triangle m_j = \gamma_j^\triangle \frac{n_j}{\tilde{M}_o n_o}
1061  * \f]
1062  *
1063  * \f$k^1 \f$ has units of m<SUP>3</SUP> kmol<SUP>-1</SUP> s<SUP>-1</SUP>.
1064  *
1065  * Therefore the generalized activity concentration of a solute species has the following form
1066  *
1067  * \f[
1068  * C_j^a = C^o_o \frac{\gamma_j^\triangle n_j}{n_o}
1069  * \f]
1070  *
1071  * The generalized activity concentration of the solvent has the same units, but it's a simpler form
1072  *
1073  * \f[
1074  * C_o^a = C^o_o a_o
1075  * \f]
1076  *
1077  * The reverse rate constant can then be obtained from the law of microscopic reversibility
1078  * and the equilibrium expression for the system.
1079  *
1080  * \f[
1081  * \frac{a_j a_k}{ a_l} = K^{o,1} = \exp(\frac{\mu^o_l - \mu^o_j - \mu^o_k}{R T} )
1082  * \f]
1083  *
1084  * \f$ K^{o,1} \f$ is the dimensionless form of the equilibrium constant.
1085  *
1086  * \f[
1087  * R^{-1} = k^{-1} C_l^a = k^{-1} (C_o \tilde{M}_o a_l)
1088  * \f]
1089  *
1090  * where
1091  *
1092  * \f[
1093  * k^{-1} = k^1 K^{o,1} C_o \tilde{M}_o
1094  * \f]
1095  *
1096  * \f$ k^{-1} \f$ has units of s<SUP>-1</SUP>.
1097  *
1098  * Note, this treatment may be modified in the future, as events dictate.
1099  *
1100  * <HR>
1101  * <H2> Instantiation of the Class </H2>
1102  * <HR>
1103  *
1104  * The constructor for this phase is now located in the default ThermoFactory
1105  * for %Cantera. The following code snippet may be used to initialize the phase
1106  * using the default construction technique within %Cantera.
1107  *
1108  * @code
1109  * ThermoPhase *HMW = newPhase("HMW_NaCl.xml", "NaCl_electrolyte");
1110  * @endcode
1111  *
1112  *
1113  * A new %HMWSoln object may be created by the following code snippets:
1114  *
1115  * @code
1116  * HMWSoln *HMW = new HMWSoln("HMW_NaCl.xml", "NaCl_electrolyte");
1117  * @endcode
1118  *
1119  * or
1120  *
1121  * @code
1122  * char iFile[80], file_ID[80];
1123  * strcpy(iFile, "HMW_NaCl.xml");
1124  * sprintf(file_ID,"%s#NaCl_electrolyte", iFile);
1125  * XML_Node *xm = get_XML_NameID("phase", file_ID, 0);
1126  * HMWSoln *dh = new HMWSoln(*xm);
1127  * @endcode
1128  *
1129  * or by the following call to importPhase():
1130  *
1131  * @code
1132  * char iFile[80], file_ID[80];
1133  * strcpy(iFile, "HMW_NaCl.xml");
1134  * sprintf(file_ID,"%s#NaCl_electrolyte", iFile);
1135  * XML_Node *xm = get_XML_NameID("phase", file_ID, 0);
1136  * HMWSoln dhphase;
1137  * importPhase(*xm, &dhphase);
1138  * @endcode
1139  *
1140  *
1141  * <HR>
1142  * <H2> XML Example </H2>
1143  * <HR>
1144  *
1145  * The phase model name for this is called StoichSubstance. It must be supplied
1146  * as the model attribute of the thermo XML element entry.
1147  * Within the phase XML block,
1148  * the density of the phase must be specified. An example of an XML file
1149  * this phase is given below.
1150  *
1151  * @verbatim
1152  <phase id="NaCl_electrolyte" dim="3">
1153  <speciesArray datasrc="#species_waterSolution">
1154  H2O(L) Na+ Cl- H+ OH-
1155  </speciesArray>
1156  <state>
1157  <temperature units="K"> 300 </temperature>
1158  <pressure units="Pa">101325.0</pressure>
1159  <soluteMolalities>
1160  Na+:3.0
1161  Cl-:3.0
1162  H+:1.0499E-8
1163  OH-:1.3765E-6
1164  </soluteMolalities>
1165  </state>
1166  <!-- thermo model identifies the inherited class
1167  from ThermoPhase that will handle the thermodynamics.
1168  -->
1169  <thermo model="HMW">
1170  <standardConc model="solvent_volume" />
1171  <activityCoefficients model="Pitzer" TempModel="complex1">
1172  <!-- Pitzer Coefficients
1173  These coefficients are from Pitzer's main
1174  paper, in his book.
1175  -->
1176  <A_Debye model="water" />
1177  <ionicRadius default="3.042843" units="Angstroms">
1178  </ionicRadius>
1179  <binarySaltParameters cation="Na+" anion="Cl-">
1180  <beta0> 0.0765, 0.008946, -3.3158E-6,
1181  -777.03, -4.4706
1182  </beta0>
1183  <beta1> 0.2664, 6.1608E-5, 1.0715E-6 </beta1>
1184  <beta2> 0.0 </beta2>
1185  <Cphi> 0.00127, -4.655E-5, 0.0,
1186  33.317, 0.09421
1187  </Cphi>
1188  <Alpha1> 2.0 </Alpha1>
1189  </binarySaltParameters>
1190 
1191  <binarySaltParameters cation="H+" anion="Cl-">
1192  <beta0> 0.1775, 0.0, 0.0, 0.0, 0.0</beta0>
1193  <beta1> 0.2945, 0.0, 0.0 </beta1>
1194  <beta2> 0.0 </beta2>
1195  <Cphi> 0.0008, 0.0, 0.0, 0.0, 0.0 </Cphi>
1196  <Alpha1> 2.0 </Alpha1>
1197  </binarySaltParameters>
1198 
1199  <binarySaltParameters cation="Na+" anion="OH-">
1200  <beta0> 0.0864, 0.0, 0.0, 0.0, 0.0 </beta0>
1201  <beta1> 0.253, 0.0, 0.0 </beta1>
1202  <beta2> 0.0 </beta2>
1203  <Cphi> 0.0044, 0.0, 0.0, 0.0, 0.0 </Cphi>
1204  <Alpha1> 2.0 </Alpha1>
1205  </binarySaltParameters>
1206 
1207  <thetaAnion anion1="Cl-" anion2="OH-">
1208  <Theta> -0.05 </Theta>
1209  </thetaAnion>
1210 
1211  <psiCommonCation cation="Na+" anion1="Cl-" anion2="OH-">
1212  <Theta> -0.05 </Theta>
1213  <Psi> -0.006 </Psi>
1214  </psiCommonCation>
1215 
1216  <thetaCation cation1="Na+" cation2="H+">
1217  <Theta> 0.036 </Theta>
1218  </thetaCation>
1219 
1220  <psiCommonAnion anion="Cl-" cation1="Na+" cation2="H+">
1221  <Theta> 0.036 </Theta>
1222  <Psi> -0.004 </Psi>
1223  </psiCommonAnion>
1224 
1225  </activityCoefficients>
1226 
1227  <solvent> H2O(L) </solvent>
1228  </thermo>
1229  <elementArray datasrc="elements.xml"> O H Na Cl </elementArray>
1230  <kinetics model="none" >
1231  </kinetics>
1232 </phase>
1233 @endverbatim
1234  *
1235  *
1236  *
1237  * @ingroup thermoprops
1238  *
1239  */
1240 class HMWSoln : public MolalityVPSSTP
1241 {
1242 
1243 public:
1244 
1245  //! Default Constructor
1246  HMWSoln();
1247 
1248  //! Construct and initialize an HMWSoln ThermoPhase object
1249  //! directly from an ASCII input file
1250  /*!
1251  * Working constructors
1252  *
1253  * The two constructors below are the normal way
1254  * the phase initializes itself. They are shells that call
1255  * the routine initThermo(), with a reference to the
1256  * XML database to get the info for the phase.
1257  *
1258  * @param inputFile Name of the input file containing the phase XML data
1259  * to set up the object
1260  * @param id ID of the phase in the input file. Defaults to the
1261  * empty string.
1262  */
1263  HMWSoln(std::string inputFile, std::string id = "");
1264 
1265  //! Construct and initialize an HMWSoln ThermoPhase object
1266  //! directly from an XML database
1267  /*!
1268  * @param phaseRef XML phase node containing the description of the phase
1269  * @param id id attribute containing the name of the phase.
1270  * (default is the empty string)
1271  */
1272  HMWSoln(XML_Node& phaseRef, std::string id = "");
1273 
1274 
1275  //! Copy Constructor
1276  /*!
1277  * Copy constructor for the object. Constructed
1278  * object will be a clone of this object, but will
1279  * also own all of its data.
1280  * This is a wrapper around the assignment operator
1281  *
1282  * @param right Object to be copied.
1283  */
1284  HMWSoln(const HMWSoln& right);
1285 
1286  //! Assignment operator
1287  /*!
1288  * Assignment operator for the object. Constructed
1289  * object will be a clone of this object, but will
1290  * also own all of its data.
1291  *
1292  * @param right Object to be copied.
1293  */
1294  HMWSoln& operator=(const HMWSoln& right);
1295 
1296 
1297  //! This is a special constructor, used to replicate test problems
1298  //! during the initial verification of the object
1299  /*!
1300  *
1301  *
1302  * test problems:
1303  * 1 = NaCl problem - 5 species -
1304  * the thermo is read in from an XML file
1305  *
1306  * speci molality charge
1307  * Cl- 6.0954 6.0997E+00 -1
1308  * H+ 1.0000E-08 2.1628E-09 1
1309  * Na+ 6.0954E+00 6.0997E+00 1
1310  * OH- 7.5982E-07 1.3977E-06 -1
1311  * HMW_params____beta0MX__beta1MX__beta2MX__CphiMX_____alphaMX__thetaij
1312  * 10
1313  * 1 2 0.1775 0.2945 0.0 0.00080 2.0 0.0
1314  * 1 3 0.0765 0.2664 0.0 0.00127 2.0 0.0
1315  * 1 4 0.0 0.0 0.0 0.0 0.0 -0.050
1316  * 2 3 0.0 0.0 0.0 0.0 0.0 0.036
1317  * 2 4 0.0 0.0 0.0 0.0 0.0 0.0
1318  * 3 4 0.0864 0.253 0.0 0.0044 2.0 0.0
1319  * Triplet_interaction_parameters_psiaa'_or_psicc'
1320  * 2
1321  * 1 2 3 -0.004
1322  * 1 3 4 -0.006
1323  *
1324  * @param testProb Hard -coded test problem to instantiate.
1325  * Current valid values are 1.
1326  */
1327  HMWSoln(int testProb);
1328 
1329  //! Destructor.
1330  virtual ~HMWSoln();
1331 
1332  //! Duplicator from the ThermoPhase parent class
1333  /*!
1334  * Given a pointer to a ThermoPhase object, this function will
1335  * duplicate the ThermoPhase object and all underlying structures.
1336  * This is basically a wrapper around the copy constructor.
1337  *
1338  * @return returns a pointer to a ThermoPhase
1339  */
1341 
1342  /**
1343  * @name Utilities
1344  * @{
1345  */
1346 
1347  /**
1348  * Equation of state type flag. The base class returns
1349  * zero. Subclasses should define this to return a unique
1350  * non-zero value. Constants defined for this purpose are
1351  * listed in mix_defs.h.
1352  */
1353  virtual int eosType() const;
1354 
1355  /**
1356  * @}
1357  * @name Molar Thermodynamic Properties of the Solution --------------
1358  * @{
1359  */
1360 
1361  /// Molar enthalpy. Units: J/kmol.
1362  /**
1363  * Molar enthalpy of the solution. Units: J/kmol.
1364  * (HKM -> Bump up to Parent object)
1365  */
1366  virtual doublereal enthalpy_mole() const;
1367 
1368  /**
1369  * Excess molar enthalpy of the solution from
1370  * the mixing process. Units: J/ kmol.
1371  *
1372  * Note this is kmol of the total solution.
1373  */
1374  virtual doublereal relative_enthalpy() const;
1375 
1376  /**
1377  * Excess molar enthalpy of the solution from
1378  * the mixing process on a molality basis.
1379  * Units: J/ (kmol add salt).
1380  *
1381  * Note this is kmol of the guessed at salt composition
1382  */
1383  virtual doublereal relative_molal_enthalpy() const;
1384 
1385 
1386  /// Molar internal energy. Units: J/kmol.
1387  /**
1388  * Molar internal energy of the solution. Units: J/kmol.
1389  * (HKM -> Bump up to Parent object)
1390  */
1391  virtual doublereal intEnergy_mole() const;
1392 
1393  /// Molar entropy. Units: J/kmol/K.
1394  /**
1395  * Molar entropy of the solution. Units: J/kmol/K.
1396  * For an ideal, constant partial molar volume solution mixture with
1397  * pure species phases which exhibit zero volume expansivity:
1398  * \f[
1399  * \hat s(T, P, X_k) = \sum_k X_k \hat s^0_k(T)
1400  * - \hat R \sum_k X_k log(X_k)
1401  * \f]
1402  * The reference-state pure-species entropies
1403  * \f$ \hat s^0_k(T,p_{ref}) \f$ are computed by the
1404  * species thermodynamic
1405  * property manager. The pure species entropies are independent of
1406  * temperature since the volume expansivities are equal to zero.
1407  * @see SpeciesThermo
1408  *
1409  * (HKM -> Bump up to Parent object)
1410  */
1411  virtual doublereal entropy_mole() const;
1412 
1413  /// Molar Gibbs function. Units: J/kmol.
1414  /*
1415  * (HKM -> Bump up to Parent object)
1416  */
1417  virtual doublereal gibbs_mole() const;
1418 
1419  /// Molar heat capacity at constant pressure. Units: J/kmol/K.
1420  virtual doublereal cp_mole() const;
1421 
1422  /// Molar heat capacity at constant volume. Units: J/kmol/K.
1423  /*
1424  * (HKM -> Bump up to Parent object)
1425  */
1426  virtual doublereal cv_mole() const;
1427 
1428  //@}
1429  /// @name Mechanical Equation of State Properties ---------------------
1430  //@{
1431  /**
1432  * In this equation of state implementation, the density is a
1433  * function only of the mole fractions. Therefore, it can't be
1434  * an independent variable. Instead, the pressure is used as the
1435  * independent variable. Functions which try to set the thermodynamic
1436  * state by calling setDensity() may cause an exception to be
1437  * thrown.
1438  */
1439 
1440  /**
1441  * Pressure. Units: Pa.
1442  * For this incompressible system, we return the internally stored
1443  * independent value of the pressure.
1444  */
1445  virtual doublereal pressure() const;
1446 
1447  //! Set the internally stored pressure (Pa) at constant
1448  //! temperature and composition
1449  /*!
1450  * This method sets the pressure within the object.
1451  * The water model is a completely compressible model.
1452  * Also, the dielectric constant is pressure dependent.
1453  *
1454  * @param p input Pressure (Pa)
1455  *
1456  * @todo Implement a variable pressure capability
1457  */
1458  virtual void setPressure(doublereal p);
1459 
1460 protected:
1461  /**
1462  * Calculate the density of the mixture using the partial
1463  * molar volumes and mole fractions as input
1464  *
1465  * The formula for this is
1466  *
1467  * \f[
1468  * \rho = \frac{\sum_k{X_k W_k}}{\sum_k{X_k V_k}}
1469  * \f]
1470  *
1471  * where \f$X_k\f$ are the mole fractions, \f$W_k\f$ are
1472  * the molecular weights, and \f$V_k\f$ are the pure species
1473  * molar volumes.
1474  *
1475  * Note, the basis behind this formula is that in an ideal
1476  * solution the partial molar volumes are equal to the pure
1477  * species molar volumes. We have additionally specified
1478  * in this class that the pure species molar volumes are
1479  * independent of temperature and pressure.
1480  *
1481  * NOTE: This is a non-virtual function, which is not a
1482  * member of the ThermoPhase base class.
1483  */
1484  void calcDensity();
1485 
1486 public:
1487  //! Returns the current value of the density
1488  /*!
1489  * @return value of the density. Units: kg/m^3
1490  */
1491  virtual doublereal density() const;
1492 
1493  //! Set the internally stored density (kg/m^3) of the phase.
1494  /*!
1495  * Overwritten setDensity() function is necessary because of
1496  * the underlying water model.
1497  *
1498  * @todo Now have a compressible ss equation for liquid water.
1499  * Therefore, this phase is compressible. May still
1500  * want to change the independent variable however.
1501  *
1502  * NOTE: This is an overwritten function from the State.h
1503  * class
1504  *
1505  * @param rho Input density (kg/m^3).
1506  */
1507  void setDensity(const doublereal rho);
1508 
1509  //! Set the internally stored molar density (kmol/m^3) for the phase.
1510  /**
1511  * Overwritten setMolarDensity() function is necessary because of the
1512  * underlying water model.
1513  *
1514  * This function will now throw an error condition if the input
1515  * isn't exactly equal to the current molar density.
1516  *
1517  * NOTE: This is a virtual function overwritten from the State.h
1518  * class
1519  *
1520  * @param conc Input molar density (kmol/m^3).
1521  */
1522  void setMolarDensity(const doublereal conc);
1523 
1524  //! Set the temperature (K)
1525  /*!
1526  * Overwritten setTemperature(double) from State.h. This
1527  * function sets the temperature, and makes sure that
1528  * the value propagates to underlying objects, such as
1529  * the water standard state model.
1530  *
1531  * @todo Make Phase::setTemperature a virtual function
1532  *
1533  * @param temp Temperature in kelvin
1534  */
1535  virtual void setTemperature(const doublereal temp);
1536 
1537  //! Set the temperature (K) and pressure (Pa)
1538  /*!
1539  * Set the temperature and pressure.
1540  *
1541  * @param t Temperature (K)
1542  * @param p Pressure (Pa)
1543  */
1544  virtual void setState_TP(doublereal t, doublereal p);
1545 
1546 
1547  /**
1548  * The isothermal compressibility. Units: 1/Pa.
1549  * The isothermal compressibility is defined as
1550  * \f[
1551  * \kappa_T = -\frac{1}{v}\left(\frac{\partial v}{\partial P}\right)_T
1552  * \f]
1553  */
1554  virtual doublereal isothermalCompressibility() const;
1555 
1556  /**
1557  * The thermal expansion coefficient. Units: 1/K.
1558  * The thermal expansion coefficient is defined as
1559  *
1560  * \f[
1561  * \beta = \frac{1}{v}\left(\frac{\partial v}{\partial T}\right)_P
1562  * \f]
1563  */
1564  virtual doublereal thermalExpansionCoeff() const;
1565 
1566  /**
1567  * @}
1568  * @name Potential Energy
1569  *
1570  * Species may have an additional potential energy due to the
1571  * presence of external gravitation or electric fields. These
1572  * methods allow specifying a potential energy for individual
1573  * species.
1574  * @{
1575  */
1576 
1577 
1578 
1579  /**
1580  * @}
1581  * @name Activities, Standard States, and Activity Concentrations
1582  *
1583  * The activity \f$a_k\f$ of a species in solution is
1584  * related to the chemical potential by \f[ \mu_k = \mu_k^0(T)
1585  * + \hat R T \log a_k. \f] The quantity \f$\mu_k^0(T,P)\f$ is
1586  * the chemical potential at unit activity, which depends only
1587  * on temperature and the pressure.
1588  * Activity is assumed to be molality-based here.
1589  * @{
1590  */
1591 
1592 
1593  //! This method returns an array of generalized activity concentrations
1594  /*!
1595  * The generalized activity concentrations, \f$ C_k^a\f$, are defined such that
1596  * \f$ a_k = C^a_k / C^0_k, \f$ where \f$ C^0_k \f$
1597  * is a standard concentration
1598  * defined below. These generalized concentrations are used
1599  * by kinetics manager classes to compute the forward and
1600  * reverse rates of elementary reactions.
1601  *
1602  * The generalized activity concentration of a solute species has the following form
1603  *
1604  * \f[
1605  * C_j^a = C^o_o \frac{\gamma_j^\triangle n_j}{n_o}
1606  * \f]
1607  *
1608  * The generalized activity concentration of the solvent has the same units, but it's a simpler form
1609  *
1610  * \f[
1611  * C_o^a = C^o_o a_o
1612  * \f]
1613  *
1614  *
1615  * @param c Array of generalized concentrations. The
1616  * units are kmol m-3 for both the solvent and the solute species
1617  */
1618  virtual void getActivityConcentrations(doublereal* c) const;
1619 
1620  //! Return the standard concentration for the kth species
1621  /*!
1622  * The standard concentration \f$ C^0_k \f$ used to normalize
1623  * the activity (i.e., generalized) concentration for use
1624  *
1625  * We have set the standard concentration for all solute species in
1626  * this phase equal to the default concentration of the solvent at the system temperature
1627  * and pressure multiplied by Mnaught (kg solvent / gmol solvent). The solvent
1628  * standard concentration is just equal to its standard state concentration.
1629  *
1630  * \f[
1631  * C_j^0 = C^o_o \tilde{M}_o \quad and C_o^0 = C^o_o
1632  * \f]
1633  *
1634  * The consequence of this is that the standard concentrations have unequal units
1635  * between the solvent and the solute. However, both the solvent and the solute
1636  * activity concentrations will have the same units of kmol kg<SUP>-3</SUP>.
1637  *
1638  * This means that the
1639  * kinetics operator essentially works on an generalized concentration basis (kmol / m3),
1640  * with units for the kinetic rate constant specified
1641  * as if all reactants (solvent or solute) are on a concentration basis (kmol /m3).
1642  * The concentration will be modified by the activity coefficients.
1643  *
1644  * For example, a bulk-phase binary reaction between liquid solute species
1645  * <I>j</I> and <I>k</I>, producing
1646  * a new liquid solute species <I>l</I> would have the
1647  * following equation for its rate of progress variable, \f$ R^1 \f$, which has
1648  * units of kmol m-3 s-1.
1649  *
1650  * \f[
1651  * 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)
1652  * \f]
1653  *
1654  * where
1655  *
1656  * \f[
1657  * 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
1658  * \f]
1659  *
1660  * \f$ C_j^a \f$ is the activity concentration of species <I>j</I>, and
1661  * \f$ C_k^a \f$ is the activity concentration of species <I>k</I>. \f$ C^o_o \f$
1662  * is the concentration of water at 298 K and 1 atm. \f$ \tilde{M}_o \f$
1663  * has units of kg solvent per gmol solvent and is equal to
1664  *
1665  * \f[
1666  * \tilde{M}_o = \frac{M_o}{1000}
1667  * \f]
1668  *
1669  * \f$ a_j \f$ is
1670  * the activity of species <I>j</I> at the current temperature and pressure
1671  * and concentration of the liquid phase is given by the molality based
1672  * activity coefficient multiplied by the molality of the jth species.
1673  *
1674  * \f[
1675  * a_j = \gamma_j^\triangle m_j = \gamma_j^\triangle \frac{n_j}{\tilde{M}_o n_o}
1676  * \f]
1677  *
1678  * \f$k^1 \f$ has units of m<SUP>3</SUP> kmol<SUP>-1</SUP> s<SUP>-1</SUP>.
1679  *
1680  * Therefore the generalized activity concentration of a solute species has the following form
1681  *
1682  * \f[
1683  * C_j^a = C^o_o \frac{\gamma_j^\triangle n_j}{n_o}
1684  * \f]
1685  *
1686  * The generalized activity concentration of the solvent has the same units, but it's a simpler form
1687  *
1688  * \f[
1689  * C_o^a = C^o_o a_o
1690  * \f]
1691  *
1692  *
1693  * @param k Optional parameter indicating the species. The default
1694  * is to assume this refers to species 0.
1695  * @return
1696  * Returns the standard Concentration in units of
1697  * m<SUP>3</SUP> kmol<SUP>-1</SUP>.
1698  *
1699  * @param k Species index
1700  */
1701  virtual doublereal standardConcentration(size_t k=0) const;
1702 
1703 
1704  //! Returns the natural logarithm of the standard
1705  //! concentration of the kth species
1706  /*!
1707  * @param k Species index
1708  */
1709  virtual doublereal logStandardConc(size_t k=0) const;
1710 
1711  //! Returns the units of the standard and generalized concentrations.
1712  /*!
1713  * Note they have the same units, as their
1714  * ratio is defined to be equal to the activity of the kth
1715  * species in the solution, which is unitless.
1716  *
1717  * This routine is used in print out applications where the
1718  * units are needed. Usually, MKS units are assumed throughout
1719  * the program and in the XML input files.
1720  *
1721  * The base %ThermoPhase class assigns the default quantities
1722  * of (kmol/m3) for all species.
1723  * Inherited classes are responsible for overriding the default
1724  * values if necessary.
1725  *
1726  * @param uA Output vector containing the units
1727  * uA[0] = kmol units - default = 1
1728  * uA[1] = m units - default = -nDim(), the number of spatial
1729  * dimensions in the Phase class.
1730  * uA[2] = kg units - default = 0;
1731  * uA[3] = Pa(pressure) units - default = 0;
1732  * uA[4] = Temperature units - default = 0;
1733  * uA[5] = time units - default = 0
1734  * @param k species index. Defaults to 0.
1735  * @param sizeUA output int containing the size of the vector.
1736  * Currently, this is equal to 6.
1737  */
1738  virtual void getUnitsStandardConc(double* uA, int k = 0,
1739  int sizeUA = 6) const;
1740 
1741  //! Get the array of non-dimensional activities at
1742  //! the current solution temperature, pressure, and solution concentration.
1743  /*!
1744  *
1745  * We resolve this function at this level by calling
1746  * on the activityConcentration function. However,
1747  * derived classes may want to override this default
1748  * implementation.
1749  *
1750  * (note solvent is on molar scale).
1751  *
1752  * @param ac Output vector of activities. Length: m_kk.
1753  */
1754  virtual void getActivities(doublereal* ac) const;
1755 
1756  //@}
1757  /// @name Partial Molar Properties of the Solution -----------------
1758  //@{
1759 
1760  //! Get the species chemical potentials. Units: J/kmol.
1761  /*!
1762  *
1763  * This function returns a vector of chemical potentials of the
1764  * species in solution.
1765  *
1766  * \f[
1767  * \mu_k = \mu^{\triangle}_k(T,P) + R T ln(\gamma_k^{\triangle} m_k)
1768  * \f]
1769  *
1770  * @param mu Output vector of species chemical
1771  * potentials. Length: m_kk. Units: J/kmol
1772  */
1773  virtual void getChemPotentials(doublereal* mu) const;
1774 
1775  //! Returns an array of partial molar enthalpies for the species
1776  //! in the mixture. Units (J/kmol)
1777  /*!
1778  * For this phase, the partial molar enthalpies are equal to the
1779  * standard state enthalpies modified by the derivative of the
1780  * molality-based activity coefficient wrt temperature
1781  *
1782  * \f[
1783  * \bar h_k(T,P) = h^{\triangle}_k(T,P)
1784  * - R T^2 \frac{d \ln(\gamma_k^\triangle)}{dT}
1785  * \f]
1786  * The solvent partial molar enthalpy is equal to
1787  * \f[
1788  * \bar h_o(T,P) = h^{o}_o(T,P) - R T^2 \frac{d \ln(a_o)}{dT}
1789  * = h^{o}_o(T,P)
1790  * + R T^2 (\sum_{k \neq o} m_k) \tilde{M_o} (\frac{d \phi}{dT})
1791  * \f]
1792  *
1793  *
1794  * @param hbar Output vector of species partial molar enthalpies.
1795  * Length: m_kk. units are J/kmol.
1796  */
1797  virtual void getPartialMolarEnthalpies(doublereal* hbar) const;
1798 
1799 
1800  //! Returns an array of partial molar entropies of the species in the
1801  //! solution. Units: J/kmol/K.
1802  /*!
1803  * Maxwell's equations provide an answer for how calculate this
1804  * (p.215 Smith and Van Ness)
1805  *
1806  * d(chemPot_i)/dT = -sbar_i
1807  *
1808  * For this phase, the partial molar entropies are equal to the
1809  * SS species entropies plus the ideal solution contribution
1810  * plus complicated functions of the
1811  * temperature derivative of the activity coefficients.
1812  *
1813  * \f[
1814  * \bar s_k(T,P) = s^{\triangle}_k(T,P)
1815  * - R \ln( \gamma^{\triangle}_k \frac{m_k}{m^{\triangle}}))
1816  * - R T \frac{d \ln(\gamma^{\triangle}_k) }{dT}
1817  * \f]
1818  * \f[
1819  * \bar s_o(T,P) = s^o_o(T,P) - R \ln(a_o)
1820  * - R T \frac{d \ln(a_o)}{dT}
1821  * \f]
1822  *
1823  * @param sbar Output vector of species partial molar entropies.
1824  * Length = m_kk. units are J/kmol/K.
1825  */
1826  virtual void getPartialMolarEntropies(doublereal* sbar) const;
1827 
1828  //! Return an array of partial molar volumes for the
1829  //! species in the mixture. Units: m^3/kmol.
1830  /*!
1831  * For this solution, the partial molar volumes are functions
1832  * of the pressure derivatives of the activity coefficients.
1833  *
1834  * \f[
1835  * \bar V_k(T,P) = V^{\triangle}_k(T,P)
1836  * + R T \frac{d \ln(\gamma^{\triangle}_k) }{dP}
1837  * \f]
1838  * \f[
1839  * \bar V_o(T,P) = V^o_o(T,P)
1840  * + R T \frac{d \ln(a_o)}{dP}
1841  * \f]
1842  *
1843  * @param vbar Output vector of species partial molar volumes.
1844  * Length = m_kk. units are m^3/kmol.
1845  */
1846  virtual void getPartialMolarVolumes(doublereal* vbar) const;
1847 
1848  //! Return an array of partial molar heat capacities for the
1849  //! species in the mixture. Units: J/kmol/K
1850  /*!
1851  * The following formulas are implemented within the code.
1852  *
1853  * \f[
1854  * \bar C_{p,k}(T,P) = C^{\triangle}_{p,k}(T,P)
1855  * - 2 R T \frac{d \ln( \gamma^{\triangle}_k)}{dT}
1856  * - R T^2 \frac{d^2 \ln(\gamma^{\triangle}_k) }{{dT}^2}
1857  * \f]
1858  * \f[
1859  * \bar C_{p,o}(T,P) = C^o_{p,o}(T,P)
1860  * - 2 R T \frac{d \ln(a_o)}{dT}
1861  * - R T^2 \frac{d^2 \ln(a_o)}{{dT}^2}
1862  * \f]
1863  *
1864  *
1865  * @param cpbar Output vector of species partial molar heat
1866  * capacities at constant pressure.
1867  * Length = m_kk. units are J/kmol/K.
1868  */
1869  virtual void getPartialMolarCp(doublereal* cpbar) const;
1870 
1871  //@}
1872 
1873 
1874 
1875 protected:
1876 
1877  //! Updates the standard state thermodynamic functions at the current T and P of the solution.
1878  /*!
1879  * @internal
1880  *
1881  * This function gets called for every call to a public function in this
1882  * class. It checks to see whether the temperature or pressure has changed and
1883  * thus whether the ss thermodynamics functions must be recalculated.
1884  *
1885  * @param pres Pressure at which to evaluate the standard states.
1886  * The default, indicated by a -1.0, is to use the current pressure
1887  */
1888  //virtual void _updateStandardStateThermo() const;
1889 
1890  //@}
1891  /// @name Thermodynamic Values for the Species Reference States ---
1892  //@{
1893 
1894 
1895  ///////////////////////////////////////////////////////
1896  //
1897  // The methods below are not virtual, and should not
1898  // be overloaded.
1899  //
1900  //////////////////////////////////////////////////////
1901 
1902  /**
1903  * @name Specific Properties
1904  * @{
1905  */
1906 
1907 
1908  /**
1909  * @name Setting the State
1910  *
1911  * These methods set all or part of the thermodynamic
1912  * state.
1913  * @{
1914  */
1915 
1916  //@}
1917 
1918  /**
1919  * @name Chemical Equilibrium
1920  * Chemical equilibrium.
1921  * @{
1922  */
1923 public:
1924 
1925  //!This method is used by the ChemEquil equilibrium solver.
1926  /*!
1927  * It sets the state such that the chemical potentials satisfy
1928  * \f[ \frac{\mu_k}{\hat R T} = \sum_m A_{k,m}
1929  * \left(\frac{\lambda_m} {\hat R T}\right) \f] where
1930  * \f$ \lambda_m \f$ is the element potential of element m. The
1931  * temperature is unchanged. Any phase (ideal or not) that
1932  * implements this method can be equilibrated by ChemEquil.
1933  *
1934  * @param lambda_RT Input vector of dimensionless element potentials
1935  * The length is equal to nElements().
1936  */
1937  virtual void setToEquilState(const doublereal* lambda_RT) {
1939  err("setToEquilState");
1940  }
1941 
1942  //@}
1943 
1944 
1945  //! Set the equation of state parameters
1946  /*!
1947  * @internal
1948  * The number and meaning of these depends on the subclass.
1949  *
1950  * @param n number of parameters
1951  * @param c array of \a n coefficients
1952  */
1953  virtual void setParameters(int n, doublereal* const c);
1954 
1955  //! Get the equation of state parameters in a vector
1956  /*!
1957  * @internal
1958  * The number and meaning of these depends on the subclass.
1959  *
1960  * @param n number of parameters
1961  * @param c array of \a n coefficients
1962  */
1963  virtual void getParameters(int& n, doublereal* const c) const;
1964 
1965  //! Set equation of state parameter values from XML
1966  //! entries.
1967  /*!
1968  * This method is called by function importPhase in
1969  * file importCTML.cpp when processing a phase definition in
1970  * an input file. It should be overloaded in subclasses to set
1971  * any parameters that are specific to that particular phase
1972  * model.
1973  *
1974  * @param eosdata An XML_Node object corresponding to
1975  * the "thermo" entry for this phase in the input file.
1976  */
1977  virtual void setParametersFromXML(const XML_Node& eosdata);
1978 
1979  //---------------------------------------------------------
1980  /// @name Critical state properties.
1981  /// These methods are only implemented by some subclasses.
1982 
1983  //@{
1984 
1985  /// Critical temperature (K).
1986  virtual doublereal critTemperature() const {
1987  err("critTemperature");
1988  return -1.0;
1989  }
1990 
1991  /// Critical pressure (Pa).
1992  virtual doublereal critPressure() const {
1993  err("critPressure");
1994  return -1.0;
1995  }
1996 
1997  /// Critical density (kg/m3).
1998  virtual doublereal critDensity() const {
1999  err("critDensity");
2000  return -1.0;
2001  }
2002 
2003  //@}
2004 
2005  /// @name Saturation properties.
2006  /// These methods are only implemented by subclasses that
2007  /// implement full liquid-vapor equations of state.
2008  ///
2009  virtual doublereal satTemperature(doublereal p) const {
2010  err("satTemperature");
2011  return -1.0;
2012  }
2013 
2014  //! Get the saturation pressure for a given temperature.
2015  /*!
2016  * Note the limitations of this function. Stability considerations
2017  * concerning multiphase equilibrium are ignored in this
2018  * calculation. Therefore, the call is made directly to the SS of
2019  * water underneath. The object is put back into its original
2020  * state at the end of the call.
2021  *
2022  * @todo This is probably not implemented correctly. The stability
2023  * of the salt should be added into this calculation. The
2024  * underlying water model may be called to get the stability
2025  * of the pure water solution, if needed.
2026  *
2027  * @param T Temperature (kelvin)
2028  */
2029  virtual doublereal satPressure(doublereal T) const;
2030 
2031  virtual doublereal vaporFraction() const {
2032  err("vaprFraction");
2033  return -1.0;
2034  }
2035 
2036  virtual void setState_Tsat(doublereal t, doublereal x) {
2037  err("setState_sat");
2038  }
2039 
2040  virtual void setState_Psat(doublereal p, doublereal x) {
2041  err("setState_sat");
2042  }
2043 
2044  //@}
2045 
2046 
2047  /*
2048  * -------------- Utilities -------------------------------
2049  */
2050 
2051 
2052  //! Initialization of a HMWSoln phase using an xml file
2053  /*!
2054  * This routine is a precursor to initThermo(XML_Node*)
2055  * routine, which does most of the work.
2056  *
2057  * @param inputFile XML file containing the description of the
2058  * phase
2059  *
2060  * @param id Optional parameter identifying the name of the
2061  * phase. If none is given, the first XML
2062  * phase element will be used.
2063  */
2064  void constructPhaseFile(std::string inputFile, std::string id);
2065 
2066  //! Import and initialize a HMWSoln phase
2067  //! specification in an XML tree into the current object.
2068  /*!
2069  * Here we read an XML description of the phase.
2070  * We import descriptions of the elements that make up the
2071  * species in a phase.
2072  * We import information about the species, including their
2073  * reference state thermodynamic polynomials. We then freeze
2074  * the state of the species.
2075  *
2076  * Then, we read the species molar volumes from the xml
2077  * tree to finish the initialization.
2078  *
2079  * @param phaseNode This object must be the phase node of a
2080  * complete XML tree
2081  * description of the phase, including all of the
2082  * species data. In other words while "phase" must
2083  * point to an XML phase object, it must have
2084  * sibling nodes "speciesData" that describe
2085  * the species in the phase.
2086  *
2087  * @param id ID of the phase. If nonnull, a check is done
2088  * to see if phaseNode is pointing to the phase
2089  * with the correct id.
2090  */
2091  void constructPhaseXML(XML_Node& phaseNode, std::string id);
2092 
2093  //! Internal initialization required after all species have
2094  //! been added
2095  /*!
2096  * @internal Initialize. This method is provided to allow
2097  * subclasses to perform any initialization required after all
2098  * species have been added. For example, it might be used to
2099  * resize internal work arrays that must have an entry for
2100  * each species. The base class implementation does nothing,
2101  * and subclasses that do not require initialization do not
2102  * need to overload this method. When importing a CTML phase
2103  * description, this method is called just prior to returning
2104  * from function importPhase.
2105  *
2106  * @see importCTML.cpp
2107  */
2108  virtual void initThermo();
2109 
2110  //! Initialize the phase parameters from an XML file.
2111  /*!
2112  * initThermoXML() (virtual from ThermoPhase)
2113  *
2114  * This gets called from importPhase(). It processes the XML file
2115  * after the species are set up. This is the main routine for
2116  * reading in activity coefficient parameters.
2117  *
2118  * @param phaseNode This object must be the phase node of a
2119  * complete XML tree
2120  * description of the phase, including all of the
2121  * species data. In other words while "phase" must
2122  * point to an XML phase object, it must have
2123  * sibling nodes "speciesData" that describe
2124  * the species in the phase.
2125  * @param id ID of the phase. If nonnull, a check is done
2126  * to see if phaseNode is pointing to the phase
2127  * with the correct id.
2128  */
2129  virtual void initThermoXML(XML_Node& phaseNode, std::string id);
2130 
2131  //! Report the molar volume of species k
2132  /*!
2133  *
2134  * units - \f$ m^3 kmol^-1 \f$
2135  *
2136  * @param k species index
2137  *
2138  * @deprecated
2139  * The getPartialMolarVolumes() expression is more precise.
2140  */
2141  DEPRECATED(double speciesMolarVolume(int k) const);
2142 
2143 
2144  //! Value of the Debye Huckel constant as a function of temperature
2145  //! and pressure.
2146  /*!
2147  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
2148  *
2149  * Units = sqrt(kg/gmol)
2150  *
2151  * @param temperature Temperature of the derivative calculation
2152  * or -1 to indicate the current temperature
2153  *
2154  * @param pressure Pressure of the derivative calculation
2155  * or -1 to indicate the current pressure
2156  */
2157  virtual double A_Debye_TP(double temperature = -1.0,
2158  double pressure = -1.0) const;
2159 
2160  //! Value of the derivative of the Debye Huckel constant with
2161  //! respect to temperature as a function of temperature
2162  //! and pressure.
2163  /*!
2164  *
2165  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
2166  *
2167  * Units = sqrt(kg/gmol)
2168  *
2169  * @param temperature Temperature of the derivative calculation
2170  * or -1 to indicate the current temperature
2171  *
2172  * @param pressure Pressure of the derivative calculation
2173  * or -1 to indicate the current pressure
2174  */
2175  virtual double dA_DebyedT_TP(double temperature = -1.0,
2176  double pressure = -1.0) const;
2177 
2178  /**
2179  * Value of the derivative of the Debye Huckel constant with
2180  * respect to pressure, as a function of temperature
2181  * and pressure.
2182  *
2183  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
2184  *
2185  * Units = sqrt(kg/gmol)
2186  *
2187  * @param temperature Temperature of the derivative calculation
2188  * or -1 to indicate the current temperature
2189  *
2190  * @param pressure Pressure of the derivative calculation
2191  * or -1 to indicate the current pressure
2192  */
2193  virtual double dA_DebyedP_TP(double temperature = -1.0,
2194  double pressure = -1.0) const;
2195 
2196  /**
2197  * Return Pitzer's definition of A_L. This is basically the
2198  * derivative of the A_phi multiplied by 4 R T**2
2199  *
2200  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
2201  * dA_phidT = d(A_Debye)/dT / 3.0
2202  * A_L = dA_phidT * (4 * R * T * T)
2203  *
2204  * Units = sqrt(kg/gmol) (RT)
2205  *
2206  *
2207  * @param temperature Temperature of the derivative calculation
2208  * or -1 to indicate the current temperature
2209  *
2210  * @param pressure Pressure of the derivative calculation
2211  * or -1 to indicate the current pressure
2212  */
2213  double ADebye_L(double temperature = -1.0,
2214  double pressure = -1.0) const;
2215 
2216  /**
2217  * Return Pitzer's definition of A_J. This is basically the
2218  * temperature derivative of A_L, and the second derivative
2219  * of A_phi
2220  *
2221  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
2222  * dA_phidT = d(A_Debye)/dT / 3.0
2223  * A_J = 2 A_L/T + 4 * R * T * T * d2(A_phi)/dT2
2224  *
2225  * Units = sqrt(kg/gmol) (R)
2226  *
2227  * @param temperature Temperature of the derivative calculation
2228  * or -1 to indicate the current temperature
2229  *
2230  * @param pressure Pressure of the derivative calculation
2231  * or -1 to indicate the current pressure
2232  */
2233  double ADebye_J(double temperature = -1.0,
2234  double pressure = -1.0) const;
2235  /**
2236  * Return Pitzer's definition of A_V. This is the
2237  * derivative wrt pressure of A_phi multiplied by - 4 R T
2238  *
2239  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
2240  * dA_phidT = d(A_Debye)/dP / 3.0
2241  * A_V = - dA_phidP * (4 * R * T)
2242  *
2243  * Units = sqrt(kg/gmol) (RT) / Pascal
2244  *
2245  * @param temperature Temperature of the derivative calculation
2246  * or -1 to indicate the current temperature
2247  *
2248  * @param pressure Pressure of the derivative calculation
2249  * or -1 to indicate the current pressure
2250  *
2251  */
2252  double ADebye_V(double temperature = -1.0,
2253  double pressure = -1.0) const;
2254 
2255  //! Value of the 2nd derivative of the Debye Huckel constant with
2256  //! respect to temperature as a function of temperature
2257  //! and pressure.
2258  /*!
2259  *
2260  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
2261  *
2262  * Units = sqrt(kg/gmol)
2263  *
2264  * @param temperature Temperature of the derivative calculation
2265  * or -1 to indicate the current temperature
2266  *
2267  * @param pressure Pressure of the derivative calculation
2268  * or -1 to indicate the current pressure
2269  */
2270  virtual double d2A_DebyedT2_TP(double temperature = -1.0,
2271  double pressure = -1.0) const;
2272 
2273  //! Reports the ionic radius of the kth species
2274  /*!
2275  * @param k Species index
2276  */
2277  double AionicRadius(int k = 0) const;
2278 
2279  /**
2280  *
2281  * formPitzer():
2282  *
2283  * Returns the form of the Pitzer parameterization used
2284  */
2285  int formPitzer() const {
2286  return m_formPitzer;
2287  }
2288 
2289  /**
2290  * Print out all of the input coefficients.
2291  */
2292  void printCoeffs() const;
2293 
2294  //! Get the array of unscaled non-dimensional molality based
2295  //! activity coefficients at the current solution temperature,
2296  //! pressure, and solution concentration.
2297  /*!
2298  * See Denbigh p. 278 for a thorough discussion. This class must be overwritten in
2299  * classes which derive from %MolalityVPSSTP. This function takes over from the
2300  * molar-based activity coefficient calculation, getActivityCoefficients(), in
2301  * derived classes.
2302  *
2303  * @param acMolality Output vector containing the molality based activity coefficients.
2304  * length: m_kk.
2305  */
2306  void getUnscaledMolalityActivityCoefficients(doublereal* acMolality) const;
2307 
2308 private:
2309 
2310  //! Apply the current phScale to a set of activity Coefficients
2311  /*!
2312  * See the Eq3/6 Manual for a thorough discussion.
2313  *
2314  */
2315  void s_updateScaling_pHScaling() const;
2316 
2317  //! Apply the current phScale to a set of derivatives of the activity Coefficients
2318  //! wrt temperature
2319  /*!
2320  * See the Eq3/6 Manual for a thorough discussion of the need
2321  */
2322  void s_updateScaling_pHScaling_dT() const;
2323 
2324  //! Apply the current phScale to a set of 2nd derivatives of the activity Coefficients
2325  //! wrt temperature
2326  /*!
2327  * See the Eq3/6 Manual for a thorough discussion of the need
2328  */
2329  void s_updateScaling_pHScaling_dT2() const;
2330 
2331  //! Apply the current phScale to a set of derivatives of the activity Coefficients
2332  //! wrt pressure
2333  /*!
2334  * See the Eq3/6 Manual for a thorough discussion of the need
2335  */
2336  void s_updateScaling_pHScaling_dP() const;
2337 
2338 
2339  //! Calculate the Chlorine activity coefficient on the NBS scale
2340  /*!
2341  * We assume here that the m_IionicMolality variable is up to date.
2342  */
2343  doublereal s_NBS_CLM_lnMolalityActCoeff() const;
2344 
2345  //! Calculate the temperature derivative of the Chlorine activity coefficient
2346  //! on the NBS scale
2347  /*!
2348  * We assume here that the m_IionicMolality variable is up to date.
2349  */
2350  doublereal s_NBS_CLM_dlnMolalityActCoeff_dT() const;
2351 
2352  //! Calculate the second temperature derivative of the Chlorine activity coefficient
2353  //! on the NBS scale
2354  /*!
2355  * We assume here that the m_IionicMolality variable is up to date.
2356  */
2357  doublereal s_NBS_CLM_d2lnMolalityActCoeff_dT2() const;
2358 
2359  //! Calculate the pressure derivative of the Chlorine activity coefficient
2360  /*!
2361  * We assume here that the m_IionicMolality variable is up to date.
2362  */
2363  doublereal s_NBS_CLM_dlnMolalityActCoeff_dP() const;
2364 
2365  //@}
2366 
2367 private:
2368 
2369  /**
2370  * This is the form of the Pitzer parameterization
2371  * used in this model.
2372  * The options are described at the top of this document,
2373  * and in the general documentation.
2374  * The list is repeated here:
2375  *
2376  * PITZERFORM_BASE = 0 (only one supported atm)
2377  *
2378  */
2380 
2381  /**
2382  * This is the form of the temperature dependence of Pitzer
2383  * parameterization used in the model.
2384  *
2385  * PITZER_TEMP_CONSTANT 0
2386  * PITZER_TEMP_LINEAR 1
2387  * PITZER_TEMP_COMPLEX1 2
2388  */
2390 
2391  /**
2392  * Format for the generalized concentration:
2393  *
2394  * 0 = unity
2395  * 1 = molar_volume
2396  * 2 = solvent_volume (default)
2397  *
2398  * The generalized concentrations can have three different forms
2399  * depending on the value of the member attribute m_formGC, which
2400  * is supplied in the constructor.
2401  * <TABLE>
2402  * <TR><TD> m_formGC </TD><TD> GeneralizedConc </TD><TD> StandardConc </TD></TR>
2403  * <TR><TD> 0 </TD><TD> X_k </TD><TD> 1.0 </TD></TR>
2404  * <TR><TD> 1 </TD><TD> X_k / V_k </TD><TD> 1.0 / V_k </TD></TR>
2405  * <TR><TD> 2 </TD><TD> X_k / V_N </TD><TD> 1.0 / V_N </TD></TR>
2406  * </TABLE>
2407  *
2408  * The value and form of the generalized concentration will affect
2409  * reaction rate constants involving species in this phase.
2410  *
2411  * (HKM Note: Using option #1 may lead to spurious results and
2412  * has been included only with warnings. The reason is that it
2413  * molar volumes of electrolytes may often be negative. The
2414  * molar volume of H+ is defined to be zero too. Either options
2415  * 0 or 2 are the appropriate choice. Option 0 leads to
2416  * bulk reaction rate constants which have units of s-1.
2417  * Option 2 leads to bulk reaction rate constants for
2418  * bimolecular rxns which have units of m-3 kmol-1 s-1.)
2419  */
2421 
2422  //! Vector containing the electrolyte species type
2423  /*!
2424  * The possible types are:
2425  * - solvent
2426  * - Charged Species
2427  * - weakAcidAssociated
2428  * - strongAcidAssociated
2429  * - polarNeutral
2430  * - nonpolarNeutral .
2431  */
2433 
2434  /**
2435  * a_k = Size of the ionic species in the DH formulation
2436  * units = meters
2437  */
2439 
2440  /**
2441  * Current value of the ionic strength on the molality scale
2442  * Associated Salts, if present in the mechanism,
2443  * don't contribute to the value of the ionic strength
2444  * in this version of the Ionic strength.
2445  */
2446  mutable double m_IionicMolality;
2447 
2448  /**
2449  * Maximum value of the ionic strength allowed in the
2450  * calculation of the activity coefficients.
2451  */
2453 
2454  /**
2455  * Reference Temperature for the Pitzer formulations.
2456  */
2458 
2459  /**
2460  * Stoichiometric ionic strength on the molality scale.
2461  * This differs from m_IionicMolality in the sense that
2462  * associated salts are treated as unassociated salts,
2463  * when calculating the Ionic strength by this method.
2464  */
2465  mutable double m_IionicMolalityStoich;
2466 
2467 public:
2468  /**
2469  * Form of the constant outside the Debye-Huckel term
2470  * called A. It's normally a function of temperature
2471  * and pressure. However, it can be set from the
2472  * input file in order to aid in numerical comparisons.
2473  * Acceptable forms:
2474  *
2475  * A_DEBYE_CONST 0
2476  * A_DEBYE_WATER 1
2477  *
2478  * The A_DEBYE_WATER form may be used for water solvents
2479  * with needs to cover varying temperatures and pressures.
2480  * Note, the dielectric constant of water is a relatively
2481  * strong function of T, and its variability must be
2482  * accounted for,
2483  */
2485 
2486 private:
2487  /**
2488  * A_Debye -> this expression appears on the top of the
2489  * ln actCoeff term in the general Debye-Huckel
2490  * expression
2491  * It depends on temperature. And, therefore,
2492  * most be recalculated whenever T or P changes.
2493  * This variable is a local copy of the calculation.
2494  *
2495  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
2496  *
2497  * where B_Debye = F / sqrt(epsilon R T/2)
2498  * (dw/1000)^(1/2)
2499  *
2500  * A_Debye = (1/ (8 Pi)) (2 Na * dw/1000)^(1/2)
2501  * (e * e / (epsilon * kb * T))^(3/2)
2502  *
2503  * Units = sqrt(kg/gmol)
2504  *
2505  * Nominal value = 1.172576 sqrt(kg/gmol)
2506  * based on:
2507  * epsilon/epsilon_0 = 78.54
2508  * (water at 25C)
2509  * epsilon_0 = 8.854187817E-12 C2 N-1 m-2
2510  * e = 1.60217653 E-19 C
2511  * F = 9.6485309E7 C kmol-1
2512  * R = 8.314472E3 kg m2 s-2 kmol-1 K-1
2513  * T = 298.15 K
2514  * B_Debye = 3.28640E9 sqrt(kg/gmol)/m
2515  * dw = C_0 * M_0 (density of water) (kg/m3)
2516  * = 1.0E3 at 25C
2517  */
2518  mutable double m_A_Debye;
2519 
2520  //! Water standard state calculator
2521  /*!
2522  * derived from the equation of state for water.
2523  */
2525 
2526  //! density of standard-state water
2527  /*!
2528  * internal temporary variable
2529  */
2531 
2532  /**
2533  * Pointer to the water property calculator
2534  */
2536 
2537  /**
2538  * Vector containing the species reference exp(-G/RT) functions
2539  * at T = m_tlast
2540  */
2542 
2543  /**
2544  * Vector of potential energies for the species.
2545  */
2546  mutable vector_fp m_pe;
2547 
2548  /**
2549  * Temporary array used in equilibrium calculations
2550  */
2551  mutable vector_fp m_pp;
2552 
2553  /**
2554  * vector of size m_kk, used as a temporary holding area.
2555  */
2557 
2558  /**
2559  * Stoichiometric species charge -> This is for calculations
2560  * of the ionic strength which ignore ion-ion pairing into
2561  * neutral molecules. The Stoichiometric species charge is the
2562  * charge of one of the ion that would occur if the species broke
2563  * into two charged ion pairs.
2564  * NaCl -> m_speciesCharge_Stoich = -1;
2565  * HSO4- -> H+ + SO42- = -2
2566  * -> The other charge is calculated.
2567  * For species that aren't ion pairs, its equal to the
2568  * m_speciesCharge[] value.
2569  */
2571 
2572  /**
2573  * Array of 2D data used in the Pitzer/HMW formulation.
2574  * Beta0_ij[i][j] is the value of the Beta0 coefficient
2575  * for the ij salt. It will be nonzero iff i and j are
2576  * both charged and have opposite sign. The array is also
2577  * symmetric.
2578  * counterIJ where counterIJ = m_counterIJ[i][j]
2579  * is used to access this array.
2580  */
2582 
2583  //! Derivative of Beta0_ij[i][j] wrt T
2584  /*!
2585  * vector index is counterIJ
2586  */
2588 
2589  //! Derivative of Beta0_ij[i][j] wrt TT
2590  /*!
2591  * vector index is counterIJ
2592  */
2594 
2595  //! Derivative of Beta0_ij[i][j] wrt P
2596  /*!
2597  * vector index is counterIJ
2598  */
2600 
2601  //! Array of coefficients for Beta0, a variable in Pitzer's papers
2602  /*!
2603  * column index is counterIJ
2604  * m_Beta0MX_ij_coeff.ptrColumn(counterIJ) is a double* containing
2605  * the vector of coefficients for the counterIJ interaction.
2606  */
2608 
2609  /*!
2610  * Array of 2D data used in the Pitzer/HMW formulation.
2611  * Beta1_ij[i][j] is the value of the Beta1 coefficient
2612  * for the ij salt. It will be nonzero iff i and j are
2613  * both charged and have opposite sign. The array is also
2614  * symmetric.
2615  * counterIJ where counterIJ = m_counterIJ[i][j]
2616  * is used to access this array.
2617  */
2619 
2620  //! Derivative of Beta1_ij[i][j] wrt T
2621  /*!
2622  * vector index is counterIJ
2623  */
2625 
2626  //! Derivative of Beta1_ij[i][j] wrt TT
2627  /*!
2628  * vector index is counterIJ
2629  */
2631 
2632  //! Derivative of Beta1_ij[i][j] wrt P
2633  /*!
2634  * vector index is counterIJ
2635  */
2637 
2638  //! Array of coefficients for Beta1, a variable in Pitzer's papers
2639  /*!
2640  * column index is counterIJ
2641  * m_Beta1MX_ij_coeff.ptrColumn(counterIJ) is a double* containing
2642  * the vector of coefficients for the counterIJ interaction.
2643  */
2645 
2646  /**
2647  * Array of 2D data used in the Pitzer/HMW formulation.
2648  * Beta2_ij[i][j] is the value of the Beta2 coefficient
2649  * for the ij salt. It will be nonzero iff i and j are
2650  * both charged and have opposite sign, and i and j
2651  * both have charges of 2 or more. The array is also
2652  * symmetric.
2653  * counterIJ where counterIJ = m_counterIJ[i][j]
2654  * is used to access this array.
2655  */
2657 
2658  //! Derivative of Beta2_ij[i][j] wrt T
2659  /*!
2660  * vector index is counterIJ
2661  */
2663 
2664  //! Derivative of Beta2_ij[i][j] wrt TT
2665  /*!
2666  * vector index is counterIJ
2667  */
2669 
2670  //! Derivative of Beta2_ij[i][j] wrt P
2671  /*!
2672  * vector index is counterIJ
2673  */
2675 
2676  //! Array of coefficients for Beta2, a variable in Pitzer's papers
2677  /*!
2678  * column index is counterIJ
2679  * m_Beta2MX_ij_coeff.ptrColumn(counterIJ) is a double* containing
2680  * the vector of coefficients for the counterIJ interaction.
2681  * This was added for the YMP database version of the code since it
2682  * contains temperature-dependent parameters for some 2-2 electrolytes.
2683  */
2685 
2686  /**
2687  * Array of 2D data used in the Pitzer/HMW formulation.
2688  * Alpha1MX_ij[i][j] is the value of the alpha1 coefficient
2689  * for the ij interaction. It will be nonzero iff i and j are
2690  * both charged and have opposite sign.
2691  * It is symmetric wrt i, j.
2692  * counterIJ where counterIJ = m_counterIJ[i][j]
2693  * is used to access this array.
2694  */
2696 
2697  /**
2698  * Array of 2D data used in the Pitzer/HMW formulation.
2699  * Alpha2MX_ij[i][j] is the value of the alpha2 coefficient
2700  * for the ij interaction. It will be nonzero iff i and j are
2701  * both charged and have opposite sign, and i and j
2702  * both have charges of 2 or more, usually.
2703  * It is symmetric wrt i, j.
2704  * counterIJ, where counterIJ = m_counterIJ[i][j],
2705  * is used to access this array.
2706  */
2708 
2709  /**
2710  * Array of 2D data used in the Pitzer/HMW formulation.
2711  * CphiMX_ij[i][j] is the value of the Cphi coefficient
2712  * for the ij interaction. It will be nonzero iff i and j are
2713  * both charged and have opposite sign, and i and j
2714  * both have charges of 2 or more. The array is also
2715  * symmetric.
2716  * counterIJ where counterIJ = m_counterIJ[i][j]
2717  * is used to access this array.
2718  */
2720 
2721  //! Derivative of Cphi_ij[i][j] wrt T
2722  /*!
2723  * vector index is counterIJ
2724  */
2726 
2727  //! Derivative of Cphi_ij[i][j] wrt TT
2728  /*!
2729  * vector index is counterIJ
2730  */
2732 
2733  //! Derivative of Cphi_ij[i][j] wrt P
2734  /*!
2735  * vector index is counterIJ
2736  */
2738 
2739  //! Array of coefficients for CphiMX, a parameter in the activity
2740  //! coefficient formulation
2741  /*!
2742  * Column index is counterIJ
2743  * m_CphiMX_ij_coeff.ptrColumn(counterIJ) is a double* containing
2744  * the vector of coefficients for the counterIJ interaction.
2745  */
2747 
2748  //! Array of 2D data for Theta_ij[i][j] in the Pitzer/HMW formulation.
2749  /*!
2750  * Array of 2D data used in the Pitzer/HMW formulation.
2751  * Theta_ij[i][j] is the value of the theta coefficient
2752  * for the ij interaction. It will be nonzero for charged
2753  * ions with the same sign. It is symmetric.
2754  * counterIJ where counterIJ = m_counterIJ[i][j]
2755  * is used to access this array.
2756  *
2757  * HKM Recent Pitzer papers have used a functional form
2758  * for Theta_ij, which depends on the ionic strength.
2759  */
2761 
2762  //! Derivative of Theta_ij[i][j] wrt T
2763  /*!
2764  * vector index is counterIJ
2765  */
2767 
2768  //! Derivative of Theta_ij[i][j] wrt TT
2769  /*!
2770  * vector index is counterIJ
2771  */
2773 
2774  //! Derivative of Theta_ij[i][j] wrt P
2775  /*!
2776  * vector index is counterIJ
2777  */
2779 
2780  //! Array of coefficients for Theta_ij[i][j] in the Pitzer/HMW formulation.
2781  /*!
2782  * Theta_ij[i][j] is the value of the theta coefficient
2783  * for the ij interaction. It will be nonzero for charged
2784  * ions with the same sign. It is symmetric.
2785  * Column index is counterIJ.
2786  * counterIJ where counterIJ = m_counterIJ[i][j]
2787  * is used to access this array.
2788  *
2789  * m_Theta_ij_coeff.ptrColumn(counterIJ) is a double* containing
2790  * the vector of coefficients for the counterIJ interaction.
2791  */
2793 
2794  //! Array of 3D data used in the Pitzer/HMW formulation.
2795  /*!
2796  * Psi_ijk[n] is the value of the psi coefficient for the
2797  * ijk interaction where
2798  *
2799  * n = k + j * m_kk + i * m_kk * m_kk;
2800  *
2801  * It is potentially nonzero everywhere.
2802  * The first two coordinates are symmetric wrt cations,
2803  * and the last two coordinates are symmetric wrt anions.
2804  */
2806 
2807  //! Derivative of Psi_ijk[n] wrt T
2808  /*!
2809  * see m_Psi_ijk for reference on the indexing into this variable.
2810  */
2812 
2813  //! Derivative of Psi_ijk[n] wrt TT
2814  /*!
2815  * see m_Psi_ijk for reference on the indexing into this variable.
2816  */
2818 
2819  //! Derivative of Psi_ijk[n] wrt P
2820  /*!
2821  * see m_Psi_ijk for reference on the indexing into this variable.
2822  */
2824 
2825  //! Array of coefficients for Psi_ijk[n] in the Pitzer/HMW formulation.
2826  /*!
2827  * Psi_ijk[n] is the value of the psi coefficient for the
2828  * ijk interaction where
2829  *
2830  * n = k + j * m_kk + i * m_kk * m_kk;
2831  *
2832  * It is potentially nonzero everywhere.
2833  * The first two coordinates are symmetric wrt cations,
2834  * and the last two coordinates are symmetric wrt anions.
2835  *
2836  *
2837  * m_Psi_ijk_coeff.ptrColumn(n) is a double* containing
2838  * the vector of coefficients for the n interaction.
2839  */
2841 
2842  //! Lambda coefficient for the ij interaction
2843  /*!
2844  * Array of 2D data used in the Pitzer/HMW formulation.
2845  * Lambda_nj[n][j] represents the lambda coefficient for the
2846  * ij interaction. This is a general interaction representing
2847  * neutral species. The neutral species occupy the first
2848  * index, i.e., n. The charged species occupy the j coordinate.
2849  * neutral, neutral interactions are also included here.
2850  */
2852 
2853  //! Derivative of Lambda_nj[i][j] wrt T. see m_Lambda_ij
2855 
2856  //! Derivative of Lambda_nj[i][j] wrt TT
2858 
2859  //! Derivative of Lambda_nj[i][j] wrt P
2861 
2862  //! Array of coefficients for Lambda_nj[i][j] in the Pitzer/HMW formulation.
2863  /*!
2864  * Lambda_ij[i][j] is the value of the theta coefficient
2865  * for the ij interaction.
2866  * Array of 2D data used in the Pitzer/HMW formulation.
2867  * Lambda_ij[i][j] represents the lambda coefficient for the
2868  * ij interaction. This is a general interaction representing
2869  * neutral species. The neutral species occupy the first
2870  * index, i.e., i. The charged species occupy the j coordinate.
2871  * Neutral, neutral interactions are also included here.
2872  *
2873  * n = j + m_kk * i
2874  *
2875  * m_Lambda_ij_coeff.ptrColumn(n) is a double* containing
2876  * the vector of coefficients for the (i,j) interaction.
2877  */
2879 
2880 
2881  //! Mu coefficient for the self-ternary neutral coefficient
2882  /*!
2883  * Array of 2D data used in the Pitzer/HMW formulation.
2884  * Mu_nnn[i] represents the Mu coefficient for the
2885  * nnn interaction. This is a general interaction representing
2886  * neutral species interacting with itself.
2887  */
2889 
2890  //! Mu coefficient temperature derivative for the self-ternary neutral coefficient
2891  /*!
2892  * Array of 2D data used in the Pitzer/HMW formulation.
2893  * Mu_nnn_L[i] represents the Mu coefficient temperature derivative for the
2894  * nnn interaction. This is a general interaction representing
2895  * neutral species interacting with itself.
2896  */
2898 
2899  //! Mu coefficient 2nd temperature derivative for the self-ternary neutral coefficient
2900  /*!
2901  * Array of 2D data used in the Pitzer/HMW formulation.
2902  * Mu_nnn_L[i] represents the Mu coefficient 2nd temperature derivative for the
2903  * nnn interaction. This is a general interaction representing
2904  * neutral species interacting with itself.
2905  */
2907 
2908  //! Mu coefficient pressure derivative for the self-ternary neutral coefficient
2909  /*!
2910  * Array of 2D data used in the Pitzer/HMW formulation.
2911  * Mu_nnn_L[i] represents the Mu coefficient pressure derivative for the
2912  * nnn interaction. This is a general interaction representing
2913  * neutral species interacting with itself.
2914  */
2916 
2917  //! Array of coefficients form_Mu_nnn term
2918  /*!
2919  *
2920  */
2922 
2923 
2924  //! Logarithm of the activity coefficients on the molality
2925  //! scale.
2926  /*!
2927  * mutable because we change this if the composition
2928  * or temperature or pressure changes.
2929  *
2930  * index is the species index
2931  */
2933 
2934  //! Logarithm of the activity coefficients on the molality
2935  //! scale.
2936  /*!
2937  * mutable because we change this if the composition
2938  * or temperature or pressure changes.
2939  *
2940  * index is the species index
2941  */
2943 
2944  //! Derivative of the Logarithm of the activity coefficients on the molality
2945  //! scale wrt T
2946  /*!
2947  * index is the species index
2948  */
2950 
2951  //! Derivative of the Logarithm of the activity coefficients on the molality
2952  //! scale wrt T
2953  /*!
2954  * index is the species index
2955  */
2957 
2958  //! Derivative of the Logarithm of the activity coefficients on the molality
2959  //! scale wrt TT
2960  /*!
2961  * index is the species index
2962  */
2964 
2965  //! Derivative of the Logarithm of the activity coefficients on the molality
2966  //! scale wrt TT
2967  /*!
2968  * index is the species index
2969  */
2971 
2972  //! Derivative of the Logarithm of the activity coefficients on the
2973  //! molality scale wrt P
2974  /*!
2975  * index is the species index
2976  */
2978 
2979  //! Derivative of the Logarithm of the activity coefficients on the
2980  //! molality scale wrt P
2981  /*!
2982  * index is the species index
2983  */
2985 
2986  /*
2987  * -------- Temporary Variables Used in the Activity Coeff Calc
2988  */
2989 
2990  //! Cropped and modified values of the molalities used in activity
2991  //! coefficient calculations
2993 
2994  //! Boolean indicating whether the molalities are cropped or are modified
2996 
2997  //! a counter variable for keeping track of symmetric binary
2998  //! interactions amongst the solute species.
2999  /*!
3000  * n = m_kk*i + j
3001  * m_CounterIJ[n] = counterIJ
3002  */
3004 
3005  /**
3006  * This is elambda, MEC
3007  */
3008  mutable double elambda[17];
3009 
3010  /**
3011  * This is elambda1, MEC
3012  */
3013  mutable double elambda1[17];
3014 
3015  /**
3016  * Various temporary arrays used in the calculation of
3017  * the Pitzer activity coefficients.
3018  * The subscript, L, denotes the same quantity's derivative
3019  * wrt temperature
3020  */
3021 
3022  //! This is the value of g(x) in Pitzer's papers
3023  /*!
3024  * vector index is counterIJ
3025  */
3027 
3028  //! This is the value of g2(x2) in Pitzer's papers
3029  /*!
3030  * vector index is counterIJ
3031  */
3033 
3034  //! hfunc, was called gprime in Pitzer's paper. However,
3035  //! it's not the derivative of gfunc(x), so I renamed it.
3036  /*!
3037  * vector index is counterIJ
3038  */
3040 
3041  //! hfunc2, was called gprime in Pitzer's paper. However,
3042  //! it's not the derivative of gfunc(x), so I renamed it.
3043  /*!
3044  * vector index is counterIJ
3045  */
3047 
3048  //! Intermediate variable called BMX in Pitzer's paper
3049  //! This is the basic cation - anion interaction
3050  /*!
3051  * vector index is counterIJ
3052  */
3054 
3055  //! Derivative of BMX_IJ wrt T
3056  /*!
3057  * vector index is counterIJ
3058  */
3060 
3061  //! Derivative of BMX_IJ wrt TT
3062  /*!
3063  * vector index is counterIJ
3064  */
3066 
3067  //! Derivative of BMX_IJ wrt P
3068  /*!
3069  * vector index is counterIJ
3070  */
3072 
3073  //! Intermediate variable called BprimeMX in Pitzer's paper
3074  /*!
3075  * vector index is counterIJ
3076  */
3078 
3079  //! Derivative of BprimeMX wrt T
3080  /*!
3081  * vector index is counterIJ
3082  */
3084 
3085  //! Derivative of BprimeMX wrt TT
3086  /*!
3087  * vector index is counterIJ
3088  */
3090 
3091  //! Derivative of BprimeMX wrt P
3092  /*!
3093  * vector index is counterIJ
3094  */
3096 
3097  //! Intermediate variable called BphiMX in Pitzer's paper
3098  /*!
3099  * vector index is counterIJ
3100  */
3102 
3103  //! Derivative of BphiMX_IJ wrt T
3104  /*!
3105  * vector index is counterIJ
3106  */
3108 
3109  //! Derivative of BphiMX_IJ wrt TT
3110  /*!
3111  * vector index is counterIJ
3112  */
3114 
3115  //! Derivative of BphiMX_IJ wrt P
3116  /*!
3117  * vector index is counterIJ
3118  */
3120 
3121  //! Intermediate variable called Phi in Pitzer's paper
3122  /*!
3123  * vector index is counterIJ
3124  */
3126 
3127  //! Derivative of m_Phi_IJ wrt T
3128  /*!
3129  * vector index is counterIJ
3130  */
3132 
3133  //! Derivative of m_Phi_IJ wrt TT
3134  /*!
3135  * vector index is counterIJ
3136  */
3138 
3139  //! Derivative of m_Phi_IJ wrt P
3140  /*!
3141  * vector index is counterIJ
3142  */
3144 
3145  //! Intermediate variable called Phiprime in Pitzer's paper
3146  /*!
3147  * vector index is counterIJ
3148  */
3150 
3151  //! Intermediate variable called PhiPhi in Pitzer's paper
3152  /*!
3153  * vector index is counterIJ
3154  */
3156 
3157  //! Derivative of m_PhiPhi_IJ wrt T
3158  /*!
3159  * vector index is counterIJ
3160  */
3162 
3163  //! Derivative of m_PhiPhi_IJ wrt TT
3164  /*!
3165  * vector index is counterIJ
3166  */
3168 
3169  //! Derivative of m_PhiPhi_IJ wrt P
3170  /*!
3171  * vector index is counterIJ
3172  */
3174 
3175  //! Intermediate variable called CMX in Pitzer's paper
3176  /*!
3177  * vector index is counterIJ
3178  */
3180 
3181  //! Derivative of m_CMX_IJ wrt T
3182  /*!
3183  * vector index is counterIJ
3184  */
3186 
3187  //! Derivative of m_CMX_IJ wrt TT
3188  /*!
3189  * vector index is counterIJ
3190  */
3192 
3193  //! Derivative of m_CMX_IJ wrt P
3194  /*!
3195  * vector index is counterIJ
3196  */
3198 
3199  //! Intermediate storage of the activity coefficient itself
3200  /*!
3201  * vector index is the species index
3202  */
3204 
3205  //! Logarithm of the molal activity coefficients
3206  /*!
3207  * Normally these are all one. However, stability schemes will change that
3208  */
3210 
3211  //! IMS Cutoff type
3213 
3214  //! value of the solute mole fraction that centers the cutoff polynomials
3215  //! for the cutoff =1 process;
3216  doublereal IMS_X_o_cutoff_;
3217 
3218  //! gamma_o value for the cutoff process at the zero solvent point
3219  doublereal IMS_gamma_o_min_;
3220 
3221  //! gamma_k minimum for the cutoff process at the zero solvent point
3222  doublereal IMS_gamma_k_min_;
3223 
3224  //! Parameter in the polyExp cutoff treatment having to do with rate of exp decay
3225  doublereal IMS_cCut_;
3226 
3227  //! Parameter in the polyExp cutoff treatment
3228  /*!
3229  * This is the slope of the f function at the zero solvent point
3230  * Default value is 0.6
3231  */
3232  doublereal IMS_slopefCut_;
3233 
3234  //! Parameter in the polyExp cutoff treatment having to do with rate of exp decay
3235  doublereal IMS_dfCut_;
3236 
3237  //! Parameter in the polyExp cutoff treatment having to do with rate of exp decay
3238  doublereal IMS_efCut_;
3239 
3240  //! Parameter in the polyExp cutoff treatment having to do with rate of exp decay
3241  doublereal IMS_afCut_;
3242 
3243  //! Parameter in the polyExp cutoff treatment having to do with rate of exp decay
3244  doublereal IMS_bfCut_;
3245 
3246  //! Parameter in the polyExp cutoff treatment
3247  /*!
3248  * This is the slope of the g function at the zero solvent point
3249  * Default value is 0.0
3250  */
3251  doublereal IMS_slopegCut_;
3252 
3253  //! Parameter in the polyExp cutoff treatment having to do with
3254  //! rate of exp decay
3255  doublereal IMS_dgCut_;
3256 
3257  //! Parameter in the polyExp cutoff treatment having to do with rate of exp decay
3258  doublereal IMS_egCut_;
3259 
3260  //! Parameter in the polyExp cutoff treatment having to do with rate of exp decay
3261  doublereal IMS_agCut_;
3262 
3263  //! Parameter in the polyExp cutoff treatment having to do with rate of exp decay
3264  doublereal IMS_bgCut_;
3265 
3266  //! value of the solvent mole fraction that centers the cutoff polynomials
3267  //! for the cutoff =1 process;
3268  doublereal MC_X_o_cutoff_;
3269 
3270  //! gamma_o value for the cutoff process at the zero solvent point
3271  doublereal MC_X_o_min_;
3272 
3273  //! Parameter in the Molality Exp cutoff treatment
3274  /*!
3275  * This is the slope of the p function at the zero solvent point
3276  * Default value is 0.0
3277  */
3278  doublereal MC_slopepCut_;
3279 
3280  //! Parameter in the Molality Exp cutoff treatment
3281  doublereal MC_dpCut_;
3282 
3283  //! Parameter in the Molality Exp cutoff treatment
3284  doublereal MC_epCut_;
3285 
3286  //! Parameter in the Molality Exp cutoff treatment
3287  doublereal MC_apCut_;
3288 
3289  //! Parameter in the Molality Exp cutoff treatment
3290  doublereal MC_bpCut_;
3291 
3292  //! Parameter in the Molality Exp cutoff treatment
3293  doublereal MC_cpCut_;
3294 
3295  //! Parameter in the Molality Exp cutoff treatment
3297 
3298  //! Parameter in the Molality Exp cutoff treatment
3300 
3301  //! Parameter in the Molality Exp cutoff treatment
3303 
3304  //! Parameter in the Molality Exp cutoff treatment
3306 
3307  //! This is a boolean-type vector indicating whether
3308  //! a species's activity coefficient is in the cropped regime
3309  /*!
3310  *
3311  * 0 = Not in cropped regime
3312  * 1 = In a transition regime where it is altered but there
3313  * still may be a temperature or pressure dependence
3314  * 2 = In a cropped regime where there is no temperature
3315  * or pressure dependence
3316  */
3317  mutable std::vector<int> CROP_speciesCropped_;
3318 
3319 
3320  //! Local error routine
3321  /*!
3322  * @param msg print out a message and error exit
3323  */
3324  doublereal err(std::string msg) const;
3325 
3326  //! Initialize all of the species - dependent lengths in the object
3327  void initLengths();
3328 
3329  //! Apply the current phScale to a set of activity Coefficients or
3330  //! activities
3331  /*!
3332  * See the Eq3/6 Manual for a thorough discussion.
3333  *
3334  * @param acMolality input/Output vector containing the molality based
3335  * activity coefficients. length: m_kk.
3336  */
3337  virtual void applyphScale(doublereal* acMolality) const;
3338 
3339 private:
3340  /*
3341  * This function will be called to update the internally stored
3342  * natural logarithm of the molality activity coefficients
3343  */
3344  void s_update_lnMolalityActCoeff() const;
3345 
3346  //! This function calculates the temperature derivative of the
3347  //! natural logarithm of the molality activity coefficients.
3348  /*!
3349  * This is the private function. It does all of the direct work.
3350  */
3351  void s_update_dlnMolalityActCoeff_dT() const;
3352 
3353  /**
3354  * This function calculates the temperature second derivative
3355  * of the natural logarithm of the molality activity
3356  * coefficients.
3357  */
3358  void s_update_d2lnMolalityActCoeff_dT2() const;
3359 
3360  /**
3361  * This function calculates the pressure derivative of the
3362  * natural logarithm of the molality activity coefficients.
3363  */
3364  void s_update_dlnMolalityActCoeff_dP() const;
3365 
3366  //! This function will be called to update the internally stored
3367  //! natural logarithm of the molality activity coefficients
3368  /*
3369  * Normally they are all one. However, sometimes they are not,
3370  * due to stability schemes
3371  *
3372  * gamma_k_molar = gamma_k_molal / Xmol_solvent
3373  *
3374  * gamma_o_molar = gamma_o_molal
3375  */
3376  void s_updateIMS_lnMolalityActCoeff() const;
3377 
3378 private:
3379  /**
3380  * This function does the main pitzer coefficient
3381  * calculation
3382  */
3383  void s_updatePitzer_lnMolalityActCoeff() const;
3384 
3385  //! Calculates the temperature derivative of the
3386  //! natural logarithm of the molality activity coefficients.
3387  /*!
3388  * Public function makes sure that all dependent data is
3389  * up to date, before calling a private function
3390  */
3392 
3393  /**
3394  * This function calculates the temperature second derivative
3395  * of the natural logarithm of the molality activity
3396  * coefficients.
3397  */
3399 
3400  //! Calculates the Pressure derivative of the
3401  //! natural logarithm of the molality activity coefficients.
3402  /*!
3403  * Public function makes sure that all dependent data is
3404  * up to date, before calling a private function
3405  */
3407 
3408 
3409 
3410 
3411  //! Calculates the Pitzer coefficients' dependence on the temperature.
3412  /*!
3413  * It will also calculate the temperature
3414  * derivatives of the coefficients, as they are important
3415  * in the calculation of the latent heats and the
3416  * heat capacities of the mixtures.
3417  *
3418  * @param doDerivs If >= 1, then the routine will calculate
3419  * the first derivative. If >= 2, the
3420  * routine will calculate the first and second
3421  * temperature derivative.
3422  * default = 2
3423  */
3424  void s_updatePitzer_CoeffWRTemp(int doDerivs = 2) const;
3425 
3426 
3427 
3428  //! Calculate the lambda interactions.
3429  /*!
3430  *
3431  * Calculate E-lambda terms for charge combinations of like sign,
3432  * using method of Pitzer (1975).
3433  *
3434  * @param is Ionic strength
3435  */
3436  void calc_lambdas(double is) const;
3437 
3438  /**
3439  * Calculate etheta and etheta_prime
3440  *
3441  * This interaction will be nonzero for species with the
3442  * same charge. this routine is not to be called for
3443  * neutral species; it core dumps or error exits.
3444  *
3445  * MEC implementation routine.
3446  *
3447  * @param z1 charge of the first molecule
3448  * @param z2 charge of the second molecule
3449  * @param etheta return pointer containing etheta
3450  * @param etheta_prime Return pointer containing etheta_prime.
3451  *
3452  * This routine uses the internal variables,
3453  * elambda[] and elambda1[].
3454  *
3455  * There is no prohibition against calling
3456  *
3457  */
3458  void calc_thetas(int z1, int z2,
3459  double* etheta, double* etheta_prime) const;
3460 
3461  //! Set up a counter variable for keeping track of symmetric binary
3462  //! interactions amongst the solute species.
3463  /*!
3464  * The purpose of this is to squeeze the ij parameters into a
3465  * compressed single counter.
3466  *
3467  * n = m_kk*i + j
3468  * m_Counter[n] = counter
3469  */
3470  void counterIJ_setup() const;
3471 
3472  //! Calculate the cropped molalities
3473  /*!
3474  * This is an internal routine that calculates values
3475  * of m_molalitiesCropped from m_molalities
3476  */
3477  void calcMolalitiesCropped() const;
3478 
3479  //! Process an XML node called "binarySaltParameters"
3480  /*!
3481  * This node contains all of the parameters necessary to describe
3482  * the Pitzer model for that particular binary salt.
3483  * This function reads the XML file and writes the coefficients
3484  * it finds to an internal data structures.
3485  *
3486  * @param BinSalt reference to the XML_Node named binarySaltParameters
3487  * containing the
3488  * anion - cation interaction
3489  */
3490  void readXMLBinarySalt(XML_Node& BinSalt);
3491 
3492  //! Process an XML node called "thetaAnion"
3493  /*!
3494  * This node contains all of the parameters necessary to describe
3495  * the binary interactions between two anions.
3496  *
3497  * @param BinSalt reference to the XML_Node named thetaAnion
3498  * containing the
3499  * anion - anion interaction
3500  */
3501  void readXMLThetaAnion(XML_Node& BinSalt);
3502 
3503  //! Process an XML node called "thetaCation"
3504  /*!
3505  * This node contains all of the parameters necessary to describe
3506  * the binary interactions between two cations.
3507  *
3508  * @param BinSalt reference to the XML_Node named thetaCation
3509  * containing the
3510  * cation - cation interaction
3511  */
3512  void readXMLThetaCation(XML_Node& BinSalt);
3513 
3514  //! Process an XML node called "psiCommonAnion"
3515  /*!
3516  * This node contains all of the parameters necessary to describe
3517  * the ternary interactions between one anion and two cations.
3518  *
3519  * @param BinSalt reference to the XML_Node named psiCommonAnion
3520  * containing the
3521  * anion - cation1 - cation2 interaction
3522  */
3523  void readXMLPsiCommonAnion(XML_Node& BinSalt);
3524 
3525  //! Process an XML node called "psiCommonCation"
3526  /*!
3527  * This node contains all of the parameters necessary to describe
3528  * the ternary interactions between one cation and two anions.
3529  *
3530  * @param BinSalt reference to the XML_Node named psiCommonCation
3531  * containing the
3532  * cation - anion1 - anion2 interaction
3533  */
3534  void readXMLPsiCommonCation(XML_Node& BinSalt);
3535 
3536  //! Process an XML node called "lambdaNeutral"
3537  /*!
3538  * This node contains all of the parameters necessary to describe
3539  * the binary interactions between one neutral species and
3540  * any other species (neutral or otherwise) in the mechanism.
3541  *
3542  * @param BinSalt reference to the XML_Node named lambdaNeutral
3543  * containing multiple
3544  * Neutral - species interactions
3545  */
3546  void readXMLLambdaNeutral(XML_Node& BinSalt);
3547 
3548  //! Process an XML node called "MunnnNeutral"
3549  /*!
3550  * This node contains all of the parameters necessary to describe
3551  * the self-ternary interactions for one neutral species.
3552  *
3553  * @param BinSalt reference to the XML_Node named Munnn
3554  * containing the self-ternary interaction
3555  */
3556  void readXMLMunnnNeutral(XML_Node& BinSalt);
3557 
3558  //! Process an XML node called "zetaCation"
3559  /*!
3560  * This node contains all of the parameters necessary to describe
3561  * the ternary interactions between one neutral, one cation, and one anion.
3562  *
3563  * @param BinSalt reference to the XML_Node named psiCommonCation
3564  * containing the
3565  * neutral - cation - anion interaction
3566  */
3567  void readXMLZetaCation(const XML_Node& BinSalt);
3568 
3569  //! Process an XML node called "croppingCoefficients"
3570  //! for the cropping coefficients values
3571  /*!
3572  * @param acNode Activity Coefficient XML Node
3573  */
3574  void readXMLCroppingCoefficients(const XML_Node& acNode);
3575 
3576  //! Precalculate the IMS Cutoff parameters for typeCutoff = 2
3577  void calcIMSCutoffParams_();
3578 
3579  //! Calculate molality cut-off parameters
3580  void calcMCCutoffParams_();
3581 
3582  //! Utility function to assign an integer value from a string
3583  //! for the ElectrolyteSpeciesType field.
3584  /*!
3585  * @param estString string name of the electrolyte species type
3586  */
3587  static int interp_est(std::string estString);
3588 
3589 public:
3590  /*!
3591  * Turn on copious debug printing when this
3592  * is true and DEBUG_MODE is turned on.
3593  */
3594  mutable int m_debugCalc;
3595 
3596  //! Return int specifying the amount of debug printing
3597  /*!
3598  * This will return 0 if DEBUG_MODE is not turned on
3599  */
3600  int debugPrinting();
3601 };
3602 
3603 }
3604 
3605 #endif
3606