#!/usr/bin/env python
# coding: utf-8
import cantera as ct
import numpy as np
from matplotlib.pylab import *
gas = ct.Solution('gri30.yaml', 'gri30')
p = 1e5 # pressure
comp_f = 'C2H6:1' # fuel composition
tin_f = 300.0 # fuel inlet temperature
rho_f = p / (8.314 / 0.030 * tin_f) # fuel inlet density
mdot_f = 0.24 # fuel inlet mass flow rate (kg/m^2/s)
vel_f = mdot_f / rho_f # fuel inlet velocity
print('Velocity of the fuel : ' + str(vel_f))
comp_o = 'O2:0.21, N2:0.78, AR:0.01' # oxidizer composition
tin_o = 300.0 # oxidizer inlet temperature
rho_o = p / (8.314 / 0.029 * tin_o) # oxidizer inlet density
mdot_o = 0.72 # oxidizer inlet mass flow rate (kg/m^2/s)
vel_o = mdot_o / rho_o # oxidizer inlet velocity
print('Velocity of the oxidizer : ' + str(vel_o))
gas.TP = tin_o, p
width = 0.02
a = (vel_o + vel_f) / width # calculation of the strain rate (s^-1)
print('Strain rate of the diffusion flame : ' + str(a))
# This will instanciate the counterflow diffusion flame. As you might notice, and this is valid for all the other cases, you can instanciate the initial grid yourself. This allows you to refine the grid when you want. This can be a good trick when your simulation is crashing and you want to compute it again.
# As far as the inlets are concerned, the composition, temperature and mass flow rate needs to be specified.
# In[22]:
initial_grid = np.linspace(0, width, 6)
f = ct.CounterflowDiffusionFlame(gas, initial_grid)
# Set the state of the two inlets
f.fuel_inlet.mdot = mdot_f
f.fuel_inlet.X = comp_f
f.fuel_inlet.T = tin_f
f.oxidizer_inlet.mdot = mdot_o
f.oxidizer_inlet.X = comp_o
f.oxidizer_inlet.T = tin_o
# This starts the calculation of the counterflow diffusion flame. By experience, you will see that, out of this wonderful tutorial case, diffusion flames are hard to converge. You can either play with the size of the domain and every parameter said all along the tutorial (indeed, sometimes it converges better if the domain is smaller), or you can try a method that is developed here in CERFACS that resolves **the diffusion flame in the z-space**.
# If you want some more information about that, come and ask the chemistry team of cerfacs.
# In[23]:
#%%capture
# First flame:
# disable the energy equation
f.energy_enabled = False
# Set error tolerances
tol_ss = [1.0e-5, 1.0e-11] # [rtol, atol] for steady-state problem
tol_ts = [1.0e-5, 1.0e-11] # [rtol, atol] for time stepping
f.flame.set_steady_tolerances(default=tol_ss)
f.flame.set_transient_tolerances(default=tol_ts)
# and solve the problem without refining the grid
f.solve(loglevel=1, refine_grid='disabled')
#################
# Second flame:
# specify grid refinement criteria, turn on the energy equation,
f.energy_enabled = True
f.set_refine_criteria(ratio=3, slope=0.8, curve=0.8)
# and solve the problem again
f.solve(loglevel=1, refine_grid='refine')
# save your results
f.save('4-Output/c2h6_diffusion.yaml', 'energy')
#################
# Third flame:
# specify grid refinement criteria, turn on the energy equation,
f.energy_enabled = True
f.set_refine_criteria(ratio=2, slope=0.2, curve=0.2, prune=0.04)
# and solve the problem again
f.solve(loglevel=1, refine_grid='refine')
# save your results
f.save('4-Output/c2h6_diffusion.yaml', 'energy continuation')
#################################################################
# Save your results if needed
#################################################################
# write the velocity, temperature, and mole fractions to a CSV file
f.write_csv('4-Output/c2h6_diffusion.csv', quiet=False)
# These are interesting quantities to plot, such as the different mass fractions and the temperature of the flame. This is all done in the following graph (with the values being adimensionalised).
# In[24]:
# Get interesting values
z = f.flame.grid
T = f.T
u = f.velocity
# Get interesting indices for computation of species
fuel_species = 'C2H6'
ifuel = gas.species_index(fuel_species)
io2 = gas.species_index('O2')
in2 = gas.species_index('N2')
# Initiate interesting vectors
c2h6 = np.zeros(f.flame.n_points,'d')
o2 = np.zeros(f.flame.n_points,'d')
hr = np.zeros(f.flame.n_points,'d')
# Computes interesting quantities for analyzing a counter-flow flame
for n in range(f.flame.n_points):
f.set_gas_state(n)
c2h6[n]= gas.Y[ifuel]
o2[n]= gas.Y[io2]
hr[n] = - np.dot(gas.net_production_rates, gas.partial_molar_enthalpies)
# In[25]:
fig=figure(1)
a=fig.add_subplot(111)
a.plot(z,T/np.max(T),z,c2h6/np.max(c2h6),z,o2/np.max(o2))
plt.title(r'$T_{adiabatic}$ vs. Position',fontsize=25)
plt.xlabel(r'Position [m]', fontsize=15)
plt.ylabel('Normalized values of different quantities',fontsize=15)
plt.legend(['Temperature','$Y_{C_2H_6}$', '$Y_{O_2}$'],fontsize=15)
show()