From b4ceb7da2edf75117c3bedafa701d6fb015e7c91 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Tue, 13 Mar 2012 17:34:47 +0000 Subject: [PATCH] Reformatted the Python docstrings to work better with Sphinx This means that the docstrings are now parsed as reStructuredText. --- doc/SConscript | 8 +- doc/sphinx/conf.py | 14 +- doc/sphinx/func.rst | 8 + doc/sphinx/mathjax.py | 68 ++ doc/sphinx/transport.rst | 2 +- interfaces/python/Cantera/Edge.py | 33 +- interfaces/python/Cantera/Func.py | 238 +++---- interfaces/python/Cantera/Interface.py | 31 +- interfaces/python/Cantera/Kinetics.py | 38 +- .../python/Cantera/OneD/BurnerDiffFlame.py | 40 +- interfaces/python/Cantera/OneD/BurnerFlame.py | 40 +- .../python/Cantera/OneD/CounterFlame.py | 68 +- interfaces/python/Cantera/OneD/FreeFlame.py | 23 +- .../python/Cantera/OneD/StagnationFlow.py | 83 ++- interfaces/python/Cantera/OneD/onedim.py | 206 +++--- interfaces/python/Cantera/Phase.py | 49 +- interfaces/python/Cantera/Reactor.py | 605 +++++++++--------- interfaces/python/Cantera/SurfacePhase.py | 4 +- interfaces/python/Cantera/ThermoPhase.py | 78 +-- interfaces/python/Cantera/Transport.py | 24 +- interfaces/python/Cantera/__init__.py | 2 +- interfaces/python/Cantera/constants.py | 26 +- interfaces/python/Cantera/gases.py | 14 +- interfaces/python/Cantera/importFromFile.py | 1 + interfaces/python/Cantera/mixture.py | 180 +++--- interfaces/python/Cantera/solution.py | 42 +- 26 files changed, 1059 insertions(+), 866 deletions(-) create mode 100644 doc/sphinx/mathjax.py diff --git a/doc/SConscript b/doc/SConscript index 40c749ed3..1049e193e 100644 --- a/doc/SConscript +++ b/doc/SConscript @@ -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) diff --git a/doc/sphinx/conf.py b/doc/sphinx/conf.py index 4c22ff3a3..99ad9afce 100644 --- a/doc/sphinx/conf.py +++ b/doc/sphinx/conf.py @@ -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'] diff --git a/doc/sphinx/func.rst b/doc/sphinx/func.rst index 1a08b980f..546bf62f3 100644 --- a/doc/sphinx/func.rst +++ b/doc/sphinx/func.rst @@ -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: diff --git a/doc/sphinx/mathjax.py b/doc/sphinx/mathjax.py new file mode 100644 index 000000000..59beff3a4 --- /dev/null +++ b/doc/sphinx/mathjax.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +""" + sphinx.ext.mathjax + ~~~~~~~~~~~~~~~~~~ + + Allow `MathJax `_ 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] + '') + 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('') + 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('(%s)' % + 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('\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) + diff --git a/doc/sphinx/transport.rst b/doc/sphinx/transport.rst index 5f2f661e6..2bcbcbedd 100644 --- a/doc/sphinx/transport.rst +++ b/doc/sphinx/transport.rst @@ -1,4 +1,4 @@ Transport Properties ==================== -.. autoclass:: Cantera.Transport.Transport +.. automodule:: Cantera.Transport diff --git a/interfaces/python/Cantera/Edge.py b/interfaces/python/Cantera/Edge.py index 675fdcb57..a49bed44c 100644 --- a/interfaces/python/Cantera/Edge.py +++ b/interfaces/python/Cantera/Edge.py @@ -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 diff --git a/interfaces/python/Cantera/Func.py b/interfaces/python/Cantera/Func.py index cb447c872..21c0bac94 100644 --- a/interfaces/python/Cantera/Func.py +++ b/interfaces/python/Cantera/Func.py @@ -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) diff --git a/interfaces/python/Cantera/Interface.py b/interfaces/python/Cantera/Interface.py index c513b173b..89540f37a 100644 --- a/interfaces/python/Cantera/Interface.py +++ b/interfaces/python/Cantera/Interface.py @@ -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 diff --git a/interfaces/python/Cantera/Kinetics.py b/interfaces/python/Cantera/Kinetics.py index b17576764..6a07e907a 100755 --- a/interfaces/python/Cantera/Kinetics.py +++ b/interfaces/python/Cantera/Kinetics.py @@ -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') diff --git a/interfaces/python/Cantera/OneD/BurnerDiffFlame.py b/interfaces/python/Cantera/OneD/BurnerDiffFlame.py index dc8294a94..3f2a1d2d4 100644 --- a/interfaces/python/Cantera/OneD/BurnerDiffFlame.py +++ b/interfaces/python/Cantera/OneD/BurnerDiffFlame.py @@ -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): diff --git a/interfaces/python/Cantera/OneD/BurnerFlame.py b/interfaces/python/Cantera/OneD/BurnerFlame.py index e2cfaf38b..5f3843cea 100644 --- a/interfaces/python/Cantera/OneD/BurnerFlame.py +++ b/interfaces/python/Cantera/OneD/BurnerFlame.py @@ -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): diff --git a/interfaces/python/Cantera/OneD/CounterFlame.py b/interfaces/python/Cantera/OneD/CounterFlame.py index 5d0a3d53d..b6431708e 100644 --- a/interfaces/python/Cantera/OneD/CounterFlame.py +++ b/interfaces/python/Cantera/OneD/CounterFlame.py @@ -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) diff --git a/interfaces/python/Cantera/OneD/FreeFlame.py b/interfaces/python/Cantera/OneD/FreeFlame.py index 7a0d2015d..daeedb18c 100644 --- a/interfaces/python/Cantera/OneD/FreeFlame.py +++ b/interfaces/python/Cantera/OneD/FreeFlame.py @@ -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) diff --git a/interfaces/python/Cantera/OneD/StagnationFlow.py b/interfaces/python/Cantera/OneD/StagnationFlow.py index ab3279045..6032e37cc 100644 --- a/interfaces/python/Cantera/OneD/StagnationFlow.py +++ b/interfaces/python/Cantera/OneD/StagnationFlow.py @@ -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): diff --git a/interfaces/python/Cantera/OneD/onedim.py b/interfaces/python/Cantera/OneD/onedim.py index 470456383..ed888c5d5 100644 --- a/interfaces/python/Cantera/OneD/onedim.py +++ b/interfaces/python/Cantera/OneD/onedim.py @@ -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) diff --git a/interfaces/python/Cantera/Phase.py b/interfaces/python/Cantera/Phase.py index deb6ef534..cbe385bf2 100755 --- a/interfaces/python/Cantera/Phase.py +++ b/interfaces/python/Cantera/Phase.py @@ -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']) """ diff --git a/interfaces/python/Cantera/Reactor.py b/interfaces/python/Cantera/Reactor.py index 02afe36ab..f29d7863c 100644 --- a/interfaces/python/Cantera/Reactor.py +++ b/interfaces/python/Cantera/Reactor.py @@ -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 diff --git a/interfaces/python/Cantera/SurfacePhase.py b/interfaces/python/Cantera/SurfacePhase.py index 5703bdaec..7697dce81 100644 --- a/interfaces/python/Cantera/SurfacePhase.py +++ b/interfaces/python/Cantera/SurfacePhase.py @@ -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): diff --git a/interfaces/python/Cantera/ThermoPhase.py b/interfaces/python/Cantera/ThermoPhase.py index aebb8a808..098eba999 100644 --- a/interfaces/python/Cantera/ThermoPhase.py +++ b/interfaces/python/Cantera/ThermoPhase.py @@ -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) diff --git a/interfaces/python/Cantera/Transport.py b/interfaces/python/Cantera/Transport.py index 1b9e7f50a..54d6a91b8 100755 --- a/interfaces/python/Cantera/Transport.py +++ b/interfaces/python/Cantera/Transport.py @@ -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 diff --git a/interfaces/python/Cantera/__init__.py b/interfaces/python/Cantera/__init__.py index 8d66cd688..d72afafb7 100755 --- a/interfaces/python/Cantera/__init__.py +++ b/interfaces/python/Cantera/__init__.py @@ -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. diff --git a/interfaces/python/Cantera/constants.py b/interfaces/python/Cantera/constants.py index cd70bdc4d..5a4a51df2 100755 --- a/interfaces/python/Cantera/constants.py +++ b/interfaces/python/Cantera/constants.py @@ -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); diff --git a/interfaces/python/Cantera/gases.py b/interfaces/python/Cantera/gases.py index e9f9df0ea..f29962aa0 100755 --- a/interfaces/python/Cantera/gases.py +++ b/interfaces/python/Cantera/gases.py @@ -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") diff --git a/interfaces/python/Cantera/importFromFile.py b/interfaces/python/Cantera/importFromFile.py index 8f355864c..c42e411d1 100755 --- a/interfaces/python/Cantera/importFromFile.py +++ b/interfaces/python/Cantera/importFromFile.py @@ -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]) diff --git a/interfaces/python/Cantera/mixture.py b/interfaces/python/Cantera/mixture.py index 7bce9effa..ecb43dd83 100644 --- a/interfaces/python/Cantera/mixture.py +++ b/interfaces/python/Cantera/mixture.py @@ -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']) """ diff --git a/interfaces/python/Cantera/solution.py b/interfaces/python/Cantera/solution.py index aaa41e434..51993f037 100755 --- a/interfaces/python/Cantera/solution.py +++ b/interfaces/python/Cantera/solution.py @@ -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)