From charlesreid1

Line 96: Line 96:
Air is composed of a 3.7:1 mix of nitrogen and oxygen. To mimic air in an oxy-fired system, an operator would try and mimic the dilution of oxygen with carbon dioxide by mixing them in a similar ratio. However, this is a variable that the operator can (must) control, because not all of the properties of a carbon dioxide-diluted flame match those of a nitrogen-diluted flame. It can be varied to make those properties match more closely.
Air is composed of a 3.7:1 mix of nitrogen and oxygen. To mimic air in an oxy-fired system, an operator would try and mimic the dilution of oxygen with carbon dioxide by mixing them in a similar ratio. However, this is a variable that the operator can (must) control, because not all of the properties of a carbon dioxide-diluted flame match those of a nitrogen-diluted flame. It can be varied to make those properties match more closely.


Just to start with
I'll be analyzing the case of ethane combustion (mainly because ethane is slightly easier to ignite, meaning the combustion simulations are shorter and therefore faster).
 
==Diluting Function==
 
It will be useful to have a function that takes a diluant species (like 'N2' or 'CO2') and a fraction, and dilutes the mixture of fuel and oxidizer accordingly.
 
If we have a mixture of N moles, and we are diluting it with a fraction y of nitrogen or carbon dioxide, we can dilute it in one of two ways:
 
'''Method 1:''' Maintain N total moles by taking <math>(1-y)N</math> moles of the original mixture and <math>yN</math> moles of diluant.
 
'''Method 2:''' Maintain N moles of original mixture by taking <math>N</math> moles of the original mixture and <math>\frac{y}{1-y} N</math> moles of diluant.
 
Method 2 makes life easier, because that way we only have to modify one component - the diluent.
 
Let's assume an equivalence ratio value <math>\phi</math> of (.............), which means our fuel to oxidizer ratio is (.......) The pseudocode, then, is:
 
<pre>
function component fraction to composition:
moles of ethane = 1.0
moles of oxygen = 2.0
total moles = moles of ethane + moles of oxygen
moles nitrogen = ( y / (1-y) ) * total moles
assemble composition vector
return composition vector
</pre>
 
Converting this to Python code,
 
<pre>
def component_frac_to_X(spname,frac):
    d = {}
    d['C2H6'] = 1.0
    d['O2']  = 2.0
    mole_sum  = sum([d[k] for k in d.keys()])
    d[spname]  = (frac/(1-frac))*mole_sum
 
    return convert_composition_dict_to_string(d)
</pre>

Revision as of 11:23, 31 March 2014

Let's analyze the effect of diluants (nitrogen and carbon dioxide) on the adiabatic flame temperature. Why, you ask? This issue of dilution is of central importance to oxy-fuel combustion, in which effluent gas containing carbon dioxide is recycled into the front of the reactor, so you're not burning with pure oxygen - a big safety hazard and an extremely hot process that'll mess up air-fired reactors.

Background

Adiabatic Flame Temperature Review

Let's review what the AFT is.

Computing the AFT in Cantera

We can compute an adiabatic flame temperature with Cantera by initializing a batch reactor, which will be adiabatic by default, and advancing it until combustion has completed. The final temperature is the adiabatic flame temperature.

in pseudocode,

function compute_adiabatic_flame_T:
    create gas phase object with associated reaction network
    set gas state
    create reactor with gas in it
    create reactor network with reactor in it
    advance reactor network for a while
    return reactor temperature

Translating that to real Python code,

from Cantera import *
from Cantera.Reactor import *
from numpy import *

def compute_adiabatic_flame_T( X0, T0, P0, dt=5.0e-3 ):
    print "Computing an adiabatic flame temperature..."
    g = GRI30()
    g.set(X = X0, T = T0, P = P0)
    r = Reactor(g)
    n = ReactorNet([r])
    ttotal = 0.10
    t = 0.0
    while t < ttotal:
        t = t + dt
        n.advance(t)
    return r.temperature()

Now we can feed a list of composition vectors or composition strings, and get a list of adiabatic flame temperatures.

Adiabatic Flame Temperature vs Equivalence Ratio

A classical plot for adiabatic flame temperature is the adiabatic flame temperature versus equivalence ratio. The equivalence ratio is defined as:

$ \phi = \frac{ \mbox{fuel-oxidizer ratio} }{ \mbox{stoich fuel-oxidizer ratio} } $

Now we can continue building on the code above. Let's create a function to vary equivalence ratio, and compute a corresponding adiabatic flame temperature. We won't worry for now about how to go from an equivalence ratio to a gas composition.

First, the pseudocode:

for phi in range_of_phis:
 convert phi to composition
 call compute_adiabatic_flame_T

Next, continuing the script above,

def equivalence_ratio_test():
    T0 = 1073.15
    P0 = 3*OneAtm
    phis = logspace(-1,1,10)
    
    afts = []
    for phi in phis:
        X = phi_to_X(phi)
        afts.append(compute_adiabatic_flame_T(X,T0,P0))
    
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.semilogx(phis,afts,'bo')
    ax.set_xlabel('Phi')
    ax.set_ylabel('Adiabatic Flame Temp [K]')
    ax.set_title('Adiab Flame Temp vs Equivalence Ratio')
    fig.savefig('AFTvsDilFrac.eps')
    fig.savefig('AFTvsDilFrac.png')

    plt.draw()
    plt.show()

Nitrogen and Carbon Dioxide Dilution

Air is composed of a 3.7:1 mix of nitrogen and oxygen. To mimic air in an oxy-fired system, an operator would try and mimic the dilution of oxygen with carbon dioxide by mixing them in a similar ratio. However, this is a variable that the operator can (must) control, because not all of the properties of a carbon dioxide-diluted flame match those of a nitrogen-diluted flame. It can be varied to make those properties match more closely.

I'll be analyzing the case of ethane combustion (mainly because ethane is slightly easier to ignite, meaning the combustion simulations are shorter and therefore faster).

Diluting Function

It will be useful to have a function that takes a diluant species (like 'N2' or 'CO2') and a fraction, and dilutes the mixture of fuel and oxidizer accordingly.

If we have a mixture of N moles, and we are diluting it with a fraction y of nitrogen or carbon dioxide, we can dilute it in one of two ways:

Method 1: Maintain N total moles by taking $ (1-y)N $ moles of the original mixture and $ yN $ moles of diluant.

Method 2: Maintain N moles of original mixture by taking $ N $ moles of the original mixture and $ \frac{y}{1-y} N $ moles of diluant.

Method 2 makes life easier, because that way we only have to modify one component - the diluent.

Let's assume an equivalence ratio value $ \phi $ of (.............), which means our fuel to oxidizer ratio is (.......) The pseudocode, then, is:

function component fraction to composition:
moles of ethane = 1.0
moles of oxygen = 2.0
total moles = moles of ethane + moles of oxygen
moles nitrogen = ( y / (1-y) ) * total moles
assemble composition vector
return composition vector

Converting this to Python code,

def component_frac_to_X(spname,frac):
    d = {}
    d['C2H6'] = 1.0
    d['O2']   = 2.0
    mole_sum  = sum([d[k] for k in d.keys()])
    d[spname]   = (frac/(1-frac))*mole_sum

    return convert_composition_dict_to_string(d)