From charlesreid1

No edit summary
 
(16 intermediate revisions by the same user not shown)
Line 3: Line 3:
CTI files use a custom markup language to specify information about the kinetics.
CTI files use a custom markup language to specify information about the kinetics.


=Division of CTI Files=
(You may also be interested in reading the [[Chemkin]] page.)


The file can be divided into multiple parts:
* Phase specification
* Species
** Gas species
** Surface species
* Reactions
** Gas reactions
** Surface reactions


=Units Specification=


The units are the first thing defined in the file:
A CTI file must specify information about three things:
* Phases - [[Cantera/CTI Files/Phases]]
* Species - [[Cantera/CTI Files/Species]]
* Reactions - [[Cantera/CTI Files/Reactions]]


<pre>
units(length = "cm", time = "s", quantity = "mol", act_energy = "J/mol")
</pre>


=Phase Specification=


==Gas==
=Units Specification=


<pre>
The units are the first thing defined in the file:
ideal_gas(name = "gas",
        elements = "O H C N Ar",
        species = """gri30: 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 AR N2""",
          transport = 'Mix',
          reactions = 'gri30: all',
          options = ['skip_undeclared_elements',
                    'skip_undeclared_species'],
          initial_state = state(temperature = 300.0, pressure = OneAtm,
                                mole_fractions = 'CH4:0.095, O2:0.21, AR:0.79')
          )
</pre>
 
==Interface (Surface)==


<pre>
<pre>
ideal_interface(name = "Pt_surf",
units(length = "cm", time = "s", quantity = "mol", act_energy = "J/mol")
                elements = " Pt  H  O  C ",
                species = """ PT(S) H(S)
H2O(S)  OH(S)  CO(S)  CO2(S)  CH3(S)
                CH2(S)s CH(S)  C(S)  O(S) """,
                phases = "gas",
                site_density = 2.7063e-9,
                reactions = "all",
                initial_state = state(temperature = 900.0,
                                      coverages = 'O(S):0.0, PT(S):0.5, H(S):0.5')
                )
</pre>
</pre>


=Species Specification=
=Phases=


<pre>
Information about specifying phases in Cantera input file here: [[Cantera/CTI Files/Phases]]
species(name = "CH3OCHO",
    atoms = " C:2  H:4  O:2 ",
    thermo = (
      NASA( [ 300.00,  1452.00], [ 2.435262000E+00,  1.819483250E-02,
                1.912365900E-06,  -8.442489450E-09,  2.617589100E-12,
              -4.465147320E+04,  1.495222650E+01] ),
      NASA( [ 1452.00,  5000.00], [  1.065691850E+01,  9.381127230E-03,
              -3.376772060E-06,  5.424555960E-10,  -3.222953300E-14,
              -4.846517580E+04,  -3.275794430E+01] )
            ),
    transport = gas_transport(
                    geom = "nonlinear",
                    diam = 4.037,
                    well_depth = 395,
                    dipole = 1.3,
                    rot_relax = 1),
    note = "4/15/ 8 THERM"
      )
</pre>
 
=Reaction Specification=
 
==Gas Reactions==
 
An example gas reaction CTI file is located at <code>cantera/data/inputs/h2o2.cti</code>.


In general, the gas phase reaction rate can be modeled as:
=Species=


<math>
Information about specifying species in Cantera input files here: [[Cantera/CTI Files/Species]]
r_{j} = k_j \sum_{i} \nu_{ij} c_{i}^{n_{ij}}
</math>


where <math>\nu_{ij}</math> is the stoichiometric coefficient for species i in reaction j, <math>c_i</math> is the molar concentration of species i, and <math>n_{ij}</math> is the order of reaction j with respect to species i.
=Reactions=


===Arrhenius Gas Kinetics===
Information about specifying reactions in Cantera input files here: [[Cantera/CTI Files/Reactions]]


The standard way to model reaction kinetics in the gas phase is to use Arrhenius kinetics. This models the reaction rate constant <math>k_j</math> as:
=CTI-Related Code=


<math>
==Conversion of Chemkin Files to CTI==
k_j = A_j T^{b_j} \exp \left( - \dfrac{ E_j }{ RT } \right)
</math>


where the Arrhenius reaction parameters are:
CTI files can be generated from the ck2cti2 app, contained in <code>cantera/src/apps/ck2cti.cpp</code>, which is a command-line utility to turn Chemkin-II reaction mechanism files, as well as transport and thermodynamic database files, into a CTI file.
* <math>A_j</math> - Arrhenius parameter pre-exponential factor
* <math>b_j</math> - Arrhenius parameter, degree of temperature influence on kinetic rate constant
* <math>E_j</math> - Arrhenius parameter, activation energy of reaction


These quantities can be specified in a CTI file as follows:
Here is the description of the utility:  


<pre>
<pre>
reaction( "A + B => C + D",  [A, b, E] )
ck2cti.py: Convert Chemkin-format mechanisms to Cantera input files (.cti)
</pre>


and the units of each are:
If the output file name is not given, an output file with the same name as the
* <math>A_j</math> - specified in units of <math>\frac{ \text{cm}^3 }{ \text{mol} \cdot \text{s} }</math>
input file, with the extension changed to '.cti'.
* <math>b_j</math> - dimensionless
* <math>E_j</math> - specified in units of <math>\frac{ \text{cal} }{ \text{mol} }</math>


====Arrhenius Gas Kinetics Example====
Usage:
    ck2cti --input=<filename>
          [--thermo=<filename>]
          [--transport=<filename>]
          [--id=<phase-id>]
          [--output=<filename>]
          [-d | --debug]


'''Example:'''
Example:
 
    ck2cti --input=chem.inp --thermo=therm.dat --transport=tran.dat
Specify the reaction
 
<math>
\text{H} + \text{O}_2 \rightarrow \text{O} + \text{OH}
</math>
 
which has the following parameter values:
 
<math>
A = 3.54700E+15 \quad \frac{ \text{cm}^3 }{ \text{mol} \cdot \text{s} }
</math>
 
<math>
b = -0.406
</math>
 
<math>
E = 16599 \quad \frac{ \text{cal} }{ \text{mol} }
</math>
 
'''Result:'''
 
<pre>
reaction(  "H + O2 <=> O + OH",  [3.54700E+15, -0.406, 16599])
</pre>
</pre>


====Arrhenius Gas Kinetics Code====
So to use this, I could run the command:
 
More information on what blocks of code process this stuff from the CTI file.
 
===Three-Body Gas Reactions===
 
A three body gas reaction is... I don't know.


<pre>
<pre>
three_body_reaction( "H2 + M <=> H + H + M",  [4.57700E+19, -1.4, 104380],
ck2cti2 --input=input.file --thermo=thermo.file --transport=transport.file --id=phaseid --output=myfile.cti
        efficiencies = " AR:0  CO:1.9  CO2:3.8  H2:2.5  H2O:12  HE:0 ")
</pre>
</pre>


====Three Body Gas Reactions Example====
where input is a Chemkin II reaction mechanism file (the meat of the CTI file), thermo is a file in which to look for thermodynamic data if there is no THERMO section of the Chemkin input file, transport is a file in which to look for transport data (no transport data is put into the final CTI file if this is left off), and phaseid is a string name to give to the phase created in the new CTI file.


It would help if I could figure out what this reaction type is, before putting together an example.
==Conversion of CTI to XML==


====Three Body Gas Reactions Code====
Once you have a CTI file (generated by hand, from a modified example, or from a Chemkin input file), the CTI file is then turned into an XML file, which is ultimately the format used by Cantera. This conversion is performed by the ct2ctml app, which is in <code>cantera/src/base/ct2ctml.cpp</code>. This code, in turn, creates a direct call from C++ to Python.


When Cantera processes a CTI file, it determines what kind of kinetics object to use. If the kinetics is for a gas phase, the object is a GasKinetics object. The GasKinetics object has a <code>GasKinetics::addReaction()</code> method, which is run for each reaction in the CTI file:
In <code>ct2ctml.cpp</code>, the following code block illustrates the call to Python to convert a CTI file to an XML file:


<source lang="cpp">
<source lang="cpp">
void GasKinetics::
    try {
addReaction(ReactionData& r)
        exec_stream_t python;
{
        python.set_wait_timeout(exec_stream_t::s_all, 1800000); // 30 minutes
    switch (r.reactionType) {
        python.start(pypath(), "-i");
    case ELEMENTARY_RXN:
        stringstream output_stream;
        addElementaryReaction(r);
        python.in() <<
        break;
            "if True:\n" << // Use this so that the rest is a single block
    case THREE_BODY_RXN:
            "    import sys\n" <<
         addThreeBodyReaction(r);
            "    sys.stderr = sys.stdout\n" <<
         break;
            "    import ctml_writer\n" <<
    case FALLOFF_RXN:
            "    ctml_writer.convert(r'" << file << "')\n" <<
         addFalloffReaction(r);
            "    sys.exit(0)\n\n"
        break;
            "sys.exit(7)\n";
    case PLOG_RXN:
         python.close_in();
        addPlogReaction(r);
         std::string line;
        break;
         while (python.out().good()) {
    case CHEBYSHEV_RXN:
            std::getline(python.out(), line);
         addChebyshevReaction(r);
            output_stream << line << std::endl;;
         break;
        }
    default:
         python.close();
         throw CanteraError("GasKinetics::addReaction", "Invalid reaction type specified");
         python_exit_code = python.exit_code();
     }
         python_output = stripws(output_stream.str());
     } catch (std::exception& err) {
</source>
</source>


The three body reaction computation is set up in <code>GasKinetics::addThreeBodyReaction</code>:
This C++ code is actually calling the Python code that will do the conversion, using routines defined in <code>cantera/interfaces/python/ctml_writer.py</code>.


<source lang="cpp">
The two lines of Python code that it calls consist of one import statement, and one call to convert the file:
void GasKinetics::
addThreeBodyReaction(ReactionData& r)
{
    // install rate coeff calculator
    size_t iloc = m_rates.install(reactionNumber(), r);


    // add constant term to rate coeff value vector
<source lang="python">
    m_rfn.push_back(r.rateCoeffParameters[0]);
import ctml_writer
 
ctml_writer.convert( [file] )
    // forward rxn order equals number of reactants + 1
    m_fwdOrder.push_back(r.reactants.size() + 1);
 
    m_3b_concm.install(reactionNumber(), r.thirdBodyEfficiencies,
                      r.default_3b_eff);
    registerReaction(reactionNumber(), THREE_BODY_RXN, iloc);
}
</source>
</source>


===Falloff Gas Reactions===
The call to <code>ctml_writer</code> references the Python routines located in <code>cantera/interfaces/python/ctml_writer.py</code>, which interprets the CTI file and turns it into an XML file.
 
<pre>
falloff_reaction( "H + O2 (+ M) <=> HO2 (+ M)",
        kf = [1.47500E+12, 0.6, 0],
        kf0  = [6.36600E+20, -1.72, 524.8],
        falloff = Troe(A = 0.8, T3 = 1e-30, T1 = 1e+30),
        efficiencies = " CO:1.9  CO2:3.8  H2:2  H2O:11  O2:0.78 ")
</pre>
 
====Falloff Gas Reaction Example====
 
====Falloff Gas Reaction Code====
 
===Other Gas Reaction Options===
 
Duplicate is the only option I see:
 
<pre>
reaction(  "HO2 + HO2 <=> H2O2 + O2",  [1.30000E+11, 0, -1629.3],
        options = ["duplicate"])
</pre>
 
==Surface Reactions==
 
Any surface reaction can be specified in the cti file using the <code>surface_reaction</code> function. The usage depends on the surface reaction form.
 
There are a variety of forms of surface reactions, each with a different specification method.
 
An example surface reaction CTI file is located at <code>cantera/data/inputs/ptcombust.cti</code>.
 
===Arrhenius Surface Kinetics===
 
The plain/default way, which uses Arrhenius kinetics:
 
<pre>
surface_reaction( "A(s) => B(s) + C",  [A, b, E])
</pre>
 
where:
* A(s), B(s), C - species whose properties are defined in the species section (see above)
* A - Arrhenius parameter, pre-exponential factor (specified in units of...)
* b - Arrhenius parameter, degree of temperature influence on kinetic rate constant
* E - Arrhenius parameter, activation energy of reaction
 
The Arrhenius expression is:
 
<math>
k = A T^b \exp \left( \frac{E}{RT} \right)
</math>
 
====Arrhenius Surface Kinetics Example====


A catalytic reaction where H2O (adsorbed onto a platinum surface) desorbs would look like this:
Looking through the <code>ctml_writer.py</code> code, you can see that it starts at the <code>convert()</code> method. The convert method then moves to the <code>write()</code> method, where it builds each piece of information specified in the CTI into an XML data structure. Finally, that data structure is written to an XML file.


<pre>
surface_reaction( "H2O(S) => H2O + PT(S)",  [1.00000E+13, 0, 40300])
</pre>
====Arrhenius Surface Kinetics Code====
Not sure where this is dealt with in the Cantera code.
===Surface Reactions with Coverage-Dependent Rates===
Still working through this coverage dependency.
This uses some kind of expression containing a, m, and e.
<pre>
surface_reaction( "A(s) => B(s) + C", Arrhenius(A, b, E, coverage=['A(s)', surface_a, surface_m, surface_e])
</pre>
Attempting to uncover how this is dealt with:
<pre>
importKinetics::getCoverageDependence()
rdata.cov vector contains coverage-related parameters/information
rdata.cov.push_back(species_index)
rdata.cov.push_back(a)
rdata.cov.push_back(m)
rdata.cov.push_back(e)
</pre>
and then
<pre>
InterfaceKinetics::addElementaryReaction
if r.cov.size > 3:
    this rxn is dependent on coverage
register rxn
</pre>
===Surface Reactions with Sticking Equations===
No idea how this works.
<pre>
surface_reaction( "A + B(s) => C + D(s)",  stick(1.00000E+00, 0, 0))
</pre>
====Sticking Surface Reactions Example====
<pre>
surface_reaction( "OH + PT(S) => OH(S)",  stick(1.00000E+00, 0, 0))
</pre>
====Sticking Surface Reactions Code====
Dunno
===Surface Reactions with Falloff===
No idea.
===Surface Reactions with Duplicate Reactions===
<pre>
surface_reaction( "O2 + 2 PT(S) => 2 O(S)",  Arrhenius(1.80000E+21, -0.5, 0),
                  options = 'duplicate')
</pre>


=Flags=


[[Category:Cantera]]
{{CanteraFlag}}

Latest revision as of 08:43, 17 April 2017

CTI = CanTera Input file

CTI files use a custom markup language to specify information about the kinetics.

(You may also be interested in reading the Chemkin page.)


A CTI file must specify information about three things:


Units Specification

The units are the first thing defined in the file:

units(length = "cm", time = "s", quantity = "mol", act_energy = "J/mol")

Phases

Information about specifying phases in Cantera input file here: Cantera/CTI Files/Phases

Species

Information about specifying species in Cantera input files here: Cantera/CTI Files/Species

Reactions

Information about specifying reactions in Cantera input files here: Cantera/CTI Files/Reactions

CTI-Related Code

Conversion of Chemkin Files to CTI

CTI files can be generated from the ck2cti2 app, contained in cantera/src/apps/ck2cti.cpp, which is a command-line utility to turn Chemkin-II reaction mechanism files, as well as transport and thermodynamic database files, into a CTI file.

Here is the description of the utility:

ck2cti.py: Convert Chemkin-format mechanisms to Cantera input files (.cti)

If the output file name is not given, an output file with the same name as the
input file, with the extension changed to '.cti'.

Usage:
    ck2cti --input=<filename>
           [--thermo=<filename>]
           [--transport=<filename>]
           [--id=<phase-id>]
           [--output=<filename>]
           [-d | --debug]

Example:
    ck2cti --input=chem.inp --thermo=therm.dat --transport=tran.dat

So to use this, I could run the command:

ck2cti2 --input=input.file --thermo=thermo.file --transport=transport.file --id=phaseid --output=myfile.cti

where input is a Chemkin II reaction mechanism file (the meat of the CTI file), thermo is a file in which to look for thermodynamic data if there is no THERMO section of the Chemkin input file, transport is a file in which to look for transport data (no transport data is put into the final CTI file if this is left off), and phaseid is a string name to give to the phase created in the new CTI file.

Conversion of CTI to XML

Once you have a CTI file (generated by hand, from a modified example, or from a Chemkin input file), the CTI file is then turned into an XML file, which is ultimately the format used by Cantera. This conversion is performed by the ct2ctml app, which is in cantera/src/base/ct2ctml.cpp. This code, in turn, creates a direct call from C++ to Python.

In ct2ctml.cpp, the following code block illustrates the call to Python to convert a CTI file to an XML file:

    try {
        exec_stream_t python;
        python.set_wait_timeout(exec_stream_t::s_all, 1800000); // 30 minutes
        python.start(pypath(), "-i");
        stringstream output_stream;
        python.in() <<
            "if True:\n" << // Use this so that the rest is a single block
            "    import sys\n" <<
            "    sys.stderr = sys.stdout\n" <<
            "    import ctml_writer\n" <<
            "    ctml_writer.convert(r'" << file << "')\n" <<
            "    sys.exit(0)\n\n"
            "sys.exit(7)\n";
        python.close_in();
        std::string line;
        while (python.out().good()) {
            std::getline(python.out(), line);
            output_stream << line << std::endl;;
        }
        python.close();
        python_exit_code = python.exit_code();
        python_output = stripws(output_stream.str());
    } catch (std::exception& err) {

This C++ code is actually calling the Python code that will do the conversion, using routines defined in cantera/interfaces/python/ctml_writer.py.

The two lines of Python code that it calls consist of one import statement, and one call to convert the file:

import ctml_writer
ctml_writer.convert( [file] )

The call to ctml_writer references the Python routines located in cantera/interfaces/python/ctml_writer.py, which interprets the CTI file and turns it into an XML file.

Looking through the ctml_writer.py code, you can see that it starts at the convert() method. The convert method then moves to the write() method, where it builds each piece of information specified in the CTI into an XML data structure. Finally, that data structure is written to an XML file.


Flags