def setUp(self): self.phases = ct.import_phases('KOH.xml', [ 'K_solid', 'K_liquid', 'KOH_a', 'KOH_b', 'KOH_liquid', 'K2O2_solid', 'K2O_solid', 'KO2_solid', 'ice', 'liquid_water', 'KOH_plasma' ]) self.mix = ct.Mixture(self.phases)
def setUp(self): self._gas = ct.Solution('h2o2.yaml') self._carbon = ct.Solution('graphite.yaml') self._mix = ct.Mixture([self._gas, self._carbon]) self._output.save(self._mix, 'foo') self._mix.T = 500 self._output.save(self._mix, 'bar')
def compute_Zst(self): s = self s.gas.TPY = s.T1, s.pres, s.y1 mix = ct.Mixture([(s.gas, 1.0)]) nc1 = mix.element_moles("C") nh1 = mix.element_moles("H") no1 = mix.element_moles("O") nn1 = mix.element_moles("N") nfsp = mix.species_moles nf = sum(nfsp) no2_per_nfuel = (nc1 + nh1 / 4 - no1 / 2) / nf n1 = 1 n0 = no2_per_nfuel / s.x0[s.gas.species_index("O2")] s.gas.TPY = s.T0, s.pres, s.y0 M0 = s.gas.mean_molecular_weight s.gas.TPY = s.T1, s.pres, s.y1 M1 = s.gas.mean_molecular_weight s.Zst = n1 * M1 / (n0 * M0 + n1 * M1)
def doAnalysis(fuel): gas.set_equivalence_ratio(1.0, fuel, air) mix = ct.Mixture([(gas, 1.0), (carbon, 0.0)]) mix.T = Ti mix.P = Pi mix.equilibrate('HP') products = mix.phase(0) prodx = dict(zip(products.species_names, products.X)) fuel = fixDict(fuel) ox = fixDict({'N2': 3.76, 'O2': 1}) inert = fixDict(prodx) dfOut = pd.DataFrame(columns=['Xf', 'Xa', 'Xi', 'phi', 'Tad', 'Flammable']) Xf = 0.01 haseverburned = False while Xf <= 1.: Xa = round(1.0 - Xf, 3) burned = False while Xa >= 0: Xi = abs(round(1.00 - Xf - Xa, 3)) MMIX = collections.defaultdict(lambda: 0) for key in gaslistfull: MMIX[key] = Xf * fuel[key] + Xa * ox[key] + Xi * inert[key] Tl, Tu = Tblend(MMIX) dres = Eqq(MMIX) if dres['phi'] > 1: if dres['Tad'] > Tu: Flammable = 1 burned = True haseverburned = True else: Flammable = 0 else: if dres['Tad'] > Tl: Flammable = 1 haseverburned = True burned = True else: Flammable = 0 dfOut = dfOut.append( { 'Xf': Xf, 'Xa': Xa, 'Xi': Xi, 'phi': dres['phi'], 'Tad': dres['Tad'], 'Flammable': Flammable }, ignore_index=True) print(Xf, Xa, Xi, Flammable, dres['Tad']) if sum(dfOut.iloc[-2::]['Flammable']) == 0.0: Xa = round(Xa - 0.1, 1) else: Xa = round(Xa - 0.01, 3) if haseverburned and burned: Xf = round(Xf + 0.1, 1) else: Xf = round(Xf + 0.01, 3) return dfOut
def test_properties(self): mix = ct.Mixture([(self.phase1, 1.0), (self.phase2, 2.0)]) self.assertEqual(mix.nSpecies, self.phase1.nSpecies + self.phase2.nSpecies) mix.temperature = 350 self.assertEqual(mix.temperature, 350) mix.pressure = 2e5 self.assertEqual(mix.pressure, 2e5)
def run(initial, phases, equilibrate): """Function handling equilibrium calculations. The function handles equilibrium calculations for both single phases (``Solution``; single entry in *phases* argument) and multiple phases (``Mixture``; multiple entries in *phases* argument). Arguments: initial (Parser): Initial condition phases (Parser): Definition of phases equilibrate (Parser): Arguments of ``equilibrate`` function Returns: Cantera `Solution` or `Mixture` object """ T = initial.T.m_as('kelvin') P = initial.P.m_as('pascal') # phases that will be included in the calculation, and their initial moles mix_phases = [] for phase in phases.values(): if phase is None: continue obj = ct.Solution(phase.mechanism) if all([key in phase for key in ['fuel', 'oxidizer']] + ['phi' in initial]): obj.TP = T, P obj.set_equivalence_ratio(initial.phi, phase.fuel, phase.oxidizer) elif 'X' in phase: obj.TPX = T, P, phase.X elif 'Y' in phase: obj.TPY = T, P, phase.Y mix_phases.append((obj, phase.get('moles'))) # equilibrate the mixture based on configuration if len(mix_phases) > 1: obj = ct.Mixture(mix_phases) obj.T = T obj.P = P kwargs = equilibrate.raw mode = kwargs.pop('mode') obj.equilibrate(mode, **kwargs) print('Tad = {:8.2f}'.format(obj.T)) return obj
def solve(self, solver, **kwargs): n_points = 12 T = 300 P = 101325 data = np.zeros((n_points, 2+self.n_species)) phi = np.linspace(0.3, 3.5, n_points) for i in range(n_points): self.gas.set_equivalence_ratio(phi[i], self.fuel, {'O2': 1.0, 'N2': 3.76}) mix = ct.Mixture(self.mix_phases) mix.T = T mix.P = P # equilibrate the mixture adiabatically at constant P mix.equilibrate('HP', solver=solver, max_steps=1000, **kwargs) data[i,:2] = (phi[i], mix.T) data[i,2:] = mix.species_moles self.compare(data, pjoin(self.test_data_dir, 'gas-carbon-equil.csv'))
def solve(self, solver): n_points = 12 T = 300 P = 101325 data = np.zeros((n_points, 2 + self.n_species)) phi = np.linspace(0.3, 3.5, n_points) for i in range(n_points): X = {self.fuel: phi[i] / self.stoich, 'O2': 1.0, 'N2': 3.76} self.gas.TPX = T, P, X mix = ct.Mixture(self.mix_phases) mix.T = T mix.P = P # equilibrate the mixture adiabatically at constant P mix.equilibrate('HP', solver=solver, max_steps=1000) data[i, :2] = (phi[i], mix.T) data[i, 2:] = mix.species_moles self.compare(data, '../data/gas-carbon-equil.csv')
def Eq(fuel, phi): gas = ct.Solution('gri30.xml', 'gri30_mix') gas.set_equivalence_ratio(phi, fuel, air) mix = ct.Mixture([(gas, 1.0), (carbon, 0.0)]) mix.T = Ti mix.P = Pi mix.equilibrate('HP') print(mix.T) Xf = 1 - sum(mix.phase(0)['N2', 'O2'].X) Xff = 1 - sum(mix.phase(0)['N2', 'O2', 'H2O', 'CO2'].X) Xair = 1 - Xf dResult = { 'phi': phi, 'Tad': mix.T, 'Xf': Xf, 'Xff': Xff, 'air': Xair, 'O2': mix.phase(0)['O2'].X } return dResult
def get_mw(self, conv=ml2l): """ Initialize parameters for cantera simulation. init() calls this function""" mx = ct.Mixture(self.phase) aq = mx.phase_index(self.phase_names[0]) org = mx.phase_index(self.phase_names[1]) mwre = np.zeros(len(self.ree)) # molecular weight of rees mwslv = np.zeros(len(self.solv)) # mw & densities for 'solvents' for re in self.ree: mwre[self.ree.index(re)] = mx.phase(aq).molecular_weights[mx.phase( aq).species_index(re + '+++')] for so in self.solv: if so == 'H2O(L)': mwslv[self.solv.index(so)] = mx.phase(aq).molecular_weights[ mx.phase(aq).species_index(so)] else: mwslv[self.solv.index(so)] = mx.phase(org).molecular_weights[ mx.phase(org).species_index(so)] return mwre, mwslv
def test_add_species_disabled(self): ref = ct.Solution('gri30.xml') reactor = ct.IdealGasReactor(self.phase) with self.assertRaises(ct.CanteraError): self.phase.add_species(ref.species('CH4')) del reactor gc.collect() self.phase.add_species(ref.species('CH4')) flame = ct.FreeFlame(self.phase, width=0.1) with self.assertRaises(ct.CanteraError): self.phase.add_species(ref.species('CO')) del flame gc.collect() self.phase.add_species(ref.species('CO')) mix = ct.Mixture([(self.phase, 2.0)]) with self.assertRaises(ct.CanteraError): self.phase.add_species(ref.species('CH2O')) del mix gc.collect() self.phase.add_species(ref.species('CH2O'))
'size': 15 }, 'tickcolor': 'rgba(0,0,0,0)', 'ticklen': 5, 'showline': True, 'showgrid': True } # Setup Cantera Pi = 101000 # Initial pressure Pa Ti = 300 # Initial unburned gas temperature K carbon = ct.Solution('graphite.xml') # Calls Gas Properties from Gri-MECH gas = ct.Solution('gri30.xml', 'gri30_mix') mix = ct.Mixture([(gas, 1.0), (carbon, 0.0)]) fuel10Ah = {'CO2': 44, 'CO': 15, 'H2': 31, 'CH4': 6, 'C3H8': 4} # 100 Percent Charge C fuelSom100pct = {'CO2': 30, 'CO': 23, 'H2': 28, 'CH4': 6, 'C2H6': 1, 'C3H8': 4} # LFP 100 SOC Golubkov 2015 Ethylene binned to Propane fuelLFP = { 'CO2': 48.3, 'CO': 9.1, 'H2': 29.4, 'CH4': 5.4, 'C2H6': 0.5, 'C3H8': 7.2 } air = {'N2': 3.76, 'O2': 1}
def setUp(self): self.mix = ct.Mixture(self.phases)
def setUp(self): self.mix = ct.Mixture([(self.phase1, 1.0), (self.phase2, 2.0)])
def run(self): # Gas Mixtures air_species = self.air # Air fuel_species = self.fuel phi = self.phi # Composition f = self.f # Temperatures and Pressures Patm = self.P # Initial Pressure T = self.T # Initial unburned gas temperature K P1 = Patm # Initial Pressure Pa = Patm # Exit pressure outside vent # Tu = T # Unburned gas temperature T1 = T # Initial Temperature # Geometry and Vent R = self.R # Radius Cd = self.Cd # Coefficient for vent Av = self.Av # Vent Area (m2) S = self.S # Solution Control tmax = self.tmax # Max Time for analysis # Create Gases carbon = ct.Solution('graphite.xml') # Calls Gas Properties from Gri-MECH gas_b = ct.Solution('gri30.xml', 'gri30_mix') # Calls Gas Properties from Gri-MECH gas_bv = ct.Solution('gri30.xml', 'gri30_mix') # Calls Gas Properties from Gri-MECH gas_u = ct.Solution('gri30.xml', 'gri30_mix') mix_phases_b = [(gas_b, 1.0), (carbon, 0.0)] # Burned Mixture mix_phases_u = [(gas_u, 1.0), (carbon, 0.0)] # Unburned Mixture gas_b.set_equivalence_ratio(phi, fuel_species, air_species) gas_bv.set_equivalence_ratio(phi, fuel_species, air_species) gas_u.set_equivalence_ratio(phi, fuel_species, air_species) gas_b.TP = T, Patm gas_bv.TP = T, Patm gas_u.TP = T, Patm unburned = ct.Mixture(mix_phases_u) # noqa burned = ct.Mixture(mix_phases_b) # # Calculate Laminar Flamespeed # CalcFlamespeed = False # if CalcFlamespeed: # # A freely-propagating flat flame # f = ct.FreeFlame(unburned, width=5) # # Energy equation enabled # f.energy_enabled = True # f.set_max_time_step(1000) # f.set_refine_criteria(ratio = 2.0, slope = 0.05, curve = 0.05) # # Solve with multi or mix component transport properties # f.transport_model = 'Mix' # f.solve(loglevel=1,auto=True,refine_grid=True) # S = f.u[0] # else: # Xh2 = float(gas_u['H2'].X) # #Laminar Burning Velocity for Hydrogen # # From Liu and MacFarlane for Xh2 < 0.42 # A1 = 4.644E-4 # A2 = -2.119E-3 # A3 = 2.344E-3 # A4 = 1.571 # A5 = 3.839E-1 # A6 = -2.21 # xh2O = 0.0 # mol fraction of steam # S = (((A1 + A2*(0.42-Xh2)+A3*(0.42-Xh2)**2) * # Tu**(A4+A5*(0.42-Xh2)))*np.exp(A6*xh2O)) # Unburned Gas Properties cp_aveu = gas_u.cp cv_aveu = gas_u.cv W_aveu = gas_u.mean_molecular_weight rou = gas_u.density # Burned Gas Properties # Chemical Equilibrium # equilibrate the mixture adiabatically at constant P burned.equilibrate('HP', solver='gibbs', max_steps=1000) cp_aveb = gas_b.cp # Average Cp cv_aveb = gas_b.cv # Average Cv W_aveb = gas_b.mean_molecular_weight # Average Molecular wt rob = gas_b.density # Average density Tb = burned.T gas_bv.equilibrate('UV') Pf_ = gas_bv.P / Patm # Ratio of specific heats for unburned gas = Cp/Cvs gammaU = cp_aveu / cv_aveu # Ratio of specific heats gammaB = cp_aveb / cv_aveb gammaE = (gammaU - 1) / (gammaB - 1) # gammaE=1.0 # Initial Volume and Mass V1 = 4.0 / 3.0 * np.pi * R**3 # Initial Volume mi = rou * V1 # Initial Mass # print("Unburned Mol Fraction") # print(gas_u.species_names,'\n', gas_u.X , '\n', # 'Mass Fraction \n', gas_u.Y) # print("Burned Mol Fraction") # print(gas_b.species_names, '\n',gas_b.X ,'\n', # 'Mass Fraction \n', gas_b.Y) # print("S: ",S) # print("Tb: ",Tb) # print("Pf: ",Pf_) # print("GammaE:", gammaE) # print("cp_aveb",cp_aveb) # start # initial conditions P_init = 1 n3init = 1E-5 * (W_aveu / W_aveb) * (Tb / T1) ninit = 1E-5 init = [P_init, n3init, ninit] t = np.linspace(0, tmax, 10000) # Solve ODE's x = odeint(vent_gas_explosion, init, t, args=(P1, R, V1, gammaE, Pf_, gammaU, mi, gas_u, S, rou, rob, gammaB, Cd, Av, f, T1, Pa)) # Output self.P_ = x[:, 0] # Pressure/initial pressure self.n3 = x[:, 1] # Burnt gas volume self.n = x[:, 2] # Ratio of burnt mass/initial mass self.r = R * (self.n3)**(1.0 / 3.0) # Spherical flame radius self.t = t self.nu = 1 - self.n # Ratio of unburned mass/initial mass self.mu = mi * self.nu # Mass of unburned gas # Number of unburned moles nmu = self.mu / (gas_u.mean_molecular_weight / 1000) self.Vu = (1 - self.n3) * V1 self.Tu = self.P_ * Patm * self.Vu / (nmu * RR) self.gas_u = gas_u self.gas_b = gas_b self.gas_bv = gas_bv self.Tb = Tb self.Pf_ = Pf_
def areaV(self, Av1): #Standard Air Composition Attribute air_species = self.air #Fuel Gas Composition Passed Into Vent Object on creation fuel_species = self.fuel #Equivalence Ratio phi = self.phi # Temperatures and Pressures Patm = self.P # Initial Pressure T = self.T # Initial unburned gas temperature K P1 = Patm # Initial Pressure Pa = Patm # Exit pressure outside vent # Tu = T # Unburned gas temperature T1 = T # Initial Temperature #Geometry parameters L = self.L W = self.W H = self.H #Face Areas Aw1 = L * H Aw2 = W * H Aw3 = W * L #Total Surface Area As = 2 * Aw1 + 2 * Aw2 + Aw3 #Hydraulic Diameter Dhe = 4 * (Aw2 / (2 * W + 2 * H)) #Area Blockage Ratio Br = self.Block #Reduced Pressure P_red = self.Reduced Pmax = self.Adiabatic Po = 0.01325 Pstat = self.Static #Vent Drag Coefficient Cd = self.Drag #Vent Static Activation Pressures P_stat = self.Static #Unburned Gas-Air Mixture Sonic Flow Mass Flux(kg/m^2-s) Gu = 230.1 #Flame speed Su = self.S #Cantera Objects carbon = ct.Solution('graphite.xml') # Calls Gas Properties from Gri-MECH -- creates burned gas object gas_b = ct.Solution('gri30.xml', 'gri30_mix') # Calls Gas Properties from Gri-MECH -- creates unburned object gas_u = ct.Solution('gri30.xml', 'gri30_mix') mix_phases_b = [(gas_b, 1.0), (carbon, 0.0)] # Burned Mixture mix_phases_u = [(gas_u, 1.0), (carbon, 0.0)] # Unburned Mixture gas_b.set_equivalence_ratio(phi, fuel_species, air_species) gas_u.set_equivalence_ratio(phi, fuel_species, air_species) Pi = 101000 #Initial pressure Pa Ti = 300 #Initital unburned gas temperature K gas_b.TP = Ti, Pi gas_u.TP = 300, ct.one_atm #---------------------- #Unburned gas-air mixture speed of sound (m/s): #au = self.equilSoundSpeeds(gas_u)[0] # save properties rtol = 1.0e-6 maxiter = 8000 gas_u.equilibrate('TP', rtol=rtol, maxiter=maxiter) s0 = gas_u.s p0 = gas_u.P r0 = gas_u.density # Perturb the pressure p1 = p0 * 1.0001 # Set the gas to a state with the same entropy and composition but # The perturbed pressure gas_u.SP = s0, p1 # Now equilibrate the gas holding S and P constant gas_u.equilibrate('SP', rtol=rtol, maxiter=maxiter) ptest = p1 - p0 ztest = gas_u.density - r0 dtest = ptest / ztest debub = { 'r0': r0, 'density': gas_u.density, 'bottom': ztest, 'top': ptest, 'div': dtest } # Equilibrium sound speed aequil = math.sqrt((p1 - p0) / (gas_u.density - r0)) #print('executed') au = aequil #-------- rho_u = gas_b.density mu_u = gas_b.viscosity unburned = ct.Mixture(mix_phases_u) # noqa burned = ct.Mixture(mix_phases_b) burned.equilibrate('HP', solver='gibbs', max_steps=1000) gamma_b = gas_b.cp / gas_b.cv #------------VENT AREA FUNCTION FROM AUSTIN'S SCRIPT------------------- Dv = math.sqrt((Av1 / self.Number)) #Reynolds number of flame through structure: Re_flame = rho_u * Su * (0.5 * Dhe) / mu_u #Phi 1: Based on Reynolds Number of Flame Front: phi_1 = max(1, (Re_flame / 4000)**0.39) #Maximum Velocity through Vent (m/s): uv = min(math.sqrt(P_red * 2 * 10**5 / rho_u), au) #Reynolds number through vent Re_vent = 0.5 * rho_u * uv * Dv / mu_u #Phi 2: Based on Reynolds Number through Vent: beta1 = 1.23 beta2 = 2.37 * 10**-3 phi_2 = max(1, beta1 * (Re_vent / 10**6)**((beta2 / Su)**0.5)) #Lambda 0: Lambda_0 = phi_1 * phi_2 #Lambda 1 Based on Obstructed surface area (m^2): Aobs = 0.3 * As #Obstruction Correction Factor if Aobs < 0.2 * As: Lambda_1 = Lambda_0 elif Aobs >= 0.2 * As: Lambda_1 = Lambda_0 * math.exp(math.sqrt((Aobs / As) - 0.2)) #L/D L_D = L / Dhe #Solving for Lambda: if L_D < 2.5: Lambda = Lambda_1 elif L_D >= 2.5: Lambda = Lambda_1 * (1 + ((L_D / 2.5) - 1)**2) # #L/D Correction Factor # if L_D > 5: # print ("L/D Above 5 see NFPA 68 Chapter 9") # elif Pmax > 10: # print ("Pmax Above 10 bar-g see NFPA 68") #Solving for vent size: C = (0.5 * Su * rho_u * Lambda / (Gu * Cd)) * (((Pmax + 1) / (Po + 1))**(1 / gamma_b) - 1) * (Po + 1)**0.5 delta = (((Pstat + 1) / (Po + 1))**(1 / gamma_b) - 1) / (( (Pmax + 1) / (Po + 1))**(1 / gamma_b) - 1) #Pred Corrction Factor if P_red <= 0.5: Avo = As * C / math.sqrt(P_red) elif P_red > 0.5: Avo = (As * Su * rho_u * Lambda / (Gu * Cd)) * (1 - ((P_red + 1) / (Pmax + 1))**(1 / gamma_b)) / ( ((P_red + 1) / (Pmax + 1))**(1 / gamma_b) - delta) return (Avo)
#Unburned gas-air mixture speed of sound (m/s): au = equilSoundSpeeds(gas)[0] #Burned Mixture Pi = 101000 #Initial pressure Pa Ti = 300 #Initial unburned gas temperature K gas_b.TP = Ti, Pi #Mass Density of Unburned Gas-Air Mixture (kg/m^3): rho_u = gas_b.density #Unburned gas-air mixture dynamic viscosity (kg/m-s): mu_u = gas_b.viscosity #Suppress the next two lines for unburned data burned = ct.Mixture(mix_phases_b) #Equilibrate the mixture adiabatically at constant P burned.equilibrate('HP', solver='gibbs', max_steps=1000) gamma_b = gas_b.cp / gas_b.cv #Suppress for unburned data #Structure Surface Area (m^2): #Length (m): L = 24.4 #Depth (m): D = 30.5 #Height (m): H = 6.1
def set_in_moles(self, feed_vol): """Function that initializes mole fractions to input feed_vol This function is called at initialization Sets in_moles to a pd.DataFrame containing initial mole fractions Columns for species and rows for different experiments This function also calls update_predicted_dict :param feed_vol: (float) feed volume of mixture (L) """ phases_copy = self._phases.copy() exp_df = self._exp_df.copy() solvent_name = self._aq_solvent_name extractant_name = self._extractant_name diluant_name = self._diluant_name solvent_rho = self._aq_solvent_rho extractant_rho = self._extractant_rho diluant_rho = self._diluant_rho extracted_species_names = self._extracted_species_ion_names extracted_species_list = self._extracted_species_list mixed = ct.Mixture(phases_copy) aq_ind = None solvent_ind = None for ind, phase in enumerate(phases_copy): if solvent_name in phase.species_names: aq_ind = ind solvent_ind = phase.species_names.index(solvent_name) if aq_ind is None: raise Exception('Solvent "{0}" not found \ in xml file'.format(solvent_name)) if aq_ind == 0: org_ind = 1 else: org_ind = 0 self._aq_ind = aq_ind self._org_ind = org_ind extractant_ind = phases_copy[org_ind].species_names.index( extractant_name) diluant_ind = phases_copy[org_ind].species_names.index(diluant_name) extracted_species_ind_list = [ phases_copy[aq_ind].species_names.index(extracted_species_name) for extracted_species_name in extracted_species_names ] extracted_species_charges = np.array([ phases_copy[aq_ind].species(extracted_species_ind).charge for extracted_species_ind in extracted_species_ind_list ]) self._extracted_species_charges = extracted_species_charges mix_aq = mixed.phase(aq_ind) mix_org = mixed.phase(org_ind) solvent_mw = mix_aq.molecular_weights[solvent_ind] # g/mol extractant_mw = mix_org.molecular_weights[extractant_ind] diluant_mw = mix_org.molecular_weights[diluant_ind] if solvent_rho is None: solvent_rho = mix_aq(aq_ind).partial_molar_volumes[ solvent_ind] / solvent_mw * 1e6 # g/L self._aq_solvent_rho = solvent_rho if extractant_rho is None: extractant_rho = mix_org(org_ind).partial_molar_volumes[ extractant_ind] / extractant_mw * 1e6 self._extractant_rho = extractant_rho if diluant_rho is None: diluant_rho = mix_org(org_ind).partial_molar_volumes[ extractant_ind] / extractant_mw * 1e6 self._diluant_rho = diluant_rho in_moles_data = [] aq_phase_solvent_moles = feed_vol * solvent_rho / solvent_mw for index, row in exp_df.iterrows(): h_plus_moles = feed_vol * row['h_i'] hydroxide_ions = 0 extracted_species_moles = np.array([ feed_vol * row['{0}_aq_i'.format(extracted_species)] for extracted_species in extracted_species_list ]) extracted_species_charge_sum = np.sum(extracted_species_charges * extracted_species_moles) chlorine_moles = extracted_species_charge_sum + h_plus_moles extractant_moles = feed_vol * row['z_i'] extractant_vol = extractant_moles * extractant_mw / extractant_rho diluant_vol = feed_vol - extractant_vol diluant_moles = diluant_vol * diluant_rho / diluant_mw complex_moles = np.zeros(len(extracted_species_list)) species_moles_aq = [ aq_phase_solvent_moles, h_plus_moles, hydroxide_ions, chlorine_moles ] species_moles_aq.extend(list(extracted_species_moles)) species_moles_aq.append(self.nacl_molarity * feed_vol) species_moles_aq[3] += self.nacl_molarity * feed_vol species_moles_org = [extractant_moles, diluant_moles] species_moles_org.extend(list(complex_moles)) if aq_ind == 0: species_moles = species_moles_aq + species_moles_org else: species_moles = species_moles_org + species_moles_aq in_moles_data.append(species_moles) self._in_moles = pd.DataFrame(in_moles_data, columns=mixed.species_names) self.update_predicted_dict() return None
def test_invalid_phase_type(self): water = ct.Water() with self.assertRaisesRegex(ct.CanteraError, 'not compatible'): self.mix = ct.Mixture([(self.phase1, 1.0), (water, 2.0)])
""" import cantera as ct import csv # create objects representing the gas phase and the condensed phases. The gas # is a mixture of multiple species, and the condensed phases are all modeled # as incompressible stoichiometric substances. See file KOH.yaml for more # information. phases = ct.import_phases('KOH.yaml', [ 'K_solid', 'K_liquid', 'KOH_a', 'KOH_b', 'KOH_liquid', 'K2O2_solid', 'K2O_solid', 'KO2_solid', 'ice', 'liquid_water', 'KOH_plasma' ]) # create the Mixture object from the list of phases mix = ct.Mixture(phases) equil_data = [] # loop over temperature for n in range(100): t = 350.0 + 50.0 * n print('T = {0}'.format(t)) mix.T = t mix.P = ct.one_atm mix.species_moles = "K:1.03, H2:2.12, O2:0.9" # set the mixture to a state of chemical equilibrium holding # temperature and pressure fixed # mix.equilibrate("TP",maxsteps=10000,loglevel=1) mix.equilibrate("TP", max_steps=10000, log_level=0)
def test_invalid_phase_type(self): water = ct.Water() with self.assertRaises(ct.CanteraError): self.mix = ct.Mixture([(self.phase1, 1.0), (water, 2.0)])
''' import cantera as ct mix = ct.Solution('liquidvapor.cti') #initial_temp,initial_press =[float(val) for val in input().split()] mix.TPX = 300,ct.one_atm,'H2O:1' mix.equilibrate('HP') print(mix.P_sat/ct.one_atm) ''' import cantera as ct liquid = ct.Solution('water.cti', 'liquid_water') solid = ct.Solution('water.cti', 'ice') gas = ct.Solution('h2o2.cti') for T in [280, 400]: gas.TPX = 300, 101325, 'AR:1.0, H2O:0.0' mix = ct.Mixture([(gas, 0.01), (liquid, 0.99), (solid, 0.0)]) mix.T = T mix.P = 101325 mix.equilibrate('TV', solver='gibbs') print(gas['H2O'].X * mix.P) print('T = {}'.format(T)) #mix()
import numpy as np #============================================================================== # set parameters #============================================================================== To = 298.195 # K (reference temperature) R = ct.gas_constant # 8314.47215 Pa*m^3/K/kmol #============================================================================== # load components to phases #============================================================================== s = ct.Solution('data/min-species.xml','solid') g = ct.Solution('data/min-species.xml','gas') #print s.species_names air = ct.Solution('data/air.cti','air') f = ct.Mixture([(s,1),(g,1)]) # preallocate variable nsp = f.n_species #============================================================================== # get standard state properties #============================================================================== # molecular weight Mw_s = s.molecular_weights Mw_g = g.molecular_weights Mw = np.concatenate((Mw_s, Mw_g)) # standard enthalpy of formation Hfo_s = s.standard_enthalpies_RT*To*R Hfo_g = g.standard_enthalpies_RT*To*R Hfo = np.concatenate((Hfo_s, Hfo_g)) ## find important indices
def __init__(self, config_file, prep_capex=0, prep_opex=0, prep_revenue=0, prep_npv=0): """Constructor. """ self.confDict = utilities.read_config(config_file) solventxHome = self.confDict["solventxHome"] reeComps = self.confDict['compositions'] self.xmlData = self.confDict['xmlData'] self.modulesData = self.confDict['modules'] self.xml = os.path.join( solventxHome, self.xmlData['xml'], self.xmlData['phase'] + '_' + ''.join(self.modulesData["input"]) + '.xml') # Set required data self.phase_names = self.confDict["phasenames"] # from xml input file self.phase = ct.import_phases(self.xml, self.phase_names) # Derived and/or reusable system parameters self.column = self.coltypes # Column name self.solv = self.confDict[ "solvents"] # solvent list -.i.e., electrolyte, extractant and organic diluent # ree by modules self.ree = self.modulesData[ "input"] #self.REEs[self.moduleID] # (rare earth) metal list # Cantera indices self.mix = ct.Mixture(self.phase) self.aq = self.mix.phase_index(self.phase_names[0]) self.org = self.mix.phase_index(self.phase_names[1]) self.ns = self.mix.n_species self.naq = self.mix.phase(self.aq).n_species self.norg = self.mix.phase(self.org).n_species self.HA_Index = self.mix.species_index( self.org, '(HA)2(org)') # index of extractant in canera species list self.Hp_Index = self.mix.species_index( self.aq, 'H+') # index of H+ in cantera species list self.Cl_Index = self.mix.species_index( self.aq, 'Cl-') # index of Cl in cantera species list self.canteranames = self.mix.species_names self.fixed_species = ['H2O(L)', 'OH-', 'Cl-', 'dodecane'] self.canteravars = [ ij for ij in self.canteranames if ij not in self.fixed_species ] # 'Cl-', self.nsy = len(self.canteravars) self.naqy = len([ ij for ij in self.mix.species_names[:self.naq] if ij not in self.fixed_species ]) self.norgy = len([ ij for ij in self.mix.species_names[self.naq:] if ij not in self.fixed_species ]) self.mwre,\ self.mwslv = self.get_mw() # g/mol self.rhoslv = [1000, 960, 750] # [g/L] self.upper = [reeComps[i]['upper'] for i in self.ree] self.lower = [reeComps[i]['lower'] for i in self.ree] ree_mass = [ np.random.uniform(i, j) for i, j in zip(self.lower, self.upper) ] self.get_conc(ree_mass) self.purity_spec = .99 # not needed? self.recov_spec = .99 # not needed? self.revenue = [0, 0, 0] self.Ns = [0, 0, 0] self.nsp = pd.DataFrame() # feed streams (aq and org) for each column self.nsp0 = pd.DataFrame() # feed streams (aq and org) for each column self.y = {} # all compositions self.Ns = {}
# phases # complete_species = [species[S] for S in ('CH4','O2','N2','CO2','H2O')] # gas = ct.Solution(thermo='IdealGas', species=complete_species) gas = ct.Solution('r_creck_52.cti') carbon = ct.Solution('graphite.xml') # the phases that will be included in the calculation, and their initial moles mix_phases = [(gas, 1.0), (carbon, 0.0)] # gaseous fuel species fuel_species = 'CH4' ############################################################################## mix = ct.Mixture(mix_phases) # create some arrays to hold the data phi = 0.7 # find fuel, nitrogen, and oxygen indices ifuel = gas.species_index(fuel_species) io2 = gas.species_index('O2') in2 = gas.species_index('N2') stoich_O2 = gas.n_atoms(fuel_species, 'C') + 0.25 * gas.n_atoms(fuel_species, 'H') X = np.zeros(gas.n_species) X[ifuel] = phi X[io2] = stoich_O2
def test_invalid_phase_type(self): water = ct.Water() with self.assertRaises(Exception): self.mix = ct.Mixture([(self.phase1, 1.0), (water, 2.0)])