Cantera  2.0
MixedSolventElectrolyte.h
1 /**
2  * @file MargulesVPSSTP.h
3  * Header for intermediate ThermoPhase object for phases which
4  * employ gibbs excess free energy based formulations
5  * (see \ref thermoprops
6  * and class \link Cantera::MargulesVPSSTP MargulesVPSSTP\endlink).
7  *
8  * Header file for a derived class of ThermoPhase that handles
9  * variable pressure standard state methods for calculating
10  * thermodynamic properties that are further based upon activities
11  * based on the molality scale. These include most of the methods for
12  * calculating liquid electrolyte thermodynamics.
13  */
14 /*
15  * Copyright (2006) Sandia Corporation. Under the terms of
16  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
17  * U.S. Government retains certain rights in this software.
18  */
19 
20 #ifndef CT_MIXEDSOLVENTELECTROLYTEVPSSTP_H
21 #define CT_MIXEDSOLVENTELECTROLYTEVPSSTP_H
22 
23 #include "MolarityIonicVPSSTP.h"
24 
25 namespace Cantera
26 {
27 
28 /**
29  * @ingroup thermoprops
30  */
31 
32 
33 //! MixedSolventElectrolyte is a derived class of GibbsExcessVPSSTP that employs
34 //! the DH and local Marguless approximations for the excess gibbs free energy
35 /*!
36  *
37  * %MargulesVPSSTP derives from class GibbsExcessVPSSTP which is derived
38  * from VPStandardStateTP,
39  * and overloads the virtual methods defined there with ones that
40  * use expressions appropriate for the Margules Excess gibbs free energy
41  * approximation.
42  *
43  * The independent unknowns are pressure, temperature, and mass fraction.
44  *
45  * Several concepts are introduced. The first concept is there are temporary
46  * variables for holding the species standard state values
47  * of Cp, H, S, G, and V at the
48  * last temperature and pressure called. These functions are not recalculated
49  * if a new call is made using the previous temperature and pressure. Currently,
50  * these variables and the calculation method are handled by the VPSSMgr class,
51  * for which VPStandardStateTP owns a pointer to.
52  *
53  * To support the above functionality, pressure and temperature variables,
54  * m_plast_ss and m_tlast_ss, are kept which store the last pressure and temperature
55  * used in the evaluation of standard state properties.
56  *
57  * This class is usually used for nearly incompressible phases. For those phases, it
58  * makes sense to change the equation of state independent variable from
59  * density to pressure. The variable m_Pcurrent contains the current value of the
60  * pressure within the phase.
61  *
62  *
63  * <HR>
64  * <H2> Specification of Species Standard %State Properties </H2>
65  * <HR>
66  *
67  * All species are defined to have standard states that depend upon both
68  * the temperature and the pressure. The Margules approximation assumes
69  * symmetric standard states, where all of the standard state assume
70  * that the species are in pure component states at the temperature
71  * and pressure of the solution. I don't think it prevents, however,
72  * some species from being dilute in the solution.
73  *
74  *
75  * <HR>
76  * <H2> Specification of Solution Thermodynamic Properties </H2>
77  * <HR>
78  *
79  * The molar excess Gibbs free energy is given by the following formula which is a sum over interactions <I>i</I>.
80  * Each of the interactions are binary interactions involving two of the species in the phase, denoted, <I>Ai</I>
81  * and <I>Bi</I>.
82  * This is the generalization of the Margules formulation for a phase
83  * that has more than 2 species.
84  *
85  * \f[
86  * G^E = \sum_i \left( H_{Ei} - T S_{Ei} \right)
87  * \f]
88  * \f[
89  * H^E_i = n X_{Ai} X_{Bi} \left( h_{o,i} + h_{1,i} X_{Bi} \right)
90  * \f]
91  * \f[
92  * S^E_i = n X_{Ai} X_{Bi} \left( s_{o,i} + s_{1,i} X_{Bi} \right)
93  * \f]
94  *
95  * where n is the total moles in the solution.
96  *
97  * The activity of a species defined in the phase is given by an excess
98  * Gibbs free energy formulation.
99  *
100  * \f[
101  * a_k = \gamma_k X_k
102  * \f]
103  *
104  * where
105  *
106  * \f[
107  * R T \ln( \gamma_k )= \frac{d(n G^E)}{d(n_k)}\Bigg|_{n_i}
108  * \f]
109  *
110  * Taking the derivatives results in the following expression
111  *
112  * \f[
113  * R T \ln( \gamma_k )= \sum_i \left( \left( \delta_{Ai,k} X_{Bi} + \delta_{Bi,k} X_{Ai} - X_{Ai} X_{Bi} \right)
114  * \left( g^E_{o,i} + g^E_{1,i} X_{Bi} \right) +
115  * \left( \delta_{Bi,k} - X_{Bi} \right) X_{Ai} X_{Bi} g^E_{1,i} \right)
116  * \f]
117  * where
118  * \f$ g^E_{o,i} = h_{o,i} - T s_{o,i} \f$ and \f$ g^E_{1,i} = h_{1,i} - T s_{1,i} \f$
119  * and where \f$ X_k \f$ is the mole fraction of species <I>k</I>.
120  *
121  * This object inherits from the class VPStandardStateTP. Therefore, the specification and
122  * calculation of all standard state and reference state values are handled at that level. Various functional
123  * forms for the standard state are permissible.
124  * The chemical potential for species <I>k</I> is equal to
125  *
126  * \f[
127  * \mu_k(T,P) = \mu^o_k(T, P) + R T \ln(\gamma_k X_k)
128  * \f]
129  *
130  * The partial molar entropy for species <I>k</I> is given by the following relation,
131  *
132  * \f[
133  * \tilde{s}_k(T,P) = s^o_k(T,P) - R \ln( \gamma_k X_k )
134  * - R T \frac{d \ln(\gamma_k) }{dT}
135  * \f]
136  *
137  * The partial molar enthalpy for species <I>k</I> is given by
138  *
139  * \f[
140  * \tilde{h}_k(T,P) = h^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT}
141  * \f]
142  *
143  * The partial molar volume for species <I>k</I> is
144  *
145  * \f[
146  * \tilde V_k(T,P) = V^o_k(T,P) + R T \frac{d \ln(\gamma_k) }{dP}
147  * \f]
148  *
149  * The partial molar Heat Capacity for species <I>k</I> is
150  *
151  * \f[
152  * \tilde{C}_{p,k}(T,P) = C^o_{p,k}(T,P) - 2 R T \frac{d \ln( \gamma_k )}{dT}
153  * - R T^2 \frac{d^2 \ln(\gamma_k) }{{dT}^2}
154  * \f]
155  *
156  * <HR>
157  * <H2> %Application within %Kinetics Managers </H2>
158  * <HR>
159  *
160  * \f$ C^a_k\f$ are defined such that \f$ a_k = C^a_k /
161  * C^s_k, \f$ where \f$ C^s_k \f$ is a standard concentration
162  * defined below and \f$ a_k \f$ are activities used in the
163  * thermodynamic functions. These activity (or generalized)
164  * concentrations are used
165  * by kinetics manager classes to compute the forward and
166  * reverse rates of elementary reactions.
167  * The activity concentration,\f$ C^a_k \f$,is given by the following expression.
168  *
169  * \f[
170  * C^a_k = C^s_k X_k = \frac{P}{R T} X_k
171  * \f]
172  *
173  * The standard concentration for species <I>k</I> is independent of <I>k</I> and equal to
174  *
175  * \f[
176  * C^s_k = C^s = \frac{P}{R T}
177  * \f]
178  *
179  * For example, a bulk-phase binary gas reaction between species j and k, producing
180  * a new gas species l would have the
181  * following equation for its rate of progress variable, \f$ R^1 \f$, which has
182  * units of kmol m-3 s-1.
183  *
184  * \f[
185  * R^1 = k^1 C_j^a C_k^a = k^1 (C^s a_j) (C^s a_k)
186  * \f]
187  * where
188  * \f[
189  * C_j^a = C^s a_j \mbox{\quad and \quad} C_k^a = C^s a_k
190  * \f]
191  *
192  *
193  * \f$ C_j^a \f$ is the activity concentration of species j, and
194  * \f$ C_k^a \f$ is the activity concentration of species k. \f$ C^s \f$
195  * is the standard concentration. \f$ a_j \f$ is
196  * the activity of species j which is equal to the mole fraction of j.
197  *
198  * The reverse rate constant can then be obtained from the law of microscopic reversibility
199  * and the equilibrium expression for the system.
200  *
201  * \f[
202  * \frac{a_j a_k}{ a_l} = K_a^{o,1} = \exp(\frac{\mu^o_l - \mu^o_j - \mu^o_k}{R T} )
203  * \f]
204  *
205  * \f$ K_a^{o,1} \f$ is the dimensionless form of the equilibrium constant, associated with
206  * the pressure dependent standard states \f$ \mu^o_l(T,P) \f$ and their associated activities,
207  * \f$ a_l \f$, repeated here:
208  *
209  * \f[
210  * \mu_l(T,P) = \mu^o_l(T, P) + R T \log(a_l)
211  * \f]
212  *
213  * We can switch over to expressing the equilibrium constant in terms of the reference
214  * state chemical potentials
215  *
216  * \f[
217  * K_a^{o,1} = \exp(\frac{\mu^{ref}_l - \mu^{ref}_j - \mu^{ref}_k}{R T} ) * \frac{P_{ref}}{P}
218  * \f]
219  *
220  * The concentration equilibrium constant, \f$ K_c \f$, may be obtained by changing over
221  * to activity concentrations. When this is done:
222  *
223  * \f[
224  * \frac{C^a_j C^a_k}{ C^a_l} = C^o K_a^{o,1} = K_c^1 =
225  * \exp(\frac{\mu^{ref}_l - \mu^{ref}_j - \mu^{ref}_k}{R T} ) * \frac{P_{ref}}{RT}
226  * \f]
227  *
228  * %Kinetics managers will calculate the concentration equilibrium constant, \f$ K_c \f$,
229  * using the second and third part of the above expression as a definition for the concentration
230  * equilibrium constant.
231  *
232  * For completeness, the pressure equilibrium constant may be obtained as well
233  *
234  * \f[
235  * \frac{P_j P_k}{ P_l P_{ref}} = K_p^1 = \exp(\frac{\mu^{ref}_l - \mu^{ref}_j - \mu^{ref}_k}{R T} )
236  * \f]
237  *
238  * \f$ K_p \f$ is the simplest form of the equilibrium constant for ideal gases. However, it isn't
239  * necessarily the simplest form of the equilibrium constant for other types of phases; \f$ K_c \f$ is
240  * used instead because it is completely general.
241  *
242  * The reverse rate of progress may be written down as
243  * \f[
244  * R^{-1} = k^{-1} C_l^a = k^{-1} (C^o a_l)
245  * \f]
246  *
247  * where we can use the concept of microscopic reversibility to
248  * write the reverse rate constant in terms of the
249  * forward reate constant and the concentration equilibrium
250  * constant, \f$ K_c \f$.
251  *
252  * \f[
253  * k^{-1} = k^1 K^1_c
254  * \f]
255  *
256  * \f$k^{-1} \f$ has units of s-1.
257  *
258  *
259  * <HR>
260  * <H2> Instantiation of the Class </H2>
261  * <HR>
262  *
263  *
264  * The constructor for this phase is located in the default ThermoFactory
265  * for %Cantera. A new %IdealGasPhase may be created by the following code
266  * snippet:
267  *
268  * @code
269  * XML_Node *xc = get_XML_File("silane.xml");
270  * XML_Node * const xs = xc->findNameID("phase", "silane");
271  * ThermoPhase *silane_tp = newPhase(*xs);
272  * IdealGasPhase *silaneGas = dynamic_cast <IdealGasPhase *>(silane_tp);
273  * @endcode
274  *
275  * or by the following constructor:
276  *
277  * @code
278  * XML_Node *xc = get_XML_File("silane.xml");
279  * XML_Node * const xs = xc->findNameID("phase", "silane");
280  * IdealGasPhase *silaneGas = new IdealGasPhase(*xs);
281  * @endcode
282  *
283  * <HR>
284  * <H2> XML Example </H2>
285  * <HR>
286  * An example of an XML Element named phase setting up a IdealGasPhase
287  * object named silane is given below.
288  *
289  *
290  * @verbatim
291  <!-- phase silane -->
292  <phase dim="3" id="silane">
293  <elementArray datasrc="elements.xml"> Si H He </elementArray>
294  <speciesArray datasrc="#species_data">
295  H2 H HE SIH4 SI SIH SIH2 SIH3 H3SISIH SI2H6
296  H2SISIH2 SI3H8 SI2 SI3
297  </speciesArray>
298  <reactionArray datasrc="#reaction_data"/>
299  <thermo model="IdealGas"/>
300  <kinetics model="GasKinetics"/>
301  <transport model="None"/>
302  </phase>
303  @endverbatim
304  *
305  * The model attribute "IdealGas" of the thermo XML element identifies the phase as
306  * being of the type handled by the IdealGasPhase object.
307  *
308  * @ingroup thermoprops
309  *
310 
311 */
313 {
314 
315 public:
316 
317  //! Constructor
318  /*!
319  * This doesn't do much more than initialize constants with
320  * default values for water at 25C. Water molecular weight
321  * comes from the default elements.xml file. It actually
322  * differs slightly from the IAPWS95 value of 18.015268. However,
323  * density conservation and therefore element conservation
324  * is the more important principle to follow.
325  */
327 
328  //! Construct and initialize a MixedSolventElectrolyte ThermoPhase object
329  //! directly from an xml input file
330  /*!
331  * Working constructors
332  *
333  * The two constructors below are the normal way
334  * the phase initializes itself. They are shells that call
335  * the routine initThermo(), with a reference to the
336  * XML database to get the info for the phase.
337  *
338  * @param inputFile Name of the input file containing the phase XML data
339  * to set up the object
340  * @param id ID of the phase in the input file. Defaults to the
341  * empty string.
342  */
343  MixedSolventElectrolyte(std::string inputFile, std::string id = "");
344 
345  //! Construct and initialize a MixedSolventElectrolyte ThermoPhase object
346  //! directly from an XML database
347  /*!
348  * @param phaseRef XML phase node containing the description of the phase
349  * @param id id attribute containing the name of the phase.
350  * (default is the empty string)
351  */
352  MixedSolventElectrolyte(XML_Node& phaseRef, std::string id = "");
353 
354 
355  //! Special constructor for a hard-coded problem
356  /*!
357  *
358  * @param testProb Hard-coded value. Only the value of 1 is
359  * used. It's for
360  * a LiKCl system
361  * -> test to predict the eutectic and liquidus correctly.
362  */
363  MixedSolventElectrolyte(int testProb);
364 
365  //! Copy constructor
366  /*!
367  * Note this stuff will not work until the underlying phase
368  * has a working copy constructor
369  *
370  * @param b class to be copied
371  */
373 
374  //! Assignment operator
375  /*!
376  *
377  * @param b class to be copied.
378  */
380 
381  //! Destructor
382  virtual ~MixedSolventElectrolyte();
383 
384  //! Duplication routine for objects which inherit from ThermoPhase.
385  /*!
386  * This virtual routine can be used to duplicate thermophase objects
387  * inherited from ThermoPhase even if the application only has
388  * a pointer to ThermoPhase to work with.
389  */
390  virtual ThermoPhase* duplMyselfAsThermoPhase() const;
391 
392  /**
393  *
394  * @name Utilities
395  * @{
396  */
397 
398 
399  //! Equation of state type flag.
400  /*!
401  * The ThermoPhase base class returns
402  * zero. Subclasses should define this to return a unique
403  * non-zero value. Known constants defined for this purpose are
404  * listed in mix_defs.h. The MolalityVPSSTP class also returns
405  * zero, as it is a non-complete class.
406  */
407  virtual int eosType() const;
408 
409  //! Initialization of a phase using an xml file
410  /*!
411  * This routine is a precursor to
412  * routine, which does most of the work.
413  *
414  * @param inputFile XML file containing the description of the
415  * phase
416  *
417  * @param id Optional parameter identifying the name of the
418  * phase. If none is given, the first XML
419  * phase element will be used.
420  */
421  void constructPhaseFile(std::string inputFile, std::string id);
422 
423  //! Import and initialize a phase
424  //! specification in an XML tree into the current object.
425  /*!
426  * Here we read an XML description of the phase.
427  * We import descriptions of the elements that make up the
428  * species in a phase.
429  * We import information about the species, including their
430  * reference state thermodynamic polynomials. We then freeze
431  * the state of the species.
432  *
433  * Then, we read the species molar volumes from the xml
434  * tree to finish the initialization.
435  *
436  * @param phaseNode This object must be the phase node of a
437  * complete XML tree
438  * description of the phase, including all of the
439  * species data. In other words while "phase" must
440  * point to an XML phase object, it must have
441  * sibling nodes "speciesData" that describe
442  * the species in the phase.
443  *
444  * @param id ID of the phase. If nonnull, a check is done
445  * to see if phaseNode is pointing to the phase
446  * with the correct id.
447  */
448  void constructPhaseXML(XML_Node& phaseNode, std::string id);
449 
450  /**
451  * @}
452  * @name Molar Thermodynamic Properties
453  * @{
454  */
455 
456 
457  /**
458  * @}
459  * @name Utilities for Solvent ID and Molality
460  * @{
461  */
462 
463 
464 
465 
466  /**
467  * @}
468  * @name Mechanical Properties
469  * @{
470  */
471 
472  /**
473  * @}
474  * @name Potential Energy
475  *
476  * Species may have an additional potential energy due to the
477  * presence of external gravitation or electric fields. These
478  * methods allow specifying a potential energy for individual
479  * species.
480  * @{
481  */
482 
483  /**
484  * @}
485  * @name Activities, Standard States, and Activity Concentrations
486  *
487  * The activity \f$a_k\f$ of a species in solution is
488  * related to the chemical potential by \f[ \mu_k = \mu_k^0(T)
489  * + \hat R T \log a_k. \f] The quantity \f$\mu_k^0(T,P)\f$ is
490  * the chemical potential at unit activity, which depends only
491  * on temperature and pressure.
492  * @{
493  */
494 
495  //! Get the array of non-dimensional molar-based activity coefficients at
496  //! the current solution temperature, pressure, and solution concentration.
497  /*!
498  * @param ac Output vector of activity coefficients. Length: m_kk.
499  */
500  virtual void getActivityCoefficients(doublereal* ac) const;
501 
502 
503 
504 
505  //@}
506  /// @name Partial Molar Properties of the Solution
507  //@{
508 
509  //! Get the species chemical potentials. Units: J/kmol.
510  /*!
511  * This function returns a vector of chemical potentials of the
512  * species in solution at the current temperature, pressure
513  * and mole fraction of the solution.
514  *
515  * @param mu Output vector of species chemical
516  * potentials. Length: m_kk. Units: J/kmol
517  */
518  virtual void getChemPotentials(doublereal* mu) const;
519 
520  /// Molar enthalpy. Units: J/kmol.
521  virtual doublereal enthalpy_mole() const;
522 
523  /// Molar entropy. Units: J/kmol.
524  virtual doublereal entropy_mole() const;
525 
526  /// Molar heat capacity at constant pressure. Units: J/kmol/K.
527  virtual doublereal cp_mole() const;
528 
529  /// Molar heat capacity at constant volume. Units: J/kmol/K.
530  virtual doublereal cv_mole() const;
531 
532  //! Returns an array of partial molar enthalpies for the species
533  //! in the mixture.
534  /*!
535  * Units (J/kmol)
536  *
537  * For this phase, the partial molar enthalpies are equal to the
538  * standard state enthalpies modified by the derivative of the
539  * molality-based activity coefficient wrt temperature
540  *
541  * \f[
542  * \bar h_k(T,P) = h^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT}
543  * \f]
544  *
545  * @param hbar Vector of returned partial molar enthalpies
546  * (length m_kk, units = J/kmol)
547  */
548  virtual void getPartialMolarEnthalpies(doublereal* hbar) const;
549 
550  //! Returns an array of partial molar entropies for the species
551  //! in the mixture.
552  /*!
553  * Units (J/kmol)
554  *
555  * For this phase, the partial molar enthalpies are equal to the
556  * standard state enthalpies modified by the derivative of the
557  * activity coefficient wrt temperature
558  *
559  * \f[
560  * \bar s_k(T,P) = s^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT}
561  * - R \ln( \gamma_k X_k)
562  * - R T \frac{d \ln(\gamma_k) }{dT}
563  * \f]
564  *
565  * @param sbar Vector of returned partial molar entropies
566  * (length m_kk, units = J/kmol/K)
567  */
568  virtual void getPartialMolarEntropies(doublereal* sbar) const;
569 
570  //! Returns an array of partial molar entropies for the species
571  //! in the mixture.
572  /*!
573  * Units (J/kmol)
574  *
575  * For this phase, the partial molar enthalpies are equal to the
576  * standard state enthalpies modified by the derivative of the
577  * activity coefficient wrt temperature
578  *
579  * \f[
580  * ???????????????
581  * \bar s_k(T,P) = s^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT}
582  * - R \ln( \gamma_k X_k)
583  * - R T \frac{d \ln(\gamma_k) }{dT}
584  * ???????????????
585  * \f]
586  *
587  * @param cpbar Vector of returned partial molar heat capacities
588  * (length m_kk, units = J/kmol/K)
589  */
590  virtual void getPartialMolarCp(doublereal* cpbar) const;
591 
592 
593  //! Return an array of partial molar volumes for the
594  //! species in the mixture. Units: m^3/kmol.
595  /*!
596  * Frequently, for this class of thermodynamics representations,
597  * the excess Volume due to mixing is zero. Here, we set it as
598  * a default. It may be overridden in derived classes.
599  *
600  * @param vbar Output vector of species partial molar volumes.
601  * Length = m_kk. units are m^3/kmol.
602  */
603  virtual void getPartialMolarVolumes(doublereal* vbar) const;
604 
605  //! Get the species electrochemical potentials.
606  /*!
607  * These are partial molar quantities.
608  * This method adds a term \f$ Fz_k \phi_k \f$ to the
609  * to each chemical potential.
610  *
611  * Units: J/kmol
612  *
613  * @param mu output vector containing the species electrochemical potentials.
614  * Length: m_kk., units = J/kmol
615  */
616  void getElectrochemPotentials(doublereal* mu) const;
617 
618  //! Get the array of temperature second derivatives of the log activity coefficients
619  /*!
620  * This function is a virtual class, but it first appears in GibbsExcessVPSSTP
621  * class and derived classes from GibbsExcessVPSSTP.
622  *
623  * units = 1/Kelvin
624  *
625  * @param d2lnActCoeffdT2 Output vector of temperature 2nd derivatives of the
626  * log Activity Coefficients. length = m_kk
627  *
628  */
629  virtual void getd2lnActCoeffdT2(doublereal* d2lnActCoeffdT2) const;
630 
631  //! Get the array of temperature derivatives of the log activity coefficients
632  /*!
633  * This function is a virtual class, but it first appears in GibbsExcessVPSSTP
634  * class and derived classes from GibbsExcessVPSSTP.
635  *
636  * units = 1/Kelvin
637  *
638  * @param dlnActCoeffdT Output vector of temperature derivatives of the
639  * log Activity Coefficients. length = m_kk
640  *
641  */
642  virtual void getdlnActCoeffdT(doublereal* dlnActCoeffdT) const;
643 
644 
645 
646  //@}
647  /// @name Properties of the Standard State of the Species in the Solution
648  //@{
649 
650 
651 
652  //@}
653  /// @name Thermodynamic Values for the Species Reference States
654  //@{
655 
656 
657  ///////////////////////////////////////////////////////
658  //
659  // The methods below are not virtual, and should not
660  // be overloaded.
661  //
662  //////////////////////////////////////////////////////
663 
664  /**
665  * @name Specific Properties
666  * @{
667  */
668 
669 
670  /**
671  * @name Setting the State
672  *
673  * These methods set all or part of the thermodynamic
674  * state.
675  * @{
676  */
677 
678 
679 
680  //@}
681 
682  /**
683  * @name Chemical Equilibrium
684  * Routines that implement the Chemical equilibrium capability
685  * for a single phase, based on the element-potential method.
686  * @{
687  */
688 
689 
690 
691  //@}
692 
693 
694 
695  /// The following methods are used in the process of constructing
696  /// the phase and setting its parameters from a specification in an
697  /// input file. They are not normally used in application programs.
698  /// To see how they are used, see files importCTML.cpp and
699  /// ThermoFactory.cpp.
700 
701 
702  /*!
703  * @internal Initialize. This method is provided to allow
704  * subclasses to perform any initialization required after all
705  * species have been added. For example, it might be used to
706  * resize internal work arrays that must have an entry for
707  * each species. The base class implementation does nothing,
708  * and subclasses that do not require initialization do not
709  * need to overload this method. When importing a CTML phase
710  * description, this method is called just prior to returning
711  * from function importPhase.
712  *
713  * @see importCTML.cpp
714  */
715  virtual void initThermo();
716 
717 
718  /**
719  * Import and initialize a ThermoPhase object
720  *
721  * @param phaseNode This object must be the phase node of a
722  * complete XML tree
723  * description of the phase, including all of the
724  * species data. In other words while "phase" must
725  * point to an XML phase object, it must have
726  * sibling nodes "speciesData" that describe
727  * the species in the phase.
728  * @param id ID of the phase. If nonnull, a check is done
729  * to see if phaseNode is pointing to the phase
730  * with the correct id.
731  */
732  void initThermoXML(XML_Node& phaseNode, std::string id);
733 
734  /**
735  * @}
736  * @name Derivatives of Thermodynamic Variables needed for Applications
737  * @{
738  */
739 
740  //! Get the change in activity coefficients w.r.t. change in state (temp, mole fraction, etc.) along
741  //! a line in parameter space or along a line in physical space
742  /*!
743  *
744  * @param dTds Input of temperature change along the path
745  * @param dXds Input vector of changes in mole fraction along the path. length = m_kk
746  * Along the path length it must be the case that the mole fractions sum to one.
747  * @param dlnActCoeffds Output vector of the directional derivatives of the
748  * log Activity Coefficients along the path. length = m_kk
749  * units are 1/units(s). if s is a physical coordinate then the units are 1/m.
750  */
751  virtual void getdlnActCoeffds(const doublereal dTds, const doublereal* const dXds, doublereal* dlnActCoeffds) const;
752 
753  //! Get the array of log concentration-like derivatives of the
754  //! log activity coefficients - diagonal component
755  /*!
756  * This function is a virtual method. For ideal mixtures
757  * (unity activity coefficients), this can return zero.
758  * Implementations should take the derivative of the
759  * logarithm of the activity coefficient with respect to the
760  * logarithm of the mole fraction.
761  *
762  * units = dimensionless
763  *
764  * @param dlnActCoeffdlnX_diag Output vector of the diagonal component of the log(mole fraction)
765  * derivatives of the log Activity Coefficients.
766  * length = m_kk
767  */
768  virtual void getdlnActCoeffdlnX_diag(doublereal* dlnActCoeffdlnX_diag) const;
769 
770  //! Get the array of derivatives of the log activity coefficients wrt mole numbers - diagonal only
771  /*!
772  * This function is a virtual method. For ideal mixtures
773  * (unity activity coefficients), this can return zero.
774  * Implementations should take the derivative of the
775  * logarithm of the activity coefficient with respect to the
776  * logarithm of the concentration-like variable (i.e. mole fraction,
777  * molality, etc.) that represents the standard state.
778  *
779  * units = dimensionless
780  *
781  * @param dlnActCoeffdlnN_diag Output vector of the diagonal entries for the log(mole fraction)
782  * derivatives of the log Activity Coefficients.
783  * length = m_kk
784  */
785  virtual void getdlnActCoeffdlnN_diag(doublereal* dlnActCoeffdlnN_diag) const;
786 
787 
788  //! Get the array of derivatives of the log activity coefficients with respect to the ln species mole numbers
789  /*!
790  * Implementations should take the derivative of the logarithm of the activity coefficient with respect to a
791  * log of a species mole number (with all other species mole numbers held constant)
792  *
793  * units = 1 / kmol
794  *
795  * dlnActCoeffdlnN[ ld * k + m] will contain the derivative of log act_coeff for the <I>m</I><SUP>th</SUP>
796  * species with respect to the number of moles of the <I>k</I><SUP>th</SUP> species.
797  *
798  * \f[
799  * \frac{d \ln(\gamma_m) }{d \ln( n_k ) }\Bigg|_{n_i}
800  * \f]
801  *
802  * @param ld Number of rows in the matrix
803  * @param dlnActCoeffdlnN Output vector of derivatives of the
804  * log Activity Coefficients. length = m_kk * m_kk
805  */
806  virtual void getdlnActCoeffdlnN(const size_t ld, doublereal* const dlnActCoeffdlnN) ;
807 
808  //@}
809 
810 private:
811 
812  //! Process an XML node called "binaryNeutralSpeciesParameters"
813  /*!
814  * This node contains all of the parameters necessary to describe
815  * the Margules model for a particular binary interaction.
816  * This function reads the XML file and writes the coefficients
817  * it finds to an internal data structures.
818  *
819  * @param xmlBinarySpecies Reference to the XML_Node named "binaryNeutralSpeciesParameters"
820  * containing the binary interaction
821  */
822  void readXMLBinarySpecies(XML_Node& xmlBinarySpecies);
823 
824  //! Resize internal arrays within the object that depend upon the number
825  //! of binary Margules interaction terms
826  /*!
827  * @param num Number of binary Margules interaction terms
828  */
829  void resizeNumInteractions(const size_t num);
830 
831 
832  //! Initialize lengths of local variables after all species have
833  //! been identified.
834  void initLengths();
835 
836  //! Update the activity coefficients
837  /*!
838  * This function will be called to update the internally stored
839  * natural logarithm of the activity coefficients
840  */
841  void s_update_lnActCoeff() const;
842 
843  //! Update the derivative of the log of the activity coefficients wrt T
844  /*!
845  * This function will be called to update the internally stored
846  * derivative of the natural logarithm of the activity coefficients
847  * wrt temperature.
848  */
849  void s_update_dlnActCoeff_dT() const;
850 
851  //! Update the derivative of the log of the activity coefficients
852  //! wrt log(mole fraction)
853  /*!
854  * This function will be called to update the internally stored
855  * derivative of the natural logarithm of the activity coefficients
856  * wrt logarithm of the mole fractions.
857  */
858  void s_update_dlnActCoeff_dlnX_diag() const;
859 
860  //! Update the derivative of the log of the activity coefficients
861  //! wrt log(moles) - diagonal only
862  /*!
863  * This function will be called to update the internally stored diagonal entries for the
864  * derivative of the natural logarithm of the activity coefficients
865  * wrt logarithm of the moles.
866  */
867  void s_update_dlnActCoeff_dlnN_diag() const;
868 
869  //! Update the derivative of the log of the activity coefficients wrt log(moles_m)
870  /*!
871  * This function will be called to update the internally stored
872  * derivative of the natural logarithm of the activity coefficients
873  * wrt logarithm of the mole number of species
874  */
875  void s_update_dlnActCoeff_dlnN() const;
876 
877 
878 private:
879  //! Error function
880  /*!
881  * Print an error string and exit
882  *
883  * @param msg Message to be printed
884  */
885  doublereal err(std::string msg) const;
886 
887 protected:
888 
889 
890  //! number of binary interaction expressions
892 
893  //! Enthalpy term for the binary mole fraction interaction of the
894  //! excess gibbs free energy expression
896 
897  //! Enthalpy term for the ternary mole fraction interaction of the
898  //! excess gibbs free energy expression
900 
901  //! Enthalpy term for the quaternary mole fraction interaction of the
902  //! excess gibbs free energy expression
904 
905  //! Entropy term for the binary mole fraction interaction of the
906  //! excess gibbs free energy expression
908 
909  //! Entropy term for the ternary mole fraction interaction of the
910  //! excess gibbs free energy expression
912 
913  //! Entropy term for the quaternary mole fraction interaction of the
914  //! excess gibbs free energy expression
916 
917  //! Enthalpy term for the binary mole fraction interaction of the
918  //! excess gibbs free energy expression
920 
921  //! Enthalpy term for the ternary mole fraction interaction of the
922  //! excess gibbs free energy expression
924 
925  //! Enthalpy term for the quaternary mole fraction interaction of the
926  //! excess gibbs free energy expression
928 
929  //! Entropy term for the binary mole fraction interaction of the
930  //! excess gibbs free energy expression
932 
933  //! Entropy term for the ternary mole fraction interaction of the
934  //! excess gibbs free energy expression
936 
937  //! Entropy term for the quaternary mole fraction interaction of the
938  //! excess gibbs free energy expression
940 
941 
942 
943  //! vector of species indices representing species A in the interaction
944  /*!
945  * Each Margules excess Gibbs free energy term involves two species, A and B.
946  * This vector identifies species A.
947  */
948  std::vector<size_t> m_pSpecies_A_ij;
949 
950  //! vector of species indices representing species B in the interaction
951  /*!
952  * Each Margules excess Gibbs free energy term involves two species, A and B.
953  * This vector identifies species B.
954  */
955  std::vector<size_t> m_pSpecies_B_ij;
956 
957  //! form of the Margules interaction expression
958  /*!
959  * Currently there is only one form.
960  */
962 
963  //! form of the temperature dependence of the Margules interaction expression
964  /*!
965  * Currently there is only one form -> constant wrt temperature.
966  */
968 
969 
970 };
971 
972 
973 
974 }
975 
976 #endif
977 
978 
979 
980 
981