*** empty log message ***

This commit is contained in:
Dave Goodwin 2004-03-10 14:30:55 +00:00
parent 183c0b3409
commit dbc7aec069
30 changed files with 260 additions and 94 deletions

View file

@ -428,10 +428,11 @@ extern "C" {
}
int DLL_EXPORT th_set_SV(int n, double* vals) {
try { th(n)->setState_SV(vals[0],vals[1]);
return 0; }
try {
th(n)->setState_SV(vals[0],vals[1]);
return 0;
}
catch (CanteraError) {return -1;}
catch (...) {return ERR;}
}
int DLL_EXPORT th_set_SP(int n, double* vals) {
@ -532,17 +533,26 @@ extern "C" {
}
double DLL_EXPORT th_satPressure(int n, double t) {
return purefluid(n)->satPressure(t);
try {
return purefluid(n)->satPressure(t);
}
catch (CanteraError) { return DERR; }
}
int DLL_EXPORT th_setState_satLiquid(int n) {
purefluid(n)->setState_satLiquid();
return 0;
try {
purefluid(n)->setState_satLiquid();
return 0;
}
catch (CanteraError) { return -1; }
}
int DLL_EXPORT th_setState_satVapor(int n) {
purefluid(n)->setState_satVapor();
return 0;
try {
purefluid(n)->setState_satVapor();
return 0;
}
catch (CanteraError) { return -1; }
}
//-------------- Kinetics ------------------//

View file

@ -287,8 +287,14 @@ extern "C" {
}
int DLL_EXPORT flowdev_install(int i, int n, int m) {
_flowdev(i)->install(*_reactor(n), *_reactor(m) );
return 0;
try {
bool ok = _flowdev(i)->install(*_reactor(n), *_reactor(m) );
if (!ok) throw CanteraError("install","Could not install flow device.");
return 0;
}
catch (CanteraError) {
return -1;
}
}
double DLL_EXPORT flowdev_massFlowRate(int i) {

View file

@ -1,5 +1,3 @@
"""
"""
import string
import os
@ -11,9 +9,10 @@ import XML
class Interface(SurfacePhase, Kinetics):
"""
...
Interface objects represent reacting 2D interfaces between bulk 3D phases. Use function
importInterface to build an Interface object from a CTI file definition, rather than
calling the Interface constructor directly.
"""
def __init__(self, src="", root=None, phases=[]):
self.ckin = 0
@ -29,16 +28,13 @@ class Interface(SurfacePhase, Kinetics):
ff = os.path.splitext(fname)
# get the 'phase' element
if src and not root:
root = XML.XML_Node(name = 'doc', src = fn, preprocess = 1)
if id:
s = root.child(id = id)
#s = XML.find_XML(src=src, root=root, id=id)
else:
s = root.child(name = "phase")
#s = XML.find_XML(src=src, root=root, name="phase")
# get the equation of state model
SurfacePhase.__init__(self, xml_phase=s)

View file

@ -10,7 +10,9 @@ import types
class ReactorBase:
"""Base class for reactors."""
def __init__(self, contents = None, type = -1):
def __init__(self, name = '', contents = None,
volume = 1.0, energy = 'on',
type = -1, verbose = 0):
"""
Create a new ReactorBase instance. If 'contents' is specified,
method 'insert' is invoked. The 'type' parameter determines
@ -18,13 +20,28 @@ class ReactorBase:
2 = Reservoir).
"""
self.__reactor_id = _cantera.reactor_new(type)
self._inlets = []
self._outlets = []
self._walls = []
self._name = name
self._verbose = verbose
if contents:
self.insert(contents)
self.setInitialVolume(volume)
self.setEnergy(energy)
def __del__(self):
"""Delete the reactor instance."""
if self._verbose:
print 'Deleting '+self._name
_cantera.reactor_del(self.__reactor_id)
def __str__(self):
return self._name
def name(self):
return self._name
def reactor_id(self):
"""The integer index used to access the kernel reactor
object. For internal use. """
@ -38,8 +55,7 @@ class ReactorBase:
self.contents = contents
_cantera.reactor_setThermoMgr(self.__reactor_id, contents._phase_id)
_cantera.reactor_setKineticsMgr(self.__reactor_id, contents.ckin)
#self.setThermoMgr(contents)
#self.setKineticsMgr(contents)
def setInitialTime(self, t0):
"""Set the initial time. Restarts integration from this time
@ -54,8 +70,13 @@ class ReactorBase:
"""Turn the energy equation on or off. If off, the reactor
temperature is held constant."""
ie = 1
if e == 'off':
if e == 'off' or e == 0:
ie = 0
if self._verbose:
if ie:
print 'enabling energy equation for reactor',self._name
else:
print 'disabling energy equation for reactor',self._name
_cantera.reactor_setEnergy(self.__reactor_id, ie)
def temperature(self):
@ -120,18 +141,40 @@ class ReactorBase:
self.contents.setMassFractions(y)
return self.contents.moleFractions()
def inlets(self):
return self._inlets
def outlets(self):
return self._outlets
def walls(self):
return self._walls
def _addInlet(self, inlet):
"""For internal use"""
self._inlets.append(inlet)
def _addOutlet(self, outlet):
self._outlets.append(outlet)
def _addWall(self, wall):
self._walls.append(wall)
class Reactor(ReactorBase):
"""
A reactor.
"""
def __init__(self, contents = None):
def __init__(self, contents = None, name = '<reactor>',
volume = 1.0, energy = 'on',
verbose = 0):
"""
Create a Reactor instance, and if 'contents' is specified,
insert it.
"""
ReactorBase.__init__(self, contents = contents, type = 1)
ReactorBase.__init__(self, contents = contents, name = name,
volume = volume, energy = energy,
verbose = verbose, type = 1)
class Reservoir(ReactorBase):
@ -140,8 +183,9 @@ class Reservoir(ReactorBase):
derives from class ReactorBase, and overloads method advance to do
nothing.
"""
def __init__(self, contents = None):
ReactorBase.__init__(self, contents = contents, type = 2)
def __init__(self, contents = None, name = '<reservoir>', verbose = 0):
ReactorBase.__init__(self, contents = contents,
name = name, verbose = verbose, type = 2)
def advance(self, time):
"""Do nothing."""
@ -155,18 +199,25 @@ class FlowDevice:
"""
Base class for devices that regulate the flow rate in a fluid line.
"""
def __init__(self, type):
def __init__(self, type, name, verbose):
"""
Create a new instance of type 'type'
"""
self._name = name
self._verbose = verbose
self.__fdev_id = _cantera.flowdev_new(type)
def __del__(self):
"""
Delete the instance.
"""
if self._verbose:
print 'deleting '+self._name
_cantera.flowdev_del(self.__fdev_id)
def name(self):
return self._name
def ready(self):
"""
Returns true if the device is ready to use.
@ -196,6 +247,11 @@ class FlowDevice:
Install the device between the upstream and downstream
reactors.
"""
if self._verbose:
print
print self._name+': installing between '+upstream.name()+' and '+downstream.name()
upstream._addOutlet(self)
downstream._addInlet(self)
_cantera.flowdev_install(self.__fdev_id, upstream.reactor_id(),
downstream.reactor_id())
def setParameters(self, c):
@ -203,28 +259,42 @@ class FlowDevice:
n = len(params)
return _cantera.flowdev_setParameters(self.__fdev_id, n, params)
_mfccount = 0
class MassFlowController(FlowDevice):
def __init__(self, upstream=None, downstream=None):
FlowDevice.__init__(self,1)
def __init__(self, upstream=None, downstream=None, name='', verbose=0):
global _mfccount
if name == '':
name = 'MFC_'+`_mfccount`
_mfccount += 1
FlowDevice.__init__(self,1,name,verbose)
if upstream and downstream:
self.install(upstream, downstream)
def setMassFlowRate(self, mdot):
if self._verbose:
print self._name+': setting mdot to '+`mdot`+' kg/s'
self.setSetpoint(mdot)
_valvecount = 0
class Valve(FlowDevice):
def __init__(self, upstream=None, downstream=None):
FlowDevice.__init__(self,3)
def __init__(self, upstream=None, downstream=None, name='', verbose=0):
global _valvecount
if name == '':
name = 'Valve_'+`_valvecount`
_valvecount += 1
FlowDevice.__init__(self,3,name,verbose)
if upstream and downstream:
self.install(upstream, downstream)
def setValveCoeff(self, v):
vv = zeros(1,'d')
vv[0] = v
if self._verbose:
print
print self._name+': setting valve coefficient to '+`v`+' kg/Pa-s'
self.setParameters(vv)
@ -300,8 +370,10 @@ class Wall:
_cantera.wall_setExpansionRate(self.__wall_id, n)
def install(self, left, right):
self.left = left
self.right = right
#self.left = left
#self.right = right
left._addWall(this)
right._addWall(this)
_cantera.wall_install(self.__wall_id, left.reactor_id(),
right.reactor_id())

View file

@ -27,6 +27,7 @@ class ReactorNet:
Create a new ReactorNet instance. If a list of reactors is supplied,
these will be added to the network.
"""
self._reactors = []
self.__reactornet_id = _cantera.reactornet_new()
if reactorlist:
for r in reactorlist:
@ -49,6 +50,7 @@ class ReactorNet:
"""
Add a reactor to the network.
"""
self._reactors.append(reactor)
_cantera.reactornet_addreactor(self.__reactornet_id, reactor.reactor_id())

View file

@ -24,7 +24,6 @@ class ThermoPhase(Phase):
"""Create a new object representing a phase of matter, or wrap
an existing kernel instance."""
#Phase.__init__(self)
self._phase_id = 0
self._owner = 0
self.idtag = ""
@ -50,17 +49,6 @@ class ThermoPhase(Phase):
if self._owner:
_cantera.thermo_delete(self._phase_id)
#def importFromXML(self, xml_root, id):
# _cantera.thermo_import_xml(self._phase_id, xml_root._xml_id, id)
def thermophase(self):
"""Return the integer index that is used to
reference the kernel object."""
return self._phase_id
def thermo_hndl(self):
return self._phase_id
def refPressure(self):
"""Reference pressure [Pa].
All standard-state thermodynamic properties are for this pressure.
@ -232,7 +220,7 @@ class ThermoPhase(Phase):
def setState_SV(self, s, v):
"""Set the state by specifying the specific entropy
and the specific volume."""
and the specific volume."""
_cantera.thermo_setfp(self._phase_id, 4, s, v)
def setState_SP(self, s, p):
@ -281,7 +269,16 @@ class ThermoPhase(Phase):
_cantera.thermo_setfp(self._phase_id,8,0.0,0.0)
def thermophase(self):
"""Return the integer index that is used to
reference the kernel object. For internal use."""
return self._phase_id
def thermo_hndl(self):
"""Return the integer index that is used to
reference the kernel object. For internal use."""
return self._phase_id

View file

@ -1,17 +1,16 @@
#
# Cantera
#
"""
Cantera provides capabilities for simulating problems involving
chemical kinetics and transport processes.
"""
import types
ok = 0
#ok = 0
from constants import *
from exceptions import *
from gases import *
from set import set
from importFromFile import *
#from _version import __createdate__
try:
from Numeric import array, asarray, zeros, ones
except:
@ -31,11 +30,9 @@ except:
"""
raise "could not import Numeric"
#
# utilities
#
# write list items in comma-separated-value format
def writeCSV(f, list):
"""Write list items to file 'f' in comma-separated-value format."""
for item in list:
if type(item) == types.StringType:
f.write(item+', ')
@ -45,6 +42,7 @@ def writeCSV(f, list):
def table(keys, values):
"""Create a map with the keys and values specified."""
x = {}
pairs = map(None, keys, values)
for p in pairs:
@ -53,9 +51,11 @@ def table(keys, values):
return x
def getCanteraError():
"""Return the Cantera error message, if any."""
import _cantera
return _cantera.get_Cantera_Error()
def refCount(a):
# import _cantera
"""Return the reference count for an object."""
import _cantera
return _cantera.ct_refcnt(a)

View file

@ -1,6 +1,6 @@
#
# constants
#
"""
Physical Constants
"""
OneAtm = 101325.0
GasConstant = 8314.0

View file

@ -1,19 +1,23 @@
"""Functions to import phase and interface definitions from CTI files."""
import solution
import Interface
import XML
def importPhase(file = '', name = ''):
"""Import a phase from a CTI file."""
return importPhases(file, [name])[0]
def importPhases(file = '', names = []):
"""Import multiple phase definitions.
"""
"""Import multiple phases from one file. The phase names should be
entered as a list of strings. """
s = []
for nm in names:
s.append(solution.Solution(src=file,id=nm))
return s
def importInterface(file = '', name = '', phases = []):
"""Import an interface definition from a CTI file."""
if name:
src = file+'#'+name
else:

View file

@ -1,7 +1,7 @@
from exceptions import CanteraError
def set(a, **options):
def setByName(a, options):
pval = None
hval = None
uval = None
@ -54,5 +54,7 @@ def set(a, **options):
else:
raise CanteraError('unimplemented property pair')
def set(a, **options):
setByName(a, options)

View file

@ -8,6 +8,7 @@ from constants import *
from ThermoPhase import ThermoPhase
from Kinetics import Kinetics
from Transport import Transport
from set import setByName
import XML
import _cantera
@ -64,5 +65,6 @@ class Solution(ThermoPhase, Kinetics, Transport):
def __repr__(self):
return _cantera.phase_report(self._phase_id, self.verbose)
def set(self, **options):
setByName(self, options)

View file

@ -1,4 +1,6 @@
# This example shows how to create functions that are evaluated in C++
# This example shows how to create 'functors' - objects that evaluate
# functions. These are useful for specifying the expansion rate of
# heat flux at a wall.
from Cantera.Func import *
@ -8,7 +10,7 @@ f1 = Polynomial([4.0, 6.0, 8.0, 1.0])
# create sin(t)
f2 = Fourier(1.0, [(0.0, 0.0), (0.0, 1.0)])
# create sin^2(t)
# functors can be combined by +,*,or / to create new functors
f3 = f2*f2
xpts = 0.1*array(range(100))

View file

@ -143,7 +143,6 @@ thermo_setfp(PyObject *self, PyObject *args)
//vector_fp v(2);
double v[2];
v[0] = v1; v[1] = v2;
// set floating-point attributes
switch (job) {
case 1:
@ -153,7 +152,8 @@ thermo_setfp(PyObject *self, PyObject *args)
case 3:
iok = th_set_UV(th, v); break;
case 4:
iok = th_set_SV(th, v); break;
iok = th_set_SV(th, v);
break;
case 5:
iok = th_set_SP(th, v); break;
case 6:

View file

@ -14,7 +14,8 @@ help(Solution)
from Cantera import Reactor
help(Reactor)
# On Windows, you can also use the module browser to view this same
# information in a web browser. From the Start menu, goto
# Programs/Python2.x/Module Docs. In the pop-up window, click on 'open
# browser', then navigate to the Cantera module
# You can also use the Python module browser to view this same
# information in a web browser. Under Windows, goto
# Programs/Python2.x/Module Docs on the Start menu. On unix or Mac
# OSX, type 'pydoc -g' at a shell prompt, A small pop-up window will
# appear. Click on 'open browser', then navigate to the Cantera module

View file

@ -165,6 +165,34 @@ namespace Cantera {
return ts;
}
virtual void setState_HP(doublereal h, doublereal p,
doublereal tol = 1.e-8) {
m_sub->Set(tpx::HP, h, p);
setState_TR(m_sub->Temp(), 1.0/m_sub->v());
check();
}
virtual void setState_UV(doublereal u, doublereal v,
doublereal tol = 1.e-8) {
m_sub->Set(tpx::UV, u, v);
setState_TR(m_sub->Temp(), 1.0/m_sub->v());
check();
}
virtual void setState_SV(doublereal s, doublereal v,
doublereal tol = 1.e-8) {
m_sub->Set(tpx::SV, s, v);
setState_TR(m_sub->Temp(), 1.0/m_sub->v());
check();
}
virtual void setState_SP(doublereal s, doublereal p,
doublereal tol = 1.e-8) {
m_sub->Set(tpx::SP, s, p);
setState_TR(m_sub->Temp(), 1.0/m_sub->v());
check();
}
/// saturation pressure
virtual doublereal satPressure(doublereal t) const {
doublereal tsv = m_sub->Temp();

View file

@ -145,7 +145,9 @@ namespace Cantera {
doublereal dt;
setDensity(1.0/v);
for (int n = 0; n < 20; n++) {
cout << "n = " << n << endl;
dt = (s - entropy_mass())*temperature()/cv_mass();
cout << "dt = " << dt << endl;
if (dt > 100.0) dt = 100.0;
else if (dt < -100.0) dt = -100.0;
setTemperature(temperature() + dt);

View file

@ -519,16 +519,20 @@ namespace Cantera {
/** Set the specific enthalpy (J/kg) and pressure (Pa). */
void setState_HP(doublereal h, doublereal p, doublereal tol = 1.e-8);
virtual void setState_HP(doublereal h, doublereal p,
doublereal tol = 1.e-8);
/** Set the specific enthalpy (J/kg) and specific volume (m^3/kg). */
void setState_UV(doublereal u, doublereal v, doublereal tol = 1.e-8);
virtual void setState_UV(doublereal u, doublereal v,
doublereal tol = 1.e-8);
/** Set the specific entropy (J/kg/K) and pressure (Pa). */
void setState_SP(doublereal s, doublereal p, doublereal tol = 1.e-8);
virtual void setState_SP(doublereal s, doublereal p,
doublereal tol = 1.e-8);
/** Set the specific entropy (J/kg/K) and specific volume (m^3/kg). */
void setState_SV(doublereal s, doublereal v, doublereal tol = 1.e-8);
virtual void setState_SV(doublereal s, doublereal v,
doublereal tol = 1.e-8);
//@}

View file

@ -9,9 +9,10 @@
*/
#include <math.h>
#include "ctvector.h"
#include <algorithm>
#include <iostream>
using namespace std;
#include "ctvector.h"
using namespace ct;
ostream& operator<<(ostream& s, const ctvector_int& v) {

View file

@ -84,8 +84,12 @@ namespace ct {
ctvector_int operator=(const ctvector_int& x);
virtual ~ctvector_int();
value_type operator[](size_t n) const { return _data[n]; }
value_type& operator[](size_t n) { return _data[n]; }
value_type operator[](size_t n) const {
return _data[n];
}
value_type& operator[](size_t n) {
return _data[n];
}
void resize(size_t n);
void resize(size_t n, value_type v0);

View file

@ -4,7 +4,7 @@
#ifdef DIAGNOSE_ALL
#define DIAGNOSE_RXNSTOICHMGR // ReactionStoichMgr
#define DIAGNOSE_REACTOR
#endif
#endif

View file

@ -1007,7 +1007,6 @@ namespace Cantera {
}
th->freezeSpecies();
th->initThermo();
setState(phase, th);
th->saveSpeciesData(db);
@ -1015,6 +1014,7 @@ namespace Cantera {
doublereal dsub = doublereal(subflag);
th->setParameters(1, &dsub);
}
setState(phase, th);
return true;
}

View file

@ -7,6 +7,7 @@
#include "ThermoPhase.h"
#include <stdio.h>
#include "mix_defs.h"
namespace Cantera {
@ -26,6 +27,13 @@ namespace Cantera {
s += p;
sprintf(p, " mean mol. weight %12.6g amu\n", th.meanMolecularWeight());
s += p;
if (th.eosType() == cPureFluid) {
// if (th.temperature() < th.critTemperature()) {
sprintf(p, " vapor fraction %12.6g \n",
th.vaporFraction());
s += p;
//}
}
if (show_thermo) {
sprintf(p, "\n");

View file

@ -175,6 +175,7 @@ namespace Cantera {
m_pressure = m_thermo->pressure();
m_intEnergy = m_thermo->intEnergy_mass();
m_mix->saveState(m_state);
}
@ -191,6 +192,8 @@ namespace Cantera {
{
int i, k, nk;
m_time = time;
m_mix->restoreState(m_state);
// updateState(y); // synchronize the reactor state with y
m_vdot = 0.0;

View file

@ -20,7 +20,7 @@
namespace Cantera {
ReactorBase::ReactorBase() : m_nsp(0),
ReactorBase::ReactorBase(string name) : m_nsp(0),
m_mix(0),
m_time(0.0),
m_vol(1.0),
@ -33,7 +33,9 @@ namespace Cantera {
m_intEnergy(0.0),
m_pressure(0.0),
m_nwalls(0)
{}
{
m_name = name;
}
// void ReactorBase::resetState() {
// m_mix->saveState(m_state);

View file

@ -40,12 +40,13 @@ namespace Cantera {
public:
ReactorBase();
ReactorBase(string name = "(none)");
virtual ~ReactorBase(){}
//-----------------------------------------------------
virtual int type() const { return 0; }
string name() { return m_name; }
/** @name Methods to set up a simulation. */
//@{
@ -158,7 +159,7 @@ namespace Cantera {
vector<Wall*> m_wall;
vector_int m_lr;
int m_nwalls;
string m_name;
private:

View file

@ -4,7 +4,9 @@
namespace Cantera {
ReactorNet::ReactorNet() : FuncEval(), m_nr(0), m_nreactors(0),
m_integ(0), m_init(false), m_nv(0), m_rtol(1.0e-6) {
m_integ(0), m_init(false), m_nv(0), m_rtol(1.0e-6),
m_verbose(false)
{
m_integ = new CVodeInt;
// use backward differencing, with a full Jacobian computed
@ -17,23 +19,35 @@ namespace Cantera {
void ReactorNet::initialize(doublereal t0) {
int n, nv;
char buf[100];
m_nv = 0;
m_reactors.clear();
m_nreactors = 0;
for (n = 0; n < m_nr; n++) {
m_r[n]->initialize(t0);
if (m_r[n]->type() == ReactorType) {
m_r[n]->initialize(t0);
Reactor* r = (Reactor*)m_r[n];
m_reactors.push_back(r);
nv = m_reactors[n]->neq();
nv = r->neq();
m_size.push_back(nv);
m_nv += nv;
m_nreactors++;
if (m_verbose) {
sprintf(buf,"Reactor %d: %d variables.\n",n,nv);
writelog(buf);
}
}
}
m_atol.resize(neq());
fill(m_atol.begin(), m_atol.end(), 1.e-15);
m_integ->setTolerances(m_rtol, neq(), m_atol.begin());
m_integ->setMaxStep(m_maxstep);
if (m_verbose) {
sprintf(buf, "Number of equations: %d\n", neq());
writelog(buf);
sprintf(buf, "Maximum time step: %g14.6\n", m_maxstep);
writelog(buf);
}
m_integ->initialize(t0, *this);
m_init = true;
}

View file

@ -64,8 +64,10 @@ namespace Cantera {
//@}
void addReactor(ReactorBase* r) {
m_r.push_back(r);
m_nr++;
if (r->type() == ReactorType) {
m_r.push_back(r);
m_nr++;
}
}
ReactorBase& reactor(int n) {
@ -101,6 +103,7 @@ namespace Cantera {
vector_fp m_atol;
doublereal m_rtol;
doublereal m_maxstep;
bool m_verbose;
private:

View file

@ -154,7 +154,8 @@ namespace Cantera {
virtual doublereal massFlowRate() {
m_mdot = m_coeffs[0]* (in().pressure() - out().pressure());
return (m_mdot > 0.0 ? m_mdot : 0.0);
if (m_mdot < 0.0) m_mdot = 0.0;
return m_mdot;
}
protected:

2
configure vendored
View file

@ -183,7 +183,7 @@ LAPACK_FTN_STRING_LEN_AT_END='y'
CXX=${CXX:=g++}
# C++ compiler flags
CXXFLAGS=${CXXFLAGS:="-O2 -g -Wall"}
CXXFLAGS=${CXXFLAGS:="-O0 -g -Wall"}
# the C++ flags required for linking
#LCXX_FLAGS=

View file

@ -413,6 +413,7 @@ namespace tpx {
y_here = prop(ify);
err_x = fabs(X - x_here);
err_y = fabs(Y - y_here);
if ((err_x < atx + rtx*Xa) && (err_y < aty + rty*Ya)) break;
/* perturb t */