18 MultiPhase::MultiPhase() :
45 MultiPhase& MultiPhase::operator=(
const MultiPhase& right)
75 for (n = 0; n < mix.
m_np; n++) {
83 size_t np = phases.size();
85 for (n = 0; n < np; n++) {
95 "phases cannot be added after init() has been called.");
117 for (m = 0; m < nel; m++) {
130 if (ename ==
"E" || ename ==
"e") {
165 size_t ip, kp, k = 0, nsp, m;
177 for (m = 0; m <
m_nel; m++) {
181 for (ip = 0; ip <
m_np; ip++) {
185 for (kp = 0; kp < nsp; kp++) {
186 if (mlocal !=
npos) {
203 for (k = 0; k <
m_nsp; k++) {
205 for (m = 0; m <
m_nel; m++) {
255 doublereal sum = 0.0, phasesum;
256 size_t i, k = 0, ik, nsp;
257 for (i = 0; i <
m_np; i++) {
260 for (ik = 0; ik < nsp; ik++) {
271 doublereal sum = 0.0;
273 for (i = 0; i <
m_np; i++) {
286 throw CanteraError(
"MultiPhase::speciesIndex",
"phase not found: " + phaseName);
288 size_t k =
m_phase[p]->speciesIndex(speciesName);
290 throw CanteraError(
"MultiPhase::speciesIndex",
"species not found: " + speciesName);
297 doublereal phasesum = 0.0;
298 size_t ik, k, nsp =
m_phase[p]->nSpecies();
299 for (ik = 0; ik < nsp; ik++) {
303 return Faraday*phasesum*
m_moles[p];
310 for (i = 0; i <
m_np; i++) {
311 m_phase[i]->getChemPotentials(mu + loc);
317 doublereal* mu,
bool standard)
const
323 for (i = 0; i <
m_np; i++) {
326 m_phase[i]->getChemPotentials(mu + loc);
328 m_phase[i]->getStandardChemPotentials(mu + loc);
349 doublereal sum = 0.0;
351 for (i = 0; i <
m_np; i++) {
362 doublereal sum = 0.0;
364 for (i = 0; i <
m_np; i++) {
375 doublereal sum = 0.0;
377 for (i = 0; i <
m_np; i++) {
388 doublereal sum = 0.0;
390 for (i = 0; i <
m_np; i++) {
401 doublereal sum = 0.0;
403 for (i = 0; i <
m_np; i++) {
419 for (
size_t k = 0; k < p->
nSpecies(); k++) {
428 for (
size_t k = 0; k < kk; k++) {
448 doublereal* dtmp = molNum;
449 for (
size_t ip = 0; ip <
m_np; ip++) {
450 doublereal phasemoles =
m_moles[ip];
453 for (ik = 0; ik < nsp; ik++) {
454 *(dtmp++) *= phasemoles;
465 size_t ik, k = 0, nsp;
466 doublereal phasemoles;
467 for (ip = 0; ip <
m_np; ip++) {
471 for (ik = 0; ik < nsp; ik++) {
477 if (phasemoles > 0.0) {
494 tmpMoles[indexS] += addedMoles;
495 tmpMoles[indexS] = std::max(tmpMoles[indexS], 0.0);
521 for (eGlobal = 0; eGlobal <
m_nel; eGlobal++) {
532 for (eGlobal = 0; eGlobal <
m_nel; eGlobal++) {
535 for (
size_t ip = 0; ip <
m_np; ip++) {
538 doublereal phasemoles =
m_moles[ip];
539 for (ik = 0; ik < nspPhase; ik++) {
542 for (eGlobal = 0; eGlobal <
m_nel; eGlobal++) {
554 for (i = 0; i < int(
m_np); i++) {
555 double vol = 1.0/
m_phase[i]->molarDensity();
562 int maxiter,
int loglevel)
565 "Use MultiPhase::equilibrate(string XY, ...) instead. To be removed "
566 "after Cantera 2.2.");
571 int maxsteps,
int maxiter,
578 doublereal hnow, herr = 1.0;
580 doublereal Tlow = -1.0, Thigh = -1.0;
582 doublereal dta=0.0, dtmax, cpb;
591 e.equilibrate(XY, err, maxsteps, loglevel);
603 for (n = 0; n < maxiter; n++) {
612 e.equilibrate(TP, err, maxsteps, loglevel);
632 cpb = (Hhigh - Hlow)/(Thigh - Tlow);
633 dt = (h0 - hnow)/cpb;
635 dtmax = 0.5*fabs(Thigh - Tlow);
640 tnew = sqrt(Tlow*Thigh);
644 herr = fabs((h0 - hnow)/h0);
668 tnew = 0.5*(
m_temp + Thigh);
669 if (fabs(tnew -
m_temp) < 1.0) {
676 throw CanteraError(
"MultiPhase::equilibrate_MultiPhaseEquil",
677 "No convergence for T");
678 }
else if (XY == SP) {
682 for (n = 0; n < maxiter; n++) {
686 e.equilibrate(TP, err, maxsteps, loglevel);
689 Tlow = std::max(Tlow,
m_temp);
691 Thigh = std::min(Thigh,
m_temp);
694 dtmax = 0.5*fabs(Thigh - Tlow);
695 dtmax = (dtmax > 500.0 ? 500.0 : dtmax);
700 if (herr < err || dta < 1.0e-4) {
718 tnew = 0.5*(
m_temp + Thigh);
723 throw CanteraError(
"MultiPhase::equilibrate_MultiPhaseEquil",
724 "No convergence for T");
725 }
else if (XY == TV) {
730 doublereal vnow, pnow, verr;
731 for (n = 0; n < maxiter; n++) {
736 e.equilibrate(TP, err, maxsteps, loglevel);
738 verr = fabs((v0 - vnow)/v0);
745 dVdP = (
volume() - vnow)/(0.01*pnow);
751 throw CanteraError(
"MultiPhase::equilibrate_MultiPhaseEquil",
758 double rtol,
int max_steps,
int max_iter,
759 int estimate_equil,
int log_level)
765 double initial_T =
m_temp;
769 if (solver ==
"auto" || solver ==
"vcs") {
771 writelog(
"Trying VCS equilibrium solver\n", log_level);
773 int ret = eqsolve.
equilibrate(ixy, estimate_equil, log_level-1,
777 "VCS solver failed. Return code: " +
int2str(ret));
779 writelog(
"VCS solver succeeded\n", log_level);
781 }
catch (std::exception& err) {
782 writelog(
"VCS solver failed.\n", log_level);
789 if (solver ==
"auto") {
796 if (solver ==
"auto" || solver ==
"gibbs") {
798 writelog(
"Trying MultiPhaseEquil (Gibbs) equilibrium solver\n",
802 writelog(
"MultiPhaseEquil solver succeeded\n", log_level);
804 }
catch (std::exception& err) {
805 writelog(
"MultiPhaseEquil solver failed.\n", log_level);
816 if (solver !=
"auto") {
818 "Invalid solver specified: '" + solver +
"'");
822 #ifdef MULTIPHASE_DEVEL
823 void importFromXML(
string infile,
string id)
830 if (x.name() !=
"multiphase")
831 throw CanteraError(
"MultiPhase::importFromXML",
832 "Current XML_Node is not a multiphase element.");
833 vector<XML_Node*> phases = x.getChildren(
"phase");
834 int np = phases.size();
837 for (n = 0; n < np; n++) {
838 XML_Node& ph = *phases[n];
840 if (ph.hasAttrib(
"src")) {
846 addPhase(p, ph.value());
882 for (
size_t e = 0; e <
m_nel; e++) {
928 for (
int iph = 0; iph < (int)
m_np; iph++) {
966 for (ip = 0; ip <
m_np; ip++) {
976 size_t p, nsp, loc = 0;
977 for (p = 0; p <
m_np; p++) {
std::map< std::string, doublereal > compositionMap
Map connecting a string name with a double.
XML_Node * get_XML_Node(const std::string &file_ID, XML_Node *root)
This routine will locate an XML node in either the input XML tree or in another input file specified ...
doublereal nAtoms(size_t k, size_t m) const
Number of atoms of element m in species k.
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
std::vector< size_t > m_spphase
Mapping between the global species number and the phase ID.
doublereal m_temp
Current value of the temperature (kelvin)
XML_Node * get_XML_File(const std::string &file, int debug)
Return a pointer to the XML tree for a Cantera input file.
size_t nElements() const
Number of elements.
bool tempOK(size_t p) const
Return true if the phase p has valid thermo data for the current temperature.
bool m_init
True if the init() routine has been called, and the MultiPhase frozen.
virtual void setState_TPX(doublereal t, doublereal p, const doublereal *x)
Set the temperature (K), pressure (Pa), and mole fractions.
void setPhaseMoles(const size_t n, const doublereal moles)
Set the number of moles of phase with index n.
doublereal speciesMoles(size_t kGlob) const
Returns the moles of global species k. units = kmol.
void checkElementIndex(size_t m) const
Check that the specified element index is in range.
std::map< std::string, size_t > m_enamemap
Returns the global element index, given the element string name.
const size_t npos
index returned by functions to indicate "no position"
std::string speciesName(const size_t kGlob) const
Name of species with global index kGlob.
void checkSpeciesArraySize(size_t kk) const
Check that an array size is at least nSpecies().
vector_int m_atomicNumber
Atomic number of each element.
doublereal phaseMoles(const size_t n) const
Return the number of moles in phase n.
void addPhase(ThermoPhase *p, doublereal moles)
Add a phase to the mixture.
Class XML_Node is a tree-based representation of the contents of an XML file.
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
doublereal phaseCharge(size_t p) const
Charge (Coulombs) of phase with index p.
doublereal equilibrate(int XY, doublereal err=1.0e-9, int maxsteps=1000, int maxiter=200, int loglevel=-99)
Set the mixture to a state of chemical equilibrium.
int phaseIndex(const std::string &pName) const
Returns the index, given the phase name.
void getMoleFractions(doublereal *const x) const
Get the species mole fraction vector.
Headers for the MultiPhase object that is used to set up multiphase equilibrium problems (see Equilib...
void getChemPotentials(doublereal *mu) const
Returns a vector of Chemical potentials.
void checkPhaseArraySize(size_t mm) const
Check that an array size is at least nPhases() Throws an exception if mm is less than nPhases()...
const doublereal Undef
Fairly random number to be used to initialize variables against to see if they are subsequently defin...
vector_fp m_moles
Vector of the number of moles in each phase.
Base class for a phase with thermodynamic properties.
void getMoleFractions(doublereal *const x) const
Returns the global Species mole fractions.
size_t speciesPhaseIndex(const size_t kGlob) const
Returns the phase index of the Kth "global" species.
std::vector< std::string > m_enames
String names of the global elements.
doublereal gibbs() const
The Gibbs function of the mixture [J].
void addSpeciesMoles(const int indexS, const doublereal addedMoles)
Adds moles of a certain species to the mixture.
vector_fp m_moleFractions
Locally stored vector of mole fractions of all species comprising the MultiPhase object.
Cantera's Interface to the Multiphase chemical equilibrium solver.
void uploadMoleFractionsFromPhases()
Update the locally-stored composition within this object to match the current compositions of the pha...
A class for multiphase mixtures.
void resize(size_t n, size_t m, doublereal v=0.0)
Resize the matrix.
void checkPhaseIndex(size_t m) const
Check that the specified phase index is in range Throws an exception if m is greater than nPhases() ...
doublereal charge() const
Total charge summed over all phases (Coulombs).
std::vector< bool > m_temp_OK
Vector of bools indicating whether temperatures are ok for phases.
void setState_TPMoles(const doublereal T, const doublereal Pres, const doublereal *Moles)
Set the state of the underlying ThermoPhase objects in one call.
void checkSpeciesIndex(size_t k) const
Check that the specified species index is in range.
std::string elementName(size_t m) const
Returns the name of the global element m.
size_t m_eloc
Global ID of the element corresponding to the electronic charge.
void getValidChemPotentials(doublereal not_mu, doublereal *mu, bool standard=false) const
Returns a vector of Valid chemical potentials.
doublereal entropy() const
The entropy of the mixture [J/K].
virtual doublereal maxTemp(size_t k=npos) const
Maximum temperature for which the thermodynamic data for the species are valid.
void addPhases(std::vector< ThermoPhase * > &phases, const vector_fp &phaseMoles)
Add a vector of phases to the mixture.
DenseMatrix m_atoms
Global Stoichiometric Coefficient array.
int atomicNumber(size_t m) const
Atomic number of element m.
std::vector< size_t > m_spstart
Vector of ints containing of first species index in the global list of species for each phase...
void setPhaseMoleFractions(const size_t n, const doublereal *const x)
Set the Mole fractions of the nth phase.
size_t m_nsp
Number of distinct species in all of the phases.
void calcElemAbundances() const
Calculate the element abundance vector.
std::string id() const
Return the string id for the phase.
size_t m_nel
Number of distinct elements in all of the phases.
void setTemperature(const doublereal T)
Set the temperature [K].
Base class for exceptions thrown by Cantera classes.
void checkElementArraySize(size_t mm) const
Check that an array size is at least nElements().
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.
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...
size_t elementIndex(const std::string &name) const
Returns the index of the element with name name.
const U & getValue(const std::map< T, U > &m, const T &key)
Const accessor for a value in a std::map.
doublereal IntEnergy() const
The internal energy of the mixture [J].
size_t m_np
Number of phases in the MultiPhase object.
vector_fp m_elemAbundances
Vector of element abundances.
std::vector< ThermoPhase * > m_phase
Vector of the ThermoPhase pointers.
void getMoles(doublereal *molNum) const
Get the mole numbers of all species in the multiphase object.
void setMolesByName(const compositionMap &xMap)
Set the number of moles of species in the mixture.
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 setPressure(doublereal P)
Set the pressure [Pa].
doublereal moleFraction(const size_t kGlob) const
Returns the mole fraction of global species k.
size_t nSpecies() const
Returns the number of species in the phase.
Interface class for the vcsnonlinear solver.
void updatePhases() const
Set the states of the phase objects to the locally-stored state within this MultiPhase object...
void setState_TP(const doublereal T, const doublereal Pres)
Set the state of the underlying ThermoPhase objects in one call.
compositionMap parseCompString(const std::string &ss, const std::vector< std::string > &names)
Parse a composition string into a map consisting of individual key:composition pairs.
virtual doublereal pressure() const
Return the thermodynamic pressure (Pa).
doublereal temperature() const
Temperature (K).
doublereal enthalpy() const
The enthalpy of the mixture [J].
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
size_t elementIndex(const std::string &name) const
Return the index of element named 'name'.
doublereal maxTemp() const
Maximum temperature for which all solution phases have valid thermo data.
doublereal cp() const
Heat capacity at constant pressure [J/K].
std::string phaseName(const size_t iph) const
Returns the name of the n'th phase.
doublereal elementMoles(size_t m) const
Total moles of global element m, summed over all phases.
void init()
Process phases and build atomic composition array.
Contains declarations for string manipulation functions within Cantera.
#define DATA_PTR(vec)
Creates a pointer to the start of the raw data for a vector.
std::vector< std::string > m_snames
Vector of species names in the problem.
std::string elementName(size_t m) const
Name of the element with index m.
void writelog(const std::string &msg)
Write a message to the screen.
An array index is out of range.
int _equilflag(const char *xy)
map property strings to integers
bool solutionSpecies(size_t kGlob) const
Return true is species kGlob is a species in a multicomponent solution phase.
thermo_t & phase(size_t n)
Return a reference to phase n.
doublereal minTemp() const
Minimum temperature for which all solution phases have valid thermo data.
doublereal m_press
Current value of the pressure (Pa)
doublereal pressure() const
Pressure [Pa].
void getElemAbundances(doublereal *elemAbundances) const
Retrieves a vector of element abundances.
size_t nSpecies() const
Number of species, summed over all phases.
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...
doublereal m_Tmax
Minimum temperature for which thermo parameterizations are valid.
doublereal m_Tmin
Minimum temperature for which thermo parameterizations are valid.
std::string speciesName(size_t k) const
Name of the species with index k.
void setMoles(const doublereal *n)
Sets all of the global species mole numbers.
doublereal volume() const
The total mixture volume [m^3].
virtual doublereal minTemp(size_t k=npos) const
Minimum temperature for which the thermodynamic data for the species or phase are valid...
size_t nPhases() const
Number of phases.
void save()
Function to put this error onto Cantera's error stack.