37 for (
size_t n = 0; n < mix.
nPhases(); n++) {
45 for (
size_t n = 0; n < phases.size(); n++) {
55 "phases cannot be added after init() has been called.");
59 throw CanteraError(
"MultiPhase::addPhase",
"Phase '{}'' is not "
60 "compatible with MultiPhase equilibrium solver", p->
name());
77 for (
size_t m = 0; m < p->
nElements(); m++) {
89 if (ename ==
"E" || ename ==
"e") {
131 for (
size_t m = 0; m <
m_nel; m++) {
134 for (
size_t ip = 0; ip <
nPhases(); ip++) {
138 for (
size_t kp = 0; kp < nsp; kp++) {
139 if (mlocal !=
npos) {
194 doublereal sum = 0.0;
195 for (
size_t i = 0; i <
nPhases(); i++) {
196 double phasesum = 0.0;
197 size_t nsp =
m_phase[i]->nSpecies();
198 for (
size_t ik = 0; ik < nsp; ik++) {
209 doublereal sum = 0.0;
210 for (
size_t i = 0; i <
nPhases(); i++) {
234 doublereal phasesum = 0.0;
235 size_t nsp =
m_phase[p]->nSpecies();
236 for (
size_t ik = 0; ik < nsp; ik++) {
247 for (
size_t i = 0; i <
nPhases(); i++) {
248 m_phase[i]->getChemPotentials(mu + loc);
254 doublereal* mu,
bool standard)
const
259 for (
size_t i = 0; i <
nPhases(); i++) {
262 m_phase[i]->getChemPotentials(mu + loc);
264 m_phase[i]->getStandardChemPotentials(mu + loc);
284 doublereal sum = 0.0;
286 for (
size_t i = 0; i <
nPhases(); i++) {
296 doublereal sum = 0.0;
298 for (
size_t i = 0; i <
nPhases(); i++) {
308 doublereal sum = 0.0;
310 for (
size_t i = 0; i <
nPhases(); i++) {
320 doublereal sum = 0.0;
322 for (
size_t i = 0; i <
nPhases(); i++) {
332 doublereal sum = 0.0;
334 for (
size_t i = 0; i <
nPhases(); i++) {
350 for (
size_t k = 0; k < p->
nSpecies(); k++) {
359 for (
size_t k = 0; k < kk; k++) {
376 doublereal* dtmp = molNum;
377 for (
size_t ip = 0; ip <
nPhases(); ip++) {
378 doublereal phasemoles =
m_moles[ip];
381 for (
size_t ik = 0; ik < nsp; ik++) {
382 *(dtmp++) *= phasemoles;
394 for (
size_t ip = 0; ip <
nPhases(); ip++) {
397 double phasemoles = 0.0;
398 for (
size_t ik = 0; ik < nsp; ik++) {
404 if (phasemoles > 0.0) {
421 tmpMoles[indexS] += addedMoles;
422 tmpMoles[indexS] = std::max(tmpMoles[indexS], 0.0);
447 for (
size_t eGlobal = 0; eGlobal <
m_nel; eGlobal++) {
456 for (
size_t eGlobal = 0; eGlobal <
m_nel; eGlobal++) {
459 for (
size_t ip = 0; ip <
nPhases(); ip++) {
462 doublereal phasemoles =
m_moles[ip];
463 for (
size_t ik = 0; ik < nspPhase; ik++) {
464 size_t kGlobal = loc + ik;
466 for (
size_t eGlobal = 0; eGlobal <
m_nel; eGlobal++) {
477 for (
size_t i = 0; i <
nPhases(); i++) {
478 double vol = 1.0/
m_phase[i]->molarDensity();
485 int maxsteps,
int maxiter,
489 doublereal dta = 0.0;
497 return e.equilibrate(XY, err, maxsteps, loglevel);
498 }
else if (XY == HP) {
501 double Thigh = 2.0*
m_Tmax;
503 for (
int n = 0; n < maxiter; n++) {
511 e.equilibrate(TP, err, maxsteps, loglevel);
531 double cpb = (Hhigh - Hlow)/(Thigh - Tlow);
532 dt = (h0 - hnow)/cpb;
534 double dtmax = 0.5*fabs(Thigh - Tlow);
539 double tnew = sqrt(Tlow*Thigh);
543 double herr = fabs((h0 - hnow)/h0);
548 double tnew =
m_temp + dt;
564 double tnew = 0.5*(
m_temp + Thigh);
565 if (fabs(tnew -
m_temp) < 1.0) {
572 throw CanteraError(
"MultiPhase::equilibrate_MultiPhaseEquil",
573 "No convergence for T");
574 }
else if (XY == SP) {
577 double Thigh = 1.0e6;
578 for (
int n = 0; n < maxiter; n++) {
582 e.equilibrate(TP, err, maxsteps, loglevel);
585 Tlow = std::max(Tlow,
m_temp);
587 Thigh = std::min(Thigh,
m_temp);
589 double dt = (s0 - snow)*
m_temp/
cp();
590 double dtmax = 0.5*fabs(Thigh - Tlow);
591 dtmax = (dtmax > 500.0 ? 500.0 : dtmax);
599 double tnew =
m_temp + dt;
611 double tnew = 0.5*(
m_temp + Thigh);
616 throw CanteraError(
"MultiPhase::equilibrate_MultiPhaseEquil",
617 "No convergence for T");
618 }
else if (XY == TV) {
621 for (
int n = 0; n < maxiter; n++) {
626 e.equilibrate(TP, err, maxsteps, loglevel);
628 double verr = fabs((v0 - vnow)/v0);
635 double dVdP = (
volume() - vnow)/(0.01*pnow);
639 throw CanteraError(
"MultiPhase::equilibrate_MultiPhaseEquil",
646 double rtol,
int max_steps,
int max_iter,
647 int estimate_equil,
int log_level)
653 double initial_T =
m_temp;
656 if (solver ==
"auto" || solver ==
"vcs") {
658 debuglog(
"Trying VCS equilibrium solver\n", log_level);
660 int ret = eqsolve.
equilibrate(ixy, estimate_equil, log_level-1,
664 "VCS solver failed. Return code: {}", ret);
666 debuglog(
"VCS solver succeeded\n", log_level);
668 }
catch (std::exception& err) {
669 debuglog(
"VCS solver failed.\n", log_level);
676 if (solver ==
"auto") {
683 if (solver ==
"auto" || solver ==
"gibbs") {
685 debuglog(
"Trying MultiPhaseEquil (Gibbs) equilibrium solver\n",
689 debuglog(
"MultiPhaseEquil solver succeeded\n", log_level);
691 }
catch (std::exception& err) {
692 debuglog(
"MultiPhaseEquil solver failed.\n", log_level);
703 if (solver !=
"auto") {
705 "Invalid solver specified: '" + solver +
"'");
721 throw IndexError(
"MultiPhase::checkElementIndex",
"elements", m,
m_nel-1);
739 for (
size_t e = 0; e <
m_nel; e++) {
750 throw IndexError(
"MultiPhase::checkSpeciesIndex",
"species", k,
m_nsp-1);
783 for (
int iph = 0; iph < (int)
nPhases(); iph++) {
784 if (
m_phase[iph]->name() == pName) {
819 for (
size_t ip = 0; ip <
nPhases(); ip++) {
830 for (
size_t p = 0; p <
nPhases(); p++) {
843 for (
size_t ip = 0; ip < x.
nPhases(); ip++) {
845 s <<
"*************** " << x.
phase(ip).
name() <<
" *****************" << std::endl;
847 s <<
"*************** Phase " << ip <<
" *****************" << std::endl;
849 s <<
"Moles: " << x.
phaseMoles(ip) << std::endl;
Headers for the MultiPhase object that is used to set up multiphase equilibrium problems (see Classes...
Header file for class ThermoPhase, the base class for phases with thermodynamic properties,...
Base class for exceptions thrown by Cantera classes.
void resize(size_t n, size_t m, doublereal v=0.0)
Resize the matrix.
An array index is out of range.
A class for multiphase mixtures.
void init()
Process phases and build atomic composition array.
void getMoleFractions(doublereal *const x) const
Returns the global Species mole fractions.
void setState_TPMoles(const doublereal T, const doublereal Pres, const doublereal *Moles)
Set the state of the underlying ThermoPhase objects in one call.
void checkPhaseIndex(size_t m) const
Check that the specified phase index is in range Throws an exception if m is greater than nPhases()
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...
bool solutionSpecies(size_t kGlob) const
Return true is species kGlob is a species in a multicomponent solution phase.
doublereal m_press
Current value of the pressure (Pa)
void setMoles(const doublereal *n)
Sets all of the global species mole numbers.
DenseMatrix m_atoms
Global Stoichiometric Coefficient array.
void getMoles(doublereal *molNum) const
Get the mole numbers of all species in the multiphase object.
void checkSpeciesIndex(size_t k) const
Check that the specified species index is in range.
size_t m_nel
Number of distinct elements in all of the phases.
vector_fp m_moleFractions
Locally stored vector of mole fractions of all species comprising the MultiPhase object.
doublereal minTemp() const
Minimum temperature for which all solution phases have valid thermo data.
double equilibrate_MultiPhaseEquil(int XY, doublereal err, int maxsteps, int maxiter, int loglevel)
Set the mixture to a state of chemical equilibrium using the MultiPhaseEquil solver.
void calcElemAbundances() const
Calculate the element abundance vector.
size_t nSpecies() const
Number of species, summed over all phases.
doublereal gibbs() const
The Gibbs function of the mixture [J].
doublereal cp() const
Heat capacity at constant pressure [J/K].
doublereal pressure() const
Pressure [Pa].
doublereal enthalpy() const
The enthalpy of the mixture [J].
std::map< std::string, size_t > m_enamemap
Returns the global element index, given the element string name.
doublereal speciesMoles(size_t kGlob) const
Returns the moles of global species k. units = kmol.
void addSpeciesMoles(const int indexS, const doublereal addedMoles)
Adds moles of a certain species to the mixture.
doublereal m_temp
Current value of the temperature (kelvin)
doublereal IntEnergy() const
The internal energy of the mixture [J].
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_fp m_elemAbundances
Vector of element abundances.
std::vector< size_t > m_spstart
Vector of ints containing of first species index in the global list of species for each phase.
doublereal m_Tmax
Minimum temperature for which thermo parameterizations are valid.
doublereal m_Tmin
Minimum temperature for which thermo parameterizations are valid.
vector_fp m_moles
Vector of the number of moles in each phase.
size_t nPhases() const
Number of phases.
size_t m_eloc
Global ID of the element corresponding to the electronic charge.
doublereal moleFraction(const size_t kGlob) const
Returns the mole fraction of global species k.
doublereal phaseMoles(const size_t n) const
Return the number of moles in phase n.
std::vector< size_t > m_spphase
Mapping between the global species number and the phase ID.
std::vector< std::string > m_snames
Vector of species names in the problem.
std::string speciesName(const size_t kGlob) const
Name of species with global index kGlob.
vector_int m_atomicNumber
Atomic number of each global element.
size_t elementIndex(const std::string &name) const
Returns the index of the element with name name.
bool tempOK(size_t p) const
Return true if the phase p has valid thermo data for the current temperature.
std::string elementName(size_t m) const
Returns the name of the global element m.
doublereal nAtoms(const size_t kGlob, const size_t mGlob) const
Returns the Number of atoms of global element mGlob in global species kGlob.
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 addPhases(std::vector< ThermoPhase * > &phases, const vector_fp &phaseMoles)
Add a vector of phases to the mixture.
std::vector< std::string > m_enames
String names of the global elements.
void setPressure(doublereal P)
Set the pressure [Pa].
doublereal elementMoles(size_t m) const
Total moles of global element m, summed over all phases.
void setPhaseMoleFractions(const size_t n, const doublereal *const x)
Set the Mole fractions of the nth phase.
doublereal charge() const
Total charge summed over all phases (Coulombs).
std::string phaseName(const size_t iph) const
Returns the name of the n'th phase.
void getValidChemPotentials(doublereal not_mu, doublereal *mu, bool standard=false) const
Returns a vector of Valid chemical potentials.
void setState_TP(const doublereal T, const doublereal Pres)
Set the state of the underlying ThermoPhase objects in one call.
doublereal entropy() const
The entropy of the mixture [J/K].
void setMolesByName(const compositionMap &xMap)
Set the number of moles of species in the mixture.
size_t m_nsp
Number of distinct species in all of the phases.
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.
doublereal volume() const
The total mixture volume [m^3].
void updatePhases() const
Set the states of the phase objects to the locally-stored state within this MultiPhase object.
void setPhaseMoles(const size_t n, const doublereal moles)
Set the number of moles of phase with index n.
void checkSpeciesArraySize(size_t kk) const
Check that an array size is at least nSpecies().
void getElemAbundances(doublereal *elemAbundances) const
Retrieves a vector of element abundances.
std::vector< bool > m_temp_OK
Vector of bools indicating whether temperatures are ok for phases.
int phaseIndex(const std::string &pName) const
Returns the index, given the phase name.
std::vector< ThermoPhase * > m_phase
Vector of the ThermoPhase pointers.
void addPhase(ThermoPhase *p, doublereal moles)
Add a phase to the mixture.
void getChemPotentials(doublereal *mu) const
Returns a vector of Chemical potentials.
void checkElementIndex(size_t m) const
Check that the specified element index is in range.
doublereal phaseCharge(size_t p) const
Charge (Coulombs) of phase with index p.
ThermoPhase & phase(size_t n)
Return a reference to phase n.
void setTemperature(const doublereal T)
Set the temperature [K].
std::string name() const
Return the name of the phase.
size_t nSpecies() const
Returns the number of species in the phase.
int atomicNumber(size_t m) const
Atomic number of element m.
size_t elementIndex(const std::string &name) const
Return the index of element named 'name'.
std::string speciesName(size_t k) const
Name of the species with index k.
void getMoleFractions(double *const x) const
Get the species mole fraction vector.
doublereal nAtoms(size_t k, size_t m) const
Number of atoms of element m in species k.
doublereal temperature() const
Temperature (K).
size_t nElements() const
Number of elements.
virtual double pressure() const
Return the thermodynamic pressure (Pa).
std::string elementName(size_t m) const
Name of the element with index m.
Base class for a phase with thermodynamic properties.
virtual std::string report(bool show_thermo=true, doublereal threshold=-1e-14) const
returns a summary of the state of the phase as a string
virtual void setState_TPX(doublereal t, doublereal p, const doublereal *x)
Set the temperature (K), pressure (Pa), and mole fractions.
virtual doublereal maxTemp(size_t k=npos) const
Maximum temperature for which the thermodynamic data for the species are valid.
virtual doublereal minTemp(size_t k=npos) const
Minimum temperature for which the thermodynamic data for the species or phase are valid.
Cantera's Interface to the Multiphase chemical equilibrium solver.
int equilibrate(int XY, int estimateEquil=0, int printLvl=0, doublereal err=1.0e-6, int maxsteps=VCS_MAXSTEPS, int loglevel=-99)
Equilibrate the solution using the current element abundances stored in the MultiPhase object.
virtual bool compatibleWithMultiPhase() const
Indicates whether this phase type can be used with class MultiPhase for equilibrium calculations.
void equilibrate(const std::string &XY, const std::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.
Namespace for the Cantera kernel.
const size_t npos
index returned by functions to indicate "no position"
const double Faraday
Faraday constant [C/kmol].
const double Undef
Fairly random number to be used to initialize variables against to see if they are subsequently defin...
void debuglog(const std::string &msg, int loglevel)
Write a message to the log only if loglevel > 0.
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
int _equilflag(const char *xy)
map property strings to integers
std::ostream & operator<<(std::ostream &s, const Array2D &m)
Output the current contents of the Array2D object.
const double OneBar
One bar [Pa].
std::map< std::string, double > compositionMap
Map connecting a string name with a double.
const U & getValue(const std::map< T, U > &m, const T &key, const U &default_val)
Const accessor for a value in a std::map.
compositionMap parseCompString(const std::string &ss, const std::vector< std::string > &names=std::vector< std::string >())
Parse a composition string into a map consisting of individual key:composition pairs.
Contains declarations for string manipulation functions within Cantera.
Various templated functions that carry out common vector operations (see Templated Utility Functions)...
Interface class for the vcsnonlinear solver.