cantera/Cantera/src/MultiPhase.h
2006-12-14 18:34:56 +00:00

313 lines
10 KiB
C++

/**
* @file MultiPhase.h
*
* $Author$
* $Date$
* $Revision$
*/
#ifndef CT_MULTIPHASE_H
#define CT_MULTIPHASE_H
#include "ct_defs.h"
#include "DenseMatrix.h"
#include "ThermoPhase.h"
namespace Cantera {
/// A class for multiphase mixtures. The mixture can contain any
/// number of phases of any type. All phases have the same
/// temperature and pressure, and a specified number of moles.
/// The phases do not need to have the same elements. For example,
/// a mixture might consist of a gaseous phase with elements (H,
/// C, O, N), a solid carbon phase containing only element C,
/// etc. A master element set will be constructed for the mixture
/// that is the union of the elements of each phase.
class MultiPhase {
public:
// some typedefs for convenience
typedef size_t index_t;
typedef ThermoPhase phase_t;
typedef DenseMatrix array_t;
typedef std::vector<phase_t*> phase_list;
/// Constructor. The constructor takes no arguments, since
/// phases are added using method addPhase.
MultiPhase();
/// Destructor. Does nothing. Class MultiPhase does not take
/// "ownership" (i.e. responsibility for destroying) the
/// phase objects.
virtual ~MultiPhase() {}
void addPhases(phase_list& phases, const vector_fp& phaseMoles);
/// Add all phases present in 'mix' to this mixture.
void addPhases(MultiPhase& mix);
/// Add a phase to the mixture.
/// @param p pointer to the phase object
/// @param moles total number of moles of all species in this phase
void addPhase(phase_t* p, doublereal moles);
/// Number of elements.
int nElements() const { return int(m_nel); }
/// Name of element \a m.
std::string elementName(int m) const { return m_enames[m]; }
/// Index of element with name \a name.
int elementIndex(std::string name) const { return m_enamemap[name] - 1;}
/// Number of species, summed over all phases.
int nSpecies() const { return int(m_nsp); }
/// Name of species with index \a k.
std::string speciesName(int k) const { return m_snames[k]; }
/// Number of atoms of element \a m in species \a k.
doublereal nAtoms(int k, int m) {
if (!m_init) init();
return m_atoms(m,k);
}
/// Species mole fractions. Write the array of species mole
/// fractions into array \c x. The mole fractions are
/// normalized to sum to one in each phase.
void getMoleFractions(doublereal* x) const {
std::copy(m_moleFractions.begin(), m_moleFractions.end(), x);
}
/// Process phases and build atomic composition array. After
/// init() has been called, no more phases may be added.
void init();
/// Moles of phase n.
doublereal phaseMoles(index_t n) const {
return m_moles[n];
}
/// Set the number of moles of phase with index n.
void setPhaseMoles(index_t n, doublereal moles) {
m_moles[n] = moles;
}
/// Return a reference to phase n. The state of phase n is
/// also updated to match the state stored locally in the
/// mixture object.
phase_t& phase(index_t n);
/// Moles of species \c k.
doublereal speciesMoles(index_t k) const;
/// Index of the species belonging to phase number \c p
/// with index \c k within the phase.
int speciesIndex(index_t k, index_t p) const {
return m_spstart[p] + k;
}
/// Minimum temperature for which all solution phases have
/// valid thermo data. Stoichiometric phases are not
/// considered, since they may have thermo data only valid for
/// conditions for which they are stable.
doublereal minTemp() const { return m_Tmin; }
/// Maximum temperature for which all solution phases have
/// valid thermo data. Stoichiometric phases are not
/// considered, since they may have thermo data only valid for
/// conditions for which they are stable.
doublereal maxTemp() const { return m_Tmax; }
/// Total charge (Coulombs).
doublereal charge() const;
/// Charge (Coulombs) of phase with index \a p.
doublereal phaseCharge(index_t p) const;
/// Total moles of element \a m, summed over all phases.
doublereal elementMoles(index_t m) const;
/// Chemical potentials. Write into array \a mu the chemical
/// potentials of all species [J/kmol]. The chemical
/// potentials are related to the activities by
/// \f[ \mu_k = \mu_k^0(T, P) + RT \ln a_k. \f].
void getChemPotentials(doublereal* mu) const;
/// Valid chemical potentials. Write into array \a mu the
/// chemical potentials of all species with thermo data valid
/// for the current temperature [J/kmol]. For other species,
/// set the chemical potential to the value \a not_mu. If \a
/// standard is set to true, then the values returned are
/// standard chemical potentials.
void getValidChemPotentials(doublereal not_mu, doublereal* mu,
bool standard = false) const;
/// Temperature [K].
doublereal temperature() const { return m_temp; }
/// Set the mixture to a state of chemical equilibrium.
/// @param XY Integer flag specifying properties to hold fixed.
/// @param err Error tolerance for \f$\Delta \mu/RT \f$ for
/// all reactions. Also used as the relative error tolerance
/// for the outer loop.
/// @param maxsteps Maximum number of steps to take in solving
/// the fixed TP problem.
/// @param maxiter Maximum number of "outer" iterations for
/// problems holding fixed something other than (T,P).
/// @param loglevel Level of diagnostic output, written to a
/// file in HTML format.
doublereal equilibrate(int XY, doublereal err = 1.0e-9,
int maxsteps = 1000, int maxiter = 200, int loglevel = -99);
/// Set the temperature [K].
void setTemperature(doublereal T) {
m_temp = T;
updatePhases();
}
/// Pressure [Pa].
doublereal pressure() const {
return m_press;
}
/// Volume [m^3].
doublereal volume() const;
/// Set the pressure [Pa].
void setPressure(doublereal P) {
m_press = P;
updatePhases();
}
/// Enthalpy [J].
doublereal enthalpy() const;
/// Entropy [J/K].
doublereal entropy() const;
/// Gibbs function [J].
doublereal gibbs() const;
/// Heat capacity at constant pressure [J/K].
doublereal cp() const;
/// Number of phases.
index_t nPhases() const {
return m_np;
}
/// Return true is species \a k is a species in a
/// multicomponent solution phase.
bool solutionSpecies(index_t k) const;
index_t speciesPhaseIndex(index_t k) const{
return m_spphase[k];
}
doublereal moleFraction(index_t k) const{
return m_moleFractions[k];
}
void setPhaseMoleFractions(index_t n, doublereal* x);
void setMolesByName(compositionMap& xMap);
void setMolesByName(const std::string& x);
void getMoles(doublereal * molNum) const;
void setMoles(doublereal* n);
/// Return true if the phase \a p has valid thermo data for
/// the current temperature.
bool tempOK(index_t p) const {
return m_temp_OK[p];
}
protected:
// These methods are meant for internal use.
/// update the locally-stored composition to match the current
/// compositions of the phase objects.
void updateMoleFractions();
/// Set the states of the phase objects to the locally-stored
/// state. Note that if individual phases have T and P different
/// than that stored locally, the phase T and P will be modified.
void updatePhases() const;
/**
* Vector of the number of moles in each phase.
* Length = m_np, number of phases.
*/
vector_fp m_moles;
/**
* Vector of the ThermoPhase Pointers.
*/
std::vector<phase_t*> m_phase;
array_t m_atoms;
/**
* Locally storred vector of mole fractions of all species
* comprising the MultiPhase object.
*/
vector_fp m_moleFractions;
vector_int m_spphase;
vector_int m_spstart;
std::vector<std::string> m_enames;
vector_int m_atomicNumber;
std::vector<std::string> m_snames;
mutable std::map<std::string, int> m_enamemap;
/**
* Number of phases in the MultiPhase object
*/
index_t m_np;
doublereal m_temp;
doublereal m_press;
/**
* Number of distinct elements in all of the phases
*/
index_t m_nel;
/**
* Number of distinct species in all of the phases
*/
index_t m_nsp;
bool m_init;
int m_eloc;
mutable std::vector<bool> m_temp_OK;
doublereal m_Tmin, m_Tmax;
};
inline std::ostream& operator<<(std::ostream& s, Cantera::MultiPhase& x) {
size_t ip;
for (ip = 0; ip < x.nPhases(); ip++) {
if (x.phase(ip).name() != "") {
s << "*************** " << x.phase(ip).name() << " *****************" << std::endl;
}
else {
s << "*************** Phase " << ip << " *****************" << std::endl;
}
s << "Moles: " << x.phaseMoles(ip) << std::endl;
s << report(x.phase(ip)) << std::endl;
}
return s;
}
int BasisOptimize( int *usedZeroedSpecies, bool doFormRxn,
MultiPhase *mphase, vector_int & orderVectorSpecies,
vector_int & orderVectorElements,
vector_fp & formRxnMatrix);
int ElemRearrange(int nComponents, const vector_fp & elementAbundances,
MultiPhase *mphase,
vector_int & orderVectorSpecies,
vector_int & orderVectorElements);
}
#endif