Project

1-D flame speed analysis for methane and hydrogen combustion mechanisms using Python and Cantera

INTRODUCTION:

Flame speed is the measured rate of expansion of a flame front in a combustion reaction. While the auto-ignition temperature and ignition delay (0-D analysis) can indicate when the reaction will take place, the flame speed (1-D analysis) is an indicator of how the flame propagates. The flame occupies a small portion of the combustible mixture at any one time and it is propagating towards the unburnt gases. The flame speed is a measure of the rate at which the unburnt mixture is entering the flame.

1. What type of analysis is this, steady-state or transient?

In reality, the problem is of a transient nature, since the flame is propagating through the domain and changes its position with time. However, it can be converted to a steady-state problem by considering the problem in the reference frame of the propagating flame. In this reference frame, the flame can be considered as stationary, while the unburnt mixture moves into the flame and the burnt gases move away from the flame. Sometimes, the solution may not converge in a steady-state. In such cases, Cantera will automatically switch to the transient approach temporarily for the first few steps and revert to the steady-state approach when a guess value is good enough for steady-state convergence.

2. Why do we need a separate file to simulate the hydrogen mechanism?

The hydrogen mechanism can also be simulated using the GRI 3.0 mechanism. However, the GRI 3.0 mechanism has been optimized for the combustion of hydrocarbons. Hence, a separate file which includes the optimized hydrogen mechanism is used to obtain more accurate results.

IMPLEMENTATION IN PYTHON USING CANTERA MODULE:

The project involves analyzing the flame speed of methane and hydrogen mechanisms. The flame speed can be affected by various parameters such as:

  • Fuel type
  • Fuel-oxidizer ratio (Equivalence ratio)
  • Initial temperature
  • Pressure

The above list may not be exhaustive but includes the parameters which can have a major impact on the simulation. For this project, we consider an equivalence ratio of `0.9` (lean mixture). Hence the species_dict, which includes the mole fractions of the species in the mixture, is modified accordingly.

Methane: `0.9 CH_4 + 2(O_2 + 3.76N_2) rarr 0.9 CO_2 + 1.8H_2O + 7.52N_2 + 0.2O_2`

Hydrogen: `1.8H_2 + O_2 + 3.76N_2 rarr 1.8H_2O + 3.76N_2 + 0.1O_2`

The initial temperature and pressure are set to `300` `K` and `1` `atm` respectively. A Solution object "gas" is created using the above initial conditions. A FreeFlame object is created with a domain length of `0.03` `m` from the gas object. The Cantera solver obtains a solution for a coarse grid using the Newton-Raphson method. The solution is then monitored for gradients and curvature and subsequent grid refinement is done at points of interest. The solving and refinement continues till a converged solution satisfying the refinement criteria is obtained. The Python code and results for both the methane and hydrogen mechanisms are shown below:

Methane mechanism (gri30.xml)

import cantera as ct
import numpy as np
import matplotlib.pyplot as plt

gas = ct.Solution('gri30.xml', 'gri30_mix')
T0 = 300.0
P0 = ct.one_atm
species_dict = {'CH4':0.9, 'O2':2, 'N2':7.52}
gas.TPX = T0, P0, species_dict

f = ct.FreeFlame(gas, width=0.03)
f.set_refine_criteria(ratio=3, slope=0.07, curve=0.14)

f.solve(loglevel=1, refine_grid=True, auto=False)

print('==============================================================================')
print('==============================================================================')
print('Mixture-averaged flamespeed = %.6f m/s\n' % (f.u[0]))
x = f.grid
T = f.T
v = f.u
conc_CO2 = f.concentrations[gas.species_index('CO2'),:]
X_CO2 = f.X[gas.species_index('CO2'),:]

fig1, ax1 = plt.subplots()
plt.subplot(2,1,1)
plt.plot(x, T, linewidth=2)
plt.grid('both',linestyle='--',linewidth=1)
plt.ylabel('Temperature [K]', fontweight='bold', fontsize=12)
frame1 = plt.gca()
frame1.axes.xaxis.set_ticklabels([])
plt.title('Temperature and Velocity along the Length of the Domain',fontweight='bold')
plt.subplot(2,1,2)
plt.plot(x, v, linewidth=2)
plt.grid('both',linestyle='--',linewidth=1)
plt.xlabel('Distance along the grid [m]', fontweight='bold', fontsize=12)
plt.ylabel('Velocity [m/s]', fontweight='bold', fontsize=12)
plt.tight_layout()

fig2, ax2 = plt.subplots()
plt.subplot(2,1,1)
plt.plot(x, conc_CO2, linewidth=2)
plt.grid('both',linestyle='--',linewidth=1)
plt.ylabel('Concentration [kmol/m$^3$]', fontweight='bold', fontsize=9)
frame1 = plt.gca()
frame1.axes.xaxis.set_ticklabels([])
plt.title('CO2 variation along the Length of the Domain',fontweight='bold')
plt.subplot(2,1,2)
plt.plot(x, X_CO2, linewidth=2)
plt.grid('both',linestyle='--',linewidth=1)
plt.xlabel('Distance along the grid [m]', fontweight='bold', fontsize=12)
plt.ylabel('Mole Fraction', fontweight='bold', fontsize=10)
plt.tight_layout()

plt.show()

Hydrogen Mechanism (H2_mech.cti):

import cantera as ct
import numpy as np
import matplotlib.pyplot as plt

gas = ct.Solution('H2_mech.cti')
T0 = 300.0
P0 = ct.one_atm
species_dict = {'H2':1.8, 'O2':1, 'N2':3.76}
gas.TPX = T0, P0, species_dict

f = ct.FreeFlame(gas, width=0.03)
f.set_refine_criteria(ratio=3, slope=0.07, curve=0.14)

f.solve(loglevel=1, refine_grid=True, auto=False)

print('==============================================================================')
print('==============================================================================')
print('Mixture-averaged flamespeed = %.6f m/s\n' % (f.u[0]))
x = f.grid
T = f.T
v = f.u
conc_CO2 = f.concentrations[gas.species_index('CO2'),:]
X_CO2 = f.X[gas.species_index('CO2'),:]

fig1, ax1 = plt.subplots()
plt.subplot(2,1,1)
plt.plot(x, T, linewidth=2)
plt.grid('both',linestyle='--',linewidth=1)
plt.ylabel('Temperature [K]', fontweight='bold', fontsize=12)
frame1 = plt.gca()
frame1.axes.xaxis.set_ticklabels([])
plt.title('Temperature and Velocity along the Length of the Domain',fontweight='bold')
plt.subplot(2,1,2)
plt.plot(x, v, linewidth=2)
plt.grid('both',linestyle='--',linewidth=1)
plt.xlabel('Distance along the grid [m]', fontweight='bold', fontsize=12)
plt.ylabel('Velocity [m/s]', fontweight='bold', fontsize=12)
plt.tight_layout()

fig2, ax2 = plt.subplots()
plt.subplot(2,1,1)
plt.plot(x, conc_CO2, linewidth=2)
plt.grid('both',linestyle='--',linewidth=1)
plt.ylabel('Concentration [kmol/m$^3$]', fontweight='bold', fontsize=9)
frame1 = plt.gca()
frame1.axes.xaxis.set_ticklabels([])
plt.title('CO2 variation along the Length of the Domain',fontweight='bold')
plt.subplot(2,1,2)
plt.plot(x, X_CO2, linewidth=2)
plt.grid('both',linestyle='--',linewidth=1)
plt.xlabel('Distance along the grid [m]', fontweight='bold', fontsize=12)
plt.ylabel('Mole Fraction', fontweight='bold', fontsize=10)
plt.tight_layout()

plt.show()

3. What do you infer from the graphs? What would you state the flame speed as?

The graphs denote the variation of variables (temperature and velocity) along the length of the domain of `0.03` `m`. The starting point of the graph (`x = 0`) indicates the flame (since we are solving the equations based on the flame's reference frame). We can see that the unburnt gases enter the flame at the initial temperature of `300` `K`. As they move into the flame, the combustion reaction occurs which increases the temperature, and hence we can see the sudden peak in the temperature and velocity. Because of the reference frame, the flame speed is the velocity at the starting point, which can be accessed as f.u[0]. The following table compares the flame speed and the highest temperature of both the mechanisms:

`{:(ul{text{Mechanism}},,ul{text{1-D Flame Speed [m/s]}},,ul{text{Max. Temperature [K]}}),(text{Methane},,0.339836,,2137.8),(text{Hydrogen},,2.138552,,2280.97):}`

After subsequent refinements to the grid, the methane combustion is solved using `155` grid points and the hydrogen combustion is solved using `122` grid points. We also plot the concentration and mole fraction of `CO_2` from the solution. The `CO_2` concentration for the methane mechanism shows that as the reaction progresses, more `CO_2` is generated, whereas, for the hydrogen mechanism, no `CO_2` is generated. This can also be seen from the reactions where there is no `CO_2` on the products side of the hydrogen combustion reaction.

From the flame speed for the methane and hydrogen mechanisms, we can also conclude that the hydrogen combustion occurs more aggressively than the methane combustion.

4. Does the width parameter have an effect on the solution?

The width parameter does not have a huge effect on the solution as long as the domain is big enough for Cantera to perform the time-integration. If the domain is too small, the solution will not be able to converge. The larger the domain, the more accurate the solution, but it will also take more computational resources to provide the solution.

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.