def compressor_inlet_state_reci(enthalpy, pressure, fluid): # return isentropic coefficient and specific volume for fluid at enthalpy # and pressure from CoolProp phase = CP.PhaseSI('P', pressure, 'H', enthalpy, fluid) if phase == 'gas': v_suc = 1 / CP.PropsSI('D', 'H', enthalpy, 'P', pressure, fluid) gamma_calc = CP.PropsSI('ISENTROPIC_EXPANSION_COEFFICIENT', 'H', enthalpy, 'P', pressure, fluid) else: # if enthalpy below saturated vapor enthalpy at pressure, assume # saturated state v_suc = 1 / CP.PropsSI('D', 'P', pressure, 'Q', 1, fluid) gamma_calc = CP.PropsSI('ISENTROPIC_EXPANSION_COEFFICIENT', 'P', pressure, 'Q', 1, fluid) # print('Warning: Values set to saturation (compressor inlet state reci)') return [v_suc, gamma_calc]
def compressor_inlet_state(temperature, pressure, fluid): # return isentropic coefficient ad specific volume for fluid at temperature # and pressure from CoolProp phase = CP.PhaseSI('P', pressure, 'T', temperature, fluid) if phase == 'gas': v_suc = 1 / CP.PropsSI('D', 'T', temperature, 'P', pressure, fluid) gamma_calc = CP.PropsSI('ISENTROPIC_EXPANSION_COEFFICIENT', 'T', temperature, 'P', pressure, fluid) else: #if temperature below saturation temperature at pressure, assume # saturated state v_suc = 1 / CP.PropsSI('D', 'P', pressure, 'Q', 1, fluid) gamma_calc = CP.PropsSI('ISENTROPIC_EXPANSION_COEFFICIENT', 'P', pressure, 'Q', 1, fluid) # print('Warning: Values set to saturation (compressor inlet state)') return [v_suc, gamma_calc]
def makeColdStream(self, Q): # Flow rate for evaporator is specified by inlet and outlet temperature... T_in, T_out = 12, 7 cp = CP.PropsSI('C', 'T', C2K(T_in), 'Q', 0, 'water') #print "cp is ",cp dh = cp * (T_out - T_in) m = -Q / dh return HRHX_integral_model.streamExample1(T_in, m, cp)
def fait_isolignes(type, valeurs, position=None, nb_points=1000, to_show=None, round_nb=0): """ S'occupe du calcul et du tracé des isolignes. """ if not(to_show): # Valeurs par défauts: to_show = list(range(len(valeurs))) # toutes ! Tmin, Tmax = plt.ylim() # On regarde les smin, smax = plt.xlim() # limites du graphique # Par défaut, l'échantillonnage en T est linéaire val_T = np.linspace(Tmin, Tmax, nb_points) # Pour chacune des valeurs demandées, nb_points_save = nb_points for val, i in zip(valeurs, range(len(valeurs))): nb_points = nb_points_save if type == 'V': # Cas particulier des volumes massiques: D = 1/v val_s = CP.PropsSI('S', 'T', val_T, 'D', 1 / val, fluide) # et non en P elif type == 'H': val_s = np.linspace(smin, smax, nb_points) val_T = [] for s in val_s: try: val_T.append(CP.PropsSI('T', 'S', s, type, val, fluide)) except: val_T.append(float("Nan")) val_T = np.array(val_T) val_s = val_s[val_T == val_T] val_T = val_T[val_T == val_T] nb_points = len(val_T) print(nb_points, "points valides sur l'isenthalpique") if nb_points < 10: continue else: # Sinon, on utilise l'éventail des températures val_s = CP.PropsSI('S', 'T', val_T, type, val, fluide) if type == 'H': val /= 1e3 # Pour mettre en kJ/kg if type == 'P': val /= 1e5 # Pour mettre en bar if round_nb > 0: val = str(round(val, round_nb)) # Pour faire joli else: val = str(int(round(val))) # là aussi... label = '${}={}$ {}'.format(LABEL[type], val, UNITS[type]) if nb_points > 10: plt.plot(val_s, val_T, color=COLOR_MAP[ type]) # Affichage courbe if i in to_show: # Ainsi que du label s'il fait partie de la liste place_label(val_s, val_T, label, int(position * nb_points))
def test_entalpia_vapor(self): temperatura = 500 entalpia_mezcla_vapor = self.paquete.entalpia_vapor( composicion=self.composicion, temperatura=temperatura) entalpia_mezcla_vapor_cp = CP.PropsSI('Hmolar', 'P', 101325, 'T', temperatura, self.compuestos_CP) assert error_relativo(entalpia_mezcla_vapor, entalpia_mezcla_vapor_cp)
def mixingData(mixture): mixingData = [] for component in mixture: fluid = component["fluid"] y = component["molefraction"] Pc = CP.PropsSI("Pcrit", fluid) Tc = CP.PropsSI("Tcrit", fluid) omega = CP.PropsSI("acentric", fluid) component_data = { "fluid": fluid, "y": y, "Pc": Pc, "Tc": Tc, "omega": omega } mixingData.append(component_data) return mixingData
def deriveVaporQuality(self, totalMass, totalEnergy, temperature): if options.enableTankTemperatureInterpolation: liquidSpecificInternalEnergy = liquidInternalEnergyInterpolator( temperature) gasSpecificInternalEnergy = gasInternalEnergyInterpolator( temperature) else: liquidSpecificInternalEnergy = CP.PropsSI('U', 'T', temperature, 'Q', 0, 'N2O') gasSpecificInternalEnergy = CP.PropsSI('U', 'T', temperature, 'Q', 1, 'N2O') x = (totalEnergy / totalMass - liquidSpecificInternalEnergy) / ( gasSpecificInternalEnergy - liquidSpecificInternalEnergy) return x
def tq_diagram_con(states, hx, fluid_ext, mdot_ext, T_ext_in, T_ext_out): """ plot TQ Diagram""" #ext side T_ext = np.linspace(T_ext_in, T_ext_out, 1000) cp = hx.cp Q_ext = mdot_ext * cp * (T_ext - T_ext_in) #R134a side T_2 = states[1].t T_3 = states[2].t P2 = states[1].p P3 = states[2].p Pr = np.linspace(P2, P3, 1000) h2 = states[1].h h3 = states[2].h hr = np.linspace(h2, h3, 1000) mdot_rr = mdot_ext * cp * (T_ext_out - T_ext_in) / (h2 - h3) Tr = CP.PropsSI('T', 'P', Pr, 'H', hr, fluid) Sr = CP.PropsSI('S', 'P', Pr, 'H', hr, fluid) sdt = 0 for i in range(len(hr) - 1): sdt += mdot_rr * (hr[i + 1] - hr[i]) / Tr[i + 1] + ( Q_ext[i + 1] - Q_ext[i]) / T_ext[i + 1] i += 1 loss_dt = sdt * T0 Qr = mdot_rr * (hr - h3) s_ext_out = CP.PropsSI('S', 'T', T_ext_out, 'P', 200000, fluid_ext) s_ext_in = CP.PropsSI('S', 'T', T_ext_in, 'P', 200000, fluid_ext) loss_tt = -mdot_rr * (states[2].h - states[1].h - T0 * (states[2].s - states[1].s)) - mdot_ext * ( cp * (T_ext_out - T_ext_in) - T0 * (s_ext_out - s_ext_in)) loss_dp = loss_tt - loss_dt plt.plot(Q_ext, T_ext) plt.plot(Qr, Tr) plt.xlabel('Q/(J/s)') plt.ylabel('T/K') plt.ylim(310, 360) plt.show() return loss_dt, loss_tt
def __init__(self, Tsh_max, Tsh_min, Psh_min, Psh_max, nT, nP, fluid): self.nP = nP self.nT = nT self.T_vec = np.linspace(Tsh_min, Tsh_max, nT) self.P_vec = np.geomspace(Psh_min, Psh_max, nP) self.fluid = fluid self.Pcrit = CP.PropsSI("PCRIT", fluid) self.CalcProperties() self.SetSubTables()
def specific_heat_cp(self, T, P): """Calculate mass specific constant pressure specific heat. :param <int> T: Temperature [K] :param <int> P: Pressure [Pa] :return <int> CP: Specific heat constant pressure [J/kg/K] """ return CP.PropsSI('C', 'T', T, 'P', P, self.name)
def energy_simulate(self, state, fluid_eva, mdot_r, T_eva_in, T_eva_out): state[self.inletstate].xx = True #pressure loss and heat exchange parameters self.dp = state[self.inletstate].p - state[self.outletstate].p self.qc = state[self.outletstate].h - state[self.inletstate].h self.cp = CP.PropsSI('C', 'T', T_eva_in, 'P', 101500, fluid_eva) self.mdot_eva = (mdot_r * self.qc) / (self.cp * (T_eva_in - T_eva_out))
def simulate(self, state, mdot_w, Tw_in, Tw_out): #ideal state[self.outletstate].x = 0.0 dp = 200000 state[self.outletstate].p = state[self.inletstate].p - dp state[self.outletstate].cal() self.cp_w = CP.PropsSI('C', 'T', Tw_in, 'P', 100000, 'water') self.qh = state[self.inletstate].h - state[self.outletstate].h self.epsilon = mdot_w * self.cp_w * (Tw_out - Tw_in) / (self.qh * mdot_r) ds = CP.PropsSI('S', 'T', Tw_out, 'P', 100000, 'water') - CP.PropsSI( 'S', 'T', Tw_in, 'P', 100000, 'water') self.loss = -mdot_r*((state[self.outletstate].h-state[self.inletstate].h)\ -T0*(state[self.outletstate].s-state[self.inletstate].s))\ -mdot_w*(self.cp_w*(Tw_out-Tw_in)-T0*(ds))
def test_presion_vapor(self): temperatura = 300 temperatura_numpy = np.array([300, 350, 400]) presion_vapor = self.paquete.presion_vapor(temperatura) presion_vapor_numpy = self.paquete.presion_vapor(temperatura_numpy) for j in range(len(self.compuestos)): for i in range(temperatura_numpy.size): presion_cp = CP.PropsSI('P', 'T', temperatura_numpy[i], 'Q', 0, self.compuestos[j].nombre) error_relativo = np.abs( (presion_vapor_numpy[i, j] - presion_cp) / presion_cp) assert error_relativo <= 1 for presion, compuesto in zip(presion_vapor, self.compuestos): presion_cp = CP.PropsSI('P', 'T', temperatura, 'Q', 0, compuesto.nombre) error_rel = abs((presion - presion_cp) / presion_cp) assert error_rel <= 1
def test_temperatura_rocio_1d(self): """Prueba el calculod de temperatura de rocio""" presion = 101325 temperatura_rocio = self.paquete.temperatura_rocio(self.composicion, presion=presion) temperatura_rocio_cp = CP.PropsSI( 'T', 'P', presion, 'Q', 1, parse_components(self.compuestos, self.composicion)) assert error_relativo(temperatura_rocio, temperatura_rocio_cp)
def gap_function(C4R_guess, C4T, M, V, D): # function to caluclate total mass flow at exit of gap for a guessed value of C4R C4 = np.sqrt(C4R_guess * C4R_guess + C4T * C4T) h4t = V.h3t h4 = h4t - 1. / 2. * C4 * C4 s4 = D.S0 # assume an isentropic process if M.gasModel == 'Ideal': T4 = h4 / D.Cp # S = Cp * log (T/D.Tref) - R log(P/D.Pref) # definition of enthalpy P4 = np.exp((D.Cp * np.log(T4 / D.Tref) - s4) / D.R) * D.Pref rho4 = P4 / (D.R * T4) else: T4 = CP.PropsSI('T', 'HMASS', h4, 'S', s4, D.fluidType) rho4 = CP.PropsSI('D', 'HMASS', h4, 'S', s4, D.fluidType) mdot4 = C4R_guess * rho4 * D.A4 return mdot4
def test_temperatura_burbuja_1d(self): """Prueba de la temperatura de burbuja usando un array de 1d""" presion = 101325 temperatura_burbuja = self.paquete.temperatura_burbuja( self.composicion, presion=presion) temperatura_burbuja_cp = CP.PropsSI( 'T', 'P', presion, 'Q', 0, parse_components(self.compuestos, self.composicion)) assert error_relativo(temperatura_burbuja, temperatura_burbuja_cp)
def tq_diagram_eva(states, hx, fluid_ext, mdot_rr, T_ext_in, T_ext_out): """ plot TQ Diagram""" #R134a side T_1 = states[0].t T_4 = states[3].t P1 = states[0].p P4 = states[3].p Pr = np.linspace(P4, P1, 1000) h1 = states[0].h h4 = states[3].h hr = np.linspace(h4, h1, 1000) #ext side T_ext = np.linspace(T_ext_in, T_ext_out, 1000) cp = hx.cp mdot_ext = mdot_rr * (h1 - h4) / (cp * (T_ext_in - T_ext_out)) Q_ext = mdot_ext * cp * (T_ext - T_ext_out) Tr = CP.PropsSI('T', 'P', Pr, 'H', hr, fluid) Sr = CP.PropsSI('S', 'P', Pr, 'H', hr, fluid) sdt = 0 for i in range(len(hr) - 1): sdt += mdot_rr * (hr[i + 1] - hr[i]) / Tr[i + 1] + ( Q_ext[i + 1] - Q_ext[i]) / T_ext[i + 1] i += 1 loss_dt = sdt * T0 Qr = mdot_rr * (hr - h4) loss_tt = -mdot_rr*((states[0].h-states[3].h)-T0*(states[0].s-states[3].s))\ -mdot_ext*(cp*(T_ext_out-T_ext_in)-T0*(cp*np.log(T_ext_out/T_ext_in))) loss_dp = loss_tt - loss_dt plt.plot(Q_ext, T_ext) plt.plot(Qr, Tr) plt.xlabel('Q/(J/s)') plt.ylabel('T/K') # plt.ylim(310, 360) plt.show() return loss_dt, loss_dp
def test_entalpia_vapor_puro(self): # Prueba usando un scalar temperatura = 500 entalpia_vapor = self.paquete.entalpia_vapor_puro(temperatura) for j in range(self.numero_compuestos): entalpia_vapor_cp = CP.PropsSI('Hmolar', 'P', 101325, 'T', temperatura, self.compuestos[j].nombre) assert error_relativo(entalpia_vapor[j], entalpia_vapor_cp) # Prueba usando un array temperaturas = np.array((400, 425, 450)) entalpias_vapor = self.paquete.entalpia_vapor_puro(temperaturas) for j in range(len(self.compuestos)): for i in range(temperaturas.size): entalpia_vapor_cp = CP.PropsSI('Hmolar', 'P', 101325, 'T', temperaturas[i], self.compuestos[j].nombre) assert error_relativo(entalpias_vapor[i, j], entalpia_vapor_cp)
def test_temperatura_rocio_2d(self): presiones = np.array([101325, 200000, 300000, 500000]) temperaturas_rocio_2d = self.paquete.temperatura_rocio( self.composicion_2d, presion=presiones) for i in range(len(presiones)): temperatura_rocio_cp = CP.PropsSI( 'T', 'P', presiones[i], 'Q', 1, parse_components(self.compuestos, self.composicion_2d[i])) assert error_relativo(temperaturas_rocio_2d[i], temperatura_rocio_cp)
def temperature(self, D, P): """Calculate temperature. :param <float> D: Density [K] :param <float> P: Pressure [Pa] :return <float> T: Temperature [K] """ return CP.PropsSI('T', 'D', D, 'P', P, self.name)
def entropy(self, T, P): """Calculate mass specific entropy. :param <int> T: Temperature [K] :param <int> P: Pressure [Pa] :return <int> S: Mass specific entropy [J/kg] """ return CP.PropsSI('S', 'T', T, 'P', P, self.name)
def internal_energy(self, T, P): """Calculate internal energy. :param <int> T: Temperature [K] :param <int> P: Pressure [Pa] :return <int> U: Mass specific internal energy [J/kg] """ return CP.PropsSI('U', 'T', T, 'P', P, self.name)
def molar_mass(self, T, P): """Calculate molar mass. :param <int> T: Temperature [K] :param <int> P: Pressure [Pa] :return <int> M: Molar Mass [kg/mol] """ return CP.PropsSI('M', 'T', T, 'P', P, self.name)
def pressure(self, D, T): """Calculate pressure. :param <int> D: Density [kg/m^3] :param <int> T: Temperature [K] :return <int> P: Pressure [Pa] """ return CP.PropsSI('P', 'D', D, 'T', T, self.name)
def viscosity(self, T, P): """Calculate viscosity. :param <int> T: Temperature [K] :param <int> P: Pressure [Pa] :return <int> V: Viscosity [Pa s] """ return CP.PropsSI('V', 'T', T, 'P', P, self.name)
def thermal_conductivity(self, T, P): """Calculate thermal conductivity. :param <float> T: Temperature [K] :param <float> P: Pressure [Pa] :return <float> K: Thermal conductivity [W/m/K] """ return CP.PropsSI('CONDUCTIVITY', 'T', T, 'P', P, self.name)
def density(self, T, P): """Calculate mass density. :param <int> T: Temperature [K] :param <int> P: Pressure [Pa] :return <float> D: Mass density [kg/m^3] """ return CP.PropsSI('D', 'T', T, 'P', P, self.name)
def speed_of_sound(self, T, P): """Calculate the speed of sound. :param <int> T: Temperature [K] :param <int> P: Pressure [Pa] :return <float> A: Speed of Sound [m/s] """ return CP.PropsSI('A', 'T', T, 'P', P, self.name)
def calc_lhv(self): r""" Calculate the lower heating value of the combustion chambers fuel. Returns ------- val : float Lower heating value of the combustion chambers fuel. .. math:: LHV = \sum_{fuels} \left(-\frac{\sum_i {\Delta H_f^0}_i - \sum_j {\Delta H_f^0}_j } {M_{fuel}} \cdot x_{fuel} \right)\\ \forall i \in \text{reation products},\\ \forall j \in \text{reation educts},\\ \forall fuel \in \text{fuels},\\ \Delta H_f^0: \text{molar formation enthalpy},\\ x_{fuel}: \text{mass fraction of fuel in fuel mixture} """ hf = {} hf['hydrogen'] = 0 hf['methane'] = -74.85 hf['ethane'] = -84.68 hf['propane'] = -103.8 hf['butane'] = -124.51 hf['O2'] = 0 hf['CO2'] = -393.5 # water (gaseous) hf['H2O'] = -241.8 lhv = 0 for f, x in self.fuel.val.items(): molar_masses[f] = CP.PropsSI('M', f) fl = set(list(hf.keys())).intersection( set([a.replace(' ', '') for a in CP.get_aliases(f)])) if len(fl) == 0: continue if list(fl)[0] in self.fuels(): structure = fluid_structure(f) n = {} for el in ['C', 'H', 'O']: if el in structure.keys(): n[el] = structure[el] else: n[el] = 0 lhv += (-(n['H'] / 2 * hf['H2O'] + n['C'] * hf['CO2'] - ((n['C'] + n['H'] / 4) * hf['O2'] + hf[list(fl)[0]])) / molar_masses[f] * 1000) * x return lhv
def tq_diagram(states,hx): """ plot TQ Diagram""" #water side Tw = np.linspace(Tw_in,Tw_out,1000) cp_w = 4200 Qw = mdot_w*cp_w*(Tw-Tw_in) #R134a side T_2 = states[1].t T_3 = states[2].t P2 = states[1].p P3 = states[2].p Pr = np.linspace(P2,P3,1000) h2 = states[1].h h3 = states[2].h hr = np.linspace(h2,h3,1000) mdot_rr = mdot_w*cp_w*(Tw_out-Tw_in)/(h2-h3) Tr = CP.PropsSI('T','P',Pr,'H',hr,fluid) Sr = CP.PropsSI('S','P',Pr,'H',hr,fluid) sdt = 0 for i in range(len(hr)-1): sdt += mdot_rr*(hr[i+1]-hr[i])/Tr[i+1] +(Qw[i+1]-Qw[i])/Tw[i+1] i +=1 Qr = mdot_rr*(hr-h3) loss_dt = sdt*T0 sw_out = CP.PropsSI('S','T',Tw_out,'P',200000,'water') sw_in = CP.PropsSI('S','T',Tw_in,'P',200000,'water') loss_tt = -mdot_rr*(states[2].h-states[1].h-T0*(states[2].s-states[1].s))-mdot_w*(cp_w*(Tw_out-Tw_in)-T0*(sw_out-sw_in)) plt.plot(Qw,Tw) plt.plot(Qr,Tr) plt.xlabel('Q/(J/s)') plt.ylabel('T/K') ylim(310, 360) plt.show() return loss_dt,loss_tt