Example #1
0
if __name__ == '__main__':
    # build a test mechanism with inert oxygen
    base_mech = 'gri30'
    test_mech = 'test_mech'
    file_types = ['.cti', '.xml']
    funcs = [make_inert_cti, make_inert_xml]
    inert_species = ['O2']
    init_temp = 1000
    init_press = ct.one_atm
    for ftype, func in zip(file_types, funcs):
        mechs = [base_mech + ftype, test_mech + ftype]
        _, _, file_out = _get_file_locations(mechs[0], mechs[1])

        func(mechs[0], inert_species, mechs[1])
        gases = [ct.Solution(m) for m in mechs]
        for idx, g in enumerate(gases):
            g.set_equivalence_ratio(1, 'H2', 'O2')
            init_mf = g.mole_fraction_dict()['O2']
            g.TP = init_temp, init_press
            r = ct.Reactor(g)
            n = ct.ReactorNet([r])
            n.advance_to_steady_state()
            print(mechs[idx])
            print('-' * len(mechs[idx]))
            print('# reactions:     {:1.0f}'.format(len(
                g.reaction_equations())))
            print('final temp:      {:1.0f} K'.format(r.thermo.TP[0]))
            print('final pressure:  {:1.0f} atm'.format(r.thermo.TP[1] /
                                                        ct.one_atm))
            print('Y_02 init/final: {:0.3f} / {:0.3f}'.format(
Example #2
0
)
parser.add_argument(
    "--yields",
    nargs='+',
    type=int,
    required=False,
    default=[-1],
    dest='yields',
    help=
    'Indices of concentration yields to include in error. -1 for none. Default -1.'
)

args = parser.parse_args()

start = timeit.default_timer()
gas = ct.Solution(args.mechanism)
reactions = gas.reactions()
Npoints = args.Npoints
filebase = args.filebase
ns = gas.n_total_species
nr = gas.n_reactions
expfile = open(args.experiments, 'r')
measure_ind = args.measure
sensitivity = args.sensitivity
num_remove = args.remove
num_exclude = args.retain
maxes = args.maxes
yields = args.yields
seed = 1000 * 1000 * num_exclude + 1000 * num_remove + args.seed
ktol = args.ktol
outflag = args.out
def run_drgep(model_file,
              importance_coeffs,
              ignition_conditions,
              psr_conditions,
              flame_conditions,
              error_limit,
              species_targets,
              species_safe,
              phase_name='',
              threshold_upper=None,
              num_threads=1,
              path=''):
    """Main function for running DRGEP reduction.
    
    Parameters
    ----------
    model_file : str
        Original model file
    ignition_conditions : list of InputIgnition
        List of autoignition initial conditions.
    psr_conditions : list of InputPSR
        List of PSR simulation conditions.
    flame_conditions : list of InputLaminarFlame
        List of laminar flame simulation conditions.
    error_limit : float
        Maximum allowable error level for reduced model
    species_targets : list of str
        List of target species names
    species_safe : list of str
        List of species names to always be retained
    phase_name : str, optional
        Optional name for phase to load from CTI file (e.g., 'gas'). 
    threshold_upper : float, optional
        Upper threshold (epsilon^*) to identify limbo species for sensitivity analysis
    num_threads : int, optional
        Number of CPU threads to use for performing simulations in parallel.
        Optional; default = 1, in which the multiprocessing module is not used.
        If 0, then use the available number of cores minus one. Otherwise,
        use the specified number of threads.
    path : str, optional
        Optional path for writing files

    Returns
    -------
    ReducedModel
        Return reduced model and associated metadata
    
    """
    solution = ct.Solution(model_file, phase_name)
    assert species_targets, 'Need to specify at least one target species.'

    # first, sample thermochemical data and generate metrics for measuring error
    # (e.g, ignition delays). Also produce adjacency matrices for graphs, which
    # will be used to produce graphs for any threshold value.
    sampled_metrics, sampled_data = drgep.sample(model_file,
                                                 ignition_conditions,
                                                 phase_name=phase_name,
                                                 num_threads=num_threads,
                                                 path=path)

    matrices = []
    for state in sampled_data:
        matrices.append(
            drgep.create_drgep_matrix((state[0], state[1], state[2:]),
                                      solution))

    # For DRGEP, find the overall interaction coefficients for all species
    # using the maximum over all the sampled states
    # importance_coeffs = drgep.get_importance_coeffs(
    #     solution.species_names, species_targets, matrices
    #     )

    # begin reduction iterations
    logging.info('Beginning reduction loop')
    logging.info(45 * '-')
    logging.info('Threshold | Number of species | Max error (%)')

    # make lists to store data
    threshold_data = []
    num_species_data = []
    error_data = []

    # start with detailed (starting) model
    previous_model = reduce_model.ReducedModel(model=solution,
                                               filename=model_file,
                                               error=0.0)

    first = True
    error_current = 0.0
    threshold = 0.01
    threshold_increment = 0.01
    while error_current <= error_limit:
        reduced_model = reduce_drgep(model_file,
                                     species_safe,
                                     threshold,
                                     importance_coeffs,
                                     ignition_conditions,
                                     sampled_metrics,
                                     phase_name=phase_name,
                                     previous_model=previous_model,
                                     num_threads=num_threads,
                                     path=path)
        error_current = reduced_model.error
        num_species = reduced_model.model.n_species

        # reduce threshold if past error limit on first iteration
        if first and error_current > error_limit:
            error_current = 0.0
            threshold /= 10
            threshold_increment /= 10
            if threshold <= 1e-6:
                raise SystemExit(
                    'Threshold value dropped below 1e-6 without producing viable reduced model'
                )
            logging.info('Threshold value too high, reducing by factor of 10')
            continue

        logging.info(
            f'{threshold:^9.2e} | {num_species:^17} | {error_current:^.2f}')

        # store data
        threshold_data.append(threshold)
        num_species_data.append(num_species)
        error_data.append(error_current)

        threshold += threshold_increment
        first = False

        # cleanup files
        if previous_model.model.n_species != reduced_model.model.n_species:
            os.remove(reduced_model.filename)

        previous_model = reduce_model.ReducedModel(
            model=reduced_model.model,
            filename=reduced_model.filename,
            error=reduced_model.error,
            limbo_species=reduced_model.limbo_species)

    if reduced_model.error > error_limit:
        threshold -= (2 * threshold_increment)
        reduced_model = reduce_drgep(model_file,
                                     species_safe,
                                     threshold,
                                     importance_coeffs,
                                     ignition_conditions,
                                     sampled_metrics,
                                     phase_name=phase_name,
                                     num_threads=num_threads,
                                     path=path)
    else:
        soln2cti.write(reduced_model,
                       f'reduced_{reduced_model.model.n_species}.cti',
                       path=path)

    if threshold_upper:
        for sp in reduced_model.model.species_names:
            if importance_coeffs[sp] < threshold_upper and (
                    sp not in species_safe):
                reduced_model.limbo_species.append(sp)

    logging.info(45 * '-')
    logging.info('Reduction complete.')
    logging.info(
        f'Skeletal model: {reduced_model.model.n_species} species and '
        f'{reduced_model.model.n_reactions} reactions.')
    logging.info(f'Maximum error: {reduced_model.error:.2f}%')
    logging.info('Final reduced model saved as ' + reduced_model.filename)

    return threshold_data, num_species_data, error_data
Example #4
0
    # set the gas to a state with the same entropy and composition but
    # the perturbed pressure
    gas.SP = s0, p1

    # frozen sound speed
    afrozen = math.sqrt((p1 - p0) / (gas.density - r0))

    # now equilibrate the gas holding S and P constant
    gas.equilibrate('SP', rtol=rtol, maxiter=maxiter)

    # equilibrium sound speed
    aequil = math.sqrt((p1 - p0) / (gas.density - r0))

    # compute the frozen sound speed using the ideal gas expression as a check
    gamma = gas.cp / gas.cv
    afrozen2 = math.sqrt(gamma * ct.gas_constant * gas.T /
                         gas.mean_molecular_weight)

    return aequil, afrozen, afrozen2


# test program
if __name__ == "__main__":
    gas = ct.Solution('gri30.yaml')
    gas.X = 'CH4:1.00, O2:2.0, N2:7.52'
    for n in range(27):
        T = 300.0 + 100.0 * n
        gas.TP = T, ct.one_atm
        print(T, equilSoundSpeeds(gas))
Example #5
0
get_ipython().run_line_magic('matplotlib', 'inline')

import sys
import os
import math
import csv
import numpy as np

import cantera as ct

#combustion chamber volume and mass flows assesment based on the dimensions of Rolls Royce AE3007

lambda_air = 1.5 #air–fuel equivalence ratio

air = ct.Solution('air.cti')
air.TP = 800, 1.4e+06 #typical temperature and pressure behind HPC
air_in=ct.Reservoir(air)
air_mdot=ct.Quantity(air, mass=20)

fuel = ct.Solution('Dagaut_Ori.cti')
fuel.TPY = 300, 3e+05, 'NC10H22:0.74,PHC3H7:0.15,CYC9H18:0.11'
fuel_in=ct.Reservoir(fuel)
fuel_mdot = ct.Quantity(fuel, mass=1)
fuel_mdot.mass=air_mdot.mass/lambda_air/14.9

#igniter (like in "combustor.py")
fuel.TPX = 1500, 2e+06, 'H:1.0'
igniter = ct.Reservoir(fuel)

fuel.TPX = 1100, 1.2e+6, 'N2:1.0' #combustion chamber already hot, otherwise some mechanims doesn't integrate properly when combustor temperature is below 1000 K
Example #6
0
# composition of the inlet premixed gas for the methane/air case
comp2 = 'CH4:0.095, O2:0.21, N2:0.78, AR:0.01'

# The inlet/surface separation is 10 cm.
width = 0.1  # m

loglevel = 1  # amount of diagnostic output (0 to 5)

################ create the gas object ########################
#
# This object will be used to evaluate all thermodynamic, kinetic, and
# transport properties. The gas phase will be taken from the definition of
# phase 'gas' in input file 'ptcombust.cti,' which is a stripped-down version
# of GRI-Mech 3.0.
gas = ct.Solution('ptcombust.cti', 'gas')
gas.TPX = tinlet, p, comp1

################ create the interface object ##################
#
# This object will be used to evaluate all surface chemical production rates.
# It will be created from the interface definition 'Pt_surf' in input file
# 'ptcombust.cti,' which implements the reaction mechanism of Deutschmann et
# al., 1995 for catalytic combustion on platinum.
#
surf_phase = ct.Interface('ptcombust.cti', 'Pt_surf', [gas])
surf_phase.TP = tsurf, p

# integrate the coverage equations in time for 1 s, holding the gas
# composition fixed to generate a good starting estimate for the coverages.
surf_phase.advance_coverages(1.0)
Example #7
0
def f4(ER_,T_0=300,P_=1,alpha_= 0,beta_ = 0):
    gas_new = ct.Solution('gri30.cti')
    gas_new.TPX = T_0,P_*ct.one_atm,'H2:%f, O2:1, N2:3.76, H2O:%f, CO:%f'%(2.*ER_,alpha_,beta_)
    gas_new.equilibrate('HP')
    return float(gas_new.T)
Example #8
0
start = time.time()

#### Input mechanism data ####:
input_file0 = 'ethanol_pt.cti'
input_file = 'ethanol_pt_redux.cti'
surf_name = 'Pt_surface'

#### Data files path ####:
basepath = os.path.dirname(__file__)
filepath = os.path.join(basepath, '../..', 'data')

#### Coverage dependency matrix file ####:
cov_file = os.path.join(filepath, 'cov_matrix/covmatrix_et_pt.inp')

#Load phases solution objects
gas0 = ct.Solution(input_file0)
surfCT0 = ct.Interface(input_file0, surf_name, [gas0])

#Load in-house surface phase object
surf0 = pfr.SurfacePhase(gas0, surfCT0, cov_file=cov_file)

#Load phases solution objects for reduced mechanism
gas = ct.Solution(input_file)
surfCT = ct.Interface(input_file, surf_name, [gas])

#Load in-house surface phase object
surf = pfr.SurfacePhase(gas, surfCT, cov_file=cov_file)

#### Current thermo state ####:
X_in = 'CH3CH2OH:0.125, H2O:0.375, HE:0.50'
T_in = 668
    return soln, fullArrayFlowData, PdropTotal / 1e6


#%%
if __name__ == '__main__':

    mdot = 0.3  #mass flow rate [kg/s]
    T0 = 300  # #ambient temperature [K]/stagnation
    stag = T0
    P1 = psi_to_MPa(
        1500
    ) * 1e6  #(100/145.038)*1e6#MPa #pressure at pipe inlet [Pa] 1500 PSI
    PInit = P1
    #define gas
    gas = ct.Solution('air.cti')
    gas.transport_model = 'Mix'
    gas.TPX = T0, P1, {'O2': 1, 'N2': 3.76}
    R = 8.314
    gamma = gas.cp / gas.cv  #ratio of specific heats [-]
    MW = gas.mean_molecular_weight
    step = 0.001  #(m) break tube up into 1mm increments
    #for loss calculations https://docs.google.com/spreadsheets/d/1gn8gLvc1uLY0blPmABOoTxjrHLD8UaT0t1OvKjpqaj4/edit#gid=0
    #Minor/Major Loss calculations:
    #https://docs.google.com/spreadsheets/d/1gn8gLvc1uLY0blPmABOoTxjrHLD8UaT0t1OvKjpqaj4/edit#gid=89965144
    Kvec = [0.75, 0.00001006424457, 0.2, 1.816115216, 7.5, 0.5, 3.30000078]
    Lvec = [1e-16, 1e-16, 1.2192, 0.5461, 1.5367, 1.2192, 0.0635]
    Dvec = [
        0.004572, 0.009398, 0.008636, 0.009398, 0.009398, 0.008636, 0.009398
    ]
    epsvec = [
Example #10
0
# -*- coding: utf-8 -*-
"""
Created on Fri Feb 02 13:01:11 2018

@author: Mark Barbet
"""
import os
import cantera as ct
import numpy as np
import matplotlib.pyplot as plt
import troe_rate as tr
gas = ct.Solution(os.getcwd() + '\\TMRP codes\\FFCM-1\\h_c2h2')
kp = []
kcalc = []

pressures = np.arange(0.0001 * ct.one_atm, 100000 * ct.one_atm, 50000)
pressures = np.arange(0.00001, 100000 * ct.one_atm, 50000)
high_rate = gas.reactions()[0].high_rate.pre_exponential_factor * (
    1000**gas.reactions()[0].high_rate.temperature_exponent) * np.exp(
        -gas.reactions()[0].high_rate.activation_energy / 1000.0 /
        ct.gas_constant)
low_rate = gas.reactions()[0].low_rate.pre_exponential_factor * (
    1000**gas.reactions()[0].low_rate.temperature_exponent) * np.exp(
        gas.reactions()[0].low_rate.activation_energy / 1000.0 /
        ct.gas_constant)

for i in np.arange(len(pressures)):
    gas.TP = 1000.0, pressures[i]
    kp.append(gas.forward_rate_constants[0])
    kcalc.append(
        tr.rate(low_rate, high_rate, 0.215, 10.7, 1043.0, 2341.0, 1000.0,
    Windows 8.1, Windows 10, Linux (Debian 9)
"""
import cantera as ct
from sdtoolbox.thermo import soundspeed_fr, soundspeed_eq
from sdtoolbox.postshock import CJspeed, PostShock_eq

## 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'
@author: dkorff

This is the object initialization file for the Li-s model. It imports input
values from li_s_battery_inputs.py and initializes the necessary objects to
run the simulations
"""

import numpy as np
import cantera as ct
import importlib
from math import pi

from li_s_battery_inputs import inputs

"Import cantera objects - this step is the same regardless of test type"
elyte_obj = ct.Solution(inputs.ctifile, inputs.elyte_phase)
sulfur_obj = ct.Solution(inputs.ctifile, inputs.cat_phase1)
Li2S_obj = ct.Solution(inputs.ctifile, inputs.cat_phase2)
carbon_obj = ct.Solution(inputs.ctifile, inputs.cat_phase3)
conductor_obj = ct.Solution(inputs.ctifile, inputs.metal_phase)
lithium_obj = ct.Solution(inputs.ctifile, inputs.an_phase)

sulfur_el_s = ct.Interface(inputs.ctifile, inputs.sulfur_elyte_phase,
                             [sulfur_obj, elyte_obj, conductor_obj])
Li2S_el_s = ct.Interface(inputs.ctifile, inputs.Li2S_elyte_phase,
                             [Li2S_obj, elyte_obj, conductor_obj])
carbon_el_s = ct.Interface(inputs.ctifile, inputs.graphite_elyte_phase,
                             [carbon_obj, elyte_obj, conductor_obj])
lithium_el_s = ct.Interface(inputs.ctifile, inputs.anode_elyte_phase,
                             [lithium_obj, elyte_obj, conductor_obj])
Li2S_tpb = ct.Interface(inputs.ctifile, 'tpb', [elyte_obj, Li2S_obj, conductor_obj])
Example #13
0
class FlameExtinguished(Exception):
    pass


# Create directory for output data files
data_directory = 'diffusion_flame_batch_data/'
if not os.path.exists(data_directory):
    os.makedirs(data_directory)

# PART 1: INITIALIZATION

# Set up an initial hydrogen-oxygen counterflow flame at 1 bar and low strain
# rate (maximum axial velocity gradient = 2414 1/s)

reaction_mechanism = 'h2o2.yaml'
gas = ct.Solution(reaction_mechanism)
width = 18e-3  # 18mm wide
f = ct.CounterflowDiffusionFlame(gas, width=width)

# Define the operating pressure and boundary conditions
f.P = 1.e5  # 1 bar
f.fuel_inlet.mdot = 0.5  # kg/m^2/s
f.fuel_inlet.X = 'H2:1'
f.fuel_inlet.T = 300  # K
f.oxidizer_inlet.mdot = 3.0  # kg/m^2/s
f.oxidizer_inlet.X = 'O2:1'
f.oxidizer_inlet.T = 300  # K

# Set refinement parameters, if used
f.set_refine_criteria(ratio=3.0, slope=0.1, curve=0.2, prune=0.03)
Example #14
0
    def cj_speed(
            cls,
            initial_pressure,
            initial_temperature,
            species_mole_fractions,
            mechanism,
            use_multiprocessing=False,
            return_r_squared=False,
            return_state=False
    ):
        """
        This function calculates CJ detonation velocity

        Original function: CJspeed in PostShock.py

        Parameters
        ----------
        initial_pressure : float
            initial pressure (Pa)
        initial_temperature : float
            initial temperature (K)
        species_mole_fractions : str or dict
            string or dictionary of reactant species mole fractions
        mechanism : str
            cti file containing mechanism data (e.g. 'gri30.cti')
        use_multiprocessing : bool
            use multiprocessing to speed up CJ speed calculation
        return_r_squared : bool
            return the R^2 value of the CJ speed vs. density ratio fit
        return_state : bool
            return the CJ state corresponding to the calculated velocity

        Returns
        -------
        dict
        """
        # DECLARATIONS
        num_steps = 20
        max_density_ratio = 2.0
        min_density_ratio = 1.5
        a = 0
        b = 0
        c = 0

        if use_multiprocessing:
            pool = mp.Pool()

        # Set error tolerances for CJ state calculation
        error_tol_temperature = 1e-4
        error_tol_velocity = 1e-4

        counter = 1
        r_squared = 0.0
        delta_r_squared = 0.0
        adjusted_density_ratio = 0.0

        while (counter <= 4) and (
                (r_squared < 0.99999) or (delta_r_squared < 1e-7)
        ):
            density_ratio_array = np.linspace(
                min_density_ratio,
                max_density_ratio,
                num_steps + 1
            )

            if use_multiprocessing:
                # parallel loop through density ratios
                stargs = [[number,
                           ratio,
                           initial_temperature,
                           initial_pressure,
                           species_mole_fractions,
                           mechanism,
                           error_tol_temperature,
                           error_tol_velocity
                           ]
                          for number, ratio in
                          zip(
                              range(len(density_ratio_array)),
                              density_ratio_array
                          )
                          ]
                # noinspection PyUnboundLocalVariable
                result = pool.starmap(cls._calculate_over_ratio_range, stargs)

            else:
                # no multiprocessing, just use map
                result = list(map(
                    cls._calculate_over_ratio_range,
                    [item for item in range(len(density_ratio_array))],
                    density_ratio_array,
                    [initial_temperature for _ in density_ratio_array],
                    [initial_pressure for _ in density_ratio_array],
                    [species_mole_fractions for _ in density_ratio_array],
                    [mechanism for _ in density_ratio_array],
                    [error_tol_temperature for _ in density_ratio_array],
                    [error_tol_velocity for _ in density_ratio_array]
                ))

            result.sort()
            cj_velocity_calculations = np.array(
                [item for (_, item) in result]
            )

            # Get curve fit
            a, b, c, r_squared = cj_curve_fit(
                density_ratio_array,
                cj_velocity_calculations
            )
            adjusted_density_ratio = -b / (2. * a)

            min_density_ratio = adjusted_density_ratio * (1 - 0.001)
            max_density_ratio = adjusted_density_ratio * (1 + 0.001)
            counter += 1

        cj_speed = a * adjusted_density_ratio**2 + \
            b * adjusted_density_ratio + c

        if return_state:
            initial_state_gas = ct.Solution(mechanism)
            working_gas = ct.Solution(mechanism)
            initial_state_gas.TPX = [
                initial_temperature,
                initial_pressure,
                species_mole_fractions
            ]
            working_gas.TPX = [
                initial_temperature,
                initial_pressure,
                species_mole_fractions
            ]
            cls.cj_state(
                working_gas,
                initial_state_gas,
                error_tol_temperature,
                error_tol_velocity,
                adjusted_density_ratio
            )

        if return_r_squared and return_state:
            # noinspection PyUnboundLocalVariable
            return {'cj speed': cj_speed,
                    'R^2': r_squared,
                    'cj state': working_gas
                    }
        elif return_state:
            # noinspection PyUnboundLocalVariable
            return {'cj speed': cj_speed,
                    'cj state': working_gas
                    }
        elif return_r_squared:
            return {'cj speed': cj_speed,
                    'R^2': r_squared
                    }
        else:
            return {'cj speed': cj_speed}
Example #15
0
 def setUpClass(cls):
     cls.gas = ct.Solution("jacobian-tests.yaml", transport_model=None)
     #   species: [H2, H, O, O2, OH, H2O, HO2, H2O2, AR]
     cls.gas.TPX = 300, 2 * ct.one_atm, "H2:1, O2:3, AR:0.4"
     cls.gas.equilibrate("HP")
     super().setUpClass()
Example #16
0
#githubtest
#print(sys.version)
import inspect
import os
print(inspect.getfile(ct))
#圧力kPa,温度K
P1 = 101.325
T1 = 288.15
phi = 0.8
P2 = P1 * 1

E2 = 0.75
E4 = 0.82
P4 = P1

inigas = ct.Solution('gri30.xml')

#初期条件を設定(Air)
gas1 = ct.Quantity(inigas)
gas1.TPX = T1, P1 * 1000, {'O2': 1, 'N2': 3.76}
H1 = gas1.h
#print(gas1.report())
#初期条件を設定(H2)

gas2 = ct.Quantity(inigas)
gas2.TPX = T1, P2 * 1000, {'H2': 2 * phi}

gas1.moles = 1
nO2 = gas1.X[gas1.species_index('O2')]
gas2.moles = nO2 * 2 * phi
Example #17
0
def create_solution_mechanism():
    # Defining Reaction Mechanism
    # Mechanism II - Marinov + Mevel
    marinov_species = ct.Species.listFromFile('marinov_ethanol_mechanism.cti')
    marinov_reactions = ct.Reaction.listFromFile(
        'marinov_ethanol_mechanism.cti')

    mevel_species = ct.Species.listFromFile('mevel_ethanol_mechanism.cti')
    mevel_reactions = ct.Reaction.listFromFile('mevel_ethanol_mechanism.cti')

    new_species = []
    new_reactions = []

    # Filter species
    for specie in mevel_species:
        # Include all nitrogen compounds except for N2
        if 'N' in specie.composition and specie.composition != {'N': 2}:
            new_species.append(specie)

    new_species_names = {specie.name for specie in new_species}
    # print('N based species: {0}'.format(', '.join(name for name in new_species_names)))

    marinov_mevel_species = marinov_species + new_species
    marinov_mevel_species_names = {
        specie.name.upper()
        for specie in marinov_mevel_species
    }

    # Filter reactions, keeping only those that only involve the selected species
    # print('\nReactions:')
    for R in mevel_reactions:
        if any(reactant in new_species_names
               for reactant in R.reactants) or any(product in new_species_names
                                                   for product in R.products):
            # for reactant in R.reactants:
            # if reactant not in marinov_mevel_species_names:
            # print('Missing reactant:', reactant, 'when analyzing reaction', R.equation)
            # for product in R.products:
            # if product not in marinov_mevel_species_names:
            # print('Missing product:', product, 'when analyzing reaction', R.equation)
            if all(reactant in marinov_mevel_species_names
                   for reactant in R.reactants):
                if all(product in marinov_mevel_species_names
                       for product in R.products):
                    new_reactions.append(R)
                    # print('Accepted reaction:', R.equation)
    # print('\n')

    marinov_mevel_species = marinov_species + new_species
    marinov_mevel_reactions = marinov_reactions + new_reactions

    marinov_mevel_gas = ct.Solution(thermo='IdealGas',
                                    kinetics='GasKinetics',
                                    species=marinov_mevel_species,
                                    reactions=marinov_mevel_reactions)

    marinov_mevel_gas = ct.Solution('sandiego2016_plus_N_CK.cti')
    print('Number of species:', marinov_mevel_gas.n_species)
    print('Number of reactions:', marinov_mevel_gas.n_reactions)

    return marinov_mevel_gas
Example #18
0
_T4 = []
_X1 = []
_X2 = []
_X3 = []
_X4 = []
_h12 = []
_h23 = []
_h34 = []
_h41 = []
_s12 = []
_s23 = []
_s34 = []
_s41 = []

"Define Fluids"
air_1 = ct.Solution('air.cti')
air_2 = ct.Solution('air.cti')
WF_1 = ct.Hfc134a()
WF_2 = ct.Hfc134a()
WF_3 = ct.Hfc134a()
WF_4 = ct.Hfc134a()

"Knowns"
T1_air = 38+273.15        # T1 ambient = 38C
P1_air = 1*10**5          # P1 ambient = 1 bar
T2_air = 10+273.15        # T2 into cabin = 10C
P2_air = P1_air           # P2 = 1 bar
air_1.TP = T1_air,P1_air  # Define state
air_2.TP = T2_air,P2_air  # Define state
h1_air = air_1.h          
h2_air = air_2.h          
Example #19
0
Requires: cantera >= 2.5.0
"""

import cantera as ct

# Simulation parameters
p = ct.one_atm  # pressure [Pa]
Tin = 300.0  # unburned gas temperature [K]
reactants = 'H2:1.1, O2:1, AR:5'  # premixed gas composition
width = 0.03  # m
loglevel = 1  # amount of diagnostic output (0 to 8)

# Solution object used to compute mixture properties, set to the state of the
# upstream fuel-air mixture
gas = ct.Solution('h2o2.yaml')
gas.TPX = Tin, p, reactants

# Set up flame object
f = ct.FreeFlame(gas, width=width)
f.set_refine_criteria(ratio=3, slope=0.06, curve=0.12)
f.show_solution()

# Solve with mixture-averaged transport model
f.transport_model = 'Mix'
f.solve(loglevel=loglevel, auto=True)

# Solve with the energy equation enabled
try:
    # save to HDF container file if h5py is installed
    f.write_hdf('adiabatic_flame.h5', group='mix', mode='w',
Example #20
0
Since reactors can have multiple inlets and outlets, they can be used to
implement mixers, splitters, etc. In this example, air and methane are mixed
in stoichiometric proportions. Due to the low temperature, no reactions occur.
Note that the air stream and the methane stream use *different* reaction
mechanisms, with different numbers of species and reactions. When gas flows
from one reactor or reservoir to another one with a different reaction
mechanism, species are matched by name. If the upstream reactor contains a
species that is not present in the downstream reaction mechanism, it will be
ignored. In general, reaction mechanisms for downstream reactors should
contain all species that might be present in any upstream reactor.
"""

import cantera as ct

# Use air for stream a.
gas_a = ct.Solution('air.xml')
gas_a.TPX = 300.0, ct.one_atm, 'O2:0.21, N2:0.78, AR:0.01'
rho_a = gas_a.density

# Use GRI-Mech 3.0 for stream b (methane) and for the mixer. If it is desired
# to have a pure mixer, with no chemistry, use instead a reaction mechanism
# for gas_b that has no reactions.
gas_b = ct.Solution('gri30.xml')
gas_b.TPX = 300.0, ct.one_atm, 'CH4:1'
rho_b = gas_b.density

# Create reservoirs for the two inlet streams and for the outlet stream.  The
# upsteam reservoirs could be replaced by reactors, which might themselves be
# connected to reactors further upstream. The outlet reservoir could be
# replaced with a reactor with no outlet, if it is desired to integrate the
# composition leaving the mixer in time, or by an arbitrary network of
Example #21
0
def write(solution):
    """Function to write cantera solution object to inp file.

    Parameters
    ----------
    solution : obj
        Cantera solution object

    Returns : str
        Name of trimmed Mechanism file (.inp)

    Example
    -------
        soln2ck.write(gas)
    """
    trimmed_solution = solution
    input_file_name_stripped = trimmed_solution.name
    cwd = os.getcwd()
    output_file_name = os.path.join(cwd,
                                    'pym_' + input_file_name_stripped + '.inp')
    f = open(output_file_name, 'w+')

    #Work functions

    calories_constant = 4184.0  #number of calories in 1000 Joules of energy

    def eliminate(input_string, char_to_replace, spaces='single'):
        """
        Eliminate characters from a string

        :param input_string
            string to be modified
        :param char_to_replace
            array of character strings to be removed
        """
        for char in char_to_replace:
            input_string = input_string.replace(char, "")
        if spaces == 'double':
            input_string = input_string.replace(" ", "  ")
        return input_string

    def section_break(title):
        """
        Insert break and new section title into cti file

        :param title:
            title string for next section_break
        """
        f.write('!' + "-" * 75 + '\n')
        f.write('!  ' + title + '\n')
        f.write('!' + "-" * 75 + '\n')

    def replace_multiple(input_string, replace_list):
        """
        Replace multiple characters in a string

        :param input_string
            string to be modified
        :param replace list
            list containing items to be replaced (value replaces key)
        """
        for original_character, new_character in replace_list.items():
            input_string = input_string.replace(original_character,
                                                new_character)
        return input_string

    def build_arrhenius(equation_object, equation_type):
        """
        Builds Arrhenius coefficient string

        :param equation_objects
            cantera equation object
        :param equation_type:
            string of equation type
        """
        coeff_sum = sum(equation_object.reactants.values())
        pre_exponential_factor = equation_object.rate.pre_exponential_factor
        temperature_exponent = '{:.3f}'.format(
            equation_object.rate.temperature_exponent)
        activation_energy = '{:.2f}'.format(
            equation_object.rate.activation_energy / calories_constant)
        if equation_type == 'ElementaryReaction':
            if coeff_sum == 1:
                pre_exponential_factor = str(
                    '{:.3E}'.format(pre_exponential_factor))
            if coeff_sum == 2:
                pre_exponential_factor = str('{:.3E}'.format(
                    pre_exponential_factor * 10**3))
            if coeff_sum == 3:
                pre_exponential_factor = str('{:.3E}'.format(
                    pre_exponential_factor * 10**6))
        if equation_type == 'ThreeBodyReaction':
            if coeff_sum == 1:
                pre_exponential_factor = str('{:.3E}'.format(
                    pre_exponential_factor * 10**3))
            if coeff_sum == 2:
                pre_exponential_factor = str('{:.3E}'.format(
                    pre_exponential_factor * 10**6))
        if (equation_type != 'ElementaryReaction'
                and equation_type != 'ThreeBodyReaction'):
            pre_exponential_factor = str(
                '{:.3E}'.format(pre_exponential_factor))
        arrhenius = [
            pre_exponential_factor, temperature_exponent, activation_energy
        ]
        return arrhenius

    def build_modified_arrhenius(equation_object, t_range):
        """
        Builds Arrhenius coefficient strings for high and low temperature ranges

        :param equation_objects
            cantera equation object
        :param t_range:
            simple string ('high' or 'low') to designate temperature range
        """
        coeff_sum = sum(equation_object.products.values())
        if t_range == 'high':
            pre_exponential_factor = equation_object.high_rate.pre_exponential_factor
            temperature_exponent = '{:.3f}'.format(
                equation_object.high_rate.temperature_exponent)
            activation_energy = '{:.2f}'.format(
                equation_object.high_rate.activation_energy /
                calories_constant)
            if coeff_sum == 1:
                pre_exponential_factor = str('{:.5E}'.format(
                    pre_exponential_factor * 10**3))
            else:
                pre_exponential_factor = str(
                    '{:.5E}'.format(pre_exponential_factor))
            arrhenius_high = [
                pre_exponential_factor, temperature_exponent, activation_energy
            ]
            return arrhenius_high
        if t_range == 'low':

            pre_exponential_factor = equation_object.low_rate.pre_exponential_factor
            temperature_exponent = '{:.3f}'.format(
                equation_object.low_rate.temperature_exponent)
            activation_energy = '{:.2f}'.format(
                equation_object.low_rate.activation_energy / calories_constant)
            if coeff_sum == 1:
                pre_exponential_factor = str('{:.5E}'.format(
                    pre_exponential_factor * 10**6))
            else:
                pre_exponential_factor = str('{:.5E}'.format(
                    pre_exponential_factor * 10**3))

            arrhenius_low = [
                pre_exponential_factor, temperature_exponent, activation_energy
            ]
            return arrhenius_low

    def build_nasa(nasa_coeffs, row):
        """
        Creates string of nasa polynomial coefficients

        :param nasa_coeffs
            cantera species thermo coefficients object
        :param row
            which row to write coefficients in
        """
        line_coeffs = ''
        lines = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14]]
        line_index = lines[row - 2]
        for ix, c in enumerate(nasa_coeffs):
            if ix in line_index:
                if c >= 0:
                    line_coeffs += ' '
                line_coeffs += str('{:.8e}'.format(c))
        return line_coeffs

    def build_species_string():
        """
        formats species string for writing
        """
        species_list_string = ''
        line = 1
        for sp_index, sp_string in enumerate(trimmed_solution.species_names):
            sp = ' '
            #get length of string next species is added
            length_new = len(sp_string)
            length_string = len(species_list_string)
            total = length_new + length_string + 3
            #if string will go over width, wrap to new line
            if total >= 70 * line:
                species_list_string += '\n'
                line += 1
            species_list_string += sp_string + ((16 - len(sp_string)) * sp)
        return species_list_string

    #Write title block to file
    section_break('Chemkin File converted from Solution Object by pyMARS')

    #Write phase definition to file
    element_names = eliminate(str(trimmed_solution.element_names),
                              ['[', ']', '\'', ','])
    element_string = Template('ELEMENTS\n' + '$element_names\n' + 'END\n')
    f.write(element_string.substitute(element_names=element_names))
    species_names = build_species_string()
    species_string = Template('SPECIES\n' + '$species_names\n' + 'END\n')
    f.write(species_string.substitute(species_names=species_names))

    #Write species to file
    section_break('Species data')
    f.write('THERMO ALL' + '\n' + '   300.000  1000.000  5000.000' + '\n')
    phase_unknown_list = []

    #write data for each species in the Solution object
    for sp_index in xrange(len(trimmed_solution.species_names)):
        d = 3.33564e-30  #1 debye = d coulomb-meters
        species = trimmed_solution.species(sp_index)
        name = str(trimmed_solution.species(sp_index).name)
        nasa_coeffs = trimmed_solution.species(sp_index).thermo.coeffs
        #Species attributes from trimmed solution object
        t_low = '{0:.3f}'.format(species.thermo.min_temp)
        t_max = '{0:.3f}'.format(species.thermo.max_temp)
        t_mid = '{0:.3f}'.format(species.thermo.coeffs[0])
        temp_range = str(t_low) + '  ' + str(t_max) + '  ' + t_mid
        species_comp = ''
        for atom in species.composition:
            species_comp += '{:<4}'.format(atom)
            species_comp += str(int(species.composition[atom]))
        if type(species.transport).__name__ == 'GasTransportData':
            species_phase = 'G'
        else:
            phase_unknown_list.append(name)
            species_phase = 'G'
        line_1 = ('{:<18}'.format(name) + '{:<6}'.format('    ') +
                  '{:<20}'.format(species_comp) +
                  '{:<4}'.format(species_phase) + '{:<31}'.format(temp_range) +
                  '{:<1}'.format('1') + '\n')
        f.write(line_1)
        line_2_coeffs = build_nasa(nasa_coeffs, 2)
        line_2 = line_2_coeffs + '    2\n'
        f.write(line_2)
        line_3_coeffs = build_nasa(nasa_coeffs, 3)
        line_3 = line_3_coeffs + '    3\n'
        f.write(line_3)
        line_4_coeffs = build_nasa(nasa_coeffs, 4)
        line_4 = line_4_coeffs + '                   4\n'
        f.write(line_4)

    f.write('END\n')

    #Write reactions to file
    section_break('Reaction Data')
    f.write('REACTIONS\n')
    #write data for each reaction in the Solution Object
    for reac_index in xrange(len(trimmed_solution.reaction_equations())):
        equation_string = str(trimmed_solution.reaction_equation(reac_index))
        equation_string = eliminate(equation_string, ' ', 'single')
        equation_object = trimmed_solution.reaction(reac_index)
        equation_type = type(equation_object).__name__
        m = str(reac_index + 1)
        if equation_type == 'ThreeBodyReaction':
            arrhenius = build_arrhenius(equation_object, equation_type)
            main_line = ('{:<51}'.format(equation_string) +
                         '{:>9}'.format(arrhenius[0]) +
                         '{:>9}'.format(arrhenius[1]) +
                         '{:>11}'.format(arrhenius[2]) + '\n')
            f.write(main_line)
            #trimms efficiencies list
            efficiencies = equation_object.efficiencies
            trimmed_efficiencies = equation_object.efficiencies
            for s in efficiencies:
                if s not in trimmed_solution.species_names:
                    del trimmed_efficiencies[s]
            replace_list_2 = {'{': '', '}': '/', '\'': '', ':': '/', ',': '/'}
            efficiencies_string = replace_multiple(str(trimmed_efficiencies),
                                                   replace_list_2)
            secondary_line = str(efficiencies_string) + '\n'
            if bool(efficiencies) is True:
                f.write(secondary_line)
        if equation_type == 'ElementaryReaction':
            arrhenius = build_arrhenius(equation_object, equation_type)
            main_line = ('{:<51}'.format(equation_string) +
                         '{:>9}'.format(arrhenius[0]) +
                         '{:>9}'.format(arrhenius[1]) +
                         '{:>11}'.format(arrhenius[2]) + '\n')
            f.write(main_line)
        if equation_type == 'FalloffReaction':
            arr_high = build_modified_arrhenius(equation_object, 'high')
            main_line = ('{:<51}'.format(equation_string) +
                         '{:>9}'.format(arr_high[0]) +
                         '{:>9}'.format(arr_high[1]) +
                         '{:>11}'.format(arr_high[2]) + '\n')
            f.write(main_line)
            arr_low = build_modified_arrhenius(equation_object, 'low')
            second_line = ('     LOW  /' + '  ' + arr_low[0] + '  ' +
                           arr_low[1] + '  ' + arr_low[2] + '/\n')
            f.write(second_line)
            j = equation_object.falloff.parameters
            #If optional Arrhenius data included:
            try:
                third_line = ('     TROE/' + '   ' + str(j[0]) + '  ' +
                              str(j[1]) + '  ' + str(j[2]) + '  ' + str(j[3]) +
                              ' /\n')
                f.write(third_line)
            except IndexError:
                pass
            #trimms efficiencies list
            efficiencies = equation_object.efficiencies
            trimmed_efficiencies = equation_object.efficiencies
            for s in efficiencies:
                if s not in trimmed_solution.species_names:
                    del trimmed_efficiencies[s]
            replace_list_2 = {'{': '', '}': '/', '\'': '', ':': '/', ',': '/'}
            efficiencies_string = replace_multiple(str(trimmed_efficiencies),
                                                   replace_list_2)

            fourth_line = str(efficiencies_string) + '\n'
            if bool(efficiencies) is True:
                f.write(fourth_line)
        #dupluicate option
        if equation_object.duplicate is True:
            duplicate_line = ' DUPLICATE' + '\n'
            f.write(duplicate_line)
    f.write('END')
    f.close()

    #Test mechanism file

    original_solution = solution
    #convert written chemkin file to cti, and get solution
    parser = ck2cti.Parser()
    outName = 'test_file.cti'
    parser.convertMech(output_file_name, outName=outName)
    new_solution = ct.Solution(outName)

    #test new solution vs original solutoin
    #test(original_solution, new_solution)
    os.remove(outName)
    return output_file_name
    """
Example #22
0
 def setUpClass(cls):
     cls.gas = ct.Solution("jacobian-tests.yaml", transport_model=None)
     #   species: [H2, H, O, O2, OH, H2O, HO2, H2O2, AR]
     cls.gas.X = [0.1, 1e-4, 1e-5, 0.2, 2e-4, 0.3, 1e-6, 5e-5, 0.4]
     cls.gas.TP = 800, 2 * ct.one_atm
     super().setUpClass()
Example #23
0
fuel_inflow_temperature = 300  #[K]

# mixture fraction
mixture_fraction_element = 'N'

# Reaction on/off
reactions = 1

# Restart from previous particle list
restart = 0

## End of settings
#..........................................................................#

# get a mixture object going
gas = ct.Solution(mech)

# equilibrate the intial compposition
gas.TPY = T, 101000, initial_composition
gas.equilibrate('HP')
for counter, mass_fraction in enumerate(gas.Y):
    initial_composition[gas.species_name(counter)] = mass_fraction
T = gas.T

# Mixture fraction setup
gas.TPY = T, 101000, oxidizer_inflow_composition
#elemental mass fraction of mt_element in oxidizer stream
Z_oxidizer = gas.elemental_mass_fraction(mixture_fraction_element)
_, rho_fuel = gas.TD

gas.TPY = T, 101000, fuel_inflow_composition
Example #24
0
 def setUpClass(cls):
     cls.gas = ct.Solution("kineticsfromscratch.yaml", transport_model=None)
     #   species: [AR, O, H2, H, OH, O2, H2O, H2O2, HO2]
     cls.gas.X = [0.1, 3e-4, 5e-5, 6e-6, 3e-3, 0.6, 0.25, 1e-6, 2e-5]
     cls.gas.TP = 2000, 5 * ct.one_atm
     super().setUpClass()
Example #25
0
        tab2 = []
        for itcon in range(ncon):
            for k in range(noptim):
                tab2.append(k)
        return (np.array(tab), np.array(tab2))
    else:
        return OptFn.gradient_constraints(x)


if __name__ == '__main__':
    # Main process, common to all tasks (master and slaves)
    # Reading input
    up = imp.load_source('user_param', sys.argv[1])

    # Cantera gas phase
    Global.gas = ct.Solution(up.mechanism)

    # Specific storage for flame computations
    Global.nflames = len(up.P_fl)*len(up.T_fl)*len(up.phi_fl)
    Global.flame_inits = [False for ii in range(Global.nflames)]
    Global.sims = [False for ii in range(Global.nflames)]
    Global.gases = [False for ii in range(Global.nflames)]
    Global.directory = up.directory
    Global.mechanism = up.mechanism

    # Define MPI message tags
    tags = Par.enum('READY', 'DONE', 'EXIT', 'START', 'SLEEP', 'WAKEUP')

    # Initializations and preliminaries
    Global.MPI = MPI
    comm = MPI.COMM_WORLD   # get MPI communicator object
Example #26
0
 def setUpClass(cls):
     cls.gas = ct.Solution("h2o2.yaml", transport_model=None)
     cls.gas.TPX = 300, 5 * ct.one_atm, "H2:1, O2:3"
     cls.gas.equilibrate("HP")
     super().setUpClass()
def reduce_drgep(model_file,
                 species_safe,
                 threshold,
                 importance_coeffs,
                 ignition_conditions,
                 sampled_metrics,
                 phase_name='',
                 previous_model=None,
                 num_threads=1,
                 path=''):
    """Given a threshold and DRGEP coefficients, reduce the model and determine the error.

    Parameters
    ----------
    model_file : str
        Filename for model being reduced
    species_safe : list of str
        List of species to always be retained
    threshold : float
        DRG threshold for trimming graph
    importance_coeffs : dict
        Dictionary with species and their overall interaction coefficients.
    ignition_conditions : list of InputIgnition
        List of autoignition initial conditions.
    sampled_metrics: numpy.ndarray
        Global metrics from original model used to evaluate error
    phase_name : str, optional
        Optional name for phase to load from CTI file (e.g., 'gas'). 
    previous_model : ReducedModel, optional
        Model produced at previous threshold level; used to avoid repeated work.
    num_threads : int, optional
        Number of CPU threads to use for performing simulations in parallel.
        Optional; default = 1, in which the multiprocessing module is not used.
        If 0, then use the available number of cores minus one. Otherwise,
        use the specified number of threads.
    path : str, optional
        Optional path for writing files

    Returns
    -------
    ReducedModel
        Return reduced model and associated metadata

    """
    solution = ct.Solution(model_file, phase_name)
    species_removed = [
        sp for sp in solution.species_names
        if importance_coeffs[sp] < threshold and sp not in species_safe
    ]

    if (previous_model and len(species_removed)
            == solution.n_species - previous_model.model.n_species):
        return previous_model

    # Cut the exclusion list from the model.
    reduced_model = reduce_model.trim(model_file,
                                      species_removed,
                                      f'reduced_{model_file}',
                                      phase_name=phase_name)
    reduced_model_filename = soln2cti.write(
        reduced_model, f'reduced_{reduced_model.n_species}.cti', path=path)

    reduced_model_metrics = sampling.sample_metrics(reduced_model_filename,
                                                    ignition_conditions,
                                                    phase_name=phase_name,
                                                    num_threads=num_threads,
                                                    path=path)
    error = sampling.calculate_error(sampled_metrics, reduced_model_metrics)

    return reduce_model.ReducedModel(model=reduced_model,
                                     filename=reduced_model_filename,
                                     error=error)
Example #28
0
 def setUpClass(cls):
     cls.gas = ct.Solution("gri30.yaml", transport_model=None)
     cls.gas.TPX = 300, 5 * ct.one_atm, "CH4:1, C3H8:.1, O2:1, N2:3.76"
     cls.gas.equilibrate("HP")
     super().setUpClass()
from SDToolbox import CJspeed
from scipy.optimize import fsolve
import time


def CJ_func(comp, A):
    [Vel, _] = CJspeed(101325, 298, comp, 'gri30.cti', 0)
    print(Vel, comp)
    A.append(Vel)
    return A, Vel


start = time.time()
T = 298
P = 101325
gas = ct.Solution('gri30.cti')
j = 1
comp = 'C3H8:1, N2O:10, N2:{0}'.format(j)
gas.TPX = T, P, comp
k_N2 = gas.cp_mass / gas.cv_mass

k_CO2 = 0.0
k_m = []
i = 0
i_m = []
gas2 = ct.Solution('gri30.cti')

gas_check = ct.Solution('gri30.cti')
gas_check.TPX = T, P, 'CO2:1'

if k_N2 > gas_check.cp_mass / gas_check.cv_mass:
Example #30
0
 def test_noninteger_atomicity(self):
     gas = ct.Solution('noninteger-atomicity.cti')
     self.assertNear(
         gas.molecular_weights[gas.species_index('CnHm')],
         10.65 * gas.atomic_weight('C') + 21.8 * gas.atomic_weight('H'))