diff --git a/Cantera/clib/src/ctmultiphase.cpp b/Cantera/clib/src/ctmultiphase.cpp index a3c727a34..cab84795c 100644 --- a/Cantera/clib/src/ctmultiphase.cpp +++ b/Cantera/clib/src/ctmultiphase.cpp @@ -67,6 +67,10 @@ static bool checkPhase(int i, int n) { } } +namespace Cantera { + int _equilflag(const char* xy); +} + extern "C" { int DLL_EXPORT mix_new() { @@ -180,7 +184,7 @@ extern "C" { doublereal DLL_EXPORT mix_equilibrate(int i, char* XY, doublereal err, int maxiter) { try { - return equilibrate(*_mix(i), XY, err, maxiter); + return equilibrate(*_mix(i), _equilflag(XY), err, maxiter); } catch (CanteraError) { return DERR; diff --git a/Cantera/python/Cantera/mixture.py b/Cantera/python/Cantera/mixture.py index 65b672e95..e0cb85c7e 100644 --- a/Cantera/python/Cantera/mixture.py +++ b/Cantera/python/Cantera/mixture.py @@ -61,19 +61,45 @@ class Mixture: """Delete the Mixture instance. The phase objects are not deleted.""" _cantera.mix_del(self.__mixid) -## def __repr__(self): -## s = '' -## for p in range(len(self._phases)): -## s += '\n******************* Phase '+self._phases[p].name()+' ******************************\n' -## s += '\n Moles: '+`self.phaseMoles(p)`+'\n' -## s += self._phases[p].__repr__()+'\n\n' -## return s + def __str__(self): + s = '' + for p in range(len(self._phases)): + s += '\n******************* Phase '+self._phases[p].name()+' ******************************\n' + s += '\n Moles: '+`self.phaseMoles(p)`+'\n' + s += self._phases[p].__repr__()+'\n\n' + return s def _addPhase(self, phase = None, moles = 0.0): """Add a phase to the mixture.""" for k in range(phase.nSpecies()): self._spnames.append(phase.speciesName(k)) _cantera.mix_addPhase(self.__mixid, phase.thermo_hndl(), moles) + + def nPhases(self): + """Total number of phases defined for the mixture.""" + return len(self._phases) + + def phaseName(self, n): + """Name of phase n.""" + return self._phases[n].name() + + def phaseNames(self): + """Names of all phases in the order added.""" + np = self.nPhases() + nm = [] + for n in range(np): + nm.append(self.phaseName(n)) + return nm + + def phaseIndex(self, phase): + """Index of phase with name 'phase'""" + np = self.nPhases() + if type(phase) <> types.StringType: + return phase + for n in range(np): + if self.phaseName(n) == phase: + return n + return -1 def nElements(self): """Total number of elements present in the mixture.""" @@ -141,9 +167,16 @@ class Mixture: def pressure(self): """The pressure [Pa].""" return _cantera.mix_pressure(self.__mixid) - def phaseMoles(self, n): + def phaseMoles(self, n = -1): """Moles of phase n.""" - return _cantera.mix_phaseMoles(self.__mixid, n) + if n == -1: + np = self.nPhases() + moles = zeros(np,'d') + for m in range(np): + moles[m] = _cantera.mix_phaseMoles(self.__mixid, m) + return moles + else: + return _cantera.mix_phaseMoles(self.__mixid, n) def setPhaseMoles(self, n, moles): """Set the number of moles of phase n.""" _cantera.mix_setPhaseMoles(self.__mixid, n, moles) diff --git a/Cantera/python/ctml_writer.py b/Cantera/python/ctml_writer.py index 0f30b90bc..d951fc05b 100644 --- a/Cantera/python/ctml_writer.py +++ b/Cantera/python/ctml_writer.py @@ -1199,6 +1199,8 @@ class stoichiometric_solid(phase): self._tr = transport def conc_dim(self): + """A stoichiometric solid always has unit activity, so the + generalized concentration is 1 (dimensionless).""" return (0,0) def build(self, p): @@ -1225,36 +1227,31 @@ class stoichiometric_liquid(stoichiometric_solid): initial_state = None, options = []): - stoichiometric_solid.__init__(self, name, 3, elements, - species, 'none', + stoichiometric_solid.__init__(self, name, elements, + species, density, transport, initial_state, options) - self._dens = density - self._pure = 1 - if self._dens < 0.0: - raise CTI_Error('density must be specified.') - self._tr = transport -class pure_solid(stoichiometric_solid): - """Deprecated. Use stoichiometric_solid""" - def __init__(self, - name = '', - elements = '', - species = '', - density = -1.0, - transport = 'None', - initial_state = None, - options = []): +## class pure_solid(stoichiometric_solid): +## """Deprecated. Use stoichiometric_solid""" +## def __init__(self, +## name = '', +## elements = '', +## species = '', +## density = -1.0, +## transport = 'None', +## initial_state = None, +## options = []): - stoichiometric_solid.__init__(self, name, 3, elements, - species, 'none', - initial_state, options) - self._dens = density - self._pure = 1 - if self._dens < 0.0: - raise CTI_Error('density must be specified.') - self._tr = transport - print 'WARNING: entry type pure_solid is deprecated.' - print 'Use stoichiometric_solid instead.' +## stoichiometric_solid.__init__(self, name, 3, elements, +## species, 'none', +## initial_state, options) +## self._dens = density +## self._pure = 1 +## if self._dens < 0.0: +## raise CTI_Error('density must be specified.') +## self._tr = transport +## print 'WARNING: entry type pure_solid is deprecated.' +## print 'Use stoichiometric_solid instead.' class metal(phase): @@ -1495,7 +1492,10 @@ if __name__ == "__main__": # $Revision$ # $Date$ # $Log$ -# Revision 1.8 2004-12-02 22:11:28 dggoodwin +# Revision 1.9 2005-01-08 22:28:01 dggoodwin +# *** empty log message *** +# +# Revision 1.8 2004/12/02 22:11:28 dggoodwin # *** empty log message *** # # Revision 1.7 2004/11/15 02:33:21 dggoodwin diff --git a/Cantera/src/ChemEquil.h b/Cantera/src/ChemEquil.h index 2abf20110..a492f3e71 100755 --- a/Cantera/src/ChemEquil.h +++ b/Cantera/src/ChemEquil.h @@ -174,9 +174,7 @@ namespace Cantera { * calculation. */ inline void equilibrate(thermo_t& s, const char* XY) { - ChemEquil e; - e.equilibrate(s,_equilflag(XY)); - s.setElementPotentials(e.elementPotentials()); + equilibrate(s,_equilflag(XY)); } } diff --git a/Cantera/src/MultiPhase.cpp b/Cantera/src/MultiPhase.cpp index 4ceddd0a3..4137b334d 100644 --- a/Cantera/src/MultiPhase.cpp +++ b/Cantera/src/MultiPhase.cpp @@ -1,4 +1,5 @@ #include "MultiPhase.h" +#include "MultiPhaseEquil.h" #include "ThermoPhase.h" #include "DenseMatrix.h" @@ -19,6 +20,7 @@ namespace Cantera { // store its number of moles m_moles.push_back(moles); + m_temp_OK.push_back(true); // update the number of phases and the total number of // species @@ -143,6 +145,22 @@ namespace Cantera { } } + /// Chemical potentials. Write into array \c mu the chemical + /// potentials of all species [J/kmol]. + void MultiPhase::getValidChemPotentials(doublereal not_mu, + doublereal* mu) { + index_t i, loc = 0; + updatePhases(); + for (i = 0; i < m_np; i++) { + if (tempOK(i) || m_phase[i]->nSpecies() > 1) + m_phase[i]->getChemPotentials(mu + loc); + else + fill(mu + loc, mu + loc + m_phase[i]->nSpecies(), not_mu); + loc += m_phase[i]->nSpecies(); + } + } + + /// Chemical potentials. Write into array \c mu the chemical /// potentials of all species [J/kmol]. void MultiPhase::getStandardChemPotentials(doublereal* mu) { @@ -240,7 +258,23 @@ namespace Cantera { doublereal* x = m_moleFractions.begin() + loc; loc += nsp; m_phase[p]->setState_TPX(m_temp, m_press, x); + m_temp_OK[p] = true; + if (m_temp < m_phase[p]->minTemp() + || m_temp > m_phase[p]->maxTemp()) m_temp_OK[p] = false; } } + + doublereal MultiPhase::equilibrate(int XY, doublereal err, + int maxsteps) { + cout << "in equil" << endl; + init(); + if (m_equil == 0) { + m_equil = new MultiPhaseEquil(this); + } + m_equil->equilibrate(XY, err, maxsteps); + delete m_equil; + m_equil = 0; + } + } diff --git a/Cantera/src/MultiPhase.h b/Cantera/src/MultiPhase.h index 109dc42e9..d894c56f8 100644 --- a/Cantera/src/MultiPhase.h +++ b/Cantera/src/MultiPhase.h @@ -7,6 +7,8 @@ namespace Cantera { + class MultiPhaseEquil; + /// 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. @@ -27,7 +29,7 @@ namespace Cantera { /// Constructor. The constructor takes no arguments, since /// phases are added using method addPhase. MultiPhase() : m_temp(0.0), m_press(0.0), - m_nel(0), m_nsp(0), m_init(false) {} + m_nel(0), m_nsp(0), m_init(false), m_equil(0) {} /// Destructor. Does nothing. Class MultiPhase does not take /// "ownership" (i.e. responsibility for destroying) the @@ -93,6 +95,8 @@ namespace Cantera { /// potentials of all species [J/kmol]. void getChemPotentials(doublereal* mu); + void getValidChemPotentials(doublereal not_mu, doublereal* mu); + /// Chemical potentials. Write into array \c mu the chemical /// potentials of all species [J/kmol]. void getStandardChemPotentials(doublereal* mu); @@ -102,6 +106,10 @@ namespace Cantera { return m_temp; } + doublereal equilibrate(int XY, doublereal err = 1.0e-9, + int maxsteps = 1000); + + /// Set the temperature [K]. void setTemperature(doublereal T) { m_temp = T; @@ -143,6 +151,10 @@ namespace Cantera { void setMoles(doublereal* n); + bool tempOK(index_t p) { + return m_temp_OK[p]; + } + protected: /// Set the states of the phase objects to the locally-stored @@ -165,6 +177,8 @@ namespace Cantera { index_t m_nel; index_t m_nsp; bool m_init; + vector m_temp_OK; + MultiPhaseEquil* m_equil; }; inline std::ostream& operator<<(std::ostream& s, Cantera::MultiPhase& x) { diff --git a/Cantera/src/MultiPhaseEquil.cpp b/Cantera/src/MultiPhaseEquil.cpp index 86f10c454..c62fa64e7 100644 --- a/Cantera/src/MultiPhaseEquil.cpp +++ b/Cantera/src/MultiPhaseEquil.cpp @@ -416,14 +416,6 @@ namespace Cantera { void MultiPhaseEquil::step(doublereal omega, vector_fp& deltaN) { index_t k, ik; - //if (m_iter > 500) { - // for (ik = 0; ik < m_nsp; ik++) { - //k = m_order[ik]; - //if (ik < m_nel) cout << "*"; - //cout << m_mix->speciesName(m_species[k]) << - // ": " << m_moles[k] << " += " << omega << " * " << deltaN[k] << endl; - // } - //} if (omega < 0.0) throw CanteraError("step","negative omega"); @@ -438,6 +430,7 @@ namespace Cantera { m_lastmoles[k] = m_moles[k]; if (m_majorsp[k]) { m_moles[k] += omega * deltaN[k]; + if (m_moles[k] < 0.0) m_moles[k] = 0.0; } else { m_moles[k] = fabs(m_moles[k])*fminn(10.0, exp(-m_deltaG_RT[ik - m_nel])); @@ -544,7 +537,8 @@ namespace Cantera { // compute the gradient of G at this new position in the // current direction. If it is positive, then we have overshot // the minimum. In this case, interpolate back. - m_mix->getChemPotentials(m_mu.begin()); + doublereal not_mu = 1.0e8; + m_mix->getValidChemPotentials(not_mu, m_mu.begin()); doublereal grad1 = 0.0; for (k = 0; k < m_nsp; k++) { grad1 += m_work[k] * m_mu[m_species[k]]; @@ -573,8 +567,8 @@ namespace Cantera { dxi.resize(m_nsp - m_nel); computeN(); - - m_mix->getChemPotentials(m_mu.begin()); + doublereal not_mu = 1.0e8; + m_mix->getValidChemPotentials(not_mu, m_mu.begin()); for (j = 0; j < m_nsp - m_nel; j++) { @@ -590,6 +584,7 @@ namespace Cantera { m_deltaG_RT[j] = dg_rt; fctr = 1.0; + // if this is a formation reaction for a single-component phase, // check whether reaction should be included ik = j + m_nel; diff --git a/Cantera/src/MultiPhaseEquil.h b/Cantera/src/MultiPhaseEquil.h index 23dd59552..09fb3dea3 100644 --- a/Cantera/src/MultiPhaseEquil.h +++ b/Cantera/src/MultiPhaseEquil.h @@ -43,7 +43,7 @@ namespace Cantera { for (i = 0; i < maxsteps; i++) { stepComposition(); if (error() < err) break; - } + } if (i >= maxsteps) { printInfo(); throw CanteraError("MultiPhaseEquil::equilibrate", diff --git a/Cantera/src/SpeciesThermoFactory.cpp b/Cantera/src/SpeciesThermoFactory.cpp index 7cea30dbf..626feb1f3 100755 --- a/Cantera/src/SpeciesThermoFactory.cpp +++ b/Cantera/src/SpeciesThermoFactory.cpp @@ -195,8 +195,10 @@ namespace Cantera { getFloatArray(f0.child("floatArray"), c0, false); if (dualRange) getFloatArray(f1ptr->child("floatArray"), c1, false); - else + else { c1.resize(7,0.0); + copy(c0.begin(), c0.end(), c1.begin()); + } } else if (fabs(tmax1 - tmin0) < 0.01) { tmin = tmin1; diff --git a/Cantera/src/config.h b/Cantera/src/config.h index 9cc9f7918..6c5c15b6c 100755 --- a/Cantera/src/config.h +++ b/Cantera/src/config.h @@ -11,7 +11,7 @@ // These flags turn on or off features that are still in // development and are not yet stable. -#undef DEV_EQUIL +#define DEV_EQUIL //------------------------ Fortran settings -------------------// @@ -59,8 +59,8 @@ typedef int ftnlen; // Fortran hidden string length type // The configure script defines this if the operatiing system is Mac // OS X, This used to add some Mac-specific directories to the default // data file search path. -#define DARWIN 0 -/* #undef HAS_SSTREAM */ +#define DARWIN 1 +#define HAS_SSTREAM 1 // Identify whether the operating system is cygwin's overlay of // windows, with gcc being used as the compiler. @@ -68,19 +68,33 @@ typedef int ftnlen; // Fortran hidden string length type // Identify whether the operating system is windows based, with // microsoft vc++ being used as the compiler -#define WINMSVC +/* #undef WINMSVC */ //--------- Fonts for reaction path diagrams ---------------------- #define RXNPATH_FONT "Helvetica" //--------------------- Python ------------------------------------ +// This path to the python executable is created during +// Cantera's setup. It identifies the python executable +// used to run Python to process .cti files. Note that this is only +// used if environment variable PYTHON_CMD is not set. +#define PYTHON_EXE "python" + // If this is defined, the Cantera Python interface will use the // Numeric package; otherwise, it will use numarray. -/* #define HAS_NUMERIC 1 */ +/* #undef HAS_NUMERIC */ + +//--------------------- Cantera ----------------------------------- + +/* #undef CANTERA_ROOT */ +// This data pathway is used to locate a directory where datafiles +// are to be found. Note, the local directory is always searched +// as well. +#define CANTERA_DATA "/Applications/Cantera/data" #define INCL_PURE_FLUIDS 1 //--------------------- compile options ---------------------------- -/* #define USE_PCH 1 */ +#define USE_PCH 1 #endif diff --git a/config.h b/config.h index 9cc9f7918..6c5c15b6c 100755 --- a/config.h +++ b/config.h @@ -11,7 +11,7 @@ // These flags turn on or off features that are still in // development and are not yet stable. -#undef DEV_EQUIL +#define DEV_EQUIL //------------------------ Fortran settings -------------------// @@ -59,8 +59,8 @@ typedef int ftnlen; // Fortran hidden string length type // The configure script defines this if the operatiing system is Mac // OS X, This used to add some Mac-specific directories to the default // data file search path. -#define DARWIN 0 -/* #undef HAS_SSTREAM */ +#define DARWIN 1 +#define HAS_SSTREAM 1 // Identify whether the operating system is cygwin's overlay of // windows, with gcc being used as the compiler. @@ -68,19 +68,33 @@ typedef int ftnlen; // Fortran hidden string length type // Identify whether the operating system is windows based, with // microsoft vc++ being used as the compiler -#define WINMSVC +/* #undef WINMSVC */ //--------- Fonts for reaction path diagrams ---------------------- #define RXNPATH_FONT "Helvetica" //--------------------- Python ------------------------------------ +// This path to the python executable is created during +// Cantera's setup. It identifies the python executable +// used to run Python to process .cti files. Note that this is only +// used if environment variable PYTHON_CMD is not set. +#define PYTHON_EXE "python" + // If this is defined, the Cantera Python interface will use the // Numeric package; otherwise, it will use numarray. -/* #define HAS_NUMERIC 1 */ +/* #undef HAS_NUMERIC */ + +//--------------------- Cantera ----------------------------------- + +/* #undef CANTERA_ROOT */ +// This data pathway is used to locate a directory where datafiles +// are to be found. Note, the local directory is always searched +// as well. +#define CANTERA_DATA "/Applications/Cantera/data" #define INCL_PURE_FLUIDS 1 //--------------------- compile options ---------------------------- -/* #define USE_PCH 1 */ +#define USE_PCH 1 #endif diff --git a/configure b/configure index 289712ddf..806c04d04 100755 --- a/configure +++ b/configure @@ -108,7 +108,7 @@ PYTHON_CMD=${PYTHON_CMD:="default"} # The Cantera Python interface can be built with either the numarray # or Numeric packages. Set this to "y" to use Numeric, or anything # else to use numarray. -USE_NUMERIC=${USE_NUMERIC:="y"} +USE_NUMERIC=${USE_NUMERIC:="n"} # Set this to 'y' when site packages must be put in system directories # but Cantera tutorials must be put in user space. An alternative to diff --git a/tools/src/package4mac.in b/tools/src/package4mac.in index 8cd0d81d7..6962fc600 100644 --- a/tools/src/package4mac.in +++ b/tools/src/package4mac.in @@ -12,6 +12,9 @@ RESDIR=$PKGDIR/Cantera/resources_dir NUMPYDIR=$PKGDIR/Numeric/root_dir/Library/Python/$PYVERSION NUMRESDIR=$PKGDIR/Numeric/resources_dir +NUMARRAYPYDIR=$PKGDIR/numarray/root_dir/Library/Python/$PYVERSION +NUMARRAYRESDIR=$PKGDIR/numarray/resources_dir + # where Cantera has been installed instdir=/Applications/Cantera pylibdir=/Library/Python/$PYVERSION @@ -24,11 +27,16 @@ $INSTALL -d $RESDIR $INSTALL -d $NUMPYDIR/Numeric $INSTALL -d $NUMRESDIR +$INSTALL -d $NUMARRAYPYDIR/Numeric +$INSTALL -d $NUMARRAYRESDIR + rm -r -f $CTDIR/* rm -r -f $PYDIR/* rm -r -f $RESDIR/* rm -r -f $NUMPYDIR/* rm -r -f $NUMRESDIR/* +rm -r -f $NUMARRAYPYDIR/* +rm -r -f $NUMARRAYRESDIR/* cp -R -f $instdir/* $CTDIR chmod +x $CTDIR/bin/* @@ -48,3 +56,5 @@ cp -f @ctroot@/License.rtf $RESDIR cp -R -f $pylibdir/Numeric/* $NUMPYDIR/Numeric cp -f $pylibdir/Numeric.pth $NUMPYDIR +cp -R -f $pylibdir/numarray/* $NUMARRAYPYDIR/numarray +