Cantera  2.0
MultiPhaseEquil.h
1 #ifndef CT_MULTIPHASE_EQUIL
2 #define CT_MULTIPHASE_EQUIL
3 
4 #include "cantera/base/ct_defs.h"
5 #include "MultiPhase.h"
6 
7 namespace Cantera
8 {
9 
10 /**
11  * Multiphase chemical equilibrium solver. Class MultiPhaseEquil
12  * is designed to be used to set a mixture containing one or more
13  * phases to a state of chemical equilibrium. It implements the
14  * VCS algorithm, described in Smith and Missen, "Chemical
15  * Reaction Equilibrium."
16  *
17  * This class only handles chemical equilibrium at a specified
18  * temperature and pressure. To compute equilibrium holding other
19  * properties fixed, it is necessary to iterate on T and P in an
20  * "outer" loop, until the specified properties have the desired
21  * values. This is done, for example, in method equilibrate of
22  * class MultiPhase.
23  *
24  * This class is primarily meant to be used internally by the
25  * equilibrate method of class MultiPhase, although there is no
26  * reason it cannot be used directly in application programs if
27  * desired.
28  *
29  * @ingroup equil
30  */
31 
33 {
34 
35 public:
36  typedef size_t index_t;
37 
38  MultiPhaseEquil(MultiPhase* mix, bool start=true, int loglevel = 0);
39 
40  virtual ~MultiPhaseEquil() {}
41 
42  size_t constituent(index_t m) {
43  if (m < m_nel) {
44  return m_order[m];
45  } else {
46  return npos;
47  }
48  }
49 
50  void getStoichVector(index_t rxn, vector_fp& nu) {
51  index_t k;
52  nu.resize(m_nsp, 0.0);
53  if (rxn > nFree()) {
54  return;
55  }
56  for (k = 0; k < m_nsp; k++) {
57  nu[m_order[k]] = m_N(k, rxn);
58  }
59  }
60 
61  int iterations() {
62  return m_iter;
63  }
64 
65  doublereal equilibrate(int XY, doublereal err = 1.0e-9,
66  int maxsteps = 1000, int loglevel=-99);
67  doublereal error();
68 
69 #if defined(WITH_HTML_LOGS)
70  std::string reactionString(index_t j);
71  void printInfo(int loglevel);
72 #else
73  inline std::string reactionString(index_t j) {
74  return std::string("");
75  }
76  inline void printInfo(int loglevel) {}
77 #endif
78 
79  void setInitialMixMoles(int loglevel = 0) {
80  setInitialMoles(loglevel);
81  finish();
82  }
83 
84  size_t componentIndex(index_t n) {
85  return m_species[m_order[n]];
86  }
87 
88  void reportCSV(const std::string& reportFile);
89 
90  double phaseMoles(index_t iph) const;
91 
92 protected:
93 
94  void getComponents(const std::vector<size_t>& order);
95  int setInitialMoles(int loglevel = 0);
96  void computeN();
97  doublereal stepComposition(int loglevel = 0);
98  //void sort(vector_fp& x);
99  void unsort(vector_fp& x);
100  void step(doublereal omega, vector_fp& deltaN, int loglevel = 0);
101  doublereal computeReactionSteps(vector_fp& dxi);
102  void updateMixMoles();
103  void finish();
104 
105  // moles of the species with sorted index ns
106  double moles(size_t ns) const {
107  return m_moles[m_order[ns]];
108  }
109  double& moles(size_t ns) {
110  return m_moles[m_order[ns]];
111  }
112  int solutionSpecies(size_t n) const {
113  return m_dsoln[m_order[n]];
114  }
115  bool isStoichPhase(size_t n) const {
116  return (m_dsoln[m_order[n]] == 0);
117  }
118  doublereal mu(size_t n) const {
119  return m_mu[m_species[m_order[n]]];
120  }
121  std::string speciesName(size_t n) const {
122  return
123  m_mix->speciesName(m_species[m_order[n]]);
124  }
125 
126  //! Number of degrees of freedom
127  index_t nFree() const {
128  return (m_nsp > m_nel) ? m_nsp - m_nel : 0;
129  }
130 
131  index_t m_nel_mix, m_nsp_mix, m_np;
132  index_t m_nel, m_nsp;
133  index_t m_eloc;
134  int m_iter;
135  MultiPhase* m_mix;
136  doublereal m_press, m_temp;
137  std::vector<size_t> m_order;
138  DenseMatrix m_N, m_A;
139  vector_fp m_work, m_work2, m_work3;
140  vector_fp m_moles, m_lastmoles, m_dxi;
141  vector_fp m_deltaG_RT, m_mu;
142  std::vector<bool> m_majorsp;
143  std::vector<size_t> m_sortindex;
144  vector_int m_lastsort;
145  vector_int m_dsoln;
146  vector_int m_incl_element, m_incl_species;
147 
148  // Vector of indices for species that are included in the
149  // calculation. This is used to exclude pure-phase species
150  // with invalid thermo data
151  std::vector<size_t> m_species;
152  std::vector<size_t> m_element;
153  std::vector<bool> m_solnrxn;
154  bool m_force;
155 };
156 
157 }
158 
159 
160 #endif