#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""Pychemqt, Chemical Engineering Process simulator
Copyright (C) 2009-2025, Juan José Gómez Romera <jjgomera@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
.. include:: UI_corriente.rst
Module with UI utilities
* :class:`Ui_corriente`: Widget for general stream input
* :class:`Corriente_Dialog`: QDialog for stream input
* :class:`StreamDefinition`: Stream definition with P,T,x,composition input
* :class:`PsychroDefinition`: Stream definition as humid air input
* :class:`StreamProperties`: Table for show stream properties
* :class:`SolidDefinition`: Solid particle stream definition
* :class:`SolidDistribution`: Dialog for define particle solid distribution
The module with library is in `<lib.corriente.html>`__
"""
from functools import partial
from math import exp, log
from tools.qt import QtCore, QtGui, QtWidgets
from numpy import all
from scipy.special import erf
from tools.UI_confThermo import UI_confThermo_widget
from tools.UI_psychrometry import PsychroInput
from lib import unidades, config
from lib.corriente import Corriente, Solid, PsyStream
from lib.thread import Evaluate
from UI import texteditor
from UI.widgets import Tabla, Entrada_con_unidades, Status
[docs]
class Ui_corriente(QtWidgets.QWidget):
"""Wdiget for global stream edit/view"""
Changed = QtCore.pyqtSignal(Corriente)
corriente = Corriente()
[docs]
def __init__(self, corriente=None, readOnly=False, psychro=False,
parent=None):
"""
corriente: Corriente instance to initialize widget
readOnly: Set initial readOnly state for widget
psychro: boolean to show aditional input stream por humid air
"""
super().__init__(parent)
self.setWindowTitle(self.tr("Stream"))
self.readOnly = readOnly
self.psychro = psychro
self.semaforo = QtCore.QSemaphore(1)
self.evaluate = Evaluate()
self.evaluate.finished.connect(self.repaint)
self.indices, self.nombres, M = config.getComponents()
self.solidos, nameSol, M = config.getComponents(solidos=True)
gridLayout1 = QtWidgets.QVBoxLayout(self)
self.toolBox = QtWidgets.QTabWidget()
self.toolBox.setTabPosition(QtWidgets.QTabWidget.TabPosition.South)
gridLayout1.addWidget(self.toolBox)
# Standard definition
self.pageDefinition = StreamDefinition()
self.pageDefinition.changedFraction.connect(self.calculo)
self.pageDefinition.changedValue.connect(self.calculo)
self.toolBox.addTab(
self.pageDefinition,
QtGui.QIcon(config.IMAGE_PATH + "button/in.png"),
self.tr("Definition"))
# Configuration per stream
self.pageConfig = UI_confThermo_widget()
self.pageConfig.changed.connect(self.calculo)
self.toolBox.addTab(
self.pageConfig,
QtGui.QIcon(config.IMAGE_PATH + "button/configure.png"),
self.tr("Thermodynamic"))
# Humid Air
if psychro:
self.pagePsychro = PsychroDefinition(readOnly=readOnly)
self.pagePsychro.Changed.connect(self.changePsychroState)
self.toolBox.addTab(
self.pagePsychro,
QtGui.QIcon(config.IMAGE_PATH + "button/psychrometric.png"),
self.tr("Humid Air"))
# Solid
self.pageSolids = SolidDefinition()
self.pageSolids.Changed.connect(self.changeSolid)
self.toolBox.addTab(self.pageSolids, self.tr("Solid"))
self.pageSolids.setEnabled(len(self.solidos))
# # Electrolite
# self.pageElectrolite = QtGui.QWidget()
# lyt_Electrolitos = QtGui.QGridLayout(self.pageElectrolite)
# lyt_Electrolitos.addWidget(QtGui.QLabel(self.tr(
# "No implemented")), 0, 0, 1, 1)
# self.toolBox.addTab(self.pageElectrolite,self.tr(
# "Electrolitos"))
# Properties
self.pageProperties = StreamProperties()
self.toolBox.addTab(
self.pageProperties,
QtGui.QIcon(config.IMAGE_PATH + "button/helpAbout.png"),
self.tr("Properties"))
# Notes
self.PageNotas = texteditor.TextEditor()
self.toolBox.addTab(
self.PageNotas,
QtGui.QIcon(config.IMAGE_PATH + "button/editor.png"),
self.tr("Notes"))
if corriente:
self.setCorriente(corriente)
else:
self.corriente = Corriente()
self.repaint()
self.setReadOnly(readOnly)
self.PageNotas.textChanged.connect(self.corriente.setNotas)
[docs]
def setReadOnly(self, bool):
self.pageDefinition.setReadOnly(bool)
self.pageSolids.setReadOnly(bool)
[docs]
def setCorriente(self, corriente, psychro=True):
if corriente:
self.corriente = corriente
self.repaint()
[docs]
def changePsychroState(self, stream):
self.setCorriente(stream.corriente, False)
[docs]
def changeSolid(self, solido):
self.corriente.setSolid(solido)
self.Changed.emit(self.corriente)
[docs]
def repaint(self, psychro=True):
# Parameter to avoid recursive repaint
if self.semaforo.available() > 0:
self.semaforo.acquire(1)
self.pageDefinition.setStream(self.corriente)
self.pageConfig.setKwargs(self.corriente.kwargs)
if psychro and self.psychro:
psystream = self.corriente.psystream
self.pagePsychro.setStream(psystream)
self.pageSolids.setSolido(self.corriente.solido)
self.PageNotas.setText(self.corriente.notas)
self.pageProperties.fill(self.corriente)
if isinstance(self, QtWidgets.QDialog):
self.status.setState(self.corriente.status, self.corriente.msg)
if self.corriente.status == 1:
self.Changed.emit(self.corriente)
self.semaforo.release(1)
[docs]
def calculo(self, variable=None, valor=None):
if self.semaforo.available() > 0:
if isinstance(self, QtWidgets.QDialog):
self.status.setState(4)
kwargs = self.pageConfig.kwargs
if variable:
kwargs[variable] = valor
self.salida(**kwargs)
[docs]
def salida(self, **kwargs):
"""Función que crea la instancia corriente"""
if not kwargs:
kwargs = self.pageDefinition.kwargs()
kwargs.update(self.pageConfig.kwargs)
kwargs["solido"] = self.pageSolids.solido
if not self.evaluate.isRunning():
self.evaluate.start(self.corriente, kwargs)
[docs]
class Corriente_Dialog(QtWidgets.QDialog, Ui_corriente):
"""Dialog to define stream with status added"""
Changed = QtCore.pyqtSignal(Corriente)
corriente = Corriente()
[docs]
def __init__(self, corriente=None, readOnly=False, psychro=False,
parent=None):
layout = QtWidgets.QHBoxLayout()
self.status = Status()
layout.addWidget(self.status)
buttonBox = QtWidgets.QDialogButtonBox(
QtWidgets.QDialogButtonBox.StandardButton.Ok
| QtWidgets.QDialogButtonBox.StandardButton.Cancel)
buttonBox.accepted.connect(self.accept)
buttonBox.rejected.connect(self.reject)
layout.addWidget(buttonBox)
super(Corriente_Dialog, self).__init__(corriente, readOnly, psychro)
self.setWindowTitle(self.tr("Edit stream properties"))
self.layout().addLayout(layout)
[docs]
class StreamDefinition(QtWidgets.QWidget):
"""Widget for stream definition as standard P,T,x composition input"""
changedValue = QtCore.pyqtSignal(str, float)
changedFraction = QtCore.pyqtSignal(str, list)
[docs]
def __init__(self, stream=None, readOnly=False, parent=None):
super().__init__(parent)
self.indices, self.nombres, M = config.getComponents()
lyt = QtWidgets.QGridLayout(self)
lyt.setVerticalSpacing(0)
lyt.addWidget(QtWidgets.QLabel(self.tr("Temperature")), 1, 1)
self.T = Entrada_con_unidades(unidades.Temperature)
self.T.valueChanged.connect(partial(self.calculo, "T"))
lyt.addWidget(self.T, 1, 2, 1, 2)
lyt.addWidget(QtWidgets.QLabel(self.tr("Pressure")), 2, 1)
self.P = Entrada_con_unidades(unidades.Pressure)
self.P.valueChanged.connect(partial(self.calculo, "P"))
lyt.addWidget(self.P, 2, 2, 1, 2)
lyt.addWidget(QtWidgets.QLabel(self.tr("Vapor fraccion")), 3, 1)
self.x = Entrada_con_unidades(float)
self.x.valueChanged.connect(partial(self.calculo, "x"))
lyt.addWidget(self.x, 3, 2, 1, 2)
lyt.addItem(QtWidgets.QSpacerItem(
10, 10, QtWidgets.QSizePolicy.Policy.Fixed,
QtWidgets.QSizePolicy.Policy.Fixed), 4, 1, 1, 2)
lyt.addWidget(QtWidgets.QLabel(self.tr("Mass flow")), 5, 1)
self.caudalMasico = Entrada_con_unidades(unidades.MassFlow)
self.caudalMasico.valueChanged.connect(
partial(self.calculo, "caudalMasico"))
lyt.addWidget(self.caudalMasico, 5, 2, 1, 2)
lyt.addWidget(QtWidgets.QLabel(self.tr("Molar flow")), 6, 1)
self.caudalMolar = Entrada_con_unidades(unidades.MolarFlow)
self.caudalMolar.valueChanged.connect(
partial(self.calculo, "caudalMolar"))
lyt.addWidget(self.caudalMolar, 6, 2, 1, 2)
lyt.addWidget(QtWidgets.QLabel(self.tr("Volumetric flow")), 7, 1)
self.caudalVolumetrico = Entrada_con_unidades(unidades.VolFlow)
self.caudalVolumetrico.valueChanged.connect(
partial(self.calculo, "caudalVolumetrico"))
lyt.addWidget(self.caudalVolumetrico, 7, 2, 1, 2)
lyt.addItem(QtWidgets.QSpacerItem(
10, 10, QtWidgets.QSizePolicy.Policy.Fixed,
QtWidgets.QSizePolicy.Policy.Fixed), 8, 1, 1, 1)
lyt.addWidget(QtWidgets.QLabel(self.tr("Composition")), 9, 1)
self.tipoFraccion = QtWidgets.QComboBox()
self.tipoFraccion.addItem(unidades.MassFlow.text())
self.tipoFraccion.addItem(unidades.MolarFlow.text())
self.tipoFraccion.addItem(self.tr("Mass fraction"))
self.tipoFraccion.addItem(self.tr("Molar fraction"))
self.tipoFraccion.setCurrentIndex(3)
self.tipoFraccion.currentIndexChanged.connect(
self.tipoFraccionesCambiado)
self.tipoFraccion.setSizePolicy(
QtWidgets.QSizePolicy.Policy.Maximum,
QtWidgets.QSizePolicy.Policy.Maximum)
lyt.addWidget(self.tipoFraccion, 9, 2)
lyt.addItem(QtWidgets.QSpacerItem(
5, 5, QtWidgets.QSizePolicy.Policy.Fixed,
QtWidgets.QSizePolicy.Policy.Fixed), 10, 1, 1, 1)
composition = QtWidgets.QWidget()
comp_lyt = QtWidgets.QGridLayout(composition)
comp_lyt.setVerticalSpacing(0)
self.xi = []
for i, nombre in enumerate(self.nombres):
label = QtWidgets.QLabel(nombre)
label.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight
| QtCore.Qt.AlignmentFlag.AlignVCenter)
comp_lyt.addWidget(label, i, 1)
widget = Entrada_con_unidades(float)
widget.valueChanged.connect(self.changeFraction)
comp_lyt.addWidget(widget, i, 2)
self.xi.append(widget)
scroll = QtWidgets.QScrollArea()
scroll.setFrameShape(QtWidgets.QFrame.Shape.NoFrame)
scroll.setWidget(composition)
lyt.addWidget(scroll, 10, 1, 1, 2)
lyt.addItem(QtWidgets.QSpacerItem(
0, 0, QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Expanding), 11, 3)
if stream:
self.setStream(stream)
else:
self.stream = Corriente()
[docs]
def setReadOnly(self, bool):
self.T.setReadOnly(bool)
self.P.setReadOnly(bool)
self.x.setReadOnly(bool)
self.caudalMasico.setReadOnly(bool)
self.caudalMolar.setReadOnly(bool)
self.caudalVolumetrico.setReadOnly(bool)
for widget in self.xi:
widget.setReadOnly(bool)
[docs]
def setStream(self, stream):
self.stream = stream
if stream.status == 1:
self.T.setValue(stream.T)
self.setResaltado(stream, "T")
self.P.setValue(stream.P)
self.setResaltado(stream, "P")
self.x.setValue(stream.x)
self.setResaltado(stream, "x")
self.caudalMasico.setValue(stream.caudalmasico)
self.setResaltado(stream, "caudalMasico")
self.caudalMolar.setValue(stream.caudalmolar)
self.setResaltado(stream, "caudalMolar")
self.caudalVolumetrico.setValue(stream.Q)
self.setResaltado(stream, "caudalVolumetrico")
if stream.tipoFlujo == 1:
self.tipoFraccion.setCurrentIndex(0)
prop = stream.caudalunitariomasico
elif stream.tipoFlujo == 2:
self.tipoFraccion.setCurrentIndex(1)
prop = stream.caudalunitariomolar
elif stream.tipoFlujo in (4, 6):
self.tipoFraccion.setCurrentIndex(2)
prop = stream.fraccion_masica
else:
self.tipoFraccion.setCurrentIndex(3)
prop = stream.fraccion
for value, widget in zip(prop, self.xi):
widget.setValue(value)
elif stream.numInputs:
for input in ["T", "P", "x", "caudalMasico", "caudalMolar",
"caudalVolumetrico"]:
if stream.kwargs[input]:
self.__getattribute__(input).setValue(stream.kwargs[input])
self.__getattribute__(input).setResaltado(True)
else:
self.__getattribute__(input).clear()
self.__getattribute__(input).setResaltado(False)
prop = None
if stream.tipoFlujo == 1:
self.tipoFraccion.setCurrentIndex(0)
propi = stream.kwargs["caudalUnitarioMasico"]
prop = []
for value in propi:
prop.append(unidades.MassFlow(value).config())
elif stream.tipoFlujo == 2:
self.tipoFraccion.setCurrentIndex(1)
propi = stream.kwargs["caudalUnitarioMolar"]
prop = []
for value in propi:
prop.append(unidades.MolarFlow(value).config())
elif stream.tipoFlujo in (4, 6):
self.tipoFraccion.setCurrentIndex(2)
prop = stream.kwargs["fraccionMasica"]
elif stream.tipoFlujo in (3, 5):
self.tipoFraccion.setCurrentIndex(3)
prop = stream.kwargs["fraccionMolar"]
elif stream.kwargs["fraccionMasica"]:
self.tipoFraccion.setCurrentIndex(2)
prop = stream.kwargs["fraccionMasica"]
elif stream.kwargs["fraccionMolar"]:
self.tipoFraccion.setCurrentIndex(3)
prop = stream.kwargs["fraccionMolar"]
if prop:
for value, widget in zip(prop, self.xi):
widget.setValue(value)
if stream.tipoFlujo:
self.caudalMolar.setValue(stream.mezcla.caudalmolar)
self.caudalMasico.setValue(stream.mezcla.caudalmasico)
[docs]
def setResaltado(self, stream, arg):
if stream.kwargs[arg]:
self.__getattribute__(arg).setResaltado(True)
else:
self.__getattribute__(arg).setResaltado(False)
[docs]
def calculo(self, key, value):
self.changedValue[str, float].emit(key, value)
[docs]
def tipoFraccionesCambiado(self, index):
values = None
if self.stream.status == 1:
if index == 0:
values = self.stream.caudalunitariomasico
elif index == 1:
values = self.stream.caudalunitariomolar
elif index == 2:
values = self.stream.fraccion_masica
else:
values = self.stream.fraccion
elif self.stream.tipoFlujo:
if index == 0:
values = self.stream.mezcla.caudalunitariomasico
elif index == 1:
values = self.stream.mezcla.caudalunitariomolar
elif index == 2:
values = self.stream.mezcla.fraccion_masica
else:
values = self.stream.mezcla.fraccion
if values:
for value, widget in zip(values, self.xi):
widget.setValue(value.config())
[docs]
def composicionEntrada(self):
key = ["caudalUnitarioMasico", "caudalUnitarioMolar", "fraccionMasica",
"fraccionMolar"][self.tipoFraccion.currentIndex()]
values = []
for widget in self.xi:
if self.tipoFraccion.currentIndex() == 0:
value = unidades.MassFlow(widget.value, "conf")
elif self.tipoFraccion.currentIndex() == 1:
value = unidades.MolarFlow(widget.value, "conf")
else:
value = widget.value
values.append(value)
return key, values
[docs]
def changeFraction(self):
key, values = self.composicionEntrada()
if sum(values) == 1.0 or all(values):
self.changedFraction[str, list].emit(key, values)
[docs]
def kwargs(self):
kwargs = {}
kwargs["T"] = self.T.value
kwargs["P"] = self.P.value
kwargs["x"] = self.x.value
kwargs["caudalMasico"] = self.caudal.value
kwargs["caudalMolar"] = self.caudalMolar.value
kwargs["caudalVolumetrico"] = self.caudalVol.value
key, fraction = self.composicionEntrada()
kwargs[key] = fraction
return kwargs
[docs]
class PsychroDefinition(QtWidgets.QWidget):
"""Widget for stream definition as humid air input"""
Changed = QtCore.pyqtSignal(PsyStream)
parameters = ["tdb", "twb", "tdp", "w", "mu", "HR", "v", "h", "Pv", "Xa", "Xw"]
stream = PsyStream()
[docs]
def __init__(self, psystream=None, readOnly=False, parent=None):
super(PsychroDefinition, self).__init__(parent)
layout = QtWidgets.QGridLayout(self)
self.inputs = PsychroInput()
self.inputs.stateChanged.connect(partial(self.calculo, "state"))
layout.addWidget(self.inputs, 1, 1, 1, 2)
layout.addItem(QtWidgets.QSpacerItem(
20, 20, QtWidgets.QSizePolicy.Policy.Fixed,
QtWidgets.QSizePolicy.Policy.Fixed), 1, 3)
layout.addItem(QtWidgets.QSpacerItem(
20, 20, QtWidgets.QSizePolicy.Policy.Fixed,
QtWidgets.QSizePolicy.Policy.Fixed), 2, 1)
vlayout = QtWidgets.QVBoxLayout()
layout.addLayout(vlayout, 1, 4, 6, 1)
vlayout.addItem(QtWidgets.QSpacerItem(
20, 20, QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Expanding))
groupbox = QtWidgets.QGroupBox(self.tr("Calculated properties"))
vlayout.addWidget(groupbox)
lytGroup = QtWidgets.QGridLayout(groupbox)
lytGroup.addWidget(QtWidgets.QLabel("Tdb"), 1, 1)
self.tdb = Entrada_con_unidades(unidades.Temperature, readOnly=True)
lytGroup.addWidget(self.tdb, 1, 2)
lytGroup.addWidget(QtWidgets.QLabel("Twb"), 2, 1)
self.twb = Entrada_con_unidades(unidades.Temperature, readOnly=True)
lytGroup.addWidget(self.twb, 2, 2)
lytGroup.addWidget(QtWidgets.QLabel("Tdp"), 3, 1)
self.tdp = Entrada_con_unidades(unidades.Temperature, readOnly=True)
lytGroup.addWidget(self.tdp, 3, 2)
lytGroup.addWidget(QtWidgets.QLabel(
self.tr("Absolute humidity")), 4, 1)
massUnit = unidades.Mass(None).text()+"/"+unidades.Mass(None).text()
self.w = Entrada_con_unidades(float, readOnly=True, textounidad=massUnit)
lytGroup.addWidget(self.w, 4, 2)
lytGroup.addWidget(QtWidgets.QLabel(
self.tr("Degree of saturation")), 5, 1)
self.mu = Entrada_con_unidades(float, readOnly=True, textounidad="%")
lytGroup.addWidget(self.mu, 5, 2)
lytGroup.addWidget(QtWidgets.QLabel(self.tr("Relative humidity")), 6, 1)
self.HR = Entrada_con_unidades(float, readOnly=True, textounidad="%")
lytGroup.addWidget(self.HR, 6, 2)
lytGroup.addWidget(QtWidgets.QLabel(self.tr("Volume")), 7, 1)
self.v = Entrada_con_unidades(unidades.SpecificVolume, readOnly=True)
lytGroup.addWidget(self.v, 7, 2)
lytGroup.addWidget(QtWidgets.QLabel(self.tr("Enthalpy")), 8, 1)
self.h = Entrada_con_unidades(unidades.Enthalpy, readOnly=True)
lytGroup.addWidget(self.h, 8, 2)
lytGroup.addWidget(QtWidgets.QLabel(self.tr("Vapour Pressure")), 9, 1)
self.Pv = Entrada_con_unidades(unidades.Pressure, readOnly=True)
lytGroup.addWidget(self.Pv, 9, 2)
lytGroup.addWidget(QtWidgets.QLabel(self.tr("Air fraction")), 10, 1)
self.Xa = Entrada_con_unidades(float, readOnly=True)
lytGroup.addWidget(self.Xa, 10, 2)
lytGroup.addWidget(QtWidgets.QLabel(self.tr("Water fraction")), 11, 1)
self.Xw = Entrada_con_unidades(float, readOnly=True)
lytGroup.addWidget(self.Xw, 11, 2)
vlayout.addItem(QtWidgets.QSpacerItem(
20, 20, QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Expanding))
layout.addWidget(QtWidgets.QLabel(self.tr("Mass Flow")), 3, 1)
self.caudalMasico = Entrada_con_unidades(
unidades.MassFlow, readOnly=readOnly)
self.caudalMasico.valueChanged.connect(
partial(self.updatekwargsFlow, "caudalMasico"))
layout.addWidget(self.caudalMasico, 3, 2)
layout.addWidget(QtWidgets.QLabel(self.tr("Molar Flow")), 4, 1)
self.caudalMolar = Entrada_con_unidades(
unidades.MolarFlow, readOnly=readOnly)
self.caudalMolar.valueChanged.connect(
partial(self.updatekwargsFlow, "caudalMolar"))
layout.addWidget(self.caudalMolar, 4, 2)
layout.addWidget(QtWidgets.QLabel(self.tr("Volumetric Flow")), 5, 1)
self.caudalVolumetrico = Entrada_con_unidades(
unidades.VolFlow, readOnly=readOnly)
self.caudalVolumetrico.valueChanged.connect(
partial(self.updatekwargsFlow, "caudalVolumetrico"))
layout.addWidget(self.caudalVolumetrico, 5, 2)
layout.addItem(QtWidgets.QSpacerItem(
5, 5, QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Expanding), 9, 2)
self.setReadOnly(readOnly)
self.inputs.updateInputs(0)
if psystream:
self.setStream(psystream)
[docs]
def setStream(self, stream):
self.stream = stream
self.rellenar(stream)
[docs]
def setReadOnly(self, readOnly):
self.inputs.setReadOnly(readOnly)
self.caudalMasico.setReadOnly(readOnly)
self.caudalMolar.setReadOnly(readOnly)
self.caudalVolumetrico.setReadOnly(readOnly)
[docs]
def calculo(self, key, value):
self.stream(**{key: value})
if self.stream:
self.rellenar(self.stream)
if self.stream.status:
self.Changed.emit(self.stream)
[docs]
def rellenar(self, stream):
state = None
if stream.status:
state = stream.state
elif stream.kwargs["state"]:
state = stream.kwargs["state"]
if state:
self.inputs.setState(state)
for par in self.parameters:
self.__getattribute__(par).setValue(state.__getattribute__(par))
self.rellenarFlow(stream)
[docs]
def rellenarFlow(self, stream):
for arg in ("caudalMasico", "caudalMolar", "caudalVolumetrico"):
if stream.kwargs[arg]:
self.__getattribute__(arg).setValue(stream.kwargs[arg])
else:
self.__getattribute__(arg).clear()
[docs]
def updatekwargsFlow(self, key, value):
self.stream.updatekwargsFlow(key, value)
self.rellenarFlow(self.stream)
if self.stream.status:
self.Changed.emit(self.stream)
[docs]
class StreamProperties(QtWidgets.QTableWidget):
"""Table to show stream properties"""
[docs]
def __init__(self, stream=None, parent=None):
super(StreamProperties, self).__init__(11, 2, parent)
for i in range(self.rowCount()):
self.setRowHeight(i, 24)
self.setColumnWidth(0, 85)
self.setColumnWidth(1, 85)
self.setEditTriggers(QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers)
self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.Fixed)
self.verticalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeMode.Fixed)
self.horizontalHeader().resizeSections(QtWidgets.QHeaderView.ResizeMode.Fixed)
horheader = [self.tr("Liquid"), self.tr("Vapor")]
self.setHorizontalHeaderLabels(horheader)
verheader = [self.tr("Mass Flow") +
", " + unidades.MassFlow(None).text(),
self.tr("Molar Flow") +
", " + unidades.MolarFlow(None).text(),
self.tr("Vol Flow") +
", " + unidades.VolFlow(None).text("QLiq"),
self.tr("Enthalpy") +
", " + unidades.Power(None).text(),
self.tr("Molecular Weight"),
self.tr("Density") +
", " + unidades.Density(None).text("DenLiq"),
self.tr("Compressibility"),
self.tr("Cp") + ", " +
unidades.SpecificHeat(None).text(),
self.tr("Viscosity") +
", " + unidades.Viscosity(None).text(),
self.tr("Conductivity") +
", " + unidades.ThermalConductivity(None).text(),
self.tr("Tension") +
", " + unidades.Tension(None).text()]
self.setVerticalHeaderLabels(verheader)
self.CaudalLiquido = Entrada_con_unidades(
unidades.MassFlow, retornar=False, readOnly=True, texto=False)
self.setCellWidget(0, 0, self.CaudalLiquido)
self.CaudalGas = Entrada_con_unidades(
unidades.MassFlow, retornar=False, readOnly=True, texto=False)
self.setCellWidget(0, 1, self.CaudalGas)
self.CaudalMolarLiquido = Entrada_con_unidades(
unidades.MolarFlow, retornar=False, readOnly=True, texto=False)
self.setCellWidget(1, 0, self.CaudalMolarLiquido)
self.CaudalMolarGas = Entrada_con_unidades(
unidades.MolarFlow, retornar=False, readOnly=True, texto=False)
self.setCellWidget(1, 1, self.CaudalMolarGas)
self.CaudalVolumetricoLiquido = Entrada_con_unidades(
unidades.VolFlow, "QLiq", retornar=False, readOnly=True, texto=False)
self.setCellWidget(2, 0, self.CaudalVolumetricoLiquido)
self.CaudalVolumetricoGas = Entrada_con_unidades(
unidades.VolFlow, "QLiq", retornar=False, readOnly=True, texto=False)
self.setCellWidget(2, 1, self.CaudalVolumetricoGas)
self.entalpiaLiquido = Entrada_con_unidades(
unidades.Power, retornar=False, readOnly=True, texto=False)
self.setCellWidget(3, 0, self.entalpiaLiquido)
self.entalpiaGas = Entrada_con_unidades(
unidades.Power, retornar=False, readOnly=True, texto=False)
self.setCellWidget(3, 1, self.entalpiaGas)
self.PesoMolecularLiquido = Entrada_con_unidades(float, readOnly=True)
self.setCellWidget(4, 0, self.PesoMolecularLiquido)
self.PesoMolecularGas = Entrada_con_unidades(float, readOnly=True)
self.setCellWidget(4, 1, self.PesoMolecularGas)
self.DensidadLiquido = Entrada_con_unidades(
unidades.Density, "DenLiq", retornar=False, readOnly=True, texto=False)
self.setCellWidget(5, 0, self.DensidadLiquido)
self.DensidadGas = Entrada_con_unidades(
unidades.Density, "DenLiq", retornar=False, readOnly=True, texto=False)
self.setCellWidget(5, 1, self.DensidadGas)
self.ZLiquido = Entrada_con_unidades(float, readOnly=True)
self.setCellWidget(6, 0, self.ZLiquido)
self.ZGas = Entrada_con_unidades(float, readOnly=True)
self.setCellWidget(6, 1, self.ZGas)
self.CpLiquido = Entrada_con_unidades(
unidades.SpecificHeat, retornar=False, readOnly=True, texto=False)
self.setCellWidget(7, 0, self.CpLiquido)
self.CpGas = Entrada_con_unidades(
unidades.SpecificHeat, retornar=False, readOnly=True, texto=False)
self.setCellWidget(7, 1, self.CpGas)
self.ViscosidadLiquido = Entrada_con_unidades(
unidades.Viscosity, retornar=False, readOnly=True, texto=False)
self.setCellWidget(8, 0, self.ViscosidadLiquido)
self.ViscosidadGas = Entrada_con_unidades(
unidades.Viscosity, retornar=False, readOnly=True, texto=False)
self.setCellWidget(8, 1, self.ViscosidadGas)
self.ConductividadLiquido = Entrada_con_unidades(
unidades.ThermalConductivity, retornar=False, readOnly=True, texto=False)
self.setCellWidget(9, 0, self.ConductividadLiquido)
self.ConductividadGas = Entrada_con_unidades(
unidades.ThermalConductivity, retornar=False, readOnly=True, texto=False)
self.setCellWidget(9, 1, self.ConductividadGas)
self.Tension = Entrada_con_unidades(
unidades.Tension, retornar=False, readOnly=True, texto=False)
self.setCellWidget(10, 0, self.Tension)
if stream:
self.fill(stream)
[docs]
def fill(self, stream):
if stream.status == 1:
if stream.x > 0:
self.CaudalGas.setValue(stream.Gas.caudalmasico)
self.CaudalMolarGas.setValue(stream.Gas.caudalmolar)
self.entalpiaGas.setValue(stream.Gas.h)
self.PesoMolecularGas.setValue(stream.Gas.M)
self.DensidadGas.setValue(stream.Gas.rho)
self.CaudalVolumetricoGas.setValue(stream.Gas.Q)
self.ZGas.setValue(stream.Gas.Z)
self.CpGas.setValue(stream.Gas.cp)
self.ViscosidadGas.setValue(stream.Gas.mu)
self.ConductividadGas.setValue(stream.Gas.k)
if stream.x < 1:
self.CaudalLiquido.setValue(stream.Liquido.caudalmasico)
self.CaudalMolarLiquido.setValue(stream.Liquido.caudalmolar)
self.entalpiaLiquido.setValue(stream.Liquido.h)
self.PesoMolecularLiquido.setValue(stream.Liquido.M)
self.DensidadLiquido.setValue(stream.Liquido.rho)
self.CaudalVolumetricoLiquido.setValue(stream.Liquido.Q)
self.ZLiquido.setValue(stream.Liquido.Z)
self.CpLiquido.setValue(stream.Liquido.cp)
self.ViscosidadLiquido.setValue(stream.Liquido.mu)
self.ConductividadLiquido.setValue(stream.Liquido.k)
self.Tension.setValue(stream.Liquido.sigma)
[docs]
class SolidDefinition(QtWidgets.QWidget):
"""Widget for solids edit/view"""
Changed = QtCore.pyqtSignal(Solid)
solido = Solid()
[docs]
def __init__(self, solid=None, readOnly=False, parent=None):
super(SolidDefinition, self).__init__(parent)
self.solidos, self.NameSol, M = config.getComponents(solidos=True)
self.semaforo = QtCore.QSemaphore(1)
self.evaluate = Evaluate()
# self.evaluate.finished.connect(self.fill)
lyt = QtWidgets.QGridLayout(self)
composition = QtWidgets.QWidget()
comp_lyt = QtWidgets.QGridLayout(composition)
comp_lyt.setVerticalSpacing(0)
self.CaudalSolidos = []
for i, nombre in enumerate(self.NameSol):
label = QtWidgets.QLabel(nombre)
label.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight
| QtCore.Qt.AlignmentFlag.AlignVCenter)
comp_lyt.addWidget(label, i, 1)
widget = Entrada_con_unidades(unidades.MassFlow)
widget.valueChanged.connect(self.caudalesSolidoFinished)
comp_lyt.addWidget(widget, i, 2)
self.CaudalSolidos.append(widget)
scroll = QtWidgets.QScrollArea()
scroll.setFrameShape(QtWidgets.QFrame.Shape.NoFrame)
scroll.setMinimumHeight(min(100, 30*len(M)))
scroll.setWidget(composition)
lyt.addWidget(scroll, 1, 1, 1, 2)
lyt.addWidget(QtWidgets.QLabel(self.tr("Mean Diameter")), 3, 1, 1, 1)
self.diametroParticula = Entrada_con_unidades(
unidades.Length, "ParticleDiameter")
self.diametroParticula.valueChanged.connect(
partial(self.calculo, "diametroMedio"))
lyt.addWidget(self.diametroParticula, 3, 2, 1, 1)
self.checkDistribucion = QtWidgets.QCheckBox(
self.tr("Use particle size distribution"))
self.checkDistribucion.toggled.connect(self.checkDistributionToggled)
lyt.addWidget(self.checkDistribucion, 5, 1, 1, 2)
header = [self.tr("Diameter")
+ ", " + unidades.Length.text("ParticleDiameter"),
self.tr("Fraction")]
self.distribucionTamanos = Tabla(
2, horizontalHeader=header, stretch=False, verticalHeader=False)
self.distribucionTamanos.editingFinished.connect(
self.distribucionFinished)
lyt.addWidget(self.distribucionTamanos, 6, 1, 1, 2)
dialog = self.buttonBox = QtWidgets.QDialogButtonBox()
self.botonNormalizar = QtWidgets.QPushButton(self.tr("Normalize"))
self.botonNormalizar.clicked.connect(self.botonNormalizar_clicked)
dialog.addButton(self.botonNormalizar,
QtWidgets.QDialogButtonBox.ButtonRole.AcceptRole)
self.botonGenerar = QtWidgets.QPushButton(self.tr("Generate"))
self.botonGenerar.clicked.connect(self.botonGenerar_clicked)
dialog.addButton(self.botonGenerar,
QtWidgets.QDialogButtonBox.ButtonRole.AcceptRole)
lyt.addWidget(dialog, 7, 1, 1, 2)
lyt.addItem(QtWidgets.QSpacerItem(
20, 20, QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Expanding), 8, 3)
self.distribucionTamanos.setConnected()
self.setSolido(solid)
[docs]
def setSolido(self, solido):
if solido:
self.solido = solido
self.fill()
[docs]
def fill(self):
if self.semaforo.available() > 0:
self.semaforo.acquire(1)
if self.solido.status:
for i, caudal in enumerate(self.solido.caudalUnitario):
self.CaudalSolidos[i].setValue(caudal)
if self.solido.status == 1:
self.checkDistribucion.setChecked(False)
else:
self.checkDistribucion.setChecked(True)
if self.solido.diametros:
diametros = [d.config("ParticleDiameter") for d in self.solido.diametros]
self.distribucionTamanos.setColumn(0, diametros)
self.distribucionTamanos.setColumn(1, self.solido.fracciones)
self.diametroParticula.setValue(self.solido.diametro_medio)
else:
pass
# print("solido", self.solido.kwargs)
self.semaforo.release(1)
[docs]
def setReadOnly(self, bool):
for w in self.CaudalSolidos:
w.setReadOnly(bool)
self.diametroParticula.setReadOnly(bool)
self.checkDistribucion.setDisabled(bool)
if bool:
triggers = QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers
else:
triggers = QtWidgets.QAbstractItemView.EditTrigger.AllEditTriggers
self.distribucionTamanos.setEditTriggers(triggers)
[docs]
def distribucionFinished(self):
conversion = unidades.Length(1, "conf", "ParticleDiameter").m
diametros = [diametro*conversion for diametro in self.distribucionTamanos.getColumn(0)]
fracciones = self.distribucionTamanos.getColumn(1)
if diametros:
kwargs = {"distribucion_diametro": diametros,
"distribucion_fraccion": fracciones}
self.calculo(**kwargs)
[docs]
def caudalesSolidoFinished(self):
caudales = self.caudalSolido()
self.calculo("caudalSolido", caudales)
[docs]
def caudalSolido(self):
caudales = []
for widget in self.CaudalSolidos:
caudales.append(widget.value)
return caudales
[docs]
def checkDistributionToggled(self, bool):
self.distribucionTamanos.setEnabled(bool)
self.botonGenerar.setEnabled(bool)
self.botonNormalizar.setEnabled(bool)
self.diametroParticula.setDisabled(bool)
if bool:
self.solido.kwargs["diametroMedio"] = None
self.distribucionFinished()
else:
self.solido.kwargs["distribucion_diametro"] = []
self.solido.kwargs["distribucion_fraccion"] = []
self.calculo("diametroMedio", self.diametroParticula.value)
[docs]
def botonNormalizar_clicked(self, diametros=None, fracciones=None):
if not diametros:
diametros = self.distribucionTamanos.getColumn(0)
if not fracciones:
fracciones = self.distribucionTamanos.getColumn(1)
if diametros:
diametros.sort()
suma = sum(fracciones)
fracciones = [fraccion/suma for fraccion in fracciones]
self.distribucionTamanos.setColumn(0, diametros)
self.distribucionTamanos.setColumn(1, fracciones)
[docs]
def botonGenerar_clicked(self):
dialog = SolidDistribution(self)
if dialog.exec():
self.distribucionTamanos.setData(dialog.matriz)
[docs]
def calculo(self, key=None, value=None, **kw):
if key:
kw[key] = value
self.solido(**kw)
if self.solido:
self.fill()
self.Changed.emit(self.solido)
# def salida(self, **kwargs):
# """Return kwargs argument to solid definition"""
# if not kwargs:
# kwargs = {}
# kwargs["caudalSolido"] = self.caudalSolido()
# kwargs["diametroMedio"] = self.diametroParticula.value
# kwargs["distribucion_diametro"] = self.TablaSolidos.getColumn(0)
# kwargs["distribucion_fraccion"] = self.TablaSolidos.getColumn(1)
#
# if not self.evaluate.isRunning():
# self.evaluate.start(self.solido, kwargs)
[docs]
class SolidDistribution(QtWidgets.QDialog):
"""
Dialog to specified parameter to model particle solid distribution
Teoretical model implemented:
Rosin, Rammler, Sperling (Weibull distribution)
Gates, Gaudin, Shumann
Gaudin, Meloy
Broadbent, Callcott
Distribución lognormal
Harris
Generate distribution to several standard test sieves:
Tyler
ASTM E 11-70
DIN 4188
AFNOR NFX11-501
ISO 565
BS 410
"""
# Standard sieves, values in mm
Sieve = {
"Tyler": [0.033, 0.043, 0.053, 0.061, 0.074, 0.088, 0.104, 0.121, 0.147,
0.173, 0.208, 0.246, 0.295, 0.351, 0.417, 0.495, 0.589, 0.701,
0.833, 0.991, 1.168, 1.397, 1.651, 1.981, 2.362, 2.794, 3.327,
3.962, 4.699, 5.613, 6.680, 7.925],
"ASTM": [0.02, 0.025, 0.032, 0.038, 0.045, 0.053, 0.063, 0.075, 0.09,
0.106, 0.125, 0.150, 0.180, 0.212, 0.250, 0.300, 0.355, 0.425,
0.5, 0.6, 0.71, 0.85, 1., 1.18, 1.4, 1.7, 2., 2.36, 2.8, 3.35,
4., 4.75, 5.6, 6.3, 6.7, 8., 9.5, 11.2, 12.5, 13.2, 16.0, 19.,
22.4, 25., 26.5, 31.5, 37.5, 45., 50., 53., 63., 75., 90.,
100., 106., 125],
"DIN": [0.02, 0.022, 0.025, 0.028, 0.032, 0.036, 0.04, 0.045, 0.05,
0.056, 0.063, 0.071, 0.08, 0.09, 0.1, 0.125, 0.14, 0.18, 0.2,
0.224, 0.25, 0.28, 0.315, 0.355, 0.4, 0.5, 0.56, 0.63, 0.71,
0.8, 0.9, 1.0, 1.18, 1.25, 1.4, 1.6, 1.8, 2., 2.24, 2.5, 2.8,
3.15, 3.55, 4., 4.5, 5., 5.6],
"AFNOR": [0.02, 0.022, 0.025, 0.028, 0.032, 0.036, 0.04, 0.045, 0.05,
0.056, 0.063, 0.071, 0.08, 0.09, 0.1, 0.125, 0.14, 0.16, 0.18,
0.2, 0.224, 0.25, 0.28, 0.315, 0.355, 0.4, 0.45, 0.5, 0.56,
0.63, 0.71, 0.8, 0.9, 1.0, 1.18, 1.25, 1.4, 1.6, 1.8, 2.,
2.24, 2.5, 3.15, 3.55, 4., 4.5, 5., 5.6],
"ISO": [0.02, 0.022, 0.025, 0.028, 0.032, 0.036, 0.045, 0.05, 0.063,
0.071, 0.08, 0.09, 0.1, 0.125, 0.14, 0.18, 0.2, 0.224, 0.25,
0.28, 0.315, 0.355, 0.4, 0.45, 0.63, 0.71, 0.8, 0.9, 1.0, 1.18,
1.25, 1.4, 1.6, 1.8, 2, 2.24, 2.5, 2.8, 3.15, 3.55, 4, 4.5, 5, 5.6],
"BS": [0.045, 0.053, 0.063, 0.075, 0.09, 0.106, 0.125, 0.15, 0.18,
0.212, 0.25, 0.3, 0.355, 0.425, 0.5, 0.6, 0.71, 0.85, 1.0, 1.18,
1.4, 1.7, 2.0, 2.36, 2.8, 3.35, 4.0, 4.75, 5.6]}
model = {
"Rosin Rammler Sperling": {
"title": ["d*=", "S="],
"unit": [unidades.Length, float],
"magnitud": ["ParticleDiameter", ""]},
"Gates Gaudin Schumann": {
"title": ["d*=", "N="],
"unit": [unidades.Length, float],
"magnitud": ["ParticleDiameter", ""]},
"Broadbent Callcott": {
"title": ["d*=", "N="],
"unit": [unidades.Length, float],
"magnitud": ["ParticleDiameter", ""]},
"Gaudin Meloy": {
"title": ["d*=", "N="],
"unit": [unidades.Length, float],
"magnitud": ["ParticleDiameter", ""]},
"Lognormal": {
"title": ["d*=", u"σ="],
"unit": [unidades.Length, float],
"magnitud": ["ParticleDiameter", ""]},
"Harris": {
"title": ["d*=", "S=", "N="],
"unit": [unidades.Length, float, float],
"magnitud": ["ParticleDiameter", "", ""]}}
[docs]
def __init__(self, parent=None):
super(SolidDistribution, self).__init__(parent)
self.setWindowTitle(self.tr("Generate solid distribution"))
self.matriz = []
layout = QtWidgets.QGridLayout(self)
layout.addWidget(QtWidgets.QLabel(self.tr("Model")), 0, 0)
self.modelo = QtWidgets.QComboBox()
layout.addWidget(self.modelo, 0, 1)
self.stacked = QtWidgets.QStackedWidget()
self.modelo.currentIndexChanged.connect(self.stacked.setCurrentIndex)
layout.addWidget(self.stacked, 1, 0, 1, 2)
layout.addWidget(QtWidgets.QLabel(self.tr("Standards:")), 2, 0, 1, 1)
self.standard = QtWidgets.QComboBox()
self.standard.addItem("Tyler")
self.standard.addItem("ASTM")
self.standard.addItem("DIN")
self.standard.addItem("BS")
self.standard.addItem("AFNOR")
self.standard.addItem("ISO")
self.standard.addItem(self.tr("Custom"))
self.standard.currentTextChanged.connect(self.standardCambiado)
layout.addWidget(self.standard, 2, 1, 1, 1)
self.diametros = QtWidgets.QLineEdit()
layout.addWidget(self.diametros, 3, 1, 1, 2)
layout.addItem(QtWidgets.QSpacerItem(
20, 20, QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Expanding), 4, 1, 1, 3)
self.buttonBox = QtWidgets.QDialogButtonBox(
QtWidgets.QDialogButtonBox.StandardButton.Cancel
| QtWidgets.QDialogButtonBox.StandardButton.Ok)
self.buttonBox.rejected.connect(self.reject)
self.buttonBox.accepted.connect(self.aceptar)
layout.addWidget(self.buttonBox, 5, 0, 1, 2)
self.entries = {}
for key in ("Rosin Rammler Sperling", "Gates Gaudin Schumann",
"Broadbent Callcott", "Gaudin Meloy", "Lognormal", "Harris"):
widget = QtWidgets.QWidget()
self.modelo.addItem(key)
lyt = QtWidgets.QGridLayout(widget)
for i, label in enumerate(self.model[key]["title"]):
lyt.addWidget(QtWidgets.QLabel(label), i, 1)
self.entries[key] = []
for i, unit in enumerate(self.model[key]["unit"]):
entry = Entrada_con_unidades(unit, self.model[key]["magnitud"][i])
self.entries[key].append(entry)
lyt.addWidget(entry, i, 2)
lyt.addItem(QtWidgets.QSpacerItem(
0, 0, QtWidgets.QSizePolicy.Policy.Expanding,
QtWidgets.QSizePolicy.Policy.Expanding), i+1, 1)
self.stacked.addWidget(widget)
self.standardCambiado("Tyler")
[docs]
def standardCambiado(self, txt):
if txt == self.tr("Custom"):
self.diametros.setEnabled(True)
else:
self.diametros.setEnabled(False)
self.estandares = self.Sieve[str(txt)]
[docs]
def aceptar(self):
if self.standard.currentIndex() < 6:
d = self.estandares
else:
# TODO:
pass
if self.modelo.currentIndex() == 0:
funcion = lambda p, d: 1.-exp(-(d/p[0]/1000.)**p[1])
parametros = [i.value for i in self.entries["Rosin Rammler Sperling"]]
elif self.modelo.currentIndex() == 1:
funcion = lambda p, d: (d/p[0]/1000.)**p[1]
parametros = [i.value for i in self.entries["Gates Gaudin Schumann"]]
elif self.modelo.currentIndex() == 2:
funcion = lambda p, d: 1-(1-d/p[0]/1000.)**p[1]
parametros = [i.value for i in self.entries["Broadbent Callcott"]]
elif self.modelo.currentIndex() == 3:
funcion = lambda p, d: 1.-exp(-(d/p[0]/1000.)**p[1])/(1-exp(-1.))
parametros = [i.value for i in self.entries["Gaudin Meloy"]]
elif self.modelo.currentIndex() == 4:
funcion = lambda p, d: erf(log(d/p[0]/1000.)/p[1])
parametros = [i.value for i in self.entries["Lognormal"]]
elif self.modelo.currentIndex() == 5:
funcion = lambda p, d: 1-(1-d/(p[0]/1000.)**p[1])**p[2]
parametros = [i.value for i in self.entries["Harris"]]
diametros = [unidades.Length(x) for x in d]
acumulado = [0]+[funcion(parametros, x) for x in d]
if acumulado[-1] < 1.:
acumulado[-1] = 1.
diferencia = [acumulado[i+1]-acumulado[i] for i in range(len(d))]
self.matriz = [[di.config("ParticleDiameter"), diff] for di, diff in
zip(diametros, diferencia)]
self.accept()
if __name__ == "__main__":
import sys
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([638], [100], distribucion)
#
# mezcla=Corriente(340, 1, 1000, Mezcla([10, 38, 22, 61], [.3, 0.5, 0.05, 0.15]), notas="Corriente de ejemplo")
# mezcla=Corriente(340, 1, 1000, Mezcla([475, 7, 62], [.3, 0.5, 0.2, ]), solido, notas="Corriente de ejemplo")
# agua=Corriente(T=300, P=1e5, caudalMasico=1, fraccionMolar=[1.])
# agua(caudalSolido=[35], diametroMedio=0.0002, notas="Corriente de agua de ejemplo")
# print agua.solido
# diametros=[17.5e-5, 22.4e-5, 26.2e-5, 31.8e-5, 37e-5, 42.4e-5, 48e-5, 54e-5, 60e-5, 69e-5, 81.3e-5, 96.5e-5, 109e-5, 127e-5]
# 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.01], distribucion_diametro=diametros, distribucion_fraccion=fracciones)
# corriente=Corriente(T=300, P=101325, caudalMasico=1., fraccionMolar=[1.], solido=solido)
# corriente=Corriente(T=273.15+30, P=101325, caudalMasico=0.01, ids=[475, 62], fraccionMolar=[1, 0])
# corriente=Corriente(caudalMasico=0.01, ids=[10, 38, 22, 61], fraccionMolar=[.3, 0.5, 0.05, 0.15])
# dialogo = Corriente_Dialog(psychro=True)
# dialogo.show()
# aire=PsyStream(caudal=5, tdb=300, HR=50)
# corriente=PsychroDefinition(aire)
# corriente.show()
# corriente = SolidDistribution()
# corriente.show()
# diametros=[17.5e-5, 22.4e-5, 26.2e-5, 31.8e-5, 37e-5, 42.4e-5, 48e-5, 54e-5, 60e-5, 69e-5, 81.3e-5, 96.5e-5, 109e-5, 127e-5]
# 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.01], distribucion_diametro=diametros, distribucion_fraccion=fracciones)
# corriente = SolidDefinition(solido)
# corriente.show()
kw = {"iapws": False, "MEoS": True, "K": "SRK", "H": "SRK", "mix": "Melhem", "Cp_ideal": 1}
# diametros=[17.5e-5, 22.4e-5, 26.2e-5, 31.8e-5, 37e-5, 42.4e-5, 48e-5, 54e-5, 60e-5, 69e-5, 81.3e-5, 96.5e-5, 109e-5, 127e-5]
# 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.01], distribucion_diametro=diametros, distribucion_fraccion=fracciones)
dm = [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]
sol = Solid(caudalSolido=[0.1], distribucion_diametro=dm,
distribucion_fraccion=fracciones, solids=[638])
corriente=Corriente(T=300., x=0.8, caudalMasico=1., fraccionMolar=[1.],
solido=sol, **kw)
dialogo = Corriente_Dialog(corriente)
dialogo.show()
# corriente=Corriente(ids=[10, 38, 22, 61], fraccionMolar=[.0, 0.5, 0.35, 0.15])
# corriente=Corriente(P=101325)
# dialogo = StreamDefinition(corriente)
# dialogo.show()
sys.exit(app.exec())