Cantera  4.0.0a1
Loading...
Searching...
No Matches
MultiPhaseEquil.h
Go to the documentation of this file.
1//! @file MultiPhaseEquil.h
2
3// This file is part of Cantera. See License.txt in the top-level directory or
4// at https://cantera.org/license.txt for license and copyright information.
5
6#ifndef CT_MULTIPHASE_EQUIL
7#define CT_MULTIPHASE_EQUIL
8
9#include "MultiPhase.h"
10
11namespace Cantera
12{
13
14/**
15 * Multiphase chemical equilibrium solver. Class MultiPhaseEquil is designed
16 * to be used to set a mixture containing one or more phases to a state of
17 * chemical equilibrium. It implements the VCS algorithm, described in Smith
18 * and Missen @cite smith1982.
19 *
20 * This class only handles chemical equilibrium at a specified temperature and
21 * pressure. To compute equilibrium holding other properties fixed, it is
22 * necessary to iterate on T and P in an "outer" loop, until the specified
23 * properties have the desired values. This is done, for example, in method
24 * equilibrate of class MultiPhase.
25 *
26 * This class is primarily meant to be used internally by the equilibrate
27 * method of class MultiPhase, although there is no reason it cannot be used
28 * directly in application programs if desired.
29 *
30 * @ingroup equilGroup
31 */
33{
34public:
35 //! Construct a multiphase equilibrium manager for a multiphase mixture.
36 //! @param mix Pointer to a multiphase mixture object.
37 //! @param start If true, the initial composition will be determined by a
38 //! linear Gibbs minimization, otherwise the initial mixture
39 //! composition will be used.
40 //! @param loglevel Desired level of debug printing. loglevel = 0 suppresses
41 //! printing. Higher values request more verbose logging output.
42 MultiPhaseEquil(MultiPhase* mix, bool start=true, int loglevel = 0);
43
44 virtual ~MultiPhaseEquil() {}
45
46 size_t constituent(size_t m) {
47 if (m < m_nel) {
48 return m_order[m];
49 } else {
50 return npos;
51 }
52 }
53
54 void getStoichVector(size_t rxn, span<double> nu) {
55 checkArraySize("MultiPhaseEquil::getStoichVector", nu.size(), m_nsp);
56 fill(nu.begin(), nu.end(), 0.0);
57 if (rxn > nFree()) {
58 return;
59 }
60 for (size_t k = 0; k < m_nsp; k++) {
61 nu[m_order[k]] = m_N(k, rxn);
62 }
63 }
64
65 int iterations() {
66 return m_iter;
67 }
68
69 double equilibrate(int XY, double err = 1.0e-9,
70 int maxsteps = 1000, int loglevel=-99);
71 double error();
72
73 string reactionString(size_t j) {
74 return "";
75 }
76 void setInitialMixMoles(int loglevel = 0) {
77 setInitialMoles(loglevel);
78 finish();
79 }
80
81 size_t componentIndex(size_t n) {
82 return m_species[m_order[n]];
83 }
84
85 void reportCSV(const string& reportFile);
86
87 double phaseMoles(size_t iph) const;
88
89protected:
90 //! This method finds a set of component species and a complete set of
91 //! formation reactions for the non-components in terms of the components.
92 //! In most cases, many different component sets are possible, and
93 //! therefore neither the components returned by this method nor the
94 //! formation reactions are unique. The algorithm used here is described
95 //! in Smith and Missen @cite smith1982.
96 //!
97 //! The component species are taken to be the first M species in array
98 //! 'species' that have linearly-independent compositions.
99 //!
100 //! @param order On entry, vector @e order should contain species index
101 //! numbers in the order of decreasing desirability as a component.
102 //! For example, if it is desired to choose the components from among
103 //! the major species, this array might list species index numbers in
104 //! decreasing order of mole fraction. If array 'species' does not
105 //! have length = nSpecies(), then the species will be considered as
106 //! candidates to be components in declaration order, beginning with
107 //! the first phase added.
108 void getComponents(span<const size_t> order);
109
110 //! Estimate the initial mole numbers. This is done by running each
111 //! reaction as far forward or backward as possible, subject to the
112 //! constraint that all mole numbers remain non-negative. Reactions for
113 //! which @f$ \Delta \mu^0 @f$ are positive are run in reverse, and ones
114 //! for which it is negative are run in the forward direction. The end
115 //! result is equivalent to solving the linear programming problem of
116 //! minimizing the linear Gibbs function subject to the element and non-
117 //! negativity constraints.
118 int setInitialMoles(int loglevel = 0);
119
120 void computeN();
121
122 //! Take one step in composition, given the gradient of G at the starting
123 //! point, and a vector of reaction steps dxi.
124 double stepComposition(int loglevel = 0);
125
126 //! Re-arrange a vector of species properties in sorted form
127 //! (components first) into unsorted, sequential form.
128 void unsort(span<double> x);
129
130 void step(double omega, span<double> deltaN, int loglevel = 0);
131
132 //! Compute the change in extent of reaction for each reaction.
133 double computeReactionSteps(span<double> dxi);
134
135 void updateMixMoles();
136
137 //! Clean up the composition. The solution algorithm can leave some
138 //! species in stoichiometric condensed phases with very small negative
139 //! mole numbers. This method simply sets these to zero.
140 void finish();
141
142 // moles of the species with sorted index ns
143 double moles(size_t ns) const {
144 return m_moles[m_order[ns]];
145 }
146 double& moles(size_t ns) {
147 return m_moles[m_order[ns]];
148 }
149 int solutionSpecies(size_t n) const {
150 return m_dsoln[m_order[n]];
151 }
152 bool isStoichPhase(size_t n) const {
153 return (m_dsoln[m_order[n]] == 0);
154 }
155 double mu(size_t n) const {
156 return m_mu[m_species[m_order[n]]];
157 }
158 string speciesName(size_t n) const {
159 return
160 m_mix->speciesName(m_species[m_order[n]]);
161 }
162
163 //! Number of degrees of freedom
164 size_t nFree() const {
165 return (m_nsp > m_nel) ? m_nsp - m_nel : 0;
166 }
167
168 size_t m_nel_mix, m_nsp_mix;
169 size_t m_nel = 0;
170 size_t m_nsp = 0;
171 size_t m_eloc = 1000;
172 int m_iter;
173 MultiPhase* m_mix;
174 double m_press, m_temp;
175 vector<size_t> m_order;
176 DenseMatrix m_N, m_A;
177 vector<double> m_work, m_work2, m_work3;
178 vector<double> m_moles, m_lastmoles, m_dxi;
179 vector<double> m_deltaG_RT, m_mu;
180 vector<bool> m_majorsp;
181 vector<size_t> m_sortindex;
182 vector<int> m_lastsort;
183 vector<int> m_dsoln;
184 vector<int> m_incl_element, m_incl_species;
185
186 // Vector of indices for species that are included in the calculation.
187 // This is used to exclude pure-phase species with invalid thermo data
188 vector<size_t> m_species;
189 vector<size_t> m_element;
190 vector<bool> m_solnrxn;
191 bool m_force = true;
192};
193
194}
195
196#endif
Headers for the MultiPhase object that is used to set up multiphase equilibrium problems (see Chemica...
A class for full (non-sparse) matrices with Fortran-compatible data storage, which adds matrix operat...
Definition DenseMatrix.h:42
Multiphase chemical equilibrium solver.
void getComponents(span< const size_t > order)
This method finds a set of component species and a complete set of formation reactions for the non-co...
double stepComposition(int loglevel=0)
Take one step in composition, given the gradient of G at the starting point, and a vector of reaction...
void unsort(span< double > x)
Re-arrange a vector of species properties in sorted form (components first) into unsorted,...
void finish()
Clean up the composition.
size_t nFree() const
Number of degrees of freedom.
double computeReactionSteps(span< double > dxi)
Compute the change in extent of reaction for each reaction.
int setInitialMoles(int loglevel=0)
Estimate the initial mole numbers.
A class for multiphase mixtures.
Definition MultiPhase.h:62
string speciesName(size_t kGlob) const
Name of species with global index kGlob.
Namespace for the Cantera kernel.
Definition AnyMap.cpp:595
const size_t npos
index returned by functions to indicate "no position"
Definition ct_defs.h:183
void checkArraySize(const char *procedure, size_t available, size_t required)
Wrapper for throwing ArraySizeError.