These changes make it unnecessary to copy header files around during the build process, which tends to confuse IDEs and debuggers. The headers which comprise Cantera's external C++ interface are now in the 'include' directory. All of the samples and demos are now in the 'samples' subdirectory.
317 lines
10 KiB
Python
Executable file
317 lines
10 KiB
Python
Executable file
"""
|
|
Kinetics managers.
|
|
"""
|
|
|
|
from Cantera.exceptions import CanteraError, getCanteraError
|
|
from Cantera.ThermoPhase import ThermoPhase
|
|
from Cantera.XML import XML_Node
|
|
from Cantera.num import zeros
|
|
import _cantera
|
|
|
|
class Kinetics:
|
|
"""
|
|
Kinetics managers. Instances of class Kinetics are responsible for
|
|
evaluating reaction rates of progress, species production rates,
|
|
and other quantities pertaining to a reaction mechanism.
|
|
|
|
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.
|
|
"""
|
|
np = len(phases)
|
|
self._sp = []
|
|
self._phnum = {}
|
|
|
|
# p0 through p4 are the integer indices of the phase objects
|
|
# corresponding to the input sequence of phases
|
|
self._end = [0]
|
|
p0 = phases[0].thermophase()
|
|
p1 = -1
|
|
p2 = -1
|
|
p3 = -1
|
|
p4 = -1
|
|
if np >= 2:
|
|
p1 = phases[1].thermophase()
|
|
if np >= 3:
|
|
p2 = phases[2].thermophase()
|
|
if np >= 4:
|
|
p3 = phases[3].thermophase()
|
|
if np >= 5:
|
|
p4 = phases[4].thermophase()
|
|
if np >= 6:
|
|
raise CanteraError("a maximum of 4 neighbor phases allowed")
|
|
|
|
self.ckin = _cantera.KineticsFromXML(xml_phase,
|
|
p0, p1, p2, p3, p4)
|
|
|
|
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))
|
|
|
|
def __del__(self):
|
|
self.clear()
|
|
|
|
def clear(self):
|
|
"""Delete the kinetics manager."""
|
|
if self.ckin > 0:
|
|
_cantera.kin_delete(self.ckin)
|
|
|
|
def kin_index(self):
|
|
print "kin_index is deprecated. Use kinetics_hndl."
|
|
return self.ckin
|
|
|
|
def kinetics_hndl(self):
|
|
return self.ckin
|
|
|
|
def kineticsType(self):
|
|
"""Kinetics manager type."""
|
|
return _cantera.kin_type(self.ckin)
|
|
|
|
def kineticsSpeciesIndex(self, name, phase):
|
|
"""The index of a species.
|
|
name -- species name
|
|
phase -- phase name
|
|
|
|
Kinetics managers for heterogeneous reaction mechanisms
|
|
maintain a list of all species in all phases. The order of the
|
|
species in this list determines the ordering of the arrays of
|
|
production rates. This method returns the index for the
|
|
specified species of the specified phase, and is used to
|
|
locate the entry for a particular species in the production
|
|
rate arrays.
|
|
|
|
"""
|
|
return _cantera.kin_speciesIndex(self.ckin, name, phase)
|
|
|
|
def kineticsStart(self, n):
|
|
"""The starting location of phase n in production rate arrays."""
|
|
return _cantera.kin_start(self.ckin, n)
|
|
|
|
def nPhases(self):
|
|
"""Number of phases."""
|
|
return _cantera.kin_nPhases(self.ckin)
|
|
|
|
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)
|
|
|
|
def isReversible(self,i):
|
|
"""
|
|
True (1) if reaction number 'i' is reversible,
|
|
and false (0) otherwise.
|
|
"""
|
|
return _cantera.kin_isreversible(self.ckin,i)
|
|
|
|
def reactionType(self,i):
|
|
"""Type of reaction 'i'"""
|
|
return _cantera.kin_rxntype(self.ckin,i)
|
|
|
|
def reactionEqn(self,i):
|
|
"""The equation for the specified reaction. If a list of equation numbers
|
|
is given, then a list of equation strings is returned."""
|
|
try:
|
|
eqs = []
|
|
for rxn in i:
|
|
eqs.append(self.reactionString(rxn))
|
|
return eqs
|
|
except:
|
|
return self.reactionString(i)
|
|
|
|
def reactionString(self, i):
|
|
"""Reaction string for reaction number 'i'"""
|
|
s = ''
|
|
nsp = _cantera.kin_nspecies(self.ckin)
|
|
for k in range(nsp):
|
|
nur = _cantera.kin_rstoichcoeff(self.ckin,k,i)
|
|
if nur <> 0.0:
|
|
if nur <> 1.0:
|
|
if nur <> round(nur):
|
|
s += str(nur)+' '
|
|
else:
|
|
s += `int(nur)`+' '
|
|
s += self._sp[k]+' + '
|
|
s = s[:-2]
|
|
if self.isReversible(i):
|
|
s += ' <=> '
|
|
else:
|
|
s += ' => '
|
|
for k in range(nsp):
|
|
nup = _cantera.kin_pstoichcoeff(self.ckin,k,i)
|
|
if nup <> 0.0:
|
|
if nup <> 1.0:
|
|
if nup <> round(nup):
|
|
s += str(nup)+' '
|
|
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
|
|
coefficient of species k in reaction i."""
|
|
nsp = _cantera.kin_nspecies(self.ckin)
|
|
nr = _cantera.kin_nreactions(self.ckin)
|
|
nu = zeros((nsp,nr),'d')
|
|
for i in range(nr):
|
|
for k in range(nsp):
|
|
nu[k,i] = _cantera.kin_rstoichcoeff(self.ckin,k,i)
|
|
return nu
|
|
|
|
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)
|
|
|
|
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."""
|
|
nsp = _cantera.kin_nspecies(self.ckin)
|
|
nr = _cantera.kin_nreactions(self.ckin)
|
|
nu = zeros((nsp,nr),'d')
|
|
for i in range(nr):
|
|
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)
|
|
|
|
def revRatesOfProgress(self):
|
|
"""Reverse rates of progress of the reactions."""
|
|
return _cantera.kin_getarray(self.ckin,20)
|
|
|
|
def netRatesOfProgress(self):
|
|
"""Net rates of progress of the reactions."""
|
|
return _cantera.kin_getarray(self.ckin,30)
|
|
|
|
def equilibriumConstants(self):
|
|
"""Equilibrium constants in concentration units for all reactions."""
|
|
return _cantera.kin_getarray(self.ckin,40)
|
|
|
|
def activationEnergies(self):
|
|
"""Activation energies in Kelvin for all reactions."""
|
|
return _cantera.kin_getarray(self.ckin,32)
|
|
|
|
def fwdRateConstants(self):
|
|
"""Forward rate constants for all reactions."""
|
|
return _cantera.kin_getarray(self.ckin,34)
|
|
|
|
def revRateConstants(self, doIrreversible = 0):
|
|
"""Reverse rate constants for all reactions."""
|
|
if doIrreversible:
|
|
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:
|
|
kp = phase.thermophase()
|
|
if self._phnum.has_key(kp):
|
|
n = self._phnum[kp]
|
|
return c[self._end[n]:self._end[n+1]]
|
|
else:
|
|
raise CanteraError('unknown phase')
|
|
else:
|
|
return c
|
|
|
|
|
|
def destructionRates(self, phase = None):
|
|
d = _cantera.kin_getarray(self.ckin,60)
|
|
if phase:
|
|
kp = phase.thermophase()
|
|
if self._phnum.has_key(kp):
|
|
n = self._phnum[kp]
|
|
return d[self._end[n]:self._end[n+1]]
|
|
else:
|
|
raise CanteraError('unknown phase')
|
|
else:
|
|
return d
|
|
|
|
|
|
def netProductionRates(self, phase = None):
|
|
w = _cantera.kin_getarray(self.ckin,70)
|
|
if phase:
|
|
kp = phase.thermophase()
|
|
if self._phnum.has_key(kp):
|
|
n = self._phnum[kp]
|
|
return w[self._end[n]:self._end[n+1]]
|
|
else:
|
|
raise CanteraError('unknown phase')
|
|
else:
|
|
return w
|
|
|
|
def sourceTerms(self):
|
|
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)
|
|
|
|
def delta_H0(self):
|
|
return _cantera.kin_getarray(self.ckin,93)
|
|
|
|
def delta_G0(self):
|
|
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)
|
|
|
|
def setMultiplier(self, value = 0.0, reaction = -1):
|
|
if reaction < 0:
|
|
nr = self.nReactions()
|
|
for i in range(nr):
|
|
_cantera.kin_setMultiplier(self.ckin,i,value)
|
|
else:
|
|
_cantera.kin_setMultiplier(self.ckin,reaction,value)
|
|
|
|
def advanceCoverages(self,dt):
|
|
return _cantera.kin_advanceCoverages(self.ckin,dt)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|