Reformatted the Python docstrings to work better with Sphinx
This means that the docstrings are now parsed as reStructuredText.
This commit is contained in:
parent
09d9ded2e7
commit
b4ceb7da2e
26 changed files with 1059 additions and 866 deletions
|
|
@ -14,6 +14,8 @@ if localenv['sphinx_docs']:
|
||||||
localenv['SPHINXBUILD'] = Dir('#build/sphinx')
|
localenv['SPHINXBUILD'] = Dir('#build/sphinx')
|
||||||
localenv['SPHINXSRC'] = Dir('sphinx')
|
localenv['SPHINXSRC'] = Dir('sphinx')
|
||||||
|
|
||||||
build(localenv.Command('${SPHINXBUILD}/html/index.html',
|
sphinxdocs = build(localenv.Command('${SPHINXBUILD}/html/index.html',
|
||||||
'sphinx/conf.py',
|
'sphinx/conf.py',
|
||||||
'sphinx-build -b html -d ${SPHINXBUILD}/doctrees ${SPHINXSRC} ${SPHINXBUILD}/html'))
|
'sphinx-build -b html -d ${SPHINXBUILD}/doctrees ${SPHINXSRC} ${SPHINXBUILD}/html'))
|
||||||
|
|
||||||
|
localenv.AlwaysBuild(sphinxdocs)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import sys, os
|
||||||
# add these directories to sys.path here. If the directory is relative to the
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
sys.path.insert(0, os.path.abspath('../../interfaces/python'))
|
sys.path.insert(0, os.path.abspath('../../interfaces/python'))
|
||||||
|
sys.path.append(os.path.abspath('.'))
|
||||||
|
|
||||||
# -- General configuration -----------------------------------------------------
|
# -- General configuration -----------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -25,11 +26,20 @@ sys.path.insert(0, os.path.abspath('../../interfaces/python'))
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||||
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.pngmath',
|
extensions = ['sphinx.ext.autodoc',
|
||||||
'sphinx.ext.autosummary']
|
'sphinx.ext.todo',
|
||||||
|
'sphinx.ext.autosummary',
|
||||||
|
'mathjax']
|
||||||
|
|
||||||
|
# @todo: Sphinx version 1.1 adds support for MathJax, so we can remove the
|
||||||
|
# custom extension for that once that version becomes more standard
|
||||||
|
|
||||||
autodoc_default_flags = ['members','show-inheritance','undoc-members']
|
autodoc_default_flags = ['members','show-inheritance','undoc-members']
|
||||||
|
|
||||||
|
autoclass_content = 'both'
|
||||||
|
|
||||||
|
mathjax_path = 'http://mathjax.connectmv.com/MathJax.js'
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
templates_path = ['_templates']
|
templates_path = ['_templates']
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,12 @@
|
||||||
Func Module
|
Func Module
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
Quick links:
|
||||||
|
* :class:`.Polynomial`
|
||||||
|
* :class:`.Gaussian`
|
||||||
|
* :class:`.Fourier`
|
||||||
|
* :class:`.Arrhenius`
|
||||||
|
|
||||||
.. automodule:: Cantera.Func
|
.. automodule:: Cantera.Func
|
||||||
|
:member-order: bysource
|
||||||
|
:no-show-inheritance:
|
||||||
|
|
|
||||||
68
doc/sphinx/mathjax.py
Normal file
68
doc/sphinx/mathjax.py
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
sphinx.ext.mathjax
|
||||||
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Allow `MathJax <http://mathjax.org/>`_ to be used to display math
|
||||||
|
in Sphinx's HTML writer - requires the MathJax JavaScript library
|
||||||
|
on your webserver/computer.
|
||||||
|
|
||||||
|
Kevin Dunn, kgdunn@gmail.com, 3-clause BSD license.
|
||||||
|
|
||||||
|
|
||||||
|
For background, installation details and support:
|
||||||
|
|
||||||
|
https://bitbucket.org/kevindunn/sphinx-extension-mathjax
|
||||||
|
|
||||||
|
"""
|
||||||
|
from docutils import nodes
|
||||||
|
from sphinx.application import ExtensionError
|
||||||
|
from sphinx.ext.mathbase import setup_math as mathbase_setup
|
||||||
|
|
||||||
|
def html_visit_math(self, node):
|
||||||
|
self.body.append(self.starttag(node, 'span', '', CLASS='math'))
|
||||||
|
self.body.append(self.builder.config.mathjax_inline[0] + \
|
||||||
|
self.encode(node['latex']) +\
|
||||||
|
self.builder.config.mathjax_inline[1] + '</span>')
|
||||||
|
raise nodes.SkipNode
|
||||||
|
|
||||||
|
def html_visit_displaymath(self, node):
|
||||||
|
self.body.append(self.starttag(node, 'div', CLASS='math'))
|
||||||
|
if node['nowrap']:
|
||||||
|
self.body.append(self.builder.config.mathjax_display[0] + \
|
||||||
|
node['latex'] +\
|
||||||
|
self.builder.config.mathjax_display[1])
|
||||||
|
self.body.append('</div>')
|
||||||
|
raise nodes.SkipNode
|
||||||
|
|
||||||
|
parts = [prt for prt in node['latex'].split('\n\n') if prt.strip() != '']
|
||||||
|
for i, part in enumerate(parts):
|
||||||
|
part = self.encode(part)
|
||||||
|
if i == 0:
|
||||||
|
# necessary to e.g. set the id property correctly
|
||||||
|
if node['number']:
|
||||||
|
self.body.append('<span class="eqno">(%s)</span>' %
|
||||||
|
node['number'])
|
||||||
|
if '&' in part or '\\\\' in part:
|
||||||
|
self.body.append(self.builder.config.mathjax_display[0] + \
|
||||||
|
'\\begin{split}' + part + '\\end{split}' + \
|
||||||
|
self.builder.config.mathjax_display[1])
|
||||||
|
else:
|
||||||
|
self.body.append(self.builder.config.mathjax_display[0] + part + \
|
||||||
|
self.builder.config.mathjax_display[1])
|
||||||
|
self.body.append('</div>\n')
|
||||||
|
raise nodes.SkipNode
|
||||||
|
|
||||||
|
def builder_inited(app):
|
||||||
|
if not app.config.mathjax_path:
|
||||||
|
raise ExtensionError('mathjax_path config value must be set for the '
|
||||||
|
'mathjax extension to work')
|
||||||
|
app.add_javascript(app.config.mathjax_path)
|
||||||
|
|
||||||
|
def setup(app):
|
||||||
|
mathbase_setup(app, (html_visit_math, None), (html_visit_displaymath, None))
|
||||||
|
app.add_config_value('mathjax_path', '', False)
|
||||||
|
app.add_config_value('mathjax_inline', [r'\(', r'\)'], 'html')
|
||||||
|
app.add_config_value('mathjax_display', [r'\[', r'\]'], 'html')
|
||||||
|
app.connect('builder-inited', builder_inited)
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
Transport Properties
|
Transport Properties
|
||||||
====================
|
====================
|
||||||
|
|
||||||
.. autoclass:: Cantera.Transport.Transport
|
.. automodule:: Cantera.Transport
|
||||||
|
|
|
||||||
|
|
@ -12,28 +12,27 @@ class Edge(EdgePhase, Kinetics):
|
||||||
|
|
||||||
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
|
between 2D surfaces. Class Edge defines no methods of its
|
||||||
own. All of its methods derive from either EdgePhase or Kinetics.
|
own. All of its methods derive from either :class:`.EdgePhase` or
|
||||||
|
:class:`.Kinetics`.
|
||||||
|
|
||||||
Function importInterface should usually be used to build an
|
Function :func:`.importInterface` should usually be used to build an
|
||||||
Edge object from a CTI file definition, rather than calling
|
Edge object from a CTI file definition, rather than calling
|
||||||
the Interface constructor directly.
|
the :class:`.Edge` constructor directly.
|
||||||
|
|
||||||
See: EdgePhase, Kinetics, importInterface
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, src="", root=None, surfaces=[]):
|
def __init__(self, src="", root=None, surfaces=[]):
|
||||||
"""
|
"""
|
||||||
src - CTML or CTI input file name. If more than one phase is
|
:param src:
|
||||||
defined in the file, src should be specified as 'filename\#id'
|
CTML or CTI input file name. If more than one phase is
|
||||||
If the file is not CTML, it will be run through the CTI -> CTML
|
defined in the file, src should be specified as ``filename#id``
|
||||||
preprocessor first.
|
If the file is not CTML, it will be run through the CTI -> CTML
|
||||||
|
preprocessor first.
|
||||||
root - If a CTML tree has already been read in that contains
|
:param root:
|
||||||
the definition of this interface, the root of this tree can be
|
If a CTML tree has already been read in that contains
|
||||||
specified instead of specifying 'src'.
|
the definition of this interface, the root of this tree can be
|
||||||
|
specified instead of specifying *src*.
|
||||||
phases - A list of all objects representing the neighboring
|
:param phases:
|
||||||
surface phases which participate in the reaction mechanism.
|
A list of all objects representing the neighboring
|
||||||
|
surface phases which participate in the reaction mechanism.
|
||||||
"""
|
"""
|
||||||
self.ckin = 0
|
self.ckin = 0
|
||||||
self._owner = 0
|
self._owner = 0
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,8 @@
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
The classes in this module are designed to allow constructing
|
The classes in this module are designed to allow constructing
|
||||||
user-defined functions of one variable in Python that can be used with the
|
user-defined functions of one variable in Python that can be used with the
|
||||||
Cantera C++ kernel. These classes are mostly shadow classes for
|
Cantera C++ kernel. These classes are mostly shadow classes for
|
||||||
corresponding classes in the C++ kernel.
|
corresponding classes in the C++ kernel.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from Cantera.num import array, asarray, ravel, shape, transpose
|
from Cantera.num import array, asarray, ravel, shape, transpose
|
||||||
|
|
@ -14,31 +11,33 @@ import types
|
||||||
|
|
||||||
|
|
||||||
class Func1:
|
class Func1:
|
||||||
"""Functors of one variable.
|
"""
|
||||||
|
Functors of one variable.
|
||||||
|
|
||||||
A Functor is an object that behaves like a function. Class 'Func1'
|
A Functor is an object that behaves like a function. :class:`Func1`
|
||||||
is the base class from which several functor classes derive. These
|
is the base class from which several functor classes derive. These
|
||||||
classes are designed to allow specifying functions of time from Python
|
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.
|
Functors can be added, multiplied, and divided to yield new functors.
|
||||||
|
|
||||||
>>> f1 = Polynomial([1.0, 0.0, 3.0]) # 3*t*t + 1
|
>>> f1 = Polynomial([1.0, 0.0, 3.0]) # 3*t*t + 1
|
||||||
>>> f1(2.0)
|
>>> f1(2.0)
|
||||||
___13
|
13
|
||||||
>>> f2 = Polynomial([-1.0, 2.0]) # 2*t - 1
|
>>> f2 = Polynomial([-1.0, 2.0]) # 2*t - 1
|
||||||
>>> f2(2.0)
|
>>> f2(2.0)
|
||||||
___5
|
5
|
||||||
>>> f3 = f1/f2 # (3*t*t + 1)/(2*t - 1)
|
>>> f3 = f1/f2 # (3*t*t + 1)/(2*t - 1)
|
||||||
>>> f3(2.0)
|
>>> f3(2.0)
|
||||||
___4.3333333
|
4.3333333
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, typ, n, coeffs=[]):
|
def __init__(self, typ, n, coeffs=[]):
|
||||||
"""
|
"""
|
||||||
The constructor is
|
The constructor is meant to be called from constructors of subclasses
|
||||||
meant to be called from constructors of subclasses of Func1.
|
of Func1: :class:`Polynomial`, :class:`Gaussian`, :class:`Arrhenius`,
|
||||||
See: Polynomial, Gaussian, Arrhenius, Fourier, Const,
|
:class:`Fourier`, :class:`Const`, :class:`PeriodicFunction`.
|
||||||
PeriodicFunction """
|
"""
|
||||||
self.n = n
|
self.n = n
|
||||||
self._own = 1
|
self._own = 1
|
||||||
self._func_id = 0
|
self._func_id = 0
|
||||||
|
|
@ -166,13 +165,14 @@ class Pow(Func1):
|
||||||
Func1.__init__(self,106,1,n)
|
Func1.__init__(self,106,1,n)
|
||||||
|
|
||||||
class Polynomial(Func1):
|
class Polynomial(Func1):
|
||||||
"""A polynomial.
|
r"""
|
||||||
|
A polynomial.
|
||||||
Instances of class 'Polynomial' evaluate
|
Instances of class 'Polynomial' evaluate
|
||||||
\f[
|
|
||||||
f(t) = \sum_{n = 0}^N a_n t^n.
|
.. math:: f(t) = \sum_{n = 0}^N a_n t^n .
|
||||||
\f]
|
|
||||||
The coefficients are supplied as a list, beginning with
|
The coefficients are supplied as a list, beginning with :math:`a_N` and
|
||||||
\f$a_N\f$ and ending with \f$a_0\f$.
|
ending with :math:`a_0`.
|
||||||
|
|
||||||
>>> p1 = Polynomial([1.0, -2.0, 3.0]) # 3t^2 - 2t + 1
|
>>> p1 = Polynomial([1.0, -2.0, 3.0]) # 3t^2 - 2t + 1
|
||||||
>>> p2 = Polynomial([6.0, 8.0]) # 8t + 6
|
>>> p2 = Polynomial([6.0, 8.0]) # 8t + 6
|
||||||
|
|
@ -187,26 +187,26 @@ class Polynomial(Func1):
|
||||||
|
|
||||||
|
|
||||||
class Gaussian(Func1):
|
class Gaussian(Func1):
|
||||||
"""A Gaussian pulse. Instances of class 'Gaussian' evaluate
|
r"""A Gaussian pulse. Instances of class 'Gaussian' evaluate
|
||||||
\f[
|
|
||||||
f(t) = A \exp[-(t - t_0) / \tau]
|
.. math:: f(t) = A \exp[-(t - t_0) / \tau]
|
||||||
\f]
|
|
||||||
where
|
where
|
||||||
\f[
|
|
||||||
\tau = \frac{\mbox{FWHM}}{2.0\sqrt{\ln(2.0)}}
|
.. math:: \tau = \frac{\mbox{FWHM}}{2.0\sqrt{\ln(2.0)}}
|
||||||
\f]
|
|
||||||
'FWHM' denotes the full width at half maximum.
|
'FWHM' denotes the full width at half maximum.
|
||||||
|
|
||||||
As an example, here is how to create
|
As an example, here is how to create a Gaussian pulse with peak amplitude
|
||||||
a Gaussian pulse with peak amplitude 10.0, centered at time 2.0,
|
10.0, centered at time 2.0, with full-width at half max = 0.2:
|
||||||
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)
|
>>> f(2.0)
|
||||||
___10
|
10
|
||||||
>>> f(1.9)
|
>>> f(1.9)
|
||||||
___5
|
5
|
||||||
>>> f(2.1)
|
>>> f(2.1)
|
||||||
___5
|
5
|
||||||
"""
|
"""
|
||||||
def __init__(self, A, t0, FWHM):
|
def __init__(self, A, t0, FWHM):
|
||||||
coeffs = array([A, t0, FWHM], 'd')
|
coeffs = array([A, t0, FWHM], 'd')
|
||||||
|
|
@ -214,35 +214,41 @@ class Gaussian(Func1):
|
||||||
|
|
||||||
|
|
||||||
class Fourier(Func1):
|
class Fourier(Func1):
|
||||||
"""Fourier series. Instances of class 'Fourier' evaluate the Fourier series
|
r"""
|
||||||
\f[
|
Fourier series. Instances of class 'Fourier' evaluate the Fourier series
|
||||||
f(t) = \frac{a_0}{2} + \sum_{n=1}^N [a_n \cos(n\omega t) + b_n \sin(n \omega t)]
|
|
||||||
\f]
|
.. math::
|
||||||
|
|
||||||
|
f(t) = \frac{a_0}{2} +
|
||||||
|
\sum_{n=1}^N [a_n \cos(n\omega t) + b_n \sin(n \omega t)]
|
||||||
|
|
||||||
where
|
where
|
||||||
\f[
|
|
||||||
a_n = \frac{\omega}{\pi}
|
.. math::
|
||||||
\int_{-\pi/\omega}^{\pi/\omega} f(t) \cos(n \omega t) dt
|
|
||||||
\f]
|
a_n = \frac{\omega}{\pi}
|
||||||
and
|
\int_{-\pi/\omega}^{\pi/\omega} f(t) \cos(n \omega t) dt
|
||||||
\f[
|
|
||||||
b_n = \frac{\omega}{\pi}
|
b_n = \frac{\omega}{\pi}
|
||||||
\int_{-\pi/\omega}^{\pi/\omega} f(t) \sin(n \omega t) dt.
|
\int_{-\pi/\omega}^{\pi/\omega} f(t) \sin(n \omega t) dt.
|
||||||
\f]
|
|
||||||
The function \f$ f(t) \f$ is periodic, with period \f$ T = 2\pi/\omega \f$.
|
The function :math:`f(t)` is periodic, with period :math:`T = 2\pi/\omega`.
|
||||||
|
|
||||||
As an example, a function with Fourier components up to the second harmonic
|
As an example, a function with Fourier components up to the second harmonic
|
||||||
is constructed as follows:
|
is constructed as follows:
|
||||||
|
|
||||||
>>> coeffs = [(a0, b0), (a1, b1), (a2, b2)]
|
>>> coeffs = [(a0, b0), (a1, b1), (a2, b2)]
|
||||||
>>> f = Fourier(omega, coeffs)
|
>>> f = Fourier(omega, coeffs)
|
||||||
Note that 'b0' must be specified, but is not
|
|
||||||
used. The value of 'b0' is arbitrary.
|
Note that ``b0`` must be specified, but is not used. The value of ``b0``
|
||||||
|
is arbitrary.
|
||||||
"""
|
"""
|
||||||
def __init__(self, omega, coefficients):
|
def __init__(self, omega, coefficients):
|
||||||
"""
|
"""
|
||||||
omega - fundamental frequency [radians/sec].
|
:param omega:
|
||||||
|
fundamental frequency [radians/sec].
|
||||||
coefficients - List of (a,b) pairs, beginning with \f$n = 0\f$.
|
:param coefficients:
|
||||||
|
List of (a,b) pairs, beginning with n = 0.
|
||||||
"""
|
"""
|
||||||
cc = asarray(coefficients,'d')
|
cc = asarray(coefficients,'d')
|
||||||
n, m = cc.shape
|
n, m = cc.shape
|
||||||
|
|
@ -252,30 +258,19 @@ class Fourier(Func1):
|
||||||
Func1.__init__(self, 1, n-1, ravel(transpose(cc)))
|
Func1.__init__(self, 1, n-1, ravel(transpose(cc)))
|
||||||
|
|
||||||
|
|
||||||
##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)])
|
|
||||||
#
|
|
||||||
class Arrhenius(Func1):
|
class Arrhenius(Func1):
|
||||||
"""Sum of modified Arrhenius terms. Instances of class 'Arrhenius' evaluate
|
r"""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)
|
.. math:: f(T) = \sum_{n=1}^N A_n T^{b_n}\exp(-E_n/T)
|
||||||
\f]
|
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
>>> f = Arrhenius([(a0, b0, e0), (a1, b1, e1)])
|
>>> f = Arrhenius([(a0, b0, e0), (a1, b1, e1)])
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, coefficients):
|
def __init__(self, coefficients):
|
||||||
"""
|
"""
|
||||||
coefficients - sequence of \f$(A, b, E)\f$ triplets.
|
:param coefficients:
|
||||||
|
sequence of (*A*, *b*, *E*) triplets.
|
||||||
"""
|
"""
|
||||||
cc = asarray(coefficients,'d')
|
cc = asarray(coefficients,'d')
|
||||||
n, m = cc.shape
|
n, m = cc.shape
|
||||||
|
|
@ -284,15 +279,16 @@ class Arrhenius(Func1):
|
||||||
Func1.__init__(self, 3, n, ravel(cc))
|
Func1.__init__(self, 3, n, ravel(cc))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Const(Func1):
|
class Const(Func1):
|
||||||
"""Constant function.
|
"""Constant function.
|
||||||
Objects created by function Const
|
Objects created by function Const act as functions that have a constant
|
||||||
act as functions that have a constant value.
|
value. These are used internally whenever a statement like
|
||||||
These are used internally whenever a statement like
|
|
||||||
>>> f = Gausian(2.0, 1.0, 0.1) + 4.0
|
>>> f = Gausian(2.0, 1.0, 0.1) + 4.0
|
||||||
is encountered. The addition operator of class Func1 is defined
|
|
||||||
so that this is equivalent to
|
is encountered. The addition operator of class Func1 is defined so that
|
||||||
|
this is equivalent to
|
||||||
|
|
||||||
>>> f = SumFunction(Gaussian(2.0, 1.0, 0.1), Const(4.0))
|
>>> f = SumFunction(Gaussian(2.0, 1.0, 0.1), Const(4.0))
|
||||||
|
|
||||||
Function Const returns instances of class Polynomial that have
|
Function Const returns instances of class Polynomial that have
|
||||||
|
|
@ -307,9 +303,10 @@ class PeriodicFunction(Func1):
|
||||||
"""Converts a function into a periodic function with period T."""
|
"""Converts a function into a periodic function with period T."""
|
||||||
def __init__(self, func, T):
|
def __init__(self, func, T):
|
||||||
"""
|
"""
|
||||||
func - initial non-periodic function
|
:param func:
|
||||||
|
initial non-periodic function
|
||||||
T - period [s]
|
:param T:
|
||||||
|
period [s]
|
||||||
"""
|
"""
|
||||||
Func1.__init__(self, 50, func.func_id(), array([T],'d'))
|
Func1.__init__(self, 50, func.func_id(), array([T],'d'))
|
||||||
func._own = 0
|
func._own = 0
|
||||||
|
|
@ -323,7 +320,6 @@ class ComboFunc1(Func1):
|
||||||
This class is the base class for functors that combine two
|
This class is the base class for functors that combine two
|
||||||
other functors in a binary operation.
|
other functors in a binary operation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, typ, f1, f2):
|
def __init__(self, typ, f1, f2):
|
||||||
self._own = 1
|
self._own = 1
|
||||||
self._func_id = 0
|
self._func_id = 0
|
||||||
|
|
@ -345,18 +341,21 @@ class SumFunction(ComboFunc1):
|
||||||
It is not necessary to explicitly create an instance of SumFunction, since
|
It is not necessary to explicitly create an instance of SumFunction, since
|
||||||
the addition operator of the base class is overloaded to return a SumFunction
|
the addition operator of the base class is overloaded to return a SumFunction
|
||||||
instance.
|
instance.
|
||||||
|
|
||||||
>>> f1 = Polynomial([2.0, 1.0])
|
>>> f1 = Polynomial([2.0, 1.0])
|
||||||
>>> f2 = Polynomial([3.0, -5.0])
|
>>> f2 = Polynomial([3.0, -5.0])
|
||||||
>>> f3 = f1 + f2 # functor to evaluate (2t + 1) + (3t - 5)
|
>>> f3 = f1 + f2 # functor to evaluate (2t + 1) + (3t - 5)
|
||||||
In this example, object 'f3' is a functor of class'SumFunction' that calls f1 and f2
|
|
||||||
and returns their sum.
|
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):
|
def __init__(self, f1, f2):
|
||||||
"""
|
"""
|
||||||
f1 - first functor.
|
:param f1:
|
||||||
|
first functor.
|
||||||
f2 - second functor.
|
:param f2:
|
||||||
|
second functor.
|
||||||
"""
|
"""
|
||||||
ComboFunc1.__init__(self, 20, f1, f2)
|
ComboFunc1.__init__(self, 20, f1, f2)
|
||||||
|
|
||||||
|
|
@ -367,23 +366,25 @@ class DiffFunction(ComboFunc1):
|
||||||
functors. It is not necessary to explicitly create an instance of
|
functors. It is not necessary to explicitly create an instance of
|
||||||
DiffFunction, since the subtraction operator of the base class is
|
DiffFunction, since the subtraction operator of the base class is
|
||||||
overloaded to return a DiffFunction instance.
|
overloaded to return a DiffFunction instance.
|
||||||
|
|
||||||
>>> f1 = Polynomial([2.0, 1.0])
|
>>> f1 = Polynomial([2.0, 1.0])
|
||||||
>>> f2 = Polynomial([3.0, -5.0])
|
>>> f2 = Polynomial([3.0, -5.0])
|
||||||
>>> f3 = f1 - f2 # functor to evaluate (2t + 1) - (3t - 5)
|
>>> f3 = f1 - f2 # functor to evaluate (2t + 1) - (3t - 5)
|
||||||
|
|
||||||
In this example, object 'f3' is a functor of class'DiffFunction' that
|
In this example, object 'f3' is a functor of class'DiffFunction' that
|
||||||
calls f1 and f2 and returns their difference.
|
calls f1 and f2 and returns their difference.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, f1, f2):
|
def __init__(self, f1, f2):
|
||||||
"""
|
"""
|
||||||
f1 - first functor.
|
:param f1:
|
||||||
|
first functor.
|
||||||
f2 - second functor.
|
:param f2:
|
||||||
|
second functor.
|
||||||
"""
|
"""
|
||||||
ComboFunc1.__init__(self, 25, f1, f2)
|
ComboFunc1.__init__(self, 25, f1, f2)
|
||||||
|
|
||||||
class ProdFunction(ComboFunc1):
|
class ProdFunction(ComboFunc1):
|
||||||
|
|
||||||
"""Product of two functions. Instances of class ProdFunction
|
"""Product of two functions. Instances of class ProdFunction
|
||||||
evaluate the product of two supplied functors. It is not
|
evaluate the product of two supplied functors. It is not
|
||||||
necessary to explicitly create an instance of 'ProdFunction',
|
necessary to explicitly create an instance of 'ProdFunction',
|
||||||
|
|
@ -395,11 +396,14 @@ class ProdFunction(ComboFunc1):
|
||||||
>>> f3 = f1 * f2 # functor to evaluate (2t + 1)*(3t - 5)
|
>>> f3 = f1 * f2 # functor to evaluate (2t + 1)*(3t - 5)
|
||||||
|
|
||||||
In this example, object 'f3' is a functor of class'ProdFunction'
|
In this example, object 'f3' is a functor of class'ProdFunction'
|
||||||
that calls f1 and f2 and returns their product. """
|
that calls f1 and f2 and returns their product.
|
||||||
|
"""
|
||||||
def __init__(self, f1, f2):
|
def __init__(self, f1, f2):
|
||||||
""" f1 - first functor.
|
"""
|
||||||
f2 - second functor.
|
:param f1:
|
||||||
|
first functor.
|
||||||
|
:param f2:
|
||||||
|
second functor.
|
||||||
"""
|
"""
|
||||||
ComboFunc1.__init__(self, 30, f1, f2)
|
ComboFunc1.__init__(self, 30, f1, f2)
|
||||||
|
|
||||||
|
|
@ -410,40 +414,45 @@ class RatioFunction(ComboFunc1):
|
||||||
It is not necessary to explicitly create an instance of 'RatioFunction', since
|
It is not necessary to explicitly create an instance of 'RatioFunction', since
|
||||||
the division operator of the base class is overloaded to return a RatioFunction
|
the division operator of the base class is overloaded to return a RatioFunction
|
||||||
instance.
|
instance.
|
||||||
|
|
||||||
>>> f1 = Polynomial([2.0, 1.0])
|
>>> f1 = Polynomial([2.0, 1.0])
|
||||||
>>> f2 = Polynomial([3.0, -5.0])
|
>>> f2 = Polynomial([3.0, -5.0])
|
||||||
>>> f3 = f1 / f2 # functor to evaluate (2t + 1)/(3t - 5)
|
>>> 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.
|
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):
|
def __init__(self, f1, f2):
|
||||||
"""
|
"""
|
||||||
f1 - first functor.
|
:param f1:
|
||||||
|
first functor.
|
||||||
f2 - second functor.
|
:param f2:
|
||||||
|
second functor.
|
||||||
"""
|
"""
|
||||||
ComboFunc1.__init__(self, 40, f1, f2)
|
ComboFunc1.__init__(self, 40, f1, f2)
|
||||||
|
|
||||||
## Function of a function.
|
|
||||||
# Instances of class CompositeFunction evaluate f(g(t)) for two supplied
|
|
||||||
# functors f and g. It is not necessary to explicitly create an instance
|
|
||||||
# of 'CompositeFunction', since the () operator of the base class is
|
|
||||||
# overloaded to return a CompositeFunction when called with a functor
|
|
||||||
# argument.
|
|
||||||
# @example
|
|
||||||
# >>> f1 = Polynomial([2.0, 1.0])
|
|
||||||
# >>> f2 = Polynomial([3.0, -5.0])
|
|
||||||
# >>> f3 = f1(f2) # functor to evaluate 2(3t - 5) + 1
|
|
||||||
# In this example, object 'f3' is a functor of class'CompositeFunction'
|
|
||||||
# that calls f1 and f2 and returns f1(f2(t)).
|
|
||||||
|
|
||||||
class CompositeFunction(ComboFunc1):
|
class CompositeFunction(ComboFunc1):
|
||||||
|
"""
|
||||||
|
Function of a function.
|
||||||
|
Instances of class CompositeFunction evaluate f(g(t)) for two supplied
|
||||||
|
functors f and g. It is not necessary to explicitly create an instance
|
||||||
|
of 'CompositeFunction', since the () operator of the base class is
|
||||||
|
overloaded to return a CompositeFunction when called with a functor
|
||||||
|
argument.
|
||||||
|
|
||||||
|
>>> f1 = Polynomial([2.0, 1.0])
|
||||||
|
>>> f2 = Polynomial([3.0, -5.0])
|
||||||
|
>>> f3 = f1(f2) # functor to evaluate 2(3t - 5) + 1
|
||||||
|
|
||||||
|
In this example, object 'f3' is a functor of class'CompositeFunction'
|
||||||
|
that calls f1 and f2 and returns f1(f2(t)).
|
||||||
|
"""
|
||||||
def __init__(self, f1, f2):
|
def __init__(self, f1, f2):
|
||||||
"""
|
"""
|
||||||
f1 - first functor.
|
:param f1:
|
||||||
|
first functor.
|
||||||
f2 - second functor.
|
:param f2:
|
||||||
|
second functor.
|
||||||
"""
|
"""
|
||||||
ComboFunc1.__init__(self, 60, f1, f2)
|
ComboFunc1.__init__(self, 60, f1, f2)
|
||||||
|
|
||||||
|
|
@ -455,8 +464,9 @@ class DerivativeFunction(Func1):
|
||||||
self._own = 1
|
self._own = 1
|
||||||
self._func_id = _cantera.func_derivative(f.func_id())
|
self._func_id = _cantera.func_derivative(f.func_id())
|
||||||
|
|
||||||
##
|
|
||||||
# The derivative of f
|
|
||||||
#
|
|
||||||
def derivative(f):
|
def derivative(f):
|
||||||
|
"""
|
||||||
|
Take the derivative of a functor *f*
|
||||||
|
"""
|
||||||
return DerivativeFunction(f)
|
return DerivativeFunction(f)
|
||||||
|
|
|
||||||
|
|
@ -12,28 +12,27 @@ class Interface(SurfacePhase, Kinetics):
|
||||||
|
|
||||||
Instances of class Interface represent reacting 2D interfaces
|
Instances of class Interface represent reacting 2D interfaces
|
||||||
between bulk 3D phases. Class Interface defines no methods of its
|
between bulk 3D phases. Class Interface defines no methods of its
|
||||||
own. All of its methods derive from either SurfacePhase or Kinetics.
|
own. All of its methods derive from either :class:`.SurfacePhase` or
|
||||||
|
:class:`.Kinetics`.
|
||||||
|
|
||||||
Function importInterface should usually be used to build an
|
Function :func:`.importInterface` should usually be used to build an
|
||||||
Interface object from a CTI file definition, rather than calling
|
Interface object from a CTI file definition, rather than calling
|
||||||
the Interface constructor directly.
|
the Interface constructor directly.
|
||||||
|
|
||||||
See: SurfacePhase, Kinetics, importInterface
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, src="", root=None, phases=[], debug = 0):
|
def __init__(self, src="", root=None, phases=[], debug = 0):
|
||||||
"""
|
"""
|
||||||
src - CTML or CTI input file name. If more than one phase is
|
:param src:
|
||||||
defined in the file, src should be specified as 'filename\#id'
|
CTML or CTI input file name. If more than one phase is
|
||||||
If the file is not CTML, it will be run through the CTI -> CTML
|
defined in the file, src should be specified as ``filename#id``
|
||||||
preprocessor first.
|
If the file is not CTML, it will be run through the CTI -> CTML
|
||||||
|
preprocessor first.
|
||||||
root - If a CTML tree has already been read in that contains
|
:param root:
|
||||||
the definition of this interface, the root of this tree can be
|
If a CTML tree has already been read in that contains the
|
||||||
specified instead of specifying 'src'.
|
definition of this interface, the root of this tree can be
|
||||||
|
specified instead of specifying *src*.
|
||||||
phases - A list of all objects representing the neighboring phases
|
:param phases:
|
||||||
which participate in the reaction mechanism.
|
A list of all objects representing the neighboring phases which
|
||||||
|
participate in the reaction mechanism.
|
||||||
"""
|
"""
|
||||||
self.ckin = 0
|
self.ckin = 0
|
||||||
self._owner = 0
|
self._owner = 0
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,18 @@ class Kinetics:
|
||||||
Kinetics managers. Instances of class Kinetics are responsible for
|
Kinetics managers. Instances of class Kinetics are responsible for
|
||||||
evaluating reaction rates of progress, species production rates,
|
evaluating reaction rates of progress, species production rates,
|
||||||
and other quantities pertaining to a reaction mechanism.
|
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=[]):
|
def __init__(self, kintype=-1, thrm=0, xml_phase=None, id=None, phases=[]):
|
||||||
"""Build a kinetics manager from an XML specification.
|
"""
|
||||||
|
Build a kinetics manager from an XML specification.
|
||||||
root -- root of a CTML tree
|
:param kintype:
|
||||||
|
Integer specifying the type of kinetics manager to create.
|
||||||
id -- id of the 'kinetics' node within the tree that contains
|
:param root:
|
||||||
the specification of the parameters.
|
Root of a CTML tree
|
||||||
|
:param id:
|
||||||
|
id of the 'kinetics' node within the tree that contains the
|
||||||
|
specification of the parameters.
|
||||||
"""
|
"""
|
||||||
np = len(phases)
|
np = len(phases)
|
||||||
self._sp = []
|
self._sp = []
|
||||||
|
|
@ -82,8 +81,11 @@ class Kinetics:
|
||||||
|
|
||||||
def kineticsSpeciesIndex(self, name, phase):
|
def kineticsSpeciesIndex(self, name, phase):
|
||||||
"""The index of a species.
|
"""The index of a species.
|
||||||
name -- species name
|
|
||||||
phase -- phase name
|
:param name:
|
||||||
|
species name
|
||||||
|
:param phase:
|
||||||
|
phase name
|
||||||
|
|
||||||
Kinetics managers for heterogeneous reaction mechanisms
|
Kinetics managers for heterogeneous reaction mechanisms
|
||||||
maintain a list of all species in all phases. The order of the
|
maintain a list of all species in all phases. The order of the
|
||||||
|
|
@ -118,13 +120,13 @@ class Kinetics:
|
||||||
|
|
||||||
def isReversible(self,i):
|
def isReversible(self,i):
|
||||||
"""
|
"""
|
||||||
True (1) if reaction number 'i' is reversible,
|
True (1) if reaction number *i* is reversible,
|
||||||
and false (0) otherwise.
|
and false (0) otherwise.
|
||||||
"""
|
"""
|
||||||
return _cantera.kin_isreversible(self.ckin,i)
|
return _cantera.kin_isreversible(self.ckin,i)
|
||||||
|
|
||||||
def reactionType(self,i):
|
def reactionType(self,i):
|
||||||
"""Type of reaction 'i'"""
|
"""Type of reaction *i*"""
|
||||||
return _cantera.kin_rxntype(self.ckin,i)
|
return _cantera.kin_rxntype(self.ckin,i)
|
||||||
|
|
||||||
def reactionEqn(self,i):
|
def reactionEqn(self,i):
|
||||||
|
|
@ -139,7 +141,7 @@ class Kinetics:
|
||||||
return self.reactionString(i)
|
return self.reactionString(i)
|
||||||
|
|
||||||
def reactionString(self, i):
|
def reactionString(self, i):
|
||||||
"""Reaction string for reaction number 'i'"""
|
"""Reaction string for reaction number *i*"""
|
||||||
s = ''
|
s = ''
|
||||||
nsp = _cantera.kin_nspecies(self.ckin)
|
nsp = _cantera.kin_nspecies(self.ckin)
|
||||||
for k in range(nsp):
|
for k in range(nsp):
|
||||||
|
|
@ -169,7 +171,7 @@ class Kinetics:
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def reactantStoichCoeff(self,k,i):
|
def reactantStoichCoeff(self,k,i):
|
||||||
"""The stoichiometric coefficient of species k as a reactant in reaction i."""
|
"""The stoichiometric coefficient of species *k* as a reactant in reaction *i*."""
|
||||||
return _cantera.kin_rstoichcoeff(self.ckin,k,i)
|
return _cantera.kin_rstoichcoeff(self.ckin,k,i)
|
||||||
|
|
||||||
def reactantStoichCoeffs(self):
|
def reactantStoichCoeffs(self):
|
||||||
|
|
@ -185,13 +187,13 @@ class Kinetics:
|
||||||
return nu
|
return nu
|
||||||
|
|
||||||
def productStoichCoeff(self,k,i):
|
def productStoichCoeff(self,k,i):
|
||||||
"""The stoichiometric coefficient of species k as a product in reaction 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):
|
def productStoichCoeffs(self):
|
||||||
"""The array of product stoichiometric coefficients. Element
|
"""The array of product stoichiometric coefficients. Element
|
||||||
[k,i] of this array is the product stoichiometric
|
[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)
|
nsp = _cantera.kin_nspecies(self.ckin)
|
||||||
nr = _cantera.kin_nreactions(self.ckin)
|
nr = _cantera.kin_nreactions(self.ckin)
|
||||||
nu = zeros((nsp,nr),'d')
|
nu = zeros((nsp,nr),'d')
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,21 @@ class BurnerDiffFlame(Stack):
|
||||||
|
|
||||||
def __init__(self, gas = None, burner = None, outlet = None, grid = None):
|
def __init__(self, gas = None, burner = None, outlet = None, grid = None):
|
||||||
"""
|
"""
|
||||||
gas -- object to use to evaluate all gas properties and reaction
|
:param gas:
|
||||||
rates. Required
|
object to use to evaluate all gas properties and reaction
|
||||||
burner -- Inlet object representing the burner. Optional;
|
rates. Required
|
||||||
if not supplied, one will be created with name 'burner'
|
:param burner:
|
||||||
outlet -- Outlet object representing the outlet. Optional;
|
Inlet object representing the burner. Optional; if not supplied,
|
||||||
if not supplied, one will be created with name 'outlet'
|
one will be created with name 'burner'
|
||||||
grid -- array of initial grid points
|
:param outlet:
|
||||||
|
Outlet object representing the outlet. Optional; if not supplied,
|
||||||
|
one will be created with name 'outlet'
|
||||||
|
:param grid:
|
||||||
|
array of initial grid points
|
||||||
|
|
||||||
A domain of type AxisymmetricFlow named 'flame' will be created to
|
A domain of type :class:`.AxisymmetricFlow` named 'flame' will be
|
||||||
represent the flame. The three domains comprising the stack
|
created to represent the flame. The three domains comprising the stack
|
||||||
are stored as self.burner, self.flame, and self.outlet.
|
are stored as ``self.burner``, ``self.flame``, and ``self.outlet``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if burner:
|
if burner:
|
||||||
|
|
@ -70,14 +74,14 @@ class BurnerDiffFlame(Stack):
|
||||||
|
|
||||||
|
|
||||||
def solve(self, loglevel = 1, refine_grid = 1):
|
def solve(self, loglevel = 1, refine_grid = 1):
|
||||||
"""Solve the flame. See Stack.solve"""
|
"""Solve the flame. :meth:`.Stack.solve`"""
|
||||||
if not self._initialized: self.init()
|
if not self._initialized: self.init()
|
||||||
Stack.solve(self, loglevel = loglevel, refine_grid = refine_grid)
|
Stack.solve(self, loglevel = loglevel, refine_grid = refine_grid)
|
||||||
|
|
||||||
|
|
||||||
def setRefineCriteria(self, ratio = 10.0, slope = 0.8,
|
def setRefineCriteria(self, ratio = 10.0, slope = 0.8,
|
||||||
curve = 0.8, prune = 0.0):
|
curve = 0.8, prune = 0.0):
|
||||||
"""See Stack.setRefineCriteria"""
|
"""See :meth:`.Stack.setRefineCriteria`"""
|
||||||
Stack.setRefineCriteria(self, domain = self.flame,
|
Stack.setRefineCriteria(self, domain = self.flame,
|
||||||
ratio = ratio, slope = slope, curve = curve,
|
ratio = ratio, slope = slope, curve = curve,
|
||||||
prune = prune)
|
prune = prune)
|
||||||
|
|
@ -89,9 +93,13 @@ class BurnerDiffFlame(Stack):
|
||||||
|
|
||||||
def set(self, tol = None, energy = '', tol_time = None):
|
def set(self, tol = None, energy = '', tol_time = None):
|
||||||
"""Set parameters.
|
"""Set parameters.
|
||||||
tol -- (rtol, atol) for steady-state
|
|
||||||
tol_time -- (rtol, atol) for time stepping
|
:param tol:
|
||||||
energy -- 'on' or 'off' to enable or disable the energy equation
|
(rtol, atol) for steady-state
|
||||||
|
:param tol_time:
|
||||||
|
(rtol, atol) for time stepping
|
||||||
|
:param energy:
|
||||||
|
``'on'`` or ``'off'`` to enable or disable the energy equation
|
||||||
"""
|
"""
|
||||||
if tol:
|
if tol:
|
||||||
self.flame.setTolerances(default = tol)
|
self.flame.setTolerances(default = tol)
|
||||||
|
|
@ -120,7 +128,7 @@ class BurnerDiffFlame(Stack):
|
||||||
|
|
||||||
def setGasState(self, j):
|
def setGasState(self, j):
|
||||||
"""Set the state of the object representing the gas to the
|
"""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()
|
nsp = self.gas.nSpecies()
|
||||||
y = zeros(nsp, 'd')
|
y = zeros(nsp, 'd')
|
||||||
for n in range(nsp):
|
for n in range(nsp):
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,21 @@ class BurnerFlame(Stack):
|
||||||
|
|
||||||
def __init__(self, gas = None, burner = None, outlet = None, grid = None):
|
def __init__(self, gas = None, burner = None, outlet = None, grid = None):
|
||||||
"""
|
"""
|
||||||
gas -- object to use to evaluate all gas properties and reaction
|
:param gas:
|
||||||
rates. Required
|
object to use to evaluate all gas properties and reaction
|
||||||
burner -- Inlet object representing the burner. Optional;
|
rates. Required
|
||||||
if not supplied, one will be created with name 'burner'
|
:param burner:
|
||||||
outlet -- Outlet object representing the outlet. Optional;
|
Inlet object representing the burner. Optional;
|
||||||
if not supplied, one will be created with name 'outlet'
|
if not supplied, one will be created with name ``burner``
|
||||||
grid -- array of initial grid points
|
:param outlet:
|
||||||
|
Outlet object representing the outlet. Optional;
|
||||||
|
if not supplied, one will be created with name ``outlet``
|
||||||
|
:param grid:
|
||||||
|
array of initial grid points
|
||||||
|
|
||||||
A domain of type AxisymmetricFlow named 'flame' will be created to
|
A domain of type :class:`.AxisymmetricFlow` named ``flame`` will be
|
||||||
represent the flame. The three domains comprising the stack
|
created to represent the flame. The three domains comprising the stack
|
||||||
are stored as self.burner, self.flame, and self.outlet.
|
are stored as ``self.burner``, ``self.flame``, and ``self.outlet``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if burner:
|
if burner:
|
||||||
|
|
@ -70,14 +74,14 @@ class BurnerFlame(Stack):
|
||||||
|
|
||||||
|
|
||||||
def solve(self, loglevel = 1, refine_grid = 1):
|
def solve(self, loglevel = 1, refine_grid = 1):
|
||||||
"""Solve the flame. See Stack.solve"""
|
"""Solve the flame. See :meth:`.Stack.solve`"""
|
||||||
if not self._initialized: self.init()
|
if not self._initialized: self.init()
|
||||||
Stack.solve(self, loglevel = loglevel, refine_grid = refine_grid)
|
Stack.solve(self, loglevel = loglevel, refine_grid = refine_grid)
|
||||||
|
|
||||||
|
|
||||||
def setRefineCriteria(self, ratio = 10.0, slope = 0.8,
|
def setRefineCriteria(self, ratio = 10.0, slope = 0.8,
|
||||||
curve = 0.8, prune = 0.0):
|
curve = 0.8, prune = 0.0):
|
||||||
"""See Stack.setRefineCriteria"""
|
"""See :meth:`.Stack.setRefineCriteria`"""
|
||||||
Stack.setRefineCriteria(self, domain = self.flame,
|
Stack.setRefineCriteria(self, domain = self.flame,
|
||||||
ratio = ratio, slope = slope, curve = curve,
|
ratio = ratio, slope = slope, curve = curve,
|
||||||
prune = prune)
|
prune = prune)
|
||||||
|
|
@ -89,9 +93,13 @@ class BurnerFlame(Stack):
|
||||||
|
|
||||||
def set(self, tol = None, energy = '', tol_time = None):
|
def set(self, tol = None, energy = '', tol_time = None):
|
||||||
"""Set parameters.
|
"""Set parameters.
|
||||||
tol -- (rtol, atol) for steady-state
|
|
||||||
tol_time -- (rtol, atol) for time stepping
|
:param tol:
|
||||||
energy -- 'on' or 'off' to enable or disable the energy equation
|
(rtol, atol) for steady-state
|
||||||
|
:param tol_time:
|
||||||
|
(rtol, atol) for time stepping
|
||||||
|
:param energy:
|
||||||
|
``'on'`` or ``'off'`` to enable or disable the energy equation
|
||||||
"""
|
"""
|
||||||
if tol:
|
if tol:
|
||||||
self.flame.setTolerances(default = tol)
|
self.flame.setTolerances(default = tol)
|
||||||
|
|
@ -120,7 +128,7 @@ class BurnerFlame(Stack):
|
||||||
|
|
||||||
def setGasState(self, j):
|
def setGasState(self, j):
|
||||||
"""Set the state of the object representing the gas to the
|
"""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()
|
nsp = self.gas.nSpecies()
|
||||||
y = zeros(nsp, 'd')
|
y = zeros(nsp, 'd')
|
||||||
for n in range(nsp):
|
for n in range(nsp):
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,12 @@ class CounterFlame(Stack):
|
||||||
"""A non-premixed counterflow flame."""
|
"""A non-premixed counterflow flame."""
|
||||||
|
|
||||||
def __init__(self, gas = None, grid = None):
|
def __init__(self, gas = None, grid = None):
|
||||||
"""The domains are [
|
"""
|
||||||
self.fuel_inlet -- class Inlet,
|
The domains are::
|
||||||
self.flame -- class AxisymmetricFlow,
|
|
||||||
self.oxidizer_inlet -- class Inlet
|
[self.fuel_inlet, # class Inlet,
|
||||||
]
|
self.flame, # class AxisymmetricFlow,
|
||||||
|
self.oxidizer_inlet] # class Inlet
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.fuel_inlet = Inlet('fuel inlet')
|
self.fuel_inlet = Inlet('fuel inlet')
|
||||||
|
|
@ -58,7 +59,7 @@ class CounterFlame(Stack):
|
||||||
"""Set the initial guess for the solution. The fuel species
|
"""Set the initial guess for the solution. The fuel species
|
||||||
must be specified, and the oxidizer may be
|
must be specified, and the oxidizer may be
|
||||||
|
|
||||||
>>> f.init(fuel = 'CH4')
|
>>> f.init(fuel='CH4')
|
||||||
|
|
||||||
The initial guess is generated by assuming infinitely-fast
|
The initial guess is generated by assuming infinitely-fast
|
||||||
chemistry."""
|
chemistry."""
|
||||||
|
|
@ -153,10 +154,13 @@ class CounterFlame(Stack):
|
||||||
|
|
||||||
def solve(self, loglevel = 1, refine_grid = 1):
|
def solve(self, loglevel = 1, refine_grid = 1):
|
||||||
"""Solve the flame.
|
"""Solve the flame.
|
||||||
loglevel -- integer flag controlling the amount of
|
|
||||||
diagnostic output. Zero suppresses all output, and
|
:param loglevel:
|
||||||
5 produces very verbose output. Default: 1
|
integer flag controlling the amount of diagnostic output. Zero
|
||||||
refine_grid -- if non-zero, enable grid refinement."""
|
suppresses all output, and 5 produces very verbose output. Default: 1
|
||||||
|
:param refine_grid:
|
||||||
|
if non-zero, enable grid refinement.
|
||||||
|
"""
|
||||||
|
|
||||||
if not self._initialized: self.init()
|
if not self._initialized: self.init()
|
||||||
Stack.solve(self, loglevel = loglevel, refine_grid = refine_grid)
|
Stack.solve(self, loglevel = loglevel, refine_grid = refine_grid)
|
||||||
|
|
@ -164,21 +168,25 @@ class CounterFlame(Stack):
|
||||||
|
|
||||||
def setRefineCriteria(self, ratio = 10.0, slope = 0.8, curve = 0.8,
|
def setRefineCriteria(self, ratio = 10.0, slope = 0.8, curve = 0.8,
|
||||||
prune = 0.0):
|
prune = 0.0):
|
||||||
"""Set the criteria used to refine the flame.
|
"""
|
||||||
ratio -- additional points will be added if the ratio of the spacing
|
Set the criteria used to refine the flame.
|
||||||
on either side of a grid point exceeds this value
|
|
||||||
slope -- maximum difference in value between two adjacent points,
|
:param ratio:
|
||||||
scaled by the maximum difference in the profile
|
additional points will be added if the ratio of the spacing
|
||||||
(0.0 < slope < 1.0). Adds points in regions of high slope.
|
on either side of a grid point exceeds this value
|
||||||
curve -- maximum difference in slope between two adjacent intervals,
|
:param slope:
|
||||||
scaled by the maximum difference in the profile
|
maximum difference in value between two adjacent points,
|
||||||
(0.0 < curve < 1.0). Adds points in regions of high
|
scaled by the maximum difference in the profile
|
||||||
curvature.
|
(0.0 < slope < 1.0). Adds points in regions of high slope.
|
||||||
prune -- if the slope or curve criteria are satisfied to the level of
|
:param curve:
|
||||||
'prune', the grid point is assumed not to be needed and is
|
maximum difference in slope between two adjacent intervals, scaled
|
||||||
removed. Set prune significantly smaller than
|
by the maximum difference in the profile (0.0 < curve < 1.0). Adds
|
||||||
'slope' and 'curve'. Set to zero to disable pruning
|
points in regions of high curvature.
|
||||||
the grid.
|
:param prune:
|
||||||
|
if the slope or curve criteria are satisfied to the level of
|
||||||
|
'prune', the grid point is assumed not to be needed and is 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,
|
>>> f.setRefineCriteria(ratio = 5.0, slope = 0.2, curve = 0.3,
|
||||||
... prune = 0.03)
|
... prune = 0.03)
|
||||||
|
|
@ -194,9 +202,13 @@ class CounterFlame(Stack):
|
||||||
|
|
||||||
def set(self, tol = None, energy = '', tol_time = None):
|
def set(self, tol = None, energy = '', tol_time = None):
|
||||||
"""Set parameters.
|
"""Set parameters.
|
||||||
tol -- (rtol, atol) for steady-state
|
|
||||||
tol_time -- (rtol, atol) for time stepping
|
:param tol:
|
||||||
energy -- 'on' or 'off' to enable or disable the energy equation
|
(rtol, atol) for steady-state
|
||||||
|
:param tol_time:
|
||||||
|
(rtol, atol) for time stepping
|
||||||
|
:param energy:
|
||||||
|
'on' or 'off' to enable or disable the energy equation
|
||||||
"""
|
"""
|
||||||
if tol:
|
if tol:
|
||||||
self.flame.setTolerances(default = tol)
|
self.flame.setTolerances(default = tol)
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,15 @@ class FreeFlame(Stack):
|
||||||
|
|
||||||
def __init__(self, gas = None, grid = None, tfix = 500.0):
|
def __init__(self, gas = None, grid = None, tfix = 500.0):
|
||||||
"""
|
"""
|
||||||
gas -- object to use to evaluate all gas properties and reaction
|
:param gas:
|
||||||
rates. Required
|
object to use to evaluate all gas properties and reaction
|
||||||
grid -- array of initial grid points
|
rates. Required
|
||||||
|
:param grid:
|
||||||
|
array of initial grid points
|
||||||
|
|
||||||
A domain of type FreeFlame named 'flame' will be created to
|
A domain of type FreeFlame named 'flame' will be created to
|
||||||
represent the flame. The three domains comprising the stack
|
represent the flame. The three domains comprising the stack
|
||||||
are stored as self.inlet, self.flame, and self.outlet.
|
are stored as ``self.inlet``, ``self.flame``, and ``self.outlet``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.inlet = Inlet('burner')
|
self.inlet = Inlet('burner')
|
||||||
|
|
@ -68,14 +70,14 @@ class FreeFlame(Stack):
|
||||||
|
|
||||||
|
|
||||||
def solve(self, loglevel = 1, refine_grid = 1):
|
def solve(self, loglevel = 1, refine_grid = 1):
|
||||||
"""Solve the flame. See Stack.solve"""
|
"""Solve the flame. See :meth:`.Stack.solve`"""
|
||||||
if not self._initialized: self.init()
|
if not self._initialized: self.init()
|
||||||
Stack.solve(self, loglevel = loglevel, refine_grid = refine_grid)
|
Stack.solve(self, loglevel = loglevel, refine_grid = refine_grid)
|
||||||
|
|
||||||
|
|
||||||
def setRefineCriteria(self, ratio = 10.0, slope = 0.8,
|
def setRefineCriteria(self, ratio = 10.0, slope = 0.8,
|
||||||
curve = 0.8, prune = 0.0):
|
curve = 0.8, prune = 0.0):
|
||||||
"""See Stack.setRefineCriteria"""
|
"""See :meth:`.Stack.setRefineCriteria`"""
|
||||||
Stack.setRefineCriteria(self, domain = self.flame,
|
Stack.setRefineCriteria(self, domain = self.flame,
|
||||||
ratio = ratio, slope = slope, curve = curve,
|
ratio = ratio, slope = slope, curve = curve,
|
||||||
prune = prune)
|
prune = prune)
|
||||||
|
|
@ -90,9 +92,12 @@ class FreeFlame(Stack):
|
||||||
|
|
||||||
def set(self, tol = None, energy = '', tol_time = None):
|
def set(self, tol = None, energy = '', tol_time = None):
|
||||||
"""Set parameters.
|
"""Set parameters.
|
||||||
tol -- (rtol, atol) for steady-state
|
:param tol:
|
||||||
tol_time -- (rtol, atol) for time stepping
|
(rtol, atol) for steady-state
|
||||||
energy -- 'on' or 'off' to enable or disable the energy equation
|
:param tol_time:
|
||||||
|
(rtol, atol) for time stepping
|
||||||
|
:param energy:
|
||||||
|
'on' or 'off' to enable or disable the energy equation
|
||||||
"""
|
"""
|
||||||
if tol:
|
if tol:
|
||||||
self.flame.setTolerances(default = tol)
|
self.flame.setTolerances(default = tol)
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,20 @@ class StagnationFlow(Stack):
|
||||||
|
|
||||||
def __init__(self, gas = None, surfchem = None, grid = None):
|
def __init__(self, gas = None, surfchem = None, grid = None):
|
||||||
"""
|
"""
|
||||||
gas -- object to use to evaluate all gas properties and reaction
|
:param gas:
|
||||||
rates. Required.
|
object to use to evaluate all gas properties and reaction
|
||||||
surfchem -- object used to evaluate surface reaction rates. If
|
rates. Required.
|
||||||
omitted, surface will be treated as inert.
|
:param surfchem:
|
||||||
grid -- array of initial grid points
|
object used to evaluate surface reaction rates. If omitted,
|
||||||
|
surface will be treated as inert.
|
||||||
|
:param grid:
|
||||||
|
array of initial grid points
|
||||||
|
|
||||||
A domain of type AxisymmetricFlow named 'flow' will be created to
|
A domain of type :class:`.AxisymmetricFlow` named ``flow`` will be
|
||||||
represent the flow, and one of type Surface named 'surface' will
|
created to represent the flow, and one of type :class:`.Surface` named
|
||||||
be created to represent the surface.
|
``surface`` will be created to represent the surface. The three domains
|
||||||
The three domains comprising the stack
|
comprising the stack are stored as ``self.inlet``, ``self.flow``,
|
||||||
are stored as self.inlet, self.flow, and self.surface.
|
and ``self.surface``.
|
||||||
"""
|
"""
|
||||||
self.inlet = Inlet('inlet')
|
self.inlet = Inlet('inlet')
|
||||||
self.gas = gas
|
self.gas = gas
|
||||||
|
|
@ -74,10 +77,14 @@ class StagnationFlow(Stack):
|
||||||
|
|
||||||
def solve(self, loglevel = 1, refine_grid = 1):
|
def solve(self, loglevel = 1, refine_grid = 1):
|
||||||
"""Solve the flame.
|
"""Solve the flame.
|
||||||
loglevel -- integer flag controlling the amount of
|
|
||||||
diagnostic output. Zero suppresses all output, and
|
:param loglevel:
|
||||||
5 produces very verbose output. Default: 1
|
integer flag controlling the amount of diagnostic output.
|
||||||
refine_grid -- if non-zero, enable grid refinement."""
|
Zero suppresses all output, and 5 produces very verbose output.
|
||||||
|
Default: 1
|
||||||
|
:param refine_grid:
|
||||||
|
if non-zero, enable grid refinement.
|
||||||
|
"""
|
||||||
|
|
||||||
if not self._initialized: self.init()
|
if not self._initialized: self.init()
|
||||||
Stack.solve(self, loglevel = loglevel, refine_grid = refine_grid)
|
Stack.solve(self, loglevel = loglevel, refine_grid = refine_grid)
|
||||||
|
|
@ -85,21 +92,25 @@ class StagnationFlow(Stack):
|
||||||
|
|
||||||
def setRefineCriteria(self, ratio = 10.0, slope = 0.8,
|
def setRefineCriteria(self, ratio = 10.0, slope = 0.8,
|
||||||
curve = 0.8, prune = 0.0):
|
curve = 0.8, prune = 0.0):
|
||||||
"""Set the criteria used to refine the flame.
|
"""
|
||||||
ratio -- additional points will be added if the ratio of the spacing
|
Set the criteria used to refine the flame.
|
||||||
on either side of a grid point exceeds this value
|
|
||||||
slope -- maximum difference in value between two adjacent points,
|
:param ratio:
|
||||||
scaled by the maximum difference in the profile
|
additional points will be added if the ratio of the spacing
|
||||||
(0.0 < slope < 1.0). Adds points in regions of high slope.
|
on either side of a grid point exceeds this value
|
||||||
curve -- maximum difference in slope between two adjacent intervals,
|
:param slope:
|
||||||
scaled by the maximum difference in the profile
|
maximum difference in value between two adjacent points, scaled by
|
||||||
(0.0 < curve < 1.0). Adds points in regions of high
|
the maximum difference in the profile (0.0 < slope < 1.0). Adds
|
||||||
curvature.
|
points in regions of high slope.
|
||||||
prune -- if the slope or curve criteria are satisfied to the level of
|
:param curve:
|
||||||
'prune', the grid point is assumed not to be needed and is
|
maximum difference in slope between two adjacent intervals, scaled
|
||||||
removed. Set prune significantly smaller than
|
by the maximum difference in the profile (0.0 < curve < 1.0). Adds
|
||||||
'slope' and 'curve'. Set to zero to disable pruning
|
points in regions of high curvature.
|
||||||
the grid.
|
:param prune:
|
||||||
|
if the slope or curve criteria are satisfied to the level of
|
||||||
|
'prune', the grid point is assumed not to be needed and is 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,
|
>>> f.setRefineCriteria(ratio = 5.0, slope = 0.2, curve = 0.3,
|
||||||
... prune = 0.03)
|
... prune = 0.03)
|
||||||
|
|
@ -115,9 +126,13 @@ class StagnationFlow(Stack):
|
||||||
|
|
||||||
def set(self, tol = None, energy = '', tol_time = None):
|
def set(self, tol = None, energy = '', tol_time = None):
|
||||||
"""Set parameters.
|
"""Set parameters.
|
||||||
tol -- (rtol, atol) for steady-state
|
|
||||||
tol_time -- (rtol, atol) for time stepping
|
:param tol:
|
||||||
energy -- 'on' or 'off' to enable or disable the energy equation
|
(rtol, atol) for steady-state
|
||||||
|
:param tol_time:
|
||||||
|
(rtol, atol) for time stepping
|
||||||
|
:param energy:
|
||||||
|
'on' or 'off' to enable or disable the energy equation
|
||||||
"""
|
"""
|
||||||
if tol:
|
if tol:
|
||||||
self.flow.setTolerances(default = tol)
|
self.flow.setTolerances(default = tol)
|
||||||
|
|
@ -140,7 +155,7 @@ class StagnationFlow(Stack):
|
||||||
|
|
||||||
def solution(self, component = '', point = -1):
|
def solution(self, component = '', point = -1):
|
||||||
"""The solution for one specified component. If a point number
|
"""The solution for one specified component. If a point number
|
||||||
is given, return the value of component 'component' at this
|
is given, return the value of component *component* at this
|
||||||
point. Otherwise, return the entire profile for this
|
point. Otherwise, return the entire profile for this
|
||||||
component."""
|
component."""
|
||||||
if point >= 0: return self.value(self.flow, component, point)
|
if point >= 0: return self.value(self.flow, component, point)
|
||||||
|
|
@ -157,7 +172,7 @@ class StagnationFlow(Stack):
|
||||||
|
|
||||||
def setGasState(self, j):
|
def setGasState(self, j):
|
||||||
"""Set the state of the object representing the gas to the
|
"""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()
|
nsp = self.gas.nSpecies()
|
||||||
y = zeros(nsp, 'd')
|
y = zeros(nsp, 'd')
|
||||||
for n in range(nsp):
|
for n in range(nsp):
|
||||||
|
|
|
||||||
|
|
@ -54,13 +54,13 @@ class Domain1D:
|
||||||
|
|
||||||
The argument list should consist of keyword/value pairs, with
|
The argument list should consist of keyword/value pairs, with
|
||||||
component names as keywords and (lower_bound, upper_bound)
|
component names as keywords and (lower_bound, upper_bound)
|
||||||
tuples as the values. The keyword 'default' may be used to
|
tuples as the values. The keyword *default* may be used to
|
||||||
specify default bounds for all unspecified components. The
|
specify default bounds for all unspecified components. The
|
||||||
keyword 'Y' can be used to stand for all species mass
|
keyword *Y* can be used to stand for all species mass
|
||||||
fractions in flow domains.
|
fractions in flow domains.
|
||||||
|
|
||||||
>>> d.setBounds(default = (0, 1),
|
>>> d.setBounds(default=(0, 1),
|
||||||
... Y = (-1.0e-5, 2.0))
|
... Y=(-1.0e-5, 2.0))
|
||||||
"""
|
"""
|
||||||
|
|
||||||
d = {}
|
d = {}
|
||||||
|
|
@ -85,6 +85,7 @@ class Domain1D:
|
||||||
|
|
||||||
def bounds(self, component):
|
def bounds(self, component):
|
||||||
"""Return the (lower, upper) bounds for a solution component.
|
"""Return the (lower, upper) bounds for a solution component.
|
||||||
|
|
||||||
>>> d.bounds('T')
|
>>> d.bounds('T')
|
||||||
(200.0, 5000.0)
|
(200.0, 5000.0)
|
||||||
"""
|
"""
|
||||||
|
|
@ -98,8 +99,7 @@ class Domain1D:
|
||||||
"""Return the (relative, absolute) error tolerances for
|
"""Return the (relative, absolute) error tolerances for
|
||||||
a solution component.
|
a solution component.
|
||||||
|
|
||||||
(r, a) = d.tolerances('u')
|
>>> (r, a) = d.tolerances('u')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
ic = self.componentIndex(component)
|
ic = self.componentIndex(component)
|
||||||
r = _cantera.domain_rtol(self._hndl, ic)
|
r = _cantera.domain_rtol(self._hndl, ic)
|
||||||
|
|
@ -107,20 +107,20 @@ class Domain1D:
|
||||||
return (r, a)
|
return (r, a)
|
||||||
|
|
||||||
def setTolerances(self, **tol):
|
def setTolerances(self, **tol):
|
||||||
"""Set the error tolerances. If 'time' is present and
|
"""Set the error tolerances. If *time* is present and
|
||||||
non-zero, then the values entered will apply to the transient
|
non-zero, then the values entered will apply to the transient
|
||||||
problem. Otherwise, they will apply to the steady-state
|
problem. Otherwise, they will apply to the steady-state
|
||||||
problem.
|
problem.
|
||||||
|
|
||||||
The argument list should consist of keyword/value pairs, with
|
The argument list should consist of keyword/value pairs, with
|
||||||
component names as keywords and (rtol, atol) tuples as the
|
component names as keywords and (rtol, atol) tuples as the
|
||||||
values. The keyword 'default' may be used to specify default
|
values. The keyword *default* may be used to specify default
|
||||||
bounds for all unspecified components. The keyword 'Y' can be
|
bounds for all unspecified components. The keyword *Y* can be
|
||||||
used to stand for all species mass fractions in flow domains.
|
used to stand for all species mass fractions in flow domains.
|
||||||
|
|
||||||
d.setTolerances(Y = (1.0e-5, 1.0e-9),
|
>>> d.setTolerances(Y=(1.0e-5, 1.0e-9),
|
||||||
default = (1.0e-7, 1.0e-12),
|
... default=(1.0e-7, 1.0e-12),
|
||||||
time = 1)
|
... time=1)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
d = {}
|
d = {}
|
||||||
|
|
@ -151,7 +151,7 @@ class Domain1D:
|
||||||
def setupGrid(self, grid):
|
def setupGrid(self, grid):
|
||||||
"""Specify the grid.
|
"""Specify the grid.
|
||||||
|
|
||||||
d.setupGrid([0.0, 0.1, 0.2])
|
>>> d.setupGrid([0.0, 0.1, 0.2])
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return _cantera.domain_setupGrid(self._hndl, asarray(grid))
|
return _cantera.domain_setupGrid(self._hndl, asarray(grid))
|
||||||
|
|
@ -164,12 +164,12 @@ class Domain1D:
|
||||||
return _cantera.domain_setDesc(self._hndl, desc)
|
return _cantera.domain_setDesc(self._hndl, desc)
|
||||||
|
|
||||||
def grid(self, n = -1):
|
def grid(self, n = -1):
|
||||||
""" If n >= 0, return the value of the nth grid point
|
""" If *n* >= 0, return the value of the nth grid point
|
||||||
from the left in this domain. If n is not supplied, return
|
from the left in this domain. If n is not supplied, return
|
||||||
the entire grid.
|
the entire grid.
|
||||||
|
|
||||||
z4 = d.grid(4)
|
>>> z4 = d.grid(4)
|
||||||
z_array = d.grid()
|
>>> z_array = d.grid()
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if n >= 0:
|
if n >= 0:
|
||||||
|
|
@ -187,7 +187,7 @@ class Domain1D:
|
||||||
|
|
||||||
grid, name, desc
|
grid, name, desc
|
||||||
|
|
||||||
d.set(name = 'flame', grid = z)
|
>>> d.set(name='flame', grid=z)
|
||||||
"""
|
"""
|
||||||
self._set(options)
|
self._set(options)
|
||||||
|
|
||||||
|
|
@ -267,7 +267,6 @@ class Bdry1D(Domain1D):
|
||||||
mdot or massflux
|
mdot or massflux
|
||||||
temperature or T
|
temperature or T
|
||||||
mole_fractions or X
|
mole_fractions or X
|
||||||
|
|
||||||
"""
|
"""
|
||||||
for opt in options.keys():
|
for opt in options.keys():
|
||||||
v = options[opt]
|
v = options[opt]
|
||||||
|
|
@ -354,11 +353,17 @@ class AxisymmetricFlow(Domain1D):
|
||||||
In an axisymmetric flow domain, the equations solved are the
|
In an axisymmetric flow domain, the equations solved are the
|
||||||
similarity equations for the flow in a finite-height gap of
|
similarity equations for the flow in a finite-height gap of
|
||||||
infinite radial extent. The solution variables are
|
infinite radial extent. The solution variables are
|
||||||
u -- axial velocity
|
|
||||||
V -- radial velocity divided by radius
|
*u*
|
||||||
T -- temperature
|
axial velocity
|
||||||
lambda -- (1/r)(dP/dr)
|
*V*
|
||||||
Y_k -- species mass fractions
|
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
|
It may be shown that if the boundary conditions on these variables
|
||||||
are independent of radius, then a similarity solution to the exact
|
are independent of radius, then a similarity solution to the exact
|
||||||
|
|
@ -409,12 +414,13 @@ class AxisymmetricFlow(Domain1D):
|
||||||
"""Set the fixed temperature profile. This profile is used
|
"""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
|
:param pos:
|
||||||
temp - array of temperature values
|
arrray of relative positions from 0 to 1
|
||||||
|
:param temp:
|
||||||
|
array of temperature values
|
||||||
|
|
||||||
>>> d.setFixedTempProfile(array([0.0, 0.5, 1.0]),
|
>>> d.setFixedTempProfile(array([0.0, 0.5, 1.0]),
|
||||||
... array([500.0, 1500.0, 2000.0])
|
... array([500.0, 1500.0, 2000.0])
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return _cantera.stflow_setFixedTempProfile(self._hndl, pos, temp)
|
return _cantera.stflow_setFixedTempProfile(self._hndl, pos, temp)
|
||||||
|
|
||||||
|
|
@ -432,7 +438,7 @@ class AxisymmetricFlow(Domain1D):
|
||||||
with no arguments or with a non-zero argument, the energy
|
with no arguments or with a non-zero argument, the energy
|
||||||
equations will be solved. If invoked with a zero argument,
|
equations will be solved. If invoked with a zero argument,
|
||||||
it will not be, and instead the temperature profiles will be
|
it will not be, and instead the temperature profiles will be
|
||||||
held to the one specified by the call to setFixedTempProfile.
|
held to the one specified by the call to :meth:`.setFixedTempProfile`.
|
||||||
Default: energy equation enabled."""
|
Default: energy equation enabled."""
|
||||||
return _cantera.stflow_solveEnergyEqn(self._hndl, _onoff[flag])
|
return _cantera.stflow_solveEnergyEqn(self._hndl, _onoff[flag])
|
||||||
|
|
||||||
|
|
@ -441,8 +447,7 @@ class AxisymmetricFlow(Domain1D):
|
||||||
In addition to the parameters that may be set by Domain1D.set,
|
In addition to the parameters that may be set by Domain1D.set,
|
||||||
this method can be used to set the pressure and energy flag
|
this method can be used to set the pressure and energy flag
|
||||||
|
|
||||||
>>> d.set(pressure = OneAtm, energy = 'on')
|
>>> d.set(pressure=OneAtm, energy='on')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
for o in opt.keys():
|
for o in opt.keys():
|
||||||
v = opt[o]
|
v = opt[o]
|
||||||
|
|
@ -456,7 +461,6 @@ class AxisymmetricFlow(Domain1D):
|
||||||
|
|
||||||
|
|
||||||
class Stack:
|
class Stack:
|
||||||
|
|
||||||
""" Class Stack is a container for one-dimensional domains. It
|
""" Class Stack is a container for one-dimensional domains. It
|
||||||
also holds the multi-domain solution vector, and controls the
|
also holds the multi-domain solution vector, and controls the
|
||||||
process of finding the solution.
|
process of finding the solution.
|
||||||
|
|
@ -480,32 +484,36 @@ class Stack:
|
||||||
def setValue(self, dom, comp, localPoint, value):
|
def setValue(self, dom, comp, localPoint, value):
|
||||||
"""Set the value of one component in one domain at one point
|
"""Set the value of one component in one domain at one point
|
||||||
to 'value'.
|
to 'value'.
|
||||||
dom -- domain object
|
|
||||||
comp -- component number
|
:param dom:
|
||||||
localPoint -- grid point number within domain 'dom', starting with
|
domain object
|
||||||
zero on the left
|
:param comp:
|
||||||
value -- numerical value
|
component number
|
||||||
|
:param localPoint:
|
||||||
|
grid point number within domain *dom* starting with zero on the left
|
||||||
|
:param value:
|
||||||
|
numerical value
|
||||||
|
|
||||||
>>> s.set(d, 3, 5, 6.7)
|
>>> s.set(d, 3, 5, 6.7)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
idom = dom.domain_hndl()
|
idom = dom.domain_hndl()
|
||||||
_cantera.sim1D_setValue(self._hndl, idom,
|
_cantera.sim1D_setValue(self._hndl, idom,
|
||||||
comp, localPoint, value)
|
comp, localPoint, value)
|
||||||
|
|
||||||
def setProfile(self, dom, comp, pos, v):
|
def setProfile(self, dom, comp, pos, v):
|
||||||
|
|
||||||
"""Set an initial estimate for a profile of one component in
|
"""Set an initial estimate for a profile of one component in
|
||||||
one domain.
|
one domain.
|
||||||
|
|
||||||
dom -- domain object
|
:param dom:
|
||||||
comp -- component name
|
domain object
|
||||||
pos -- sequence of relative positions, from 0 on the
|
:param comp:
|
||||||
left to 1 on the right
|
component name
|
||||||
v -- sequence of values at the relative positions specified in 'pos'
|
:param pos:
|
||||||
|
sequence of relative positions, from 0 on the left to 1 on the right
|
||||||
|
:param 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])
|
>>> s.setProfile(d, 'T', [0.0, 0.2, 1.0], [400.0, 800.0, 1500.0])
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
idom = dom.index()
|
idom = dom.index()
|
||||||
|
|
@ -515,12 +523,15 @@ class Stack:
|
||||||
|
|
||||||
def setFlatProfile(self, dom, comp, v):
|
def setFlatProfile(self, dom, comp, v):
|
||||||
"""Set a flat profile for one component in one domain.
|
"""Set a flat profile for one component in one domain.
|
||||||
dom -- domain object
|
|
||||||
comp -- component name
|
:param dom:
|
||||||
v -- value
|
domain object
|
||||||
|
:param comp:
|
||||||
|
component name
|
||||||
|
:param v:
|
||||||
|
value
|
||||||
|
|
||||||
>>> s.setFlatProfile(d, 'u', -3.0)
|
>>> s.setFlatProfile(d, 'u', -3.0)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
idom = dom.index()
|
idom = dom.index()
|
||||||
icomp = dom.componentIndex(comp)
|
icomp = dom.componentIndex(comp)
|
||||||
|
|
@ -533,18 +544,18 @@ class Stack:
|
||||||
|
|
||||||
>>> s.showSolution()
|
>>> s.showSolution()
|
||||||
>>> s.showSolution('soln.txt')
|
>>> s.showSolution('soln.txt')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
_cantera.sim1D_showSolution(self._hndl, fname)
|
_cantera.sim1D_showSolution(self._hndl, fname)
|
||||||
|
|
||||||
def setTimeStep(self, stepsize, nsteps):
|
def setTimeStep(self, stepsize, nsteps):
|
||||||
"""Set the sequence of time steps to try when Newton fails.
|
"""Set the sequence of time steps to try when Newton fails.
|
||||||
|
|
||||||
stepsize -- initial time step size [s]
|
:param stepsize:
|
||||||
nsteps - sequence of integer step numbers
|
initial time step size [s]
|
||||||
|
:param nsteps:
|
||||||
|
sequence of integer step numbers
|
||||||
|
|
||||||
>>> s.setTimeStep(1.0e-5, [1, 2, 5, 10])
|
>>> s.setTimeStep(1.0e-5, [1, 2, 5, 10])
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# 3/20/09
|
# 3/20/09
|
||||||
# The use of asarray seems to set the nsteps array to be of
|
# The use of asarray seems to set the nsteps array to be of
|
||||||
|
|
@ -559,10 +570,12 @@ class Stack:
|
||||||
|
|
||||||
def solve(self, loglevel=1, refine_grid=1):
|
def solve(self, loglevel=1, refine_grid=1):
|
||||||
"""Solve the problem.
|
"""Solve the problem.
|
||||||
loglevel -- integer flag controlling the amount of
|
|
||||||
diagnostic output. Zero suppresses all output, and
|
:param loglevel:
|
||||||
5 produces very verbose output. Default: 1
|
integer flag controlling the amount of diagnostic output. Zero
|
||||||
refine_grid -- if non-zero, enable grid refinement."""
|
suppresses all output, and 5 produces very verbose output. Default: 1
|
||||||
|
:param refine_grid:
|
||||||
|
if non-zero, enable grid refinement."""
|
||||||
|
|
||||||
return _cantera.sim1D_solve(self._hndl, loglevel, refine_grid)
|
return _cantera.sim1D_solve(self._hndl, loglevel, refine_grid)
|
||||||
|
|
||||||
|
|
@ -574,33 +587,38 @@ class Stack:
|
||||||
def setRefineCriteria(self, domain = None, ratio = 10.0, slope = 0.8,
|
def setRefineCriteria(self, domain = None, ratio = 10.0, slope = 0.8,
|
||||||
curve = 0.8, prune = 0.05):
|
curve = 0.8, prune = 0.05):
|
||||||
"""Set the criteria used to refine one domain.
|
"""Set the criteria used to refine one domain.
|
||||||
domain -- domain object
|
|
||||||
ratio -- additional points will be added if the ratio of the spacing
|
|
||||||
on either side of a grid point exceeds this value
|
|
||||||
slope -- maximum difference in value between two adjacent points,
|
|
||||||
scaled by the maximum difference in the profile
|
|
||||||
(0.0 < slope < 1.0). Adds points in regions of high slope.
|
|
||||||
curve -- maximum difference in slope between two adjacent intervals,
|
|
||||||
scaled by the maximum difference in the profile
|
|
||||||
(0.0 < curve < 1.0). Adds points in regions of high
|
|
||||||
curvature.
|
|
||||||
prune -- if the slope or curve criteria are satisfied to the level of
|
|
||||||
'prune', the grid point is assumed not to be needed and is
|
|
||||||
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,
|
:param domain:
|
||||||
... prune = 0.03)
|
domain object
|
||||||
|
:param ratio:
|
||||||
|
additional points will be added if the ratio of the spacing
|
||||||
|
on either side of a grid point exceeds this value
|
||||||
|
:param slope:
|
||||||
|
maximum difference in value between two adjacent points, scaled by
|
||||||
|
the maximum difference in the profile (0.0 < slope < 1.0). Adds
|
||||||
|
points in regions of high slope.
|
||||||
|
:param curve:
|
||||||
|
maximum difference in slope between two adjacent intervals, scaled
|
||||||
|
by the maximum difference in the profile (0.0 < curve < 1.0). Adds
|
||||||
|
points in regions of high curvature.
|
||||||
|
:param prune:
|
||||||
|
if the slope or curve criteria are satisfied to the level of
|
||||||
|
'prune', the grid point is assumed not to be needed and is 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)
|
||||||
"""
|
"""
|
||||||
idom = domain.index()
|
idom = domain.index()
|
||||||
return _cantera.sim1D_setRefineCriteria(self._hndl,
|
return _cantera.sim1D_setRefineCriteria(self._hndl,
|
||||||
idom, ratio, slope, curve, prune)
|
idom, ratio, slope, curve, prune)
|
||||||
|
|
||||||
def save(self, file = 'soln.xml', id = 'solution', desc = 'none'):
|
def save(self, file = 'soln.xml', id = 'solution', desc = 'none'):
|
||||||
"""Save the solution in XML format.
|
"""Save the solution in XML format.
|
||||||
|
|
||||||
>>> s.save(file = 'save.xml', id = 'energy_off',
|
>>> s.save(file='save.xml', id='energy_off',
|
||||||
... desc = 'solution with energy eqn. disabled')
|
... desc='solution with energy eqn. disabled')
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return _cantera.sim1D_save(self._hndl, file, id, desc)
|
return _cantera.sim1D_save(self._hndl, file, id, desc)
|
||||||
|
|
@ -608,8 +626,10 @@ class Stack:
|
||||||
def restore(self, file = 'soln.xml', id = 'solution'):
|
def restore(self, file = 'soln.xml', id = 'solution'):
|
||||||
"""Set the solution vector to a previously-saved solution.
|
"""Set the solution vector to a previously-saved solution.
|
||||||
|
|
||||||
file -- solution file
|
:param file:
|
||||||
id -- solution name within the file
|
solution file
|
||||||
|
:param id:
|
||||||
|
solution name within the file
|
||||||
|
|
||||||
>>> s.restore(file = 'save.xml', id = 'energy_off')
|
>>> s.restore(file = 'save.xml', id = 'energy_off')
|
||||||
"""
|
"""
|
||||||
|
|
@ -630,13 +650,15 @@ class Stack:
|
||||||
|
|
||||||
def value(self, domain, component, localPoint):
|
def value(self, domain, component, localPoint):
|
||||||
"""Solution value at one point.
|
"""Solution value at one point.
|
||||||
domain -- domain object
|
|
||||||
component -- component name
|
:param domain:
|
||||||
localPoint -- grid point number in the domain, starting with
|
domain object
|
||||||
zero at the left
|
:param component:
|
||||||
|
component name
|
||||||
|
:param localPoint:
|
||||||
|
grid point number in the domain, starting with zero at the left
|
||||||
|
|
||||||
>>> t = s.value(flow, 'T', 6)
|
>>> t = s.value(flow, 'T', 6)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
icomp = domain.componentIndex(component)
|
icomp = domain.componentIndex(component)
|
||||||
idom = domain.index()
|
idom = domain.index()
|
||||||
|
|
@ -644,6 +666,7 @@ class Stack:
|
||||||
|
|
||||||
def profile(self, domain, component):
|
def profile(self, domain, component):
|
||||||
"""Spatial profile of one component in one domain.
|
"""Spatial profile of one component in one domain.
|
||||||
|
|
||||||
>>> print s.profile(flow, 'T')
|
>>> print s.profile(flow, 'T')
|
||||||
"""
|
"""
|
||||||
np = domain.nPoints()
|
np = domain.nPoints()
|
||||||
|
|
@ -655,13 +678,15 @@ class Stack:
|
||||||
def workValue(self, dom, icomp, localPoint):
|
def workValue(self, dom, icomp, localPoint):
|
||||||
"""Internal work array value at one point. After calling eval,
|
"""Internal work array value at one point. After calling eval,
|
||||||
this array contains the values of the residual function.
|
this array contains the values of the residual function.
|
||||||
domain -- domain object
|
|
||||||
component -- component name
|
:param domain:
|
||||||
localPoint -- grid point number in the domain, starting with
|
domain object
|
||||||
zero at the left
|
:param component:
|
||||||
|
component name
|
||||||
|
:param localPoint:
|
||||||
|
grid point number in the domain, starting with zero at the left
|
||||||
|
|
||||||
>>> t = s.value(flow, 'T', 6)
|
>>> t = s.value(flow, 'T', 6)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
idom = dom.index()
|
idom = dom.index()
|
||||||
return _cantera.sim1D_workValue(self._hndl, idom, icomp, localPoint)
|
return _cantera.sim1D_workValue(self._hndl, idom, icomp, localPoint)
|
||||||
|
|
@ -674,8 +699,11 @@ class Stack:
|
||||||
def setMaxJacAge(self, ss_age, ts_age):
|
def setMaxJacAge(self, ss_age, ts_age):
|
||||||
"""Set the maximum number of times the Jacobian will be used
|
"""Set the maximum number of times the Jacobian will be used
|
||||||
before it must be re-evaluated.
|
before it must be re-evaluated.
|
||||||
ss_age -- age criterion during steady-state mode
|
|
||||||
ts_age -- age criterion during time-stepping mode
|
:param ss_age:
|
||||||
|
age criterion during steady-state mode
|
||||||
|
:param ts_age:
|
||||||
|
age criterion during time-stepping mode
|
||||||
"""
|
"""
|
||||||
return _cantera.sim1D_setMaxJacAge(self._hndl, ss_age, ts_age)
|
return _cantera.sim1D_setMaxJacAge(self._hndl, ss_age, ts_age)
|
||||||
|
|
||||||
|
|
@ -683,7 +711,7 @@ class Stack:
|
||||||
"""Set the factor by which the time step will be increased
|
"""Set the factor by which the time step will be increased
|
||||||
after a successful step, or decreased after an unsuccessful one.
|
after a successful step, or decreased after an unsuccessful one.
|
||||||
|
|
||||||
s.timeStepFactor(3.0)
|
>>> s.timeStepFactor(3.0)
|
||||||
"""
|
"""
|
||||||
return _cantera.sim1D_timeStepFactor(self._hndl, tfactor)
|
return _cantera.sim1D_timeStepFactor(self._hndl, tfactor)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,10 +72,11 @@ class Phase:
|
||||||
return _cantera.phase_nspecies(self._phase_id)
|
return _cantera.phase_nspecies(self._phase_id)
|
||||||
|
|
||||||
def nAtoms(self, species = None, element = None):
|
def nAtoms(self, species = None, element = None):
|
||||||
"""Number of atoms of element 'element' in species 'species'.
|
"""Number of atoms of element *element* in species *species*.
|
||||||
The element and species may be specified by name or by number.
|
The element and species may be specified by name or by number.
|
||||||
|
|
||||||
>>> ph.nAtoms('CH4','H')
|
>>> ph.nAtoms('CH4','H')
|
||||||
___ 4
|
4
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -122,9 +123,9 @@ class Phase:
|
||||||
|
|
||||||
def moleFractions(self, species = None):
|
def moleFractions(self, species = None):
|
||||||
"""Species mole fraction array.
|
"""Species mole fraction array.
|
||||||
If optional argument 'species'
|
If optional argument *species* is supplied, then only the values
|
||||||
is supplied, then only the values for the selected species are
|
for the selected species are returned.
|
||||||
returned.
|
|
||||||
>>> x1 = ph.moleFractions() # all species
|
>>> x1 = ph.moleFractions() # all species
|
||||||
>>> x2 = ph.moleFractions(['OH', 'CH3'. 'O2'])
|
>>> x2 = ph.moleFractions(['OH', 'CH3'. 'O2'])
|
||||||
"""
|
"""
|
||||||
|
|
@ -132,8 +133,8 @@ class Phase:
|
||||||
return self.selectSpecies(x, species)
|
return self.selectSpecies(x, species)
|
||||||
|
|
||||||
def moleFraction(self, species):
|
def moleFraction(self, species):
|
||||||
"""Mole fraction of a species, referenced by name or
|
"""Mole fraction of a species, referenced by name or index number.
|
||||||
index number.
|
|
||||||
>>> ph.moleFraction(4)
|
>>> ph.moleFraction(4)
|
||||||
>>> ph.moleFraction('CH4')
|
>>> ph.moleFraction('CH4')
|
||||||
"""
|
"""
|
||||||
|
|
@ -143,9 +144,9 @@ class Phase:
|
||||||
|
|
||||||
def massFractions(self, species = None):
|
def massFractions(self, species = None):
|
||||||
"""Species mass fraction array.
|
"""Species mass fraction array.
|
||||||
If optional argument 'species'
|
If optional argument *species* is supplied, then only the values for
|
||||||
is supplied, then only the values for the selected species are
|
the selected species are returned.
|
||||||
returned.
|
|
||||||
>>> y1 = ph.massFractions() # all species
|
>>> y1 = ph.massFractions() # all species
|
||||||
>>> y2 = ph.massFractions(['OH', 'CH3'. 'O2'])
|
>>> y2 = ph.massFractions(['OH', 'CH3'. 'O2'])
|
||||||
"""
|
"""
|
||||||
|
|
@ -156,6 +157,7 @@ class Phase:
|
||||||
def massFraction(self, species):
|
def massFraction(self, species):
|
||||||
"""Mass fraction of one species, referenced by name or
|
"""Mass fraction of one species, referenced by name or
|
||||||
index number.
|
index number.
|
||||||
|
|
||||||
>>> ph.massFraction(4)
|
>>> ph.massFraction(4)
|
||||||
>>> ph.massFraction('CH4')
|
>>> ph.massFraction('CH4')
|
||||||
"""
|
"""
|
||||||
|
|
@ -164,7 +166,7 @@ class Phase:
|
||||||
|
|
||||||
|
|
||||||
def elementName(self,m):
|
def elementName(self,m):
|
||||||
"""Name of the element with index number m."""
|
"""Name of the element with index number *m*."""
|
||||||
return _cantera.phase_getstring(self._phase_id,1,m)
|
return _cantera.phase_getstring(self._phase_id,1,m)
|
||||||
|
|
||||||
def elementNames(self):
|
def elementNames(self):
|
||||||
|
|
@ -173,7 +175,7 @@ class Phase:
|
||||||
return map(self.elementName,range(nel))
|
return map(self.elementName,range(nel))
|
||||||
|
|
||||||
def elementIndex(self, element):
|
def elementIndex(self, element):
|
||||||
"""The index of element 'element', which may be specified as
|
"""The index of element *element*, which may be specified as
|
||||||
a string or an integer index. In the latter case, the index is
|
a string or an integer index. In the latter case, the index is
|
||||||
checked for validity and returned. If no such element is
|
checked for validity and returned. If no such element is
|
||||||
present, an exception is thrown."""
|
present, an exception is thrown."""
|
||||||
|
|
@ -189,9 +191,8 @@ class Phase:
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def speciesName(self,k):
|
def speciesName(self,k):
|
||||||
"""Name of the species with index k."""
|
"""Name of the species with index *k*."""
|
||||||
return _cantera.phase_getstring(self._phase_id,2,k)
|
return _cantera.phase_getstring(self._phase_id,2,k)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -202,7 +203,7 @@ class Phase:
|
||||||
|
|
||||||
|
|
||||||
def speciesIndex(self, species):
|
def speciesIndex(self, species):
|
||||||
"""The index of species 'species', which may be specified as
|
"""The index of species *species*, which may be specified as
|
||||||
a string or an integer index. In the latter case, the index is
|
a string or an integer index. In the latter case, the index is
|
||||||
checked for validity and returned. If no such species is
|
checked for validity and returned. If no such species is
|
||||||
present, an exception is thrown."""
|
present, an exception is thrown."""
|
||||||
|
|
@ -238,16 +239,15 @@ class Phase:
|
||||||
def setMoleFractions(self, x, norm = 1):
|
def setMoleFractions(self, x, norm = 1):
|
||||||
"""Set the mole fractions.
|
"""Set the mole fractions.
|
||||||
|
|
||||||
x - string or array of mole fraction values
|
:param x:
|
||||||
|
string or array of mole fraction values
|
||||||
norm - If non-zero (default), array values will be
|
:param norm:
|
||||||
scaled to sum to 1.0.
|
If non-zero (default), array values will be scaled to sum to 1.0.
|
||||||
|
|
||||||
>>> ph.setMoleFractions('CO:1, H2:7, H2O:7.8')
|
>>> ph.setMoleFractions('CO:1, H2:7, H2O:7.8')
|
||||||
>>> x = [1.0]*ph.nSpecies()
|
>>> x = [1.0]*ph.nSpecies()
|
||||||
>>> ph.setMoleFractions(x)
|
>>> ph.setMoleFractions(x)
|
||||||
>>> ph.setMoleFractions(x, norm = 0) # don't normalize values
|
>>> ph.setMoleFractions(x, norm = 0) # don't normalize values
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if type(x) == types.StringType:
|
if type(x) == types.StringType:
|
||||||
_cantera.phase_setstring(self._phase_id,1,x)
|
_cantera.phase_setstring(self._phase_id,1,x)
|
||||||
|
|
@ -259,7 +259,7 @@ class Phase:
|
||||||
|
|
||||||
def setMassFractions(self, x, norm = 1):
|
def setMassFractions(self, x, norm = 1):
|
||||||
"""Set the mass fractions.
|
"""Set the mass fractions.
|
||||||
See: setMoleFractions
|
See :meth:`~.Phase.setMoleFractions`
|
||||||
"""
|
"""
|
||||||
if type(x) == types.StringType:
|
if type(x) == types.StringType:
|
||||||
_cantera.phase_setstring(self._phase_id,2,x)
|
_cantera.phase_setstring(self._phase_id,2,x)
|
||||||
|
|
@ -282,6 +282,7 @@ class Phase:
|
||||||
def setState_TNX(self, t, n, x):
|
def setState_TNX(self, t, n, x):
|
||||||
"""Set the temperature, molardensity, and mole fractions. The mole
|
"""Set the temperature, molardensity, and mole fractions. The mole
|
||||||
fractions may be entered as a string or array,
|
fractions may be entered as a string or array,
|
||||||
|
|
||||||
>>> ph.setState_TNX(600.0, 2.0e-3, 'CH4:0.4, O2:0.6')
|
>>> ph.setState_TNX(600.0, 2.0e-3, 'CH4:0.4, O2:0.6')
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -306,6 +307,7 @@ class Phase:
|
||||||
return an array of those values corresponding to species
|
return an array of those values corresponding to species
|
||||||
listed in 'species'. This method is used internally to implement
|
listed in 'species'. This method is used internally to implement
|
||||||
species selection in methods like moleFractions, massFractions, etc.
|
species selection in methods like moleFractions, massFractions, etc.
|
||||||
|
|
||||||
>>> f = ph.chemPotentials()
|
>>> f = ph.chemPotentials()
|
||||||
>>> muo2, muh2 = ph.selectSpecies(f, ['O2', 'H2'])
|
>>> muo2, muh2 = ph.selectSpecies(f, ['O2', 'H2'])
|
||||||
"""
|
"""
|
||||||
|
|
@ -321,9 +323,10 @@ class Phase:
|
||||||
return asarray(f)
|
return asarray(f)
|
||||||
|
|
||||||
def selectElements(self, f, elements):
|
def selectElements(self, f, elements):
|
||||||
"""Given an array 'f' of floating-point element properties,
|
"""Given an array *f* of floating-point element properties,
|
||||||
return a nummodule array of those values corresponding to elements
|
return a nummodule array of those values corresponding to elements
|
||||||
listed in 'elements'.
|
listed in *elements*.
|
||||||
|
|
||||||
>>> f = ph.elementPotentials()
|
>>> f = ph.elementPotentials()
|
||||||
>>> lam_o, lam_h = ph.selectElements(f, ['O', 'H'])
|
>>> lam_o, lam_h = ph.selectElements(f, ['O', 'H'])
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@ class ReactorBase:
|
||||||
volume = 1.0, energy = 'on',
|
volume = 1.0, energy = 'on',
|
||||||
type = -1, verbose = 0):
|
type = -1, verbose = 0):
|
||||||
"""
|
"""
|
||||||
See class 'Reactor' for a description of the constructor parameters.
|
See :class:`.Reactor` for a description of the constructor parameters.
|
||||||
The 'type' parameter specifies whether a Reactor (type = 2) or
|
The *type* parameter specifies whether a :class:`.Reactor` (type = 2) or
|
||||||
Reservoir (type = 1) will be created.
|
:class:`.Reservoir` (type = 1) will be created.
|
||||||
"""
|
"""
|
||||||
self.__reactor_id = _cantera.reactor_new(type)
|
self.__reactor_id = _cantera.reactor_new(type)
|
||||||
self._type = type
|
self._type = type
|
||||||
|
|
@ -84,7 +84,7 @@ class ReactorBase:
|
||||||
|
|
||||||
def insert(self, contents):
|
def insert(self, contents):
|
||||||
"""
|
"""
|
||||||
Insert 'contents' into the reactor. Sets the objects used to compute
|
Insert *contents* into the reactor. Sets the objects used to compute
|
||||||
thermodynamic properties and kinetic rates.
|
thermodynamic properties and kinetic rates.
|
||||||
"""
|
"""
|
||||||
# store a reference to contents so that it will live as long
|
# store a reference to contents so that it will live as long
|
||||||
|
|
@ -108,7 +108,7 @@ class ReactorBase:
|
||||||
|
|
||||||
def _setEnergy(self, eflag):
|
def _setEnergy(self, eflag):
|
||||||
"""Turn the energy equation on or off. If the argument is the
|
"""Turn the energy equation on or off. If the argument is the
|
||||||
string 'off' or the number 0, the energy equation is disabled,
|
string ``'off'`` or the number 0, the energy equation is disabled,
|
||||||
and the reactor temperature is held constant at its initial
|
and the reactor temperature is held constant at its initial
|
||||||
value."""
|
value."""
|
||||||
ie = 1
|
ie = 1
|
||||||
|
|
@ -158,26 +158,27 @@ class ReactorBase:
|
||||||
def advance(self, time):
|
def advance(self, time):
|
||||||
"""Deprecated.
|
"""Deprecated.
|
||||||
Advance the state of the reactor in time from the current
|
Advance the state of the reactor in time from the current
|
||||||
time to time 'time'. Note: this method is deprecated. See
|
time to time *time*. Note: this method is deprecated. See
|
||||||
class ReactorNet."""
|
:class:`.ReactorNet`."""
|
||||||
raise "use method advance of class ReactorNet"
|
raise "use method advance of class ReactorNet"
|
||||||
#return _cantera.reactor_advance(self.__reactor_id, time)
|
#return _cantera.reactor_advance(self.__reactor_id, time)
|
||||||
|
|
||||||
def step(self, time):
|
def step(self, time):
|
||||||
"""Deprecated.
|
"""Deprecated.
|
||||||
Take one internal time step from the current time toward
|
Take one internal time step from the current time toward
|
||||||
time 'time'. Note: this method is deprecated. See class
|
time *time*. Note: this method is deprecated. See class
|
||||||
ReactorNet."""
|
:class:`.ReactorNet`."""
|
||||||
raise "use method step of class ReactorNet"
|
raise "use method step of class ReactorNet"
|
||||||
#return _cantera.reactor_step(self.__reactor_id, time)
|
#return _cantera.reactor_step(self.__reactor_id, time)
|
||||||
|
|
||||||
def massFraction(self, s):
|
def massFraction(self, s):
|
||||||
"""The mass fraction of species s, specified either by name or
|
"""The mass fraction of species *s*, specified either by name or
|
||||||
index number.
|
index number.
|
||||||
|
|
||||||
>>> y1 = r.massFraction(7)
|
>>> y1 = r.massFraction(7)
|
||||||
___0.02
|
0.02
|
||||||
>>> y2 = r.massFraction('CH3O')
|
>>> y2 = r.massFraction('CH3O')
|
||||||
___0.02
|
0.02
|
||||||
"""
|
"""
|
||||||
if type(s) == types.StringType:
|
if type(s) == types.StringType:
|
||||||
kk = self._contents.speciesIndex(s)
|
kk = self._contents.speciesIndex(s)
|
||||||
|
|
@ -202,10 +203,11 @@ class ReactorBase:
|
||||||
def moleFraction(self, s):
|
def moleFraction(self, s):
|
||||||
"""The mole fraction of species s, specified either by name or
|
"""The mole fraction of species s, specified either by name or
|
||||||
index number.
|
index number.
|
||||||
|
|
||||||
>>> x1 = r.moleFraction(9)
|
>>> x1 = r.moleFraction(9)
|
||||||
___0.00012
|
0.00012
|
||||||
>>> x2 = r.moleFraction('CH3')
|
>>> x2 = r.moleFraction('CH3')
|
||||||
___0.00012
|
0.00012
|
||||||
"""
|
"""
|
||||||
if type(s) == types.StringType:
|
if type(s) == types.StringType:
|
||||||
kk = self._contents.speciesIndex(s)
|
kk = self._contents.speciesIndex(s)
|
||||||
|
|
@ -218,45 +220,53 @@ class ReactorBase:
|
||||||
"""Return the list of flow devices installed on inlets to this reactor.
|
"""Return the list of flow devices installed on inlets to this reactor.
|
||||||
This method can be used to access information about the flows entering
|
This method can be used to access information about the flows entering
|
||||||
the reactor:
|
the reactor:
|
||||||
|
|
||||||
>>> for n in r.inlets():
|
>>> for n in r.inlets():
|
||||||
... print n.name(), n.massFlowRate()
|
... print n.name(), n.massFlowRate()
|
||||||
See: MassFlowController, Valve, PressureController.
|
|
||||||
|
See: :class:`.MassFlowController`, :class:`.Valve`,
|
||||||
|
:class:`.PressureController`.
|
||||||
"""
|
"""
|
||||||
return self._inlets
|
return self._inlets
|
||||||
|
|
||||||
def outlets(self):
|
def outlets(self):
|
||||||
"""Return the list of flow devices installed on outlets
|
"""Return the list of flow devices installed on outlets
|
||||||
on this reactor.
|
on this reactor.
|
||||||
|
|
||||||
>>> for o in r.outlets():
|
>>> for o in r.outlets():
|
||||||
... print o.name(), o.massFlowRate()
|
... print o.name(), o.massFlowRate()
|
||||||
See: MassFlowController, Valve, PressureController.
|
|
||||||
|
See: :class:`.MassFlowController`, :class:`.Valve`,
|
||||||
|
:class:`.PressureController`.
|
||||||
"""
|
"""
|
||||||
return self._outlets
|
return self._outlets
|
||||||
|
|
||||||
def walls(self):
|
def walls(self):
|
||||||
"""Return the list of walls installed on this reactor.
|
"""Return the list of walls installed on this reactor.
|
||||||
|
|
||||||
>>> for w in r.walls():
|
>>> for w in r.walls():
|
||||||
... print w.name()
|
... print w.name()
|
||||||
See: Wall.
|
|
||||||
|
See: :class:`.Wall`.
|
||||||
"""
|
"""
|
||||||
return self._walls
|
return self._walls
|
||||||
|
|
||||||
def _addInlet(self, inlet, other):
|
def _addInlet(self, inlet, other):
|
||||||
"""For internal use. Store a reference to 'inlet'
|
"""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)
|
self._inlets.append(inlet)
|
||||||
if self._type == 2 and other._type == 1:
|
if self._type == 2 and other._type == 1:
|
||||||
self._reservoirs.append(other)
|
self._reservoirs.append(other)
|
||||||
|
|
||||||
def _addOutlet(self, outlet, other):
|
def _addOutlet(self, outlet, other):
|
||||||
"""For internal use. Store a reference to 'outlet'
|
"""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)
|
self._outlets.append(outlet)
|
||||||
if self._type == 2 and other._type == 1:
|
if self._type == 2 and other._type == 1:
|
||||||
self._reservoirs.append(other)
|
self._reservoirs.append(other)
|
||||||
|
|
||||||
def _addWall(self, wall, other):
|
def _addWall(self, wall, other):
|
||||||
"""For internal use. Store a reference to 'wall'
|
"""For internal use. Store a reference to *wall*
|
||||||
so that it will not be deleted before this object."""
|
so that it will not be deleted before this object."""
|
||||||
self._walls.append(wall)
|
self._walls.append(wall)
|
||||||
if self._type == 2 and other._type == 1:
|
if self._type == 2 and other._type == 1:
|
||||||
|
|
@ -265,12 +275,14 @@ class ReactorBase:
|
||||||
def syncContents(self):
|
def syncContents(self):
|
||||||
"""Set the state of the object representing the reactor contents
|
"""Set the state of the object representing the reactor contents
|
||||||
to the current reactor state.
|
to the current reactor state.
|
||||||
|
|
||||||
>>> r = Reactor(gas)
|
>>> r = Reactor(gas)
|
||||||
>>> (statements that change the state of object 'gas')
|
>>> (statements that change the state of object 'gas')
|
||||||
>>> r.syncContents()
|
>>> r.syncContents()
|
||||||
|
|
||||||
After this statement, the state of object 'gas' is synchronized
|
After this statement, the state of object 'gas' is synchronized
|
||||||
with the reactor state.
|
with the reactor state.
|
||||||
See 'contents'.
|
See :meth:`.contents`.
|
||||||
"""
|
"""
|
||||||
self._contents.setState_TRY(self.temperature(),
|
self._contents.setState_TRY(self.temperature(),
|
||||||
self.density(),
|
self.density(),
|
||||||
|
|
@ -280,19 +292,21 @@ class ReactorBase:
|
||||||
"""Return an object representing the reactor contents, after first
|
"""Return an object representing the reactor contents, after first
|
||||||
synchronizing its state with the current reactor state. This method
|
synchronizing its state with the current reactor state. This method
|
||||||
is useful when some property of the fluid in the reactor is
|
is useful when some property of the fluid in the reactor is
|
||||||
needed that is not provided by a method of class Reactor.
|
needed that is not provided by a method of :class:`.Reactor`.
|
||||||
|
|
||||||
>>> r = Reactor(gas)
|
>>> r = Reactor(gas)
|
||||||
>>> (statements that change the state of object 'gas')
|
>>> (statements that change the state of object 'gas')
|
||||||
>>> c = r.contents()
|
>>> c = r.contents()
|
||||||
>>> print c.gibbs_mole(), c.chemPotentials()
|
>>> print c.gibbs_mole(), c.chemPotentials()
|
||||||
|
|
||||||
Note that after calling method 'contents', object 'c'
|
Note that after calling :meth:`.contents`, object *c*
|
||||||
references the same underlying kernel object as object 'gas'
|
references the same underlying kernel object as object *gas*
|
||||||
does. Therefore, all properties of 'c' and 'gas' are
|
does. Therefore, all properties of *c* and *gas* are
|
||||||
identical. (Remember that Python objects are really C
|
identical. (Remember that Python objects are really C
|
||||||
pointers; at the C level, both point to the same data
|
pointers; at the C level, both point to the same data
|
||||||
structure.)
|
structure.)
|
||||||
It is also allowed to write
|
It is also allowed to write
|
||||||
|
|
||||||
>>> gas = r.contents()
|
>>> gas = r.contents()
|
||||||
"""
|
"""
|
||||||
self.syncContents()
|
self.syncContents()
|
||||||
|
|
@ -328,44 +342,51 @@ _reservoircount = 0
|
||||||
class Reactor(ReactorBase):
|
class Reactor(ReactorBase):
|
||||||
"""
|
"""
|
||||||
Zero-dimensional reactors. Instances of class Reactor represent
|
Zero-dimensional reactors. Instances of class Reactor represent
|
||||||
zero-dimensional reactors. By default, they are closed (no inlets
|
zero-dimensional reactors. By default, they are closed (no inlets or
|
||||||
or outlets), have fixed volume, and have adiabatic, chemically-intert
|
outlets), have fixed volume, and have adiabatic, chemically-inert walls.
|
||||||
walls. These properties may all be changed by adding appropriate
|
These properties may all be changed by adding appropriate components.
|
||||||
components.
|
See :class:`.Wall`, :class:`.MassFlowController`, and :class:`.Valve`.
|
||||||
See classes 'Wall', 'MassFlowController', and 'Valve'.
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, contents = None, name = '',
|
def __init__(self, contents = None, name = '',
|
||||||
volume = 1.0, energy = 'on',
|
volume = 1.0, energy = 'on',
|
||||||
verbose = 0):
|
verbose = 0):
|
||||||
"""
|
"""
|
||||||
contents - Reactor contents. If not specified, the reactor is
|
:param contents:
|
||||||
initially empty. In this case, call method 'insert' to specify
|
Reactor contents. If not specified, the reactor is initially empty.
|
||||||
the contents.
|
In this case, call :meth:`.insert` to specify the contents.
|
||||||
|
:param name:
|
||||||
|
Used only to identify this reactor in output. If not specified,
|
||||||
|
defaults to ``'Reactor_n'``, where *n* is an integer assigned in
|
||||||
|
the order :class:`.Reactor` objects are created.
|
||||||
|
:param volume:
|
||||||
|
Initial reactor volume. Defaults to 1 m^3.
|
||||||
|
:param energy:
|
||||||
|
Set to ``'on'`` or ``'off'``. If set to ``'off'``, the energy
|
||||||
|
equation is not solved, and the temperature is held at its
|
||||||
|
initial value. The default in ``'on'``.
|
||||||
|
:param verbose:
|
||||||
|
If set to a non-zero value, additional diagnostic information
|
||||||
|
will be printed.
|
||||||
|
|
||||||
name - Used only to identify this reactor in output. If not
|
Some examples showing how to create :class:`Reactor` objects are
|
||||||
specified, defaults to 'Reactor_n', where n is an integer
|
shown below.
|
||||||
assigned in the order Reactor objects are created.
|
|
||||||
|
|
||||||
volume - Initial reactor volume. Defaults to 1 m^3.
|
|
||||||
|
|
||||||
energy - Set to 'on' or 'off'. If set to 'off', the energy
|
|
||||||
equation is not solved, and the temperature is held at its
|
|
||||||
initial value. The default in 'on'.
|
|
||||||
|
|
||||||
verbose - if set to a non-zero value, additional diagnostic
|
|
||||||
information will be printed.
|
|
||||||
|
|
||||||
Some examples showing how to create Reactor objects are shown below.
|
|
||||||
>>> gas = GRI30()
|
>>> gas = GRI30()
|
||||||
>>> r1 = Reactor(gas)
|
>>> r1 = Reactor(gas)
|
||||||
|
|
||||||
This is equivalent to:
|
This is equivalent to:
|
||||||
|
|
||||||
>>> r1 = Reactor()
|
>>> r1 = Reactor()
|
||||||
>>> r1.insert(gas)
|
>>> r1.insert(gas)
|
||||||
|
|
||||||
Arguments may be specified using keywords in any order:
|
Arguments may be specified using keywords in any order:
|
||||||
|
|
||||||
>>> r2 = Reactor(contents = gas, energy = 'off',
|
>>> r2 = Reactor(contents = gas, energy = 'off',
|
||||||
... name = 'isothermal_reactor')
|
... name = 'isothermal_reactor')
|
||||||
>>> r3 = Reactor(contents = gas, name = 'adiabatic_reactor')
|
>>> r3 = Reactor(contents = gas, name = 'adiabatic_reactor')
|
||||||
|
|
||||||
Here's an array of reactors:
|
Here's an array of reactors:
|
||||||
|
|
||||||
>>> reactor_array = [Reactor(), Reactor(gas), Reactor(Air())]
|
>>> reactor_array = [Reactor(), Reactor(gas), Reactor(Air())]
|
||||||
"""
|
"""
|
||||||
global _reactorcount
|
global _reactorcount
|
||||||
|
|
@ -377,31 +398,28 @@ class Reactor(ReactorBase):
|
||||||
verbose = verbose, type = 2)
|
verbose = verbose, type = 2)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class FlowReactor(ReactorBase):
|
class FlowReactor(ReactorBase):
|
||||||
"""
|
|
||||||
"""
|
|
||||||
def __init__(self, contents = None, name = '',
|
def __init__(self, contents = None, name = '',
|
||||||
volume = 1.0, energy = 'on',
|
volume = 1.0, energy = 'on',
|
||||||
mdot = -1.0,
|
mdot = -1.0,
|
||||||
verbose = 0):
|
verbose = 0):
|
||||||
"""
|
"""
|
||||||
contents - Reactor contents. If not specified, the reactor is
|
:param contents:
|
||||||
initially empty. In this case, call method 'insert' to specify
|
Reactor contents. If not specified, the reactor is initially empty.
|
||||||
the contents.
|
In this case, call :meth:`.insert` to specify the contents.
|
||||||
|
:param name:
|
||||||
name - Used only to identify this reactor in output. If not
|
Used only to identify this reactor in output. If not specified,
|
||||||
specified, defaults to 'Reactor_n', where n is an integer
|
defaults to ``Reactor_n``, where n is an integer assigned in the
|
||||||
assigned in the order Reactor objects are created.
|
order Reactor objects are created.
|
||||||
|
:param volume:
|
||||||
volume - Initial reactor volume. Defaults to 1 m^3.
|
Initial reactor volume. Defaults to 1 m^3.
|
||||||
|
:param energy:
|
||||||
energy - Set to 'on' or 'off'. If set to 'off', the energy
|
Set to ``'on'`` or ``'off'``. If set to ``'off'``, the energy
|
||||||
equation is not solved, and the temperature is held at its
|
equation is not solved, and the temperature is held at its
|
||||||
initial value. The default in 'on'.
|
initial value. The default in ``'on'``.
|
||||||
|
:param verbose:
|
||||||
verbose - if set to a non-zero value, additional diagnostic
|
if set to a non-zero value, additional diagnostic information
|
||||||
information will be printed.
|
will be printed.
|
||||||
"""
|
"""
|
||||||
global _reactorcount
|
global _reactorcount
|
||||||
if name == '':
|
if name == '':
|
||||||
|
|
@ -418,28 +436,27 @@ class FlowReactor(ReactorBase):
|
||||||
|
|
||||||
|
|
||||||
class ConstPressureReactor(ReactorBase):
|
class ConstPressureReactor(ReactorBase):
|
||||||
"""
|
|
||||||
"""
|
|
||||||
def __init__(self, contents = None, name = '',
|
def __init__(self, contents = None, name = '',
|
||||||
volume = 1.0, energy = 'on',
|
volume = 1.0, energy = 'on',
|
||||||
verbose = 0):
|
verbose = 0):
|
||||||
"""
|
"""
|
||||||
contents - Reactor contents. If not specified, the reactor is
|
:param contents:
|
||||||
initially empty. In this case, call method 'insert' to specify
|
Reactor contents. If not specified, the reactor is
|
||||||
the contents.
|
initially empty. In this case, call :meth:`.insert` to specify
|
||||||
|
the contents.
|
||||||
name - Used only to identify this reactor in output. If not
|
:param name:
|
||||||
specified, defaults to 'Reactor_n', where n is an integer
|
Used only to identify this reactor in output. If not specified,
|
||||||
assigned in the order Reactor objects are created.
|
defaults to ``'Reactor_n'``, where n is an integer assigned in the
|
||||||
|
order :class:`.Reactor` objects are created.
|
||||||
volume - Initial reactor volume. Defaults to 1 m^3.
|
:param volume:
|
||||||
|
Initial reactor volume. Defaults to 1 m^3.
|
||||||
energy - Set to 'on' or 'off'. If set to 'off', the energy
|
:param energy:
|
||||||
equation is not solved, and the temperature is held at its
|
Set to ``'on'`` or ``'off'``. If set to ``'off'``, the energy
|
||||||
initial value. The default in 'on'.
|
equation is not solved, and the temperature is held at its
|
||||||
|
initial value. The default in ``'on'``.
|
||||||
verbose - if set to a non-zero value, additional diagnostic
|
:param verbose:
|
||||||
information will be printed.
|
If set to a non-zero value, additional diagnostic
|
||||||
|
information will be printed.
|
||||||
"""
|
"""
|
||||||
global _reactorcount
|
global _reactorcount
|
||||||
if name == '':
|
if name == '':
|
||||||
|
|
@ -458,27 +475,31 @@ class Reservoir(ReactorBase):
|
||||||
"""
|
"""
|
||||||
def __init__(self, contents = None, name = '', verbose = 0):
|
def __init__(self, contents = None, name = '', verbose = 0):
|
||||||
"""
|
"""
|
||||||
contents - Reservoir contents. If not specified, the reservoir is
|
:param contents:
|
||||||
initially empty. In this case, call method insert to specify
|
Reservoir contents. If not specified, the reservoir is initially
|
||||||
the contents.
|
empty. In this case, call :meth:`.insert` to specify the contents.
|
||||||
|
:param name:
|
||||||
name - Used only to identify this reservoir in output. If not
|
Used only to identify this reservoir in output. If not specified,
|
||||||
specified, defaults to 'Reservoir_n', where n is an integer
|
defaults to ``'Reservoir_n'``, where n is an integer assigned in
|
||||||
assigned in the order Reservoir objects are created.
|
the order Reservoir objects are created.
|
||||||
|
:param verbose:
|
||||||
verbose - if set to a non-zero value, additional diagnostic
|
if set to a non-zero value, additional diagnostic information will
|
||||||
information will be printed.
|
be printed.
|
||||||
|
|
||||||
Some examples showing how to create Reservoir objects are shown below.
|
Some examples showing how to create Reservoir objects are shown below.
|
||||||
|
|
||||||
>>> gas = GRI30()
|
>>> gas = GRI30()
|
||||||
>>> res1 = Reservoir(gas)
|
>>> res1 = Reservoir(gas)
|
||||||
|
|
||||||
This is equivalent to:
|
This is equivalent to:
|
||||||
|
|
||||||
>>> res1 = Reactor()
|
>>> res1 = Reactor()
|
||||||
>>> res1.insert(gas)
|
>>> res1.insert(gas)
|
||||||
|
|
||||||
Arguments may be specified using keywords in any order:
|
Arguments may be specified using keywords in any order:
|
||||||
>>> res2 = Reservoir(contents = Air(),
|
|
||||||
... name = 'environment')
|
>>> res2 = Reservoir(contents=Air(), name='environment')
|
||||||
>>> res3 = Reservoir(contents = gas, name = 'upstream_state')
|
>>> res3 = Reservoir(contents=gas, name='upstream_state')
|
||||||
"""
|
"""
|
||||||
global _reservoircount
|
global _reservoircount
|
||||||
if name == '':
|
if name == '':
|
||||||
|
|
@ -492,8 +513,6 @@ class Reservoir(ReactorBase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#------------------ FlowDevice ---------------------------------
|
#------------------ FlowDevice ---------------------------------
|
||||||
|
|
||||||
class FlowDevice:
|
class FlowDevice:
|
||||||
|
|
@ -502,7 +521,7 @@ class FlowDevice:
|
||||||
"""
|
"""
|
||||||
def __init__(self, type, name, verbose):
|
def __init__(self, type, name, verbose):
|
||||||
"""
|
"""
|
||||||
Create a new instance of type 'type'
|
Create a new instance of type *type*
|
||||||
"""
|
"""
|
||||||
self._name = name
|
self._name = name
|
||||||
self._verbose = verbose
|
self._verbose = verbose
|
||||||
|
|
@ -534,7 +553,8 @@ class FlowDevice:
|
||||||
"""
|
"""
|
||||||
Install the device between the upstream and downstream
|
Install the device between the upstream and downstream
|
||||||
reactors or reservoirs.
|
reactors or reservoirs.
|
||||||
>>> f.install(upstream = reactor1, downstream = reservoir2)
|
|
||||||
|
>>> f.install(upstream=reactor1, downstream=reservoir2)
|
||||||
"""
|
"""
|
||||||
if self._verbose:
|
if self._verbose:
|
||||||
print
|
print
|
||||||
|
|
@ -557,64 +577,62 @@ class FlowDevice:
|
||||||
_mfccount = 0
|
_mfccount = 0
|
||||||
|
|
||||||
class MassFlowController(FlowDevice):
|
class MassFlowController(FlowDevice):
|
||||||
|
r"""
|
||||||
|
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
|
||||||
|
|
||||||
"""Mass flow controllers. A mass flow controller maintains a
|
.. math::
|
||||||
specified mass flow rate independent of upstream and downstream
|
|
||||||
conditions. The equation used to compute the mass flow rate is
|
|
||||||
\f[
|
|
||||||
\dot m = \max(\dot m_0, 0.0),
|
|
||||||
\f] where \f$ \dot m_0 \f$ is either
|
|
||||||
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
|
\dot m = \max(\dot m_0, 0.0),
|
||||||
will maintain the flow even if the downstream pressure is greater
|
|
||||||
than the upstream pressure. This allows simple implementation of
|
|
||||||
loops, in which exhaust gas from a reactor is fed back into it
|
|
||||||
through an inlet. But note that this capability should be used
|
|
||||||
with caution, since no account is taken of the work required to do
|
|
||||||
this.
|
|
||||||
|
|
||||||
A mass flow controller is assumed to be adiabatic, non-reactive,
|
where :math:`\dot m_0` is either a constant value or a function of time.
|
||||||
and have negligible volume, so that it is internally always in
|
Note that if :math:`\dot m_0 < 0`, the mass flow rate will be set to zero,
|
||||||
steady-state even if the upstream and downstream reactors are
|
since reversal of the flow direction is not allowed.
|
||||||
not. The fluid enthalpy, chemical composition, and mass flow rate
|
|
||||||
are constant across a mass flow controller, and the pressure
|
Unlike a real mass flow controller, a MassFlowController object will
|
||||||
difference equals the difference in pressure between the upstream
|
maintain the flow even if the downstream pressure is greater than the
|
||||||
and downstream reactors.
|
upstream pressure. This allows simple implementation of loops, in which
|
||||||
|
exhaust gas from a reactor is fed back into it through an inlet. But note
|
||||||
|
that this capability should be used with caution, since no account is
|
||||||
|
taken of the work required to do this.
|
||||||
|
|
||||||
|
A mass flow controller is assumed to be adiabatic, non-reactive, and have
|
||||||
|
negligible volume, so that it is internally always in steady-state even if
|
||||||
|
the upstream and downstream reactors are not. The fluid enthalpy, chemical
|
||||||
|
composition, and mass flow rate are constant across a mass flow controller,
|
||||||
|
and the pressure difference equals the difference in pressure between the
|
||||||
|
upstream and downstream reactors.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
>>> mfc1 = MassFlowController(upstream = res1, downstream = reactr,
|
>>> mfc1 = MassFlowController(upstream=res1, downstream=reactr,
|
||||||
... name = 'fuel_mfc', mdot = 0.1)
|
... name='fuel_mfc', mdot = 0.1)
|
||||||
>>> air_mdot = Gaussian(A = 0.1, t0 = 2.0, FWHM = 0.1)
|
>>> air_mdot = Gaussian(A=0.1, t0=2.0, FWHM=0.1)
|
||||||
>>> mfc2 = MassFlowController(upstream = res2, downstream = reactr,
|
>>> mfc2 = MassFlowController(upstream=res2, downstream=reactr,
|
||||||
... name = 'air_mfc', mdot = air_mdot)
|
... name='air_mfc', mdot=air_mdot)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, upstream=None,
|
def __init__(self, upstream=None,
|
||||||
downstream=None,
|
downstream=None,
|
||||||
name='',
|
name='',
|
||||||
verbose=0, mdot = 0.0):
|
verbose=0, mdot = 0.0):
|
||||||
"""
|
"""
|
||||||
upstream - upstream reactor or reservoir.
|
:param upstream:
|
||||||
|
upstream reactor or reservoir.
|
||||||
downstream - downstream reactor or reservoir.
|
:param downstream:
|
||||||
|
downstream reactor or reservoir.
|
||||||
name - name used to identify the mass flow controller in output.
|
:param name:
|
||||||
If no name is specified, it defaults to 'MFC_n', where n is an
|
name used to identify the mass flow controller in output. If no
|
||||||
integer assigned in the order the MassFlowController object
|
name is specified, it defaults to ``MFC_n``, where n is an integer
|
||||||
was created.
|
assigned in the order the MassFlowController object was created.
|
||||||
|
:param mdot:
|
||||||
mdot - Mass flow rate [kg/s]. This mass flow rate, which may
|
Mass flow rate [kg/s]. This mass flow rate, which may be a constant
|
||||||
be a constant of a function of time, will be maintained,
|
or a function of time, will be maintained, independent of upstream
|
||||||
independent of unstream and downstream conditions, unless
|
and downstream conditions, unless reset by calling method
|
||||||
reset by calling method 'set'.
|
:meth:`.set`.
|
||||||
|
:param verbose:
|
||||||
verbose - if set to a positive integer, additional diagnostic
|
if set to a positive integer, additional diagnostic information
|
||||||
information will be printed.
|
will be printed.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
global _mfccount
|
global _mfccount
|
||||||
if name == '':
|
if name == '':
|
||||||
|
|
@ -650,56 +668,51 @@ class MassFlowController(FlowDevice):
|
||||||
_valvecount = 0
|
_valvecount = 0
|
||||||
|
|
||||||
class Valve(FlowDevice):
|
class Valve(FlowDevice):
|
||||||
"""Valves. In Cantera, a Valve object is a flow devices with mass
|
r"""Valves. In Cantera, a Valve object is a flow devices with mass
|
||||||
flow rate that is a function of the pressure drop across it. The default behavior
|
flow rate that is a function of the pressure drop across it. The default behavior
|
||||||
is linear:
|
is linear:
|
||||||
\f[ \dot m = K_v (P_1 - P_2) \f]
|
|
||||||
if \f$ P_1 > P_2. \f$
|
|
||||||
Otherwise,
|
|
||||||
\f$ \dot m = 0 \f$.
|
|
||||||
However, an arbitrary function \f$ F\f$ can also be specified, such that
|
|
||||||
\f[
|
|
||||||
\dot m = F(P_1 - P_2).
|
|
||||||
\f]
|
|
||||||
if \f$ P_1 > P_2, \f$
|
|
||||||
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.
|
|
||||||
|
|
||||||
'Valve' objects are often used between an upstream reactor and a
|
.. math:: \dot m = K_v (P_1 - P_2)
|
||||||
downstream reactor or reservoir to maintain them both at nearly the
|
|
||||||
same pressure. By setting the constant \f$ K_v \f$ to a
|
|
||||||
sufficiently large value, very small pressure differences will
|
|
||||||
result in flow between the reactors that counteracts the pressure
|
|
||||||
difference.
|
|
||||||
|
|
||||||
A Valve is assumed to be adiabatic, non-reactive, and have
|
if :math:`P_1 > P_2.` Otherwise, :math:`\dot m = 0`.
|
||||||
negligible internal volume, so that it is internally always in
|
However, an arbitrary function can also be specified, such that
|
||||||
steady-state even if the upstream and downstream reactors are
|
|
||||||
not. The fluid enthalpy, chemical composition, and mass flow rate
|
.. math:: \dot m = F(P_1 - P_2)
|
||||||
are constant across a Valve, and the pressure difference equals
|
|
||||||
the difference in pressure between the upstream and downstream
|
if :math:`P_1 > P_2`, or :math:`\dot m = 0` otherwise.
|
||||||
reactors.
|
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.
|
||||||
|
|
||||||
|
:class:`Valve` objects are often used between an upstream reactor and a
|
||||||
|
downstream reactor or reservoir to maintain them both at nearly the same
|
||||||
|
pressure. By setting the constant :math:`K_v` to a sufficiently large
|
||||||
|
value, very small pressure differences will result in flow between the
|
||||||
|
reactors that counteracts the pressure difference.
|
||||||
|
|
||||||
|
A Valve is assumed to be adiabatic, non-reactive, and have negligible
|
||||||
|
internal volume, so that it is internally always in steady-state even if
|
||||||
|
the upstream and downstream reactors are not. The fluid enthalpy, chemical
|
||||||
|
composition, and mass flow rate 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,
|
def __init__(self, upstream=None, downstream=None,
|
||||||
name='', Kv = 0.0, mdot0 = 0.0, verbose=0):
|
name='', Kv = 0.0, mdot0 = 0.0, verbose=0):
|
||||||
"""
|
"""
|
||||||
upstream - upstream reactor or reservoir.
|
:param upstream:
|
||||||
|
upstream reactor or reservoir.
|
||||||
downstream - downstream reactor or reservoir.
|
:param downstream:
|
||||||
|
downstream reactor or reservoir.
|
||||||
name - name used to identify the valve in output.
|
:param name:
|
||||||
If no name is specified, it defaults to 'Valve_n', where n is an
|
name used to identify the valve in output. If no name is specified,
|
||||||
integer assigned in the order the Valve object
|
it defaults to ``Valve_n``, where n is an integer assigned in the
|
||||||
was created.
|
order the Valve object was created.
|
||||||
|
:param Kv:
|
||||||
Kv - the constant in the mass flow rate equation.
|
the constant in the mass flow rate equation.
|
||||||
|
:param verbose:
|
||||||
verbose - if set to a positive integer, additional diagnostic
|
if set to a positive integer, additional diagnostic information
|
||||||
information will be printed.
|
will be printed.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
global _valvecount
|
global _valvecount
|
||||||
if name == '':
|
if name == '':
|
||||||
|
|
@ -712,7 +725,7 @@ class Valve(FlowDevice):
|
||||||
|
|
||||||
|
|
||||||
def setValveCoeff(self, Kv = -1.0):
|
def setValveCoeff(self, Kv = -1.0):
|
||||||
"""Set or reset the valve coefficient \f$ K_v \f$."""
|
"""Set or reset the valve coefficient :math:`K_v`."""
|
||||||
vv = zeros(1,'d')
|
vv = zeros(1,'d')
|
||||||
vv[0] = Kv
|
vv[0] = Kv
|
||||||
if self._verbose:
|
if self._verbose:
|
||||||
|
|
@ -729,11 +742,12 @@ class Valve(FlowDevice):
|
||||||
raise CanteraError("Wrong type for valve characteristic function.")
|
raise CanteraError("Wrong type for valve characteristic function.")
|
||||||
|
|
||||||
def set(self, Kv = -1.0, F = None):
|
def set(self, Kv = -1.0, F = None):
|
||||||
"""Set or reset valve properties. All keywords are optional.
|
r"""Set or reset valve properties. All keywords are optional.
|
||||||
|
|
||||||
Kv - constant in linear mass flow rate equation.
|
:param Kv:
|
||||||
|
constant in linear mass flow rate equation.
|
||||||
F - function of \f$\Delta P\f$.
|
:param F:
|
||||||
|
function of :math:`\Delta P`.
|
||||||
"""
|
"""
|
||||||
if F:
|
if F:
|
||||||
self.setFunction(F)
|
self.setFunction(F)
|
||||||
|
|
@ -745,36 +759,35 @@ class Valve(FlowDevice):
|
||||||
_pccount = 0
|
_pccount = 0
|
||||||
|
|
||||||
class PressureController(FlowDevice):
|
class PressureController(FlowDevice):
|
||||||
|
r"""
|
||||||
|
A PressureController is designed to be used in conjunction with another
|
||||||
|
'master' flow controller, typically a :class:`.MassFlowController`. The
|
||||||
|
master flow controller is installed on the inlet of the reactor, and the
|
||||||
|
corresponding :class:`.PressureController` is installed on on outlet of the
|
||||||
|
reactor. The :class:`.PressureController` mass flow rate is equal to the
|
||||||
|
master mass flow rate, plus a small correction dependent on the pressure
|
||||||
|
difference:
|
||||||
|
|
||||||
""" A PressureController is designed to be used in conjunction
|
.. math:: \dot m = \dot m_{\rm master} + K_v(P_1 - P_2).
|
||||||
with another 'master' flow controller, typically a
|
|
||||||
MassFlowController. The master flow controller is installed on the
|
|
||||||
inlet of the reactor, and the corresponding PressureController is
|
|
||||||
installed on on outlet of the reactor. The PressureController mass
|
|
||||||
flow rate is equal to the master mass flow rate, plus a
|
|
||||||
small correction dependent on the pressure difference:
|
|
||||||
\f[
|
|
||||||
\dot m = \dot m_{\rm master} + K_v(P_1 - P_2).
|
|
||||||
\f]
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, upstream=None, downstream=None,
|
def __init__(self, upstream=None, downstream=None,
|
||||||
name='', master = None, Kv = 0.0, verbose=0):
|
name='', master = None, Kv = 0.0, verbose=0):
|
||||||
"""
|
"""
|
||||||
upstream - upstream reactor or reservoir.
|
:param upstream:
|
||||||
|
upstream reactor or reservoir.
|
||||||
downstream - downstream reactor or reservoir.
|
:param downstream:
|
||||||
|
downstream reactor or reservoir.
|
||||||
name - name used to identify the pressure controller in
|
:param name:
|
||||||
output. If no name is specified, it defaults to
|
name used to identify the pressure controller in output. If no
|
||||||
'PressureController_n', where n is an integer assigned in the
|
name is specified, it defaults to ``PressureController_n``, where
|
||||||
order the PressureController object was created.
|
n is an integer assigned in the order the PressureController
|
||||||
|
object was created.
|
||||||
Kv - the constant in the mass flow rate equation.
|
:param Kv:
|
||||||
|
the constant in the mass flow rate equation.
|
||||||
verbose - if set to a positive integer, additional diagnostic
|
:param verbose:
|
||||||
information will be printed.
|
if set to a positive integer, additional diagnostic information
|
||||||
|
will be printed.
|
||||||
"""
|
"""
|
||||||
global _pccount
|
global _pccount
|
||||||
if name == '':
|
if name == '':
|
||||||
|
|
@ -788,7 +801,7 @@ class PressureController(FlowDevice):
|
||||||
|
|
||||||
|
|
||||||
def setPressureCoeff(self, Kv):
|
def setPressureCoeff(self, Kv):
|
||||||
"""Set or reset the pressure coefficient \f$ K_v \f$."""
|
"""Set or reset the pressure coefficient :math:`K_v`."""
|
||||||
vv = zeros(1,'d')
|
vv = zeros(1,'d')
|
||||||
vv[0] = Kv
|
vv[0] = Kv
|
||||||
if self._verbose:
|
if self._verbose:
|
||||||
|
|
@ -814,44 +827,40 @@ class PressureController(FlowDevice):
|
||||||
_wallcount = 0
|
_wallcount = 0
|
||||||
|
|
||||||
class Wall:
|
class Wall:
|
||||||
"""
|
r"""
|
||||||
Reactor walls.
|
Reactor walls.
|
||||||
|
|
||||||
A Wall separates two reactors, or a reactor and a reservoir. A
|
A Wall separates two reactors, or a reactor and a reservoir. A wall has a
|
||||||
wall has a finite area, may conduct or radiate heat between the
|
finite area, may conduct or radiate heat between the two reactors on either
|
||||||
two reactors on either side, and may move like a piston.
|
side, and may move like a piston.
|
||||||
|
|
||||||
Walls are stateless objects in Cantera, meaning that no
|
Walls are stateless objects in Cantera, meaning that no differential
|
||||||
differential equation is integrated to determine any wall
|
equation is integrated to determine any wall property. Since it is the wall
|
||||||
property. Since it is the wall (piston) velocity that enters the
|
(piston) velocity that enters the energy equation, this means that it is
|
||||||
energy equation, this means that it is the velocity, not the
|
the velocity, not the acceleration or displacement, that is specified.
|
||||||
acceleration or displacement, that is specified. The wall
|
The wall velocity is computed from
|
||||||
velocity is computed from
|
|
||||||
\f[
|
.. math:: v = K(P_{\rm left} - P_{\rm right}) + v_0(t),
|
||||||
v = K(P_{\\rm left} - P_{\\rm right}) + v_0(t),
|
|
||||||
\f]
|
where :math:`K` is a non-negative constant, and :math:`v_0(t)` is a
|
||||||
where $K$ is a non-negative constant, and \f$v_0(t)$ is a
|
|
||||||
specified function of time. The velocity is positive if the wall is
|
specified function of time. The velocity is positive if the wall is
|
||||||
moving to the right.
|
moving to the right.
|
||||||
|
|
||||||
The heat flux through the wall is computed from
|
The heat flux through the wall is computed from
|
||||||
\f[
|
|
||||||
q = U(T_{\\rm left} - T_{\\rm right}) + \epsilon\sigma (T_{\\rm left}^4
|
|
||||||
- T_{\\rm right}^4) + q_0(t),
|
|
||||||
\f]
|
|
||||||
where \f$ U \f$ is the overall heat transfer coefficient for
|
|
||||||
conduction/convection, and \f$ \\epsilon \f$ is the emissivity.
|
|
||||||
The function \f$ q_0(t)$ is a specified function of time.
|
|
||||||
The heat flux is positive when heat flows from the reactor on the left
|
|
||||||
to the reactor on the right.
|
|
||||||
|
|
||||||
A heterogeneous reaction mechanism may be specified for one or
|
.. math:: q = U(T_{\rm left} - T_{\rm right}) + \epsilon\sigma (T_{\rm left}^4 - T_{\rm right}^4) + q_0(t),
|
||||||
both of the wall surfaces. The mechanism object (typically an
|
|
||||||
instance of class Interface) must be constructed so that it is
|
where :math:`U` is the overall heat transfer coefficient for
|
||||||
properly linked to the object representing the fluid in the
|
conduction/convection, and :math:`\epsilon` is the emissivity. The function
|
||||||
reactor the surface in question faces. The surface temperature on
|
:math:`q_0(t)` is a specified function of time. The heat flux is positive
|
||||||
each side is taken to be equal to the temperature of the reactor
|
when heat flows from the reactor on the left to the reactor on the right.
|
||||||
it faces.
|
|
||||||
|
A heterogeneous reaction mechanism may be specified for one or both of the
|
||||||
|
wall surfaces. The mechanism object (typically an instance of class
|
||||||
|
:class:`.Interface`) must be constructed so that it is properly linked to
|
||||||
|
the object representing the fluid in the 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 = '',
|
def __init__(self, left, right, name = '',
|
||||||
|
|
@ -859,35 +868,32 @@ class Wall:
|
||||||
Q = None, velocity = None,
|
Q = None, velocity = None,
|
||||||
kinetics = [None, None]):
|
kinetics = [None, None]):
|
||||||
"""
|
"""
|
||||||
Constructor arguments:
|
:param left:
|
||||||
|
Reactor or reservoir on the left. Required.
|
||||||
left - Reactor or reservoir on the left. Required.
|
:param right:
|
||||||
|
Reactor or reservoir on the right. Required.
|
||||||
right - Reactor or reservoir on the right. Required.
|
:param name:
|
||||||
|
Name string. If omitted, the name is ``'Wall_n'``, where ``'n'``
|
||||||
name - Name string.
|
is an integer assigned in the order walls are created.
|
||||||
If omitted, the name is 'Wall_n', where 'n' is an integer
|
:param A:
|
||||||
assigned in the order walls are created.
|
Wall area [m^2]. Defaults to 1.0 m^2.
|
||||||
|
:param K:
|
||||||
A - Wall area [m^2]. Defaults to 1.0 m^2.
|
Wall expansion rate parameter [m/s/Pa]. Defaults to 0.0.
|
||||||
|
:param U:
|
||||||
K - Wall expansion rate parameter [m/s/Pa]. Defaults to 0.0.
|
Overall heat transfer coefficient [W/m^2]. Defaults to 0.0
|
||||||
|
(adiabbatic wall).
|
||||||
U - Overall heat transfer coefficient [W/m^2]. Defaults to 0.0
|
:param Q:
|
||||||
(adiabbatic wall).
|
Heat flux function :math:`q_0(t)` [W/m^2]. Optional. Default:
|
||||||
|
:math:`q_0(t) = 0.0`.
|
||||||
Q - Heat flux function \f$ q_0(t) \f$ [W/m^2]. Optional. Default:
|
:param velocity:
|
||||||
\f$ q_0(t) = 0.0 \f$.
|
Wall velocity function :math:`v_0(t)` [m/s].
|
||||||
|
Default: :math:`v_0(t) = 0.0`.
|
||||||
velocity - Wall velocity function \f$ v_0(t) \f$ [m/s].
|
:param kinetics:
|
||||||
Default: \f$ v_0(t) = 0.0 \f$.
|
Surface reaction mechanisms for the left-facing and right-facing
|
||||||
|
surface, respectively. These must be instances of class Kinetics,
|
||||||
kinetics - Surface reaction mechanisms for the left-facing and
|
or of a class derived from Kinetics, such as Interface. If
|
||||||
right-facing surface, respectively. These must be instances of
|
chemistry occurs on only one side, enter ``None`` for the
|
||||||
class Kinetics, or of a class derived from Kinetics, such as
|
non-reactive side.
|
||||||
Interface. If chemistry occurs on only one side, enter 'None'
|
|
||||||
for the non-reactive side.
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
typ = 0
|
typ = 0
|
||||||
self.__wall_id = _cantera.wall_new(typ)
|
self.__wall_id = _cantera.wall_new(typ)
|
||||||
|
|
@ -916,7 +922,7 @@ class Wall:
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
""" Delete the Wall instance. This method is called
|
""" Delete the Wall instance. This method is called
|
||||||
automatically when no Python object stores a reference to this
|
automatically when no Python object stores a reference to this
|
||||||
Wall. Since reactors and reserviors store references to all
|
Wall. Since reactors and reservoirs store references to all
|
||||||
Walls installed on them, this method will only be called after
|
Walls installed on them, this method will only be called after
|
||||||
the reactors/reservoirs have been deleted. """
|
the reactors/reservoirs have been deleted. """
|
||||||
|
|
||||||
|
|
@ -936,7 +942,8 @@ class Wall:
|
||||||
|
|
||||||
def setArea(self, a):
|
def setArea(self, a):
|
||||||
"""
|
"""
|
||||||
Set the area (m^2). The wall area may be changed manually at any time during a simulation.
|
Set the area (m^2). The wall area may be changed manually at any time
|
||||||
|
during a simulation.
|
||||||
"""
|
"""
|
||||||
_cantera.wall_setArea(self.__wall_id, a)
|
_cantera.wall_setArea(self.__wall_id, a)
|
||||||
|
|
||||||
|
|
@ -960,8 +967,7 @@ class Wall:
|
||||||
def setHeatFlux(self, qfunc):
|
def setHeatFlux(self, qfunc):
|
||||||
"""
|
"""
|
||||||
Specify the time-dependent heat flux function [W/m2].
|
Specify the time-dependent heat flux function [W/m2].
|
||||||
'qfunc' must be a functor (an instance of a subclass of Cantera.Func1).
|
*qfunc* must be a functor (an instance of :class:`.Func1`).
|
||||||
See: Func1.
|
|
||||||
"""
|
"""
|
||||||
n = 0
|
n = 0
|
||||||
if qfunc: n = qfunc.func_id()
|
if qfunc: n = qfunc.func_id()
|
||||||
|
|
@ -974,9 +980,8 @@ class Wall:
|
||||||
|
|
||||||
def setVelocity(self, vfunc):
|
def setVelocity(self, vfunc):
|
||||||
"""
|
"""
|
||||||
Specify the velocity function [m/s]. 'vfunc' must
|
Specify the velocity function [m/s]. *vfunc* must
|
||||||
be a functor (an instance of a subclass of Cantera.Func1)
|
be a functor (an instance of :class:`.Func1`)
|
||||||
See: Func1.
|
|
||||||
"""
|
"""
|
||||||
n = 0
|
n = 0
|
||||||
if vfunc: n = vfunc.func_id()
|
if vfunc: n = vfunc.func_id()
|
||||||
|
|
@ -1027,7 +1032,7 @@ class Wall:
|
||||||
raise CanteraError("side must be 'left' or 'right'")
|
raise CanteraError("side must be 'left' or 'right'")
|
||||||
|
|
||||||
def set(self, **p):
|
def set(self, **p):
|
||||||
"""Set various wall parameters: 'A', 'U', 'K', 'Q'. 'velocity'.
|
"""Set various wall parameters: *A*, *U*, *K*, *Q*, *velocity*.
|
||||||
These have the same meanings as in the constructor.
|
These have the same meanings as in the constructor.
|
||||||
"""
|
"""
|
||||||
for item in p.keys():
|
for item in p.keys():
|
||||||
|
|
@ -1063,7 +1068,6 @@ class Wall:
|
||||||
|
|
||||||
|
|
||||||
class ReactorNet:
|
class ReactorNet:
|
||||||
|
|
||||||
"""Networks of reactors. ReactorNet objects are used to
|
"""Networks of reactors. ReactorNet objects are used to
|
||||||
simultaneously advance the state of a set of coupled reactors.
|
simultaneously advance the state of a set of coupled reactors.
|
||||||
|
|
||||||
|
|
@ -1075,10 +1079,7 @@ class ReactorNet:
|
||||||
|
|
||||||
>>> reactor_network = ReactorNet([r1, r2])
|
>>> reactor_network = ReactorNet([r1, r2])
|
||||||
>>> reactor_network.advance(time)
|
>>> reactor_network.advance(time)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, reactorlist = None):
|
def __init__(self, reactorlist = None):
|
||||||
"""
|
"""
|
||||||
Create a new ReactorNet instance. If a list of reactors is supplied,
|
Create a new ReactorNet instance. If a list of reactors is supplied,
|
||||||
|
|
@ -1134,7 +1135,7 @@ class ReactorNet:
|
||||||
return _cantera.reactornet_advance(self.__reactornet_id, time)
|
return _cantera.reactornet_advance(self.__reactornet_id, time)
|
||||||
|
|
||||||
def step(self, time):
|
def step(self, time):
|
||||||
"""Take a single internal time step toward time 'time'.
|
"""Take a single internal time step toward time *time*.
|
||||||
The time after taking the step is returned."""
|
The time after taking the step is returned."""
|
||||||
return _cantera.reactornet_step(self.__reactornet_id, time)
|
return _cantera.reactornet_step(self.__reactornet_id, time)
|
||||||
|
|
||||||
|
|
@ -1151,22 +1152,20 @@ class ReactorNet:
|
||||||
|
|
||||||
def sensitivity(self, component = '', parameter = -1, reactor = ''):
|
def sensitivity(self, component = '', parameter = -1, reactor = ''):
|
||||||
|
|
||||||
"""Sensitivity of solution component 'component' with respect
|
"""Sensitivity of solution component *component* with respect
|
||||||
to one or more parameters.
|
to one or more parameters.
|
||||||
|
|
||||||
component -- name of the species or other variable for which
|
:param component:
|
||||||
sensitivity information is desired.
|
name of the species or other variable for which sensitivity
|
||||||
|
information is desired.
|
||||||
parameter -- single integer or sequence of integers specifying
|
:param parameter:
|
||||||
the parameters. The parameters are numbered from zero,
|
single integer or sequence of integers specifying the parameters.
|
||||||
beginning with the parameters for the first reactor and
|
The parameters are numbered from zero, beginning with the parameters
|
||||||
continuing through those for the last reactor in the
|
for the first reactor and continuing through those for the last
|
||||||
network. If omitted, the sensitivity with respect to all
|
reactor in the network. If omitted, the sensitivity with respect
|
||||||
parameters will be returned.
|
to all parameters will be returned.
|
||||||
|
:param reactor:
|
||||||
reactor -- reactor containing the desired component.
|
reactor containing the desired component.
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
n = 0
|
n = 0
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class SurfacePhase(ThermoPhase):
|
||||||
return _cantera.surf_sitedensity(self._phase_id)
|
return _cantera.surf_sitedensity(self._phase_id)
|
||||||
|
|
||||||
def setCoverages(self, theta):
|
def setCoverages(self, theta):
|
||||||
"""Set the surface coverages to the values in array 'theta'."""
|
"""Set the surface coverages to the values in array *theta*."""
|
||||||
nt = len(theta)
|
nt = len(theta)
|
||||||
if nt == self.nSpecies():
|
if nt == self.nSpecies():
|
||||||
_cantera.surf_setcoverages(self._phase_id,
|
_cantera.surf_setcoverages(self._phase_id,
|
||||||
|
|
@ -34,7 +34,7 @@ class SurfacePhase(ThermoPhase):
|
||||||
|
|
||||||
def setConcentrations(self, conc):
|
def setConcentrations(self, conc):
|
||||||
"""Set the surface concentrations to the values in
|
"""Set the surface concentrations to the values in
|
||||||
array 'conc'."""
|
array *conc*."""
|
||||||
_cantera.surf_setconcentrations(self._phase_id, conc)
|
_cantera.surf_setconcentrations(self._phase_id, conc)
|
||||||
|
|
||||||
def concentrations(self):
|
def concentrations(self):
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,8 @@ class ThermoPhase(Phase):
|
||||||
providing methods that require knowledge of the equation of state.
|
providing methods that require knowledge of the equation of state.
|
||||||
|
|
||||||
Class ThermoPhase is not usually instantiated directly. It is used
|
Class ThermoPhase is not usually instantiated directly. It is used
|
||||||
as base class for classes Solution and Interface.
|
as base class for classes :class:`~Cantera.Solution` and
|
||||||
|
:class:`~Cantera.Interface.Interface`.
|
||||||
@see Solution, Interface
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# used in the 'equilibrate' method
|
# used in the 'equilibrate' method
|
||||||
|
|
@ -30,12 +29,13 @@ class ThermoPhase(Phase):
|
||||||
|
|
||||||
def __init__(self, xml_phase=None, index=-1):
|
def __init__(self, xml_phase=None, index=-1):
|
||||||
"""
|
"""
|
||||||
xml_phase - CTML node specifying the attributes of this phase
|
:param xml_phase:
|
||||||
|
CTML node specifying the attributes of this phase
|
||||||
index - optional. If positive, create only a Python wrapper for
|
:param index:
|
||||||
an existing kernel object, instead of creating a new kernel object.
|
optional. If positive, create only a Python wrapper for an existing
|
||||||
The value of 'index' is the integer index number to reference the
|
kernel object, instead of creating a new kernel object. The value
|
||||||
existing kernel object.
|
of *index* is the integer index number to reference the existing
|
||||||
|
kernel object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self._phase_id = 0
|
self._phase_id = 0
|
||||||
|
|
@ -43,8 +43,8 @@ class ThermoPhase(Phase):
|
||||||
self.idtag = ""
|
self.idtag = ""
|
||||||
|
|
||||||
if index >= 0:
|
if index >= 0:
|
||||||
# create a Python wrapper for an existing kernel
|
# create a Python wrapper for an existing kernel
|
||||||
# ThermoPhase instance
|
# ThermoPhase instance
|
||||||
self._phase_id = index
|
self._phase_id = index
|
||||||
|
|
||||||
elif xml_phase:
|
elif xml_phase:
|
||||||
|
|
@ -280,36 +280,38 @@ class ThermoPhase(Phase):
|
||||||
|
|
||||||
def equilibrate(self, XY, solver = -1, rtol = 1.0e-9,
|
def equilibrate(self, XY, solver = -1, rtol = 1.0e-9,
|
||||||
maxsteps = 1000, maxiter = 100, loglevel = 0):
|
maxsteps = 1000, maxiter = 100, loglevel = 0):
|
||||||
""" Set to a state of chemical equilibrium holding property pair
|
"""
|
||||||
'XY' constant.
|
Set to a state of chemical equilibrium holding property pair
|
||||||
|
*XY* constant.
|
||||||
|
|
||||||
|
:param XY:
|
||||||
|
A two-letter string, which must be one of the set::
|
||||||
|
|
||||||
|
['TP','TV','HP','SP','SV','UV','PT','VT','PH','PS','VS','VU']
|
||||||
|
|
||||||
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
|
If H, U, S, or V is specified, the value must be the specific
|
||||||
value (per unit mass)
|
value (per unit mass)
|
||||||
|
:param solver:
|
||||||
solver --- Specifies the equilibrium solver to use. If solver =
|
Specifies the equilibrium solver to use. If solver = 0, a fast
|
||||||
0, a fast solver using the element potential method will be
|
solver using the element potential method will be used. If
|
||||||
used. If solver > 0, a slower but more robust Gibbs
|
solver > 0, a slower but more robust Gibbs minimization solver
|
||||||
minimization solver will be used. If solver < 0 or
|
will be used. If solver < 0 or unspecified, the fast solver will
|
||||||
unspecified, the fast solver will be tried first, then if it
|
be tried first, then if it fails the other will be tried.
|
||||||
fails the other will be tried.
|
:param rtol:
|
||||||
|
the relative error tolerance.
|
||||||
rtol -- the relative error tolerance.
|
:param maxsteps:
|
||||||
|
maximum number of steps in composition to take to find a converged
|
||||||
maxsteps -- maximum number of steps in composition to take to
|
solution.
|
||||||
find a converged solution.
|
:param maxiter:
|
||||||
|
For the Gibbs minimization solver only, this specifies the number
|
||||||
maxiter -- for the Gibbs minimization solver only, this
|
of 'outer' iterations on T or P when some property pair other than
|
||||||
specifies the number of 'outer' iterations on T or P when some
|
TP is specified.
|
||||||
property pair other than TP is specified.
|
:param loglevel:
|
||||||
|
Set to a value > 0 to write diagnostic output to a file in HTML
|
||||||
loglevel -- set to a value > 0 to write diagnostic output to a
|
format. Larger values generate more detailed information. The file
|
||||||
file in HTML format. Larger values generate more detailed
|
will be named ``equilibrate_log.html.`` Subsequent files will be
|
||||||
information. The file will be named 'equilibrate_log.html.'
|
named ``equilibrate_log1.html``, etc., so that log files are
|
||||||
Subsequent files will be named 'equillibrate_log1.html', etc.,
|
not overwritten.
|
||||||
so that log files are not overwritten.
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
_cantera.thermo_equil(self._phase_id, XY, solver,
|
_cantera.thermo_equil(self._phase_id, XY, solver,
|
||||||
rtol, maxsteps, maxiter, loglevel)
|
rtol, maxsteps, maxiter, loglevel)
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ from Cantera.num import asarray
|
||||||
import exceptions
|
import exceptions
|
||||||
|
|
||||||
class Transport:
|
class Transport:
|
||||||
|
|
||||||
"""Transport properties.
|
"""Transport properties.
|
||||||
|
|
||||||
This class provides the Python interface to the family of
|
This class provides the Python interface to the family of
|
||||||
|
|
@ -34,8 +33,8 @@ class Transport:
|
||||||
|
|
||||||
In the C++ kernel, a transport manager implements a single
|
In the C++ kernel, a transport manager implements a single
|
||||||
transport model, and is an instance of a subclass of the base
|
transport model, and is an instance of a subclass of the base
|
||||||
class 'Transport'. The structure in Python is a little
|
class ``Transport``. The structure in Python is a little
|
||||||
different. A single class 'Transport' represents any kernel-level
|
different. A single class ``Transport`` represents any kernel-level
|
||||||
transport manager. In addition, multiple kernel-kevel transport
|
transport manager. In addition, multiple kernel-kevel transport
|
||||||
managers may be installed in one Python transport manager,
|
managers may be installed in one Python transport manager,
|
||||||
although only one is active at any one time. This feature allows
|
although only one is active at any one time. This feature allows
|
||||||
|
|
@ -45,13 +44,16 @@ class Transport:
|
||||||
phase=None, model = "", loglevel=0):
|
phase=None, model = "", loglevel=0):
|
||||||
"""Create a transport property manager.
|
"""Create a transport property manager.
|
||||||
|
|
||||||
xml_phase --- XML phase element
|
:param xml_phase:
|
||||||
phase --- ThermoPhase instance representing the phase that the
|
XML phase element
|
||||||
transport properties are for
|
:param phase:
|
||||||
model --- string specifying transport model. If omitted or
|
:class:`.ThermoPhase` instance representing the phase that the
|
||||||
set to 'Default', the model will be read from the
|
transport properties are for
|
||||||
input file.
|
:param model:
|
||||||
loglevel --- controls the amount of diagnostic output
|
String specifying transport model. If omitted or set to ``Default``,
|
||||||
|
the model will be read from the input file.
|
||||||
|
:param loglevel:
|
||||||
|
controls the amount of diagnostic output
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# if the transport model is not specified, look for attribute
|
# if the transport model is not specified, look for attribute
|
||||||
|
|
@ -84,7 +86,7 @@ class Transport:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def addTransportModel(self, model, loglevel=1):
|
def addTransportModel(self, model, loglevel=1):
|
||||||
"""Add a new transport model. Note that if 'model' is the
|
"""Add a new transport model. Note that if *model* is the
|
||||||
name of an already-installed transport model, the new
|
name of an already-installed transport model, the new
|
||||||
transport manager will take the place of the old one, which
|
transport manager will take the place of the old one, which
|
||||||
will no longer be accessible. This method does not change the
|
will no longer be accessible. This method does not change the
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ if not os.getenv('PYTHON_CMD'):
|
||||||
|
|
||||||
def writeCSV(f, list):
|
def writeCSV(f, list):
|
||||||
"""
|
"""
|
||||||
Write list items to file 'f' in
|
Write list items to file *f* in
|
||||||
comma-separated-value format. Strings will be written as-is, and
|
comma-separated-value format. Strings will be written as-is, and
|
||||||
other types of objects will be converted to strings and then
|
other types of objects will be converted to strings and then
|
||||||
written. Each call to writeCSV writes one line of the file.
|
written. Each call to writeCSV writes one line of the file.
|
||||||
|
|
|
||||||
|
|
@ -7,43 +7,43 @@ the Cantera kernel.
|
||||||
|
|
||||||
import math
|
import math
|
||||||
|
|
||||||
## One atmosphere in Pascals
|
#: One atmosphere in Pascals
|
||||||
OneAtm = 101325.0
|
OneAtm = 101325.0
|
||||||
|
|
||||||
## The ideal gas constant in J/kmo-K
|
#: The ideal gas constant in J/kmo-K
|
||||||
GasConstant = 8314.47215
|
GasConstant = 8314.47215
|
||||||
|
|
||||||
## Avogadro's Number, /kmol
|
#: Avogadro's Number, /kmol
|
||||||
Avogadro = 6.02214179e26
|
Avogadro = 6.02214179e26
|
||||||
|
|
||||||
## The ideal gas constant in cal/mol-K
|
#: The ideal gas constant in cal/mol-K
|
||||||
GasConst_cal_mol_K = 1.987
|
GasConst_cal_mol_K = 1.987
|
||||||
|
|
||||||
## Boltzmann-s constant
|
#: Boltzmann-s constant
|
||||||
Boltzmann = GasConstant / Avogadro
|
Boltzmann = GasConstant / Avogadro
|
||||||
|
|
||||||
## The Stefan-Boltzmann constant, W/m^2K^4
|
#: The Stefan-Boltzmann constant, W/m^2K^4
|
||||||
StefanBoltz = 5.6704004e-8
|
StefanBoltz = 5.6704004e-8
|
||||||
|
|
||||||
## The charge on an electron (C)
|
#: The charge on an electron (C)
|
||||||
ElectronCharge = 1.60217648740e-19
|
ElectronCharge = 1.60217648740e-19
|
||||||
|
|
||||||
## The mass of an electron (kg)
|
#: The mass of an electron (kg)
|
||||||
ElectronMass = 9.1093821545e-31
|
ElectronMass = 9.1093821545e-31
|
||||||
|
|
||||||
Pi = 3.1415926
|
Pi = 3.1415926
|
||||||
|
|
||||||
## Faraday's constant, C/kmol
|
#: Faraday's constant, C/kmol
|
||||||
Faraday = ElectronCharge * Avogadro
|
Faraday = ElectronCharge * Avogadro
|
||||||
|
|
||||||
## Planck's constant (J/s)
|
#: Planck's constant (J/s)
|
||||||
Planck = 6.6262e-34
|
Planck = 6.6262e-34
|
||||||
|
|
||||||
## Permittivity of free space
|
#: Permittivity of free space
|
||||||
epsilon_0 = 8.85417817e-12 ## Farads/m = C^2/N/m^2
|
epsilon_0 = 8.85417817e-12 ## Farads/m = C^2/N/m^2
|
||||||
|
|
||||||
## Permeability of free space \f$ \mu_0 \f$ in N/A^2.
|
#: Permeability of free space :math:`\mu_0` in N/A^2.
|
||||||
permeability_0 = 4.0e-7*Pi; ## N/A^2
|
permeability_0 = 4.0e-7*Pi; ## N/A^2
|
||||||
|
|
||||||
## Speed of Light (m/s).
|
#: Speed of Light (m/s).
|
||||||
lightSpeed = 1.0/math.sqrt(epsilon_0 * permeability_0);
|
lightSpeed = 1.0/math.sqrt(epsilon_0 * permeability_0);
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,18 @@ from Cantera.solution import Solution
|
||||||
import os
|
import os
|
||||||
|
|
||||||
def IdealGasMix(src="", id = "", loglevel = 0):
|
def IdealGasMix(src="", id = "", loglevel = 0):
|
||||||
"""Return a Solution object representing an ideal gas mixture.
|
"""Return a :class:`.Solution` object representing an ideal gas mixture.
|
||||||
|
|
||||||
src --- input file
|
:param src:
|
||||||
id --- XML id tag for phase
|
input file
|
||||||
|
:param id:
|
||||||
|
XML id tag for phase
|
||||||
"""
|
"""
|
||||||
return Solution(src=src,id=id,loglevel=loglevel)
|
return Solution(src=src,id=id,loglevel=loglevel)
|
||||||
|
|
||||||
|
|
||||||
def GRI30(transport = ""):
|
def GRI30(transport = ""):
|
||||||
"""Return a Solution instance implementing reaction mechanism
|
"""Return a :class:`.Solution` instance implementing reaction mechanism
|
||||||
GRI-Mech 3.0."""
|
GRI-Mech 3.0."""
|
||||||
if transport == "":
|
if transport == "":
|
||||||
return Solution(src="gri30.cti", id="gri30")
|
return Solution(src="gri30.cti", id="gri30")
|
||||||
|
|
@ -34,12 +36,12 @@ def GRI30(transport = ""):
|
||||||
|
|
||||||
|
|
||||||
def Air():
|
def Air():
|
||||||
"""Return a Solution instance implementing the O/N/Ar portion of
|
"""Return a :class:`.Solution` instance implementing the O/N/Ar portion of
|
||||||
reaction mechanism GRI-Mech 3.0. The initial composition is set to
|
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")
|
return Solution(src="air.cti", id="air")
|
||||||
|
|
||||||
|
|
||||||
def Argon():
|
def Argon():
|
||||||
"""Return a Solution instance representing pure argon."""
|
"""Return a :class:`.Solution` instance representing pure argon."""
|
||||||
return Solution(src="argon.cti", id="argon")
|
return Solution(src="argon.cti", id="argon")
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ def importInterface(file, name = '', phases = []):
|
||||||
The 'phases' argument is a list of objects representing the other phases
|
The 'phases' argument is a list of objects representing the other phases
|
||||||
that participate in the interfacial reactions, for example an object
|
that participate in the interfacial reactions, for example an object
|
||||||
representing a gas phase or a solid.
|
representing a gas phase or a solid.
|
||||||
|
|
||||||
>>> gas1, cryst1 = importPhases('diamond.cti', ['gas', 'solid'])
|
>>> gas1, cryst1 = importPhases('diamond.cti', ['gas', 'solid'])
|
||||||
>>> diamond_surf = importInterface('diamond.cti', [gas1, cryst1])
|
>>> diamond_surf = importInterface('diamond.cti', [gas1, cryst1])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ class Mixture:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, phases=[]):
|
def __init__(self, phases=[]):
|
||||||
""" init """
|
|
||||||
self.__mixid = _cantera.mix_new()
|
self.__mixid = _cantera.mix_new()
|
||||||
self._spnames = []
|
self._spnames = []
|
||||||
self._phases = []
|
self._phases = []
|
||||||
|
|
@ -89,7 +88,7 @@ class Mixture:
|
||||||
return self._phases[n]
|
return self._phases[n]
|
||||||
|
|
||||||
def phaseName(self, n):
|
def phaseName(self, n):
|
||||||
"""Name of phase n."""
|
"""Name of phase *n*."""
|
||||||
return self._phases[n].name()
|
return self._phases[n].name()
|
||||||
|
|
||||||
def phaseNames(self):
|
def phaseNames(self):
|
||||||
|
|
@ -101,7 +100,7 @@ class Mixture:
|
||||||
return nm
|
return nm
|
||||||
|
|
||||||
def phaseIndex(self, phase):
|
def phaseIndex(self, phase):
|
||||||
"""Index of phase with name 'phase'"""
|
"""Index of phase with name *phase*"""
|
||||||
np = self.nPhases()
|
np = self.nPhases()
|
||||||
if type(phase) <> types.StringType:
|
if type(phase) <> types.StringType:
|
||||||
return phase
|
return phase
|
||||||
|
|
@ -116,9 +115,9 @@ class Mixture:
|
||||||
|
|
||||||
def elementIndex(self, element):
|
def elementIndex(self, element):
|
||||||
"""Index of element with name 'element'.
|
"""Index of element with name 'element'.
|
||||||
|
|
||||||
>>> mix.elementIndex('H')
|
>>> mix.elementIndex('H')
|
||||||
2
|
2
|
||||||
>>>
|
|
||||||
"""
|
"""
|
||||||
if type(element) == types.StringType:
|
if type(element) == types.StringType:
|
||||||
return _cantera.mix_elementIndex(self.__mixid, element)
|
return _cantera.mix_elementIndex(self.__mixid, element)
|
||||||
|
|
@ -131,7 +130,7 @@ class Mixture:
|
||||||
return _cantera.mix_nSpecies(self.__mixid)
|
return _cantera.mix_nSpecies(self.__mixid)
|
||||||
|
|
||||||
def speciesName(self, k):
|
def speciesName(self, k):
|
||||||
"""Name of the species with index k. Note that index numbers
|
"""Name of the species with index *k*. Note that index numbers
|
||||||
are assigned in order as phases are added."""
|
are assigned in order as phases are added."""
|
||||||
return self._spnames[k]
|
return self._spnames[k]
|
||||||
|
|
||||||
|
|
@ -143,7 +142,7 @@ class Mixture:
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def speciesIndex(self, species):
|
def speciesIndex(self, species):
|
||||||
"""Index of species with name 'species'. If 'species' is not a string,
|
"""Index of species with name *species*. If *species* is not a string,
|
||||||
then it is simply returned."""
|
then it is simply returned."""
|
||||||
if type(species) == types.StringType:
|
if type(species) == types.StringType:
|
||||||
return self._spnames.index(species)
|
return self._spnames.index(species)
|
||||||
|
|
@ -151,7 +150,7 @@ class Mixture:
|
||||||
return species
|
return species
|
||||||
|
|
||||||
def nAtoms(self, k, m):
|
def nAtoms(self, k, m):
|
||||||
"""Number of atoms of element m in species k. Both the species and
|
"""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.
|
the element may be referenced either by name or by index number.
|
||||||
|
|
||||||
>>> n = mix.nAtoms('CH4','H')
|
>>> n = mix.nAtoms('CH4','H')
|
||||||
|
|
@ -188,7 +187,7 @@ class Mixture:
|
||||||
return _cantera.mix_charge(self.__mixid)
|
return _cantera.mix_charge(self.__mixid)
|
||||||
|
|
||||||
def phaseCharge(self, p):
|
def phaseCharge(self, p):
|
||||||
"""The charge of phase p (Coulombs)."""
|
"""The charge of phase *p* (Coulombs)."""
|
||||||
return _cantera.mix_phaseCharge(self.__mixid, p)
|
return _cantera.mix_phaseCharge(self.__mixid, p)
|
||||||
|
|
||||||
def setPressure(self, p):
|
def setPressure(self, p):
|
||||||
|
|
@ -201,7 +200,7 @@ class Mixture:
|
||||||
return _cantera.mix_pressure(self.__mixid)
|
return _cantera.mix_pressure(self.__mixid)
|
||||||
|
|
||||||
def phaseMoles(self, n = -1):
|
def phaseMoles(self, n = -1):
|
||||||
"""Moles of phase n."""
|
"""Moles of phase *n*."""
|
||||||
if n == -1:
|
if n == -1:
|
||||||
np = self.nPhases()
|
np = self.nPhases()
|
||||||
moles = zeros(np,'d')
|
moles = zeros(np,'d')
|
||||||
|
|
@ -212,7 +211,7 @@ class Mixture:
|
||||||
return _cantera.mix_phaseMoles(self.__mixid, n)
|
return _cantera.mix_phaseMoles(self.__mixid, n)
|
||||||
|
|
||||||
def setPhaseMoles(self, n, moles):
|
def setPhaseMoles(self, n, moles):
|
||||||
"""Set the number of moles of phase n."""
|
"""Set the number of moles of phase *n*."""
|
||||||
_cantera.mix_setPhaseMoles(self.__mixid, n, moles)
|
_cantera.mix_setPhaseMoles(self.__mixid, n, moles)
|
||||||
|
|
||||||
def setSpeciesMoles(self, moles):
|
def setSpeciesMoles(self, moles):
|
||||||
|
|
@ -238,7 +237,7 @@ class Mixture:
|
||||||
return self.selectSpecies(moles, species)
|
return self.selectSpecies(moles, species)
|
||||||
|
|
||||||
def elementMoles(self, m):
|
def elementMoles(self, m):
|
||||||
"""Total number of moles of element m, summed over all species.
|
"""Total number of moles of element *m*, summed over all species.
|
||||||
The element may be referenced either by index number or by name.
|
The element may be referenced either by index number or by name.
|
||||||
"""
|
"""
|
||||||
mm = self.elementIndex(m)
|
mm = self.elementIndex(m)
|
||||||
|
|
@ -271,46 +270,45 @@ class Mixture:
|
||||||
mixture, subject to element conservation constraints. For a
|
mixture, subject to element conservation constraints. For a
|
||||||
description of the theory, see Smith and Missen, "Chemical
|
description of the theory, see Smith and Missen, "Chemical
|
||||||
Reaction Equilibrium." The VCS algorithm is implemented in
|
Reaction Equilibrium." The VCS algorithm is implemented in
|
||||||
Cantera kernel class MultiPhaseEquil.
|
Cantera kernel class ``MultiPhaseEquil``.
|
||||||
|
|
||||||
The VCS algorithm solves for the equilibrium composition for
|
The VCS algorithm solves for the equilibrium composition for
|
||||||
specified temperature and pressure. If any other property pair
|
specified temperature and pressure. If any other property pair
|
||||||
other than "TP" is specified, then an outer iteration loop is
|
other than ``TP`` is specified, then an outer iteration loop is
|
||||||
used to adjust T and/or P so that the specified property
|
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.
|
:param XY:
|
||||||
Currently, 'TP', 'HP', and 'SP' are implemented. Default: 'TP'.
|
Two-letter string specifying the two properties to hold fixed.
|
||||||
|
Currently, ``'TP'``, ``'HP'``, and ``'SP'`` are implemented.
|
||||||
err - Error tolerance. Iteration will continue until (Delta
|
Default: ``'TP'``.
|
||||||
mu)/RT is less than this value for each reaction. Default:
|
:param err:
|
||||||
1.0e-9. Note that this default is very conservative, and good
|
Error tolerance. Iteration will continue until (Delta mu)/RT is
|
||||||
equilibrium solutions may be obtained with larger error
|
less than this value for each reaction. Default: 1.0e-9. Note that
|
||||||
tolerances.
|
this default is very conservative, and good equilibrium solutions
|
||||||
|
may be obtained with larger error tolerances.
|
||||||
maxsteps - Maximum number of steps to take while solving the
|
:param maxsteps:
|
||||||
equilibrium problem for specified T and P. Default: 1000.
|
Maximum number of steps to take while solving the equilibrium
|
||||||
|
problem for specified *T* and *P*. Default: 1000.
|
||||||
maxiter - Maximum number of temperature and/or pressure iterations.
|
:param maxiter:
|
||||||
This is only relevant if a property pair other than (T,P) is
|
Maximum number of temperature and/or pressure iterations.
|
||||||
specified. Default: 200.
|
This is only relevant if a property pair other than (T,P) is
|
||||||
|
specified. Default: 200.
|
||||||
loglevel - Controls the amount of diagnostic output. If
|
:param loglevel:
|
||||||
loglevel = 0, no diagnostic output is written. For values > 0,
|
Controls the amount of diagnostic output. If loglevel = 0, no
|
||||||
more detailed information is written to the log file as
|
diagnostic output is written. For values > 0, more detailed
|
||||||
loglevel increases. The default is loglevel = 0.
|
information is written to the log file as loglevel increases.
|
||||||
|
The default is loglevel = 0.
|
||||||
The logfile is written in HTML format, and may be viewed with
|
The logfile is written in HTML format, and may be viewed with
|
||||||
any web browser. The default log file name is
|
any web browser. The default log file name is
|
||||||
"equilibrium_log.html", but if this file exists, the log
|
``equilibrium_log.html``, but if this file exists, the log
|
||||||
information will be written to "equilibrium_log{n}.html",
|
information will be written to "equilibrium_log{n}.html", where
|
||||||
where {n} is an integer chosen so that the log file does not
|
{n} is an integer chosen so that the log file does not already
|
||||||
already exist. Therefore, if 'equilibrate' is called multiple
|
exist. Therefore, if 'equilibrate' is called multiple times,
|
||||||
times, multiple log files will be written, with names
|
multiple log files will be written, with names
|
||||||
"equilibrate_log.html", "equilibrate_log1.html",
|
``equilibrate_log.html``, ``equilibrate_log1.html``,
|
||||||
"equilibrate_log2.html", and so on. Existing log files will
|
``equilibrate_log2.html``, and so on. Existing log files will
|
||||||
not be overwritten.
|
not be overwritten.
|
||||||
|
|
||||||
|
|
||||||
>>> mix.equilibrate('TP')
|
>>> mix.equilibrate('TP')
|
||||||
>>> mix.equilibrate('TP', err = 1.0e-6, maxiter = 500)
|
>>> mix.equilibrate('TP', err = 1.0e-6, maxiter = 500)
|
||||||
|
|
@ -333,62 +331,62 @@ class Mixture:
|
||||||
|
|
||||||
The VCS algorithm solves for the equilibrium composition for
|
The VCS algorithm solves for the equilibrium composition for
|
||||||
specified temperature and pressure. If any other property pair
|
specified temperature and pressure. If any other property pair
|
||||||
other than "TP" is specified, then an outer iteration loop is
|
other than ``'TP'`` is specified, then an outer iteration loop is
|
||||||
used to adjust T and/or P so that the specified property
|
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.
|
:param XY:
|
||||||
Currently, 'TP', 'HP', and 'SP' are implemented. Default: 'TP'.
|
Two-letter string specifying the two properties to hold fixed.
|
||||||
|
Currently, ``'TP'``, ``'HP'``, and ``'SP'`` are implemented.
|
||||||
printLvl - Controls the amount of diagnostic output written to cout. If
|
Default: ``'TP'``.
|
||||||
printLvl = 0, no diagnostic output is written. For values > 0,
|
:param printLvl:
|
||||||
more detailed information is written to cout.
|
Controls the amount of diagnostic output written to cout. If
|
||||||
The default is printLvl = 0.
|
printLvl = 0, no diagnostic output is written. For values > 0,
|
||||||
|
more detailed information is written to cout.
|
||||||
solver - Determines which solver is used.
|
The default is printLvl = 0.
|
||||||
- 1 MultiPhaseEquil solver
|
:param solver:
|
||||||
- 2 VCSnonideal Solver (default)
|
Determines which solver is used.
|
||||||
|
- 1 MultiPhaseEquil solver
|
||||||
err - Error tolerance. Iteration will continue until (Delta
|
- 2 VCSnonideal Solver (default)
|
||||||
mu)/RT is less than this value for each reaction. Default:
|
:param err:
|
||||||
1.0e-9. Note that this default is very conservative, and good
|
Error tolerance. Iteration will continue until (Delta mu)/RT is
|
||||||
equilibrium solutions may be obtained with larger error
|
less than this value for each reaction. Default: 1.0e-9. Note that
|
||||||
tolerances.
|
this default is very conservative, and good equilibrium solutions
|
||||||
|
May be obtained with larger error tolerances.
|
||||||
maxsteps - Maximum number of steps to take while solving the
|
:param maxsteps:
|
||||||
equilibrium problem for specified T and P. Default: 1000.
|
Maximum number of steps to take while solving the equilibrium
|
||||||
|
problem for specified T and P. Default: 1000.
|
||||||
maxiter - Maximum number of temperature and/or pressure iterations.
|
:param maxiter:
|
||||||
This is only relevant if a property pair other than (T,P) is
|
Maximum number of temperature and/or pressure iterations. This is
|
||||||
specified. Default: 200.
|
only relevant if a property pair other than (T,P) is specified.
|
||||||
|
Default: 200.
|
||||||
loglevel - Controls the amount of diagnostic output written to html. If
|
:param loglevel:
|
||||||
loglevel = 0, no diagnostic output is written. For values > 0,
|
Controls the amount of diagnostic output written to html. If
|
||||||
more detailed information is written to the log file as
|
loglevel = 0, no diagnostic output is written. For values > 0,
|
||||||
loglevel increases. The default is loglevel = 0.
|
more detailed information is written to the log file as
|
||||||
|
loglevel increases. The default is loglevel = 0.
|
||||||
The logfile is written in HTML format, and may be viewed with
|
The logfile is written in HTML format, and may be viewed with
|
||||||
any web browser. The default log file name is
|
any web browser. The default log file name is
|
||||||
"equilibrium_log.html", but if this file exists, the log
|
"equilibrium_log.html", but if this file exists, the log
|
||||||
information will be written to "equilibrium_log{n}.html",
|
information will be written to "equilibrium_log{n}.html",
|
||||||
where {n} is an integer chosen so that the log file does not
|
where {n} is an integer chosen so that the log file does not
|
||||||
already exist. Therefore, if 'equilibrate' is called multiple
|
already exist. Therefore, if 'equilibrate' is called multiple
|
||||||
times, multiple log files will be written, with names
|
times, multiple log files will be written, with names
|
||||||
"equilibrate_log.html", "equilibrate_log1.html",
|
"equilibrate_log.html", "equilibrate_log1.html",
|
||||||
"equilibrate_log2.html", and so on. Existing log files will
|
"equilibrate_log2.html", and so on. Existing log files will
|
||||||
not be overwritten.
|
not be overwritten.
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
i = _cantera.mix_vcs_equilibrate(self.__mixid, XY, estimateEquil,
|
i = _cantera.mix_vcs_equilibrate(self.__mixid, XY, estimateEquil,
|
||||||
printLvl, solver, rtol, maxsteps,
|
printLvl, solver, rtol, maxsteps,
|
||||||
maxiter, loglevel)
|
maxiter, loglevel)
|
||||||
|
|
||||||
def selectSpecies(self, f, species):
|
def selectSpecies(self, f, species):
|
||||||
"""Given an array 'f' of floating-point species properties,
|
"""Given an array *f* of floating-point species properties,
|
||||||
return an array of those values corresponding to species
|
return an array of those values corresponding to species
|
||||||
listed in 'species'. This method is used internally to implement
|
listed in *species*. This method is used internally to implement
|
||||||
species selection in methods like moleFractions, massFractions, etc.
|
species selection in methods like :meth:`~.Phase.moleFractions`,
|
||||||
|
:meth:`~.Phase.massFractions`, etc.
|
||||||
|
|
||||||
>>> f = mix.chemPotentials()
|
>>> f = mix.chemPotentials()
|
||||||
>>> muo2, muh2 = mix.selectSpecies(f, ['O2', 'H2'])
|
>>> muo2, muh2 = mix.selectSpecies(f, ['O2', 'H2'])
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,12 @@ class Solution(ThermoPhase, Kinetics, Transport):
|
||||||
mixture of gases, a liquid solution, or a solid solution, for
|
mixture of gases, a liquid solution, or a solid solution, for
|
||||||
example.
|
example.
|
||||||
|
|
||||||
Class Solution derives from classes ThermoPhase, Kinetics, and
|
Class Solution derives from classes :class:`.ThermoPhase`, :class:`.Kinetics`,
|
||||||
Transport. It defines very few methods of its own, and is
|
and :class:`.Transport`. It defines very few methods of its own, and is
|
||||||
provided largely for convenience, so that a single object can be
|
provided largely for convenience, so that a single object can be
|
||||||
used to compute thermodynamic, kinetic, and transport properties
|
used to compute thermodynamic, kinetic, and transport properties
|
||||||
of a solution. Functions like IdealGasMix and others defined in
|
of a solution. Functions like :func:`.IdealGasMix` and others defined in
|
||||||
module gases return objects of class Solution.
|
module gases return objects of class :class:`.Solution`.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -70,16 +70,28 @@ class Solution(ThermoPhase, Kinetics, Transport):
|
||||||
|
|
||||||
def set(self, **options):
|
def set(self, **options):
|
||||||
"""Set various properties.
|
"""Set various properties.
|
||||||
T --- temperature [K]
|
|
||||||
P --- pressure [Pa]
|
:param T:
|
||||||
Rho --- density [kg/m3]
|
temperature [K]
|
||||||
V --- specific volume [m3/kg]
|
:param P:
|
||||||
H --- specific enthalpy [J/kg]
|
pressure [Pa]
|
||||||
U --- specific internal energy [J/kg]
|
:param Rho:
|
||||||
S --- specific entropy [J/kg/K]
|
density [kg/m3]
|
||||||
X --- mole fractions (string or array)
|
:param V:
|
||||||
Y --- mass fractions (string or array)
|
specific volume [m3/kg]
|
||||||
Vapor --- saturated vapor fraction
|
:param H:
|
||||||
Liquid --- saturated liquid fraction
|
specific enthalpy [J/kg]
|
||||||
|
:param U:
|
||||||
|
specific internal energy [J/kg]
|
||||||
|
:param S:
|
||||||
|
specific entropy [J/kg/K]
|
||||||
|
:param X:
|
||||||
|
mole fractions (string or array)
|
||||||
|
:param Y:
|
||||||
|
mass fractions (string or array)
|
||||||
|
:param Vapor:
|
||||||
|
saturated vapor fraction
|
||||||
|
:param Liquid:
|
||||||
|
saturated liquid fraction
|
||||||
"""
|
"""
|
||||||
setByName(self, options)
|
setByName(self, options)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue