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