Hello everyone !
I'm a PhD student in plasma physics in France and I started to use Cantera a few weeks ago, but with little success...
My goal is to reproduce the rapid cooling of a gas mixture and to track the mole fraction of the main species, to see if the mixture has the time to reach the chemical equilibrium or not. The mixture being at atmospheric pressure the whole time.
To do so, using Chemkin, I calculated the equilibrium mole fractions of the mixture at a temperature (eg 9000 K) as the initial conditions, imposed a temporal temperature profile (eg decreasing exponential to 6000 K) and ran the code with a specified kinetic model.
After that I calculated the equilibrium mole fraction at the final temperature (ex 6000 K) and compared the results with the final state obtained before.
I'm trying to reproduce these steps on Cantera.
I succeeded to import my input files (kinetic model and thermodynamic constants) but after that I fail to impose the temporal temperature profile and to obtain consistent results...
I think I'm doing something wrong, because even for a simpler case: equilibrium composition of 3000 K as initial conditions, temperature constant of 2500 K, the mixture does not reach the 2500 K equilibrium but converge to something else. See the example below using GRI30:
```
import numpy as np
import cantera as ct
import matplotlib.pyplot as plt
# Temperature initial and final
T_ini = 3000
T_end = 2500
gas = ct.Solution('gri30.yaml')
# Calculate the final state at equilibrium
gas.TPX = T_end, ct.one_atm, 'CO2:1'
gas.equilibrate('TP')
eq_data = gas.mole_fraction_dict()
# Set the initial state
gas.TPX = T_ini, ct.one_atm, 'CO2:1'
gas.equilibrate('TP')
reactor = ct.IdealGasConstPressureReactor(gas)
sim = ct.ReactorNet([reactor])
# Set the final temperature
gas.TPX = T_end, ct.one_atm, 'CO2:1'
reactor.syncState()
sim.reinitialize()
# Calculate the temporal evolution
time = np.linspace(1e-6, 1e1, int(1e4))
data = {specie : np.zeros(len(time)) for specie in eq_data.keys()}
n = 0
for t in time:
t_sim = sim.advance(t)
for specie in gas.mole_fraction_dict().keys():
if specie in data.keys():
data[specie][n] = gas.mole_fraction_dict()[specie]
n += 1
# Calculate the ratio [N]/[N]eq_T_end
ratio = {}
for specie in eq_data.keys():
ratio[specie] = data[specie]/eq_data[specie]
# %% Plot
plot_species = ['CO', 'CO2', 'O2']
color = ['k', 'b', 'r', 'c', 'g']
fig, [ax1, ax2] = plt.subplots(2, 1, sharex=True)
for i in range(len(plot_species)):
ax2.plot(time, data[plot_species[i]], color[i], label=plot_species[i])
ax2.plot(time, eq_data[plot_species[i]]*np.ones(len(time)), color[i]+'--', label=plot_species[i]+' Equilibrium', linewidth=2)
ax1.plot(time, ratio[plot_species[i]], color[i], label=plot_species[i])
ax1.set_ylabel('[N]/[N]eq at {0}'.format(T_end))
ax2.set_ylabel('Mole Fraction')
ax2.set_xlabel('Time (s)')
ax1.legend()
ax2.legend()
```
So mainly, I have 2 questions:
- I do not understand why Cantera does not reach the same equilibrium since the kinetic backward rates are calculated using the same thermodynamic constants used to calculate the final composition, am I doing something wrong ?
- Do you know any way to impose a temporal profile in Cantera ?
Thank you very much in advance for your answers.
Corentin