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