def get_ignition_delay(cantera_file_path, temperature, pressure, stoichiometry=1.0, isomer='N'): """ Get the ignition delay at temperature (K) and pressure (bar) and stochiometry (phi), for the butanol isomer (n,s,t,i) """ try: ct.suppress_thermo_warnings(True) except AttributeError: print("Sorry about the warnings...") gas = ct.Solution(cantera_file_path) assert isomer in ['N', 'S', 'T', 'I' ], "Expecting isomer N, S, T, or I not {}".format(isomer) oxygen_mole = 1.0 butanol_mole = stoichiometry * oxygen_mole / 6. X_string = isomer + 'C7H16:{0}, O2:{1}'.format(butanol_mole, oxygen_mole) gas.TPX = temperature, pressure * 1e5, X_string reactor = ct.IdealGasReactor(gas) reactor_network = ct.ReactorNet([reactor]) time = 0.0 end_time = 1000e-3 times = [] concentrations = [] pressures = [] temperatures = [] print_data = True while time < end_time: time = reactor_network.time times.append(time) temperatures.append(reactor.T) pressures.append(reactor.thermo.P) concentrations.append(reactor.thermo.concentrations) reactor_network.step(end_time) print("reached end time {0:.4f} ms in {1} steps ".format( times[-1] * 1e3, len(times))) concentrations = np.array(concentrations) times = np.array(times) pressures = np.array(pressures) temperatures = np.array(temperatures) dTdt = (temperatures[1:] - temperatures[:-1]) / (times[1:] - times[:-1]) step_with_fastest_T_rise = dTdt.argmax() if step_with_fastest_T_rise > 1 and step_with_fastest_T_rise < len( times) - 2: ignition_time_ms = 1e3 * times[step_with_fastest_T_rise] print( "At {0} K {1} bar, ignition delay time is {2} ms for {3}-butanol". format(temperature, pressure, ignition_time_ms, isomer)) return ignition_time_ms else: print( "At {0} K {1} bar, no ignition is detected for {2}-butanol".format( temperature, pressure, isomer)) return np.infty
def set_env(): import os import cantera absdir = os.path.abspath(os.path.dirname(os.path.realpath(__file__))) absdir = os.path.join(absdir, 'data') os.environ['CANTERA_DATA'] = f'{absdir}:$CANTERA_DATA' cantera.add_directory(absdir) cantera.suppress_thermo_warnings()
def __init__(self, cti_file=None, plotting=True): self.reactive_experiments = {} self.nonreactive_experiments = {} self.reactive_case = None self.reactive_file = None self.nonreactive_case = None self.nonreactive_file = None self.presout = None self.volout = None self.nonreactive_sim = None self.reactive_sim = None self.plotting = plotting if self.plotting: self.all_runs_figure = None self.all_runs_lines = {} self.nonreactive_figure = None self.pressure_comparison_figure = None self.simulation_figure = None self.output_attributes = [ 'reactive_file', 'nonreactive_file', 'nonreactive_end_time', 'reactive_end_time', 'reactive_compression_time', 'nonreactive_offset_points', 'reactive_offset_points' ] if cti_file is None: path_args = {'strict': True} if sys.version_info >= (3, 6) else {} try: cti_file = str(Path('./species.cti').resolve(**path_args)) except FileNotFoundError: cti_file = str(Path(input('Input the name of the CTI file: ')).resolve()) self.cti_file = cti_file with open(str(cti_file), 'r') as in_file: self.cti_source = in_file.read() ct.suppress_thermo_warnings(False) ct.Solution(self.cti_file) ct.suppress_thermo_warnings()
def __init__(self, cti_file=None, plotting=True): self.reactive_experiments = {} self.nonreactive_experiments = {} self.reactive_case = None self.reactive_file = None self.nonreactive_case = None self.nonreactive_file = None self.presout = None self.volout = None self.nonreactive_sim = None self.reactive_sim = None self.plotting = plotting if self.plotting: self.all_runs_figure = None self.all_runs_lines = {} self.nonreactive_figure = None self.pressure_comparison_figure = None self.simulation_figure = None self.output_attributes = [ 'reactive_file', 'nonreactive_file', 'nonreactive_end_time', 'reactive_end_time', 'reactive_compression_time', 'nonreactive_offset_points', 'reactive_offset_points' ] if cti_file is None: path_args = {'strict': True} if sys.version_info >= (3, 6) else {} try: cti_file = str(Path('./species.cti').resolve(**path_args)) except FileNotFoundError: cti_file = str(Path(input('Input the name of the CTI file: ')).resolve()) self.cti_file = cti_file with open(str(cti_file), 'r') as in_file: self.cti_source = in_file.read() ct.suppress_thermo_warnings(False) ct.Solution(self.cti_file) ct.suppress_thermo_warnings()
"""Contains main driver function for pyMARS program.""" from cantera import Solution, suppress_thermo_warnings # local imports import soln2cti from drgep import run_drgep from drg import run_drg from pfa import run_pfa from sensitivity_analysis import run_sa from convert_chemkin_file import convert # Avoid long warnings from Cantera about thermodynamic polynomials suppress_thermo_warnings() def pymars(model_file, conditions, error, method, target_species, retained_species=None, run_sensitivity_analysis=False, epsilon_star=0.1): """Driver function for pyMARS to reduce a model. Parameters ---------- model_file : str Cantera-format model to be reduced (e.g., 'mech.cti'). conditions : str File with list of autoignition initial conditions. error : float
.. moduleauthor:: Kyle Niemeyer <*****@*****.**> """ # Python 2 compatibility from __future__ import print_function from __future__ import division # Standard libraries import os from collections import namedtuple import numpy # Related modules try: import cantera as ct ct.suppress_thermo_warnings() except ImportError: print("Error: Cantera must be installed.") raise try: import tables except ImportError: print('PyTables must be installed') raise # Local imports from .utils import units from .detect_peaks import detect_peaks def first_derivative(x, y):
@author: boss """ """ This is just a change to the discription to test pushing a change in the code. """ import cantera import matplotlib.pyplot as plt import numpy as np import math import time #import pickle #import cProfile #from statistics import mode cantera.suppress_thermo_warnings() ####Set experiment parameters mechanism='grimech30.cti' #Mechanism file #Parameters for main loop T = np.linspace(600,1000,2) #Temperature [K] P = np.linspace(1,30,2) #Pressure [atm] Phi = np.linspace(0.1,2,2) #Equivalence ratio Fuel = np.linspace(0.001,0.01,2)#Fuel mole fraction #Parameters for mixture fuel_name = 'CH4' #chemical formula of fuel #fuel C(x)H(y)O(z) x=1 #moles of carbon in fuel y=4 #moles of hydrogen in fuel z=0 #moles of oxygen in fuel diluent_name = 'N2' #chemical formula of diluent
def run_single(self): gas=self.processor.solution reactorPressure=gas.P self.reactorPressure=self.processor.solution.P pressureValveCoefficient=self.pvalveCoefficient maxPressureRiseAllowed=self.maxPrise print(maxPressureRiseAllowed,self.reactorPressure,pressureValveCoefficient) #Build the system components for JSR pretic=time.time() if bool(self.observables) and self.kineticSens==1: ################################################################### #Block to create temp reactor network to pre-solve JSR without kinetic sens ct.suppress_thermo_warnings() tempgas=ct.Solution(self.processor.cti_path) tempgas.TPX=self.processor.solution.TPX tempfuelAirMixtureTank=ct.Reservoir(tempgas) tempexhaust=ct.Reservoir(tempgas) tempstirredReactor=ct.IdealGasReactor(tempgas,energy=self.energycon, volume=self.reactor_volume) tempmassFlowController=ct.MassFlowController(upstream=tempfuelAirMixtureTank, downstream=tempstirredReactor, mdot=tempstirredReactor.mass/self.residence_time) tempPressureRegulator=ct.Valve(upstream=tempstirredReactor,downstream=tempexhaust, K=pressureValveCoefficient) tempreactorNetwork=ct.ReactorNet([tempstirredReactor]) tempreactorNetwork.rtol = self.rtol tempreactorNetwork.atol = self.atol print(self.rtol,self.atol) tempreactorNetwork.advance_to_steady_state() ################################################################### #reactorNetwork.advance_to_steady_state() #reactorNetwork.reinitialize() elif self.kineticSens and bool(self.observables)==False: #except: print('Please supply a non-empty list of observables for sensitivity analysis or set kinetic_sens=0') pretoc=time.time() print('Presolving Took {:3.2f}s to compute'.format(pretoc-pretic)) fuelAirMixtureTank=ct.Reservoir(self.processor.solution) exhaust=ct.Reservoir(self.processor.solution) if bool(self.observables) and self.kineticSens==1: stirredReactor=ct.IdealGasReactor(tempgas,energy=self.energycon, volume=self.reactor_volume) else: stirredReactor=ct.IdealGasReactor(self.processor.solution,energy=self.energycon, volume=self.reactor_volume) #stirredReactor=ct.IdealGasReactor(self.processor.solution,energy=self.energycon, # volume=self.reactor_volume) massFlowController=ct.MassFlowController(upstream=fuelAirMixtureTank, downstream=stirredReactor, mdot=stirredReactor.mass/self.residence_time) pressureRegulator=ct.Valve(upstream=stirredReactor,downstream=exhaust,K=pressureValveCoefficient) reactorNetwork=ct.ReactorNet([stirredReactor]) if bool(self.observables) and self.kineticSens==1: for i in range(gas.n_reactions): stirredReactor.add_sensitivity_reaction(i) reactorNetwork.rtol_sensitivity=0.0000001 reactorNetwork.atol_sensitivity=0.00000001 print('Sens tols:'+str(reactorNetwork.atol_sensitivity)+', '+str(reactorNetwork.rtol_sensitivity)) # now compile a list of all variables for which we will store data columnNames = [stirredReactor.component_name(item) for item in range(stirredReactor.n_vars)] columnNames = ['pressure'] + columnNames # use the above list to create a DataFrame timeHistory = pd.DataFrame(columns=columnNames) # Start the stopwatch tic = time.time() reactorNetwork.rtol = self.rtol reactorNetwork.atol = self.atol #reactorNetwork.max_err_test_fails= 10000 #print(reactorNetwork.max_err_test_fails) if self.physicalSens==1 and bool(self.observables)==False: #except: print('Please supply a non-empty list of observables for sensitivity analysis or set physical_sens=0') #Establish a matrix to hold sensitivities for kinetic parameters, along with tolerances if self.kineticSens==1 and bool(self.observables): #senscolumnNames = ['Reaction']+observables senscolumnNames = self.observables #sensArray = pd.DataFrame(columns=senscolumnNames) #senstempArray = np.zeros((gas.n_reactions,len(observables))) dfs = [pd.DataFrame() for x in range(len(self.observables))] #tempArray = [np.zeros(self.processor.solution.n_reactions) for x in range(len(self.observables))] #stirredReactor.thermo.X=tempstirredReactor.thermo.X posttic=time.time() # for steps in range(10): # reactorNetwork.step() reactorNetwork.advance_to_steady_state() posttoc=time.time() print('Main Solver Took {:3.2f}s to compute'.format(posttoc-posttic)) final_pressure=stirredReactor.thermo.P sens=reactorNetwork.sensitivities() #print(sens[:,787]) #print(gas.species_names) #print(self.observables) #print(sens) if self.kineticSens==1 and bool(self.observables): #print((pd.DataFrame(sens[0,:])).transpose()) #test=pd.concat([pd.DataFrame(),pd.DataFrame(sens[0,:]).transpose()]) #print(test) for k in range(len(self.observables)): index=gas.species_names.index(self.observables[k]) dfs[k] = dfs[k].append(((pd.DataFrame(sens[index+3,:])).transpose()),ignore_index=True) #dfs[k]=pd.concat([dfs[k],pd.DataFrame(sens[k,:]).transpose()]) #dfs[k]=pd.DataFrame(sens[k,:]).transpose() #print(dfs) toc = time.time() print('Simulation Took {:3.2f}s to compute'.format(toc-tic)+' at T = '+str(stirredReactor.T)) #print(dfs[0]) columnNames = [] #Store solution to a solution array #for l in np.arange(stirredReactor.n_vars): #columnNames.append(stirredReactor.component_name(l)) columnNames=[stirredReactor.component_name(item) for item in range(stirredReactor.n_vars)] #state=stirredReactor.get_state() state=np.hstack([stirredReactor.mass, stirredReactor.volume, stirredReactor.T, stirredReactor.thermo.X]) data=pd.DataFrame(state).transpose() data.columns=columnNames pressureDifferential = timeHistory['pressure'].max()-timeHistory['pressure'].min() if(abs(pressureDifferential/self.reactorPressure) > maxPressureRiseAllowed): #except: print("WARNING: Non-trivial pressure rise in the reactor. Adjust K value in valve") if self.kineticSens==1: numpyMatrixsksens = [dfs[dataframe].values for dataframe in range(len(dfs))] self.kineticSensitivities = np.dstack(numpyMatrixsksens) #print(np.shape(self.kineticSensitivities)) self.solution=data return (self.solution,self.kineticSensitivities) else: self.solution=data return (self.solution,[])
# and # # b = 0.08664*R*Tc/Pc # # where R is the gas constant. # # For stable species, the critical properties are readily available. For # radicals and other short-lived intermediates, the Joback method is used to # estimate critical properties. For details of the method, see: Joback and Reid, # "Estimation of pure- component properties from group-contributions," Chem. # Eng. Comm. 57 (1987) 233-243, doi: 10.1080/00986448708960487 # There is a slight discontinuity in the thermo for three species at the mid- # point temperature. We are aware and okay, so we will suppress the warning # statement (note: use this feature at your own risk in other codes!) ct.suppress_thermo_warnings() """Real gas IDT calculation""" # Load the real gas mechanism: real_gas = ct.Solution('nDodecane_Reitz.cti','nDodecane_RK') # Set the state of the gas object: real_gas.TP = reactorTemperature, reactorPressure # Define the fuel, oxidizer and set the stoichiometry: real_gas.set_equivalence_ratio(phi=1.0, fuel='c12h26', oxidizer={'o2':1.0, 'n2':3.76}) # Create a reactor object and add it to a reactor network
def Engine(fname): import sys import numpy as np import cantera as ct import matplotlib.pyplot as plt import csv import time # from scipy.interpolate import interp1d import math from openpyxl import load_workbook def volume(t): theta = t * omega + IVC * np.pi / 180 #theta in radian; TDC corresponds to theta=0 v = V_min * (1 + ((r_c - 1) / 2) * (L / a + 1 - np.cos(theta) - np.sqrt(pow(L / a, 2) - pow(np.sin(theta), 2)))) return v def surfA(t): area = np.pi * math.pow(D, 2) / 4 SA = 2 * area + np.pi * D * volume(t) / area return SA def vel(t): #Note - the only input to the passed through function is time theta = t * omega + IVC * np.pi / 180 #TDC corresponds to theta=0 z = np.sqrt(pow(L / a, 2) - pow(np.sin(theta), 2)) v = omega * (V_min / A_p) * ( (r_c - 1) / 2) * np.sin(theta) * (1 + np.cos(theta) / z) return v def qfluxB( t): #Note - the only input to the passed through function is time rho = m_t / volume(t) T = (unb.mass * unb.thermo.T + bur.mass * bur.thermo.T) / (unb.mass + bur.mass) k = k_0 * pow(T, n_k) #W/m-K, for air mu = mu_0 * pow(T, n_mu) #kg/m-s, for air Re = rho * MPS * D / mu Nu = Nu_0 * pow(Re, n_Nu) h = Nu * k / D area = surfA(t) * bur.volume / volume(t) q = h * area * (bur.thermo.T - T_w) * HeatOn return q def qfluxU( t): #Note - the only input to the passed through function is time rho = m_t / volume(t) T = (unb.mass * unb.thermo.T + bur.mass * bur.thermo.T) / (unb.mass + bur.mass) k = k_0 * pow(T, n_k) #W/m-K, for air mu = mu_0 * pow(T, n_mu) #kg/m-s, for air Re = rho * MPS * D / mu Nu = Nu_0 * pow(Re, n_Nu) h = Nu * k / D area = surfA(t) * unb.volume / volume(t) q = h * area * (unb.thermo.T - T_w) / A_p * HeatOn return q def mflow( t): #Note - the only input to the passed through function is time theta = t * omega + IVC * np.pi / 180 #TDC corresponds to theta=0 if (theta >= theta_0r) and (theta <= theta_99r): # dxb=1/Deltathetar dxb = b * (m + 1) / Deltathetar * pow( ((theta - theta_0r) / Deltathetar), m) * math.exp(-b * pow( ((theta - theta_0r) / Deltathetar), m + 1)) else: dxb = 0 mf = burnflag * m_t * omega * dxb #mass flow unb to bur return mf ## MAIN - read inputs wb = load_workbook(fname) ws = wb.active r_c = ws['A1'].value # compression ratio L = ws['A2'].value # con rod length [m] D = ws['A3'].value # bore [m] stroke = ws['A4'].value # stroke [m] IVC = ws['A5'].value # IVC crank angle where TDC = 0 EVO = ws['A6'].value # EVO crank angle where TDC = 0 CrevOn = ws['A7'].value # Flag to determine whether to use crevice model HeatOn = ws[ 'A8'].value # Flag to determine whether to use heat transfer model crevfrac = ws['A9'].value # crevice volume fraction of minimum volume RPM = ws['A10'].value # engine speed b = ws['A11'].value # Wiebe b parameter m = ws['A12'].value # Wiebe m parameter theta_0 = ws['A13'].value # Wiebe combustion start parameter Deltatheta = ws['A14'].value # Wiebe combustion duration parameter eta_c = ws['A15'].value # combustion efficiency T_IVC = ws['A16'].value # IVC temperature [K] P_IVC = ws['A17'].value # IVC pressure [bar] T_w = ws['A18'].value # wall temperature [K] RON = ws['A19'].value # fuel RON MON = ws['A20'].value # fuel MON Phi = ws['A21'].value # equivalence ratio burnflag = ws[ 'A22'].value # fraction of mass transferred out of unburned zone k_0 = ws['A23'].value # thermal conductivity [W/m-K] n_k = ws['A24'].value # thermal conductivity temperature exponent mu_0 = ws['A25'].value # dynamic viscosity [kg/m-s] n_mu = ws['A26'].value # viscosity temperature exponent Nu_0 = ws['A27'].value # Nusselt number correlation scaling constant n_Nu = ws[ 'A28'].value # Nusselt number correlation Reynolds number exponent Chemflag = ws['A29'].value # End gas chemistry flag; 1=on Y_EGR = ws['A30'].value # EGR mass fraction Y_f_ref = ws['A31'].value # mass fraction of FUEL to the reformer Phi_ref = ws['A32'].value # reformer equivalence ratio Ref_comp = ws[ 'A33'].value # reformer composition: 0=PCI; 1=equilibriu; 2=ideal mechanism = ws['A34'].value # kinetic mechanism ## Engine geometry calculations a = stroke / 2 # crank radius A_p = np.pi * D * D / 4 # piston area [m^2] V_disp = A_p * stroke # displacement volume [m^3] V_min = V_disp / (r_c - 1) # TDC volume [m^3] V_max = V_min + V_disp # BDC volume [m^3] MPS = 2 * stroke * RPM / 60 #mean piston speed [m/s] ## Engine operating conditions theta_0r = theta_0 * np.pi / 180 #start of combustion in radians Deltathetar = Deltatheta * np.pi / 180 #combustion duration in radians theta_99r = theta_0r + Deltathetar * math.pow( -math.log(0.01) / b, 1 / m) #99% of mass burn for Wiebe omega = RPM * 2 * np.pi / 60 #rotation rate in radian per second based on RPM T_0 = T_IVC # K P_0 = 1e5 * P_IVC # Pa ct.suppress_thermo_warnings() env = ct.Solution('air.xml') env.TP = T_w, P_0 gas = ct.Solution(mechanism) x_init = np.zeros(gas.X.shape) c4 = ws['C41'].value #0.01 #n-butane c5 = ws['C42'].value #0.0 #iso-pentane c5_2 = ws['C43'].value #0.04 #n-pentane ic8 = ws['C44'].value #0.93 #Iso-octane c6 = ws['C45'].value #0.0 #added for 1-hexene nc7 = ws['C46'].value #0.0 #n-heptane c7_2 = ws['C47'].value #0.0 #tolune tmb = ws['C48'].value #0.02 #1,2,4 Trimethyl benzene eth = ws['C49'].value #0 #Ethanol x_init[gas.species_index('C4H10')] = c4 x_init[gas.species_index('IC5H12')] = c5 x_init[gas.species_index('NC5H12')] = c5_2 x_init[gas.species_index('C6H12-1')] = c6 x_init[gas.species_index('NC7H16')] = nc7 x_init[gas.species_index('C6H5CH3')] = c7_2 x_init[gas.species_index('IC8')] = ic8 x_init[gas.species_index('T124MBZ')] = tmb x_init[gas.species_index('C2H5OH')] = eth # x_init[gas.species_index('NO')]=150e-6 #150 ppm NO ## Determine global composition nC = (4 * c4) + (5 * c5) + (5 * c5_2) + (6 * c6) + (7 * nc7) + ( 8 * ic8) + (9 * tmb) + (2 * eth) + (7 * c7_2) nH = (10 * c4) + (12 * c5) + (12 * c5_2) + (12 * c6) + (16 * nc7) + ( 18 * ic8) + (12 * tmb) + (6 * eth) + (8 * c7_2) nO = 1 * eth x_init[gas.species_index('O2')] = (nC + nH / 4 - nO / 2) / Phi x_init[gas.species_index('N2')] = 3.76 * (nC + nH / 4 - nO / 2) / Phi gas.TPX = 300, 1e5, x_init y_global = gas.Y ## Determine EGR composition keep = np.zeros(gas.X.shape) keep[gas.species_index('N2')] = 1 keep[gas.species_index('O2')] = 1 keep[gas.species_index('CO2')] = 1 keep[gas.species_index('CO')] = 1 keep[gas.species_index('H2O')] = 1 keep[gas.species_index('H2')] = 1 gas.TPY = 300, 1e5, y_global gas.equilibrate('HP') #find equilibrium concentration y_EGR = gas.Y * keep # y_EGR[7:86]=0; #set minor species to zero; based on MECHANISM gas.Y = y_EGR #use Cantera to renormalize mass fraction y_EGR = gas.Y y_eng = 1 / (1 + Y_EGR) * y_global + +Y_EGR / (1 + Y_EGR) * y_EGR gas.TPX = 298, 1e5, x_init delta_uf = gas.standard_int_energies_RT * (ct.gas_constant * 298) / gas.molecular_weights tmax = (EVO - IVC) / 6 / RPM # time for one revolution step = 8 * (EVO - IVC) tim = np.linspace(tmax / step, tmax, step) theta = IVC + omega * tim * 180 / np.pi ## Cantera reactor setup gas.TPY = T_0, P_0, y_eng #reactants # gas.set_multiplier(1) #option to make reactants inert unb = ct.IdealGasReactor(gas) if Chemflag == 0: unb.chemistry_enabled = False gas.TPY = T_0, P_0, y_eng #products gas.equilibrate( 'HP' ) #make the products hot so that mass will burn when it moves into products bur = ct.IdealGasReactor(gas) r3 = ct.Reservoir(env) #outside world gas.TPY = T_w, P_0, y_eng crev = ct.IdealGasReactor(gas) #crevices crev.chemistry_enabled = False #no reaction in crevices piston = ct.Wall(unb, r3, velocity=vel, A=A_p, Q=qfluxU) flame = ct.Wall( unb, bur, K=0.01, A=A_p) #expansion rate K set to lowest value possible to have const P topland = ct.Wall( crev, r3, U=1e3) #heat xfer rate set to keep close to wall temperature head = ct.Wall(bur, r3, A=1, Q=qfluxB) mfc = ct.MassFlowController(unb, bur, mdot=mflow) V1 = ct.Valve(unb, crev) V1.set_valve_coeff(1e-6 * CrevOn) V2 = ct.Valve(crev, bur) V2.set_valve_coeff(1e-6 * CrevOn) sim = ct.ReactorNet([unb, bur, crev]) sim.atol = 1e-12 sim.rtol = 1e-6 initvol = 1e-3 unb.volume = (1 - initvol) * volume(0) bur.volume = initvol * volume(0) crev.volume = crevfrac * V_min m_t = unb.mass + bur.mass + crev.mass vol = np.zeros(step) T = np.zeros(step) vol2 = np.zeros(step) P = np.zeros(step) outdat = np.zeros((step, 13)) SpecMatrix = np.zeros((step, gas.X.shape[0])) #burnflag=0.82 #flag to stop combustion if unburned mass gets too low # y_old=unb.thermo.Y for i in range(step): #step): if math.fmod(i, 32) == 0: print(i / step) sim.advance(tim[i]) # burnflag=unb.mass/m_t # if unb.mass/m_t < 1-eta_c: # burnflag=0 outdat[i, 0] = IVC + tim[i] * RPM / 60 * 360 outdat[i, 1] = bur.thermo.P / 1e5 outdat[i, 2] = bur.thermo.T outdat[i, 3] = bur.mass / m_t outdat[i, 4] = qfluxB(tim[i]) outdat[i, 5] = unb.thermo.T outdat[i, 6] = qfluxU(tim[i]) * A_p outdat[i, 7] = unb.mass / m_t outdat[i, 8] = crev.mass / m_t outdat[i, 9] = volume(sim.time) outdat[i, 10] = -(unb.kinetics.net_production_rates * unb.thermo.molecular_weights ).dot(delta_uf) * unb.volume * 60 / (RPM * 360) outdat[i, 11] = m_t outdat[i, 12] = ct.gas_constant / gas.mean_molecular_weight outdat[i, 13] = volume(tim[i]) SpecMatrix[i] = gas.X # outdat[i,10]=-(unb.thermo.Y-y_old).dot(delta_uf)/(tim[2]-tim[1])*unb.mass # y_old=unb.thermo.Y return outdat, SpecMatrix
def CV_IgDelay_Thesis(x_initial, Temp, Press, PureFlag, fname, RK_Flag): import sys import time as ttime import numpy as np import cantera as ct #import matplotlib.pyplot as plt import csv #from scipy.interpolate import interp1d import math from openpyxl import load_workbook ct.suppress_thermo_warnings() if RK_Flag == 1: gas = ct.Solution('renKokjohn.cti') else: gas = ct.Solution('LLNL_gasoline_20170621_nox_galway.cti') if PureFlag == 1 and RK_Flag != 1: """=========Determine Species if using Pure Fuel==============""" #gas1 = ct.Solution('ic8_ver3_mech.cti') #gas = ct.Solution('RenKokjohn.cti') Phi = 1 x_init = np.zeros(gas.X.shape) wb = load_workbook(fname) ws = wb.active c4 = ws['C41'].value #0.01 #n-butane c5 = ws['C42'].value #0.0 #iso-pentane c5_2 = ws['C43'].value #0.04 #n-pentane ic8 = ws['C44'].value #0.93 #Iso-octane c6 = ws['C45'].value #0.0 #added for 1-hexene nc7 = ws['C46'].value #0.0 #n-heptane c7_2 = ws['C47'].value #0.0 #tolune tmb = ws['C48'].value #0.02 #1,2,4 Trimethyl benzene eth = ws['C49'].value #0 #Ethanol x_init[gas.species_index('C4H10')] = c4 x_init[gas.species_index('IC5H12')] = c5 x_init[gas.species_index('NC5H12')] = c5_2 x_init[gas.species_index('C6H12-1')] = c6 x_init[gas.species_index('NC7H16')] = nc7 x_init[gas.species_index('C6H5CH3')] = c7_2 x_init[gas.species_index('IC8')] = ic8 x_init[gas.species_index('T124MBZ')] = tmb x_init[gas.species_index('C2H5OH')] = eth # x_init[gas.species_index('NO')]=150e-6 #150 ppm NO ## Determine global composition carbon = np.zeros(gas.X.size) hydrogen = np.zeros(gas.X.size) oxygen = np.zeros(gas.X.size) for i in range(gas.n_species): carbon[i] = gas.n_atoms(i, 'C') hydrogen[i] = gas.n_atoms(i, 'H') oxygen[i] = gas.n_atoms(i, 'O') nC = np.dot(x_init, carbon) nH = np.dot(x_init, hydrogen) nO = np.dot(x_init, oxygen) print(nC) print(nH) print(nO) x_init[gas.species_index('O2')] = (nC + nH / 4 - nO / 2) / Phi x_init[gas.species_index('N2')] = 3.76 * (nC + nH / 4 - nO / 2) / Phi elif PureFlag == 1 and RK_Flag == 1: """=========Determine Species if using Pure Fuel==============""" #gas1 = ct.Solution('ic8_ver3_mech.cti') #gas = ct.Solution('RenKokjohn.cti') Phi = 1 x_init = np.zeros(gas.X.shape) wb = load_workbook(fname) ws = wb.active c4 = ws['C50'].value #0.01 #n-butane c5 = ws['C51'].value #0.0 #iso-pentane c5_2 = ws['C52'].value #0.04 #n-pentane ic8 = ws['C53'].value #0.93 #Iso-octane c6 = ws['C54'].value #0.0 #added for 1-hexene nc7 = ws['C55'].value #0.0 #n-heptane c7_2 = ws['C56'].value #0.0 #tolune tmb = ws['C57'].value #0.02 #1,2,4 Trimethyl benzene eth = ws['C58'].value #0 #Ethanol x_init[gas.species_index('nC7h16')] = nc7 x_init[gas.species_index('jc8h16')] = c6 #added for di-isobutylene x_init[gas.species_index('ic8h18')] = ic8 x_init[gas.species_index('C2H5OH')] = eth x_init[gas.species_index('c7h8')] = c7_2 carbon = np.zeros(gas.X.size) hydrogen = np.zeros(gas.X.size) oxygen = np.zeros(gas.X.size) for i in range(gas.n_species): carbon[i] = gas.n_atoms(i, 'C') hydrogen[i] = gas.n_atoms(i, 'H') oxygen[i] = gas.n_atoms(i, 'O') nC = np.dot(x_init, carbon) nH = np.dot(x_init, hydrogen) nO = np.dot(x_init, oxygen) x_init[gas.species_index('O2')] = (nC + nH / 4 - nO / 2) / Phi x_init[gas.species_index('N2')] = 3.76 * (nC + nH / 4 - nO / 2) / Phi # print(nC) # print(nH) # print(nO) else: x_init = x_initial # print('Starting Reactor') # print('whatever') gas.TPX = Temp, Press, x_init # print(gas.report()) r1 = ct.IdealGasReactor(gas) #Ignition Delay reactor sim2 = ct.ReactorNet([r1]) time = 0 #Initialize Time Temp_cur = 0 #ig_temp_cont[n] Press_cv = [] Temp_cv = [] timeapp = [] # print('Starting Calculation') # ttime.sleep(5) while (Temp_cur < Temp + 50 and time < 20e-3): time += 1.e-6 sim2.advance(time) time_cur = time #milliseconds Reac_Press = r1.thermo.P Reac_Temp = r1.T Temp_cur = Reac_Temp # times.append(time_cur) Press_cv.append(Reac_Press) Temp_cv.append(Reac_Temp) timeapp.append(time) # if np.remainder(time,1.e-3)<1e-8: # print(time) # print('Running') Final_temp = Reac_Temp tau = (time_cur) return tau, Final_temp
""" import os import shutil import copy import errno import pickle import time, sys import numpy as np import cantera as ct import datetime import flames import common_functions as cf ct.suppress_thermo_warnings() #Suppress cantera warnings! def run_flame_simulation(mech, arrtype, pres, temp, fue, oxi, dilu, mix_params, safi, par, Mingrid, Mul_soret, Loglevel): """ Takes information from initializer and runs necessary functions to perform a one-dimensional simulation. Simulation results will be saved if booleans are set to True. Parameters ---------- mech : str A .cti mechanism file containing all reaction and species information. arrtype : str Defines the scale that conditions are in. Either linear or logarithmic