Cantera  3.2.0a5
Loading...
Searching...
No Matches
MultiPhase.h
Go to the documentation of this file.
1/**
2 * @file MultiPhase.h
3 * Headers for the @link Cantera::MultiPhase MultiPhase@endlink
4 * object that is used to set up multiphase equilibrium problems (see @ref equilGroup).
5 */
6
7// This file is part of Cantera. See License.txt in the top-level directory or
8// at https://cantera.org/license.txt for license and copyright information.
9
10#ifndef CT_MULTIPHASE_H
11#define CT_MULTIPHASE_H
12
14
15namespace Cantera
16{
17
18class ThermoPhase;
19
20//! A class for multiphase mixtures. The mixture can contain any
21//! number of phases of any type.
22/*!
23 * This object is the basic tool used by %Cantera for use in Multiphase
24 * equilibrium calculations.
25 *
26 * It is a container for a set of phases. Each phase has a given number of
27 * kmoles. Therefore, MultiPhase may be considered an "extrinsic"
28 * thermodynamic object, in contrast to the ThermoPhase object, which is an
29 * "intrinsic" thermodynamic object.
30 *
31 * @warning The multiphase equilibrium solvers currently have a number of problems that
32 * lead to solver failures or incorrect results for some inputs. See the
33 * [list of issues on GitHub](https://github.com/Cantera/cantera/issues?q=is%3Aopen+is%3Aissue+label%3AEquilibrium)
34 * for more information.
35 *
36 * MultiPhase may be considered to be "upstream" of the ThermoPhase objects in
37 * the sense that setting a property within MultiPhase, such as temperature,
38 * pressure, or species mole number, affects the underlying ThermoPhase
39 * object, but not the other way around.
40 *
41 * All phases have the same temperature and pressure, and a specified number
42 * of moles for each phase. The phases do not need to have the same elements.
43 * For example, a mixture might consist of a gaseous phase with elements (H,
44 * C, O, N), a solid carbon phase containing only element C, etc. A master
45 * element set will be constructed for the mixture that is the intersection of
46 * the elements of each phase.
47 *
48 * Below, reference is made to global species and global elements. These refer
49 * to the collective species and elements encompassing all of the phases
50 * tracked by the object.
51 *
52 * The global element list kept by this object is an intersection of the
53 * element lists of all the phases that comprise the MultiPhase.
54 *
55 * The global species list kept by this object is a concatenated list of all
56 * of the species in all the phases that comprise the MultiPhase. The ordering
57 * of species is contiguous with respect to the phase id.
58 *
59 * @ingroup equilGroup
60 */
62{
63public:
64 //! Constructor.
65 /*!
66 * The constructor takes no arguments, since phases are added using
67 * method addPhase().
68 */
69 MultiPhase() = default;
70
71 //! Destructor. Does nothing. Class MultiPhase does not take "ownership"
72 //! (that is, responsibility for destroying) the phase objects.
73 virtual ~MultiPhase();
74
75 //! Add a vector of phases to the mixture
76 /*!
77 * See the single addPhases command. This just does a bunch of phases
78 * at one time
79 * @param phases Vector of pointers to phases
80 * @param phaseMoles Vector of mole numbers in each phase (kmol)
81 */
82 void addPhases(vector<ThermoPhase*>& phases, const vector<double>& phaseMoles);
83
84 //! Add all phases present in 'mix' to this mixture.
85 /*!
86 * @param mix Add all of the phases in another MultiPhase
87 * object to the current object.
88 */
89 void addPhases(MultiPhase& mix);
90
91 //! Add a phase to the mixture.
92 /*!
93 * This function must be called before the init() function is called,
94 * which serves to freeze the MultiPhase.
95 *
96 * @param p pointer to the phase object
97 * @param moles total number of moles of all species in this phase
98 * @since New in %Cantera 3.2.
99 */
100 void addPhase(shared_ptr<ThermoPhase> p, double moles);
101
102 //! Add a phase to the mixture.
103 /*!
104 * This function must be called before the init() function is called,
105 * which serves to freeze the MultiPhase.
106 *
107 * @param p pointer to the phase object
108 * @param moles total number of moles of all species in this phase
109 */
110 void addPhase(ThermoPhase* p, double moles);
111
112 //! Number of elements.
113 size_t nElements() const {
114 return m_nel;
115 }
116
117 //! Check that the specified element index is in range.
118 /*!
119 * @since Starting in %Cantera 3.2, returns the input element index, if valid.
120 * @exception Throws an IndexError if m is greater than nElements()-1
121 */
122 size_t checkElementIndex(size_t m) const;
123
124 //! Check that an array size is at least nElements().
125 //! Throws an exception if mm is less than nElements(). Used before calls
126 //! which take an array pointer.
127 //! @deprecated To be removed after %Cantera 3.2. Only used by legacy CLib.
128 void checkElementArraySize(size_t mm) const;
129
130 //! Returns the name of the global element *m*.
131 /*!
132 * @param m index of the global element
133 */
134 string elementName(size_t m) const;
135
136 //! Returns the index of the element with name @e name.
137 /*!
138 * @param name String name of the global element
139 * @deprecated To be removed after %Cantera 3.2. Use 2-parameter version instead.
140 */
141 size_t elementIndex(const string& name) const;
142
143 //! Returns the index of the element with name @e name.
144 /*!
145 * @param name String name of the global element.
146 * @param raise If `true`, raise exception if the specified element is not found;
147 * otherwise, return @ref npos.
148 * @since Added the `raise` argument in %Cantera 3.2. If not specified, the default
149 * behavior if an element is not found in %Cantera 3.2 is to return `npos`.
150 * After %Cantera 3.2, the default behavior will be to throw an exception.
151 * @exception Throws a CanteraError if the specified element is not found and
152 * `raise` is `true`.
153 */
154 size_t elementIndex(const string& name, bool raise) const;
155
156 //! Number of species, summed over all phases.
157 size_t nSpecies() const {
158 return m_nsp;
159 }
160
161 //! Check that the specified species index is in range.
162 /*!
163 * @since Starting in %Cantera 3.2, returns the input species index, if valid.
164 * @exception Throws an IndexError if k is greater than nSpecies()-1
165 */
166 size_t checkSpeciesIndex(size_t k) const;
167
168 //! Check that an array size is at least nSpecies().
169 //! Throws an exception if kk is less than nSpecies(). Used before calls
170 //! which take an array pointer.
171 //! @deprecated To be removed after %Cantera 3.2. Only used by legacy CLib.
172 void checkSpeciesArraySize(size_t kk) const;
173
174 //! Name of species with global index @e kGlob
175 /*!
176 * @param kGlob global species index
177 */
178 string speciesName(size_t kGlob) const;
179
180 //! Returns the Number of atoms of global element @e mGlob in
181 //! global species @e kGlob.
182 /*!
183 * @param kGlob global species index
184 * @param mGlob global element index
185 * @returns the number of atoms.
186 */
187 double nAtoms(const size_t kGlob, const size_t mGlob) const;
188
189 //! Returns the global Species mole fractions.
190 /*!
191 * Write the array of species mole
192 * fractions into array @c x. The mole fractions are
193 * normalized to sum to one in each phase.
194 *
195 * @param x vector of mole fractions. Length = number of global species.
196 */
197 void getMoleFractions(double* const x) const;
198
199 //! Process phases and build atomic composition array.
200 /*!
201 * This method must be called after all phases are added, before doing
202 * anything else with the mixture. After init() has been called, no more
203 * phases may be added.
204 */
205 void init();
206
207 //! Returns the name of the n'th phase
208 /*!
209 * @param iph phase Index
210 */
211 string phaseName(size_t iph) const;
212
213 //! Returns the index, given the phase name
214 /*!
215 * @param pName Name of the phase
216 * @returns the index. A value of -1 means the phase isn't in the object.
217 * @deprecated To be removed after %Cantera 3.2. Use 2-parameter version instead.
218 */
219 int phaseIndex(const string& pName) const;
220
221 //! Returns the index, given the phase name
222 /*!
223 * @param pName Name of the phase
224 * @param raise If `true`, raise exception if the specified phase is not found.
225 * @returns the index. A value of -1 means the phase isn't in the object.
226 * @since Added the `raise` argument in %Cantera 3.2 and changed return type. If
227 * not specified, the default behavior if a phase is not found in %Cantera 3.2
228 * is to return @ref npos.
229 * @exception Throws a CanteraError if the specified phase is not found and
230 * `raise` is `true`.
231 */
232 size_t phaseIndex(const string& pName, bool raise) const;
233
234 //! Return the number of moles in phase n.
235 /*!
236 * @param n Index of the phase.
237 */
238 double phaseMoles(const size_t n) const;
239
240 //! Set the number of moles of phase with index n.
241 /*!
242 * @param n Index of the phase
243 * @param moles Number of moles in the phase (kmol)
244 */
245 void setPhaseMoles(const size_t n, const double moles);
246
247 //! Return a reference to phase n.
248 /*!
249 * The state of phase n is also updated to match the state stored locally
250 * in the mixture object.
251 *
252 * @param n Phase Index
253 * @return Reference to the ThermoPhase object for the phase
254 */
255 ThermoPhase& phase(size_t n);
256
257 //! Check that the specified phase index is in range
258 /*!
259 * @since Starting in %Cantera 3.2, returns the input species index, if valid.
260 * @exception Throws an IndexError if m is greater than nPhases()-1
261 */
262 size_t checkPhaseIndex(size_t m) const;
263
264 //! Check that an array size is at least nPhases()
265 //! Throws an exception if mm is less than nPhases(). Used before calls
266 //! which take an array pointer.
267 //! @deprecated To be removed after %Cantera 3.2. Unused
268 void checkPhaseArraySize(size_t mm) const;
269
270 //! Returns the moles of global species @c k. units = kmol
271 /*!
272 * @param kGlob Global species index k
273 */
274 double speciesMoles(size_t kGlob) const;
275
276 //! Return the global index of the species belonging to phase number @c p
277 //! with local index @c k within the phase.
278 /*!
279 * @param k local index of the species within the phase
280 * @param p index of the phase
281 */
282 size_t speciesIndex(size_t k, size_t p) const {
283 return m_spstart[p] + k;
284 }
285
286 //! Return the global index of the species belonging to phase name @c phaseName
287 //! with species name @c speciesName
288 /*!
289 * @param speciesName Species Name
290 * @param phaseName Phase Name
291 *
292 * @returns the global index
293 *
294 * If the species or phase name is not recognized, this routine throws a
295 * CanteraError.
296 */
297 size_t speciesIndex(const string& speciesName, const string& phaseName);
298
299 //! Minimum temperature for which all solution phases have valid thermo
300 //! data. Stoichiometric phases are not considered, since they may have
301 //! thermo data only valid for conditions for which they are stable.
302 double minTemp() const {
303 return m_Tmin;
304 }
305
306 //! Maximum temperature for which all solution phases have valid thermo
307 //! data. Stoichiometric phases are not considered, since they may have
308 //! thermo data only valid for conditions for which they are stable.
309 double maxTemp() const {
310 return m_Tmax;
311 }
312
313 //! Total charge summed over all phases (Coulombs).
314 double charge() const;
315
316 //! Charge (Coulombs) of phase with index @e p.
317 /*!
318 * The net charge is computed as @f[ Q_p = N_p \sum_k F z_k X_k @f]
319 * where the sum runs only over species in phase @e p.
320 * @param p index of the phase for which the charge is desired.
321 */
322 double phaseCharge(size_t p) const;
323
324 //! Total moles of global element @e m, summed over all phases.
325 /*!
326 * @param m Index of the global element
327 */
328 double elementMoles(size_t m) const;
329
330 //! Returns a vector of Chemical potentials.
331 /*!
332 * Write into array @e mu the chemical potentials of all species
333 * [J/kmol]. The chemical potentials are related to the activities by
334 *
335 * @f$
336 * \mu_k = \mu_k^0(T, P) + RT \ln a_k.
337 * @f$.
338 *
339 * @param mu Chemical potential vector. Length = num global species. Units
340 * = J/kmol.
341 */
342 void getChemPotentials(double* mu) const;
343
344 //! Returns a vector of Valid chemical potentials.
345 /*!
346 * Write into array @e mu the chemical potentials of all species with
347 * thermo data valid for the current temperature [J/kmol]. For other
348 * species, set the chemical potential to the value @e not_mu. If @e
349 * standard is set to true, then the values returned are standard chemical
350 * potentials.
351 *
352 * This method is designed for use in computing chemical equilibrium by
353 * Gibbs minimization. For solution phases (more than one species), this
354 * does the same thing as getChemPotentials. But for stoichiometric
355 * phases, this writes into array @e mu the user-specified value @e not_mu
356 * instead of the chemical potential if the temperature is outside the
357 * range for which the thermo data for the one species in the phase are
358 * valid. The need for this arises since many condensed phases have thermo
359 * data fit only for the temperature range for which they are stable. For
360 * example, in the NASA database, the fits for H2O(s) are only done up to
361 * 0 C, the fits for H2O(L) are only done from 0 C to 100 C, etc. Using
362 * the polynomial fits outside the range for which the fits were done can
363 * result in spurious chemical potentials, and can lead to condensed
364 * phases appearing when in fact they should be absent.
365 *
366 * By setting @e not_mu to a large positive value, it is possible to force
367 * routines which seek to minimize the Gibbs free energy of the mixture to
368 * zero out any phases outside the temperature range for which their
369 * thermo data are valid.
370 *
371 * @param not_mu Value of the chemical potential to set species in phases,
372 * for which the thermo data is not valid
373 * @param mu Vector of chemical potentials. length = Global species,
374 * units = J kmol-1
375 * @param standard If this method is called with @e standard set to true,
376 * then the composition-independent standard chemical
377 * potentials are returned instead of the composition-
378 * dependent chemical potentials.
379 */
380 void getValidChemPotentials(double not_mu, double* mu,
381 bool standard = false) const;
382
383 //! Temperature [K].
384 double temperature() const {
385 return m_temp;
386 }
387
388 //! Equilibrate a MultiPhase object
389 /*!
390 * Set this mixture to chemical equilibrium by calling one of Cantera's
391 * equilibrium solvers. The XY parameter indicates what two thermodynamic
392 * quantities are to be held constant during the equilibration process.
393 *
394 * @param XY String representation of what two properties are being
395 * held constant
396 * @param solver Name of the solver to be used to equilibrate the phase.
397 * If solver = 'vcs', the vcs_MultiPhaseEquil solver will be used. If
398 * solver = 'gibbs', the MultiPhaseEquil solver will be used. If solver
399 * = 'auto', the 'vcs' solver will be tried first, followed by the
400 * 'gibbs' solver if the first one fails.
401 * @param rtol Relative tolerance
402 * @param max_steps Maximum number of steps to take to find the solution
403 * @param max_iter The maximum number of outer temperature or pressure
404 * iterations to take when T and/or P is not held fixed.
405 * @param estimate_equil integer indicating whether the solver should
406 * estimate its own initial condition. If 0, the initial mole fraction
407 * vector in the ThermoPhase object is used as the initial condition.
408 * If 1, the initial mole fraction vector is used if the element
409 * abundances are satisfied. If -1, the initial mole fraction vector is
410 * thrown out, and an estimate is formulated.
411 * @param log_level loglevel Controls amount of diagnostic output.
412 * log_level=0 suppresses diagnostics, and increasingly-verbose
413 * messages are written as loglevel increases.
414 *
415 * @ingroup equilGroup
416 */
417 void equilibrate(const string& XY, const string& solver="auto",
418 double rtol=1e-9, int max_steps=50000, int max_iter=100,
419 int estimate_equil=0, int log_level=0);
420
421 //! Set the temperature [K].
422 /*!
423 * @param T value of the temperature (Kelvin)
424 */
425 void setTemperature(const double T);
426
427 //! Set the state of the underlying ThermoPhase objects in one call
428 /*!
429 * @param T Temperature of the system (kelvin)
430 * @param Pres pressure of the system (pascal)
431 */
432 void setState_TP(const double T, const double Pres);
433
434 //! Set the state of the underlying ThermoPhase objects in one call
435 /*!
436 * @param T Temperature of the system (kelvin)
437 * @param Pres pressure of the system (pascal)
438 * @param Moles Vector of mole numbers of all the species in all the phases
439 * (kmol)
440 */
441 void setState_TPMoles(const double T, const double Pres, const double* Moles);
442
443 //! Pressure [Pa].
444 double pressure() const {
445 return m_press;
446 }
447
448 //! The total mixture volume [m^3].
449 /*!
450 * Returns the cumulative sum of the volumes of all the phases in the
451 * mixture.
452 */
453 double volume() const;
454
455 //! Set the pressure [Pa].
456 /*!
457 * @param P Set the pressure in the MultiPhase object (Pa)
458 */
459 void setPressure(double P) {
460 m_press = P;
461 updatePhases();
462 }
463
464 //! The enthalpy of the mixture [J].
465 double enthalpy() const;
466
467 //! The internal energy of the mixture [J].
468 double IntEnergy() const;
469
470 //! The entropy of the mixture [J/K].
471 double entropy() const;
472
473 //! The Gibbs function of the mixture [J].
474 double gibbs() const;
475
476 //! Heat capacity at constant pressure [J/K]. Note that this does not
477 //! account for changes in composition of the mixture with temperature.
478 double cp() const;
479
480 //! Number of phases.
481 size_t nPhases() const {
482 return m_phase.size();
483 }
484
485 //! Return true is species @e kGlob is a species in a multicomponent
486 //! solution phase.
487 /*!
488 * @param kGlob index of the global species
489 */
490 bool solutionSpecies(size_t kGlob) const;
491
492 //! Returns the phase index of the Kth "global" species
493 /*!
494 * @param kGlob Global species index.
495 * @returns the index of the owning phase.
496 */
497 size_t speciesPhaseIndex(const size_t kGlob) const;
498
499 //! Returns the mole fraction of global species k
500 /*!
501 * @param kGlob Index of the global species.
502 */
503 double moleFraction(const size_t kGlob) const;
504
505 //! Set the Mole fractions of the nth phase
506 /*!
507 * This function sets the mole fractions of the nth phase. Note, the mole
508 * number of the phase stays constant
509 *
510 * @param n index of the phase
511 * @param x Vector of input mole fractions.
512 */
513 void setPhaseMoleFractions(const size_t n, const double* const x);
514
515 //! Set the number of moles of species in the mixture
516 /*!
517 * @param xMap Composition of the species with nonzero mole numbers.
518 * Mole numbers that are less than or equal to zero will be
519 * set to zero. units = kmol.
520 */
521 void setMolesByName(const Composition& xMap);
522
523 //! Set the moles via a string containing their names.
524 /*!
525 * The string x is in the form of a composition map. Species which are not
526 * listed are set to zero.
527 *
528 * @param x string x in the form of a composition map
529 * where values are the moles of the species.
530 */
531 void setMolesByName(const string& x);
532
533 //! Get the mole numbers of all species in the multiphase object
534 /*!
535 * @param[out] molNum Vector of doubles of length nSpecies() containing the
536 * global mole numbers (kmol).
537 */
538 void getMoles(double* molNum) const;
539
540 //! Sets all of the global species mole numbers
541 /*!
542 * The state of each phase object is also updated to have the specified
543 * composition and the mixture temperature and pressure.
544 *
545 * @param n Vector of doubles of length nSpecies() containing the global
546 * mole numbers (kmol).
547 */
548 void setMoles(const double* n);
549
550 //! Adds moles of a certain species to the mixture
551 /*!
552 * @param indexS Index of the species in the MultiPhase object
553 * @param addedMoles Value of the moles that are added to the species.
554 */
555 void addSpeciesMoles(const int indexS, const double addedMoles);
556
557 //! Retrieves a vector of element abundances
558 /*!
559 * @param elemAbundances Vector of element abundances
560 * Length = number of elements in the MultiPhase object.
561 * Index is the global element index. Units is in kmol.
562 */
563 void getElemAbundances(double* elemAbundances) const;
564
565 //! Return true if the phase @e p has valid thermo data for the current
566 //! temperature.
567 /*!
568 * @param p Index of the phase.
569 */
570 bool tempOK(size_t p) const;
571
572 // These methods are meant for internal use.
573
574 //! Update the locally-stored composition within this object to match the
575 //! current compositions of the phase objects.
576 /*!
577 * Query the underlying ThermoPhase objects for their mole fractions and
578 * fill in the mole fraction vector of this current object. Adjust element
579 * compositions within this object to match.
580 *
581 * This is an upload operation in the sense that we are taking downstream
582 * information (ThermoPhase object info) and applying it to an upstream
583 * object (MultiPhase object).
584 */
586
587 //! Set the states of the phase objects to the locally-stored
588 //! state within this MultiPhase object.
589 /*!
590 * This method sets each phase to the mixture temperature and pressure,
591 * and sets the phase mole fractions based on the mixture mole numbers.
592 *
593 * This is an download operation in the sense that we are taking upstream
594 * object information (MultiPhase object) and applying it to downstream
595 * objects (ThermoPhase object information)
596 *
597 * Therefore, the term, "update", is appropriate for a downstream operation.
598 */
599 void updatePhases() const;
600
601private:
602 //! Calculate the element abundance vector
603 void calcElemAbundances() const;
604
605 //! Set the mixture to a state of chemical equilibrium using the
606 //! MultiPhaseEquil solver.
607 /*!
608 * @param XY Integer flag specifying properties to hold fixed.
609 * @param err Error tolerance for @f$ \Delta \mu/RT @f$ for all reactions.
610 * Also used as the relative error tolerance for the outer loop.
611 * @param maxsteps Maximum number of steps to take in solving the fixed TP
612 * problem.
613 * @param maxiter Maximum number of "outer" iterations for problems holding
614 * fixed something other than (T,P).
615 * @param loglevel Level of diagnostic output
616 */
617 double equilibrate_MultiPhaseEquil(int XY, double err, int maxsteps,
618 int maxiter, int loglevel);
619
620 //! Vector of the number of moles in each phase.
621 /*!
622 * Length = m_np, number of phases.
623 */
624 vector<double> m_moles;
625
626 //! Vector of the ThermoPhase pointers.
627 vector<ThermoPhase*> m_phase;
628
629 //! Vector of shared ThermoPhase pointers.
630 //! Contains valid phase entries if added by addPhase(shared_ptr<ThermoPhase>) and
631 //! null pointers if a phase is added via addPhase(ThermoPhase*).
632 vector<shared_ptr<ThermoPhase>> m_sharedPhase;
633
634 //! Global Stoichiometric Coefficient array
635 /*!
636 * This is a two dimensional array m_atoms(m, k). The first index is the
637 * global element index. The second index, k, is the global species index.
638 * The value is the number of atoms of type m in species k.
639 */
641
642 //! Locally stored vector of mole fractions of all species comprising the
643 //! MultiPhase object.
644 vector<double> m_moleFractions;
645
646 //! Mapping between the global species number and the phase ID
647 /*!
648 * m_spphase[kGlobal] = iPhase
649 * Length = number of global species
650 */
651 vector<size_t> m_spphase;
652
653 //! Vector of ints containing of first species index in the global list of
654 //! species for each phase
655 /*!
656 * kfirst = m_spstart[ip], kfirst is the index of the first species in
657 * the ip'th phase.
658 */
659 vector<size_t> m_spstart;
660
661 //! String names of the global elements. This has a length equal to the
662 //! number of global elements.
663 vector<string> m_enames;
664
665 //! Atomic number of each global element.
666 vector<int> m_atomicNumber;
667
668 //! Vector of species names in the problem. Vector is over all species
669 //! defined in the object, the global species index.
670 vector<string> m_snames;
671
672 //! Returns the global element index, given the element string name
673 /*!
674 * -> used in the construction. However, wonder if it needs to be global.
675 */
676 map<string, size_t> m_enamemap;
677
678 //! Current value of the temperature (kelvin)
679 double m_temp = 298.15;
680
681 //! Current value of the pressure (Pa)
682 double m_press = OneBar;
683
684 //! Number of distinct elements in all of the phases
685 size_t m_nel = 0;
686
687 //! Number of distinct species in all of the phases
688 size_t m_nsp = 0;
689
690 //! True if the init() routine has been called, and the MultiPhase frozen
691 bool m_init = false;
692
693 //! Global ID of the element corresponding to the electronic charge. If
694 //! there is none, then this is equal to -1
695 size_t m_eloc = npos;
696
697 //! Vector of bools indicating whether temperatures are ok for phases.
698 /*!
699 * If the current temperature is outside the range of valid temperatures
700 * for the phase thermodynamics, the phase flag is set to false.
701 */
702 mutable vector<bool> m_temp_OK;
703
704 //! Minimum temperature for which thermo parameterizations are valid.
705 //! Stoichiometric phases are ignored in this determination. units Kelvin
706 double m_Tmin = 1.0;
707
708 //! Minimum temperature for which thermo parameterizations are valid.
709 //! Stoichiometric phases are ignored in this determination. units Kelvin
710 double m_Tmax = 100000.0;
711
712 //! Vector of element abundances
713 /*!
714 * m_elemAbundances[mGlobal] = kmol of element mGlobal summed over all
715 * species in all phases.
716 */
717 mutable vector<double> m_elemAbundances;
718};
719
720//! Function to output a MultiPhase description to a stream
721/*!
722 * Writes out a description of the contents of each phase of the
723 * MultiPhase using the report function.
724 *
725 * @param s ostream
726 * @param x Reference to a MultiPhase
727 * @returns a reference to the ostream
728 */
729std::ostream& operator<<(std::ostream& s, MultiPhase& x);
730
731//! Choose the optimum basis of species for the equilibrium calculations.
732/*!
733 * This is done by choosing the species with the largest mole fraction not
734 * currently a linear combination of the previous components. Then, calculate
735 * the stoichiometric coefficient matrix for that basis.
736 *
737 * Calculates the identity of the component species in the mechanism. Rearranges
738 * the solution data to put the component data at the front of the species list.
739 *
740 * Then, calculates SC(J,I) the formation reactions for all noncomponent
741 * species in the mechanism.
742 *
743 * @param[in] mphase Pointer to the multiphase object. Contains the species
744 * mole fractions, which are used to pick the current optimal species
745 * component basis.
746 * @param[in] orderVectorElements Order vector for the elements. The element
747 * rows in the formula matrix are rearranged according to this vector.
748 * @param[in] orderVectorSpecies Order vector for the species. The species are
749 * rearranged according to this formula. The first nComponents of this
750 * vector contain the calculated species components on exit.
751 * @param[in] doFormRxn If true, the routine calculates the formation
752 * reaction matrix based on the calculated component species. If
753 * false, this step is skipped.
754 * @param[out] usedZeroedSpecies = If true, then a species with a zero
755 * concentration was used as a component. The problem may be converged.
756 * @param[out] formRxnMatrix
757 * @return The number of components.
758 *
759 * @ingroup equilGroup
760 */
761size_t BasisOptimize(int* usedZeroedSpecies, bool doFormRxn,
762 MultiPhase* mphase, vector<size_t>& orderVectorSpecies,
763 vector<size_t>& orderVectorElements,
764 vector<double>& formRxnMatrix);
765
766//! Handles the potential rearrangement of the constraint equations
767//! represented by the Formula Matrix.
768/*!
769 * Rearrangement is only necessary when the number of components is less
770 * than the number of elements. For this case, some constraints can never
771 * be satisfied exactly, because the range space represented by the Formula
772 * Matrix of the components can't span the extra space. These constraints,
773 * which are out of the range space of the component Formula matrix
774 * entries, are migrated to the back of the Formula matrix.
775 *
776 * A prototypical example is an extra element column in FormulaMatrix[], which
777 * is identically zero. For example, let's say that argon is has an element
778 * column in FormulaMatrix[], but no species in the mechanism actually
779 * contains argon. Then, nc < ne. Unless the entry for desired element
780 * abundance vector for Ar is zero, then this element abundance constraint can
781 * never be satisfied. The constraint vector is not in the range space of the
782 * formula matrix.
783 *
784 * Also, without perturbation of FormulaMatrix[], BasisOptimize[] would
785 * produce a zero pivot because the matrix would be singular (unless the argon
786 * element column was already the last column of FormulaMatrix[].
787 *
788 * This routine borrows heavily from BasisOptimize algorithm. It finds nc
789 * constraints which span the range space of the Component Formula matrix, and
790 * assigns them as the first nc components in the formula matrix. This
791 * guarantees that BasisOptimize has a nonsingular matrix to invert.
792 *
793 * @param[in] nComponents Number of components calculated previously.
794 * @param[in] elementAbundances Current value of the element abundances
795 * @param[in] mphase Input pointer to a MultiPhase object
796 * @param[in] orderVectorSpecies input vector containing the ordering of the
797 * global species in mphase. This is used to extract the component
798 * basis of the mphase object.
799 * @param[out] orderVectorElements Output vector containing the order of the
800 * elements that is necessary for calculation of the formula matrix.
801 *
802 * @ingroup equilGroup
803 */
804void ElemRearrange(size_t nComponents, const vector<double>& elementAbundances,
805 MultiPhase* mphase,
806 vector<size_t>& orderVectorSpecies,
807 vector<size_t>& orderVectorElements);
808
809//! External int that is used to turn on debug printing for the
810//! BasisOptimize program.
811/*!
812 * Set this to 1 if you want debug printing from BasisOptimize.
813 */
814extern int BasisOptimize_print_lvl;
815}
816
817#endif
Headers for the DenseMatrix object, which deals with dense rectangular matrices and description of th...
A class for full (non-sparse) matrices with Fortran-compatible data storage, which adds matrix operat...
Definition DenseMatrix.h:55
A class for multiphase mixtures.
Definition MultiPhase.h:62
void init()
Process phases and build atomic composition array.
size_t speciesIndex(size_t k, size_t p) const
Return the global index of the species belonging to phase number p with local index k within the phas...
Definition MultiPhase.h:282
bool solutionSpecies(size_t kGlob) const
Return true is species kGlob is a species in a multicomponent solution phase.
vector< ThermoPhase * > m_phase
Vector of the ThermoPhase pointers.
Definition MultiPhase.h:627
double nAtoms(const size_t kGlob, const size_t mGlob) const
Returns the Number of atoms of global element mGlob in global species kGlob.
size_t checkPhaseIndex(size_t m) const
Check that the specified phase index is in range.
void setMolesByName(const Composition &xMap)
Set the number of moles of species in the mixture.
void setMoles(const double *n)
Sets all of the global species mole numbers.
DenseMatrix m_atoms
Global Stoichiometric Coefficient array.
Definition MultiPhase.h:640
double gibbs() const
The Gibbs function of the mixture [J].
size_t m_nel
Number of distinct elements in all of the phases.
Definition MultiPhase.h:685
double speciesMoles(size_t kGlob) const
Returns the moles of global species k. units = kmol.
void getValidChemPotentials(double not_mu, double *mu, bool standard=false) const
Returns a vector of Valid chemical potentials.
double m_temp
Current value of the temperature (kelvin)
Definition MultiPhase.h:679
void calcElemAbundances() const
Calculate the element abundance vector.
size_t nSpecies() const
Number of species, summed over all phases.
Definition MultiPhase.h:157
size_t checkElementIndex(size_t m) const
Check that the specified element index is in range.
double enthalpy() const
The enthalpy of the mixture [J].
double pressure() const
Pressure [Pa].
Definition MultiPhase.h:444
vector< size_t > m_spstart
Vector of ints containing of first species index in the global list of species for each phase.
Definition MultiPhase.h:659
vector< size_t > m_spphase
Mapping between the global species number and the phase ID.
Definition MultiPhase.h:651
void getMoles(double *molNum) const
Get the mole numbers of all species in the multiphase object.
double minTemp() const
Minimum temperature for which all solution phases have valid thermo data.
Definition MultiPhase.h:302
vector< double > m_moleFractions
Locally stored vector of mole fractions of all species comprising the MultiPhase object.
Definition MultiPhase.h:644
vector< double > m_elemAbundances
Vector of element abundances.
Definition MultiPhase.h:717
double equilibrate_MultiPhaseEquil(int XY, double err, int maxsteps, int maxiter, int loglevel)
Set the mixture to a state of chemical equilibrium using the MultiPhaseEquil solver.
void checkPhaseArraySize(size_t mm) const
Check that an array size is at least nPhases() Throws an exception if mm is less than nPhases().
vector< bool > m_temp_OK
Vector of bools indicating whether temperatures are ok for phases.
Definition MultiPhase.h:702
double phaseCharge(size_t p) const
Charge (Coulombs) of phase with index p.
int phaseIndex(const string &pName) const
Returns the index, given the phase name.
size_t nPhases() const
Number of phases.
Definition MultiPhase.h:481
size_t m_eloc
Global ID of the element corresponding to the electronic charge.
Definition MultiPhase.h:695
double entropy() const
The entropy of the mixture [J/K].
double temperature() const
Temperature [K].
Definition MultiPhase.h:384
void getChemPotentials(double *mu) const
Returns a vector of Chemical potentials.
double moleFraction(const size_t kGlob) const
Returns the mole fraction of global species k.
string speciesName(size_t kGlob) const
Name of species with global index kGlob.
double m_press
Current value of the pressure (Pa)
Definition MultiPhase.h:682
bool tempOK(size_t p) const
Return true if the phase p has valid thermo data for the current temperature.
void addPhases(vector< ThermoPhase * > &phases, const vector< double > &phaseMoles)
Add a vector of phases to the mixture.
map< string, size_t > m_enamemap
Returns the global element index, given the element string name.
Definition MultiPhase.h:676
vector< shared_ptr< ThermoPhase > > m_sharedPhase
Vector of shared ThermoPhase pointers.
Definition MultiPhase.h:632
void addSpeciesMoles(const int indexS, const double addedMoles)
Adds moles of a certain species to the mixture.
size_t elementIndex(const string &name) const
Returns the index of the element with name name.
void checkElementArraySize(size_t mm) const
Check that an array size is at least nElements().
size_t speciesPhaseIndex(const size_t kGlob) const
Returns the phase index of the Kth "global" species.
void setPressure(double P)
Set the pressure [Pa].
Definition MultiPhase.h:459
void setState_TPMoles(const double T, const double Pres, const double *Moles)
Set the state of the underlying ThermoPhase objects in one call.
vector< string > m_enames
String names of the global elements.
Definition MultiPhase.h:663
void addPhase(shared_ptr< ThermoPhase > p, double moles)
Add a phase to the mixture.
double phaseMoles(const size_t n) const
Return the number of moles in phase n.
MultiPhase()=default
Constructor.
void getMoleFractions(double *const x) const
Returns the global Species mole fractions.
size_t m_nsp
Number of distinct species in all of the phases.
Definition MultiPhase.h:688
void setPhaseMoleFractions(const size_t n, const double *const x)
Set the Mole fractions of the nth phase.
vector< int > m_atomicNumber
Atomic number of each global element.
Definition MultiPhase.h:666
double volume() const
The total mixture volume [m^3].
void uploadMoleFractionsFromPhases()
Update the locally-stored composition within this object to match the current compositions of the pha...
bool m_init
True if the init() routine has been called, and the MultiPhase frozen.
Definition MultiPhase.h:691
vector< string > m_snames
Vector of species names in the problem.
Definition MultiPhase.h:670
double m_Tmin
Minimum temperature for which thermo parameterizations are valid.
Definition MultiPhase.h:706
void updatePhases() const
Set the states of the phase objects to the locally-stored state within this MultiPhase object.
void getElemAbundances(double *elemAbundances) const
Retrieves a vector of element abundances.
void checkSpeciesArraySize(size_t kk) const
Check that an array size is at least nSpecies().
size_t checkSpeciesIndex(size_t k) const
Check that the specified species index is in range.
size_t nElements() const
Number of elements.
Definition MultiPhase.h:113
double charge() const
Total charge summed over all phases (Coulombs).
double cp() const
Heat capacity at constant pressure [J/K].
void setTemperature(const double T)
Set the temperature [K].
void setState_TP(const double T, const double Pres)
Set the state of the underlying ThermoPhase objects in one call.
ThermoPhase & phase(size_t n)
Return a reference to phase n.
double maxTemp() const
Maximum temperature for which all solution phases have valid thermo data.
Definition MultiPhase.h:309
double IntEnergy() const
The internal energy of the mixture [J].
string elementName(size_t m) const
Returns the name of the global element m.
vector< double > m_moles
Vector of the number of moles in each phase.
Definition MultiPhase.h:624
void setPhaseMoles(const size_t n, const double moles)
Set the number of moles of phase with index n.
double elementMoles(size_t m) const
Total moles of global element m, summed over all phases.
string phaseName(size_t iph) const
Returns the name of the n'th phase.
double m_Tmax
Minimum temperature for which thermo parameterizations are valid.
Definition MultiPhase.h:710
virtual ~MultiPhase()
Destructor.
Base class for a phase with thermodynamic properties.
void equilibrate(const string &XY, const string &solver="auto", double rtol=1e-9, int max_steps=50000, int max_iter=100, int estimate_equil=0, int log_level=0)
Equilibrate a MultiPhase object.
void ElemRearrange(size_t nComponents, const vector< double > &elementAbundances, MultiPhase *mphase, vector< size_t > &orderVectorSpecies, vector< size_t > &orderVectorElements)
Handles the potential rearrangement of the constraint equations represented by the Formula Matrix.
size_t BasisOptimize(int *usedZeroedSpecies, bool doFormRxn, MultiPhase *mphase, vector< size_t > &orderVectorSpecies, vector< size_t > &orderVectorElements, vector< double > &formRxnMatrix)
Choose the optimum basis of species for the equilibrium calculations.
const double OneBar
One bar [Pa].
Definition ct_defs.h:99
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:180
int BasisOptimize_print_lvl
External int that is used to turn on debug printing for the BasisOptimize program.
std::ostream & operator<<(std::ostream &s, const Array2D &m)
Output the current contents of the Array2D object.
Definition Array.cpp:100
map< string, double > Composition
Map from string names to doubles.
Definition ct_defs.h:177