rho3 = [driver_gas.density] P3 = [driver_gas.P] T3 = [driver_gas.T] S4 = driver_gas.entropy_mass ## compute unsteady expansion (frozen) print('Generating points on isentrope P-u curve') vv = 1/rho3[0] while u3[-1] < u2[-1]: vv = vv*1.01 driver_gas.SVX = S4,vv,driver_gas.X if EQ_EXP: # required for equilibrium expansion driver_gas.equilibrate('SV') a3.append(soundspeed_eq(driver_gas)) else: # use this for frozen expansion a3.append(soundspeed_fr(driver_gas)) P3.append(driver_gas.P) T3.append(driver_gas.T) rho3.append(driver_gas.density) u3.append(u3[-1] - 0.5*(P3[-1]-P3[-2])*(1/(rho3[-1]*a3[-1]) + 1./(rho3[-2]*a3[-2]))) ## Input limits for finding intersection of polars # Convert all lists to numpy arrays P2 = np.asarray(P2); u2 = np.asarray(u2); P3 = np.asarray(P3); u3 = np.asarray(u3); T2 = np.asarray(T2); a2 = np.asarray(a2); rho2 = np.asarray(rho2); T3 = np.asarray(T3); a3 = np.asarray(a3); rho3 = np.asarray(rho3);
taua = CVout1['ind_time'] taub = CVout2['ind_time'] if taua == 0 and taub == 0: theta_effective_CV = 0 else: theta_effective_CV = 1 / Ts * ((np.log(taua) - np.log(taub)) / ((1 / Ta) - (1 / Tb))) # Find Gavrikov induction length based on 50% limiting species consumption, # fuel for lean mixtures, oxygen for rich mixtures # Westbrook time based on 50% temperature rise limit_species = 'H2' i_limit = gas.species_index(limit_species) gas.TPX = Ts, Ps, q X_initial = gas.X[i_limit] gas.equilibrate('UV') X_final = gas.X[i_limit] T_final = gas.T X_gav = 0.5 * (X_initial - X_final) + X_final T_west = 0.5 * (T_final - Ts) + Ts for i, X in enumerate(CVout1['speciesX'][i_limit, :]): if X > X_gav: t_gav = CVout1['time'][i] x_gav = t_gav * out['U'][0] for i, T in enumerate(CVout1['T']): if T < T_west: t_west = CVout1['time'][i] x_west = t_west * out['U'][0]
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 ## # Set freestream velocity .01% above sound speed U1 = a1*1.0001 mu_min = np.arcsin(a1/U1) # Mach angle # check to see if flow speed is supersonic
wmax = np.sqrt(2*h0) # initialize variables for computing PM properties and plotting rho = []; a = []; P = []; T = []; h = []; mu = []; M = []; Me = []; u = []; ue = []; v1 = 1/rho2 # lower limit to specific volume in PM fan v2 = 50*v1 # upper limit to specific volume in PM fan vstep = 1000 ## # Compute expansion conditions over range from minimum to maximum specific volume. # User can adjust the increment and endpoint to get a smooth output curve and reliable integral. # Could also try a logarithmic range for some cases. for v in np.linspace(v1,v2,num=vstep): rho.append(1/v) x = gas.X # update mole fractions based on last gas state gas.SVX = s2,v,x gas.equilibrate('SV') # required for equilibrium expansion h.append(gas.enthalpy_mass) u.append(np.sqrt(2*(h0-h[-1]))) # flow speed within expansion # Need to explicitly upcast to complex, otherwise get NaN: ue.append(np.real(np.sqrt(2*(np.asarray(h1-h[-1],dtype=complex))))) # ideal axial velocity for RDE model a.append(soundspeed_eq(gas)) # use this for equilibrium expansion, almost always the case for detonation products #a.append(soundspeed_fr(gas)) # use this for frozen expansion Me.append(ue[-1]/a[-1]) M.append(u[-1]/a[-1]) if M[-1] < 1: # Sometimes the first M value has been observed to be ~0.999 which leads to errors # in the arcsin and sqrt functions that follow M[-1] = 1.00001 mu.append(np.arcsin(1/M[-1])) T.append(gas.T) P.append(gas.P)