diff --git a/doc/sphinx/_static/images/sofc-phases.png b/doc/sphinx/_static/images/sofc-phases.png new file mode 100644 index 000000000..bf3b84d8f Binary files /dev/null and b/doc/sphinx/_static/images/sofc-phases.png differ diff --git a/doc/sphinx/defining-phases.rst b/doc/sphinx/cti/classes.rst similarity index 91% rename from doc/sphinx/defining-phases.rst rename to doc/sphinx/cti/classes.rst index cb3c9fcf0..73a77eb57 100644 --- a/doc/sphinx/defining-phases.rst +++ b/doc/sphinx/cti/classes.rst @@ -1,12 +1,12 @@ -*************** -Defining Phases -*************** -CTI Class Documentation -======================= +******************* +CTI Class Reference +******************* + +.. py:module:: ctml_writer Basic Classes & Functions -------------------------- +========================= .. autofunction:: ctml_writer.units @@ -14,7 +14,7 @@ Basic Classes & Functions :no-undoc-members: Phases of Matter ----------------- +================ .. autoclass:: ctml_writer.phase :no-members: @@ -56,7 +56,7 @@ Phases of Matter :no-undoc-members: Elements and Species --------------------- +==================== .. autoclass:: ctml_writer.element :no-undoc-members: @@ -65,7 +65,7 @@ Elements and Species :no-undoc-members: Thermodynamic Properties ------------------------- +======================== .. autoclass:: ctml_writer.Mu0_table :no-undoc-members: @@ -86,13 +86,13 @@ Thermodynamic Properties :no-undoc-members: Transport Properties --------------------- +==================== .. autoclass:: ctml_writer.gas_transport :no-undoc-members: Reactions ---------- +========= .. autoclass:: ctml_writer.reaction :no-undoc-members: @@ -119,7 +119,7 @@ Reactions :no-undoc-members: Falloff Parameterizations -^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------- .. autoclass:: ctml_writer.Troe :no-undoc-members: diff --git a/doc/sphinx/cti/example-combustion.rst b/doc/sphinx/cti/example-combustion.rst new file mode 100644 index 000000000..9e91f3c04 --- /dev/null +++ b/doc/sphinx/cti/example-combustion.rst @@ -0,0 +1,4 @@ +============================ +Example: Hydrogen Combustion +============================ + diff --git a/doc/sphinx/cti/index.rst b/doc/sphinx/cti/index.rst new file mode 100644 index 000000000..8bc97d645 --- /dev/null +++ b/doc/sphinx/cti/index.rst @@ -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 diff --git a/doc/sphinx/cti/input-files.rst b/doc/sphinx/cti/input-files.rst new file mode 100644 index 000000000..d349f26ce --- /dev/null +++ b/doc/sphinx/cti/input-files.rst @@ -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 `` = ``, 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 + + + O + HCCO [=] H + 2 CO + + + 1.000000E+14 + 0 + 0.000000 + + + HCCO:1 O:1 + H:1 CO:2 + + +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 "", line 1, in + 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`. diff --git a/doc/sphinx/cti/intro.rst b/doc/sphinx/cti/intro.rst new file mode 100644 index 000000000..b40187ef4 --- /dev/null +++ b/doc/sphinx/cti/intro.rst @@ -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. diff --git a/doc/sphinx/cti/phases.rst b/doc/sphinx/cti/phases.rst new file mode 100644 index 000000000..7947a88b3 --- /dev/null +++ b/doc/sphinx/cti/phases.rst @@ -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``). diff --git a/doc/sphinx/cti/reactions.rst b/doc/sphinx/cti/reactions.rst new file mode 100644 index 000000000..1a269245a --- /dev/null +++ b/doc/sphinx/cti/reactions.rst @@ -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. + diff --git a/doc/sphinx/cti/species.rst b/doc/sphinx/cti/species.rst new file mode 100644 index 000000000..576e4c793 --- /dev/null +++ b/doc/sphinx/cti/species.rst @@ -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 `_. 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. diff --git a/doc/sphinx/index.rst b/doc/sphinx/index.rst index 78094a40e..1d180f579 100644 --- a/doc/sphinx/index.rst +++ b/doc/sphinx/index.rst @@ -12,7 +12,7 @@ Contents Compiliation Instructions - defining-phases + cti/index python/index C++ Introduction