示例#1
0
    def __call__(self, t, y):
        """
        Set of ODEs to solve ZND Detonation Problem.
    
        INPUT:
            t = time
            y = solution array [pressure, density, position, species mass 1, 2, ..]
            gas = working gas object
            U1 = shock velocity (m/s)
            r1 = initial density (kg/m^3)
        
        OUTPUT:
            An array containing time derivatives of:
                pressure, density, distance and species mass fractions, 
            formatted in a way that the integrator in zndsolve can recognize.
            
        """
        self.gas.DPY = y[1], y[0], y[3:]
        c = soundspeed_fr(self.gas)
        U = self.U1 * self.r1 / self.gas.density
        M = U / c
        eta = 1 - M**2

        sigmadot = getThermicity(self.gas)
        Pdot = -self.gas.density * U**2 * sigmadot / eta
        rdot = -self.gas.density * sigmadot / eta

        dYdt = self.gas.net_production_rates * self.gas.molecular_weights / self.gas.density

        return np.hstack((Pdot, rdot, U, dYdt))
示例#2
0
    def __call__(self, t, y):
        self.gas.DPY = y[1], y[0], y[4:]
        rho = y[1]
        wdot = self.gas.net_production_rates
        mw = self.gas.molecular_weights

        c = soundspeed_fr(self.gas)

        U = y[2]  # velocity has to be updated
        M = U / c  # Mach Number
        eta = 1 - M**2  # Sonic Parameter
        walpha = self.U1 * self.r1 / self.Delta / rho  # area change function

        sigmadot = getThermicity(self.gas)

        Pdot = -rho * U**2 * (sigmadot - walpha) / eta  # Pressure Derivative
        rdot = -rho * (sigmadot - walpha * M**2) / eta  # Density Derivative
        Udot = U * (sigmadot - walpha) / eta  # Velocity Derivative

        dYdt = mw * wdot / rho  # mass production rates

        return np.hstack((Pdot, rdot, Udot, U, dYdt))
示例#3
0
##
# set the initial state and compute properties
P1 = 100000.
T1 = 300.
q = 'O2:0.2095 N2:0.7808 CO2:0.0004 Ar:0.0093'
mech = 'airNASA9ions.cti'
gas = ct.Solution(mech)
gas.TPX = T1, P1, q

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
U = a1 * 1.0001
mu_min = np.arcsin(a1 / U)  # Mach angle
# check to see if flow speed is supersonic
if U < a1:
    exit('Flow subsonic. Exiting.')

# stagnation enthalpy
示例#4
0
import cantera as ct
from sdtoolbox.thermo import soundspeed_fr
from sdtoolbox.postshock import PostShock_fr
from numpy import linspace
import datetime

# set initial state of gas, avoid using precise stoichiometric ratios.
P1 = 100000
T1 = 300
q = 'O2:0.2095 N2:0.7808 CO2:0.0004 Ar:0.0093'
mech = 'airNASA9ions.cti'
gas1 = ct.Solution(mech)
gas1.TPX = T1, P1, q

print('Computing frozen postshock state for ' + q + ' using ' + mech)
Umin = soundspeed_fr(gas1) + 50

# Evaluate the frozen state of the gas behind a shock wave traveling at speeds up to a maximum value.

Umax = 2000.
Ustep = 100.  # Ustep will be approximated
nsteps = int((Umax - Umin) / Ustep)

speed = []
P = []
R = []
T = []
a = []
gamma = []
w2 = []
u2 = []
            # make solution and initialize to starting conditions, store density
            gas_initial = ct.Solution(mech)
            gas_initial.TPX = T1, P1, q
            rho_1 = gas_initial.density
            csound = soundspeed_eq(gas_initial)

            # compute CJ speed, print, and add to speed array
            [cj_speed, R2, plot_data] = CJspeed(P1,
                                                T1,
                                                q,
                                                mech,
                                                fullOutput=True)
            # compute equilibrium CJ state parameters
            gas = PostShock_eq(cj_speed, P1, T1, q, mech)
            ae = soundspeed_eq(gas)
            af = soundspeed_fr(gas)
            rho_2 = gas.density
            gammae = ae**2 * rho_2 / gas.P
            gammaf = af**2 * rho_2 / gas.P
            w2 = cj_speed * rho_1 / rho_2
            u2 = cj_speed - w2
            D = cj_speed  # u2 * rho_2 / rho_1
            Dcalc = (1.29 + 1) / 1.29 * np.power(1.29 * 8314 * 2700 / 28, 0.5)
            mach = D / csound
            print('\nCJ computation for ' + mech + ' with composition:')
            print(q)
            print('Initial conditions: P1 = %.3e Pa & T1 = %.2f K' % (P1, T1))
            print('CJ Speed   %.1f m/s' % cj_speed)
            print('CJ State')
            print('   Pressure   %.3e Pa' % gas.P)
            print('   Temperature  %.1f K' % gas.T)
## Select case for the driven gas operations (use equilibrium only for very strong shocks)
CASE_DRIVEN = 'frozen' # non reactive driven gas
#CASE_DRIVEN = 'equilibrium' #reactive driven gas
print('demo_ShockTube, driver case: '+CASE_DRIVER+' driven case: '+CASE_DRIVEN)

## set initial state, composition, and gas object for driven section
P1 = 1200.; T1 = 300. 
q1 = 'N2:1.0 O2:3.76';   
driven_mech = 'airNASA9noions.cti'
driven_gas = ct.Solution(driven_mech)
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)
EQ = False
##
# set the initial state and compute properties
PA = 100000.; TA = 1000.  # layer state
q = 'PG:1'
mech = 'PG14.cti'

gas = ct.Solution(mech)
gas.TPX = TA,PA,q

x1 = gas.X
P1 = gas.P
T1 = gas.T
rho1 = gas.density
v1 = 1/rho1
a1 = soundspeed_fr(gas) 
s1 = gas.entropy_mass
h1 = gas.enthalpy_mass
RU = ct.gas_constant
W = gas.mean_molecular_weight
R = RU/W
##
# Set lower layer velocity using the Mach number
M2 = 1.05
layer_speed = a1*M2
U = layer_speed
mu_min = np.arcsin(a1/U) # Mach angle
# check to see if flow speed is supersonic
if U < a1:
    exit('Flow subsonic. Exiting.')
示例#8
0
 xfuel.append(fuelmin + i*deltafuel)
 xoxidizer.append((1-xfuel[-1])/(1+beta))
 xdiluent.append(beta*xoxidizer[-1])
 phi.append(xfuel[-1]/(stoich*xoxidizer[-1]))
 x[ifuel] = xfuel[-1]
 x[ioxidizer] = xoxidizer[-1]
 x[idiluent] = xdiluent[-1]
 print('Case '+str(i+1)+' Fuel concentration: '+str(x[ifuel]*100)+'%')
 print('Molefractions')
 print('   fuel ('+fuel+'): '+str(x[ifuel]))
 print('   oxidizer ('+oxidizer+'): '+ str(x[ioxidizer]))
 print('   diluent ('+diluent+'): '+ str(x[idiluent]))
 print('   Phi = '+str(phi[-1]))
 gas.TPX = T1,P1,x
 init_rho = gas.density
 init_af = soundspeed_fr(gas)
 
 # Constant Pressure Explosion State
 gas.equilibrate('HP')
 hp_rho.append(gas.density)
 hp_exp.append(init_rho/hp_rho[-1])
 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))
 
示例#9
0
def stgsolve(gas,
             gas1,
             U1,
             Delta,
             t_end=1e-3,
             max_step=1e-4,
             t_eval=None,
             relTol=1e-5,
             absTol=1e-8):
    """
    Reaction zone structure computation for blunt body flow using
    Hornung's approximation of linear gradient in rho u 
    
    FUNCTION SYNTAX:
    output = stgsolve(gas,gas1,U1,Delta,**kwargs)
    
    INPUT
        gas = Cantera gas object - postshock state
        gas1 = Cantera gas object - initial state
        U1 = shock velocity (m/s)
        Delta = shock standoff distance (m)
        
    OPTIONAL INPUT:
        t_end = end time for integration, in sec
        max_step = maximum time step for integration, in sec
        t_eval = array of time values to evaluate the solution at.
                    If left as 'None', solver will select values.
                    Sometimes these may be too sparse for good-looking plots.
        relTol = relative tolerance
        absTol = absolute tolerance
    
    
    OUTPUT:
        output = a dictionary containing the following results:
            time = time array
            distance = distance array
            
            T = temperature array
            P = pressure array
            rho = density array
            U = velocity array
            thermicity = thermicity array
            distance = distance array
            species = species mass fraction array
            
            M = Mach number array
            af = frozen sound speed array
            g = gamma (cp/cv) array
            wt = mean molecular weight array
            sonic = sonic parameter (c^2-U^2) array
                        
            gas1 = a copy of the input initial state
            U1 = shock velocity
            Delta = shock standoff distance
    """

    r1 = gas1.density
    r = gas.density
    U = U1 * r1 / r

    x_start = 0
    y0 = np.hstack((gas.P, r, U, x_start,
                    gas.Y))  # scaled pressure starts at 1, i.e. PSC/PSC

    tel = [0, t_end]  # Timespan

    output = {}

    out = solve_ivp(StgSys(gas, U1, r1, Delta),
                    tel,
                    y0,
                    method='Radau',
                    atol=absTol,
                    rtol=relTol,
                    max_step=max_step,
                    t_eval=t_eval)

    output['time'] = out.t
    output['P'] = out.y[0, :]
    output['rho'] = out.y[1, :]
    output['U'] = out.y[2, :]
    output['distance'] = out.y[3, :]
    output['species'] = out.y[4:, :]

    # Initialize additional output matrices where needed
    b = len(output['time'])
    output['T'] = np.zeros(b)
    output['thermicity'] = np.zeros(b)
    output['M'] = np.zeros(b)
    output['af'] = np.zeros(b)
    output['g'] = np.zeros(b)
    output['wt'] = np.zeros(b)
    output['sonic'] = np.zeros(b)
    output['Delta'] = Delta

    # Have to loop for operations involving the working gas object
    for i, P in enumerate(output['P']):
        gas.DPY = output['rho'][i], P, output['species'][:, i]
        output['T'][i] = gas.T

        #################################################################################################
        # Extract WEIGHT, GAMMA, SOUND SPEED, VELOCITY, MACH NUMBER, c^2-U^2,
        # THERMICITY, and TEMPERATURE GRADIENT
        #################################################################################################

        af = soundspeed_fr(gas)  # frozen sound speed
        M = output['U'][i] / af  # Mach Number in shock-fixed frame
        eta = 1 - M**2  # Sonic Parameter
        sonic = af**2 * eta

        # Assign output structure
        output['thermicity'][i] = getThermicity(gas)
        output['M'][i] = M
        output['af'][i] = af
        output['g'][i] = gas.cp / gas.cv
        output['wt'][i] = gas.mean_molecular_weight
        output['sonic'][i] = sonic

    output['gas1'] = gas1
    output['U1'] = U1
    return output
示例#10
0
    mu1 = gas.viscosity
    nu1 = mu1/rho1
    kcond1 = gas.thermal_conductivity
    kdiff1 = kcond1/(rho1*gas.cp_mass)

## Find Explosion state
gas.equilibrate(CASE) 
## Evaluate properties of gas object 
T2 = gas.T
P2 = gas.P
rho2 = gas.density
V2 = 1/rho2
S2 = gas.entropy_mass
x2 = gas.X
c2_eq = soundspeed_eq(gas)
c2_fr = soundspeed_fr(gas)
gamma2_fr =  c2_fr**2*rho2/P2
gamma2_eq =  c2_eq**2*rho2/P2

if transport:
    mu = gas.viscosity
    nu = mu/rho2
    kcond = gas.thermal_conductivity
    kdiff = kcond/(rho2*gas.cp_mass)
    Pr = mu*gas.cp_mass/kcond

## Print out
print(CASE+' computation for '+mech+' with composition '+q)
print('Initial State')
print('   Pressure '+str(P1)+' (Pa)')
print('   Temperature '+str(T1)+' (K)')
T1 = 300
P1atm = P1 / ct.one_atm
q = 'H2:2 O2:1 N2:3.76'
mech = 'Mevel2017.cti'
gas1 = ct.Solution(mech)
gas1.TPX = T1, P1, q

print('Initial state: ' + q + ', P1 = %.2f atm,  T1 = %.2f K' % (P1atm, T1))
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)
示例#12
0
def zndsolve(gas,
             gas1,
             U1,
             t_end=1e-3,
             max_step=1e-4,
             t_eval=None,
             relTol=1e-5,
             absTol=1e-8,
             advanced_output=False):
    """
    ZND Model Detonation Struction Computation
    Solves the set of ODEs defined in ZNDSys.
    
    FUNCTION SYNTAX:
    output = zndsolve(gas,gas1,U1,**kwargs)
    
    INPUT
        gas = Cantera gas object - postshock state
        gas1 = Cantera gas object - initial state
        U1 = shock velocity (m/s)
        
    OPTIONAL INPUT:
        t_end = end time for integration, in sec
        max_step = maximum time step for integration, in sec
        t_eval = array of time values to evaluate the solution at.
                    If left as 'None', solver will select values.
                    Sometimes these may be too sparse for good-looking plots.
        relTol = relative tolerance
        absTol = absolute tolerance
        advanced_output = calculates optional extra parameters such as induction lengths
    
    
    OUTPUT:
        output = a dictionary containing the following results:
            time = time array
            distance = distance array
            
            T = temperature array
            P = pressure array
            rho = density array
            U = velocity array
            thermicity = thermicity array
            species = species mass fraction array
            
            M = Mach number array
            af = frozen sound speed array
            g = gamma (cp/cv) array
            wt = mean molecular weight array
            sonic = sonic parameter (c^2-U^2) array
            
            tfinal = final target integration time
            xfinal = final distance reached
            
            gas1 = a copy of the input initial state
            U1 = shock velocity
            
            and, if advanced_output=True:
            ind_time_ZND = time to maximum thermicity gradient
            ind_len_ZND = distance to maximum thermicity gradient
            exo_time_ZND = pulse width (in secs) of thermicity  (using 1/2 max)
            ind_time_ZND = pulse width (in meters) of thermicity (using 1/2 max)
            max_thermicity_width_ZND = according to Ng et al definition
    """
    ###########################################################
    # Define initial information
    ###########################################################
    r1 = gas1.density

    x_start = 0.
    y0 = np.hstack((gas.P, gas.density, x_start, gas.Y))

    tel = [0., t_end]  # Timespan

    output = {}

    out = solve_ivp(ZNDSys(gas, U1, r1),
                    tel,
                    y0,
                    method='Radau',
                    atol=absTol,
                    rtol=relTol,
                    max_step=max_step,
                    t_eval=t_eval)

    output['time'] = out.t
    output['P'] = out.y[0, :]
    output['rho'] = out.y[1, :]
    output['distance'] = out.y[2, :]
    output['species'] = out.y[3:, :]

    output['tfinal'] = t_end
    output['xfinal'] = output['distance'][-1]

    # Initialize additional output matrices where needed
    b = len(output['time'])
    output['T'] = np.zeros(b)
    output['U'] = np.zeros(b)
    output['thermicity'] = np.zeros(b)
    output['af'] = np.zeros(b)
    output['g'] = np.zeros(b)
    output['wt'] = np.zeros(b)
    if advanced_output:
        output['ind_len_ZND'] = 0
        output['ind_time_ZND'] = 0
        output['exo_len_ZND'] = 0
        output['exo_time_ZND'] = 0

    #############################################################################
    # Extract TEMPERATURE, WEIGHT, GAMMA, SOUND SPEED, VELOCITY, MACH NUMBER,
    # c^2-U^2, THERMICITY, and TEMPERATURE GRADIENT
    #############################################################################

    # Have to loop for operations involving the working gas object
    for i, P in enumerate(output['P']):
        gas.DPY = output['rho'][i], P, output['species'][:, i]
        af = soundspeed_fr(gas)
        U = U1 * r1 / gas.density

        output['T'][i] = gas.T
        output['U'][i] = U
        output['thermicity'][i] = getThermicity(gas)
        output['af'][i] = af
        output['g'][i] = gas.cp / gas.cv
        output['wt'][i] = gas.mean_molecular_weight

    # Vectorize operations where possible
    output['M'] = output['U'] / output['af']
    eta = 1 - output['M']**2
    output['sonic'] = eta * output['af']**2

    if advanced_output:
        ################################################################################################
        # Find INDUCTION TIME and LENGTH based on MAXIMUM THERMICITY
        ################################################################################################
        n = output['thermicity'].argmax()

        output['ind_time_ZND'] = output['time'][n]
        output['ind_len_ZND'] = output['distance'][n]
        output['max_thermicity_ZND'] = max(
            output['thermicity'])  # required for Ng et al Chi parameter

        #######################################################
        # Check for eigenvalue detonation
        #######################################################

        if n == b:
            print(
                'Error: Maximum thermicity occurs at the end of the reaction zone'
            )
            print(
                '       You may have an eigenvalue detonation, your final integration length may be too short,'
            )
            print(
                '       your mixture may be too rich/lean, or something else may be wrong'
            )
            print(' ')
            print('Mach Number (end of reaction): ' + str(output['M'][b]) +
                  ' - if close to 1, check for eigenvalue detonation')
            output['ind_time_ZND'] = output['time'][b]
            output['ind_len_ZND'] = output['distance'][b]
            output['exo_time_ZND'] = 0
            output['exo_len_ZND'] = 0
            print('Induction Time: ' + str(output['ind_time_ZND']))
            print('Exothermic Pulse Time: ' + str(output['exo_time_ZND']))
            return output

        elif n == 0:
            print(
                'Error: Maximum thermicity occurs at the beginning of the reaction zone'
            )
            print(
                '       You may have an eigenvalue detonation, your final integration length may be too short,'
            )
            print(
                '       your mixture may be too rich/lean, or something else may be wrong'
            )
            print(' ')
            print('Mach Number (end of reaction): ' + str(output['M'][b]) +
                  ' - if close to 1, check for eigenvalue detonation')
            output['ind_time_ZND'] = output['time'][0]
            output['ind_len_ZND'] = output['distance'][0]
            output['exo_time_ZND'] = 0
            output['exo_len_ZND'] = 0
            print('Induction Time: ' + str(output['ind_time_ZND']))
            print('Exothermic Pulse Time: ' + str(output['exo_time_ZND']))
            return output

        else:
            max_sigmadot = max(output['thermicity'])
            half_sigmadot_flag1 = 0
            half_sigmadot_flag2 = 0
            # Go into a loop to find two times when sigma_dot is half its maximum
            tstep2 = 0  # JML temporary
            for j, thermicity in enumerate(list(output['thermicity'])):
                if half_sigmadot_flag1 == 0:
                    if thermicity > 0.5 * max_sigmadot:
                        half_sigmadot_flag1 = 1
                        tstep1 = j

                elif half_sigmadot_flag2 == 0:
                    if thermicity < 0.5 * max_sigmadot:
                        half_sigmadot_flag2 = 1
                        tstep2 = j
                    else:
                        tstep2 = 0

        if tstep2 == 0:
            print('Error: No pulse in the thermicity')
            print(
                '       You may have an eigenvalue detonation, your final integration length may be too short,'
            )
            print(
                '       your mixture may be too rich/lean, or something else may be wrong'
            )
            output['exo_time_ZND'] = 0
            output['exo_len_ZND'] = 0
        else:
            output['exo_time_ZND'] = output['time'][tstep2] - output['time'][
                tstep1]
            output['exo_len_ZND'] = output['distance'][tstep2] - output[
                'distance'][tstep1]

    #################################################################
    # Append extra data used to make output file (via znd_fileout)
    output['gas1'] = gas1
    output['U1'] = U1

    return output
示例#13
0
 P.append(gas.P)
 R.append(gas.density)
 T.append(gas.T)
 # species
 X = gas.X
 xH.append(X[iH])
 xO.append(X[iO])
 xOH.append(X[iOH])
 xH2.append(X[iH2])
 xO2.append(X[iO2])
 xH2O.append(X[iH2O])
 # gamma computed from Gruneisen coefficient
 grun_eq.append(gruneisen_eq(gas))
 grun_fr.append(gruneisen_fr(gas))
 a_eq.append(soundspeed_eq(gas))
 a_fr.append(soundspeed_fr(gas)) 
 # logarithmic slope of isentropes in P-V coordinates
 kappa_fr.append(a_fr[-1]**2*R[-1]/P[-1])
 kappa_eq.append(a_eq[-1]**2*R[-1]/P[-1])
 # logarithmic slope of isentropes in T-V coordinates
 # equilibrium
 gas.SV = S2,1.01*V
 gas.equilibrate('SV')
 T_2 = gas.T
 gas.SV = S2,0.99*V
 gas.equilibrate('SV')
 T_1 = gas.T
 tvdvdt_eq.append(-V*(T_2-T_1)/(0.02*V)/T[-1])
 # frozen
 gas.SVX = S2,V*1.01,X2
 T_2 = gas.T
示例#14
0
#P1 = 200000.; T1 = 300.;  #Fujiwara initial state
#q = 'C2H4:1.0, O2:3';     #ethylene oxygen, Kasahara
#q = 'H2:2.0, O2:1.0, AR:7.0'; #hydrogen oxygen argon
#q = 'H2:2.0, O2:1.0';  #hydrogen oxygen
#q = 'H2:2.0, O2:1.0, N2:3.76';  #hydrogen air
#q = 'C2H4:1.0, O2:3, N2:11.28';     #ethylene air
q  = 'CH4:1.0, O2:2.0, N2:7.52';  #methane-air
#q = 'C3H8:1.0, O2:5';  #propane oxygen
mech = 'gri30_highT.cti'
gas = ct.Solution(mech)
gas.TPX = T1,P1,q

h1 = gas.enthalpy_mass
s1 = gas.entropy_mass
rho1 = gas.density
a1_fr = soundspeed_fr(gas)
w1 = gas.mean_molecular_weight
R1 = ct.gas_constant/w1
gamma1_fr =  a1_fr**2*rho1/P1

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)+' ')

##
示例#15
0
# P1 = Initial Pressure
# T1 = Initial Temperature
# U = Shock Speed
# q = Initial Composition
# mech = Cantera mechanism File name
plots = True

#set initial state
P1 = 100000
T1 = 295
q = 'C2H4:1 O2:3.01'
mech = 'gri30_highT.cti'
gas1 = ct.Solution(mech)
gas = ct.Solution(mech)
gas1.TPX = T1, P1, q
a1_fr = soundspeed_fr(gas1)
D1 = gas1.density
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)
cj_speed = CJspeed(P1, T1, q, mech)

# Evaluate gas state
gas = PostShock_eq(cj_speed,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*cj_speed/R2
u2 = cj_speed - w2
x2 = gas.X
a2_eq = soundspeed_eq(gas)
a2_fr = soundspeed_fr(gas)
gamma2_fr =  a2_fr**2*R2/P2
gamma2_eq =  a2_eq**2*R2/P2

# Print out
set_printoptions(precision=4)
print('CJ computation for '+mech+' with composition '+q)
print('CJ Parameters')
print('   UCJ '+str(cj_speed)+' (m/s)')
print('   Pressure '+str(P2)+' (Pa)')
print('   Temperature '+str(T2)+' (K)')
print('   Density '+str(R2)+' (kg/m3)')
print('   Entropy '+str(S2)+' (J/kg-K)')
print('   w2 (wave frame) '+str(w2)+' (m/s)')
print('   u2 (lab frame) '+str(u2)+' (m/s)')
print('   a2 (frozen) '+str(a2_fr)+' (m/s)')
from sdtoolbox.thermo import soundspeed_eq,soundspeed_fr
from sdtoolbox.postshock import PostShock_eq,PostShock_fr

transport = True
mech = 'airNASA9noions.cti'
gas1 = ct.Solution(mech)
gas2 = ct.Solution(mech)
gas3 = ct.Solution(mech)

## set initial state of gas.
P1 = 770
T1 = 728
q = 'O2:1 N2:3.76'
gas1.TPX = T1,P1,q
rho1 = gas1.density
af1 = soundspeed_fr(gas1)
M1 = 7.16 # shock Mach number
speed = M1*af1
gamma1_fr = af1**2*rho1/P1
if transport:
    mu1 = gas1.viscosity
    nu1 = mu1/rho1
    kcond1 = gas1.thermal_conductivity
    kdiff1 = kcond1/(rho1*gas1.cp_mass)
    Pr = mu1*gas1.cp_mass/kcond1

## Print out initial state
print('Shock computation for '+mech+' with composition '+q)
print('Initial State')
print('   Shock speed '+str(speed)+' (m/s)')
print('   Frozen sound Speed '+str(af1)+' (m/s)')
示例#18
0
## set initial state, composition, and gas object
P1 = 100000.
T1 = 300.
#q = 'H2:2.00 O2:1.0 N2:3.76'
#q = 'C2H4:1.00 O2:3 N2:11.28'
q = 'C2H2:1 O2:2.5 AR:3'
#q = 'C2H4:1. O2:3'
#q = 'O2:1. N2:3.76'
mech = 'gri30_highT.cti'
gas1 = ct.Solution(mech)
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
    Windows 8.1, Windows 10, Linux (Debian 9)
"""
import cantera as ct
from sdtoolbox.thermo import soundspeed_fr
from sdtoolbox.postshock import PostShock_fr
import datetime
import matplotlib.pyplot as plt

# set initial state of gas, avoid using precise stoichiometric ratios.
P1 = 100000
T1 = 295
q = 'O2:0.2095 N2:0.7808 CO2:0.0004 Ar:0.0093'
mech = 'airNASA9ions.cti'
gas1 = ct.Solution(mech)
gas1.TPX = T1, P1, q
a1_fr = soundspeed_fr(gas1)
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.
示例#20
0
    vR[i] = v2
    PRpa = (P1 - r1**2 * U1**2 * (v2 - v1))
    PR[i] = PRpa / ct.one_atm
    i = i + 1
    v2 = v2 - stepv
print('Rayleigh Line Array Created')

# Frozen (reactant) HUGONIOT
n = 50
PH1 = np.zeros(n + 1, float)
vH1 = np.zeros(n + 1, float)

PH1[0] = P1 / ct.one_atm
vH1[0] = v1

Umin = 1.1 * soundspeed_fr(gas1)

stepU = (1.1 * U1 - Umin) / float(n)
i = 0
while (i < n):
    U = Umin + stepU * float(i)
    gas = PostShock_fr(U, P1, T1, q, mech)
    PH1[i + 1] = gas.P / ct.one_atm
    vH1[i + 1] = 1 / gas.density
    i = i + 1

print('Reactant Hugoniot Array Created')

# Compute four frozen isentropes
# one passing through initial state
# one passing through postshock state
示例#21
0
# (where U = w) so that we can keep the code as similar as possible to the MATLAB equivalent
# Numpy actually handles this case and returns the correct value for the limit arctan(inf)
import warnings

warnings.filterwarnings("ignore", category=RuntimeWarning)

##
# set the initial state and compute properties
P1 = 100000
T1 = 300
q = 'H2:2 O2:1 N2:3.76'
mech = 'Mevel2017.cti'
gas1 = ct.Solution(mech)
gas1.TPX = T1, P1, q
rho1 = gas1.density
a1 = soundspeed_fr(gas1)

##
# Set freestream velocity and find limiting speeds
U = 1500.
beta_min = np.arcsin(a1 / U)  # Mach angle
wmin = a1 + 1.  # start just above sound speed
# check to see if shock speed is above sound speed
if (U < a1):
    exit('Shock speed below sound speed. Exiting.')

# set maximum normal speed
wmax = U

# initialize variables for plotting
rho2 = []