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