*** empty log message ***
This commit is contained in:
parent
4f3912b7b1
commit
f0b91575da
11 changed files with 228 additions and 16 deletions
|
|
@ -66,6 +66,15 @@ extern "C" {
|
|||
return 0;
|
||||
}
|
||||
|
||||
double DLL_EXPORT bndry_spreadrate(int i) {
|
||||
return ((Inlet1D*)_bndry(i))->spreadRate();
|
||||
}
|
||||
|
||||
int DLL_EXPORT bndry_setSpreadRate(int i, double v) {
|
||||
((Inlet1D*)_bndry(i))->setSpreadRate(v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DLL_EXPORT bndry_setmdot(int i, double mdot) {
|
||||
try {
|
||||
_bndry(i)->setMdot(mdot);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ extern "C" {
|
|||
int DLL_IMPORT bndry_del(int i);
|
||||
double DLL_IMPORT bndry_temperature(int i);
|
||||
int DLL_IMPORT bndry_settemperature(int i, double t);
|
||||
double DLL_IMPORT bndry_spreadrate(int i);
|
||||
int DLL_IMPORT bndry_setSpreadRate(int i, double v);
|
||||
int DLL_IMPORT bndry_setmdot(int i, double mdot);
|
||||
double DLL_IMPORT bndry_mdot(int i);
|
||||
int DLL_IMPORT bndry_setxin(int i, double* xin);
|
||||
|
|
|
|||
|
|
@ -557,6 +557,44 @@ class Flow1D:
|
|||
return nin
|
||||
|
||||
|
||||
def prune(self, loglevel = 2):
|
||||
"""Prune the grid.
|
||||
|
||||
"""
|
||||
r = self.refiner
|
||||
r.components = range(4,self.nsp+4)
|
||||
if self.energy:
|
||||
r.components.append(2)
|
||||
|
||||
znew, xn = r.prune(grid = self.z, solution = self.x)
|
||||
nout = len(self.z) - len(znew)
|
||||
|
||||
if nout > 0:
|
||||
self.setGrid(znew)
|
||||
self.x = array(xn,'d')
|
||||
self.xnew = zeros(shape(xn),'d')
|
||||
|
||||
# update the fixed temperature values if the energy
|
||||
# equation is not being solved
|
||||
|
||||
if self.energy == 0:
|
||||
for j in range(self.npts):
|
||||
zz, tt = self.initial['T']
|
||||
t = interp.interp(self.z[j],zz,tt)
|
||||
self.holdTemperature(j,t)
|
||||
else:
|
||||
for j in range(self.npts):
|
||||
self.holdTemperature(j,self.x[j,2])
|
||||
self.setEnergyEqn('on')
|
||||
|
||||
if loglevel > 0:
|
||||
print 'Prune: ',
|
||||
print 'removed',nout,'points.'
|
||||
print 'Grid size = ',len(self.z)
|
||||
|
||||
return nout
|
||||
|
||||
|
||||
def save(self, filename, id, desc="", append=0):
|
||||
"""Save a solution to a file.
|
||||
|
||||
|
|
|
|||
|
|
@ -321,6 +321,28 @@ class OneDim:
|
|||
self._end.append(self._loc)
|
||||
return new_points
|
||||
|
||||
def prune(self, loglevel = 2):
|
||||
"""Prune the grid of every flow domain."""
|
||||
rem_points = 0
|
||||
for f in self._flow:
|
||||
rem_points += f.prune(loglevel)
|
||||
if rem_points > 0:
|
||||
self.collect()
|
||||
_cantera.onedim_resize(self.__onedim_id)
|
||||
self._shape = []
|
||||
self._size = []
|
||||
self._start = []
|
||||
self._end = []
|
||||
self._loc = 0
|
||||
for d in self._domain:
|
||||
np, nv = d.shape()
|
||||
self._shape.append((np, nv))
|
||||
self._size.append(np*nv)
|
||||
self._start.append(self._loc)
|
||||
self._loc += np*nv
|
||||
self._end.append(self._loc)
|
||||
return rem_points
|
||||
|
||||
def setEnergyFactor(self, e):
|
||||
for f in self._flow:
|
||||
f.setEnergyFactor(e)
|
||||
|
|
|
|||
|
|
@ -34,6 +34,9 @@ class Boundary1D:
|
|||
self.T = T
|
||||
self.x[0,1] = T
|
||||
_cantera.bndry_settemperature(self.__bndry_id, T)
|
||||
if V <> -999.0:
|
||||
self.V = V
|
||||
_cantera.bndry_setspreadrate(self.__bndry_id, V)
|
||||
if X:
|
||||
self.X = X
|
||||
if type(X) == types.StringType:
|
||||
|
|
|
|||
|
|
@ -17,6 +17,19 @@ class BurnerFlame:
|
|||
|
||||
flame = BurnerFlame(gas, domain, fuel, oxidizer, inert, grid, pressure)
|
||||
|
||||
arguments:
|
||||
|
||||
gas --- an object representing the gas mixture
|
||||
domain --- [zmin, zmax]
|
||||
fuel --- a string specifying the fuel stream composition
|
||||
oxidizer --- a string specifying the oxidizer stream composition
|
||||
inert --- a string specifying the composition of an inert
|
||||
stream (optional)
|
||||
grid --- a sequence defining the initial grid. The first point
|
||||
should be zmin, and the last one zmax. If omitted,
|
||||
a default grid will be used.
|
||||
pressure --- the pressure, which is treated as constant.
|
||||
|
||||
example:
|
||||
flame = BurnerFlame(gas = GRI30(),
|
||||
domain = [0.0, 10.0*units.cm],
|
||||
|
|
@ -31,6 +44,7 @@ class BurnerFlame:
|
|||
fuel = '', oxidizer = '', inert = '',
|
||||
grid = None, pressure = -1.0):
|
||||
|
||||
# check that all required inputs have been specified
|
||||
if not gas or not domain or not fuel or not oxidizer or not pressure:
|
||||
raise self.__doc__
|
||||
|
||||
|
|
@ -38,18 +52,26 @@ class BurnerFlame:
|
|||
self.p = pressure
|
||||
|
||||
dx = (domain[1] - domain[0])
|
||||
|
||||
# if no grid specified, use this one that concentrates points
|
||||
# near the burner
|
||||
if grid == None:
|
||||
grid = dx * array([0.0, 0.01, 0.03, 0.1, 0.3, 0.6, 1.0])
|
||||
|
||||
|
||||
self.__flow = Flow1D(flow_type = 'OneDim', gas = gas,
|
||||
grid = grid, pressure = self.p)
|
||||
|
||||
|
||||
#------ these methods are deprecated, but still needed for now.
|
||||
self.inlet = Inlet(gas)
|
||||
self.outlet = Outlet(gas)
|
||||
|
||||
self.__flow.setBoundaries(left = self.inlet, right = self.outlet)
|
||||
|
||||
#----------------------------------------------------------------
|
||||
|
||||
# The container contains only the Flow1D object. Should be
|
||||
# modified at some point to contain an Inlet1D and an Outlet1D
|
||||
# object.
|
||||
self.__container = OneDim([self.__flow])
|
||||
self.start = 0
|
||||
|
||||
|
|
@ -57,7 +79,6 @@ class BurnerFlame:
|
|||
# get the compositions of the fuel and oxidizer streams, and
|
||||
# calculate the fuel/oxidizer ratio for stoichiometric
|
||||
# combustion
|
||||
|
||||
gas.setMoleFractions(fuel)
|
||||
self._xfuel = gas.moleFractions()
|
||||
|
||||
|
|
@ -73,18 +94,28 @@ class BurnerFlame:
|
|||
self._stoich_FO = stoich.stoich_fuel_to_oxidizer(gas, fuel, oxidizer)
|
||||
|
||||
|
||||
|
||||
# TODO: accout for inert stream
|
||||
def setEquivRatio(self, phi):
|
||||
"""Set the equivalence ratio."""
|
||||
f_flow = self._stoich_FO * phi
|
||||
comp = f_flow * self._xfuel + self._xox
|
||||
self.gas.setState_PX(self.p, comp)
|
||||
self.inlet.set(X = self.gas.moleFractions())
|
||||
|
||||
|
||||
def setEquilProducts(self):
|
||||
"""Set the flame state to chemical equilibrium.
|
||||
"""Generate a starting estimate for the flame state.
|
||||
|
||||
The following procedure is used:
|
||||
|
||||
1) At the burner, the composition is the specified inlet
|
||||
composition;
|
||||
2) The last 80% of the domain has constant composition and
|
||||
temperature corresponding to the adiabatic equilibrium
|
||||
solution;
|
||||
3) In the initial 20%, the composition and temperature vary linearly
|
||||
from the inlet values to the equilibrium values.
|
||||
|
||||
This is useful to generate a starting estimate.
|
||||
"""
|
||||
x0 = self.inlet.X
|
||||
self.gas.setState_TPX(self.inlet.T, self.p, x0)
|
||||
|
|
@ -104,30 +135,84 @@ class BurnerFlame:
|
|||
xinit[nm] = x
|
||||
self.__flow.setInitialProfiles(xinit)
|
||||
|
||||
|
||||
def plot(self, plotfile = '', title = '', fmt = 'TECPLOT',
|
||||
zone = 'c0', append = 0):
|
||||
"""Plot the current solution."""
|
||||
self.__flow.plotter.plot(fname = plotfile, title = title,
|
||||
fmt = fmt, zone = zone, append=append)
|
||||
|
||||
|
||||
def setInitialProfiles(self, **init):
|
||||
"""Specify estimates for the initial profiles.
|
||||
|
||||
"""
|
||||
self.__flow.setInitialProfiles(init)
|
||||
self.start = 1
|
||||
|
||||
def restore(self, src = '', solution = ''):
|
||||
"""Start from a previously-saved solution."""
|
||||
self.__container.restore(0, src, solution)
|
||||
self.start = 1
|
||||
|
||||
def setTolerances(self, V = None, T = None, Y = None):
|
||||
"""Set tolerances for convergence for velocity, temperature,
|
||||
and mass fractions."""
|
||||
self.__flow.setTolerances( V, V, T, Y)
|
||||
|
||||
def prune(self, loglevel = 2):
|
||||
"""Remove unneeded grid points.
|
||||
|
||||
This method attempts to remove each grid point one by one, and
|
||||
calls 'refine' each time to see whether it puts it back. If it does,
|
||||
the point is not removed, otherwise it is.
|
||||
"""
|
||||
self.__container.prune(loglevel)
|
||||
|
||||
def refine(self, loglevel = 2):
|
||||
"""Refine the grid using the current grid refinement parameters."""
|
||||
self.__container.refine(loglevel)
|
||||
|
||||
def show(self):
|
||||
"""Print a summary of the current solution to the screen."""
|
||||
self.__flow.show()
|
||||
|
||||
def stretch(self, factor):
|
||||
"""Stretch the grid by 'factor'"""
|
||||
self.__flow.setGrid(factor*self.__flow.z)
|
||||
|
||||
def set(self, **opt):
|
||||
"""Set options.
|
||||
|
||||
The options that may be set are:
|
||||
|
||||
energy --- 'on' or 'off'. If 'on', the energy equation is
|
||||
solved; otherwise, the temperature is held to the specified
|
||||
profile.
|
||||
|
||||
pressure --- the pressure in Pa.
|
||||
|
||||
mdot --- the inlet mass flow rate per unit area.
|
||||
|
||||
equiv_ratio --- the equivalence ratio
|
||||
|
||||
T_burner --- the burner surface temperature [K].
|
||||
|
||||
refine --- a triplet specifying the refinement criteria.
|
||||
See refine.py for more information.
|
||||
|
||||
tol --- error tolerances for u, V, T, and Y.
|
||||
|
||||
max_jac_age --- the maximum number of times to use a Jacobian
|
||||
before recomputing it.
|
||||
|
||||
timesteps --- number and duration of time steps to take
|
||||
when Newton iteration fails. The format is
|
||||
( number_sequence, initial_stepsize )
|
||||
|
||||
These parameters can be changed as the solution proceeds."""
|
||||
|
||||
# TODO: is this necessary?
|
||||
if self.__container == None:
|
||||
self.__container = OneDim([self.__flow,])
|
||||
|
||||
|
|
@ -153,23 +238,38 @@ class BurnerFlame:
|
|||
elif o == 'timesteps':
|
||||
self.__container.setOptions(nsteps = v[0], timestep = v[1])
|
||||
|
||||
|
||||
def solve(self, loglevel = 0):
|
||||
""" Solve the flame equations.
|
||||
|
||||
If no starting estimate has been given, setEquilProducts()
|
||||
is called to generate one.
|
||||
|
||||
"""
|
||||
if not self.start:
|
||||
self.setEquilProducts()
|
||||
self.start = 1
|
||||
solve(self.__container, loglevel = loglevel, refine_grid = 1)
|
||||
|
||||
def esolve(self, loglevel = 0, efactor = 1.0e4):
|
||||
if not self.start:
|
||||
self.setEquilProducts()
|
||||
self.start = 1
|
||||
esolve(self.__container, efactor = efactor, loglevel = loglevel, refine_grid = 1)
|
||||
|
||||
## def esolve(self, loglevel = 0, efactor = 1.0e4):
|
||||
## if not self.start:
|
||||
## self.setEquilProducts()
|
||||
## self.start = 1
|
||||
## esolve(self.__container, efactor = efactor, loglevel = loglevel, refine_grid = 1)
|
||||
|
||||
|
||||
def save(self, soln, desc, file = 'flame.xml'):
|
||||
"""Save the current solution.
|
||||
|
||||
soln --- string to identify this solution in the file.
|
||||
desc --- descriptive text string.
|
||||
file --- file name.
|
||||
"""
|
||||
self.__container.save(file, soln, desc)
|
||||
|
||||
def showStatistics(self):
|
||||
"""Show numerical statistics."""
|
||||
self.__container.showStatistics()
|
||||
|
||||
|
||||
|
|
@ -312,7 +412,13 @@ class StagnationFlame:
|
|||
|
||||
def enableEnergy(self, pt):
|
||||
self.__flow.setEnergyEqn('on',loglevel=1,pt=pt)
|
||||
|
||||
|
||||
def prune(self, loglevel = 2):
|
||||
self.__container.prune(loglevel)
|
||||
|
||||
def refine(self, loglevel = 2):
|
||||
self.__container.refine(loglevel)
|
||||
|
||||
def set(self, **opt):
|
||||
|
||||
if self.__container == None:
|
||||
|
|
@ -331,6 +437,8 @@ class StagnationFlame:
|
|||
self.setEquivRatio(v)
|
||||
elif o == 'T_burner':
|
||||
self.__left.set(T = v)
|
||||
elif o == 'spreadingRate':
|
||||
self.__left.set(V = v)
|
||||
elif o == 'T_surface':
|
||||
self.__right.set(T = v)
|
||||
elif o == 'refine':
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ class Refiner:
|
|||
np = len(g)
|
||||
|
||||
self.direction = 1
|
||||
gnew, snew = self.refine(g, sol, threshold)
|
||||
gnew, gn, snew, ok = self.refine(g, sol, threshold)
|
||||
if (len(gnew) > np):
|
||||
g = g0
|
||||
sol = s0
|
||||
|
|
@ -124,7 +124,7 @@ class Refiner:
|
|||
return (g, sol)
|
||||
|
||||
|
||||
def refine(self, grid = None, solution = None, threshold = None):
|
||||
def refine(self, grid = None, solution = None, threshold = None, prune = 1):
|
||||
|
||||
self.ok = 0
|
||||
# grid parameters
|
||||
|
|
|
|||
|
|
@ -68,6 +68,28 @@ py_bndry_settemperature(PyObject *self, PyObject *args)
|
|||
return Py_BuildValue("i",0);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
py_bndry_spreadrate(PyObject *self, PyObject *args)
|
||||
{
|
||||
int n;
|
||||
if (!PyArg_ParseTuple(args, "i:bndry_spreadrate", &n))
|
||||
return NULL;
|
||||
double v = bndry_spreadrate(n);
|
||||
return Py_BuildValue("d",v);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
py_bndry_setspreadrate(PyObject *self, PyObject *args)
|
||||
{
|
||||
int n;
|
||||
double v;
|
||||
if (!PyArg_ParseTuple(args, "id:bndry_setspreadrate", &n, &v))
|
||||
return NULL;
|
||||
int iok = bndry_setspreadrate(n, v);
|
||||
if (iok < 0) return reportError(iok);
|
||||
return Py_BuildValue("i",0);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
py_bndry_mdot(PyObject *self, PyObject *args)
|
||||
{
|
||||
|
|
@ -124,6 +146,8 @@ static PyMethodDef ct_methods[] = {
|
|||
{"bndry_setxin", py_bndry_setxin, METH_VARARGS},
|
||||
{"bndry_setxinbyname", py_bndry_setxinbyname, METH_VARARGS},
|
||||
{"bndry_settemperature", py_bndry_settemperature, METH_VARARGS},
|
||||
{"bndry_setspreadrate", py_bndry_setspreadrate, METH_VARARGS},
|
||||
{"bndry_spreadrate", py_bndry_spreadrate, METH_VARARGS},
|
||||
{"bndry_new", py_bndry_new, METH_VARARGS},
|
||||
{"bndry_del", py_bndry_del, METH_VARARGS},
|
||||
{"bndry_mdot", py_bndry_mdot, METH_VARARGS},
|
||||
|
|
|
|||
|
|
@ -83,6 +83,11 @@ namespace Cantera {
|
|||
needJacUpdate();
|
||||
}
|
||||
|
||||
/// spreading rate
|
||||
virtual double spreadRate() {
|
||||
return m_V0;
|
||||
}
|
||||
|
||||
/// Temperature [K].
|
||||
doublereal temperature() {return m_temp;}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,7 +156,8 @@ depends:
|
|||
export:
|
||||
@INSTALL@ -d $(export_dir)
|
||||
if (test -d $(ct)); then rm -r -f $(ct); fi
|
||||
cd $(export_dir); cvs export -D 1/01/2010 cantera-export-$(version)
|
||||
cd $(export_dir); cvs export -D 1/01/2010 cantera
|
||||
cd $(export-dir); mv cantera $(ct)
|
||||
cd $(ct); rm -r -f Cantera/matlab/cantera/@Thermo
|
||||
|
||||
pack: export
|
||||
|
|
|
|||
2
configure
vendored
2
configure
vendored
|
|
@ -150,7 +150,7 @@ LAPACK_FTN_STRING_LEN_AT_END='y'
|
|||
CXX=${CXX:=g++}
|
||||
|
||||
# C++ compiler flags
|
||||
CXXFLAGS=${CXXFLAGS:="-O0 -Wall"}
|
||||
CXXFLAGS=${CXXFLAGS:="-O2 -Wall"}
|
||||
|
||||
# the C++ flags required for linking
|
||||
#LCXX_FLAGS=
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue