def calculo(self): ind1 = self.Comp1.currentIndex() ind2 = self.Comp2.currentIndex() if ind1 != ind2: zi = arange(0.025, 1., 0.025) id1 = self.indices[ind1] id2 = self.indices[ind2] x = [0] y = [0] for z in zi: try: fraccion = [0.] * len(self.indices) fraccion[ind1] = z fraccion[ind2] = 1 - z mez = Mezcla(tipo=3, fraccionMolar=fraccion, caudalMasico=1.) tb = mez.componente[0].Tb corr = Corriente(T=tb, P=101325., mezcla=mez) T = corr.eos._Dew_T() corr = Corriente(T=T, P=101325., mezcla=mez) while corr.Liquido.fraccion[0] == corr.Gas.fraccion[ 0] and corr.T < corr.mezcla.componente[1].Tb: corr = Corriente(T=corr.T - 0.1, P=101325., mezcla=mez) x.append(corr.Liquido.fraccion[0]) y.append(corr.Gas.fraccion[0]) except: pass x.append(1) y.append(1) self.rellenar(x, y)
def loadFromStream(self, stream, huella=True, run=True): """Read project from stream huella: boolean to save project file to pychemqt_temporal""" # read configuration config = ConfigParser() for i in range(stream.readInt32()): section = stream.readString() config.add_section(section) for contador_option in range(stream.readInt32()): option = stream.readString() valor = stream.readString() config.set(section, option, valor) #TODO: Necesario para cargar los proyectos viejos # config.set("Thermo", "freesteam", "False") config.set("Units", "MolarSpecificHeat", "0") self.setConfig(config) if not huella: os.rename(conf_dir+"pychemqtrc_temporal", conf_dir+"pychemqtrc_temporal_bak") config.write(open(conf_dir+"pychemqtrc_temporal", "w")) # read equipments items = {} contador_equipos = stream.readInt32() for i in range(contador_equipos): id = stream.readString() if id[0] == "e": equip = equipments[stream.readInt32()]() equip.readFromStream(stream, run) else: equip = None items[id] = equip self.setItems(items) # read streams streams = {} contador_streams = stream.readInt32() for item in range(contador_streams): id = stream.readInt32() up = stream.readString() down = stream.readString() ind_up = stream.readInt32() ind_down = stream.readInt32() obj = Corriente() obj.readFromStream(stream, run) streams[id] = (up, down, ind_up, ind_down, obj) if huella: if down[0] == "e": equip = self.items[down] if isinstance(equip, Mixer): kwargs = {"entrada": obj, "id_entrada": ind_down} else: kwargs = {equip.kwargsInput[ind_down]: obj} equip(**kwargs) self.setStreams(streams) if not huella: os.rename(conf_dir+"pychemqtrc_temporal_bak", conf_dir+"pychemqtrc_temporal")
def readFromJSON(self, data, huella=True): """Read project from stream huella: boolean to save project file to pychemqt_temporal""" # read configuration config = ConfigParser() for section, options in data["config"].items(): config.add_section(section) for option, value in options.items(): config.set(section, option, value) self.setConfig(config) if not huella: os.rename(conf_dir + "pychemqtrc_temporal", conf_dir + "pychemqtrc_temporal_bak") config.write(open(conf_dir + "pychemqtrc_temporal", "w")) # read equipments items = {} for id, equip in data["equipment"].items(): if id[0] == "e": index = equip["id"] eq = equipments[index]() eq.readFromJSON(equip) else: eq = None items[id] = eq self.setItems(items) # read streams streams = {} for id, stream in data["stream"].items(): id = int(id) up = stream["up"] down = stream["down"] ind_up = stream["ind_up"] ind_down = stream["ind_down"] obj = Corriente() obj.readFromJSON(stream) streams[id] = (up, down, ind_up, ind_down, obj) if huella: if down[0] == "e": equip = self.items[down] if isinstance(equip, Mixer): kwargs = {"entrada": obj, "id_entrada": ind_down} equip.cleanOldValues(**kwargs) else: kwargs = {equip.kwargsInput[ind_down]: obj} equip.kwargs.update(kwargs) if up[0] == "e": equip = self.items[up] # Equipment with variable output streams must be corrected while len(equip.salida) <= ind_up: equip.salida.append(None) equip.salida[ind_up] = obj self.setStreams(streams) if not huella: os.rename(conf_dir + "pychemqtrc_temporal_bak", conf_dir + "pychemqtrc_temporal")
def readFromJSON(self, data, huella=True): """Read project from stream huella: boolean to save project file to pychemqt_temporal""" # read configuration config = ConfigParser() for section, options in data["config"].items(): config.add_section(section) for option, value in options.items(): config.set(section, option, value) self.setConfig(config) if not huella: os.rename(conf_dir+"pychemqtrc_temporal", conf_dir+"pychemqtrc_temporal_bak") config.write(open(conf_dir+"pychemqtrc_temporal", "w")) # read equipments items = {} for id, equip in data["equipment"].items(): if id[0] == "e": index = equip["id"] eq = equipments[index]() eq.readFromJSON(equip) else: eq = None items[id] = eq self.setItems(items) # read streams streams = {} for id, stream in data["stream"].items(): id = int(id) up = stream["up"] down = stream["down"] ind_up = stream["ind_up"] ind_down = stream["ind_down"] obj = Corriente() obj.readFromJSON(stream) streams[id] = (up, down, ind_up, ind_down, obj) if huella: if down[0] == "e": equip = self.items[down] if isinstance(equip, Mixer): kwargs = {"entrada": obj, "id_entrada": ind_down} equip.cleanOldValues(**kwargs) else: kwargs = {equip.kwargsInput[ind_down]: obj} equip.kwargs.update(kwargs) if up[0] == "e": equip = self.items[up] # Equipment with variable output streams must be corrected while len(equip.salida) <= ind_up: equip.salida.append(None) equip.salida[ind_up] = obj self.setStreams(streams) if not huella: os.rename(conf_dir+"pychemqtrc_temporal_bak", conf_dir+"pychemqtrc_temporal")
def calculo(self): self.entrada = self.kwargs["entrada"] self.rendimientoCalculado = Dimensionless(self.kwargs["rendimiento"]) if self.kwargs["Pout"]: DeltaP = Pressure(self.kwargs["Pout"] - self.entrada.P) elif self.kwargs["deltaP"]: DeltaP = Pressure(self.kwargs["deltaP"]) elif self.kwargs["Carga"]: DeltaP = Pressure(self.kwargs["Carga"] * self.entrada.Liquido.rho * g) else: DeltaP = Pressure(0) if self.kwargs["usarCurva"]: if self.kwargs["diametro"] != self.kwargs["curvaCaracteristica"][ 0] or self.kwargs["velocidad"] != self.kwargs[ "curvaCaracteristica"][1]: self.curvaActual = self.calcularCurvaActual() else: self.curvaActual = self.kwargs["curvaCaracteristica"] self.Ajustar_Curvas_Caracteristicas() if not self.kwargs["usarCurva"]: head = Length(DeltaP / g / self.entrada.Liquido.rho) power = Power(head * g * self.entrada.Liquido.rho * self.entrada.Q / self.rendimientoCalculado) P_freno = Power(power * self.rendimientoCalculado) elif not self.kwargs["incognita"]: head = Length(polyval(self.CurvaHQ, self.entrada.Q)) self.DeltaP = Pressure(head * g * self.entrada.Liquido.rho) power = Power(self.entrada.Q * DeltaP) P_freno = Power(polyval(self.CurvaPotQ, self.entrada.Q)) self.rendimientoCalculado = Dimensionless(power / P_freno) else: head = Length(self.DeltaP / g / self.entrada.Liquido.rho) caudalvolumetrico = roots( [self.CurvaHQ[0], self.CurvaHQ[1], self.CurvaHQ[2] - head])[0] power = Power(caudalvolumetrico * self.DeltaP) self.entrada = Corriente( self.entrada.T, self.entrada.P.atm, caudalvolumetrico * self.entrada.Liquido.rho * 3600, self.entrada.mezcla, self.entrada.solido) P_freno = Power(polyval(self.CurvaPotQ, caudalvolumetrico)) self.rendimientoCalculado = Dimensionless(power / P_freno) self.headCalculada = head self.power = power self.P_freno = P_freno self.salida = [self.entrada.clone(P=self.entrada.P + DeltaP)] self.Pin = self.entrada.P self.PoutCalculada = self.salida[0].P self.Q = self.entrada.Q.galUSmin self.volflow = self.entrada.Q
def calculo(self): self.entrada = self.kwargs["entrada"] Pout = self.kwargs["Pout"] DeltaP = self.kwargs["DeltaP"] Dew = self.kwargs["Dew"] Bubble = self.kwargs["Bubble"] if self.kwargs["off"] == 1: if Pout: self.Pout = unidades.Pressure(Pout) elif DeltaP: self.Pout = unidades.Pressure(self.entrada.P - DeltaP) elif Dew: corriente = self.entrada.clone(T=Dew) self.Pout = corriente.eos._Dew_P() elif Bubble: corriente = self.entrada.clone(T=Bubble) self.Pout = corriente.eos._Bubble_P() self.salida = [self.entrada.clone(P=self.Pout)] elif self.kwargs["off"] == 2: self.entrada = Corriente() self.salida = [self.entrada] else: self.salida = [self.entrada] self.outT = self.salida[0].T self.outP = self.salida[0].P self.outX = self.salida[0].x
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
def calculo(self): """Calculate procedure, only apply pressure loss method chosen""" self.entrada = self.kwargs["entrada"] Pout = self.kwargs["Pout"] DeltaP = self.kwargs["DeltaP"] Dew = self.kwargs["Dew"] Bubble = self.kwargs["Bubble"] if self.kwargs["off"] == 1: if Pout: self.Pout = unidades.Pressure(Pout) elif DeltaP: self.Pout = unidades.Pressure(self.entrada.P-DeltaP) elif Dew: corriente = self.entrada.clone(T=Dew) self.Pout = corriente.eos._Dew_P() elif Bubble: corriente = self.entrada.clone(T=Bubble) self.Pout = corriente.eos._Bubble_P() self.salida = [self.entrada.clone(P=self.Pout)] elif self.kwargs["off"] == 2: self.entrada = Corriente() self.salida = [self.entrada] else: self.salida = [self.entrada] self.Pout = unidades.Pressure(self.salida[0].P) # Calculate other properties self.outT = self.salida[0].T self.outX = self.salida[0].x
def calculo(self): self.entrada = self.kwargs["entrada"] self.criterio = self.kwargs["criterio"] Pout = self.kwargs["Pout"] if self.criterio == 2: self.Pout = unidades.Pressure(Pout) else: lst = [] for entrada in self.entrada: if entrada.status: lst.append(entrada.P) if self.criterio == 0: self.Pout = unidades.Pressure(min(lst)) else: self.Pout = unidades.Pressure(sum(lst, 0.0) / len(lst)) h_in = 0 To = 0 caudalunitariomasico = [0] * len(self.entrada[0].fraccion) for entrada in self.entrada: if entrada.status: h_in += entrada.h To += entrada.T * entrada.caudalmasico for i, caudal in enumerate(entrada.caudalunitariomasico): caudalunitariomasico[i] += caudal To /= sum(caudalunitariomasico) if self.entrada[0].Config.get("Components", "Solids"): #TODO: Add solid mixer pass f = lambda T: Corriente( T=T, P=self.Pout, caudalUnitarioMasico=caudalunitariomasico ).h - h_in T = fsolve(f, To)[0] salida = Corriente(T=T, P=self.Pout, caudalUnitarioMasico=caudalunitariomasico) self.salida = [salida] self.outT = salida.T self.outP = salida.P self.outX = salida.x self.outMolarFlow = salida.caudalmolar self.outMassFlow = salida.caudalmasico self.outVolFlow = salida.Q
def cleanOldValues(self, **kwargs): if kwargs.has_key("entrada"): if isinstance(kwargs["entrada"], list): kwargs["id_entrada"] = None else: corriente = kwargs["entrada"] kwargs["entrada"] = self.kwargs["entrada"][:] while len(kwargs["entrada"]) < kwargs["id_entrada"] + 1: kwargs["entrada"].append(Corriente()) kwargs["entrada"][kwargs["id_entrada"]] = corriente kwargs["id_entrada"] = None self.kwargs.update(kwargs)
def calculo(self): """Calculate procedure, only a mass balance""" self.entrada = self.kwargs["entrada"] self.criterio = self.kwargs["criterio"] # Define output pressure if self.criterio == 2: Pout = self.kwargs["Pout"] else: lst = [] for entrada in self.entrada: if entrada.status: lst.append(entrada.P) if self.criterio == 0: Pout = min(lst) else: Pout = sum(lst, 0.0) / len(lst) self.Pout = unidades.Pressure(Pout) # Heat balance for calculate output temperature h_in = 0 To = 0 massUnitFlow = [0]*len(self.entrada[0].fraccion) for entrada in self.entrada: if entrada.status: h_in += entrada.h To += entrada.T*entrada.caudalmasico for i, caudal in enumerate(entrada.caudalunitariomasico): massUnitFlow[i] += caudal To /= sum(massUnitFlow) def f(T): output = Corriente(T=T, P=self.Pout, caudalUnitarioMasico=massUnitFlow) return output.h-h_in T = fsolve(f, To)[0] # TODO: Add solid mixer capability if self.entrada[0].solido: pass salida = Corriente(T=T, P=self.Pout, caudalUnitarioMasico=massUnitFlow) self.salida = [salida] # Calculate other properties self.outT = salida.T self.outX = salida.x self.outMolarFlow = salida.caudalmolar self.outMassFlow = salida.caudalmasico self.outVolFlow = salida.Q
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 cleanOldValues(self, **kwargs): """Clean incompatible kwargs parameters New defined entrada delete old entrada Entrada as list not need the id_entrada """ if "entrada" in kwargs: if isinstance(kwargs["entrada"], list): kwargs["id_entrada"] = None else: corriente = kwargs["entrada"] kwargs["entrada"] = self.kwargs["entrada"][:] while len(kwargs["entrada"]) < kwargs["id_entrada"]+1: kwargs["entrada"].append(Corriente()) kwargs["entrada"][kwargs["id_entrada"]] = corriente kwargs["id_entrada"] = None self.kwargs.update(kwargs)
def addStream(self, id, up, down, obj=Corriente(), ind_up=0, ind_down=0): if up[0] == "i": obj = self.items[up] stream = (up, down, ind_up, ind_down, obj) if id not in list(self.streams.keys()): self.streams[id] = stream # self.graph.add_edge((up, down)) if down[0] == "e": eq = self.items[down] if isinstance(eq, Mixer): kwargs = {"entrada": obj, "id_entrada": ind_down} else: kwargs = {eq.kwargsInput[ind_down]: obj} eq(**kwargs)
def calculo(self): self.entrada=self.kwargs["entrada"] self.rendimientoCalculado=Dimensionless(self.kwargs["rendimiento"]) if self.kwargs["Pout"]: DeltaP=Pressure(self.kwargs["Pout"]-self.entrada.P) elif self.kwargs["deltaP"]: DeltaP=Pressure(self.kwargs["deltaP"]) elif self.kwargs["Carga"]: DeltaP=Pressure(self.kwargs["Carga"]*self.entrada.Liquido.rho*g) else: DeltaP=Pressure(0) if self.kwargs["usarCurva"]: if self.kwargs["diametro"]!=self.kwargs["curvaCaracteristica"][0] or self.kwargs["velocidad"]!=self.kwargs["curvaCaracteristica"][1]: self.curvaActual=self.calcularCurvaActual() else: self.curvaActual=self.kwargs["curvaCaracteristica"] self.Ajustar_Curvas_Caracteristicas() if not self.kwargs["usarCurva"]: head=Length(DeltaP/g/self.entrada.Liquido.rho) power=Power(head*g*self.entrada.Liquido.rho*self.entrada.Q/self.rendimientoCalculado) P_freno=Power(power*self.rendimientoCalculado) elif not self.kwargs["incognita"]: head=Length(polyval(self.CurvaHQ,self.entrada.Q)) self.DeltaP=Pressure(head*g*self.entrada.Liquido.rho) power=Power(self.entrada.Q*DeltaP) P_freno=Power(polyval(self.CurvaPotQ,self.entrada.Q)) self.rendimientoCalculado=Dimensionless(power/P_freno) else: head=Length(self.DeltaP/g/self.entrada.Liquido.rho) caudalvolumetrico=roots([self.CurvaHQ[0], self.CurvaHQ[1], self.CurvaHQ[2]-head])[0] power=Power(caudalvolumetrico*self.DeltaP) self.entrada=Corriente(self.entrada.T, self.entrada.P.atm, caudalvolumetrico*self.entrada.Liquido.rho*3600, self.entrada.mezcla, self.entrada.solido) P_freno=Power(polyval(self.CurvaPotQ,caudalvolumetrico)) self.rendimientoCalculado=Dimensionless(power/P_freno) self.headCalculada=head self.power=power self.P_freno=P_freno self.salida=[self.entrada.clone(P=self.entrada.P+DeltaP)] self.Pin=self.entrada.P self.PoutCalculada=self.salida[0].P self.Q=self.entrada.Q.galUSmin self.volflow=self.entrada.Q
def calculo(self): if self.todos_datos(): self.rellenoSalida() def rellenoSalida(self): pass def todos_datos(self): pass def calcularCostos(self): if self.todos_datos(): if self.tipo.currentIndex()==0: self.FireHeater.Coste(self.factorInstalacion.value(), 0, self.tipobox.currentIndex(), self.material.currentIndex()) else: self.FireHeater.Coste(self.factorInstalacion.value(), 1, self.tipocilindrico.currentIndex(), self.material.currentIndex()) self.C_adq.setValue(self.FireHeater.C_adq.config()) self.C_inst.setValue(self.FireHeater.C_inst.config()) if __name__ == "__main__": import sys from lib.corriente import Corriente, Mezcla app = QtWidgets.QApplication(sys.argv) agua=Corriente(300, 1, 3600, Mezcla([62], [1])) dialogo = UI_equipment(agua) dialogo.show() sys.exit(app.exec_())
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
elif self.material == 2: #Monel a, b = 70., 5.50 else: #Nickel a, b = 84.4, 6.56 else: #Proceso inorgánico if self.material == 0: #Hastelloy a, b = 300., 10. elif self.material == 1: #Acero Inoxidable a, b = 98., 5.06 elif self.material == 2: #Monel a, b = 114., 7.14 else: #Nickel a, b = 143., 9.43 W = self.entrada.caudal.Tmh C = (a + b * W) * 1000 self.C_adq = unidades.Currency(C * self.Current_index / self.Base_index) self.C_inst = unidades.Currency(self.C_adq * self.f_install) if __name__ == '__main__': entrada = Corriente(423.15, 3, 9000, [[46, 47, 49, 64], [0.78, 0.21, 0.0001, 0.0009]], [64], [[1e-6, 1]]) cristalizador = Crystallizer(entrada, 0.1) # agua=Corriente(300, 1, 4.3756, [[62], [1]]) # scrubber=Scrubber(entrada, agua, 0.1)
self.tiempo.setResaltado(False) self.deltaP.setReadOnly(False) self.deltaP.setRetornar(True) self.deltaP.setResaltado(True) else: self.numFiltros.setReadOnly(True) self.numFiltros.setRetornar(False) self.numFiltros.setResaltado(False) self.tiempo.setReadOnly(False) self.tiempo.setRetornar(True) self.tiempo.setResaltado(True) self.deltaP.setReadOnly(False) self.deltaP.setRetornar(True) self.deltaP.setResaltado(True) if __name__ == "__main__": import sys from lib.corriente import Mezcla, Corriente, Solid app = QtWidgets.QApplication(sys.argv) distribucion = [[17.5, 0.02], [22.4, 0.03], [26.2, 0.05], [31.8, 0.1], [37, 0.1], [42.4, 0.1], [48, 0.1], [54, 0.1], [60, 0.1], [69, 0.1], [81.3, 0.1], [96.5, 0.05], [109, 0.03], [127, 0.02]] solido = Solid([64], [138718], distribucion) entrada = Corriente(423.15, 3, 11784, Mezcla([475], [1]), solido) dialogo = UI_equipment(entrada) dialogo.show() sys.exit(app.exec_())
self.DeTube.setValue(material[6]) def showFinTube(self): dialogo = Dialog_Finned(self.Equipment.kwargs) if dialogo.exec_(): kwarg = dialogo.kwarg() self.calculo(**kwarg) if __name__ == "__main__": import sys from lib.corriente import Corriente app = QtGui.QApplication(sys.argv) caliente = Corriente(T=140 + 273.15, P=361540., caudalMasico=1.36, ids=[62], fraccionMolar=[1.]) fria = Corriente(T=20 + 273.15, P=101325., caudalMasico=5000 / 3600., ids=[62], fraccionMolar=[1.]) Cambiador = Hairpin(entradaTubo=caliente, entradaExterior=fria, modo=1, DiTube=0.0525, DeTube=0.0603, DeeTube=0.0779, kTube=54, rTube=0.0459994e-3,
17.5e-6, 22.4e-6, 26.2e-6, 31.8e-6, 37e-6, 42.4e-6, 48e-6, 54e-6, 60e-6, 69e-6, 81.3e-6, 96.5e-6, 109e-6, 127e-6 ] fracciones = [ 0.02, 0.03, 0.05, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.05, 0.03, 0.02 ] solido = Solid(T=300, caudalSolido=[1 / 3600.], distribucion_diametro=diametros, distribucion_fraccion=fracciones, solids=[638]) kw = {"fraccionMolar": [1.], "MEoS": True} aire = Corriente(T=350, P=101325, caudalMasico=0.01, ids=[475], solido=solido, **kw) agua = Corriente(T=300, P=101325, caudalMasico=0.1, ids=[62], **kw) scrubber = Scrubber(entradaGas=aire, entradaLiquido=agua, diametro=0.25, modelo_rendimiento=0, modelo_DeltaP=1, k=1000) dialogo = UI_equipment(scrubber) # dialogo = UI_equipment() dialogo.show() sys.exit(app.exec_())
valor = self.fracciones.getColumn(0, False) if self.criterio.currentIndex() == 0: if len(valor)+1 < self.fracciones.rowCount(): return elif len(valor)+1 == self.fracciones.rowCount(): valor.append(1-sum(valor)) elif len(valor) == self.fracciones.rowCount(): valor[-1] = 1-sum(valor[:-1]) self.calculo(**{parametro: valor}) def rellenar(self): UI_equip.rellenar(self) if self.Equipment.status == 1 and self.criterio.currentIndex() == 1: self.entrada.setCorriente(self.Equipment.entrada) def rellenarInput(self): UI_equip.rellenarInput(self) self.fracciones.setColumn(0, self.Equipment.kwargs["split"]) if __name__ == "__main__": import sys from lib.corriente import Corriente app = QtWidgets.QApplication(sys.argv) agua = Corriente(T=300, P=101325, caudalMasico=1, ids=[62], fraccionMolar=[0.1]) divisor = Divider(entrada=agua, salidas=2, split=[0.3, 0.7]) dialogo = UI_equipment(divisor) dialogo.show() sys.exit(app.exec_())
self.rellenoSalida() def rellenoSalida(self): pass def todos_datos(self): pass def calcularCostos(self): if self.todos_datos(): self.ShellTube.Coste(self.factorInstalacion.value(), 0, self.tipo.currentIndex(), self.material.currentIndex()) self.C_adq.setValue(self.ShellTube.C_adq.config()) self.C_inst.setValue(self.ShellTube.C_inst.config()) if __name__ == "__main__": import sys from lib.corriente import Corriente, Mezcla app = QtWidgets.QApplication(sys.argv) agua = Corriente(T=300, P=101325, caudalMasico=3600, ids=[62], fraccion=[1]) dialogo = UI_equipment(agua) dialogo.show() sys.exit(app.exec_())
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
# agua=Corriente(T=300, P=101325., caudalMasico=1000, ids=[4, 5, 6, 7, 8, 10, 11, 12, 13], fraccionMolar=[0.02361538, 0.2923077, 0.3638462, 0.02769231, 0.01153846, 0.01769231, 0.03007692, 0.2093846, 0.02384615]) # columna=ColumnFUG(entrada=agua, LK=2, LKsplit=0.9, HK=3, HKsplit=0.9, R_Rmin=1.05, calc_feed=0, DeltaP=0.1) # print columna.Rmin # print columna.DutyCondenser.MJh, columna.DutyReboiler.MJh # blend=Corriente(T=340, P=101325, caudalMasico=1, fraccionMolar=[0.3, 0.5, 0.05, 0.15]) # columna=ColumnFUG(entrada=blend, LK=0, LKsplit=0.9866, HK=3, HKsplit=0.639, R_Rmin=1.1, feed=0) # P = unidades.Pressure(315, "psi") # blend=Corriente(T=T, P=P, caudalMasico=1, fraccionMolar=[0.26, 0.09, 0.25, 0.17, 0.11, 0.12]) # columna=ColumnFUG(entrada=blend, LK=0, LKsplit=0.96666, HK=3, HKsplit=0.95, R_Rmin=1.2) # print columna.DutyCondenser # print((blend.mezcla.ids)) # kw = {"MEoS": True, "coolProp": True} # entrada = Corriente(T=300, x=0.5, caudalMasico=0.01, ids=[5, 6, 7, 8], # fraccionMolar=[.3, 0.5, 0.05, 0.15], **kw) kw = {"MEoS": True, "coolProp": True, "ids": [5, 6, 7, 8, 10]} entrada = Corriente(**kw) entrada(T=300) entrada(x=0.5) entrada(caudalMasico=0.01) entrada(fraccionMolar=[.3, 0.25, 0.05, 0.15, 0.25]) flash = Flash(entrada=entrada) print(flash.propTxt()) # from scipy import * # from scipy.integrate import odeint # from pylab import * # import matplotlib.pyplot as plt # batch()
class Pump(equipment): """Clase que modela un equipo de bombeo de líquidos Parámetros: entrada: instancia de la clase corriente que define la corriente de entrada en la bomba usarCurva: 0 - Funcionamiento fijo 1 - Funcionamiento siguiendo la curva característica incognita: Indica la variable a calcular en el caso de que se use la curva caracteristica 0 - Carga (incremento de presión) 1 - Caudal, en este caso sobreescribe el caudal de la corriente de entrada rendimiento: rendimiento de la bomba, no necesario si se ha definido la curva característica de la bomba deltaP: incremento de presión proporcionado por la bomba, no será necesario si se define la curva característica y es el caudal la variable a calcular, en atmosferas Pout: Presión a la salida de la bomba Carga: Cambio de presión basada en altura de columna de fluido curvaCaracteristica: array que define la curva característica, en la forma: [Dia, rpm, [Q1,..Qn], [h1,...,hn], [Pot1,...,Potn], [NPSH1,...NPSHn]]. diametro: diametro nominal bomba velocidad: velocidad de giro de la bomba Coste tipo_bomba 0 - Centrifugal pumps 1 - Reciprocating pumps 2 - Gear pumps 3 - Vertical mixed flow 4 - Vertical axial flow tipo_centrifuga 0 - One stage, 3550 rpm, VSC 1 - One stage, 1750 rpm, VSC 2 - One stage, 3550 rpm, HSC 3 - One stage, 1750 rpm, HSC 4 - Two stage, 3550 rpm, HSC 5 - Multistage, 3550 rpm, HSC Material 0 - Cast iron 1 - Case steel 2 - 304 or 316 fittings 3 - Stainless steel 304 or 316 4 - Case Gould's alloy no. 20 5 - Nickel 6 - Monel 7 - ISO B 8 - ISO B 9 - Titanium 10 - Hastelloy C 11 - Ductile iron 12 - Bronze motor: Tipo de motor 0 - Open drip-proof 1 - Totally enclosed, fan-cooled 2 - Explosion-proof rpm 0 - 3600 rpm 1 - 1800 rpm 2 - 1200 rpm >>> agua=Corriente(T=300, P=101325, caudalMasico=1, fraccionMolar=[1.]) >>> bomba=Pump(entrada=agua, rendimiento=0.75, deltaP=20*101325, tipo_bomba=1) >>> print bomba.power.hp 3.63596053358 >>> print bomba.C_inst 3493.24497823 """ title = QApplication.translate("pychemqt", "Pump") help = "" kwargs = { "entrada": None, "usarCurva": 0, "incognita": 0, "rendimiento": 0.0, "deltaP": 0.0, "Pout": 0.0, "Carga": 0.0, "curvaCaracteristica": [], "diametro": 0.0, "velocidad": 0.0, "f_install": 2.8, "Base_index": 0.0, "Current_index": 0.0, "tipo_bomba": 0, "tipo_centrifuga": 0, "material": 0, "motor": 0, "rpm": 0 } kwargsInput = ("entrada", ) kwargsCheck = ("usarCurva", ) kwargsValue = ("Pout", "deltaP", "rendimiento", "Carga", "diametro", "velocidad") kwargsList = ("incognita", "tipo_bomba", "tipo_centrifuga", "material", "motor", "rpm") calculateValue = ("PoutCalculada", "power", "headCalculada", "volflow", "rendimientoCalculado") calculateCostos = ("C_bomba", "C_motor", "C_adq", "C_inst") indiceCostos = 7 TEXT_BOMBA = [ QApplication.translate("pychemqt", "Centrifugal"), QApplication.translate("pychemqt", "Reciprocating"), QApplication.translate("pychemqt", "Gear pump"), QApplication.translate("pychemqt", "Vertical mixed flow"), QApplication.translate("pychemqt", "Vertical axial flow") ] TEXT_CENTRIFUGA = [ QApplication.translate("pychemqt", "One stage, 3550 rpm, VSC"), QApplication.translate("pychemqt", "One stage, 1750 rpm, VSC"), QApplication.translate("pychemqt", "One stage, 3550 rpm, HSC"), QApplication.translate("pychemqt", "One stage, 1750 rpm, HSC"), QApplication.translate("pychemqt", "Two stage, 3550 rpm, HSC"), QApplication.translate("pychemqt", "Multistage, 3550 rpm, HSC") ] TEXT_MATERIAL = [ QApplication.translate("pychemqt", "Cast iron"), QApplication.translate("pychemqt", "Case steel"), QApplication.translate("pychemqt", "304 or 316 fittings"), QApplication.translate("pychemqt", "Stainless steel 304 or 316"), QApplication.translate("pychemqt", "Case Gould's alloy no. 20"), QApplication.translate("pychemqt", "Nickel"), QApplication.translate("pychemqt", "Monel (Ni-Cu)"), QApplication.translate("pychemqt", "ISO B"), QApplication.translate("pychemqt", "ISO C"), QApplication.translate("pychemqt", "Titanium"), QApplication.translate("pychemqt", "Hastelloy C (Ni-Fe-Mo)"), QApplication.translate("pychemqt", "Ductile iron"), QApplication.translate("pychemqt", "Bronze") ] TEXT_MOTOR = [ QApplication.translate("pychemqt", "Open drip-proof"), QApplication.translate("pychemqt", "Totally enclosed, fan-cooled"), QApplication.translate("pychemqt", "Explosion-proof") ] TEXT_RPM = ["3600 RPM", "1800 RPM", "1200 RPM"] @property def isCalculable(self): if self.kwargs["f_install"] and self.kwargs[ "Base_index"] and self.kwargs["Current_index"]: self.statusCoste = True else: self.statusCoste = False if not self.kwargs["entrada"]: self.msg = QApplication.translate("pychemqt", "undefined input") self.status = 0 else: presion = self.kwargs["Pout"] or self.kwargs[ "deltaP"] or self.kwargs["Carga"] if self.kwargs["usarCurva"]: if self.kwargs["incognita"]: if presion and self.kwargs["curvaCaracteristica"]: self.msg = "" self.status = 1 return True elif presion: self.msg = QApplication.translate( "pychemqt", "undefined pump curve") self.status = 0 else: self.msg = QApplication.translate( "pychemqt", "undefined out pressure condition") self.status = 0 elif self.kwargs["curvaCaracteristica"]: self.msg = "" self.status = 1 return True else: self.msg = QApplication.translate("pychemqt", "undefined pump curve") self.status = 0 else: if presion and self.kwargs["rendimiento"]: self.msg = "" self.status = 1 return True elif presion: self.msg = QApplication.translate("pychemqt", "undefined efficiency") self.status = 0 else: self.msg = QApplication.translate( "pychemqt", "undefined out pressure condition") self.status = 0 def calculo(self): self.entrada = self.kwargs["entrada"] self.rendimientoCalculado = Dimensionless(self.kwargs["rendimiento"]) if self.kwargs["Pout"]: DeltaP = Pressure(self.kwargs["Pout"] - self.entrada.P) elif self.kwargs["deltaP"]: DeltaP = Pressure(self.kwargs["deltaP"]) elif self.kwargs["Carga"]: DeltaP = Pressure(self.kwargs["Carga"] * self.entrada.Liquido.rho * g) else: DeltaP = Pressure(0) if self.kwargs["usarCurva"]: if self.kwargs["diametro"] != self.kwargs["curvaCaracteristica"][ 0] or self.kwargs["velocidad"] != self.kwargs[ "curvaCaracteristica"][1]: self.curvaActual = self.calcularCurvaActual() else: self.curvaActual = self.kwargs["curvaCaracteristica"] self.Ajustar_Curvas_Caracteristicas() if not self.kwargs["usarCurva"]: head = Length(DeltaP / g / self.entrada.Liquido.rho) power = Power(head * g * self.entrada.Liquido.rho * self.entrada.Q / self.rendimientoCalculado) P_freno = Power(power * self.rendimientoCalculado) elif not self.kwargs["incognita"]: head = Length(polyval(self.CurvaHQ, self.entrada.Q)) self.DeltaP = Pressure(head * g * self.entrada.Liquido.rho) power = Power(self.entrada.Q * DeltaP) P_freno = Power(polyval(self.CurvaPotQ, self.entrada.Q)) self.rendimientoCalculado = Dimensionless(power / P_freno) else: head = Length(self.DeltaP / g / self.entrada.Liquido.rho) caudalvolumetrico = roots( [self.CurvaHQ[0], self.CurvaHQ[1], self.CurvaHQ[2] - head])[0] power = Power(caudalvolumetrico * self.DeltaP) self.entrada = Corriente( self.entrada.T, self.entrada.P.atm, caudalvolumetrico * self.entrada.Liquido.rho * 3600, self.entrada.mezcla, self.entrada.solido) P_freno = Power(polyval(self.CurvaPotQ, caudalvolumetrico)) self.rendimientoCalculado = Dimensionless(power / P_freno) self.headCalculada = head self.power = power self.P_freno = P_freno self.salida = [self.entrada.clone(P=self.entrada.P + DeltaP)] self.Pin = self.entrada.P self.PoutCalculada = self.salida[0].P self.Q = self.entrada.Q.galUSmin self.volflow = self.entrada.Q def Ajustar_Curvas_Caracteristicas(self): """Define la curva característica de la bomba a partir de los datos, todos ellos en forma de array de igual dimensión Q: caudal, m3/s h: carga, m mu: rendimiento NPSHr: carga neta de aspiración requerida por la bomba para no entrar en cavitación """ Q = r_[self.curvaActual[2]] h = r_[self.curvaActual[3]] Pot = r_[self.curvaActual[4]] NPSH = r_[self.curvaActual[5]] funcion_h = lambda p, x: p[0] * x**2 + p[1] * x + p[ 2] # Función a ajustar residuo_h = lambda p, x, y: funcion_h(p, x) - y # Residuo inicio = r_[0, 0, 0] ajuste_h, exito_h = optimize.leastsq(residuo_h, inicio, args=(Q, h)) self.CurvaHQ = ajuste_h funcion_Pot = lambda p, x: p[0] * x**2 + p[1] * x + p[ 2] # Función a ajustar residuo_Pot = lambda p, x, y: funcion_Pot(p, x) - y # Residuo inicio = r_[0, 0, 0] ajuste_Pot, exito_Pot = optimize.leastsq(residuo_Pot, inicio, args=(Q, Pot)) self.CurvaPotQ = ajuste_Pot funcion_NPSH = lambda p, x: p[0] + p[1] * exp(p[2] * x ) # Función a ajustar residuo_NPSH = lambda p, x, y: funcion_NPSH(p, x) - y # Residuo inicio = r_[0, 0, 0] ajuste_NPSH, exito_NPSH = optimize.leastsq(residuo_NPSH, inicio, args=(Q, NPSH)) self.CurvaNPSHQ = ajuste_NPSH def calcularCurvaActual(self): """Método que define curvas caracteristica de la bomba a una velocidad de giro y diametro del propulsor diferente de la curva característica original haciendo uso de las leyes de afinidad, perry 10.25 Table 10.7""" D1 = self.kwargs["curvaCaracteristica"][0] N1 = self.kwargs["curvaCaracteristica"][1] D2 = self.kwargs["diametro"] N2 = self.kwargs["velocidad"] Q1 = r_[self.kwargs["curvaCaracteristica"][2]] h1 = r_[self.kwargs["curvaCaracteristica"][3]] Pot1 = r_[self.kwargs["curvaCaracteristica"][4]] npsh1 = r_[self.kwargs["curvaCaracteristica"][5]] Q2 = Q1 * D2 / D1 * N2 / N1 h2 = h1 * N2**2 / N1**2 * D2**2 / D1**2 Pot2 = Pot1 * N2**3 / N1**3 * D2**3 / D1**3 npsh2 = npsh1 * N2**2 / N1**2 * D2**2 / D1**2 #Esta relación no es tan fiable como las anteriores return [D2, N2, Q2, h2, Pot2, npsh2] def coste(self): HP = self.power.hp LnHP = log(self.power.hp) #Coste Bomba if self.kwargs["tipo_bomba"] == 0: #Centrifugal pumps QH = log(self.Q * self.power.hp**0.5) Fm = [ 1., 1.35, 1.15, 2., 2., 3.5, 3.3, 4.95, 4.6, 9.7, 2.95, 1.15, 1.90 ] b1 = [0., 5.1029, 0.0632, 2.0290, 13.7321, 9.8849][self.kwargs["tipo_centrifuga"]] b2 = [0., -1.2217, 0.2744, -0.2371, -2.8304, -1.6164][self.kwargs["tipo_centrifuga"]] b3 = [0., 0.0771, -0.0253, 0.0102, 0.1542, 0.0834][self.kwargs["tipo_centrifuga"]] Ft = exp(b1 + b2 * QH + b3 * QH**2) Cb = Fm[self.kwargs["material"]] * Ft * 1.55 * exp(8.833 - 0.6019 * QH + 0.0519 * QH**2) elif self.kwargs["tipo_bomba"] == 1: #Reciprocating pumps if self.kwargs["material"] == 0: #Case iron Cb = 40. * self.Q**0.81 elif self.kwargs["material"] == 3: #316 Staineless steel Cb = 410. * self.Q**0.52 elif self.kwargs["material"] == 12: #Bronze Cb = 410. * 1.4 * self.Q**0.52 elif self.kwargs["material"] == 5: #Nickel Cb = 410. * 1.86 * self.Q**0.52 elif self.kwargs["material"] == 6: #Monel Cb = 410. * 2.20 * self.Q**0.52 else: #Material not available. Assume case iron Cb = 40. * self.Q**0.81 elif self.kwargs["tipo_bomba"] == 2: #Gear pumps Cb = 1000 * exp(-0.0881 + 0.1986 * log(self.Q) + 0.0291 * log(self.Q)**2) elif self.kwargs["tipo_bomba"] == 3: #Vertical mixed flow Cb = 0.036 * self.Q**0.82 * 1000 elif self.kwargs["tipo_bomba"] == 4: #Vertical axial flow Cb = 0.02 * self.Q**0.78 * 1000 C_bomba = Cb * self.kwargs["Current_index"] / self.kwargs["Base_index"] #Coste motor if self.kwargs["motor"] == 0: #Open, drip-proof if self.kwargs["rpm"] == 0 and HP <= 7.5: a1, a2, a3 = 4.8314, 0.0966, 0.10960 elif self.kwargs["rpm"] == 0 and 7.5 < HP <= 250.: a1, a2, a3 = 4.1514, 0.5347, 0.05252 elif self.kwargs["rpm"] == 0 and HP > 250.: a1, a2, a3 = 4.2432, 1.03251, -0.03595 elif self.kwargs["rpm"] == 1 and HP <= 7.5: a1, a2, a3 = 4.7075, -0.01511, 0.22888 elif self.kwargs["rpm"] == 1 and 7.5 < HP <= 250: a1, a2, a3 = 4.5212, 0.47242, 0.04820 elif self.kwargs["rpm"] == 1 and HP > 250.: a1, a2, a3 = 7.4044, -0.06464, 0.05448 elif self.kwargs["rpm"] == 2 and HP <= 7.5: a1, a2, a3 = 4.9298, 0.30118, 0.12630 elif self.kwargs["rpm"] == 2 and 7.5 < HP <= 250: a1, a2, a3 = 5.0999, 0.35861, 0.06052 elif self.kwargs["rpm"] == 2 and HP > 250.: a1, a2, a3 = 4.6163, 0.88531, -0.02188 elif self.kwargs["motor"] == 1: #Totally enclosed, fan-cooled if self.kwargs["rpm"] == 0 and HP <= 7.5: a1, a2, a3 = 5.1058, 0.03316, 0.15374 elif self.kwargs["rpm"] == 0 and 7.5 < HP <= 250.: a1, a2, a3 = 3.8544, 0.83311, 0.02399 elif self.kwargs["rpm"] == 0 and HP > 250.: a1, a2, a3 = 5.3182, 1.08470, -0.05695 elif self.kwargs["rpm"] == 1 and HP <= 7.5: a1, a2, a3 = 4.9687, -0.00930, 0.22616 elif self.kwargs["rpm"] == 1 and HP > 7.5: a1, a2, a3 = 4.5347, 0.57065, 0.04609 elif self.kwargs["rpm"] == 2 and HP <= 7.5: a1, a2, a3 = 5.1532, 0.28931, 0.14357 elif self.kwargs["rpm"] == 2 and HP > 7.5: a1, a2, a3 = 5.3858, 0.31004, 0.07406 elif self.kwargs["motor"] == 2: #Explosion-proof if self.kwargs["rpm"] == 0 and HP <= 7.5: a1, a2, a3 = 5.3934, -0.00333, 0.15475 elif self.kwargs["rpm"] == 0 and HP > 7.5: a1, a2, a3 = 4.4442, 0.60820, 0.05202 elif self.kwargs["rpm"] == 1 and HP <= 7.5: a1, a2, a3 = 5.2851, 0.00048, 0.19949 elif self.kwargs["rpm"] == 1 and HP > 7.5: a1, a2, a3 = 4.8178, 0.51086, 0.05293 elif self.kwargs["rpm"] == 2 and HP <= 7.5: a1, a2, a3 = 5.4166, 0.31216, 0.10573 elif self.kwargs["rpm"] == 2 and HP > 7.5: a1, a2, a3 = 5.5655, 0.31284, 0.07212 C_motor = 1.2 * exp(a1 + a2 * LnHP + a3 * LnHP**2) * self.kwargs[ "Current_index"] / self.kwargs["Base_index"] self.C_bomba = Currency(C_bomba) self.C_motor = Currency(C_motor) self.C_adq = Currency(C_bomba + C_motor) self.C_inst = Currency(self.C_adq * self.kwargs["f_install"]) def propTxt(self): txt = "#---------------" + QApplication.translate( "pychemqt", "Calculate properties") + "-----------------#" + os.linesep txt += "%-25s\t%s" % (QApplication.translate( "pychemqt", "Input Pressure"), self.entrada.P.str) + os.linesep txt += "%-25s\t%s" % (QApplication.translate( "pychemqt", "Output Pressure"), self.salida[0].P.str) + os.linesep txt += "%-25s\t%s" % (QApplication.translate( "pychemqt", "Head"), self.headCalculada.str) + os.linesep txt += "%-25s\t%s" % (QApplication.translate( "pychemqt", "Brake horsepower"), self.P_freno.str) + os.linesep txt += "%-25s\t%s" % (QApplication.translate( "pychemqt", "Volumetric Flow"), self.volflow.str) + os.linesep txt += "%-25s\t%s" % (QApplication.translate( "pychemqt", "Power"), self.power.str) + os.linesep txt += "%-25s\t %0.4f" % (QApplication.translate( "pychemqt", "Efficiency"), self.rendimientoCalculado) + os.linesep txt += "%-25s\t %0.4f" % ("Cp/Cv", self.entrada.Liquido.cp_cv) + os.linesep if self.statusCoste: txt += os.linesep txt += "#---------------" + QApplication.translate( "pychemqt", "Preliminary Cost Estimation" ) + "-----------------#" + os.linesep txt += "%-25s\t %0.2f" % (QApplication.translate( "pychemqt", "Base index"), self.kwargs["Base_index"]) + os.linesep txt += "%-25s\t %0.2f" % (QApplication.translate( "pychemqt", "Current index"), self.kwargs["Current_index"]) + os.linesep txt += "%-25s\t %0.2f" % (QApplication.translate( "pychemqt", "Install factor"), self.kwargs["f_install"]) + os.linesep txt += "%-25s\t %s" % (QApplication.translate( "pychemqt", "Pump type"), self.TEXT_BOMBA[self.kwargs["tipo_bomba"]]) if self.kwargs["tipo_bomba"] == 0: txt += ", " + self.TEXT_CENTRIFUGA[ self.kwargs["tipo_centrifuga"]] + os.linesep else: txt += os.linesep txt += "%-25s\t %s" % ( QApplication.translate("pychemqt", "Material"), self.TEXT_MATERIAL[self.kwargs["material"]]) + os.linesep txt += "%-25s\t%s" % (QApplication.translate( "pychemqt", "Pump Cost"), self.C_bomba.str) + os.linesep txt += "%-25s\t %s, %s" % ( QApplication.translate("pychemqt", "Motor type"), self.TEXT_MOTOR[self.kwargs["motor"]], self.TEXT_RPM[self.kwargs["rpm"]]) + os.linesep txt += "%-25s\t%s" % (QApplication.translate( "pychemqt", "Motor Cost"), self.C_motor.str) + os.linesep txt += "%-25s\t%s" % (QApplication.translate( "pychemqt", "Purchase Cost"), self.C_adq.str) + os.linesep txt += "%-25s\t%s" % (QApplication.translate( "pychemqt", "Installed Cost"), self.C_inst.str) + os.linesep return txt @classmethod def propertiesEquipment(cls): list = [ (QApplication.translate("pychemqt", "Input Pressure"), "Pin", Pressure), (QApplication.translate("pychemqt", "Output Pressure"), "PoutCalculada", Pressure), (QApplication.translate("pychemqt", "Head"), "headCalculada", Length), (QApplication.translate("pychemqt", "Brake horsepower"), "P_freno", Power), (QApplication.translate("pychemqt", "Volumetric Flow"), "volflow", VolFlow), (QApplication.translate("pychemqt", "Power"), "power", Power), (QApplication.translate("pychemqt", "Efficiency"), "rendimientoCalculado", Dimensionless), (QApplication.translate("pychemqt", "Pump Type"), ("TEXT_BOMBA", "tipo_bomba"), str), (QApplication.translate("pychemqt", "Centrifuge Type"), ("TEXT_CENTRIFUGA", "tipo_centrifuga"), str), (QApplication.translate("pychemqt", "Material"), ("TEXT_MATERIAL", "material"), str), (QApplication.translate("pychemqt", "Motor Type"), ("TEXT_MOTOR", "motor"), str), (QApplication.translate("pychemqt", "Motor RPM"), ("TEXT_RPM", "rpm"), str), (QApplication.translate("pychemqt", "Pump Cost"), "C_bomba", Currency), (QApplication.translate("pychemqt", "Motor Cost"), "C_motor", Currency), (QApplication.translate("pychemqt", "Purchase Cost"), "C_adq", Currency), (QApplication.translate("pychemqt", "Installed Cost"), "C_inst", Currency) ] return list def datamap2xls(self): datamap = ( ("PoutCalculada", "value", "H15"), ("PoutCalculada", "unit", "I15"), ("Pin", "value", "H16"), ("Pin", "unit", "I16"), ) return datamap def export2pdf(self): bomba = pdf("Bomba") bomba.bomba(self) bomba.dibujar() os.system("evince datasheet.pdf") def export2xls(self): font0 = xlwt.Font() font0.bold = True font0.height = 300 print font0.height style0 = xlwt.XFStyle() style0.font = font0 style1 = xlwt.XFStyle() style1.num_format_str = 'D-MMM-YY' wb = xlwt.Workbook() ws = wb.add_sheet('A Test Sheet') ws.write(0, 0, 'Test', style0) ws.write(2, 0, 1) ws.write(2, 1, 1) ws.write(2, 2, xlwt.Formula("A3+B3")) wb.save('datasheet.xls') os.system("gnumeric datasheet.xls")
def loadFromStream(self, stream, huella=True, run=True): """Read project from stream huella: boolean to save project file to pychemqt_temporal""" # read configuration config = ConfigParser() for i in range(stream.readInt32()): section = stream.readString() config.add_section(section) for contador_option in range(stream.readInt32()): option = stream.readString() valor = stream.readString() config.set(section, option, valor) #TODO: Necesario para cargar los proyectos viejos # config.set("Thermo", "freesteam", "False") config.set("Units", "MolarSpecificHeat", "0") self.setConfig(config) if not huella: os.rename(conf_dir + "pychemqtrc_temporal", conf_dir + "pychemqtrc_temporal_bak") config.write(open(conf_dir + "pychemqtrc_temporal", "w")) # read equipments items = {} contador_equipos = stream.readInt32() for i in range(contador_equipos): id = stream.readString() if id[0] == "e": equip = equipments[stream.readInt32()]() equip.readFromStream(stream, run) else: equip = None items[id] = equip self.setItems(items) # read streams streams = {} contador_streams = stream.readInt32() for item in range(contador_streams): id = stream.readInt32() up = stream.readString() down = stream.readString() ind_up = stream.readInt32() ind_down = stream.readInt32() obj = Corriente() obj.readFromStream(stream, run) streams[id] = (up, down, ind_up, ind_down, obj) if huella: if down[0] == "e": equip = self.items[down] if isinstance(equip, Mixer): kwargs = {"entrada": obj, "id_entrada": ind_down} else: kwargs = {equip.kwargsInput[ind_down]: obj} equip(**kwargs) self.setStreams(streams) if not huella: os.rename(conf_dir + "pychemqtrc_temporal_bak", conf_dir + "pychemqtrc_temporal")
(QApplication.translate("pychemqt", "Purchase Cost"), "C_adq", Currency), (QApplication.translate("pychemqt", "Installed Cost"), "C_inst", Currency) ] return list if __name__ == '__main__': # import doctest # doctest.testmod() # corriente=Corriente(T=400, P=101325, caudalMasico=0.1, fraccionMasica=[1., 0, 0, 0]) # compresor=Compressor(entrada=corriente, metodo=1, termodinamica=0, razon=3, rendimiento=0.75, etapas=1) # print compresor.power.kW # compresor(compresor=2, transmision=1, motor=0, rpm=1) # print compresor.C_inst corriente = Corriente(T=873.15, P=1013250, caudalMasico=0.1, fraccionMasica=[1.]) turbina = Turbine(entrada=corriente, metodo=1, razon=0.3, rendimiento=0.5) print turbina.power.MJh print turbina.C_inst print turbina.salida[0].T # agua=Corriente(T=500, P=101325., caudalMasico=1, fraccionMasica=[1.]) # print agua.P*2 # compresor=Compressor(entrada=agua, Pout=5*101325, rendimiento=0.75)
decimales=2) self.C_inst.setReadOnly(True) layout.addWidget(self.C_inst, 1, 2) lyt_Cost.addItem( QtWidgets.QSpacerItem(20, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding), 13, 0, 1, 6) # Output tab self.addSalida( QtWidgets.QApplication.translate("pychemqt", "Destilate")) self.addSalida(QtWidgets.QApplication.translate("pychemqt", "Residue")) if equipment: self.setEquipment(equipment) if __name__ == "__main__": import sys from lib.corriente import Corriente app = QtWidgets.QApplication(sys.argv) entrada = Corriente(T=340, P=101325, caudalMasico=0.01, ids=[10, 38, 22, 61], fraccionMolar=[.3, 0.5, 0.05, 0.15]) flash = Flash(entrada=entrada) dialogo = UI_equipment(flash) dialogo.show() sys.exit(app.exec_())
self.rendimientoAdmisible.setResaltado(tipo_calculo) self.changeParams("metodo", tipo_calculo) if __name__ == "__main__": import sys from lib.corriente import Corriente, Solid app = QtWidgets.QApplication(sys.argv) diametros = [ 17.5e-6, 22.4e-6, 26.2e-6, 31.8e-6, 37e-6, 42.4e-6, 48e-6, 54e-6, 60e-6, 69e-6, 81.3e-6, 96.5e-6, 109e-6, 127e-6 ] fracciones = [ 0.02, 0.03, 0.05, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.05, 0.03, 0.02 ] solido = Solid(caudalSolido=[0.1], distribucion_diametro=diametros, distribucion_fraccion=fracciones) corriente = Corriente(T=300, P=101325, caudalMasico=1., fraccionMolar=[1.], solido=solido) precipitador = ElectricPrecipitator(entrada=corriente, metodo=1, rendimientoAdmisible=0.9) dialogo = UI_equipment(precipitador) dialogo.show() sys.exit(app.exec_())
class Pump(equipment): """Clase que modela un equipo de bombeo de líquidos Parámetros: entrada: instancia de la clase corriente que define la corriente de entrada en la bomba usarCurva: 0 - Funcionamiento fijo 1 - Funcionamiento siguiendo la curva característica incognita: Indica la variable a calcular en el caso de que se use la curva caracteristica 0 - Carga (incremento de presión) 1 - Caudal, en este caso sobreescribe el caudal de la corriente de entrada rendimiento: rendimiento de la bomba, no necesario si se ha definido la curva característica de la bomba deltaP: incremento de presión proporcionado por la bomba, no será necesario si se define la curva característica y es el caudal la variable a calcular, en atmosferas Pout: Presión a la salida de la bomba Carga: Cambio de presión basada en altura de columna de fluido curvaCaracteristica: array que define la curva característica, en la forma: [Dia, rpm, [Q1,..Qn], [h1,...,hn], [Pot1,...,Potn], [NPSH1,...NPSHn]]. diametro: diametro nominal bomba velocidad: velocidad de giro de la bomba Coste tipo_bomba 0 - Centrifugal pumps 1 - Reciprocating pumps 2 - Gear pumps 3 - Vertical mixed flow 4 - Vertical axial flow tipo_centrifuga 0 - One stage, 3550 rpm, VSC 1 - One stage, 1750 rpm, VSC 2 - One stage, 3550 rpm, HSC 3 - One stage, 1750 rpm, HSC 4 - Two stage, 3550 rpm, HSC 5 - Multistage, 3550 rpm, HSC Material 0 - Cast iron 1 - Case steel 2 - 304 or 316 fittings 3 - Stainless steel 304 or 316 4 - Case Gould's alloy no. 20 5 - Nickel 6 - Monel 7 - ISO B 8 - ISO B 9 - Titanium 10 - Hastelloy C 11 - Ductile iron 12 - Bronze motor: Tipo de motor 0 - Open drip-proof 1 - Totally enclosed, fan-cooled 2 - Explosion-proof rpm 0 - 3600 rpm 1 - 1800 rpm 2 - 1200 rpm >>> agua=Corriente(T=300, P=101325, caudalMasico=1, fraccionMolar=[1.]) >>> bomba=Pump(entrada=agua, rendimiento=0.75, deltaP=20*101325, tipo_bomba=1) >>> print bomba.power.hp 3.63596053358 >>> print bomba.C_inst 3493.24497823 """ title=QApplication.translate("pychemqt", "Pump") help="" kwargs={"entrada": None, "usarCurva": 0, "incognita": 0, "rendimiento": 0.0, "deltaP": 0.0, "Pout": 0.0, "Carga": 0.0, "curvaCaracteristica": [], "diametro": 0.0, "velocidad": 0.0, "f_install": 2.8, "Base_index": 0.0, "Current_index": 0.0, "tipo_bomba": 0, "tipo_centrifuga": 0, "material": 0, "motor": 0, "rpm": 0} kwargsInput=("entrada", ) kwargsCheck=("usarCurva", ) kwargsValue=("Pout", "deltaP", "rendimiento", "Carga", "diametro", "velocidad") kwargsList=("incognita", "tipo_bomba", "tipo_centrifuga", "material", "motor", "rpm") calculateValue=("PoutCalculada", "power", "headCalculada", "volflow", "rendimientoCalculado") calculateCostos=("C_bomba", "C_motor", "C_adq", "C_inst") indiceCostos=7 TEXT_BOMBA=[QApplication.translate("pychemqt", "Centrifugal"), QApplication.translate("pychemqt", "Reciprocating"), QApplication.translate("pychemqt", "Gear pump"), QApplication.translate("pychemqt", "Vertical mixed flow"), QApplication.translate("pychemqt", "Vertical axial flow")] TEXT_CENTRIFUGA=[QApplication.translate("pychemqt", "One stage, 3550 rpm, VSC"), QApplication.translate("pychemqt", "One stage, 1750 rpm, VSC"), QApplication.translate("pychemqt", "One stage, 3550 rpm, HSC"), QApplication.translate("pychemqt", "One stage, 1750 rpm, HSC"), QApplication.translate("pychemqt", "Two stage, 3550 rpm, HSC"), QApplication.translate("pychemqt", "Multistage, 3550 rpm, HSC")] TEXT_MATERIAL=[QApplication.translate("pychemqt", "Cast iron"), QApplication.translate("pychemqt", "Case steel"), QApplication.translate("pychemqt", "304 or 316 fittings"), QApplication.translate("pychemqt", "Stainless steel 304 or 316"), QApplication.translate("pychemqt", "Case Gould's alloy no. 20"), QApplication.translate("pychemqt", "Nickel"), QApplication.translate("pychemqt", "Monel (Ni-Cu)"), QApplication.translate("pychemqt", "ISO B"), QApplication.translate("pychemqt", "ISO C"), QApplication.translate("pychemqt", "Titanium"), QApplication.translate("pychemqt", "Hastelloy C (Ni-Fe-Mo)"), QApplication.translate("pychemqt", "Ductile iron"), QApplication.translate("pychemqt", "Bronze")] TEXT_MOTOR=[QApplication.translate("pychemqt", "Open drip-proof"), QApplication.translate("pychemqt", "Totally enclosed, fan-cooled"), QApplication.translate("pychemqt", "Explosion-proof")] TEXT_RPM=["3600 RPM", "1800 RPM", "1200 RPM"] @property def isCalculable(self): if self.kwargs["f_install"] and self.kwargs["Base_index"] and self.kwargs["Current_index"]: self.statusCoste=True else: self.statusCoste=False if not self.kwargs["entrada"]: self.msg=QApplication.translate("pychemqt", "undefined input") self.status=0 else: presion=self.kwargs["Pout"] or self.kwargs["deltaP"] or self.kwargs["Carga"] if self.kwargs["usarCurva"]: if self.kwargs["incognita"]: if presion and self.kwargs["curvaCaracteristica"]: self.msg="" self.status=1 return True elif presion: self.msg=QApplication.translate("pychemqt", "undefined pump curve") self.status=0 else: self.msg=QApplication.translate("pychemqt", "undefined out pressure condition") self.status=0 elif self.kwargs["curvaCaracteristica"]: self.msg="" self.status=1 return True else: self.msg=QApplication.translate("pychemqt", "undefined pump curve") self.status=0 else: if presion and self.kwargs["rendimiento"]: self.msg="" self.status=1 return True elif presion: self.msg=QApplication.translate("pychemqt", "undefined efficiency") self.status=0 else: self.msg=QApplication.translate("pychemqt", "undefined out pressure condition") self.status=0 def calculo(self): self.entrada=self.kwargs["entrada"] self.rendimientoCalculado=Dimensionless(self.kwargs["rendimiento"]) if self.kwargs["Pout"]: DeltaP=Pressure(self.kwargs["Pout"]-self.entrada.P) elif self.kwargs["deltaP"]: DeltaP=Pressure(self.kwargs["deltaP"]) elif self.kwargs["Carga"]: DeltaP=Pressure(self.kwargs["Carga"]*self.entrada.Liquido.rho*g) else: DeltaP=Pressure(0) if self.kwargs["usarCurva"]: if self.kwargs["diametro"]!=self.kwargs["curvaCaracteristica"][0] or self.kwargs["velocidad"]!=self.kwargs["curvaCaracteristica"][1]: self.curvaActual=self.calcularCurvaActual() else: self.curvaActual=self.kwargs["curvaCaracteristica"] self.Ajustar_Curvas_Caracteristicas() if not self.kwargs["usarCurva"]: head=Length(DeltaP/g/self.entrada.Liquido.rho) power=Power(head*g*self.entrada.Liquido.rho*self.entrada.Q/self.rendimientoCalculado) P_freno=Power(power*self.rendimientoCalculado) elif not self.kwargs["incognita"]: head=Length(polyval(self.CurvaHQ,self.entrada.Q)) self.DeltaP=Pressure(head*g*self.entrada.Liquido.rho) power=Power(self.entrada.Q*DeltaP) P_freno=Power(polyval(self.CurvaPotQ,self.entrada.Q)) self.rendimientoCalculado=Dimensionless(power/P_freno) else: head=Length(self.DeltaP/g/self.entrada.Liquido.rho) caudalvolumetrico=roots([self.CurvaHQ[0], self.CurvaHQ[1], self.CurvaHQ[2]-head])[0] power=Power(caudalvolumetrico*self.DeltaP) self.entrada=Corriente(self.entrada.T, self.entrada.P.atm, caudalvolumetrico*self.entrada.Liquido.rho*3600, self.entrada.mezcla, self.entrada.solido) P_freno=Power(polyval(self.CurvaPotQ,caudalvolumetrico)) self.rendimientoCalculado=Dimensionless(power/P_freno) self.headCalculada=head self.power=power self.P_freno=P_freno self.salida=[self.entrada.clone(P=self.entrada.P+DeltaP)] self.Pin=self.entrada.P self.PoutCalculada=self.salida[0].P self.Q=self.entrada.Q.galUSmin self.volflow=self.entrada.Q def Ajustar_Curvas_Caracteristicas(self): """Define la curva característica de la bomba a partir de los datos, todos ellos en forma de array de igual dimensión Q: caudal, m3/s h: carga, m mu: rendimiento NPSHr: carga neta de aspiración requerida por la bomba para no entrar en cavitación """ Q=r_[self.curvaActual[2]] h=r_[self.curvaActual[3]] Pot=r_[self.curvaActual[4]] NPSH=r_[self.curvaActual[5]] funcion_h = lambda p, x: p[0]*x**2+p[1]*x+p[2] # Función a ajustar residuo_h = lambda p, x, y: funcion_h(p, x) - y # Residuo inicio=r_[0, 0, 0] ajuste_h, exito_h=optimize.leastsq(residuo_h,inicio,args=(Q, h)) self.CurvaHQ=ajuste_h funcion_Pot = lambda p, x: p[0]*x**2+p[1]*x+p[2] # Función a ajustar residuo_Pot = lambda p, x, y: funcion_Pot(p, x) - y # Residuo inicio=r_[0, 0, 0] ajuste_Pot, exito_Pot=optimize.leastsq(residuo_Pot,inicio,args=(Q, Pot)) self.CurvaPotQ=ajuste_Pot funcion_NPSH = lambda p, x: p[0]+p[1]*exp(p[2]*x) # Función a ajustar residuo_NPSH = lambda p, x, y: funcion_NPSH(p, x) - y # Residuo inicio=r_[0, 0, 0] ajuste_NPSH, exito_NPSH=optimize.leastsq(residuo_NPSH,inicio,args=(Q, NPSH)) self.CurvaNPSHQ=ajuste_NPSH def calcularCurvaActual(self): """Método que define curvas caracteristica de la bomba a una velocidad de giro y diametro del propulsor diferente de la curva característica original haciendo uso de las leyes de afinidad, perry 10.25 Table 10.7""" D1=self.kwargs["curvaCaracteristica"][0] N1=self.kwargs["curvaCaracteristica"][1] D2=self.kwargs["diametro"] N2=self.kwargs["velocidad"] Q1=r_[self.kwargs["curvaCaracteristica"][2]] h1=r_[self.kwargs["curvaCaracteristica"][3]] Pot1=r_[self.kwargs["curvaCaracteristica"][4]] npsh1=r_[self.kwargs["curvaCaracteristica"][5]] Q2=Q1*D2/D1*N2/N1 h2=h1*N2**2/N1**2*D2**2/D1**2 Pot2=Pot1*N2**3/N1**3*D2**3/D1**3 npsh2=npsh1*N2**2/N1**2*D2**2/D1**2 #Esta relación no es tan fiable como las anteriores return [D2, N2, Q2, h2, Pot2, npsh2] def coste(self): HP=self.power.hp LnHP = log(self.power.hp) #Coste Bomba if self.kwargs["tipo_bomba"]==0: #Centrifugal pumps QH=log(self.Q*self.power.hp**0.5) Fm=[1., 1.35, 1.15, 2., 2., 3.5, 3.3, 4.95, 4.6, 9.7, 2.95, 1.15, 1.90] b1=[0., 5.1029, 0.0632, 2.0290, 13.7321, 9.8849][self.kwargs["tipo_centrifuga"]] b2=[0., -1.2217, 0.2744, -0.2371, -2.8304, -1.6164][self.kwargs["tipo_centrifuga"]] b3=[0., 0.0771, -0.0253, 0.0102, 0.1542, 0.0834][self.kwargs["tipo_centrifuga"]] Ft = exp(b1 + b2 * QH + b3 * QH**2) Cb=Fm[self.kwargs["material"]]*Ft*1.55*exp(8.833-0.6019*QH+0.0519*QH**2) elif self.kwargs["tipo_bomba"]==1: #Reciprocating pumps if self.kwargs["material"] == 0: #Case iron Cb=40.*self.Q**0.81 elif self.kwargs["material"] == 3: #316 Staineless steel Cb = 410.*self.Q**0.52 elif self.kwargs["material"] == 12: #Bronze Cb = 410.* 1.4 * self.Q**0.52 elif self.kwargs["material"] == 5: #Nickel Cb = 410. * 1.86 * self.Q**0.52 elif self.kwargs["material"] == 6: #Monel Cb = 410. * 2.20 * self.Q**0.52 else: #Material not available. Assume case iron Cb = 40. *self.Q**0.81 elif self.kwargs["tipo_bomba"]==2: #Gear pumps Cb=1000*exp(-0.0881+0.1986*log(self.Q)+0.0291*log(self.Q)**2) elif self.kwargs["tipo_bomba"]==3: #Vertical mixed flow Cb=0.036*self.Q**0.82*1000 elif self.kwargs["tipo_bomba"]==4: #Vertical axial flow Cb=0.02*self.Q**0.78*1000 C_bomba=Cb * self.kwargs["Current_index"] / self.kwargs["Base_index"] #Coste motor if self.kwargs["motor"] == 0: #Open, drip-proof if self.kwargs["rpm"] == 0 and HP <= 7.5: a1, a2, a3 = 4.8314, 0.0966, 0.10960 elif self.kwargs["rpm"] == 0 and 7.5< HP <= 250.: a1, a2, a3 = 4.1514, 0.5347, 0.05252 elif self.kwargs["rpm"] == 0 and HP > 250.: a1, a2, a3 = 4.2432, 1.03251, -0.03595 elif self.kwargs["rpm"] == 1 and HP <= 7.5: a1, a2, a3 = 4.7075, -0.01511, 0.22888 elif self.kwargs["rpm"] == 1 and 7.5< HP <= 250: a1, a2, a3 = 4.5212, 0.47242, 0.04820 elif self.kwargs["rpm"] == 1 and HP > 250.: a1, a2, a3 = 7.4044, -0.06464, 0.05448 elif self.kwargs["rpm"] == 2 and HP <= 7.5: a1, a2, a3 = 4.9298, 0.30118, 0.12630 elif self.kwargs["rpm"] == 2 and 7.5< HP <= 250: a1, a2, a3 = 5.0999, 0.35861, 0.06052 elif self.kwargs["rpm"] == 2 and HP > 250.: a1, a2, a3 = 4.6163, 0.88531, -0.02188 elif self.kwargs["motor"] == 1: #Totally enclosed, fan-cooled if self.kwargs["rpm"] == 0 and HP <= 7.5: a1, a2, a3 = 5.1058, 0.03316, 0.15374 elif self.kwargs["rpm"] == 0 and 7.5< HP <= 250.: a1, a2, a3 = 3.8544, 0.83311, 0.02399 elif self.kwargs["rpm"] == 0 and HP > 250.: a1, a2, a3 = 5.3182, 1.08470, -0.05695 elif self.kwargs["rpm"] == 1 and HP <= 7.5: a1, a2, a3 = 4.9687, -0.00930, 0.22616 elif self.kwargs["rpm"] == 1 and HP > 7.5: a1, a2, a3 = 4.5347, 0.57065, 0.04609 elif self.kwargs["rpm"] == 2 and HP <= 7.5: a1, a2, a3 = 5.1532, 0.28931, 0.14357 elif self.kwargs["rpm"] == 2 and HP > 7.5: a1, a2, a3 = 5.3858, 0.31004, 0.07406 elif self.kwargs["motor"] == 2: #Explosion-proof if self.kwargs["rpm"] == 0 and HP <= 7.5: a1, a2, a3 = 5.3934, -0.00333, 0.15475 elif self.kwargs["rpm"] == 0 and HP > 7.5: a1, a2, a3 = 4.4442, 0.60820, 0.05202 elif self.kwargs["rpm"] == 1 and HP <= 7.5: a1, a2, a3 = 5.2851, 0.00048, 0.19949 elif self.kwargs["rpm"] == 1 and HP > 7.5: a1, a2, a3 = 4.8178, 0.51086, 0.05293 elif self.kwargs["rpm"] == 2 and HP <= 7.5: a1, a2, a3 = 5.4166, 0.31216, 0.10573 elif self.kwargs["rpm"] == 2 and HP > 7.5: a1, a2, a3 = 5.5655, 0.31284, 0.07212 C_motor = 1.2 * exp(a1 + a2 * LnHP + a3 * LnHP**2) * self.kwargs["Current_index"] / self.kwargs["Base_index"] self.C_bomba=Currency(C_bomba) self.C_motor=Currency(C_motor) self.C_adq=Currency(C_bomba+C_motor) self.C_inst=Currency(self.C_adq*self.kwargs["f_install"]) def propTxt(self): txt="#---------------"+QApplication.translate("pychemqt", "Calculate properties")+"-----------------#"+os.linesep txt+="%-25s\t%s" %(QApplication.translate("pychemqt", "Input Pressure"), self.entrada.P.str)+os.linesep txt+="%-25s\t%s" %(QApplication.translate("pychemqt", "Output Pressure"), self.salida[0].P.str)+os.linesep txt+="%-25s\t%s" %(QApplication.translate("pychemqt", "Head"), self.headCalculada.str)+os.linesep txt+="%-25s\t%s" %(QApplication.translate("pychemqt", "Brake horsepower"), self.P_freno.str)+os.linesep txt+="%-25s\t%s" %(QApplication.translate("pychemqt", "Volumetric Flow"), self.volflow.str)+os.linesep txt+="%-25s\t%s" %(QApplication.translate("pychemqt", "Power"), self.power.str)+os.linesep txt+="%-25s\t %0.4f" %(QApplication.translate("pychemqt", "Efficiency"), self.rendimientoCalculado)+os.linesep txt+="%-25s\t %0.4f" %("Cp/Cv", self.entrada.Liquido.cp_cv)+os.linesep if self.statusCoste: txt+=os.linesep txt+="#---------------"+QApplication.translate("pychemqt", "Preliminary Cost Estimation")+"-----------------#"+os.linesep txt+="%-25s\t %0.2f" %(QApplication.translate("pychemqt", "Base index"), self.kwargs["Base_index"])+os.linesep txt+="%-25s\t %0.2f" %(QApplication.translate("pychemqt", "Current index"), self.kwargs["Current_index"])+os.linesep txt+="%-25s\t %0.2f" %(QApplication.translate("pychemqt", "Install factor"), self.kwargs["f_install"])+os.linesep txt+="%-25s\t %s" %(QApplication.translate("pychemqt", "Pump type"), self.TEXT_BOMBA[self.kwargs["tipo_bomba"]]) if self.kwargs["tipo_bomba"]==0: txt+=", "+self.TEXT_CENTRIFUGA[self.kwargs["tipo_centrifuga"]]+os.linesep else: txt+=os.linesep txt+="%-25s\t %s" %(QApplication.translate("pychemqt", "Material"), self.TEXT_MATERIAL[self.kwargs["material"]])+os.linesep txt+="%-25s\t%s" %(QApplication.translate("pychemqt", "Pump Cost"), self.C_bomba.str)+os.linesep txt+="%-25s\t %s, %s" %(QApplication.translate("pychemqt", "Motor type"), self.TEXT_MOTOR[self.kwargs["motor"]], self.TEXT_RPM[self.kwargs["rpm"]])+os.linesep txt+="%-25s\t%s" %(QApplication.translate("pychemqt", "Motor Cost"), self.C_motor.str)+os.linesep txt+="%-25s\t%s" %(QApplication.translate("pychemqt", "Purchase Cost"), self.C_adq.str)+os.linesep txt+="%-25s\t%s" %(QApplication.translate("pychemqt", "Installed Cost"), self.C_inst.str)+os.linesep return txt @classmethod def propertiesEquipment(cls): list=[(QApplication.translate("pychemqt", "Input Pressure"), "Pin", Pressure), (QApplication.translate("pychemqt", "Output Pressure"), "PoutCalculada", Pressure), (QApplication.translate("pychemqt", "Head"), "headCalculada", Length), (QApplication.translate("pychemqt", "Brake horsepower"), "P_freno", Power), (QApplication.translate("pychemqt", "Volumetric Flow"), "volflow", VolFlow), (QApplication.translate("pychemqt", "Power"), "power", Power), (QApplication.translate("pychemqt", "Efficiency"), "rendimientoCalculado", Dimensionless), (QApplication.translate("pychemqt", "Pump Type"), ("TEXT_BOMBA", "tipo_bomba"), str), (QApplication.translate("pychemqt", "Centrifuge Type"), ("TEXT_CENTRIFUGA", "tipo_centrifuga"), str), (QApplication.translate("pychemqt", "Material"), ("TEXT_MATERIAL", "material"), str), (QApplication.translate("pychemqt", "Motor Type"), ("TEXT_MOTOR", "motor"), str), (QApplication.translate("pychemqt", "Motor RPM"), ("TEXT_RPM", "rpm"), str), (QApplication.translate("pychemqt", "Pump Cost"), "C_bomba", Currency), (QApplication.translate("pychemqt", "Motor Cost"), "C_motor", Currency), (QApplication.translate("pychemqt", "Purchase Cost"), "C_adq", Currency), (QApplication.translate("pychemqt", "Installed Cost"), "C_inst", Currency)] return list def datamap2xls(self): datamap=(("PoutCalculada", "value", "H15"), ("PoutCalculada", "unit", "I15"), ("Pin", "value", "H16"), ("Pin", "unit", "I16"), ) return datamap def export2pdf(self): bomba=pdf("Bomba") bomba.bomba(self) bomba.dibujar() os.system("evince datasheet.pdf") def export2xls(self): font0 = xlwt.Font() font0.bold = True font0.height = 300 print font0.height style0 = xlwt.XFStyle() style0.font = font0 style1 = xlwt.XFStyle() style1.num_format_str = 'D-MMM-YY' wb = xlwt.Workbook() ws = wb.add_sheet('A Test Sheet') ws.write(0, 0, 'Test', style0) ws.write(2, 0, 1) ws.write(2, 1, 1) ws.write(2, 2, xlwt.Formula("A3+B3")) wb.save('datasheet.xls') os.system("gnumeric datasheet.xls")
# project.setInput(2, fria) # Cambiador(modo=1, # DiTube=0.0525, DeTube=0.0603, DeeTube=0.0779, kTube=54, rTube=0.0459994e-3, # annulliFouling= 0.000352, tubeFouling=0.000176, LTube=2.5) # project.setItem(1, Cambiador) # print project.getOutput(1), project.getStream(2) # eq=project.getItem(1) # print eq.kwargs # print eq.status, eq.msg # print "Project has cycle: ", project.hasCycle() # bomba(entrada=entrada, rendimiento=0.75, deltaP=2) # # items={"i1": entrada, "e1": bomba} # streams=[("i1", "e1", 0, 0), ("e1", "o1", 0, 0)] # # project=Project(items=items, streams=streams) # project.printer() # print dir(gv) # print gv.nextin(project.graph) project = Project() project.addItem("i1", Corriente()) project.addItem("i2", Corriente()) mezclador = Mixer() project.addItem("e1", mezclador) project.addStream(1, "i1", "e1", ind_down=0) project.addStream(2, "i2", "e1", ind_down=1) project.addItem("o1", Corriente()) project.addStream(3, "e1", "o1")
# NHPS=r_[0]*9 # bomba(entrada=agua, usarCurva=1, calculo=1, DeltaP=DeltaP.atm, curvaCaracteristica=[3.5, 1500, Q, h, Pot, NHPS]) ## print bomba.head, "m" ## print bomba.entrada.caudal_volumetrico.m3h, "m3h" ## print bomba.rendimiento*100, "%" ## print bomba.power.hp, "HP, ", bomba.power.kW, "kW" ## print bomba.salida.P.atm, "atm" ## print agua.caudal_volumetrico.m3h, bomba.entrada.caudal_volumetrico.m3h # bomba.coste(2.8, 421.2, 600) ## print bomba.C_bomba, bomba.C_motor, bomba.C_adq, bomba.C_inst ## print bomba.C_inst # bomba.export2xls() agua = Corriente(T=275, P=101325., ids=[62], caudalMasico=1, fraccionMolar=[1.]) bomba = Pump(entrada=agua, rendimiento=0.75, deltaP=20 * 101325, tipo_bomba=1) # print bomba.power.hp # print bomba.C_inst # print bool(bomba) # bomba.clear() # print bomba.__dict__ # print bool(bomba) # bomba=Pump() # print bomba.__class__
lyt_Calc.addWidget(QtWidgets.QLabel(QtWidgets.QApplication.translate( "pychemqt", "T bubble point")), 6, 1) self.Bubble = Entrada_con_unidades(Temperature) self.Bubble.valueChanged.connect(partial(self.changeParams, "Bubble")) lyt_Calc.addWidget(self.Bubble, 6, 2) lyt_Calc.addItem(QtWidgets.QSpacerItem( 20, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding), 10, 1, 1, 6) self.criterio_Changed(0) if equipment: self.setEquipment(equipment) def criterio_Changed(self, int): self.Pout.setEnabled(int == 1) self.DeltaP.setEnabled(int == 1) self.Dew.setEnabled(int == 1) self.Bubble.setEnabled(int == 1) self.calculo(off=int) if __name__ == "__main__": import sys from lib.corriente import Corriente app = QtWidgets.QApplication(sys.argv) agua = Corriente(T=300, P=101325, caudalMasico=1, fraccionMasica=[1.]) valvula = Valve(entrada=agua, off=1, DeltaP=1000) dialogo = UI_equipment(valvula) dialogo.show() sys.exit(app.exec_())
list = [(QApplication.translate("pychemqt", "Output Temperature"), "outT", unidades.Temperature), (QApplication.translate("pychemqt", "Output Pressure"), "outP", unidades.Pressure), (QApplication.translate("pychemqt", "Output vapor fraction"), "outX", unidades.Dimensionless), (QApplication.translate("pychemqt", "Working Condition"), ("TEXT_WORKING", "off"), str)] return list if __name__ == '__main__': # import doctest # doctest.testmod() agua = Corriente(T=300, P=101325, caudalMasico=1, fraccionMasica=[1.]) # agua2=Corriente(T=300, P=101325*2, caudalMasico=2, fraccionMasica=[1.]) mezclador = Mixer(entrada=[agua, Corriente()], criterio=0) # print mezclador.status, mezclador.msg print mezclador.salida[0].kwargs # print mezclador.salida[0].caudalmasico, # agua3=Corriente(T=300, P=101325, caudalMasico=4, fraccionMasica=[1., 0, 0, 0]) # mezclador(id_entrada=2, entrada=agua3) # print mezclador.salida[0].caudalmasico # agua=Corriente(T=300, P=101325, caudalMasico=1, fraccionMolar=[0.3, 0.2, 0.25, 0.25]) # divisor=Divider(entrada=agua, salidas=3) # divisor(split=[0.3, 0.45, 0.25]) # print divisor.status, divisor.kwargs["salidas"], divisor.msg # # agua=Corriente(T=300, P=101325, caudalMasico=1, fraccionMasica=[1., 0, 0, 0])