Cantera  2.1.2
DebyeHuckel.h
Go to the documentation of this file.
1 /**
2  * @file DebyeHuckel.h
3  * Headers for the %DebyeHuckel ThermoPhase object, which models dilute
4  * electrolyte solutions
5  * (see \ref thermoprops and \link Cantera::DebyeHuckel DebyeHuckel \endlink) .
6  *
7  * Class %DebyeHuckel represents a dilute liquid electrolyte phase which
8  * obeys the Debye Huckel formulation for nonideality.
9  */
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_DEBYEHUCKEL_H
17 #define CT_DEBYEHUCKEL_H
18 
19 #include "MolalityVPSSTP.h"
20 #include "electrolytes.h"
21 #include "cantera/base/Array.h"
22 
23 namespace Cantera
24 {
25 
26 /*!
27  * @name Formats for the Activity Coefficients
28  *
29  * These are possible formats for the molality-based activity coefficients.
30  */
31 //@{
32 #define DHFORM_DILUTE_LIMIT 0
33 #define DHFORM_BDOT_AK 1
34 #define DHFORM_BDOT_ACOMMON 2
35 #define DHFORM_BETAIJ 3
36 #define DHFORM_PITZER_BETAIJ 4
37 //@}
38 /*
39  * @name Acceptable ways to calculate the value of A_Debye
40  */
41 //@{
42 #define A_DEBYE_CONST 0
43 #define A_DEBYE_WATER 1
44 //@}
45 
46 class WaterProps;
47 class PDSS_Water;
48 
49 /**
50  * @ingroup thermoprops
51  *
52  * Class %DebyeHuckel represents a dilute liquid electrolyte phase which
53  * obeys the Debye Huckel formulation for nonideality.
54  *
55  * The concentrations of the ionic species are assumed to obey the electroneutrality
56  * condition.
57  *
58  * <HR>
59  * <H2> Specification of Species Standard %State Properties </H2>
60  * <HR>
61  *
62  * The standard states are on the unit molality basis. Therefore, in the
63  * documentation below, the normal \f$ o \f$ superscript is replaced with
64  * the \f$ \triangle \f$ symbol. The reference state symbol is now
65  * \f$ \triangle, ref \f$.
66  *
67  *
68  * It is assumed that the reference state thermodynamics may be
69  * obtained by a pointer to a populated species thermodynamic property
70  * manager class (see ThermoPhase::m_spthermo). How to relate pressure
71  * changes to the reference state thermodynamics is resolved at this level.
72  *
73  * For an incompressible,
74  * stoichiometric substance, the molar internal energy is
75  * independent of pressure. Since the thermodynamic properties
76  * are specified by giving the standard-state enthalpy, the
77  * term \f$ P_0 \hat v\f$ is subtracted from the specified molar
78  * enthalpy to compute the molar internal energy. The entropy is
79  * assumed to be independent of the pressure.
80  *
81  * The enthalpy function is given by the following relation.
82  *
83  * \f[
84  * h^\triangle_k(T,P) = h^{\triangle,ref}_k(T)
85  * + \tilde v \left( P - P_{ref} \right)
86  * \f]
87  *
88  * For an incompressible,
89  * stoichiometric substance, the molar internal energy is
90  * independent of pressure. Since the thermodynamic properties
91  * are specified by giving the standard-state enthalpy, the
92  * term \f$ P_{ref} \tilde v\f$ is subtracted from the specified reference molar
93  * enthalpy to compute the molar internal energy.
94  *
95  * \f[
96  * u^\triangle_k(T,P) = h^{\triangle,ref}_k(T) - P_{ref} \tilde v
97  * \f]
98  *
99  * The standard state heat capacity and entropy are independent
100  * of pressure. The standard state gibbs free energy is obtained
101  * from the enthalpy and entropy functions.
102  *
103  * The vector Phase::m_speciesSize[] is used to hold the
104  * base values of species sizes. These are defined as the
105  * molar volumes of species at infinite dilution at 300 K and 1 atm
106  * of water. m_speciesSize are calculated during the initialization of the
107  * %DebyeHuckel object and are then not touched.
108  *
109  * The current model assumes that an incompressible molar volume for
110  * all solutes. The molar volume for the water solvent, however,
111  * is obtained from a pure water equation of state, waterSS.
112  * Therefore, the water standard state varies with both T and P.
113  * It is an error to request standard state water properties at a T and P
114  * where the water phase is not a stable phase, i.e., beyond its
115  * spinodal curve.
116  *
117  * <HR>
118  * <H2> Specification of Solution Thermodynamic Properties </H2>
119  * <HR>
120  *
121  * Chemical potentials
122  * of the solutes, \f$ \mu_k \f$, and the solvent, \f$ \mu_o \f$, which are based
123  * on the molality form, have the following general format:
124  *
125  * \f[
126  * \mu_k = \mu^{\triangle}_k(T,P) + R T ln(\gamma_k^{\triangle} \frac{m_k}{m^\triangle})
127  * \f]
128  * \f[
129  * \mu_o = \mu^o_o(T,P) + RT ln(a_o)
130  * \f]
131  *
132  * where \f$ \gamma_k^{\triangle} \f$ is the molality based activity coefficient for species
133  * \f$k\f$.
134  *
135  * Individual activity coefficients of ions can not be independently measured. Instead,
136  * only binary pairs forming electroneutral solutions can be measured.
137 
138  *
139  * <H3> Ionic Strength </H3>
140  *
141  * Most of the parameterizations within the model use the ionic strength
142  * as a key variable. The ionic strength, \f$ I\f$ is defined as follows
143  *
144  * \f[
145  * I = \frac{1}{2} \sum_k{m_k z_k^2}
146  * \f]
147  *
148  * \f$ m_k \f$ is the molality of the kth species. \f$ z_k \f$ is the charge
149  * of the kth species. Note, the ionic strength is a defined units quantity.
150  * The molality has defined units of gmol kg-1, and therefore the ionic
151  * strength has units of sqrt( gmol kg-1).
152  *
153  * In some instances, from some authors, a different
154  * formulation is used for the ionic strength in the equations below. The different
155  * formulation is due to the possibility of the existence of weak acids and how
156  * association wrt to the weak acid equilibrium relation affects the calculation
157  * of the activity coefficients via the assumed value of the ionic strength.
158  *
159  * If we are to assume that the association reaction doesn't have an effect
160  * on the ionic strength, then we will want to consider the associated weak
161  * acid as in effect being fully dissociated, when we calculate an effective
162  * value for the ionic strength. We will call this calculated value, the
163  * stoichiometric ionic strength, \f$ I_s \f$, putting a subscript s to denote
164  * it from the more straightforward calculation of \f$ I \f$.
165  *
166  * \f[
167  * I_s = \frac{1}{2} \sum_k{m_k^s z_k^2}
168  * \f]
169  *
170  * Here, \f$ m_k^s \f$ is the value of the molalities calculated assuming that
171  * all weak acid-base pairs are in their fully dissociated states. This calculation may
172  * be simplified by considering that the weakly associated acid may be made up of two
173  * charged species, k1 and k2, each with their own charges, obeying the following relationship:
174  *
175  * \f[
176  * z_k = z_{k1} + z_{k2}
177  * \f]
178  * Then, we may only need to specify one charge value, say, \f$ z_{k1}\f$,
179  * the cation charge number,
180  * in order to get both numbers, since we have already specified \f$ z_k \f$
181  * in the definition of original species.
182  * Then, the stoichiometric ionic strength may be calculated via the following formula.
183  *
184  * \f[
185  * I_s = \frac{1}{2} \left(\sum_{k,ions}{m_k z_k^2}+
186  * \sum_{k,weak_assoc}(m_k z_{k1}^2 + m_k z_{k2}^2) \right)
187  * \f]
188  *
189  * The specification of which species are weakly associated acids is made in the input
190  * file via the
191  * <TT> stoichIsMods </TT> XML block, where the charge for k1 is also specified.
192  * An example is given below:
193  *
194  * @code
195  * <stoichIsMods>
196  * NaCl(aq):-1.0
197  * </stoichIsMods>
198  * @endcode
199  *
200  * Because we need the concept of a weakly associated acid in order to calculated
201  * \f$ I_s \f$ we need to
202  * catalog all species in the phase. This is done using the following categories:
203  *
204  * - <B>cEST_solvent</B> Solvent species (neutral)
205  * - <B>cEST_chargedSpecies</B> Charged species (charged)
206  * - <B>cEST_weakAcidAssociated</B> Species which can break apart into charged species.
207  * It may or may not be charged. These may or
208  * may not be be included in the
209  * species solution vector.
210  * - <B>cEST_strongAcidAssociated</B> Species which always breaks apart into charged species.
211  * It may or may not be charged. Normally, these aren't included
212  * in the speciation vector.
213  * - <B>cEST_polarNeutral </B> Polar neutral species
214  * - <B>cEST_nonpolarNeutral</B> Non polar neutral species
215  *
216  * Polar and non-polar neutral species are differentiated, because some additions
217  * to the activity
218  * coefficient expressions distinguish between these two types of solutes. This is the so-called
219  * salt-out effect.
220  *
221  * The type of species is specified in the <TT>electrolyteSpeciesType</TT> XML block.
222  * Note, this is not
223  * considered a part of the specification of the standard state for the species,
224  * at this time. Therefore,
225  * this information is put under the <TT>activityCoefficient</TT> XML block. An example
226  * is given below
227  *
228  * @code
229  * <electrolyteSpeciesType>
230  * H2L(L):solvent
231  * H+:chargedSpecies
232  * NaOH(aq):weakAcidAssociated
233  * NaCl(aq):strongAcidAssociated
234  * NH3(aq):polarNeutral
235  * O2(aq):nonpolarNeutral
236  * </electrolyteSpeciesType>
237  * @endcode
238  *
239  * Much of the species electrolyte type information is inferred from other information in the
240  * input file. For example, as species which is charged is given the "chargedSpecies" default
241  * category. A neutral solute species is put into the "nonpolarNeutral" category by default.
242  *
243  * The specification of solute activity coefficients depends on the model
244  * assumed for the Debye-Huckel term. The model is set by the
245  * internal parameter #m_formDH. We will now describe each category in its own section.
246  *
247  *
248  * <H3> Debye-Huckel Dilute Limit </H3>
249  *
250  * DHFORM_DILUTE_LIMIT = 0
251  *
252  * This form assumes a dilute limit to DH, and is mainly for informational purposes:
253  * \f[
254  * \ln(\gamma_k^\triangle) = - z_k^2 A_{Debye} \sqrt{I}
255  * \f]
256  * where \f$ I\f$ is the ionic strength
257  * \f[
258  * I = \frac{1}{2} \sum_k{m_k z_k^2}
259  * \f]
260  *
261  * The activity for the solvent water,\f$ a_o \f$, is not independent and must be
262  * determined from the Gibbs-Duhem relation.
263  *
264  * \f[
265  * \ln(a_o) = \frac{X_o - 1.0}{X_o} + \frac{ 2 A_{Debye} \tilde{M}_o}{3} (I)^{3/2}
266  * \f]
267  *
268  *
269  * <H3> Bdot Formulation </H3>
270  *
271  * DHFORM_BDOT_AK = 1
272  *
273  * This form assumes Bethke's format for the Debye Huckel activity coefficient:
274  *
275  * \f[
276  * \ln(\gamma_k^\triangle) = -z_k^2 \frac{A_{Debye} \sqrt{I}}{ 1 + B_{Debye} a_k \sqrt{I}}
277  * + \log(10) B^{dot}_k I
278  * \f]
279  *
280  * Note, this particular form where \f$ a_k \f$ can differ in multielectrolyte
281  * solutions has problems with respect to a Gibbs-Duhem analysis. However,
282  * we include it here because there is a lot of data fit to it.
283  *
284  * The activity for the solvent water,\f$ a_o \f$, is not independent and must be
285  * determined from the Gibbs-Duhem relation. Here, we use:
286  *
287  * \f[
288  * \ln(a_o) = \frac{X_o - 1.0}{X_o}
289  * + \frac{ 2 A_{Debye} \tilde{M}_o}{3} (I)^{1/2}
290  * \left[ \sum_k{\frac{1}{2} m_k z_k^2 \sigma( B_{Debye} a_k \sqrt{I} ) } \right]
291  * - \frac{\log(10)}{2} \tilde{M}_o I \sum_k{ B^{dot}_k m_k}
292  * \f]
293  * where
294  * \f[
295  * \sigma (y) = \frac{3}{y^3} \left[ (1+y) - 2 \ln(1 + y) - \frac{1}{1+y} \right]
296  * \f]
297  *
298  * Additionally, Helgeson's formulation for the water activity is offered as an
299  * alternative.
300  *
301  *
302  * <H3> Bdot Formulation with Uniform Size Parameter in the Denominator </H3>
303  *
304  * DHFORM_BDOT_AUNIFORM = 2
305  *
306  * This form assumes Bethke's format for the Debye-Huckel activity coefficient
307  *
308  * \f[
309  * \ln(\gamma_k^\triangle) = -z_k^2 \frac{A_{Debye} \sqrt{I}}{ 1 + B_{Debye} a \sqrt{I}}
310  * + \log(10) B^{dot}_k I
311  * \f]
312  *
313  * The value of a is determined at the beginning of the calculation, and not changed.
314  *
315  * \f[
316  * \ln(a_o) = \frac{X_o - 1.0}{X_o}
317  * + \frac{ 2 A_{Debye} \tilde{M}_o}{3} (I)^{3/2} \sigma( B_{Debye} a \sqrt{I} )
318  * - \frac{\log(10)}{2} \tilde{M}_o I \sum_k{ B^{dot}_k m_k}
319  * \f]
320  *
321  *
322  * <H3> Beta_IJ formulation </H3>
323  *
324  * DHFORM_BETAIJ = 3
325  *
326  * This form assumes a linear expansion in a virial coefficient form.
327  * It is used extensively in the book by Newmann, "Electrochemistry Systems",
328  * and is the beginning of more complex treatments for stronger electrolytes,
329  * fom Pitzer and from Harvey, Moller, and Weire.
330  *
331  * \f[
332  * \ln(\gamma_k^\triangle) = -z_k^2 \frac{A_{Debye} \sqrt{I}}{ 1 + B_{Debye} a \sqrt{I}}
333  * + 2 \sum_j \beta_{j,k} m_j
334  * \f]
335  *
336  * In the current treatment the binary interaction coefficients, \f$ \beta_{j,k}\f$, are
337  * independent of temperature and pressure.
338  *
339  * \f[
340  * \ln(a_o) = \frac{X_o - 1.0}{X_o}
341  * + \frac{ 2 A_{Debye} \tilde{M}_o}{3} (I)^{3/2} \sigma( B_{Debye} a \sqrt{I} )
342  * - \tilde{M}_o \sum_j \sum_k \beta_{j,k} m_j m_k
343  * \f]
344  *
345  * In this formulation the ionic radius, \f$ a \f$, is a constant. This must be supplied to the
346  * model, in an <DFN> ionicRadius </DFN> XML block.
347  *
348  * The \f$ \beta_{j,k} \f$ parameters are binary interaction parameters. They are supplied to
349  * the object in an <TT> DHBetaMatrix </TT> XML block. There are in principle \f$ N (N-1) /2 \f$
350  * different, symmetric interaction parameters, where \f$ N \f$ are the number of solute species in the
351  * mechanism.
352  * An example is given below.
353  *
354  * An example <TT> activityCoefficients </TT> XML block for this formulation is supplied below
355  *
356  * @code
357  * <activityCoefficients model="Beta_ij">
358  * <!-- A_Debye units = sqrt(kg/gmol) -->
359  * <A_Debye> 1.172576 </A_Debye>
360  * <!-- B_Debye units = sqrt(kg/gmol)/m -->
361  * <B_Debye> 3.28640E9 </B_Debye>
362  * <ionicRadius default="3.042843" units="Angstroms">
363  * </ionicRadius>
364  * <DHBetaMatrix>
365  * H+:Cl-:0.27
366  * Na+:Cl-:0.15
367  * Na+:OH-:0.06
368  * </DHBetaMatrix>
369  * <stoichIsMods>
370  * NaCl(aq):-1.0
371  * </stoichIsMods>
372  * <electrolyteSpeciesType>
373  * H+:chargedSpecies
374  * NaCl(aq):weakAcidAssociated
375  * </electrolyteSpeciesType>
376  * </activityCoefficients>
377  * @endcode
378  *
379  * <H3> Pitzer Beta_IJ formulation </H3>
380  *
381  * DHFORM_PITZER_BETAIJ = 4
382  *
383  * This form assumes an activity coefficient formulation consistent
384  * with a truncated form of Pitzer's formulation. Pitzer's formulation is equivalent
385  * to the formulations above in the dilute limit, where rigorous theory may be applied.
386  *
387  * \f[
388  * \ln(\gamma_k^\triangle) = -z_k^2 \frac{A_{Debye}}{3} \frac{\sqrt{I}}{ 1 + B_{Debye} a \sqrt{I}}
389  * -2 z_k^2 \frac{A_{Debye}}{3} \frac{\ln(1 + B_{Debye} a \sqrt{I})}{ B_{Debye} a}
390  * + 2 \sum_j \beta_{j,k} m_j
391  * \f]
392  *
393  *
394  * \f[
395  * \ln(a_o) = \frac{X_o - 1.0}{X_o}
396  * + \frac{ 2 A_{Debye} \tilde{M}_o}{3} \frac{(I)^{3/2} }{1 + B_{Debye} a \sqrt{I} }
397  * - \tilde{M}_o \sum_j \sum_k \beta_{j,k} m_j m_k
398  * \f]
399  *
400  * <H3> Specification of the Debye Huckel Constants </H3>
401  *
402  * In the equations above, the formulas for \f$ A_{Debye} \f$ and \f$ B_{Debye} \f$
403  * are needed. The %DebyeHuckel object uses two methods for specifying these quantities.
404  * The default method is to assume that \f$ A_{Debye} \f$ is a constant, given
405  * in the initialization process, and stored in the
406  * member double, m_A_Debye. Optionally, a full water treatment may be employed that makes
407  * \f$ A_{Debye} \f$ a full function of <I>T</I> and <I>P</I>.
408  *
409  * \f[
410  * A_{Debye} = \frac{F e B_{Debye}}{8 \pi \epsilon R T} {\left( C_o \tilde{M}_o \right)}^{1/2}
411  * \f]
412  * where
413  *
414  * \f[
415  * B_{Debye} = \frac{F} {{(\frac{\epsilon R T}{2})}^{1/2}}
416  * \f]
417  * Therefore:
418  * \f[
419  * A_{Debye} = \frac{1}{8 \pi}
420  * {\left(\frac{2 N_a \rho_o}{1000}\right)}^{1/2}
421  * {\left(\frac{N_a e^2}{\epsilon R T }\right)}^{3/2}
422  * \f]
423  *
424  * where
425  * - \f$ N_a \f$ is Avogadro's number
426  * - \f$ \rho_w \f$ is the density of water
427  * - \f$ e \f$ is the electronic charge
428  * - \f$ \epsilon = K \epsilon_o \f$ is the permittivity of water
429  * - \f$ K \f$ is the dielectric constant of water
430  * - \f$ \epsilon_o \f$ is the permittivity of free space
431  * - \f$ \rho_o \f$ is the density of the solvent in its standard state.
432  *
433  * Nominal value at 298 K and 1 atm = 1.172576 (kg/gmol)<SUP>1/2</SUP> based on:
434  * - \f$ \epsilon / \epsilon_0 \f$ = 78.54 (water at 25C)
435  * - T = 298.15 K
436  * - B_Debye = 3.28640E9 (kg/gmol)<SUP>1/2</SUP> m<SUP>-1</SUP>
437  *
438  * An example of a fixed value implementation is given below.
439  * @code
440  * <activityCoefficients model="Beta_ij">
441  * <!-- A_Debye units = sqrt(kg/gmol) -->
442  * <A_Debye> 1.172576 </A_Debye>
443  * <!-- B_Debye units = sqrt(kg/gmol)/m -->
444  * <B_Debye> 3.28640E9 </B_Debye>
445  * </activityCoefficients>
446  * @endcode
447  *
448  * An example of a variable value implementation is given below.
449  *
450  * @code
451  * <activityCoefficients model="Beta_ij">
452  * <A_Debye model="water" />
453  * <!-- B_Debye units = sqrt(kg/gmol)/m -->
454  * <B_Debye> 3.28640E9 </B_Debye>
455  * </activityCoefficients>
456  * @endcode
457  *
458  * Currently, \f$ B_{Debye} \f$ is a constant in the model, specified either by a default
459  * water value, or through the input file. This may have to be looked at, in the future.
460  *
461  * <HR>
462  * <H2> %Application within %Kinetics Managers </H2>
463  * <HR>
464  *
465  * For the time being, we have set the standard concentration for all species in
466  * this phase equal to the default concentration of the solvent at 298 K and 1 atm.
467  * This means that the
468  * kinetics operator essentially works on an activities basis, with units specified
469  * as if it were on a concentration basis.
470  *
471  * For example, a bulk-phase binary reaction between liquid species j and k, producing
472  * a new liquid species l would have the
473  * following equation for its rate of progress variable, \f$ R^1 \f$, which has
474  * units of kmol m-3 s-1.
475  *
476  * \f[
477  * R^1 = k^1 C_j^a C_k^a = k^1 (C_o a_j) (C_o a_k)
478  * \f]
479  * where
480  * \f[
481  * C_j^a = C_o a_j \quad and \quad C_k^a = C_o a_k
482  * \f]
483  *
484  * \f$ C_j^a \f$ is the activity concentration of species j, and
485  * \f$ C_k^a \f$ is the activity concentration of species k. \f$ C_o \f$
486  * is the concentration of water at 298 K and 1 atm. \f$ a_j \f$ is
487  * the activity of species j at the current temperature and pressure
488  * and concentration of the liquid phase. \f$k^1 \f$ has units of m3 kmol-1 s-1.
489  *
490  * The reverse rate constant can then be obtained from the law of microscopic reversibility
491  * and the equilibrium expression for the system.
492  *
493  * \f[
494  * \frac{a_j a_k}{ a_l} = K^{o,1} = \exp(\frac{\mu^o_l - \mu^o_j - \mu^o_k}{R T} )
495  * \f]
496  *
497  * \f$ K^{o,1} \f$ is the dimensionless form of the equilibrium constant.
498  *
499  * \f[
500  * R^{-1} = k^{-1} C_l^a = k^{-1} (C_o a_l)
501  * \f]
502  *
503  * where
504  *
505  * \f[
506  * k^{-1} = k^1 K^{o,1} C_o
507  * \f]
508  *
509  * \f$k^{-1} \f$ has units of s-1.
510  *
511  * Note, this treatment may be modified in the future, as events dictate.
512  *
513  * <HR>
514  * <H2> Instantiation of the Class </H2>
515  * <HR>
516  *
517  * The constructor for this phase is NOT located in the default ThermoFactory
518  * for %Cantera. However, a new %DebyeHuckel object may be created by
519  * the following code snippets:
520  *
521  * @code
522  * DebyeHuckel *DH = new DebyeHuckel("DH_NaCl.xml", "NaCl_electrolyte");
523  * @endcode
524  *
525  * or
526  *
527  * @code
528  * XML_Node *xm = get_XML_NameID("phase", "DH_NaCl.xml#NaCl_electrolyte", 0);
529  * DebyeHuckel *dh = new DebyeHuckel(*xm);
530  * @endcode
531  *
532  * or by the following call to importPhase():
533  *
534  * @code
535  * XML_Node *xm = get_XML_NameID("phase", "DH_NaCl.xml#NaCl_electrolyte", 0);
536  * DebyeHuckel dhphase;
537  * importPhase(*xm, &dhphase);
538  * @endcode
539  *
540  * <HR>
541  * <H2> XML Example </H2>
542  * <HR>
543  *
544  * The phase model name for this is called StoichSubstance. It must be supplied
545  * as the model attribute of the thermo XML element entry.
546  * Within the phase XML block,
547  * the density of the phase must be specified. An example of an XML file
548  * this phase is given below.
549  *
550  * @verbatim
551  <phase id="NaCl_electrolyte" dim="3">
552  <speciesArray datasrc="#species_waterSolution">
553  H2O(L) Na+ Cl- H+ OH- NaCl(aq) NaOH(aq)
554  </speciesArray>
555  <state>
556  <temperature units="K"> 300 </temperature>
557  <pressure units="Pa">101325.0</pressure>
558  <soluteMolalities>
559  Na+:3.0
560  Cl-:3.0
561  H+:1.0499E-8
562  OH-:1.3765E-6
563  NaCl(aq):0.98492
564  NaOH(aq):3.8836E-6
565  </soluteMolalities>
566  </state>
567  <!-- thermo model identifies the inherited class
568  from ThermoPhase that will handle the thermodynamics.
569  -->
570  <thermo model="DebyeHuckel">
571  <standardConc model="solvent_volume" />
572  <activityCoefficients model="Beta_ij">
573  <!-- A_Debye units = sqrt(kg/gmol) -->
574  <A_Debye> 1.172576 </A_Debye>
575  <!-- B_Debye units = sqrt(kg/gmol)/m -->
576  <B_Debye> 3.28640E9 </B_Debye>
577  <ionicRadius default="3.042843" units="Angstroms">
578  </ionicRadius>
579  <DHBetaMatrix>
580  H+:Cl-:0.27
581  Na+:Cl-:0.15
582  Na+:OH-:0.06
583  </DHBetaMatrix>
584  <stoichIsMods>
585  NaCl(aq):-1.0
586  </stoichIsMods>
587  <electrolyteSpeciesType>
588  H+:chargedSpecies
589  NaCl(aq):weakAcidAssociated
590  </electrolyteSpeciesType>
591  </activityCoefficients>
592  <solvent> H2O(L) </solvent>
593  </thermo>
594  <elementArray datasrc="elements.xml"> O H Na Cl </elementArray>
595 </phase>
596 @endverbatim
597  *
598  *
599  */
601 {
602 public:
603  //! Default Constructor
604  DebyeHuckel();
605 
606  //! Copy constructor
607  DebyeHuckel(const DebyeHuckel&);
608 
609  //! Assignment operator
611 
612  //! Full constructor for creating the phase.
613  /*!
614  * @param inputFile File name containing the XML description of the phase
615  * @param id id attribute containing the name of the phase.
616  */
617  DebyeHuckel(const std::string& inputFile, const std::string& id = "");
618 
619  //! Full constructor for creating the phase.
620  /*!
621  * @param phaseRef XML phase node containing the description of the phase
622  * @param id id attribute containing the name of the phase.
623  */
624  DebyeHuckel(XML_Node& phaseRef, const std::string& id = "");
625 
626  /// Destructor.
627  virtual ~DebyeHuckel();
628 
629  //! Duplicator from the ThermoPhase parent class
630  /*!
631  * Given a pointer to a ThermoPhase object, this function will
632  * duplicate the ThermoPhase object and all underlying structures.
633  * This is basically a wrapper around the copy constructor.
634  *
635  * @return returns a pointer to a ThermoPhase
636  */
638 
639  //! @name Utilities
640  //! @{
641 
642  /**
643  * Equation of state type flag. The base class returns
644  * zero. Subclasses should define this to return a unique
645  * non-zero value. Constants defined for this purpose are
646  * listed in mix_defs.h.
647  */
648  virtual int eosType() const;
649 
650  //! @}
651  //! @name Molar Thermodynamic Properties of the Solution
652  //! @{
653 
654  /// Molar enthalpy of the solution. Units: J/kmol.
655  virtual doublereal enthalpy_mole() const;
656 
657  /// Molar internal energy of the solution. Units: J/kmol.
658  virtual doublereal intEnergy_mole() const;
659 
660  /// Molar entropy. Units: J/kmol/K.
661  /**
662  * For an ideal, constant partial molar volume solution mixture with
663  * pure species phases which exhibit zero volume expansivity:
664  * \f[
665  * \hat s(T, P, X_k) = \sum_k X_k \hat s^0_k(T)
666  * - \hat R \sum_k X_k log(X_k)
667  * \f]
668  * The reference-state pure-species entropies
669  * \f$ \hat s^0_k(T,p_{ref}) \f$ are computed by the
670  * species thermodynamic
671  * property manager. The pure species entropies are independent of
672  * temperature since the volume expansivities are equal to zero.
673  * @see SpeciesThermo
674  */
675  virtual doublereal entropy_mole() const;
676 
677  /// Molar Gibbs function. Units: J/kmol.
678  virtual doublereal gibbs_mole() const;
679 
680  /// Molar heat capacity at constant pressure. Units: J/kmol/K.
681  virtual doublereal cp_mole() const;
682 
683  //! Molar heat capacity at constant volume. Units: J/kmol/K.
684  /*
685  * (HKM -> Bump up to Parent object)
686  */
687  virtual doublereal cv_mole() const;
688 
689  //@}
690  /** @name Mechanical Equation of State Properties
691  //@{
692  *
693  * In this equation of state implementation, the density is a
694  * function only of the mole fractions. Therefore, it can't be
695  * an independent variable. Instead, the pressure is used as the
696  * independent variable. Functions which try to set the thermodynamic
697  * state by calling setDensity() may cause an exception to be
698  * thrown.
699  */
700 
701  //! Return the thermodynamic pressure (Pa).
702  /*!
703  * For this incompressible system, we return the internally stored
704  * independent value of the pressure.
705  */
706  virtual doublereal pressure() const;
707 
708  //! Set the internally stored pressure (Pa) at constant
709  //! temperature and composition
710  /*!
711  * This method sets the pressure within the object.
712  * The water model is a completely compressible model.
713  * Also, the dielectric constant is pressure dependent.
714  *
715  * @param p input Pressure (Pa)
716  *
717  * @todo Implement a variable pressure capability
718  */
719  virtual void setPressure(doublereal p);
720 
721 protected:
722  //! Calculate the density of the mixture using the partial
723  //! molar volumes and mole fractions as input
724  /*!
725  * The formula for this is
726  *
727  * \f[
728  * \rho = \frac{\sum_k{X_k W_k}}{\sum_k{X_k V_k}}
729  * \f]
730  *
731  * where \f$X_k\f$ are the mole fractions, \f$W_k\f$ are
732  * the molecular weights, and \f$V_k\f$ are the pure species
733  * molar volumes.
734  *
735  * Note, the basis behind this formula is that in an ideal
736  * solution the partial molar volumes are equal to the pure
737  * species molar volumes. We have additionally specified
738  * in this class that the pure species molar volumes are
739  * independent of temperature and pressure.
740  */
741  virtual void calcDensity();
742 
743 public:
744  //! Set the internally stored density (gm/m^3) of the phase.
745  /*!
746  * Overwritten setDensity() function is necessary because the
747  * density is not an independent variable.
748  *
749  * This function will now throw an error condition
750  *
751  * @internal May have to adjust the strategy here to make
752  * the eos for these materials slightly compressible, in order
753  * to create a condition where the density is a function of
754  * the pressure.
755  *
756  * This function will now throw an error condition if the
757  * input isn't exactly equal to the current density.
758  *
759  * @todo Now have a compressible ss equation for liquid water.
760  * Therefore, this phase is compressible. May still
761  * want to change the independent variable however.
762  *
763  * @param rho Input density (kg/m^3).
764  */
765  void setDensity(const doublereal rho);
766 
767  //! Set the internally stored molar density (kmol/m^3) of the phase.
768  /**
769  * Overwritten setMolarDensity() function is necessary because the
770  * density is not an independent variable.
771  *
772  * This function will now throw an error condition if the input
773  * isn't exactly equal to the current molar density.
774  *
775  * @param conc Input molar density (kmol/m^3).
776  */
777  virtual void setMolarDensity(const doublereal conc);
778 
779  //! Set the temperature (K)
780  /*!
781  * This function sets the temperature, and makes sure that
782  * the value propagates to underlying objects, such as
783  * the water standard state model.
784  *
785  * @param temp Temperature in kelvin
786  */
787  virtual void setTemperature(const doublereal temp);
788 
789  //! Set the temperature (K) and pressure (Pa)
790  /*!
791  * Set the temperature and pressure.
792  *
793  * @param t Temperature (K)
794  * @param p Pressure (Pa)
795  */
796  virtual void setState_TP(doublereal t, doublereal p);
797 
798  /**
799  * The isothermal compressibility. Units: 1/Pa.
800  * The isothermal compressibility is defined as
801  * \f[
802  * \kappa_T = -\frac{1}{v}\left(\frac{\partial v}{\partial P}\right)_T
803  * \f]
804  *
805  * It's equal to zero for this model, since the molar volume
806  * doesn't change with pressure or temperature.
807  */
808  virtual doublereal isothermalCompressibility() const;
809 
810  /**
811  * The thermal expansion coefficient. Units: 1/K.
812  * The thermal expansion coefficient is defined as
813  *
814  * \f[
815  * \beta = \frac{1}{v}\left(\frac{\partial v}{\partial T}\right)_P
816  * \f]
817  *
818  * It's equal to zero for this model, since the molar volume
819  * doesn't change with pressure or temperature.
820  */
821  virtual doublereal thermalExpansionCoeff() const;
822 
823  /**
824  * @}
825  * @name Activities, Standard States, and Activity Concentrations
826  *
827  * The activity \f$a_k\f$ of a species in solution is
828  * related to the chemical potential by \f[ \mu_k = \mu_k^0(T)
829  * + \hat R T \log a_k. \f] The quantity \f$\mu_k^0(T,P)\f$ is
830  * the chemical potential at unit activity, which depends only
831  * on temperature and the pressure.
832  * Activity is assumed to be molality-based here.
833  * @{
834  */
835 
836  //! This method returns an array of generalized concentrations
837  /*!
838  * \f$ C_k\f$ that are defined such that
839  * \f$ a_k = C_k / C^0_k, \f$ where \f$ C^0_k \f$
840  * is a standard concentration
841  * defined below. These generalized concentrations are used
842  * by kinetics manager classes to compute the forward and
843  * reverse rates of elementary reactions.
844  *
845  * @param c Array of generalized concentrations. The
846  * units depend upon the implementation of the
847  * reaction rate expressions within the phase.
848  */
849  virtual void getActivityConcentrations(doublereal* c) const;
850 
851  //! Return the standard concentration for the kth species
852  /*!
853  * The standard concentration \f$ C^0_k \f$ used to normalize
854  * the activity (i.e., generalized) concentration in
855  * kinetics calculations.
856  *
857  * For the time being, we will use the concentration of pure
858  * solvent for the the standard concentration of all species.
859  * This has the effect of making reaction rates
860  * based on the molality of species proportional to the
861  * molality of the species.
862  *
863  * @param k Optional parameter indicating the species. The default
864  * is to assume this refers to species 0.
865  * @return
866  * Returns the standard Concentration in units of
867  * m<SUP>3</SUP> kmol<SUP>-1</SUP>.
868  */
869  virtual doublereal standardConcentration(size_t k=0) const;
870 
871  //! Natural logarithm of the standard concentration of the kth species.
872  /*!
873  * @param k index of the species (defaults to zero)
874  */
875  virtual doublereal logStandardConc(size_t k=0) const;
876 
877  //! Returns the units of the standard and generalized concentrations.
878  /*!
879  * Note they have the same units, as their
880  * ratio is defined to be equal to the activity of the kth
881  * species in the solution, which is unitless.
882  *
883  * This routine is used in print out applications where the
884  * units are needed. Usually, MKS units are assumed throughout
885  * the program and in the XML input files.
886  *
887  * The base %ThermoPhase class assigns the default quantities
888  * of (kmol/m3) for all species.
889  * Inherited classes are responsible for overriding the default
890  * values if necessary.
891  *
892  * On return uA contains the powers of the units (MKS assumed)
893  * of the standard concentrations and generalized concentrations
894  * for the kth species.
895  *
896  * @param uA Output vector containing the units
897  * uA[0] = kmol units - default = 1
898  * uA[1] = m units - default = -nDim(), the number of spatial
899  * dimensions in the Phase class.
900  * uA[2] = kg units - default = 0;
901  * uA[3] = Pa(pressure) units - default = 0;
902  * uA[4] = Temperature units - default = 0;
903  * uA[5] = time units - default = 0
904  * @param k species index. Defaults to 0.
905  * @param sizeUA output int containing the size of the vector.
906  * Currently, this is equal to 6.
907  * @deprecated
908  */
909  virtual void getUnitsStandardConc(double* uA, int k = 0,
910  int sizeUA = 6) const;
911 
912  //! Get the array of non-dimensional activities at
913  //! the current solution temperature, pressure, and solution concentration.
914  /*!
915  *
916  * We resolve this function at this level by calling
917  * on the activityConcentration function. However,
918  * derived classes may want to override this default
919  * implementation.
920  *
921  * (note solvent activity coefficient is on molar scale).
922  *
923  * @param ac Output vector of activities. Length: m_kk.
924  */
925  virtual void getActivities(doublereal* ac) const;
926 
927  //! Get the array of non-dimensional molality-based
928  //! activity coefficients at
929  //! the current solution temperature, pressure, and solution concentration.
930  /*!
931  * note solvent is on molar scale. The solvent molar
932  * based activity coefficient is returned.
933  *
934  * Note, most of the work is done in an internal private routine
935  *
936  * @param acMolality Vector of Molality-based activity coefficients
937  * Length: m_kk
938  */
939  virtual void
940  getMolalityActivityCoefficients(doublereal* acMolality) const;
941 
942  //@}
943  /// @name Partial Molar Properties of the Solution
944  //@{
945 
946 
947  //! Get the species chemical potentials. Units: J/kmol.
948  /*!
949  *
950  * This function returns a vector of chemical potentials of the
951  * species in solution.
952  *
953  * \f[
954  * \mu_k = \mu^{\triangle}_k(T,P) + R T ln(\gamma_k^{\triangle} m_k)
955  * \f]
956  *
957  * @param mu Output vector of species chemical
958  * potentials. Length: m_kk. Units: J/kmol
959  */
960  virtual void getChemPotentials(doublereal* mu) const;
961 
962  //! Returns an array of partial molar enthalpies for the species
963  //! in the mixture. Units (J/kmol)
964  /*!
965  * For this phase, the partial molar enthalpies are equal to the
966  * standard state enthalpies modified by the derivative of the
967  * molality-based activity coefficient wrt temperature
968  *
969  * \f[
970  * \bar h_k(T,P) = h^{\triangle}_k(T,P) - R T^2 \frac{d \ln(\gamma_k^\triangle)}{dT}
971  * \f]
972  * The solvent partial molar enthalpy is equal to
973  * \f[
974  * \bar h_o(T,P) = h^{o}_o(T,P) - R T^2 \frac{d \ln(a_o}{dT}
975  * \f]
976  *
977  * The temperature dependence of the activity coefficients currently
978  * only occurs through the temperature dependence of the Debye constant.
979  *
980  * @param hbar Output vector of species partial molar enthalpies.
981  * Length: m_kk. units are J/kmol.
982  */
983  virtual void getPartialMolarEnthalpies(doublereal* hbar) const;
984 
985  //! Returns an array of partial molar entropies of the species in the
986  //! solution. Units: J/kmol/K.
987  /**
988  * Maxwell's equations provide an insight in how to calculate this
989  * (p.215 Smith and Van Ness)
990  * \f[
991  * \frac{d\mu_i}{dT} = -\bar{s}_i
992  * \f]
993  *
994  * For this phase, the partial molar entropies are equal to the
995  * SS species entropies plus the ideal solution contribution.following
996  * contribution:
997  * \f[
998  * \bar s_k(T,P) = \hat s^0_k(T) - R log(M0 * molality[k])
999  * \f]
1000  * \f[
1001  * \bar s_{solvent}(T,P) = \hat s^0_{solvent}(T)
1002  * - R ((xmolSolvent - 1.0) / xmolSolvent)
1003  * \f]
1004  *
1005  * The reference-state pure-species entropies,\f$ \hat s^0_k(T) \f$,
1006  * at the reference pressure, \f$ P_{ref} \f$, are computed by the
1007  * species thermodynamic
1008  * property manager. They are polynomial functions of temperature.
1009  * @see SpeciesThermo
1010  *
1011  * @param sbar Output vector of species partial molar entropies.
1012  * Length = m_kk. units are J/kmol/K.
1013  */
1014  virtual void getPartialMolarEntropies(doublereal* sbar) const;
1015 
1016  //! Return an array of partial molar heat capacities for the
1017  //! species in the mixture. Units: J/kmol/K
1018  /*!
1019  * @param cpbar Output vector of species partial molar heat
1020  * capacities at constant pressure.
1021  * Length = m_kk. units are J/kmol/K.
1022  */
1023  virtual void getPartialMolarCp(doublereal* cpbar) const;
1024 
1025  //! Return an array of partial molar volumes for the
1026  //! species in the mixture. Units: m^3/kmol.
1027  /*!
1028  * For this solution, the partial molar volumes are normally
1029  * equal to theconstant species molar volumes, except
1030  * when the activity coefficients depend on pressure.
1031  *
1032  * The general relation is
1033  *
1034  * vbar_i = d(chemPot_i)/dP at const T, n
1035  * = V0_i + d(Gex)/dP)_T,M
1036  * = V0_i + RT d(lnActCoeffi)dP _T,M
1037  *
1038  * @param vbar Output vector of species partial molar volumes.
1039  * Length = m_kk. units are m^3/kmol.
1040  */
1041  virtual void getPartialMolarVolumes(doublereal* vbar) const;
1042 
1043  //@}
1044 
1045 protected:
1046  /**
1047  * @name Chemical Equilibrium
1048  * @{
1049  */
1050 
1051  //!This method is used by the ChemEquil equilibrium solver.
1052  /*!
1053  * It sets the state such that the chemical potentials satisfy
1054  * \f[ \frac{\mu_k}{\hat R T} = \sum_m A_{k,m}
1055  * \left(\frac{\lambda_m} {\hat R T}\right) \f] where
1056  * \f$ \lambda_m \f$ is the element potential of element m. The
1057  * temperature is unchanged. Any phase (ideal or not) that
1058  * implements this method can be equilibrated by ChemEquil.
1059  *
1060  * @param lambda_RT Input vector of dimensionless element potentials
1061  * The length is equal to nElements().
1062  */
1063 public:
1064  virtual void setToEquilState(const doublereal* lambda_RT) {
1065  err("setToEquilState");
1066  }
1067 
1068  //@}
1069 
1070  //! Set the equation of state parameters
1071  /*!
1072  * @internal
1073  * The number and meaning of these depends on the subclass.
1074  *
1075  * @param n number of parameters
1076  * @param c array of \a n coefficients
1077  * @deprecated Unimplemented
1078  */
1079  virtual void setParameters(int n, doublereal* const c);
1080 
1081  //! Get the equation of state parameters in a vector
1082  /*!
1083  * @internal
1084  * The number and meaning of these depends on the subclass.
1085  *
1086  * @param n number of parameters
1087  * @param c array of \a n coefficients
1088  * @deprecated Unimplemented
1089  */
1090  virtual void getParameters(int& n, doublereal* const c) const;
1091 
1092  //! Set equation of state parameter values from XML entries.
1093  /*!
1094  *
1095  * This method is called by function importPhase() in
1096  * file importCTML.cpp when processing a phase definition in
1097  * an input file. It should be overloaded in subclasses to set
1098  * any parameters that are specific to that particular phase
1099  * model. Note, this method is called before the phase is
1100  * initialized with elements and/or species.
1101  *
1102  * HKM -> Right now, the parameters are set elsewhere (initThermoXML)
1103  * It just didn't seem to fit.
1104  *
1105  * @param eosdata An XML_Node object corresponding to
1106  * the "thermo" entry for this phase in the input file.
1107  */
1108  virtual void setParametersFromXML(const XML_Node& eosdata);
1109 
1110  /// @name Saturation properties.
1111  /// These methods are only implemented by subclasses that
1112  /// implement full liquid-vapor equations of state.
1113  ///
1114  virtual doublereal satTemperature(doublereal p) const {
1115  err("satTemperature");
1116  return -1.0;
1117  }
1118 
1119  //! Get the saturation pressure for a given temperature.
1120  /*!
1121  * Note the limitations of this function. Stability considerations
1122  * concerning multiphase equilibrium are ignored in this
1123  * calculation. Therefore, the call is made directly to the SS of
1124  * water underneath. The object is put back into its original
1125  * state at the end of the call.
1126  *
1127  * @todo This is probably not implemented correctly. The stability
1128  * of the salt should be added into this calculation. The
1129  * underlying water model may be called to get the stability
1130  * of the pure water solution, if needed.
1131  *
1132  * @param T Temperature (kelvin)
1133  */
1134  virtual doublereal satPressure(doublereal T) {
1135  err("satPressure");
1136  return -1.0;
1137  }
1138 
1139  virtual doublereal vaporFraction() const {
1140  err("vaprFraction");
1141  return -1.0;
1142  }
1143 
1144  virtual void setState_Tsat(doublereal t, doublereal x) {
1145  err("setState_sat");
1146  }
1147 
1148  virtual void setState_Psat(doublereal p, doublereal x) {
1149  err("setState_sat");
1150  }
1151 
1152  //@}
1153 
1154  /*
1155  * -------------- Utilities -------------------------------
1156  */
1157 
1158  //! Initialize the object's internal lengths after species are set
1159  /**
1160  * @internal Initialize. This method is provided to allow
1161  * subclasses to perform any initialization required after all
1162  * species have been added. For example, it might be used to
1163  * resize internal work arrays that must have an entry for
1164  * each species. The base class implementation does nothing,
1165  * and subclasses that do not require initialization do not
1166  * need to overload this method. When importing a CTML phase
1167  * description, this method is called just prior to returning
1168  * from function importPhase().
1169  *
1170  * Cascading call sequence downwards starting with Parent.
1171  *
1172  * @internal
1173  *
1174  * @see importCTML.cpp
1175  */
1176  virtual void initThermo();
1177 
1178  //! Process the XML file after species are set up.
1179  /*!
1180  * This gets called from importPhase(). It processes the XML file
1181  * after the species are set up. This is the main routine for
1182  * reading in activity coefficient parameters.
1183  *
1184  * @param phaseNode This object must be the phase node of a
1185  * complete XML tree
1186  * description of the phase, including all of the
1187  * species data. In other words while "phase" must
1188  * point to an XML phase object, it must have
1189  * sibling nodes "speciesData" that describe
1190  * the species in the phase.
1191  * @param id ID of the phase. If nonnull, a check is done
1192  * to see if phaseNode is pointing to the phase
1193  * with the correct id.
1194  */
1195  virtual void initThermoXML(XML_Node& phaseNode, const std::string& id);
1196 
1197  //! Return the Debye Huckel constant as a function of temperature
1198  //! and pressure (Units = sqrt(kg/gmol))
1199  /*!
1200  * The default is to assume that it is constant, given
1201  * in the initialization process, and stored in the
1202  * member double, m_A_Debye. Optionally, a full water treatment may be employed that makes
1203  * \f$ A_{Debye} \f$ a full function of T and P.
1204  *
1205  * \f[
1206  * A_{Debye} = \frac{F e B_{Debye}}{8 \pi \epsilon R T} {\left( C_o \tilde{M}_o \right)}^{1/2}
1207  * \f]
1208  * where
1209  * \f[
1210  * B_{Debye} = \frac{F} {{(\frac{\epsilon R T}{2})}^{1/2}}
1211  * \f]
1212  * Therefore:
1213  * \f[
1214  * A_{Debye} = \frac{1}{8 \pi}
1215  * {\left(\frac{2 N_a \rho_o}{1000}\right)}^{1/2}
1216  * {\left(\frac{N_a e^2}{\epsilon R T }\right)}^{3/2}
1217  * \f]
1218  *
1219  * where
1220  * - Units = sqrt(kg/gmol)
1221  * - \f$ N_a \f$ is Avogadro's number
1222  * - \f$ \rho_w \f$ is the density of water
1223  * - \f$ e \f$ is the electronic charge
1224  * - \f$ \epsilon = K \epsilon_o \f$ is the permittivity of water
1225  * - \f$ K \f$ is the dielectric constant of water,
1226  * - \f$ \epsilon_o \f$ is the permittivity of free space.
1227  * - \f$ \rho_o \f$ is the density of the solvent in its standard state.
1228  *
1229  * Nominal value at 298 K and 1 atm = 1.172576 (kg/gmol)<SUP>1/2</SUP>
1230  * based on:
1231  * - \f$ \epsilon / \epsilon_0 \f$ = 78.54 (water at 25C)
1232  * - T = 298.15 K
1233  * - B_Debye = 3.28640E9 (kg/gmol)<SUP>1/2</SUP> m<SUP>-1</SUP>
1234  *
1235  * @param temperature Temperature in kelvin. Defaults to -1, in which
1236  * case the temperature of the phase is assumed.
1237  *
1238  * @param pressure Pressure (Pa). Defaults to -1, in which
1239  * case the pressure of the phase is assumed.
1240  */
1241  virtual double A_Debye_TP(double temperature = -1.0,
1242  double pressure = -1.0) const;
1243 
1244  //! Value of the derivative of the Debye Huckel constant with
1245  //! respect to temperature.
1246  /*!
1247  * This is a function of temperature and pressure. See A_Debye_TP() for
1248  * a definition of \f$ A_{Debye} \f$.
1249  *
1250  * Units = sqrt(kg/gmol) K-1
1251  *
1252  * @param temperature Temperature in kelvin. Defaults to -1, in which
1253  * case the temperature of the phase is assumed.
1254  *
1255  * @param pressure Pressure (Pa). Defaults to -1, in which
1256  * case the pressure of the phase is assumed.
1257  */
1258  virtual double dA_DebyedT_TP(double temperature = -1.0,
1259  double pressure = -1.0) const;
1260 
1261  //! Value of the 2nd derivative of the Debye Huckel constant with
1262  //! respect to temperature as a function of temperature and pressure.
1263  /*!
1264  * This is a function of temperature and pressure. See A_Debye_TP() for
1265  * a definition of \f$ A_{Debye} \f$.
1266  *
1267  * Units = sqrt(kg/gmol) K-2
1268  *
1269  * @param temperature Temperature in kelvin. Defaults to -1, in which
1270  * case the temperature of the phase is assumed.
1271  *
1272  * @param pressure Pressure (Pa). Defaults to -1, in which
1273  * case the pressure of the phase is assumed.
1274  */
1275  virtual double d2A_DebyedT2_TP(double temperature = -1.0,
1276  double pressure = -1.0) const;
1277 
1278  //! Value of the derivative of the Debye Huckel constant with
1279  //! respect to pressure, as a function of temperature and pressure.
1280  /*!
1281  * This is a function of temperature and pressure. See A_Debye_TP() for
1282  * a definition of \f$ A_{Debye} \f$.
1283  *
1284  * Units = sqrt(kg/gmol) Pa-1
1285  *
1286  * @param temperature Temperature in kelvin. Defaults to -1, in which
1287  * case the temperature of the phase is assumed.
1288  *
1289  * @param pressure Pressure (Pa). Defaults to -1, in which
1290  * case the pressure of the phase is assumed.
1291  */
1292  virtual double dA_DebyedP_TP(double temperature = -1.0,
1293  double pressure = -1.0) const;
1294 
1295  //!Reports the ionic radius of the kth species
1296  /*!
1297  * @param k species index.
1298  */
1299  double AionicRadius(int k = 0) const;
1300 
1301  //! Returns the form of the Debye-Huckel parameterization used
1302  int formDH() const {
1303  return m_formDH;
1304  }
1305 
1306  //! Returns a reference to M_Beta_ij
1308  return m_Beta_ij;
1309  }
1310 
1311 private:
1312  //! Static function that implements the non-polar species
1313  //! salt-out modifications.
1314  /*!
1315  * Returns the calculated activity coefficients.
1316  *
1317  * @param IionicMolality Value of the ionic molality (sqrt(gmol/kg))
1318  */
1319  double _nonpolarActCoeff(double IionicMolality) const;
1320 
1321  //! Formula for the osmotic coefficient that occurs in the GWB.
1322  /*!
1323  * It is originally from Helgeson for a variable
1324  * NaCl brine. It's to be used with extreme caution.
1325  */
1326  double _osmoticCoeffHelgesonFixedForm() const;
1327 
1328  //! Formula for the log of the water activity that occurs in the GWB.
1329  /*!
1330  * It is originally from Helgeson for a variable
1331  * NaCl brine. It's to be used with extreme caution.
1332  */
1333  double _lnactivityWaterHelgesonFixedForm() const;
1334  //@}
1335 
1336 protected:
1337 
1338 
1339  //! form of the Debye-Huckel parameterization used in the model.
1340  /*!
1341  * The options are described at the top of this document,
1342  * and in the general documentation.
1343  * The list is repeated here:
1344  *
1345  * DHFORM_DILUTE_LIMIT = 0 (default)
1346  * DHFORM_BDOT_AK = 1
1347  * DHFORM_BDOT_AUNIFORM = 2
1348  * DHFORM_BETAIJ = 3
1349  * DHFORM_PITZER_BETAIJ = 4
1350  */
1352 
1353  /**
1354  * Format for the generalized concentration:
1355  *
1356  * 0 = unity
1357  * 1 = molar_volume
1358  * 2 = solvent_volume (default)
1359  *
1360  * The generalized concentrations can have three different forms
1361  * depending on the value of the member attribute m_formGC, which
1362  * is supplied in the constructor.
1363  * <TABLE>
1364  * <TR><TD> m_formGC </TD><TD> GeneralizedConc </TD><TD> StandardConc </TD></TR>
1365  * <TR><TD> 0 </TD><TD> X_k </TD><TD> 1.0 </TD></TR>
1366  * <TR><TD> 1 </TD><TD> X_k / V_k </TD><TD> 1.0 / V_k </TD></TR>
1367  * <TR><TD> 2 </TD><TD> X_k / V_N </TD><TD> 1.0 / V_N </TD></TR>
1368  * </TABLE>
1369  *
1370  * The value and form of the generalized concentration will affect
1371  * reaction rate constants involving species in this phase.
1372  *
1373  * (HKM Note: Using option #1 may lead to spurious results and
1374  * has been included only with warnings. The reason is that it
1375  * molar volumes of electrolytes may often be negative. The
1376  * molar volume of H+ is defined to be zero too. Either options
1377  * 0 or 2 are the appropriate choice. Option 0 leads to
1378  * bulk reaction rate constants which have units of s-1.
1379  * Option 2 leads to bulk reaction rate constants for
1380  * bimolecular rxns which have units of m-3 kmol-1 s-1.)
1381  */
1383 
1384  //! Vector containing the electrolyte species type
1385  /*!
1386  * The possible types are:
1387  * - solvent
1388  * - Charged Species
1389  * - weakAcidAssociated
1390  * - strongAcidAssociated
1391  * - polarNeutral
1392  * - nonpolarNeutral
1393  * .
1394  */
1396 
1397  /**
1398  * a_k = Size of the ionic species in the DH formulation
1399  * units = meters
1400  */
1402 
1403  //! Current value of the ionic strength on the molality scale
1404  mutable double m_IionicMolality;
1405 
1406  /**
1407  * Maximum value of the ionic strength allowed in the
1408  * calculation of the activity coefficients.
1409  */
1411 
1412 public:
1413 
1414  /**
1415  * If true, then the fixed for of Helgeson's activity
1416  * for water is used instead of the rigorous form
1417  * obtained from Gibbs-Duhem relation. This should be
1418  * used with caution, and is really only included as a
1419  * validation exercise.
1420  */
1422 protected:
1423 
1424  //! Stoichiometric ionic strength on the molality scale
1425  mutable double m_IionicMolalityStoich;
1426 
1427 public:
1428 
1429  /**
1430  * Form of the constant outside the Debye-Huckel term
1431  * called A. It's normally a function of temperature
1432  * and pressure. However, it can be set from the
1433  * input file in order to aid in numerical comparisons.
1434  * Acceptable forms:
1435  *
1436  * A_DEBYE_CONST 0
1437  * A_DEBYE_WATER 1
1438  *
1439  * The A_DEBYE_WATER form may be used for water solvents
1440  * with needs to cover varying temperatures and pressures.
1441  * Note, the dielectric constant of water is a relatively
1442  * strong function of T, and its variability must be
1443  * accounted for,
1444  */
1446 
1447 protected:
1448 
1449  //! Current value of the Debye Constant, A_Debye
1450  /**
1451  * A_Debye -> this expression appears on the top of the
1452  * ln actCoeff term in the general Debye-Huckel
1453  * expression
1454  * It depends on temperature and pressure.
1455  *
1456  * A_Debye = (F e B_Debye) / (8 Pi epsilon R T)
1457  *
1458  * Units = sqrt(kg/gmol)
1459  *
1460  * Nominal value(298K, atm) = 1.172576 sqrt(kg/gmol)
1461  * based on:
1462  * epsilon/epsilon_0 = 78.54
1463  * (water at 25C)
1464  * T = 298.15 K
1465  * B_Debye = 3.28640E9 sqrt(kg/gmol)/m
1466  *
1467  * note in Pitzer's nomenclature, A_phi = A_Debye/3.0
1468  */
1469  mutable double m_A_Debye;
1470 
1471  //! Current value of the constant that appears in the denominator
1472  /**
1473  * B_Debye -> this expression appears on the bottom of the
1474  * ln actCoeff term in the general Debye-Huckel
1475  * expression
1476  * It depends on temperature
1477  *
1478  * B_Bebye = F / sqrt( epsilon R T / 2 )
1479  *
1480  * Units = sqrt(kg/gmol) / m
1481  *
1482  * Nominal value = 3.28640E9 sqrt(kg/gmol) / m
1483  * based on:
1484  * epsilon/epsilon_0 = 78.54
1485  * (water at 25C)
1486  * T = 298.15 K
1487  */
1488  double m_B_Debye;
1489 
1490  //! Array of B_Dot values
1491  /**
1492  * This expression is an extension of the Debye-Huckel expression used
1493  * in some formulations to extend DH to higher molalities. B_dot is
1494  * specific to the major ionic pair.
1495  */
1497 
1498  /**
1499  * These are coefficients to describe the increase in activity coeff for
1500  * non-polar molecules due to the electrolyte becoming stronger (the
1501  * so-called salt-out effect)
1502  */
1504 
1505 
1506  //! Pointer to the Water standard state object
1507  /*!
1508  * derived from the equation of state for water.
1509  */
1511 
1512  //! Storage for the density of water's standard state
1513  /*!
1514  * Density depends on temperature and pressure.
1515  */
1517 
1518  //! Pointer to the water property calculator
1520 
1521  //! Temporary array used in equilibrium calculations
1522  mutable vector_fp m_pp;
1523 
1524  //! vector of size m_kk, used as a temporary holding area.
1526 
1527  /**
1528  * Stoichiometric species charge -> This is for calculations
1529  * of the ionic strength which ignore ion-ion pairing into
1530  * neutral molecules. The Stoichiometric species charge is the
1531  * charge of one of the ion that would occur if the species broke
1532  * into two charged ion pairs.
1533  * NaCl -> m_speciesCharge_Stoich = -1;
1534  * HSO4- -> H+ + SO42- = -2
1535  * -> The other charge is calculated.
1536  * For species that aren't ion pairs, it's equal to the
1537  * m_speciesCharge[] value.
1538  */
1540 
1541  /**
1542  * Array of 2D data used in the DHFORM_BETAIJ formulation
1543  * Beta_ij.value(i,j) is the coefficient of the jth species
1544  * for the specification of the chemical potential of the ith
1545  * species.
1546  */
1548 
1549  //! Logarithm of the activity coefficients on the molality scale.
1550  /*!
1551  * mutable because we change this if the composition
1552  * or temperature or pressure changes.
1553  */
1555 
1556  //! Derivative of log act coeff wrt T
1558 
1559  //! 2nd Derivative of log act coeff wrt T
1561 
1562  //! Derivative of log act coeff wrt P
1564 
1565 private:
1566 
1567  //! Bail out of functions with an error exit if they are not implemented.
1568  doublereal err(const std::string& msg) const;
1569 
1570  //! Initialize the internal lengths.
1571  /*!
1572  * This internal function adjusts the lengths of arrays based on
1573  * the number of species.
1574  */
1575  void initLengths();
1576 
1577 private:
1578  //! Calculate the log activity coefficients
1579  /*!
1580  * This function updates the internally stored natural logarithm of the
1581  * molality activity coefficients. This is the main routine for
1582  * implementing the activity coefficient formulation.
1583  */
1584  void s_update_lnMolalityActCoeff() const;
1585 
1586  //! Calculation of temperature derivative of activity coefficient
1587  /*!
1588  * Using internally stored values, this function calculates
1589  * the temperature derivative of the logarithm of the
1590  * activity coefficient for all species in the mechanism.
1591  *
1592  * We assume that the activity coefficients are current in this routine
1593  *
1594  * The solvent activity coefficient is on the molality scale. Its derivative is too.
1595  */
1596  void s_update_dlnMolalityActCoeff_dT() const;
1597 
1598  //! Calculate the temperature 2nd derivative of the activity coefficient
1599  /*!
1600  * Using internally stored values, this function calculates
1601  * the temperature 2nd derivative of the logarithm of the
1602  * activity coefficient for all species in the mechanism.
1603  *
1604  * We assume that the activity coefficients are current in this routine
1605  *
1606  * solvent activity coefficient is on the molality
1607  * scale. Its derivatives are too.
1608  */
1609  void s_update_d2lnMolalityActCoeff_dT2() const;
1610 
1611  //! Calculate the pressure derivative of the activity coefficient
1612  /*!
1613  * Using internally stored values, this function calculates
1614  * the pressure derivative of the logarithm of the
1615  * activity coefficient for all species in the mechanism.
1616  *
1617  * We assume that the activity coefficients, molalities,
1618  * and A_Debye are current.
1619  *
1620  * solvent activity coefficient is on the molality
1621  * scale. Its derivatives are too.
1622  */
1623  void s_update_dlnMolalityActCoeff_dP() const;
1624 };
1625 
1626 }
1627 
1628 #endif
double m_IionicMolalityStoich
Stoichiometric ionic strength on the molality scale.
Definition: DebyeHuckel.h:1425
void s_update_d2lnMolalityActCoeff_dT2() const
Calculate the temperature 2nd derivative of the activity coefficient.
double _lnactivityWaterHelgesonFixedForm() const
Formula for the log of the water activity that occurs in the GWB.
int m_form_A_Debye
Form of the constant outside the Debye-Huckel term called A.
Definition: DebyeHuckel.h:1445
virtual double A_Debye_TP(double temperature=-1.0, double pressure=-1.0) const
Return the Debye Huckel constant as a function of temperature and pressure (Units = sqrt(kg/gmol)) ...
virtual void getPartialMolarCp(doublereal *cpbar) const
Return an array of partial molar heat capacities for the species in the mixture.
virtual doublereal satPressure(doublereal T)
Get the saturation pressure for a given temperature.
Definition: DebyeHuckel.h:1134
virtual doublereal vaporFraction() const
Return the fraction of vapor at the current conditions.
Definition: DebyeHuckel.h:1139
virtual doublereal pressure() const
Return the thermodynamic pressure (Pa).
vector_fp m_dlnActCoeffMolaldT
Derivative of log act coeff wrt T.
Definition: DebyeHuckel.h:1557
virtual doublereal isothermalCompressibility() const
The isothermal compressibility.
virtual void getActivityConcentrations(doublereal *c) const
This method returns an array of generalized concentrations.
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
ThermoPhase * duplMyselfAsThermoPhase() const
Duplicator from the ThermoPhase parent class.
Header file for a common definitions used in electrolytes thermodynamics.
virtual doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:100
virtual void initThermo()
Initialize the object's internal lengths after species are set.
virtual void setParameters(int n, doublereal *const c)
Set the equation of state parameters.
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...
bool m_useHelgesonFixedForm
If true, then the fixed for of Helgeson's activity for water is used instead of the rigorous form obt...
Definition: DebyeHuckel.h:1421
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...
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
doublereal err(const std::string &msg) const
Bail out of functions with an error exit if they are not implemented.
int formDH() const
Returns the form of the Debye-Huckel parameterization used.
Definition: DebyeHuckel.h:1302
virtual doublereal gibbs_mole() const
Molar Gibbs function. Units: J/kmol.
void setDensity(const doublereal rho)
Set the internally stored density (gm/m^3) of the phase.
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
virtual void setState_TP(doublereal t, doublereal p)
Set the temperature (K) and pressure (Pa)
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...
DebyeHuckel()
Default Constructor.
Definition: DebyeHuckel.cpp:31
virtual int eosType() const
Equation of state type flag.
Class DebyeHuckel represents a dilute liquid electrolyte phase which obeys the Debye Huckel formulati...
Definition: DebyeHuckel.h:600
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:101
virtual void setTemperature(const doublereal temp)
Set the temperature (K)
Header file for class Cantera::Array2D.
std::vector< int > vector_int
Vector of ints.
Definition: ct_defs.h:167
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. ...
virtual void setToEquilState(const doublereal *lambda_RT)
This method is used by the ChemEquil equilibrium solver.
Definition: DebyeHuckel.h:1064
virtual void getParameters(int &n, doublereal *const c) const
Get the equation of state parameters in a vector.
The WaterProps class is used to house several approximation routines for properties of water...
Definition: WaterProps.h:96
virtual void setState_Tsat(doublereal t, doublereal x)
Set the state to a saturated system at a particular temperature.
Definition: DebyeHuckel.h:1144
Array2D m_Beta_ij
Array of 2D data used in the DHFORM_BETAIJ formulation Beta_ij.value(i,j) is the coefficient of the j...
Definition: DebyeHuckel.h:1547
void s_update_lnMolalityActCoeff() const
Calculate the log activity coefficients.
vector_fp m_Aionic
a_k = Size of the ionic species in the DH formulation units = meters
Definition: DebyeHuckel.h:1401
Class for the liquid water pressure dependent standard state.
Definition: PDSS_Water.h:54
double _nonpolarActCoeff(double IionicMolality) const
Static function that implements the non-polar species salt-out modifications.
double m_maxIionicStrength
Maximum value of the ionic strength allowed in the calculation of the activity coefficients.
Definition: DebyeHuckel.h:1410
int m_formDH
form of the Debye-Huckel parameterization used in the model.
Definition: DebyeHuckel.h:1351
double m_A_Debye
Current value of the Debye Constant, A_Debye.
Definition: DebyeHuckel.h:1469
vector_fp m_lnActCoeffMolal
Logarithm of the activity coefficients on the molality scale.
Definition: DebyeHuckel.h:1554
virtual void setState_Psat(doublereal p, doublereal x)
Set the state to a saturated system at a particular pressure.
Definition: DebyeHuckel.h:1148
PDSS_Water * m_waterSS
Pointer to the Water standard state object.
Definition: DebyeHuckel.h:1510
vector_fp m_B_Dot
Array of B_Dot values.
Definition: DebyeHuckel.h:1496
virtual doublereal logStandardConc(size_t k=0) const
Natural logarithm of the standard concentration of the kth species.
Array2D & get_Beta_ij()
Returns a reference to M_Beta_ij.
Definition: DebyeHuckel.h:1307
int m_formGC
Format for the generalized concentration:
Definition: DebyeHuckel.h:1382
double _osmoticCoeffHelgesonFixedForm() const
Formula for the osmotic coefficient that occurs in the GWB.
virtual doublereal enthalpy_mole() const
Molar enthalpy of the solution. Units: J/kmol.
void initLengths()
Initialize the internal lengths.
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies of the species in the solution.
virtual void setParametersFromXML(const XML_Node &eosdata)
Set equation of state parameter values from XML entries.
virtual void calcDensity()
Calculate the density of the mixture using the partial molar volumes and mole fractions as input...
DebyeHuckel & operator=(const DebyeHuckel &)
Assignment operator.
vector_int m_electrolyteSpeciesType
Vector containing the electrolyte species type.
Definition: DebyeHuckel.h:1395
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
void s_update_dlnMolalityActCoeff_dT() const
Calculation of temperature derivative of activity coefficient.
vector_fp m_speciesCharge_Stoich
Stoichiometric species charge -> This is for calculations of the ionic strength which ignore ion-ion ...
Definition: DebyeHuckel.h:1539
virtual doublereal intEnergy_mole() const
Molar internal energy of the solution. Units: J/kmol.
double m_IionicMolality
Current value of the ionic strength on the molality scale.
Definition: DebyeHuckel.h:1404
doublereal temperature() const
Temperature (K).
Definition: Phase.h:528
double AionicRadius(int k=0) const
Reports the ionic radius of the kth species.
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
vector_fp m_npActCoeff
These are coefficients to describe the increase in activity coeff for non-polar molecules due to the ...
Definition: DebyeHuckel.h:1503
vector_fp m_d2lnActCoeffMolaldT2
2nd Derivative of log act coeff wrt T
Definition: DebyeHuckel.h:1560
vector_fp m_tmpV
vector of size m_kk, used as a temporary holding area.
Definition: DebyeHuckel.h:1525
vector_fp m_pp
Temporary array used in equilibrium calculations.
Definition: DebyeHuckel.h:1522
double m_B_Debye
Current value of the constant that appears in the denominator.
Definition: DebyeHuckel.h:1488
void s_update_dlnMolalityActCoeff_dP() const
Calculate the pressure derivative of the activity coefficient.
WaterProps * m_waterProps
Pointer to the water property calculator.
Definition: DebyeHuckel.h:1519
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Process the XML file after species are set up.
virtual doublereal standardConcentration(size_t k=0) const
Return the standard concentration for the kth species.
virtual void getActivities(doublereal *ac) const
Get the array of non-dimensional activities at the current solution temperature, pressure, and solution concentration.
vector_fp m_dlnActCoeffMolaldP
Derivative of log act coeff wrt P.
Definition: DebyeHuckel.h:1563
virtual void getMolalityActivityCoefficients(doublereal *acMolality) const
Get the array of non-dimensional molality-based activity coefficients at the current solution tempera...
virtual void getUnitsStandardConc(double *uA, int k=0, int sizeUA=6) const
Returns the units of the standard and generalized concentrations.
virtual ~DebyeHuckel()
Destructor.
virtual doublereal thermalExpansionCoeff() const
The thermal expansion coefficient.
virtual doublereal satTemperature(doublereal p) const
Return the saturation temperature given the pressure.
Definition: DebyeHuckel.h:1114
virtual void setPressure(doublereal p)
Set the internally stored pressure (Pa) at constant temperature and composition.
double m_densWaterSS
Storage for the density of water's standard state.
Definition: DebyeHuckel.h:1516
virtual void setMolarDensity(const doublereal conc)
Set the internally stored molar density (kmol/m^3) of the phase.