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