Howto: reduced chemistry and Cantera

This page shows step by step how to implement a reduced chemistry description into Cantera.

Paths are relative to the folder containing cantera sources. You should already have a compiled version of Cantera working on your computer (help can be found here or here).

How does it work ?

When creating a gas phase, cantera reads from the cti file a number of flags (ie. transport = mixture averaged diffusion or multicomponent).

We are interested in the kinetics flag, which is not necessarily mentioned (its default value is ‘GasKinetics’).

For this implementation, we create new possible flags in the form of ‘GasKinetics_XX’ where XX is an integer : from 01 to 99.

Example: h2_3s.cti which has the flag ‘GasKinetics_02’

The integer is then passed to the routine computing the rates. If its value is between 1 and 99, it calls the function list.f

list.f is simply a case function and calls the right fortran routine for the computation of the rates (for instance h2_3s.f).

Solution #1:

Download the files provided below.

Replace src/kinetics/GasKinetics.cpp and src/kinetics/GasFactory.cpp
Replace include/cantera/kinetics/GasKinetics.h
Create a folder src/kinetics/ReducedKinetics
copy list.f into this folder.
copy the fortran routines for the rates (depending on the chemistry description)

Edit src/SConscript so that cantera includes the fortran routines when built
after the line        (‘kinetics’, [‘cpp’], defaultSetup),
>>        (‘kinetics/ReducedKinetics’, [‘f’], defaultSetup),
rebuild, reinstall cantera.

Solution #2:

Edit directly the following files (this may be a better solution if the code gets updated).

include/cantera/kinetics/GasKinetics.h
add line after “protected:” in
int ReducedKineticsType;

src/kinetics/GasKinetics.cpp:
After:  namespace Cantera{
>>    extern int chemType;
>>    extern “C” {
>>        void CALL_FORTRAN(reacrates)(doublereal*, doublereal*, const doublereal* , doublereal &, doublereal &, int &);}

In the first constructor:
>>         ReducedKineticsType = chemType;

in the second
>>      ReducedKineticsType(0)

in the third:
>>    ReducedKineticsType = right.ReducedKineticsType;

in void GasKinetics::updateROP()

after update_rates_T()
>>    if (ReducedKineticsType == 0) {

After   m_rxnstoich.multiplyRevProducts(&m_conc[0], &m_ropr[0]);

 >>   }
>>   else{
>>       doublereal T = thermo().temperature();
>>       doublereal P = thermo().pressure();
>>       CALL_FORTRAN(reacrates)( &m_ropf[0], &m_ropr[0], &m_conc[0], P, T, ReducedKineticsType);
}

and so on:
for (size_t i = 0; i < m_rfn.size(); i++) {
AssertFinite(m_rfn[i], “GasKinetics::updateROP”,
“m_rfn[” + int2str(i) + “] is not finite.”);
AssertFinite(m_ropf[i], “GasKinetics::updateROP”,
“m_ropf[” + int2str(i) + “] is not finite.”);
AssertFinite(m_ropr[i], “GasKinetics::updateROP”,
“m_ropr[” + int2str(i) + “] is not finite.”);
}

    m_ROP_ok = true;
}

In src/kinetics/KineticsFactory.cpp:
Along with ntypes, string _types and _itypes declaration (on top):
>>int chemType = 0;

After loop on kin type
>>   if(kintype.substr(0,11) == _types[1]) {
>>        if(kintype.length() > 11){
>>        ikin = _itypes[1];
>>        string mychem_str = kintype.substr(12,2);
>>        chemType = atoi(mychem_str.c_str()) ;
>>        }
>>    }

Similarly, in the second function:

>>    if(model.substr(0,11) == _types[1]) {
>>        if(model.length() > 11){
>>            ikin = _itypes[1];
>>            string mychem_str = model.substr(12,2);
>>            chemType = atoi(mychem_str.c_str()) ;
>>        }
>>    }

In src/SConscript:

after         (‘kinetics’, [‘cpp’], defaultSetup),
>>        (‘kinetics/ReducedKinetics’, [‘f’], defaultSetup),

include folder ReducedKinetics and contents in src/kinetics/.

All cti files into data/inputs

Also in «Reduced chemistry»