Example #1
0
    def induction_length(self,
                         cj_speed=False,
                         P1=False,
                         T1=False,
                         q=False,
                         mech=False,
                         t_end=1e-5):
        # Assign default values innit
        if cj_speed is False:
            cj_speed = self.cj_speed
        if P1 is False:
            P1 = self.P1
        if T1 is False:
            T1 = self.T1
        if q is False:
            q = self.q
        if mech is False:
            mech = self.SDTmech
        # Set up gas object
        gas1 = ct.Solution(mech)
        gas1.TPX = T1, P1, q
        # Find post-shock conditions
        gas = PostShock_fr(cj_speed, P1, T1, q, mech)
        # Solve ZND ODEs to find the width of the ZND "plateau"
        znd_out = zndsolve(gas,
                           gas1,
                           cj_speed,
                           t_end=t_end,
                           advanced_output=True)
        plateau_length = znd_out['ind_len_ZND']

        return plateau_length
Example #2
0
    def calc_vnpressure(self):
        # Calculation for the Chapman-Jouget speeds
        cj_speed_mps = self.calc_cjspeed()

        if self.ps_fr is False:
            # Post shock (frozen) pressure to be determined
            self.ps_fr = PostShock_fr(U1=cj_speed_mps, P1=self.P1, T1=self.T1, q=self.q, mech=self.mech)

        vn_pressure_pa = self.ps_fr.P

        return vn_pressure_pa
print('   gamma2 (equilibrium) '+str(gamma2_eq)+' (m/s)')
print('--------------------------------------')
#
gas3 = ct.Solution(mech)
p3,UR,gas3 = reflected_eq(gas1,gas,gas3,cj_speed)
print('Reflected CJ shock (equilibrium) computation for '+mech+' with composition '+q)
print('   CJ speed '+str(cj_speed)+' (m/s)')
print('   Reflected wave speed '+str(UR)+' (m/s)')
print('Post-Reflected Shock Parameters')
print('   Pressure '+str(gas3.P)+' (Pa)')
print('   Temperature '+str(gas3.T)+' (K)')
print('   Density '+str(gas3.density)+' (kg/m3)')
print('--------------------------------------');
#
print('Shock computation for '+mech+' with composition '+q)
gas = PostShock_fr(cj_speed,P1,T1,q,mech)
print('    shock speed '+str(cj_speed)+' (m/s)')
print('Postshock State')
print('    Pressure '+str(gas.P)+' (Pa)')
print('    Temperature '+str(gas.T)+' (K)')
print('    Density '+str(gas.density)+' (kg/m3)')
print('    Entropy '+str(gas.entropy_mass)+' (J/kg-K)')
w2 = cj_speed*gas1.density/gas.density
u2 = cj_speed-w2
print('    w2 (wave frame) '+str(w2)+' (m/s)')
print('    u2 (lab frame) '+str(u2)+' (m/s)')
print('    a2 (frozen) '+str(soundspeed_fr(gas))+' (m/s)')
gamma2_fr =  soundspeed_fr(gas)**2*gas.density/gas.P
print('    gamma2 (frozen) '+str(gamma2_fr)+' (m/s)')
print('--------------------------------------')
#
Example #4
0
Umax = 2000.
Ustep = 100.  # Ustep will be approximated
nsteps = int((Umax - Umin) / Ustep)

speed = []
P = []
R = []
T = []
a = []
gamma = []
w2 = []
u2 = []
for speeds in linspace(Umin, Umax, num=nsteps):
    speed.append(speeds)
    gas = PostShock_fr(speed[-1], P1, T1, q, mech)
    P.append(gas.P)
    R.append(gas.density)
    T.append(gas.T)
    a.append(soundspeed_fr(gas))
    gamma.append(a[-1]**2 * R[-1] / P[-1])
    w2.append(gas1.density * speed[-1] / R[-1])
    u2.append(speed[-1] - w2[-1])

##################################################################################################
# Create output file in text format with Tecplot-style variable labels for
# columns
##################################################################################################
fn = 'shock_adiabat.txt'
d = datetime.date.today()
fid = open(fn, 'w')
driven_gas.TPX = T1,P1,q1

## Evaluate initial state 
rho1 = driven_gas.density
a1 = soundspeed_fr(driven_gas)

## Evaluate post-shock state (frozen) for a range of shock speeds 
print('Generating points on shock P-u curve')
Ustart = a1*1.01; Ustop = 8*a1; Ustep = 25
nsteps = int((Ustop-Ustart)/Ustep)

a2 = []; P2 = []; T2 = []; rho2 = []; u2 = []; Us = []

for U in np.linspace(Ustart,Ustop,num=nsteps):
    if CASE_DRIVEN=='frozen':
        shocked_gas = PostShock_fr(U, P1, T1, q1, driven_mech)
    elif CASE_DRIVEN=='equilibrium':
        shocked_gas = PostShock_eq(U, P1, T1, q1, driven_mech)
    a2.append(soundspeed_fr(shocked_gas))
    P2.append(shocked_gas.P)
    T2.append(shocked_gas.T)
    rho2.append(shocked_gas.density)
    w2 = rho1*U/shocked_gas.density
    u2.append(U - w2)
    Us.append(U)

if CASE_DRIVER=='gas':
    ## Set initial state for driver section - pressurized gas and no reaction
    # for nonreacting driver, use frozen expansion
    EQ_EXP = False
    P_driver = 3e6; T_driver = 300.;
Example #6
0
    hp_T.append(gas.T)
    hp_ae.append(soundspeed_eq(gas))
    
    # Constant Volume Explosion State
    gas.TPX = T1,P1,x    
    gas.equilibrate('UV')
    uv_P.append(gas.P)
    uv_T.append(gas.T)
    uv_ae.append(soundspeed_eq(gas))
    
    # CJ speed
    gas.TPX = T1,P1,x    
    Ucj.append(CJspeed(P1, T1, x, mech))

    # vN state
    gas1 = PostShock_fr(Ucj[-1], P1, T1, x, mech)
    vn_T.append(gas1.T)
    vn_P.append(gas1.P)
    vn_rho.append(gas1.density)
    vn_af.append(soundspeed_fr(gas1))

    # ZND Structure
    ZNDout = zndsolve(gas1,gas,Ucj[-1],advanced_output=True)
    ind_len_ZND.append(ZNDout['ind_len_ZND'])
    exo_len_ZND.append(ZNDout['exo_len_ZND'])

    # CJ state
    gas1 = PostShock_eq(Ucj[-1],P1, T1,x,mech)
    cj_T.append(gas1.T)
    cj_P.append(gas1.P)
    cj_rho.append(gas1.density)
    print(q)
    print('Initial conditions: P1 = %.3e atm & T1 = %.2f K' %
          (initpress, inittemp))
    # generate gas solution and set initial conditions
    preshockgas = ct.Solution(mech)
    preshockgas.TPX = inittemp, initpress * ct.one_atm, q

    # calculate CJ speed for gas mixture
    cj_speed = CJspeed(initpress * ct.one_atm,
                       inittemp,
                       q,
                       mech,
                       fullOutput=False)

    # calculate postshock gas condition
    postshockgas = PostShock_fr(cj_speed, initpress * ct.one_atm, inittemp, q,
                                mech)
    # save and print initial shock temp and pressure
    shockedpress = postshockgas.P / 101325
    shockedtemp = postshockgas.T
    print(f'    PostShock Pressure: {postshockgas.P/101325} atm')
    print(f'    PostShock Temperature: {postshockgas.T} K')

    # Resolution: The PFR will be simulated by 'n_steps' time steps
    n_steps = 3000000

    # create a new reactor
    r1 = ct.IdealGasConstPressureReactor(postshockgas)
    # create a reactor network for performing time integration
    sim1 = ct.ReactorNet([r1])

    # approximate a time step to achieve a similar resolution as in the next method
print('   Frozen sound Speed '+str(af1)+' (m/s)')
print('   Shock Mach number '+str(M1))
print('   Pressure '+str(P1)+' (Pa)')
print('   Temperature '+str(T1)+' (K)')
print('   Density '+str(rho1)+' (kg/m3)')
print('   gamma2 (based on frozen sound speed) '+str(gamma1_fr)+' (m/s)')
print('   Specific heat at constant pressure '+str(gas1.cp_mass)+' (J/kg K)')
if transport:
    print('   viscosity '+str(mu1)+' (kg/m s)')
    print('   viscosity (kinematic)'+str(nu1)+' (m2/s)')
    print('   thermal conductivity '+str(kcond1)+' (W/m K)')
    print('   thermal diffusivity '+str(kdiff1)+' (m2/s)')
    print('   Prandtl number '+str(Pr))

## Postshock (Frozen)
gas2 = PostShock_fr(speed,P1,T1,q,mech)
af2 = soundspeed_fr(gas2)
ae2 = soundspeed_eq(gas2)
P2 = gas2.P
T2 = gas2.T
S2 = gas2.entropy_mass
rho2 = gas2.density
gamma2_fr = af2**2*rho2/P2
gamma2_eq = ae2**2*rho2/P2
w2 = rho1*speed/rho2
u2 = speed - w2
if transport:
    mu = gas2.viscosity
    nu = mu/rho2
    kcond = gas2.thermal_conductivity
    kdiff = kcond/(rho2*gas2.cp_mass)
print('Mechanism: ' + mech)

# create gas objects for other states
gas2 = ct.Solution(mech)
gas3 = ct.Solution(mech)

# compute minimum incident wave speed
a_fr = soundspeed_fr(gas1)
# incident wave must be greater than or equal to frozen sound speed for
# frozen shock wave computations
UI = 3 * a_fr

print('Incident shock speed UI = %.2f m/s' % (UI))

# compute postshock gas state object gas2
gas2 = PostShock_fr(UI, P1, T1, q, mech)
P2 = gas2.P / ct.one_atm

print('Frozen Post-Incident-Shock State')
print('T2 = %.2f K, P2 = %.2f atm' % (gas2.T, P2))

# compute reflected shock post-shock state gas3
[p3, UR, gas3] = reflected_fr(gas1, gas2, gas3, UI)
# Outputs:
# p3 - pressure behind reflected wave
# UR = Reflected shock speed relative to reflecting surface
# gas3 = gas object with properties of postshock state

P3 = gas3.P / ct.one_atm
print('Frozen Post-Reflected-Shock State')
print('T3 = %.2f K,  P3 = %.2f atm' % (gas3.T, P3))
Example #10
0
print('Initial Conditions')
print(x + ', Temperature = %.2f K' % (T1))
print('For %s initial pressures' % (npoints))

for i in range(npoints):
    P1[i] = Po*(0.1 +1.1/npoints*(i))
    P = P1[i]
    print('%i : P1 = %.2f atm' % (i+1,P/ct.one_atm))

    gas.TPX = T1,P1[i],x
    
    ### Constant Volume Explosion Data ###
    # FIND POST SHOCK STATE FOR GIVEN SPEED
    cj_speed[i] = CJspeed(P1[i], T1, x, mech)
    gas = PostShock_fr(cj_speed[i], P1[i], T1, x, mech)
    Ts[i] = gas.T #frozen shock temperature   
    Ps[i] = gas.P #frozen shock pressure
    # SOLVE CONSTANT VOLUME EXPLOSION ODES
    CVout = cvsolve(gas,t_end=1e-4)
    exo_time_CV[i] = CVout['exo_time']
    ind_time_CV[i] = CVout['ind_time']
    
    
    ### ZND Detonation Data ###
    # FIND POST SHOCK STATE FOR GIVEN SPEED
    gas1.TPX = T1,P1[i],x
    gas = PostShock_fr(cj_speed[i], P1[i], T1, x, mech)
    Ts[i] = gas.T #frozen shock temperature   
    Ps[i] = gas.P #frozen shock pressure
    # SOLVE ZND DETONATION ODES
Example #11
0
h1 = gas1.enthalpy_mass
r1 = gas1.density
v1 = 1.0 / gas1.density

#Get CJ Point
cj_speed = CJspeed(P1, T1, q, mech)
gas = PostShock_eq(cj_speed, P1, T1, q, mech)
vcj = 1.0 / gas.density
Pcj = gas.P / ct.one_atm

print('CJ Point Found')

U1 = od * cj_speed

#Find Postshock specific volume for U1
gas = PostShock_fr(U1, P1, T1, q, mech)
vsj = 1.0 / gas.density
Psj = gas.P / ct.one_atm

#Find Gamma
gas = PostShock_fr(gbound * cj_speed, P1, T1, q, mech)
g = gas.cp_mass / gas.cv_mass

# RAYLEIGH LINE, SJUMP MIN & MAX, GAMMA CONSTRAINT
minp = 0.1 * vcj
maxp = 2.0 * vcj
step = 0.01 * vcj
i = 0
v2 = minp
n = np.int((maxp - minp) / step)
vR = np.zeros(n, float)
P1 = ct.one_atm; P1atm = P1/ct.one_atm

print('Initial Conditions')
print(x + ', Pressure = %.2f atm, Temperature = %.2f K' % (P1atm,T1))
print('For %s values of overdrive' % (npoints))
cj_speed = CJspeed(P1, T1, x, mech)


for i in range(npoints):
    overdrive[i] = (1.0 +0.6/npoints*(i)) #Overdrive = U/Ucj
    ratio = overdrive[i]
    print('%i : Overdrive = %.2f ' % (i+1,ratio))

    # Find post shock state for given speed
    gas.TPX = T1,P1,x
    gas = PostShock_fr(cj_speed*overdrive[i], P1, T1, x, mech)
    Ts[i] = gas.T # frozen shock temperature   
    Ps[i] = gas.P # frozen shock pressure
    
    ### Constant Volume Explosion Data ###
    # Solve constant volume explosion ODEs
    CVout = cvsolve(gas)
    exo_time_CV[i] = CVout['exo_time']
    ind_time_CV[i] = CVout['ind_time']    

    
    ### ZND Detonation Data ###
    gas.TPX = T1,P1,x
    gas = PostShock_fr(cj_speed*overdrive[i], P1, T1, x, mech)
    # Solve znd detonation ODEs
    ZNDout = zndsolve(gas,gas1,cj_speed*overdrive[i],advanced_output=True)
Example #13
0
rho5 = []; w4 = []; w5 = []; u5 = []; vt4 = []; a5 = []; 
P5 = []; T5 = []; h5 = []; s5 = []; beta = []; theta = [];

##
# compute shock jump conditions over range from minimum to maximum normal
# speeds.  Adjust the increment to get a smooth output curve.
wstep = 5
nsteps = int((wmax-wmin)/wstep) 
for w in np.linspace(wmin,wmax,num=nsteps):
    if EQ:
        # equilibrium state
        gas = PostShock_eq(w, P4, T4, x4, mech)
        a5.append(soundspeed_eq(gas))
    else:
        #  for non-reactive or cold upstream state, use frozen shock calculation
        gas = PostShock_fr(w, P4, T4, qs, mech)
        a5.append(soundspeed_fr(gas))
    
    rho5.append(gas.density)
    ratio = rho4/rho5[-1]
    w4.append(w)
    w5.append(w*ratio)
    P5.append(gas.P)
    T5.append(gas.T)
    h5.append(gas.enthalpy_mass)
    s5.append(gas.entropy_mass)
    beta.append(np.arcsin(w/U4))
    vt4.append(U4*np.cos(beta[-1]))
    theta.append(beta[-1] - np.arctan(w5[-1]/np.sqrt(U4**2-w**2)))
    u5.append(np.sqrt(w5[-1]**2 + vt4[-1]**2))
R1 = gas1.density
gamma1_fr = a1_fr**2 * R1 / P1

print('Initial Conditions')
print('   pressure ' + str(P1) + ' (Pa)')
print('   temperature ' + str(T1) + ' (K)')
print('   density ' + str(R1) + ' (kg/m3)')
print('a1 (frozen) ' + str(a1_fr) + ' (m/s)')
print('gamma1 (frozen) ' + str(gamma1_fr) + ' (m/s)')

print('Computing shock state and isentrope for ' + q + ' using ' + mech)

# Evaluate the frozen state of the gas behind a shock wave
# traveling at a specified speed (must be greater than sound speed)
shock_speed = 1633.
gas = PostShock_fr(shock_speed, P1, T1, q, mech)

# Evaluate properties of gas object and print out
T2 = gas.T
P2 = gas.P
R2 = gas.density
V2 = 1 / R2
S2 = gas.entropy_mass
w2 = gas1.density * shock_speed / R2
u2 = shock_speed - w2
x2 = gas.X
a2_fr = soundspeed_fr(gas)
gamma2_fr = a2_fr**2 * R2 / P2

print('Shock speed ' + str(shock_speed) + ' (m/s)')
print('Frozen Post-Shock State')
Example #15
0
mech = 'airNASA9ions.cti'
fname = 'AirFr'
U1 = 1000.
plt_num = 1
# EDIT VALUES ABOVE THIS LINE
##############################
# set initial state
gas1 = ct.Solution(mech)
gas1.TPX = T1, P1, q
h1 = gas1.enthalpy_mass
r1 = gas1.density
v1 = 1.0 / gas1.density
s1 = gas1.s

#Get postshock state
gas = PostShock_fr(U1, P1, T1, q, mech)
v_ps = 1.0 / gas.density
P_ps = gas.P / ct.one_atm

# RAYLEIGH LINE,
minv = 0.9 * v_ps
maxv = 1.00 * v1
stepv = 0.01 * v1
n = np.int((maxv - minv) / stepv)
vR = np.zeros(n, float)
PR = np.zeros(n, float)

i = 0
v2 = maxv
while (i < n):
    vR[i] = v2
##
# compute shock jump conditions over range from minimum to maximum normal
# speeds.  Adjust the increment to get a smooth output curve.

step = 5 # approximate desired step size (will not be exactly followed)
npoints = int((wmax-wmin)/step)

for w in np.linspace(wmin,wmax,num=npoints): 
    if EQ:
        # equilibrium state
        gas = PostShock_eq(w, Ps, Ts, xs, mech)
        a2.append(soundspeed_eq(gas))
    else:
        # for non-reactive or cold upstream state, use frozen shock calculation
        gas = PostShock_fr(w, Ps, Ts, qs, mech)
        a2.append(soundspeed_fr(gas))

    rho2.append(gas.density)
    ratio = rhos/rho2[-1]
    w1.append(w)
    w2.append(w*ratio)
    P2.append(gas.P)
    beta.append(np.arcsin(w/US))
    vt.append(US*np.cos(beta[-1]))
    theta.append(beta[-1] - np.arctan(w2[-1]/np.sqrt(US**2-w**2)))
    u2.append(np.sqrt(w2[-1]**2 + vt[-1]**2))


# pick up normal shock as last point
w = US
Example #17
0
Tested with: 
    Python 3.5 and 3.6, Cantera 2.3 and 2.4
Under these operating systems:
    Windows 8.1, Windows 10, Linux (Debian 9)
"""

import cantera as ct
from sdtoolbox.postshock import PostShock_fr

# Initial state specification:
# P1 = Initial Pressure  
# T1 = Initial Temperature 
# U = Shock Speed 
# q = Initial Composition 
# mech = Cantera mechanism File name

P1 = 100000; P1atm = P1/ct.one_atm
T1 = 300
U = 2000
q = 'H2:2 O2:1 N2:3.76'
mech = 'Mevel2017.cti'
 
gas = PostShock_fr(U, P1, T1, q, mech)
Ps = gas.P/ct.one_atm

print(' ')
print('Initial state: ' + q + ', P1 = %.2f atm,  T1 = %.2f K' % (P1atm,T1) )
print('Mechanism: ' + mech)
print('Frozen postshock state: Ps = %.2f atm, Ts = %.2f K' % (Ps,gas.T))
print(' ')
Example #18
0
w1 = []
w2 = []
u2 = []
v = []
a2 = []
P2 = []
beta = []
theta = []

##
# compute shock jump conditions over range from minimum to maximum normal
# speeds.  Adjust the increment to get a smooth output curve.
wstep = 5
nsteps = int((wmax - wmin) / wstep)
for w in np.linspace(wmin, wmax, num=nsteps):
    gas = PostShock_fr(w, P1, T1, q, mech)
    # gas = PostShock_eq(w, P1, T1, q, mech) #will not converge at low temperature.
    rho2.append(gas.density)
    a2.append(soundspeed_fr(gas))
    ratio = rho1 / rho2[-1]
    w1.append(w)
    w2.append(w * ratio)
    P2.append(gas.P)
    beta.append(np.arcsin(w / U))
    v.append(U * np.cos(beta[-1]))
    theta.append(beta[-1] - np.arctan(w2[-1] / np.sqrt(U**2 - w**2)))
    u2.append(np.sqrt(w2[-1]**2 + v[-1]**2))

## pick up normal shock as last point
w = U
gas = PostShock_fr(w, P1, T1, q, mech)