def calc_cjtemperature(self): # Calculation for the Chapman-Jouget speeds cj_speed_mps = self.calc_cjspeed() if self.ps_eq is False: # Post shock (equilibrium) pressure to be determined self.ps_eq = PostShock_eq(U1=cj_speed_mps, P1=self.P1, T1=self.T1, q=self.q, mech=self.mech) cj_temperature_k = self.ps_eq.T return cj_temperature_k
## # SET TYPE OF EXPANSION COMPUTATION # Frozen: EQ = False Equilibrium: EQ = True EQ = True ## # set the initial state and compute properties P1 = 100000.; T1 = 300. q = 'O2:1 N2:3.76 H2:2' mech = 'Mevel2017.cti' gas = ct.Solution(mech) # Find CJ speed cj_speed = CJspeed(P1, T1, q, mech) # Evaluate gas state gas = PostShock_eq(cj_speed,P1, T1, q, mech) if EQ: # use this for equilibrium expansion gas.equilibrate('TP') a1 = soundspeed_eq(gas) else: # use this for frozen expansion a1 = soundspeed_fr(gas) x1 = gas.X rho1 = gas.density v1 = 1/rho1 s1 = gas.entropy_mass h1 = gas.enthalpy_mass ##
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) cj_af.append(soundspeed_fr(gas1)) # Reflected CJ state [ref_P[i],Uref[i],gas2] = reflected_eq(gas,gas1,gas2,Ucj[-1]) # State 3 - Plateau at end of Taylor wave # print('Generating points on isentrope and computing Taylor wave velocity') w2 = gas.density*Ucj[-1]/cj_rho[-1] S2 = gas1.entropy_mass u2 = Ucj[-1] - w2 u = [u2] P = [gas1.P] R = [gas1.density]
plt.xlabel('Initial temperature [Kelvins]') plt.ylabel('CJ speed [m/s]') plt.title('Cj detonation speed of methane-air mixture', fontweight='bold') plt.grid() plt.savefig('methane_cjspeed(T1).png', dpi=1000) plt.show() for phi in range(50, 175, 25): T1 = [] X = 'O2:2, N2:7.52, CH4:' + str(phi / 100) PostShock_T = [] for T in range(250, 2500, 250): gas.TPX = T, P1, X T1.append(T) U = CJspeed(P1, T, X, mech) gas = PostShock_eq(U, P1, T, X, mech) PostShock_T.append(gas.T) plt.plot(T1, PostShock_T, label="phi=%.2f" % (phi / 100)) plt.legend() plt.xlabel('Initial temperature [Kelvins]') plt.ylabel('Post shock temperature [K]') plt.title('Post shock temerature of methane-air mixture', fontweight='bold') plt.grid() plt.savefig('methane_T(T1).png', dpi=1000) plt.show() for phi in range(50, 175, 25): T1 = [] X = 'O2:2, N2:7.52, CH4:' + str(phi / 100) PostShock_P = []
# set maximum normal speed wmax = US # initialize variables for plotting rho2 = []; w1 = []; w2 = []; u2 = []; vt = []; 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. 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))
# set initial state, composition, and gas object P1 = 100000 T1 = 300 q = 'H2:0.31 N2O:0.69' mech = 'Mevel2015.cti' gas1 = ct.Solution(mech) gas1.TPX = T1,P1,q rho1 = gas1.density # Find CJ speed cj_speed = CJspeed(P1, T1, q, mech) # CJ state gas = PostShock_eq(cj_speed,P1, T1, q, mech) print('CJ computation for '+mech+' with composition ',q) P2 = gas.P T2 = gas.T q2 = gas.X rho2 = gas.density w2 = rho1/rho2*cj_speed u2= cj_speed-w2 Umin = soundspeed_eq(gas) print('CJ speed '+str(cj_speed)+' (m/s)'); print('CJ State'); print(' Pressure '+str(P2)+' (Pa)'); print(' Particle velocity '+str(u2)+' (m/s)'); # reflected shock from CJ detonation gas3 = ct.Solution(mech);
q = 'H2:2 O2:1 N2:3.76' mech = 'Mevel2017.cti' ## compute initial state gas1 = ct.Solution(mech) gas1.TPX = T1, P1, q h1 = gas1.enthalpy_mass r1 = gas1.density v1 = 1 / r1 ## compute CJ speed cj_speed = CJspeed(P1, T1, q, mech) print('CJ speed ' + str(cj_speed)) ## compute CJ state gas = PostShock_eq(cj_speed, P1, T1, q, mech) vcj = 1 / gas.density pcj = gas.P Pcj = pcj / ct.one_atm tcj = gas.T scj = gas.entropy_mass qcj = gas.X U1 = cj_speed ## Compute RAYLEIGH Line vR = [] PR = [] vmin = 0.3 * vcj vmax = 1.7 * vcj vinc = .01 * vcj
### 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 ZNDout = zndsolve(gas,gas1,cj_speed[i],advanced_output=True) ind_time_ZND[i] = ZNDout['ind_time_ZND'] ind_len_ZND[i] = ZNDout['ind_len_ZND'] exo_time_ZND[i] = ZNDout['exo_time_ZND'] exo_len_ZND[i] = ZNDout['exo_len_ZND'] Tf_ZND[i] = ZNDout['T'][-1] ##Calculate CJstate Properties### gas = PostShock_eq(cj_speed[i],P1[i], T1,x, mech) T2[i] = gas.T P2[i] = gas.P rho2[i] = gas.density #Approximate the effective activation energy using finite differences Ta = Ts[i]*(1.02) gas.TPX = Ta,Ps[i],x CVout1 = cvsolve(gas,t_end=1e-4) taua = CVout1['ind_time'] Tb = Ts[i]*(0.98) gas.TPX = Tb,Ps[i],x CVout2 = cvsolve(gas,t_end=1e-4) taub = CVout2['ind_time'] #Approximate effective activation energy for CV explosion if taua == 0 and taub == 0:
P1 = 100000 T1 = 500 q = 'H2:2 O2:1 ' mech = 'gri30.xml' fname = 'h2air' # Find CJ speed and related data, make CJ diagnostic plots cj_speed, R2, plot_data = CJspeed(P1, T1, q, mech, fullOutput=True) CJspeed_plot(plot_data, cj_speed) # Set up gas object gas1 = ct.Solution(mech) gas1.TPX = T1, P1, q # Find equilibrium post shock state for given speed gas = PostShock_eq(cj_speed, P1, T1, q, mech) u_cj = cj_speed * gas1.density / gas.density # Find frozen post shock state for given speed gas = PostShock_fr(cj_speed, P1, T1, q, mech) # Solve ZND ODEs, make ZND plots out = zndsolve(gas, gas1, cj_speed, t_end=1e-3, advanced_output=True) # Find CV parameters including effective activation energy gas.TPX = T1, P1, q gas = PostShock_fr(cj_speed, P1, T1, q, mech) Ts = gas.T Ps = gas.P Ta = Ts * 1.02 gas.TPX = Ta, Ps, q
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) exo_time_ZND[i] = ZNDout['exo_time_ZND'] exo_len_ZND[i] = ZNDout['exo_len_ZND'] ind_time_ZND[i] = ZNDout['ind_time_ZND'] ind_len_ZND[i] = ZNDout['ind_len_ZND'] Tf_ZND[i] = ZNDout['T'][-1] ### Calculate CJ state properties ### gas = PostShock_eq(cj_speed*overdrive[i], P1, T1, x, mech); T2[i] = gas.T P2[i] = gas.P rho2[i] = gas.density # Approximate the effective activation energy using finite differences factor = 0.02 Ta = Ts[i]*(1.0+factor) gas.TPX = Ta,Ps[i],x CVout1 = cvsolve(gas) taua = CVout1['ind_time'] Tb = Ts[i]*(1.0-factor) gas.TPX = Tb,Ps[i],x CVout2 = cvsolve(gas) taub = CVout2['ind_time'] # Approximate effective activation energy for CV explosion
fname = 'h2air' od = 1 gbound = 1.4 makePlot = True # EDIT VALUES ABOVE THIS LINE ############################## gas1 = ct.Solution(mech) gas1.TPX = T1, P1, q 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
q = 'O2:0.2095 N2:0.7808 CO2:0.0004 Ar:0.0093' mech = 'airNASA9ions.cti' fname = 'Air' U1 = 3500. 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 #Get equilibrium postshock state gas = PostShock_eq(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
print('Layer detonation computation for '+mech+' with composition '+q) print('State 1 - Initial state of reacting layer') print(' Pressure '+str(P1)+' (Pa)') print(' Temperature '+str(T1)+' (K)') print(' Density '+str(rho1)+' (kg/m3)') print(' Sound speed (frozen) '+str(a1_fr)+' (m/s)') print(' Enthalpy '+str(h1)+' (J/kg)') print(' Entropy '+str(s1)+' (J/kg K)') print(' gamma (frozen) '+str(gamma1_fr)+' ') ## # Find CJ speed U_CJ = CJspeed(P1, T1, q, mech) # Evaluate CJ gas state gas = PostShock_eq(U_CJ,P1, T1, q, mech) x2 = gas.X P2 = gas.P T2 = gas.T rho2 = gas.density a2_eq = soundspeed_eq(gas) s2 = gas.entropy_mass h2 = gas.enthalpy_mass w2 = rho1*U_CJ/rho2 u2 = U_CJ-w2 gamma2_eq = a2_eq**2*rho2/P2 print('State 2 - CJ ') print(' CJ speed '+str(U_CJ)+' (m/s)') print(' Pressure '+str(P2)+' (Pa)') print(' Temperature '+str(T2)+' (K)')
gamma1_fr = a1_fr * a1_fr * D1 / P1 print('Initial State:') print(' Composition ' + q) print(' Pressure %.2f (Pa) ' % (P1)) print(' Temperature %.2f (K) ' % (T1)) print(' Density %.3f (kg/m3) ' % (D1)) print(' a1 (frozen) %.2f (m/s)' % (a1_fr)) print(' gamma1 (frozen) %.4f ' % (gamma1_fr)) print('Computing CJ state and isentrope for ' + q + ' using ' + mech) # compute CJ speed cj_speed = CJspeed(P1, T1, q, mech) # compute equilibrium CJ state gas = PostShock_eq(cj_speed, P1, T1, q, mech) T2 = gas.T P2 = gas.P D2 = gas.density V2 = 1. / D2 S2 = gas.entropy_mass w2 = D1 * cj_speed / D2 u2 = cj_speed - w2 a2_eq = soundspeed_eq(gas) a2_fr = soundspeed_fr(gas) gamma2_fr = a2_fr * a2_fr * D2 / P2 gamma2_eq = a2_eq * a2_eq * D2 / P2 print('CJ speed = %.2f (m/s)' % (cj_speed)) print('CJ State')
## 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.; q4 = 'He:1.0' driver_mech = 'Mevel2017.cti'
# create gas objects for other states gas2 = ct.Solution(mech) gas3 = ct.Solution(mech) # compute minimum incident wave speed fig_num = 0; cj_speed = CJspeed(P1, T1, q, mech) # incident wave must be greater than or equal to cj_speed for # equilibrium computations UI = 1.2*cj_speed print('Incident shock speed UI = %.2f m/s' % (UI)) # compute postshock gas state object gas2 gas2 = PostShock_eq(UI, P1, T1, q, mech); P2 = gas2.P/ct.one_atm; print ('Equilibrium 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_eq(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 ('Equilibrium Post-Reflected-Shock State') print ('T3 = %.2f K, P3 = %.2f atm' % (gas3.T,P3))
plt.xlabel('Initial pressure [bar]') plt.ylabel('CJ speed [m/s]') plt.title('Cj detonation speed of hydrogen-air mixture', fontweight='bold') plt.grid() plt.savefig('hydrogen_cjspeed(P1).png', dpi=1000) plt.show() for phi in range(50, 175, 25): P1 = [] X = 'O2:0.5, N2:1.88, H2:' + str(phi / 100) PostShock_T = [] for P in range(100000, 1250000, 250000): gas.TPX = T1, P, X P1.append(P / 100000) U = CJspeed(P, T1, X, mech) gas = PostShock_eq(U, P, T1, X, mech) PostShock_T.append(gas.T) plt.plot(P1, PostShock_T, label="phi=%.2f" % (phi / 100)) plt.legend() plt.xlabel('Initial pressure [bar]') plt.ylabel('Post shock temperature [K]') plt.title('Post shock temerature of hydrogen-air mixture', fontweight='bold') plt.grid() plt.savefig('hydrogen_T(P1).png', dpi=1000) plt.show() for phi in range(50, 175, 25): P1 = [] X = 'O2:0.5, N2:1.88, H2:' + str(phi / 100) PostShock_P = []
gas1.TPX = T1, P1, q ## Evaluate initial state R1 = gas1.density c1_fr = soundspeed_fr(gas1) cp1 = gas1.cp_mass w1 = gas1.mean_molecular_weight gamma1_fr = c1_fr**2 * R1 / P1 ## Set shock speed cj_speed = CJspeed(P1, T1, q, mech) Us = cj_speed ## Evaluate gas state # q = 'O2:1. N2:3.76' gas = PostShock_eq(Us, P1, T1, q, mech) ## Evaluate properties of gas object T2 = gas.T P2 = gas.P R2 = gas.density V2 = 1 / R2 S2 = gas.entropy_mass w2 = gas1.density * Us / R2 u2 = Us - w2 x2 = gas.X c2_eq = soundspeed_eq(gas) c2_fr = soundspeed_fr(gas) gamma2_fr = c2_fr**2 * R2 / P2 gamma2_eq = c2_eq**2 * R2 / P2
for rho1 in np.linspace(start,stop,num=nsteps): gas1.SVX = s0,1/rho1,x0 P1 = gas1.P T1 = gas1.T print('Density '+str(rho1)+' (kg/m^3)') fid.write('# Initial conditions\n') fid.write('# Temperature (K) %4.1f\n' % T1) fid.write('# Pressure (Pa) %2.1f\n' % P1) fid.write('# Density (kg/m^3) %1.4e\n' % rho1) # Find CJ speed cj_speed = CJspeed(P1, T1, q, mech) print('CJspeed '+str(cj_speed)+' (m/s)'); gas = PostShock_eq(cj_speed,P1, T1, q, mech) P2 = gas.P # Evaluate overdriven detonations and reflected shocks fstart = 1.; fstop = 1.5; fstep = 0.05 fnsteps = int((fstop-fstart)/fstep) speed = []; vs = []; ps = []; pr = []; vr = [] for f in np.linspace(fstart,fstop,num=fnsteps): u_shock = f*cj_speed speed.append(u_shock) print(' Detonation Speed '+str(speed[-1])+' (m/s)') gas = PostShock_eq(u_shock,P1, T1, q, mech) # Evaluate properties of gas object vs.append(1./gas.density) ps.append(gas.P) [p3,UR,gas3] = reflected_eq(gas1,gas,gas3,u_shock)
print(' Specific heat at constant pressure '+str(gas2.cp_mass)+' (J/kg K)') print(' Expansion ratio '+str(rho1/rho2)+' (kg/m3)') print(' Entropy '+str(S2)+' (J/kg-K)') print(' Sound speed (frozen) '+str(af2)+' (m/s)') print(' Sound speed (equilibrium) '+str(ae2)+' (m/s)') print(' gamma2 (based on frozen sound speed) '+str(gamma2_fr)+' (m/s)') print(' gamma2 (based on equilibrium sound speed) '+str(gamma2_eq)+' (m/s)') if transport: print(' viscosity '+str(mu)+' (kg/m s)') print(' viscosity (kinematic)'+str(nu)+' (m2/s)') print(' thermal conductivity '+str(kcond)+' (W/m K)') print(' thermal diffusivity '+str(kdiff)+' (m2/s)') print(' Prandtl number '+str(Pr)) ## Postshock (Equilibrium) gas3 = PostShock_eq(speed,P1,T1,q,mech) af3 = soundspeed_fr(gas3) ae3 = soundspeed_eq(gas3) P3 = gas3.P T3 = gas3.T rho3 = gas3.density S3 = gas3.entropy_mass gamma3_fr = af3**2*rho3/P3 gamma3_eq = ae3**2*rho3/P3 w3 = rho1*speed/rho3 u3 = speed - w3 if transport: mu = gas3.viscosity nu = mu/rho3 kcond = gas3.thermal_conductivity kdiff = kcond/(rho3*gas3.cp_mass)