From charlesreid1

CTI = CanTera Input file

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

Division of CTI Files

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:

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

Phase Specification

Gas

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')
          )

Interface (Surface)

ideal_interface(name = "Pt_surf",
                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')
                )

Species Specification

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"
       )

Reaction Specification

Gas Reactions

An example gas reaction CTI file is located at cantera/data/inputs/h2o2.cti.

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

$ r_{j} = k_j \sum_{i} \nu_{ij} c_{i}^{n_{ij}} $

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

Arrhenius Gas Kinetics

The standard way to model reaction kinetics in the gas phase is to use Arrhenius kinetics. This models the reaction rate constant $ k_j $ as:

$ k_j = A_j T^{b_j} \exp \left( - \dfrac{ E_j }{ RT } \right) $

where the Arrhenius reaction parameters are:

  • $ A_j $ - Arrhenius parameter pre-exponential factor
  • $ b_j $ - Arrhenius parameter, degree of temperature influence on kinetic rate constant
  • $ E_j $ - Arrhenius parameter, activation energy of reaction

These quantities can be specified in a CTI file as follows:

reaction(  "A + B => C + D",  [A, b, E] )

and the units of each are:

  • $ A_j $ - specified in units of $ \frac{ \text{cm}^3 }{ \text{mol} \cdot \text{s} } $
  • $ b_j $ - dimensionless
  • $ E_j $ - specified in units of $ \frac{ \text{cal} }{ \text{mol} } $

Arrhenius Gas Kinetics Example

Example:

Specify the reaction

$ \text{H} + \text{O}_2 \rightarrow \text{O} + \text{OH} $

which has the following parameter values:

$ A = 3.54700E+15 \quad \frac{ \text{cm}^3 }{ \text{mol} \cdot \text{s} } $

$ b = -0.406 $

$ E = 16599 \quad \frac{ \text{cal} }{ \text{mol} } $

Result:

reaction(  "H + O2 <=> O + OH",  [3.54700E+15, -0.406, 16599])

Arrhenius Gas Kinetics Code

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.

three_body_reaction( "H2 + M <=> H + H + M",  [4.57700E+19, -1.4, 104380],
         efficiencies = " AR:0  CO:1.9  CO2:3.8  H2:2.5  H2O:12  HE:0 ")

Three Body Gas Reactions Example

It would help if I could figure out what this reaction type is, before putting together an example.

Three Body Gas Reactions Code

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 GasKinetics::addReaction() method, which is run for each reaction in the CTI file:

void GasKinetics::
addReaction(ReactionData& r)
{
    switch (r.reactionType) {
    case ELEMENTARY_RXN:
        addElementaryReaction(r);
        break;
    case THREE_BODY_RXN:
        addThreeBodyReaction(r);
        break;
    case FALLOFF_RXN:
        addFalloffReaction(r);
        break;
    case PLOG_RXN:
        addPlogReaction(r);
        break;
    case CHEBYSHEV_RXN:
        addChebyshevReaction(r);
        break;
    default:
        throw CanteraError("GasKinetics::addReaction", "Invalid reaction type specified");
    }

The three body reaction computation is set up in GasKinetics::addThreeBodyReaction:

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
    m_rfn.push_back(r.rateCoeffParameters[0]);

    // 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);
}

Falloff Gas Reactions

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 ")

Falloff Gas Reaction Example

Falloff Gas Reaction Code

Other Gas Reaction Options

Duplicate is the only option I see:

reaction(  "HO2 + HO2 <=> H2O2 + O2",  [1.30000E+11, 0, -1629.3],
         options = ["duplicate"])

Surface Reactions

Any surface reaction can be specified in the cti file using the surface_reaction 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 cantera/data/inputs/ptcombust.cti.

Arrhenius Surface Kinetics

The plain/default way, which uses Arrhenius kinetics:

surface_reaction( "A(s) => B(s) + C",   [A, b, E]) 

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:

$ k = A T^b \exp \left( \frac{E}{RT} \right) $

Arrhenius Surface Kinetics Example

A catalytic reaction where H2O (adsorbed onto a platinum surface) desorbs would look like this:

surface_reaction( "H2O(S) => H2O + PT(S)",   [1.00000E+13, 0, 40300])

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.

surface_reaction( "A(s) => B(s) + C", Arrhenius(A, b, E, coverage=['A(s)', surface_a, surface_m, surface_e])

Attempting to uncover how this is dealt with:

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)

and then

InterfaceKinetics::addElementaryReaction
if r.cov.size > 3:
    this rxn is dependent on coverage
register rxn

Surface Reactions with Sticking Equations

No idea how this works.

surface_reaction( "OH + PT(S) => OH(S)",   stick(1.00000E+00, 0, 0))

Surface Reactions with Falloff

No idea.

Surface Reactions with Duplicate Reactions

surface_reaction( "O2 + 2 PT(S) => 2 O(S)",   Arrhenius(1.80000E+21, -0.5, 0),
                  options = 'duplicate')