Prerelease_1_6_0_branch merged into trunk

This commit is contained in:
Dave Goodwin 2005-06-18 16:58:39 +00:00
parent 4158c19375
commit 9bd690ae04
295 changed files with 24396 additions and 5446 deletions

View file

@ -2,7 +2,6 @@ Makefile
configure.sol
configure.linux
build
config.h
win32_old
configure.vc++
configure.my_vc++

View file

@ -11,7 +11,6 @@
build_f90=@BUILD_F90@
build_python=@BUILD_PYTHON@
build_particles=@BUILD_PARTICLES@
build_matlab = @BUILD_MATLAB@
all:
@ -21,9 +20,6 @@ all:
ifeq ($(build_f90),1)
cd fortran/src; @MAKE@
endif
ifeq ($(build_particles),1)
cd cads; @MAKE@
endif
clean:
cd src; @MAKE@ clean

View file

@ -168,12 +168,17 @@ public:
}
}
/**
* Constructor.
*/
Cabinet(bool canDelete = true) : _can_delete(canDelete) { add(new M); }
private:
/**
* Constructor.
*/
Cabinet(bool canDelete = true) : _can_delete(canDelete) { add(new M); }
// Cabinet(bool canDelete = true) : _can_delete(canDelete) { add(new M); }
/**

View file

@ -9,17 +9,22 @@
###############################################################
SUFFIXES=
SUFFIXES= .cpp .d .o
.SUFFIXES :
.SUFFIXES : .cpp .d .o
INSTALL_TSC = ../../../bin/install_tsc
do_ranlib = @DO_RANLIB@
CXX_FLAGS = @CXXFLAGS@ $(CXX_OPT)
OBJS = ct.o Storage.o ctsurf.o ctrpath.o \
ctreactor.o ctfunc.o ctxml.o ctonedim.o ctmultiphase.o
CLIB_H= Cabinet.h ctreactor.h clib_defs.h ctfunc.h \
ctnum.h ctsurf.h ct.h ctrpath.h Storage.h \
ctbdry.h ctonedim.h ctxml.h ctmultiphase.h ctstagn.h
DEPENDS = $(OBJS:.o=.d)
# Fortran libraries
FORT_LIBS = @FLIBS@
@ -67,14 +72,24 @@ ifeq ($(shared_ctlib),1)
@SHARED@ $(LINK_OPTIONS) \
$(EXT_LIBS) @LIBS@ $(FORT_LIBS)
else
@ARCHIVE@ $(CTLIB) $(OBJS)
@ARCHIVE@ $(CTLIB) $(OBJS)
ifeq ($(do_ranlib),1)
@RANLIB@ $(CTLIB)
endif
endif
clean:
$(RM) $(OBJS) $(CTLIB)
install:
@INSTALL@ $(CTLIB) @prefix@/lib/cantera
@INSTALL@ -d @ct_libdir@
@INSTALL@ -m 644 $(CTLIB) @ct_libdir@
ifeq ($(do_ranlib),1)
ifeq ($(shared_ctlib),0)
@RANLIB@ @ct_libdir@/$(LIB_NAME).a
endif
endif
win-install:
@INSTALL@ ../../../lib/clib.lib @prefix@/lib/cantera

View file

@ -30,7 +30,15 @@ int Storage::addThermo(thermo_t* th) {
__thtable.push_back(th);
int n = static_cast<int>(__thtable.size()) - 1;
th->setIndex(n);
__thmap[th->id()] = n;
//string id = th->id();
//if (__thmap.count(id) == 0) {
// __thmap[id] = n;
// th->setID(id);
//}
//else {
// throw CanteraError("Storage::addThermo","id already used");
// return -1;
//}
return n;
}

View file

@ -59,7 +59,10 @@ inline int nThermo() {
return Storage::storage()->nThermo();
}
namespace Cantera {
void writephase(const ThermoPhase& th, bool show_thermo);
}
/**
* Exported functions.
*/
@ -101,6 +104,12 @@ extern "C" {
return ph(n)->molarDensity();
}
int DLL_EXPORT phase_setMolarDensity(int n, double ndens) {
if (ndens < 0.0) return -1;
ph(n)->setMolarDensity(ndens);
return 0;
}
doublereal DLL_EXPORT phase_meanMolecularWeight(int n) {
return ph(n)->meanMolecularWeight();
}
@ -223,6 +232,20 @@ extern "C" {
return -10;
}
int DLL_EXPORT phase_getName(int n, int lennm, char* nm) {
string name = ph(n)->name();
int lout = min(lennm,name.size());
copy(name.c_str(), name.c_str() + lout, nm);
nm[lout] = '\0';
return 0;
}
int DLL_EXPORT phase_setName(int n, const char* nm) {
string name = string(nm);
ph(n)->setName(name);
return 0;
}
int DLL_EXPORT phase_getSpeciesName(int n, int k, int lennm, char* nm) {
try {
string spnm = ph(n)->speciesName(k);
@ -402,7 +425,7 @@ extern "C" {
thermo_t* thrm = th(n);
int nel = thrm->nElements();
if (lenm >= nel) {
equilibrate(*thrm, "TP");
equilibrate(*thrm, "TP", 0);
thrm->getElementPotentials(lambda);
return 0;
}
@ -464,9 +487,11 @@ extern "C" {
catch (CanteraError) {return -1;}
}
int DLL_EXPORT th_equil(int n, int XY) {
int DLL_EXPORT th_equil(int n, int XY, int solver,
double rtol, int maxsteps, int loglevel) {
try {
equilibrate(*th(n), XY); return 0;
equilibrate(*th(n), XY, solver, rtol, maxsteps,
loglevel); return 0;
}
catch (CanteraError) {return -1;}
}
@ -629,7 +654,7 @@ extern "C" {
}
int DLL_EXPORT kin_start(int n, int p) {
return kin(n)->start(p);
return kin(n)->kineticsSpeciesIndex(0,p);
}
int DLL_EXPORT kin_speciesIndex(int n, const char* nm, const char* ph) {
@ -848,7 +873,8 @@ extern "C" {
}
int DLL_EXPORT kin_phase(int n, int i) {
return thermo_index(kin(n)->thermo(i).id());
return kin(n)->thermo(i).index();
// return thermo_index(kin(n)->thermo(i).id());
}
int DLL_EXPORT kin_getEquilibriumConstants(int n, int len, double* kc) {
@ -1005,6 +1031,15 @@ extern "C" {
catch (CanteraError) { return -1; }
}
int DLL_EXPORT write_phase(int nth, int show_thermo) {
try {
bool stherm = (show_thermo != 0);
writephase(*th(nth), stherm);
return 0;
}
catch (CanteraError) { return -1; }
}
int DLL_EXPORT getCanteraError(int buflen, char* buf) {
string e;
e = lastErrorMessage();
@ -1104,9 +1139,18 @@ extern "C" {
}
// int DLL_EXPORT ck_to_cti(char* in_file, char* db_file,
// char* tr_file, char* id_tag) {
// return pip::convert_ck(in_file, db_file, tr_file, id_tag);
// }
int DLL_EXPORT ck_to_cti(char* in_file, char* db_file,
char* tr_file, char* id_tag, int debug, int validate) {
bool dbg = (debug != 0);
bool val = (validate != 0);
return pip::convert_ck(in_file, db_file, tr_file, id_tag, dbg, val);
}
int DLL_EXPORT writelogfile(char* logfile) {
write_logfile(string(logfile));
return 0;
}
}

View file

@ -2,7 +2,7 @@
#define CTC_CT_H
#include "clib_defs.h"
#include "../../../config.h"
#include "../../src/config.h"
extern "C" {
@ -13,6 +13,7 @@ extern "C" {
double DLL_IMPORT phase_density(int n);
int DLL_IMPORT phase_setDensity(int n, double rho);
double DLL_IMPORT phase_molarDensity(int n);
int DLL_IMPORT phase_setMolarDensity(int n, double ndens);
double DLL_IMPORT phase_meanMolecularWeight(int n);
double DLL_IMPORT phase_moleFraction(int n, int k);
double DLL_IMPORT phase_massFraction(int n, int k);
@ -28,10 +29,14 @@ extern "C" {
int DLL_IMPORT phase_getMolecularWeights(int n, int lenm, double* mw);
int DLL_IMPORT phase_getElementName(int n, int k, int lennm, char* nm);
int DLL_IMPORT phase_getSpeciesName(int n, int m, int lennm, char* nm);
int DLL_IMPORT phase_getName(int n, int lennm, char* nm);
int DLL_IMPORT phase_setName(int n, const char* nm);
int DLL_IMPORT phase_elementIndex(int n, char* nm);
int DLL_IMPORT phase_speciesIndex(int n, char* nm);
int DLL_IMPORT phase_report(int nth,
int ibuf, char* buf, int show_thermo);
int DLL_EXPORT write_phase(int nth, int show_thermo);
double DLL_IMPORT phase_nAtoms(int n, int k, int m);
int DLL_IMPORT phase_addElement(int n, char* name, double weight);
@ -75,7 +80,8 @@ extern "C" {
int DLL_IMPORT th_set_UV(int n, double* vals);
int DLL_IMPORT th_set_SV(int n, double* vals);
int DLL_IMPORT th_set_SP(int n, double* vals);
int DLL_IMPORT th_equil(int n, int XY);
int DLL_IMPORT th_equil(int n, int XY, int solver,
double rtol, int maxsteps, int loglevel);
#ifdef INCL_PURE_FLUIDS
double DLL_IMPORT th_critTemperature(int n);
@ -153,7 +159,8 @@ extern "C" {
int ith, int ikin);
int DLL_IMPORT ck_to_cti(char* in_file, char* db_file,
char* tr_file, char* id_tag);
char* tr_file, char* id_tag, int debug, int validate);
int DLL_IMPORT writelogfile(char* logfile);
}
#endif

View file

@ -20,7 +20,7 @@ using namespace Cantera;
typedef Func1 func_t;
Cabinet<func_t>* Cabinet<func_t>::__storage = 0;
template<> Cabinet<func_t>* Cabinet<func_t>::__storage = 0;
inline func_t* _func(int i) {
return Cabinet<func_t>::cabinet()->item(i);

View file

@ -21,7 +21,7 @@
typedef MultiPhase mix_t;
Cabinet<mix_t>* Cabinet<mix_t>::__storage = 0;
template<> Cabinet<mix_t>* Cabinet<mix_t>::__storage = 0;
inline mix_t* _mix(int i) {
return Cabinet<mix_t>::cabinet()->item(i);
@ -120,6 +120,10 @@ extern "C" {
return DERR;
}
double DLL_EXPORT mix_nPhases(int i) {
return _mix(i)->nPhases();
}
doublereal DLL_EXPORT mix_phaseMoles(int i, int n) {
if (!checkPhase(i, n)) return DERR;
return _mix(i)->phaseMoles(n);
@ -146,8 +150,11 @@ extern "C" {
int DLL_EXPORT mix_setMolesByName(int i, char* n) {
_mix(i)->setMolesByName(string(n));
return 0;
try {
_mix(i)->setMolesByName(string(n));
return 0;
}
catch (CanteraError) { return -1; }
}
int DLL_EXPORT mix_setTemperature(int i, double t) {
@ -182,9 +189,10 @@ extern "C" {
doublereal DLL_EXPORT mix_equilibrate(int i, char* XY,
doublereal err, int maxiter) {
doublereal err, int maxsteps, int maxiter, int loglevel) {
try {
return equilibrate(*_mix(i), _equilflag(XY), err, maxiter);
return _mix(i)->equilibrate(_equilflag(XY),
err, maxsteps, maxiter, loglevel);
}
catch (CanteraError) {
return DERR;

View file

@ -19,14 +19,15 @@ extern "C" {
int DLL_IMPORT mix_setPressure(int i, double p);
double DLL_IMPORT mix_pressure(int i);
double DLL_IMPORT mix_nAtoms(int i, int k, int m);
double DLL_IMPORT mix_nPhases(int i);
double DLL_IMPORT mix_phaseMoles(int i, int n);
int DLL_IMPORT mix_setPhaseMoles(int i, int n, double v);
int DLL_IMPORT mix_setMoles(int i, int nlen, double* n);
int DLL_IMPORT mix_setMolesByName(int i, char* n);
int DLL_IMPORT mix_setMolesByName(int i, char* n);
double DLL_IMPORT mix_speciesMoles(int i, int k);
double DLL_IMPORT mix_elementMoles(int i, int m);
double DLL_IMPORT mix_equilibrate(int i, char* XY,
double err, int maxiter);
double err, int maxsteps, int maxiter, int loglevel);
int DLL_IMPORT mix_getChemPotentials(int i, int lenmu, double* mu);
}
#endif

View file

@ -28,8 +28,8 @@
#define DERR -999.999
Cabinet<Sim1D>* Cabinet<Sim1D>::__storage = 0;
Cabinet<Domain1D>* Cabinet<Domain1D>::__storage = 0;
template<> Cabinet<Sim1D>* Cabinet<Sim1D>::__storage = 0;
template<> Cabinet<Domain1D>* Cabinet<Domain1D>::__storage = 0;
inline Sim1D* _sim1D(int i) {
@ -329,14 +329,24 @@ extern "C" {
//------------------ stagnation flow domains --------------------
int DLL_EXPORT stflow_new(int iph, int ikin, int itr) {
int DLL_EXPORT stflow_new(int iph, int ikin, int itr, int itype) {
try {
IdealGasPhase* ph = (IdealGasPhase*)_thermo(iph);
AxiStagnFlow* x = new AxiStagnFlow(ph, ph->nSpecies(), 2);
x->setKinetics(*_kinetics(ikin));
x->setTransport(*_transport(itr));
return Cabinet<Domain1D>::cabinet()->add(x);
if (itype == 1) {
AxiStagnFlow* x = new AxiStagnFlow(ph, ph->nSpecies(), 2);
x->setKinetics(*_kinetics(ikin));
x->setTransport(*_transport(itr));
return Cabinet<Domain1D>::cabinet()->add(x);
}
else if (itype == 2) {
FreeFlame* x = new FreeFlame(ph, ph->nSpecies(), 2);
x->setKinetics(*_kinetics(ikin));
x->setTransport(*_transport(itr));
return Cabinet<Domain1D>::cabinet()->add(x);
}
else {
return -2;
}
}
catch (CanteraError) { return -1; }
}
@ -601,4 +611,11 @@ extern "C" {
catch (CanteraError) { return -1; }
}
int DLL_EXPORT sim1D_setFixedTemperature(int i, double temp) {
try {
_sim1D(i)->setFixedTemperature(temp);
}
catch (CanteraError) { return -1; }
}
}

View file

@ -45,7 +45,7 @@ extern "C" {
int DLL_IMPORT inlet_setSpreadRate(int i, double v);
int DLL_IMPORT stflow_new(int iph, int ikin, int itr);
int DLL_IMPORT stflow_new(int iph, int ikin, int itr, int itype=1);
int DLL_IMPORT stflow_setTransport(int i, int itr);
int DLL_IMPORT stflow_setPressure(int i, double p);
int DLL_IMPORT stflow_setFixedTempProfile(int i, int n, double* pos,
@ -79,7 +79,7 @@ extern "C" {
int DLL_IMPORT sim1D_setMaxJacAge(int i, int ss_age, int ts_age);
int DLL_IMPORT sim1D_timeStepFactor(int i, double tfactor);
int DLL_IMPORT sim1D_setTimeStepLimits(int i, double tsmin, double tsmax);
int DLL_IMPORT sim1D_setFixedTemperature(int i, double temp);
}

View file

@ -22,15 +22,17 @@
#define ERR -999
#define DERR -999.999
using namespace CanteraZeroD;
typedef ReactorBase reactor_t;
typedef ReactorNet reactornet_t;
typedef FlowDevice flowdev_t;
typedef Wall wall_t;
Cabinet<reactor_t>* Cabinet<reactor_t>::__storage = 0;
Cabinet<reactornet_t>* Cabinet<reactornet_t>::__storage = 0;
Cabinet<flowdev_t>* Cabinet<flowdev_t>::__storage = 0;
Cabinet<wall_t>* Cabinet<wall_t>::__storage = 0;
template<> Cabinet<reactor_t>* Cabinet<reactor_t>::__storage = 0;
template<> Cabinet<reactornet_t>* Cabinet<reactornet_t>::__storage = 0;
template<> Cabinet<flowdev_t>* Cabinet<flowdev_t>::__storage = 0;
template<> Cabinet<wall_t>* Cabinet<wall_t>::__storage = 0;
inline reactor_t* _reactor(int i) {
return Cabinet<reactor_t>::cabinet()->item(i);

View file

@ -10,8 +10,8 @@
// Cantera includes
#include "ReactionPath.h"
#include "ReactionPath.h"
#include "Cabinet.h"
#include "Storage.h"
@ -22,8 +22,10 @@
typedef ReactionPathDiagram diag_t;
typedef ReactionPathBuilder builder_t;
Cabinet<ReactionPathDiagram>* Cabinet<ReactionPathDiagram>::__storage = 0;
Cabinet<builder_t>* Cabinet<builder_t>::__storage = 0;
template<> Cabinet<ReactionPathDiagram>* Cabinet<ReactionPathDiagram>::__storage = 0;
template<> Cabinet<builder_t>* Cabinet<builder_t>::__storage = 0;
inline ReactionPathDiagram* _diag(int i) {
return Cabinet<ReactionPathDiagram>::cabinet()->item(i);

View file

@ -19,7 +19,7 @@
#define ERR -999
#define DERR -999.999
Cabinet<XML_Node>* Cabinet<XML_Node>::__storage = 0;
template<> Cabinet<XML_Node>* Cabinet<XML_Node>::__storage = 0;
inline XML_Node* _xml(int i) {
return Cabinet<XML_Node>::cabinet(false)->item(i);

View file

@ -11,14 +11,32 @@
build_f90=@BUILD_F90@
build_python=@BUILD_PYTHON@
build_particles=@BUILD_PARTICLES@
INCDIR = ../../build/include/cantera
INSTALL_TSC = ../../../bin/install_tsc
CXX_H = Cantera.h equilibrium.h IncompressibleSolid.h \
kinetics.h onedim.h surface.h GRI30.h integrators.h \
Metal.h PureFluid.h transport.h Edge.h \
IdealGasMix.h Interface.h numerics.h \
reactionpaths.h zerodim.h
all:
@INSTALL@ include/*.h ../../build/include/cantera
@(cd include ; \
for lh in $(CXX_H) ; do \
$(INSTALL_TSC) "$${lh}" $(INCDIR) ; \
done)
cd src; @MAKE@
cd demos; @MAKE@
clean:
@(for lh in $(CXX_H) ; do \
th=$(INCDIR)/"$${lh}" ; \
if test -f "$${th}" ; then \
$(RM) "$${th}" ; \
echo "$(RM) $${th}" ; \
fi \
done)
cd src; @MAKE@ clean
cd demos; @MAKE@ clean

View file

@ -16,7 +16,7 @@ OBJS = demos.o
# additional flags to be passed to the linker. If your program
# requires other external libraries, put them here
LINK_OPTIONS =
LINK_OPTIONS = @EXTRA_LINK@
#############################################################################
@ -53,6 +53,8 @@ LCXX_FLAGS = -L$(CANTERA_LIBDIR) @LOCAL_LIB_DIRS@ @CXXFLAGS@
PROGRAM = $(PROG_NAME)$(EXE_EXT)
DEPENDS = $(OBJS:.o=.d)
all: $(PROGRAM)
$(PROGRAM): $(OBJS) $(CANTERA_LIBDIR)/libcantera.a
@ -71,8 +73,11 @@ install:
@INSTALL@ Makefile.install @ct_demodir@/cxx/Makefile
chown -R @username@ @ct_demodir@/cxx
depends: $(DEPENDS)
cat *.d > .depends
$(RM) $(DEPENDS)
clean:
$(RM) $(OBJS) $(PROGRAM)
$(RM) $(OBJS) $(PROGRAM) .depends
../../../bin/rm_cvsignore

View file

@ -78,7 +78,8 @@ int flamespeed(int np, void* p) {
//-------- step 1: create the flow -------------
AxiStagnFlow flow(&gas);
//AxiStagnFlow flow(&gas);
FreeFlame flow(&gas);
// create an initial grid
int nz=5;
@ -123,7 +124,7 @@ int flamespeed(int np, void* p) {
domains.push_back(&flow);
domains.push_back(&outlet);
OneDim flamesim(domains);
// OneDim flamesim(domains);
Sim1D flame(domains);
@ -172,9 +173,9 @@ int flamespeed(int np, void* p) {
bool refine_grid = true;
/* Solve species*/
flow.fixTemperature();
refine_grid=false;
flame.solve(loglevel,refine_grid);
//flow.fixTemperature();
//refine_grid=false;
//flame.solve(loglevel,refine_grid);
/* Solve freely propagating flame*/
@ -183,12 +184,14 @@ int flamespeed(int np, void* p) {
location will then be fixed for remainder of
calculation.*/
flow.solveEnergyEqn();
refine_grid=true;
flow.fixTemperature();
refine_grid=false;
flame.setFixedTemperature(900.0);
flame.setAdiabaticFlame();
flame.solve(loglevel=1,refine_grid);
// flame.setAdiabaticFlame();
flame.solve(loglevel,refine_grid);
refine_grid = true;
flow.solveEnergyEqn();
flame.solve(loglevel,refine_grid);
int np=flow.nPoints();
vector<doublereal> zvec,Tvec,COvec,CO2vec,Uvec;

View file

@ -16,6 +16,7 @@
#pragma warning(disable:4503)
#endif
#include <cantera/Cantera.h>
#include <cantera/zerodim.h>
#include <cantera/IdealGasMix.h>
#include <cantera/numerics.h>

View file

@ -71,6 +71,7 @@ int openRankine(int np, void* p) {
double heat_in = h["3"] - h["2"];
double efficiency = work/heat_in;
cout << "efficiency = " << efficiency << endl;
#ifdef WIN32
#ifndef CXX_DEMO

View file

@ -6,6 +6,7 @@ namespace std{}
using namespace std;
// definitions
#define CANTERA_APP
#include "kernel/ct_defs.h"
// some useful functions
@ -14,6 +15,9 @@ using namespace std;
// the CanteraError exception class
#include "kernel/ctexceptions.h"
//
#include "kernel/importCTML.h"
using namespace Cantera;
#endif

View file

@ -1,12 +1,12 @@
/*
* header file providing support for chemical equilibrium.
/**
* @file equilibrium.h
*
* Header file providing support for chemical equilibrium calculations.
*/
#ifndef CT_EQUIL_INCL
#define CT_EQUIL_INCL
#include "kernel/ChemEquil.h"
//#ifdef DEV_EQUIL
#include "kernel/MultiPhaseEquil.h"
//#endif
#endif

View file

@ -0,0 +1,18 @@
#ifndef CXX_IMPORTPHASE
#define CXX_IMPORTPHASE
#include <string>
#include "kernel/ThermoPhase.h"
#include "kernel/importCTML.h"
namespace Cantera {
ThermoPhase* importPhase(string infile, string id="") {
ThermoPhase* p = newPhase(infile, id);
return p;
}
}
#endif

View file

@ -1,3 +1,7 @@
/**
* @file integrators.h
* ODE integrators. Currently, the only integrator is CVODE.
*/
#ifndef CT_INTEG_H_INCL
#define CT_INTEG_H_INCL

View file

@ -7,5 +7,6 @@
#include "kernel/oneD/Inlet1D.h"
#include "kernel/oneD/MultiNewton.h"
#include "kernel/oneD/MultiJac.h"
#include "kernel/oneD/StFlow.h"
#endif

View file

@ -1,3 +1,11 @@
/**
* @file transport.h
*
* Support for transport property calculation from C++ application programs.
* This header file includes several headers from the Cantera kernel needed
* to evaluate transport properties.
*/
#ifndef CT_TRANSPORT_INCL
#define CT_TRANSPORT_INCL

View file

@ -1,10 +1,11 @@
#ifndef CT_INCL_ZERODIM_H
#define CT_INCL_ZERODIM_H
#include "kernel/zeroD/Reactor.h"
#include "kernel/zeroD/ReactorNet.h"
#include "kernel/zeroD/Reservoir.h"
#include "kernel/zeroD/Wall.h"
#include "kernel/zeroD/flowControllers.h"
using namespace CanteraZeroD;
#endif

View file

@ -14,6 +14,7 @@ namespace Cantera {
*/
string report(const ThermoPhase& th, bool show_thermo) {
try {
char p[200];
string s = "";
@ -71,6 +72,10 @@ namespace Cantera {
s += p;
}
return s;
}
catch (CanteraError) {
return string("<error>");
}
}
/**

View file

@ -42,6 +42,7 @@ module cantera_kinetics
phase%kin_id = newkineticsfromxml(xml_phase%xml_id, phase%thermo_id, &
missing, missing, missing, missing)
end if
phase%nrxn = kin_nreactions(phase%kin_id)
end subroutine newKinetics
integer function ctkin_kineticsType(self)
@ -110,7 +111,7 @@ module cantera_kinetics
subroutine ctkin_getRevRatesOfProgress(self, revROP)
implicit none
type(phase_t), intent(inout) :: self
double precision, intent(out) :: revROP(*)
double precision, intent(out) :: revROP(self%nrxn)
self%err = kin_getrevratesofprogress(self%kin_id, revROP)
end subroutine ctkin_getrevratesofprogress

View file

@ -10,6 +10,7 @@ module cantera_thermo
integer :: err
integer :: nel
integer :: nsp
integer :: nrxn
end type phase_t
! these definitions are for use with the equilibrate function.
@ -43,6 +44,7 @@ contains
self%thermo_id = newthermofromxml(xml_phase%xml_id)
self%nel = phase_nelements(self%thermo_id)
self%nsp = phase_nspecies(self%thermo_id)
self%nrxn = 0
self%err = 0
else
call cantera_error('newThermoPhase','xml_phase or id must be specified.')

View file

@ -15,6 +15,7 @@ SRCS = cantera/private/ctmethods.cpp \
cantera/private/xmlmethods.cpp \
cantera/private/phasemethods.cpp \
cantera/private/thermomethods.cpp \
cantera/private/mixturemethods.cpp \
cantera/private/kineticsmethods.cpp \
cantera/private/transportmethods.cpp \
cantera/private/reactormethods.cpp \
@ -23,7 +24,8 @@ SRCS = cantera/private/ctmethods.cpp \
cantera/private/flowdevicemethods.cpp \
cantera/private/onedimmethods.cpp \
cantera/private/surfmethods.cpp \
cantera/private/funcmethods.cpp
cantera/private/funcmethods.cpp \
cantera/private/write.cpp
CANTERA_LIBDIR=@buildlib@
@ -32,7 +34,9 @@ os_is_win=@OS_IS_WIN@
ifeq ($(os_is_win),0)
LIB_DEPS = $(CANTERA_LIBDIR)/libcantera.a $(CANTERA_LIBDIR)/libzeroD.a \
$(CANTERA_LIBDIR)/liboneD.a \
$(CANTERA_LIBDIR)/libtransport.a
$(CANTERA_LIBDIR)/libtransport.a \
$(CANTERA_LIBDIR)/libclib.a \
$(CANTERA_LIBDIR)/libconverters.a
else
LIB_DEPS = $(CANTERA_LIBDIR)/cantera.lib $(CANTERA_LIBDIR)/zeroD.lib \
$(CANTERA_LIBDIR)/oneD.lib \
@ -60,6 +64,7 @@ install:
@INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera-demos
@INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/private
@INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/@ThermoPhase/private
@INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/@Mixture/private
@INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/@Kinetics/private
@INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/@Transport/private
@INSTALL@ -d @prefix@/matlab/toolbox/cantera/cantera/@Interface/private
@ -95,6 +100,10 @@ install:
*.m @prefix@/matlab/toolbox/cantera/cantera/@Interface
cd cantera/@Interface/private; @INSTALL@ *.m \
@prefix@/matlab/toolbox/cantera/cantera/@Interface/private
cd cantera/@Mixture; @INSTALL@ \
*.m @prefix@/matlab/toolbox/cantera/cantera/@Mixture
cd cantera/@Mixture/private; @INSTALL@ *.m \
@prefix@/matlab/toolbox/cantera/cantera/@Mixture/private
cd cantera/@XML_Node; @INSTALL@ *.m \
@prefix@/matlab/toolbox/cantera/cantera/@XML_Node
cd cantera/@Reactor; @INSTALL@ *.m \
@ -127,6 +136,12 @@ install:
@prefix@/matlab/toolbox/cantera/cantera/1D/@Stack
cd cantera/1D/@Stack/private; @INSTALL@ *.m \
@prefix@/matlab/toolbox/cantera/cantera/1D/@Stack/private
@INSTALL@ -d @ct_demodir@/matlab
@INSTALL@ cantera/examples/*.m @ct_demodir@/matlab
@INSTALL@ -d @ct_tutdir@/matlab
@INSTALL@ cantera/tutorial/*.m @ct_tutdir@/matlab
chown -R @username@ @ct_demodir@/matlab
chown -R @username@ @ct_tutdir@/matlab
clean:
@ -150,6 +165,9 @@ endif
run-demo:
(cd @ct_dir@; matlab -nojvm -nosplash -r cantera_demos)
test-demo:
(cd @ct_dir@/demos/matlab; matlab -nojvm -nosplash -r test_demos)
# end of file

View file

@ -10,7 +10,7 @@ elseif nargin == 2
if a == 1
if isa(b,'Solution')
d.dom_id = domain_methods(0, 1, thermo_hndl(b), kinetics_hndl(b), ...
trans_hndl(b));
trans_hndl(b), 1);
else
error('Wrong argument type. Expecting instance of class Solution.');
end
@ -23,7 +23,17 @@ elseif nargin == 2
else
error('wrong object type');
end
elseif nargin == 3
if a == 1
if isa(b,'Solution')
d.dom_id = domain_methods(0, 1, thermo_hndl(b), kinetics_hndl(b), ...
trans_hndl(b), c);
else
error('Wrong argument type. Expecting instance of class Solution.');
end
else
error('unknown domain type');
end
end
if d.dom_id < 0
error(geterr);

View file

@ -10,4 +10,6 @@ elseif nargin == 5
v = ctmethods(90, n, job, a, b, c);
elseif nargin == 6
v = ctmethods(90, n, job, a, b, c, d);
elseif nargin == 7
v = ctmethods(90, n, job, a, b, c, d, e);
end

View file

@ -0,0 +1,61 @@
function m = Mixture(phases)
%
% MIXTURE - Multiphase mixtures.
%
% Class Mixture represents
% mixtures of one or more phases of matter. To construct a mixture,
% supply a cell array of phases and mole numbers:
%
% >> gas = importPhase('gas.cti');
% >> graphite = importPhase('graphite.cti');
% >> mix = Mixture({gas, 1.0; graphite, 0.1});
%
% Phases may also be added later using the addPhase method:
%
% >> water = importPhase('water.cti');
% >> addPhase(mix, water, 3.0);
%
% Note that the objects representing each phase compute only the
% intensive state of the phase -- they do not store any information
% on the amount of this phase. Mixture objects, on the other hand,
% represent the full extensive state.
%
% Mixture objects are 'lightweight' in the sense that they do not
% store parameters needed to compute thermodynamic or kinetic
% properties of the phases. These are contained in the
% ('heavyweight') phase objects. Multiple mixture objects may be
% constructed using the same set of phase objects. Each one stores
% its own state information locally, and synchronizes the phase
% objects whenever it requires phase properties.
%
if nargin > 1
error('Mixture: wrong number of arguments');
end
% create an empty mixture
m.mixindex = mixturemethods(0, 0, 0);
m.phases = phases;
m = class(m,'Mixture');
% if phases are supplied, add them
if nargin == 1
if ~isa(phases,'cell')
error('enter phases as a cell array');
end
% first column contains the phase objects, and the second column
% the mole numbers of each phase
[np nc] = size(phases);
if nc ~= 2
error('wrong size for phases cell array');
end
for n = 1:np
addPhase(m, phases{n,1}, phases{n,2});
end
setTemperature(m, temperature(phases{n,1}));
setPressure(m, pressure(phases{n,1}));
end

View file

@ -0,0 +1,21 @@
function addPhase(self, phase, moles)
% ADDPHASE - Add a phase to the mixture.
%
% carbon = importPhase('graphite.cti');
% addPhase(mix, carbon, 1.0);
%
if ~isa(phase,'ThermoPhase')
error('phase object of wrong type.');
end
if ~isa(moles,'numeric')
error('number of moles must be numeric.');
end
if moles < 0.0
error('negative moles!');
end
iphase = thermo_hndl(phase);
iok = mixturemethods(4, mix_hndl(self), iphase, moles);
if iok < 0
error('error adding phase');
end

View file

@ -0,0 +1,3 @@
function mu = chemPotentials(self)
% CHEMPOTENTIALS - Chemical potentials of all species in all phases
mu = mixturemethods(41, mix_hndl(self));

View file

@ -0,0 +1,8 @@
function display(self)
[np nc] = size(self.phases);
for n = 1:np
s = [sprintf('\n******************* Phase %d', n) ...
sprintf(' ******************************\n\n Moles: %12.6g', phaseMoles(self,n))];
disp(s);
display(self.phases{n,1});
end

View file

@ -0,0 +1,5 @@
function n = elementIndex(self, name)
% ELEMENTINDEX - index of element with name 'name'
%
n = mixturemethods(22, mix_hndl(self), name);

View file

@ -0,0 +1,70 @@
function r = equilibrate(self, XY, err, maxsteps, maxiter, ...
loglevel)
%
% EQUILIBRATE - Set the mixture to a state of chemical equilibrium.
%
% This method uses a version of the VCS algorithm to find the
% composition that minimizes the total Gibbs free energy of the
% mixture, subject to element conservation constraints. For a
% description of the theory, see Smith and Missen, "Chemical
% Reaction Equilibrium." The VCS algorithm is implemented in
% Cantera kernel class MultiPhaseEquil.
%
% The VCS algorithm solves for the equilibrium composition for
% specified temperature and pressure. If any other property pair
% other than "TP" is specified, then an outer iteration loop is
% used to adjust T and/or P so that the specified property
% values are obtained.
%
% XY - Two-letter string specifying the two properties to hold
% fixed. Currently, 'TP', 'HP', and 'SP' are
% implemented. Default: 'TP'.
%
% err - Error tolerance. Iteration will continue until (Delta
% mu)/RT is less than this value for each reaction. Default:
% 1.0e-9. Note that this default is very conservative, and good
% equilibrium solutions may be obtained with larger error
% tolerances.
%
% maxsteps - Maximum number of steps to take while solving the
% equilibrium problem for specified T and P. Default: 1000.
%
% maxiter - Maximum number of temperature and/or pressure
% iterations. This is only relevant if a property pair other
% than (T,P) is specified. Default: 200.
%
% loglevel - Controls the amount of diagnostic output. If
% loglevel = 0, no diagnostic output is written. For values > 0,
% more detailed information is written to the log file as
% loglevel increases. The default is loglevel = 0.
%
% The logfile is written in HTML format, and may be viewed with
% any web browser. The default log file name is
% "equilibrium_log.html", but if this file exists, the log
% information will be written to "equilibrium_log{n}.html",
% where {n} is an integer chosen so that the log file does not
% already exist. Therefore, if 'equilibrate' is called multiple
% times, multiple log files will be written, with names
% "equilibrate_log.html", "equilibrate_log1.html",
% "equilibrate_log2.html", and so on. Existing log files will
% not be overwritten.
%
% >> equilibrate(mix, 'TP')
% >> equilibrate('TP', 1.0e-6, 500)
%
if nargin < 6
loglevel = 0;
end
if nargin < 5
maxiter = 200;
end
if nargin < 4
maxsteps = 1000;
end
if nargin < 3
err = 1.0e-9;
end
if nargin < 2
XY = 'TP';
end
r = mixturemethods(31, mix_hndl(self), XY, err, maxsteps, maxiter, loglevel);

View file

@ -0,0 +1,6 @@
function i = mix_hndl(self)
% MIX_HNDL - integer used to access kernel object
%
i = self.mixindex;

View file

@ -0,0 +1,5 @@
function n = nElements(self)
% NELEMENTS - number of elements
%
n = mixturemethods(21, mix_hndl(self));

View file

@ -0,0 +1,5 @@
function n = nPhases(self)
% NPHASES - number of phases
%
n = mixturemethods(19, mix_hndl(self));

View file

@ -0,0 +1,5 @@
function n = nSpecies(self)
% NSPECIES - number of species
%
n = mixturemethods(24, mix_hndl(self));

View file

@ -0,0 +1,15 @@
function moles = phaseMoles(self, n)
% PHASEMOLES - moles of phase number 'n' (kmol).
%
if nargin == 2
moles = mixturemethods(28, mix_hndl(self), n);
elseif nargin == 1
np = nPhases(self);
for n = 1:np
m(n) = mixturemethods(28, mix_hndl(self), n);
end
moles = m;
else
error('wrong number of arguments');
end

View file

@ -0,0 +1,5 @@
function n = pressure(self)
% PRESSURE - pressure (Pa)
%
n = mixturemethods(26, mix_hndl(self));

View file

@ -0,0 +1,17 @@
function v = mixturemethods(n, job, a, b, c, d, e, f)
%
if nargin == 2
v = ctmethods(120, n, job);
elseif nargin == 3
v = ctmethods(120, n, job, a);
elseif nargin == 4
v = ctmethods(120, n, job, a, b);
elseif nargin == 5
v = ctmethods(120, n, job, a, b, c);
elseif nargin == 6
v = ctmethods(120, n, job, a, b, c, d);
elseif nargin == 7
v = ctmethods(120, n, job, a, b, c, d, e);
elseif nargin == 8
v = ctmethods(120, n, job, a, b, c, d, e, f);
end

View file

@ -0,0 +1,7 @@
function setPhaseMoles(self, n, moles)
% SETPHASEMOLES - set the number of moles of phase number 'n' to
% 'moles' (kmol).
%
mixturemethods(7, mix_hndl(self), n, moles);

View file

@ -0,0 +1,6 @@
function setPressure(self, P)
% SETPRESSURE - set the mixture pressure (Pa)
%
mixturemethods(6, mix_hndl(self), P);

View file

@ -0,0 +1,12 @@
function setSpeciesMoles(self, moles)
% SETSPECIESMOLES - Set the moles of the species [kmol]. The moles may
% be specified either as a string, or as an array. If an array is
% used, it must be dimensioned at least as large as the total number
% of species in the mixture. Note that the species may belong to any
% phase, and unspecified species are set to zero.
%
% >> setSpeciesMoles(mix, 'C(s):1.0, CH4:2.0, O2:0.2');
%
mixturemethods(8, mix_hndl(self), moles);

View file

@ -0,0 +1,6 @@
function setTemperature(self, T)
% SETTEMPERATURE - set the mixture temperature
%
mixturemethods(5, mix_hndl(self), T);

View file

@ -0,0 +1,5 @@
function n = speciesIndex(self, k, p)
% SPECIESINDEX - index of species with name 'name'
%
n = mixturemethods(23, mix_hndl(self), k, p);

View file

@ -0,0 +1,5 @@
function n = temperature(self)
% TEMPERATURE - temperature (K)
%
n = mixturemethods(25, mix_hndl(self));

View file

@ -1,5 +1,5 @@
function m = mass(r)
% MASS -
%
reactormethods(23, reactor_hndl(r));
m = reactormethods(23, reactor_hndl(r));

View file

@ -2,7 +2,11 @@ function setEnergy(f, flag)
% SETENERGY -
%
iflag = 0
if flag = 'on'
iflag = 1
try
if strcmp(flag,{'on'})
iflag = 1
end
catch
iflag = 0
end
reactormethods(9, f.index, iflag)

View file

@ -1,22 +0,0 @@
function display(a)
s = [sprintf('\n temperature %12.6g K\n', temperature(a)) ...
sprintf(' pressure %12.6g Pa\n', pressure(a)) ...
sprintf(' density %12.6g kg/m^3\n', density(a)) ...
sprintf(' mean mol. weight %12.6g amu', ...
meanMolecularWeight(a))];
disp(s);
nsp = nSpecies(a);
x = moleFractions(a);
y = massFractions(a);
s = [...
sprintf('\n X Y \n') ...
sprintf(' ------------- ------------ ')];
disp(s);
for k = 1:nsp
disp(sprintf('%18s %12.6e %12.6e', char(speciesName(a,k)), x(k), y(k)));
end
disp(' ');

View file

@ -0,0 +1,3 @@
function display(self)
phase_get(thermo_hndl(self), 15, 1);

View file

@ -1,4 +1,4 @@
function a = equilibrate(a, xy)
function a = equilibrate(a, xy, solver, rtol, maxsteps, loglevel)
% EQUILIBRATE Set the phase to a state of chemical equilibrium.
%
% The second argument must be one of the strings 'TP', 'TV',
@ -8,36 +8,47 @@ function a = equilibrate(a, xy)
% specified, it is the specific value (per unit mass), not the
% molar value, that is held fixed.
%
if nargin ~= 2
error('two arguments required')
% use the ChemEquil solver by default
if nargin < 3
solver = 0;
end
if nargin < 4
rtol = 1.0e-9;
end
if nargin < 5
maxsteps = 1000;
end
if nargin < 6
loglevel = 0;
end
iok = 0;
switch xy
case 'TP'
iok = thermo_set(a.tp_id, 50, 104);
iok = thermo_set(a.tp_id, 50, 104, solver, rtol, maxsteps, loglevel);
case 'TV'
iok = thermo_set(a.tp_id, 50, 100);
iok = thermo_set(a.tp_id, 50, 100, solver, rtol, maxsteps, loglevel);
case 'HP'
iok = thermo_set(a.tp_id, 50, 101);
iok = thermo_set(a.tp_id, 50, 101, solver, rtol, maxsteps, loglevel);
case 'SP'
iok = thermo_set(a.tp_id, 50, 102);
iok = thermo_set(a.tp_id, 50, 102, solver, rtol, maxsteps, loglevel);
case 'SV'
iok = thermo_set(a.tp_id, 50, 107);
iok = thermo_set(a.tp_id, 50, 107, solver, rtol, maxsteps, loglevel);
case 'UV'
iok = thermo_set(a.tp_id, 50, 105);
iok = thermo_set(a.tp_id, 50, 105, solver, rtol, maxsteps, loglevel);
case 'PT'
iok = thermo_set(a.tp_id, 50, 104);
iok = thermo_set(a.tp_id, 50, 104, solver, rtol, maxsteps, loglevel);
case 'VT'
iok = thermo_set(a.tp_id, 50, 100);
iok = thermo_set(a.tp_id, 50, 100, solver, rtol, maxsteps, loglevel);
case 'PH'
iok = thermo_set(a.tp_id, 50, 101);
iok = thermo_set(a.tp_id, 50, 101, solver, rtol, maxsteps, loglevel);
case 'PS'
iok = thermo_set(a.tp_id, 50, 102);
iok = thermo_set(a.tp_id, 50, 102, solver, rtol, maxsteps, loglevel);
case 'VS'
iok = thermo_set(a.tp_id, 50, 107);
iok = thermo_set(a.tp_id, 50, 107, solver, rtol, maxsteps, loglevel);
case 'VU'
iok = thermo_set(a.tp_id, 50, 105);
iok = thermo_set(a.tp_id, 50, 105, solver, rtol, maxsteps, loglevel);
otherwise
error('unsupported option')
end

View file

@ -0,0 +1,6 @@
function nm = name(self)
% NAME - user-specified phase name.
nm = phase_get(thermo_hndl(self), 42);

View file

@ -1,8 +1,14 @@
function i = thermo_set(n, job, a, b)
function i = thermo_set(n, job, a, b, c, d, e)
if nargin == 2
i = ctmethods(20,n,-job);
elseif nargin == 3
i = ctmethods(20,n,-job,a);
else
elseif nargin == 4
i = ctmethods(20, n,-job, a, b);
elseif nargin == 5
i = ctmethods(20, n,-job, a, b, c);
elseif nargin == 6
i = ctmethods(20, n,-job, a, b, c, d);
elseif nargin == 7
i = ctmethods(20, n,-job, a, b, c, d, e);
end

View file

@ -0,0 +1,9 @@
function setName(self, name)
% SETNAME - Set the name of the phase.
%
if isa(name,'char')
phase_set(thermo_hndl(self), 32, name);
else
error('name must be a string.');
end

View file

@ -1,9 +1,11 @@
disp('building Cantera...');
diary
mex -I../../../build/include private/ctmethods.cpp ...
private/ctfunctions.cpp ...
private/xmlmethods.cpp private/phasemethods.cpp ...
private/thermomethods.cpp private/kineticsmethods.cpp ...
private/mixturemethods.cpp ...
private/transportmethods.cpp private/reactormethods.cpp ...
private/reactornetmethods.cpp ...
private/wallmethods.cpp private/flowdevicemethods.cpp ...
@ -21,4 +23,5 @@ mex -I../../../build/include private/ctmethods.cpp ...
../../../build/lib/i686-pc-win32/ctblas.lib ...
../../../build/lib/i686-pc-win32/tpx.lib
disp('done.');
diary off
exit;

View file

@ -14,7 +14,14 @@ function f = ck2cti(infile, thermo, transport)
% function return value is a string containing the output file
% name.
%
prog = [ctbin,'/ck2cti'];
%prog = [ctbin,'/ck2cti'];
% set this to zero to turn off mechanism validation
validate = 1;
% set this to one to turn on debugging. Use only if ck2cti
% fails, and you want to see how the parser is parsing the input file.
debug = 0;
if nargin == 0
error('input file name must be supplied')
@ -34,16 +41,18 @@ else
outfile = [infile '.cti'];
end
iok = system([prog,' -i ',infile,' -t ',thermo,' -tr ',transport, ...
' -id ',idtag,' > ',outfile]);
iok = ctmethods(0,1, infile, thermo, transport, idtag, debug, validate);
%iok = system([prog,' -i ',infile,' -t ',thermo,' -tr ',transport, ...
% ' -id ',idtag,' > ',outfile]);
if iok
ierr2 = system([prog,' > log'])
if ierr2
error(['Program ck2cti is not found at ',prog,['. Edit file' ...
[' ctbin.m to point to the Cantera bin directory.']]])
else
error(['Error occurred while running ck2cti. Check file ck2cti.log' ...
' for error messages.']);
end
%ierr2 = system([prog,' > log'])
%if ierr2
% error(['Program ck2cti is not found at ',prog,['. Edit file' ...
% [' ctbin.m to point to the Cantera bin directory.']]])
% else
error(['Error occurred while running ck2cti. Check file ck2cti.log' ...
' for error messages.']);
%end
end
f = outfile;

View file

@ -14,8 +14,8 @@
%
help catcomb;
disp('press any key to start the simulation');
pause;
%disp('press any key to start the simulation');
%pause;
clear all;
cleanup;

View file

@ -4,8 +4,8 @@
% at low pressure.
help flame1;
disp('press any key to begin the simulation');
pause;
%disp('press any key to begin the simulation');
%pause;
t0 = cputime; % record the starting time

View file

@ -90,7 +90,7 @@ for j = 1:n
pv(5:end,j) = y;
end
% plot the temperature and OH mole fractions.
% plot the temperature and OH mass fractions.
figure(1);
plot(pv(1,:),pv(2,:));
xlabel('time');
@ -101,5 +101,5 @@ figure(2);
ioh = speciesIndex(gas,'OH');
plot(pv(1,:),pv(4+ioh,:));
xlabel('time');
ylabel('Mole Fraction');
title('OH Mole Fraction');
ylabel('Mass Fraction');
title('OH Mass Fraction');

View file

@ -102,5 +102,5 @@ figure(2);
ioh = speciesIndex(gas,'OH');
plot(pv(1,:),pv(4+ioh,:));
xlabel('time');
ylabel('Mole Fraction');
title('OH Mole Fraction');
ylabel('Mass Fraction');
title('OH Mass Fraction');

View file

@ -23,7 +23,7 @@ out = ode15s(@conuv,tel,y0,options,gas,mw);
disp(['CPU time = ' num2str(cputime - t0)]);
if nargout == 0
% plot the temperature and OH mole fractions.
% plot the temperature and OH mass fractions.
figure(1);
plot(out.x,out.y(1,:));
xlabel('time');
@ -34,7 +34,7 @@ if nargout == 0
ioh = speciesIndex(gas,'OH');
plot(out.x,out.y(1+ioh,:));
xlabel('time');
ylabel('Mole Fraction');
title('OH Mole Fraction');
ylabel('Mass Fraction');
title('OH Mass Fraction');
end

View file

@ -33,6 +33,6 @@ if nargout == 0
ioh = speciesIndex(gas,'OH');
plot(out.x,out.y(1+ioh,:));
xlabel('time');
ylabel('Mole Fraction');
title('OH Mole Fraction');
ylabel('Mass Fraction');
title('OH Mass Fraction');
end

View file

@ -32,7 +32,7 @@ if nargout == 0
ioh = speciesIndex(gas,'OH');
plot(out.x,out.y(1+ioh,:));
xlabel('time');
ylabel('Mole Fraction');
title('OH Mole Fraction');
ylabel('Mass Fraction');
title('OH Mass Fraction');
end

View file

@ -0,0 +1,12 @@
% runs selected examples without pausing
equil(0);
isentropic(0);
reactor1(0);
reactor2(0);
surfreactor;
periodic_cstr;
rankine(300.0, 2.0*oneatm, 0.8, 0.7);
prandtl1(0);
flame1;
catcomb;
exit;

View file

@ -20,7 +20,7 @@ void ctfunctions( int nlhs, mxArray *plhs[],
{
int job = getInt(prhs[1]);
int j, m, iok, id;
int j, m, iok, id, dbg, validate;
char *file, *key, *val;
char *infile, *dbfile, *trfile, *outfile, *idtag;
@ -31,7 +31,7 @@ void ctfunctions( int nlhs, mxArray *plhs[],
// convert CK file to CTI
case 1:
if (nrhs < 6) {
if (nrhs < 8) {
mexErrMsgTxt("Wrong number of inputs.");
return;
}
@ -39,8 +39,9 @@ void ctfunctions( int nlhs, mxArray *plhs[],
dbfile = getString(prhs[3]);
trfile = getString(prhs[4]);
idtag = getString(prhs[5]);
iok = -1; //ck_to_cti(infile, dbfile, trfile, idtag);
dbg = getInt(prhs[6]);
validate = getInt(prhs[7]);
iok = ck_to_cti(infile, dbfile, trfile, idtag, dbg, validate);
break;
// get Cantera error

View file

@ -1,6 +1,9 @@
const double Undef = -999.123;
//const double DERR = -999.999;
#include <string>
using namespace std;
void reportError();
void checkNArgs(const int n, const int nrhs);
@ -21,12 +24,16 @@ inline char* getString(const mxArray* p) {
int m = mxGetM(p);
int n = mxGetN(p);
int buflen = m*n + 1;
string msg;
if (m == 1) {
input_buf = (char*)mxCalloc(buflen, sizeof(char));
status = mxGetString(p, input_buf, buflen);
if(status != 0)
mexWarnMsgTxt("Not enough space. String is truncated.");
if(status != 0) {
msg = string(input_buf)
+ "\nNot enough space. String is truncated.";
mexWarnMsgTxt(msg.c_str());
}
}
else {
mexErrMsgTxt("string must be a row vector");

View file

@ -9,8 +9,8 @@
* class is indicated by the first parameter in the call from MATLAB.
*/
#include "mex.h"
#include "../../../clib/src/ct.h"
#include "mex.h"
#include "ctmatutils.h"
#include "mllogger.h"
#include "../../../src/global.h"
@ -32,6 +32,7 @@ const int FLOWDEVICE_CLASS = 80;
const int ONEDIM_CLASS = 90;
const int SURF_CLASS = 100;
const int FUNC_CLASS = 110;
const int MIXTURE_CLASS = 120;
void ctfunctions( int nlhs, mxArray *plhs[], int nrhs,
const mxArray *prhs[] );
@ -45,6 +46,9 @@ void thermomethods( int nlhs, mxArray *plhs[], int nrhs,
void phasemethods( int nlhs, mxArray *plhs[], int nrhs,
const mxArray *prhs[] );
void mixturemethods( int nlhs, mxArray *plhs[], int nrhs,
const mxArray *prhs[] );
void surfmethods( int nlhs, mxArray *plhs[], int nrhs,
const mxArray *prhs[] );
@ -106,6 +110,8 @@ extern "C" {
thermomethods(nlhs, plhs, nrhs, prhs); break;
case PHASE_CLASS:
phasemethods(nlhs, plhs, nrhs, prhs); break;
case MIXTURE_CLASS:
mixturemethods(nlhs, plhs, nrhs, prhs); break;
case KINETICS_CLASS:
kineticsmethods(nlhs, plhs, nrhs, prhs); break;
case TRANSPORT_CLASS:

View file

@ -0,0 +1,173 @@
#include "mex.h"
#include "../../../clib/src/ctmultiphase.h"
#include "../../../clib/src/ct.h"
#include "ctmatutils.h"
#include <iostream>
using namespace std;
void mixturemethods( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
int j, m, iok, n;
char *file, *key, *val;
int job = getInt(prhs[1]);
int i = getInt(prhs[2]);
double r = Undef;
double v = Undef;
if (nrhs > 3 && job != 8 && job != 22 && job != 23)
v = getDouble(prhs[3]);
// constructor
if (job == 0) {
n = mix_new();
plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
double *h = mxGetPr(plhs[0]);
*h = double(n);
if (n < 0) reportError();
return;
}
// options that do not return a value
double moles, err;
char *nmstr, *XY, *nm;
int maxiter, maxsteps, loglevel;
if (job < 15) {
switch (job) {
case 1:
iok = mix_del(i);
break;
case 2:
iok = mix_copy(i);
break;
case 3:
iok = mix_assign(i, int(v));
break;
case 4:
checkNArgs(5, nrhs);
moles = getDouble(prhs[4]);
iok = mix_addPhase(i, int(v), moles);
break;
case 5:
iok = mix_setTemperature(i, v);
break;
case 6:
iok = mix_setPressure(i, v);
break;
case 7:
checkNArgs(5, nrhs);
moles = getDouble(prhs[4]);
iok = mix_setPhaseMoles(i, int(v)-1, moles);
break;
case 8:
checkNArgs(4, nrhs);
nmstr = getString(prhs[3]);
iok = mix_setMolesByName(i, nmstr);
break;
default:
mexErrMsgTxt("unknown job parameter");
}
plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
double *h = mxGetPr(plhs[0]);
*h = double(iok);
if (iok < 0) reportError();
return;
}
// options that return a value of type 'double'
else if (job < 40) {
switch (job) {
case 19:
r = mix_nPhases(i);
break;
case 21:
r = mix_nElements(i);
break;
case 22:
checkNArgs(4, nrhs);
nm = getString(prhs[3]);
r = mix_elementIndex(i, nm)+1;
break;
case 23:
checkNArgs(5, nrhs);
m = getInt(prhs[3]);
n = getInt(prhs[4]);
r = mix_speciesIndex(i, m-1, n-1)+1;
break;
case 24:
r = mix_nSpecies(i);
break;
case 25:
r = mix_temperature(i);
break;
case 26:
r = mix_pressure(i);
break;
case 27:
m = getInt(prhs[4]);
r = mix_nAtoms(i,int(v), m);
break;
case 28:
r = mix_phaseMoles(i, int(v)-1);
break;
case 29:
r = mix_speciesMoles(i, int(v)-1);
break;
case 30:
r = mix_elementMoles(i, int(v)-1);
break;
case 31:
checkNArgs(8, nrhs);
XY = getString(prhs[3]);
err = getDouble(prhs[4]);
maxsteps = getInt(prhs[5]);
maxiter = getInt(prhs[6]);
loglevel = getInt(prhs[7]);
r = mix_equilibrate(i, XY, err, maxsteps,
maxiter, loglevel);
break;
default:
mexErrMsgTxt("unknown job parameter");
}
plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
double *h = mxGetPr(plhs[0]);
*h = r;
if (r == Undef) reportError();
return;
}
// species properties
else if (job < 60) {
int iok = 0;
int nsp = mix_nSpecies(i);
double* x = new double[nsp];
switch (job) {
case 41:
iok = mix_getChemPotentials(i,nsp,x);
break;
default:
;
}
plhs[0] = mxCreateNumericMatrix(nsp,1,
mxDOUBLE_CLASS,mxREAL);
double *h = mxGetPr(plhs[0]);
if (iok >= 0) {
for (int i = 0; i < nsp; i++) h[i] = x[i];
delete x;
return;
}
else {
for (int i = 0; i < nsp; i++) h[i] = -999.99;
delete x;
mexErrMsgTxt("unknown attribute");
return;
}
}
}

View file

@ -27,17 +27,18 @@ void onedimmethods( int nlhs, mxArray *plhs[],
int idom, icomp, localPoint;
if (job < 10) {
int ph, kin, tr, nd, sz, k, *ptrs;
int ph, kin, tr, itype, nd, sz, k, *ptrs;
switch (job) {
// construct a new stagnation flow instance
case 1:
checkNArgs(6, nrhs);
checkNArgs(7, nrhs);
ph = getInt(prhs[3]);
kin = getInt(prhs[4]);
tr = getInt(prhs[5]);
indx = stflow_new(ph, kin, tr);
itype = getInt(prhs[6]);
indx = stflow_new(ph, kin, tr, itype);
break;
// construct a new Inlet1D instance
@ -99,6 +100,12 @@ void onedimmethods( int nlhs, mxArray *plhs[],
//writelog("done\n");
break;
// construct a new OutletRes1D instance
case -2:
checkNArgs(3,nrhs);
indx = outletres_new();
break;
default:
mexErrMsgTxt("onedimmethods: unknown object type");
}

View file

@ -15,7 +15,7 @@
int status, buflen;
char* input_buf;
double* ptr;
int n, nsp, mjob;
int n, nsp, mjob, show_thermo;
// methods to set attributes
if (job < 0) {
@ -93,6 +93,9 @@
case 31:
iok = phase_setMassFractionsByName(ph, input_buf);
break;
case 32:
iok = phase_setName(ph, input_buf);
break;
default:
mexErrMsgTxt("what?");
}
@ -135,6 +138,10 @@
k = getInt(prhs[3]);
m = getInt(prhs[4]);
vv = phase_nAtoms(ph,k-1,m-1); break;
case 15:
show_thermo = getInt(prhs[3]);
vv = write_phase(ph,show_thermo);
break;
default:
ok = false;
}
@ -228,6 +235,11 @@
output_buf = (char*)mxCalloc(buflen, sizeof(char));
iok = phase_getElementName(ph, mel-1, buflen, output_buf);
break;
case 42:
buflen = 40;
output_buf = (char*)mxCalloc(buflen, sizeof(char));
iok = phase_getName(ph, buflen, output_buf);
break;
default:
iok = -1;
}

View file

@ -6,9 +6,9 @@
static void thermoset( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] ) {
if (nrhs != 4) {
mexErrMsgTxt("wrong number of input parameters.");
}
//if (nrhs != 4) {
// mexErrMsgTxt("wrong number of input parameters.");
//}
int ierr = 0;
double vv;
int th = getInt(prhs[1]);
@ -60,8 +60,12 @@ static void thermoset( int nlhs, mxArray *plhs[],
// equilibrate
else if (job == 50) {
int xy = int(*ptr);
ierr = th_equil(th, xy);
int xy = getInt(prhs[3]); //int(*ptr);
int solver = getInt(prhs[4]);
double rtol = getDouble(prhs[5]);
int maxsteps = getInt(prhs[6]);
int loglevel = getInt(prhs[7]);
ierr = th_equil(th, xy, solver, rtol, maxsteps, loglevel);
}
if (ierr < 0) reportError();

View file

@ -11,7 +11,7 @@ namespace Cantera {
int n = 0;
while (ch != '\0') {
if (ch =='\n') {
ss += "');";
ss += " ');";
mexEvalString(ss.c_str());
ss = "disp('";
}

View file

@ -11,70 +11,77 @@ help tut1
gas1 = GRI30
% If you have successfully installed the Cantera toolbox,
% you should see something like this:
%
%
% temperature 300 K
% pressure 101325 Pa
% density 0.081896 kg/m^3
% mean mol. weight 2.01594 amu
%
% X Y
% ------------- ------------
% H2 1.000000e+000 1.000000e+000
% H 0.000000e+000 0.000000e+000
% O 0.000000e+000 0.000000e+000
% O2 0.000000e+000 0.000000e+000
% OH 0.000000e+000 0.000000e+000
% H2O 0.000000e+000 0.000000e+000
% HO2 0.000000e+000 0.000000e+000
% H2O2 0.000000e+000 0.000000e+000
% C 0.000000e+000 0.000000e+000
% CH 0.000000e+000 0.000000e+000
% CH2 0.000000e+000 0.000000e+000
% CH2(S) 0.000000e+000 0.000000e+000
% CH3 0.000000e+000 0.000000e+000
% CH4 0.000000e+000 0.000000e+000
% CO 0.000000e+000 0.000000e+000
% CO2 0.000000e+000 0.000000e+000
% HCO 0.000000e+000 0.000000e+000
% CH2O 0.000000e+000 0.000000e+000
% CH2OH 0.000000e+000 0.000000e+000
% CH3O 0.000000e+000 0.000000e+000
% CH3OH 0.000000e+000 0.000000e+000
% C2H 0.000000e+000 0.000000e+000
% C2H2 0.000000e+000 0.000000e+000
% C2H3 0.000000e+000 0.000000e+000
% C2H4 0.000000e+000 0.000000e+000
% C2H5 0.000000e+000 0.000000e+000
% C2H6 0.000000e+000 0.000000e+000
% HCCO 0.000000e+000 0.000000e+000
% CH2CO 0.000000e+000 0.000000e+000
% HCCOH 0.000000e+000 0.000000e+000
% N 0.000000e+000 0.000000e+000
% NH 0.000000e+000 0.000000e+000
% NH2 0.000000e+000 0.000000e+000
% NH3 0.000000e+000 0.000000e+000
% NNH 0.000000e+000 0.000000e+000
% NO 0.000000e+000 0.000000e+000
% NO2 0.000000e+000 0.000000e+000
% N2O 0.000000e+000 0.000000e+000
% HNO 0.000000e+000 0.000000e+000
% CN 0.000000e+000 0.000000e+000
% HCN 0.000000e+000 0.000000e+000
% H2CN 0.000000e+000 0.000000e+000
% HCNN 0.000000e+000 0.000000e+000
% HCNO 0.000000e+000 0.000000e+000
% HOCN 0.000000e+000 0.000000e+000
% HNCO 0.000000e+000 0.000000e+000
% NCO 0.000000e+000 0.000000e+000
% N2 0.000000e+000 0.000000e+000
% AR 0.000000e+000 0.000000e+000
% C3H7 0.000000e+000 0.000000e+000
% C3H8 0.000000e+000 0.000000e+000
% CH2CHO 0.000000e+000 0.000000e+000
% CH3CHO 0.000000e+000 0.000000e+000
% If you have successfully installed the Cantera toolbox, you should
%see something like this:
% temperature 300 K
% pressure 101325 Pa
% density 0.081889 kg/m^3
% mean mol. weight 2.01588 amu
%
% 1 kg 1 kmol
% ----------- ------------
% enthalpy 26470.1 5.336e+04 J
% internal energy -1.21088e+06 -2.441e+06 J
% entropy 64914 1.309e+05 J/K
% Gibbs function -1.94477e+07 -3.92e+07 J
% heat capacity c_p 14311.8 2.885e+04 J/K
% heat capacity c_v 10187.3 2.054e+04 J/K
%
% X Y Chem. Pot. / RT
% ------------- ------------ ------------
% H2 1 1 -15.7173
% H 0 0
% O 0 0
% O2 0 0
% OH 0 0
% H2O 0 0
% HO2 0 0
% H2O2 0 0
% C 0 0
% CH 0 0
% CH2 0 0
% CH2(S) 0 0
% CH3 0 0
% CH4 0 0
% CO 0 0
% CO2 0 0
% HCO 0 0
% CH2O 0 0
% CH2OH 0 0
% CH3O 0 0
% CH3OH 0 0
% C2H 0 0
% C2H2 0 0
% C2H3 0 0
% C2H4 0 0
% C2H5 0 0
% C2H6 0 0
% HCCO 0 0
% CH2CO 0 0
% HCCOH 0 0
% N 0 0
% NH 0 0
% NH2 0 0
% NH3 0 0
% NNH 0 0
% NO 0 0
% NO2 0 0
% N2O 0 0
% HNO 0 0
% CN 0 0
% HCN 0 0
% H2CN 0 0
% HCNN 0 0
% HCNO 0 0
% HOCN 0 0
% HNCO 0 0
% NCO 0 0
% N2 0 0
% AR 0 0
% C3H7 0 0
% C3H8 0 0
% CH2CHO 0 0
% CH3CHO 0 0
%
% What you have just done is to create an object ("gas1") that
% implements GRI-Mech 3.0, the 53-species, 325-reaction natural gas
@ -101,7 +108,7 @@ gas1 = GRI30
% Setting the state
% -----------------
% The state of the object can easily be changed. For example,
% The state of the object can be easily changed. For example,
setTemperature(gas1, 1200)
@ -141,14 +148,14 @@ setTemperature(gas1, 1200)
% on an object. In MATLAB, methods take the object as the first
% argument.)
set(gas1, 'Temperature', 900.0, 'Pressure', 1.e5)
set(gas1, 'Temperature', 900.0, 'Pressure', 1.e5);
% This statement sets both temperature and pressure at the same
% time. Any number of property/value pairs can be specified in a
% call to 'set'. For example, the following sets the mole fractions
% too:
set(gas1, 'Temperature', 900.0, 'Pressure', 1.e5, 'MoleFractions', ...
'CH4:1,O2:2,N2:7.52')
'CH4:1,O2:2,N2:7.52');
% The 'set' method also accepts abbreviated property names:
@ -156,17 +163,75 @@ set(gas1,'T',900.0,'P',1.e5,'X','CH4:1,O2:2,N2:7.52')
% Either version results in
%
% temperature 900 K
% pressure 100000 Pa
% density 0.3693 kg/m^3
% mean mol. weight 27.6332 amu
%
% X Y
% ------------- ------------
% O2 1.901141e-001 2.201489e-001
% CH4 9.505703e-002 5.518732e-002
% N2 7.148289e-001 7.246638e-001
%
% temperature 900 K
% pressure 100000 Pa
% density 0.369279 kg/m^3
% mean mol. weight 27.6332 amu
%
% 1 kg 1 kmol
% ----------- ------------
% enthalpy 455660 1.259e+07 J
% internal energy 184862 5.108e+06 J
% entropy 8529.31 2.357e+05 J/K
% Gibbs function -7.22072e+06 -1.995e+08 J
% heat capacity c_p 1304.4 3.604e+04 J/K
% heat capacity c_v 1003.52 2.773e+04 J/K
%
% X Y Chem. Pot. / RT
% ------------- ------------ ------------
% H2 0 0
% H 0 0
% O 0 0
% O2 0.190114 0.220149 -27.9596
% OH 0 0
% H2O 0 0
% HO2 0 0
% H2O2 0 0
% C 0 0
% CH 0 0
% CH2 0 0
% CH2(S) 0 0
% CH3 0 0
% CH4 0.095057 0.0551863 -37.0813
% CO 0 0
% CO2 0 0
% HCO 0 0
% CH2O 0 0
% CH2OH 0 0
% CH3O 0 0
% CH3OH 0 0
% C2H 0 0
% C2H2 0 0
% C2H3 0 0
% C2H4 0 0
% C2H5 0 0
% C2H6 0 0
% HCCO 0 0
% CH2CO 0 0
% HCCOH 0 0
% N 0 0
% NH 0 0
% NH2 0 0
% NH3 0 0
% NNH 0 0
% NO 0 0
% NO2 0 0
% N2O 0 0
% HNO 0 0
% CN 0 0
% HCN 0 0
% H2CN 0 0
% HCNN 0 0
% HCNO 0 0
% HOCN 0 0
% HNCO 0 0
% NCO 0 0
% N2 0.714829 0.724665 -24.935
% AR 0 0
% C3H7 0 0
% C3H8 0 0
% CH2CHO 0 0
% CH3CHO 0 0
% Other properties may also be set using 'set', including some that
% can't be set individually. The following property pairs may be

View file

@ -11,7 +11,7 @@ help tut4
% 'equilibrate' method.
%
g = GRI30;
set(g,'T',300.0,'P',oneatm,'X','CH4:0.95,O2:2,N2:7.52')
set(g,'T',1200.0,'P',oneatm,'X','CH4:0.95,O2:2,N2:7.52')
equilibrate(g,'TP')
% The above statement sets the state of object 'g' to the state of
@ -19,21 +19,26 @@ equilibrate(g,'TP')
% fixed. Alternatively, the specific enthalpy and pressure can be held
% fixed:
set(g,'T',300.0,'P',oneatm,'X','CH4:0.95,O2:2.0,N2:7.52');
disp('fixed H and P:');
set(g,'T',1200.0,'P',oneatm,'X','CH4:0.95,O2:2.0,N2:7.52');
equilibrate(g,'HP')
% Other options are
% 'UV' fixed specific internal energy and specific volume
% 'SV' fixed specific entropy and specific volume
% 'SP' fixed specific entropy and pressure
set(g,'T',300.0,'P',oneatm,'X','CH4:0.95,O2:2,N2:7.52');
disp('fixed U and V:');
set(g,'T',1200.0,'P',oneatm,'X','CH4:0.95,O2:2,N2:7.52');
equilibrate(g,'UV')
set(g,'T',300.0,'P',oneatm,'X','CH4:0.95,O2:2,N2:7.52');
disp('fixed S and V:');
set(g,'T',1200.0,'P',oneatm,'X','CH4:0.95,O2:2,N2:7.52');
equilibrate(g,'SV')
set(g,'T',300.0,'P',oneatm,'X','CH4:0.95,O2:2,N2:7.52');
disp('fixed S and P:');
set(g,'T',1200.0,'P',oneatm,'X','CH4:0.95,O2:2,N2:7.52');
equilibrate(g,'SP')
% How can you tell if 'equilibrate' has correctly found the

View file

@ -13,9 +13,10 @@ f.close()
fb = open('cantera/buildux.m','w')
fb.write("""
disp('building Cantera..');
mex private/ctmethods.cpp private/ctfunctions.cpp ...
mex -v private/ctmethods.cpp private/ctfunctions.cpp ...
private/xmlmethods.cpp private/phasemethods.cpp ...
private/thermomethods.cpp private/kineticsmethods.cpp ...
private/mixturemethods.cpp ...
private/transportmethods.cpp private/reactormethods.cpp ...
private/reactornetmethods.cpp ...
private/wallmethods.cpp private/flowdevicemethods.cpp ...

View file

@ -52,17 +52,16 @@ class Kinetics:
p4 = phases[4].thermophase()
if np >= 6:
raise CanteraError("a maximum of 4 neighbor phases allowed")
self.ckin = _cantera.KineticsFromXML(xml_phase,
p0, p1, p2, p3, p4)
for nn in range(self._np):
p = self.phase(nn)
p = phases[nn] # self.phase(nn)
self._phnum[p.thermophase()] = nn
self._end.append(self._end[-1]+p.nSpecies())
for k in range(p.nSpecies()):
self._sp.append(p.speciesName(k))
def __del__(self):
self.clear()
@ -141,7 +140,10 @@ class Kinetics:
nur = _cantera.kin_rstoichcoeff(self.ckin,k,i)
if nur <> 0.0:
if nur <> 1.0:
s += `int(nur)`+' '
if nur <> round(nur):
s += `nur`+' '
else:
s += `int(nur)`+' '
s += self._sp[k]+' + '
s = s[:-2]
if self.isReversible(i):
@ -152,7 +154,10 @@ class Kinetics:
nup = _cantera.kin_pstoichcoeff(self.ckin,k,i)
if nup <> 0.0:
if nup <> 1.0:
s += `int(nup)`+' '
if nup <> round(nup):
s += `nup`+' '
else:
s += `int(nup)`+' '
s += self._sp[k]+' + '
s = s[:-2]
return s

View file

@ -55,7 +55,7 @@ class BurnerFlame(Stack):
t0 = self.burner.temperature()
# get adiabatic flame temperature and composition
gas.equilibrate('HP')
gas.equilibrate('HP',solver=1)
teq = gas.temperature()
yeq = gas.massFractions()
u1 = self.burner.mdot()/gas.density()

View file

@ -0,0 +1,135 @@
from onedim import *
from Cantera import _cantera
from Cantera.num import array, zeros
class FreeFlame(Stack):
"""A freely-propagating flat flame."""
def __init__(self, gas = None, grid = None, tfix = 500.0):
"""
gas -- object to use to evaluate all gas properties and reaction
rates. Required
grid -- array of initial grid points
A domain of type FreeFlame named 'flame' will be created to
represent the flame. The three domains comprising the stack
are stored as self.inlet, self.flame, and self.outlet.
"""
self.inlet = Inlet('burner')
self.gas = gas
self.inlet.set(temperature = gas.temperature())
self.outlet = Outlet('outlet')
self.pressure = gas.pressure()
# type 2 is Cantera C++ class FreeFlame
self.flame = AxisymmetricFlow('flame',gas = gas,type=2)
self.flame.setupGrid(grid)
Stack.__init__(self, [self.inlet, self.flame, self.outlet])
self.setRefineCriteria()
self._initialized = 0
self.tfix = tfix
def init(self):
"""Set the initial guess for the solution. The adiabatic flame
temperature and equilibrium composition are computed for the
inlet gas composition. The temperature profile rises linearly
in the first 20% of the flame to Tad, then is flat. The mass
fraction profiles are set similarly.
"""
self.getInitialSoln()
gas = self.gas
nsp = gas.nSpecies()
yin = zeros(nsp, 'd')
for k in range(nsp):
yin[k] = self.inlet.massFraction(k)
gas.setState_TPY(self.inlet.temperature(), self.pressure, yin)
u0 = self.inlet.mdot()/gas.density()
t0 = self.inlet.temperature()
# get adiabatic flame temperature and composition
gas.equilibrate('HP',solver=1)
teq = gas.temperature()
yeq = gas.massFractions()
u1 = self.inlet.mdot()/gas.density()
z1 = 0.5
locs = array([0.0, 0.3, z1, 1.0],'d')
self.setProfile('u', locs, [u0, u0, u1, u1])
self.setProfile('T', locs, [t0, t0, teq, teq])
self.setFixedTemperature(self.tfix)
for n in range(nsp):
self.setProfile(gas.speciesName(n), locs, [yin[n], yin[n],
yeq[n], yeq[n]])
self._initialized = 1
def solve(self, loglevel = 1, refine_grid = 1):
"""Solve the flame. See Stack.solve"""
if not self._initialized: self.init()
Stack.solve(self, loglevel = loglevel, refine_grid = refine_grid)
def setRefineCriteria(self, ratio = 10.0, slope = 0.8,
curve = 0.8, prune = 0.0):
"""See Stack.setRefineCriteria"""
Stack.setRefineCriteria(self, domain = self.flame,
ratio = ratio, slope = slope, curve = curve,
prune = prune)
def setFixedTemperature(self, temp):
_cantera.sim1D_setFixedTemperature(self._hndl, temp)
def setProfile(self, component, locs, vals):
"""Set a profile in the flame"""
self._initialized = 1
Stack.setProfile(self, self.flame, component, locs, vals)
def set(self, tol = None, energy = '', tol_time = None):
"""Set parameters.
tol -- (rtol, atol) for steady-state
tol_time -- (rtol, atol) for time stepping
energy -- 'on' or 'off' to enable or disable the energy equation
"""
if tol:
self.flame.setTolerances(default = tol)
if tol_time:
self.flame.setTolerances(default = tol_time, time = 1)
if energy:
self.flame.set(energy = energy)
def T(self, point = -1):
"""Temperature profile or value at one point."""
return self.solution('T', point)
def u(self, point = -1):
"""Axial velocity profile or value at one point."""
return self.solution('u', point)
def V(self, point = -1):
"""Radial velocity profile or value at one point."""
return self.solution('V', point)
def solution(self, component = '', point = -1):
"""Solution component at one point, or full profile if no
point specified."""
if point >= 0: return self.value(self.flame, component, point)
else: return self.profile(self.flame, component)
def setGasState(self, j):
"""Set the state of the object representing the gas to the
current solution at grid point j."""
nsp = self.gas.nSpecies()
y = zeros(nsp, 'd')
for n in range(nsp):
nm = self.gas.speciesName(n)
y[n] = self.solution(nm, j)
self.gas.setState_TPY(self.T(j), self.pressure, y)

View file

@ -371,12 +371,12 @@ class AxisymmetricFlow(Domain1D):
allowed, as well as arbitrary variation of the transport
properties.
"""
def __init__(self, id = 'axisymmetric_flow', gas = None):
def __init__(self, id = 'axisymmetric_flow', gas = None, type = 1):
Domain1D.__init__(self)
iph = gas.thermo_hndl()
ikin = gas.kinetics_hndl()
itr = gas.transport_hndl()
self._hndl = _cantera.stflow_new(iph, ikin, itr)
self._hndl = _cantera.stflow_new(iph, ikin, itr, type)
if id: self.setID(id)
self._p = -1.0
self.setPressure(gas.pressure())
@ -676,6 +676,10 @@ class Stack:
"""Set the maximum and minimum time steps."""
return _cantera.sim1D_setTimeStepLimits(self._hndl, tsmin, tsmax)
def setFixedTemperature(self, temp):
"""This is a temporary fix."""
_cantera.sim1D_setFixedTemperature(self._hndl, temp)
def clearDomains():
"""Clear all domains."""
_cantera.domain_clear()

View file

@ -12,6 +12,14 @@ from exceptions import CanteraError
__revision__ = "$Id$"
# return true is x is a sequence
def _isseq(n, x):
try:
y = x[n-1]
return 1
except:
return 0
class Phase:
"""Phases of matter.
@ -224,6 +232,10 @@ class Phase:
def setDensity(self, rho):
"""Set the density [kg/m3]."""
_cantera.phase_setfp(self._phase_id,2,rho)
def setMolarDensity(self, n):
"""Set the density [kmol/m3]."""
_cantera.phase_setfp(self._phase_id,3,n)
def setMoleFractions(self, x, norm = 1):
"""Set the mole fractions.
@ -241,9 +253,11 @@ class Phase:
"""
if type(x) == types.StringType:
_cantera.phase_setstring(self._phase_id,1,x)
else:
elif _isseq(self.nSpecies(), x):
_cantera.phase_setarray(self._phase_id,1,norm,asarray(x))
else:
raise CanteraError('mole fractions must be a string or array')
def setMassFractions(self, x, norm = 1):
"""Set the mass fractions.
@ -251,8 +265,11 @@ class Phase:
"""
if type(x) == types.StringType:
_cantera.phase_setstring(self._phase_id,2,x)
else:
_cantera.phase_setarray(self._phase_id,2,norm,asarray(x))
elif _isseq(self.nSpecies(), x):
_cantera.phase_setarray(self._phase_id,2,norm,asarray(x))
else:
raise CanteraError('mass fractions must be a string or array')
def setState_TRX(self, t, rho, x):
"""Set the temperature, density, and mole fractions. The mole
@ -264,6 +281,16 @@ class Phase:
self.setMoleFractions(x)
self.setDensity(rho)
def setState_TNX(self, t, n, x):
"""Set the temperature, molardensity, and mole fractions. The mole
fractions may be entered as a string or array,
>>> ph.setState_TNX(600.0, 2.0e-3, 'CH4:0.4, O2:0.6')
"""
self.setTemperature(t)
self.setMoleFractions(x)
self.setMolarDensity(n)
def setState_TRY(self, t, rho, y):
"""Set the temperature, density, and mass fractions."""
self.setTemperature(t)
@ -293,7 +320,7 @@ class Phase:
fs.append(f[k])
return asarray(fs)
else:
return f
return asarray(f)
def selectElements(self, f, elements):
"""Given an array 'f' of floating-point element properties,
@ -310,5 +337,5 @@ class Phase:
fs.append(f[k])
return asarray(fs)
else:
return f
return asarray(f)

View file

@ -269,7 +269,8 @@ class ThermoPhase(Phase):
"""Set the electric potential."""
_cantera.thermo_setfp(self._phase_id, 6, v, 0);
def equilibrate(self, XY):
def equilibrate(self, XY, solver = 0, rtol = 1.0e-9,
maxsteps = 1000, loglevel = 0):
"""Set to a state of chemical equilibrium holding property pair
'XY' constant. The pair is specified by a two-letter string,
which must be one of the set
@ -279,7 +280,7 @@ class ThermoPhase(Phase):
"""
ixy = ThermoPhase._equilmap[XY]
if ixy > 0:
_cantera.thermo_equil(self._phase_id, ixy)
_cantera.thermo_equil(self._phase_id, ixy, solver, rtol, maxsteps, loglevel)
else:
raise 'invalid equilibrium option: '+XY

View file

@ -4,15 +4,13 @@
"""
import types
import _cantera
from constants import *
from exceptions import *
from gases import *
from set import set
from importFromFile import *
from mixture import Mixture
from num import *
def writeCSV(f, list):
"""
Write list items to file 'f' in
@ -40,17 +38,25 @@ def table(keys, values):
def getCanteraError():
"""Return the Cantera error message, if any."""
import _cantera
return _cantera.get_Cantera_Error()
def refCount(a):
"""Return the reference count for an object."""
import _cantera
return _cantera.ct_refcnt(a)
def addDirectory(dir):
"""Add a directory to search for Cantera data files."""
import _cantera
return _cantera.ct_addDirectory(dir)
def writeLogFile(file):
return _cantera.ct_writelogfile(file)
# workaround for case problems in CVS repository file Mixture.py. On some
# systems it appears as mixture.py, and on others as Mixture.py
try:
from Mixture import Mixture
except:
from mixture import Mixture
from num import *

View file

@ -0,0 +1,34 @@
import _cantera
"""
Convert a Chemkin-format input file to CTI format.
Parameters:
infile - name of the Chemkin-format input file.
thermodb - Thermodynamic database. This may be a standard
Chemkin-format thermo database, or may be any
Chemkin-format input file containing a THERMO section.
trandb - Transport database. File containing species transport
parameters in Chemkin format. If this argument is omitted,
the CTI file will not contain transport property information.
idtag - ID tag. Used to identify the ideal_gas entry in the CTI file. Optional.
debug - If set to 1, extra debugging output will be written. This
should only be used if ck2cti fails, in order to view
intermediate output of the parser. Default: off (0).
validate - If set to 1, the mechanism will be checked for errors. This
is recommended, but for very large mechanisms may slow down
the conversion process. Default: on (1).
The translated file is written to the standard output.
"""
def ck2cti(infile = "chem.inp", thermodb = "", trandb
= "", idtag = "", debug = 0, validate = 1):
_cantera.ct_ck2cti(infile,
thermodb, trandb, idtag, debug, validate)

View file

@ -6,7 +6,7 @@ Physical Constants
OneAtm = 101325.0
# The ideal gas constant in J/kmo-K
GasConstant = 8314.0
GasConstant = 8314.47215
# Avogadro's Number, /kmol
Avogadro = 6.022136736e26

View file

@ -6,10 +6,11 @@ import _cantera
import types
from Cantera.num import zeros, array, asarray
from exceptions import CanteraError
from Cantera import writeLogFile
class Mixture:
"""
xxx Multiphase mixtures. Class Mixture represents
Multiphase mixtures. Class Mixture represents
mixtures of one or more phases of matter. To construct a mixture,
supply a list of phases to the constructor, each paired with the
number of moles for that phase:
@ -180,14 +181,14 @@ class Mixture:
def setPhaseMoles(self, n, moles):
"""Set the number of moles of phase n."""
_cantera.mix_setPhaseMoles(self.__mixid, n, moles)
def setMoles(self, moles):
def setSpeciesMoles(self, moles):
"""Set the moles of the species [kmol]. The moles may be
specified either as a string, or as an array. If an array is
used, it must be dimensioned at least as large as the total
number of species in the mixture. Note that the species may
belong to any phase, and unspecified species are set to zero.
>>> mix.setMoles('C(s):1.0, CH4:2.0, O2:0.2')
>>> mix.setSpeciesMoles('C(s):1.0, CH4:2.0, O2:0.2')
"""
if type(moles) == types.StringType:
@ -197,7 +198,7 @@ class Mixture:
def speciesMoles(self, species = ""):
"""Moles of species k."""
moles = array(self.nSpecies(),'d')
moles = zeros(self.nSpecies(),'d')
for k in range(self.nSpecies()):
moles[k] = _cantera.mix_speciesMoles(self.__mixid, k)
return self.selectSpecies(moles, species)
@ -227,30 +228,64 @@ class Mixture:
else:
raise CanteraError("unknown property: "+o)
def equilibrate(self, XY = "TP", err = 1.0e-9, maxiter = 1000):
def equilibrate(self, XY = "TP", err = 1.0e-9,
maxsteps = 1000, maxiter = 200, loglevel = 0):
"""Set the mixture to a state of chemical equilibrium.
This method uses the VCS algorithm to find the composition
that minimizes the total Gibbs free energy of the mixture,
subject to element conservation constraints. For a description
of the theory, see Smith and Missen, "Chemical Reaction
Equilibrium." The VCS algorithm is implemented in Cantera
kernel class MultiPhaseEquil.
This method uses a version of the VCS algorithm to find the
composition that minimizes the total Gibbs free energy of the
mixture, subject to element conservation constraints. For a
description of the theory, see Smith and Missen, "Chemical
Reaction Equilibrium." The VCS algorithm is implemented in
Cantera kernel class MultiPhaseEquil.
The VCS algorithm solves for the equilibrium composition for
specified temperature and pressure. If any other property pair
other than "TP" is specified, then an outer iteration loop is
used to adjust T and/or P so that the specified property
values are obtained.
XY - Two-letter string specifying the two properties to hold fixed.
Currently, only TP (constant T and P) is implemented. Default: "TP".
Currently, 'TP', 'HP', and 'SP' are implemented. Default: 'TP'.
err - Error tolerance. Iteration will continue until (Delta
mu)/RT is less than this value for each reaction. Default:
1.0e-9.
1.0e-9. Note that this default is very conservative, and good
equilibrium solutions may be obtained with larger error
tolerances.
maxiter - Maximum number of iterations to attempt. Default: 1000.
maxsteps - Maximum number of steps to take while solving the
equilibrium problem for specified T and P. Default: 1000.
maxiter - Maximum number of temperature and/or pressure iterations.
This is only relevant if a property pair other than (T,P) is
specified. Default: 200.
loglevel - Controls the amount of diagnostic output. If
loglevel = 0, no diagnostic output is written. For values > 0,
more detailed information is written to the log file as
loglevel increases. The default is loglevel = 0.
The logfile is written in HTML format, and may be viewed with
any web browser. The default log file name is
"equilibrium_log.html", but if this file exists, the log
information will be written to "equilibrium_log{n}.html",
where {n} is an integer chosen so that the log file does not
already exist. Therefore, if 'equilibrate' is called multiple
times, multiple log files will be written, with names
"equilibrate_log.html", "equilibrate_log1.html",
"equilibrate_log2.html", and so on. Existing log files will
not be overwritten.
>>> mix.equilibrate('TP')
>>> mix.equilibrate('TP', err = 1.0e-6, maxiter = 500)
"""
return _cantera.mix_equilibrate(self.__mixid, XY, err, maxiter)
i = _cantera.mix_equilibrate(self.__mixid, XY, err, maxsteps,
maxiter, loglevel)
if loglevel > 0:
writeLogFile("equilibrate_log");
def selectSpecies(self, f, species):
"""Given an array 'f' of floating-point species properties,
@ -263,12 +298,12 @@ class Mixture:
sp = []
if species:
if type(species) == types.StringType:
sp = [sp]
sp = [species]
else:
sp = species
fs = []
k = 0
for s in s:
for s in sp:
k = self.speciesIndex(s)
fs.append(f[k])
return asarray(fs)

View file

@ -1,26 +1,27 @@
import _cantera
nummodule = None
try:
import numarray
nummodule = numarray
except:
try:
if _cantera.nummod == 'numarray':
import numarray
nummodule = numarray
else:
import Numeric
nummodule = Numeric
except:
print """
except:
print """
ERROR: numarray / numeric not found!
ERROR: """+_cantera.nummod+""" not found!
Cantera uses a set of numerical extensions to Python, but these do
not appear to be present on your system. To install the required
package, go to http://sourceforge.net/projects/numpy, and install
either the numarray or Numeric package for your system. If you are
either the """+_cantera.nummod+""" package for your system. If you are
using a Windows system, use the binary installer to install the
selected package for you automatically.
"""
raise "could not import numarray or Numeric"
raise "could not import "+_cantera.nummod
zeros = nummodule.zeros
array = nummodule.array

View file

@ -15,7 +15,10 @@ python_site_package_topdir=@python_prefix@
CANTERA_LIBDIR= @buildlib@
LIB_DEPS = $(CANTERA_LIBDIR)/libcantera.a $(CANTERA_LIBDIR)/libzeroD.a \
$(CANTERA_LIBDIR)/liboneD.a \
$(CANTERA_LIBDIR)/libtransport.a
$(CANTERA_LIBDIR)/libtransport.a \
$(CANTERA_LIBDIR)/libclib.a \
$(CANTERA_LIBDIR)/libconverters.a
WIN_LIB_DEPS = $(CANTERA_LIBDIR)/cantera.lib $(CANTERA_LIBDIR)/zeroD.lib \
$(CANTERA_LIBDIR)/oneD.lib \
$(CANTERA_LIBDIR)/transport.lib
@ -40,7 +43,7 @@ all: _build
win: _winbuild
_build: $(SRCS) $(LIB_DEPS)
_build: $(SRCS) $(LIB_DEPS) Makefile
touch src/pycantera.cpp
(CXX=@CXX@; export CXX; CC=@CC@; export CC; @PYTHON_CMD@ setup.py build)
echo 'ok' > _build

View file

@ -199,17 +199,25 @@ _pref = 1.0e5 # 1 bar
_name = 'noname'
# these lists store top-level entries
_elements = []
_species = []
_speciesnames = []
_phases = []
_reactions = []
_atw = {}
_enames = {}
_valsp = ''
_valrxn = ''
_valexport = ''
_valfmt = ''
def export_species(file, fmt = 'CSV'):
global _valexport
global _valfmt
_valexport = file
_valfmt = fmt
def validate(species = 'yes', reactions = 'yes'):
global _valsp
global _valrxn
@ -265,7 +273,12 @@ def write():
v = x.addChild("validate")
v["species"] = _valsp
v["reactions"] = _valrxn
if _elements:
ed = x.addChild("elementData")
for e in _elements:
e.build(ed)
for ph in _phases:
ph.build(x)
s = species_set(name = _name, species = _species)
@ -281,6 +294,11 @@ def write():
else:
print x
if _valexport:
f = open(_valexport,'w')
for s in _species:
s.export(f, _valfmt)
f.close()
def addFloat(x, nm, val, fmt='', defunits=''):
"""
@ -320,20 +338,65 @@ def getAtomicComp(atoms):
return d
def getReactionSpecies(s):
"""Take a reaction string and return a
dictionary mapping species names to stoichiometric
coefficients. If any species appears more than once,
the returned stoichiometric coefficient is the sum.
>>> s = 'CH3 + 3 H + 5.2 O2 + 0.7 H'
>>> getReactionSpecies(s)
>>> {'CH3':1, 'H':3.7, 'O2':5.2}
"""
# get rid of the '+' signs separating species. Only plus signs
# surrounded by spaces are replaced, so that plus signs may be
# used in species names (e.g. 'Ar3+')
toks = s.replace(' + ',' ').split()
d = {}
n = 1
n = 1.0
for t in toks:
if t > '0' and t < '9':
n = int(t)
else:
if d.has_key(t):
d[t] += n
# try to convert the token to a number.
try:
n = float(t)
if n <= 0.0:
raise CTI_Error("zero or negative stoichiometric coefficient:"
+s)
#if t > '0' and t < '9':
# n = int(t)
#else:
# token isn't a number, so it must be a species name
except:
if d.has_key(t): # already seen this token
d[t] += n # so increment its value by the last
# value of n
else:
d[t] = n
n = 1
d[t] = n # first time this token has been seen,
# so set its value to n
n = 1 # reset n to 1.0 for species that do not
# specify a stoichiometric coefficient
return d
class element:
def __init__(self, symbol = '',
atomic_mass = 0.01,
atomic_number = 0):
self._sym = symbol
self._atw = atomic_mass
self._num = atomic_number
global _elements
_elements.append(self)
def build(self, db):
e = db.addChild("element")
e["name"] = self._sym
e["atomicWt"] = `self._atw`
e["atomicNumber"] = `self._num`
class species_set:
def __init__(self, name = '', species = []):
self._s = species
@ -384,12 +447,33 @@ class species:
# self.type = SPECIES
global _species
global _enames
_species.append(self)
global _speciesnames
if name in _speciesnames:
raise CTI_Error('species '+name+' multiply defined.')
_speciesnames.append(name)
for e in self._atoms.keys():
_enames[e] = 1
def export(self, f, fmt = 'CSV'):
global _enames
if fmt == 'CSV':
str = self._name+','
for e in _enames:
if self._atoms.has_key(e):
str += `self._atoms[e]`+','
else:
str += '0,'
f.write(str)
if type(self._thermo) == types.InstanceType:
self._thermo.export(f, fmt)
else:
nt = len(self._thermo)
for n in range(nt):
self._thermo[n].export(f, fmt)
f.write('\n')
def build(self, p):
hdr = ' species '+self._name+' '
@ -425,6 +509,8 @@ class thermo:
"""Base class for species standard-state thermodynamic properties."""
def _build(self, p):
return p.addChild("thermo")
def export(self, f, fmt = 'CSV'):
pass
class NASA(thermo):
@ -438,7 +524,14 @@ class NASA(thermo):
raise CTI_Error('NASA coefficient list must have length = 7')
self._coeffs = coeffs
def export(self, f, fmt='CSV'):
if fmt == 'CSV':
str = 'NASA,'+`self._t[0]`+','+`self._t[1]`+','
for i in range(7):
str += '%17.9E, ' % self._coeffs[i]
f.write(str)
def build(self, t):
n = t.addChild("NASA")
n['Tmin'] = `self._t[0]`
@ -786,7 +879,6 @@ class reaction:
unit_fctr = (math.pow(_length[_ulen], -ldim) *
math.pow(_moles[_umol], -mdim) / _time[_utime])
if type(kf) == types.InstanceType:
k = kf
else:
@ -1320,6 +1412,64 @@ class incompressible_solid(phase):
k['model'] = 'none'
class lattice:
def __init__(self, name = '', site_density = -1.0,
vacancy_species = ''):
self._name = name
self._n = site_density
self._vac = vacancy_species
if name == '':
raise CTI_Error('sublattice name must be specified')
if site_density < 0.0:
raise CTI_Error('sublattice '+name
+' site density must be specified')
def build(self,p):
lat = p.addChild('Lattice')
lat['name'] = self._name
addFloat(lat, 'site_density', self._n, defunits = _umol+'/'+_ulen+'3')
if self._vac:
lat.addChild('vacancy_species',self._vac)
class lattice_solid(phase):
"""A solid crystal consisting of one or more sublattices."""
def __init__(self,
name = '',
elements = '',
species = '',
lattices = [],
transport = 'None',
initial_state = None,
options = []):
phase.__init__(self, name, 3, elements, species, 'none',
initial_state, options)
self._lattices = lattices
if lattices == []:
raise CTI_Error('One or more sublattices must be specified.')
self._pure = 0
self._tr = transport
def conc_dim(self):
return (0,0)
def build(self, p):
ph = phase.build(self, p)
e = ph.addChild("thermo")
e['model'] = 'LatticeSolid'
if self._lattices:
lat = e.addChild('LatticeArray')
for n in self._lattices:
n.build(lat)
if self._tr:
t = ph.addChild('transport')
t['model'] = self._tr
k = ph.addChild("kinetics")
k['model'] = 'none'
class liquid_vapor(phase):
"""A fluid with a complete liquid/vapor equation of state.
This entry type selects one of a set of predefined fluids with
@ -1485,105 +1635,3 @@ if __name__ == "__main__":
execfile(file)
write()
##########################################
#
# $Author$
# $Revision$
# $Date$
# $Log$
# 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
# changed f90 mod file handling in Makefiles
#
# Revision 1.6 2004/09/29 11:00:39 dggoodwin
# *** empty log message ***
#
# Revision 1.5 2004/09/20 10:25:02 dggoodwin
# *** empty log message ***
#
# Revision 1.4 2004/07/14 11:24:13 dggoodwin
# *** empty log message ***
#
# Revision 1.3 2004/06/09 01:02:31 dggoodwin
# *** empty log message ***
#
# Revision 1.2 2004/06/04 06:05:31 dggoodwin
# *** empty log message ***
#
# Revision 1.1 2004/06/02 04:39:09 dggoodwin
# moved ctml_writer.py out of Cantera package
#
# Revision 1.34 2004/05/30 04:02:55 dggoodwin
# converted to pure python
#
# Revision 1.33 2004/04/23 19:03:21 dggoodwin
# *** empty log message ***
#
# Revision 1.32 2004/04/23 16:35:32 dggoodwin
# *** empty log message ***
#
# Revision 1.31 2004/03/12 05:59:59 dggoodwin
# *** empty log message ***
#
# Revision 1.30 2004/02/08 13:25:21 dggoodwin
# *** empty log message ***
#
# Revision 1.29 2004/02/08 13:22:31 dggoodwin
# *** empty log message ***
#
# Revision 1.28 2004/02/08 13:09:10 dggoodwin
# *** empty log message ***
#
# Revision 1.27 2004/02/03 16:42:54 dggoodwin
# *** empty log message ***
#
# Revision 1.26 2004/02/03 03:31:06 dggoodwin
# *** empty log message ***
#
# Revision 1.25 2003/11/24 16:39:33 dggoodwin
# -
#
# Revision 1.24 2003/11/13 12:29:45 dggoodwin
# *** empty log message ***
#
# Revision 1.23 2003/11/12 18:58:15 dggoodwin
# *** empty log message ***
#
# Revision 1.22 2003/11/01 04:48:20 dggoodwin
# added capability to have species names with embedded commas
#
# Revision 1.21 2003/10/14 06:48:07 dggoodwin
# *** empty log message ***
#
# Revision 1.20 2003/09/22 13:14:34 dggoodwin
# *** empty log message ***
#
# Revision 1.19 2003/08/26 03:39:02 dggoodwin
# *** empty log message ***
#
# Revision 1.18 2003/08/21 14:29:53 dggoodwin
# *** empty log message ***
#
# Revision 1.17 2003/08/20 15:35:32 dggoodwin
# *** empty log message ***
#
# Revision 1.16 2003/08/19 22:02:01 hkmoffa
# Fixed an error in an argument list
#
# Revision 1.15 2003/08/18 05:05:02 dggoodwin
# added support for specified reaction order, sticking coefficients,
# coverage dependence of rate coefficients; fixed error where site_density
# was not being converted to SI.
#
# Revision 1.14 2003/08/16 20:17:21 dggoodwin
# changed handling of reaction pre-exponential units to write converted
# value to CTML, rather than pass original value with a units string
#
#
###########################################

View file

@ -0,0 +1,70 @@
units(length = "cm", time = "s", quantity = "mol", act_energy = "cal/mol")
# ideal gas containing all gaseous species in the NASA database
# that contain the elements K, O, and H. "Element" E is included
# too for charged species.
ideal_gas(name = "KOH_plasma",
elements = " K O H E",
species = """nasa_gas: all""",
options = ["skip_undeclared_elements"],
initial_state = state(temperature = 300.0,
pressure = OneAtm) )
# solid potassium
stoichiometric_solid(name = "K_solid",
elements = "K",
density = (0.86,'g/cm3'),
species = "nasa_condensed: K(cr)")
# liquid potassium
stoichiometric_liquid(name = "K_liquid",
elements = "K",
density = (1.0,'g/cm3'),
species = "nasa_condensed: K(L)")
# potassium hydroxide "a"
stoichiometric_solid(name = "KOH_a",
elements = "K O H",
density = (2.04,'g/cm3'),
species = "nasa_condensed: KOH(a)")
# potassium hydroxide "b"
stoichiometric_solid(name = "KOH_b",
elements = "K O H",
density = (1.0,'g/cm3'),
species = "nasa_condensed: KOH(b)")
# liquid potassium hydroxide
stoichiometric_liquid(name = "KOH_liquid",
elements = "K O H",
density = (1.0,'g/cm3'),
species = "nasa_condensed: KOH(L)")
stoichiometric_solid(name = "K2O2_solid",
elements = "K O",
density = (1.0,'g/cm3'),
species = "nasa_condensed: K2O2(s)")
stoichiometric_solid(name = "K2O_solid",
elements = "K O",
density = (1.0,'g/cm3'),
species = "nasa_condensed: K2O(s)")
stoichiometric_solid(name = "KO2_solid",
elements = "K O",
density = (1.0,'g/cm3'),
species = "nasa_condensed: KO2(s)")
stoichiometric_solid(name = "ice",
elements = "H O",
density = (0.917,'g/cm3'),
species = "nasa_condensed: H2O(s)")
stoichiometric_liquid(name = "liquid_water",
elements = "H O",
density = (1.0,'g/cm3'),
species = "nasa_condensed: H2O(L)")

View file

@ -0,0 +1,100 @@
"""
Adiabatic flame temperature and equilibrium composition for a
fuel/air mixture as a function of equivalence ratio,
including formation of solid carbon.
"""
from Cantera import *
import sys
##############################################################
#
# Edit these parameters to change the initial temperature, the
# pressure, and the phases in the mixture
#
###############################################################
temp = 300.0
pres = 101325.0
# phases
gas = importPhase('gri30.cti')
carbon = importPhase('graphite.cti')
# the phases that will be included in the calculation, and their
# initial moles
mix_phases = [ (gas, 1.0), (carbon, 0.0) ]
# gaseous fuel species
fuel_species = 'CH4'
# air composition
air_N2_O2_ratio = 3.76
# equivalence ratio range
phi_min = 0.3
phi_max = 3.5
npoints = 50
##################################################
mix = Mixture(mix_phases)
nsp = mix.nSpecies()
# create some arrays to hold the data
phi = zeros(npoints,'d')
tad = zeros(npoints,'d')
xeq = zeros([nsp,npoints],'d')
# find fuel, nitrogen, and oxygen indices
ifuel, io2, in2 = gas.speciesIndex([fuel_species, 'O2', 'N2'])
if ifuel < 0:
raise "fuel species "+fuel_species+" not present!"
if gas.nAtoms(fuel_species,'O') > 0 or gas.nAtoms(fuel_species,'N') > 0:
raise "Error: only hydrocarbon fuels are supported."
stoich_O2 = gas.nAtoms(fuel_species,'C') + 0.25*gas.nAtoms(fuel_species,'H')
for i in range(npoints):
phi[i] = phi_min + (phi_max - phi_min)*i/(npoints - 1)
x = zeros(nsp,'d')
x[ifuel] = phi[i]
x[io2] = stoich_O2
x[in2] = stoich_O2*air_N2_O2_ratio
# set the gas state
gas.set(T = temp, P = pres, X = x)
# create a mixture of 1 mole of gas, and 0 moles of solid carbon.
mix = Mixture(mix_phases)
mix.setTemperature(temp)
mix.setPressure(pres)
# equilibrate the mixture adiabatically at constant P
mix.equilibrate('HP', maxsteps = 1000,
err = 1.0e-6, maxiter = 200, loglevel=0)
tad[i] = mix.temperature();
print 'At phi = %12.4g, Tad = %12.4g' % (phi[i],tad[i])
xeq[:,i] = mix.speciesMoles()
# write output CSV file for importing into Excel
csvfile = 'adiabatic.csv'
f = open(csvfile,'w')
writeCSV(f,['T (K)']+mix.speciesNames())
for n in range(npoints):
writeCSV(f,[phi[n], tad[n]]+list(xeq[:,n]))
f.close()
print 'output written to '+csvfile
# make plots
if '--plot' in sys.argv:
import plotting
plotting.plotEquilData(mix, phi, tad, xeq)

View file

@ -0,0 +1,40 @@
# An equilibrium example with charged species in the gas phase
# and multiple condensed phases.
from Cantera import *
# create objects representing the gas phase and the condensed
# phases. The gas is a mixture of multiple species, and the condensed
# phases are all modeled as incompressible stoichiometric
# substances. See file KOH.cti for more information.
phases = importPhases('KOH.cti',
['K_solid',
'K_liquid', 'KOH_a', 'KOH_b',
'KOH_liquid', 'K2O2_solid',
'K2O_solid', 'KO2_solid',
'ice', 'liquid_water','KOH_plasma'])
# create the Mixture object from the list of phases
mix = Mixture(phases)
# open the output file and write the column headings
f = open('equil_koh.csv','w')
writeCSV(f,['T']+mix.speciesNames())
# loop over temperature
for n in range(500):
t = 350.0 + 10.0*n
print 'T = ',t
mix.set(T= t, P = OneAtm, Moles="K:1.03, H2:2.12, O2:0.9")
# set the mixture to a state of chemical equilibrium holding
# temperature and pressure fixed
mix.equilibrate("TP",maxsteps=1000,loglevel=0)
# write out the moles of each species
writeCSV(f,[t]+ list(mix.speciesMoles()))
# close the output file
f.close()

View file

@ -0,0 +1,85 @@
from matplotlib.pylab import *
from matplotlib import get_backend, interactive
import sys
# Print a warning if 'python' rather than 'pythonw' is invoked on a
# Mac. Does nothing on other platforms.
def warnMac():
if sys.platform == 'darwin':
if sys.executable == '/usr/bin/python':
b = get_backend()
if b[-3:] == 'Agg':
print 'Error: on a Mac, this script must be run with pythonw instead of python'
print 'to display plots'
return -1
return 0
def plotEquilData(mix, phi, tad, xeq):
if warnMac() < 0: return
npoints = len(phi)
nsp = mix.nSpecies()
#titles = ['Major Species', 'Minor Species', 'N Minor Species']
# assign species to 3 plots
p = {}
mm = 0
for k in range(nsp):
if amax(xeq[k,:]) > 0.01:
p[k] = 0 # major species plot
else:
mm += 1
if mix.nAtoms(k,'N') <= 0:
p[k] = 1 # non-N minor species plot
else:
p[k] = 2 # N-containing minor species plot
clf
subplot(2,2,1)
plot(phi,tad)
xlabel('Equivalence Ratio')
ylabel('Temperature (K)')
title('Adiabatic Flame Temperature')
axis([phi[1], phi[-1], amin(tad)-200.0, amax(tad)+200.0])
# do three species plots
for m in range(3):
subplot(2,2,2+m);
hold(True);
for i in range(nsp):
if p[i] == m:
for j in range(npoints):
if xeq[i,j] <= 0.0:
xeq[i,j] = 1.0e-20
if m == 0:
plot(phi, xeq[i,:])
else:
semilogy(phi,xeq[i,:])
xmax = amax(xeq[i,:])
for j in range(npoints):
if xeq[i,j] == xmax: break
offset = 0.0
if j == 0:
offset = 0.3
elif j >= npoints-1:
offset = -0.3
text(phi[j]+offset,xeq[i,j],mix.speciesName(i))
if m == 0:
axis([phi[1], phi[-1], 0.0, 1.0]);
else:
axis([phi[1], phi[-1], 1.0e-14, 1]);
xlabel('Equivalence Ratio');
ylabel('Mole Fraction');
#title(titles[m]);
hold(False)
show()

View file

@ -0,0 +1,23 @@
# homogeneous equilibrium of a gas
from Cantera import *
# create an object representing the gas phase
gas = importPhase("h2o2.cti")
# set the initial state
gas.set(T = 2000.0, P = 0.1*OneAtm, X = "H2:1.0, O2:0.6")
# equilibrate the gas holding T and P fixed
gas.equilibrate("TP")
# print a summary of the results
print gas
# Individual properties can also be retrieved...
x = gas.moleFractions()
y = gas.massFractions()
mu = gas.chemPotentials()
names = gas.speciesNames()
for n in range(gas.nSpecies()):
print "%20s %10.4g %10.4g %10.4g " % (names[n], x[n], y[n], mu[n])

View file

@ -0,0 +1,61 @@
# Equilibrium of a (nearly) stoichiometric hydrogen/oxygen mixture at
# fixed temperature.
# Cantera has 2 different equilibrium solvers. The 'ChemEquil' solver
# uses the element potential method for homogeneous equilibrium in gas
# mixtures. It is fast, but sometimes doesn't converge. The
# 'MultiPhaseEquil' solver uses the VCS algorithm (Gibbs
# minimization), which is slower but more robust. As the name
# suggests, it can also handle multiple phases. Here we'll solve a
# problem for which the ChemEquil solver fails, but the
# MultiPhaseEquil solver has no problem.
from Cantera import *
# create an object representing the gas phase
gas = importPhase("h2o2.cti")
temp = 400.0
# make the composition very close to stoichiometric
comp = "H2:1.00000001, O2:0.5"
# set the initial state
gas.set(T = temp, P = OneAtm, X = comp)
# equilibrate the gas holding T and P fixed. First try the default
# (ChemEquil) solver... (This will fail, throwing an exception that
# will be caught in the 'except' block, where we will try the other
# solver.)
try:
gas.equilibrate("TP")
except:
print "ChemEquil solver failed! Try the MultiPhaseEquil solver..."
# Try again. Reset the gas to the initial state
gas.set(T = temp, P = OneAtm, X = comp)
# setting parameter 'solver' to 1 requests that the
# MultiPhaseEquil solver be used (specifying 0 would cause
# ChemEquil to be used). Some other useful parameters are rtol
# (relative error tolerance, default = 1.0e-9), max_steps (default = 1000),
# loglevel (default = 0).
gas.equilibrate("TP", solver = 1, rtol = 1.0e-10, loglevel = 4)
# print a summary of the results
print gas
# To check that this is an equilibrium state, verify that the chemical
# potentials may be computed by summing the element potentials for each atom.
# (The element potentials are the chemical potentials of the atomic vapors.)
mu_H2, mu_OH, mu_H2O, mu_O2, lambda_H, lambda_O = gas.chemPotentials(
["H2", "OH", "H2O", "O2", "H", "O"])
print mu_H2, 2.0*lambda_H
print mu_O2, 2.0*lambda_O
print mu_OH, lambda_H + lambda_O
print mu_H2O, 2.0*lambda_H + lambda_O

Some files were not shown because too many files have changed in this diff Show more