def stoich_fuel_to_oxidizer(mix, fuel, oxidizer): """Fuel to oxidizer ratio for stoichiometric combustion. This function only works for fuels composed of carbon, hydrogen, and/or oxygen. The fuel to oxidizer ratio is returned that results in """ # fuel mix.setMoleFractions(fuel) f_carbon = elementMoles(mix, 'C') f_oxygen = elementMoles(mix, 'O') f_hydrogen = elementMoles(mix, 'H') #oxidizer mix.setMoleFractions(oxidizer) o_carbon = elementMoles(mix, 'C') o_oxygen = elementMoles(mix, 'O') o_hydrogen = elementMoles(mix, 'H') B = array([f_carbon, f_hydrogen, f_oxygen],'d') A = array([[1.0, 0.0, -o_carbon], [0.0, 2.0, -o_hydrogen], [2.0, 1.0, -o_oxygen]], 'd') num = array(A,'d') num[:,2] = B r = det3(num)/det3(A) if r <= 0.0: raise CanteraError('negative or zero computed stoichiometric fuel/oxidizer ratio!') return 1.0/r
def stoich_fuel_to_oxidizer(mix, fuel, oxidizer): """Fuel to oxidizer ratio for stoichiometric combustion. This function only works for fuels composed of carbon, hydrogen, and/or oxygen. The fuel to oxidizer ratio is returned that results in """ # fuel mix.setMoleFractions(fuel) f_carbon = elementMoles(mix, 'C') f_oxygen = elementMoles(mix, 'O') f_hydrogen = elementMoles(mix, 'H') #oxidizer mix.setMoleFractions(oxidizer) o_carbon = elementMoles(mix, 'C') o_oxygen = elementMoles(mix, 'O') o_hydrogen = elementMoles(mix, 'H') B = array([f_carbon, f_hydrogen, f_oxygen], 'd') A = array([[1.0, 0.0, -o_carbon], [0.0, 2.0, -o_hydrogen], [2.0, 1.0, -o_oxygen]], 'd') num = array(A, 'd') num[:, 2] = B r = det3(num) / det3(A) if r <= 0.0: raise CanteraError( 'negative or zero computed stoichiometric fuel/oxidizer ratio!') return 1.0 / r
def init(self): """Set the initial guess for the solution. The adiabatic flame temperature and equilibrium composition are computed for the burner gas composition. The temperature profile rises linearly in the first 20% of the flame to Tad, then is flat. The mass fraction profiles are set similarly. """ self.getInitialSoln() gas = self.gas nsp = gas.nSpecies() yin = zeros(nsp, 'd') for k in range(nsp): yin[k] = self.burner.massFraction(k) gas.setState_TPY(self.burner.temperature(), self.pressure, yin) u0 = self.burner.mdot() / gas.density() t0 = self.burner.temperature() # get adiabatic flame temperature and composition gas.equilibrate('HP', solver=1) teq = gas.temperature() yeq = gas.massFractions() u1 = self.burner.mdot() / gas.density() z1 = 0.2 locs = array([0.0, z1, 1.0], 'd') self.setProfile('u', locs, [u0, u1, u1]) self.setProfile('T', locs, [t0, teq, teq]) for n in range(nsp): self.setProfile(gas.speciesName(n), locs, [yin[n], yeq[n], yeq[n]]) self._initialized = 1
def init(self): """Set the initial guess for the solution. The adiabatic flame temperature and equilibrium composition are computed for the burner gas composition. The temperature profile rises linearly in the first 20% of the flame to Tad, then is flat. The mass fraction profiles are set similarly. """ self.getInitialSoln() gas = self.gas nsp = gas.nSpecies() yin = zeros(nsp, 'd') for k in range(nsp): yin[k] = self.burner.massFraction(k) gas.setState_TPY(self.burner.temperature(), self.pressure, yin) u0 = self.burner.mdot()/gas.density() t0 = self.burner.temperature() # get adiabatic flame temperature and composition gas.equilibrate('HP') teq = gas.temperature() yeq = gas.massFractions() u1 = self.burner.mdot()/gas.density() z1 = 0.2 locs = array([0.0, z1, 1.0],'d') self.setProfile('u', locs, [u0, u1, u1]) self.setProfile('T', locs, [t0, teq, teq]) for n in range(nsp): self.setProfile(gas.speciesName(n), locs, [yin[n], yeq[n], yeq[n]]) self._initialized = 1
def __init__(self, func, T): """ func - initial non-periodic function T - period [s] """ Func1.__init__(self, 50, func.func_id(), array([T], 'd'))
def __init__(self, func, T): """ func - initial non-periodic function T - period [s] """ Func1.__init__(self, 50, func.func_id(), array([T],'d')) func._own = 0
def setCoverages(self, cov): if type(cov) == types.DictType: cv = [0.0] * len(self.species) for c in cov.keys(): cv[self.indexmap[c]] = cov[c] else: cv = cov ctsurf.surf_setcoverages(self.__surf_id, array(cv, 'd'))
def __init__(self, func, T): """ :param func: initial non-periodic function :param T: period [s] """ Func1.__init__(self, 50, func.func_id(), array([T], 'd')) func._own = 0
def __init__(self, func, T): """ :param func: initial non-periodic function :param T: period [s] """ Func1.__init__(self, 50, func.func_id(), array([T], "d")) func._own = 0
def init(self, products='inlet'): """Set the initial guess for the solution. If products = 'equil', then the equilibrium composition at the adiabatic flame temperature will be used to form the initial guess. Otherwise the inlet composition will be used.""" self.getInitialSoln() gas = self.gas nsp = gas.nSpecies() yin = zeros(nsp, 'd') for k in range(nsp): yin[k] = self.inlet.massFraction(k) gas.setState_TPY(self.inlet.temperature(), self.pressure, yin) u0 = self.inlet.mdot() / gas.density() t0 = self.inlet.temperature() V0 = 0.0 tsurf = self.surface.temperature() zz = self.flow.grid() dz = zz[-1] - zz[0] if products == 'equil': gas.equilibrate('HP') teq = gas.temperature() yeq = gas.massFractions() locs = array([0.0, 0.3, 0.7, 1.0], 'd') self.setProfile('T', locs, [t0, teq, teq, tsurf]) for n in range(nsp): self.setProfile(gas.speciesName(n), locs, [yin[n], yeq[n], yeq[n], yeq[n]]) else: locs = array([0.0, 1.0], 'd') self.setProfile('T', locs, [t0, tsurf]) for n in range(nsp): self.setProfile(gas.speciesName(n), locs, [yin[n], yin[n]]) locs = array([0.0, 1.0], 'd') self.setProfile('u', locs, [u0, 0.0]) self.setProfile('V', locs, [V0, V0]) self._initialized = 1
def init(self, products = 'inlet'): """Set the initial guess for the solution. If products = 'equil', then the equilibrium composition at the adiabatic flame temperature will be used to form the initial guess. Otherwise the inlet composition will be used.""" self.getInitialSoln() gas = self.gas nsp = gas.nSpecies() yin = zeros(nsp, 'd') for k in range(nsp): yin[k] = self.inlet.massFraction(k) gas.setState_TPY(self.inlet.temperature(), self.flow.pressure(), yin) u0 = self.inlet.mdot()/gas.density() t0 = self.inlet.temperature() V0 = 0.0 tsurf = self.surface.temperature() zz = self.flow.grid() dz = zz[-1] - zz[0] if products == 'equil': gas.equilibrate('HP') teq = gas.temperature() yeq = gas.massFractions() locs = array([0.0, 0.3, 0.7, 1.0],'d') self.setProfile('T', locs, [t0, teq, teq, tsurf]) for n in range(nsp): self.setProfile(gas.speciesName(n), locs, [yin[n], yeq[n], yeq[n], yeq[n]]) else: locs = array([0.0, 1.0],'d') self.setProfile('T', locs, [t0, tsurf]) for n in range(nsp): self.setProfile(gas.speciesName(n), locs, [yin[n], yin[n]]) locs = array([0.0, 1.0],'d') self.setProfile('u', locs, [u0, 0.0]) self.setProfile('V', locs, [V0, V0]) self._initialized = 1
def __init__(self, typ, n, coeffs=[]): """ The constructor is meant to be called from constructors of subclasses of Func1: :class:`Polynomial`, :class:`Gaussian`, :class:`Arrhenius`, :class:`Fourier`, :class:`Const`, :class:`PeriodicFunction`. """ self.n = n self._own = 1 self._func_id = 0 self._typ = typ if _cantera.nummod == 'numpy': self.coeffs = array(coeffs, dtype=float, ndmin=1) else: self.coeffs = asarray(coeffs, 'd') self._func_id = _cantera.func_new(typ, n, self.coeffs)
def __init__(self, typ, n, coeffs=[]): """ The constructor is meant to be called from constructors of subclasses of Func1: :class:`Polynomial`, :class:`Gaussian`, :class:`Arrhenius`, :class:`Fourier`, :class:`Const`, :class:`PeriodicFunction`. """ self.n = n self._own = 1 self._func_id = 0 self._typ = typ if _cantera.nummod == "numpy": self.coeffs = array(coeffs, dtype=float, ndmin=1) else: self.coeffs = asarray(coeffs, "d") self._func_id = _cantera.func_new(typ, n, self.coeffs)
def __init__(self, typ, n, coeffs=[]): """ The constructor is meant to be called from constructors of subclasses of Func1. See: Polynomial, Gaussian, Arrhenius, Fourier, Const, PeriodicFunction """ self.n = n self._own = 1 self._func_id = 0 self._typ = typ if _cantera.nummod == 'numpy': self.coeffs = array(coeffs, dtype=float, ndmin=1) else: self.coeffs = asarray(coeffs,'d') self._func_id = _cantera.func_new(typ, n, self.coeffs)
def _setParameters(self, c): params = array(c,'d') n = len(params) return _cantera.flowdev_setParameters(self.__fdev_id, n, params)
# parameter values # # These are grouped here to simplify changing flame conditions p = OneAtm # pressure tin_f = 300.0 # fuel inlet temperature tin_o = 300.0 # oxidizer inlet temperature mdot_o = 0.72 # kg/m^2/s mdot_f = 0.24 # kg/m^2/s comp_o = 'O2:0.21, N2:0.78, AR:0.01'; # air composition comp_f = 'C2H6:1'; # fuel composition # distance between inlets is 2 cm; start with an evenly-spaced 6-point # grid initial_grid = 0.02*array([0.0, 0.2, 0.4, 0.6, 0.8, 1.0],'d') tol_ss = [1.0e-5, 1.0e-9] # [rtol, atol] for steady-state # problem tol_ts = [1.0e-3, 1.0e-9] # [rtol, atol] for time stepping loglevel = 1 # amount of diagnostic output (0 # to 5) refine_grid = 1 # 1 to enable refinement, 0 to # disable ################ create the gas object ######################## #
def addReaction(self, r): """Add a reaction to the surface mechanism.""" self._freeze_species = 1 self.rxns.append(r) # check balance for e in self.elements: n = 0 for rr in r.reactants: n += rr.nAtoms(e) for pp in r.products: n -= pp.nAtoms(e) if n <> 0: raise CanteraError('Reaction does not balance. \nElement ' + e + ' out of balance by ' + ` n ` + ' atoms.') rmap = {} rindex2object = {} for rr in r.reactants: if rmap.has_key(rr): rmap[rr][1] += 1 rmap[rr][2] += 1 else: rmap[rr] = [self._index(rr), 1, 1] rindex2object[self._index(rr)] = rr pmap = {} for pp in r.products: if pmap.has_key(pp): pmap[pp][1] += 1 pmap[pp][2] += 1 else: pmap[pp] = [self._index(pp), 1, 1] rinfo = array(rmap.values(), 'i') pinfo = array(pmap.values(), 'i') rindex = rinfo[:, 0] for rr in r.order.keys(): loc = self._index(rr) for n in range(len(rindex)): if loc == rindex[n]: rinfo[n, 2] = r.order[rr] rstoich = rinfo[:, 1] rorder = rinfo[:, 2] pindex = pinfo[:, 0] pstoich = pinfo[:, 1] funit = 1.0 fb = 0.0 # sticking probabilities are dimensionless, and are limited to # reactions with one bulk reactant. The reaction rate is # computed as the sticking probability multiplied by the # incident flux, times the coverages of all surface species # reactants. if r.stick: rb = self._bulkReactants(r.reactants) if len(rb) <> 1: raise CanteraError( 'A sticking probability can only be specified if there' + ' is exactly one bulk-phase reactant') wt = rb[0].weight # mean speed / sqrt(T) cfactor = math.sqrt(8.0 * constants.GasConstant / (constants.Pi * wt)) for n in range(len(rindex)): if not self.isBulkSpecies(rindex[n]): sz = rindex2object[rindex[n]].size funit /= math.pow(self.s0 / sz, rorder[n]) preExp = funit * r.stick[0] * cfactor / 4.0 b = r.stick[1] + 0.5 e = r.stick[2] r.rate = [preExp, b, e] # Reaction rates are specified using several different # conventions. Here the various possibilities are converted # into rates per unit area, with reactant amounts specified in # concentrations. else: for n in range(len(rindex)): if self.isBulkSpecies(rindex[n]): if r.type.bulk == 'conc': funit /= (math.pow(self._uconc3, rorder[n])) elif r.type.bulk == 'bar': funit *= math.pow(1.e-5 * constants.GasConstant, rorder[n]) fb += rorder[n] else: if r.type.surf == 'conc': funit /= (math.pow(self._uconc2, rorder[n])) elif r.type.surf == 'cov': sz = rindex2object[rindex[n]].size funit /= math.pow(self.s0 / sz, rorder[n]) if r.type.result == 'per_area': funit *= self._uconc2 elif r.type.result == 'per_site': print 'multiplying A by ', self.s0 funit *= self.s0 # modify the pre-exponential term, and the temperature # exponent r.rate[0] *= funit print 'A = ', r.rate[0] r.rate[1] += fb rate = array(r.rate, 'd') # convert the activation energy to K rate[2] *= self._ue self.rxndata.append((rindex, rstoich, rorder, pindex, pstoich, rate)) ctsurf.surfkin_addreaction(self.__surf_id, len(rindex), array(rindex, 'i'), array(rstoich, 'i'), array(rorder, 'i'), len(pindex), array(pindex, 'i'), array(pstoich, 'i'), len(r.rate), rate)
def __init__(self, A, t0, FWHM): coeffs = array([A, t0, FWHM], 'd') Func1.__init__(self, 4, 0, coeffs)
def _setParameters(self, c): params = array(c, 'd') n = len(params) return _cantera.flowdev_setParameters(self.__fdev_id, n, params)