def conversion(self, corriente, T): """Calculate reaction conversion corriente: Corriente instance for reaction T: Temperature of reaction""" if self.tipo == 0: # Material balance without equilibrium or kinetics considerations alfa = self.kwargs["conversion"] elif self.tipo == 1: # Chemical equilibrium without kinetics if isinstance(self.keq, list): A, B, C, D, E, F, G, H = self.keq keq = exp(A + B / T + C * log(T) + D * T + E * T**2 + F * T**3 + G * T**4 + H * T**5) else: keq = self.keq def f(alfa): conc_out = [ (corriente.caudalunitariomolar[i] + alfa * self.coef[i]) / corriente.Q.m3h for i in range(len(self.componentes)) ] productorio = 1 for i in range(len(self.componentes)): productorio *= conc_out[i]**self.coef[i] return keq - productorio alfa = fsolve(f, 0.5) print(alfa, f(alfa)) avance = alfa * self.coef[self.base] * corriente.caudalunitariomolar[ self.base] Q_out = [ corriente.caudalunitariomolar[i] + avance * self.coef[i] / self.coef[self.base] for i in range(len(self.componentes)) ] minimo = min(Q_out) if minimo < 0: # The key component is not correct, redo the result indice = Q_out.index(minimo) avance = self.coef[indice] * corriente.caudalunitariomolar[indice] Q_out = [ corriente.caudalunitariomolar[i] + avance * self.coef[i] / self.coef[indice] for i in range(len(self.componentes)) ] h = unidades.Power( self.Hr * self.coef[self.base] / self.coef[indice] * avance, "Jh") else: h = unidades.Power(self.Hr * avance, "Jh") print(alfa, avance) caudal = sum(Q_out) fraccion = [caudal_i / caudal for caudal_i in Q_out] return fraccion, h
def calculo(self): self.entrada = self.kwargs.get("entrada", None) self.thermal = self.kwargs.get("thermal", 0) #TODO: implementar para más de una reacción self.reaccion = self.kwargs.get("reaccion", 0)[0] # P=self.kwargs.get("P", 0) # if P: # self.entrada=Corriente(self.entrada.T, P, self.entrada.caudalmasico.kgh, self.entrada.mezcla, self.entrada.solido) T = self.kwargs.get("T", 0) if T: self.T = unidades.Temperature(T) else: self.T = self.entrada.T self.Q = unidades.Power(self.kwargs.get("Q", 0)) self.Text = self.kwargs.get("Text", 0) self.U = unidades.HeatTransfCoef(self.kwargs.get("U", 0)) if self.thermal in [0, 2]: def f(T): fracciones, h = self.reaccion.conversion(self.entrada, T) corriente = Corriente(T, self.entrada.P.atm, self.entrada.caudalmasico.kgh, Mezcla(self.entrada.ids, fracciones), self.entrada.solido) return corriente.h - self.Q - self.entrada.h - h T = fsolve(f, self.entrada.T) fracciones, h = self.reaccion.conversion(self.entrada, T) elif self.thermal == 1: T = self.T fracciones, h = self.reaccion.conversion(self.entrada, T) elif self.thermal == 3: pass print(fracciones) self.Salida = Corriente(T=T, P=self.entrada.P, caudalMasico=self.entrada.caudalmasico, fraccionMolar=fracciones, solido=self.entrada.solido) self.Heat = unidades.Power(self.Salida.h - self.entrada.h - h)
def readStatefromJSON(self, state): """Load instance parameter from saved file""" self.L = unidades.Length(state["L"]) self.rho = unidades.Density(state["rho"]) self.mu = unidades.Viscosity(state["mu"]) self.material = state["material"] self.Dn = state["Dn"] self.rugosidad = unidades.Length(state["rugosidad"]) self.De = unidades.Length(state["De"]) self.w = unidades.Length(state["w"]) self.Di = unidades.Length(state["Di"]) self.eD = unidades.Dimensionless(state["eD"]) self.seccion = unidades.Area(state["seccion"]) self.A = unidades.Area(state["A"]) self.V = unidades.Speed(state["V"]) self.Re = unidades.Dimensionless(state["Re"]) self.K = unidades.Dimensionless(state["K"]) self.DeltaP_h = unidades.DeltaP(state["DeltaP_h"]) self.DeltaP_ac = unidades.DeltaP(state["DeltaP_ac"]) self.f = unidades.Dimensionless(state["f"]) self.DeltaP_f = unidades.DeltaP(state["DeltaP_f"]) self.DeltaP_v = unidades.DeltaP(state["DeltaP_v"]) self.DeltaP = unidades.DeltaP(state["DeltaP"]) self.DeltaP_100ft = unidades.Dimensionless(state["DeltaP_100ft"]) self.Tout = unidades.Temperature(state["Tout"]) self.Heat = unidades.Power(state["Heat"]) self.Pin = unidades.Pressure(state["Pin"]) self.Pout = unidades.Pressure(state["Pout"]) self.statusCoste = state["statusCoste"] if self.statusCoste: self.C_adq = unidades.Currency(state["C_adq"]) self.C_inst = unidades.Currency(state["C_inst"]) self.salida = [None]
def calculo(self): self.entrada = self.kwargs["entrada"] self.L = unidades.Length(self.kwargs["l"]) if self.entrada.x == 0: self.rho = self.entrada.Liquido.rho self.mu = self.entrada.Liquido.mu else: self.rho = self.entrada.Gas.rho self.mu = self.entrada.Gas.mu self.material = self.kwargs["material"][0] + " " + self.kwargs[ "material"][1] self.Dn = self.kwargs["material"][3] self.rugosidad = unidades.Length(self.kwargs["material"][2], "mm") self.De = unidades.Length(self.kwargs["material"][6], "mm") self.w = unidades.Length(self.kwargs["material"][5], "mm") self.Di = unidades.Length((self.De - 2 * self.w)) self.eD = unidades.Dimensionless(self.rugosidad / self.Di) self.seccion = unidades.Area(pi / 4 * self.Di**2) self.A = unidades.Area(pi * self.De * self.L) self.V = unidades.Speed(self.entrada.Q / self.seccion) self.Re = Re(self.Di, self.V, self.rho, self.mu) K = 0 for accesorio in self.kwargs["accesorios"]: K += accesorio[2] * accesorio[3] self.K = unidades.Dimensionless(K) self.DeltaP_h = unidades.Pressure(g * self.kwargs["h"] * self.rho) self.DeltaP_ac = unidades.Pressure(self.K * self.V**2 / 2 * self.rho) self.f = f_friccion(self.Re, self.eD) self.DeltaP_f = self.__DeltaP_friccion() #TODO: self.DeltaP_v = unidades.Pressure(0) self.DeltaP = unidades.Pressure(self.DeltaP_f + self.DeltaP_ac + self.DeltaP_h) self.DeltaP_100ft = self.DeltaP * 100 / self.L.ft self.Pout = unidades.Pressure(self.entrada.P - self.DeltaP) if self.kwargs["thermal"] == 0: self.Tout = self.entrada.T self.Heat = unidades.Power(0) else: cambiador = Heat_Exchanger() cambiador.calculo(entrada=self.entrada, modo=self.kwargs["thermal"], Heat=self.kwargs["Q"], deltaP=self.DeltaP, A=self.A, U=self.kwargs["U"], Text=self.kwargs["Text"]) self.Tout = cambiador.salida[0].T self.Heat = cambiador.Heat self.salida = [self.entrada.clone(T=self.Tout, P=self.Pout)] self.Pin = self.entrada.P self.Pout = self.salida[0].P
def calculo(self): self.entrada = self.kwargs["entrada"] self.LKsplit = unidades.Dimensionless(self.kwargs["LKsplit"]) self.HKsplit = unidades.Dimensionless(self.kwargs["HKsplit"]) self.RCalculada = unidades.Dimensionless(self.kwargs["R"]) self.R_Rmin = unidades.Dimensionless(self.kwargs["R_Rmin"]) if self.kwargs["Pd"]: self.Pd = unidades.Pressure(self.kwargs["Pd"]) else: self.Pd = self.entrada.P self.DeltaP = unidades.Pressure(self.kwargs["DeltaP"]) #Estimate splits of components b = [] d = [] for i, caudal_i in enumerate(self.entrada.caudalunitariomolar): if i == self.kwargs["LK"]: b.append(caudal_i * (1 - self.LKsplit)) d.append(caudal_i * self.LKsplit) elif i == self.kwargs["HK"]: d.append(caudal_i * (1 - self.HKsplit)) b.append(caudal_i * self.HKsplit) elif self.entrada.eos.Ki[i] > self.entrada.eos.Ki[ self.kwargs["LK"]]: b.append(0) d.append(caudal_i) elif self.entrada.eos.Ki[i] < self.entrada.eos.Ki[ self.kwargs["HK"]]: d.append(0) b.append(caudal_i) else: d.append(caudal_i * 0.5) b.append(caudal_i * 0.5) while True: bo = b do = d xt = [Q / sum(d) for Q in d] xb = [Q / sum(b) for Q in b] Qt = sum( [di * comp.M for di, comp in zip(d, self.entrada.componente)]) Qb = sum( [bi * comp.M for bi, comp in zip(b, self.entrada.componente)]) destilado = Corriente(T=self.entrada.T, P=self.Pd, caudalMasico=Qt, fraccionMolar=xt) residuo = Corriente(T=self.entrada.T, P=self.Pd, caudalMasico=Qb, fraccionMolar=xb) #TODO: Add algorithm to calculate Pd and condenser type fig 12.4 pag 230 #Fenske equation for Nmin alfam = (destilado.eos.Ki[self.kwargs["LK"]] / destilado.eos.Ki[self.kwargs["HK"]] * residuo.eos.Ki[self.kwargs["LK"]] / residuo.eos.Ki[self.kwargs["HK"]])**0.5 Nmin = log10( destilado.caudalunitariomolar[self.kwargs["LK"]] / destilado.caudalunitariomolar[self.kwargs["HK"]] * residuo.caudalunitariomolar[self.kwargs["HK"]] / residuo.caudalunitariomolar[self.kwargs["LK"]]) / log10(alfam) #Evaluación composición salidas b = [] d = [] for i in range(len(self.entrada.ids)): if i in [self.kwargs["LK"], self.kwargs["HK"]]: b.append(bo[i]) d.append(do[i]) else: alfa = (destilado.eos.Ki[i] / destilado.eos.Ki[self.kwargs["HK"]] * residuo.eos.Ki[i] / residuo.eos.Ki[self.kwargs["HK"]])**0.5 b.append(self.entrada.caudalunitariomolar[i] / (1 + do[self.kwargs["HK"]] / bo[self.kwargs["HK"]] * alfa**Nmin)) d.append(self.entrada.caudalunitariomolar[i] * do[self.kwargs["HK"]] / bo[self.kwargs["HK"]] * alfa**Nmin / (1 + do[self.kwargs["HK"]] / bo[self.kwargs["HK"]] * alfa**Nmin)) res = sum([ abs(inicial - final) for inicial, final in zip(bo, b) ]) + sum([abs(inicial - final) for inicial, final in zip(do, d)]) if res < 1e-10: self.Nmin = Nmin - self.kwargs["condenser"] + 1 break #Calculo de la razón de reflujo mínima, ecuación de Underwood alfa = self.entrada.eos.Ki[self.kwargs["LK"]] / self.entrada.eos.Ki[ self.kwargs["HK"]] self.Rmin = unidades.Dimensionless( abs( float(destilado.caudalmolar / self.entrada.caudalmolar * (destilado.fraccion[self.kwargs["LK"]] / self.entrada.Liquido.fraccion[self.kwargs["LK"]] - alfa * destilado.fraccion[self.kwargs["HK"]] / self.entrada.Liquido.fraccion[self.kwargs["HK"]]) / (alfa - 1)))) #Cálculo del número de etapas reales, ecuación de Gilliland if self.R_Rmin and not self.RCalculada: self.RCalculada = unidades.Dimensionless(self.R_Rmin * self.Rmin) X = (self.RCalculada - self.Rmin) / (self.RCalculada + 1) Y = 1 - exp((1 + 54.4 * X) / (11 + 117.2 * X) * (X - 1) / X**0.5) self.NTray = unidades.Dimensionless((Y + self.Nmin) / (1 - Y) - 1 - self.kwargs["condenser"]) #Cálculo del piso de la alimentación if self.kwargs["feed"]: #Ec. de Fenske alfa_b = residuo.eos.Ki[self.kwargs["LK"]] / residuo.eos.Ki[ self.kwargs["HK"]] alfa_d = destilado.eos.Ki[self.kwargs["LK"]] / destilado.eos.Ki[ self.kwargs["HK"]] alfa_f = self.entrada.eos.Ki[ self.kwargs["LK"]] / self.entrada.eos.Ki[self.kwargs["HK"]] ratio = log(destilado.fraccion[self.kwargs["LK"]] / self.entrada.fraccion[self.kwargs["LK"]] * self.entrada.fraccion[self.kwargs["HK"]] / destilado.fraccion[self.kwargs["HK"]]) / log( self.entrada.fraccion[self.kwargs["LK"]] / residuo.fraccion[self.kwargs["LK"]] * residuo.fraccion[self.kwargs["HK"]] / self.entrada.fraccion[self.kwargs["HK"]]) * log( (alfa_b * alfa_f)**0.5) / log( (alfa_d * alfa_f)**0.5) else: #Ec. de Kirkbride ratio = (self.entrada.fraccion[self.kwargs["HK"]] / self.entrada.fraccion[self.kwargs["LK"]] * residuo.fraccion[self.kwargs["LK"]]**2 / destilado.fraccion[self.kwargs["HK"]]**2 * residuo.caudalmolar / destilado.caudalmolar)**0.206 self.Ns = self.NTray / (ratio + 1) self.Nr = self.NTray - self.Ns self.N_feed = unidades.Dimensionless(self.Ns + 1) if self.kwargs["condenser"]: #Parcial Tout = destilado.eos._Dew_T() else: Tout = destilado.eos._Bubble_T() Tin = destilado.eos._Dew_T() SalidaDestilado = destilado.clone(T=Tout) #FIXME: o el ejemplo está mal planteado o este valor es ilógico ToutReboiler = residuo.eos._Bubble_T() ToutReboiler2 = residuo.eos._Dew_T() print((ToutReboiler, ToutReboiler2, Tin, Tout)) SalidaResiduo = residuo.clone(T=ToutReboiler) self.salida = [SalidaDestilado, SalidaResiduo] inCondenser = destilado.clone(T=Tin, P=self.entrada.P, split=self.RCalculada + 1) outCondenser = destilado.clone(T=Tout, P=self.entrada.P, split=self.RCalculada + 1) self.DutyCondenser = unidades.Power(outCondenser.h - inCondenser.h) self.DutyReboiler = unidades.Power(SalidaDestilado.h + SalidaResiduo.h - self.DutyCondenser - self.entrada.h) self.DestiladoT = SalidaDestilado.T self.DestiladoP = SalidaDestilado.P self.DestiladoMassFlow = SalidaDestilado.caudalmasico self.DestiladoMolarComposition = SalidaDestilado.fraccion self.ResiduoT = SalidaResiduo.T self.ResiduoP = SalidaResiduo.P self.ResiduoMassFlow = SalidaResiduo.caudalmasico self.ResiduoMolarComposition = SalidaResiduo.fraccion self.LKName = self.salida[0].componente[self.kwargs["LK"]].nombre self.HKName = self.salida[0].componente[self.kwargs["HK"]].nombre