*** empty log message ***

This commit is contained in:
Dave Goodwin 2005-11-10 20:48:27 +00:00
parent 6547372987
commit 4ed7e64194
31 changed files with 1900 additions and 634 deletions

View file

@ -1,6 +1,7 @@
// Cantera includes
#include "zeroD/Reactor.h"
#include "zeroD/FlowReactor.h"
#include "zeroD/ReactorNet.h"
#include "zeroD/Reservoir.h"
#include "zeroD/Wall.h"
@ -167,6 +168,28 @@ extern "C" {
return 0;
}
int DLL_EXPORT flowReactor_setMassFlowRate(int i, double mdot) {
reactor_t* r = _reactor(i);
if (r->type() == ReactorType) ((FlowReactor*)r)->setMassFlowRate(mdot);
return 0;
}
int DLL_EXPORT reactor_nSensParams(int i) {
reactor_t* r = _reactor(i);
if (r->type() >= ReactorType)
return ((Reactor*)r)->nSensParams();
else {
cout << "type problem..." << r->type() << endl;
return 0;
}
}
int DLL_EXPORT reactor_addSensitivityReaction(int i, int rxn) {
reactor_t* r = _reactor(i);
((Reactor*)r)->addSensitivityReaction(rxn);
return 0;
}
// reactor networks
@ -208,6 +231,11 @@ extern "C" {
return 0;
}
int DLL_EXPORT reactornet_setSensitivityTolerances(int i, double rtol, double atol) {
_reactornet(i)->setSensitivityTolerances(rtol, atol);
return 0;
}
int DLL_EXPORT reactornet_addreactor(int i, int n) {
try {
_reactornet(i)->addReactor(_reactor(n));
@ -247,6 +275,9 @@ extern "C" {
return _reactornet(i)->atol();
}
double DLL_EXPORT reactornet_sensitivity(int i, char* v, int p, int r) {
return _reactornet(i)->sensitivity(v, p, r);
}
// flow devices
@ -406,4 +437,10 @@ extern "C" {
else return 0;
}
int DLL_EXPORT wall_addSensitivityReaction(int i, int lr, int rxn) {
_wall(i)->addSensitivityReaction(lr, rxn);
return 0;
}
}

View file

@ -25,6 +25,9 @@ extern "C" {
double DLL_IMPORT reactor_intEnergy_mass(int i);
double DLL_IMPORT reactor_pressure(int i);
double DLL_IMPORT reactor_massFraction(int i, int k);
int DLL_IMPORT reactor_nSensParams(int i);
int DLL_IMPORT reactor_addSensitivityReaction(int i, int rxn);
int DLL_IMPORT flowReactor_setMassFlowRate(int i, double mdot);
int DLL_IMPORT reactornet_new();
int DLL_IMPORT reactornet_del(int i);
@ -33,12 +36,14 @@ extern "C" {
int DLL_IMPORT reactornet_setInitialTime(int i, double t);
int DLL_IMPORT reactornet_setMaxTimeStep(int i, double maxstep);
int DLL_IMPORT reactornet_setTolerances(int i, double rtol, double atol);
int DLL_IMPORT reactornet_setSensitivityTolerances(int i, double rtol, double atol);
int DLL_IMPORT reactornet_addreactor(int i, int n);
int DLL_IMPORT reactornet_advance(int i, double t);
double DLL_IMPORT reactornet_step(int i, double t);
double DLL_IMPORT reactornet_time(int i);
double DLL_IMPORT reactornet_rtol(int i);
double DLL_IMPORT reactornet_atol(int i);
double DLL_IMPORT reactornet_sensitivity(int i, char* v, int p, int r);
int DLL_IMPORT flowdev_new(int type);
int DLL_IMPORT flowdev_del(int i);
@ -67,6 +72,7 @@ extern "C" {
int DLL_IMPORT wall_setVelocity(int i, int n);
int DLL_IMPORT wall_setEmissivity(int i, double epsilon);
int DLL_IMPORT wall_ready(int i);
int DLL_IMPORT wall_addSensitivityReaction(int i, int lr, int rxn);
}

View file

@ -41,7 +41,13 @@ py_"""+name+"""(PyObject *self, PyObject *args)
"""+rtype+""" _val;"""
global _class, _newclass
cls, func = name.split('_')
toks = name.split('_')
cls = toks[0]
if len(toks) == 2:
func = toks[1]
else:
func = toks[1] + toks[2]
if cls != _class:
_class = cls
_newclass = 1
@ -135,7 +141,14 @@ def writepyclass(f, name, args):
f.write(" def __init__(self):\n")
f.write(" pass\n");
_newclass = 0
cls, nm = name.split('_')
toks = name.split('_')
cls = toks[0]
if len(toks) == 2:
nm = toks[1]
else:
nm = toks[1] + toks[2]
f.write(' def '+nm+'(self')
for a in args[1:]:
f.write(', '+a[1])

View file

@ -53,6 +53,8 @@ int kinetics1(int np, void* p) {
r.insert(gas);
env.insert(gas);
r.addHomogenRxnSens(0);
// create a wall between the reactor and the environment
Wall w;
w.install(r,env);
@ -76,11 +78,16 @@ int kinetics1(int np, void* p) {
Array2D soln(nsp+4, 1);
saveSoln(0, 0.0, gas, soln);
// create a container object to run the simulation
// and add the reactor to it
ReactorNet sim;
sim.addReactor(&r);
// main loop
clock_t t0 = clock(); // save start time
for (int i = 1; i <= nsteps; i++) {
tm = i*dt;
r.advance(tm);
sim.advance(tm);
cout << "time = " << tm << " s" << endl;
saveSoln(tm, gas, soln);
}
@ -98,8 +105,8 @@ int kinetics1(int np, void* p) {
cout << " Tfinal = " << r.temperature() << endl;
cout << " time = " << tmm << endl;
cout << " number of residual function evaluations = "
<< r.integrator().nEvals() << endl;
cout << " time per evaluation = " << tmm/r.integrator().nEvals()
<< sim.integrator().nEvals() << endl;
cout << " time per evaluation = " << tmm/sim.integrator().nEvals()
<< endl << endl;
cout << "Output files:" << endl
<< " kin1.csv (Excel CSV file)" << endl

View file

@ -1,5 +1,31 @@
function x = Func(typ, n, p)
%
% Func - a class for functors.
%
% A functor is an object that behaves like a function. Cantera
% defines a set of functors to use to create arbitrary functions to
% specify things like heat fluxes, piston speeds, etc., in reactor
% network simulations. Of course, they can be used for other things
% too.
%
% The main feature of a functor class is that it overloads the '()'
% operator to evaluate the function. For example, suppose object
% 'f' is a functor that evaluates the polynomial '2x^2 - 3x +
% 1'. Then writing 'f(2)' would cause the method that evaluates the
% function to be invoked, and would pass it the argument '2'. The
% return value would of course be 3.
%
% The types of functors you can create in Cantera are these:
% 1. A polynomial
% 2. A Fourier series
% 3. A sum of Arrhenius terms
% 4. A Gaussian.
% You can also create composite functors by adding, multiplying, or
% dividing these basic functors, or other composite functors.
%
% Note: this MATLAB class shadows the underlying C++ Cantera class
% "Func1". See the Cantera C++ documentation for more details.
%
if ~isa(typ, 'char')
error('Function type must be a string')
end
@ -15,11 +41,18 @@ elseif strcmp(typ,'fourier')
itype = 1;
elseif strcmp(typ,'arrhenius')
itype = 3;
elseif strcmp(typ,'gaussian')
itype = 4;
end
if itype > 0
x.coeffs = p;
x.index = funcmethods(0,itype,n,p);
elseif strcmp(typ,'periodic')
itype = 50;
x.f1 = n;
x.coeffs = p;
x.index = funcmethods(0,itype,n.index,p);
else
if strcmp(typ,'sum')
itype = 20;

View file

@ -44,9 +44,12 @@ else
end
d = d - 1;
end
elseif strcmp(p.typ,'gaussian')
s = num2str(p.coeffs(1));
s = ['Gaussian(' num2str(p.coeffs(1)) ',' ...
num2str(p.coeffs(2)) ',' ...
num2str(p.coeffs(3)) ')'];
else
print 'char not yet implemented';
end
s = ['*** char not yet implemented for' p.typ ' ***'];
end
end

View file

@ -1,5 +1,7 @@
function r = plus(a, b)
% PLUS -
%
% PLUS - Return a functor representing the sum of two functors a
% and b.
%
r = Func('sum',a,b);

View file

@ -9,7 +9,7 @@ function a = equilibrate(a, xy, solver, rtol, maxsteps, maxiter, loglevel)
% solver -- specifies the equilibrium solver to use. If solver
% = 0, a fast solver using the element potential method will be
% used. If solver > 0, a slower but more robust Gibbs
% minimization solver will be used. If solver < 0 or
% minimization solver will be used. If solver < 0 or is
% unspecified, the fast solver will be tried first, then if it
% fails the other will be tried.
%
@ -25,8 +25,9 @@ function a = equilibrate(a, xy, solver, rtol, maxsteps, maxiter, loglevel)
% loglevel -- set to a value > 0 to write diagnostic output to
% a file in HTML format. Larger values generate more detailed
% information. The file will be named 'equilibrate_log.html.'
% Subsequent files will be named 'equillibrate_log1.html',
% etc., so that log files are not overwritten.
% Subsequent files will be named 'equilibrate_log1.html',
% 'equilibrate_log2.html', etc., so that log files are not
% overwritten.
%
%

View file

@ -191,7 +191,7 @@ set(inlt,'X',comp2);
setRefineCriteria(sim1D, 2, 100.0, 0.15, 0.2);
% solve the problem for the final time
solve(sim1D, loglevel, refine_grid); %refine_grid);
solve(sim1D, loglevel, refine_grid);
% show the solution
sim1D

View file

@ -1,13 +1,16 @@
function g = gaussian(A, x0, FWHM)
% POLY - create a Gaussian Func instance
%
% gaussian(A, x0, FWHM)
%
% A - value at x = x0
% x0 - location of maximum
% FWHM - full width at half-maximum
function g = gaussian(peak, center, width)
%
g = Func('gaussian', 0, [A x0 FWHM]);
% GAUSSIAN - create a Gaussian Func instance
%
% gaussian(peak, center, width)
%
% peak - the peak value
% center - value of x at which the peak is located
% width - full width at half-maximum. The value of the
% function at center +/- (width)/2 is one-half
% the peak value.
%
g = Func('gaussian', 0, [peak, center, width]);

View file

@ -1,8 +1,12 @@
function poly = polynom(coeffs)
% POLY - create a polynomial Func instance
%
% POLY - create an instance of class 'Func' representing a polynomial.
%
% Create a polynomial:
% polynom([-2 6 3]) 3x^2 + 6x - 2
% The polynomial coefficients are specified by a one-dimensional
% array [a0 a1 .... aN].
%
% polynom([-2 6 3]) 3x^2 + 6x - 2
% polynom([1.0 -2.5 0 0 2]) 2x^4 - 2.5x + 1
%
[n m] = size(coeffs);
if n == 1

View file

@ -22,10 +22,14 @@ void funcmethods( int nlhs, mxArray *plhs[],
int lenp = msize*nsize;
nn = func_new(type, n, lenp, ptr);
}
else {
else if (type < 45) {
int m = getInt(prhs[4]);
nn = func_new(type, n, m, ptr);
}
else {
ptr = mxGetPr(prhs[4]);
nn = func_new(type, n, 0, ptr);
}
plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
double *h = mxGetPr(plhs[0]);
*h = double(nn);

View file

@ -60,8 +60,8 @@ msg = sprintf('time to create gas1b: %f', cputime - t0)
% If for some reason Cantera has difficulty finding where these files
% are on your system, set environment variable CANTERA_DATA to the
% directory where they are located. Alternatively, you can call function
% addDirectory to add a directory to the Cantera search path:
addDirectory('/usr/local/cantera/my_data_files');
% adddir to add a directory to the Cantera search path:
adddir('/usr/local/cantera/my_data_files');
% Cantera input files are plain text files, and can be created with
% any text editor. See the document 'Defining Phases and Interfaces'
@ -121,7 +121,7 @@ diamonnd_surf2 = importInterface('diamond.xml','diamond_100',...
%
% Here's an example of how to use it:
%
% ck2cti -i mech.inp -t therm.dat -tr tran.dat -id mymech > mech.cti
% ck2cti -i mech.inp -t therm.dat -tr tran.dat -id mymech
%
clear all

View file

@ -12,20 +12,20 @@ g = GRI30
class(g)
% This tells you that g belongs to a class called 'solution'. To find
% This tells you that g belongs to a class called 'Solution'. To find
% the methods for this class, type
methods solution
methods Solution
% This command returns only a few method names. These are the ones
% directly defined in this class. But solution inherits many other
% methods from base classes. To see all of its methods, type
methods solution -full
methods Solution -full
% Now a long list is printed, along with a specification of the class
% the method is inherited from. For example, 'setPressure' is
% inherited from a class 'thermophase'. Don't be concerned at this
% inherited from a class 'ThermoPhase'. Don't be concerned at this
% point about what these base classes are - we'll come back to them
% later.

View file

@ -4,8 +4,10 @@ Zero-dimensional reactors.
import _cantera
from Cantera.num import array, zeros
from Cantera.exceptions import CanteraError
import types
_ilr = {'left':0, 'right':1, 'unknown':-1}
class ReactorBase:
"""Base class for reactors and reservoirs.
@ -38,6 +40,7 @@ class ReactorBase:
self._reservoirs = []
self._name = name
self._verbose = verbose
self._paramid = []
self.insert(contents)
self._setInitialVolume(volume)
self._setEnergy(energy)
@ -296,6 +299,29 @@ class ReactorBase:
return self._contents
def nSensParams(self):
"""Number of sensitivity parameters for this reactor."""
return _cantera.reactor_nSensParams(self.__reactor_id)
def addSensitivityReaction(self, reactions = []):
if len(reactions) == 0:
nr = self._contents.nReactions()
for n in range(nr):
self._paramid.append(self._contents.reactionEqn(n))
_cantera.reactor_addSensitivityReaction(self.__reactor_id,
n)
else:
for n in reactions:
self._paramid.append(self._contents.reactionEqn(n))
_cantera.reactor_addSensitivityReaction(self.__reactor_id,
n)
def sensParamName(self, n = -1):
if n < 0:
return self._paramid
else:
return self._paramid[n]
_reactorcount = 0
_reservoircount = 0
@ -812,6 +838,8 @@ class Wall:
self.setKinetics(kinetics[0],kinetics[1])
self._paramid = []
def __del__(self):
""" Delete the Wall instance. This method is called
automatically when no Python object stores a reference to this
@ -910,11 +938,21 @@ class Wall:
ileft = 0
iright = 0
if left:
ileft = left.kin_index()
ileft = left.kinetics_hndl()
if right:
iright = right.kin_index()
iright = right.kinetics_hndl()
self._leftkin = left
self._rightkin = right
_cantera.wall_setkinetics(self.__wall_id, ileft, iright)
def kinetics(self, side = 'left'):
if side == 'left':
return self._leftkin
elif side == 'right':
return self._rightkin
else:
raise CanteraError("side must be 'left' or 'right'")
def set(self, **p):
"""Set various wall parameters: 'A', 'U', 'K', 'Q'. 'velocity'.
These have the same meanings as in the constructor.
@ -936,6 +974,21 @@ class Wall:
raise 'unknown parameter: ',item
def addSensitivityReaction(self, side = 'unknown', reactions = []):
k = self.kinetics(side)
if len(reactions) == 0:
nr = k.nReactions()
for n in range(nr):
self._paramid.append(k.reactionEqn(n))
_cantera.wall_addSensitivityReaction(self.__wall_id,
_ilr[side], n)
else:
for n in reactions:
self._paramid.append(k.reactionEqn(n))
_cantera.wall_addSensitivityReaction(self.__wall_id,
_ilr[side], n)
class ReactorNet:
"""Networks of reactors. ReactorNet objects are used to
@ -995,10 +1048,12 @@ class ReactorNet:
"""The current time [s]."""
return _cantera.reactornet_time(self.__reactornet_id)
def setTolerances(self, rtol = 1.0e-9, atol = 1.0e-20):
def setTolerances(self, rtol = 1.0e-9,
atol = 1.0e-20, rtolsens= -1.0, atolsens = -1.0):
"""Set the relative and absolute error tolerances used in
integrating the reactor equations."""
_cantera.reactornet_setTolerances(self.__reactornet_id, rtol, atol)
_cantera.reactornet_setSensitivityTolerances(self.__reactornet_id, rtolsens, atolsens)
def advance(self, time):
"""Advance the state of the reactor network in time from the current
@ -1011,5 +1066,54 @@ class ReactorNet:
return _cantera.reactornet_step(self.__reactornet_id, time)
def reactors(self):
"""Return the list of reactors in the network."""
return self._reactors
def nSensParams(self):
"""Number of sensitivity parameters."""
sum = 0
for r in self._reactors:
sum += r.nSensParams()
return sum
def sensitivity(self, component = '', parameter = -1, reactor = ''):
"""Sensitivity of solution component 'component' with respect
to one or more parameters.
component -- name of the species or other variable for which
sensitivity information is desired.
parameter -- single integer or sequence of integers specifying
the parameters. The parameters are numbered from zero,
beginning with the parameters for the first reactor and
continuing through those for the last reactor in the
network. If omitted, the sensitivity with respect to all
parameters will be returned.
reactor -- reactor containing the desired component.
"""
n = 0
if reactor <> '':
for reac in self._reactors:
if reac.name() == reactor:
break
else:
n = n+1
np = self.nSensParams()
if parameter >= 0 and parameter < np:
return _cantera.reactornet_sensitivity(self.__reactornet_id,
component, parameter, n)
elif parameter == -1:
s = []
for m in range(np):
s.append(_cantera.reactornet_sensitivity(self.__reactornet_id,
component, m, n))
return s
else:
raise CanteraError("sensitivity requested for illegal parameter number:"+`parameter`)

View file

@ -1,2 +1,4 @@
*.xml
*.log

View file

@ -1,7 +1,7 @@
from Cantera import *
import math
def equilSoundSpeeds(gas):
def equilSoundSpeeds(gas, rtol = 1.0e-6, maxiter = 5000):
"""Returns a tuple containing the equilibrium and frozen sound
speeds for a gas with an equilibrium composition. The gas is
@ -12,41 +12,49 @@ def equilSoundSpeeds(gas):
"""
# set the gas to equilibrium at its current T and P
gas.equilibrate('TP')
gas.equilibrate('TP', rtol = rtol, maxiter = maxiter)
# save properties
s0 = gas.entropy_mass()
p0 = gas.pressure()
r0 = gas.density()
# perturb the density
r1 = r0*1.0001
# perturb the pressure
p1 = p0*1.0001
# set the gas to a state with the same entropy and composition but
# the perturbed density
gas.set(S = s0, V = 1.0/r1)
# the perturbed pressure
gas.set(S = s0, P = p1)
# save the pressure for this case for the frozen sound speed
pfrozen = gas.pressure()
# save the density for this case for the frozen sound speed
rho_frozen = gas.density()
# now equilibrate the gas holding S and V constant
gas.equilibrate("SV")
# now equilibrate the gas holding S and P constant
gas.equilibrate("SP", loglevel=0, rtol = rtol, maxiter = maxiter) # , rtol = 1.0e-3, maxsteps=10000)
p1 = gas.pressure()
r1 = gas.density()
# equilibrium sound speed
aequil = math.sqrt((p1 - p0)/(r1 - r0));
# frozen sound speed
afrozen = math.sqrt((pfrozen - p0)/(r1 - r0));
return (aequil, afrozen)
afrozen = math.sqrt((p1 - p0)/(rho_frozen - r0));
# compute the frozen sound speed using the ideal gas
# expression as a check
cp = gas.cp_mass()
cv = gas.cv_mass()
gamma = cp/cv
afrozen2 = math.sqrt(gamma*GasConstant*gas.temperature()
/gas.meanMolecularWeight())
return (aequil, afrozen, afrozen2)
# test program
if __name__ == "__main__":
gas = GRI30()
gas.set(X = 'CH4:0.1.1, O2:2.0, N2:3.76')
gas.set(X = 'CH4:1.00, O2:2.0, N2:7.52')
for n in range(27):
temp = 300.0 + n*100.0
gas.set(T = temp, P = OneAtm)

View file

@ -46,7 +46,7 @@ for n in range(100):
args = sys.argv
if len(args) > 1 and args[1] == '-plot':
try:
from matplotlib.matlab import *
from matplotlib.pylab import *
clf
subplot(2,2,1)
plot(tim,data[:,0])

View file

@ -22,6 +22,10 @@ bllibstr = "@BLAS_LAPACK_LIBS@"
bllibs = bllibstr.replace('-l',' ')
bllist = bllibs.split()
cvlibstr = "@CVODE_LIBS@"
cvlibs = cvlibstr.replace('-l',' ')
cvlist = cvlibs.split()
extra_link = "@EXTRA_LINK@"
linkargs = extra_link.split()
@ -34,11 +38,11 @@ for d in dirlist:
if platform == "win32":
libs = ["clib", "zeroD","oneD","transport",
"cantera","recipes"] + bllist + ["ctmath", "cvode", "tpx", "converters"]
"cantera","recipes"] + bllist + cvlist + ["ctmath", "tpx", "converters"]
else:
libs = ["clib", "zeroD","oneD","transport",
"cantera", "converters"] + bllist + ["ctmath", "cvode", "tpx",
"cantera", "converters"] + bllist + cvlist + ["ctmath", "tpx",
"stdc++", "ctf2c", "m"]
# values:

View file

@ -79,6 +79,48 @@ py_reactor_setKineticsMgr(PyObject *self, PyObject *args)
return Py_BuildValue("i",0);
}
static PyObject *
py_reactor_nSensParams(PyObject *self, PyObject *args)
{
int _val;
int i;
if (!PyArg_ParseTuple(args, "i:reactor_nSensParams", &i))
return NULL;
_val = reactor_nSensParams(i);
return Py_BuildValue("i",_val);
}
static PyObject *
py_reactor_addSensitivityReaction(PyObject *self, PyObject *args)
{
int _val;
int i;
int rxn;
if (!PyArg_ParseTuple(args, "ii:reactor_addSensitivityReaction", &i, &rxn))
return NULL;
_val = reactor_addSensitivityReaction(i,rxn);
if (int(_val) == -1) return reportCanteraError();
return Py_BuildValue("i",_val);
}
static PyObject *
py_flowReactor_setMassFlowRate(PyObject *self, PyObject *args)
{
int _val;
int i;
double mdot;
if (!PyArg_ParseTuple(args, "id:flowReactor_setMassFlowRate", &i, &mdot))
return NULL;
_val = flowReactor_setMassFlowRate(i,mdot);
if (int(_val) == -1) return reportCanteraError();
return Py_BuildValue("i",_val);
}
// static PyObject*
// py_reactor_advance(PyObject *self, PyObject *args)
// {
@ -192,6 +234,7 @@ py_reactor_massFraction(PyObject *self, PyObject *args)
return Py_BuildValue("d",y);
}
static PyObject*
py_flowdev_new(PyObject *self, PyObject *args)
{
@ -473,6 +516,20 @@ py_wall_ready(PyObject *self, PyObject *args)
return Py_BuildValue("i",0);
}
static PyObject *
py_wall_addSensitivityReaction(PyObject *self, PyObject *args)
{
int _val;
int i;
int lr;
int rxn;
if (!PyArg_ParseTuple(args, "iii:wall_addSensitivityReaction", &i, &lr, &rxn))
return NULL;
_val = wall_addSensitivityReaction(i,lr,rxn);
if (int(_val) == -1) return reportCanteraError();
return Py_BuildValue("i",_val);
}
static PyObject*
py_reactornet_new(PyObject *self, PyObject *args)
@ -504,6 +561,18 @@ py_reactornet_setTolerances(PyObject *self, PyObject *args)
return Py_BuildValue("i",0);
}
static PyObject*
py_reactornet_setSensitivityTolerances(PyObject *self, PyObject *args)
{
int n;
double rtol, atol;
if (!PyArg_ParseTuple(args, "idd:reactornet_setSensitivityTolerances", &n, &rtol, &atol))
return NULL;
int iok = reactornet_setSensitivityTolerances(n, rtol, atol);
if (iok < 0) return reportError(iok);
return Py_BuildValue("i",0);
}
static PyObject*
py_reactornet_setInitialTime(PyObject *self, PyObject *args)
{
@ -558,3 +627,45 @@ py_reactornet_step(PyObject *self, PyObject *args)
return NULL;
return Py_BuildValue("d",reactornet_step(n, t));
}
static PyObject *
py_reactornet_rtol(PyObject *self, PyObject *args)
{
double _val;
int i;
if (!PyArg_ParseTuple(args, "i:reactornet_rtol", &i))
return NULL;
_val = reactornet_rtol(i);
return Py_BuildValue("d",_val);
}
static PyObject *
py_reactornet_atol(PyObject *self, PyObject *args)
{
double _val;
int i;
if (!PyArg_ParseTuple(args, "i:reactornet_atol", &i))
return NULL;
_val = reactornet_atol(i);
return Py_BuildValue("d",_val);
}
static PyObject *
py_reactornet_sensitivity(PyObject *self, PyObject *args)
{
double _val;
int i;
char* v;
int p, r;
if (!PyArg_ParseTuple(args, "isii:reactornet_sensitivity", &i, &v, &p, &r))
return NULL;
_val = reactornet_sensitivity(i,v,p,r);
return Py_BuildValue("d",_val);
}

View file

@ -201,6 +201,7 @@ static PyMethodDef ct_methods[] = {
//{"reactor_setInitialTime", py_reactor_setInitialTime, METH_VARARGS},
{"reactornet_setInitialTime", py_reactornet_setInitialTime, METH_VARARGS},
{"reactornet_setTolerances", py_reactornet_setTolerances, METH_VARARGS},
{"reactornet_setSensitivityTolerances", py_reactornet_setSensitivityTolerances, METH_VARARGS},
{"flowdev_new", py_flowdev_new, METH_VARARGS},
{"flowdev_massFlowRate", py_flowdev_massFlowRate, METH_VARARGS},
{"flowdev_del", py_flowdev_del, METH_VARARGS},
@ -233,6 +234,12 @@ static PyMethodDef ct_methods[] = {
{"reactornet_del", py_reactornet_del, METH_VARARGS},
{"reactor_intEnergy_mass", py_reactor_intEnergy_mass, METH_VARARGS},
{"reactor_massFraction", py_reactor_massFraction, METH_VARARGS},
{"reactor_nSensParams", py_reactor_nSensParams, METH_VARARGS},
{"reactor_addSensitivityReaction", py_reactor_addSensitivityReaction, METH_VARARGS},
{"flowReactor_setMassFlowRate", py_flowReactor_setMassFlowRate, METH_VARARGS},
{"reactornet_rtol", py_reactornet_rtol, METH_VARARGS},
{"reactornet_atol", py_reactornet_atol, METH_VARARGS},
{"reactornet_sensitivity", py_reactornet_sensitivity, METH_VARARGS},
{"wall_install", py_wall_install, METH_VARARGS},
{"wall_setkinetics", py_wall_setkinetics, METH_VARARGS},
{"wall_area", py_wall_area, METH_VARARGS},
@ -248,6 +255,7 @@ static PyMethodDef ct_methods[] = {
{"wall_setEmissivity", py_wall_setEmissivity, METH_VARARGS},
{"wall_setExpansionRateCoeff", py_wall_setExpansionRateCoeff, METH_VARARGS},
{"wall_ready", py_wall_ready, METH_VARARGS},
{"wall_addSensitivityReaction", py_wall_addSensitivityReaction, METH_VARARGS},
{"func_new", py_func_new, METH_VARARGS},
{"func_newcombo", py_func_newcombo, METH_VARARGS},

View file

@ -31,6 +31,9 @@ namespace Cantera {
public:
FuncEval() {}
virtual ~FuncEval() {}
/**
* Evaluate the right-hand-side function. Called by the
* integrator.

1116
ChangeLog

File diff suppressed because it is too large Load diff

View file

@ -12,6 +12,7 @@
#define DEV_EQUIL
#undef DEBUG_MODE
//------------------------ Fortran settings -------------------//
@ -42,6 +43,8 @@ typedef int ftnlen; // Fortran hidden string length type
#define FTN_TRAILING_UNDERSCORE
#undef HAS_SUNDIALS
//-------- LAPACK / BLAS ---------
// Define if you are using LAPACK and BLAS from the Intel Math Kernel

869
config/configure vendored

File diff suppressed because it is too large Load diff

View file

@ -59,19 +59,13 @@ AC_SUBST(USE_CLIB_DLL)
prdef="/usr/local/cantera"
if test "x$OS_IS_DARWIN" = "x1"; then prdef="/Applications/Cantera"; fi
#AC_PREFIX_DEFAULT([$prdef])
local_inst=1
if test "x${prefix}" = "xNONE"; then
#if test "x${OS_IS_CYGWIN}" = "x1" -o "x${OS_IS_WIN}" = "x1" ; then
# prefix=${CANTERA_INSTALL_DIR}
# mkdir ${prefix}
#else
prefix=${prdef}
#${ac_default_prefix}
#fi
local_inst=0
prefix=${prdef}
local_inst=0
fi
exec_prefix=${prefix}
if test "x${OS_IS_WIN}" = "x1"; then
prefix=`cygpath -a -m "${prefix}" `
@ -81,7 +75,6 @@ AC_SUBST(prefix)
AC_SUBST(local_inst)
#
# Determination of Python site-package directory location
#
@ -244,6 +237,20 @@ if test -n "$USER_SRC_DIR"; then USERDIR=$USER_SRC_DIR; INCL_USER_CODE=1; fi
AC_SUBST(USERDIR)
AC_SUBST(INCL_USER_CODE)
use_sundials=0
sundials_inc=
CVODE_LIBS='-lcvode'
if test "x$USE_SUNDIALS" = "xy"; then
use_sundials=1
AC_DEFINE(HAS_SUNDIALS)
CVODE_LIBS='-lsundials_cvodes -lsundials_shared -lsundials_nvecserial'
sundials_include='-I '${SUNDIALS_HOME}/include
fi
AC_SUBST(use_sundials)
AC_SUBST(CVODE_LIBS)
AC_SUBST(sundials_include)
#########################################################
# The Cantera Kernel
#########################################################
@ -359,6 +366,7 @@ AC_SUBST(KERNEL_OBJ)
AC_SUBST(BUILD_CK)
AC_SUBST(LIB_DIR)
########################################################
# BLAS and LAPACK
########################################################
@ -447,8 +455,8 @@ LOCAL_LIBS=$LOCAL_LIBS' '-lcantera
#then LOCAL_LIBS=$LOCAL_LIBS' '-lrecipes
#fi
if test -n "$NEED_CVODE"
then LOCAL_LIBS=$LOCAL_LIBS' '-lcvode
if test -n "$NEED_CVODE"; then
LOCAL_LIBS=$LOCAL_LIBS' '$CVODE_LIBS
fi
if test -n "$NEED_LAPACK"
@ -481,6 +489,14 @@ if test -n "$BLAS_LAPACK_DIR"
then LOCAL_LIB_DIRS=$LOCAL_LIB_DIRS' -L'$BLAS_LAPACK_DIR
fi
if test -n "$SUNDIALS_HOME"
then LOCAL_LIB_DIRS=$LOCAL_LIB_DIRS' -L'$SUNDIALS_HOME/lib
fi
echo $SUNDIALS_HOME
echo $LOCAL_LIB_DIRS
AC_SUBST(LOCAL_LIB_DIRS)
AC_SUBST(LOCAL_LIBS)
@ -783,8 +799,8 @@ if test -z "$EXE_EXT"; then EXE_EXT=$EXEEXT; fi
AC_SUBST(EXE_EXT)
dnl AC_LANG_FORTRAN77
local_math_libs='-lcvode'
AC_SUBST(local_math_libs)
#local_math_libs='-lcvode'
#AC_SUBST(local_math_libs)
math_libs='-lcvode -lctmath'

32
configure vendored
View file

@ -25,7 +25,7 @@
# If you define this to be <prefix>, then instead of running this
# script as ./configure --prefix=<prefix> you can just run it as
# ./configure
CANTERA_CONFIG_PREFIX=${CANTERA_CONFIG_PREFIX:="/usr/local/cantera"}
CANTERA_CONFIG_PREFIX=${CANTERA_CONFIG_PREFIX:=""}
#----------------------------------------------------------------------
@ -186,7 +186,7 @@ WITH_PURE_FLUIDS='y'
# Enable expanded electrochemistry capabilities, include thermo
# models for electrolyte solutions
WITH_ELECTROLYTES='n'
WITH_ELECTROLYTES='y'
######################################################################
# if set to 'y', the ck2cti program that converts Chemkin input files
# to Cantera format will be built. If you don't use Chemkin format
@ -217,8 +217,29 @@ ENABLE_RXNPATH='y'
# non-ideal pure substance models for a few fluids imported from the
# 'TPX' package. (http://adam.caltech.edu/software/tpx)
ENABLE_TPX='y'
#-----------------------------------------------------------------
# CVODE / CVODES
#-----------------------------------------------------------------
#
# Cantera uses the CVODE ODE integrator to time-integrate reactor
# network ODE's and for various other purposes. An older version of
# CVODE comes with Cantera, but it is possible to use the latest
# version as well, which now supports sensitivity analysis (CVODES).
# CVODES is a part of the 'sundials' package from Lawrence Livermore
# National Laboratory. Due to its size, sundials is not distributed
# with Cantera, but it is free software that may be downloaded and
# installed separately. If you have sundials, set USE_SUNDIALS to 'y',
# and set SUNDIALS_HOME to the directory where you have installed
# sundials. Note that sensitivity analysis with Cantera requires use
# of sundials.
#
# See: http://www.llnl.gov/CASC/sundials
#
USE_SUNDIALS='y'
SUNDIALS_HOME='/usr/local/sundials'
#-----------------------------------------------------------------
# BLAS and LAPACK
#-----------------------------------------------------------------
@ -265,7 +286,7 @@ CXX=${CXX:=g++}
CC=${CC:=gcc}
# C++ compiler flags
CXXFLAGS=${CXXFLAGS:="-O3 -g -Wall"}
CXXFLAGS=${CXXFLAGS:="-O3 -Wall"}
# the C++ flags required for linking. Uncomment if additional flags
# need to be passed to the linker.
@ -412,6 +433,8 @@ export CANTERA_INSTALL_DIR
export USE_NUMERIC
export NUMARRAY_HOME
export CANTERA_PYTHON_HOME
export USE_SUNDIALS
export SUNDIALS_HOME
export WITH_LATTICE_SOLID
export WITH_METAL
@ -439,6 +462,7 @@ fi
#
./configure $CCPREFIX $1 $2 $3 $4
#-------------- deprecated options ------------------------------------
#
#----------------------------------------------------------------------

View file

@ -10,6 +10,7 @@
BUILD_LAPACK=@build_lapack@
BUILD_BLAS=@build_blas@
BUILD_WITH_F2C=@build_with_f2c@
USE_SUNDIALS=@use_sundials@
LIBS = blas/libctblas.a lapack/libctlapack.a math/libctmath.a \
cvode/libcvode.a tpx/libtpx.a
@ -45,7 +46,9 @@ endif
# cd recipes; @MAKE@
cd math; @MAKE@
endif
ifeq ($(USE_SUNDIALS),0)
cd cvode; @MAKE@
endif
cd tpx; @MAKE@
clean:

View file

@ -6,6 +6,7 @@
do_ranlib = @DO_RANLIB@
CXX_FLAGS = @CXXFLAGS@ $(CXX_OPT)
#COBJS = tpx_files.o
COBJS = Methane.o Nitrogen.o Oxygen.o Water.o Hydrogen.o RedlichKwong.o \
CarbonDioxide.o Heptane.o lk.o Sub.o utils.o HFC134a.o

View file

@ -20,6 +20,7 @@ NUMARRAYRESDIR=$PKGDIR/numarray/resources_dir
# where Cantera has been installed
instdir=/Applications/Cantera
pylibdir=/Library/Python/$PYVERSION
$INSTALL -d $CTDIR

View file

@ -45,7 +45,7 @@ CANTERA_LIBDIR=@ct_libdir@
CANTERA_INCDIR=@ct_incroot@
# flags passed to the C++ compiler/linker for the linking step
LCXXFLAGS = -L$(CANTERA_LIBDIR) @CXXFLAGS@
LCXXFLAGS = -L$(CANTERA_LIBDIR) @LOCAL_LIB_DIRS@ @CXXFLAGS@
# how to compile C++ source files to object files
.@CXX_EXT@.@OBJ_EXT@: