Cleaned up whitespace in all Python files using reindent.py

4 spaces per indentation level, no tabs, no trailing whitespace,
and a single newline at end of each file.
This commit is contained in:
Ray Speth 2012-02-27 18:13:05 +00:00
parent b0ccecf4e4
commit 6cb4bd93ce
111 changed files with 3083 additions and 3322 deletions

View file

@ -22,8 +22,3 @@ import Cantera.OneD
writepydoc(Cantera.OneD, out)
out.close()

View file

@ -17,7 +17,7 @@ class DustyGasTransport(Transport):
DustyGasTransport.
"""
def __init__(self, phase = None):
"""
phase - The object representing the gas phase within the
@ -39,14 +39,14 @@ class DustyGasTransport(Transport):
def setMeanParticleDiameter(self, diameter):
"""Set the mean particle diameter [m]. Internal. See: set"""
self.setParameters(3, 0, [diameter, 0.0])
self.setParameters(3, 0, [diameter, 0.0])
def setPermeability(self, permeability):
"""Set the permeability. If not called, the value for close-packed
spheres is used. Internal."""
self.setParameters(4, 0, [permeability, 0.0])
def set(self, **p):
"""Set model parameters. This is a convenience method that simply
calls other methods depending on the keyword.
@ -58,7 +58,7 @@ class DustyGasTransport(Transport):
tortuous.
pore_radius - The pore radius [m].
All keywords are optional.
"""
for o in p.keys():
@ -74,7 +74,3 @@ class DustyGasTransport(Transport):
self.setPermeability(p[o])
else:
raise 'unknown parameter'

View file

@ -6,11 +6,11 @@ from SurfacePhase import EdgePhase
from Kinetics import Kinetics
import XML
class Edge(EdgePhase, Kinetics):
class Edge(EdgePhase, Kinetics):
"""
One-dimensional edge between two surfaces.
Instances of class Edge represent reacting 1D edges between
Instances of class Edge represent reacting 1D edges between
between 2D surfaces. Class Edge defines no methods of its
own. All of its methods derive from either EdgePhase or Kinetics.
@ -43,9 +43,9 @@ class Edge(EdgePhase, Kinetics):
fn = src.split('#')
id = ""
if len(fn) > 1:
id = fn[1]
id = fn[1]
fn = fn[0]
# read in the root element of the tree if not building from
# an already-built XML tree. Enable preprocessing if the film
# is a .cti file instead of XML.
@ -60,9 +60,9 @@ class Edge(EdgePhase, Kinetics):
# otherwise, find the first element with tag name 'phase'
# (1D, 2D and 3D phases use the CTML tag name 'phase'
else:
s = root.child(name = "phase")
s = root.child(name = "phase")
# build the surface phase
# build the surface phase
EdgePhase.__init__(self, xml_phase=s)
# build the reaction mechanism. This object (representing the

View file

@ -14,12 +14,12 @@ import types
class Func1:
"""Functors of one variable.
"""Functors of one variable.
A Functor is an object that behaves like a function. Class 'Func1'
is the base class from which several functor classes derive. These
classes are designed to allow specifying functions of time from Python
that can be used by the C++ kernel.
that can be used by the C++ kernel.
Functors can be added, multiplied, and divided to yield new functors.
>>> f1 = Polynomial([1.0, 0.0, 3.0]) # 3*t*t + 1
@ -32,7 +32,7 @@ class Func1:
>>> f3(2.0)
___4.3333333
"""
def __init__(self, typ, n, coeffs=[]):
"""
The constructor is
@ -55,7 +55,7 @@ class Func1:
def __repr__(self):
return self.write()
def __call__(self, t):
"""Implements function syntax, so that F(t) is equivalent to
F.value(t)."""
@ -65,7 +65,7 @@ class Func1:
return CompositeFunction(self, t)
else:
return _cantera.func_value(self._func_id, t)
def __add__(self, other):
"""Overloads operator '+'
@ -75,17 +75,17 @@ class Func1:
# it.
if type(other) == types.FloatType:
return SumFunction(self, Const(other))
return SumFunction(self, other)
def __radd__(self, other):
"""Overloads operator '+'
Returns a new function other(t) + self(t)"""
# if 'other' is a number, then create a 'Const' functor for
# it.
# it.
if type(other) == types.FloatType:
return SumFunction(Const(other),self)
return SumFunction(Const(other),self)
return SumFunction(other, self)
def __sub__(self, other):
@ -97,9 +97,9 @@ class Func1:
# it.
if type(other) != types.InstanceType:
return DiffFunction(self, Const(other))
return DiffFunction(self, other)
def __rsub__(self, other):
"""Overloads operator '-'
@ -110,13 +110,13 @@ class Func1:
if type(other) != types.InstanceType:
return DiffFunction(Const(other), self)
return DiffFunction(other, self)
def __mul__(self, other):
"""Overloads operator '*'
Return a new function self(t)*other(t)"""
if type(other) != types.InstanceType:
return ProdFunction(self, Const(other))
return ProdFunction(self, Const(other))
return ProdFunction(self, other)
def __rmul__(self, other):
@ -124,15 +124,15 @@ class Func1:
Returns a new function other(t)*self(t)"""
if type(other) != types.InstanceType:
return ProdFunction(Const(other), self)
return ProdFunction(Const(other), self)
return ProdFunction(other, self)
def __div__(self, other):
"""Overloads operator '/'
Returns a new function self(t)/other(t)"""
if type(other) != types.InstanceType:
return RatioFunction(self, Const(other))
return RatioFunction(self, Const(other))
return RatioFunction(self, other)
def __rdiv__(self, other):
@ -140,8 +140,8 @@ class Func1:
Returns a new function other(t)/self(t)"""
if type(other) != types.InstanceType:
return RatioFunction(Const(other), self)
return RatioFunction(other, self)
return RatioFunction(Const(other), self)
return RatioFunction(other, self)
def func_id(self):
"""Internal. Return the integer index used internally to access the
@ -150,8 +150,8 @@ class Func1:
def write(self, arg = 'x', length = 1000):
return _cantera.func_write(self._func_id, length, arg)
class Sin(Func1):
def __init__(self,omega=1.0):
Func1.__init__(self,100,1,omega)
@ -164,7 +164,7 @@ class Exp(Func1):
class Pow(Func1):
def __init__(self, n):
Func1.__init__(self,106,1,n)
class Polynomial(Func1):
"""A polynomial.
Instances of class 'Polynomial' evaluate
@ -173,7 +173,7 @@ class Polynomial(Func1):
\f]
The coefficients are supplied as a list, beginning with
\f$a_N\f$ and ending with \f$a_0\f$.
>>> p1 = Polynomial([1.0, -2.0, 3.0]) # 3t^2 - 2t + 1
>>> p2 = Polynomial([6.0, 8.0]) # 8t + 6
@ -184,10 +184,10 @@ class Polynomial(Func1):
"""
Func1.__init__(self, 2, len(coeffs)-1, coeffs)
class Gaussian(Func1):
"""A Gaussian pulse. Instances of class 'Gaussian' evaluate
"""A Gaussian pulse. Instances of class 'Gaussian' evaluate
\f[
f(t) = A \exp[-(t - t_0) / \tau]
\f]
@ -200,7 +200,7 @@ class Gaussian(Func1):
As an example, here is how to create
a Gaussian pulse with peak amplitude 10.0, centered at time 2.0,
with full-width at half max = 0.2:
>>> f = Gaussian(A = 10.0, t0 = 2.0, FWHM = 0.2)
>>> f = Gaussian(A = 10.0, t0 = 2.0, FWHM = 0.2)
>>> f(2.0)
___10
>>> f(1.9)
@ -212,7 +212,7 @@ class Gaussian(Func1):
coeffs = array([A, t0, FWHM], 'd')
Func1.__init__(self, 4, 0, coeffs)
class Fourier(Func1):
"""Fourier series. Instances of class 'Fourier' evaluate the Fourier series
\f[
@ -240,11 +240,11 @@ class Fourier(Func1):
def __init__(self, omega, coefficients):
"""
omega - fundamental frequency [radians/sec].
coefficients - List of (a,b) pairs, beginning with \f$n = 0\f$.
"""
cc = asarray(coefficients,'d')
cc = asarray(coefficients,'d')
n, m = cc.shape
if m <> 2:
raise CanteraError('provide (a, b) for each term')
@ -256,32 +256,32 @@ class Fourier(Func1):
# \f[
# f(T) = \sum_{n=1}^N A_n T^{b_n}\exp(-E_n/T)
# \f]
#
#
# Example:
#
# >>> f = Arrhenius([(a0, b0, e0), (a1, b1, e1)])
#
#
class Arrhenius(Func1):
"""Sum of modified Arrhenius terms. Instances of class 'Arrhenius' evaluate
\f[
f(T) = \sum_{n=1}^N A_n T^{b_n}\exp(-E_n/T)
\f]
Example:
>>> f = Arrhenius([(a0, b0, e0), (a1, b1, e1)])
"""
def __init__(self, coefficients):
"""
coefficients - sequence of \f$(A, b, E)\f$ triplets.
"""
cc = asarray(coefficients,'d')
n, m = cc.shape
if m <> 3:
raise CanteraError('Three Arrhenius parameters (A, b, E) required.')
Func1.__init__(self, 3, n, ravel(cc))
Func1.__init__(self, 3, n, ravel(cc))
@ -299,7 +299,7 @@ class Const(Func1):
degree zero, with the constant term set to the desired value.
"""
def __init__(self, value):
Func1.__init__(self,110,1,value)
Func1.__init__(self,110,1,value)
#return Polynomial([value])
@ -313,7 +313,7 @@ class PeriodicFunction(Func1):
"""
Func1.__init__(self, 50, func.func_id(), array([T],'d'))
func._own = 0
# functions that combine two functions
@ -323,7 +323,7 @@ class ComboFunc1(Func1):
This class is the base class for functors that combine two
other functors in a binary operation.
"""
def __init__(self, typ, f1, f2):
self._own = 1
self._func_id = 0
@ -331,14 +331,14 @@ class ComboFunc1(Func1):
if type(f1) == types.IntType:
f1 = Const(f1)
if type(f2) == types.IntType:
f2 = Const(f2)
f2 = Const(f2)
self.f1 = f1
self.f2 = f2
self.f1._own = 0
self.f2._own = 0
self._func_id = _cantera.func_newcombo(typ, f1.func_id(), f2.func_id())
class SumFunction(ComboFunc1):
"""Sum of two functions.
Instances of class SumFunction evaluate the sum of two supplied functors.
@ -351,11 +351,11 @@ class SumFunction(ComboFunc1):
In this example, object 'f3' is a functor of class'SumFunction' that calls f1 and f2
and returns their sum.
"""
def __init__(self, f1, f2):
"""
f1 - first functor.
f2 - second functor.
"""
ComboFunc1.__init__(self, 20, f1, f2)
@ -373,15 +373,15 @@ class DiffFunction(ComboFunc1):
In this example, object 'f3' is a functor of class'DiffFunction' that
calls f1 and f2 and returns their difference.
"""
def __init__(self, f1, f2):
"""
f1 - first functor.
f2 - second functor.
"""
ComboFunc1.__init__(self, 25, f1, f2)
class ProdFunction(ComboFunc1):
"""Product of two functions. Instances of class ProdFunction
@ -389,14 +389,14 @@ class ProdFunction(ComboFunc1):
necessary to explicitly create an instance of 'ProdFunction',
since the multiplication operator of the base class is overloaded
to return a 'ProdFunction' instance.
>>> f1 = Polynomial([2.0, 1.0])
>>> f2 = Polynomial([3.0, -5.0])
>>> f3 = f1 * f2 # functor to evaluate (2t + 1)*(3t - 5)
In this example, object 'f3' is a functor of class'ProdFunction'
that calls f1 and f2 and returns their product. """
def __init__(self, f1, f2):
""" f1 - first functor.
f2 - second functor.
@ -415,13 +415,13 @@ class RatioFunction(ComboFunc1):
>>> f3 = f1 / f2 # functor to evaluate (2t + 1)/(3t - 5)
In this example, object 'f3' is a functor of class'RatioFunction' that calls f1 and f2
and returns their ratio.
"""
"""
def __init__(self, f1, f2):
"""
f1 - first functor.
f2 - second functor.
"""
"""
ComboFunc1.__init__(self, 40, f1, f2)
## Function of a function.
@ -442,12 +442,12 @@ class CompositeFunction(ComboFunc1):
def __init__(self, f1, f2):
"""
f1 - first functor.
f2 - second functor.
"""
ComboFunc1.__init__(self, 60, f1, f2)
f2 - second functor.
"""
ComboFunc1.__init__(self, 60, f1, f2)
class DerivativeFunction(Func1):
def __init__(self, f):
self.f = f
@ -460,6 +460,3 @@ class DerivativeFunction(Func1):
#
def derivative(f):
return DerivativeFunction(f)

View file

@ -6,10 +6,10 @@ from SurfacePhase import SurfacePhase, EdgePhase
from Kinetics import Kinetics
import XML
class Interface(SurfacePhase, Kinetics):
class Interface(SurfacePhase, Kinetics):
"""
Two-dimensional interfaces.
Instances of class Interface represent reacting 2D interfaces
between bulk 3D phases. Class Interface defines no methods of its
own. All of its methods derive from either SurfacePhase or Kinetics.
@ -43,9 +43,9 @@ class Interface(SurfacePhase, Kinetics):
fn = src.split('#')
id = ""
if len(fn) > 1:
id = fn[1]
id = fn[1]
fn = fn[0]
# read in the root element of the tree if not building from
# an already-built XML tree. Enable preprocessing if the film
# is a .cti file instead of XML.
@ -60,9 +60,9 @@ class Interface(SurfacePhase, Kinetics):
# otherwise, find the first element with tag name 'phase'
# (both 2D and 3D phases use the CTML tag name 'phase'
else:
s = root.child(name = "phase")
s = root.child(name = "phase")
# build the surface phase
# build the surface phase
SurfacePhase.__init__(self, xml_phase=s)
# build the reaction mechanism. This object (representing the
@ -74,4 +74,3 @@ class Interface(SurfacePhase, Kinetics):
"""Delete the Interface instance."""
Kinetics.__del__(self)
SurfacePhase.__del__(self)

View file

@ -16,14 +16,14 @@ class Kinetics:
parameters -
kintype - integer specifying the type of kinetics manager to create.
"""
def __init__(self, kintype=-1, thrm=0, xml_phase=None, id=None, phases=[]):
"""Build a kinetics manager from an XML specification.
root -- root of a CTML tree
id -- id of the 'kinetics' node within the tree that contains
the specification of the parameters.
"""
@ -55,15 +55,15 @@ class Kinetics:
self._np = self.nPhases()
for nn in range(self._np):
p = 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))
p = 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()
def clear(self):
"""Delete the kinetics manager."""
if self.ckin > 0:
@ -75,7 +75,7 @@ class Kinetics:
def kinetics_hndl(self):
return self.ckin
def kineticsType(self):
"""Kinetics manager type."""
return _cantera.kin_type(self.ckin)
@ -107,11 +107,11 @@ class Kinetics:
def reactionPhaseIndex(self):
"""The phase in which the reactions take place."""
return _cantera.kin_reactionPhaseIndex(self)
def phase(self, n):
"""Return an object representing the nth phase."""
return ThermoPhase(index = _cantera.kin_phase(self.ckin, n))
def nReactions(self):
"""Number of reactions."""
return _cantera.kin_nreactions(self.ckin)
@ -162,16 +162,16 @@ class Kinetics:
if nup <> 1.0:
if nup <> round(nup):
s += str(nup)+' '
else:
else:
s += `int(nup)`+' '
s += self._sp[k]+' + '
s = s[:-2]
return s
def reactantStoichCoeff(self,k,i):
"""The stoichiometric coefficient of species k as a reactant in reaction i."""
return _cantera.kin_rstoichcoeff(self.ckin,k,i)
def reactantStoichCoeffs(self):
"""The array of reactant stoichiometric coefficients. Element
[k,i] of this array is the reactant stoichiometric
@ -186,12 +186,12 @@ class Kinetics:
def productStoichCoeff(self,k,i):
"""The stoichiometric coefficient of species k as a product in reaction i."""
return _cantera.kin_pstoichcoeff(self.ckin,k,i)
return _cantera.kin_pstoichcoeff(self.ckin,k,i)
def productStoichCoeffs(self):
"""The array of product stoichiometric coefficients. Element
[k,i] of this array is the product stoichiometric
coefficient of species k in reaction i."""
coefficient of species k in reaction i."""
nsp = _cantera.kin_nspecies(self.ckin)
nr = _cantera.kin_nreactions(self.ckin)
nu = zeros((nsp,nr),'d')
@ -199,7 +199,7 @@ class Kinetics:
for k in range(nsp):
nu[k,i] = _cantera.kin_pstoichcoeff(self.ckin,k,i)
return nu
def fwdRatesOfProgress(self):
"""Forward rates of progress of the reactions."""
return _cantera.kin_getarray(self.ckin,10)
@ -230,7 +230,7 @@ class Kinetics:
return _cantera.kin_getarray(self.ckin,35)
else:
return _cantera.kin_getarray(self.ckin,36)
def creationRates(self, phase = None):
c = _cantera.kin_getarray(self.ckin,50)
if phase:
@ -241,13 +241,13 @@ class Kinetics:
else:
raise CanteraError('unknown phase')
else:
return c
return c
def destructionRates(self, phase = None):
d = _cantera.kin_getarray(self.ckin,60)
if phase:
kp = phase.thermophase()
kp = phase.thermophase()
if self._phnum.has_key(kp):
n = self._phnum[kp]
return d[self._end[n]:self._end[n+1]]
@ -256,11 +256,11 @@ class Kinetics:
else:
return d
def netProductionRates(self, phase = None):
w = _cantera.kin_getarray(self.ckin,70)
w = _cantera.kin_getarray(self.ckin,70)
if phase:
kp = phase.thermophase()
kp = phase.thermophase()
if self._phnum.has_key(kp):
n = self._phnum[kp]
return w[self._end[n]:self._end[n+1]]
@ -268,28 +268,28 @@ class Kinetics:
raise CanteraError('unknown phase')
else:
return w
def sourceTerms(self):
return _cantera.kin_getarray(self.ckin,80)
return _cantera.kin_getarray(self.ckin,80)
def delta_H(self):
return _cantera.kin_getarray(self.ckin,90)
def delta_G(self):
return _cantera.kin_getarray(self.ckin,91)
def delta_S(self):
return _cantera.kin_getarray(self.ckin,92)
return _cantera.kin_getarray(self.ckin,92)
def delta_H0(self):
return _cantera.kin_getarray(self.ckin,93)
def delta_G0(self):
return _cantera.kin_getarray(self.ckin,94)
return _cantera.kin_getarray(self.ckin,94)
def delta_S0(self):
return _cantera.kin_getarray(self.ckin,95)
def multiplier(self,i):
return _cantera.kin_multiplier(self.ckin,i)
@ -299,19 +299,7 @@ class Kinetics:
for i in range(nr):
_cantera.kin_setMultiplier(self.ckin,i,value)
else:
_cantera.kin_setMultiplier(self.ckin,reaction,value)
_cantera.kin_setMultiplier(self.ckin,reaction,value)
def advanceCoverages(self,dt):
return _cantera.kin_advanceCoverages(self.ckin,dt)
return _cantera.kin_advanceCoverages(self.ckin,dt)

View file

@ -3,7 +3,7 @@ from Cantera.num import array, zeros
class BurnerDiffFlame(Stack):
"""A burner-stabilized flat flame."""
def __init__(self, gas = None, burner = None, outlet = None, grid = None):
"""
gas -- object to use to evaluate all gas properties and reaction
@ -18,7 +18,7 @@ class BurnerDiffFlame(Stack):
represent the flame. The three domains comprising the stack
are stored as self.burner, self.flame, and self.outlet.
"""
if burner:
self.burner = burner
else:
@ -44,7 +44,7 @@ class BurnerDiffFlame(Stack):
in the first 20% of the flame to Tad, then is flat. The mass
fraction profiles are set similarly.
"""
self.getInitialSoln()
self.getInitialSoln()
gas = self.gas
nsp = gas.nSpecies()
yin = zeros(nsp, 'd')
@ -53,7 +53,7 @@ class BurnerDiffFlame(Stack):
gas.setState_TPY(self.burner.temperature(), self.pressure, yin)
u0 = self.burner.mdot()/gas.density()
t0 = self.burner.temperature()
# get adiabatic flame temperature and composition
gas.equilibrate('HP')
teq = gas.temperature()
@ -99,24 +99,24 @@ class BurnerDiffFlame(Stack):
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)
"""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)
"""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)
else: return self.profile(self.flame, component)
def setGasState(self, j):
"""Set the state of the object representing the gas to the
@ -127,8 +127,3 @@ class BurnerDiffFlame(Stack):
nm = self.gas.speciesName(n)
y[n] = self.solution(nm, j)
self.gas.setState_TPY(self.T(j), self.pressure, y)

View file

@ -3,7 +3,7 @@ from Cantera.num import array, zeros
class BurnerFlame(Stack):
"""A burner-stabilized flat flame."""
def __init__(self, gas = None, burner = None, outlet = None, grid = None):
"""
gas -- object to use to evaluate all gas properties and reaction
@ -18,7 +18,7 @@ class BurnerFlame(Stack):
represent the flame. The three domains comprising the stack
are stored as self.burner, self.flame, and self.outlet.
"""
if burner:
self.burner = burner
else:
@ -44,7 +44,7 @@ class BurnerFlame(Stack):
in the first 20% of the flame to Tad, then is flat. The mass
fraction profiles are set similarly.
"""
self.getInitialSoln()
self.getInitialSoln()
gas = self.gas
nsp = gas.nSpecies()
yin = zeros(nsp, 'd')
@ -53,7 +53,7 @@ class BurnerFlame(Stack):
gas.setState_TPY(self.burner.temperature(), self.pressure, yin)
u0 = self.burner.mdot()/gas.density()
t0 = self.burner.temperature()
# get adiabatic flame temperature and composition
gas.equilibrate('HP',solver=1)
teq = gas.temperature()
@ -99,24 +99,24 @@ class BurnerFlame(Stack):
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)
"""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)
"""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)
else: return self.profile(self.flame, component)
def setGasState(self, j):
"""Set the state of the object representing the gas to the
@ -127,8 +127,3 @@ class BurnerFlame(Stack):
nm = self.gas.speciesName(n)
y[n] = self.solution(nm, j)
self.gas.setState_TPY(self.T(j), self.pressure, y)

View file

@ -1,7 +1,7 @@
"""A counterflow flame."""
from onedim import *
from Cantera.num import zeros
from Cantera.num import zeros
import math
def erfc(x):
@ -31,7 +31,7 @@ def erf(x):
class CounterFlame(Stack):
"""A non-premixed counterflow flame."""
def __init__(self, gas = None, grid = None):
"""The domains are [
self.fuel_inlet -- class Inlet,
@ -41,7 +41,7 @@ class CounterFlame(Stack):
"""
self.fuel_inlet = Inlet('fuel inlet')
self.oxidizer_inlet = Inlet('oxidizer inlet')
self.oxidizer_inlet = Inlet('oxidizer inlet')
self.gas = gas
self.fuel_inlet.set(temperature = gas.temperature())
self.oxidizer_inlet.set(temperature = gas.temperature())
@ -62,7 +62,7 @@ class CounterFlame(Stack):
The initial guess is generated by assuming infinitely-fast
chemistry."""
self.getInitialSoln()
self.getInitialSoln()
gas = self.gas
nsp = gas.nSpecies()
wt = gas.molecularWeights()
@ -86,26 +86,26 @@ class CounterFlame(Stack):
y0ox = self.oxidizer_inlet.massFraction(iox)
phi = s*y0f/y0ox
zst = 1.0/(1.0 + phi)
yin_f = zeros(nsp, 'd')
yin_o = zeros(nsp, 'd')
yst = zeros(nsp, 'd')
yst = zeros(nsp, 'd')
for k in range(nsp):
yin_f[k] = self.fuel_inlet.massFraction(k)
yin_o[k] = self.oxidizer_inlet.massFraction(k)
yst[k] = zst*yin_f[k] + (1.0 - zst)*yin_o[k]
gas.setState_TPY(self.fuel_inlet.temperature(), self.pressure, yin_f)
mdotf = self.fuel_inlet.mdot()
u0f = mdotf/gas.density()
u0f = mdotf/gas.density()
t0f = self.fuel_inlet.temperature()
gas.setState_TPY(self.oxidizer_inlet.temperature(),
self.pressure, yin_o)
mdoto = self.oxidizer_inlet.mdot()
u0o = mdoto/gas.density()
t0o = self.oxidizer_inlet.temperature()
u0o = mdoto/gas.density()
t0o = self.oxidizer_inlet.temperature()
# get adiabatic flame temperature and composition
tbar = 0.5*(t0o + t0f)
gas.setState_TPY(tbar, self.pressure, yst)
@ -124,7 +124,7 @@ class CounterFlame(Stack):
nz = len(zz)
y = zeros([nz,nsp],'d')
t = zeros(nz,'d')
t = zeros(nz,'d')
for j in range(nz):
x = zz[j]
zeta = f*(x - x0)
@ -138,7 +138,7 @@ class CounterFlame(Stack):
for k in range(nsp):
y[j,k] = yin_o[k] + zmix*(yeq[k] - yin_o[k])/zst
t[j] = t0o + (teq - t0o)*zmix/zst
t[0] = t0f
t[-1] = t0o
zrel = zz/dz
@ -147,7 +147,7 @@ class CounterFlame(Stack):
self.setProfile('T', zrel, t)
for k in range(nsp):
self.setProfile(gas.speciesName(k), zrel, y[:,k])
self._initialized = 1
@ -157,7 +157,7 @@ class CounterFlame(Stack):
diagnostic output. Zero suppresses all output, and
5 produces very verbose output. Default: 1
refine_grid -- if non-zero, enable grid refinement."""
if not self._initialized: self.init()
Stack.solve(self, loglevel = loglevel, refine_grid = refine_grid)
@ -179,16 +179,16 @@ class CounterFlame(Stack):
removed. Set prune significantly smaller than
'slope' and 'curve'. Set to zero to disable pruning
the grid.
>>> f.setRefineCriteria(ratio = 5.0, slope = 0.2, curve = 0.3,
... prune = 0.03)
"""
"""
Stack.setRefineCriteria(self, domain = self.flame,
ratio = ratio, slope = slope, curve = curve,
prune = prune)
def setProfile(self, component, locs, vals):
"""Set a profile in the flame"""
"""Set a profile in the flame"""
self._initialized = 1
Stack.setProfile(self, self.flame, component, locs, vals)
@ -197,25 +197,25 @@ class CounterFlame(Stack):
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):
"""The temperature [K]"""
return self.solution('T', point)
def u(self, point = -1):
"""The axial velocity [m/s]"""
return self.solution('u', point)
return self.solution('u', point)
def V(self, point = -1):
"""The radial velocity divided by radius [s^-1]"""
return self.solution('V', point)
return self.solution('V', point)
def solution(self, component = '', point = -1):
"""The solution for one specified component. If a point number
@ -223,19 +223,14 @@ class CounterFlame(Stack):
point. Otherwise, return the entire profile for this
component."""
if point >= 0: return self.value(self.flame, component, point)
else: return self.profile(self.flame, component)
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."""
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

@ -5,7 +5,7 @@ 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
@ -16,16 +16,16 @@ class FreeFlame(Stack):
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()
@ -40,7 +40,7 @@ class FreeFlame(Stack):
in the first 20% of the flame to Tad, then is flat. The mass
fraction profiles are set similarly.
"""
self.getInitialSoln()
self.getInitialSoln()
gas = self.gas
nsp = gas.nSpecies()
yin = zeros(nsp, 'd')
@ -49,7 +49,7 @@ class FreeFlame(Stack):
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()
@ -82,7 +82,7 @@ class FreeFlame(Stack):
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
@ -100,24 +100,24 @@ class FreeFlame(Stack):
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)
"""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)
"""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)
else: return self.profile(self.flame, component)
def setGasState(self, j):
"""Set the state of the object representing the gas to the
@ -128,8 +128,3 @@ class FreeFlame(Stack):
nm = self.gas.speciesName(n)
y[n] = self.solution(nm, j)
self.gas.setState_TPY(self.T(j), self.pressure, y)

View file

@ -3,7 +3,7 @@ from Cantera.num import array, zeros
class StagnationFlow(Stack):
"""An axisymmetric flow impinging on a surface at normal incidence."""
def __init__(self, gas = None, surfchem = None, grid = None):
"""
gas -- object to use to evaluate all gas properties and reaction
@ -17,7 +17,7 @@ class StagnationFlow(Stack):
be created to represent the surface.
The three domains comprising the stack
are stored as self.inlet, self.flow, and self.surface.
"""
"""
self.inlet = Inlet('inlet')
self.gas = gas
self.surfchem = surfchem
@ -35,7 +35,7 @@ class StagnationFlow(Stack):
then the equilibrium composition at the adiabatic flame temperature
will be used to form the initial guess. Otherwise the inlet composition
will be used."""
self.getInitialSoln()
self.getInitialSoln()
gas = self.gas
nsp = gas.nSpecies()
yin = zeros(nsp, 'd')
@ -45,12 +45,12 @@ class StagnationFlow(Stack):
u0 = self.inlet.mdot()/gas.density()
t0 = self.inlet.temperature()
V0 = 0.0
tsurf = self.surface.temperature()
zz = self.flow.grid()
dz = zz[-1] - zz[0]
if products == 'equil':
gas.equilibrate('HP')
teq = gas.temperature()
@ -59,15 +59,15 @@ class StagnationFlow(Stack):
self.setProfile('T', locs, [t0, teq, teq, tsurf])
for n in range(nsp):
self.setProfile(gas.speciesName(n), locs, [yin[n], yeq[n], yeq[n], yeq[n]])
else:
else:
locs = array([0.0, 1.0],'d')
self.setProfile('T', locs, [t0, tsurf])
for n in range(nsp):
self.setProfile(gas.speciesName(n), locs, [yin[n], yin[n]])
locs = array([0.0, 1.0],'d')
locs = array([0.0, 1.0],'d')
self.setProfile('u', locs, [u0, 0.0])
self.setProfile('V', locs, [V0, V0])
self.setProfile('V', locs, [V0, V0])
self._initialized = 1
@ -78,7 +78,7 @@ class StagnationFlow(Stack):
diagnostic output. Zero suppresses all output, and
5 produces very verbose output. Default: 1
refine_grid -- if non-zero, enable grid refinement."""
if not self._initialized: self.init()
Stack.solve(self, loglevel = loglevel, refine_grid = refine_grid)
@ -100,16 +100,16 @@ class StagnationFlow(Stack):
removed. Set prune significantly smaller than
'slope' and 'curve'. Set to zero to disable pruning
the grid.
>>> f.setRefineCriteria(ratio = 5.0, slope = 0.2, curve = 0.3,
... prune = 0.03)
"""
"""
Stack.setRefineCriteria(self, domain = self.flow,
ratio = ratio, slope = slope, curve = curve,
prune = prune)
def setProfile(self, component, locs, vals):
"""Set a profile in the flame"""
"""Set a profile in the flame"""
self._initialized = 1
Stack.setProfile(self, self.flow, component, locs, vals)
@ -118,31 +118,31 @@ class StagnationFlow(Stack):
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.flow.setTolerances(default = tol)
if tol_time:
self.flow.setTolerances(default = tol_time, time = 1)
if energy:
self.flow.set(energy = energy)
def T(self, point = -1):
"""The temperature [K]"""
"""The temperature [K]"""
return self.solution('T', point)
def u(self, point = -1):
"""The axial velocity [m/s]"""
return self.solution('u', point)
"""The axial velocity [m/s]"""
return self.solution('u', point)
def V(self, point = -1):
"""The radial velocity divided by radius [s^-1]"""
return self.solution('V', point)
"""The radial velocity divided by radius [s^-1]"""
return self.solution('V', point)
def solution(self, component = '', point = -1):
"""The solution for one specified component. If a point number
is given, return the value of component 'component' at this
point. Otherwise, return the entire profile for this
component."""
component."""
if point >= 0: return self.value(self.flow, component, point)
else: return self.profile(self.flow, component)
@ -157,15 +157,10 @@ class StagnationFlow(Stack):
def setGasState(self, j):
"""Set the state of the object representing the gas to the
current solution at grid point j."""
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

@ -6,5 +6,3 @@ from BurnerFlame import BurnerFlame
from BurnerDiffFlame import BurnerDiffFlame
from CounterFlame import CounterFlame
from StagnationFlow import StagnationFlow

View file

@ -6,26 +6,26 @@ _onoff = {'on':1, 'yes':1, 'off':0, 'no':0, 1:1, 0:0}
class Domain1D:
"""Base class for one-dimensional domains."""
def __init__(self):
self._hndl = 0
def __del__(self):
_cantera.domain_del(self._hndl)
def domain_hndl(self):
"""Integer used to reference the kernel object."""
return self._hndl
def type(self):
"""Domain type. Integer."""
return _cantera.domain_type(self._hndl)
def index(self):
"""Index of this domain in a stack. Returns -1 if this domain
is not part of a stack."""
return _cantera.domain_index(self._hndl)
def nComponents(self):
"""Number of solution components at each grid point."""
return _cantera.domain_nComponents(self._hndl)
@ -44,12 +44,12 @@ class Domain1D:
for n in range(self.nComponents()):
names.append(self.componentName(n))
return names
def componentIndex(self, name):
"""Index of the component with name 'name'"""
return _cantera.domain_componentIndex(self._hndl, name)
def setBounds(self, **bounds):
def setBounds(self, **bounds):
"""Set the lower and upper bounds on the solution.
The argument list should consist of keyword/value pairs, with
@ -62,13 +62,13 @@ class Domain1D:
>>> d.setBounds(default = (0, 1),
... Y = (-1.0e-5, 2.0))
"""
d = {}
if bounds.has_key('default'):
for n in range(self.nComponents()):
d[self.componentName(n)] = bounds['default']
del bounds['default']
for b in bounds.keys():
if b == 'Y':
if self.type >= 50:
@ -88,7 +88,7 @@ class Domain1D:
>>> d.bounds('T')
(200.0, 5000.0)
"""
ic = self.componentIndex(component)
lower = _cantera.domain_lowerBound(self._hndl, ic)
upper = _cantera.domain_upperBound(self._hndl, ic)
@ -97,20 +97,20 @@ class Domain1D:
def tolerances(self, component):
"""Return the (relative, absolute) error tolerances for
a solution component.
(r, a) = d.tolerances('u')
"""
ic = self.componentIndex(component)
r = _cantera.domain_rtol(self._hndl, ic)
a = _cantera.domain_atol(self._hndl, ic)
a = _cantera.domain_atol(self._hndl, ic)
return (r, a)
def setTolerances(self, **tol):
"""Set the error tolerances. If 'time' is present and
non-zero, then the values entered will apply to the transient
problem. Otherwise, they will apply to the steady-state
problem.
problem.
The argument list should consist of keyword/value pairs, with
component names as keywords and (rtol, atol) tuples as the
@ -122,13 +122,13 @@ class Domain1D:
default = (1.0e-7, 1.0e-12),
time = 1)
"""
d = {}
if tol.has_key('default'):
for n in range(self.nComponents()):
d[self.componentName(n)] = tol['default']
del tol['default']
itime = 0
for b in tol.keys():
if b == 'time': itime = -1
@ -147,22 +147,22 @@ class Domain1D:
# print 'setting tol for ',b,' itime = ',itime
_cantera.domain_setTolerances(self._hndl, n, d[b][0], d[b][1], itime)
def setupGrid(self, grid):
"""Specify the grid.
d.setupGrid([0.0, 0.1, 0.2])
"""
return _cantera.domain_setupGrid(self._hndl, asarray(grid))
def setID(self, id):
return _cantera.domain_setID(self._hndl, id)
def setDesc(self, desc):
"""Set the description of this domain."""
return _cantera.domain_setDesc(self._hndl, desc)
def grid(self, n = -1):
""" If n >= 0, return the value of the nth grid point
from the left in this domain. If n is not supplied, return
@ -191,7 +191,7 @@ class Domain1D:
"""
self._set(options)
def _set(self, options):
for opt in options.keys():
v = options[opt]
@ -212,14 +212,14 @@ class Domain1D:
def _dict2arrays(self, d = None, array1 = None, array2 = None):
nc = self.nComponents()
if d.has_key('default'):
a1 = zeros(nc,'d') + d['default'][0]
a1 = zeros(nc,'d') + d['default'][0]
a2 = zeros(nc,'d') + d['default'][1]
del d['default']
else:
if array1: a1 = array(array1)
else: a1 = zeros(nc,'d')
if array2: a2 = array(array2)
else: a2 = zeros(nc,'d')
else: a2 = zeros(nc,'d')
for k in d.keys():
c = self.componentIndex(k)
@ -229,19 +229,19 @@ class Domain1D:
else:
raise CanteraError('unknown component '+k)
return (a1, a2)
class Bdry1D(Domain1D):
"""Base class for boundary domains."""
def __init__(self):
Domain1D.__init__(self)
def setMdot(self, mdot):
"""Set the mass flow rate per unit area [kg/m2]."""
_cantera.bdry_setMdot(self._hndl, mdot)
def setTemperature(self, t):
"""Set the temperature [K]"""
_cantera.bdry_setTemperature(self._hndl, t)
@ -276,10 +276,10 @@ class Bdry1D(Domain1D):
del options[opt]
elif opt == 'temperature' or opt == 'T':
self.setTemperature(v)
del options[opt]
del options[opt]
elif opt == 'mole_fractions' or opt == 'X':
self.setMoleFractions(v)
del options[opt]
del options[opt]
self._set(options)
@ -292,41 +292,41 @@ class Inlet(Bdry1D):
Bdry1D.__init__(self)
self._hndl = _cantera.inlet_new()
if id: self.setID(id)
def setSpreadRate(self, V0 = 0.0):
"""Set the spead rate, defined as the value of V = v/r at the inlet."""
_cantera.inlet_setSpreadRate(self._hndl, V0)
class Outlet(Bdry1D):
"""A one-dimensional outlet. An outlet imposes a
zero-gradient boundary condition on the flow."""
def __init__(self, id = 'outlet'):
Bdry1D.__init__(self)
Bdry1D.__init__(self)
self._hndl = _cantera.outlet_new()
if id: self.setID(id)
if id: self.setID(id)
class OutletRes(Bdry1D):
"""A one-dimensional outlet into a reservoir."""
def __init__(self, id = 'outletres'):
Bdry1D.__init__(self)
self._hndl = _cantera.outletres_new()
if id: self.setID(id)
def __init__(self, id = 'outletres'):
Bdry1D.__init__(self)
self._hndl = _cantera.outletres_new()
if id: self.setID(id)
class SymmPlane(Bdry1D):
"""A symmetry plane."""
def __init__(self, id = 'symmetry_plane'):
Bdry1D.__init__(self)
Bdry1D.__init__(self)
self._hndl = _cantera.symm_new()
if id: self.setID(id)
if id: self.setID(id)
class Surface(Bdry1D):
"""A surface (possibly reacting)."""
def __init__(self, id = 'surface', surface_mech = None):
Bdry1D.__init__(self)
Bdry1D.__init__(self)
if surface_mech:
self._hndl = _cantera.reactingsurf_new()
self.setKineticsMgr(surface_mech)
@ -339,7 +339,7 @@ class Surface(Bdry1D):
"""Set the kinetics manager (surface reaction mechanism object)."""
_cantera.reactingsurf_setkineticsmgr(self._hndl,
kin.kinetics_hndl())
def setCoverageEqs(self, onoff='on'):
"""Turn solving the surface coverage equations on or off."""
if onoff == 'on':
@ -347,19 +347,19 @@ class Surface(Bdry1D):
else:
_cantera.reactingsurf_enableCoverageEqs(self._hndl, 0)
class AxisymmetricFlow(Domain1D):
"""An axisymmetric flow domain.
In an axisymmetric flow domain, the equations solved are the
similarity equations for the flow in a finite-height gap of
infinite radial extent. The solution variables are
u -- axial velocity
u -- axial velocity
V -- radial velocity divided by radius
T -- temperature
lambda -- (1/r)(dP/dr)
Y_k -- species mass fractions
It may be shown that if the boundary conditions on these variables
are independent of radius, then a similarity solution to the exact
governing equations exists in which these variables are all
@ -382,7 +382,7 @@ class AxisymmetricFlow(Domain1D):
self._p = -1.0
self.setPressure(gas.pressure())
self.solveEnergyEqn()
def setPressure(self, p):
"""Set the pressure [Pa]. The pressure is a constant, since
the governing equations are those for the low-Mach-number limit."""
@ -404,20 +404,20 @@ class AxisymmetricFlow(Domain1D):
def pressure(self):
"""Pressure [Pa]."""
return self._p
def setFixedTempProfile(self, pos, temp):
"""Set the fixed temperature profile. This profile is used
whenever the energy equation is disabled.
whenever the energy equation is disabled.
pos - arrray of relative positions from 0 to 1
temp - array of temperature values
>>> d.setFixedTempProfile(array([0.0, 0.5, 1.0]),
... array([500.0, 1500.0, 2000.0])
"""
return _cantera.stflow_setFixedTempProfile(self._hndl, pos, temp)
def solveSpeciesEqs(self, flag = 1):
"""Enable or disable solving the species equations. If invoked
with no arguments or with a non-zero argument, the species
@ -426,14 +426,14 @@ class AxisymmetricFlow(Domain1D):
held at their initial values. Default: species equations
enabled."""
return _cantera.stflow_solveSpeciesEqs(self._hndl, _onoff[flag])
def solveEnergyEqn(self, flag = 1):
"""Enable or disable solving the energy equation. If invoked
with no arguments or with a non-zero argument, the energy
equations will be solved. If invoked with a zero argument,
it will not be, and instead the temperature profiles will be
held to the one specified by the call to setFixedTempProfile.
Default: energy equation enabled."""
Default: energy equation enabled."""
return _cantera.stflow_solveEnergyEqn(self._hndl, _onoff[flag])
def set(self, **opt):
@ -453,13 +453,13 @@ class AxisymmetricFlow(Domain1D):
self.solveEnergyEqn(flag = _onoff[v])
else:
self._set(opt)
class Stack:
""" Class Stack is a container for one-dimensional domains. It
also holds the multi-domain solution vector, and controls the
process of finding the solution.
process of finding the solution.
Domains are ordered left-to-right, with domain number 0 at the left.
@ -473,7 +473,7 @@ class Stack:
hndls[n] = domains[n].domain_hndl()
self._hndl = _cantera.sim1D_new(hndls)
self._domains = domains
def __del__(self):
_cantera.sim1D_del(self._hndl)
@ -492,9 +492,9 @@ class Stack:
idom = dom.domain_hndl()
_cantera.sim1D_setValue(self._hndl, idom,
comp, localPoint, value)
def setProfile(self, dom, comp, pos, v):
"""Set an initial estimate for a profile of one component in
one domain.
@ -505,14 +505,14 @@ class Stack:
v -- sequence of values at the relative positions specified in 'pos'
>>> s.setProfile(d, 'T', [0.0, 0.2, 1.0], [400.0, 800.0, 1500.0])
"""
idom = dom.index()
icomp = dom.componentIndex(comp)
_cantera.sim1D_setProfile(self._hndl, idom, icomp,
asarray(pos), asarray(v))
def setFlatProfile(self, dom, comp, v):
"""Set a flat profile for one component in one domain.
dom -- domain object
@ -523,9 +523,9 @@ class Stack:
"""
idom = dom.index()
icomp = dom.componentIndex(comp)
icomp = dom.componentIndex(comp)
_cantera.sim1D_setFlatProfile(self._hndl, idom, icomp, v)
def showSolution(self, fname='-'):
"""Show the current solution. If called with no argument,
the solution is printed to the screen. If a filename is
@ -536,7 +536,7 @@ class Stack:
"""
_cantera.sim1D_showSolution(self._hndl, fname)
def setTimeStep(self, stepsize, nsteps):
"""Set the sequence of time steps to try when Newton fails.
@ -551,26 +551,26 @@ class Stack:
# type double. This needs to be checked out further.
# Probably a function of python version and Numerics version
_cantera.sim1D_setTimeStep(self._hndl, stepsize, asarray(nsteps))
def getInitialSoln(self):
"""Load the initial solution from each domain into the global
solution vector."""
_cantera.sim1D_getInitialSoln(self._hndl)
def solve(self, loglevel=1, refine_grid=1):
"""Solve the problem.
loglevel -- integer flag controlling the amount of
diagnostic output. Zero suppresses all output, and
5 produces very verbose output. Default: 1
refine_grid -- if non-zero, enable grid refinement."""
return _cantera.sim1D_solve(self._hndl, loglevel, refine_grid)
def refine(self, loglevel=1):
"""Refine the grid, adding points where solution is not
adequately resolved."""
return _cantera.sim1D_refine(self._hndl, loglevel)
def setRefineCriteria(self, domain = None, ratio = 10.0, slope = 0.8,
curve = 0.8, prune = 0.05):
"""Set the criteria used to refine one domain.
@ -589,7 +589,7 @@ class Stack:
removed. Set prune significantly smaller than
'slope' and 'curve'. Set to zero to disable pruning
the grid.
>>> s.setRefineCriteria(d, ratio = 5.0, slope = 0.2, curve = 0.3,
... prune = 0.03)
"""
@ -601,10 +601,10 @@ class Stack:
>>> s.save(file = 'save.xml', id = 'energy_off',
... desc = 'solution with energy eqn. disabled')
"""
return _cantera.sim1D_save(self._hndl, file, id, desc)
def restore(self, file = 'soln.xml', id = 'solution'):
"""Set the solution vector to a previously-saved solution.
@ -662,15 +662,15 @@ class Stack:
>>> t = s.value(flow, 'T', 6)
"""
idom = dom.index()
"""
idom = dom.index()
return _cantera.sim1D_workValue(self._hndl, idom, icomp, localPoint)
def eval(self, rdt, count=1):
"""Evaluate the residual function. If count = 0, do is 'silently',
without adding to the function evaluation counter"""
return _cantera.sim1D_eval(self._hndl, rdt, count)
def setMaxJacAge(self, ss_age, ts_age):
"""Set the maximum number of times the Jacobian will be used
before it must be re-evaluated.
@ -678,7 +678,7 @@ class Stack:
ts_age -- age criterion during time-stepping mode
"""
return _cantera.sim1D_setMaxJacAge(self._hndl, ss_age, ts_age)
def timeStepFactor(self, tfactor):
"""Set the factor by which the time step will be increased
after a successful step, or decreased after an unsuccessful one.
@ -686,7 +686,7 @@ class Stack:
s.timeStepFactor(3.0)
"""
return _cantera.sim1D_timeStepFactor(self._hndl, tfactor)
def setTimeStepLimits(self, tsmin, tsmax):
"""Set the maximum and minimum time steps."""
return _cantera.sim1D_setTimeStepLimits(self._hndl, tsmin, tsmax)
@ -694,7 +694,7 @@ class Stack:
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

@ -17,7 +17,7 @@ def _isseq(n, x):
return 1
except:
return 0
class Phase:
"""Phases of matter.
@ -30,21 +30,21 @@ class Phase:
It does not know about the pressure, or any other thermodynamic property
requiring the equation of state -- class ThermoPhase derives from Phase
and adds those properties.
and adds those properties.
Class Phase is not usually instantiated directly. It is used as a
base class for class ThermoPhase.
"""
#def __init__(self, index = -1):
# pass
def phase_id(self):
"""The integer index used to access the kernel-level object.
Internal."""
return self._phase_id
def nElements(self):
"""Number of elements."""
return _cantera.phase_nelements(self._phase_id)
@ -66,7 +66,7 @@ class Phase:
return asarray(ae)
else:
return atw
def nSpecies(self):
"""Number of species."""
return _cantera.phase_nspecies(self._phase_id)
@ -76,7 +76,7 @@ class Phase:
The element and species may be specified by name or by number.
>>> ph.nAtoms('CH4','H')
___ 4
"""
try:
m = self.elementIndex(element)
@ -86,7 +86,7 @@ class Phase:
return na
except CanteraError:
return 0
def temperature(self):
"""Temperature [K]."""
return _cantera.phase_temperature(self._phase_id)
@ -97,7 +97,7 @@ class Phase:
def volume_mass(self):
"""Specific volume [m^3/kg]."""
return 1.0/_cantera.phase_density(self._phase_id)
return 1.0/_cantera.phase_density(self._phase_id)
def molarDensity(self):
"""Molar density [kmol/m^3]."""
@ -138,7 +138,7 @@ class Phase:
>>> ph.moleFraction('CH4')
"""
k = self.speciesIndex(species)
return _cantera.phase_molefraction(self._phase_id,k)
return _cantera.phase_molefraction(self._phase_id,k)
def massFractions(self, species = None):
@ -177,7 +177,7 @@ class Phase:
a string or an integer index. In the latter case, the index is
checked for validity and returned. If no such element is
present, an exception is thrown."""
nel = self.nElements()
if type(element) == types.IntType:
m = element
@ -189,14 +189,14 @@ class Phase:
return m
def speciesName(self,k):
"""Name of the species with index k."""
return _cantera.phase_getstring(self._phase_id,2,k)
def speciesNames(self):
"""Return a tuple of all species names."""
"""Return a tuple of all species names."""
nsp = self.nSpecies()
return map(self.speciesName,range(nsp))
@ -212,7 +212,7 @@ class Phase:
for sp in species:
s.append(self.speciesIndex(sp))
return s
if type(species) == types.IntType or type(species) == types.FloatType:
k = species
else:
@ -221,8 +221,8 @@ class Phase:
raise CanteraError("""Species """+`species`+""" not in set """
+`self.speciesNames()`)
return k
def setTemperature(self, t):
"""Set the temperature [K]."""
_cantera.phase_setfp(self._phase_id,1,t)
@ -233,8 +233,8 @@ class Phase:
def setMolarDensity(self, n):
"""Set the density [kmol/m3]."""
_cantera.phase_setfp(self._phase_id,3,n)
_cantera.phase_setfp(self._phase_id,3,n)
def setMoleFractions(self, x, norm = 1):
"""Set the mole fractions.
@ -251,12 +251,12 @@ class Phase:
"""
if type(x) == types.StringType:
_cantera.phase_setstring(self._phase_id,1,x)
elif _isseq(self.nSpecies(), x):
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.
See: setMoleFractions
@ -267,14 +267,14 @@ class Phase:
_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
fractions may be entered as a string or array,
>>> ph.setState_TRX(600.0, 2.0e-3, 'CH4:0.4, O2:0.6')
"""
self.setTemperature(t)
self.setMoleFractions(x)
self.setDensity(rho)
@ -284,23 +284,23 @@ class Phase:
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)
self.setMolarDensity(n)
def setState_TRY(self, t, rho, y):
"""Set the temperature, density, and mass fractions."""
"""Set the temperature, density, and mass fractions."""
self.setTemperature(t)
self.setMassFractions(y)
self.setDensity(rho)
self.setDensity(rho)
def setState_TR(self, t, rho):
"""Set the temperature and density, leaving the composition
unchanged."""
unchanged."""
self.setTemperature(t)
self.setDensity(rho)
def selectSpecies(self, f, species):
"""Given an array 'f' of floating-point species properties,
return an array of those values corresponding to species
@ -309,7 +309,7 @@ class Phase:
>>> f = ph.chemPotentials()
>>> muo2, muh2 = ph.selectSpecies(f, ['O2', 'H2'])
"""
if species:
fs = []
k = 0
@ -336,4 +336,3 @@ class Phase:
return asarray(fs)
else:
return asarray(f)

View file

@ -65,23 +65,23 @@ class ReactorBase:
if self._contents:
s += "\n"+`self._contents`
return s
def __repr__(self):
s = self._name
s += ':\n Volume = '+`self.volume()`
s += ':\n Volume = '+`self.volume()`
if self._contents:
s += ": \n"+`self._contents`
return s
def name(self):
"""The name of the reactor."""
return self._name
def reactor_id(self):
"""The integer index used to access the kernel reactor
object. For internal use."""
return self.__reactor_id
def insert(self, contents):
"""
Insert 'contents' into the reactor. Sets the objects used to compute
@ -94,7 +94,7 @@ class ReactorBase:
_cantera.reactor_setThermoMgr(self.__reactor_id, contents._phase_id)
_cantera.reactor_setKineticsMgr(self.__reactor_id, contents.ckin)
def setInitialTime(self, T0):
"""Deprecated.
Set the initial time. Restarts integration from this time
@ -118,7 +118,7 @@ class ReactorBase:
if ie:
print 'enabling energy equation for reactor',self._name
else:
print 'disabling energy equation for reactor',self._name
print 'disabling energy equation for reactor',self._name
_cantera.reactor_setEnergy(self.__reactor_id, ie)
def temperature(self):
@ -132,7 +132,7 @@ class ReactorBase:
def volume(self):
"""The total reactor volume [m^3]. The volume may change with time
if non-rigid walls are installed on the reactor."""
return _cantera.reactor_volume(self.__reactor_id)
return _cantera.reactor_volume(self.__reactor_id)
def time(self):
"""Deprecated. The current time [s]."""
@ -153,7 +153,7 @@ class ReactorBase:
def pressure(self):
"""The pressure in the reactor [Pa]."""
return _cantera.reactor_pressure(self.__reactor_id)
return _cantera.reactor_pressure(self.__reactor_id)
def advance(self, time):
"""Deprecated.
@ -168,9 +168,9 @@ class ReactorBase:
Take one internal time step from the current time toward
time 'time'. Note: this method is deprecated. See class
ReactorNet."""
raise "use method step of class ReactorNet"
#return _cantera.reactor_step(self.__reactor_id, time)
raise "use method step of class ReactorNet"
#return _cantera.reactor_step(self.__reactor_id, time)
def massFraction(self, s):
"""The mass fraction of species s, specified either by name or
index number.
@ -206,14 +206,14 @@ class ReactorBase:
___0.00012
>>> x2 = r.moleFraction('CH3')
___0.00012
"""
"""
if type(s) == types.StringType:
kk = self._contents.speciesIndex(s)
else:
kk = s
x = self.moleFractions()
return x[kk]
def inlets(self):
"""Return the list of flow devices installed on inlets to this reactor.
This method can be used to access information about the flows entering
@ -221,7 +221,7 @@ class ReactorBase:
>>> for n in r.inlets():
... print n.name(), n.massFlowRate()
See: MassFlowController, Valve, PressureController.
"""
"""
return self._inlets
def outlets(self):
@ -229,7 +229,7 @@ class ReactorBase:
on this reactor.
>>> for o in r.outlets():
... print o.name(), o.massFlowRate()
See: MassFlowController, Valve, PressureController.
See: MassFlowController, Valve, PressureController.
"""
return self._outlets
@ -240,20 +240,20 @@ class ReactorBase:
See: Wall.
"""
return self._walls
def _addInlet(self, inlet, other):
"""For internal use. Store a reference to 'inlet'
so that it will not be deleted before this object."""
so that it will not be deleted before this object."""
self._inlets.append(inlet)
if self._type == 2 and other._type == 1:
self._reservoirs.append(other)
self._reservoirs.append(other)
def _addOutlet(self, outlet, other):
"""For internal use. Store a reference to 'outlet'
so that it will not be deleted before this object."""
so that it will not be deleted before this object."""
self._outlets.append(outlet)
if self._type == 2 and other._type == 1:
self._reservoirs.append(other)
self._reservoirs.append(other)
def _addWall(self, wall, other):
"""For internal use. Store a reference to 'wall'
@ -275,7 +275,7 @@ class ReactorBase:
self._contents.setState_TRY(self.temperature(),
self.density(),
self.massFractions())
def contents(self):
"""Return an object representing the reactor contents, after first
synchronizing its state with the current reactor state. This method
@ -285,7 +285,7 @@ class ReactorBase:
>>> (statements that change the state of object 'gas')
>>> c = r.contents()
>>> print c.gibbs_mole(), c.chemPotentials()
Note that after calling method 'contents', object 'c'
references the same underlying kernel object as object 'gas'
does. Therefore, all properties of 'c' and 'gas' are
@ -297,7 +297,7 @@ class ReactorBase:
"""
self.syncContents()
return self._contents
def nSensParams(self):
"""Number of sensitivity parameters for this reactor."""
@ -321,7 +321,7 @@ class ReactorBase:
return self._paramid
else:
return self._paramid[n]
_reactorcount = 0
_reservoircount = 0
@ -383,7 +383,7 @@ class FlowReactor(ReactorBase):
"""
def __init__(self, contents = None, name = '',
volume = 1.0, energy = 'on',
mdot = -1.0,
mdot = -1.0,
verbose = 0):
"""
contents - Reactor contents. If not specified, the reactor is
@ -412,11 +412,11 @@ class FlowReactor(ReactorBase):
verbose = verbose, type = 3)
if mdot > 0.0:
self.setMassFlowRate(mdot)
def setMassFlowRate(self, mdot):
_cantera.flowReactor_setMassFlowRate(self.__reactor_id, mdot)
class ConstPressureReactor(ReactorBase):
"""
"""
@ -448,7 +448,7 @@ class ConstPressureReactor(ReactorBase):
ReactorBase.__init__(self, contents = contents, name = name,
volume = volume, energy = energy,
verbose = verbose, type = 4)
class Reservoir(ReactorBase):
"""
@ -476,17 +476,17 @@ class Reservoir(ReactorBase):
>>> res1 = Reactor()
>>> res1.insert(gas)
Arguments may be specified using keywords in any order:
>>> res2 = Reservoir(contents = Air(),
>>> res2 = Reservoir(contents = Air(),
... name = 'environment')
>>> res3 = Reservoir(contents = gas, name = 'upstream_state')
"""
"""
global _reservoircount
if name == '':
name = 'Reservoir_'+`_reservoircount`
_reservoircount += 1
ReactorBase.__init__(self, contents = contents,
name = name, verbose = verbose, type = 1)
def advance(self, time):
"""Deprecated. Do nothing."""
pass
@ -515,11 +515,11 @@ class FlowDevice:
if self._verbose:
print 'deleting '+self._name
_cantera.flowdev_del(self.__fdev_id)
def name(self):
"""The name specified when initially constructed."""
return self._name
def ready(self):
"""
Deprecated. Returns true if the device is ready to use.
@ -533,7 +533,7 @@ class FlowDevice:
def install(self, upstream, downstream):
"""
Install the device between the upstream and downstream
reactors or reservoirs.
reactors or reservoirs.
>>> f.install(upstream = reactor1, downstream = reservoir2)
"""
if self._verbose:
@ -546,18 +546,18 @@ class FlowDevice:
def _setParameters(self, c):
params = array(c,'d')
n = len(params)
return _cantera.flowdev_setParameters(self.__fdev_id, n, params)
return _cantera.flowdev_setParameters(self.__fdev_id, n, params)
def setFunction(self, f):
_cantera.flowdev_setFunction(self.__fdev_id, f.func_id())
def flowdev_id(self):
return self.__fdev_id
_mfccount = 0
class MassFlowController(FlowDevice):
"""Mass flow controllers. A mass flow controller maintains a
specified mass flow rate independent of upstream and downstream
conditions. The equation used to compute the mass flow rate is
@ -567,7 +567,7 @@ class MassFlowController(FlowDevice):
a constant value or a function of time. Note that if \f$\dot m_0 <
0\f$, the mass flow rate will be set to zero, since reversal of
the flow direction is not allowed.
Unlike a real mass flow controller, a MassFlowController object
will maintain the flow even if the downstream pressure is greater
than the upstream pressure. This allows simple implementation of
@ -585,13 +585,13 @@ class MassFlowController(FlowDevice):
and downstream reactors.
Examples:
>>> mfc1 = MassFlowController(upstream = res1, downstream = reactr,
... name = 'fuel_mfc', mdot = 0.1)
>>> air_mdot = Gaussian(A = 0.1, t0 = 2.0, FWHM = 0.1)
>>> mfc2 = MassFlowController(upstream = res2, downstream = reactr,
... name = 'air_mfc', mdot = air_mdot)
"""
def __init__(self, upstream=None,
downstream=None,
@ -614,7 +614,7 @@ class MassFlowController(FlowDevice):
verbose - if set to a positive integer, additional diagnostic
information will be printed.
"""
global _mfccount
if name == '':
@ -662,10 +662,10 @@ class Valve(FlowDevice):
\dot m = F(P_1 - P_2).
\f]
if \f$ P_1 > P_2, \f$
or \f$ \dot m = 0 \f$ otherwise.
or \f$ \dot m = 0 \f$ otherwise.
It is never possible for the flow to reverse
and go from the downstream to the upstream reactor/reservoir through
a line containing a Valve object.
a line containing a Valve object.
'Valve' objects are often used between an upstream reactor and a
downstream reactor or reservoir to maintain them both at nearly the
@ -681,15 +681,15 @@ class Valve(FlowDevice):
are constant across a Valve, and the pressure difference equals
the difference in pressure between the upstream and downstream
reactors.
"""
def __init__(self, upstream=None, downstream=None,
name='', Kv = 0.0, mdot0 = 0.0, verbose=0):
"""
upstream - upstream reactor or reservoir.
downstream - downstream reactor or reservoir.
name - name used to identify the valve in output.
If no name is specified, it defaults to 'Valve_n', where n is an
integer assigned in the order the Valve object
@ -699,8 +699,8 @@ class Valve(FlowDevice):
verbose - if set to a positive integer, additional diagnostic
information will be printed.
"""
"""
global _valvecount
if name == '':
name = 'Valve_'+`_valvecount`
@ -739,7 +739,7 @@ class Valve(FlowDevice):
self.setFunction(F)
if Kv > 0.0:
self.setValveCoeff(Kv)
_pccount = 0
@ -762,9 +762,9 @@ class PressureController(FlowDevice):
name='', master = None, Kv = 0.0, verbose=0):
"""
upstream - upstream reactor or reservoir.
downstream - downstream reactor or reservoir.
name - name used to identify the pressure controller in
output. If no name is specified, it defaults to
'PressureController_n', where n is an integer assigned in the
@ -774,8 +774,8 @@ class PressureController(FlowDevice):
verbose - if set to a positive integer, additional diagnostic
information will be printed.
"""
"""
global _pccount
if name == '':
name = 'PressureController_'+`_pccount`
@ -800,15 +800,15 @@ class PressureController(FlowDevice):
"""Set the master flow controller."""
_cantera.flowdev_setMaster(self.flowdev_id(),
master.flowdev_id())
def set(self, Kv = -1.0, master = None):
if master:
self.setMaster(master)
if Kv > 0.0:
self.setPressureCoeff(Kv)
#------------- Wall ---------------------------
_wallcount = 0
@ -816,7 +816,7 @@ _wallcount = 0
class Wall:
"""
Reactor walls.
A Wall separates two reactors, or a reactor and a reservoir. A
wall has a finite area, may conduct or radiate heat between the
two reactors on either side, and may move like a piston.
@ -852,7 +852,7 @@ class Wall:
reactor the surface in question faces. The surface temperature on
each side is taken to be equal to the temperature of the reactor
it faces.
"""
def __init__(self, left, right, name = '',
A = 1.0, K = 0.0, U = 0.0,
@ -860,7 +860,7 @@ class Wall:
kinetics = [None, None]):
"""
Constructor arguments:
left - Reactor or reservoir on the left. Required.
right - Reactor or reservoir on the right. Required.
@ -898,30 +898,30 @@ class Wall:
else:
_nm = name
_wallcount += 1
if left and right:
self.install(left, right)
else:
raise CanteraError('both left and right reactors must be specified.')
self.setArea(A)
self.setExpansionRateCoeff(K)
self.setVelocity(velocity)
self.setVelocity(velocity)
self.setHeatTransferCoeff(U)
self.setHeatFlux(Q)
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
Wall. Since reactors and reserviors store references to all
Walls installed on them, this method will only be called after
the reactors/reservoirs have been deleted. """
_cantera.wall_del(self.__wall_id)
def ready(self):
"""
Return 1 if the wall instance is ready for use, 0 otherwise. Deprecated.
@ -955,8 +955,8 @@ class Wall:
Set the emissivity.
"""
_cantera.wall_setEmissivity(self.__wall_id, epsilon)
def setHeatFlux(self, qfunc):
"""
Specify the time-dependent heat flux function [W/m2].
@ -970,8 +970,8 @@ class Wall:
def setExpansionRateCoeff(self, k):
"""Set the coefficient K that determines the expansion rate
resulting from a unit pressure drop."""
_cantera.wall_setExpansionRateCoeff(self.__wall_id, k)
_cantera.wall_setExpansionRateCoeff(self.__wall_id, k)
def setVelocity(self, vfunc):
"""
Specify the velocity function [m/s]. 'vfunc' must
@ -999,7 +999,7 @@ class Wall:
def heatFlux(self):
return self.heatFlowRate()/self.area()
def install(self, left, right):
left._addWall(self, right)
right._addWall(self, left)
@ -1025,7 +1025,7 @@ class Wall:
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.
@ -1036,7 +1036,7 @@ class Wall:
elif item == 'R':
self.setThermalResistance(p[item])
elif item == 'U':
self.setHeatTransferCoeff(p[item])
self.setHeatTransferCoeff(p[item])
elif item == 'K':
self.setExpansionRateCoeff(p[item])
elif item == 'Q':
@ -1045,7 +1045,7 @@ class Wall:
self.setVelocity(p[item])
else:
raise 'unknown parameter: ',item
def addSensitivityReaction(self, side = 'unknown', reactions = []):
k = self.kinetics(side)
@ -1060,10 +1060,10 @@ class Wall:
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
simultaneously advance the state of a set of coupled reactors.
@ -1075,7 +1075,7 @@ class ReactorNet:
>>> reactor_network = ReactorNet([r1, r2])
>>> reactor_network.advance(time)
"""
@ -1102,7 +1102,7 @@ class ReactorNet:
kernel reactornet object. For internal use. """
return self.__reactornet_id
def add(self, reactor):
"""
Add a reactor to the network.
@ -1111,7 +1111,7 @@ class ReactorNet:
_cantera.reactornet_addreactor(self.__reactornet_id,
reactor.reactor_id())
def setInitialTime(self, t0):
"""Set the initial time. Restarts integration from this time
using the current state as the initial condition. Default: 0.0 s"""
@ -1126,8 +1126,8 @@ class ReactorNet:
"""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)
_cantera.reactornet_setSensitivityTolerances(self.__reactornet_id, rtolsens, atolsens)
def advance(self, time):
"""Advance the state of the reactor network in time from the current
time to time 'time'."""
@ -1136,7 +1136,7 @@ class ReactorNet:
def step(self, time):
"""Take a single internal time step toward time 'time'.
The time after taking the step is returned."""
return _cantera.reactornet_step(self.__reactornet_id, time)
return _cantera.reactornet_step(self.__reactornet_id, time)
def reactors(self):
"""Return the list of reactors in the network."""
@ -1148,7 +1148,7 @@ class ReactorNet:
for r in self._reactors:
sum += r.nSensParams()
return sum
def sensitivity(self, component = '', parameter = -1, reactor = ''):
"""Sensitivity of solution component 'component' with respect
@ -1166,9 +1166,9 @@ class ReactorNet:
reactor -- reactor containing the desired component.
"""
n = 0
if reactor <> '':
for reac in self._reactors:
@ -1188,5 +1188,3 @@ class ReactorNet:
return s
else:
raise CanteraError("sensitivity requested for illegal parameter number:"+`parameter`)

View file

@ -7,7 +7,7 @@ modified Arrhenius form, and the thermal conductivity is constant.
All parameters are user-specified, not computed from a physical model.
Examples:
>>> tr = SolidTransport(solid_phase)
>>> tr.setThermalConductivity(0.5) # W/m/K
>>> tr.setDiffCoeff(species = "OxygenIon", A = 2.0, n = 0.0, E = 700.0)
@ -30,5 +30,3 @@ class SolidTransport(Transport):
def setDiffCoeff(self, species = "", A = 0.0, n = 0.0, E = 0.0):
k = self._phase.speciesIndex(species)
self.setParameters(0, k, [A, n, E])

View file

@ -17,7 +17,7 @@ class SurfacePhase(ThermoPhase):
def siteDensity(self):
"""Site density [kmol/m2]"""
return _cantera.surf_sitedensity(self._phase_id)
def setCoverages(self, theta):
"""Set the surface coverages to the values in array 'theta'."""
nt = len(theta)

View file

@ -37,25 +37,25 @@ class ThermoPhase(Phase):
The value of 'index' is the integer index number to reference the
existing kernel object.
"""
self._phase_id = 0
self._owner = 0
self.idtag = ""
if index >= 0:
# create a Python wrapper for an existing kernel
# ThermoPhase instance
# ThermoPhase instance
self._phase_id = index
elif xml_phase:
# create a new kernel instance from an XML specification
self._phase_id = _cantera.ThermoFromXML(xml_phase._xml_id)
self.idtag = xml_phase["id"]
self._owner = 1
else:
raise CanteraError('either xml_phase or index must be specified')
def __del__(self):
"""Delete the object. If it is the owner of the kernel object,
@ -73,7 +73,7 @@ class ThermoPhase(Phase):
def setName(self, name):
""" Set the name attribute. This can be any string"""
self.idtag = name
def refPressure(self):
"""Reference pressure [Pa].
All standard-state thermodynamic properties are for this pressure.
@ -90,7 +90,7 @@ class ThermoPhase(Phase):
return _cantera.thermo_mintemp(self._phase_id, -1)
else:
return _cantera.thermo_mintemp(self._phase_id,
self.speciesIndex(sp))
self.speciesIndex(sp))
def maxTemp(self, sp=None):
""" Maximum temperature for which thermodynamic property fits
@ -102,7 +102,7 @@ class ThermoPhase(Phase):
return _cantera.thermo_maxtemp(self._phase_id, -1)
else:
return _cantera.thermo_maxtemp(self._phase_id,
self.speciesIndex(sp))
self.speciesIndex(sp))
def enthalpy_mole(self):
""" The molar enthalpy [J/kmol]."""
@ -110,7 +110,7 @@ class ThermoPhase(Phase):
def intEnergy_mole(self):
""" The molar internal energy [J/kmol]."""
return _cantera.thermo_getfp(self._phase_id,2)
return _cantera.thermo_getfp(self._phase_id,2)
def entropy_mole(self):
""" The molar entropy [J/kmol/K]."""
@ -119,7 +119,7 @@ class ThermoPhase(Phase):
def gibbs_mole(self):
""" The molar Gibbs function [J/kmol]."""
return _cantera.thermo_getfp(self._phase_id,4)
def cp_mole(self):
""" The molar heat capacity at constant pressure [J/kmol/K]."""
return _cantera.thermo_getfp(self._phase_id,5)
@ -130,15 +130,15 @@ class ThermoPhase(Phase):
def pressure(self):
""" The pressure [Pa]."""
return _cantera.thermo_getfp(self._phase_id,7)
return _cantera.thermo_getfp(self._phase_id,7)
def electricPotential(self):
"""Electric potential [V]."""
return _cantera.thermo_getfp(self._phase_id,25)
def chemPotentials(self, species = []):
"""Species chemical potentials.
This method returns an array containing the species
chemical potentials [J/kmol]. The expressions used to
compute these depend on the model implemented by the
@ -148,19 +148,19 @@ class ThermoPhase(Phase):
def elementPotentials(self, elements = []):
"""Element potentials of the elements.
This method returns an array containing the element potentials
[J/kmol]. The element potentials are only defined for
equilibrium states. This method first sets the composition to
a state of equilibrium holding T and P constant, then computes
the element potentials for this equilibrium state. """
lamb = _cantera.thermo_getarray(self._phase_id,21)
return self.selectElements(lamb, elements)
def enthalpies_RT(self, species = []):
"""Pure species non-dimensional reference state enthalpies.
This method returns an array containing the pure-species
standard-state enthalpies divided by RT. For gaseous species,
these values are ideal gas enthalpies."""
@ -169,7 +169,7 @@ class ThermoPhase(Phase):
def entropies_R(self, species = []):
"""Pure species non-dimensional entropies.
This method returns an array containing the pure-species
standard-state entropies divided by R. For gaseous species,
these values are ideal gas entropies."""
@ -178,24 +178,24 @@ class ThermoPhase(Phase):
def gibbs_RT(self, species = []):
"""Pure species non-dimensional Gibbs free energies.
This method returns an array containing the pure-species
standard-state Gibbs free energies divided by R.
For gaseous species, these are ideal gas values."""
For gaseous species, these are ideal gas values."""
grt = (_cantera.thermo_getarray(self._phase_id,23)
- _cantera.thermo_getarray(self._phase_id,24))
return self.selectSpecies(grt, species)
def cp_R(self, species = []):
"""Pure species non-dimensional heat capacities
at constant pressure.
This method returns an array containing the pure-species
standard-state heat capacities divided by R. For gaseous
species, these values are ideal gas heat capacities."""
cpr = _cantera.thermo_getarray(self._phase_id,25)
return self.selectSpecies(cpr, species)
def setPressure(self, p):
"""Set the pressure [Pa]."""
@ -203,27 +203,27 @@ class ThermoPhase(Phase):
def enthalpy_mass(self):
"""Specific enthalpy [J/kg]."""
return _cantera.thermo_getfp(self._phase_id,8)
return _cantera.thermo_getfp(self._phase_id,8)
def intEnergy_mass(self):
"""Specific internal energy [J/kg]."""
return _cantera.thermo_getfp(self._phase_id,9)
return _cantera.thermo_getfp(self._phase_id,9)
def entropy_mass(self):
"""Specific entropy [J/kg/K]."""
return _cantera.thermo_getfp(self._phase_id,10)
return _cantera.thermo_getfp(self._phase_id,10)
def gibbs_mass(self):
"""Specific Gibbs free energy [J/kg]."""
return _cantera.thermo_getfp(self._phase_id,11)
return _cantera.thermo_getfp(self._phase_id,11)
def cp_mass(self):
"""Specific heat at constant pressure [J/kg/K]."""
return _cantera.thermo_getfp(self._phase_id,12)
return _cantera.thermo_getfp(self._phase_id,12)
def cv_mass(self):
"""Specific heat at constant volume [J/kg/K]."""
return _cantera.thermo_getfp(self._phase_id,13)
"""Specific heat at constant volume [J/kg/K]."""
return _cantera.thermo_getfp(self._phase_id,13)
def setState_TPX(self, t, p, x):
"""Set the temperature [K], pressure [Pa], and
@ -234,23 +234,23 @@ class ThermoPhase(Phase):
def setState_TPY(self, t, p, y):
"""Set the temperature [K], pressure [Pa], and
mass fractions."""
mass fractions."""
self.setTemperature(t)
self.setMassFractions(y)
self.setPressure(p)
def setState_TP(self, t, p):
"""Set the temperature [K] and pressure [Pa]."""
"""Set the temperature [K] and pressure [Pa]."""
self.setTemperature(t)
self.setPressure(p)
def setState_PX(self, p, x):
"""Set the pressure [Pa], and mole fractions."""
"""Set the pressure [Pa], and mole fractions."""
self.setMoleFractions(x)
self.setPressure(p)
def setState_PY(self, p, y):
"""Set the pressure [Pa], and mass fractions."""
"""Set the pressure [Pa], and mass fractions."""
self.setMassFractions(y)
self.setPressure(p)
@ -262,54 +262,54 @@ class ThermoPhase(Phase):
def setState_UV(self, u, v):
"""Set the state by specifying the specific internal
energy and the specific volume."""
_cantera.thermo_setfp(self._phase_id, 3, u, v)
_cantera.thermo_setfp(self._phase_id, 3, u, v)
def setState_SV(self, s, v):
"""Set the state by specifying the specific entropy
and the specific volume."""
_cantera.thermo_setfp(self._phase_id, 4, s, v)
def setState_SP(self, s, p):
"""Set the state by specifying the specific entropy
energy and the pressure."""
_cantera.thermo_setfp(self._phase_id, 5, s, p)
energy and the pressure."""
_cantera.thermo_setfp(self._phase_id, 5, s, p)
def setElectricPotential(self, v):
"""Set the electric potential."""
_cantera.thermo_setfp(self._phase_id, 6, v, 0);
def equilibrate(self, XY, solver = -1, rtol = 1.0e-9,
maxsteps = 1000, maxiter = 100, loglevel = 0):
""" Set to a state of chemical equilibrium holding property pair
'XY' constant.
XY --- A two-letter string, which must be one of the set
['TP','TV','HP','SP','SV','UV','PT','VT','PH','PS','VS','VU'].
If H, U, S, or V is specified, the value must be the specific
value (per unit mass)
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
unspecified, the fast solver will be tried first, then if it
fails the other will be tried.
rtol -- the relative error tolerance.
maxsteps -- maximum number of steps in composition to take to
find a converged solution.
maxiter -- for the Gibbs minimization solver only, this
specifies the number of 'outer' iterations on T or P when some
property pair other than TP is specified.
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.
"""
_cantera.thermo_equil(self._phase_id, XY, solver,
rtol, maxsteps, maxiter, loglevel)
@ -326,7 +326,7 @@ class ThermoPhase(Phase):
def restoreState(self, s):
"""Restore the state to that stored in array s."""
self.setState_TRY(s[0], s[1], s[2:])
def thermophase(self):
"""Return the integer index that is used to
reference the kernel object. For internal use."""
@ -334,12 +334,5 @@ class ThermoPhase(Phase):
def thermo_hndl(self):
"""Return the integer index that is used to
reference the kernel object. For internal use."""
reference the kernel object. For internal use."""
return self._phase_id

View file

@ -40,7 +40,7 @@ class Transport:
managers may be installed in one Python transport manager,
although only one is active at any one time. This feature allows
switching between transport models."""
def __init__(self, xml_phase=None,
phase=None, model = "", loglevel=0):
"""Create a transport property manager.
@ -63,13 +63,13 @@ class Transport:
self.model = ""
else:
self.model = model
self.__tr_id = 0
self.__tr_id = _cantera.Transport(self.model,
phase._phase_id, loglevel)
self.trnsp = phase.nSpecies()
self._phase_id = phase._phase_id
# dictionary holding all installed transport managers
self._models = {}
self._models[self.model] = self.__tr_id
@ -92,7 +92,7 @@ class Transport:
new_id = _cantera.Transport(model,
self._phase_id, loglevel)
self._models[model] = new_id
def switchTransportModel(self, model):
"""Switch to a different transport model."""
@ -102,7 +102,7 @@ class Transport:
else:
raise CanteraError("Transport model "+model+" not defined. Use "
+"method addTransportModel first.")
def desc(self):
"""A short description of the active model."""
if self.model == 'Multi':
@ -111,15 +111,15 @@ class Transport:
return 'Mixture-averaged'
else:
return self.model
def transport_id(self):
"""For internal use."""
return self.__tr_id
def transport_hndl(self):
"""For internal use."""
"""For internal use."""
return self.__tr_id
def viscosity(self):
"Viscosity [Pa-s]."""
return _cantera.tran_viscosity(self.__tr_id)
@ -143,11 +143,11 @@ class Transport:
"""Species diffusion coefficients. (m^2/s)."""
return self.mixDiffCoeffs()
def mixDiffCoeffs(self):
"""Mixture-averaged diffusion coefficients."""
return _cantera.tran_mixDiffCoeffs(self.__tr_id,
self.trnsp)
self.trnsp)
def multiDiffCoeffs(self):
"""Two-dimensional array of species multicomponent diffusion
@ -159,10 +159,10 @@ class Transport:
"""Set model-specific parameters."""
return _cantera.tran_setParameters(self.__tr_id,
type, k, asarray(params))
def molarFluxes(self, state1, state2, delta):
return _cantera.tran_getMolarFluxes(self.__tr_id, self.trnsp,
return _cantera.tran_getMolarFluxes(self.__tr_id, self.trnsp,
asarray(state1), asarray(state2),
delta)

View file

@ -1,5 +1,5 @@
"""
This module provides the Python interface to C++ class XML_Node.
This module provides the Python interface to C++ class XML_Node.
"""
import _cantera
@ -7,17 +7,17 @@ import types
import tempfile
import string
import exceptions
class XML_Node:
"""A node in an XML tree."""
def __init__(self, name="--", src="", wrap=0, root=None, preprocess=0, debug=0):
"""
Return an instance representing a node in an XML tree.
If 'src' is specified, then the XML tree found in file 'src' is
constructed, and this node forms the root of the tree. The XML tree
is saved, and a second call with the same value for 'src' will use
the XML tree already read in, instead of reading it in again.
the XML tree already read in, instead of reading it in again.
If 'wrap' is greater than zero, then only a Python wrapper is
created - no new kernel object results.
@ -34,11 +34,11 @@ class XML_Node:
elif src:
self._xml_id = _cantera.xml_get_XML_File(src, debug)
self.wrap = 1 # disable deleting
# create a new empty node
else:
self._xml_id = _cantera.xml_new(name)
def __del__(self):
"""Delete the node. Does nothing if this node is only a wrapper."""
if not self.wrap:
@ -70,10 +70,10 @@ class XML_Node:
if (tag == "" or ch.tag() == tag):
children.append(ch)
return children
def removeChild(self, child):
"""Remove a child and all its descendants."""
_cantera.xml_removeChild(self._xml_id, child._xml_id)
_cantera.xml_removeChild(self._xml_id, child._xml_id)
def addChild(self, name, value=""):
"""Add a child with tag 'name', and set its value if the value
@ -89,7 +89,7 @@ class XML_Node:
x = self.attrib(key)
if x: return 1
else: return 0
def attrib(self, key):
"""Return attribute 'key', or the empty string if this attribute
does not exist."""
@ -105,7 +105,7 @@ class XML_Node:
def addComment(self, comment):
"""Add a comment."""
_cantera.xml_addComment(self._xml_id, comment)
def value(self, loc=""):
"""Return the value of this node, or, if
the loc argument is supplied, of the node with relative
@ -123,7 +123,7 @@ class XML_Node:
m = _cantera.xml_findID(self._xml_id, id)
elif name:
m = _cantera.xml_findByName(self._xml_id, name)
ch = XML_Node(wrap=m)
return ch
@ -133,12 +133,12 @@ class XML_Node:
def __setitem__(self, key, value):
"""Set a new attribute using the syntax node[key] = value."""
return self.addAttrib(key, value)
return self.addAttrib(key, value)
def __int__(self):
"""Conversion to integer."""
return self._xml_id
def __call__(self, loc=''):
"""Get the value using the syntax node(loc)."""
return self.value(loc)
@ -160,16 +160,7 @@ class XML_Node:
def clear_XML():
_cantera.xml_clear()
def getFloatArray(node, convert_units=0):
sz = int(node['size'])
return _cantera.ctml_getFloatArray(node._xml_id, convert_units, sz)

View file

@ -32,7 +32,7 @@ def writeCSV(f, list):
f.write(item+', ')
else:
f.write(`item`+', ')
f.write('\n')
@ -47,7 +47,7 @@ def table(keys, values):
def getCanteraError():
"""Return the Cantera error message, if any."""
return _cantera.get_Cantera_Error()
return _cantera.get_Cantera_Error()
def refCount(a):
"""Return the reference count for an object."""
@ -65,13 +65,12 @@ def reset():
"""Release all cached Cantera data. Equivalent to
starting a fresh session."""
_cantera.ct_appdelete()
# 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 *
from num import *

View file

@ -24,11 +24,10 @@ 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.
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

@ -13,7 +13,7 @@ def elementMoles(s, element):
# in s. If it does not, return zero moles.
try:
m = s.elementIndex(element)
if m < 0.0: return 0.0
if m < 0.0: return 0.0
except:
return 0.0

View file

@ -13,7 +13,7 @@ def write_CSV_data(fname, names, npts, nvar, append, data):
method 'value', defined so that data.value(j,n) returns
the value of variable n at point j.
"""
if append > 0:
f = open(fname,'a')
else:
@ -26,6 +26,3 @@ def write_CSV_data(fname, names, npts, nvar, append, data):
f.write('%10.4e, ' % data.value(j,n))
f.write('\n')
f.close()

View file

@ -24,4 +24,3 @@ class CanteraError(Exception):
class OptionError(CanteraError):
def __init__(self, msg):
self.msg = 'Unknown option: '+msg

View file

@ -30,17 +30,16 @@ def GRI30(transport = ""):
elif transport == "Mix":
return Solution(src="gri30.cti", id="gri30_mix")
elif transport == "Multi":
return Solution(src="gri30.cti", id="gri30_multi")
return Solution(src="gri30.cti", id="gri30_multi")
def Air():
"""Return a Solution instance implementing the O/N/Ar portion of
reaction mechanism GRI-Mech 3.0. The initial composition is set to
that of air"""
that of air"""
return Solution(src="air.cti", id="air")
def Argon():
"""Return a Solution instance representing pure argon."""
"""Return a Solution instance representing pure argon."""
return Solution(src="argon.cti", id="argon")

View file

@ -36,7 +36,7 @@ def importInterface(file, name = '', phases = []):
representing a gas phase or a solid.
>>> gas1, cryst1 = importPhases('diamond.cti', ['gas', 'solid'])
>>> diamond_surf = importInterface('diamond.cti', [gas1, cryst1])
Note the difference between the lists in the argument lists of these
two functions. In importPhases, a list of name strings is entered,
which are used to identify the appropriate definitions in the input
@ -50,7 +50,7 @@ def importInterface(file, name = '', phases = []):
src = file+'#'+name
else:
src = file
return Interface.Interface(src = src, phases = phases)
return Interface.Interface(src = src, phases = phases)
def importEdge(file, name = '', surfaces = []):
@ -58,5 +58,4 @@ def importEdge(file, name = '', surfaces = []):
src = file+'#'+name
else:
src = file
return Edge.Edge(src = src, surfaces = surfaces)
return Edge.Edge(src = src, surfaces = surfaces)

View file

@ -6,13 +6,13 @@ def interp(z0, z, f):
Sequences z and f must be of the same length,
and the entries in z must be monotonically increasing.
Example:
Example:
>>> z = [0.0, 0.2, 0.5, 1.2, 2.1]
>>> f = [3.0, 2.0, 1.0, 0.0, -1.0]
>>>print interp(-2, z, f), interp(0.5, z, f), interp(6, z, f)
3.0 7.0 -9.0
"""
n = len(z)
# if z0 is outside the range of z, then return the endpoint value,
@ -61,4 +61,4 @@ def quadInterp(z0, z, f):
## f = [3.0, 5.0, 11.0, 0.0, -9.0]
## print interp(-2, z, f), interp(0.3, z, f), interp(6, z, f)
## print quadInterp(-2, z, f), quadInterp(0.3, z, f), quadInterp(6, z, f)
## print quadInterp(-2, z, f), quadInterp(0.3, z, f), quadInterp(6, z, f)

View file

@ -15,7 +15,7 @@ import XML
import _cantera
class PureFluid(ThermoPhase):
class PureFluid(ThermoPhase):
"""
A class for chemically-reacting solutions.
@ -38,16 +38,16 @@ class PureFluid(ThermoPhase):
if id:
s = root.child(id = id)
else:
s = root.child(name = "phase")
self._name = s['id']
# initialize the equation of state
ThermoPhase.__init__(self, xml_phase=s)
def __del__(self):
ThermoPhase.__del__(self)
@ -56,7 +56,7 @@ class PureFluid(ThermoPhase):
def name(self):
return self._name
def set(self, **options):
"""Set various properties.
T --- temperature [K]
@ -72,7 +72,7 @@ class PureFluid(ThermoPhase):
Liquid --- saturated liquid fraction
"""
setByName(self, options)
def critTemperature(self):
"""Critical temperature [K]."""
return _cantera.thermo_getfp(self._phase_id,50)
@ -96,11 +96,11 @@ class PureFluid(ThermoPhase):
def setState_Tsat(self, t, vaporFraction):
"""Set the state of a saturated liquid/vapor mixture by
specifying the temperature and vapor fraction."""
_cantera.thermo_setfp(self._phase_id,7, t, vaporFraction)
specifying the temperature and vapor fraction."""
_cantera.thermo_setfp(self._phase_id,7, t, vaporFraction)
def Water():
return PureFluid('liquidvapor.cti','water')
@ -124,4 +124,3 @@ def CarbonDioxide():
def Heptane():
return PureFluid('liquidvapor.cti','heptane')

View file

@ -14,7 +14,7 @@ class Mixture:
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:
>>> gas = importPhase('gas.cti')
>>> gas.speciesNames()
['H2', 'H', 'O2', 'O', 'OH']
@ -24,7 +24,7 @@ class Mixture:
>>> mix = Mixture([(gas, 1.0), (graphite, 0.1)])
>>> mix.speciesNames()
['H2', 'H', 'O2', 'O', 'OH', 'C(g)']
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
@ -36,10 +36,10 @@ class Mixture:
('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 phases
objects whenever it requires phase properties.
objects whenever it requires phase properties.
"""
def __init__(self, phases=[]):
""" init """
self.__mixid = _cantera.mix_new()
@ -58,9 +58,9 @@ class Mixture:
moles = 0
self._addPhase(ph, moles)
self._phases.append(ph)
_cantera.mix_init(self.__mixid)
_cantera.mix_init(self.__mixid)
self.setTemperature(self._phases[0].temperature())
self.setPressure(self._phases[0].pressure())
self.setPressure(self._phases[0].pressure())
def __del__(self):
"""Delete the Mixture instance. The phase objects are not deleted."""
@ -77,7 +77,7 @@ class Mixture:
def _addPhase(self, phase = None, moles = 0.0):
"""Add a phase to the mixture."""
for k in range(phase.nSpecies()):
self._spnames.append(phase.speciesName(k))
self._spnames.append(phase.speciesName(k))
_cantera.mix_addPhase(self.__mixid, phase.thermo_hndl(), moles)
def nPhases(self):
@ -87,7 +87,7 @@ class Mixture:
def phase(self, n):
"""Return the object representing the nth phase in the mixture."""
return self._phases[n]
def phaseName(self, n):
"""Name of phase n."""
return self._phases[n].name()
@ -109,7 +109,7 @@ class Mixture:
if self.phaseName(n) == phase:
return n
return -1
def nElements(self):
"""Total number of elements present in the mixture."""
return _cantera.mix_nElements(self.__mixid)
@ -124,24 +124,24 @@ class Mixture:
return _cantera.mix_elementIndex(self.__mixid, element)
else:
return element
def nSpecies(self):
"""Total number of species present in the mixture. This is the
sum of the numbers of species in each phase."""
return _cantera.mix_nSpecies(self.__mixid)
def speciesName(self, k):
"""Name of the species with index k. Note that index numbers
are assigned in order as phases are added."""
return self._spnames[k]
def speciesNames(self):
n = self.nSpecies()
s = []
for k in range(n):
s.append(self.speciesName(k))
return s
def speciesIndex(self, species):
"""Index of species with name 'species'. If 'species' is not a string,
then it is simply returned."""
@ -149,7 +149,7 @@ class Mixture:
return self._spnames.index(species)
else:
return species
def nAtoms(self, k, m):
"""Number of atoms of element m in species k. Both the species and
the element may be referenced either by name or by index number.
@ -161,45 +161,45 @@ class Mixture:
kk = self.speciesIndex(k)
mm = self.elementIndex(m)
return _cantera.mix_nAtoms(self.__mixid, kk, mm)
def setTemperature(self, t):
"""Set the temperature [K]. The temperatures of all phases are
set to this value, holding the pressure fixed."""
return _cantera.mix_setTemperature(self.__mixid, t)
def temperature(self):
"""The temperature [K]."""
return _cantera.mix_temperature(self.__mixid)
def minTemp(self):
"""The minimum temperature for which all species in
multi-species solutions have valid thermo data. Stoichiometric
phases are not considered in determining minTemp. """
return _cantera.mix_minTemp(self.__mixid)
def maxTemp(self):
"""The maximum temperature for which all species in
multi-species solutions have valid thermo data. Stoichiometric
phases are not considered in determining maxTemp. """
phases are not considered in determining maxTemp. """
return _cantera.mix_maxTemp(self.__mixid)
def charge(self):
"""The total charge in Coulombs, summed over all phases."""
return _cantera.mix_charge(self.__mixid)
def phaseCharge(self, p):
"""The charge of phase p (Coulombs)."""
return _cantera.mix_phaseCharge(self.__mixid, p)
def setPressure(self, p):
"""Set the pressure [Pa]. The pressures of all phases are set
to the specified value, holding the temperature fixed."""
return _cantera.mix_setPressure(self.__mixid, p)
def pressure(self):
"""The pressure [Pa]."""
return _cantera.mix_pressure(self.__mixid)
def phaseMoles(self, n = -1):
"""Moles of phase n."""
if n == -1:
@ -208,13 +208,13 @@ class Mixture:
for m in range(np):
moles[m] = _cantera.mix_phaseMoles(self.__mixid, m)
return moles
else:
else:
return _cantera.mix_phaseMoles(self.__mixid, n)
def setPhaseMoles(self, n, moles):
"""Set the number of moles of phase n."""
_cantera.mix_setPhaseMoles(self.__mixid, n, moles)
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
@ -229,21 +229,21 @@ class Mixture:
_cantera.mix_setMolesByName(self.__mixid, moles)
else:
_cantera.mix_setMoles(self.__mixid, asarray(moles))
def speciesMoles(self, species = ""):
"""Moles of species k."""
moles = zeros(self.nSpecies(),'d')
for k in range(self.nSpecies()):
moles[k] = _cantera.mix_speciesMoles(self.__mixid, k)
return self.selectSpecies(moles, species)
def elementMoles(self, m):
"""Total number of moles of element m, summed over all species.
The element may be referenced either by index number or by name.
"""
mm = self.elementIndex(m)
return _cantera.mix_elementMoles(self.__mixid, mm)
def chemPotentials(self, species=[]):
"""The chemical potentials of all species [J/kmol]."""
mu = zeros(self.nSpecies(),'d')
@ -261,7 +261,7 @@ class Mixture:
self.setSpeciesMoles(v)
else:
raise CanteraError("unknown property: "+o)
def equilibrate(self, XY = "TP", err = 1.0e-9,
maxsteps = 1000, maxiter = 200, loglevel = 0):
"""Set the mixture to a state of chemical equilibrium.
@ -277,11 +277,11 @@ class Mixture:
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.
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
@ -310,11 +310,11 @@ class Mixture:
"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)
"""
i = _cantera.mix_equilibrate(self.__mixid, XY, err, maxsteps,
maxiter, loglevel)
@ -335,8 +335,8 @@ class Mixture:
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.
values are obtained.
XY - Two-letter string specifying the two properties to hold fixed.
Currently, 'TP', 'HP', and 'SP' are implemented. Default: 'TP'.
@ -348,7 +348,7 @@ class Mixture:
solver - Determines which solver is used.
- 1 MultiPhaseEquil solver
- 2 VCSnonideal Solver (default)
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
@ -377,13 +377,13 @@ class Mixture:
"equilibrate_log.html", "equilibrate_log1.html",
"equilibrate_log2.html", and so on. Existing log files will
not be overwritten.
"""
i = _cantera.mix_vcs_equilibrate(self.__mixid, XY, estimateEquil,
printLvl, solver, rtol, maxsteps,
maxiter, loglevel)
def selectSpecies(self, f, species):
"""Given an array 'f' of floating-point species properties,
return an array of those values corresponding to species
@ -406,5 +406,3 @@ class Mixture:
return asarray(fs)
else:
return f

View file

@ -13,16 +13,16 @@ try:
nummodule = Numeric
except:
print """
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 """+_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 "+_cantera.nummod

View file

@ -27,7 +27,7 @@ PathDiagram keyword options:
-- type 'both' or 'net' (forward and reverse arrows,
or net arrow)
-- dot_options options passed through to 'dot'
colors:
-- normal_color color for normal-weight lines
-- bold_color color for bold-weight lines
@ -38,7 +38,7 @@ PathDiagram keyword options:
-- normal_threshold min relative strength for normal-weight path
Below this value, paths are dashed.
-- bold_threshold min relative strength for bold-weight path
"""
import _cantera
@ -64,10 +64,10 @@ class PathDiagram:
def __del__(self):
_cantera.rdiag_del(self.__rdiag_id)
def id(self):
return self.__rdiag_id
def write(self, fmt, file):
_cantera.rdiag_write(self.__rdiag_id, fmt, file)
@ -79,7 +79,7 @@ class PathDiagram:
def displayOnly(self, node=-1):
_cantera.rdiag_displayOnly(self.__rdiag_id, node)
def setOptions(self, options):
for o in options.keys():
v = options[o]
@ -111,7 +111,7 @@ class PathDiagram:
elif o == "label_threshold":
_cantera.rdiag_setLabelThreshold(self.__rdiag_id, v)
elif o == "font":
_cantera.rdiag_setFont(self.__rdiag_id, v)
_cantera.rdiag_setFont(self.__rdiag_id, v)
elif o == "flow_type":
if v == "one_way":
_cantera.rdiag_setFlowType(self.__rdiag_id, 0)
@ -119,9 +119,9 @@ class PathDiagram:
_cantera.rdiag_setFlowType(self.__rdiag_id, 1)
else:
raise("unknown attribute "+o)
class PathBuilder:
def __init__(self, kin, logfile=""):
if logfile == "":
logfile = "rxnpath.log"
@ -131,7 +131,7 @@ class PathBuilder:
def __del__(self):
_cantera.rbuild_del(self.__rbuild_id)
def build(self, diagram = None, element = "C",
dotfile = "rxnpaths.dot", format="dot"):
if diagram == None:
@ -140,7 +140,7 @@ class PathBuilder:
"buildlog", diagram.id(), 1)
if format == "dot":
diagram.write(0, dotfile)
diagram.write(1, "rp.txt")
diagram.write(1, "rp.txt")
elif format == "plain":
diagram.write(1, dotfile)
@ -156,14 +156,11 @@ def view(url, ext = 'png'):
import webbrowser
dot_server = 'http://webdot.graphviz.org/cgi-bin/webdot/'
webbrowser.open(dot_server+url+'.dot.'+ext)
if __name__ == "__main__":
from Cantera.gases import GRI30
gas = GRI30()
x = [1.0] * gas.nSpecies()
gas.setState_TPX(1800.0, 1.01325e5, x)
write(gas, 'C', 'c:/users/dgg/test.dot')

View file

@ -22,8 +22,8 @@ def setByName(a, options):
Entropy S specific entropy
Vapor Vap vapor fraction in a two-phase mixture
Liquid Liq liquid fraction in a two-phase mixture
"""
tval = None
@ -33,7 +33,7 @@ def setByName(a, options):
sval = None
vval = None
qval = None
np = 0
nt = 0
nv = 0
@ -43,7 +43,7 @@ def setByName(a, options):
nh = 0
nu = 0
nq = 0
for o in options.keys():
val = options[o]
if o == 'Temperature' or o == 'T':
@ -60,7 +60,7 @@ def setByName(a, options):
a.setMoleFractions(val)
elif o == 'MassFractions' or o == 'Y':
ny += 1
a.setMassFractions(val)
a.setMassFractions(val)
elif o == 'Pressure' or o == 'P':
pval = val
np += 1
@ -69,7 +69,7 @@ def setByName(a, options):
nh += 1
elif o == 'IntEnergy' or o == 'U':
uval = val
nu += 1
nu += 1
elif o == 'Entropy' or o == 'S':
sval = val
ns += 1
@ -78,8 +78,8 @@ def setByName(a, options):
qval = val
elif o == 'Liquid' or o == 'Liq':
nq += 1
qval = 1.0 - val
qval = 1.0 - val
else:
raise CanteraError('unknown property: '+o)
@ -90,7 +90,7 @@ def setByName(a, options):
for n in nn:
if n > 1:
raise CanteraError('property specified multiple times')
ntot = nt + np + nv + ns + nh + nu + nq
# set individual properties
@ -127,8 +127,6 @@ def setByName(a, options):
else:
raise CanteraError('unimplemented property pair')
def set(a, **options):
setByName(a, options)

View file

@ -11,12 +11,12 @@ from SolidTransport import SolidTransport
import XML
import _cantera
class Solid(ThermoPhase, Kinetics, SolidTransport):
class Solid(ThermoPhase, Kinetics, SolidTransport):
"""
"""
def __init__(self, src="", root=None):
self.ckin = 0
self._owner = 0
self.verbose = 1
@ -31,7 +31,7 @@ class Solid(ThermoPhase, Kinetics, SolidTransport):
Kinetics.__init__(self, xml_phase=s, phases=[self])
SolidTransport.__init__(self, phase=self)
#self.setState_TP(300.0, OneAtm)
@ -43,4 +43,3 @@ class Solid(ThermoPhase, Kinetics, SolidTransport):
SolidTransport.__del__(self)
Kinetics.__del__(self)
ThermoPhase.__del__(self)

View file

@ -2,7 +2,7 @@
from solution import Solution
def Solid(src="",
def Solid(src="",
kmodel=1, transport=None):
return Solution(import_file=import_file,
thermo_db="",
@ -11,4 +11,3 @@ def Solid(src="",
kmodel=kmodel,
trmodel=transport,
validate=0)

View file

@ -9,7 +9,7 @@ from set import setByName
import XML
import _cantera
class Solution(ThermoPhase, Kinetics, Transport):
class Solution(ThermoPhase, Kinetics, Transport):
"""
A class for chemically-reacting solutions.
@ -40,12 +40,12 @@ class Solution(ThermoPhase, Kinetics, Transport):
if id:
s = root.child(id = id)
else:
s = root.child(name = "phase")
self._name = s['id']
# initialize the equation of state
ThermoPhase.__init__(self, xml_phase=s)
@ -56,7 +56,7 @@ class Solution(ThermoPhase, Kinetics, Transport):
# initialize the transport model
Transport.__init__(self, xml_phase=s, phase=self,
model = '', loglevel=loglevel)
def __del__(self):
Transport.__del__(self)
Kinetics.__del__(self)
@ -67,7 +67,7 @@ class Solution(ThermoPhase, Kinetics, Transport):
def name(self):
return self._name
def set(self, **options):
"""Set various properties.
T --- temperature [K]
@ -83,4 +83,3 @@ class Solution(ThermoPhase, Kinetics, Transport):
Liquid --- saturated liquid fraction
"""
setByName(self, options)

View file

@ -1,7 +1,7 @@
""" Solve a steady-state problem by combined damped Newton iteration
and time integration. Function solve is no longer used, now that the
functional equivalent has been added to the Cantera C++ kernel. """
from Cantera import CanteraError
from Cantera.num import array
import math, types
@ -17,7 +17,7 @@ def solve(sim, loglevel = 0, refine_grid = 1, plotfile = '', savefile = ''):
Solve a steady-state problem by combined damped Newton iteration
and time integration.
"""
new_points = 1
# get options
@ -29,14 +29,14 @@ def solve(sim, loglevel = 0, refine_grid = 1, plotfile = '', savefile = ''):
if type(_steps) == types.IntType: _steps = [_steps]
len_nsteps = len(_steps)
dt = sim.option('timestep')
dt = sim.option('timestep')
ll = loglevel
soln_number = -1
max_timestep = sim.option('max_timestep')
sim.collect()
# loop until refine adds no more points
while new_points > 0:
@ -48,35 +48,35 @@ def solve(sim, loglevel = 0, refine_grid = 1, plotfile = '', savefile = ''):
while ok == 0:
# Try to solve the steady-state problem by damped
# Newton iteration.
# Newton iteration.
try:
if loglevel > 0:
print 'Attempt Newton solution of ',\
'steady-state problem...',
sim.newton_solve(loglevel-1)
if loglevel > 0:
print 'success.\n\n'
print '%'*79+'\n'
print '%'*79+'\n'
print 'Problem solved on ',sim.npts,' point grid(s).\n'
print '%'*79+'\n'
print '%'*79+'\n'
ok = 1
soln_number += 1
sim.finish()
except CanteraError:
# Newton iteration failed.
if loglevel > 0: print '\n'
# Take nsteps time steps, starting with step size
# dt. The final dt may be smaller than the initial
# value if one or more steps fail.
if loglevel == 1:
print 'Take',nsteps,' timesteps',
dt = sim.py_timeStep(nsteps,dt,loglevel=ll-1)
if loglevel == 1: print dt, math.log10(sim.ssnorm())
istep += 1
@ -87,7 +87,7 @@ def solve(sim, loglevel = 0, refine_grid = 1, plotfile = '', savefile = ''):
nsteps = _steps[istep]
if dt > max_timestep: dt = max_timestep
# A converged solution was found. Save and/or plot it, then
# check whether the grid should be refined.
@ -104,11 +104,9 @@ def solve(sim, loglevel = 0, refine_grid = 1, plotfile = '', savefile = ''):
if loglevel > 2: sim.show()
if refine_grid:
# Call refine to add new points, if needed
new_points = sim.refine(loglevel = loglevel - 1)
else:
new_points = 0

View file

@ -13,9 +13,9 @@ def stoich_fuel_to_oxidizer(mix, fuel, oxidizer):
This function only works for fuels composed of carbon, hydrogen,
and/or oxygen. The fuel to oxidizer ratio is returned that results in
"""
# fuel
mix.setMoleFractions(fuel)
f_carbon = elementMoles(mix, 'C')
@ -43,4 +43,3 @@ def stoich_fuel_to_oxidizer(mix, fuel, oxidizer):
if __name__ == "__main__":
g = GRI30()
print stoich_fuel_to_oxidizer(g, 'CH4:1', 'O2:1')

View file

@ -15,7 +15,7 @@ def write_TECPLOT_zone(fname, title, zone, names, npts, nvar, append, data):
method 'value', defined so that data.value(j,n) returns
the value of variable n at point j.
"""
if append > 0:
f = open(fname,'a')
else:
@ -35,6 +35,3 @@ def write_TECPLOT_zone(fname, title, zone, names, npts, nvar, append, data):
f.write('%10.4e ' % data[j,n])
f.write('\n')
f.close()

View file

@ -9,238 +9,236 @@ _ATOL = 1.e-15
_RTOL = 1.e-7
class CompFrame(Frame):
def __init__(self,master):
Frame.__init__(self,master)
self.config(relief=FLAT, bd=4)
self.top = self.master.top
self.controls=Frame(self)
self.hide = IntVar()
self.hide.set(0)
self.comp = IntVar()
self.comp.set(0)
self.controls.grid(column=1,row=0,sticky=W+E+N)
self.makeControls()
mf = self.master
def makeControls(self):
Radiobutton(self.controls,text='Moles',
variable=self.comp,value=0,
command=self.show).grid(column=0,row=0,sticky=W)
Radiobutton(self.controls,text='Mass',
variable=self.comp,value=1,
command=self.show).grid(column=0,row=1,sticky=W)
Radiobutton(self.controls,text='Concentration',
variable=self.comp,value=2,
command=self.show).grid(column=0,row=2,sticky=W)
Button(self.controls,text='Clear',
command=self.zero).grid(column=0,row=4,sticky=W+E)
Button(self.controls,text='Normalize',
command=self.norm).grid(column=0,row=5,sticky=W+E)
Checkbutton(self.controls,text='Hide Missing\nSpecies',
variable=self.hide,onvalue=1,
offvalue=0,command=self.master.redo).grid(column=0,
row=3,
sticky=W)
def __init__(self,master):
Frame.__init__(self,master)
self.config(relief=FLAT, bd=4)
self.top = self.master.top
self.controls=Frame(self)
self.hide = IntVar()
self.hide.set(0)
self.comp = IntVar()
self.comp.set(0)
self.controls.grid(column=1,row=0,sticky=W+E+N)
self.makeControls()
mf = self.master
def norm(self):
mf = self.master
mf.update()
data = mf.comp
sum = 0.0
for sp in data:
sum += sp
for i in range(len(mf.comp)):
mf.comp[i] /= sum
self.show()
def makeControls(self):
Radiobutton(self.controls,text='Moles',
variable=self.comp,value=0,
command=self.show).grid(column=0,row=0,sticky=W)
Radiobutton(self.controls,text='Mass',
variable=self.comp,value=1,
command=self.show).grid(column=0,row=1,sticky=W)
Radiobutton(self.controls,text='Concentration',
variable=self.comp,value=2,
command=self.show).grid(column=0,row=2,sticky=W)
Button(self.controls,text='Clear',
command=self.zero).grid(column=0,row=4,sticky=W+E)
Button(self.controls,text='Normalize',
command=self.norm).grid(column=0,row=5,sticky=W+E)
Checkbutton(self.controls,text='Hide Missing\nSpecies',
variable=self.hide,onvalue=1,
offvalue=0,command=self.master.redo).grid(column=0,
row=3,
sticky=W)
def set(self):
c = self.comp.get()
mix = self.top.mix
mf = self.master
g = mix.g
if c == 0:
mix.setMoles(mf.comp)
def norm(self):
mf = self.master
mf.update()
elif c == 1:
mix.setMass(mf.comp)
data = mf.comp
sum = 0.0
for sp in data:
sum += sp
for i in range(len(mf.comp)):
mf.comp[i] /= sum
self.show()
elif c == 2:
pass
self.top.thermo.setState()
self.top.kinetics.show()
def set(self):
c = self.comp.get()
mix = self.top.mix
mf = self.master
g = mix.g
if c == 0:
mix.setMoles(mf.comp)
def show(self):
mf = self.master
mf.active = self
c = self.comp.get()
mix = self.top.mix
g = mix.g
if c == 0:
mf.var.set("Moles")
#mf.data = spdict(mix.g, mix.moles())
mf.comp = mix.moles()
elif c == 1:
mix.setMass(mf.comp)
elif c == 1:
mf.var.set("Mass")
#mf.data = spdict(mix.g,mix.mass())
mf.comp = mix.mass()
elif c == 2:
pass
self.top.thermo.setState()
self.top.kinetics.show()
def show(self):
mf = self.master
mf.active = self
c = self.comp.get()
mix = self.top.mix
g = mix.g
if c == 0:
mf.var.set("Moles")
#mf.data = spdict(mix.g, mix.moles())
mf.comp = mix.moles()
elif c == 1:
mf.var.set("Mass")
#mf.data = spdict(mix.g,mix.mass())
mf.comp = mix.mass()
elif c == 2:
mf.var.set("Concentration")
mf.comp = mix.concentrations()
#mf.data = spdict(mix,mix,mf.comp)
for s in mf.variable.keys():
try:
k = g.speciesIndex(s)
if mf.comp[k] > _CUTOFF:
mf.variable[s].set(mf.comp[k])
else:
mf.variable[s].set(0.0)
except:
pass
def zero(self):
mf = self.master
mf.comp *= 0.0
self.show()
elif c == 2:
mf.var.set("Concentration")
mf.comp = mix.concentrations()
#mf.data = spdict(mix,mix,mf.comp)
for s in mf.variable.keys():
try:
k = g.speciesIndex(s)
if mf.comp[k] > _CUTOFF:
mf.variable[s].set(mf.comp[k])
else:
mf.variable[s].set(0.0)
except:
pass
def zero(self):
mf = self.master
mf.comp *= 0.0
self.show()
class MixtureFrame(Frame):
def __init__(self,master,top):
Frame.__init__(self,master)
self.config(relief=GROOVE, bd=4)
self.top = top
self.top.mixframe = self
self.g = self.top.mix.g
#self.scroll = Scrollbar(self)
self.entries=Frame(self)
#self.scroll.config(command=self.entries.xview)
#self.scroll.grid(column=0,row=1)
self.var = StringVar()
self.var.set("Moles")
self.comp = array(self.top.mix.moles())
self.names = self.top.mix.speciesNames()
self.nsp = len(self.names)
#self.data = self.top.mix.moleDict()
self.makeControls()
self.makeEntries()
self.entries.bind('<Double-l>',self.minimize)
self.ctype = 0
self.newcomp = 0
def makeControls(self):
self.c = CompFrame(self)
#self.k = KineticsFrame(self)
self.active = self.c
self.c.grid(column=1,row=0,sticky=E+W+N+S)
#self.k.grid(column=2,row=0,sticky=E+W+N+S)
def __init__(self,master,top):
Frame.__init__(self,master)
self.config(relief=GROOVE, bd=4)
self.top = top
self.top.mixframe = self
self.g = self.top.mix.g
#self.scroll = Scrollbar(self)
self.entries=Frame(self)
#self.scroll.config(command=self.entries.xview)
#self.scroll.grid(column=0,row=1)
self.var = StringVar()
self.var.set("Moles")
self.comp = array(self.top.mix.moles())
self.names = self.top.mix.speciesNames()
self.nsp = len(self.names)
#self.data = self.top.mix.moleDict()
self.makeControls()
self.makeEntries()
self.entries.bind('<Double-l>',self.minimize)
self.ctype = 0
self.newcomp = 0
def update(self):
self.newcomp = 0
for s in self.variable.keys():
k = self.g.speciesIndex(s)
current = self.comp[k]
val = self.variable[s].get()
dv = abs(val - current)
if dv > _RTOL*abs(current) + _ATOL:
self.comp[k] = val
self.newcomp = 1
def makeControls(self):
self.c = CompFrame(self)
#self.k = KineticsFrame(self)
self.active = self.c
self.c.grid(column=1,row=0,sticky=E+W+N+S)
#self.k.grid(column=2,row=0,sticky=E+W+N+S)
def show(self):
self.active.show()
## for k in range(self.nsp):
## sp = self.names[k]
## if self.comp[k] > _CUTOFF:
## self.variable[sp].set(self.comp[k])
## else:
## self.variable[sp].set(0.0)
def redo(self):
self.update()
self.entries.destroy()
self.entries=Frame(self)
self.makeEntries()
def update(self):
self.newcomp = 0
for s in self.variable.keys():
k = self.g.speciesIndex(s)
current = self.comp[k]
val = self.variable[s].get()
dv = abs(val - current)
if dv > _RTOL*abs(current) + _ATOL:
self.comp[k] = val
self.newcomp = 1
def minimize(self,Event=None):
self.c.hide.set(1)
self.redo()
self.c.grid_forget()
self.entries.bind("<Double-1>",self.maximize)
def maximize(self,Event=None):
self.c.hide.set(0)
self.redo()
self.c.grid(column=1,row=0,sticky=E+W+N+S)
self.entries.bind("<Double-1>",self.minimize)
def show(self):
self.active.show()
## for k in range(self.nsp):
## sp = self.names[k]
## if self.comp[k] > _CUTOFF:
## self.variable[sp].set(self.comp[k])
## else:
## self.variable[sp].set(0.0)
def up(self, x):
self.update()
if self.newcomp:
self.c.set()
self.c.show()
self.top.update()
#thermo.showState()
#self.top.kinetics.show()
def makeEntries(self):
self.entries.grid(row=0,column=0,sticky=W+N+S+E)
self.entries.config(relief=FLAT,bd=4)
DATAKEYS = self.top.species
self.variable = {}
def redo(self):
self.update()
self.entries.destroy()
self.entries=Frame(self)
self.makeEntries()
n=0
ncol = 3
col = 0
row = 60
def minimize(self,Event=None):
self.c.hide.set(1)
self.redo()
self.c.grid_forget()
self.entries.bind("<Double-1>",self.maximize)
equil = 0
if self.top.thermo:
equil = self.top.thermo.equil.get()
for sp in DATAKEYS:
s = sp # self.top.species[sp]
k = s.index
if row > 25:
row = 0
col = col + 2
l = Label(self.entries,text='Species')
l.grid(column=col,row=row,sticky=E+W)
e1 = Entry(self.entries)
e1.grid(column=col+1,row=row,sticky=E+W)
e1['textvariable'] = self.var
e1.config(state=DISABLED)
e1.config(bg='lightyellow',relief=RIDGE)
row = row + 1
def maximize(self,Event=None):
self.c.hide.set(0)
self.redo()
self.c.grid(column=1,row=0,sticky=E+W+N+S)
self.entries.bind("<Double-1>",self.minimize)
spname = s.name
val = self.comp[k]
if not self.c.hide.get() or val: showit = 1
else: showit = 0
def up(self, x):
self.update()
if self.newcomp:
self.c.set()
self.c.show()
self.top.update()
#thermo.showState()
#self.top.kinetics.show()
l=SpeciesInfo(self.entries,species=s,
text=spname,relief=FLAT,justify=RIGHT,
fg='darkblue')
entry1 = Entry(self.entries)
self.variable[spname] = DoubleVar()
self.variable[spname].set(self.comp[k])
entry1['textvariable']=self.variable[spname]
entry1.bind('<Any-Leave>',self.up)
if showit:
l.grid(column= col ,row=row,sticky=E)
entry1.grid(column=col+1,row=row)
n=n+1
row = row + 1
if equil == 1:
entry1.config(state=DISABLED,bg='lightgray')
def makeEntries(self):
self.entries.grid(row=0,column=0,sticky=W+N+S+E)
self.entries.config(relief=FLAT,bd=4)
DATAKEYS = self.top.species
self.variable = {}
n=0
ncol = 3
col = 0
row = 60
equil = 0
if self.top.thermo:
equil = self.top.thermo.equil.get()
for sp in DATAKEYS:
s = sp # self.top.species[sp]
k = s.index
if row > 25:
row = 0
col = col + 2
l = Label(self.entries,text='Species')
l.grid(column=col,row=row,sticky=E+W)
e1 = Entry(self.entries)
e1.grid(column=col+1,row=row,sticky=E+W)
e1['textvariable'] = self.var
e1.config(state=DISABLED)
e1.config(bg='lightyellow',relief=RIDGE)
row = row + 1
spname = s.name
val = self.comp[k]
if not self.c.hide.get() or val: showit = 1
else: showit = 0
l=SpeciesInfo(self.entries,species=s,
text=spname,relief=FLAT,justify=RIGHT,
fg='darkblue')
entry1 = Entry(self.entries)
self.variable[spname] = DoubleVar()
self.variable[spname].set(self.comp[k])
entry1['textvariable']=self.variable[spname]
entry1.bind('<Any-Leave>',self.up)
if showit:
l.grid(column= col ,row=row,sticky=E)
entry1.grid(column=col+1,row=row)
n=n+1
row = row + 1
if equil == 1:
entry1.config(state=DISABLED,bg='lightgray')
## if self.c.hide.get():
## b=Button(self.entries,height=1,command=self.maximize)
## else:
## b=Button(self.entries,command=self.minimize)
## b=Button(self.entries,height=1,command=self.maximize)
## else:
## b=Button(self.entries,command=self.minimize)
## b.grid(column=col,columnspan=2, row=row+1)

View file

@ -5,209 +5,209 @@ from ScrolledText import ScrolledText
#import filewindow
def ff():
print ' hi '
print ' hi '
class ControlWindow(Frame):
fncs = [ff]*10
def __init__(self, title, master=None):
self.app = master
Frame.__init__(self,master)
self.grid(row=0,column=0,sticky=E+W+N+S)
self.master.title(title)
fncs = [ff]*10
def __init__(self, title, master=None):
self.app = master
Frame.__init__(self,master)
self.grid(row=0,column=0,sticky=E+W+N+S)
self.master.title(title)
def addButtons(self, label, funcs):
self.buttonholder = Frame(self, relief=FLAT, bd=2)
self.buttonholder.pack(side=TOP,anchor=W)
b = Label(self.buttonholder,text=label)
b.pack(side=LEFT,fill=X)
for f in funcs:
b=Button(self.buttonholder,
text=f[0],command=f[1], padx=1,pady=1)
b.pack(side=LEFT,fill=X)
def disableButtons(self, *buttons):
for button in self.buttonholder.slaves():
if (button.cget('text') in buttons):
try:
button.config(state=DISABLED)
except:
pass
def enableButtons(self, *buttons):
for button in self.buttonholder.slaves():
if (button.cget('text') in buttons):
try:
button.config(state=NORMAL)
except:
pass
def addButtons(self, label, funcs):
self.buttonholder = Frame(self, relief=FLAT, bd=2)
self.buttonholder.pack(side=TOP,anchor=W)
b = Label(self.buttonholder,text=label)
b.pack(side=LEFT,fill=X)
for f in funcs:
b=Button(self.buttonholder,
text=f[0],command=f[1], padx=1,pady=1)
b.pack(side=LEFT,fill=X)
def disableButtons(self, *buttons):
for button in self.buttonholder.slaves():
if (button.cget('text') in buttons):
try:
button.config(state=DISABLED)
except:
pass
def newFrame(self, label, var):
fr = Frame(self, relief = RIDGE, bd = 2)
fr.pack(side=TOP,fill=X)
c = Checkbutton(fr, variable=var)
c.pack(side = LEFT, fill = X)
b = Label(fr,text=label,foreground="NavyBlue")
b.pack(side=LEFT,fill=X)
return fr
##creates a new Toplevel object
##options: transient=<callback for window close>,
## placement=(<screen x-coord>, <screen y-coord>)
def newWindow(self, master, title, **options):
new = Toplevel(master)
new.title(title)
#new.config(takefocus=0)
if 'transient' in options.keys():
new.transient(master)
if options['transient']:
new.protocol('WM_DELETE_WINDOW', options['transient'])
if 'placement' in options.keys():
new.geometry("+%d+%d" % tuple(options['placement']))
return new
def enableButtons(self, *buttons):
for button in self.buttonholder.slaves():
if (button.cget('text') in buttons):
try:
button.config(state=NORMAL)
except:
pass
##routes mouse and keyboard events to the window and
##waits for it to close before returning
def makemodal(self, window):
window.focus_set()
window.grab_set()
window.wait_window()
return
def PlotMenu(self, fr, label, funcs):
filebutton = Menubutton(fr,text=label, padx=3,pady=1)
filebutton.pack(side=LEFT)
filemenu = Menu(filebutton,tearoff=TRUE)
i = 0
for f in funcs:
filemenu.add_command(label=f[0], command=f[1])
i = i + 1
filebutton['menu']=filemenu
return filemenu
def newFrame(self, label, var):
fr = Frame(self, relief = RIDGE, bd = 2)
fr.pack(side=TOP,fill=X)
c = Checkbutton(fr, variable=var)
c.pack(side = LEFT, fill = X)
b = Label(fr,text=label,foreground="NavyBlue")
b.pack(side=LEFT,fill=X)
return fr
##creates a new Toplevel object
##options: transient=<callback for window close>,
## placement=(<screen x-coord>, <screen y-coord>)
def newWindow(self, master, title, **options):
new = Toplevel(master)
new.title(title)
#new.config(takefocus=0)
if 'transient' in options.keys():
new.transient(master)
if options['transient']:
new.protocol('WM_DELETE_WINDOW', options['transient'])
if 'placement' in options.keys():
new.geometry("+%d+%d" % tuple(options['placement']))
return new
##routes mouse and keyboard events to the window and
##waits for it to close before returning
def makemodal(self, window):
window.focus_set()
window.grab_set()
window.wait_window()
return
def PlotMenu(self, fr, label, funcs):
filebutton = Menubutton(fr,text=label, padx=3,pady=1)
filebutton.pack(side=LEFT)
filemenu = Menu(filebutton,tearoff=TRUE)
i = 0
for f in funcs:
filemenu.add_command(label=f[0], command=f[1])
i = i + 1
filebutton['menu']=filemenu
return filemenu
def testevent(event):
print 'event ',event.value
print 'event ',event.value
def make_menu(name, menubar, list):
nc = len(name)
button=Menubutton(menubar, text=name, width=nc+4, padx=3,pady=1)
button.pack(side=LEFT)
menu = Menu(button,tearoff=FALSE)
m = menu
i = 0
for entry in list:
i += 1
if entry == 'separator':
menu.add_separator({})
elif type(entry)==ListType:
for num in entry:
menu.entryconfig(num,state=DISABLED)
elif type(entry[1]) != ListType:
if i == 20:
i = 0
submenu = Menu(button,tearoff=FALSE)
m.add_cascade(label='More...',
menu=submenu)
m = submenu
if len(entry) == 2 or entry[2] == 'command':
m.add_command(label=entry[0],
command=entry[1])
elif entry[2] == 'check':
entry[3].set(0)
if len(entry) >= 5: val = entry[4]
else: val = 1
m.add_checkbutton(label=entry[0],
command=entry[1],
variable = entry[3],
onvalue=val)
else:
submenu=make_menu(entry[0], menu, entry[1])
m.add_cascade(label=entry[0],
menu=submenu)
button['menu']=menu
return button
nc = len(name)
button=Menubutton(menubar, text=name, width=nc+4, padx=3,pady=1)
button.pack(side=LEFT)
menu = Menu(button,tearoff=FALSE)
m = menu
i = 0
for entry in list:
i += 1
if entry == 'separator':
menu.add_separator({})
elif type(entry)==ListType:
for num in entry:
menu.entryconfig(num,state=DISABLED)
elif type(entry[1]) != ListType:
if i == 20:
i = 0
submenu = Menu(button,tearoff=FALSE)
m.add_cascade(label='More...',
menu=submenu)
m = submenu
if len(entry) == 2 or entry[2] == 'command':
m.add_command(label=entry[0],
command=entry[1])
elif entry[2] == 'check':
entry[3].set(0)
if len(entry) >= 5: val = entry[4]
else: val = 1
m.add_checkbutton(label=entry[0],
command=entry[1],
variable = entry[3],
onvalue=val)
else:
submenu=make_menu(entry[0], menu, entry[1])
m.add_cascade(label=entry[0],
menu=submenu)
button['menu']=menu
return button
def menuitem_state(button, *statelist):
for menu in button.children.keys():
if isinstance(button.children[menu], Menu):
for (commandnum, onoff) in statelist:
if onoff==0:
button.children[menu].entryconfig(commandnum,state=DISABLED)
if onoff==1:
button.children[menu].entryconfig(commandnum,state=NORMAL)
else:
pass
for menu in button.children.keys():
if isinstance(button.children[menu], Menu):
for (commandnum, onoff) in statelist:
if onoff==0:
button.children[menu].entryconfig(commandnum,state=DISABLED)
if onoff==1:
button.children[menu].entryconfig(commandnum,state=NORMAL)
else:
pass
class ArgumentWindow(Toplevel):
import tkMessageBox
def __init__(self, sim, **options):
Toplevel.__init__(self, sim.cwin)
self.resizable(FALSE,FALSE)
self.protocol("WM_DELETE_WINDOW", lambda:0) #self.cancelled)
self.transient(sim.cwin)
if 'placement' in options.keys():
self.geometry("+%d+%d" % tuple(options['placement']))
self.title('Thermal Model Initialization')
self.sim = sim
self.make_options()
buttonframe = Frame(self)
buttonframe.pack(side=BOTTOM)
b1=Button(buttonframe, text='OK', command=self.callback)
b1.pack(side=LEFT)
#b2=Button(buttonframe, text='Cancel', command=self.cancelled)
#b2.pack(side=LEFT)
self.bind("<Return>", self.callback)
#self.bind("<Escape>", self.cancelled)
import tkMessageBox
def __init__(self, sim, **options):
Toplevel.__init__(self, sim.cwin)
self.resizable(FALSE,FALSE)
self.protocol("WM_DELETE_WINDOW", lambda:0) #self.cancelled)
self.transient(sim.cwin)
if 'placement' in options.keys():
self.geometry("+%d+%d" % tuple(options['placement']))
self.title('Thermal Model Initialization')
self.sim = sim
self.initial_focus = self
self.initial_focus.focus_set()
#self.wait_window(self)
def make_options(self):
pass
self.make_options()
### must override this function ###
### with the entry forms ###
### be sure to use pack or a ###
### frame that is packed into self ###
buttonframe = Frame(self)
buttonframe.pack(side=BOTTOM)
b1=Button(buttonframe, text='OK', command=self.callback)
b1.pack(side=LEFT)
#b2=Button(buttonframe, text='Cancel', command=self.cancelled)
#b2.pack(side=LEFT)
self.bind("<Return>", self.callback)
#self.bind("<Escape>", self.cancelled)
def getArguments(self):
pass
self.initial_focus = self
self.initial_focus.focus_set()
#self.wait_window(self)
### must override this function ###
### with the validation checking ###
### must return None if error, ###
### and non_null if ok ###
def callback(self, event=None):
g=self.getArguments()
if not g:
self.initial_focus.focus_set()
return
self.withdraw()
self.update_idletasks()
def make_options(self):
pass
self.assign(g)
self.cancelled()
### must override this function ###
### with the entry forms ###
### be sure to use pack or a ###
### frame that is packed into self ###
def assign(self, obj):
pass
def getArguments(self):
pass
### must override this function ###
### to do the assignment in sim ###
### must override this function ###
### with the validation checking ###
### must return None if error, ###
### and non_null if ok ###
def cancelled(self,event=None):
self.sim.cwin.focus_set()
self.destroy()
def callback(self, event=None):
g=self.getArguments()
if not g:
self.initial_focus.focus_set()
return
self.withdraw()
self.update_idletasks()
self.assign(g)
self.cancelled()
def assign(self, obj):
pass
### must override this function ###
### to do the assignment in sim ###
def cancelled(self,event=None):
self.sim.cwin.focus_set()
self.destroy()
if __name__=='__main__':
t = Tk()
ControlWindow(t).mainloop()
t = Tk()
ControlWindow(t).mainloop()

View file

@ -21,11 +21,11 @@ def testit(e = None):
class DataFrame(Frame):
def __init__(self,master,top):
# if master==None:
# if master==None:
self.master = Toplevel()
self.master.protocol("WM_DELETE_WINDOW",self.hide)
#else:
# self.master = master
# self.master = master
#self.vis = vis
Frame.__init__(self,self.master)
@ -57,7 +57,7 @@ class DataFrame(Frame):
Label(self.scframe,text='Grid Point').grid(column=0,row=0)
self.sc.grid(row=0,column=1)
self.sc.bind('<ButtonRelease-1>',self.updateState)
self.gr.grid(row=4,column=0,columnspan=10)
self.gr.grid(row=4,column=0,columnspan=10)
self.grid(column=0,row=10)
self.makeMenu()
@ -69,7 +69,7 @@ class DataFrame(Frame):
self.menubar.grid(row=0,column=0,sticky=N+W+E,columnspan=10)
f = [('Open...',self.browseForDatafile)]
#make_menu('File',self.menubar,items)
make_menu('File',self.menubar,f)
make_menu('File',self.menubar,f)
make_menu('Dataset',self.menubar,self.datasets)
make_menu('Plot',self.menubar,self.vars)
@ -87,7 +87,7 @@ class DataFrame(Frame):
fname = os.path.basename(self.datafile.get())
ff = os.path.splitext(fname)
self.datasets = []
if len(ff) == 2 and (ff[1] == '.xml' or ff[1] == '.ctml'):
if len(ff) == 2 and (ff[1] == '.xml' or ff[1] == '.ctml'):
x = XML.XML_Node('root',src=self.datafile.get())
c = x.child('ctml')
@ -100,9 +100,9 @@ class DataFrame(Frame):
i += 1
self.solnid.set(self.solns[-1]['id'])
self.soln = self.solns[-1]
self.importData()
elif len(ff) == 2 and (ff[1] == '.csv' or ff[1] == '.CSV'):
self.importCSV()
@ -143,7 +143,7 @@ class DataFrame(Frame):
fdata[j,n] = float(v[j])
except:
fdata[j,n] = 0.0
self.nsp = self.g.nSpecies()
self.y = zeros(self.nsp,'d')
self.data = zeros((self.nsp+6,self.np),'d')
@ -159,29 +159,29 @@ class DataFrame(Frame):
v2 = vars[n]
if v2 == 'T':
self.data[T_LOC,:] = fdata[n,:]
self.label[T_LOC] = vars[n]
self.label[T_LOC] = vars[n]
w.append(('T', self.newplot, 'check', self.loc, T_LOC))
elif v2 == 'P':
self.data[P_LOC,:] = fdata[n,:]
self.label[P_LOC] = vars[n]
self.label[P_LOC] = vars[n]
w.append((vars[n], self.newplot, 'check', self.loc, P_LOC))
elif v2 == 'u':
self.data[U_LOC,:] = fdata[n,:]
self.label[U_LOC] = vars[n]
self.label[U_LOC] = vars[n]
w.append((vars[n], self.newplot, 'check', self.loc, U_LOC))
elif v2 == 'V':
self.data[V_LOC,:] = fdata[n,:]
self.label[V_LOC] = vars[n]
self.label[V_LOC] = vars[n]
w.append((vars[n], self.newplot, 'check', self.loc, V_LOC))
elif k >= 0:
self.data[k+Y_LOC,:] = fdata[n,:]
self.label[k+Y_LOC] = vars[n]
self.label[k+Y_LOC] = vars[n]
w.append((vars[n], self.newplot, 'check', self.loc, k + Y_LOC))
if self.data[P_LOC,0] == 0.0:
self.data[P_LOC,:] = ones(self.np,'d')*OneAtm
print 'Warning: no pressure data. P set to 1 atm.'
print 'Warning: no pressure data. P set to 1 atm.'
self.sc.config(cnf={'from':0,'to':self.np-1})
if self.loc.get() <= 0:
self.loc.set(self.lastloc)
@ -189,12 +189,12 @@ class DataFrame(Frame):
self.vars = w
#self.makeMenu()
self.scframe.grid(row=5,column=0,columnspan=10)
self.scframe.grid(row=5,column=0,columnspan=10)
def pickSoln(self):
self.solnid.set(self.solns[self.whichsoln.get()]['id'])
self.soln = self.solns[self.whichsoln.get()]
self.soln = self.solns[self.whichsoln.get()]
# self.t.destroy()
self.importData()
@ -208,10 +208,10 @@ class DataFrame(Frame):
self.ydata = None
if self.plt:
self.plt.destroy()
self.nsp = self.g.nSpecies()
self.label = ['-']*(self.nsp + 6)
self.y = zeros(self.nsp,'d')
gdata = self.soln.child('flowfield/grid_data')
xp = self.soln.child('flowfield').children('float')
@ -236,23 +236,23 @@ class DataFrame(Frame):
self.label[0] = t
elif k >= 0:
self.data[k + Y_LOC] = v
self.label[k + Y_LOC] = t
self.label[k + Y_LOC] = t
w.append((t, self.newplot, 'check', self.loc, k + Y_LOC))
elif t == 'T':
self.data[T_LOC,:] = v
self.label[T_LOC] = t
self.label[T_LOC] = t
w.append((t, self.newplot, 'check', self.loc, T_LOC))
elif t == 'u':
self.data[U_LOC,:] = v
self.label[U_LOC] = t
self.label[U_LOC] = t
w.append((t, self.newplot, 'check', self.loc, U_LOC))
elif t == 'V':
self.data[V_LOC,:] = v
self.label[V_LOC] = t
self.label[V_LOC] = t
w.append((t, self.newplot, 'check', self.loc, V_LOC))
self.data[P_LOC,:] = ones(self.np,'d')*p
self.label[P_LOC] = 'P (Pa)'
self.label[P_LOC] = 'P (Pa)'
self.sc.config(cnf={'from':0,'to':self.np-1})
if self.loc.get() <= 0:
self.loc.set(self.lastloc)
@ -356,9 +356,4 @@ class DataFrame(Frame):
i = i + 1
ymin = fctr*math.floor(ymin/fctr)
ymax = fctr*(math.floor(ymax/fctr + 1))
return (ymin, ymax, fctr)
return (ymin, ymax, fctr)

View file

@ -4,228 +4,226 @@ import math
from Cantera.num import *
def plotLimits(ypts, f=0.0, ndiv=5, logscale=0):
"""Return plot limits that"""
if logscale:
threshold = 1.0e-19
else:
threshold = -1.0e20
ymax = -1.e20
ymin = 1.e20
for y in ypts:
if y > ymax: ymax = y
if y < ymin and y > threshold: ymin = y
"""Return plot limits that"""
if logscale:
threshold = 1.0e-19
else:
threshold = -1.0e20
ymax = -1.e20
ymin = 1.e20
for y in ypts:
if y > ymax: ymax = y
if y < ymin and y > threshold: ymin = y
dy = abs(ymax - ymin)
dy = abs(ymax - ymin)
if logscale:
ymin = math.floor(math.log10(ymin))
ymax = math.floor(math.log10(ymax))+1
fctr = 1.0
if logscale:
ymin = math.floor(math.log10(ymin))
ymax = math.floor(math.log10(ymax))+1
fctr = 1.0
## if dy < 0.2*ymin:
## ymin = ymin*.9
## ymax = ymax*1.1
## dy = abs(ymax - ymin)
## else:
else:
ymin = ymin - f*dy
ymax = ymax + f*dy
dy = abs(ymax - ymin)
else:
ymin = ymin - f*dy
ymax = ymax + f*dy
dy = abs(ymax - ymin)
try:
p10 = math.floor(math.log10(0.1*dy))
fctr = math.pow(10.0, p10)
except:
return (ymin -1.0, ymax + 1.0, 1.0)
mm = [2.0, 2.5, 2.0]
i = 0
while dy/fctr > ndiv:
fctr = mm[i % 3]*fctr
i = i + 1
ymin = fctr*math.floor(ymin/fctr)
ymax = fctr*(math.floor(ymax/fctr+0.999))
try:
p10 = math.floor(math.log10(0.1*dy))
fctr = math.pow(10.0, p10)
except:
return (ymin -1.0, ymax + 1.0, 1.0)
mm = [2.0, 2.5, 2.0]
i = 0
while dy/fctr > ndiv:
fctr = mm[i % 3]*fctr
i = i + 1
ymin = fctr*math.floor(ymin/fctr)
ymax = fctr*(math.floor(ymax/fctr+0.999))
return (ymin, ymax, fctr)
return (ymin, ymax, fctr)
class DataGraph(Frame):
def __init__(self,master,
data, ix=0, iy=0,
title='',
label = ('x-axis','y-axis'),
logscale = (0,0),
pixelX=500,
pixelY=500):
data, ix=0, iy=0,
title='',
label = ('x-axis','y-axis'),
logscale = (0,0),
pixelX=500,
pixelY=500):
self.logscale = logscale
self.data = data
self.ix = ix
self.iy = iy
self.data = data
self.ix = ix
self.iy = iy
self.minX, self.maxX, self.dx = plotLimits(data[ix,:],
logscale=self.logscale[0])
self.minY, self.maxY, self.dy = plotLimits(data[iy,:],
logscale=self.logscale[1])
logscale=self.logscale[0])
self.minY, self.maxY, self.dy = plotLimits(data[iy,:],
logscale=self.logscale[1])
Frame.__init__(self,master, relief=RIDGE, bd=2)
self.title = Label(self,text=' ')
self.title.grid(row=0,column=1,sticky=W+E)
self.graph_w, self.graph_h = pixelX - 120, pixelY - 70
self.origin = (100, 20)
self.canvas = Canvas(self,
width=pixelX,
height=pixelY,
relief=SUNKEN,bd=1)
id = self.canvas.create_rectangle(self.origin[0],self.origin[1],
self.title = Label(self,text=' ')
self.title.grid(row=0,column=1,sticky=W+E)
self.graph_w, self.graph_h = pixelX - 120, pixelY - 70
self.origin = (100, 20)
self.canvas = Canvas(self,
width=pixelX,
height=pixelY,
relief=SUNKEN,bd=1)
id = self.canvas.create_rectangle(self.origin[0],self.origin[1],
pixelX-20,pixelY-50)
self.canvas.grid(row=1,column=1,rowspan=2,sticky=N+S+E+W)
self.last_points=[]
self.canvas.grid(row=1,column=1,rowspan=2,sticky=N+S+E+W)
self.last_points=[]
self.ticks(self.minX, self.maxX, self.dx,
self.minY, self.maxY, self.dy, 10)
self.screendata()
self.draw()
self.canvas.create_text(self.origin[0] + self.graph_w/2,
self.origin[1] + self.graph_h + 30,
text=label[0],anchor=N)
self.canvas.create_text(self.origin[0] - 50,
self.origin[1] + self.graph_h/2,
text=label[1],anchor=E)
self.minY, self.maxY, self.dy, 10)
self.screendata()
self.draw()
self.canvas.create_text(self.origin[0] + self.graph_w/2,
self.origin[1] + self.graph_h + 30,
text=label[0],anchor=N)
self.canvas.create_text(self.origin[0] - 50,
self.origin[1] + self.graph_h/2,
text=label[1],anchor=E)
def writeValue(self, y):
yval = '%15.4f' % (y)
self.title.config(text = yval)
yval = '%15.4f' % (y)
self.title.config(text = yval)
def delete(self, ids):
for id in ids:
self.canvas.delete(id)
self.canvas.delete(id)
def screendata(self):
self.xdata = array(self.data[self.ix,:])
self.ydata = array(self.data[self.iy,:])
npts = len(self.ydata)
if self.logscale[0] > 0:
self.xdata = log10(self.xdata)
if self.logscale[1] > 0:
self.ydata = log10(self.ydata)
f = float(self.graph_w)/(self.maxX-self.minX)
self.xdata = (self.xdata - self.minX)*f + self.origin[0]
f = float(self.graph_h)/(self.maxY-self.minY)
self.ydata = (self.maxY - self.ydata)*f + self.origin[1]
self.xdata = array(self.data[self.ix,:])
self.ydata = array(self.data[self.iy,:])
npts = len(self.ydata)
if self.logscale[0] > 0:
self.xdata = log10(self.xdata)
if self.logscale[1] > 0:
self.ydata = log10(self.ydata)
f = float(self.graph_w)/(self.maxX-self.minX)
self.xdata = (self.xdata - self.minX)*f + self.origin[0]
f = float(self.graph_h)/(self.maxY-self.minY)
self.ydata = (self.maxY - self.ydata)*f + self.origin[1]
def toscreen(self,x,y):
if self.logscale[0] > 0:
x = log10(x)
if self.logscale[1] > 0:
y = log10(y)
f = float(self.graph_w)/(self.maxX-self.minX)
xx = (x - self.minX)*f + self.origin[0]
f = float(self.graph_h)/(self.maxY-self.minY)
yy = (self.maxY - y)*f + self.origin[1]
return (xx, yy)
if self.logscale[0] > 0:
x = log10(x)
if self.logscale[1] > 0:
y = log10(y)
f = float(self.graph_w)/(self.maxX-self.minX)
xx = (x - self.minX)*f + self.origin[0]
f = float(self.graph_h)/(self.maxY-self.minY)
yy = (self.maxY - y)*f + self.origin[1]
return (xx, yy)
def move(self, id, newpos, oldpos):
dxpt = (newpos[0] - oldpos[0])/(self.maxX-self.minX)*self.graph_w
dypt = -(newpos[1] - oldpos[1])/(self.maxY-self.minY)*self.graph_h
self.canvas.move(id, dxpt, dypt)
self.writeValue(newpos[1])
dypt = -(newpos[1] - oldpos[1])/(self.maxY-self.minY)*self.graph_h
self.canvas.move(id, dxpt, dypt)
self.writeValue(newpos[1])
def plot(self,n,color='black'):
xpt, ypt = self.toscreen(self.data[self.ix,n],
self.data[self.iy,n])
#xpt = (x-self.minX)/(self.maxX-self.minX)*float(self.graph_w) + self.origin[0]
#ypt = (self.maxY-y)/(self.maxY-self.minY)*float(self.graph_h) + self.origin[1]
id_ycross = self.canvas.create_line(xpt,self.graph_h+self.origin[1],xpt,self.origin[1],fill = 'gray')
id_xcross = self.canvas.create_line(self.origin[0],ypt,self.graph_w+self.origin[0],ypt,fill = 'gray')
id = self.canvas.create_oval(xpt-2,ypt-2,xpt+2,ypt+2,fill=color)
#self.writeValue(y)
s = '(%g, %g)' % (self.data[self.ix,n],self.data[self.iy,n])
if n > 0 and self.data[self.iy,n] > self.data[self.iy,n-1]:
idt = self.canvas.create_text(xpt+5,ypt+5,text=s,anchor=NW)
else:
idt = self.canvas.create_text(xpt+5,ypt-5,text=s,anchor=SW)
return [id,id_xcross,id_ycross, idt]
xpt, ypt = self.toscreen(self.data[self.ix,n],
self.data[self.iy,n])
#xpt = (x-self.minX)/(self.maxX-self.minX)*float(self.graph_w) + self.origin[0]
#ypt = (self.maxY-y)/(self.maxY-self.minY)*float(self.graph_h) + self.origin[1]
id_ycross = self.canvas.create_line(xpt,self.graph_h+self.origin[1],xpt,self.origin[1],fill = 'gray')
id_xcross = self.canvas.create_line(self.origin[0],ypt,self.graph_w+self.origin[0],ypt,fill = 'gray')
id = self.canvas.create_oval(xpt-2,ypt-2,xpt+2,ypt+2,fill=color)
#self.writeValue(y)
s = '(%g, %g)' % (self.data[self.ix,n],self.data[self.iy,n])
if n > 0 and self.data[self.iy,n] > self.data[self.iy,n-1]:
idt = self.canvas.create_text(xpt+5,ypt+5,text=s,anchor=NW)
else:
idt = self.canvas.create_text(xpt+5,ypt-5,text=s,anchor=SW)
return [id,id_xcross,id_ycross, idt]
def draw(self,color='red'):
npts = len(self.xdata)
for n in range(1,npts):
self.canvas.create_line(self.xdata[n-1],self.ydata[n-1],
self.xdata[n],self.ydata[n],fill=color)
npts = len(self.xdata)
for n in range(1,npts):
self.canvas.create_line(self.xdata[n-1],self.ydata[n-1],
self.xdata[n],self.ydata[n],fill=color)
def addLabel(self, y, orient=0):
if orient==0:
xpt, ypt = self.toscreen(y, 1.0)
ypt = self.origin[1] + self.graph_h + 5
self.canvas.create_text(xpt,ypt,text=y,anchor=N)
else:
xpt, ypt = self.toscreen(self.minX, y)
xpt = self.origin[0] - 5
self.canvas.create_text(xpt,ypt,text=y,anchor=E)
xpt, ypt = self.toscreen(y, 1.0)
ypt = self.origin[1] + self.graph_h + 5
self.canvas.create_text(xpt,ypt,text=y,anchor=N)
else:
xpt, ypt = self.toscreen(self.minX, y)
xpt = self.origin[0] - 5
self.canvas.create_text(xpt,ypt,text=y,anchor=E)
def addLegend(self,text,color=None):
m=Message(self,text=text,width=self.graph_w-10)
m.pack(side=BOTTOM)
if color:
m.config(fg=color)
m=Message(self,text=text,width=self.graph_w-10)
m.pack(side=BOTTOM)
if color:
m.config(fg=color)
def pauseWhenFinished(self):
self.wait_window()
self.wait_window()
def minorTicks(self, x0, x1, y, n, size, orient=0):
xtick = x0
dx = (x1 - x0)/float(n)
if orient == 0:
while xtick <= x1:
xx, yy = self.toscreen(xtick, y)
self.canvas.create_line(xx,yy,
xx,yy-size)
xtick += dx
else:
while xtick <= x1:
xx, yy = self.toscreen(y, xtick)
self.canvas.create_line(xx,yy,
xx+size,yy)
xtick += dx
def ticks(self, xmin, xmax, dx, ymin, ymax, dy, size):
if self.logscale[0]:
xmin = math.pow(10.0,xmin)
xmax = math.pow(10.0,xmax)
if self.logscale[1]:
ymin = math.pow(10.0,ymin)
ymax = math.pow(10.0,ymax)
dx = (x1 - x0)/float(n)
if orient == 0:
while xtick <= x1:
xx, yy = self.toscreen(xtick, y)
self.canvas.create_line(xx,yy,
xx,yy-size)
xtick += dx
else:
while xtick <= x1:
xx, yy = self.toscreen(y, xtick)
self.canvas.create_line(xx,yy,
xx+size,yy)
xtick += dx
n = 5
def ticks(self, xmin, xmax, dx, ymin, ymax, dy, size):
if self.logscale[0]:
xmin = math.pow(10.0,xmin)
xmax = math.pow(10.0,xmax)
if self.logscale[1]:
ymin = math.pow(10.0,ymin)
ymax = math.pow(10.0,ymax)
n = 5
ytick = ymin
while ytick <= ymax:
xx, yy = self.toscreen(xmin, ytick)
self.canvas.create_line(xx, yy, xx + size,yy)
self.addLabel(ytick,1)
xx, yy = self.toscreen(xmax, ytick)
self.canvas.create_line(xx, yy, xx - size,yy)
ytick0 = ytick
if self.logscale[1]:
ytick *= 10.0
n = 10
else: ytick = ytick + dy
if ytick <= ymax:
self.minorTicks(ytick0, ytick, xmin, n, 5, 1)
self.minorTicks(ytick0, ytick, xmax, n, -5, 1)
n = 5
xx, yy = self.toscreen(xmin, ytick)
self.canvas.create_line(xx, yy, xx + size,yy)
self.addLabel(ytick,1)
xx, yy = self.toscreen(xmax, ytick)
self.canvas.create_line(xx, yy, xx - size,yy)
ytick0 = ytick
if self.logscale[1]:
ytick *= 10.0
n = 10
else: ytick = ytick + dy
if ytick <= ymax:
self.minorTicks(ytick0, ytick, xmin, n, 5, 1)
self.minorTicks(ytick0, ytick, xmax, n, -5, 1)
n = 5
xtick = xmin
while xtick <= xmax:
xx, yy = self.toscreen(xtick, ymin)
self.canvas.create_line(xx, yy, xx, yy - size)
self.addLabel(xtick,0)
xx, yy = self.toscreen(xtick, ymax)
self.canvas.create_line(xx, yy, xx, yy + size)
if self.logscale[0]:
xtick *= 10.0
n = 10
else: xtick = xtick + dx
if xtick <= xmax:
self.minorTicks(xtick - dx, xtick, ymin, n, 5, 0)
self.minorTicks(xtick - dx, xtick, ymax, n, -5, 0)
xx, yy = self.toscreen(xtick, ymin)
self.canvas.create_line(xx, yy, xx, yy - size)
self.addLabel(xtick,0)
xx, yy = self.toscreen(xtick, ymax)
self.canvas.create_line(xx, yy, xx, yy + size)
if self.logscale[0]:
xtick *= 10.0
n = 10
else: xtick = xtick + dx
if xtick <= xmax:
self.minorTicks(xtick - dx, xtick, ymin, n, 5, 0)
self.minorTicks(xtick - dx, xtick, ymax, n, -5, 0)

View file

@ -7,188 +7,187 @@ from config import *
from SpeciesFrame import getSpecies
def testit():
pass
pass
class EditFrame(Frame):
def redraw(self):
try:
self.eframe.destroy()
self.sframe.destroy()
self.rframe.destroy()
except:
pass
self.addElementFrame()
self.addSpeciesFrame()
self.addReactionFrame()
def __init__(self, master, app):
Frame.__init__(self, master)
self.mix = app.mix
print self.mix, dir(self.mix)
self.app = app
self.master = master
self.master.title("Cantera Mechanism Editor")
self.redraw()
def addReactionFrame(self):
self.rframe = Frame(self)
self.rframe.config(relief=GROOVE,bd=4)
self.rframe.grid(row=2,column=0,columnspan=10,sticky=E+W)
b=Button(self.rframe,text='Reactions',command=testit)
b.grid(column=5, row=0)
def redraw(self):
try:
self.eframe.destroy()
self.sframe.destroy()
self.rframe.destroy()
except:
pass
self.addElementFrame()
self.addSpeciesFrame()
self.addReactionFrame()
def addElementFrame(self):
self.eframe = Frame(self)
self.eframe.config(relief=GROOVE,bd=4)
self.eframe.grid(row=0,column=0,columnspan=10,sticky=E+W)
self.element_labels = []
n = 0
for el in self.mix._mech.elementNames():
x = Label(self.eframe,text=el,fg='darkblue')
x.grid(column = n, row=0)
self.element_labels.append(x)
n = n + 1
b=Button(self.eframe,text='Element',command=self.chooseElements, default=ACTIVE)
b.grid(column=0, row=1, columnspan=10)
def __init__(self, master, app):
Frame.__init__(self, master)
self.mix = app.mix
print self.mix, dir(self.mix)
self.app = app
self.master = master
self.master.title("Cantera Mechanism Editor")
self.redraw()
def addReactionFrame(self):
self.rframe = Frame(self)
self.rframe.config(relief=GROOVE,bd=4)
self.rframe.grid(row=2,column=0,columnspan=10,sticky=E+W)
b=Button(self.rframe,text='Reactions',command=testit)
b.grid(column=5, row=0)
def addElementFrame(self):
self.eframe = Frame(self)
self.eframe.config(relief=GROOVE,bd=4)
self.eframe.grid(row=0,column=0,columnspan=10,sticky=E+W)
self.element_labels = []
n = 0
for el in self.mix._mech.elementNames():
x = Label(self.eframe,text=el,fg='darkblue')
x.grid(column = n, row=0)
self.element_labels.append(x)
n = n + 1
b=Button(self.eframe,text='Element',command=self.chooseElements, default=ACTIVE)
b.grid(column=0, row=1, columnspan=10)
def addSpeciesFrame(self):
self.sframe = Frame(self)
self.sframe.config(relief=GROOVE,bd=4)
self.sframe.grid(row=1,column=0,columnspan=10,sticky=E+W)
r = 0
c = 0
splist = self.app.species
self.spcheck = []
self.spec = []
for i in range(self.app.mech.nSpecies()):
self.spec.append(IntVar())
self.spec[i].set(1)
self.spcheck.append( Checkbutton(self.sframe,
text=splist[i].name,
variable=self.spec[i],
onvalue = 1, offvalue = 0) )
self.spcheck[i].grid(row = r, column = c, sticky = N+W)
self.spcheck[i].bind("<Button-3>", self.editSpecies)
c = c + 1
if c > 4:
c, r = 0, r + 1
def addSpeciesFrame(self):
self.sframe = Frame(self)
self.sframe.config(relief=GROOVE,bd=4)
self.sframe.grid(row=1,column=0,columnspan=10,sticky=E+W)
r = 0
c = 0
splist = self.app.species
self.spcheck = []
self.spec = []
for i in range(self.app.mech.nSpecies()):
self.spec.append(IntVar())
self.spec[i].set(1)
self.spcheck.append( Checkbutton(self.sframe,
text=splist[i].name,
variable=self.spec[i],
onvalue = 1, offvalue = 0) )
self.spcheck[i].grid(row = r, column = c, sticky = N+W)
self.spcheck[i].bind("<Button-3>", self.editSpecies)
c = c + 1
if c > 4:
c, r = 0, r + 1
def getspecies(self):
print getSpecies(self.mix.speciesNames(),
self.mix.speciesNames())
def editSpecies(self, event=None):
e = Toplevel(event.widget.master)
w = event.widget
txt = w.cget('text')
sp = self.app.mix.species[txt]
def getspecies(self):
print getSpecies(self.mix.speciesNames(),
self.mix.speciesNames())
# name, etc.
e1 = Frame(e, relief=FLAT)
self.addEntry(e1,'Name',0,0,sp.name)
self.addEntry(e1,'ID Tag',1,0,sp.id)
self.addEntry(e1,'Phase',2,0,sp.phase)
e1.grid(row=0,column=0)
def editSpecies(self, event=None):
e = Toplevel(event.widget.master)
w = event.widget
txt = w.cget('text')
sp = self.app.mix.species[txt]
# elements
elframe = Frame(e)
elframe.grid(row=1,column=0)
Label(elframe,text='Elemental Composition').grid(row=0,column=0,columnspan=2,sticky=E+W)
# name, etc.
e1 = Frame(e, relief=FLAT)
self.addEntry(e1,'Name',0,0,sp.name)
self.addEntry(e1,'ID Tag',1,0,sp.id)
self.addEntry(e1,'Phase',2,0,sp.phase)
e1.grid(row=0,column=0)
i = 0
for el in self.app.mech.elementNames():
self.addEntry(elframe,el,i,0,self.mech.nAtoms(sp, el))
i = i + 1
# elements
elframe = Frame(e)
elframe.grid(row=1,column=0)
Label(elframe,text='Elemental Composition').grid(row=0,column=0,columnspan=2,sticky=E+W)
# thermo
thframe = Frame(e)
thframe.grid(row=0,rowspan=2,column=1)
thframe.config(relief=GROOVE,bd=4)
i = 0
Label(thframe,text='Thermodynamic Properties').grid(row=0,
column=0, columnspan=4, sticky=E+W)
if isinstance(sp.thermoParam(),NasaPolynomial):
Label(thframe,text='Parametrization:').grid(row=1,column=1)
self.addEntry(thframe,'',2,0,'NasaPolynomial')
Label(thframe,text='Temperatures (min, mid, max):').grid(row=3,column=1)
self.addEntry(thframe,'',4,0,`sp.minTemp`)
self.addEntry(thframe,'',5,0,`sp.midTemp`)
self.addEntry(thframe,'',6,0,`sp.maxTemp`)
low = Frame(thframe)
low.config(relief=GROOVE,bd=4)
low.grid(row=1,rowspan=6,column=3,columnspan=2)
Label(low,text='Coefficients for the Low\n Temperature Range').grid(row=0,column=0,columnspan=2,sticky=E+W)
c = sp.thermoParam().coefficients(sp.minTemp)
for j in range(7):
self.addEntry(low,'a'+`j`,j+3,0,`c[j]`)
high = Frame(thframe)
high.config(relief=GROOVE,bd=4)
high.grid(row=1,rowspan=6,column=5,columnspan=2)
Label(high,text='Coefficients for the High\n Temperature Range').grid(row=0,column=0,columnspan=2,sticky=E+W)
c = sp.thermoParam().coefficients(sp.maxTemp)
for j in range(7):
self.addEntry(high,'a'+`j`,j+3,0,`c[j]`)
com = Frame(e)
com.grid(row=10,column=0,columnspan=5)
ok = Button(com,text='OK',default=ACTIVE)
ok.grid(row=0,column=0)
ok.bind('<1>',self.modifySpecies)
Button(com,text='Cancel',command=e.destroy).grid(row=0,column=1)
self.especies = e
def modifySpecies(self,event=None):
button = event.widget
e = self.especies
for fr in e.children.values():
for item in fr.children.values():
try:
print item.cget('selection')
except:
pass
e.destroy()
def addEntry(self,master,name,row,column,text):
if name:
Label(master, text=name).grid(row=row, column=column)
nm = Entry(master)
nm.grid(row=row, column=column+1)
nm.insert(END,text)
def chooseElements(self):
oldel = self.mix.g.elementNames()
newel = getElements(self.mix.g.elementNames())
removeList = []
for el in oldel:
if not el in newel:
removeList.append(el)
#self.app.mech.removeElements(removeList)
addList = []
for el in newel:
if not el in oldel:
addList.append(el)
#self.app.mech.addElements(addList)
try:
self.redraw()
self.app.makeWindows()
except:
handleError('Edit err')
self.app.mix = IdealGasMixture(self.app.mech)
self.mix = self.app.mix
nn = self.mix.speciesList[0].name
self.mix.set(temperature = 300.0, pressure = 101325.0, moles = {nn:1.0})
for label in self.element_labels:
label.destroy()
self.element_labels = []
n = 0
for el in self.mix._mech.elementList():
x = Label(self.eframe,text=el.symbol(),fg='darkblue')
x.grid(column = n, row=0)
self.element_labels.append(x)
n = n + 1
i = 0
for el in self.app.mech.elementNames():
self.addEntry(elframe,el,i,0,self.mech.nAtoms(sp, el))
i = i + 1
self.app.makeWindows()
# thermo
thframe = Frame(e)
thframe.grid(row=0,rowspan=2,column=1)
thframe.config(relief=GROOVE,bd=4)
i = 0
Label(thframe,text='Thermodynamic Properties').grid(row=0,
column=0, columnspan=4, sticky=E+W)
if isinstance(sp.thermoParam(),NasaPolynomial):
Label(thframe,text='Parametrization:').grid(row=1,column=1)
self.addEntry(thframe,'',2,0,'NasaPolynomial')
Label(thframe,text='Temperatures (min, mid, max):').grid(row=3,column=1)
self.addEntry(thframe,'',4,0,`sp.minTemp`)
self.addEntry(thframe,'',5,0,`sp.midTemp`)
self.addEntry(thframe,'',6,0,`sp.maxTemp`)
low = Frame(thframe)
low.config(relief=GROOVE,bd=4)
low.grid(row=1,rowspan=6,column=3,columnspan=2)
Label(low,text='Coefficients for the Low\n Temperature Range').grid(row=0,column=0,columnspan=2,sticky=E+W)
c = sp.thermoParam().coefficients(sp.minTemp)
for j in range(7):
self.addEntry(low,'a'+`j`,j+3,0,`c[j]`)
high = Frame(thframe)
high.config(relief=GROOVE,bd=4)
high.grid(row=1,rowspan=6,column=5,columnspan=2)
Label(high,text='Coefficients for the High\n Temperature Range').grid(row=0,column=0,columnspan=2,sticky=E+W)
c = sp.thermoParam().coefficients(sp.maxTemp)
for j in range(7):
self.addEntry(high,'a'+`j`,j+3,0,`c[j]`)
com = Frame(e)
com.grid(row=10,column=0,columnspan=5)
ok = Button(com,text='OK',default=ACTIVE)
ok.grid(row=0,column=0)
ok.bind('<1>',self.modifySpecies)
Button(com,text='Cancel',command=e.destroy).grid(row=0,column=1)
self.especies = e
def modifySpecies(self,event=None):
button = event.widget
e = self.especies
for fr in e.children.values():
for item in fr.children.values():
try:
print item.cget('selection')
except:
pass
e.destroy()
def addEntry(self,master,name,row,column,text):
if name:
Label(master, text=name).grid(row=row, column=column)
nm = Entry(master)
nm.grid(row=row, column=column+1)
nm.insert(END,text)
def chooseElements(self):
oldel = self.mix.g.elementNames()
newel = getElements(self.mix.g.elementNames())
removeList = []
for el in oldel:
if not el in newel:
removeList.append(el)
#self.app.mech.removeElements(removeList)
addList = []
for el in newel:
if not el in oldel:
addList.append(el)
#self.app.mech.addElements(addList)
try:
self.redraw()
self.app.makeWindows()
except:
handleError('Edit err')
self.app.mix = IdealGasMixture(self.app.mech)
self.mix = self.app.mix
nn = self.mix.speciesList[0].name
self.mix.set(temperature = 300.0, pressure = 101325.0, moles = {nn:1.0})
for label in self.element_labels:
label.destroy()
self.element_labels = []
n = 0
for el in self.mix._mech.elementList():
x = Label(self.eframe,text=el.symbol(),fg='darkblue')
x.grid(column = n, row=0)
self.element_labels.append(x)
n = n + 1
self.app.makeWindows()

View file

@ -34,7 +34,7 @@ class PeriodicTable(Frame):
self.control = Frame(self)
self.control.config(relief=GROOVE,bd=4)
Button(self.control, text = 'Display',command=self.show).pack(fill=X,pady=3, padx=10)
Button(self.control, text = 'Clear',command=self.clear).pack(fill=X,pady=3, padx=10)
Button(self.control, text = 'Clear',command=self.clear).pack(fill=X,pady=3, padx=10)
Button(self.control, text = ' OK ',command=self.get).pack(side=BOTTOM,
fill=X,pady=3, padx=10)
Button(self.control, text = 'Cancel',command=self.master.quit).pack(side=BOTTOM,
@ -64,7 +64,7 @@ class PeriodicTable(Frame):
self.c[e]['bg'] = self.color(e, sel=1)
def deselect(self, el):
e = string.capitalize(el)
e = string.capitalize(el)
self.c[e]['relief'] = FLAT
self.c[e]['bg'] = self.color(e, sel=0)
@ -72,7 +72,7 @@ class PeriodicTable(Frame):
for el in ellist:
ename = el
self.select(ename)
def setColors(self,event):
el = event.widget['text']
if event.widget['relief'] == RAISED:
@ -82,7 +82,7 @@ class PeriodicTable(Frame):
event.widget['relief'] = RAISED
back = self.color(el, sel=1)
event.widget['bg'] = back
def color(self, el, sel=0):
_normal = ['#88dddd','#dddd88','#dd8888']
_selected = ['#aaffff','#ffffaa','#ffaaaa']
@ -104,7 +104,7 @@ class PeriodicTable(Frame):
if self.c[el]['relief'] == RAISED:
selected.append(periodicTable[el])
showElementProperties(selected)
def get(self):
self.selected = []
names = _pos.keys()
@ -114,7 +114,7 @@ class PeriodicTable(Frame):
self.selected.append(periodicTable[el])
#self.master.quit()'
self.master.destroy()
def clear(self):
for el in _pos.keys():
self.c[el]['bg'] = self.color(el, sel=0)
@ -132,7 +132,7 @@ class ElementPropertyFrame(Frame):
row=0,
sticky=W+S,
padx=10,
pady=10)
pady=10)
for el in ellist:
Label(self,
text=el.name).grid(column=0,
@ -176,9 +176,7 @@ def showElementProperties(ellist):
m.title('Element Properties')
elem = []
ElementPropertyFrame(m, ellist).pack()
if __name__ == "__main__":
print getElements()

View file

@ -3,128 +3,126 @@ from Tkinter import *
import math
class Graph(Frame):
def __init__(self,master,title,minX,maxX,minY,maxY,pixelX=250,pixelY=250):
Frame.__init__(self,master, relief=RIDGE, bd=2)
# self.pack()
self.title = Label(self,text=' ')
self.title.grid(row=0,column=1,sticky=W+E)
self.graph_w, self.graph_h = pixelX, pixelY
self.maxX, self.maxY = maxX, maxY #float(math.floor(maxX + 1)), \
#float(math.floor(maxY + 1))
self.minX, self.minY = minX, minY # float(math.floor(minX)), float(math.floor(minY))
self.canvas = Canvas(self,
width=self.graph_w,
height=self.graph_h,
relief=SUNKEN,bd=1)
ymintext = "%8.1f" % (self.minY)
ymaxtext = "%8.1f" % (self.maxY)
self.ml=Label(self, text=ymintext)
self.mr=Label(self, text=ymaxtext)
self.ml.grid(row=2,column=0,sticky=S+E)
self.mr.grid(row=1,column=0,sticky=N+E)
self.canvas.grid(row=1,column=1,rowspan=2,sticky=N+S+E+W)
self.last_points=[]
def __init__(self,master,title,minX,maxX,minY,maxY,pixelX=250,pixelY=250):
Frame.__init__(self,master, relief=RIDGE, bd=2)
# self.pack()
self.title = Label(self,text=' ')
self.title.grid(row=0,column=1,sticky=W+E)
self.graph_w, self.graph_h = pixelX, pixelY
self.maxX, self.maxY = maxX, maxY #float(math.floor(maxX + 1)), \
#float(math.floor(maxY + 1))
self.minX, self.minY = minX, minY # float(math.floor(minX)), float(math.floor(minY))
self.canvas = Canvas(self,
width=self.graph_w,
height=self.graph_h,
relief=SUNKEN,bd=1)
ymintext = "%8.1f" % (self.minY)
ymaxtext = "%8.1f" % (self.maxY)
self.ml=Label(self, text=ymintext)
self.mr=Label(self, text=ymaxtext)
self.ml.grid(row=2,column=0,sticky=S+E)
self.mr.grid(row=1,column=0,sticky=N+E)
self.canvas.grid(row=1,column=1,rowspan=2,sticky=N+S+E+W)
self.last_points=[]
def writeValue(self, y):
yval = '%15.4f' % (y)
self.title.config(text = yval)
def delete(self, ids):
for id in ids:
self.canvas.delete(id)
def move(self, id, newpos, oldpos):
dxpt = (newpos[0] - oldpos[0])/(self.maxX-self.minX)*self.graph_w
dypt = -(newpos[1] - oldpos[1])/(self.maxY-self.minY)*self.graph_h
self.canvas.move(id, dxpt, dypt)
self.writeValue(newpos[1])
def plot(self,x,y,color='black'):
xpt = (x-self.minX)/(self.maxX-self.minX)*float(self.graph_w) + 1.5
ypt = (self.maxY-y)/(self.maxY-self.minY)*float(self.graph_h) - 1.5
id_ycross = self.canvas.create_line(xpt,self.graph_h,xpt,0,fill = 'gray')
id_xcross = self.canvas.create_line(0,ypt,self.graph_w,ypt,fill = 'gray')
id = self.canvas.create_oval(xpt-2,ypt-2,xpt+2,ypt+2,fill=color)
self.writeValue(y)
return [id,id_xcross,id_ycross]
def writeValue(self, y):
yval = '%15.4f' % (y)
self.title.config(text = yval)
def reset(self,minX,maxX,minY,maxY):
self.maxX, self.maxY = maxX, maxY
self.minX, self.minY = minX, minY
self.canvas.destroy()
self.canvas = Canvas(self,
width=self.graph_w,
height=self.graph_h,
relief=SUNKEN,bd=1)
self.canvas.create_text(4,2,text=self.maxY,anchor=NW)
self.canvas.create_text(4,self.graph_h,text=self.minY,anchor=SW)
self.ml["text"] = `minX`
self.mr["text"] = `maxX`
self.canvas.pack()
self.last_points = []
def delete(self, ids):
for id in ids:
self.canvas.delete(id)
def join(self,point_list):
i = 0
for pt in point_list:
x, y, color = pt
if self.last_points == []:
last_x, last_y, last_color = pt
else:
last_x, last_y, last_color = self.last_points[i]
i = i + 1
xpt = (x - self.minX)/(float(self.maxX - self.minX)/self.graph_w) + 1.5
ypt = (self.maxY-y)/(float(self.maxY - self.minY)/self.graph_h) - 1.5
last_xpt = (last_x - self.minX)/(float(self.maxX - self.minX)/self.graph_w) + 1.5
last_ypt = (self.maxY-last_y)/(float(self.maxY - self.minY)/self.graph_h) - 1.5
self.canvas.create_line(last_xpt,last_ypt,
xpt,ypt,fill=color)
self.last_points = point_list
self.canvas.update()
return
def move(self, id, newpos, oldpos):
dxpt = (newpos[0] - oldpos[0])/(self.maxX-self.minX)*self.graph_w
dypt = -(newpos[1] - oldpos[1])/(self.maxY-self.minY)*self.graph_h
self.canvas.move(id, dxpt, dypt)
self.writeValue(newpos[1])
def addLegend(self,text,color=None):
m=Message(self,text=text,width=self.graph_w-10)
m.pack(side=BOTTOM)
if color:
m.config(fg=color)
def plot(self,x,y,color='black'):
xpt = (x-self.minX)/(self.maxX-self.minX)*float(self.graph_w) + 1.5
ypt = (self.maxY-y)/(self.maxY-self.minY)*float(self.graph_h) - 1.5
id_ycross = self.canvas.create_line(xpt,self.graph_h,xpt,0,fill = 'gray')
id_xcross = self.canvas.create_line(0,ypt,self.graph_w,ypt,fill = 'gray')
id = self.canvas.create_oval(xpt-2,ypt-2,xpt+2,ypt+2,fill=color)
self.writeValue(y)
return [id,id_xcross,id_ycross]
def pauseWhenFinished(self):
self.wait_window()
def reset(self,minX,maxX,minY,maxY):
self.maxX, self.maxY = maxX, maxY
self.minX, self.minY = minX, minY
self.canvas.destroy()
self.canvas = Canvas(self,
width=self.graph_w,
height=self.graph_h,
relief=SUNKEN,bd=1)
self.canvas.create_text(4,2,text=self.maxY,anchor=NW)
self.canvas.create_text(4,self.graph_h,text=self.minY,anchor=SW)
self.ml["text"] = `minX`
self.mr["text"] = `maxX`
self.canvas.pack()
self.last_points = []
def join(self,point_list):
i = 0
for pt in point_list:
x, y, color = pt
if self.last_points == []:
last_x, last_y, last_color = pt
else:
last_x, last_y, last_color = self.last_points[i]
i = i + 1
xpt = (x - self.minX)/(float(self.maxX - self.minX)/self.graph_w) + 1.5
ypt = (self.maxY-y)/(float(self.maxY - self.minY)/self.graph_h) - 1.5
last_xpt = (last_x - self.minX)/(float(self.maxX - self.minX)/self.graph_w) + 1.5
last_ypt = (self.maxY-last_y)/(float(self.maxY - self.minY)/self.graph_h) - 1.5
self.canvas.create_line(last_xpt,last_ypt,
xpt,ypt,fill=color)
self.last_points = point_list
self.canvas.update()
return
def addLegend(self,text,color=None):
m=Message(self,text=text,width=self.graph_w-10)
m.pack(side=BOTTOM)
if color:
m.config(fg=color)
def pauseWhenFinished(self):
self.wait_window()
if __name__=='__main__':
root= Tk()
g = Graph(root,'graph1',0,10,0.01,120)
h = Graph(root,'graph2',0,15,0,20000)
g.pack(side=LEFT)
h.pack(side=RIGHT)
root= Tk()
g = Graph(root,'graph1',0,10,0.01,120)
h = Graph(root,'graph2',0,15,0,20000)
g.pack(side=LEFT)
h.pack(side=RIGHT)
#root.protocol("WM_DELETE_WINDOW", root.destroy())
j = Graph(root,'Graph',0,1000,0,2000)
j.pack()
#root.protocol("WM_DELETE_WINDOW", root.destroy())
j = Graph(root,'Graph',0,1000,0,2000)
j.pack()
j.plot(0, 0, color='red')
j.last_points = [ (0, 0, 'red') ]
for i in range(100):
j.join( [ ( (i*10),(i*10+500), 'red' ) ] )
j.plot(0, 0, color='red')
j.last_points = [ (0, 0, 'red') ]
for i in range(100):
j.join( [ ( (i*10),(i*10+500), 'red' ) ] )
g.addLegend('An example of the GraphFrame')
h.addLegend('This is where the legend goes')
for i in range(100):
if root:
x,y = float(i)/10, i
g.plot(x,y,color='red')
h.plot(i,i**2)#(0,0)
#h.join([(i,i**2,'black')])
else:
break
#print("finished")
g.pauseWhenFinished()
h.pauseWhenFinished()
print g
g.addLegend('An example of the GraphFrame')
h.addLegend('This is where the legend goes')
for i in range(100):
if root:
x,y = float(i)/10, i
g.plot(x,y,color='red')
h.plot(i,i**2)#(0,0)
#h.join([(i,i**2,'black')])
else:
break
#print("finished")
g.pauseWhenFinished()
h.pauseWhenFinished()
print g

View file

@ -5,119 +5,119 @@ from Cantera import *
from tkFileDialog import askopenfilename
class ImportFrame(Frame):
def __init__(self,top):
self.master = Toplevel()
self.master.title('Convert and Import CK File')
self.master.protocol("WM_DELETE_WINDOW",self.hide)
Frame.__init__(self,self.master)
self.config(relief=GROOVE, bd=4)
self.top = top
self.infile = StringVar()
def __init__(self,top):
self.master = Toplevel()
self.master.title('Convert and Import CK File')
self.master.protocol("WM_DELETE_WINDOW",self.hide)
Label(self,text="Input File").grid(row=0,column=0)
Entry(self, width=40,
textvariable=self.infile).grid(column=1,row=0)
Button(self, text='Browse',
command=self.browseForInput).grid(row=0,column=2)
Frame.__init__(self,self.master)
self.config(relief=GROOVE, bd=4)
self.top = top
self.infile = StringVar()
self.thermo = StringVar()
Label(self,text="Thermodynamic Database").grid(row=1,column=0)
Entry(self, width=40,
textvariable=self.thermo).grid(column=1,row=1)
Button(self, text='Browse',
command=self.browseForThermo).grid(row=1,column=2)
Label(self,text="Input File").grid(row=0,column=0)
Entry(self, width=40,
textvariable=self.infile).grid(column=1,row=0)
Button(self, text='Browse',
command=self.browseForInput).grid(row=0,column=2)
self.thermo = StringVar()
Label(self,text="Thermodynamic Database").grid(row=1,column=0)
Entry(self, width=40,
textvariable=self.thermo).grid(column=1,row=1)
Button(self, text='Browse',
command=self.browseForThermo).grid(row=1,column=2)
self.transport = StringVar()
Label(self,text="Transport Database").grid(row=2,column=0)
Entry(self, width=40,
textvariable=self.transport).grid(column=1,row=2)
Button(self, text='Browse',
command=self.browseForTransport).grid(row=2,column=2)
self.transport = StringVar()
Label(self,text="Transport Database").grid(row=2,column=0)
Entry(self, width=40,
textvariable=self.transport).grid(column=1,row=2)
Button(self, text='Browse',
command=self.browseForTransport).grid(row=2,column=2)
bframe = Frame(self)
bframe.config(relief=GROOVE, bd=1)
bframe.grid(row=100,column=0)
Button(bframe, text='OK', width=8, command=self.importfile).grid(row=0,column=0)
self.grid(column=0,row=0)
Button(bframe, text='Cancel', width=8, command=self.hide).grid(row=0,column=1)
self.grid(column=0,row=0)
self.hide()
bframe = Frame(self)
bframe.config(relief=GROOVE, bd=1)
bframe.grid(row=100,column=0)
Button(bframe, text='OK', width=8, command=self.importfile).grid(row=0,column=0)
self.grid(column=0,row=0)
Button(bframe, text='Cancel', width=8, command=self.hide).grid(row=0,column=1)
self.grid(column=0,row=0)
self.hide()
def browseForInput(self, e=None):
pathname = askopenfilename(
filetypes=[("Reaction Mechanism Files",
("*.inp","*.mech","*.ck2")),
("All Files", "*.*")])
if pathname:
self.infile.set(pathname)
self.show()
def browseForInput(self, e=None):
pathname = askopenfilename(
filetypes=[("Reaction Mechanism Files",
("*.inp","*.mech","*.ck2")),
("All Files", "*.*")])
if pathname:
self.infile.set(pathname)
self.show()
def browseForThermo(self, e=None):
pathname = askopenfilename(
filetypes=[("Thermodynamic Databases",
("*.dat","*.inp","*.therm")),
("All Files", "*.*")])
if pathname:
self.thermo.set(pathname)
self.show()
def browseForThermo(self, e=None):
pathname = askopenfilename(
filetypes=[("Thermodynamic Databases",
("*.dat","*.inp","*.therm")),
("All Files", "*.*")])
if pathname:
self.thermo.set(pathname)
self.show()
def browseForTransport(self, e=None):
pathname = askopenfilename(
filetypes=[("Transport Databases", "*.dat"),
("All Files", "*.*")])
if pathname:
self.transport.set(pathname)
self.show()
def browseForTransport(self, e=None):
pathname = askopenfilename(
filetypes=[("Transport Databases", "*.dat"),
("All Files", "*.*")])
if pathname:
self.transport.set(pathname)
self.show()
def importfile(self):
ckfile = self.infile.get()
thermdb = self.thermo.get()
trandb = self.transport.get()
p = os.path.normpath(os.path.dirname(ckfile))
fname = os.path.basename(ckfile)
ff = os.path.splitext(fname)
nm = ""
if len(ff) > 1: nm = ff[0]
else: nm = ff
outfile = p+os.sep+nm+'.xml'
try:
print 'not supported.'
#ck2ctml(infile = ckfile, thermo = thermdb,
# transport = trandb, outfile = outfile,
# id = nm)
self.hide()
return
except:
print 'Errors were encountered. See log file ck2ctml.log'
self.hide()
return
self.top.loadmech(nm,outfile,1)
self.hide()
## cmd = 'ck2ctml -i '+ckfile+' -o '+outfile
## if thermdb <> "":
## cmd += ' -t '+thermdb
## if trandb <> "":
## cmd += ' -tr '+trandb
## cmd += ' -id '+nm
## ok = os.system(cmd)
## if ok == 0:
## self.top.loadmech(nm,outfile,1)
def importfile(self):
ckfile = self.infile.get()
thermdb = self.thermo.get()
trandb = self.transport.get()
p = os.path.normpath(os.path.dirname(ckfile))
fname = os.path.basename(ckfile)
ff = os.path.splitext(fname)
nm = ""
if len(ff) > 1: nm = ff[0]
else: nm = ff
outfile = p+os.sep+nm+'.xml'
try:
print 'not supported.'
#ck2ctml(infile = ckfile, thermo = thermdb,
# transport = trandb, outfile = outfile,
# id = nm)
self.hide()
return
except:
print 'Errors were encountered. See log file ck2ctml.log'
self.hide()
return
self.top.loadmech(nm,outfile,1)
self.hide()
## cmd = 'ck2ctml -i '+ckfile+' -o '+outfile
## if thermdb <> "":
## cmd += ' -t '+thermdb
## if trandb <> "":
## cmd += ' -tr '+trandb
## cmd += ' -id '+nm
## ok = os.system(cmd)
## if ok == 0:
## self.top.loadmech(nm,outfile,1)
def hide(self):
#self.vis.set(0)
self.master.withdraw()
def hide(self):
#self.vis.set(0)
self.master.withdraw()
def show(self):
#v = self.vis.get()
#if v == 0:
# self.hide()
# return
def show(self):
#v = self.vis.get()
#if v == 0:
# self.hide()
# return
self.master.deiconify()
self.master.deiconify()

View file

@ -11,408 +11,407 @@ _ATOL = 1.e-15
_RTOL = 1.e-7
def showsvg():
f = open('_rp_svg.html','w')
f.write('<embed src="rxnpath.svg" name="rxnpath" height=500\n')
f.write('type="image/svg-xml" pluginspage="http://www.adobe.com/svg/viewer/install/">\n')
f.close()
webbrowser.open('file:///'+os.getcwd()+'/_rp_svg.html')
f = open('_rp_svg.html','w')
f.write('<embed src="rxnpath.svg" name="rxnpath" height=500\n')
f.write('type="image/svg-xml" pluginspage="http://www.adobe.com/svg/viewer/install/">\n')
f.close()
webbrowser.open('file:///'+os.getcwd()+'/_rp_svg.html')
def showpng():
f = open('_rp_png.html','w')
f.write('<img src="rxnpath.png" height=500/>\n')
f.close()
webbrowser.open('file:///'+os.getcwd()+'/_rp_png.html')
f = open('_rp_png.html','w')
f.write('<img src="rxnpath.png" height=500/>\n')
f.close()
webbrowser.open('file:///'+os.getcwd()+'/_rp_png.html')
class KineticsFrame(Frame):
def __init__(self,master):
Frame.__init__(self,master)
self.config(relief=FLAT, bd=4)
self.top = self.master.top
self.controls=Frame(self)
self.hide = IntVar()
self.hide.set(0)
self.comp = IntVar()
self.comp.set(2)
self.controls.grid(column=1,row=0,sticky=W+E+N)
self.makeControls()
mf = self.master
def makeControls(self):
Radiobutton(self.controls,text='Creation Rates',
variable=self.comp,value=0,
command=self.show).grid(column=0,row=0,sticky=W)
Radiobutton(self.controls,text='Destruction Rates',
variable=self.comp,value=1,
command=self.show).grid(column=0,row=1,sticky=W)
Radiobutton(self.controls,text='Net Production Rates',
variable=self.comp,value=2,
command=self.show).grid(column=0,row=2,sticky=W)
def __init__(self,master):
Frame.__init__(self,master)
self.config(relief=FLAT, bd=4)
self.top = self.master.top
self.controls=Frame(self)
self.hide = IntVar()
self.hide.set(0)
self.comp = IntVar()
self.comp.set(2)
self.controls.grid(column=1,row=0,sticky=W+E+N)
self.makeControls()
mf = self.master
def show(self):
mf = self.master
mf.active = self
c = self.comp.get()
mix = self.top.mix
g = mix.g
if c == 0:
mf.var.set("Creation Rates")
#mf.data = spdict(mix.g, mix.moles())
mf.comp = g.creationRates()
def makeControls(self):
Radiobutton(self.controls,text='Creation Rates',
variable=self.comp,value=0,
command=self.show).grid(column=0,row=0,sticky=W)
Radiobutton(self.controls,text='Destruction Rates',
variable=self.comp,value=1,
command=self.show).grid(column=0,row=1,sticky=W)
Radiobutton(self.controls,text='Net Production Rates',
variable=self.comp,value=2,
command=self.show).grid(column=0,row=2,sticky=W)
elif c == 1:
mf.var.set("Destruction Rates")
#mf.data = spdict(mix.g,mix.mass())
mf.comp = g.destructionRates()
def show(self):
mf = self.master
mf.active = self
c = self.comp.get()
mix = self.top.mix
g = mix.g
if c == 0:
mf.var.set("Creation Rates")
#mf.data = spdict(mix.g, mix.moles())
mf.comp = g.creationRates()
elif c == 2:
mf.var.set("Net Production Rates")
mf.comp = g.netProductionRates()
#mf.data = spdict(mix,mix,mf.comp)
for s in mf.variable.keys():
try:
k = g.speciesIndex(s)
if mf.comp[k] > _CUTOFF or -mf.comp[k] > _CUTOFF:
mf.variable[s].set(mf.comp[k])
else:
mf.variable[s].set(0.0)
except:
pass
elif c == 1:
mf.var.set("Destruction Rates")
#mf.data = spdict(mix.g,mix.mass())
mf.comp = g.destructionRates()
elif c == 2:
mf.var.set("Net Production Rates")
mf.comp = g.netProductionRates()
#mf.data = spdict(mix,mix,mf.comp)
for s in mf.variable.keys():
try:
k = g.speciesIndex(s)
if mf.comp[k] > _CUTOFF or -mf.comp[k] > _CUTOFF:
mf.variable[s].set(mf.comp[k])
else:
mf.variable[s].set(0.0)
except:
pass
class SpeciesKineticsFrame(Frame):
def __init__(self,master,top):
Frame.__init__(self,master)
self.config(relief=GROOVE, bd=4)
self.top = top
self.top.kinetics = self
self.g = self.top.mix.g
self.entries=Frame(self)
self.var = StringVar()
self.var.set("Net Production Rates")
self.names = self.top.mix.speciesNames()
self.nsp = len(self.names)
self.comp = [0.0]*self.nsp
self.makeControls()
self.makeEntries()
self.entries.bind('<Double-l>',self.minimize)
self.ctype = 0
def makeControls(self):
self.c = KineticsFrame(self)
#self.rr = ReactionKineticsFrame(self, self.top)
self.c.grid(column=1,row=0,sticky=E+W+N+S)
#self.rr.grid(column=0,row=1,sticky=E+W+N+S)
def __init__(self,master,top):
Frame.__init__(self,master)
self.config(relief=GROOVE, bd=4)
self.top = top
self.top.kinetics = self
self.g = self.top.mix.g
self.entries=Frame(self)
self.var = StringVar()
self.var.set("Net Production Rates")
self.names = self.top.mix.speciesNames()
self.nsp = len(self.names)
self.comp = [0.0]*self.nsp
self.makeControls()
self.makeEntries()
self.entries.bind('<Double-l>',self.minimize)
self.ctype = 0
def show(self):
self.c.show()
def redo(self):
self.update()
self.entries.destroy()
self.entries=Frame(self)
self.makeEntries()
def makeControls(self):
self.c = KineticsFrame(self)
#self.rr = ReactionKineticsFrame(self, self.top)
self.c.grid(column=1,row=0,sticky=E+W+N+S)
#self.rr.grid(column=0,row=1,sticky=E+W+N+S)
def minimize(self,Event=None):
self.c.hide.set(1)
self.redo()
self.c.grid_forget()
self.entries.bind("<Double-1>",self.maximize)
def maximize(self,Event=None):
self.c.hide.set(0)
self.redo()
self.c.grid(column=1,row=0,sticky=E+W+N+S)
self.entries.bind("<Double-1>",self.minimize)
def show(self):
self.c.show()
def up(self, x):
self.update()
def makeEntries(self):
self.entries.grid(row=0,column=0,sticky=W+N+S+E)
self.entries.config(relief=FLAT,bd=4)
DATAKEYS = self.top.species
self.variable = {}
def redo(self):
self.update()
self.entries.destroy()
self.entries=Frame(self)
self.makeEntries()
n=0
ncol = 3
col = 0
row = 60
def minimize(self,Event=None):
self.c.hide.set(1)
self.redo()
self.c.grid_forget()
self.entries.bind("<Double-1>",self.maximize)
for sp in DATAKEYS:
s = sp
k = s.index
if row > 15:
row = 0
col = col + 2
l = Label(self.entries,text='Species')
l.grid(column=col,row=row,sticky=E+W)
e1 = Entry(self.entries)
e1.grid(column=col+1,row=row,sticky=E+W)
e1['textvariable'] = self.var
e1.config(state=DISABLED)
e1.config(bg='lightyellow',relief=RIDGE)
row = row + 1
def maximize(self,Event=None):
self.c.hide.set(0)
self.redo()
self.c.grid(column=1,row=0,sticky=E+W+N+S)
self.entries.bind("<Double-1>",self.minimize)
spname = s.name
val = self.comp[k]
if not self.c.hide.get() or val: showit = 1
else: showit = 0
def up(self, x):
self.update()
l=SpeciesInfo(self.entries,species=s,
text=spname,relief=FLAT,justify=RIGHT,
fg='darkblue')
entry1 = Entry(self.entries)
self.variable[spname] = DoubleVar()
self.variable[spname].set(self.comp[k])
entry1['textvariable']=self.variable[spname]
entry1.bind('<Any-Leave>',self.up)
if showit:
l.grid(column= col ,row=row,sticky=E)
entry1.grid(column=col+1,row=row)
n=n+1
row = row + 1
entry1.config(state=DISABLED,bg='lightgray')
def makeEntries(self):
self.entries.grid(row=0,column=0,sticky=W+N+S+E)
self.entries.config(relief=FLAT,bd=4)
DATAKEYS = self.top.species
self.variable = {}
n=0
ncol = 3
col = 0
row = 60
for sp in DATAKEYS:
s = sp
k = s.index
if row > 15:
row = 0
col = col + 2
l = Label(self.entries,text='Species')
l.grid(column=col,row=row,sticky=E+W)
e1 = Entry(self.entries)
e1.grid(column=col+1,row=row,sticky=E+W)
e1['textvariable'] = self.var
e1.config(state=DISABLED)
e1.config(bg='lightyellow',relief=RIDGE)
row = row + 1
spname = s.name
val = self.comp[k]
if not self.c.hide.get() or val: showit = 1
else: showit = 0
l=SpeciesInfo(self.entries,species=s,
text=spname,relief=FLAT,justify=RIGHT,
fg='darkblue')
entry1 = Entry(self.entries)
self.variable[spname] = DoubleVar()
self.variable[spname].set(self.comp[k])
entry1['textvariable']=self.variable[spname]
entry1.bind('<Any-Leave>',self.up)
if showit:
l.grid(column= col ,row=row,sticky=E)
entry1.grid(column=col+1,row=row)
n=n+1
row = row + 1
entry1.config(state=DISABLED,bg='lightgray')
class ReactionKineticsFrame(Frame):
def __init__(self,vis,top):
self.master = Toplevel()
self.master.protocol("WM_DELETE_WINDOW",self.hide)
self.vis = vis
Frame.__init__(self,self.master)
self.config(relief=GROOVE, bd=4)
self.top = top
self.g = self.top.mix.g
nr = self.g.nReactions()
self.eqs=Text(self,width=40,height=30)
self.data = []
self.start = DoubleVar()
if nr > 30:
self.end = self.start.get()+30
else:
self.end = self.start.get()+nr
for i in range(4):
self.data.append(Text(self,width=15,height=30))
def __init__(self,vis,top):
self.master = Toplevel()
self.master.protocol("WM_DELETE_WINDOW",self.hide)
self.vis = vis
Frame.__init__(self,self.master)
self.config(relief=GROOVE, bd=4)
self.top = top
self.g = self.top.mix.g
nr = self.g.nReactions()
self.eqs=Text(self,width=40,height=30)
self.data = []
self.start = DoubleVar()
if nr > 30:
self.end = self.start.get()+30
else:
self.end = self.start.get()+nr
for n in range(nr):
s = self.g.reactionEqn(n)
self.eqs.insert(END,s+'\n')
self.eqs.grid(column=0,row=1,sticky=W+E+N)
for i in range(4):
self.data[i].grid(column=i+1,row=1,sticky=W+E+N)
Label(self, text='Reaction').grid(column=0,row=0,sticky=W+E+N)
Label(self, text='Fwd ROP').grid(column=1,row=0,sticky=W+E+N)
Label(self, text='Rev ROP').grid(column=2,row=0,sticky=W+E+N)
Label(self, text='Net ROP').grid(column=3,row=0,sticky=W+E+N)
Label(self, text='Kp').grid(column=4,row=0,sticky=W+E+N)
for i in range(4):
self.data.append(Text(self,width=15,height=30))
self.scfr = Frame(self)
self.scfr.config(relief=GROOVE,bd=4)
for n in range(nr):
s = self.g.reactionEqn(n)
self.eqs.insert(END,s+'\n')
self.eqs.grid(column=0,row=1,sticky=W+E+N)
for i in range(4):
self.data[i].grid(column=i+1,row=1,sticky=W+E+N)
Label(self, text='Reaction').grid(column=0,row=0,sticky=W+E+N)
Label(self, text='Fwd ROP').grid(column=1,row=0,sticky=W+E+N)
Label(self, text='Rev ROP').grid(column=2,row=0,sticky=W+E+N)
Label(self, text='Net ROP').grid(column=3,row=0,sticky=W+E+N)
Label(self, text='Kp').grid(column=4,row=0,sticky=W+E+N)
## self.sc = Scrollbar(self.scfr,command=self.show,
## variable = self.start,
## orient='horizontal',length=400)
self.sc = Scale(self.scfr,command=self.show,
variable=self.start,
orient='vertical',length=400)
# self.sc.config(cnf={'from':0,'to':nr},variable = self.start)
#self.sc.bind('<Any-Enter>',self.couple)
#self.scfr.bind('<Any-Leave>',self.decouple)
self.sc.pack(side=RIGHT,fill=Y)
self.scfr.grid(row=0,column=6,rowspan=10,sticky=N+E+W)
self.grid(column=0,row=0)
self.scfr = Frame(self)
self.scfr.config(relief=GROOVE,bd=4)
self.hide()
## self.sc = Scrollbar(self.scfr,command=self.show,
## variable = self.start,
## orient='horizontal',length=400)
self.sc = Scale(self.scfr,command=self.show,
variable=self.start,
orient='vertical',length=400)
# self.sc.config(cnf={'from':0,'to':nr},variable = self.start)
#self.sc.bind('<Any-Enter>',self.couple)
#self.scfr.bind('<Any-Leave>',self.decouple)
self.sc.pack(side=RIGHT,fill=Y)
self.scfr.grid(row=0,column=6,rowspan=10,sticky=N+E+W)
self.grid(column=0,row=0)
## def decouple(self,event=None):
## d = DoubleVar()
## xx = self.start.get()
## d.set(xx)
## self.sc.config(variable = d)
## def couple(self,event=None):
## self.sc.config(variable = self.start)
def hide(self):
# self.vis.set(0)
self.master.withdraw()
def show(self,e=None,b=None,c=None):
v = self.vis.get()
print e,b,c
#if v == 0:
# self.hide()
# return
self.master.deiconify()
nr = self.g.nReactions()
frop = self.g.fwdRatesOfProgress()
rrop = self.g.revRatesOfProgress()
kp = self.g.equilibriumConstants()
self.data[0].delete(1.0,END)
self.data[1].delete(1.0,END)
self.data[2].delete(1.0,END)
self.data[3].delete(1.0,END)
self.eqs.delete(1.0,END)
self.hide()
n0 = int(self.start.get())
nn = nr - n0
if nn > 30: nn = 30
for n in range(n0, nn+n0):
s = '%12.5e \n' % (frop[n],)
self.data[0].insert(END,s)
s = '%12.5e \n' % (rrop[n],)
self.data[1].insert(END,s)
s = '%12.5e \n' % (frop[n] - rrop[n],)
self.data[2].insert(END,s)
s = '%12.5e \n' % (kp[n],)
self.data[3].insert(END,s)
self.eqs.insert(END, self.g.reactionEqn(n)+'\n')
## def decouple(self,event=None):
## d = DoubleVar()
## xx = self.start.get()
## d.set(xx)
## self.sc.config(variable = d)
## def couple(self,event=None):
## self.sc.config(variable = self.start)
def hide(self):
# self.vis.set(0)
self.master.withdraw()
def show(self,e=None,b=None,c=None):
v = self.vis.get()
print e,b,c
#if v == 0:
# self.hide()
# return
self.master.deiconify()
nr = self.g.nReactions()
frop = self.g.fwdRatesOfProgress()
rrop = self.g.revRatesOfProgress()
kp = self.g.equilibriumConstants()
self.data[0].delete(1.0,END)
self.data[1].delete(1.0,END)
self.data[2].delete(1.0,END)
self.data[3].delete(1.0,END)
self.eqs.delete(1.0,END)
n0 = int(self.start.get())
nn = nr - n0
if nn > 30: nn = 30
for n in range(n0, nn+n0):
s = '%12.5e \n' % (frop[n],)
self.data[0].insert(END,s)
s = '%12.5e \n' % (rrop[n],)
self.data[1].insert(END,s)
s = '%12.5e \n' % (frop[n] - rrop[n],)
self.data[2].insert(END,s)
s = '%12.5e \n' % (kp[n],)
self.data[3].insert(END,s)
self.eqs.insert(END, self.g.reactionEqn(n)+'\n')
class ReactionPathFrame(Frame):
def __init__(self,top):
self.master = Toplevel()
self.master.protocol("WM_DELETE_WINDOW",self.hide)
#self.vis = vis
Frame.__init__(self,self.master)
self.config(relief=GROOVE, bd=4)
self.grid(column=0,row=0)
self.top = top
self.g = self.top.mix.g
self.el = IntVar()
self.el.set(0)
self.thresh = DoubleVar()
scframe = Frame(self)
self.sc = Scale(scframe,variable = self.thresh,
orient='horizontal',digits=3,length=300,resolution=0.01)
self.sc.config(cnf={'from':-6,'to':0})
Label(scframe,text='log10 Threshold').grid(column=0,row=0)
self.sc.grid(row=0,column=1,columnspan=10)
self.sc.bind('<ButtonRelease-1>',self.show)
scframe.grid(row=3,column=0,columnspan=10)
enames = self.g.elementNames()
self.nel = len(enames)
i = 1
eframe = Frame(self)
Label(eframe,text='Element').grid(column=0,row=0,sticky=W)
for e in enames:
Radiobutton(eframe,text=e,
variable=self.el,value=i-1,
command=self.show).grid(column=i,row=0,sticky=W)
i += 1
eframe.grid(row=0,column=0)
def __init__(self,top):
self.master = Toplevel()
self.master.protocol("WM_DELETE_WINDOW",self.hide)
#self.vis = vis
Frame.__init__(self,self.master)
self.config(relief=GROOVE, bd=4)
self.grid(column=0,row=0)
self.top = top
self.g = self.top.mix.g
self.el = IntVar()
self.el.set(0)
self.thresh = DoubleVar()
self.detailed = IntVar()
Checkbutton(self, text = 'Show details', variable=self.detailed,
command=self.show).grid(column=1,row=0)
self.net = IntVar()
Checkbutton(self, text = 'Show net flux',
variable=self.net,
command=self.show).grid(column=2,row=0)
self.local = StringVar()
Label(self,text='Species').grid(column=1,row=1,sticky=E)
sp = Entry(self, textvariable=self.local,
width=15)
sp.grid(column=2,row=1)
sp.bind('<Any-Leave>',self.show)
self.b = rxnpath.PathBuilder(self.g)
scframe = Frame(self)
self.sc = Scale(scframe,variable = self.thresh,
orient='horizontal',digits=3,length=300,resolution=0.01)
self.sc.config(cnf={'from':-6,'to':0})
Label(scframe,text='log10 Threshold').grid(column=0,row=0)
self.sc.grid(row=0,column=1,columnspan=10)
self.sc.bind('<ButtonRelease-1>',self.show)
scframe.grid(row=3,column=0,columnspan=10)
self.fmt = StringVar()
self.fmt.set('svg')
i = 1
fmtframe = Frame(self)
fmtframe.config(relief=GROOVE, bd=4)
self.browser = IntVar()
self.browser.set(0)
Checkbutton(fmtframe, text = 'Display in Web Browser',
variable=self.browser,
command=self.show).grid(column=0,columnspan=6,row=0)
Label(fmtframe,text='Format').grid(column=0,row=1,sticky=W)
for e in ['svg', 'png', 'gif', 'jpg']:
Radiobutton(fmtframe,text=e,
variable=self.fmt,value=e,
command=self.show).grid(column=i,row=1,sticky=W)
i += 1
fmtframe.grid(row=5,column=0,columnspan=10,sticky=E+W)
self.cv = Canvas(self,relief=SUNKEN,bd=1)
self.cv.grid(column=0,row=4,sticky=W+E+N,columnspan=10)
enames = self.g.elementNames()
self.nel = len(enames)
pframe = Frame(self)
pframe.config(relief=GROOVE, bd=4)
self.dot = StringVar()
self.dot.set('dot -Tgif rxnpath.dot > rxnpath.gif')
Label(pframe,text='DOT command:').grid(column=0,row=0,sticky=W)
Entry(pframe,width=60,textvariable=self.dot).grid(column=0,
row=1,sticky=W)
pframe.grid(row=6,column=0,columnspan=10,sticky=E+W)
self.thresh.set(-2.0)
self.hide()
i = 1
eframe = Frame(self)
Label(eframe,text='Element').grid(column=0,row=0,sticky=W)
for e in enames:
Radiobutton(eframe,text=e,
variable=self.el,value=i-1,
command=self.show).grid(column=i,row=0,sticky=W)
i += 1
eframe.grid(row=0,column=0)
def hide(self):
#self.vis.set(0)
self.master.withdraw()
def show(self,e=None):
self.detailed = IntVar()
Checkbutton(self, text = 'Show details', variable=self.detailed,
command=self.show).grid(column=1,row=0)
self.net = IntVar()
Checkbutton(self, text = 'Show net flux',
variable=self.net,
command=self.show).grid(column=2,row=0)
self.local = StringVar()
Label(self,text='Species').grid(column=1,row=1,sticky=E)
sp = Entry(self, textvariable=self.local,
width=15)
sp.grid(column=2,row=1)
sp.bind('<Any-Leave>',self.show)
self.master.deiconify()
el = self.g.elementName(self.el.get())
det = 'false'
if self.detailed.get() == 1: det = 'true'
flow = 'one_way'
if self.net.get() == 1: flow = 'net'
self.d = rxnpath.PathDiagram(arrow_width=-2,
flow_type=flow,
detailed = det,
threshold=math.pow(10.0,
self.thresh.get()))
node = self.local.get()
try:
k = self.g.speciesIndex(node)
self.d.displayOnly(k)
except:
self.d.displayOnly()
self.b = rxnpath.PathBuilder(self.g)
self.b.build(element = el, diagram = self.d,
dotfile = 'rxnpath.dot', format = 'dot')
#self.b.build(element = el, diagram = self.d,
# dotfile = 'rxnpath.txt', format = 'plain')
self.fmt = StringVar()
self.fmt.set('svg')
i = 1
fmtframe = Frame(self)
fmtframe.config(relief=GROOVE, bd=4)
self.browser = IntVar()
self.browser.set(0)
Checkbutton(fmtframe, text = 'Display in Web Browser',
variable=self.browser,
command=self.show).grid(column=0,columnspan=6,row=0)
Label(fmtframe,text='Format').grid(column=0,row=1,sticky=W)
for e in ['svg', 'png', 'gif', 'jpg']:
Radiobutton(fmtframe,text=e,
variable=self.fmt,value=e,
command=self.show).grid(column=i,row=1,sticky=W)
i += 1
fmtframe.grid(row=5,column=0,columnspan=10,sticky=E+W)
if self.browser.get() == 1:
fmt = self.fmt.get()
os.system('dot -T'+fmt+' rxnpath.dot > rxnpath.'+fmt)
if fmt == 'svg': showsvg()
elif fmt == 'png': showpng()
else:
path = 'file:///'+os.getcwd()+'/rxnpath.'+fmt
webbrowser.open(path)
try:
self.cv.delete(self.image)
except:
pass
self.cv.configure(width=0, height=0)
else:
os.system(self.dot.get())
self.rp = None
try:
self.cv.delete(self.image)
except:
pass
try:
self.rp = PhotoImage(file='rxnpath.gif')
self.cv.configure(width=self.rp.width(),
height=self.rp.height())
self.image = self.cv.create_image(0,0,anchor=NW,
image=self.rp)
except:
pass
self.cv = Canvas(self,relief=SUNKEN,bd=1)
self.cv.grid(column=0,row=4,sticky=W+E+N,columnspan=10)
pframe = Frame(self)
pframe.config(relief=GROOVE, bd=4)
self.dot = StringVar()
self.dot.set('dot -Tgif rxnpath.dot > rxnpath.gif')
Label(pframe,text='DOT command:').grid(column=0,row=0,sticky=W)
Entry(pframe,width=60,textvariable=self.dot).grid(column=0,
row=1,sticky=W)
pframe.grid(row=6,column=0,columnspan=10,sticky=E+W)
self.thresh.set(-2.0)
self.hide()
def hide(self):
#self.vis.set(0)
self.master.withdraw()
def show(self,e=None):
self.master.deiconify()
el = self.g.elementName(self.el.get())
det = 'false'
if self.detailed.get() == 1: det = 'true'
flow = 'one_way'
if self.net.get() == 1: flow = 'net'
self.d = rxnpath.PathDiagram(arrow_width=-2,
flow_type=flow,
detailed = det,
threshold=math.pow(10.0,
self.thresh.get()))
node = self.local.get()
try:
k = self.g.speciesIndex(node)
self.d.displayOnly(k)
except:
self.d.displayOnly()
self.b.build(element = el, diagram = self.d,
dotfile = 'rxnpath.dot', format = 'dot')
#self.b.build(element = el, diagram = self.d,
# dotfile = 'rxnpath.txt', format = 'plain')
if self.browser.get() == 1:
fmt = self.fmt.get()
os.system('dot -T'+fmt+' rxnpath.dot > rxnpath.'+fmt)
if fmt == 'svg': showsvg()
elif fmt == 'png': showpng()
else:
path = 'file:///'+os.getcwd()+'/rxnpath.'+fmt
webbrowser.open(path)
try:
self.cv.delete(self.image)
except:
pass
self.cv.configure(width=0, height=0)
else:
os.system(self.dot.get())
self.rp = None
try:
self.cv.delete(self.image)
except:
pass
try:
self.rp = PhotoImage(file='rxnpath.gif')
self.cv.configure(width=self.rp.width(),
height=self.rp.height())
self.image = self.cv.create_image(0,0,anchor=NW,
image=self.rp)
except:
pass

View file

@ -10,7 +10,7 @@ _autoload = [
(' GRI-Mech 3.0', 'gri30.cti'),
(' Air', 'air.cti'),
(' H/O/Ar', 'h2o2.cti')
]
]
def testit():
pass
@ -18,41 +18,41 @@ def testit():
class MechManager(Frame):
def __init__(self,master,app):
Frame.__init__(self,master)
#self.config(relief=GROOVE, bd=4)
self.app = app
self.master = master
self.mechindx = IntVar()
self.mechindx.set(1)
#m = Label(self, text = 'Loaded Mechanisms')
#m.grid(column=0,row=0)
Frame.__init__(self,master)
#self.config(relief=GROOVE, bd=4)
self.app = app
self.master = master
self.mechindx = IntVar()
self.mechindx.set(1)
#m = Label(self, text = 'Loaded Mechanisms')
#m.grid(column=0,row=0)
# m.bind('<Double-1>',self.show)
# self.mechindx.set(0)
self.mechanisms = []
self.mlist = [ [] ]
i = 1
#for m in self.mechanisms:
# self.mlist.append((m[0], self.setMechanism, 'check', self.mechindx, i))
# i = i + 1
#self.mlist.append([])
self.mechanisms = []
self.mlist = [ [] ]
i = 1
#for m in self.mechanisms:
# self.mlist.append((m[0], self.setMechanism, 'check', self.mechindx, i))
# i = i + 1
#self.mlist.append([])
self.mechmenu = make_menu('Mixtures', self, self.mlist)
self.mechmenu.grid(row=0,column=0,sticky=W)
self.mechmenu = make_menu('Mixtures', self, self.mlist)
self.mechmenu.grid(row=0,column=0,sticky=W)
self.mfr = None
self.mfr = None
def addMechanism(self, name, mech):
self.mechanisms.append((name, mech))
il = len(self.mechanisms)
self.mlist[-1] = (name, self.setMechanism, 'check', self.mechindx, il)
self.mlist[-1] = (name, self.setMechanism, 'check', self.mechindx, il)
self.mlist.append([])
self.mechmenu = make_menu('Mixtures', self, self.mlist)
self.mechindx.set(il)
self.mechmenu.grid(row=0,column=0,sticky=W)
def delMechanism(self, mech):
self.mechanisms.remove(mech)
self.show()
@ -73,14 +73,9 @@ class MechManager(Frame):
## i = i + 1
## print 'end'
def setMechanism(self, event=None):
i = self.mechindx.get()
self.app.mech = self.mechanisms[i-1][1]
self.app.makeMix()
self.app.makeWindows()
self.app.makeWindows()

View file

@ -3,18 +3,18 @@ from Cantera.num import zeros, ones
from utilities import handleError
def spdict(phase, x):
nm = phase.speciesNames()
data = {}
for k in range(len(nm)):
data[nm[k]] = x[k]
return data
nm = phase.speciesNames()
data = {}
for k in range(len(nm)):
data[nm[k]] = x[k]
return data
class Species:
def __init__(self,g,name):
self.g = g
t = g.temperature()
p = g.pressure()
x = g.moleFractions()
t = g.temperature()
p = g.pressure()
x = g.moleFractions()
self.name = name
self.symbol = name
self.index = g.speciesIndex(name)
@ -23,28 +23,28 @@ class Species:
self.molecularWeight = g.molecularWeights()[self.index]
self.c = []
self.e = g.elementNames()
self.hf0 = self.enthalpy_RT(298.15)*GasConstant*298.15
g.setState_TPX(t,p,x)
self.hf0 = self.enthalpy_RT(298.15)*GasConstant*298.15
g.setState_TPX(t,p,x)
for n in range(len(self.e)):
na = g.nAtoms(self.index, n)
if na > 0:
self.c.append((self.e[n],na))
def composition(self):
return self.c
def enthalpy_RT(self,t):
self.g.setTemperature(t)
return self.g.enthalpies_RT()[self.index]
def cp_R(self,t):
self.g.setTemperature(t)
return self.g.cp_R()[self.index]
return self.g.cp_R()[self.index]
def entropy_R(self,t):
self.g.setTemperature(t)
return self.g.entropies_R()[self.index]
return self.g.entropies_R()[self.index]
class Mix:
def __init__(self,g):
self.g = g
@ -71,14 +71,14 @@ class Mix:
for k in range(self.nsp):
sum += self._moles[k]*self.wt[k]
return sum
def moleDict(self):
d = {}
nm = self.g.speciesNames()
for e in range(self.nsp):
d[nm[e]] = self._moles[e]
return d
def setMass(self, m):
self.setMoles( m/self.wt)
@ -99,7 +99,7 @@ class Mix:
density = None, enthalpy = None,
entropy = None, intEnergy = None, equil = 0):
total_mass = self.totalMass()
if temperature and pressure:
self.g.setState_TP(temperature, pressure)
if equil:
@ -114,7 +114,7 @@ class Mix:
self.g.setState_HP(enthalpy, pressure)
if equil:
self.g.equilibrate('HP',solver=0)
elif pressure and entropy:
self.g.setState_SP(entropy, pressure)
if equil:
@ -130,12 +130,9 @@ class Mix:
if equil:
self.g.equilibrate('UV',solver=0)
# else:
# handleError('unsupported property pair', warning=1)
# else:
# handleError('unsupported property pair', warning=1)
total_moles = total_mass/self.g.meanMolecularWeight()
self._moles = self.g.moleFractions()*total_moles

View file

@ -8,109 +8,107 @@ _ATOL = 1.e-15
_RTOL = 1.e-7
class NewFlowFrame(Frame):
def __init__(self,master):
Frame.__init__(self,master)
self.config(relief=GROOVE, bd=4)
self.app = self.master.app
self.controls=Frame(self)
self.hide = IntVar()
self.hide.set(0)
self.p = DoubleVar()
#self.comp.set(1.0)
self.controls.grid(column=1,row=0,sticky=W+E+N)
#self.makeControls()
mf = self.master
def __init__(self,master):
Frame.__init__(self,master)
self.config(relief=GROOVE, bd=4)
self.app = self.master.app
self.controls=Frame(self)
self.hide = IntVar()
self.hide.set(0)
self.p = DoubleVar()
#self.comp.set(1.0)
self.controls.grid(column=1,row=0,sticky=W+E+N)
#self.makeControls()
mf = self.master
e1 = Entry(self)
e1.grid(column=0,row=0,sticky=E+W)
e1['textvariable'] = self.p
#e1.config(state=ENABLED)
e1.config(relief=RIDGE)
## def makeControls(self):
## Radiobutton(self.controls,text='Moles',
## variable=self.comp,value=0,command=self.show).grid(column=0,row=0,sticky=W)
## Radiobutton(self.controls,text='Mass',variable=self.comp,value=1,command=self.show).grid(column=0,row=1,sticky=W)
## Radiobutton(self.controls,text='Concentration',variable=self.comp,value=2,command=self.show).grid(column=0,row=2,sticky=W)
## Button(self.controls,text='Clear',command=self.zero).grid(column=0,row=4,sticky=W+E)
## Button(self.controls,text='Normalize',command=self.norm).grid(column=0,row=5,sticky=W+E)
## Checkbutton(self.controls,text='Hide Missing\nSpecies',
## variable=self.hide,onvalue=1,offvalue=0,command=self.master.redo).grid(column=0,row=3,sticky=W)
e1 = Entry(self)
e1.grid(column=0,row=0,sticky=E+W)
e1['textvariable'] = self.p
#e1.config(state=ENABLED)
e1.config(relief=RIDGE)
## def makeControls(self):
## self.c = CompFrame(self)
## self.c.grid(column=1,row=0,sticky=E+W+N+S)
## def redo(self):
## self.update()
## self.entries.destroy()
## self.entries=Frame(self)
## self.makeEntries()
## def minimize(self,Event=None):
## self.c.hide.set(1)
## self.redo()
## self.c.grid_forget()
## self.entries.bind("<Double-1>",self.maximize)
## def maximize(self,Event=None):
## self.c.hide.set(0)
## self.redo()
## self.c.grid(column=1,row=0,sticky=E+W+N+S)
## self.entries.bind("<Double-1>",self.minimize)
## def makeControls(self):
## Radiobutton(self.controls,text='Moles',
## variable=self.comp,value=0,command=self.show).grid(column=0,row=0,sticky=W)
## Radiobutton(self.controls,text='Mass',variable=self.comp,value=1,command=self.show).grid(column=0,row=1,sticky=W)
## Radiobutton(self.controls,text='Concentration',variable=self.comp,value=2,command=self.show).grid(column=0,row=2,sticky=W)
## Button(self.controls,text='Clear',command=self.zero).grid(column=0,row=4,sticky=W+E)
## Button(self.controls,text='Normalize',command=self.norm).grid(column=0,row=5,sticky=W+E)
## Checkbutton(self.controls,text='Hide Missing\nSpecies',
## variable=self.hide,onvalue=1,offvalue=0,command=self.master.redo).grid(column=0,row=3,sticky=W)
## def makeEntries(self):
## self.entries.grid(row=0,column=0,sticky=W+N+S+E)
## self.entries.config(relief=GROOVE,bd=4)
## DATAKEYS = self.top.species
## self.variable = {}
## def makeControls(self):
## self.c = CompFrame(self)
## self.c.grid(column=1,row=0,sticky=E+W+N+S)
## n=0
## ncol = 3
## col = 0
## row = 60
## def redo(self):
## self.update()
## self.entries.destroy()
## self.entries=Frame(self)
## self.makeEntries()
## presbox =
## for sp in DATAKEYS:
## s = sp # self.top.species[sp]
## k = s.index
## if row > 15:
## row = 0
## col = col + 2
## l = Label(self.entries,text='Species')
## l.grid(column=col,row=row,sticky=E+W)
## e1 = Entry(self.entries)
## e1.grid(column=col+1,row=row,sticky=E+W)
## e1['textvariable'] = self.var
## e1.config(state=DISABLED)
## e1.config(bg='lightyellow',relief=RIDGE)
## row = row + 1
## def minimize(self,Event=None):
## self.c.hide.set(1)
## self.redo()
## self.c.grid_forget()
## self.entries.bind("<Double-1>",self.maximize)
## spname = s.name
## val = self.comp[k]
## if not self.c.hide.get() or val: showit = 1
## else: showit = 0
## def maximize(self,Event=None):
## self.c.hide.set(0)
## self.redo()
## self.c.grid(column=1,row=0,sticky=E+W+N+S)
## self.entries.bind("<Double-1>",self.minimize)
## l=SpeciesInfo(self.entries,species=s,
## def makeEntries(self):
## self.entries.grid(row=0,column=0,sticky=W+N+S+E)
## self.entries.config(relief=GROOVE,bd=4)
## DATAKEYS = self.top.species
## self.variable = {}
## n=0
## ncol = 3
## col = 0
## row = 60
## presbox =
## for sp in DATAKEYS:
## s = sp # self.top.species[sp]
## k = s.index
## if row > 15:
## row = 0
## col = col + 2
## l = Label(self.entries,text='Species')
## l.grid(column=col,row=row,sticky=E+W)
## e1 = Entry(self.entries)
## e1.grid(column=col+1,row=row,sticky=E+W)
## e1['textvariable'] = self.var
## e1.config(state=DISABLED)
## e1.config(bg='lightyellow',relief=RIDGE)
## row = row + 1
## spname = s.name
## val = self.comp[k]
## if not self.c.hide.get() or val: showit = 1
## else: showit = 0
## l=SpeciesInfo(self.entries,species=s,
## text=spname,relief=FLAT,justify=RIGHT,
## fg='darkblue')
## entry1 = Entry(self.entries)
## self.variable[spname] = DoubleVar()
## self.variable[spname].set(self.comp[k])
## entry1['textvariable']=self.variable[spname]
## entry1.bind('<Any-Leave>',self.up)
## if showit:
## l.grid(column= col ,row=row,sticky=E)
## entry1.grid(column=col+1,row=row)
## n=n+1
## row = row + 1
## fg='darkblue')
## entry1 = Entry(self.entries)
## self.variable[spname] = DoubleVar()
## self.variable[spname].set(self.comp[k])
## entry1['textvariable']=self.variable[spname]
## entry1.bind('<Any-Leave>',self.up)
## if showit:
## l.grid(column= col ,row=row,sticky=E)
## entry1.grid(column=col+1,row=row)
## n=n+1
## row = row + 1
## if self.c.hide.get():
## b=Button(self.entries,height=1,command=self.maximize)
## else:
## b=Button(self.entries,command=self.minimize)
## b=Button(self.entries,height=1,command=self.maximize)
## else:
## b=Button(self.entries,command=self.minimize)
## b.grid(column=col,columnspan=2, row=row+1)

View file

@ -18,10 +18,10 @@ class SpeciesFrame(Frame):
self.species = {}
for sp in speciesList:
self.species[sp.name] = sp
self.control.config(relief=GROOVE,bd=4)
Button(self.control, text = 'Display',command=self.show).pack(fill=X,pady=3, padx=10)
Button(self.control, text = 'Clear',command=self.clear).pack(fill=X,pady=3, padx=10)
Button(self.control, text = 'Clear',command=self.clear).pack(fill=X,pady=3, padx=10)
Button(self.control, text = ' OK ',command=self.get).pack(side=BOTTOM,
fill=X,pady=3, padx=10)
Button(self.control, text = 'Cancel',command=self.master.quit).pack(side=BOTTOM,
@ -64,7 +64,7 @@ class SpeciesFrame(Frame):
for sp in splist:
spname = sp.name
self.select(spname)
def setColors(self,event):
el = event.widget['text']
if event.widget['relief'] == RAISED:
@ -77,7 +77,7 @@ class SpeciesFrame(Frame):
back = self.color(el, sel=1)
event.widget['bg'] = back
event.widget['fg'] = fore
def color(self, el, sel=0):
_normal = ['#88dddd','#005500','#dd8888']
_selected = ['#aaffff','#88dd88','#ffaaaa']
@ -98,7 +98,7 @@ class SpeciesFrame(Frame):
if self.c[sp.name]['relief'] == RAISED:
selected.append(sp)
#showElementProperties(selected)
def get(self):
self.selected = []
for sp in self.species.values():
@ -106,7 +106,7 @@ class SpeciesFrame(Frame):
self.selected.append(sp)
#self.master.quit()'
self.master.destroy()
def clear(self):
for sp in self.species.values():
self.c[sp]['bg'] = self.color(sp, sel=0)
@ -124,7 +124,7 @@ class SpeciesFrame(Frame):
## row=0,
## sticky=W+S,
## padx=10,
## pady=10)
## pady=10)
## for el in ellist:
## Label(self,
## text=el.name).grid(column=0,
@ -168,9 +168,7 @@ def showElementProperties(ellist):
m.title('Element Properties')
elem = []
ElementPropertyFrame(m, ellist).pack()
if __name__ == "__main__":
print getSpecies()

View file

@ -6,240 +6,237 @@ from UnitChooser import UnitVar
from GraphFrame import Graph
def testit():
pass
pass
class SpeciesInfo(Label):
def __init__(self,master,phase=None,species=None,**opt):
Label.__init__(self,master,opt)
self.sp = species
self.phase = phase
self.bind('<Double-1>', self.show)
self.bind('<Button-3>', self.show)
self.bind('<Any-Enter>', self.highlight)
self.bind('<Any-Leave>', self.nohighlight)
def highlight(self, event=None):
self.config(fg='yellow')
def nohighlight(self, event=None):
self.config(fg='darkblue')
def show(self, event):
self.new=Toplevel()
self.new.title(self.sp.symbol)
#self.new.transient(self.master)
self.new.bind("<Return>", self.update,"+")
self.cpr = 0.0
self.t = 0.0
self.cpl = 0.0
self.tl = 0.0
self.cpp = [[(0.0, 0.0, 'red')]]
# elemental composition
self.eframe = Frame(self.new)
self.eframe.config(relief=GROOVE,bd=4)
self.eframe.grid(row=0,column=0,columnspan=10,sticky=E+W)
r = 1
Label(self.eframe,text='Atoms:')\
.grid(row=0,column=0,sticky=N+W)
for el, c in self.sp.composition():
Label(self.eframe,text=`int(c)`+' '+el).grid(row=0,column=r)
r = r + 1
# thermodynamic properties
self.thermo = Frame(self.new)
self.thermo.config(relief=GROOVE,bd=4)
self.thermo.grid(row=1,column=0,columnspan=10,sticky=N+E+W)
Label(self.thermo,text = 'Standard Heat of Formation at 298 K: ').grid(row=0, column=0, sticky=W)
Label(self.thermo,text = '%8.2f kJ/mol' % (self.sp.hf0*1.0e-6)).grid(row=0, column=1, sticky=W)
Label(self.thermo,text = 'Molar Mass: ').grid(row=1, column=0, sticky=W)
Label(self.thermo,text = self.sp.molecularWeight).grid(row=1, column=1, sticky=W)
labels = ['Temperature', 'c_p', 'Enthalpy', 'Entropy']
units = [temperature, specificEntropy, specificEnergy, specificEntropy]
whichone = [0, 1, 1, 1]
r = 2
self.prop = []
for prop in labels:
Label(self.thermo,text=prop).grid(row=r,column=0,sticky=W)
p = UnitVar(self.thermo,units[r-2],whichone[r-2])
p.grid(row=r,column=1,sticky=W)
p.v.config(state=DISABLED,bg='lightgray')
self.prop.append(p)
r = r + 1
tmin = self.sp.minTemp
tmax = self.sp.maxTemp
cp = self.sp.cp_R(tmin)
hh = self.sp.enthalpy_RT(tmin)
ss = self.sp.entropy_R(tmin)
self.prop[0].bind("<Any-Enter>", self.decouple)
self.prop[0].bind("<Any-Leave>", self.update)
self.prop[0].bind("<Key>", self.update)
self.prop[0].v.config(state=NORMAL,bg='white')
self.prop[0].set(300.0)
self.graphs = Frame(self.new)
self.graphs.config(relief=GROOVE,bd=4)
self.graphs.grid(row=2,column=0,columnspan=10,sticky=E+W)
self.cpdata = []
self.hdata = []
self.sdata = []
t = tmin
n = int((tmax - tmin)/100.0)
while t <= tmax:
self.cpdata.append((t,self.sp.cp_R(t)))
self.hdata.append((t,self.sp.enthalpy_RT(t)))
self.sdata.append((t,self.sp.entropy_R(t)))
t = t + n
# specific heat
Label(self.graphs,text='c_p/R').grid(row=0,column=0,sticky=W+E)
ymin, ymax, dtick = self.plotLimits(self.cpdata)
self.cpg = Graph(self.graphs,'',tmin,tmax,ymin,ymax,
pixelX=150,pixelY=150)
self.cpg.canvas.config(bg='white')
self.cpg.grid(row=1,column=0,columnspan=2,sticky=W+E)
self.ticks(ymin, ymax, dtick, tmin, tmax, self.cpg)
# enthalpy
Label(self.graphs,text='enthalpy/RT').grid(row=0,column=3,sticky=W+E)
ymin, ymax, dtick = self.plotLimits(self.hdata)
self.hg = Graph(self.graphs,'',tmin,tmax,ymin,ymax,
pixelX=150,pixelY=150)
self.hg.canvas.config(bg='white')
self.hg.grid(row=1,column=3,columnspan=2,sticky=W+E)
self.ticks(ymin, ymax, dtick, tmin, tmax, self.hg)
# entropy
Label(self.graphs,text='entropy/R').grid(row=0,column=5,sticky=W+E)
ymin, ymax, dtick = self.plotLimits(self.sdata)
self.sg = Graph(self.graphs,'',tmin,tmax,ymin,ymax,
pixelX=150,pixelY=150)
self.sg.canvas.config(bg='white')
self.sg.grid(row=1,column=5,columnspan=2,sticky=W+E)
self.ticks(ymin, ymax, dtick, tmin, tmax, self.sg)
n = int((tmax - tmin)/100.0)
t = tmin
self.cpp = []
for t, cp in self.cpdata:
self.cpg.join([(t,cp,'red')])
for t, h in self.hdata:
self.hg.join([(t,h,'green')])
for t, s in self.sdata:
self.sg.join([(t,s,'blue')])
self.cpdot = self.cpg.plot(tmin,cp,'red')
self.hdot = self.hg.plot(tmin,hh,'green')
self.sdot = self.sg.plot(tmin,ss,'blue')
b=Button(self.new,text=' OK ',command=self.finished, default=ACTIVE)
#ed=Button(self.new,text='Edit',command=testit)
b.grid(column=0, row=4,sticky=W)
#ed.grid(column=1,row=4,sticky=W)
self.scfr = Frame(self.new)
self.scfr.config(relief=GROOVE,bd=4)
self.scfr.grid(row=3,column=0,columnspan=10,sticky=N+E+W)
self.sc = Scale(self.scfr,command=self.update,variable = self.prop[0].x,
orient='horizontal',digits=7,length=400)
self.sc.config(cnf={'from':tmin,'to':tmax})
self.sc.bind('<Any-Enter>',self.couple)
self.scfr.bind('<Any-Leave>',self.decouple)
self.sc.grid(row=0,column=0,columnspan=10)
def decouple(self,event=None):
d = DoubleVar()
xx = self.prop[0].get()
d.set(xx)
self.sc.config(variable = d)
def couple(self,event=None):
self.sc.config(variable = self.prop[0].x)
#self.update()
def update(self,event=None):
try:
tmp = self.prop[0].get()
cnd = self.sp.cp_R(tmp)
cc = cnd*GasConstant
self.prop[1].set(cc)
hnd = self.sp.enthalpy_RT(tmp)
hh = hnd*tmp*GasConstant
self.prop[2].set(hh)
snd = self.sp.entropy_R(tmp)
ss = snd*tmp*GasConstant
self.prop[3].set(ss)
def __init__(self,master,phase=None,species=None,**opt):
Label.__init__(self,master,opt)
self.sp = species
self.phase = phase
self.bind('<Double-1>', self.show)
self.bind('<Button-3>', self.show)
self.bind('<Any-Enter>', self.highlight)
self.bind('<Any-Leave>', self.nohighlight)
self.cppoint = tmp, cnd
self.hpoint = tmp, hnd
self.spoint = tmp, snd
if hasattr(self, 'cpdot'):
self.cpg.delete(self.cpdot)
self.cpdot = self.cpg.plot(self.cppoint[0], self.cppoint[1],'red')
self.hg.delete(self.hdot)
self.hdot = self.hg.plot(self.hpoint[0], self.hpoint[1],'green')
self.sg.delete(self.sdot)
self.sdot = self.sg.plot(self.spoint[0], self.spoint[1],'blue')
except:
pass
def plotLimits(self, xy):
ymax = -1.e10
ymin = 1.e10
for x, y in xy:
if y > ymax: ymax = y
if y < ymin: ymin = y
dy = abs(ymax - ymin)
if dy < 0.2*ymin:
ymin = ymin*.9
ymax = ymax*1.1
dy = abs(ymax - ymin)
else:
ymin = ymin - 0.1*dy
ymax = ymax + 0.1*dy
dy = abs(ymax - ymin)
p10 = math.floor(math.log10(0.1*dy))
fctr = math.pow(10.0, p10)
mm = [2.0, 2.5, 2.0]
i = 0
while dy/fctr > 5:
fctr = mm[i % 3]*fctr
i = i + 1
ymin = fctr*math.floor(ymin/fctr)
ymax = fctr*(math.floor(ymax/fctr + 1))
return (ymin, ymax, fctr)
def highlight(self, event=None):
self.config(fg='yellow')
def ticks(self, ymin, ymax, dtick, tmin, tmax, plot):
ytick = ymin
eps = 1.e-3
while ytick <= ymax:
if abs(ytick) < eps:
plot.join([(tmin, ytick, 'gray')])
plot.join([(tmax, ytick, 'gray')])
plot.last_points = []
else:
plot.join([(tmin, ytick, 'gray')])
plot.join([(tmin + 0.05*(tmax - tmin), ytick, 'gray')])
plot.last_points = []
plot.join([(2.0*tmax, ytick, 'gray')])
plot.join([(tmax - 0.05*(tmax - tmin), ytick, 'gray')])
plot.last_points = []
ytick = ytick + dtick
def nohighlight(self, event=None):
self.config(fg='darkblue')
def finished(self,event=None):
self.new.destroy()
def show(self, event):
self.new=Toplevel()
self.new.title(self.sp.symbol)
#self.new.transient(self.master)
self.new.bind("<Return>", self.update,"+")
self.cpr = 0.0
self.t = 0.0
self.cpl = 0.0
self.tl = 0.0
self.cpp = [[(0.0, 0.0, 'red')]]
# elemental composition
self.eframe = Frame(self.new)
self.eframe.config(relief=GROOVE,bd=4)
self.eframe.grid(row=0,column=0,columnspan=10,sticky=E+W)
r = 1
Label(self.eframe,text='Atoms:')\
.grid(row=0,column=0,sticky=N+W)
for el, c in self.sp.composition():
Label(self.eframe,text=`int(c)`+' '+el).grid(row=0,column=r)
r = r + 1
# thermodynamic properties
self.thermo = Frame(self.new)
self.thermo.config(relief=GROOVE,bd=4)
self.thermo.grid(row=1,column=0,columnspan=10,sticky=N+E+W)
Label(self.thermo,text = 'Standard Heat of Formation at 298 K: ').grid(row=0, column=0, sticky=W)
Label(self.thermo,text = '%8.2f kJ/mol' % (self.sp.hf0*1.0e-6)).grid(row=0, column=1, sticky=W)
Label(self.thermo,text = 'Molar Mass: ').grid(row=1, column=0, sticky=W)
Label(self.thermo,text = self.sp.molecularWeight).grid(row=1, column=1, sticky=W)
labels = ['Temperature', 'c_p', 'Enthalpy', 'Entropy']
units = [temperature, specificEntropy, specificEnergy, specificEntropy]
whichone = [0, 1, 1, 1]
r = 2
self.prop = []
for prop in labels:
Label(self.thermo,text=prop).grid(row=r,column=0,sticky=W)
p = UnitVar(self.thermo,units[r-2],whichone[r-2])
p.grid(row=r,column=1,sticky=W)
p.v.config(state=DISABLED,bg='lightgray')
self.prop.append(p)
r = r + 1
tmin = self.sp.minTemp
tmax = self.sp.maxTemp
cp = self.sp.cp_R(tmin)
hh = self.sp.enthalpy_RT(tmin)
ss = self.sp.entropy_R(tmin)
self.prop[0].bind("<Any-Enter>", self.decouple)
self.prop[0].bind("<Any-Leave>", self.update)
self.prop[0].bind("<Key>", self.update)
self.prop[0].v.config(state=NORMAL,bg='white')
self.prop[0].set(300.0)
self.graphs = Frame(self.new)
self.graphs.config(relief=GROOVE,bd=4)
self.graphs.grid(row=2,column=0,columnspan=10,sticky=E+W)
self.cpdata = []
self.hdata = []
self.sdata = []
t = tmin
n = int((tmax - tmin)/100.0)
while t <= tmax:
self.cpdata.append((t,self.sp.cp_R(t)))
self.hdata.append((t,self.sp.enthalpy_RT(t)))
self.sdata.append((t,self.sp.entropy_R(t)))
t = t + n
# specific heat
Label(self.graphs,text='c_p/R').grid(row=0,column=0,sticky=W+E)
ymin, ymax, dtick = self.plotLimits(self.cpdata)
self.cpg = Graph(self.graphs,'',tmin,tmax,ymin,ymax,
pixelX=150,pixelY=150)
self.cpg.canvas.config(bg='white')
self.cpg.grid(row=1,column=0,columnspan=2,sticky=W+E)
self.ticks(ymin, ymax, dtick, tmin, tmax, self.cpg)
# enthalpy
Label(self.graphs,text='enthalpy/RT').grid(row=0,column=3,sticky=W+E)
ymin, ymax, dtick = self.plotLimits(self.hdata)
self.hg = Graph(self.graphs,'',tmin,tmax,ymin,ymax,
pixelX=150,pixelY=150)
self.hg.canvas.config(bg='white')
self.hg.grid(row=1,column=3,columnspan=2,sticky=W+E)
self.ticks(ymin, ymax, dtick, tmin, tmax, self.hg)
# entropy
Label(self.graphs,text='entropy/R').grid(row=0,column=5,sticky=W+E)
ymin, ymax, dtick = self.plotLimits(self.sdata)
self.sg = Graph(self.graphs,'',tmin,tmax,ymin,ymax,
pixelX=150,pixelY=150)
self.sg.canvas.config(bg='white')
self.sg.grid(row=1,column=5,columnspan=2,sticky=W+E)
self.ticks(ymin, ymax, dtick, tmin, tmax, self.sg)
n = int((tmax - tmin)/100.0)
t = tmin
self.cpp = []
for t, cp in self.cpdata:
self.cpg.join([(t,cp,'red')])
for t, h in self.hdata:
self.hg.join([(t,h,'green')])
for t, s in self.sdata:
self.sg.join([(t,s,'blue')])
self.cpdot = self.cpg.plot(tmin,cp,'red')
self.hdot = self.hg.plot(tmin,hh,'green')
self.sdot = self.sg.plot(tmin,ss,'blue')
b=Button(self.new,text=' OK ',command=self.finished, default=ACTIVE)
#ed=Button(self.new,text='Edit',command=testit)
b.grid(column=0, row=4,sticky=W)
#ed.grid(column=1,row=4,sticky=W)
self.scfr = Frame(self.new)
self.scfr.config(relief=GROOVE,bd=4)
self.scfr.grid(row=3,column=0,columnspan=10,sticky=N+E+W)
self.sc = Scale(self.scfr,command=self.update,variable = self.prop[0].x,
orient='horizontal',digits=7,length=400)
self.sc.config(cnf={'from':tmin,'to':tmax})
self.sc.bind('<Any-Enter>',self.couple)
self.scfr.bind('<Any-Leave>',self.decouple)
self.sc.grid(row=0,column=0,columnspan=10)
def decouple(self,event=None):
d = DoubleVar()
xx = self.prop[0].get()
d.set(xx)
self.sc.config(variable = d)
def couple(self,event=None):
self.sc.config(variable = self.prop[0].x)
#self.update()
def update(self,event=None):
try:
tmp = self.prop[0].get()
cnd = self.sp.cp_R(tmp)
cc = cnd*GasConstant
self.prop[1].set(cc)
hnd = self.sp.enthalpy_RT(tmp)
hh = hnd*tmp*GasConstant
self.prop[2].set(hh)
snd = self.sp.entropy_R(tmp)
ss = snd*tmp*GasConstant
self.prop[3].set(ss)
self.cppoint = tmp, cnd
self.hpoint = tmp, hnd
self.spoint = tmp, snd
if hasattr(self, 'cpdot'):
self.cpg.delete(self.cpdot)
self.cpdot = self.cpg.plot(self.cppoint[0], self.cppoint[1],'red')
self.hg.delete(self.hdot)
self.hdot = self.hg.plot(self.hpoint[0], self.hpoint[1],'green')
self.sg.delete(self.sdot)
self.sdot = self.sg.plot(self.spoint[0], self.spoint[1],'blue')
except:
pass
def plotLimits(self, xy):
ymax = -1.e10
ymin = 1.e10
for x, y in xy:
if y > ymax: ymax = y
if y < ymin: ymin = y
dy = abs(ymax - ymin)
if dy < 0.2*ymin:
ymin = ymin*.9
ymax = ymax*1.1
dy = abs(ymax - ymin)
else:
ymin = ymin - 0.1*dy
ymax = ymax + 0.1*dy
dy = abs(ymax - ymin)
p10 = math.floor(math.log10(0.1*dy))
fctr = math.pow(10.0, p10)
mm = [2.0, 2.5, 2.0]
i = 0
while dy/fctr > 5:
fctr = mm[i % 3]*fctr
i = i + 1
ymin = fctr*math.floor(ymin/fctr)
ymax = fctr*(math.floor(ymax/fctr + 1))
return (ymin, ymax, fctr)
def ticks(self, ymin, ymax, dtick, tmin, tmax, plot):
ytick = ymin
eps = 1.e-3
while ytick <= ymax:
if abs(ytick) < eps:
plot.join([(tmin, ytick, 'gray')])
plot.join([(tmax, ytick, 'gray')])
plot.last_points = []
else:
plot.join([(tmin, ytick, 'gray')])
plot.join([(tmin + 0.05*(tmax - tmin), ytick, 'gray')])
plot.last_points = []
plot.join([(2.0*tmax, ytick, 'gray')])
plot.join([(tmax - 0.05*(tmax - tmin), ytick, 'gray')])
plot.last_points = []
ytick = ytick + dtick
def finished(self,event=None):
self.new.destroy()

View file

@ -16,131 +16,128 @@ _ENTHALPY = 4
_ENTROPY = 5
class ThermoFrame(Frame):
def __init__(self,master,top):
Frame.__init__(self,master)
self.config(relief=GROOVE, bd=4)
self.top = top
self.mix = self.top.mix
self.warn = 0
self.internal = Frame(self)
self.internal.pack(side=LEFT,anchor=N+W,padx=2,pady=2)
self.controls=Frame(self.internal)
self.controls.pack(side=LEFT,anchor=N+W,padx=4,pady=5)
self.entries=Frame(self.internal)
self.entries.pack(side=LEFT,anchor=N,padx=4,pady=2)
self.makeEntries()
self.makeControls()
self.showState()
def makeControls(self):
Button(self.controls,text='Set State', width=15,
command=self.setState).grid(column=0,row=0)
self.equil = IntVar()
self.equil.set(0)
Button(self.controls,text='Equilibrate', width=15,
command=self.eqset).grid(column=0,row=1)
## Radiobutton(self.controls,text='Frozen',variable = self.equil,
def __init__(self,master,top):
Frame.__init__(self,master)
self.config(relief=GROOVE, bd=4)
self.top = top
self.mix = self.top.mix
self.warn = 0
self.internal = Frame(self)
self.internal.pack(side=LEFT,anchor=N+W,padx=2,pady=2)
self.controls=Frame(self.internal)
self.controls.pack(side=LEFT,anchor=N+W,padx=4,pady=5)
self.entries=Frame(self.internal)
self.entries.pack(side=LEFT,anchor=N,padx=4,pady=2)
self.makeEntries()
self.makeControls()
self.showState()
def makeControls(self):
Button(self.controls,text='Set State', width=15,
command=self.setState).grid(column=0,row=0)
self.equil = IntVar()
self.equil.set(0)
Button(self.controls,text='Equilibrate', width=15,
command=self.eqset).grid(column=0,row=1)
## Radiobutton(self.controls,text='Frozen',variable = self.equil,
## command=self.freeze,value=0).grid(column=0,row=2,sticky='W')
## Radiobutton(self.controls,text='Equilibrium',
## variable=self.equil,
## Radiobutton(self.controls,text='Equilibrium',
## variable=self.equil,
## command=self.eqset,value=1).grid(column=0,row=3,sticky='W')
def eqset(self):
self.equil.set(1)
self.setState()
self.equil.set(0)
#if self.top.mixframe:
# self.top.mixframe.redo()
def freeze(self):
self.equil.set(0)
if self.top.mixframe:
self.top.mixframe.redo()
def makeEntries(self):
self.entries.pack()
self.variable = {}
self.prop = []
props = ['Temperature', 'Pressure', 'Density',
'Internal Energy', 'Enthalpy', 'Entropy']
units = [temperature, pressure, density, specificEnergy,
specificEnergy, specificEntropy]
defaultunit = [0, 2, 0, 1, 1, 1]
for i in range(len(props)):
self.prop.append(ThermoProp(self.entries, self, i, props[i],
0.0, units[i], defaultunit[i]))
#self.prop[-1].entry.bind("<Any-Leave>",self.setState)
self.last2 = self.prop[3]
self.last1 = self.prop[2]
self.prop[0].checked.set(1)
self.prop[0].check()
self.prop[1].checked.set(1)
self.prop[1].check()
self.showState()
def eqset(self):
self.equil.set(1)
self.setState()
self.equil.set(0)
#if self.top.mixframe:
# self.top.mixframe.redo()
def checkTPBoxes(self):
if not self.prop[0].isChecked():
self.prop[0].checked.set(1)
self.prop[0].check()
if not self.prop[1].isChecked():
self.prop[1].checked.set(1)
self.prop[1].check()
def showState(self):
self.prop[_TEMPERATURE].set(self.mix.g.temperature())
self.prop[_PRESSURE].set(self.mix.g.pressure())
self.prop[_DENSITY].set(self.mix.g.density())
self.prop[_INTENERGY].set(self.mix.g.intEnergy_mass())
self.prop[_ENTHALPY].set(self.mix.g.enthalpy_mass())
self.prop[_ENTROPY].set(self.mix.g.entropy_mass())
def freeze(self):
self.equil.set(0)
if self.top.mixframe:
self.top.mixframe.redo()
def setState(self,event=None):
if event:
self.warn = 0
else:
self.warn = 1
self.top.mixfr.update()
i = self.equil.get()
optlist = ['frozen','equilibrium']
opt = [optlist[i]]
if self.prop[_PRESSURE].isChecked() \
and self.prop[_TEMPERATURE].isChecked():
self.mix.set(
temperature = self.prop[_TEMPERATURE].get(),
pressure = self.prop[_PRESSURE].get(),
equil=i)
def makeEntries(self):
self.entries.pack()
self.variable = {}
self.prop = []
props = ['Temperature', 'Pressure', 'Density',
'Internal Energy', 'Enthalpy', 'Entropy']
units = [temperature, pressure, density, specificEnergy,
specificEnergy, specificEntropy]
defaultunit = [0, 2, 0, 1, 1, 1]
for i in range(len(props)):
self.prop.append(ThermoProp(self.entries, self, i, props[i],
0.0, units[i], defaultunit[i]))
#self.prop[-1].entry.bind("<Any-Leave>",self.setState)
self.last2 = self.prop[3]
self.last1 = self.prop[2]
self.prop[0].checked.set(1)
self.prop[0].check()
self.prop[1].checked.set(1)
self.prop[1].check()
self.showState()
elif self.prop[_DENSITY].isChecked() \
and self.prop[_TEMPERATURE].isChecked():
self.mix.set(
temperature = self.prop[_TEMPERATURE].get(),
density = self.prop[_DENSITY].get(),
equil=i)
elif self.prop[_ENTROPY].isChecked() \
and self.prop[_PRESSURE].isChecked():
self.mix.set(pressure = self.prop[_PRESSURE].get(),
entropy = self.prop[_ENTROPY].get(),
equil=i)
elif self.prop[_ENTHALPY].isChecked() \
and self.prop[_PRESSURE].isChecked():
self.mix.set(pressure = self.prop[_PRESSURE].get(),
enthalpy = self.prop[_ENTHALPY].get(),
equil=i)
elif self.prop[_INTENERGY].isChecked() \
and self.prop[_DENSITY].isChecked():
self.mix.set(density = self.prop[_DENSITY].get(),
intEnergy = self.prop[_INTENERGY].get(),
equil=i)
else:
if self.warn > 0:
handleError("unsupported property pair")
def checkTPBoxes(self):
if not self.prop[0].isChecked():
self.prop[0].checked.set(1)
self.prop[0].check()
if not self.prop[1].isChecked():
self.prop[1].checked.set(1)
self.prop[1].check()
self.top.update()
def showState(self):
self.prop[_TEMPERATURE].set(self.mix.g.temperature())
self.prop[_PRESSURE].set(self.mix.g.pressure())
self.prop[_DENSITY].set(self.mix.g.density())
self.prop[_INTENERGY].set(self.mix.g.intEnergy_mass())
self.prop[_ENTHALPY].set(self.mix.g.enthalpy_mass())
self.prop[_ENTROPY].set(self.mix.g.entropy_mass())
def setState(self,event=None):
if event:
self.warn = 0
else:
self.warn = 1
self.top.mixfr.update()
i = self.equil.get()
optlist = ['frozen','equilibrium']
opt = [optlist[i]]
if self.prop[_PRESSURE].isChecked() \
and self.prop[_TEMPERATURE].isChecked():
self.mix.set(
temperature = self.prop[_TEMPERATURE].get(),
pressure = self.prop[_PRESSURE].get(),
equil=i)
elif self.prop[_DENSITY].isChecked() \
and self.prop[_TEMPERATURE].isChecked():
self.mix.set(
temperature = self.prop[_TEMPERATURE].get(),
density = self.prop[_DENSITY].get(),
equil=i)
elif self.prop[_ENTROPY].isChecked() \
and self.prop[_PRESSURE].isChecked():
self.mix.set(pressure = self.prop[_PRESSURE].get(),
entropy = self.prop[_ENTROPY].get(),
equil=i)
elif self.prop[_ENTHALPY].isChecked() \
and self.prop[_PRESSURE].isChecked():
self.mix.set(pressure = self.prop[_PRESSURE].get(),
enthalpy = self.prop[_ENTHALPY].get(),
equil=i)
elif self.prop[_INTENERGY].isChecked() \
and self.prop[_DENSITY].isChecked():
self.mix.set(density = self.prop[_DENSITY].get(),
intEnergy = self.prop[_INTENERGY].get(),
equil=i)
else:
if self.warn > 0:
handleError("unsupported property pair")
self.top.update()

View file

@ -5,64 +5,62 @@ _tv = ['Temperature','Internal Energy','Enthalpy']
_pv = ['Pressure', 'Density']
def badpair(a,b):
if a.name in _tv:
if not b.name in _pv:
return 1
else:
if not b.name in _tv:
return 1
if a.name in _tv:
if not b.name in _pv:
return 1
else:
if not b.name in _tv:
return 1
class ThermoProp:
def __init__(self, master, thermoframe, row, name, value, units, defaultunit=0):
self.value = DoubleVar()
self.thermoframe = thermoframe
self.entry = UnitVar(master,units,defaultunit)
self.entry.grid(column=1,row=row,sticky=W)
self.entry.v.config(state=DISABLED,bg='lightgray')
self.checked=IntVar()
self.checked.set(0)
self.name = name
self.c=Checkbutton(master,
text=name,
variable=self.checked,
onvalue=1,
offvalue=0,
command=self.check
)
self.c.grid(column=0,row=row, sticky=W+N)
def __init__(self, master, thermoframe, row, name, value, units, defaultunit=0):
self.value = DoubleVar()
self.thermoframe = thermoframe
self.entry = UnitVar(master,units,defaultunit)
self.entry.grid(column=1,row=row,sticky=W)
self.entry.v.config(state=DISABLED,bg='lightgray')
self.checked=IntVar()
self.checked.set(0)
self.name = name
self.c=Checkbutton(master,
text=name,
variable=self.checked,
onvalue=1,
offvalue=0,
command=self.check
)
self.c.grid(column=0,row=row, sticky=W+N)
def check(self):
if self == self.thermoframe.last1:
self.checked.set(1)
return
elif self == self.thermoframe.last2:
self.checked.set(1)
self.thermoframe.last2 = self.thermoframe.last1
self.thermoframe.last1 = self
return
# elif badpair(self, self.thermoframe.last1):
# self.checked.set(0)
# return
self._check()
self.thermoframe.last2.checked.set(0)
self.thermoframe.last2._check()
self.thermoframe.last2 = self.thermoframe.last1
self.thermoframe.last1 = self
def _check(self):
if self.isChecked():
self.entry.v.config(state=NORMAL,bg='white')
else:
self.entry.v.config(state=DISABLED,bg='lightgray')
def check(self):
if self == self.thermoframe.last1:
self.checked.set(1)
return
elif self == self.thermoframe.last2:
self.checked.set(1)
self.thermoframe.last2 = self.thermoframe.last1
self.thermoframe.last1 = self
return
# elif badpair(self, self.thermoframe.last1):
# self.checked.set(0)
# return
def isChecked(self):
return self.checked.get()
self._check()
self.thermoframe.last2.checked.set(0)
self.thermoframe.last2._check()
self.thermoframe.last2 = self.thermoframe.last1
self.thermoframe.last1 = self
def set(self, value):
self.entry.set(value)
def get(self):
return self.entry.get()
def _check(self):
if self.isChecked():
self.entry.v.config(state=NORMAL,bg='white')
else:
self.entry.v.config(state=DISABLED,bg='lightgray')
def isChecked(self):
return self.checked.get()
def set(self, value):
self.entry.set(value)
def get(self):
return self.entry.get()

View file

@ -1,35 +1,34 @@
from Tkinter import *
class TransportFrame(Frame):
def show(self, i, frame, row, col):
if self.checked[i].get():
frame.grid(row=row,column=col,sticky=N+E+S+W)
else:
frame.grid_forget()
def showcomp(self):
self.show(0, self.top.mixfr, 8, 0)
def show(self, i, frame, row, col):
if self.checked[i].get():
frame.grid(row=row,column=col,sticky=N+E+S+W)
else:
frame.grid_forget()
def showthermo(self):
self.show(1, self.top.thermo, 7, 0)
def __init__(self,master,top):
self.top = top
self.c = []
self.checked = []
Frame.__init__(self,master)
self.config(relief=GROOVE, bd=4)
lbl = ['multicomponent', 'mixture-averaged']
cmds = [self.showcomp, self.showthermo]
for i in range(2):
self.checked.append(IntVar())
self.checked[i].set(0)
self.c.append(Checkbutton(self,
text=lbl[i],
variable=self.checked[i],
onvalue=1,
offvalue=0,
command=cmds[i]
))
self.c[i].grid(column=i,row=0, sticky=W+N)
def showcomp(self):
self.show(0, self.top.mixfr, 8, 0)
def showthermo(self):
self.show(1, self.top.thermo, 7, 0)
def __init__(self,master,top):
self.top = top
self.c = []
self.checked = []
Frame.__init__(self,master)
self.config(relief=GROOVE, bd=4)
lbl = ['multicomponent', 'mixture-averaged']
cmds = [self.showcomp, self.showthermo]
for i in range(2):
self.checked.append(IntVar())
self.checked[i].set(0)
self.c.append(Checkbutton(self,
text=lbl[i],
variable=self.checked[i],
onvalue=1,
offvalue=0,
command=cmds[i]
))
self.c[i].grid(column=i,row=0, sticky=W+N)

View file

@ -2,83 +2,81 @@ from Tkinter import *
import re
class UnitVar(Frame):
def __init__(self,master,unitmod,defaultunit=0):
Frame.__init__(self,master)
self.x = DoubleVar()
self.xsi = 0.0
self.x.set(0.0)
self.unitmod = unitmod
try:
self.unitlist = self.unitmod.units
except:
self.unitlist = []
unitlist=dir(self.unitmod)
for it in unitlist:
if it[0] != '_':
self.unitlist.append(it)
self.v = Entry(self,textvariable=self.x)
self.s = StringVar()
tmp = re.sub('__',' / ',self.unitlist[defaultunit])
self.s.set(tmp)
self.conv = eval('self.unitmod.'+re.sub(' / ','__',self.s.get())).value
self.u = Label(self)
self.u.config(textvariable=self.s,fg='darkblue')
self.u.bind('<Double-1>', self.select)
self.u.bind('<Any-Enter>',self.highlight)
self.u.bind('<Any-Leave>',self.nohighlight)
self.v.grid(row=0,column=0)
self.u.grid(row=0,column=1)
def __init__(self,master,unitmod,defaultunit=0):
Frame.__init__(self,master)
self.x = DoubleVar()
self.xsi = 0.0
self.x.set(0.0)
self.unitmod = unitmod
try:
self.unitlist = self.unitmod.units
except:
self.unitlist = []
unitlist=dir(self.unitmod)
for it in unitlist:
if it[0] != '_':
self.unitlist.append(it)
self.v = Entry(self,textvariable=self.x)
self.s = StringVar()
tmp = re.sub('__',' / ',self.unitlist[defaultunit])
self.s.set(tmp)
self.conv = eval('self.unitmod.'+re.sub(' / ','__',self.s.get())).value
self.u = Label(self)
self.u.config(textvariable=self.s,fg='darkblue')
self.u.bind('<Double-1>', self.select)
self.u.bind('<Any-Enter>',self.highlight)
self.u.bind('<Any-Leave>',self.nohighlight)
self.v.grid(row=0,column=0)
self.u.grid(row=0,column=1)
def highlight(self, event=None):
self.u.config(fg='yellow')
def nohighlight(self, event=None):
self.u.config(fg='darkblue')
def select(self, event):
self.new=Toplevel()
self.new.title("Units")
self.new.transient(self.master)
self.new.bind("<Return>", self.finished,"+")
r=0
c=0
for each in self.unitlist:
if each[0] != '_' and each[:1] != '__' and each != 'SI':
each = re.sub('__',' / ',each)
Radiobutton(self.new,
text=each,
variable=self.u['textvariable'],
value=each,
command=self.update,
).grid(column=c, row=r, sticky=W)
r=r+1
if (r>10):
r=0
c=c+1
r=r+1
b=Button(self.new,text='OK',command=self.finished, default=ACTIVE)
b.grid(column=c, row=r)
self.new.grab_set()
self.new.focus_set()
self.new.wait_window()
def highlight(self, event=None):
self.u.config(fg='yellow')
def finished(self,event=None):
self.new.destroy()
def update(self):
self.xsi = self.x.get() * self.conv
self.conv = eval('self.unitmod.'+re.sub(' / ','__',self.s.get())).value
self.x.set(self.xsi/self.conv)
def nohighlight(self, event=None):
self.u.config(fg='darkblue')
def get(self):
self.xsi = self.x.get() * self.conv
return self.xsi
def select(self, event):
self.new=Toplevel()
self.new.title("Units")
self.new.transient(self.master)
self.new.bind("<Return>", self.finished,"+")
def set(self,value):
self.xsi = value
self.x.set(value/self.conv)
r=0
c=0
for each in self.unitlist:
if each[0] != '_' and each[:1] != '__' and each != 'SI':
each = re.sub('__',' / ',each)
Radiobutton(self.new,
text=each,
variable=self.u['textvariable'],
value=each,
command=self.update,
).grid(column=c, row=r, sticky=W)
r=r+1
if (r>10):
r=0
c=c+1
r=r+1
b=Button(self.new,text='OK',command=self.finished, default=ACTIVE)
b.grid(column=c, row=r)
self.new.grab_set()
self.new.focus_set()
self.new.wait_window()
def finished(self,event=None):
self.new.destroy()
def update(self):
self.xsi = self.x.get() * self.conv
self.conv = eval('self.unitmod.'+re.sub(' / ','__',self.s.get())).value
self.x.set(self.xsi/self.conv)
def get(self):
self.xsi = self.x.get() * self.conv
return self.xsi
def set(self,value):
self.xsi = value
self.x.set(value/self.conv)

View file

@ -39,33 +39,33 @@ candela = unit(1.0, (0, 0, 0, 0, 0, 0, 1))
#
# The 21 derived SI units with special names
#
radian = dimensionless # plane angle
steradian = dimensionless # solid angle
hertz = 1/second # frequency
newton = meter*kilogram/second**2 # force
pascal = newton/meter**2 # pressure
joule = newton*meter # work, heat
watt = joule/second # power, radiant flux
coulomb = ampere*second # electric charge
volt = watt/ampere # electric potential difference
farad = coulomb/volt # capacitance
ohm = volt/ampere # electric resistance
siemens = ampere/volt # electric conductance
weber = volt*second # magnetic flux
tesla = weber/meter**2 # magnetic flux density
henry = weber/ampere # inductance
celsius = kelvin # Celsius temperature
lumen = candela*steradian # luminous flux
lux = lumen/meter**2 # illuminance
becquerel = 1/second # radioactivity
gray = joule/kilogram # absorbed dose
sievert = joule/kilogram # dose equivalent
radian = dimensionless # plane angle
steradian = dimensionless # solid angle
hertz = 1/second # frequency
newton = meter*kilogram/second**2 # force
pascal = newton/meter**2 # pressure
joule = newton*meter # work, heat
watt = joule/second # power, radiant flux
coulomb = ampere*second # electric charge
volt = watt/ampere # electric potential difference
farad = coulomb/volt # capacitance
ohm = volt/ampere # electric resistance
siemens = ampere/volt # electric conductance
weber = volt*second # magnetic flux
tesla = weber/meter**2 # magnetic flux density
henry = weber/ampere # inductance
celsius = kelvin # Celsius temperature
lumen = candela*steradian # luminous flux
lux = lumen/meter**2 # illuminance
becquerel = 1/second # radioactivity
gray = joule/kilogram # absorbed dose
sievert = joule/kilogram # dose equivalent
#
# The prefixes
@ -112,12 +112,12 @@ if __name__ == "__main__":
print " radian: %s" % radian
print " steradian: %s" % steradian
print " hertz: %s" % hertz
print " newton: %s" % newton
print " pascal: %s" % pascal
print " joule: %s" % joule
print " watt: %s" % watt
print " coulomb: %s" % coulomb
print " volt: %s" % volt
print " farad: %s" % farad
@ -126,12 +126,12 @@ if __name__ == "__main__":
print " weber: %s" % weber
print " tesla: %s" % tesla
print " henry: %s" % henry
print " degree Celcius: %s" % celcius
print " lumen: %s" % lumen
print " lux: %s" % lux
print " becquerel: %s" % becquerel
print " gray: %s" % gray
print " sievert: %s" % sievert

View file

@ -29,7 +29,7 @@ class unit:
_zero = (0,) * 7
_negativeOne = (-1, ) * 7
_labels = ('m', 'kg', 's', 'A', 'K', 'mol', 'cd')
@ -56,7 +56,7 @@ class unit:
def __mul__(self, other):
if type(other) == type(0) or type(other) == type(0.0):
return unit(other*self.value, self.derivation)
value = self.value * other.value
derivation = tuple(map(operator.add, self.derivation, other.derivation))
@ -66,7 +66,7 @@ class unit:
def __div__(self, other):
if type(other) == type(0) or type(other) == type(0.0):
return unit(self.value/other, self.derivation)
value = self.value / other.value
derivation = tuple(map(operator.sub, self.derivation, other.derivation))
@ -81,7 +81,7 @@ class unit:
derivation = tuple(map(operator.mul, [other]*7, self.derivation))
return unit(value, derivation)
def __pos__(self): return self
@ -107,7 +107,7 @@ class unit:
value = other/self.value
derivation = tuple(map(operator.mul, self._negativeOne, self.derivation))
return unit(value, derivation)
@ -115,7 +115,7 @@ class unit:
return self.value
#if self.derivation == self._zero: return self.value
#raise BadConversion(self)
def __str__(self):
str = "%g" % self.value
@ -130,6 +130,6 @@ class unit:
return str
dimensionless = unit(1, unit._zero)
#
# End of file

View file

@ -1,5 +1,4 @@
# from Cantera import *
from main import MixMaster

View file

@ -3,5 +3,3 @@ from Cantera import *
# thermo parametrizations
#from Cantera.Species.Thermo.NasaPolynomial import NasaPolynomial

View file

@ -12,12 +12,12 @@ class App:
self.root = master.root
except:
self.root = master
self.frame = Frame(master)
self.frame.grid(row = 0, column = 0)
self.makemenu(self.frame)
self.quitbutton = Button(self.frame, text = "Quit",
command = self.frame.quit)
self.quitbutton.grid(row = 1, column = 0)
@ -32,11 +32,11 @@ class App:
def newflow(self):
n = newflow.NewFlowDialog(self.root)
def makemenu(self,frame):
self.menubar = Frame(frame, relief=FLAT, bd=0)
self.menubar.grid(row = 0, column = 0)
self.filemenu = menu.make_menu('File', self.menubar,
[('New...', self.newflow),
('Open...', self.notyet),
@ -53,4 +53,3 @@ root = Tk()
app = App(root)
root.mainloop()

View file

@ -6,7 +6,7 @@ elements = {
'N':build.element(7, 'N', 'Nitrogen', 14.0067),
'Ar':build.element(18, 'Ar', 'Argon', 39.948)
}
species = {
species = {
'H2':Species( name = 'H2',
id = 'TPIS78',
elements = {'H': 2},
@ -432,7 +432,7 @@ species = {
lowCoefficients = [4.7294595, -0.0031932858, 4.7534921e-005, -5.7458611e-008, 2.1931112e-011, -21572.878, 4.1030159]) )
}
reactions = [
reactions = [
build.reaction([(-2, 'O'), (1, 'O2')],[1002, 0, 1, 'M', 0],
{'H2': 1.4, 'AR': -0.17, 'C2H6': 2.0, 'CO': 0.75, 'CH4': 1.0, 'CO2': 2.6, 'H2O': 14.4},
build.rateCoeff('3',build.arrhenius(120000000000.0, -1.0, 0.0) ),species),

View file

@ -39,7 +39,7 @@ def testit():
class MixMaster:
def stop(self):
sys.exit(0)
@ -53,7 +53,7 @@ class MixMaster:
def loadmech(self, mechname, pathname, mw=1):
p = os.path.normpath(os.path.dirname(pathname))
self.fname = os.path.basename(pathname)
ff = os.path.splitext(self.fname)
@ -61,7 +61,7 @@ class MixMaster:
try:
self.mech = IdealGasMix(pathname)
self.mechname = ff[0]
except:
utilities.handleError('could not create gas mixture object: '
+ff[0]+'\n')
@ -72,7 +72,7 @@ class MixMaster:
if not mechname:
mechname = self.mechname
self.mechframe.addMechanism(mechname, self.mech)
if mw==1:
self.makeWindows()
@ -111,7 +111,7 @@ class MixMaster:
self.mixfr.show()
def makeMix(self):
self.mix = Mix(self.mech)
nsp = self.mech.nSpecies()
@ -142,14 +142,14 @@ class MixMaster:
self._windows = {}
self._vis = {}
self.windows = []
self.cwin = ControlWindow(_app_title,self.master)
self.cwin.master.resizable(FALSE,FALSE)
self.menubar = Frame(self.cwin, relief=GROOVE,bd=2)
self.menubar.grid(row=0,column=0,sticky=N+W+E)
self.mixfr = None
self.mixfr = None
self.thermo = None
self.transport = None
self.kinetics = None
@ -157,7 +157,7 @@ class MixMaster:
self.rxnpaths = None
self.edit = None
self.fname = None
self.mechframe = MechManager(self.cwin, self)
self.mechframe.grid(row=1,column=0,sticky=N+W)
@ -171,7 +171,7 @@ class MixMaster:
]
self.filemenu = make_menu('File', self.menubar, fileitems)
self.vtherm = IntVar()
self.vcomp = IntVar()
self.vtran = IntVar()
@ -190,9 +190,9 @@ class MixMaster:
#toolitems = [(' Convert...', self.importfile),
# []]
#self.toolmenu = make_menu('Tools', self.menubar, toolitems)
#self.toolmenu = make_menu('Tools', self.menubar, toolitems)
w = [(' Thermodynamic State', self.showthermo, 'check', self.vtherm),
(' Composition', self.showcomp, 'check', self.vcomp),
'separator',
@ -200,31 +200,31 @@ class MixMaster:
(' Reactions...', self.showrxns),
(' Reaction Paths...', self.showrpaths),
[]]
self.viewmenu = make_menu('Windows', self.menubar, w)
self.helpmenu = make_menu('Help', self.menubar,
[('About '+_app_title+'...', self.aboutmix),
('About Cantera...', testit),
[]
])
# load the preloaded mechanisms
for m in _autoload:
self.loadmech(m[0],m[1],0)
self.makeWindows()
self.makeWindows()
self.addWindow('import',ImportFrame(self))
self.vtherm.set(1)
self.showthermo()
## self.vcomp.set(1)
## self.showcomp()
self.master.iconify()
self.master.update()
self.master.deiconify()
self.master.iconify()
self.master.update()
self.master.deiconify()
self.cwin.mainloop()
@ -237,13 +237,13 @@ class MixMaster:
def makeWindows(self):
# if self.mixfr:
for w in self.windows:
try:
w.destroy()
except:
pass
try:
w.destroy()
except:
pass
fr = [MixtureFrame, ThermoFrame, TransportFrame]
self.mixfr = MixtureFrame(self.cwin, self)
self.thermo = ThermoFrame(self.cwin, self)
@ -254,13 +254,13 @@ class MixMaster:
self.addWindow('rxnpaths',ReactionPathFrame(self))
self.addWindow('dataset',DataFrame(None, self))
#self.edit = EditFrame(t, self)
self.windows = [self.mixfr,
self.thermo, self.transport,
self.kinetics]
self.showthermo()
self.showcomp()
#self.showtransport()
@ -268,19 +268,19 @@ class MixMaster:
#self.showrxns()
#self.showrpaths()
#self.showdata()
if self.mech:
self.mechframe.grid(row=1,column=0)
else:
self.mechframe.grid_forget()
#self.showedit()
def show(self, frame, vis, row, col):
if vis:
frame.grid(row=row,column=col,sticky=N+E+S+W)
else:
frame.grid_forget()
def showthermo(self):
if self.thermo:
self.show(self.thermo, self.vtherm.get(), 7, 0)
@ -291,25 +291,25 @@ class MixMaster:
def showkinetics(self):
if self.kinetics:
self.show(self.kinetics, self.vkin.get(), 10, 0)
self.show(self.kinetics, self.vkin.get(), 10, 0)
def showrxns(self):
self._windows['rxndata'].show()
self._windows['rxndata'].show()
def showrpaths(self):
self._windows['rxnpaths'].show()
def showdata(self):
self._windows['dataset'].browseForDatafile()
def aboutmix(self):
m = tkMessageBox.showinfo(title = 'About MixMaster',
message = """
MixMaster
version """+_app_version+"""
written by:
Prof. David G. Goodwin
@ -322,10 +322,4 @@ California Institute of Technology
if __name__ == "__main__":
MixMaster()
MixMaster()

View file

@ -2,7 +2,7 @@ from Tkinter import *
def make_menu(name, menubar, list):
from types import *
button=Menubutton(menubar, text=name, padx=3,pady=1)
button=Menubutton(menubar, text=name, padx=3,pady=1)
button.pack(side=LEFT, anchor=W)
menu = Menu(button,tearoff=FALSE)
for entry in list:

View file

@ -20,14 +20,14 @@ class NewFlowDialog:
lb = Listbox(geom)
for item in ["One-Dimensional", "Stagnation"]:
lb.insert(END, item)
lb.grid(row = 0, column = 0)
lb.grid(row = 0, column = 0)
glb = Listbox(geom)
for item in ["Axisymmetric","2D"]:
glb.insert(END, item)
glb.grid(row = 1, column = 0)
# ------------- pressure input ----------------
self.p = DoubleVar()
self.pbox = Entry(top, textvariable = self.p)
self.pbox.grid(row = 0, column = 1)
@ -42,46 +42,46 @@ class NewFlowDialog:
gl = Label(gasf, text='Gas Mixture Specification')
gl.grid(row = 0, column = 0)
self.infile = StringVar()
Label(gasf, text='Mixture Input File').grid(row = 1, column = 0)
Entry(gasf, textvariable = self.infile).grid(row = 1, column = 1)
Button(gasf, text='Browse..', command=self.getinfile).grid(row = 1,
column = 2)
self.spfile = StringVar()
self.spfile = StringVar()
Label(gasf, text='Species Database').grid(row = 2, column = 0)
Entry(gasf, textvariable = self.spfile).grid(row = 2, column = 1)
Button(gasf, text='Browse..', command=self.getspfile).grid(row = 2,
column = 2)
self.trfile = StringVar()
self.trfile = StringVar()
Label(gasf, text='Transport Database').grid(row = 3, column = 0)
Entry(gasf, textvariable = self.trfile).grid(row = 3, column = 1)
Button(gasf, text='Browse..', command=self.gettrfile).grid(row = 3,
column = 2)
# ------------- grid -------------------------
gf = Frame(top, bd=2, relief=GROOVE)
gf.grid(row = 5, column = 0, columnspan=2)
gr = Label(gf, text='Initial Grid')
gr.grid(row = 0, column = 0)
self.zleft = DoubleVar()
self.zright = DoubleVar()
self.zright = DoubleVar()
ll = Label(gf, text='Left boundary at ')
rl = Label(gf, text='Right boundary at ')
lbb = Entry(gf, textvariable = self.zleft)
rbb = Entry(gf, textvariable = self.zright)
rbb = Entry(gf, textvariable = self.zright)
ll.grid(row = 1, column = 0)
rl.grid(row = 2, column = 0)
lbb.grid(row = 1, column = 1)
rbb.grid(row = 2, column = 1)
rbb.grid(row = 2, column = 1)
ok = Button(top, text = 'OK', command=self.ok)
ok.grid(row = 20, column = 20)
@ -101,12 +101,12 @@ class NewFlowDialog:
self.gas = IdealGasMix(import_file = infile,
thermo_db = spfile)
else:
self.gas = IdealGasMix(import_file = infile)
self.gas = IdealGasMix(import_file = infile)
except:
tkMessageBox.showerror('Create Gas',
'Error reading file %s. See log file for more information.' % infile)
#self.flow = Flow1D(flow_type = ftype, flow_geom = fgeom,
# pressure = p, grid = gr, gas = g)
self.top.destroy()
@ -127,9 +127,4 @@ class NewFlowDialog:
pathname = askopenfilename(filetypes=[
("Transport Data Files", "*.xml *.dat"),
("All Files", "*.*")])
self.trfile.set(pathname)
self.trfile.set(pathname)

View file

@ -37,8 +37,3 @@ def handleError(message = '<error>', window = None,
else:
m = tkMessageBox.showerror(title = 'Error', message = message,
parent = window)

File diff suppressed because it is too large Load diff

View file

@ -54,35 +54,35 @@ if ifuel < 0:
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
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)
# 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)
# 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)
mix.vcs_equilibrate('HP', maxsteps = 1000,
rtol = 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()
# equilibrate the mixture adiabatically at constant P
#
# mix.equilibrate('HP', maxsteps = 1000,
# err = 1.0e-6, maxiter = 200, loglevel=0)
mix.vcs_equilibrate('HP', maxsteps = 1000,
rtol = 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
@ -100,4 +100,3 @@ print 'output written to '+csvfile
if '--plot' in sys.argv:
import plotting
plotting.plotEquilData(mix, phi, tad, xeq)

View file

@ -1,5 +1,5 @@
# An equilibrium example with charged species in the gas phase
# and multiple condensed phases.
# and multiple condensed phases.
# Note: This example runs fine on Mac and linux platforms, but
# encounters some convergence difficulties under Windows. The reasons
@ -35,11 +35,9 @@ for n in range(100):
# temperature and pressure fixed
# mix.equilibrate("TP",maxsteps=10000,loglevel=1)
mix.vcs_equilibrate("TP",printLvl=0,maxsteps=10000,loglevel=0)
# write out the moles of each species
writeCSV(f,[t]+ list(mix.speciesMoles()))
# close the output file
f.close()

View file

@ -20,7 +20,7 @@ def plotEquilData(mix, phi, tad, xeq):
if warnMac() < 0: return
npoints = len(phi)
nsp = mix.nSpecies()
#titles = ['Major Species', 'Minor Species', 'N Minor Species']
@ -50,7 +50,7 @@ def plotEquilData(mix, phi, tad, xeq):
subplot(2,2,2+m);
hold(True);
for i in range(nsp):
if p[i] == m:
for j in range(npoints):
@ -74,7 +74,7 @@ def plotEquilData(mix, phi, tad, xeq):
if m == 0:
axis([phi[1], phi[-1], 0.0, 1.0]);
else:
axis([phi[1], phi[-1], 1.0e-14, 1]);
axis([phi[1], phi[-1], 1.0e-14, 1]);
xlabel('Equivalence Ratio');
ylabel('Mole Fraction');
@ -82,4 +82,3 @@ def plotEquilData(mix, phi, tad, xeq):
hold(False)
show()

View file

@ -43,7 +43,7 @@ gas.set(T = temp, P = OneAtm, X = comp)
####################################################################
try:
gas.equilibrate("TP", solver = 0) # use the ChemEquil (0) solver
gas.equilibrate("TP", solver = 0) # use the ChemEquil (0) solver
except:
print "ChemEquil solver failed! Try the MultiPhaseEquil solver..."

View file

@ -24,9 +24,9 @@ tol_ts = [1.0e-5, 1.0e-9] # [rtol atol] for time stepping
loglevel = 1 # amount of diagnostic output (0
# to 5)
refine_grid = 1 # 1 to enable refinement, 0 to
# disable
# disable
gas = GRI30('Mix')
@ -37,7 +37,7 @@ gas.setState_TPX(tin, p, comp)
f = FreeFlame(gas = gas, grid = initial_grid, tfix = 600.0)
# set the upstream properties
# set the upstream properties
f.inlet.set(mole_fractions = comp, temperature = tin)
f.set(tol = tol_ss, tol_time = tol_ts)

View file

@ -32,9 +32,9 @@ tol_ts = [1.0e-4, 1.0e-9] # [rtol atol] for time stepping
loglevel = 1 # amount of diagnostic output (0
# to 5)
refine_grid = 1 # 1 to enable refinement, 0 to
# disable
# disable
################ create the gas object ########################
@ -85,4 +85,3 @@ fcsv.close()
print 'solution saved to flame1.csv'
f.showStats()

View file

@ -27,9 +27,9 @@ tol_ts = [1.0e-5, 1.0e-4] # [rtol atol] for time stepping
loglevel = 1 # amount of diagnostic output (0
# to 5)
refine_grid = 1 # 1 to enable refinement, 0 to
# disable
# disable
################ create the gas object ########################
@ -94,8 +94,3 @@ fcsv.close()
print 'solution saved to flame2.csv'
f.showStats()

View file

@ -25,7 +25,7 @@ def getTempData(filename):
print 'problem?'
print 'The one line found is: ',lines[0]
for line in lines:
if line[0] == '#': # use '#' as the comment character
pass
@ -38,13 +38,13 @@ def getTempData(filename):
pass
print 'read',len(z),'temperature values.'
f.close()
# convert z values into non-dimensional relative positions.
n = len(z)
zmax = z[n-1]
for i in range(n):
z[i] = z[i]/zmax
return [z,t]
@ -70,9 +70,9 @@ tol_ts = [1.0e-5, 1.0e-4] # [rtol atol] for time stepping
loglevel = 1 # amount of diagnostic output (0
# to 5)
refine_grid = 1 # 1 to enable refinement, 0 to
# disable
# disable
################ create the gas object ########################
@ -142,8 +142,3 @@ fcsv.close()
print 'solution saved to flame_fixed_T.csv'
f.showStats()

View file

@ -28,9 +28,9 @@ tol_ts = [1.0e-4, 1.0e-9] # [rtol atol] for time stepping
loglevel = 1 # amount of diagnostic output (0
# to 5)
refine_grid = 1 # 1 to enable refinement, 0 to
# disable
# disable
################ create the gas object ########################
@ -81,4 +81,3 @@ fcsv.close()
print 'solution saved to freeflame1.csv'
print 'flamespeed = ',u[0],'m/s'
f.showStats()

View file

@ -34,9 +34,9 @@ tol_ts = [1.0e-3, 1.0e-9] # [rtol, atol] for time stepping
loglevel = 1 # amount of diagnostic output (0
# to 5)
refine_grid = 1 # 1 to enable refinement, 0 to
# disable
# disable
################ create the gas object ########################
@ -119,6 +119,3 @@ print 'solution saved to npflame1.csv'
f.showSolution()
f.showStats(0)

View file

@ -47,7 +47,7 @@ tol_ts = [1.0e-4, 1.0e-9] # [rtol atol] for time stepping
loglevel = 1 # amount of diagnostic output (0
# to 5)
refine_grid = 1 # 1 to enable refinement, 0 to
# disable
ratio = 5.0
@ -114,4 +114,3 @@ for md in mdot:
print 'solution saved to flame1.csv'
f.showStats()

View file

@ -80,7 +80,7 @@ def NewtonSolver(f, xstart, C = 0.0):
"""
f0 = f(xstart) - C
x0 = xstart
dx = 1.0e-6
dx = 1.0e-6
xlast = 999.0
n = 0
while n < 200:
@ -91,9 +91,9 @@ def NewtonSolver(f, xstart, C = 0.0):
# avoid taking steps too large
if abs(step) > 0.1:
step = 0.1*step/abs(step)
x0 += step
emax = 0.00001 # 0.01 mV tolerance
emax = 0.00001 # 0.01 mV tolerance
if abs(f0) < emax and n > 8:
return x0
xlast = x0
@ -187,7 +187,7 @@ def cathode_curr(E):
# the cathode potential.
ee = E + oxide_c.electricPotential()
cathode_bulk.setElectricPotential(ee)
# get the species net production rates due to the cathode-side TPB
# reaction mechanism. The production rate array has the values for
# the neighbor species in the order listed in the .cti file,
@ -277,13 +277,13 @@ for n in range(100):
# note that both the bulk and the surface potentials must be set
oxide_c.setElectricPotential(phi_oxide_c)
oxide_surf_c.setElectricPotential(phi_oxide_c)
oxide_surf_c.setElectricPotential(phi_oxide_c)
# Find the value of the cathode potential relative to the
# cathode-side electrolyte that yields the same current density
# as the anode current density
Ec = NewtonSolver(cathode_curr, xstart = Ec0 + 0.1, C = curr)
cathode_bulk.setElectricPotential(phi_oxide_c + Ec);
# write the current density, anode and cathode overpotentials,

View file

@ -5,7 +5,7 @@ import math
def soundspeed(gas):
"""The speed of sound. Assumes an ideal gas."""
# if gas.isIdealGas():
gamma = gas.cp_mass()/gas.cv_mass()
return math.sqrt(gamma * GasConstant
@ -14,11 +14,11 @@ def soundspeed(gas):
# raise "non-ideal not implemented."
def isentropic(g = None):
"""
ISENTROPIC isentropic, adiabatic flow example
In this example, the area ratio vs. Mach number curve is
computed. If a gas object is supplied, it will be used for the
calculations, with the stagnation state given by the input gas
@ -39,24 +39,24 @@ def isentropic(g = None):
s0 = gas.entropy_mass()
h0 = gas.enthalpy_mass()
p0 = gas.pressure()
mdot = 1 # arbitrary
amin = 1.e14
data = zeros((200,4),'d')
# compute values for a range of pressure ratios
for r in range(200):
p = p0*(r+1)/201.0
# set the state using (p,s0)
gas.set(S = s0, P = p)
h = gas.enthalpy_mass()
rho = gas.density()
v2 = 2.0*(h0 - h) # h + V^2/2 = h0
v = math.sqrt(v2)
v = math.sqrt(v2)
area = mdot/(rho*v); # rho*v*A = constant
if area < amin: amin = area
data[r,:] = [area, v/soundspeed(gas), gas.temperature(), p/p0]
@ -65,7 +65,7 @@ def isentropic(g = None):
return data
if __name__ == "__main__":
print isentropic.__doc__
@ -78,13 +78,7 @@ if __name__ == "__main__":
xlabel('Mach Number')
title('Isentropic Flow: Area Ratio vs. Mach Number')
show()
except:
print 'area ratio, Mach number, temperature, pressure ratio'
print data

View file

@ -28,7 +28,7 @@ def equilSoundSpeeds(gas, rtol = 1.0e-6, maxiter = 5000):
# save the density for this case for the frozen sound speed
rho_frozen = gas.density()
# now equilibrate the gas holding S and P constant
gas.equilibrate("SP", loglevel=0, rtol = rtol, maxiter = maxiter) # , rtol = 1.0e-3, maxsteps=10000)
@ -52,12 +52,10 @@ def equilSoundSpeeds(gas, rtol = 1.0e-6, maxiter = 5000):
# test program
if __name__ == "__main__":
gas = GRI30()
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)
print temp, equilSoundSpeeds(gas)

View file

@ -29,7 +29,7 @@ def show_rate_coefficients(mech, doIrrev = 0):
for i in range(nr):
print '%40s %12.5g %12.5g ' % (eqs[i], kf[i], kr[i])
print 'units: kmol, m, s'
@ -42,7 +42,5 @@ if __name__ == "__main__":
mech = importPhase(sys.argv[1], sys.argv[2])
else:
mech = GRI30()
show_rate_coefficients(mech)

View file

@ -25,5 +25,3 @@ for name in fluids.keys():
mw = f.meanMolecularWeight()
zc = pc*mw/(rc*GasConstant*tc)
print '%20s %10.4g %10.4G %10.4G' % (name, tc, pc, zc)

View file

@ -51,7 +51,7 @@ def expand(fluid, pfinal, eta):
def printState(n, fluid):
print '\n\n***************** State '+`n`+' ******************\n', fluid
###############################################################
@ -85,10 +85,3 @@ printState(4,w)
eff = (turbine_work - pump_work)/heat_added
print 'efficiency = ',eff

View file

@ -31,7 +31,7 @@ output_urldir = 'http://your.http.server/'
#-----------------------------------------------------------------------
# these lines can be replaced by any commands that generate
# an object of a class derived from class Kinetics (such as IdealGasMix)
# in some state.
# in some state.
gas = GRI30()
gas.setState_TPX(2500.0, OneAtm, 'CH4:0.4, O2:1, N2:3.76')
gas.equilibrate('TP')
@ -52,5 +52,3 @@ if len(opts) > 1 and opts[1] == "-view":
# graphics format. Must be one of png, svg, gif, or jpg
fmt = 'svg'
rxnpath.view(url, fmt)

View file

@ -80,4 +80,3 @@ while tnow < tfinal:
writeCSV(f, [tnow, combustor.temperature(), tres]
+list(combustor.moleFractions()))
f.close()

View file

@ -81,4 +81,3 @@ for n in range(30):
# view the state of the gas in the mixer
print mixer.contents()

View file

@ -92,7 +92,7 @@ for n in range(30):
if mixer.temperature() > 1200.0:
mfc3.set(mdot = 0.0)
sim.setInitialTime(t)
print '%14.5g %14.5g %14.5g %14.5g %14.5g' % (t, mixer.temperature(),
mixer.enthalpy_mass(),
mixer.pressure(),
@ -100,4 +100,3 @@ for n in range(30):
# view the state of the gas in the mixer
print mixer.contents()

View file

@ -60,10 +60,10 @@ for n in range(30):
v1.append(r1.volume())
v2.append(r2.volume())
v.append(r1.volume() + r2.volume())
xco.append(r2.moleFraction('CO'))
xco.append(r2.moleFraction('CO'))
xh2.append(r1.moleFraction('H2'))
# plot the results if matplotlib is installed.
# see http://matplotlib.sourceforge.net to get it
args = sys.argv
@ -93,7 +93,6 @@ if len(args) > 1 and (args[1] == '-plot' or
except:
print """matplotlib required.
http://matplotlib.sourceforge.net"""
else:
print """To view a plot of these results, run this script with the option -plot"""

View file

@ -34,10 +34,10 @@ for n in range(100):
sim.advance(time)
tim[n] = time
data[n,0] = r.temperature()
data[n,1] = r.moleFraction('OH')
data[n,1] = r.moleFraction('OH')
data[n,2] = r.moleFraction('H')
data[n,3] = r.moleFraction('H2')
print '%10.3e %10.3f %10.3f %14.6e' % (sim.time(), r.temperature(),
data[n,3] = r.moleFraction('H2')
print '%10.3e %10.3f %10.3f %14.6e' % (sim.time(), r.temperature(),
r.pressure(), r.intEnergy_mass())

View file

@ -98,7 +98,7 @@ print 'Directory: '+os.getcwd()
args = sys.argv
if len(args) > 1 and args[1] == '-plot':
try:
try:
from matplotlib.pylab import *
clf
subplot(2,2,1)
@ -106,22 +106,21 @@ if len(args) > 1 and args[1] == '-plot':
legend(['Reactor 1','Reactor 2'],2)
xlabel('Time (s)');
ylabel('Temperature (K)');
subplot(2,2,2)
plot(tm, pres[:,0],'g-',tm, pres[:,1],'b-')
legend(['Reactor 1','Reactor 2'],2)
xlabel('Time (s)');
ylabel('Pressure (Bar)');
subplot(2,2,3)
plot(tm, vol[:,0],'g-',tm, vol[:,1],'b-')
legend(['Reactor 1','Reactor 2'],2)
xlabel('Time (s)');
ylabel('Volume (m^3)');
ylabel('Volume (m^3)');
show()
except:
pass
else:
print """To view a plot of these results, run this script with the option -plot"""

View file

@ -47,17 +47,17 @@ for n in range(np):
sim.advance(time)
tim[n] = time
data[n,0] = r.temperature()
data[n,1] = r.moleFraction('OH')
data[n,1] = r.moleFraction('OH')
data[n,2] = r.moleFraction('H')
data[n,3] = r.moleFraction('CH4')
# sensitivity of OH to reaction 2
data[n,4] = sim.sensitivity('OH',2)
# sensitivity of OH to reaction 3
# sensitivity of OH to reaction 3
data[n,5] = sim.sensitivity('OH',3)
print '%10.3e %10.3f %10.3f %14.6e %10.3f %10.3f' % (sim.time(), r.temperature(),
print '%10.3e %10.3f %10.3f %14.6e %10.3f %10.3f' % (sim.time(), r.temperature(),
r.pressure(), r.intEnergy_mass(), data[n,4], data[n,5])
@ -88,7 +88,7 @@ if len(args) > 1 and args[1] == '-plot':
plot(tim,data[:,4],'-',tim,data[:,5],'-g')
legend([r.sensParamName(2),r.sensParamName(3)],'best')
xlabel('Time (s)');
ylabel('OH Sensitivity');
ylabel('OH Sensitivity');
show()
except:
print 'could not make plots'

View file

@ -33,7 +33,7 @@ cat_area_per_vol = 1000.0 / cm # Catalyst particle surface area
# per unit volume
velocity = 40.0 * cm / minute # gas velocity
porosity = 0.3 # Catalyst bed porosity
# input file containing the surface reaction mechanism
cti_file = 'methane_pox_on_pt.cti'
@ -90,79 +90,79 @@ mass_flow_rate = velocity * rho0 * area
# reactor, integrating each one to steady state.
for n in range(NReactors):
# create a new reactor
r = Reactor(contents = gas, energy = 'off', volume = rvol)
# create a reservoir to represent the reactor immediately
# upstream. Note that the gas object is set already to the
# state of the upstream reactor
upstream = Reservoir(gas, name = 'upstream')
# create a new reactor
r = Reactor(contents = gas, energy = 'off', volume = rvol)
# create a reservoir for the reactor to exhaust into. The
# composition of this reservoir is irrelevant.
downstream = Reservoir(gas, name = 'downstream')
# create a reservoir to represent the reactor immediately
# upstream. Note that the gas object is set already to the
# state of the upstream reactor
upstream = Reservoir(gas, name = 'upstream')
# use a 'Wall' object to implement the reacting surface in the
# reactor. Since walls have to be installed between two
# reactors/reserviors, we'll install it between the upstream
# reservoir and the reactor. The area is set to the desired
# catalyst area in the reactor, and surface reactions are
# included only on the side facing the reactor.
w = Wall(left = upstream, right = r, A = cat_area, kinetics = [None, surf])
# We need a valve between the reactor and the downstream reservoir.
# This will determine the pressure in the reactor. Set Kv large
# enough that the pressure difference is very small.
v = Valve(upstream = r, downstream = downstream, Kv = 3.0e-6)
# create a reservoir for the reactor to exhaust into. The
# composition of this reservoir is irrelevant.
downstream = Reservoir(gas, name = 'downstream')
# The mass flow rate into the reactor will be fixed by using a
# MassFlowController object.
m = MassFlowController(upstream = upstream,
downstream = r, mdot = mass_flow_rate)
# use a 'Wall' object to implement the reacting surface in the
# reactor. Since walls have to be installed between two
# reactors/reserviors, we'll install it between the upstream
# reservoir and the reactor. The area is set to the desired
# catalyst area in the reactor, and surface reactions are
# included only on the side facing the reactor.
w = Wall(left = upstream, right = r, A = cat_area, kinetics = [None, surf])
# We need a valve between the reactor and the downstream reservoir.
# This will determine the pressure in the reactor. Set Kv large
# enough that the pressure difference is very small.
v = Valve(upstream = r, downstream = downstream, Kv = 3.0e-6)
sim = ReactorNet([upstream, r, downstream])
# The mass flow rate into the reactor will be fixed by using a
# MassFlowController object.
m = MassFlowController(upstream = upstream,
downstream = r, mdot = mass_flow_rate)
# set relative and absolute tolerances on the simulation
sim.setTolerances(rtol = 1.0e-4, atol = 1.0e-11)
time = 0
while 1 > 0:
time = time + dt
sim.advance(time)
# check whether surface coverages are in steady
# state. This will be the case if the creation and
# destruction rates for a surface (but not gas) species
# are equal.
alldone = 1
sim = ReactorNet([upstream, r, downstream])
# Note: netProduction = creation - destruction. By
# supplying the surface object as an argument, only the
# values for the surface species are returned by these
# methods
sdot = surf.netProductionRates(surf)
cdot = surf.creationRates(surf)
ddot = surf.destructionRates(surf)
for ks in range(nsurf):
ratio = sdot[ks]/(cdot[ks] + ddot[ks])
if ratio < 0.0: ratio = -ratio
if ratio > 1.0e-9 or time < 10*dt:
alldone = 0
if alldone: break
# set relative and absolute tolerances on the simulation
sim.setTolerances(rtol = 1.0e-4, atol = 1.0e-11)
# set the gas object state to that of this reactor, in
# preparation for the simulation of the next reactor
# downstream, where this object will set the inlet conditions
gas = r.contents()
time = 0
while 1 > 0:
time = time + dt
sim.advance(time)
dist = n*rlen * 1.0e3 # distance in mm
# check whether surface coverages are in steady
# state. This will be the case if the creation and
# destruction rates for a surface (but not gas) species
# are equal.
alldone = 1
# write the gas mole fractions and surface coverages
# vs. distance
writeCSV(f, [dist, r.temperature() - 273.15,
r.pressure()/OneAtm] + list(gas.moleFractions())
+ list(surf.coverages()))
# Note: netProduction = creation - destruction. By
# supplying the surface object as an argument, only the
# values for the surface species are returned by these
# methods
sdot = surf.netProductionRates(surf)
cdot = surf.creationRates(surf)
ddot = surf.destructionRates(surf)
for ks in range(nsurf):
ratio = sdot[ks]/(cdot[ks] + ddot[ks])
if ratio < 0.0: ratio = -ratio
if ratio > 1.0e-9 or time < 10*dt:
alldone = 0
if alldone: break
# set the gas object state to that of this reactor, in
# preparation for the simulation of the next reactor
# downstream, where this object will set the inlet conditions
gas = r.contents()
dist = n*rlen * 1.0e3 # distance in mm
# write the gas mole fractions and surface coverages
# vs. distance
writeCSV(f, [dist, r.temperature() - 273.15,
r.pressure()/OneAtm] + list(gas.moleFractions())
+ list(surf.coverages()))
f.close()
@ -179,5 +179,3 @@ f.close()
element = 'C'
rxnpath.write(surf, element, 'carbon_pathways.dot')

View file

@ -3,7 +3,7 @@ from os.path import walk
pycmd = os.getenv("PYTHON_CMD")
if not pycmd:
pycmd = "python"
def run_example(dir, file):
print "******************************************"
print " Example "+file+" ("+dir+")"
@ -16,7 +16,7 @@ def run_examples(a, dir, files):
for f in files:
base, ext = os.path.splitext(f)
print base, " <> ",ext
if dir <> "." and ext == ".py":
if dir <> "." and ext == ".py":
run_example(dir, f)
walk(".",run_examples,None)

View file

@ -1,5 +1,5 @@
# CATCOMB -- Catalytic combustion of methane on platinum.
#
#
# This script solves a catalytic combustion problem. A stagnation flow
# is set up, with a gas inlet 10 cm from a platinum surface at 900
# K. The lean, premixed methane/air mixture enters at ~ 6 cm/s (0.06
@ -49,10 +49,10 @@ tol_ts = [1.0e-4, 1.0e-9] # [rtol, atol] for time stepping
loglevel = 1 # amount of diagnostic output
# (0 to 5)
refine_grid = 1 # 1 to enable refinement, 0 to
# disable
################ create the gas object ########################
#
# This object will be used to evaluate all thermodynamic, kinetic,
@ -60,7 +60,7 @@ refine_grid = 1 # 1 to enable refinement, 0 to
#
# The gas phase will be taken from the definition of phase 'gas' in
# input file 'ptcombust.cti,' which is a stripped-down version of
# GRI-Mech 3.0.
# GRI-Mech 3.0.
gas = importPhase('ptcombust.cti','gas')
gas.set(T = tinlet, P = p, X = comp1)
@ -71,7 +71,7 @@ gas.set(T = tinlet, P = p, X = comp1)
# rates. It will be created from the interface definition 'Pt_surf'
# in input file 'ptcombust.cti,' which implements the reaction
# mechanism of Deutschmann et al., 1995 for catalytic combustion on
# platinum.
# platinum.
#
surf_phase = importInterface('ptcombust.cti','Pt_surf', [gas])
surf_phase.setTemperature(tsurf)
@ -79,7 +79,7 @@ surf_phase.setTemperature(tsurf)
# integrate the coverage equations in time for 1 s, holding the gas
# composition fixed to generate a good starting estimate for the
# coverages.
# coverages.
surf_phase.advanceCoverages(1.0)
# create the object that simulates the stagnation flow, and specify an
@ -94,7 +94,7 @@ sim.surface.set(T = tsurf)
# Set error tolerances
sim.set(tol = tol_ss, tol_time = tol_ts)
# Method 'init' must be called before beginning a simulation
# Method 'init' must be called before beginning a simulation
sim.init()
# Show the initial solution estimate
@ -172,10 +172,10 @@ cov = sim.coverages()
names = surf_phase.speciesNames()
for n in range(len(names)):
writeCSV(f, [names[n], cov[n]])
f.close()
print 'solution saved to catcomb.csv'
# show some statistics
# show some statistics
sim.showStats()

View file

@ -42,7 +42,3 @@ for n in range(20):
f.close()
print 'H concentration, growth rate, and surface coverages written to file diamond.csv'

View file

@ -35,7 +35,7 @@ print gas1
# heat capacity c_p 14311.8 2.885e+04 J/K
# heat capacity c_v 10187.3 2.054e+04 J/K
# X Y
# X Y
# ------------- ------------
# H2 1.000000e+00 1.000000e+00
# H 0.000000e+00 0.000000e+00
@ -132,8 +132,8 @@ print gas1
# density 0.081896 kg/m^3
# mean mol. weight 2.01594 amu
#
# X Y
# ------------- ------------
# X Y
# ------------- ------------
# H2 1.000000e+000 1.000000e+000
# (other species not shown)
#
@ -156,7 +156,7 @@ print gas1
# b) Setting the pressure is done holding temperature and
# composition fixed. (The density changes.)
#
#
# c) Setting the composition is done holding temperature
# and density fixed. (The pressure changes).
#
@ -196,7 +196,7 @@ print gas1
# heat capacity c_p 1304.4 3.604e+04 J/K
# heat capacity c_v 1003.52 2.773e+04 J/K
# X Y
# X Y
# ------------- ------------
# H2 0.000000e+00 0.000000e+00
# H 0.000000e+00 0.000000e+00
@ -286,9 +286,3 @@ print gas1
# To set the mass fractions to equal values:
gas1.set(Y = x)
print gas1

View file

@ -117,6 +117,3 @@ diamonnd_surf2 = importInterface('diamond.xml','diamond_100',
#
# ck2cti -i mech.inp -t therm.dat -tr tran.dat -id mymech > mech.cti
#

View file

@ -7,7 +7,7 @@ print """
######################################################
# Suppose you have created a Cantera object and want to know what
# methods are available for it, and get help on using the methods.
# methods are available for it, and get help on using the methods.
from Cantera import *
g = GRI30()
@ -42,7 +42,7 @@ help(g.__class__)
# do this instead: Run 'pythonw' interactively (not 'python'), import
# module 'pydoc', and call function 'gui':
#
# pythonw
# pythonw
# >>> import pydoc
# >>> pydoc.gui()
#

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