コード例 #1
0
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
コード例 #2
0
ファイル: __init__.py プロジェクト: mbkumar/CanteraPFR
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()
コード例 #3
0
ファイル: conditions.py プロジェクト: rwhitt2049/UConnRCMPy
    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()
コード例 #4
0
ファイル: conditions.py プロジェクト: bryanwweber/UConnRCMPy
    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()
コード例 #5
0
"""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
コード例 #6
0
ファイル: simulation.py プロジェクト: AdamKrivoshein/PyTeCK
.. 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):
コード例 #7
0
@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
コード例 #8
0
    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,[])
コード例 #9
0
ファイル: NonIdealShockTube.py プロジェクト: wbessler/cantera
# 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
コード例 #10
0
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