Translated the "Defining Phases" guide to Sphinx/reST format
This commit is contained in:
parent
e323340c73
commit
d02ccc5334
10 changed files with 1537 additions and 13 deletions
BIN
doc/sphinx/_static/images/sofc-phases.png
Normal file
BIN
doc/sphinx/_static/images/sofc-phases.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
|
|
@ -1,12 +1,12 @@
|
||||||
***************
|
|
||||||
Defining Phases
|
|
||||||
***************
|
|
||||||
|
|
||||||
CTI Class Documentation
|
*******************
|
||||||
=======================
|
CTI Class Reference
|
||||||
|
*******************
|
||||||
|
|
||||||
|
.. py:module:: ctml_writer
|
||||||
|
|
||||||
Basic Classes & Functions
|
Basic Classes & Functions
|
||||||
-------------------------
|
=========================
|
||||||
|
|
||||||
.. autofunction:: ctml_writer.units
|
.. autofunction:: ctml_writer.units
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@ Basic Classes & Functions
|
||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
|
|
||||||
Phases of Matter
|
Phases of Matter
|
||||||
----------------
|
================
|
||||||
|
|
||||||
.. autoclass:: ctml_writer.phase
|
.. autoclass:: ctml_writer.phase
|
||||||
:no-members:
|
:no-members:
|
||||||
|
|
@ -56,7 +56,7 @@ Phases of Matter
|
||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
|
|
||||||
Elements and Species
|
Elements and Species
|
||||||
--------------------
|
====================
|
||||||
|
|
||||||
.. autoclass:: ctml_writer.element
|
.. autoclass:: ctml_writer.element
|
||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
|
|
@ -65,7 +65,7 @@ Elements and Species
|
||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
|
|
||||||
Thermodynamic Properties
|
Thermodynamic Properties
|
||||||
------------------------
|
========================
|
||||||
|
|
||||||
.. autoclass:: ctml_writer.Mu0_table
|
.. autoclass:: ctml_writer.Mu0_table
|
||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
|
|
@ -86,13 +86,13 @@ Thermodynamic Properties
|
||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
|
|
||||||
Transport Properties
|
Transport Properties
|
||||||
--------------------
|
====================
|
||||||
|
|
||||||
.. autoclass:: ctml_writer.gas_transport
|
.. autoclass:: ctml_writer.gas_transport
|
||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
|
|
||||||
Reactions
|
Reactions
|
||||||
---------
|
=========
|
||||||
|
|
||||||
.. autoclass:: ctml_writer.reaction
|
.. autoclass:: ctml_writer.reaction
|
||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
|
|
@ -119,7 +119,7 @@ Reactions
|
||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
|
|
||||||
Falloff Parameterizations
|
Falloff Parameterizations
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
-------------------------
|
||||||
|
|
||||||
.. autoclass:: ctml_writer.Troe
|
.. autoclass:: ctml_writer.Troe
|
||||||
:no-undoc-members:
|
:no-undoc-members:
|
||||||
4
doc/sphinx/cti/example-combustion.rst
Normal file
4
doc/sphinx/cti/example-combustion.rst
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
============================
|
||||||
|
Example: Hydrogen Combustion
|
||||||
|
============================
|
||||||
|
|
||||||
16
doc/sphinx/cti/index.rst
Normal file
16
doc/sphinx/cti/index.rst
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
***************
|
||||||
|
Defining Phases
|
||||||
|
***************
|
||||||
|
|
||||||
|
*A guide to Cantera's input file format*
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
intro
|
||||||
|
input-files
|
||||||
|
phases
|
||||||
|
species
|
||||||
|
reactions
|
||||||
|
classes
|
||||||
|
example-combustion
|
||||||
483
doc/sphinx/cti/input-files.rst
Normal file
483
doc/sphinx/cti/input-files.rst
Normal file
|
|
@ -0,0 +1,483 @@
|
||||||
|
.. py:currentmodule:: ctml_writer
|
||||||
|
|
||||||
|
.. _sec-input-files:
|
||||||
|
|
||||||
|
************************
|
||||||
|
Working with Input Files
|
||||||
|
************************
|
||||||
|
|
||||||
|
Before we can describe how to define phases, interfaces, and their components
|
||||||
|
(elements, species, and reactions), we need to go over a few points about the
|
||||||
|
mechanics of writing and processing input files.
|
||||||
|
|
||||||
|
Input File Syntax
|
||||||
|
=================
|
||||||
|
|
||||||
|
An input file consists of *entries* and *directives*, both of which have a
|
||||||
|
syntax much like functions. An entry defines an object---for example, a
|
||||||
|
reaction, or a species, or a phase. A directive sets options that affect how the
|
||||||
|
entry parameters are interpreted, such as the default unit system, or how
|
||||||
|
certain errors should be handled.
|
||||||
|
|
||||||
|
Cantera's input files follow the syntax rules for Python, so if you're familiar
|
||||||
|
with Python syntax you already understand many of the details and can probably
|
||||||
|
skip ahead to :ref:`sec-dimensions`.
|
||||||
|
|
||||||
|
Entries have fields that can be assigned values. A species entry is shown below
|
||||||
|
that has fields name and atoms (plus several others)::
|
||||||
|
|
||||||
|
species(name='C60', atoms='C:60')
|
||||||
|
|
||||||
|
Most entries have some fields that are required; these must be assigned values,
|
||||||
|
or else processing of the file will abort and an error message will be
|
||||||
|
printed. Other fields may be optional, and take default values if not assigned.
|
||||||
|
|
||||||
|
An entry may be either a *top-level entry* or an *embedded entry*. Top-level
|
||||||
|
entries specify a phase, an interface, an element, a species, or a reaction, and
|
||||||
|
begin in the first (leftmost) column. Embedded entries specify a model, or a
|
||||||
|
group of parameters for a top-level entry, and are usually embedded in a field
|
||||||
|
of another entry.
|
||||||
|
|
||||||
|
The fields of an entry are specified in the form ``<field_name> = <value>``, and may
|
||||||
|
be listed on one line, or extend across several. For example, two entries for
|
||||||
|
graphite are shown below. The first is compact::
|
||||||
|
|
||||||
|
stoichiometric_solid(name='graphite', species='C(gr)', elements='C', density=(2.2, 'g/cm3')))
|
||||||
|
|
||||||
|
and the second is formatted to be easier to read::
|
||||||
|
|
||||||
|
stoichiometric_solid(
|
||||||
|
name = 'graphite',
|
||||||
|
elements = 'C',
|
||||||
|
species = 'C(gr)',
|
||||||
|
density = (2.2, 'g/cm3')
|
||||||
|
)
|
||||||
|
|
||||||
|
Both are completely equivalent.
|
||||||
|
|
||||||
|
The species ``C(gr)`` that appears in the definition of the graphite phase is
|
||||||
|
also defined by a top-level entry. If the heat capacity of graphite is
|
||||||
|
approximated as constant, then the following definition could be used::
|
||||||
|
|
||||||
|
species(name='C(gr)',
|
||||||
|
atoms='C:1',
|
||||||
|
thermo=const_cp(t0=298.15,
|
||||||
|
h0=0.0,
|
||||||
|
s0=(5.6, 'J/mol/K'), # NIST
|
||||||
|
cp0=(8.43, 'J/mol/K'))) # Taylor and Groot (1980)
|
||||||
|
|
||||||
|
Note that the thermo field is assigned an embedded entry of type
|
||||||
|
:class:`const_cp`. Entries are stored as they are encountered when the file is
|
||||||
|
read, and only processed once the end of the file has been reached. Therefore,
|
||||||
|
the order in which they appear is unimportant.
|
||||||
|
|
||||||
|
Comments
|
||||||
|
--------
|
||||||
|
|
||||||
|
The character ``#`` is the comment character. Everything to the right of this
|
||||||
|
character on a line is ignored::
|
||||||
|
|
||||||
|
# set the default units
|
||||||
|
units(length = 'cm', # use centimeters for length
|
||||||
|
quantity = 'mol') # use moles for quantity
|
||||||
|
|
||||||
|
Strings
|
||||||
|
-------
|
||||||
|
|
||||||
|
Strings may be enclosed in single quotes or double quotes, but they must
|
||||||
|
match. To create a string containing single quotes, enclose it in double quotes,
|
||||||
|
and vice versa. If you want to create a string to extend over multiple lines,
|
||||||
|
enclose it in triple double quotes.
|
||||||
|
|
||||||
|
Strings may be enclosed in single quotes or double quotes, but they must
|
||||||
|
match. To create a string containing single quotes, enclose it in double quotes,
|
||||||
|
and vice versa. If you want to create a string to extend over multiple lines,
|
||||||
|
enclose it in triple quotes::
|
||||||
|
|
||||||
|
string1 = 'A string.'
|
||||||
|
string2 = "Also a 'string'"
|
||||||
|
string3 = """This is
|
||||||
|
a
|
||||||
|
string too."""
|
||||||
|
|
||||||
|
The multi-line form is useful when specifying a phase containing a large number
|
||||||
|
of species::
|
||||||
|
|
||||||
|
species = """ H2 H O O2 OH H2O HO2 H2O2 C CH
|
||||||
|
CH2 CH2(S) CH3 CH4 CO CO2 HCO CH2O CH2OH CH3O
|
||||||
|
CH3OH C2H C2H2 C2H3 C2H4 C2H5 C2H6 HCCO CH2CO HCCOH
|
||||||
|
N NH NH2 NH3 NNH NO NO2 N2O HNO CN
|
||||||
|
HCN H2CN HCNN HCNO HOCN HNCO NCO N2 AR C3H7
|
||||||
|
C3H8 CH2CHO CH3CHO """
|
||||||
|
|
||||||
|
Sequences
|
||||||
|
---------
|
||||||
|
|
||||||
|
A sequence of multiple items is specified by separating the items by commas and
|
||||||
|
enclosing them in square brackets or parentheses. The individual items can have
|
||||||
|
any type---strings, integers, floating-point numbers (or even entries or other
|
||||||
|
lists). Square brackets are often preferred, since parentheses are also used for
|
||||||
|
other purposes in the input file, but either can be used::
|
||||||
|
|
||||||
|
s0 = (3.5, 'J/mol/K') # these are
|
||||||
|
s0 = [3.5, 'J/mol/K'] # equivalent
|
||||||
|
|
||||||
|
Variables
|
||||||
|
---------
|
||||||
|
|
||||||
|
Another way to specify the species C(gr) is shown here::
|
||||||
|
|
||||||
|
graphite_thermo = const_cp(t0=298.15,
|
||||||
|
h0=0.0,
|
||||||
|
s0=(5.6, 'J/mol/K'), # NIST
|
||||||
|
cp0=(8.43, 'J/mol/K')) # Taylor and Groot (1980)
|
||||||
|
|
||||||
|
species(name='C(gr)', atoms='C:1', thermo=graphite_thermo)
|
||||||
|
|
||||||
|
In this form, the ``const_cp`` entry is stored in a variable, instead of being
|
||||||
|
directly embedded within the species entry. The *thermo* field is assigned this
|
||||||
|
variable.
|
||||||
|
|
||||||
|
Variables can also be used for any other parameter type. For example, if you are
|
||||||
|
defining several phases in the file, and you want to set them all to the same
|
||||||
|
initial pressure, you could define a pressure variable::
|
||||||
|
|
||||||
|
P_initial = (2.0, 'atm')
|
||||||
|
|
||||||
|
and then set the pressure field in each embedded state entry to this variable.
|
||||||
|
|
||||||
|
Omitting Field Names
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Field names may be omitted if the values are entered in the order specified in
|
||||||
|
the entry declaration. (Entry declarations are the text printed on a colored
|
||||||
|
background in the following chapters.) It is also possible to omit only some of
|
||||||
|
the field names, as long as these fields are listed first, in order, before any
|
||||||
|
named fields.
|
||||||
|
|
||||||
|
For example, The first four entries below are equivalent, while the last two are
|
||||||
|
incorrect and would generate an error when processed::
|
||||||
|
|
||||||
|
element(symbol="Ar", atomic_mass=39.948) # OK
|
||||||
|
element(atomic_mass=39.948, symbol='Ar') # OK
|
||||||
|
element('Ar', atomic_mass=39.948) # OK
|
||||||
|
element("Ar", 39.948) # OK
|
||||||
|
|
||||||
|
element(39.948, "Ar") # error
|
||||||
|
element(symbol="Ar", 39.948) # error
|
||||||
|
|
||||||
|
.. _sec-dimensions:
|
||||||
|
|
||||||
|
Dimensional Values
|
||||||
|
==================
|
||||||
|
|
||||||
|
Many fields have numerical values that represent dimensional quantities---a
|
||||||
|
pressure, or a density, for example. If these are entered without specifying the
|
||||||
|
units, the default units (set by the :class:`units` directive described in
|
||||||
|
:ref:`sec-default-units`) will be used. However, it is also possible to specify
|
||||||
|
the units for each individual dimensional quantity (unless stated
|
||||||
|
otherwise). All that is required is to group the value in parentheses or square
|
||||||
|
brackets with a string specifying the units::
|
||||||
|
|
||||||
|
pressure = 1.0e5 # default is Pascals
|
||||||
|
pressure = (1.0, 'bar') # this is equivalent
|
||||||
|
density = (4.0, 'g/cm3')
|
||||||
|
density = 4000.0 # kg/m3
|
||||||
|
|
||||||
|
Compound unit strings may be used, as long as a few rules are followed:
|
||||||
|
|
||||||
|
1. Units in the denominator follow ``/``.
|
||||||
|
2. Units in the numerator follow ``-``, except for the first one.
|
||||||
|
3. Numerical exponents follow the unit string without a ``^`` character, and must
|
||||||
|
be in the range 2--6. Negative values are not allowed.
|
||||||
|
|
||||||
|
Examples of compound units::
|
||||||
|
|
||||||
|
A = (1.0e20, 'cm6/mol2/s') # OK
|
||||||
|
h = (6.626e-34, 'J-s') # OK
|
||||||
|
density = (3.0, 'g/cm3') # OK
|
||||||
|
A = (1.0e20, 'cm^6/mol/s') # error (^)
|
||||||
|
A = (1.0e20, 'cm6/mol2-s') # error ('s' should be in denominator)
|
||||||
|
density = (3.0, 'g-cm-3') # error (negative exponent)
|
||||||
|
|
||||||
|
.. _sec-default-units:
|
||||||
|
|
||||||
|
Setting the Default Units
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
The default unit system may be set with the :func:`units` directive. Note
|
||||||
|
that unit conversions are not done until the entire file has been read. Only one
|
||||||
|
units directive should be present in a file, and the defaults it specifies apply
|
||||||
|
to the entire file. If the file does not contain a units directive, the default
|
||||||
|
units are meters, kilograms, kilomoles, and seconds.
|
||||||
|
|
||||||
|
Shown below are two equivalent ways of specifying the site density for an
|
||||||
|
interface. In the first version, the site density is specified without a units
|
||||||
|
string, and so its units are constructed from the default units for quantity and
|
||||||
|
length, which are set with a units directive::
|
||||||
|
|
||||||
|
units(length = 'cm', quantity = 'molec')
|
||||||
|
interface(name = 'Si-100',
|
||||||
|
site_density = 1.0e15, # molecules/cm2 (default units)
|
||||||
|
...)
|
||||||
|
|
||||||
|
The second version uses a different default unit system, but overrides the
|
||||||
|
default units by specifying an explicit units string for the site density::
|
||||||
|
|
||||||
|
units(length = 'cm', quantity = 'mol')
|
||||||
|
interface(name = 'Si-100',
|
||||||
|
site_density = (1.0e15, 'molec/cm2') # override default units
|
||||||
|
...)
|
||||||
|
|
||||||
|
The second version is equivalent to the first, but would be very different if
|
||||||
|
the units of the site density were not specified!
|
||||||
|
|
||||||
|
The *length*, *quantity* and *time* units are used to construct the units for
|
||||||
|
reaction pre-exponential factors. The *energy* units are used for molar
|
||||||
|
thermodynamic properties, in combination with the units for *quantity*.
|
||||||
|
|
||||||
|
Since activation energies are often specified in units other than those used for
|
||||||
|
thermodynamic properties, a separate field is devoted to the default units for
|
||||||
|
activation energies::
|
||||||
|
|
||||||
|
units(length = 'cm', quantity = 'mol', act_energy = 'kcal/mol')
|
||||||
|
kf = Arrhenius(A = 1.0e14, b = 0.0, E = 54.0) # E is 54 kcal/mol
|
||||||
|
|
||||||
|
See :func:`units` for the declaration of the units directive.
|
||||||
|
|
||||||
|
Recognized Units
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Cantera recognizes the following units in various contexts:
|
||||||
|
|
||||||
|
=========== ==============
|
||||||
|
field allowed values
|
||||||
|
=========== ==============
|
||||||
|
length ``'cm', 'm', 'mm'``
|
||||||
|
quantity ``'mol', 'kmol', 'molec'``
|
||||||
|
time ``'s', 'min', 'hr', 'ms'``
|
||||||
|
energy ``'J', 'kJ', 'cal', 'kcal'``
|
||||||
|
act_energy ``'kJ/mol', 'J/mol', 'J/kmol', 'kcal/mol', 'cal/mol', 'eV', 'K'``
|
||||||
|
pressure ``'Pa', 'atm', 'bar'``
|
||||||
|
=========== ==============
|
||||||
|
|
||||||
|
Processing Input Files
|
||||||
|
======================
|
||||||
|
|
||||||
|
A Two-step Process
|
||||||
|
------------------
|
||||||
|
|
||||||
|
From the point of view of the user, it appears that a Cantera application that
|
||||||
|
imports a phase definition reads the input file, and uses the information there
|
||||||
|
to construct the object representing the phase or interface in the
|
||||||
|
application. While this is the net effect, it is actually a two-step
|
||||||
|
process. When a function like importPhase is called to import a phase definition
|
||||||
|
from a file, a preprocessor runs automatically to read the input file and create
|
||||||
|
a data file that contains the same information but in an XML-based format called
|
||||||
|
CTML. After the preprocessor finishes, Cantera imports the phase definition from
|
||||||
|
the CTML data file.
|
||||||
|
|
||||||
|
The CTML file is saved in the same directory as the input file, and has the same
|
||||||
|
name but with the extension changed to ``.xml``. If the input file has the name
|
||||||
|
``propane.cti``, for example, then the CTML file will be placed in the same
|
||||||
|
directory with name ``propane.xml``. If you like, once the CTML file has been
|
||||||
|
created, you can specify it rather than the ``.cti`` input file in calls to
|
||||||
|
importPhase (or similar functions). This is slightly faster, since the
|
||||||
|
preprocessing step can be skipped. It also allows Cantera simulations to be run
|
||||||
|
on systems that do not have Python, which Cantera uses in the preprocessing step
|
||||||
|
but does not require to read CTML files.
|
||||||
|
|
||||||
|
Two File Formats
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Why two file formats? There are several reasons. XML is a widely-used standard
|
||||||
|
for data files, and it is designed to be relatively easy to parse. This makes it
|
||||||
|
possible for other applications to use Cantera CTML data files, without
|
||||||
|
requiring the substantial chemical knowledge that would be required to use .cti
|
||||||
|
files. For example, "web services" (small applications that run remotely over a
|
||||||
|
network) are often designed to accept XML input data over the network, perform a
|
||||||
|
calculation, and send the output in XML back across the network. Supporting an
|
||||||
|
XML-based data file format facilitates using Cantera in web services or other
|
||||||
|
network computing applications.
|
||||||
|
|
||||||
|
The difference between the high-level description in a .cti input file and the
|
||||||
|
lower-level description in the CTML file may be illustrated by how reactions are
|
||||||
|
handled. In the input file, the reaction stoichiometry and its reversibility or
|
||||||
|
irreversibility are determined from the reaction equation. For example::
|
||||||
|
|
||||||
|
O + HCCO <=> H + 2 CO
|
||||||
|
|
||||||
|
specifies a reversible reaction between an oxygen atom and the ketenyl radical
|
||||||
|
HCCO to produce one hydrogen atom and two carbon monoxide molecules. If ``<=>``
|
||||||
|
were replaced with ``=>``, then it would specify that the reaction should be
|
||||||
|
treated as irreversible.
|
||||||
|
|
||||||
|
Of course, this convention is not spelled out in the input file---the parser
|
||||||
|
simply has to know it, and has to also know that a "reactant" appears on the
|
||||||
|
left side of the equation, a "product" on the right, that the optional number in
|
||||||
|
front of a species name is its stoichiometric coefficient (but if missing the
|
||||||
|
value is one), etc. The preprocessor does know all this, but we cannot expect
|
||||||
|
the same level of knowledge of chemical conventions by a generic XML parser.
|
||||||
|
|
||||||
|
Therefore, in the CTML file, reactions are explicitly specified to be reversible
|
||||||
|
or irreversible, and the reactants and products are explicitly listed with their
|
||||||
|
stoichiometric coefficients. The XML file is, in a sense, a "dumbed-down"
|
||||||
|
version of the input file, spelling out explicitly things that are only implied
|
||||||
|
in the input file syntax, so that "dumb" (i.e., easy to write) parsers can be
|
||||||
|
used to read the data with minimal risk of misinterpretation.
|
||||||
|
|
||||||
|
The reaction definition::
|
||||||
|
|
||||||
|
reaction( "O + HCCO <=> H + 2 CO", [1.00000E+14, 0, 0])
|
||||||
|
|
||||||
|
in the input file is translated by the preprocessor to the following CTML text:
|
||||||
|
|
||||||
|
.. code-block:: xml
|
||||||
|
|
||||||
|
<reaction id="0028" reversible="yes">
|
||||||
|
<equation>O + HCCO [=] H + 2 CO</equation>
|
||||||
|
<rateCoeff>
|
||||||
|
<Arrhenius>
|
||||||
|
<A units="cm3/mol/s"> 1.000000E+14</A>
|
||||||
|
<b>0</b>
|
||||||
|
<E units="cal/mol">0.000000</E>
|
||||||
|
</Arrhenius>
|
||||||
|
</rateCoeff>
|
||||||
|
<reactants>HCCO:1 O:1</reactants>
|
||||||
|
<products>H:1 CO:2</products>
|
||||||
|
</reaction>
|
||||||
|
|
||||||
|
The CTML version is much more verbose, and would be much more tedious to write
|
||||||
|
by hand, but is much easier to parse, particularly since it is not necessary to
|
||||||
|
write a custom parser---virtually any standard XML parser, of which there are
|
||||||
|
many, can be used to read the CTML data.
|
||||||
|
|
||||||
|
So in general files that are easy for knowledgable users (you) to write are more
|
||||||
|
difficult for machines to parse, because they make use of high-level
|
||||||
|
application-specific knowledge and conventions to simplify the
|
||||||
|
notation. Conversely, files that are designed to be easily parsed are tedious to
|
||||||
|
write because so much has to be spelled out explicitly. A natural solution is to
|
||||||
|
use two formats, one designed for writing by humans, the other for reading by
|
||||||
|
machines, and provide a preprocessor to convert the human-friendly format to the
|
||||||
|
machine-friendly one.
|
||||||
|
|
||||||
|
Preprocessor Intenals: the ``ctml_writer`` Module
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
If you are interested in seeing the internals of how the preprocessing works,
|
||||||
|
take a look at file ``ctml_writer.py`` in the Cantera Python package. Or simply
|
||||||
|
start Python, and type::
|
||||||
|
|
||||||
|
>>> from Cantera import ctml_writer
|
||||||
|
>>> help(ctml_writer)
|
||||||
|
|
||||||
|
The ``ctml_writer.py`` module can also be run as a script to convert input .cti
|
||||||
|
files to CTML. For example, if you have an input file ``phasedefs.cti``, then
|
||||||
|
simply type at the command line::
|
||||||
|
|
||||||
|
python ctml_writer.py phasedefs.cti
|
||||||
|
|
||||||
|
to create CTML file ``phasedefs.xml``.
|
||||||
|
|
||||||
|
Of course, most of the time creation of the CTML file will happen behind the
|
||||||
|
scenes, and you will not need to be concerned with CTML files at all.
|
||||||
|
|
||||||
|
Error Handling
|
||||||
|
==============
|
||||||
|
|
||||||
|
During processing of an input file, errors may be encountered. These could be
|
||||||
|
syntax errors, or could be ones that are flagged as errors by Cantera due to
|
||||||
|
some apparent inconsistency in the data---an unphysical value, a species that
|
||||||
|
contains an undeclared element, a reaction that contains an undeclared species,
|
||||||
|
missing species or element definitions, multiple definitions of elements,
|
||||||
|
species, or reactions, and so on.
|
||||||
|
|
||||||
|
Syntax Errors
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Syntax errors are caught by the Python preprocessor, not by Cantera, and must be
|
||||||
|
corrected before proceeding further. Python prints a "traceback" that allows
|
||||||
|
you to find the line that contains the error. For example, consider the
|
||||||
|
following input file, which is intended to create a gas with the species and
|
||||||
|
reactions of GRI-Mech 3.0, but has a misspelled the field name ``reactions``::
|
||||||
|
|
||||||
|
ideal_gas(name = 'gas',
|
||||||
|
elements = 'H O',
|
||||||
|
species = 'gri30: all',
|
||||||
|
reactionss = 'gri30: all')
|
||||||
|
|
||||||
|
When this definition is imported into an application, an error message like the
|
||||||
|
following would be printed to the screen, and execution of the program or script
|
||||||
|
would terminate. ::
|
||||||
|
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "<stdin>", line 1, in <module>
|
||||||
|
File "/some/path/Cantera/importFromFile.py", line 18, in importPhase
|
||||||
|
return importPhases(file, [name], loglevel, debug)[0]
|
||||||
|
File "/some/path/Cantera/importFromFile.py", line 25, in importPhases
|
||||||
|
s.append(solution.Solution(src=file,id=nm,loglevel=loglevel,debug=debug))
|
||||||
|
File "/some/path/solution.py", line 39, in __init__
|
||||||
|
preprocess = 1, debug = debug)
|
||||||
|
File "/some/path/Cantera/XML.py", line 35, in __init__
|
||||||
|
self._xml_id = _cantera.xml_get_XML_File(src, debug)
|
||||||
|
cantera.error:
|
||||||
|
|
||||||
|
************************************************
|
||||||
|
Cantera Error!
|
||||||
|
************************************************
|
||||||
|
|
||||||
|
Procedure: ct2ctml
|
||||||
|
Error: Error converting input file "./gas.cti" to CTML.
|
||||||
|
Python command was: '/usr/bin/python'
|
||||||
|
The exit code was: 4
|
||||||
|
-------------- start of converter log --------------
|
||||||
|
TypeError on line 4 of './gas.cti':
|
||||||
|
__init__() got an unexpected keyword argument 'reactionss'
|
||||||
|
|
||||||
|
| Line |
|
||||||
|
| 1 | ideal_gas(name = 'gas',
|
||||||
|
| 2 | elements = 'H O',
|
||||||
|
| 3 | species = 'gri30: all',
|
||||||
|
> 4 > reactionss = 'gri30: all')
|
||||||
|
| 5 |
|
||||||
|
--------------- end of converter log ---------------
|
||||||
|
|
||||||
|
The top part of the error message shows the chain of functions that were called
|
||||||
|
before the error was encountered. For the most part, these are internal Cantera
|
||||||
|
functions not of direct concern here. The relevant part of this error message is
|
||||||
|
the part starting with the "Cantera Error" heading, and specifically the
|
||||||
|
contents of the *converter log* section. This message says that that on line 4
|
||||||
|
of ``gas.cti``, the the keyword argument ``reactionss`` was not
|
||||||
|
recognized. Seeing this message, it is clear that the problem is that
|
||||||
|
*reactions* is misspelled.
|
||||||
|
|
||||||
|
Cantera Errors
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Now let's consider the other class of errors---ones that Cantera, not Python,
|
||||||
|
detects. Continuing the example above, suppose that the misspelling is
|
||||||
|
corrected, and the input file processed again. Again an error message results,
|
||||||
|
but this time it is from Cantera::
|
||||||
|
|
||||||
|
cantera.error:
|
||||||
|
Procedure: installSpecies
|
||||||
|
Error: species C contains undeclared element C
|
||||||
|
|
||||||
|
The problem is that the phase definition specifies that all species are to be
|
||||||
|
imported from dataset gri30, but only the elements H and O are declared. The
|
||||||
|
gri30 datset contains species composed of the elements H, O, C, N, and Ar. If
|
||||||
|
the definition is modified to declare these additional elements::
|
||||||
|
|
||||||
|
ideal_gas(name = 'gas',
|
||||||
|
elements = 'H O C N Ar',
|
||||||
|
species = 'gri30: all',
|
||||||
|
reactions = 'gri30: all')
|
||||||
|
|
||||||
|
it may be imported successfully.
|
||||||
|
|
||||||
|
Errors of this type do not have to be fatal, as long as you tell Cantera how you
|
||||||
|
want to handle them. You can, for example, instruct Cantera to quitely skip
|
||||||
|
importing any species that contain undeclared elements, instead of flagging them
|
||||||
|
as errors. You can also specify that reactions containing undeclared species
|
||||||
|
(also usually an error) should be skipped. This allows you to very easily
|
||||||
|
extract a portion of a large reaction mechanism, as described in :ref:`sec-phase-options`.
|
||||||
40
doc/sphinx/cti/intro.rst
Normal file
40
doc/sphinx/cti/intro.rst
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
************
|
||||||
|
Introduction
|
||||||
|
************
|
||||||
|
|
||||||
|
Virtually every Cantera simulation involves one or more phases of
|
||||||
|
matter. Depending on the calculation being performed, it may be necessary to
|
||||||
|
evaluate thermodynamic properties, transport properties, and/or homogeneous
|
||||||
|
reaction rates for the phase(s) present. In problems with multiple phases, the
|
||||||
|
properties of the interfaces between phases, and the heterogeneous reaction
|
||||||
|
rates at these interfaces, may also be required.
|
||||||
|
|
||||||
|
Before the properties can be evaluated, each phase must be defined, meaning that
|
||||||
|
the models to use to compute its properties and reaction rates must be
|
||||||
|
specified, along with any parameters the models require. For example, a solid
|
||||||
|
phase might be defined as being incompressible, with a specified density and
|
||||||
|
composition. A gaseous phase for a combustion simulation might be defined as an
|
||||||
|
ideal gas consisting of a mixture of many species that react with one another
|
||||||
|
via a specified set of reactions.
|
||||||
|
|
||||||
|
For phases containing multiple species and reactions, a large amount of data is
|
||||||
|
required to define the phase, since the contribution of each species to the
|
||||||
|
thermodynamic and transport properties must be specified, and rate information
|
||||||
|
must be given for each reaction. While this could be done directly in an
|
||||||
|
application program, a better approach is put the phase and interface
|
||||||
|
definitions in a text file that can be read by the application, so that a given
|
||||||
|
phase model can be re-used for other simulations.
|
||||||
|
|
||||||
|
This guide describes how to write such files to define phases and interfaces for
|
||||||
|
use in Cantera simulations. Section :ref:`sec-input-files` contains a summary of
|
||||||
|
some basic rules for writing input files, a discussion of how they are
|
||||||
|
processed, and of how errors are handled. In Section :ref:`sec-phases`, we will
|
||||||
|
go over how to define phases and interfaces, including how to import species and
|
||||||
|
reactions from external files. Then in :ref:`sec-species` and
|
||||||
|
:ref:`sec-reactions`, we'll look in depth at how to specify the component parts
|
||||||
|
of phase and interface models---the elements, species, and reactions.
|
||||||
|
|
||||||
|
.. In Section ##REF##, we'll put it all together, and present some complete,
|
||||||
|
realistic example problems, showing the input file containing the definitions
|
||||||
|
of all phases and interfaces, the application code to use the input file to
|
||||||
|
solve a problem, and the resulting output.
|
||||||
466
doc/sphinx/cti/phases.rst
Normal file
466
doc/sphinx/cti/phases.rst
Normal file
|
|
@ -0,0 +1,466 @@
|
||||||
|
.. py:currentmodule:: ctml_writer
|
||||||
|
|
||||||
|
.. _sec-phases:
|
||||||
|
|
||||||
|
***************************
|
||||||
|
Phases and their Interfaces
|
||||||
|
***************************
|
||||||
|
|
||||||
|
Now that we have covered how to write syntactically-correct input files, we can
|
||||||
|
turn our attention to the content of the file. We'll start by describing the
|
||||||
|
entries for phases of various types, and the look at how to define interfaces
|
||||||
|
between phases.
|
||||||
|
|
||||||
|
Phases
|
||||||
|
======
|
||||||
|
|
||||||
|
For each phase that appears in a problem, a corresponding entry should be
|
||||||
|
present in the input file(s). For example, suppose we want to conduct a
|
||||||
|
simulation with detailed chemistry of an idealized solid-oxide fuel cell shown
|
||||||
|
below. The problem involves three solid phases (A nickel anode, a
|
||||||
|
platinum cathode, and an oxygen-conducting yttrium-stabilized zirconia
|
||||||
|
electrolyte), and two different gas phases (a fuel mixture on the anode side,
|
||||||
|
and air on the cathode side). The problem also involves a number of interfaces
|
||||||
|
at which heterogeneous chemistry may occur---two gas-metal interfaces, two
|
||||||
|
gas-electrolyte interfaces, and two metal-electrolyte interfaces.
|
||||||
|
|
||||||
|
.. figure:: /_static/images/sofc-phases.png
|
||||||
|
:align: center
|
||||||
|
|
||||||
|
Phases entering into a hypothetical microkinetic simulation of an idealized
|
||||||
|
solid-oxide fuel cell.
|
||||||
|
|
||||||
|
How to carry out this fuel cell simulation is beyond the scope of this document;
|
||||||
|
we introduce it here only to give an example of the types of phases and
|
||||||
|
interfaces that might need to be defined in order to carry out a simulation. (Of
|
||||||
|
course, many simulations with Cantera only require defining a single phase.)
|
||||||
|
|
||||||
|
There are several different types of entries, corresponding to different types
|
||||||
|
of phases. Phases are created using one of the directives corresponding to an
|
||||||
|
implemented phase type:
|
||||||
|
|
||||||
|
* :class:`ideal_gas`
|
||||||
|
* :class:`stoichiometric_solid`
|
||||||
|
* :class:`stoichiometric_liquid`
|
||||||
|
* :class:`metal`
|
||||||
|
* :class:`semiconductor`
|
||||||
|
* :class:`incompressible_solid`
|
||||||
|
* :class:`lattice`
|
||||||
|
* :class:`lattice_solid`
|
||||||
|
* :class:`liquid_vapor`
|
||||||
|
* :class:`redlich_kwong`
|
||||||
|
* :class:`ideal_interface`
|
||||||
|
* :class:`edge`
|
||||||
|
|
||||||
|
These phase typese share many common features, however, and so we will begin by
|
||||||
|
discussing those aspects common to all entries for phases. The :class:`phase`
|
||||||
|
class contains the features common to all phase types.
|
||||||
|
|
||||||
|
Phase Attributes
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Phase Name
|
||||||
|
^^^^^^^^^^
|
||||||
|
|
||||||
|
The ``name`` field is a string that identifies the phase. It must not contain
|
||||||
|
any whitespace characters or reserved XML characters, and must be unique within
|
||||||
|
the file among all phase definitions of any type.
|
||||||
|
|
||||||
|
Phases are referenced by name when importing them into an application program,
|
||||||
|
or when defining an interface between phases.
|
||||||
|
|
||||||
|
Declaring the Elements
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The elements that may be present in the phase are declared in the elements
|
||||||
|
field. This must be a string of element symbols separated by spaces and/or
|
||||||
|
commas. Each symbol must either match one listed in the database file
|
||||||
|
``elements.xml``, or else match the symbol of an element entry defined elsewhere
|
||||||
|
in the input file (See :ref:`sec-elements`).
|
||||||
|
|
||||||
|
The ``elements.xml`` database contains most elements of the periodic table, with
|
||||||
|
their natural-abundance atomic masses. It also contains a few isotopes (D, Tr),
|
||||||
|
and an "element" for an electron (E). This pseudo-element can be used to specify
|
||||||
|
the composition of charged species. Note that two-character symbols should have
|
||||||
|
an uppercase first letter, and a lowercase second letter (e.g. ``Cu``, not ``CU``).
|
||||||
|
|
||||||
|
It should be noted that the order of the element symbols in the string
|
||||||
|
determines the order in which they are stored internally by Cantera. For
|
||||||
|
example, if a phase definition specifies the elements as::
|
||||||
|
|
||||||
|
ideal_gas(name = "gasmix",
|
||||||
|
elements = "H C O N Ar",
|
||||||
|
...)
|
||||||
|
|
||||||
|
then when this definition is imported by an application, element-specific
|
||||||
|
properties will be ordered in the same way::
|
||||||
|
|
||||||
|
>>> gas = importPhase('example.cti', 'gasmix')
|
||||||
|
>>> for n in range(gas.nElements()):
|
||||||
|
... print n, gas.elementSymbol(n)
|
||||||
|
0 H
|
||||||
|
1 C
|
||||||
|
2 O
|
||||||
|
3 N
|
||||||
|
4 Ar
|
||||||
|
|
||||||
|
For some calculations, such as multi-phase chemical equilibrium, it is important
|
||||||
|
to synchronize the elements among multiple phases, so that each phase contains
|
||||||
|
the same elements with the same ordering. In such cases, simply use the same
|
||||||
|
string in the elements field for all phases.
|
||||||
|
|
||||||
|
Defining the Species
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The species in the phase are declared in the species field. They are not defined
|
||||||
|
there, only declared. Species definitions may be imported from other files, or
|
||||||
|
species may be defined locally using species entries elsewhere in the file.
|
||||||
|
|
||||||
|
If a single string of species symbols is given, then it is assumed that these
|
||||||
|
are locally defined. For each one, a corresponding species entry must be present
|
||||||
|
somewhere in the file, either preceding or following the phase entry. Note that
|
||||||
|
the string may extend over multiple lines by delimiting it with triple quotes::
|
||||||
|
|
||||||
|
# commas are optional
|
||||||
|
species = 'AR SI Si2 SiH SiH2 SiH3 SiH4'
|
||||||
|
species = 'H, O, OH, H2O, HO2, H2O2, H2, O2'
|
||||||
|
|
||||||
|
# include all species defined in this file
|
||||||
|
species = 'all'
|
||||||
|
|
||||||
|
# a multi-line species declaration
|
||||||
|
species = """ H2 H O O2 OH H2O HO2 H2O2 C CH
|
||||||
|
CH2 CH2(S) CH3 CH4 CO CO2 HCO CH2O CH2OH CH3O
|
||||||
|
CH3OH C2H C2H2 C2H3 C2H4 C2H5 C2H6 HCCO CH2CO HCCOH
|
||||||
|
N NH NH2 NH3 NNH NO NO2 N2O HNO CN
|
||||||
|
HCN H2CN HCNN HCNO HOCN HNCO NCO N2 AR C3H7
|
||||||
|
C3H8 CH2CHO CH3CHO """
|
||||||
|
|
||||||
|
If the species are imported from another file, instead of being defined locally,
|
||||||
|
then the string should begin with the file name (without extension), followed by
|
||||||
|
a colon::
|
||||||
|
|
||||||
|
# import selected species from silicon.xml
|
||||||
|
species = "silicon: SI SI2 SIH SIH2 SIH3 SIH4 SI2H6"
|
||||||
|
|
||||||
|
# import all species from silicon.xml
|
||||||
|
species = "silicon: all"
|
||||||
|
|
||||||
|
In this case, the species definitions will be taken from file ``silicon.xml``,
|
||||||
|
which must exist either in the local directory or somewhere on the Cantera
|
||||||
|
search path.
|
||||||
|
|
||||||
|
It is also possible to import species from several sources, or mix local
|
||||||
|
definitions with imported ones, by specifying a sequence of strings::
|
||||||
|
|
||||||
|
species = ["CL2 CL F F2 HF HCL", # defined in this file
|
||||||
|
"air: O2 N2 NO", # imported from 'air.xml'
|
||||||
|
"ions: CL- F-"] # imported from 'ions.xml'
|
||||||
|
|
||||||
|
Note that the strings must be separated by commas, and enclosed in square
|
||||||
|
brackets or parentheses.
|
||||||
|
|
||||||
|
Declaring the Reactions
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The reactions among the species are declared in the ``reactions`` field. Just as
|
||||||
|
with species, reactions may be defined locally in the file, or may be imported
|
||||||
|
from one or more other files. All reactions must only involve species that have
|
||||||
|
been declared for the phase.
|
||||||
|
|
||||||
|
Unlike species, reactions do not have a name, but do have an optional ``ID``
|
||||||
|
field. If the ``ID`` field is not assigned a value, then when the reaction entry
|
||||||
|
is read it will be assigned a four-digit string encoding the reaction number,
|
||||||
|
beginning with ``'0001'`` for the first reaction in the file, and incrementing
|
||||||
|
by one for each new reaction.
|
||||||
|
|
||||||
|
If all reactions defined locally in the input file are to be included in the
|
||||||
|
phase definition, then assign the ``reactions`` field the string ``'all'``::
|
||||||
|
|
||||||
|
reactions = 'all'
|
||||||
|
|
||||||
|
If, on the other hand, only some of the reactions defined in the file are to be
|
||||||
|
included, then a range can be specified using the reaction ``ID`` fields::
|
||||||
|
|
||||||
|
reactions = 'nox-12 to nox-24'
|
||||||
|
|
||||||
|
In determining which reactions to include, a lexical comparison of id strings is
|
||||||
|
performed. This means, for example, that ``'nox-8'`` is greater than
|
||||||
|
``'nox-24'``. (If it is rewritten ``'nox-08'``, however, then it would be lexically
|
||||||
|
less than ``'nox-24'``.)
|
||||||
|
|
||||||
|
Just as described above for species, reactions can be imported from another
|
||||||
|
file, and reactions may be imported from several sources. Examples::
|
||||||
|
|
||||||
|
# import all reactions defined in this file
|
||||||
|
reactions = "all"
|
||||||
|
|
||||||
|
# import all reactions defined in rxns.xml
|
||||||
|
reactions = "rxns: all"
|
||||||
|
|
||||||
|
# import reactions 1-14 in rxns.xml
|
||||||
|
reactions = "rxns: 0001 to 0014"
|
||||||
|
|
||||||
|
# import reactions from several sources
|
||||||
|
reactions = ["all", # all local reactions
|
||||||
|
"gas: all", # all reactions in gas.xml
|
||||||
|
"nox: n005 to n008"] # reactions 5 to 8 in nox.xml
|
||||||
|
|
||||||
|
The Kinetics Model
|
||||||
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
A *kinetics model* is a set of equations to use to compute reaction rates. In
|
||||||
|
most cases, each type of phase has an associated kinetics model that is used by
|
||||||
|
default, and so the ``kinetics`` field does not need to be assigned a value. For
|
||||||
|
example, the :class:`ideal_gas` entry has an associated kinetics model called
|
||||||
|
``GasKinetics`` that implements mass-action kinetics, computes reverse rates
|
||||||
|
from thermochemistry for reversible reactions, and provides various
|
||||||
|
pressure-independent and pressure-dependent reaction types. Other models could
|
||||||
|
be implemented, and this field would then be used to select the desired
|
||||||
|
model. For now, the ``kinetics`` field can be safely ignored.
|
||||||
|
|
||||||
|
The Transport Model
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
A *transport model* is a set of equations used to compute transport
|
||||||
|
properties. For one :class:`ideal_gas` phases, multiple transport models are
|
||||||
|
available; the one desired can be selected by assiging a string to this
|
||||||
|
field. See :ref:`sec-gas-transport-models` for more details.
|
||||||
|
|
||||||
|
The Initial State
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The phase may be assigned an initial state to which it will be set when the
|
||||||
|
definition is imported into an application and an object created. This is done
|
||||||
|
by assigning field ``initial_state`` an embedded entry of type :class:`state`,
|
||||||
|
described in :ref:`sec-state-entry`.
|
||||||
|
|
||||||
|
Most of the attributes defined here are "immutable," meaning that once the
|
||||||
|
definition has been imported into an application, they cannot be changed by the
|
||||||
|
application. For example, it is not possible to change the elements or the
|
||||||
|
species. The temperature, pressure, and composition, however, are "mutable"---
|
||||||
|
they can be changed. This is why the field defining the state is called the
|
||||||
|
``initial_state``; the object in the application will be initially set to this
|
||||||
|
state, but it may be changed at any time.
|
||||||
|
|
||||||
|
.. _sec-phase-options:
|
||||||
|
|
||||||
|
Special Processing Options
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The options field is used to indicate how certain conditions should be handled
|
||||||
|
when importing the phase definition. The options field may be assigned a string
|
||||||
|
or a sequence of strings from the table below.
|
||||||
|
|
||||||
|
============================== ================
|
||||||
|
Option String Meaning
|
||||||
|
============================== ================
|
||||||
|
``'no_validation'`` Turn off all validation. Use when the definition
|
||||||
|
has been previously validated to speed up importing
|
||||||
|
the definition into an application. Use with caution!
|
||||||
|
``'skip_undeclared_elements'`` When importing species, skip any containing undeclared
|
||||||
|
elements, rather than flagging them as an error.
|
||||||
|
``'skip_undeclared_species'`` When importing reactions, skip any containing undeclared
|
||||||
|
species, rather than flagging them as an error.
|
||||||
|
============================== ================
|
||||||
|
|
||||||
|
Using the ``options`` field, it is possible to extract a sub-mechanism from a large
|
||||||
|
reaction mechanism, as follows::
|
||||||
|
|
||||||
|
ideal_gas(name = 'hydrogen_mech',
|
||||||
|
species = 'gri30: all',
|
||||||
|
reactions = 'gri30:all',
|
||||||
|
options = ('skip_undeclared_elements',
|
||||||
|
'skip_undeclared_species'))
|
||||||
|
|
||||||
|
If we import this into Matlab, for example, we get a gas mixture containing the
|
||||||
|
8 species (out of 53 total) that contain only H and O:
|
||||||
|
|
||||||
|
.. code-block:: matlab
|
||||||
|
|
||||||
|
>> gas = importPhase('gas.cti', 'hydrogen_mech')
|
||||||
|
|
||||||
|
temperature 300 K
|
||||||
|
pressure 1237.28 Pa
|
||||||
|
density 0.001 kg/m^3
|
||||||
|
mean mol. weight 2.01588 amu
|
||||||
|
|
||||||
|
X Y
|
||||||
|
------------ ------------
|
||||||
|
H2 1.000000e+00 1.000000e+00
|
||||||
|
H 0.000000e+00 0.000000e+00
|
||||||
|
O 0.000000e+00 0.000000e+00
|
||||||
|
O2 0.000000e+00 0.000000e+00
|
||||||
|
OH 0.000000e+00 0.000000e+00
|
||||||
|
H2O 0.000000e+00 0.000000e+00
|
||||||
|
HO2 0.000000e+00 0.000000e+00
|
||||||
|
H2O2 0.000000e+00 0.000000e+00
|
||||||
|
|
||||||
|
>> eqs = reactionEqn(gas)
|
||||||
|
|
||||||
|
eqs =
|
||||||
|
|
||||||
|
'2 O + M <=> O2 + M'
|
||||||
|
'O + H + M <=> OH + M'
|
||||||
|
'O + H2 <=> H + OH'
|
||||||
|
'O + HO2 <=> OH + O2'
|
||||||
|
'O + H2O2 <=> OH + HO2'
|
||||||
|
'H + O2 + M <=> HO2 + M'
|
||||||
|
'H + 2 O2 <=> HO2 + O2'
|
||||||
|
'H + O2 + H2O <=> HO2 + H2O'
|
||||||
|
'H + O2 <=> O + OH'
|
||||||
|
'2 H + M <=> H2 + M'
|
||||||
|
'2 H + H2 <=> 2 H2'
|
||||||
|
'2 H + H2O <=> H2 + H2O'
|
||||||
|
'H + OH + M <=> H2O + M'
|
||||||
|
'H + HO2 <=> O + H2O'
|
||||||
|
'H + HO2 <=> O2 + H2'
|
||||||
|
'H + HO2 <=> 2 OH'
|
||||||
|
'H + H2O2 <=> HO2 + H2'
|
||||||
|
'H + H2O2 <=> OH + H2O'
|
||||||
|
'OH + H2 <=> H + H2O'
|
||||||
|
'2 OH (+ M) <=> H2O2 (+ M)'
|
||||||
|
'2 OH <=> O + H2O'
|
||||||
|
'OH + HO2 <=> O2 + H2O'
|
||||||
|
'OH + H2O2 <=> HO2 + H2O'
|
||||||
|
'OH + H2O2 <=> HO2 + H2O'
|
||||||
|
'2 HO2 <=> O2 + H2O2'
|
||||||
|
'2 HO2 <=> O2 + H2O2'
|
||||||
|
'OH + HO2 <=> O2 + H2O'
|
||||||
|
|
||||||
|
Ideal Gas Mixtures
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Now we turn to the specific entry types for phases, beginning with
|
||||||
|
:class:`ideal_gas`.
|
||||||
|
|
||||||
|
Many combustion and CVD simulations make use of reacting ideal gas
|
||||||
|
mixtures. These can be defined using the :class:`ideal_gas` entry. The Cantera
|
||||||
|
ideal gas model allows any number of species, and any number of reactions among
|
||||||
|
them. It supports all of the options in the widely-used model described by Kee
|
||||||
|
et al. [1989], plus some additional options for species thermodynamic properties
|
||||||
|
and reaction rate expressions.
|
||||||
|
|
||||||
|
An example of an ideal_gas entry is shown below::
|
||||||
|
|
||||||
|
ideal_gas(name='air8',
|
||||||
|
elements='N O Ar',
|
||||||
|
species='gri30: N2 O2 N O NO NO2 N2O AR',
|
||||||
|
reactions='all',
|
||||||
|
transport='mix',
|
||||||
|
initial_state=state(temperature=500.0,
|
||||||
|
pressure=(1.0, 'atm'),
|
||||||
|
mole_fractions='N2:0.78, O2:0.21, AR:0.01'))
|
||||||
|
|
||||||
|
This entry defines an ideal gas mixture that contains 8 species, the definitions
|
||||||
|
of which are imported from dataset gri30 (file ``gri30.xml``). All reactions
|
||||||
|
defined in the file are to be included, transport properties are to be computed
|
||||||
|
using mixture rules, and the state of the gas is to be set initially to 500 K, 1
|
||||||
|
atm, and a composition that corresponds to air.
|
||||||
|
|
||||||
|
.. _sec-gas-transport-models:
|
||||||
|
|
||||||
|
Transport Models
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Two transport models are available for use with ideal gas mixtures. The first is
|
||||||
|
a multicomponent transport model that is based on the model described by
|
||||||
|
Dixon-Lewis [1968] (see also Kee et al. [2003]). The second is a model that uses
|
||||||
|
mixture rules. To select the multicomponent model, set the transport field to
|
||||||
|
the string ``'multi'``, and to select the mixture-averaged model, set it to the
|
||||||
|
string ``'mix'``::
|
||||||
|
|
||||||
|
ideal_gas(name="gas1",
|
||||||
|
...,
|
||||||
|
transport="multi", # use multicomponent formulation
|
||||||
|
...)
|
||||||
|
|
||||||
|
ideal_gas(name="gas2",
|
||||||
|
...,
|
||||||
|
transport="mix", # use mixture-averaged formulation
|
||||||
|
...)
|
||||||
|
|
||||||
|
Stoichiometric Solid
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
A :class:`stoichiometric_solid` is one that is modeled as having a precise,
|
||||||
|
fixed composition, given by the composition of the one species present. A
|
||||||
|
stoichiometric solid can be used to define a condensed phase that can
|
||||||
|
participate in heterogeneous reactions. (Of course, there cannot be homogeneous
|
||||||
|
reactions, since the composition is fixed.) ::
|
||||||
|
|
||||||
|
stoichiometric_solid(name='graphite',
|
||||||
|
elements='C',
|
||||||
|
species='C(gr)',
|
||||||
|
density=(2.2, 'g/cm3'),
|
||||||
|
initial_state=state(temperature=300.0,
|
||||||
|
pressure=(1.0, 'atm'))
|
||||||
|
|
||||||
|
Stoichiometric Liquid
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
A stoichiometric liquid differs from a stoichiometric solid in only one respect:
|
||||||
|
the transport manager computes the viscosity as well as the thermal
|
||||||
|
conductivity.
|
||||||
|
|
||||||
|
Interfaces
|
||||||
|
==========
|
||||||
|
|
||||||
|
Now that we have seen how to define bulk, three-dimensional phases, we can
|
||||||
|
describe the procedure to define an interface between phases.
|
||||||
|
|
||||||
|
Cantera presently implements a simple model for an interface that treats is as a
|
||||||
|
two-dimensional ideal solution of interfacial species. There is a fixed site
|
||||||
|
density :math:`n^0`, and each site may be occupied by one of several adsorbates,
|
||||||
|
or may be empty. The chemical potential of each species is computed using the
|
||||||
|
expression for an ideal solution:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
\mu_k = \mu^0_k + \hat{R}T \log \theta_k,
|
||||||
|
|
||||||
|
where :math:`\theta_k` is the coverage of species :math:`k` on the surface. The
|
||||||
|
coverage is related to the surface concentration :math:`C_k` by
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
\theta_k = \frac{C_k n_k}{n^0} ,
|
||||||
|
|
||||||
|
where :math:`n_k` is the number of sites covered or blocked by species
|
||||||
|
:math:`k`.
|
||||||
|
|
||||||
|
The entry type for this interface model is
|
||||||
|
:class:`ideal_interface`. (Additional interface models may be added to allow
|
||||||
|
non-ideal, coverage-dependent properties.)
|
||||||
|
|
||||||
|
Defining an interface is much like defining a phase. There are two new fields:
|
||||||
|
``phases`` and ``site_density``. The phases field specifies the bulk phases that
|
||||||
|
participate in the heterogeneous reactions. Although in most cases this string
|
||||||
|
will list one or two phases, no limit is placed on the number. This is
|
||||||
|
particularly useful in some electrochemical problems, where reactions take place
|
||||||
|
near the triple-phase bounday where a gas, an electrolyte, and a metal all meet.
|
||||||
|
|
||||||
|
The ``site_density`` field is the number of adsorption sites per unit area.
|
||||||
|
|
||||||
|
Another new aspect is in the embedded :class:`state` entry in the
|
||||||
|
``initial_state`` field. When specifying the initial state of an interface, the
|
||||||
|
:class:`state` entry has a field *coverages*, which can be assigned a string
|
||||||
|
specifying the initial surface species coverages::
|
||||||
|
|
||||||
|
ideal_interface(name='silicon_surface',
|
||||||
|
elements='Si H',
|
||||||
|
species='s* s-SiH3 s-H',
|
||||||
|
reactions='all',
|
||||||
|
phases='gas bulk-Si',
|
||||||
|
site_density=(1.0e15, 'molec/cm2'),
|
||||||
|
initial_state=state(temperature=1200.0,
|
||||||
|
coverages='s-H:1'))
|
||||||
|
|
||||||
|
.. _sec-state-entry:
|
||||||
|
|
||||||
|
The :class:`state` entry
|
||||||
|
========================
|
||||||
|
|
||||||
|
The initial state of either a phase or an interface may be set using an embedded
|
||||||
|
:class:`state` entry. Note that only one of (``pressure``, ``density``) may be
|
||||||
|
specified, and only one (``mole_fractions``, ``mass_fractions``, ``coverages``).
|
||||||
290
doc/sphinx/cti/reactions.rst
Normal file
290
doc/sphinx/cti/reactions.rst
Normal file
|
|
@ -0,0 +1,290 @@
|
||||||
|
.. py:currentmodule:: ctml_writer
|
||||||
|
|
||||||
|
.. _sec-reactions:
|
||||||
|
|
||||||
|
*********
|
||||||
|
Reactions
|
||||||
|
*********
|
||||||
|
|
||||||
|
Cantera supports a number of different types of reactions, including several
|
||||||
|
types of homogeneous reactions, surface reactions, and electrochemical
|
||||||
|
reactions. For each, there is a corresponding entry type. The simplest entry
|
||||||
|
type is :class:`reaction`, which can be used for any homogeneous reaction that
|
||||||
|
has a rate expression that obeys the law of mass action, with a rate coefficient
|
||||||
|
that depends only on temperature.
|
||||||
|
|
||||||
|
Common Attributes
|
||||||
|
=================
|
||||||
|
|
||||||
|
All of the entry types that define reactions share some common features. These
|
||||||
|
are described first, followed by descriptions of the individual reaction types
|
||||||
|
in the following sections.
|
||||||
|
|
||||||
|
The Reaction Equation
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
The reaction equation determines the reactant and product stoichiometry. A
|
||||||
|
relatively simple parsing strategy is currently used, which assumes that all
|
||||||
|
coefficient and species symbols on either side of the equation are delimited by
|
||||||
|
spaces::
|
||||||
|
|
||||||
|
2 CH2 <=> CH + CH3 # OK
|
||||||
|
2 CH2<=>CH + CH3 # OK
|
||||||
|
2CH2 <=> CH + CH3 # error
|
||||||
|
CH2 + CH2 <=> CH + CH3 # OK
|
||||||
|
2 CH2 <=> CH+CH3 # error
|
||||||
|
|
||||||
|
The incorrect versions here would generate "undeclared species" errors and would
|
||||||
|
halt processing of the input file. In the first case, the error would be that
|
||||||
|
the species ``2CH2`` is undeclared, and in the second case it would be species
|
||||||
|
``CH+CH3``.
|
||||||
|
|
||||||
|
Whether the reaction is reversible or not is determined by the form of the
|
||||||
|
equality sign in the reaction equation. If either ``<=>`` or ``=`` is found,
|
||||||
|
then the reaction is regarded as reversible, and the reverse rate will be
|
||||||
|
computed from detailed balance. If, on the other hand, ``=>`` is found, the
|
||||||
|
reaction will be treated as irreversible.
|
||||||
|
|
||||||
|
The rate coefficient is specified with an embedded entry corresponding to the
|
||||||
|
rate coefficient type. At present, the only implemented type is the modified
|
||||||
|
Arrhenius function
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
k_f(T) = A T^n \exp(-E/\hat{R}T)
|
||||||
|
|
||||||
|
whish is defined with an :class:`Arrhenius` entry::
|
||||||
|
|
||||||
|
rate_coeff = Arrhenius(A=1.0e13, n=0, E=(7.3, 'kcal/mol'))
|
||||||
|
rate_coeff = Arrhenius(1.0e13, 0, (7.3, 'kcal/mol'))
|
||||||
|
|
||||||
|
As a shorthand, if the ``rate_coeff`` field is assigned a sequence of three numbers, these are assumed to be :math:`(A, n, E)` in the modified Arrhenius function::
|
||||||
|
|
||||||
|
rate_coeff = [1.0e13, 0, (7.3, 'kcal/mol')] # equivalent to above
|
||||||
|
|
||||||
|
The units of the pre-exponential factor *A* can be specified explicitly if
|
||||||
|
desired. If not specified, they will be constructed using the *quantity*, length,
|
||||||
|
and time units specified in the units directive. Since the units of *A* depend on
|
||||||
|
the reaction order, the units of each reactant concentration (different for bulk
|
||||||
|
species in solution, surface species, and pure condensed-phase species), and the
|
||||||
|
units of the rate of progress (different for homogeneous and heterogeneous
|
||||||
|
reactions), it is usually best not to specify units for *A*, in which case they
|
||||||
|
will be computed taking all of these factors into account.
|
||||||
|
|
||||||
|
Note: if :math:`n \ne 0`, then the term :math:`T^n` should have units of
|
||||||
|
:math:`K^n`, which would change the units of *A*. This is not done, however, so
|
||||||
|
the units associated with A are really the units for :math:`k_f` . One way to
|
||||||
|
formally express this is to replace :math:`T^n` by the non-dimensional quantity
|
||||||
|
:math:`[T/(1 K)]^n`.
|
||||||
|
|
||||||
|
The ID String
|
||||||
|
-------------
|
||||||
|
|
||||||
|
An optional identifying string can be entered in the ``ID`` field, which can
|
||||||
|
then be used in the ``reactions`` field of a :class:`phase` or interface entry
|
||||||
|
to identify this reaction. If omitted, the reactions are assigned ID strings as
|
||||||
|
they are read in, beginning with ``'0001'``, ``'0002'``, etc.
|
||||||
|
|
||||||
|
Note that the ID string is only used when selectively importing reactions. If
|
||||||
|
all reactions in the local file or in an external one are imported into a phase
|
||||||
|
or interface, then the reaction ``ID`` field is not used.
|
||||||
|
|
||||||
|
Options
|
||||||
|
-------
|
||||||
|
|
||||||
|
Certain conditions are normally flagged as errors by Cantera. In some cases,
|
||||||
|
theey may not be errors, and the options field can be used to specify how they
|
||||||
|
should be handled.
|
||||||
|
|
||||||
|
``skip``
|
||||||
|
The ``'skip'`` option can be used to temporarily remove this reaction from
|
||||||
|
the phase or interface that imports it, just as if the reaction entry were
|
||||||
|
commented out. The advantage of using skip instead of commenting it out is
|
||||||
|
that a warning message is printed each time a phase or interface definition
|
||||||
|
tries to import it. This serves as a reminder that this reaction is not
|
||||||
|
included, which can easily be forgotten when a reaction is "temporarily"
|
||||||
|
commented out of an input file.
|
||||||
|
|
||||||
|
``duplicate``
|
||||||
|
Normally, when a reaction is imported into a phase, it is checked to see
|
||||||
|
that it is not a duplicate of another reaction already present in the phase,
|
||||||
|
and an error results if a duplicate is found. But in some cases, it may be
|
||||||
|
appropriate to include duplicate reactions, for example if a reaction can
|
||||||
|
proceed through two distinctly different pathways, each with its own rate
|
||||||
|
expression. Another case where duplicate reactions can be used is if it is
|
||||||
|
desired to implement a reaction rate coefficient of the form:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
k_f(T) = \sum_{n=1}^{N} A_n T^{b_n} exp(-E_n/\hat{R}T)
|
||||||
|
|
||||||
|
While Cantera does not provide such a form for reaction rates, it can be
|
||||||
|
implemented by defining *N* duplicate reactions, and assigning one rate
|
||||||
|
coefficient in the sum to each reaction. If the ``'duplicate'`` option is
|
||||||
|
specified, then the reaction not only *may* have a duplicate, it *must*. Any
|
||||||
|
reaction that specifies that it is a duplicate, but cannot be paired with
|
||||||
|
another reaction in the phase that qualifies as its duplicate generates an
|
||||||
|
error.
|
||||||
|
|
||||||
|
``negative_A``
|
||||||
|
If some of the terms in the above sum have negative :math:`A_n`, this scheme
|
||||||
|
fails, since Cantera normally does not allow negative pre-exponential
|
||||||
|
factors. But if there are duplicate reactions such that the total rate is
|
||||||
|
positive, then negative *A* parameters are acceptable, as long as the
|
||||||
|
``'negative_A'`` option is specified.
|
||||||
|
|
||||||
|
Reactions with Pressure-Independent Rate
|
||||||
|
========================================
|
||||||
|
|
||||||
|
The :class:`reaction` entry is used to represent homogeneous reactions with
|
||||||
|
pressure-independent rate coefficients and mass action kinetics. Examples of
|
||||||
|
reaction entries that implement some reactions in the GRI-Mech 3.0 natural gas
|
||||||
|
combustion mechanism [Smith et al., 1997] are shown below::
|
||||||
|
|
||||||
|
units(length = 'cm', quantity = 'mol', act_energy = 'cal/mol')
|
||||||
|
...
|
||||||
|
reaction( "O + H2 <=> H + OH", [3.87000E+04, 2.7, 6260])
|
||||||
|
reaction( "O + HO2 <=> OH + O2", [2.00000E+13, 0.0, 0])
|
||||||
|
reaction( "O + H2O2 <=> OH + HO2", [9.63000E+06, 2.0, 4000])
|
||||||
|
reaction( "O + HCCO <=> H + 2 CO", [1.00000E+14, 0.0, 0])
|
||||||
|
reaction( "H + O2 + AR <=> HO2 + AR", [7.00000E+17, -0.8, 0])
|
||||||
|
reaction( "HO2 + C3H7 <=> O2 + C3H8", [2.55000E+10, 0.255, -943])
|
||||||
|
reaction( "HO2 + C3H7 => OH + C2H5 + CH2O", [2.41000E+13, 0.0, 0])
|
||||||
|
|
||||||
|
Three-Body Reactions
|
||||||
|
====================
|
||||||
|
|
||||||
|
A three-body reaction is a gas-phase reaction of the form:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
{\rm A + B} \rightleftharpoons {\rm AB + M}
|
||||||
|
|
||||||
|
Here M is an unspecified collision partner that carries away excess energy to
|
||||||
|
stabilize the AB molecule (forward direction) or supplies energy to break the AB
|
||||||
|
bond (reverse direction).
|
||||||
|
|
||||||
|
Different species may be more or less effective in acting as the collision partner. A species that is much lighter than
|
||||||
|
A and B may not be able to transfer much of its kinetic energy, and so would be inefficient as a collision partner. On
|
||||||
|
the other hand, a species with a transition from its ground state that is nearly resonant with one in the AB* activated
|
||||||
|
complex may be much more effective at exchanging energy than would otherwise be expected.
|
||||||
|
|
||||||
|
These effects can be accounted for by defining a collision efficiency
|
||||||
|
:math:`\epsilon` for each species, defined such that the forward reaction rate is
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
k_f(T)[A][B][M]
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
[M] = \sum_k \epsilon_k C_k
|
||||||
|
|
||||||
|
where :math:`C_k` is the concentration of species *k*. Since any constant
|
||||||
|
collision efficiency can be absorbed into the rate coefficient :math:`k_f(T)`, the
|
||||||
|
default collision efficiency is 1.0.
|
||||||
|
|
||||||
|
A three-body reaction may be defined using the :class:`three_body_reaction` entry. The equation string for a three-body
|
||||||
|
reaction must contain an ``'M'`` or ``'m'`` on both the reactant and product sides of the equation.
|
||||||
|
|
||||||
|
Some examples from GRI-Mech 3.0 are shown below::
|
||||||
|
|
||||||
|
three_body_reaction( "2 O + M <=> O2 + M", [1.20000E+17, -1, 0],
|
||||||
|
" AR:0.83 C2H6:3 CH4:2 CO:1.75 CO2:3.6 H2:2.4 H2O:15.4 ")
|
||||||
|
|
||||||
|
three_body_reaction( "O + H + M <=> OH + M", [5.00000E+17, -1, 0],
|
||||||
|
efficiencies = " AR:0.7 C2H6:3 CH4:2 CO:1.5 CO2:2 H2:2 H2O:6 ")
|
||||||
|
|
||||||
|
three_body_reaction(
|
||||||
|
equation = "H + OH + M <=> H2O + M",
|
||||||
|
rate_coeff = [2.20000E+22, -2, 0],
|
||||||
|
efficiencies = " AR:0.38 C2H6:3 CH4:2 H2:0.73 H2O:3.65 "
|
||||||
|
)
|
||||||
|
|
||||||
|
As always, the field names are optional *if* the field values are entered in the
|
||||||
|
declaration order.
|
||||||
|
|
||||||
|
Falloff Reactions
|
||||||
|
=================
|
||||||
|
|
||||||
|
A *falloff reaction* is one that has a rate that is first-order in [M] at low
|
||||||
|
pressure, like a three-body reaction, but becomes zero-order in [M] as [M]
|
||||||
|
increases. Dissociation / association reactions of polyatomic molecules often
|
||||||
|
exhibit this behavior.
|
||||||
|
|
||||||
|
The simplest expression for the rate coefficient for a falloff reaction is the
|
||||||
|
Lindemann form [Lindemann, 1922]:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
k_f(T, [{\rm M}]) = \frac{k_0[{\rm M}]}{1 + \frac{k_0{\rm [M]}}{k_\infty}}
|
||||||
|
|
||||||
|
In the low-pressure limit, this approaches :math:`k0{\rm [M]}`, and in the
|
||||||
|
high-pressure limit it approaches :math:`k_\infty`.
|
||||||
|
|
||||||
|
Defining the non-dimensional reduced pressure:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
P_r = \frac{k_0 {\rm [M]}}{k_\infty}
|
||||||
|
|
||||||
|
The rate constant may be written as
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
k_f(T, P_r) = k_\infty \left(\frac{P_r}{1 + P_r}\right)
|
||||||
|
|
||||||
|
More accurate models for unimolecular processes lead to other, more complex,
|
||||||
|
forms for the dependence on reduced pressure. These can be accounted for by
|
||||||
|
multiplying the Lindemann expression by a function :math:`F(T, P_r)`:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
k_f(T, P_r) = k_\infty \left(\frac{P_r}{1 + P_r}\right) F(T, P_r)
|
||||||
|
|
||||||
|
This expression is used to compute the rate coefficient for falloff
|
||||||
|
reactions. The function :math:`F(T, P_r)` is the *falloff function*, and is
|
||||||
|
specified by assigning an embedded entry to the ``falloff`` field.
|
||||||
|
|
||||||
|
The Troe Falloff Function
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
A widely-used falloff function is the one proposed by Gilbert et al. [1983]:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
\log_{10} F(T, P_r) = \frac{\log_{10} F_{cent}(T)}{1 + f_1^2}
|
||||||
|
|
||||||
|
F_{cent}(T) = (1-A) \exp(-T/T_3) + A \exp (-T/T_1) + \exp(-T_2/T)
|
||||||
|
|
||||||
|
f_1 = (\log_{10} P_r + C) / (N - 0.14 (\log_{10} P_r + C))
|
||||||
|
|
||||||
|
C = -0.4 - 0.67\; \log_{10} F_{cent}
|
||||||
|
|
||||||
|
N = 0.75 - 1.27\; \log_{10} F_{cent}
|
||||||
|
|
||||||
|
The :class:`Troe` directive requires specifying the first three parameters
|
||||||
|
:math:`(A, T_3, T_1)`. The fourth paramteter, :math:`T_2`, is optional, defaulting to 0.0.
|
||||||
|
|
||||||
|
The SRI Falloff Function
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
This falloff function is based on the one originally due to Stewart et
|
||||||
|
al. [1989], which required three parameters :math:`(a, b, c)`. Kee et al. [1989]
|
||||||
|
generalized this function slightly by adding two more parameters :math:`(d,
|
||||||
|
e)`. (The original form corresponds to :math:`d = 1, e = 0`.) Cantera supports
|
||||||
|
the extended 5-parameter form, given by:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
F(T, P_r) = d \bigl[a \exp(-b/T) + \exp(-T/c)\bigr]^{1/(1+\log_{10}^2 P_r )} T^e
|
||||||
|
|
||||||
|
In keeping with the nomenclature of [Kee et al., 1989], we will refer to this as
|
||||||
|
the "SRI" falloff function. It is implemented by the :class:`SRI` directive.
|
||||||
|
|
||||||
|
.. :: NOTE: "definingphases.pdf" contains documentation for the Wang-Frenklach falloff
|
||||||
|
function, which has a C++ implementation, but doesn't appear to be implemented
|
||||||
|
in the CTI or CTML parsers.
|
||||||
|
|
||||||
225
doc/sphinx/cti/species.rst
Normal file
225
doc/sphinx/cti/species.rst
Normal file
|
|
@ -0,0 +1,225 @@
|
||||||
|
.. py:currentmodule:: ctml_writer
|
||||||
|
|
||||||
|
.. _sec-species:
|
||||||
|
|
||||||
|
********************
|
||||||
|
Elements and Species
|
||||||
|
********************
|
||||||
|
|
||||||
|
.. _sec-elements:
|
||||||
|
|
||||||
|
Elements
|
||||||
|
========
|
||||||
|
|
||||||
|
The element entry defines an element or an isotope of an element. Note that
|
||||||
|
these entries are not often needed, since the the database file ``elements.xml``
|
||||||
|
is searched for element definitions when importing phase and interface
|
||||||
|
definitions. An explicit element entry is needed only if an isotope not in
|
||||||
|
``elements.xml`` is required::
|
||||||
|
|
||||||
|
element(symbol='C-13',
|
||||||
|
atomic_mass=13.003354826)
|
||||||
|
element("O-!8", 17.9991603)
|
||||||
|
|
||||||
|
Species
|
||||||
|
=======
|
||||||
|
|
||||||
|
For each species, a :class:`species` entry is required. Species are defined at
|
||||||
|
the top-level of the input file---their definitions are not embedded in a phase
|
||||||
|
or interface entry.
|
||||||
|
|
||||||
|
Species Name
|
||||||
|
------------
|
||||||
|
|
||||||
|
The name field may contain embedded parentheses, ``+`` or ``-`` signs to
|
||||||
|
indicate the charge, or just about anything else that is printable and not a
|
||||||
|
reserved character in XML. Some example name specifications::
|
||||||
|
|
||||||
|
name = 'CH4'
|
||||||
|
name = 'methane'
|
||||||
|
name = 'argon_2+'
|
||||||
|
name = 'CH2(singlet)'
|
||||||
|
|
||||||
|
Elemental Composition
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
The elemental composition is specified in the atoms entry, as follows::
|
||||||
|
|
||||||
|
atoms = "C:1 O:2" # CO2
|
||||||
|
atoms = "C:1, O:2" # CO2 with optional comma
|
||||||
|
atoms = "Y:1 Ba:2 Cu:3 O:6.5" # stoichiometric YBCO
|
||||||
|
atoms = "" # a surface species representing an empty site
|
||||||
|
atoms = "Ar:1 E:-2" # Ar++
|
||||||
|
|
||||||
|
For gaseous species, the elemental composition is well-defined, since the
|
||||||
|
species represent distinct molecules. For species in solid or liquid solutions,
|
||||||
|
or on surfaces, there may be several possible ways of defining the species. For
|
||||||
|
example, an aqueous species might be defined with or without including the water
|
||||||
|
molecules in the solvation cage surrounding it.
|
||||||
|
|
||||||
|
For surface species, it is possible to omit the ``atoms`` field entirely, in
|
||||||
|
which case it is composed of nothing, and represents an empty surface site. This
|
||||||
|
can also be done to represent vacancies in solids. A charged vacancy can be
|
||||||
|
defined to be composed solely of electrons::
|
||||||
|
|
||||||
|
species(name = 'ysz-oxygen-vacancy',
|
||||||
|
atoms = 'O:0, E:2',
|
||||||
|
...)
|
||||||
|
|
||||||
|
Note that an atom number of zero may be given if desired, but is completely
|
||||||
|
equivalent to omitting that element.
|
||||||
|
|
||||||
|
The number of atoms of an element must be non-negative, except for the special
|
||||||
|
"element" ``E`` that represents an electron.
|
||||||
|
|
||||||
|
Thermodynamic Properties
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
The :class:`phase` and :class:`ideal_interface` entries discussed in the last
|
||||||
|
chapter implement specific models for the thermodynamic properties appropriate
|
||||||
|
for the type of phase or interface they represent. Although each one may use
|
||||||
|
different expressions to compute the properties, they all require thermodynamic
|
||||||
|
property information for the individual species. For the phase types implemented
|
||||||
|
at present, the properties needed are:
|
||||||
|
|
||||||
|
1. the molar heat capacity at constant pressure :math:`\hat{c}^0_p(T)` for a
|
||||||
|
range of temperatures and a reference pressure :math:`P_0`;
|
||||||
|
2. the molar enthalpy :math:`\hat{h}(T_0, P_0)` at :math:`P_0` and a reference
|
||||||
|
temperature :math:`T_0`;
|
||||||
|
3. the absolute molar entropy :math:`\hat{s}(T_0, P_0)` at :math:`(T_0, P_0)`.
|
||||||
|
|
||||||
|
See: :ref:`sec-thermo-models`
|
||||||
|
|
||||||
|
Species Transport Coefficients
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
Transport property models in general require coefficients that express the
|
||||||
|
effect of each species on the transport properties of the phase. The
|
||||||
|
``transport`` field may be assigned an embedded entry that provides
|
||||||
|
species-specific coefficients.
|
||||||
|
|
||||||
|
Currently, the only entry type is :class:`gas_transport`, which supplies
|
||||||
|
parameters needed by the ideal-gas transport property models. The field values
|
||||||
|
and their units of the :class:`gas_transport` entry are compatible with the
|
||||||
|
transport database parameters described by Kee et al. [1986]. Entries in
|
||||||
|
transport databases in the format described in their report can be used directly
|
||||||
|
in the fields of the :class:`gas_transport` entry, without requiring any unit
|
||||||
|
conversion. The numeric field values should all be entered as pure numbers, with
|
||||||
|
no attached units string.
|
||||||
|
|
||||||
|
.. _sec-thermo-models:
|
||||||
|
|
||||||
|
Thermodynamic Property Models
|
||||||
|
=============================
|
||||||
|
|
||||||
|
The entry types described in this section can be used to provide data for the
|
||||||
|
``thermo`` field of a :class:`species`. Each implements a different
|
||||||
|
*parameterization* (functional form) for the heat capacity. Note that there is
|
||||||
|
no requirement that all species in a phase use the same parameterization; each
|
||||||
|
species can use the one most appropriate to represent how the heat capacity
|
||||||
|
depends on temperature.
|
||||||
|
|
||||||
|
Currently, three entry types are implemented, all of which provide species
|
||||||
|
properties appropriate for models of ideal gas mixtures, ideal solutions, and
|
||||||
|
pure compounds. Non-ideal phase models are not yet implemented, but may be in
|
||||||
|
future releases. When they are, additional entry types may also be added that
|
||||||
|
provide species-specific coefficients required by specific non-ideal equations
|
||||||
|
of state.
|
||||||
|
|
||||||
|
The NASA Polynomial Parameterization
|
||||||
|
------------------------------------
|
||||||
|
|
||||||
|
The NASA polynomial parameterization is used to compute the species
|
||||||
|
reference-state thermodynamic properties :math:`\hat{c}^0_p(T)`,
|
||||||
|
:math:`\hat{h}^0(T)` and :math:`\hat{s}^0(T)`.
|
||||||
|
|
||||||
|
The NASA parameterization represents :math:`\hat{c}^0_p(T)` with a fourth-order
|
||||||
|
polynomial:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
\frac{c_p^0(T)}{R} = a_0 + a_1 T + a_2 T^2 + a_3 T^3 + a_4 T^4
|
||||||
|
|
||||||
|
\frac{h^0(T)}{RT} = a_0 + \frac{a1}{2}T + \frac{a_2}{3} T^2 +
|
||||||
|
\frac{a_3}{4} T^3 + \frac{a_4}{5} T^4 + a_5
|
||||||
|
|
||||||
|
\frac{s^0(T)}{R} = a_o \ln T + a_1 T + \frac{a_2}{2} T^2 + \frac{a_3}{3} T^3 +
|
||||||
|
\frac{a_4}{4} T^4 + a_6
|
||||||
|
|
||||||
|
Note that this is the "old" NASA polynomial form, used in the original NASA
|
||||||
|
equilibrium program and in Chemkin. It is not compatible with the form used in
|
||||||
|
the most recent version of the NASA equilibrium program, which uses 9
|
||||||
|
coefficients, not 7.
|
||||||
|
|
||||||
|
A NASA parameterization is defined by an embedded :class:`NASA` entry. Very
|
||||||
|
often, two NASA parameterizations are used for two contiguous temperature
|
||||||
|
ranges. This can be specified by assigning the ``thermo`` field of the
|
||||||
|
``species`` entry a sequence of two :class:`NASA` entries::
|
||||||
|
|
||||||
|
# use one NASA parameterization for T < 1000 K, and another for T > 1000 K.
|
||||||
|
species(name = "O2",
|
||||||
|
atoms = " O:2 ",
|
||||||
|
thermo = (
|
||||||
|
NASA( [ 200.00, 1000.00], [ 3.782456360E+00, -2.996734160E-03,
|
||||||
|
9.847302010E-06, -9.681295090E-09, 3.243728370E-12,
|
||||||
|
-1.063943560E+03, 3.657675730E+00] ),
|
||||||
|
NASA( [ 1000.00, 3500.00], [ 3.282537840E+00, 1.483087540E-03,
|
||||||
|
-7.579666690E-07, 2.094705550E-10, -2.167177940E-14,
|
||||||
|
-1.088457720E+03, 5.453231290E+00] ) ) )
|
||||||
|
|
||||||
|
The Shomate Parameterization
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
The Shomate parameterization is:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
\hat{c}_p^0(T) = A + Bt + Ct^2 + Dt^3 | \frac{E}{t^2}
|
||||||
|
|
||||||
|
\hat{h}^0(T) = At + \frac{Bt^2}{2} + \frac{Ct^3}{3} + \frac{Dt^4}{4} -
|
||||||
|
\frac{E}{t} + F
|
||||||
|
|
||||||
|
\hat{s}^0(T) = A \ln t + B t + \frac{Ct^2}{2} + \frac{Dt^3}{3} -
|
||||||
|
\frac{E}{2t^2} + G
|
||||||
|
|
||||||
|
where :math:`t = T / 1000 K`. It requires 7 coefficients A, B, C, D, E, F, and
|
||||||
|
G. This parameterization is used to represent reference-state properties in the
|
||||||
|
`NIST Chemistry WebBook <http://webbook.nist.gov/chemistry>`_. The values of the
|
||||||
|
coefficients A through G should be entered precisely as shown there, with no
|
||||||
|
units attached. Unit conversions to SI will be handled internally.
|
||||||
|
|
||||||
|
Example usage of the :class:`shomate` directive::
|
||||||
|
|
||||||
|
# use a single Shomate parameterization.
|
||||||
|
species(name = "O2",
|
||||||
|
atoms = " O:2 ",
|
||||||
|
thermo = Shomate( [298.0, 6000.0],
|
||||||
|
[29.659, 6.137261, -1.186521, 0.09578, -0.219663,
|
||||||
|
-9.861391, 237.948] ) )
|
||||||
|
|
||||||
|
Constant Heat Capacity
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
In some cases, species properties may only be required at a single temperature
|
||||||
|
or over a narrow temperature range. In such cases, the heat capacity can be
|
||||||
|
approximated as constant, and simpler expressions used for the thermodynamic
|
||||||
|
properties. The :class:`const_cp` parameterization computes the properties as
|
||||||
|
follows:
|
||||||
|
|
||||||
|
.. math::
|
||||||
|
|
||||||
|
\hat{c}_p^0(T) = \hat{c}_p^0(T_0)
|
||||||
|
|
||||||
|
\hat{h}^0(T) = \hat{h}^0(T_0) + \hat{c}_p^0\cdot(T-T_0)
|
||||||
|
|
||||||
|
\hat{s}^0(T) = \hat{s}^0(T_0) + \hat{c}_p^0 \ln (T/T_0)
|
||||||
|
|
||||||
|
The parameterization uses four constants: :math:`T_0, \hat{c}_p^0(T_0),
|
||||||
|
\hat{h}^0(T_0), \hat{s}^0(T)`.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
thermo = const_cp( t0 = 1200.0,
|
||||||
|
h0 = (-5.0, 'kcal/mol') )
|
||||||
|
|
||||||
|
.. See ##REF## for more examples of use of this parameterization.
|
||||||
|
|
@ -12,7 +12,7 @@ Contents
|
||||||
|
|
||||||
Compiliation Instructions <compiling>
|
Compiliation Instructions <compiling>
|
||||||
|
|
||||||
defining-phases
|
cti/index
|
||||||
|
|
||||||
python/index
|
python/index
|
||||||
C++ Introduction <cxx-intro>
|
C++ Introduction <cxx-intro>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue