summaryrefslogtreecommitdiff
path: root/src/main/python
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/python')
-rw-r--r--src/main/python/DockWidgets/DistillationColumnStagewiseResults.py18
-rw-r--r--src/main/python/DockWidgets/DockWidget.py168
-rw-r--r--src/main/python/DockWidgets/DockWidgetCompoundSeparator.py134
-rw-r--r--src/main/python/DockWidgets/DockWidgetCompressorExpander.py167
-rw-r--r--src/main/python/DockWidgets/DockWidgetDistillationColumn.py390
-rw-r--r--src/main/python/DockWidgets/DockWidgetFlash.py90
-rw-r--r--src/main/python/DockWidgets/DockWidgetMaterialStream.py368
-rw-r--r--src/main/python/DockWidgets/DockWidgetMixer.py66
-rw-r--r--src/main/python/DockWidgets/DockWidgetShortcutColumn.py148
-rw-r--r--src/main/python/DockWidgets/DockWidgetSplitter.py85
-rw-r--r--src/main/python/DockWidgets/__init__.py0
-rw-r--r--src/main/python/DockWidgets/__pycache__/DistillationColumnStagewiseResults.cpython-36.pycbin0 -> 942 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DistillationColumnStagewiseResults.cpython-37.pycbin0 -> 946 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidget.cpython-36.pycbin0 -> 4843 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidget.cpython-37.pycbin0 -> 4847 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetCompoundSeparator.cpython-36.pycbin0 -> 4450 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetCompoundSeparator.cpython-37.pycbin0 -> 4454 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetCompressorExpander.cpython-36.pycbin0 -> 5466 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetCompressorExpander.cpython-37.pycbin0 -> 5470 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetDistillationColumn.cpython-36.pycbin0 -> 10450 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetDistillationColumn.cpython-37.pycbin0 -> 10387 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetFlash.cpython-36.pycbin0 -> 3547 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetFlash.cpython-37.pycbin0 -> 3551 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetMaterialStream.cpython-36.pycbin0 -> 9701 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetMaterialStream.cpython-37.pycbin0 -> 9690 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetMixer.cpython-36.pycbin0 -> 2703 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetMixer.cpython-37.pycbin0 -> 2707 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetShortcutColumn.cpython-36.pycbin0 -> 5592 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetShortcutColumn.cpython-37.pycbin0 -> 5589 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetSplitter.cpython-36.pycbin0 -> 3338 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/DockWidgetSplitter.cpython-37.pycbin0 -> 3342 bytes
-rw-r--r--src/main/python/DockWidgets/__pycache__/__init__.cpython-37.pycbin0 -> 208 bytes
-rw-r--r--src/main/python/OMChem/CompSep.py71
-rw-r--r--src/main/python/OMChem/ConvReactor.py44
-rw-r--r--src/main/python/OMChem/Cooler.py76
-rw-r--r--src/main/python/OMChem/DistCol.py103
-rw-r--r--src/main/python/OMChem/EngStm.py18
-rw-r--r--src/main/python/OMChem/Flash.py55
-rw-r--r--src/main/python/OMChem/Flowsheet.py307
-rw-r--r--src/main/python/OMChem/Heater.py75
-rw-r--r--src/main/python/OMChem/Mixer.py58
-rw-r--r--src/main/python/OMChem/Pump.py62
-rw-r--r--src/main/python/OMChem/ShortcutColumn.py86
-rw-r--r--src/main/python/OMChem/Splitter.py61
-rw-r--r--src/main/python/OMChem/Valve.py58
-rw-r--r--src/main/python/OMChem/__init__.py0
-rw-r--r--src/main/python/OMChem/__pycache__/EngStm.cpython-36.pycbin0 -> 925 bytes
-rw-r--r--src/main/python/OMChem/__pycache__/EngStm.cpython-37.pycbin0 -> 929 bytes
-rw-r--r--src/main/python/OMChem/__pycache__/Flowsheet.cpython-36.pycbin0 -> 8426 bytes
-rw-r--r--src/main/python/OMChem/__pycache__/Flowsheet.cpython-37.pycbin0 -> 8400 bytes
-rw-r--r--src/main/python/OMChem/__pycache__/__init__.cpython-37.pycbin0 -> 203 bytes
-rw-r--r--src/main/python/OMChem/adiabatic_comp.py67
-rw-r--r--src/main/python/OMChem/adiabatic_exp.py67
-rw-r--r--src/main/python/OMChem/setup.py54
-rw-r--r--src/main/python/mainApp.py417
-rw-r--r--src/main/python/utils/Bin_Phase_env.py241
-rw-r--r--src/main/python/utils/ComponentSelector.py177
-rw-r--r--src/main/python/utils/Container.py264
-rw-r--r--src/main/python/utils/Graphics.py694
-rw-r--r--src/main/python/utils/Streams.py476
-rw-r--r--src/main/python/utils/UnitOperations.py739
-rw-r--r--src/main/python/utils/__init__.py0
-rw-r--r--src/main/python/utils/__pycache__/Bin_Phase_env.cpython-37.pycbin0 -> 7968 bytes
-rw-r--r--src/main/python/utils/__pycache__/ComponentSelector.cpython-37.pycbin0 -> 5514 bytes
-rw-r--r--src/main/python/utils/__pycache__/Container.cpython-37.pycbin0 -> 7735 bytes
-rw-r--r--src/main/python/utils/__pycache__/Graphics.cpython-37.pycbin0 -> 23723 bytes
-rw-r--r--src/main/python/utils/__pycache__/Streams.cpython-37.pycbin0 -> 12744 bytes
-rw-r--r--src/main/python/utils/__pycache__/UnitOperations.cpython-37.pycbin0 -> 26682 bytes
-rw-r--r--src/main/python/utils/__pycache__/__init__.cpython-37.pycbin0 -> 202 bytes
-rw-r--r--src/main/python/utils/thermopackage.txt6
70 files changed, 5910 insertions, 0 deletions
diff --git a/src/main/python/DockWidgets/DistillationColumnStagewiseResults.py b/src/main/python/DockWidgets/DistillationColumnStagewiseResults.py
new file mode 100644
index 0000000..65527dc
--- /dev/null
+++ b/src/main/python/DockWidgets/DistillationColumnStagewiseResults.py
@@ -0,0 +1,18 @@
+import os, sys
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+from PyQt5.uic import loadUiType
+from PyQt5.QtWidgets import QWidget
+
+ui_dialog,_ = loadUiType(parentPath+'/ui/DockWidgets/DistillationColumnStagewiseResults.ui')
+
+
+class DistillationColumnStagewiseResults(QWidget,ui_dialog):
+
+ def __init__(self, parent=None):
+ QWidget.__init__(self, parent)
+ self.setupUi(self)
+ # self.setWindowTitle(self.parent.obj.name)
diff --git a/src/main/python/DockWidgets/DockWidget.py b/src/main/python/DockWidgets/DockWidget.py
new file mode 100644
index 0000000..764d8fb
--- /dev/null
+++ b/src/main/python/DockWidgets/DockWidget.py
@@ -0,0 +1,168 @@
+import os, sys
+
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtGui import *
+from PyQt5.uic import loadUiType
+from python.utils.ComponentSelector import *
+from python.utils.Graphics import *
+
+ui_dialog,_ = loadUiType(parentPath+'/ui/DockWidgets/DockWidget.ui')
+
+class DockWidget(QDockWidget,ui_dialog):
+
+ def __init__(self,name,comptype,obj,container, parent=None):
+ QDockWidget.__init__(self,parent)
+ self.setupUi(self)
+ self.setWindowTitle(obj.name)
+ self.name=name
+ self.obj=obj
+ self.type = comptype
+ self.input_dict = {}
+ self.modes()
+ self.comboBox.currentIndexChanged.connect(self.mode_selection)
+
+ #print("constructor ", self.input_dict)
+ self.pushButton_2.clicked.connect(self.param)
+
+ self.dict = {} # a dictionary
+ self.container = container
+
+ # input data tab
+ def modes(self):
+ modes_list = self.obj.modes_list
+ if(modes_list):
+ for j in modes_list:
+ self.comboBox.addItem(str(self.obj.variables[j]['name']))
+ self.comboBox.setCurrentText(self.obj.variables[self.obj.mode]['name'])
+ self.mode_selection()
+ else:
+ self.comboBox.setDisabled(True)
+ self.input_dict= {}
+ self.input_dict = self.obj.param_getter()
+ self.input_params_list()
+
+ def mode_selection(self):
+ self.input_dict= {}
+ for i in reversed(range(self.formLayout.count())):
+ self.formLayout.removeRow(i)
+ #print(self.comboBox.currentText())
+ for i in self.obj.variables:
+ if self.obj.variables[i]['name'] == self.comboBox.currentText():
+ currentText = i
+ break
+ self.input_dict = self.obj.param_getter(currentText)
+ #print('mode selection ', self.input_dict)
+ self.input_params_list()
+
+ def input_params_list(self):
+ try:
+ #print("input_params_list ", self.input_dict)
+ for c,i in enumerate(self.input_dict):
+ #print(i)
+ if i == None:
+ continue
+ l = QLineEdit(str(self.obj.variables[i]['value']))
+ l.setFixedWidth(80)
+ lay = QGridLayout()
+ lay.addWidget(QLabel(self.obj.variables[i]['name']+":"),0,0, alignment=Qt.AlignLeft)
+ lay.addWidget(l,0,1, alignment=Qt.AlignCenter)
+ lay.addWidget(QLabel(self.obj.variables[i]['unit']),0,2, alignment=Qt.AlignLeft)
+ self.formLayout.addRow(lay)
+ self.input_dict[i] = l
+ except Exception as e:
+ print(e)
+
+
+ def show_error(self):
+ QMessageBox.about(self, 'Important', "Please fill all fields with data")
+
+ def param(self):
+ try:
+ self.dict = {}
+ #print("param.input_dict ", self.input_dict)
+ for i in self.input_dict:
+ if (self.input_dict[i] == None):
+ continue
+ else:
+ #print(self.input_dict[i], i, self.obj.type)
+ if (self.input_dict[i].text()):
+ self.dict[i] = self.input_dict[i].text()
+ else:
+ #print(self.input_dict[i].text())
+ self.show_error()
+ break
+
+ #print("param ", self.dict)
+ self.obj.param_setter(self.dict)
+ for i in self.container.graphics.graphicsView.items():
+ try:
+ if(i.name == self.name):
+ i.update_tooltip()
+ except:
+ pass
+ if(self.isVisible()):
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189)
+ self.hide()
+
+ except Exception as e:
+ print(e)
+
+ @staticmethod
+ def show_result(lst):
+ for i in lst:
+ try:
+ i.results_category(i.name)
+ except AttributeError:
+ pass
+
+ def clear_results(self):
+ self.tableWidget.setRowCount(0)
+
+ # result data tab
+ def results_category(self,name):
+ flag = True
+ try:
+ #print("Under result category name ", name)
+ result=self.container.result
+ obj = self.container.fetch_object(name)
+ self.tableWidget.setRowCount(0)
+ variKeys = list(obj.variables.keys())
+ #print(variKeys)
+ for i, val in enumerate(variKeys):
+ propertyname = name + '.' + val
+ #print(i,val, propertyname)
+ if propertyname in result[0]:
+ ind = result[0].index(propertyname)
+ resultval = str(result[-1][ind])
+ #print("######Resultsfetch####",val,resultval)
+ rowPosition = self.tableWidget.rowCount()
+ self.tableWidget.insertRow(rowPosition)
+ self.tableWidget.setItem(rowPosition , 0, QTableWidgetItem(obj.variables[val]['name']))
+ self.tableWidget.setItem(rowPosition , 1, QTableWidgetItem(resultval))
+ self.tableWidget.setItem(rowPosition , 2, QTableWidgetItem(obj.variables[val]['unit']))
+ self.tableWidget.resizeColumnsToContents()
+
+ # Updating result in class
+ obj.variables[val]['value'] = resultval
+ # try:
+ # if obj.type == "Heater":
+ # print(obj.variables[val]['name'] + str(obj.variables[val]['value']))
+ # except Exception as e:
+ # print(e)
+
+
+
+ except Exception as e:
+ print(e)
+
+ def closeEvent(self,event):
+ scrollHVal = self.parent().container.graphics.graphicsView.horizontalScrollBarVal
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189) \ No newline at end of file
diff --git a/src/main/python/DockWidgets/DockWidgetCompoundSeparator.py b/src/main/python/DockWidgets/DockWidgetCompoundSeparator.py
new file mode 100644
index 0000000..26f8fd4
--- /dev/null
+++ b/src/main/python/DockWidgets/DockWidgetCompoundSeparator.py
@@ -0,0 +1,134 @@
+import os, sys
+
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtGui import *
+from PyQt5.uic import loadUiType
+import pandas as pd
+from functools import partial
+from python.utils.ComponentSelector import *
+from collections import defaultdict
+from python.utils.Graphics import *
+
+ui_dialog,_ = loadUiType(parentPath+'/ui/DockWidgets/DockWidgetCompoundSeparator.ui')
+
+class DockWidgetCompoundSeparator(QDockWidget,ui_dialog):
+
+ def __init__(self,name,comptype,obj,container,parent=None):
+ QDockWidget.__init__(self,parent)
+ self.setupUi(self)
+ self.setWindowTitle(obj.name)
+ self.name=name
+ self.obj=obj
+ self.type = comptype
+ self.input_dict = []
+ self.lst = []
+ self.input_params_list()
+ self.dict = []
+
+ def input_params_list(self):
+ try:
+ if self.type == 'CompoundSeparator':
+ self.lst.clear()
+ self.calculationGroupBox = QGroupBox('Calculation Parameters')
+ self.calculationLayout = QGridLayout()
+
+ r1 = QRadioButton('Stream 1')
+ r1.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+ r2 = QRadioButton('Stream 2')
+ r2.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+ if self.obj.variables['SepStrm']['value'] == 1:
+ r1.setChecked(True)
+ r2.setChecked(False)
+ else:
+ r1.setChecked(False)
+ r2.setChecked(True)
+
+
+ self.lst = [r1, r2]
+ self.calculationLayout.addWidget(r1, 0, 1)
+ self.calculationLayout.addWidget(r2, 0, 2)
+
+ for k,val in enumerate(self.obj.compounds):
+ combo = QComboBox()
+ #print("CompoundSeparator combo")
+ for j in self.obj.SepFact_modes:
+ combo.addItem(str(j))
+ #print(self.obj.variables['SepFact_c']['value'][k])
+ combo.setCurrentText(self.obj.variables['SepFact_c']['value'][k])
+ combo.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+ l = QLineEdit(str(self.obj.variables['SepVal_c']['value'][k]))
+ l.setFixedWidth(80)
+ l.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+ self.calculationLayout.addWidget(QLabel(val+" :"), k+1,0, alignment=Qt.AlignLeft)
+ self.calculationLayout.addWidget(combo, k+1, 1, alignment=Qt.AlignCenter)
+ self.calculationLayout.addWidget(l,k+1,2, alignment=Qt.AlignCenter)
+ self.lst.append(combo)
+ self.lst.append(l)
+
+ self.calculationLayout.setColumnStretch(3, len(self.obj.compounds)+1)
+ self.calculationGroupBox.setLayout(self.calculationLayout)
+
+ btn = QPushButton('Submit')
+ btn.clicked.connect(self.param)
+
+ self.gridLayout.setVerticalSpacing(5)
+ self.gridLayout.addWidget(self.calculationGroupBox,0,0)
+ self.gridLayout.addWidget(btn,1,0)
+
+ self.input_dict = self.lst
+
+ except Exception as e:
+ print(e)
+
+ def show_error(self):
+ QMessageBox.about(self, 'Important', "Please fill all fields with data")
+
+ def update_compounds(self):
+ try:
+ self.obj.init_variables()
+ t_item = self.calculationGroupBox.layout().itemAt(0)
+ self.calculationGroupBox.layout().removeItem(t_item)
+ while(t_item):
+ t_widget = t_item.widget()
+ if(t_widget):
+ t_widget.setHidden(True)
+ self.calculationGroupBox.layout().removeWidget(t_widget)
+ t_item = self.calculationGroupBox.layout().itemAt(0)
+ self.input_params_list()
+ except Exception as e:
+ print(e)
+
+
+ def param(self):
+ try:
+ self.dict=[]
+
+ self.dict = [self.input_dict[0].isChecked(), self.input_dict[1].isChecked()]
+ j = 2
+ for i in range(len(self.obj.compounds)):
+ self.dict.append(self.input_dict[j+i].currentText())
+ if(self.input_dict[j+i+1].text()):
+ self.dict.append(self.input_dict[j+i+1].text())
+ j += 1
+ else:
+ self.show_error()
+
+
+ self.obj.param_setter(self.dict)
+ if(self.isVisible()):
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189)
+ self.hide()
+
+ except Exception as e:
+ print(e)
+ def closeEvent(self,event):
+ scrollHVal = self.parent().container.graphics.graphicsView.horizontalScrollBarVal
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189) \ No newline at end of file
diff --git a/src/main/python/DockWidgets/DockWidgetCompressorExpander.py b/src/main/python/DockWidgets/DockWidgetCompressorExpander.py
new file mode 100644
index 0000000..9a8cb07
--- /dev/null
+++ b/src/main/python/DockWidgets/DockWidgetCompressorExpander.py
@@ -0,0 +1,167 @@
+import os, sys
+
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtGui import *
+from PyQt5.uic import loadUiType
+from python.utils.ComponentSelector import *
+from python.utils.Graphics import *
+
+ui_dialog,_ = loadUiType(parentPath+'/ui/DockWidgets/DockWidgetCompressorExpander.ui')
+
+class DockWidgetCompressorExpander(QDockWidget,ui_dialog):
+
+ def __init__(self,name,comptype,obj,container, parent=None):
+ QDockWidget.__init__(self,parent)
+ self.setupUi(self)
+ self.setWindowTitle(obj.name)
+ self.name=name
+ self.obj=obj
+ self.type = comptype
+ self.input_dict = {}
+ self.x_pclist = []
+ self.modes()
+ self.comboBox.currentIndexChanged.connect(self.mode_selection)
+
+ self.pushButton_2.clicked.connect(self.param)
+ self.dict = {}
+
+ self.name_type = None
+ self.container = container
+
+ # input data tab
+ def modes(self):
+ modes_list = self.obj.modes_list
+ if(modes_list):
+ for j in modes_list:
+ self.comboBox.addItem(str(self.obj.variables[j]['name']))
+ self.mode_selection()
+ else:
+ self.comboBox.setDisabled(True)
+ self.input_dict= {}
+ self.input_dict = self.obj.param_getter()
+ self.input_params_list()
+
+ def mode_selection(self):
+ self.input_dict= {}
+ for i in reversed(range(self.formLayout.count())):
+ self.formLayout.removeRow(i)
+ #print(self.comboBox.currentText())
+ for i in self.obj.variables:
+ if self.obj.variables[i]['name'] == self.comboBox.currentText():
+ currentText = i
+ break
+ self.input_dict = self.obj.param_getter(currentText)
+ #print('mode selection ', self.input_dict)
+ self.input_params_list()
+
+ def input_params_list(self):
+ try:
+ #print("input_params_list ", self.input_dict)
+ for c,i in enumerate(self.input_dict):
+ if i == None:
+ continue
+
+ l = QLineEdit()
+ if self.input_dict[i] != None:
+ l.setText(str(self.input_dict[i]))
+ l.setFixedWidth(80)
+ lay = QGridLayout()
+ lay.addWidget(QLabel(self.obj.variables[i]['name']+":"),0,0, alignment=Qt.AlignLeft)
+ lay.addWidget(l,0,1, alignment=Qt.AlignCenter)
+ lay.addWidget(QLabel(self.obj.variables[i]['unit']),0,2, alignment=Qt.AlignLeft)
+
+ self.formLayout.addRow(lay)
+ self.input_dict[i] = l
+
+ self.lines = [line.rstrip('\n') for line in open(parentPath+'/python/utils/thermopackage.txt')]
+ for j in self.lines:
+ self.cbTP.addItem(str(j))
+ self.input_dict['Thermo Package'] = self.cbTP
+
+ except Exception as e:
+ print(e)
+
+ def show_error(self):
+ QMessageBox.about(self, 'Important', "Please fill all fields with data")
+
+ def param(self):
+ try:
+ self.dict={}
+ for i in self.input_dict:
+ if (self.input_dict[i] == None):
+ continue
+ elif (i == "Thermo Package"):
+ self.dict[i] = self.input_dict[i].currentText()
+ else:
+ #print(self.input_dict[i], i, self.obj.type)
+ if (self.input_dict[i].text()):
+ self.dict[i] = self.input_dict[i].text()
+ else:
+ #print(self.input_dict[i].text())
+ self.show_error()
+ break
+
+ self.obj.param_setter(self.dict)
+
+ for i in self.container.graphics.graphicsView.items():
+ try:
+ if(i.name == self.name):
+ i.update_tooltip()
+ except:
+ pass
+ if(self.isVisible()):
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189)
+ self.hide()
+
+ except Exception as e:
+ print(e)
+
+ @staticmethod
+ def show_result(lst):
+ for i in lst:
+ try:
+ i.results_category(i.name)
+ except AttributeError:
+ pass
+
+ def clear_results(self):
+ self.tableWidget.setRowCount(0)
+
+ # result data tab
+ def results_category(self,name):
+ flag = True
+ try:
+ #print("Under result category name ", name)
+ result=self.container.result
+ obj = self.container.fetch_object(name)
+ self.tableWidget.setRowCount(0)
+ variKeys = list(obj.variables.keys())
+ #print(variKeys)
+ for i, val in enumerate(variKeys):
+ propertyname = name + '.' + val
+ #print(i,val, propertyname)
+ if propertyname in result[0]:
+ ind = result[0].index(propertyname)
+ resultval = str(result[-1][ind])
+ #print("######Resultsfetch####",val,resultval)
+ rowPosition = self.tableWidget.rowCount()
+ self.tableWidget.insertRow(rowPosition)
+ self.tableWidget.setItem(rowPosition , 0, QTableWidgetItem(obj.variables[val]['name']))
+ self.tableWidget.setItem(rowPosition , 1, QTableWidgetItem(resultval))
+ self.tableWidget.setItem(rowPosition , 2, QTableWidgetItem(obj.variables[val]['unit']))
+ self.tableWidget.resizeColumnsToContents()
+
+ except Exception as e:
+ print(e)
+
+ def closeEvent(self,event):
+ scrollHVal = self.parent().container.graphics.graphicsView.horizontalScrollBarVal
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189) \ No newline at end of file
diff --git a/src/main/python/DockWidgets/DockWidgetDistillationColumn.py b/src/main/python/DockWidgets/DockWidgetDistillationColumn.py
new file mode 100644
index 0000000..7895b32
--- /dev/null
+++ b/src/main/python/DockWidgets/DockWidgetDistillationColumn.py
@@ -0,0 +1,390 @@
+import os, sys
+
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtGui import *
+from PyQt5.uic import loadUiType
+import pandas as pd
+from functools import partial
+from collections import defaultdict
+
+from python.utils.ComponentSelector import *
+from python.DockWidgets.DistillationColumnStagewiseResults import DistillationColumnStagewiseResults
+from python.utils.Graphics import *
+
+ui_dialog,_ = loadUiType(parentPath+'/ui/DockWidgets/DockWidgetDistillationColumn.ui')
+
+
+class DockWidgetDistillationColumn(QDockWidget, ui_dialog):
+
+ def __init__(self,name,comptype,obj,container,parent=None):
+ QDockWidget.__init__(self,parent)
+ self.setupUi(self)
+ self.setWindowTitle(obj.name)
+ self.name=name
+ self.obj=obj
+ self.type = comptype
+ self.input_dict = []
+ self.pushButton_2.clicked.connect(self.param)
+ self.dict = []
+ self.input_params_list()
+ self.name_type = None
+ self.container = container
+ self.stage_res_table = DistillationColumnStagewiseResults()
+ self.stageResultsButton.clicked.connect(self.showStagewiseResults)
+
+ # input data tab
+
+ def input_params_list(self):
+ try:
+ print("input_params_list ", self.input_dict)
+
+ # tab 1
+
+ l1 = QLineEdit()
+ l1.setFixedWidth(80)
+ l1.setText(str(self.obj.variables['Nt']['value']))
+ self.lay1.addWidget(QLabel(self.obj.variables['Nt']['name'] + " :"), 0 ,0, alignment=Qt.AlignLeft)
+ self.lay1.addWidget(l1,0,1, alignment=Qt.AlignLeft)
+ self.input_dict.append(l1)
+
+ for i in range(self.obj.variables['Ni']['value']):
+ print(i)
+ l = QLineEdit()
+ l.setFixedWidth(80)
+ if len(self.obj.variables['InT_s']['value']) is not 0:
+ l.setText(str(self.obj.variables['InT_s']['value'][i]))
+ self.lay1.addWidget(QLabel(self.obj.variables['InT_s']['name'] +" " + str(i+1) + " location :"),2*(i+1),0, alignment=Qt.AlignLeft)
+ self.lay1.addWidget(l,2*(i+1),1, alignment=Qt.AlignLeft)
+ self.input_dict.append(l)
+
+ # tab 2
+ self.l4.setText(self.obj.variables['Ctype']['name']+":")
+
+ self.u1.setText(self.obj.variables['Ctype']['unit'])
+ self.l5.setText(self.obj.variables['Pcond']['name']+":")
+ self.le5.setText(str(self.obj.variables['Pcond']['value']))
+ self.u2.setText(self.obj.variables['Pcond']['unit'])
+ self.l6.setText(self.obj.variables['C_Spec']['name']+":")
+ self.le6.setText(str(self.obj.variables['C_Spec']['value']))
+ self.l7.setText("Compounds :")
+
+ self.cb5.addItem("Total")
+ self.cb5.addItem("Partial")
+ self.cb5.setCurrentText(self.obj.variables['Ctype']['value'])
+
+ for j in self.obj.Cspec_list:
+ self.cb1.addItem(str(j))
+ self.cb1.setCurrentText(self.obj.variables['C_Spec']['type'])
+ for j in self.obj.compounds:
+ self.cb2.addItem(str(j))
+ self.cb2.setCurrentText(self.obj.variables['C_Spec']['comp'])
+
+ self.cb2.setDisabled(True)
+ self.cb1.currentIndexChanged.connect(self.fun2)
+
+ self.le5.setFixedWidth(80)
+ self.le6.setFixedWidth(80)
+ self.le7.setFixedWidth(80)
+ self.le8.setFixedWidth(80)
+ self.cb1.setFixedWidth(180)
+ self.cb2.setFixedWidth(80)
+ self.cb3.setFixedWidth(180)
+ self.cb4.setFixedWidth(80)
+ self.cb5.setFixedWidth(80)
+ self.u2.setAlignment(Qt.AlignLeft)
+ self.u3.setAlignment(Qt.AlignLeft)
+
+ self.input_dict.append(self.cb5)
+ self.input_dict.append(self.le5)
+ self.input_dict.append(self.cb1)
+ self.input_dict.append(self.cb2)
+ self.input_dict.append(self.le6)
+
+ # tab3
+ self.l8.setText(self.obj.variables['Preb']['name']+":")
+ self.le7.setText(str(self.obj.variables['Preb']['value']))
+ self.u3.setText(self.obj.variables['Preb']['unit'])
+ self.l9.setText(self.obj.variables['R_Spec']['name']+":")
+ self.le8.setText(str(self.obj.variables['R_Spec']['value']))
+ self.l10.setText('Compounds')
+
+ for j in self.obj.Rspec_list:
+ self.cb3.addItem(str(j))
+ self.cb3.setCurrentText(self.obj.variables['R_Spec']['type'])
+ for j in self.obj.compounds:
+ self.cb4.addItem(str(j))
+ self.cb4.setCurrentText(self.obj.variables['R_Spec']['comp'])
+ self.cb4.setDisabled(True)
+ self.cb3.currentIndexChanged.connect(self.fun3)
+
+ self.input_dict.append(self.le7)
+ self.input_dict.append(self.cb3)
+ self.input_dict.append(self.cb4)
+ self.input_dict.append(self.le8)
+
+ self.lines = [line.rstrip('\n') for line in open(parentPath+'/python/utils/thermopackage.txt')]
+ for j in self.lines:
+ self.cbTP.addItem(str(j))
+ self.cbTP.setCurrentText(self.obj.variables['thermo_package']['value'])
+
+ self.input_dict.append(self.cbTP)
+
+ # self.input_dict = [self.le1, self.le2, self.le3, self.cb5, self.le5, self.cb1, self.cb2, self.le6, self.le7, self.cb3, self.cb4, self.le8]
+
+ except Exception as e:
+ print(e)
+
+ def update_compounds(self):
+ self.cb2.clear()
+ self.cb4.clear()
+ for j in self.obj.compounds:
+ self.cb2.addItem(str(j))
+ self.cb2.setCurrentText(self.obj.variables['C_Spec']['comp'])
+ for j in self.obj.compounds:
+ self.cb4.addItem(str(j))
+ self.cb4.setCurrentText(self.obj.variables['R_Spec']['comp'])
+
+ def fun2(self):
+ if self.cb1.currentText() == 'Compound Molar Fraction' or self.cb1.currentText() == 'Compound Molar Flow (mol/s)':
+ self.cb2.setDisabled(False)
+ else:
+ self.cb2.setDisabled(True)
+
+ def fun3(self):
+ if self.cb3.currentText() == 'Compound Molar Fraction' or self.cb3.currentText() == 'Compound Molar Flow (mol/s)':
+ self.cb4.setDisabled(False)
+ else:
+ self.cb4.setDisabled(True)
+
+ def Show_Error(self):
+ QMessageBox.about(self, 'Important', "Please fill all fields with data")
+
+ def param(self):
+ try:
+ self.dict= []
+ temp = 0
+ print("param.input_dict ", self.input_dict)
+ self.dict.append(int(self.input_dict[0].text()))
+
+ for i in range(self.obj.variables['Ni']['value']):
+ self.dict.append(int(self.input_dict[i+1].text()))
+ temp = i + 1
+ print(temp)
+
+ # print(temp)
+ # print(self.input_dict[temp+1])
+ self.dict.append(self.input_dict[temp+1].currentText())
+ # print(temp+1)
+ self.dict.append(int(self.input_dict[temp+2].text()))
+ #print(temp+2)
+ self.dict.append(self.input_dict[temp+3].currentText())
+ #print(temp+3)
+ self.dict.append(self.input_dict[temp+4].currentText())
+ #print(temp+4)
+ self.dict.append(int(self.input_dict[temp+5].text()))
+ #print(temp+5)
+ self.dict.append(int(self.input_dict[temp+6].text()))
+ #print(temp+6)
+ self.dict.append(self.input_dict[temp+7].currentText())
+ #print(temp+7)
+ self.dict.append(self.input_dict[temp+8].currentText())
+ #print(temp+8)
+ self.dict.append(int(self.input_dict[temp+9].text()))
+ #print(temp+9)
+ self.dict.append(self.input_dict[temp+10].currentText())
+ #print(temp + 10)
+
+ #print("param ", self.dict)
+ self.obj.param_setter(self.dict)
+ if(self.isVisible()):
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189)
+ self.hide()
+
+ except Exception as e:
+ print(e)
+
+ def showStagewiseResults(self):
+ self.stage_res_table.show()
+
+ @staticmethod
+ def showResult(lst):
+ # DockWidget1.flag = True
+ for i in lst:
+ try:
+ i.results_category(i.name)
+ except AttributeError:
+ pass
+
+ def clear_results(self):
+ self.tableWidget.setRowCount(0)
+ self.stage_res_table.T_table.setRowCount(0)
+ self.stage_res_table.T_table.setColumnCount(0)
+ self.stage_res_table.x_pc_table.setRowCount(0)
+ self.stage_res_table.x_pc_table.setColumnCount(0)
+
+ # result data tab
+ def results_category(self,name):
+ flag = True
+ try:
+ #print("Under result category name ", name)
+ result = self.container.result
+ obj = self.container.fetch_object(name)
+ self.tableWidget.setRowCount(0)
+ variKeys = obj.result_parameters
+ #print(variKeys)
+ for i, val in enumerate(variKeys):
+ propertyname = name + '.' + val
+ #print(i, val, propertyname)
+ if propertyname in result[0]:
+ ind = result[0].index(propertyname)
+ resultval = str(result[-1][ind])
+ obj.variables[val]['value'] = result[-1][ind]
+ #print("######Resultsfetch####", val, resultval)
+ rowPosition = self.tableWidget.rowCount()
+ self.tableWidget.insertRow(rowPosition)
+ self.tableWidget.setItem(rowPosition, 0, QTableWidgetItem(obj.variables[val]['name']))
+ self.tableWidget.setItem(rowPosition, 1, QTableWidgetItem(resultval))
+ self.tableWidget.setItem(rowPosition, 2, QTableWidgetItem(obj.variables[val]['unit']))
+ self.tableWidget.resizeColumnsToContents()
+
+ # Stagewise Results
+ Nt = self.obj.variables['Nt']['value']
+ Nc = len(self.obj.compounds)
+ # initializing temporary arrays
+ Stages_T = [None for i in range(Nt)]
+ # Can be uncommented when F_p and F_pc implemented in modelica table
+ # Stages_F_p = [[None for i in range(3)] for j in range(Nt)]
+ # Stages_F_pc = [[[None for i in range(3)] for j in range(Nc)] for k in range(Nt)]
+ Stages_x_pc = [[[None for i in range(3)] for j in range(Nc)] for k in range(Nt)]
+
+ Stages_res_varikeys = ['T']
+ for i in range(Nc):
+ for j in range(3):
+ Stages_res_varikeys.append('x_pc[' + str(j + 1) + ',' + str(i + 1) + ']')
+
+ for v in Stages_res_varikeys:
+ propertyname = name + '.condenser.' + v
+ if propertyname in result[0]:
+ ind = result[0].index(propertyname)
+ if v == 'T':
+ Stages_T[0] = result[-1][ind]
+ # Can be uncommented when F_p is implemented in modelica model
+ # elif v == 'F_p':
+ # if result[0][ind][result[0][ind].index('[') + 1] == '1':
+ # Stages_F_p[0][0] = result[-1][ind]
+ # elif result[0][ind][result[0][ind].index('[') + 1] == '2':
+ # Stages_F_p[0][1] = result[-1][ind]
+ # else:
+ # Stages_F_p[0][2] = result[-1][ind]
+ else:
+ #print(ind)
+ phase_no = int(result[0][ind][result[0][ind].index('[') + 1])
+ comp_no = int(result[0][ind][result[0][ind].index(']') - 1])
+ Stages_x_pc[0][comp_no - 1][phase_no - 1] = result[-1][ind]
+ # Can be uncommented and improved when F_pc implemented in modelica model
+ # if v == 'F_pc':
+ # Stages_F_pc[0][comp_no - 1][phase_no - 1] = result[-1][ind]
+ # else:
+ # Stages_x_pc[0][comp_no - 1][phase_no - 1] = result[-1][ind]
+
+ for i in range(1, Nt - 1):
+ propertyname = name + '.tray[' + str(i) + '].' + v
+ if propertyname in result[0]:
+ ind = result[0].index(propertyname)
+ if v == 'T':
+ Stages_T[i] = result[-1][ind]
+ # Can be uncommented when F_p implemented in modelica model
+ # elif v == 'F_p':
+ # if result[0][ind][result[0][ind].index('[') + 1] == '1':
+ # Stages_F_p[i][0] = result[-1][ind]
+ # elif result[0][ind][result[0][ind].index('[') + 1] == '2':
+ # Stages_F_p[i][1] = result[-1][ind]
+ # else:
+ # Stages_F_p[i][2] = result[-1][ind]
+ else:
+ # print(ind)
+ # print(result[0][ind])
+ phase_no = int(result[0][ind].split('.')[-1][result[0][ind].split('.')[-1].index('[') + 1])
+ comp_no = int(result[0][ind].split('.')[-1][result[0][ind].split('.')[-1].index(']') - 1])
+ Stages_x_pc[i][comp_no - 1][phase_no - 1] = result[-1][ind]
+ # Can be uncommented when F_pc implemented in modelica model
+ # if v == 'F_pc':
+ # Stages_F_pc[i][comp_no - 1][phase_no - 1] = result[-1][ind]
+ # else:
+ # Stages_x_pc[i][comp_no - 1][phase_no - 1] = result[-1][ind]
+
+ propertyname = name + '.reboiler.' + v
+ if propertyname in result[0]:
+ ind = result[0].index(propertyname)
+ if v == 'T':
+ Stages_T[-1] = result[-1][ind]
+ # Can be uncommented when F_p implemented in modelica model
+ # elif v == 'F_p':
+ # if result[0][ind][result[0][ind].index('[') + 1] == '1':
+ # Stages_F_p[-1][0] = result[-1][ind]
+ # elif result[0][ind][result[0][ind].index('[') + 1] == '2':
+ # Stages_F_p[-1][1] = result[-1][ind]
+ # else:
+ # Stages_F_p[-1][2] = result[-1][ind]
+ else:
+ print(ind)
+ phase_no = int(result[0][ind][result[0][ind].index('[') + 1])
+ comp_no = int(result[0][ind][result[0][ind].index(']') - 1])
+ Stages_x_pc[-1][comp_no - 1][phase_no - 1] = result[-1][ind]
+ # Can be uncommented when F_pc implemented in modelica model
+ # if v == 'F_pc':
+ # Stages_F_pc[-1][comp_no - 1][phase_no - 1] = result[-1][ind]
+ # else:
+ # Stages_x_pc[-1][comp_no - 1][phase_no - 1] = result[-1][ind]
+
+ # Assigning temp variables to obj variabes
+ self.obj.variables['Stages.T']['value'] = Stages_T
+ # Can be uncommented when F_p and F_pc implemented in modelica model
+ # self.obj.variables['Stages.F_p']['value'] = Stages_F_p
+ # self.obj.variables['Stages.F_pc']['value'] = Stages_F_pc
+ self.obj.variables['Stages.x_pc']['value'] = Stages_x_pc
+
+ # filling stagewise result table
+ tables = [self.stage_res_table.T_table, self.stage_res_table.x_pc_table]
+ # Can be uncommented when F_p and F_pc implemented in modelica model
+ # tables = [self.stage_res_table.T_table, self.stage_res_table.F_p_table, self.stage_res_table.F_pc_table, self.stage_res_table.x_pc_table]
+
+ for t in tables:
+ t.setRowCount(Nt)
+ t.setVerticalHeaderItem(0, QTableWidgetItem('Condenser'))
+ t.setVerticalHeaderItem(Nt -1, QTableWidgetItem('Reboiler'))
+ for i in range(1, Nt - 1):
+ t.setVerticalHeaderItem(i, QTableWidgetItem('Stage ' + str(i)))
+
+ T_table = self.stage_res_table.T_table
+ T_table.setColumnCount(1)
+ for i in range(Nt):
+ T_table.setItem(i, 0, QTableWidgetItem(Stages_T[i]))
+
+ x_pc_table = self.stage_res_table.x_pc_table
+ x_pc_table.setColumnCount(2*Nc)
+ for i in range(Nc):
+ x_pc_table.setHorizontalHeaderItem(2*i, QTableWidgetItem(self.obj.compounds[i] + '(Vapor)'))
+ x_pc_table.setHorizontalHeaderItem(2*i + 1, QTableWidgetItem(self.obj.compounds[i] + '(Liquid)'))
+
+ for i in range(Nt):
+ for j in range(Nc):
+ x_pc_table.setItem(i, 2*j, QTableWidgetItem(Stages_x_pc[i][j][1]))
+ x_pc_table.setItem(i, 2 * j + 1, QTableWidgetItem(Stages_x_pc[i][j][2]))
+
+ for t in tables:
+ t.resizeColumnsToContents()
+ except Exception as e:
+ print(e)
+
+ def closeEvent(self,event):
+ scrollHVal = self.parent().container.graphics.graphicsView.horizontalScrollBarVal
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189) \ No newline at end of file
diff --git a/src/main/python/DockWidgets/DockWidgetFlash.py b/src/main/python/DockWidgets/DockWidgetFlash.py
new file mode 100644
index 0000000..c001fe2
--- /dev/null
+++ b/src/main/python/DockWidgets/DockWidgetFlash.py
@@ -0,0 +1,90 @@
+import os, sys
+
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtGui import *
+from PyQt5.uic import loadUiType
+from python.utils.ComponentSelector import *
+from python.utils.Graphics import *
+
+ui_dialog,_ = loadUiType(parentPath+'/ui/DockWidgets/DockWidgetFlash.ui')
+
+class DockWidgetFlash(QDockWidget,ui_dialog):
+
+ def __init__(self,name,comptype,obj,container,parent=None):
+ QDockWidget.__init__(self,parent)
+ self.setupUi(self)
+ self.setWindowTitle(obj.name)
+ self.name=name
+ self.obj=obj
+ self.type = comptype
+ self.input_dict = []
+ self.input_params_list()
+ self.btn.clicked.connect(self.param)
+ self.dict = [] # a list
+
+ def input_params_list(self):
+ try:
+ self.l1.setText(self.obj.variables['thermo_package']['name']+":")
+ self.lines = [line.rstrip('\n') for line in open(parentPath+'/python/utils/thermopackage.txt')]
+ for j in self.lines:
+ self.cb1.addItem(str(j))
+ self.cb1.setCurrentText(self.obj.variables['thermo_package']['value'])
+
+ self.check1.setText(self.obj.variables['Tdef']['name']+":")
+ self.le2.setText(str(self.obj.variables['Tdef']['value']))
+ self.u2.setText(self.obj.variables['Tdef']['unit'])
+ self.check1.toggled.connect(self.fun)
+ self.check1.setChecked(self.obj.variables['BTdef']['value'])
+ self.check2.setText(self.obj.variables['Pdef']['name']+":")
+ self.le3.setText(str(self.obj.variables['Pdef']['value']))
+ self.u3.setText(self.obj.variables['Pdef']['unit'])
+ self.check2.toggled.connect(self.fun)
+ self.check2.setChecked(self.obj.variables['BPdef']['value'])
+
+ self.le2.setFixedWidth(80)
+ self.le3.setFixedWidth(80)
+ self.cb1.setFixedWidth(80)
+
+ self.input_dict = [self.cb1, self.check1, self.le2, self.check2, self.le3]
+
+ except Exception as e:
+ print(e)
+
+ def fun(self):
+ if self.check1.isChecked():
+ self.le2.setDisabled(False)
+ else:
+ self.le2.setDisabled(True)
+ if self.check2.isChecked():
+ self.le3.setDisabled(False)
+ else:
+ self.le3.setDisabled(True)
+
+ def show_error(self):
+ QMessageBox.about(self, 'Important', "Please fill all fields with data")
+
+ def param(self):
+ try:
+ self.dict = []
+ #print("param.input_dict ", self.input_dict)
+ self.dict = [self.input_dict[0].currentText(),self.input_dict[1].isChecked(), float(self.input_dict[2].text()), self.input_dict[3].isChecked(), float(self.input_dict[4].text())]
+ #print("param ", self.dict)
+ self.obj.param_setter(self.dict)
+ if(self.isVisible()):
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189)
+ self.hide()
+
+ except Exception as e:
+ print(e)
+
+ def closeEvent(self,event):
+ scrollHVal = self.parent().container.graphics.graphicsView.horizontalScrollBarVal
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189) \ No newline at end of file
diff --git a/src/main/python/DockWidgets/DockWidgetMaterialStream.py b/src/main/python/DockWidgets/DockWidgetMaterialStream.py
new file mode 100644
index 0000000..d2aefb6
--- /dev/null
+++ b/src/main/python/DockWidgets/DockWidgetMaterialStream.py
@@ -0,0 +1,368 @@
+import os, sys
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtGui import *
+from PyQt5.uic import loadUiType
+from python.utils.ComponentSelector import *
+from python.utils.Graphics import *
+
+ui_dialog,_ = loadUiType(parentPath+'/ui/DockWidgets/DockWidgetMaterialStream.ui')
+
+class DockWidgetMaterialStream(QDockWidget,ui_dialog):
+
+ def __init__(self,name,comptype,obj,container,parent=None):
+ QDockWidget.__init__(self,parent)
+ self.setupUi(self)
+ self.setWindowTitle(obj.name)
+ self.name=name
+ self.obj=obj
+ self.type = comptype
+ self.input_dict = {}
+ self.x_pclist = []
+
+ self.comboBox.currentIndexChanged.connect(self.mode_selection)
+
+ self.pushButton_2.clicked.connect(self.param)
+ self.dict = {} # a dictionary
+
+ self.name_type = None
+ self.container = container
+
+ header = QTreeWidgetItem(['Compound','Value','Unit'])
+ self.mTreeWidget.setHeaderItem(header)
+ self.lTreeWidget.setHeaderItem(header)
+ self.vTreeWidget.setHeaderItem(header)
+ lines = [line.rstrip('\n') for line in open(parentPath+'/python/utils/thermopackage.txt')]
+ for j in lines:
+ self.cbTP.addItem(str(j))
+ self.modes()
+
+ # input data tab
+ def modes(self):
+ modes_list = self.obj.modes_list
+ if(modes_list):
+ for j in modes_list:
+ self.comboBox.addItem(str(j))
+ self.comboBox.setCurrentText(self.obj.mode)
+ self.mode_selection()
+ else:
+ self.input_dict= {}
+ self.input_dict = self.obj.param_getter()
+ self.input_params_list()
+
+ def mode_selection(self):
+ self.input_dict= {}
+ try: # removing existing rows while changing modes
+ for i in reversed(range(self.formLayout.count())):
+ self.formLayout.removeRow(i)
+ except Exception as e:
+ print(e)
+ self.input_dict = self.obj.param_getter(self.comboBox.currentText())
+ self.obj.mode = self.comboBox.currentText()
+ self.input_params_list()
+
+ def input_params_list(self):
+ try:
+ for c,i in enumerate(self.input_dict):
+ if(i=="x_pc"):
+ noc = len(compound_selected)
+ #print(noc)
+ self.x_pclist.clear()
+
+ self.comp_gb = QGroupBox("Mole Fractions")
+ lay = QGridLayout()
+ for j in range(noc):
+ try:
+ l = QLineEdit(str(self.obj.variables['x_pc']['value'][j]))
+ except:
+ l = QLineEdit()
+ l.setFixedWidth(100)
+ self.input_dict[i] = "x_pc"
+ lay.addWidget(QLabel(str(compound_selected[j])+":"),j,0, alignment= Qt.AlignLeft)
+ lay.addWidget(l,j,1, alignment=Qt.AlignCenter)
+ self.x_pclist.append(l)
+ lay.setSizeConstraint(QLayout.SetFixedSize)
+ self.comp_gb.setLayout(lay)
+ self.formLayout.addRow(self.comp_gb)
+ elif i == "Thermo Package":
+ self.cbTP.setCurrentText(self.input_dict[i])
+ else:
+ #print("elseloop")
+ l = QLineEdit()
+ if self.input_dict[i] != None:
+ l.setText(str(self.input_dict[i]))
+ l.setFixedWidth(80)
+ lay = QGridLayout()
+ if i !='MolFlow':
+ lay.addWidget(QLabel(self.obj.variables[i]['name']+":"),0,0, alignment=Qt.AlignLeft)
+ else:
+ lay.addWidget(QLabel(i+":"),0,0, alignment=Qt.AlignLeft)
+ lay.addWidget(l,0,1, alignment=Qt.AlignCenter)
+ if(i != 'MolFlow'):
+ lay.addWidget(QLabel(self.obj.variables[i]['unit']),0,2, alignment=Qt.AlignLeft)
+ else:
+ lay.addWidget(QLabel("mol/s"),0,2, alignment=Qt.AlignLeft)
+ self.formLayout.addRow(lay)
+ self.input_dict[i] = l
+
+
+ except Exception as e:
+ print(e)
+
+ def show_error(self):
+ QMessageBox.about(self, 'Important', "Please fill all fields with data")
+
+ def update_compounds(self):
+ try:
+ noc = len(compound_selected)
+ #print(noc)
+ self.x_pclist.clear()
+
+ lay = QGridLayout()
+ for j in range(noc):
+ l = QLineEdit()
+ lay.addWidget(QLabel(str(compound_selected[j]) + ":"), j, 0, alignment=Qt.AlignLeft)
+ lay.addWidget(l, j, 1, alignment=Qt.AlignCenter)
+ self.x_pclist.append(l)
+ lay.setSizeConstraint(QLayout.SetFixedSize)
+ self.comp_gb.setLayout(lay)
+ indexx = self.comboBox.currentIndex()
+ self.comboBox.setCurrentIndex(1)
+ self.comboBox.setCurrentIndex(indexx)
+ self.obj.init_variables()
+ except Exception as e:
+ print(e)
+
+ def param(self):
+ try:
+ self.dict={}
+ #print("param.input_dict ", self.input_dict)
+ for i in self.input_dict:
+ #print(i)
+ if(i =="x_pc"):
+ l=[]
+ mf = []
+ total_moles = 0
+ for mol_frac in self.x_pclist:
+ if (mol_frac.text()):
+ l.append(mol_frac.text())
+ total_moles += float(l[-1])
+ else:
+ self.show_error()
+ break
+ for c in range(len(compound_selected)):
+ mf.append(str(float(l[c])/total_moles))
+ self.obj.variables[compound_selected[c]]['value'] = str(float(l[c])/total_moles)
+ self.x_pclist[c].setText(mf[-1])
+ self.dict[i] = ",".join(mf)
+ elif (i == "Thermo Package"):
+ self.dict[i] = self.cbTP.currentText()
+ else:
+ if (self.input_dict[i].text()):
+ self.dict[i] = self.input_dict[i].text()
+ else:
+ #print(self.input_dict[i])
+ self.show_error()
+ break
+
+ #print("param ", self.dict)
+
+ self.obj.param_setter(self.dict)
+
+ for i in self.container.graphics.graphicsView.items():
+ try:
+ if(i.name == self.name):
+ i.update_tooltip()
+ except:
+ pass
+ if(self.isVisible()):
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189)
+ self.hide()
+
+ except Exception as e:
+ print(e)
+
+ def update_input_values(self):
+ self.init()
+
+ @staticmethod
+ def show_result(ms_lst):
+ for i in ms_lst:
+ i.results_category(i.name)
+
+ def clear_results(self):
+ self.mTreeWidget.clear()
+ self.mTableWidget.setRowCount(0)
+ self.lTreeWidget.clear()
+ self.lTableWidget.setRowCount(0)
+ self.vTreeWidget.clear()
+ self.vTableWidget.setRowCount(0)
+
+ # result data tab
+ def results_category(self,name):
+ try:
+ #print("Under result category name ", name)
+ result=self.container.result
+ obj = self.container.fetch_object(name)
+
+
+ d = {"Mole Fraction":"x_pc", "Mass Fraction":"xm_pc", "Mole Flow":"F_pc", "Mass Flow":"Fm_pc"}
+ ms_lst = list(d.keys())
+ klst = list(d.values())
+
+ p = {"Pressure":"P", "Temperature":"T","Vapour Phase Mole Fraction":"xvap", "Phase Molar Enthalpy":"H_p",
+ "Phase Molar Entropy":"S_p", "Molar Flow Rate":"F_p","Mass Flow Rate":"Fm_p"}
+
+ # Amounts Tab
+ if obj.type == 'MaterialStream':
+ ll = [] # list for basis names
+ for basis in d:
+ propertyname = name + '.' + d[basis]
+ #print("basis ", basis, propertyname)
+ for i in result[0]:
+ if (propertyname in i):
+ ll.append(i)
+ #print(ll)
+
+ j = 0
+ namee = 'none'
+ #print("namee ", namee)
+ #initialization for treewidgets
+ lroot = 1
+ mroot = 1
+ vroot = 1
+
+
+ for i,k in enumerate(ll):
+ ind = result[0].index(k)
+ #print("index ", ind)
+ #print("str ", k)
+ resultval = str(result[-1][ind])
+ #print("######Resultsfetch####",resultval)
+ #print(k[k.find(".")+1:k.find("[")])
+ obj.variables[k.split('.')[1]]['value'] = resultval
+
+ if namee not in k:
+ mroot = QTreeWidgetItem(self.mTreeWidget, [ms_lst[j]])
+ lroot = QTreeWidgetItem(self.lTreeWidget, [ms_lst[j]])
+ vroot = QTreeWidgetItem(self.vTreeWidget, [ms_lst[j]])
+ namee = klst[j]
+
+ phase_no = int(k[k.index(',') - 1]) # phase no is from modelica list
+ compound_no = int(k[k.index(',') + 1]) - 1 # compound is from python list
+
+ if phase_no == 1:
+ child = QTreeWidgetItem(mroot, [compound_selected[compound_no], str(round(float(resultval),4)),
+ obj.variables[k.split('.')[1]]['unit']])
+ elif phase_no == 2:
+ child = QTreeWidgetItem(lroot, [compound_selected[compound_no], str(round(float(resultval),4)),
+ obj.variables[k.split('.')[1]]['unit']])
+ elif phase_no == 3:
+ child = QTreeWidgetItem(vroot, [compound_selected[compound_no], str(round(float(resultval),4)),
+ obj.variables[k.split('.')[1]]['unit']])
+ if (compound_no + 1) == len(compound_selected):
+ j += 1
+
+
+
+ # Phase Properties Tab
+ phaseResLst = []
+ for phase in p:
+ propertyname = name + '.' + p[phase]
+ #print("phase ", phase, propertyname)
+ for i in result[0]:
+ if i.find('['):
+ if (propertyname == i[0:i.find('[')]):
+ phaseResLst.append(i)
+ if propertyname == i:
+ phaseResLst.append(i)
+ #print(phaseResLst)
+
+ self.mTableWidget.setRowCount(0)
+ self.lTableWidget.setRowCount(0)
+ self.vTableWidget.setRowCount(0)
+
+ for i,val in enumerate(phaseResLst):
+ ind = result[0].index(val)
+ resultval = str(result[-1][ind])
+ #print(resultval, i, val)
+ obj.variables[val.split('.')[1]]['value'] = resultval
+ if '[' in val:
+ #print(val)
+ temp = val[val.find('.')+1:val.find('[')]
+ #print(temp)
+ if '1' in val.split('.')[1]:
+ #print(obj.variables[val.split('.')[1]]['name'])
+ mrowPosition = self.mTableWidget.rowCount()
+ self.mTableWidget.insertRow(mrowPosition)
+ self.mTableWidget.setItem(mrowPosition , 0, QTableWidgetItem(obj.variables[val.split('.')[1]]['name']))
+ self.mTableWidget.setItem(mrowPosition , 1, QTableWidgetItem(str(round(float(resultval),4))))
+ self.mTableWidget.setItem(mrowPosition , 2, QTableWidgetItem(obj.variables[val.split('.')[1]]['unit']))
+ self.mTableWidget.resizeColumnsToContents()
+
+ if '2' in val.split('.')[1]:
+ lrowPosition = self.lTableWidget.rowCount()
+ self.lTableWidget.insertRow(lrowPosition)
+ self.lTableWidget.setItem(lrowPosition , 0, QTableWidgetItem(obj.variables[val.split('.')[1]]['name']))
+ self.lTableWidget.setItem(lrowPosition , 1, QTableWidgetItem(str(round(float(resultval),4))))
+ self.lTableWidget.setItem(lrowPosition , 2, QTableWidgetItem(obj.variables[val.split('.')[1]]['unit']))
+ self.lTableWidget.resizeColumnsToContents()
+ if '3' in val.split('.')[1]:
+ vrowPosition = self.vTableWidget.rowCount()
+ self.vTableWidget.insertRow(vrowPosition)
+ self.vTableWidget.setItem(vrowPosition , 0, QTableWidgetItem(obj.variables[val.split('.')[1]]['name']))
+ self.vTableWidget.setItem(vrowPosition , 1, QTableWidgetItem(str(round(float(resultval),4))))
+ self.vTableWidget.setItem(vrowPosition , 2, QTableWidgetItem(obj.variables[val.split('.')[1]]['unit']))
+ self.vTableWidget.resizeColumnsToContents()
+ if not '[' in val:
+ #print(obj.variables[val.split('.')[1]]['name'])
+ mrowPosition = self.mTableWidget.rowCount()
+ self.mTableWidget.insertRow(mrowPosition)
+ self.mTableWidget.setItem(mrowPosition , 0, QTableWidgetItem(obj.variables[val.split('.')[1]]['name']))
+ self.mTableWidget.setItem(mrowPosition , 1, QTableWidgetItem(str(round(float(resultval),4))))
+ self.mTableWidget.setItem(mrowPosition , 2, QTableWidgetItem(obj.variables[val.split('.')[1]]['unit']))
+ self.mTableWidget.resizeColumnsToContents()
+
+
+ # updating the input data from fetched results from simulation
+ #print(self.comboBox.currentText())
+
+ self.input_dict = {}
+ self.input_dict = self.obj.param_getter(self.comboBox.currentText())
+ # print("before", self.input_dict)
+ for i in range(len(compound_selected)):
+ #print(i)
+ self.input_dict['x_pc[1,' + str(i+1) + ']'] = self.obj.variables['x_pc[1,' + str(i+1) +']']['value']
+ # self.input_dict['thermo_package'] = temp
+ # print("after", self.input_dict)
+
+ # changing index for updating the input data
+ indexx = self.comboBox.currentIndex()
+ self.comboBox.setCurrentIndex(1)
+ self.comboBox.setCurrentIndex(indexx)
+
+ try:
+
+ for i in self.parent().container.graphics.graphicsView.items():
+ try:
+ if i.obj == self.obj:
+ i.update_tooltip()
+ except Exception as e:
+ pass
+ except Exception as e:
+ print(e)
+
+
+ except Exception as e:
+ print(e)
+ def closeEvent(self,event):
+ scrollHVal = self.parent().container.graphics.graphicsView.horizontalScrollBarVal
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189)
+ \ No newline at end of file
diff --git a/src/main/python/DockWidgets/DockWidgetMixer.py b/src/main/python/DockWidgets/DockWidgetMixer.py
new file mode 100644
index 0000000..5d89589
--- /dev/null
+++ b/src/main/python/DockWidgets/DockWidgetMixer.py
@@ -0,0 +1,66 @@
+import os, sys
+
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtGui import *
+from PyQt5.uic import loadUiType
+from python.utils.ComponentSelector import *
+from python.utils.Graphics import *
+
+ui_dialog,_ = loadUiType(parentPath+'/ui/DockWidgets/DockWidgetMixer.ui')
+
+class DockWidgetMixer(QDockWidget,ui_dialog):
+
+ def __init__(self,name,comptype,obj,container,parent=None):
+ QDockWidget.__init__(self,parent)
+ self.setupUi(self)
+ self.setWindowTitle(obj.name)
+ self.name=name
+ self.obj=obj
+ self.type = comptype
+ self.input_dict = []
+ self.x_pclist = []
+ self.input_params_list()
+ self.btn.clicked.connect(self.param)
+ self.dict = {}
+
+ # input data tab
+ def input_params_list(self):
+ try:
+ self.l1.setText(self.obj.variables['NI']['name']+":")
+ self.le1.setText(str(self.obj.variables['NI']['value']))
+ self.u1.setText(self.obj.variables['NI']['unit'])
+ for i in self.obj.Pout_modes:
+ self.cb2.addItem(str(i))
+ self.cb2.setCurrentText(self.obj.variables['outPress']['value'])
+
+ self.l2.setText(self.obj.variables['outPress']['name']+":")
+ self.input_dict = [self.le1, self.cb2]
+
+ except Exception as e:
+ print(e)
+
+ def show_error(self):
+ QMessageBox.about(self, 'Important', "Please fill all fields with data")
+
+ def param(self):
+ try:
+ self.dict={}
+ self.dict = [int(self.input_dict[0].text()), self.input_dict[1].currentText()]
+ self.obj.param_setter(self.dict)
+ if(self.isVisible()):
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189)
+ self.hide()
+
+ except Exception as e:
+ print(e)
+ def closeEvent(self,event):
+ scrollHVal = self.parent().container.graphics.graphicsView.horizontalScrollBarVal
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189) \ No newline at end of file
diff --git a/src/main/python/DockWidgets/DockWidgetShortcutColumn.py b/src/main/python/DockWidgets/DockWidgetShortcutColumn.py
new file mode 100644
index 0000000..b627e9d
--- /dev/null
+++ b/src/main/python/DockWidgets/DockWidgetShortcutColumn.py
@@ -0,0 +1,148 @@
+import os, sys
+
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtGui import *
+from PyQt5.uic import loadUiType
+from python.utils.ComponentSelector import *
+from python.utils.Graphics import *
+
+ui_dialog,_ = loadUiType(parentPath+'/ui/DockWidgets/DockWidgetShortcutColumn.ui')
+
+class DockWidgetShortcutColumn(QDockWidget,ui_dialog):
+
+ def __init__(self,name,comptype,obj,container,parent=None):
+ QDockWidget.__init__(self,parent)
+ self.setupUi(self)
+ self.setWindowTitle(obj.name)
+ self.name=name
+ self.obj=obj
+ self.type = comptype
+ self.input_dict = []
+ self.input_params_list()
+ self.btn.clicked.connect(self.param)
+ self.dict = []
+
+ self.name_type = None
+ self.container = container
+
+ # input data tab
+ def input_params_list(self):
+ try:
+ self.l1.setText(self.obj.variables['HKey']['name']+":")
+ self.l2.setText(self.obj.variables['LKey']['name']+":")
+
+ print(self.obj.compounds)
+ for i in self.obj.compounds:
+ self.cb1.addItem(str(i))
+ self.cb2.addItem(str(i))
+ self.cb1.setCurrentText(self.obj.compounds[int(self.obj.variables['HKey']['value'])-1])
+ self.cb2.setCurrentText(self.obj.compounds[int(self.obj.variables['LKey']['value'])-1])
+
+ self.l3.setText(self.obj.variables['HKey_x_pc']['name']+":")
+ self.le3.setText(str(self.obj.variables['HKey_x_pc']['value']))
+ self.u3.setText(self.obj.variables['HKey_x_pc']['unit'])
+ self.l4.setText(self.obj.variables['LKey_x_pc']['name']+":")
+ self.u4.setText(self.obj.variables['LKey_x_pc']['unit'])
+ self.le4.setText(str(self.obj.variables['LKey_x_pc']['value']))
+
+ self.l5.setText(self.obj.variables['Ctype']['name']+":")
+ self.cb5.addItem('Total')
+ self.cb5.addItem('Partial')
+ self.cb5.setCurrentText(self.obj.variables['Ctype']['value'])
+
+ self.l6.setText(self.obj.variables['Pcond']['name']+":")
+ self.le6.setText(str(self.obj.variables['Pcond']['value']))
+ self.u6.setText(self.obj.variables['Pcond']['unit'])
+ self.l7.setText(self.obj.variables['Preb']['name']+":")
+ self.u7.setText(self.obj.variables['Preb']['unit'])
+ self.le7.setText(str(self.obj.variables['Preb']['value']))
+
+ self.l8.setText(self.obj.variables['RR']['name']+":")
+ self.le8.setText(str(self.obj.variables['RR']['value']))
+
+ self.l9.setText("Thermo Package :")
+
+ self.lines = [line.rstrip('\n') for line in open(parentPath+'/python/utils/thermopackage.txt')]
+ for j in self.lines:
+ self.cb6.addItem(str(j))
+ self.cb6.setCurrentText(self.obj.variables['thermo_package']['value'])
+
+ self.input_dict = [self.cb1, self.cb2, self.le3, self.le4, self.cb5, self.le6, self.le7, self.le8, self.cb6]
+
+ except Exception as e:
+ print(e)
+
+ def update_compounds(self):
+ self.cb1.clear()
+ self.cb2.clear()
+ for i in self.obj.compounds:
+ self.cb1.addItem(str(i))
+ self.cb2.addItem(str(i))
+ self.cb1.setCurrentText(self.obj.compounds[int(self.obj.variables['HKey']['value']) - 1])
+ self.cb2.setCurrentText(self.obj.compounds[int(self.obj.variables['LKey']['value']) - 1])
+
+ def show_error(self):
+ QMessageBox.about(self, 'Important', "Please fill all fields with data")
+
+ def param(self):
+ try:
+ self.dict=[]
+ self.dict = [self.input_dict[0].currentText(),self.input_dict[1].currentText(),float(self.input_dict[2].text()), float(self.input_dict[3].text()),
+ self.input_dict[4].currentText(), float(self.input_dict[5].text()), float(self.input_dict[6].text()), float(self.input_dict[7].text()),
+ self.input_dict[8].currentText()]
+ self.obj.param_setter(self.dict)
+ if(self.isVisible()):
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189)
+ self.hide()
+
+ except Exception as e:
+ print(e)
+
+ @staticmethod
+ def show_result(lst):
+ for i in lst:
+ try:
+ i.results_category(i.name)
+ except AttributeError:
+ pass
+
+ def clear_results(self):
+ self.tableWidget.setRowCount(0)
+
+ # result data tab
+ def results_category(self,name):
+ flag = True
+ try:
+ #print("Under result category name ", name)
+ result=self.container.result
+ obj = self.container.fetch_object(name)
+ self.tableWidget.setRowCount(0)
+ variKeys = obj.result_parameters
+ #print(variKeys)
+ for i, val in enumerate(variKeys):
+ propertyname = name + '.' + val
+ #print(i,val, propertyname)
+ if propertyname in result[0]:
+ ind = result[0].index(propertyname)
+ resultval = str(result[-1][ind])
+ obj.variables[val]['value']= result[-1][ind]
+ #print("######Resultsfetch####",val,resultval)
+ rowPosition = self.tableWidget.rowCount()
+ self.tableWidget.insertRow(rowPosition)
+ self.tableWidget.setItem(rowPosition , 0, QTableWidgetItem(obj.variables[val]['name']))
+ self.tableWidget.setItem(rowPosition , 1, QTableWidgetItem(resultval))
+ self.tableWidget.setItem(rowPosition , 2, QTableWidgetItem(obj.variables[val]['unit']))
+ self.tableWidget.resizeColumnsToContents()
+ except Exception as e:
+ print(e)
+ def closeEvent(self,event):
+ scrollHVal = self.parent().container.graphics.graphicsView.horizontalScrollBarVal
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189) \ No newline at end of file
diff --git a/src/main/python/DockWidgets/DockWidgetSplitter.py b/src/main/python/DockWidgets/DockWidgetSplitter.py
new file mode 100644
index 0000000..296e111
--- /dev/null
+++ b/src/main/python/DockWidgets/DockWidgetSplitter.py
@@ -0,0 +1,85 @@
+import os, sys
+
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtGui import *
+from PyQt5.uic import loadUiType
+from python.utils.ComponentSelector import *
+from python.utils.Graphics import *
+
+ui_dialog,_ = loadUiType(parentPath+'/ui/DockWidgets/DockWidgetSplitter.ui')
+
+class DockWidgetSplitter(QDockWidget,ui_dialog):
+
+ def __init__(self,name,comptype,obj,container,parent=None):
+ QDockWidget.__init__(self,parent)
+ self.setupUi(self)
+ self.setWindowTitle(obj.name)
+ self.name=name
+ self.obj=obj
+ self.type = comptype
+ self.input_dict = []
+ self.input_params_list()
+ self.btn.clicked.connect(self.param)
+ self.dict = {}
+
+ # input data tab
+ def input_params_list(self):
+ try:
+ self.l1.setText(self.obj.variables['No']['name']+":")
+ self.le1.setText(str(self.obj.variables['No']['value']))
+ self.u1.setText(self.obj.variables['No']['unit'])
+
+ self.l2.setText(self.obj.variables['CalcType']['name'] + ":")
+ for i in self.obj.CalcType_modes:
+ self.cb2.addItem(str(i))
+ self.cb2.setCurrentText(self.obj.variables['CalcType']['value'])
+
+ self.l3.setText("Stream 1 :")
+ self.le3.setText(str(self.obj.variables['SpecVal_s']['value'][0]))
+ self.u3.setText(self.obj.variables['SpecVal_s']['unit'])
+ self.l4.setText("Stream 2 :")
+ self.le4.setText(str(self.obj.variables['SpecVal_s']['value'][1]))
+ self.u4.setText(str(self.obj.variables['SpecVal_s']['unit']))
+ self.cb2.currentIndexChanged.connect(self.fun)
+
+ self.input_dict = [self.le1, self.cb2, self.le3, self.le4]
+
+ except Exception as e:
+ print(e)
+
+ def fun(self):
+ if self.cb2.currentText() == 'Molar_Flow':
+ self.u3.setText('mol/s')
+ self.u4.setText('mol/s')
+ elif self.cb2.currentText() == 'Mass_Flow':
+ self.u3.setText('g/s')
+ self.u4.setText('g/s')
+ else:
+ self.u3.setText('')
+ self.u4.setText('')
+
+ def show_error(self):
+ QMessageBox.about(self, 'Important', "Please fill all fields with data")
+
+ def param(self):
+ try:
+ self.dict={}
+ self.dict = [int(self.input_dict[0].text()),self.input_dict[1].currentText(), float(self.input_dict[2].text()), float(self.input_dict[3].text())]
+ self.obj.param_setter(self.dict)
+ if(self.isVisible()):
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189)
+ self.hide()
+ except Exception as e:
+ print(e)
+
+ def closeEvent(self,event):
+ scrollHVal = self.parent().container.graphics.graphicsView.horizontalScrollBarVal
+ currentVal = self.parent().container.graphics.graphicsView.horizontalScrollBar().value()
+ self.parent().container.graphics.graphicsView.horizontalScrollBar().setValue(currentVal-189) \ No newline at end of file
diff --git a/src/main/python/DockWidgets/__init__.py b/src/main/python/DockWidgets/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/main/python/DockWidgets/__init__.py
diff --git a/src/main/python/DockWidgets/__pycache__/DistillationColumnStagewiseResults.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DistillationColumnStagewiseResults.cpython-36.pyc
new file mode 100644
index 0000000..0feb70b
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DistillationColumnStagewiseResults.cpython-36.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DistillationColumnStagewiseResults.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DistillationColumnStagewiseResults.cpython-37.pyc
new file mode 100644
index 0000000..d8c43f1
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DistillationColumnStagewiseResults.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidget.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidget.cpython-36.pyc
new file mode 100644
index 0000000..853e89a
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidget.cpython-36.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidget.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidget.cpython-37.pyc
new file mode 100644
index 0000000..90c3ef9
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidget.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetCompoundSeparator.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetCompoundSeparator.cpython-36.pyc
new file mode 100644
index 0000000..355cf3a
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetCompoundSeparator.cpython-36.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetCompoundSeparator.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetCompoundSeparator.cpython-37.pyc
new file mode 100644
index 0000000..eed70e1
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetCompoundSeparator.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetCompressorExpander.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetCompressorExpander.cpython-36.pyc
new file mode 100644
index 0000000..88102aa
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetCompressorExpander.cpython-36.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetCompressorExpander.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetCompressorExpander.cpython-37.pyc
new file mode 100644
index 0000000..05d0157
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetCompressorExpander.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetDistillationColumn.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetDistillationColumn.cpython-36.pyc
new file mode 100644
index 0000000..f5eccbb
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetDistillationColumn.cpython-36.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetDistillationColumn.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetDistillationColumn.cpython-37.pyc
new file mode 100644
index 0000000..a3cba32
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetDistillationColumn.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetFlash.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetFlash.cpython-36.pyc
new file mode 100644
index 0000000..34d90b2
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetFlash.cpython-36.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetFlash.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetFlash.cpython-37.pyc
new file mode 100644
index 0000000..08f6dae
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetFlash.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetMaterialStream.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetMaterialStream.cpython-36.pyc
new file mode 100644
index 0000000..1181e13
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetMaterialStream.cpython-36.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetMaterialStream.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetMaterialStream.cpython-37.pyc
new file mode 100644
index 0000000..abc5f50
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetMaterialStream.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetMixer.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetMixer.cpython-36.pyc
new file mode 100644
index 0000000..1fc6df4
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetMixer.cpython-36.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetMixer.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetMixer.cpython-37.pyc
new file mode 100644
index 0000000..2974d48
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetMixer.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetShortcutColumn.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetShortcutColumn.cpython-36.pyc
new file mode 100644
index 0000000..99d84d1
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetShortcutColumn.cpython-36.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetShortcutColumn.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetShortcutColumn.cpython-37.pyc
new file mode 100644
index 0000000..46cd536
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetShortcutColumn.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetSplitter.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetSplitter.cpython-36.pyc
new file mode 100644
index 0000000..6c8bb16
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetSplitter.cpython-36.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetSplitter.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetSplitter.cpython-37.pyc
new file mode 100644
index 0000000..d23e668
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/DockWidgetSplitter.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/DockWidgets/__pycache__/__init__.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/__init__.cpython-37.pyc
new file mode 100644
index 0000000..9a9342e
--- /dev/null
+++ b/src/main/python/DockWidgets/__pycache__/__init__.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/OMChem/CompSep.py b/src/main/python/OMChem/CompSep.py
new file mode 100644
index 0000000..d538acb
--- /dev/null
+++ b/src/main/python/OMChem/CompSep.py
@@ -0,0 +1,71 @@
+from OMChem.EngStm import EngStm
+import json
+class CompSep():
+ counter = 1
+ def __init__(self,CompNames = [],name='CompSep',SepFact=['Molar_Flow','Mass_Flow'],SepStrm=1,SepFactValue=[]):
+ self.SepFact = json.dumps(SepFact).replace('[','{').replace(']','}')
+ self.SepStrm = str(SepStrm)
+ self.SepFactValue = json.dumps(SepFactValue).replace('[','{').replace(']','}')
+ self.OM_data_eqn = ''
+ self.OM_data_init = ''
+ self.InputStms = []
+ self.OutputStms = []
+ self.type = 'CompSep'
+ self.EngStms = EngStm(name='EngStm')
+
+ # new
+ self.name = name + str(CompSep.counter)
+ self.no_of_input = 1
+ self.no_of_output = 2
+ CompSep.counter += 1
+
+ def getname(self):
+ return self.name
+
+ def modesList(self):
+ return []
+
+ def paramgetter(self,mode=None):
+ dict = {"SepStrm":None,"SepFactValue":None,"SepFact":None}
+ return dict
+
+ def paramsetter(self,dict):
+ self.SepStrm = dict['SepStrm']
+ self.SepFactValue = dict['SepFactValue']
+ self.SepFact = dict['SepFact']
+
+ def OM_Flowsheet_Init(self, addedcomp):
+ self.OM_data_init = ''
+ comp_count = len(addedcomp)
+ self.OM_data_init = self.OM_data_init + 'Simulator.Streams.Energy_Stream '+self.EngStms.name+';\n'
+ self.OM_data_init = self.OM_data_init + (
+ "Simulator.Unit_Operations.Compound_Separator " + self.name + "(Nc = " + str(comp_count))
+ self.OM_data_init = self.OM_data_init + (",comp = {")
+ comp = str(addedcomp).strip('[').strip(']')
+ comp = comp.replace("'", "")
+ self.OM_data_init = self.OM_data_init + comp + ("},")
+ self.OM_data_init = self.OM_data_init + ("sepFact = "+self.SepFact+",sepStrm = " + self.SepStrm + ", sepFactVal = " + self.SepFactValue + ");\n")
+
+ return self.OM_data_init
+
+ def connect(self,InputStms = None,OutputStms = []):
+ self.InputStms = InputStms
+ self.OutputStms = OutputStms
+
+ def OM_Flowsheet_Eqn(self, addedcomp):
+ self.OM_data_eqn = ''
+ comp_count = len(addedcomp)
+ strcount = 1
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.InputStms[0].name + '.outlet,' + self.name + '.inlet' + ');\n')
+
+ for strm in self.OutputStms:
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + strm.name + '.inlet,' + self.name + '.outlet'+str(strcount)+');\n')
+ strcount += 1
+
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.EngStms.name + '.outlet,' + self.name + '.energy);\n')
+ sepFac = str(self.SepFactValue).strip('[').strip(']')
+
+ self.OM_data_eqn = self.OM_data_eqn + (self.name+'.sepFactVal= {'+ sepFac + '};\n')
+
+ return self.OM_data_eqn
+
diff --git a/src/main/python/OMChem/ConvReactor.py b/src/main/python/OMChem/ConvReactor.py
new file mode 100644
index 0000000..5c83106
--- /dev/null
+++ b/src/main/python/OMChem/ConvReactor.py
@@ -0,0 +1,44 @@
+import json
+from OMChem.EngStm import EngStm
+class ConvReactor():
+ def __init__(self,name='',Nr=None,b=None,X=None,Z=None,a=[],operation=None,Tdef=None):
+ self.Nr = str(Nr)
+ self.b = str(b)
+ self.X = str(X)
+ self.Z = str(Z)
+ self.a = json.dumps(a).replace('[','{').replace(']','}')
+ self.operation = str(operation)
+ self.name = name
+ self.OM_data_eqn = ''
+ self.OM_data_init = ''
+ self.InputStms = []
+ self.OutputStms = []
+ self.Tdef = str(Tdef)
+
+ self.type = 'ConvReactor'
+ self.EngStms = EngStm(name="EngStm")
+
+ def OM_Flowsheet_Init(self, addedcomp):
+ self.OM_data_init = ''
+ comp_count = len(addedcomp)
+ self.OM_data_init = self.OM_data_init + 'Simulator.Streams.Energy_Stream '+self.EngStms.name+';\n'
+ self.OM_data_init = self.OM_data_init + ( "Simulator.Unit_Operations.ConversionReactor " + self.name + "(Nr = " + self.Nr + ',b = ' + self.b + ',X = ' + self.X + ',Z = ' + self.Z + ',a = ' + self.a + ',operation = ' + self.operation + ',Tdef = ' + self.Tdef + ');\n')
+ return self.OM_data_init
+
+ def connect(self,InputStms = None,OutputStms = None):
+ self.InputStms = InputStms
+ self.OutputStms = OutputStms
+
+
+ def OM_Flowsheet_Eqn(self, addedcomp):
+ self.OM_data_eqn = ''
+ comp_count = len(addedcomp)
+ strcount = 1
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.InputStms[0].name + '.outlet,' + self.name + '.inlet' + ');\n')
+
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.OutputStms[0].name + '.inlet,' + self.name + '.outlet);\n')
+
+
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.EngStms.name + '.inlet,' + self.name + '.EnergyStream);\n')
+
+ return self.OM_data_eqn
diff --git a/src/main/python/OMChem/Cooler.py b/src/main/python/OMChem/Cooler.py
new file mode 100644
index 0000000..9a44033
--- /dev/null
+++ b/src/main/python/OMChem/Cooler.py
@@ -0,0 +1,76 @@
+from OMChem.EngStm import EngStm
+class Cooler():
+ counter = 1
+ def __init__(self,name='Cooler',PressureDrop = None, eff = None):
+ self.PressureDrop = PressureDrop
+ self.eff = eff
+ # self.name = name
+ self.OM_data_eqn = ''
+ self.OM_data_init = ''
+ self.InputStms = None
+ self.OutputStms = None
+ #self.heatRem = heatRem
+ self.EngStms = EngStm(name='EngStm')
+ self.type = 'Cooler'
+ self.mode = None
+ self.modeVal = None
+
+ self.Prop = {
+ 'pressDrop':None,
+ 'eff':None,
+ 'outT':None,
+ 'tempDrop':None,
+ 'heatRem':None,
+ }
+ # new
+ self.name = name + str(Cooler.counter)
+ self.no_of_input = 1
+ self.no_of_output = 1
+ Cooler.counter += 1
+
+ def getname(self):
+ return self.name
+
+ def connect(self,InputStms = None,OutputStms = None):
+ self.InputStms = InputStms
+ self.OutputStms = OutputStms
+
+ def modesList(self):
+ return ["heatRem","outT","outVapPhasMolFrac","tempDrop","enFlo"]
+
+ def paramgetter(self,mode="heatRem"):
+ self.mode = mode
+ dict = {"PressureDrop":None,"eff":None,self.mode:None}
+ return dict
+
+ def paramsetter(self,dict):
+
+ self.PressureDrop = dict['PressureDrop']
+ self.eff = dict['eff']
+ self.modeVal = dict[self.mode]
+
+ def OM_Flowsheet_Init(self, addedcomp):
+ self.OM_data_init = ''
+ comp_count = len(addedcomp)
+ self.OM_data_init = self.OM_data_init + 'Simulator.Streams.Energy_Stream '+self.EngStms.name+';\n'
+ self.OM_data_init = self.OM_data_init + (
+ "Simulator.Unit_Operations.Cooler " + self.name + "(Nc = " + str(comp_count))
+ self.OM_data_init = self.OM_data_init + (",comp = {")
+ comp = str(addedcomp).strip('[').strip(']')
+ comp = comp.replace("'", "")
+ self.OM_data_init = self.OM_data_init + comp + ("},")
+ self.OM_data_init = self.OM_data_init + 'pressDrop = ' + str(self.PressureDrop) + ','
+ self.OM_data_init = self.OM_data_init + 'eff = ' + str(self.eff) + ');\n'
+ return self.OM_data_init
+
+ def OM_Flowsheet_Eqn(self, addedcomp):
+ self.OM_data_eqn = ''
+ # self.OM_data_eqn = self.name + '.pressDrop = ' + str(self.PressDrop) + ';\n'
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.InputStms[0].name + '.outlet,' + self.name + '.inlet' + ');\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.name + '.outlet,' + self.OutputStms[0].name + '.inlet);\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.EngStms.name + '.outlet,'+ self.name + '.energy);\n')
+ if(self.mode =="enFlo"):
+ self.OM_data_eqn = self.OM_data_eqn + (self.EngStms.name+'.'+self.mode+'='+ self.modeVal + ';\n')
+ else:
+ self.OM_data_eqn = self.OM_data_eqn + (self.name+'.'+self.mode+'='+ self.modeVal + ';\n')
+ return self.OM_data_eqn \ No newline at end of file
diff --git a/src/main/python/OMChem/DistCol.py b/src/main/python/OMChem/DistCol.py
new file mode 100644
index 0000000..c4a88c3
--- /dev/null
+++ b/src/main/python/OMChem/DistCol.py
@@ -0,0 +1,103 @@
+from OMChem.EngStm import EngStm
+class DistCol():
+ counter = 1
+ def __init__(self,name='DistCol', numStage = None,numFeeds = None,feedStages = None):
+ self.numStage = numStage
+ self.numFeeds=numFeeds
+ self.feedStages=feedStages
+ self.name = name + str(DistCol.counter)
+ self.OM_data_eqn = ''
+ self.OM_data_init = ''
+ self.InputStms = None
+ self.OutputStms = None
+ self.EngStm1 = EngStm(name='EngStm1'+self.name)
+ self.EngStm2 = EngStm(name='EngStm2'+self.name)
+ self.count = DistCol.counter
+ self.thermoPackage='Raoults_Law'
+ self.type = 'DistCol'
+ self.mode = None
+ self.condType=''
+ self.modeVal = None
+ self.condP=None
+ self.rebP=None
+
+ # new
+ self.no_of_input = 2
+ self.no_of_output = 2
+ DistCol.counter += 1
+
+ def getname(self):
+ return self.name
+
+ def connect(self,InputStms = None,OutputStms = None):
+ self.InputStms = InputStms
+ self.OutputStms = OutputStms
+
+ def modesList(self):
+ return ["refluxRatio","sideDrawMolFlo","T"]
+
+ def paramgetter(self,mode="refluxRatio"):
+ self.mode=mode
+ dict = { "numStage" : None,"numFeeds" :None,"feedStages" :None,"thermoPackage":None,"condType":None,self.mode:None,"condensor.P":None,"reboiler.P":None}
+ return dict
+
+ def paramsetter(self,dict):
+ self.numStage = dict["numStage"]
+ self.numFeeds = dict["numFeeds"]
+ self.feedStages = dict["feedStages"].split(",")
+ self.modeVal=dict[self.mode]
+ self.condP=dict["condensor.P"]
+ self.rebP=dict["reboiler.P"]
+ self.condType=dict["condType"]
+
+ def OM_Flowsheet_Init(self, addedcomp):
+ self.OM_data_init = ''
+ self.OM_data_init = self.OM_data_init + 'model Condensor\n'
+ self.OM_data_init = self.OM_data_init + 'extends Simulator.Unit_Operations.Distillation_Column.Cond;\n'
+ self.OM_data_init = self.OM_data_init + 'extends Simulator.Files.Thermodynamic_Packages.'+self.thermoPackage+';\n'
+ self.OM_data_init = self.OM_data_init + 'end Condensor;\n'
+ self.OM_data_init = self.OM_data_init + 'model Tray\n'
+ self.OM_data_init = self.OM_data_init + 'extends Simulator.Unit_Operations.Distillation_Column.DistTray;\n'
+ self.OM_data_init = self.OM_data_init + 'extends Simulator.Files.Thermodynamic_Packages.'+self.thermoPackage+';\n'
+ self.OM_data_init = self.OM_data_init + 'end Tray;\n'
+ self.OM_data_init = self.OM_data_init + 'model Reboiler\n'
+ self.OM_data_init = self.OM_data_init + 'extends Simulator.Unit_Operations.Distillation_Column.Reb;\n'
+ self.OM_data_init = self.OM_data_init + 'extends Simulator.Files.Thermodynamic_Packages.'+self.thermoPackage+';\n'
+ self.OM_data_init = self.OM_data_init + 'end Reboiler;\n'
+ self.OM_data_init = self.OM_data_init + ("model distCol"+str(self.count)+"\n")
+ self.OM_data_init = self.OM_data_init + ("extends Simulator.Unit_Operations.Distillation_Column.DistCol;\n" )
+ self.OM_data_init = self.OM_data_init + ("Condensor condensor(Nc = Nc, comp = comp, condType =condType, boolFeed = boolFeed[1], T(start = 300));\n" )
+ self.OM_data_init = self.OM_data_init + ("Reboiler reboiler(Nc = Nc, comp = comp, boolFeed = boolFeed[noOfStages]);\n" )
+ self.OM_data_init = self.OM_data_init + ("Tray tray[noOfStages - 2](each Nc = Nc, each comp = comp, boolFeed = boolFeed[2:noOfStages -1]);\n" )
+ self.OM_data_init = self.OM_data_init + ("end distCol"+str(self.count)+";\n")
+ comp_count = len(addedcomp)
+ self.OM_data_init = self.OM_data_init + (
+ "distCol"+str(self.count)+" "+ self.name + "(Nc = " + str(comp_count))
+ self.OM_data_init = self.OM_data_init + (",comp = {")
+ comp = str(addedcomp).strip('[').strip(']')
+ comp = comp.replace("'", "")
+ self.feedStages=str(self.feedStages).strip('[').strip(']')
+ self.feedStages = self.feedStages.replace("'", "")
+ self.OM_data_init = self.OM_data_init + comp + ("},")+("noOfStages="+self.numStage+","+"noOfFeeds="+self.numFeeds+",feedStages="+"{"+self.feedStages+"}"+",condensor.condType="+"\""+self.condType+"\""+");\n")
+ self.OM_data_init = self.OM_data_init + 'Simulator.Streams.Energy_Stream '+self.EngStm1.name+';\n'
+ self.OM_data_init = self.OM_data_init + 'Simulator.Streams.Energy_Stream '+self.EngStm2.name+';\n'
+ return self.OM_data_init
+
+ def OM_Flowsheet_Eqn(self, addedcomp):
+ self.OM_data_eqn = ''
+ self.OM_data_eqn = self.OM_data_eqn + ('connect('+self.name+'.'+'condensor_duty'+','+ self.EngStm1.name+'.inlet);\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect('+self.name+'.reboiler_duty'+', '+self.EngStm2.name+'.inlet);\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect('+self.name+'.distillate'+", "+self.OutputStms[0].name+'.inlet);\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect('+self.name+'.bottoms'+", "+self.OutputStms[1].name+'.inlet);\n')
+ for i in range(len(self.InputStms)):
+ self.OM_data_eqn = self.OM_data_eqn + ('connect('+self.InputStms[i].name+'.outlet'+", "+self.name+'.feed['+str(i+1)+']);\n')
+ self.OM_data_eqn = self.OM_data_eqn + (self.OutputStms[1].name+'.'+'totMolFlow[1] = '+str(self.OutputStms[1].Prop['totMolFlo[1]'])+';\n')
+ if self.mode=="refluxRatio":
+ self.OM_data_eqn = self.OM_data_eqn + (self.name+'.'+str(self.mode)+'='+ str(self.modeVal) + ';\n')
+ else:
+ self.OM_data_eqn = self.OM_data_eqn + (self.name+'.condensor.'+self.mode+'='+ str(self.modeVal) + ';\n')
+
+ self.OM_data_eqn = self.OM_data_eqn + self.name +'.reboiler.P='+self.rebP+';\n'
+ self.OM_data_eqn = self.OM_data_eqn + self.name +'.condensor.P='+self.condP+';\n'
+ return self.OM_data_eqn
+
diff --git a/src/main/python/OMChem/EngStm.py b/src/main/python/OMChem/EngStm.py
new file mode 100644
index 0000000..c02a5d5
--- /dev/null
+++ b/src/main/python/OMChem/EngStm.py
@@ -0,0 +1,18 @@
+
+class EngStm():
+
+ def __init__(self,name = 'Engstm'):
+ self.name = name
+ self.type = 'EngStm'
+ self.OM_data_init = ''
+ self.OM_data_eqn = ''
+
+
+ def OM_Flowsheet_Init(self,addedcomp):
+ self.OM_data_init = ''
+ self.OM_data_init = self.OM_data_init + 'Simulator.Streams.Energy_Stream '+self.name+';\n'
+ return self.OM_data_init
+
+ def OM_Flowsheet_Eqn(self,addedcomp):
+ self.OM_data_eqn=''
+ return self.OM_data_eqn
diff --git a/src/main/python/OMChem/Flash.py b/src/main/python/OMChem/Flash.py
new file mode 100644
index 0000000..165849a
--- /dev/null
+++ b/src/main/python/OMChem/Flash.py
@@ -0,0 +1,55 @@
+class Flash():
+ counter = 1
+ def __init__(self,name='Flash'):
+ self.OM_data_eqn = ''
+ self.OM_data_init = ''
+ self.InputStms = None
+ self.OutputStms = None
+ self.type = 'flash'
+ self.count = Flash.counter
+ self.thermoPackage =None
+
+ # new
+ self.name = name + str(Flash.counter)
+ self.no_of_input = 1
+ self.no_of_output = 2
+ Flash.counter += 1
+
+ def getname(self):
+ return self.name
+
+ def connect(self,InputStms = None,OutputStms = None):
+ self.InputStms = InputStms
+ self.OutputStms = OutputStms
+
+ def modesList(self):
+ return []
+
+ def paramgetter(self,mode=None):
+ dict = {"thermoPackage":None}
+ return dict
+ def paramsetter(self,dict):
+ self.thermoPackage = dict['thermoPackage']
+
+ def OM_Flowsheet_Init(self, addedcomp):
+ self.OM_data_init = ''
+ self.OM_data_init = self.OM_data_init + ("model fls"+str(self.count)+"\n")
+ self.OM_data_init = self.OM_data_init + ("extends Simulator.Unit_Operations.Flash;\n" )
+ self.OM_data_init = self.OM_data_init + ("extends Simulator.Files.Thermodynamic_Packages."+self.thermoPackage+";\n")
+ self.OM_data_init = self.OM_data_init + ("end fls"+str(self.count)+";\n")
+ comp_count = len(addedcomp)
+ self.OM_data_init = self.OM_data_init + (
+ "fls"+str(self.count)+" "+ self.name + "(Nc = " + str(comp_count))
+ self.OM_data_init = self.OM_data_init + (",comp = {")
+ comp = str(addedcomp).strip('[').strip(']')
+ comp = comp.replace("'", "")
+ self.OM_data_init = self.OM_data_init + comp + ("});\n")
+ return self.OM_data_init
+
+ def OM_Flowsheet_Eqn(self, addedcomp):
+ self.OM_data_eqn = ''
+ comp_count = len(addedcomp)
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.InputStms[0].name + '.outlet,' + self.name + '.feed' + ');\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.name + '.vapor,' + self.OutputStms[0].name + '.inlet);\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.name + '.liquid,' + self.OutputStms[1].name + '.inlet);\n')
+ return self.OM_data_eqn \ No newline at end of file
diff --git a/src/main/python/OMChem/Flowsheet.py b/src/main/python/OMChem/Flowsheet.py
new file mode 100644
index 0000000..a83ac4e
--- /dev/null
+++ b/src/main/python/OMChem/Flowsheet.py
@@ -0,0 +1,307 @@
+import os
+import csv
+from subprocess import Popen, PIPE,STARTUPINFO,STARTF_USESHOWWINDOW
+import pandas as pd
+
+class Flowsheet():
+ def __init__(self):
+ self.sim_name = '../Simulator'
+ self.sim_method = ''
+ self.unit_operations = []
+ self.data = []
+ self.compounds = []
+ self.interface = ''
+ self.omc_path = None
+ self.root_dir = os.getcwd() # Chemical-Simulator-GUI
+ self.sim_dir_path = os.path.join(self.root_dir, self.sim_name) # Chemical-Simulator-GUI/Simulator
+ self.Flomo_path = os.path.join(self.sim_dir_path,'Flowsheet.mo')
+ self.eqn_mos_path = os.path.join(self.sim_dir_path,'simulateEQN.mos')
+ self.sm_mos_path = os.path.join(self.sim_dir_path,'simulateSM.mos')
+ self.result_data = []
+ self.stdout=None
+ self.stderr=None
+
+ def get_omc_path(self,msg):
+ try:
+ self.omhome = os.environ.get('OPENMODELICAHOME')
+ if self.omhome is None:
+ self.omhome = os.path.split(os.path.split(os.path.realpath(spawn.find_executable("omc")))[0])[0]
+ elif os.path.exists('/opt/local/bin/omc'):
+ self.omhome = '/opt/local'
+ elif os.path.exists('/usr/bin/omc'):
+ self.omhome = '/usr'
+ return os.path.join(self.omhome, 'bin', 'omc')
+ except BaseException:
+ msg.parent().parent().parent().container.disableInterfaceforSimulation(False)
+ msg.append("<span style=\"color:red\"><b>Installation Error : </b>The OpenModelica compiler is missing in the System path please install it.</span>")
+ print("The OpenModelica compiler is missing in the System path please install it" )
+ raise
+
+ def add_unit_operations(self,unitop):
+ self.unit_operations.append(unitop)
+
+ def remove_unit_operations(self,unitop):
+ self.unit_operations.remove(unitop)
+
+ def add_compound_list(self,C):
+ self.compounds = C
+
+ def send_for_simulation_Eqn(self,msg):
+ self.result_data = []
+ self.omc_path = self.get_omc_path(msg)
+ #print(self.omc_path)
+
+ if self.sim_method == 'Eqn':
+ simpath = self.eqn_mos_path
+ os.chdir(self.sim_dir_path)
+ startupinfo = STARTUPINFO
+ startupinfo.dwFlags |= STARTF_USESHOWWINDOW
+ self.process = Popen([self.omc_path, '-s',simpath], stdout=PIPE, stderr=PIPE, startupinfo=startupinfo)
+ self.stdout, self.stderr = self.process.communicate()
+
+ os.chdir(self.root_dir)
+ if ('timeSimulation = 0.0,\n' in self.stdout.decode("utf-8")):
+ self.result_data = []
+ else:
+ csvpath = os.path.join(self.sim_dir_path,'Flowsheet_res.csv')
+ with open (csvpath,'r') as resultFile:
+ self.result_data = []
+ csvreader = csv.reader(resultFile,delimiter=',')
+ for row in csvreader:
+ self.result_data.append(row)
+
+ def send_for_simulation_SM(self,unitop):
+ self.result_data = []
+ self.omc_path = self.get_omc_path()
+ os.chdir(self.sim_dir_path)
+ self.process = Popen([self.omc_path, '-s',unitop.name,'.mos'], stdout=PIPE, stderr=PIPE)
+ stdout, stderr = self.process.communicate()
+ # print("############### StdOut ################")
+ # print(stdout)
+ self.result_data = []
+ #print('Simulating '+unitop.name+'...')
+ csvpath = os.path.join(self.sim_dir_path,unitop.name+'_res.csv')
+ with open(csvpath,'r') as resultFile:
+ csvreader = csv.reader(resultFile,delimiter=',')
+ for row in csvreader:
+ self.result_data.append(row)
+ self.ext_data()
+
+ def ext_data(self):
+ for unit in self.unit_operations:
+ if unit[0].type == 'MaterialStream':
+ for key, value in unit[0].Prop.items():
+ property_name = unit[0].name + '.' + key
+ if property_name in self.result_data[0]:
+ ind = self.result_data[0].index(property_name)
+ resultval = str(self.result_data[-1][ind])
+ unit[0].Prop[key] = resultval
+
+ def simulate_EQN(self,msg):
+ self.data = []
+ self.sim_method = 'Eqn'
+ self.data.append("model Flowsheet\n")
+
+ tempCompounds = self.compounds
+ for c in tempCompounds:
+ CompName = c
+ CompName = CompName.replace(" ", "")
+ CompName = CompName.replace("-", "")
+ CompName = CompName.replace(",", "")
+ CompName = CompName.replace("1", "One")
+ CompName = CompName.replace("2", "Two")
+ CompName = CompName.replace("3", "Three")
+ CompName = CompName.replace("4", "Four")
+ CompName = CompName.replace("5", "Five")
+ self.data.append("parameter database." + CompName +' '+ CompName + "; \n")
+ tempCompounds[tempCompounds.index(c)] = CompName
+
+ self.data.append("parameter Integer Nc = " + str(len(tempCompounds)) + ";\n")
+ self.data.append("parameter Simulator.Files.ChemsepDatabase.GeneralProperties C[Nc] = {" +
+ str(tempCompounds).strip('[').strip(']').replace("'", "") + "};\n")
+
+ for unitop in self.unit_operations:
+ if unitop.type != 'MaterialStream':
+ self.data.append(unitop.OM_Flowsheet_Initialize())
+ else:
+ self.data.append(unitop.OM_Flowsheet_Initialize(self.compounds))
+
+ self.data.append("equation\n")
+
+ self.outlist = []
+ self.stm = ['MaterialStream','EngStm']
+ for unitop in self.unit_operations:
+ if unitop.type not in self.stm:
+ for j in unitop.output_stms.values():
+ self.outlist.append(j)
+
+ for unitop in self.unit_operations:
+ if unitop not in self.outlist:
+ if unitop.type == 'MaterialStream':
+ self.data.append(unitop.OM_Flowsheet_Equation(self.compounds,'Eqn'))
+ else:
+ self.data.append(unitop.OM_Flowsheet_Equation())
+ else:
+ pass
+ with open(self.Flomo_path, 'w') as txtfile:
+ for d in self.data:
+ txtfile.write(str(d))
+ txtfile.write('end Flowsheet;\n')
+ #print(self.eqn_mos_path)
+ with open(self.eqn_mos_path, 'w') as mosFile:
+ mosFile.write('loadModel(Modelica);\n')
+ mosFile.write('loadFile(\"Simulator/package.mo\");\n')
+ mosFile.write('loadFile(\"database.mo\");\n')
+ mosFile.write('loadFile(\"Flowsheet.mo\");\n')
+ mosFile.write('simulate(Flowsheet, outputFormat=\"csv\", stopTime=1.0, numberOfIntervals=1);\n')
+
+ #print('Initiating Simulation in Equation Oriented Mode')
+
+ self.send_for_simulation_Eqn(msg)
+
+ def simulate_SM(self,ip,op):
+ self.sim_method = 'SM'
+ self.data = []
+ self.result_data = []
+ self.unit = []
+ self.csvlist = []
+
+ for i in ip:
+ common = ip[i]
+
+ for k,v in op.items():
+ if(set(v) & set(common)):
+ if((i in self.unit) and (k in self.unit)):
+ pass
+ elif(i in self.unit):
+ self.unit.insert(self.unit.index(i),k)
+ elif(k in self.unit):
+ self.unit.append(i)
+ else:
+ self.unit.append(k)
+ self.unit.append(i)
+
+ for unitop in self.unit:
+ os.chdir(self.root_dir)
+ self.data = []
+ if unitop.type not in ['MaterialStream','EngStm']:
+ inpstms = unitop.input_stms
+ outstms = unitop.output_stms
+
+ try:
+ engstms = unitop.EngStms
+ except:
+ engstms = None
+
+ self.data.append("model "+unitop.name.lower()+'\n')
+
+ for c in self.compounds:
+ c = c.title()
+ lcase = c.lower()
+ self.data.append("parameter Simulator.Files.Chemsep_Database." + c +' '+ c + "; \n")
+
+ self.data.append(unitop.OM_Flowsheet_Initialize())
+
+ if type(outstms) is list:
+ for stm in outstms:
+ self.data.append(stm.OM_Flowsheet_Initialize())
+ else:
+ self.data.append(outstms.OM_Flowsheet_Initialize())
+
+ if engstms:
+ self.data.append(engstms.OM_Flowsheet_Initialize())
+
+ if type(inpstms) is list:
+ for stm in inpstms:
+ self.data.append(stm.OM_Flowsheet_Initialize())
+ else:
+ self.data.append(inpstms.OM_Flowsheet_Initialize())
+
+ self.data.append('equation\n')
+ self.data.append(unitop.OM_Flowsheet_Equation())
+
+ if type(inpstms) is list:
+ for stm in inpstms:
+ self.data.append(stm.OM_Flowsheet_Equation())
+ else:
+ self.data.append(inpstms.OM_Flowsheet_Equation())
+
+ unitmofile = os.path.join(self.sim_dir_path,unitop.name.lower()+'.mo')
+
+ with open(unitmofile,'w') as unitFile:
+ for d in self.data:
+ unitFile.write(d)
+ unitFile.write('end '+unitop.name.lower()+';\n')
+
+ unitmosfile = os.path.join(self.sim_dir_path,unitop.name.lower()+'.mos')
+ with open(unitmosfile, 'w') as mosFile:
+ mosFile.write('loadModel(Modelica);\n')
+ mosFile.write("loadFile(\"Simulator\package.mo\");\n")
+
+ mosFile.write("loadFile(\""+unitop.name.lower()+".mo\");\n")
+ mosFile.write("simulate("+unitop.name.lower()+", outputFormat=\"csv\", stopTime=1.0, numberOfIntervals=1);\n")
+
+ #print("Initiating simulation in Sequential Modular Mode")
+ self.omc_path = self.get_omc_path()
+ os.chdir(self.sim_dir_path)
+ sim = os.path.join(self.sim_dir_path,unitop.name.lower()+'.mos')
+ self.process = Popen([self.omc_path, '-s',sim], stdout=PIPE, stderr=PIPE)
+ self.stdout, self.stderr = self.process.communicate()
+ os.chdir(self.root_dir)
+
+ # print("############### StdOut ################")
+ # print(self.stdout)
+ # print("############### StdErr ################")
+ # print(self.stderr)
+ # print('Simulating '+unitop.name.lower()+'...')
+ csvpath = os.path.join(self.sim_dir_path,unitop.name.lower()+'_res.csv')
+
+ self.csvlist.append(csvpath)
+
+ with open(csvpath,'r') as resultFile:
+ csvreader = csv.reader(resultFile,delimiter=',')
+ for row in csvreader:
+ self.result_data.append(row)
+
+ os.chdir(self.root_dir)
+ if type(inpstms) is list:
+ for stm in inpstms:
+ for key,value in stm.Prop.items():
+ property_name = stm.name + '.' + key
+ if property_name in self.result_data[0]:
+ ind = self.result_data[0].index(property_name)
+ resultval = str(self.result_data[-1][ind])
+ stm.Prop[key] = resultval
+ else:
+ for key, value in inpstms.Prop.items():
+ property_name = inpstms.name + '.' + key
+ if property_name in self.result_data[0]:
+ ind = self.result_data[0].index(property_name)
+ resultval = str(self.result_data[-1][ind])
+ inpstms.Prop[key] = resultval
+
+ if type(outstms) is list:
+ for stm in outstms:
+ for key, value in stm.Prop.items():
+ property_name = stm.name + '.' + key
+ if property_name in self.result_data[0]:
+ ind = self.result_data[0].index(property_name)
+ resultval = str(self.result_data[-1][ind])
+ stm.Prop[key] = resultval
+ else:
+ for key, value in outstms.Prop.items():
+ property_name = outstms.name + '.' + key
+ if property_name in self.result_data[0]:
+ ind = self.result_data[0].index(property_name)
+ resultval = str(self.result_data[-1][ind])
+ outstms.Prop[key] = resultval
+
+ self.dataframes = [pd.read_csv(i) for i in self.csvlist]
+ os.chdir(self.sim_dir_path)
+ dffinal = pd.concat(self.dataframes,axis=1)
+ dffinal.to_csv('FlowsheetSEQ.csv',index=False)
+ self.result_data.clear()
+ with open(os.path.join(self.sim_dir_path+'/FlowsheetSEQ.csv'),'r') as resultFile:
+ csvreader = csv.reader(resultFile,delimiter=',')
+ for row in csvreader:
+ self.result_data.append(row)
diff --git a/src/main/python/OMChem/Heater.py b/src/main/python/OMChem/Heater.py
new file mode 100644
index 0000000..a24253d
--- /dev/null
+++ b/src/main/python/OMChem/Heater.py
@@ -0,0 +1,75 @@
+from OMChem.EngStm import EngStm
+class Heater():
+ counter = 1
+ def __init__(self,name='Heater',PressureDrop = None, eff = None):
+ self.PressureDrop = PressureDrop
+ self.eff = eff
+ self.OM_data_eqn = ''
+ self.OM_data_init = ''
+ self.InputStms = None
+ self.OutputStms = None
+ self.EngStms = EngStm(name='EngStm'+name)
+ self.type = 'Heater'
+ self.mode = None
+ self.modeVal = None
+
+ self.Prop = {
+ 'pressDrop':None,
+ 'eff':None,
+ 'outT':None,
+ 'tempInc':None,
+ 'heatAdd':None,
+ }
+
+ # new
+ self.name = name + str(Heater.counter)
+ self.no_of_input = 1
+ self.no_of_output = 1
+ Heater.counter += 1
+
+ def getname(self):
+ return self.name
+
+ def connect(self,InputStms = None,OutputStms = None):
+ self.InputStms = InputStms
+ self.OutputStms = OutputStms
+
+ def modesList(self):
+ return ["heatAdd","outT","outVapPhasMolFrac","tempInc","enFlo"]
+
+ def paramgetter(self,mode="heatAdd"):
+ self.mode = mode
+ dict = {"PressureDrop":None,"eff":None,self.mode:None}
+ return dict
+
+ def paramsetter(self,dict):
+
+ self.PressureDrop = dict['PressureDrop']
+ self.eff = dict['eff']
+ self.modeVal = dict[self.mode]
+
+ def OM_Flowsheet_Init(self, addedcomp):
+ self.OM_data_init = ''
+ comp_count = len(addedcomp)
+ self.OM_data_init = self.OM_data_init + 'Simulator.Streams.Energy_Stream '+self.EngStms.name+';\n'
+ self.OM_data_init = self.OM_data_init + (
+ "Simulator.Unit_Operations.Heater " + self.name + "(Nc = " + str(comp_count))
+ self.OM_data_init = self.OM_data_init + (",comp = {")
+ comp = str(addedcomp).strip('[').strip(']')
+ comp = comp.replace("'", "")
+ self.OM_data_init = self.OM_data_init + comp + ("},")
+ self.OM_data_init = self.OM_data_init + 'pressDrop = ' + str(self.PressureDrop) +','
+ self.OM_data_init = self.OM_data_init + 'eff = ' + str(self.eff) + ');\n'
+ return self.OM_data_init
+
+ def OM_Flowsheet_Eqn(self, addedcomp):
+ self.OM_data_eqn = ''
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.InputStms[0].name + '.outlet,' + self.name + '.inlet' + ');\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.name + '.outlet,' + self.OutputStms[0].name + '.inlet);\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.EngStms.name + '.outlet,' + self.name + '.energy);\n')
+
+ if(self.mode =="enFlo"):
+ self.OM_data_eqn = self.OM_data_eqn + (self.EngStms.name+'.'+self.mode+'='+ self.modeVal + ';\n')
+ else:
+ self.OM_data_eqn = self.OM_data_eqn + (self.name+'.'+self.mode+'='+ self.modeVal + ';\n')
+ return self.OM_data_eqn
diff --git a/src/main/python/OMChem/Mixer.py b/src/main/python/OMChem/Mixer.py
new file mode 100644
index 0000000..c726cdc
--- /dev/null
+++ b/src/main/python/OMChem/Mixer.py
@@ -0,0 +1,58 @@
+class Mixer():
+ counter = 1 #
+ def __init__(self,name='Mixer',NOI=5,Pcal = 'Inlet_Average'):
+ self.NOI = NOI
+ self.Pcal = Pcal
+ self.OM_data_eqn = ''
+ self.OM_data_init = ''
+ self.InputStms = []
+ self.OutputStms = None
+ self.type = 'Mixer'
+
+ # new
+ self.name = name + str(Mixer.counter)
+ self.no_of_input = 4
+ self.no_of_output = 1
+ Mixer.counter += 1
+
+ def getname(self):
+ return self.name
+
+ def modesList(self):
+ return []
+
+ def paramgetter(self,mode=None):
+ dict = {}
+ return dict
+
+ def paramsetter(self,dict):
+ self.NOI = dict["NOI"]
+
+ def OM_Flowsheet_Init(self, addedcomp):
+ self.OM_data_init = ''
+ comp_count = len(addedcomp)
+
+ self.OM_data_init = self.OM_data_init + (
+ "Simulator.Unit_Operations.Mixer " + self.name + "(Nc = " + str(comp_count))
+ self.OM_data_init = self.OM_data_init + (",comp = {")
+ comp = str(addedcomp).strip('[').strip(']')
+ comp = comp.replace("'", "")
+ self.OM_data_init = self.OM_data_init + comp + ("},")
+ self.OM_data_init = self.OM_data_init + ("outPress = \""+self.Pcal+"\",NI=" + str(self.NOI) + ");\n")
+ return self.OM_data_init
+
+ def connect(self,InputStms = [],OutputStms = None):
+ self.NOI=len(InputStms)
+ self.InputStms = InputStms
+ self.OutputStms = OutputStms
+
+ def OM_Flowsheet_Eqn(self, addedcomp):
+ self.OM_data_eqn = ''
+ comp_count = len(addedcomp)
+ strcount = 1
+ for strm in self.InputStms:
+ self.OM_data_eqn = self.OM_data_eqn + (
+ 'connect(' + strm.name + '.outlet,' + self.name + '.inlet[' + str(strcount) + ']);\n')
+ strcount += 1
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.name + '.outlet,' + self.OutputStms[0].name + '.inlet);\n')
+ return self.OM_data_eqn
diff --git a/src/main/python/OMChem/Pump.py b/src/main/python/OMChem/Pump.py
new file mode 100644
index 0000000..e9b9149
--- /dev/null
+++ b/src/main/python/OMChem/Pump.py
@@ -0,0 +1,62 @@
+from OMChem.EngStm import EngStm
+class Pump():
+ counter = 1
+ def __init__(self,name='Pump',eff = None):
+ self.eff = eff
+ self.OM_data_eqn = ''
+ self.OM_data_init = ''
+ self.InputStms = None
+ self.OutputStms = None
+ self.EngStms = EngStm(name='EngStm'+name)
+ self.type = 'Pump'
+ self.mode = None
+ self.modeVal = None
+ # new
+ self.name = name + str(Pump.counter)
+ self.no_of_input = 1
+ self.no_of_output = 1
+ Pump.counter += 1
+
+ def getname(self):
+ return self.name
+
+ def connect(self,InputStms = None,OutputStms = None):
+ self.InputStms = InputStms
+ self.OutputStms = OutputStms
+
+ def modesList(self):
+ return ["pressInc","outP","reqPow","enFlo"]
+
+ def paramgetter(self,mode="pressInc"):
+ self.mode = mode
+ dict = {"eff":None,self.mode:None}
+ return dict
+
+ def paramsetter(self,dict):
+ self.eff = dict['eff']
+ self.modeVal = dict[self.mode]
+
+ def OM_Flowsheet_Init(self, addedcomp):
+ self.OM_data_init = ''
+ comp_count = len(addedcomp)
+ self.OM_data_init = self.OM_data_init + 'Simulator.Streams.Energy_Stream '+self.EngStms.name+';\n'
+ self.OM_data_init = self.OM_data_init + (
+ "Simulator.Unit_Operations.Centrifugal_Pump " + self.name + "(Nc = " + str(comp_count))
+ self.OM_data_init = self.OM_data_init + (",comp = {")
+ comp = str(addedcomp).strip('[').strip(']')
+ comp = comp.replace("'", "")
+ self.OM_data_init = self.OM_data_init + comp + ("},")
+ self.OM_data_init = self.OM_data_init + 'eff = ' + str(self.eff) + ');\n'
+ return self.OM_data_init
+
+ def OM_Flowsheet_Eqn(self, addedcomp):
+ self.OM_data_eqn = ''
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.InputStms[0].name + '.outlet,' + self.name + '.inlet' + ');\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.name + '.outlet,' + self.OutputStms[0].name + '.inlet);\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.EngStms.name + '.outlet,' + self.name + '.energy);\n')
+
+ if(self.mode =="enFlo"):
+ self.OM_data_eqn = self.OM_data_eqn + (self.EngStms.name+'.'+self.mode+'='+ self.modeVal + ';\n')
+ else:
+ self.OM_data_eqn = self.OM_data_eqn + (self.name+'.'+self.mode+'='+ self.modeVal + ';\n')
+ return self.OM_data_eqn
diff --git a/src/main/python/OMChem/ShortcutColumn.py b/src/main/python/OMChem/ShortcutColumn.py
new file mode 100644
index 0000000..60d9d1b
--- /dev/null
+++ b/src/main/python/OMChem/ShortcutColumn.py
@@ -0,0 +1,86 @@
+from OMChem.EngStm import EngStm
+class ShortcutColumn():
+ counter = 1
+ def __init__(self,name='ShortCol',condP = None, rebP = None, LKey = None, HKey = None):
+ self.condP = condP
+ self.rebP = rebP
+ self.LKey = LKey
+ self.HKey = HKey
+ self.LKeyMolFrac = None
+ self.HKeyMolFrac = None
+ self.name = name + str(ShortcutColumn.counter)
+ self.OM_data_eqn = ''
+ self.OM_data_init = ''
+ self.InputStms = None
+ self.OutputStms = None
+
+ self.EngStm1 = EngStm(name='EngStm1'+self.name)
+ self.EngStm2 = EngStm(name='EngStm2'+self.name)
+ self.count = ShortcutColumn.counter
+ self.condType=''
+ self.actR = None
+ self.thermoPackage='Raoults_Law'
+ self.type = 'ShortCol'
+
+ # new
+ self.no_of_input = 1
+ self.no_of_output = 2
+ ShortcutColumn.counter += 1
+
+ def getname(self):
+ return self.name
+
+ def modesList(self):
+ return []
+
+ def paramgetter(self,mode=None):
+ dict = { "HKey" : None,"LKey" :None,"HKeyMolFrac":None,"LKeyMolFrac":None,"condType":None,"thermoPackage":None,"condP":None,"rebP":None,"actR":None}
+ return dict
+
+ def paramsetter(self,dict):
+ self.HKey = dict["HKey"]
+ self.LKey = dict["LKey"]
+ self.HKeyMolFrac = dict["HKeyMolFrac"]
+ self.LKeyMolFrac=dict["LKeyMolFrac"]
+ self.condP=dict["condP"]
+ self.rebP=dict["rebP"]
+ self.actR=dict["actR"]
+ self.condType=dict["condType"]
+ self.thermoPackage=dict["thermoPackage"]
+ def connect(self,InputStms = None,OutputStms = None):
+ self.InputStms = InputStms
+ self.OutputStms = OutputStms
+ def OM_Flowsheet_Init(self, addedcomp):
+ self.OM_data_init = ''
+ self.OM_data_init = self.OM_data_init + ("model sc"+str(self.count)+"\n")
+ self.OM_data_init = self.OM_data_init + ("extends Simulator.Unit_Operations.Shortcut_Column;\n" )
+ self.OM_data_init = self.OM_data_init + ("extends Simulator.Files.Thermodynamic_Packages."+self.thermoPackage+";\n")
+ self.OM_data_init = self.OM_data_init + ("end sc"+str(self.count)+";\n")
+ comp_count = len(addedcomp)
+ self.OM_data_init = self.OM_data_init + "sc"+str(self.count)+ " " + self.name + "(Nc = " + str(comp_count)
+ self.OM_data_init = self.OM_data_init + (",comp = {")
+ comp = str(addedcomp).strip('[').strip(']')
+ comp = comp.replace("'", "")
+ self.OM_data_init = self.OM_data_init + comp + ("},")
+ self.OM_data_init = self.OM_data_init + 'condType = ' + "\""+self.condType+"\""+','
+ self.OM_data_init = self.OM_data_init + 'HKey = ' + str(self.HKey) +','
+ self.OM_data_init = self.OM_data_init + 'LKey = ' + str(self.LKey) + ');\n'
+ self.OM_data_init = self.OM_data_init + 'Simulator.Streams.Energy_Stream '+self.EngStm1.name+';\n'
+ self.OM_data_init = self.OM_data_init + 'Simulator.Streams.Energy_Stream '+self.EngStm2.name+';\n'
+ return self.OM_data_init
+
+ def OM_Flowsheet_Eqn(self, addedcomp):
+ self.OM_data_eqn = ''
+
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.name + '.reboiler_duty,' +self.EngStm1.name +'.outlet);\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.EngStm2.name+'.inlet,' + self.name + '.condenser_duty);\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.name + '.distillate,' + self.OutputStms[0].name + '.inlet);\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.name + '.bottoms,' + self.OutputStms[1].name + '.inlet);\n')
+
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.InputStms[0].name + '.outlet,' + self.name + '.feed);\n')
+ self.OM_data_eqn = self.OM_data_eqn + self.name +'.rebP = ' + self.rebP + ';\n'
+ self.OM_data_eqn = self.OM_data_eqn + self.name +'.condP = ' + self.condP + ';\n'
+ self.OM_data_eqn = self.OM_data_eqn + self.name +'.mixMolFrac[2,'+self.name+'.LKey]='+self.LKeyMolFrac+ ';\n'
+ self.OM_data_eqn = self.OM_data_eqn + self.name +'.mixMolFrac[3,'+self.name+'.HKey]='+self.HKeyMolFrac+ ';\n'
+ self.OM_data_eqn = self.OM_data_eqn + self.name +'.actR=' + self.actR + ';\n'
+ return self.OM_data_eqn \ No newline at end of file
diff --git a/src/main/python/OMChem/Splitter.py b/src/main/python/OMChem/Splitter.py
new file mode 100644
index 0000000..98d41ab
--- /dev/null
+++ b/src/main/python/OMChem/Splitter.py
@@ -0,0 +1,61 @@
+
+import json
+class Splitter():
+ counter = 1
+ def __init__(self,name='Splitter',NOO=5,calcType = 'Molar_Flow',specval = [50,50]):
+ self.NOO = NOO
+ self.calcType = calcType
+ self.name = name
+ self.OM_data_eqn = ''
+ self.OM_data_init = ''
+ self.InputStms = None
+ self.OutputStms = []
+ self.type = 'Splitter'
+ self.specval = json.dumps(specval).replace('[','{').replace(']','}')
+ # new
+ self.name = name + str(Splitter.counter)
+ self.no_of_input = 1
+ self.no_of_output = 4
+ Splitter.counter += 1
+
+ def getname(self):
+ return self.name
+
+ def modesList(self):
+ return []
+ def paramgetter(self,mode=None):
+ dict = {"NOO":None}
+ return dict
+ def paramsetter(self,dict):
+ self.NOI = dict["NOO"]
+
+ def OM_Flowsheet_Init(self, addedcomp):
+ self.OM_data_init = ''
+ comp_count = len(addedcomp)
+ self.OM_data_init = self.OM_data_init + (
+ "Simulator.Unit_Operations.Splitter " + self.name + "(Nc = " + str(comp_count))
+ self.OM_data_init = self.OM_data_init + (",comp = {")
+ comp = str(addedcomp).strip('[').strip(']')
+ comp = comp.replace("'", "")
+ self.OM_data_init = self.OM_data_init + comp + ("},")
+ self.OM_data_init = self.OM_data_init + ("calcType = \""+self.calcType+"\",NO=" + str(self.NOO) + ");\n")
+ return self.OM_data_init
+
+ def connect(self,InputStms = None,OutputStms = []):
+ self.NOO=len(OutputStms)
+ self.InputStms = InputStms
+ self.OutputStms = OutputStms
+
+
+ def OM_Flowsheet_Eqn(self, addedcomp):
+ self.OM_data_eqn = ''
+ comp_count = len(addedcomp)
+ strcount = 1
+ #print("Output#########",self.OutputStms)
+ for strm in self.OutputStms:
+ self.OM_data_eqn = self.OM_data_eqn + (
+ 'connect(' + strm.name + '.inlet,' + self.name + '.outlet[' + str(strcount) + ']);\n')
+ strcount += 1
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.name + '.inlet,' + self.InputStms[0].name + '.outlet);\n')
+ self.OM_data_eqn = self.OM_data_eqn + self.name +'.' +'specVal =' + self.specval +';\n'
+ return self.OM_data_eqn
diff --git a/src/main/python/OMChem/Valve.py b/src/main/python/OMChem/Valve.py
new file mode 100644
index 0000000..05fa55f
--- /dev/null
+++ b/src/main/python/OMChem/Valve.py
@@ -0,0 +1,58 @@
+class Valve():
+ counter = 1
+ def __init__(self,name='Valve'):
+ self.mode = None
+ self.modeVal = None
+ self.OM_data_eqn = ''
+ self.OM_data_init = ''
+ self.InputStms = None
+ self.OutputStms = None
+ self.type = 'Valve'
+
+ self.Prop = {
+ 'pressDrop':None,
+ 'outP':None
+ }
+ # new
+ self.name = name + str(Valve.counter)
+ self.no_of_input = 1
+ self.no_of_output = 1
+ Valve.counter += 1
+
+ def getname(self):
+ return self.name
+
+ def modesList(self):
+ return ["pressDrop","outP"]
+
+ def paramgetter(self,mode="pressDrop"):
+ self.mode = mode
+ dict = {self.mode:None}
+ return dict
+
+ def paramsetter(self,dict):
+
+ self.modeVal = dict[self.mode]
+
+ def connect(self,InputStms = None,OutputStms = None):
+ self.InputStms = InputStms
+ self.OutputStms = OutputStms
+
+ def OM_Flowsheet_Init(self, addedcomp):
+ self.OM_data_init = ''
+ comp_count = len(addedcomp)
+ self.OM_data_init = self.OM_data_init + (
+ "Simulator.Unit_Operations.Valve " + self.name + "(Nc = " + str(comp_count))
+ self.OM_data_init = self.OM_data_init + (",comp = {")
+ comp = str(addedcomp).strip('[').strip(']')
+ comp = comp.replace("'", "")
+ self.OM_data_init = self.OM_data_init + comp + ("});\n")
+ return self.OM_data_init
+
+ def OM_Flowsheet_Eqn(self, addedcomp):
+ self.OM_data_eqn = ''
+
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.InputStms[0].name + '.outlet,' + self.name + '.inlet' + ');\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.name + '.outlet,' + self.OutputStms[0].name + '.inlet);\n')
+ self.OM_data_eqn = self.OM_data_eqn + (self.name+'.'+self.mode+'='+ self.modeVal + ';\n')
+ return self.OM_data_eqn \ No newline at end of file
diff --git a/src/main/python/OMChem/__init__.py b/src/main/python/OMChem/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/main/python/OMChem/__init__.py
diff --git a/src/main/python/OMChem/__pycache__/EngStm.cpython-36.pyc b/src/main/python/OMChem/__pycache__/EngStm.cpython-36.pyc
new file mode 100644
index 0000000..a5f5a78
--- /dev/null
+++ b/src/main/python/OMChem/__pycache__/EngStm.cpython-36.pyc
Binary files differ
diff --git a/src/main/python/OMChem/__pycache__/EngStm.cpython-37.pyc b/src/main/python/OMChem/__pycache__/EngStm.cpython-37.pyc
new file mode 100644
index 0000000..d065cdb
--- /dev/null
+++ b/src/main/python/OMChem/__pycache__/EngStm.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/OMChem/__pycache__/Flowsheet.cpython-36.pyc b/src/main/python/OMChem/__pycache__/Flowsheet.cpython-36.pyc
new file mode 100644
index 0000000..4039084
--- /dev/null
+++ b/src/main/python/OMChem/__pycache__/Flowsheet.cpython-36.pyc
Binary files differ
diff --git a/src/main/python/OMChem/__pycache__/Flowsheet.cpython-37.pyc b/src/main/python/OMChem/__pycache__/Flowsheet.cpython-37.pyc
new file mode 100644
index 0000000..1a76d03
--- /dev/null
+++ b/src/main/python/OMChem/__pycache__/Flowsheet.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/OMChem/__pycache__/__init__.cpython-37.pyc b/src/main/python/OMChem/__pycache__/__init__.cpython-37.pyc
new file mode 100644
index 0000000..ee871fe
--- /dev/null
+++ b/src/main/python/OMChem/__pycache__/__init__.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/OMChem/adiabatic_comp.py b/src/main/python/OMChem/adiabatic_comp.py
new file mode 100644
index 0000000..bda0476
--- /dev/null
+++ b/src/main/python/OMChem/adiabatic_comp.py
@@ -0,0 +1,67 @@
+from OMChem.EngStm import EngStm
+class AdiabaticCompressor():
+ counter = 1
+ def __init__(self,name='AdiabaticCompressor', eff = None):
+ self.eff = eff
+ self.name = name + str(AdiabaticCompressor.counter)
+
+ self.OM_data_eqn = ''
+ self.OM_data_init = ''
+ self.InputStms = None
+ self.OutputStms = None
+ self.EngStms = EngStm(name='EngStm'+self.name)
+ self.count = AdiabaticCompressor.counter
+ self.type = 'AdiabaticCompressor'
+ self.thermoPackage ="RaoultsLaw"
+ self.mode = None
+ self.modeVal = None
+ # new
+ self.no_of_input = 1
+ self.no_of_output = 1
+ AdiabaticCompressor.counter += 1
+
+ def getname(self):
+ return self.name
+
+ def connect(self,InputStms = None,OutputStms = None):
+ self.InputStms = InputStms
+ self.OutputStms = OutputStms
+
+ def modesList(self):
+ return ["pressInc","outP","reqPow"]
+
+ def paramgetter(self,mode="pressInc"):
+ self.mode = mode
+ dict = {"eff":None,self.mode:None,"thermoPackage":None}
+ return dict
+
+ def paramsetter(self,dict):
+ self.eff = dict['eff']
+ self.modeVal = dict[self.mode]
+
+ def OM_Flowsheet_Init(self, addedcomp):
+ self.OM_data_init = ''
+ self.OM_data_init = self.OM_data_init + 'Simulator.Streams.Energy_Stream '+self.EngStms.name+';\n'
+ self.OM_data_init = self.OM_data_init + ("model adiaComp"+str(self.count)+"\n")
+ self.OM_data_init = self.OM_data_init + ("extends Simulator.Unit_Operations.Adiabatic_Compressor;\n" )
+ self.OM_data_init = self.OM_data_init + ("extends Simulator.Files.Thermodynamic_Packages."+self.thermoPackage+";\n")
+ self.OM_data_init = self.OM_data_init + ("end adiaComp"+str(self.count)+";\n")
+ comp_count = len(addedcomp)
+ self.OM_data_init = self.OM_data_init + (
+ "adiaComp"+str(self.count)+" "+ self.name + "(Nc = " + str(comp_count))
+ self.OM_data_init = self.OM_data_init + (",comp = {")
+ comp = str(addedcomp).strip('[').strip(']')
+ comp = comp.replace("'", "")
+ self.OM_data_init = self.OM_data_init + comp + ("},")+("eff="+self.eff+");\n")
+ return self.OM_data_init
+
+ def OM_Flowsheet_Eqn(self, addedcomp):
+ self.OM_data_eqn = ''
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.InputStms[0].name + '.outlet,' + self.name + '.inlet' + ');\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.name + '.outlet,' + self.OutputStms[0].name + '.inlet);\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.EngStms.name + '.outlet,' + self.name + '.energy);\n')
+
+ self.OM_data_eqn = self.OM_data_eqn + (self.name+'.'+self.mode+'='+ self.modeVal + ';\n')
+
+ return self.OM_data_eqn
+
diff --git a/src/main/python/OMChem/adiabatic_exp.py b/src/main/python/OMChem/adiabatic_exp.py
new file mode 100644
index 0000000..48381fa
--- /dev/null
+++ b/src/main/python/OMChem/adiabatic_exp.py
@@ -0,0 +1,67 @@
+from OMChem.EngStm import EngStm
+class AdiabaticExpander():
+ counter = 1
+ def __init__(self,name='AdiabaticExpander', eff = None):
+ self.eff = eff
+ self.name = name + str(AdiabaticExpander.counter)
+ self.OM_data_eqn = ''
+ self.OM_data_init = ''
+ self.InputStms = None
+ self.OutputStms = None
+ self.EngStms = EngStm(name='EngStm'+self.name)
+ self.count = AdiabaticExpander.counter
+ self.type = 'AdiabaticExpander'
+ self.thermoPackage ="RaoultsLaw"
+ self.mode = None
+ self.modeVal = None
+
+ # new
+ self.no_of_input = 1
+ self.no_of_output = 1
+ AdiabaticExpander.counter += 1
+
+ def getname(self):
+ return self.name
+
+ def connect(self,InputStms = None,OutputStms = None):
+ self.InputStms = InputStms
+ self.OutputStms = OutputStms
+
+ def modesList(self):
+ return ["pressDrop","outP","genPow"]
+
+ def paramgetter(self,mode="pressDrop"):
+ self.mode = mode
+ dict = {"eff":None,self.mode:None,"thermoPackage":None}
+ return dict
+
+ def paramsetter(self,dict):
+ self.eff = dict['eff']
+ self.modeVal = dict[self.mode]
+
+ def OM_Flowsheet_Init(self, addedcomp):
+ self.OM_data_init = ''
+ self.OM_data_init = self.OM_data_init + 'Simulator.Streams.Energy_Stream '+self.EngStms.name+';\n'
+ self.OM_data_init = self.OM_data_init + ("model adiaComp"+str(self.count)+"\n")
+ self.OM_data_init = self.OM_data_init + ("extends Simulator.Unit_Operations.Adiabatic_Expander;\n" )
+ self.OM_data_init = self.OM_data_init + ("extends Simulator.Files.Thermodynamic_Packages."+self.thermoPackage+";\n")
+ self.OM_data_init = self.OM_data_init + ("end adiaComp"+str(self.count)+";\n")
+ comp_count = len(addedcomp)
+ self.OM_data_init = self.OM_data_init + (
+ "adiaComp"+str(self.count)+" "+ self.name + "(Nc = " + str(comp_count))
+ self.OM_data_init = self.OM_data_init + (",comp = {")
+ comp = str(addedcomp).strip('[').strip(']')
+ comp = comp.replace("'", "")
+ self.OM_data_init = self.OM_data_init + comp + ("},")+("eff="+self.eff+");\n")
+ return self.OM_data_init
+
+ def OM_Flowsheet_Eqn(self, addedcomp):
+ self.OM_data_eqn = ''
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.InputStms[0].name + '.outlet,' + self.name + '.inlet' + ');\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.name + '.outlet,' + self.OutputStms[0].name + '.inlet);\n')
+ self.OM_data_eqn = self.OM_data_eqn + ('connect(' + self.EngStms.name + '.outlet,' + self.name + '.energy);\n')
+
+ self.OM_data_eqn = self.OM_data_eqn + (self.name+'.'+self.mode+'='+ self.modeVal + ';\n')
+
+ return self.OM_data_eqn
+
diff --git a/src/main/python/OMChem/setup.py b/src/main/python/OMChem/setup.py
new file mode 100644
index 0000000..037da1c
--- /dev/null
+++ b/src/main/python/OMChem/setup.py
@@ -0,0 +1,54 @@
+try:
+ from setuptools import setup
+except ImportError:
+ from distutils.core import setup
+
+from subprocess import call
+import sys
+import os
+# Python 3.3 offers shutil.which()
+from distutils import spawn
+
+def warningOrError(errorOnFailure, msg):
+ if errorOnFailure:
+ raise Exception(msg)
+ else:
+ print(msg)
+
+def generateIDL():
+ errorOnFailure = not os.path.exists(os.path.join(os.path.dirname(__file__), 'OMPythonIDL', '__init__.py'))
+ try:
+ omhome = os.path.split(os.path.split(os.path.realpath(spawn.find_executable("omc")))[0])[0]
+ except:
+ omhome = None
+ omhome = omhome or os.environ.get('OPENMODELICAHOME')
+
+ if omhome is None:
+ warningOrError(errorOnFailure, "Failed to find OPENMODELICAHOME (searched for environment variable as well as the omc executable)")
+ return
+ idl = os.path.join(omhome,"share","omc","omc_communication.idl")
+ if not os.path.exists(idl):
+ warningOrError(errorOnFailure, "Path not found: %s" % idl)
+ return
+
+ if 0 is not call(["omniidl","-bpython","-Wbglobal=_OMCIDL","-Wbpackage=OMPythonIDL",idl]):
+ warningOrError(errorOnFailure, "omniidl command failed")
+ return
+ print("Generated OMPythonIDL files")
+generateIDL()
+
+setup(name='OMPython',
+ version='2.0.7',
+ description='OpenModelica-Python API Interface',
+ author='Anand Kalaiarasi Ganeson',
+ author_email='ganan642@student.liu.se',
+ maintainer='Adeel Asghar',
+ maintainer_email='adeel.asghar@liu.se',
+ license="BSD, OSMC-PL 1.2, GPL (user's choice)",
+ url='http://openmodelica.org/',
+ packages=['OMPython', 'OMPython.OMParser', 'OMPythonIDL', 'OMPythonIDL._OMCIDL', 'OMPythonIDL._OMCIDL__POA'],
+ install_requires=[
+ # 'omniORB', # Required, but not part of pypi
+ 'pyparsing'
+ ]
+)
diff --git a/src/main/python/mainApp.py b/src/main/python/mainApp.py
new file mode 100644
index 0000000..bd6638c
--- /dev/null
+++ b/src/main/python/mainApp.py
@@ -0,0 +1,417 @@
+import pickle
+import threading
+import os
+import ctypes
+import sys
+import datetime
+from functools import partial
+import pyuac
+
+current = os.path.dirname(os.path.realpath(__file__))
+parentPath = os.path.dirname(current)
+sys.path.append(parentPath)
+
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtGui import *
+import PyQt5.QtGui as QtGui
+import PyQt5.QtCore as QtCore
+import PyQt5.QtWidgets as QtWidgets
+
+from python.OMChem.Flowsheet import Flowsheet
+from python.utils.ComponentSelector import *
+from python.utils.Bin_Phase_env import *
+from python.utils.UnitOperations import *
+from python.utils.Streams import *
+from python.utils.Container import *
+from python.utils.Graphics import *
+
+ui,_ = loadUiType(parentPath+'/ui/utils/main.ui')
+
+'''
+ MainApp class is responsible for all the main App Ui operations
+'''
+class MainApp(QMainWindow,ui):
+ '''
+ Initializing the application
+ '''
+ def __init__(self):
+ QMainWindow.__init__(self)
+
+ # Loading and setting up style sheet
+ self.setupUi(self)
+
+ # Initializing attributes
+ self.zoom_count = 0
+ self.thrd = None
+
+ # Creating instances of classes for the main app
+ self.container = Container(self.textBrowser, self.graphicsView)
+ self.comp = ComponentSelector(self)
+ self.comp.accepted.connect(self.update_compounds)
+
+ # Setting up interactive canvas
+ self.scene = self.container.graphics.get_scene()
+ self.graphicsView.setScene(self.scene)
+ self.graphicsView.setMouseTracking(True)
+ self.graphicsView.keyPressEvent=self.delete_call
+
+ self.setDockNestingEnabled(True)
+ self.setCorner(Qt.BottomRightCorner, Qt.RightDockWidgetArea)
+ self.setCorner(Qt.BottomLeftCorner, Qt.LeftDockWidgetArea)
+ self.addDockWidget(Qt.BottomDockWidgetArea,self.dockWidget_2)
+
+ # Calling initialisation
+ self.menu_bar()
+ self.button_handler()
+ self.comp.show()
+
+ '''
+ MenuBar function handels all the all the operations of
+ menu bar like new,zoom,comounds selector, simulation options.
+ '''
+ def menu_bar(self):
+ self.actionSelectCompounds.triggered.connect(self.select_compounds)
+ self.actionSelectCompounds.setShortcut('Ctrl+C')
+ self.actionZoomIn.triggered.connect(self.zoom_in)
+ self.actionZoomIn.setShortcut('Ctrl++')
+ self.actionNew.triggered.connect(self.new)
+ self.actionNew.setShortcut('Ctrl+N')
+ self.actionZoomOut.triggered.connect(self.zoom_out)
+ self.actionZoomOut.setShortcut('Ctrl+-')
+ self.actionResetZoom.triggered.connect(self.zoom_reset)
+ self.actionResetZoom.setShortcut('Ctrl+R')
+ self.actionHelp.triggered.connect(self.help)
+ self.actionHelp.setShortcut('Ctrl+H')
+ self.actionSequentialMode.triggered.connect(partial(self.simulate,'SM'))
+ self.actionSequentialMode.setShortcut('Ctrl+M')
+ self.actionEquationOriented.triggered.connect(partial(self.simulate,'EQN'))
+ self.actionEquationOriented.setShortcut('Ctrl+E')
+ # self.actionUndo.triggered.connect(self.undo)
+ # self.actionUndo.setShortcut('Ctrl+Z')
+ # self.actionRedo.triggered.connect(self.redo)
+ # self.actionRedo.setShortcut('Ctrl+Y')
+ self.actionSave.triggered.connect(self.save)
+ self.actionSave.setShortcut('Ctrl+S')
+ self.actionOpen.triggered.connect(self.open)
+ self.actionOpen.setShortcut('Ctrl+O')
+ self.actionTerminate.triggered.connect(self.terminate)
+ self.actionTerminate.setShortcut('Ctrl+T')
+ self.actionBinaryPhaseEnvelope.triggered.connect(self.bin_phase_env)
+ self.actionViewMessageBrowser.triggered.connect(self.toggle_message_browser_view)
+ self.actionViewComponentSelector.triggered.connect(self.toggle_component_selector_view)
+
+ '''
+ Handles all the buttons of different components.
+ '''
+ def button_handler(self):
+ self.pushButton.clicked.connect(partial(self.component,'MaterialStream'))
+ self.pushButton_7.clicked.connect(partial(self.component,'Mixer'))
+ self.pushButton_14.clicked.connect(partial(self.component,'CentrifugalPump'))
+ self.pushButton_26.clicked.connect(partial(self.component,'DistillationColumn'))
+ self.pushButton_18.clicked.connect(partial(self.component,'ShortcutColumn'))
+ self.pushButton_11.clicked.connect(partial(self.component,'Heater'))
+ self.pushButton_10.clicked.connect(partial(self.component,'Splitter'))
+ self.pushButton_9.clicked.connect(partial(self.component,'Flash'))
+ self.pushButton_25.clicked.connect(partial(self.component,'Valve'))
+ self.pushButton_12.clicked.connect(partial(self.component,'Cooler'))
+ self.pushButton_13.clicked.connect(partial(self.component,'CompoundSeparator'))
+ self.pushButton_15.clicked.connect(partial(self.component,'AdiabaticCompressor'))
+ self.pushButton_16.clicked.connect(partial(self.component,'AdiabaticExpander'))
+
+ '''
+ Displays help box
+ '''
+ def help(self):
+ msgBox = QMessageBox()
+ msgBox.setIcon(QMessageBox.Question)
+ msgBox.setTextFormat(Qt.RichText);
+ msgBox.setText("For any Help or Suggestion you can contact us at\n contact-om@fossee.in or at <a href='https://www.fossee.in'>Visit fossee.in!</a>")
+ msgBox.setStandardButtons(QMessageBox.Ok)
+ msgBox.exec_()
+
+ '''
+ Creates Binary Phase envelope
+ '''
+ def bin_phase_env(self):
+ if len(self.comp.get_compounds())<2:
+ QMessageBox.about(self, 'Important', "Please select at least 2 Compounds first")
+ self.comp.show()
+ else:
+ self.bin_phase = BinPhaseEnv(self.comp)
+ self.bin_phase.show()
+
+ '''
+ Shows Compounds Selector Dialog
+ '''
+ def select_compounds(self):
+ self.comp.show()
+
+ '''
+ Updates compounds after compound selected modified during simulation creation
+ '''
+ def update_compounds(self):
+ self.container.update_compounds()
+
+
+ '''
+ Returns current time in a required particular format
+ '''
+ def current_time(self):
+ now = datetime.datetime.now()
+ time = str(now.hour) + ":" + str(now.minute) + ":" +str(now.second)
+ return time
+
+ '''
+ Simulate function is responsible for the simulation
+ of the designed flowsheet in a particular mode
+ selected by the user.
+ '''
+ def simulate(self,mode):
+ self.thrd = threading.Thread(target=self.container.simulate, args=(mode,))
+ self.thrd.start()
+
+ '''
+ Terminate the current running simulation
+ '''
+ def terminate(self):
+ os.chdir(self.container.flowsheet.root_dir)
+ if self.thrd:
+ thread_id = self.thrd.ident
+ # print('____________________Going to terminate simulation thread with Thread ID:',thread_id,'____________________')
+ # print('____________________Going to terminate the new process created for omc____________________')
+ self.container.flowsheet.process.terminate()
+ print('____________________New process created for omc is terminated.____________________')
+ res = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, ctypes.py_object(SystemExit))
+ self.textBrowser.append("<span style=\"color:red\">["+str(self.current_time())+"]<b>Simulation Terminated.</b></span>")
+ self.container.disableInterfaceforSimulation(False)
+ # print('____________________Simulation thread terminated____________________')
+ if res > 1:
+ ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 0)
+ # print('Exception raise (Thread termination) failure')
+
+ '''
+ Resets the zoom level to default scaling
+ '''
+ def zoom_reset(self):
+ if(self.zoom_count>0):
+ for i in range(self.zoom_count):
+ self.zoomout()
+ elif(self.zoom_count<0):
+ for i in range(abs(self.zoom_count)):
+ self.zoomin()
+
+ '''
+ ZoomOut the canvas
+ '''
+ def zoom_out(self):
+ self.graphicsView.scale(1.0/1.15,1.0/1.15)
+ self.zoom_count -=1
+
+ '''
+ ZoomIn the canvas
+ '''
+ def zoom_in(self):
+ self.graphicsView.scale(1.15,1.15)
+ self.zoom_count +=1
+
+ '''
+ Instantiate a NodeItem object for selected type of
+ component and added that on canvas/flowsheeting area.
+ '''
+ def component(self,unit_operation_type):
+ if(self.comp.is_compound_selected()):
+ self.type = unit_operation_type
+ if(self.type=="MaterialStream"):
+ self.obj = MaterialStream(compound_names = compound_selected)
+ else:
+ self.obj = eval(self.type)()
+ self.container.add_unit_operation(self.obj)
+
+ else:
+ QMessageBox.about(self, 'Important', "Please Select Compounds first")
+ self.comp.show()
+
+ '''
+ New is used to delete all the existing work.
+ '''
+ def new(self):
+ self.setWindowTitle('Untitled - Chemical Simulator GUI')
+ #self.undo_redo_helper()
+ self.comp = ComponentSelector(self)
+ self.textBrowser.append("<span>[" + str(self.current_time()) + "] <b>New</b> flowsheet is created ... </span>")
+ dock_widget_lst.clear()
+
+ '''
+ Handels all the operations which will happen when delete button is pressed.
+ '''
+ def delete_call(self,event):
+ try:
+ if event.key() == QtCore.Qt.Key_Delete:
+ l=self.scene.selectedItems()
+ self.container.delete(l)
+ except Exception as e:
+ print(e)
+
+ # '''
+ # It helps by clearing screen and loading the objects by undo redo methods
+ # '''
+ # def undo_redo_helper(self):
+ # for i in self.container.unit_operations:
+ # type(i).counter = 1
+ # self.container = None
+ # for i in dock_widget_lst:
+ # i.hide()
+ # del i
+ # lst.clear()
+ # self.container = Container(self.textBrowser, self.graphicsView)
+
+ # compound_selected.clear()
+ # self.scene = self.container.graphics.get_scene()
+ # self.graphicsView.setScene(self.scene)
+ # self.graphicsView.setMouseTracking(True)
+ # self.graphicsView.keyPressEvent=self.delete_call
+
+ # '''
+ # Function for undo
+ # '''
+ # def undo(self):
+ # redo_data = pop('Undo')
+ # if redo_data is not None:
+ # push('Redo', redo_data)
+ # undo_data = get_last_list('Undo')
+ # messages = self.textBrowser.toPlainText()
+ # try:
+ # self.undo_redo_helper()
+ # self.container.graphics.load_canvas(undo_data, self.container)
+ # self.textBrowser.setText(messages)
+ # except Exception as e:
+ # print(e)
+ # self.textBrowser.append(messages)
+ # else:
+ # messages = self.textBrowser.toPlainText()
+ # self.textBrowser.setText(messages)
+ # self.textBrowser.append("<span>[" + str(self.current_time()) + "] <b>No more undo can be done!</b>... </span>")
+
+ # '''
+ # Function for redo
+ # '''
+ # def redo(self):
+ # redo_data = pop('Redo')
+ # if redo_data is not None:
+ # push('Undo', redo_data)
+ # messages = self.textBrowser.toPlainText()
+ # self.undo_redo_helper()
+ # self.container.graphics.load_canvas(redo_data, self.container)
+ # self.textBrowser.setText(messages)
+ # else:
+ # messages = self.textBrowser.toPlainText()
+ # self.textBrowser.setText(messages)
+ # self.textBrowser.append("<span>[" + str(self.current_time()) + "] <b>No more redo can be done!</b>... </span>")
+
+ '''
+ Function for saving the current canvas items and compound_selected
+ '''
+ def save(self):
+ data = []
+ for i in self.container.unit_operations:
+ data.append(i)
+ i.saved = True
+ data.append(compound_selected)
+ data.append(self.container.result)
+
+ file_format = 'sim'
+ initial_path = QDir.currentPath() + ' untitled.' + file_format
+ file_name, _ = QFileDialog.getSaveFileName(self, "Save As",
+ initial_path, "%s Files (*.%s);; All Files (*)" %
+ (file_format.upper(), file_format))
+ try:
+ with open(file_name, 'wb') as f:
+ pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)
+ fileName = file_name.split('/')[-1].split('.')[0]
+ self.setWindowTitle(fileName+' - Chemical Simulator GUI')
+ except Exception as e:
+ pass
+
+ '''
+ Function for loading previous saved canvas and simulation
+ '''
+ def open(self):
+ try:
+ file_format = 'sim'
+ initial_path = QDir.currentPath() + 'untitled.' + file_format
+
+ file_name, _ = QFileDialog.getOpenFileName(self, "Open As",
+ initial_path, "%s Files (*.%s);; All Files (*)" %
+ (file_format.upper(), file_format))
+ if file_name:
+ fileName = file_name.split('/')[-1].split('.')[0]
+ self.setWindowTitle(fileName+' - Chemical Simulator GUI')
+
+ #self.undo_redo_helper()
+
+ with open(file_name, 'rb') as f:
+ obj = pickle.load(f)
+ temp_result = obj[-1]
+ obj.pop()
+ compound_selected = obj[-1]
+ obj.pop()
+ self.comp.set_compounds(compound_selected)
+ for i in compound_selected:
+ self.comp.compound_selection(self.comp, i)
+ self.comp.hide()
+ self.container.graphics.load_canvas(obj, self.container)
+ self.container.result = temp_result
+ DockWidget.show_result(dock_widget_lst)
+
+ for i in dock_widget_lst:
+ #Submitting values
+ i.param()
+
+ #Disbaling input data tab for output stream
+ for i in self.container.graphics.scene.items():
+ if (isinstance(i, NodeItem) and i.type == 'MaterialStream'):
+ i.update_tooltip_selectedVar()
+ no_input_lines = len(i.input[0].in_lines)
+ no_output_lines = len(i.output[0].out_lines)
+ if(no_input_lines>0): #Checks if material stream is input or output stream if it is output stream it continues
+ i.obj.disableInputDataTab(i.dock_widget)
+
+ except Exception as e:
+ print(e)
+
+ '''
+ Function for toggling the display of Component Selector
+ '''
+ def toggle_component_selector_view(self):
+ if(self.actionViewComponentSelector.isChecked()):
+ self.dockWidget.show()
+ else:
+ self.dockWidget.hide()
+
+ '''
+ Function for toggling the display of Message Browser
+ '''
+ def toggle_message_browser_view(self):
+ if(self.actionViewMessageBrowser.isChecked()):
+ self.dockWidget_2.show()
+ else:
+ self.dockWidget_2.hide()
+
+
+def main():
+
+ # clean_file('Undo')
+ # clean_file('Redo')
+
+ app = QApplication(sys.argv)
+ window = MainApp()
+ window.showMaximized()
+ app.exec()
+
+
+if __name__ == '__main__':
+ if not pyuac.isUserAdmin():
+ pyuac.runAsAdmin()
+ else:
+ main()
diff --git a/src/main/python/utils/Bin_Phase_env.py b/src/main/python/utils/Bin_Phase_env.py
new file mode 100644
index 0000000..dd6f938
--- /dev/null
+++ b/src/main/python/utils/Bin_Phase_env.py
@@ -0,0 +1,241 @@
+import sys
+import pandas as pd
+import numpy as np
+import os
+import csv
+from subprocess import Popen, PIPE
+
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtGui import *
+import PyQt5.QtGui as QtGui
+import PyQt5.QtCore as QtCore
+import PyQt5.QtWidgets as QtWidgets
+from PyQt5.uic import loadUiType
+
+
+import pyqtgraph as pg
+import pyqtgraph.exporters
+
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+ui_dialog,_ = loadUiType(parentPath+'/ui/utils/Binary_Phase_Env.ui')
+pg.CONFIG_OPTIONS['crashWarning'] = False
+
+class BinPhaseEnv(QWidget,ui_dialog):
+ def __init__(self,comp):
+ QWidget.__init__(self)
+ self.setupUi(self)
+
+ self.comp = comp
+ self.compunds = self.comp.get_compounds()
+
+ for i in self.compunds:
+ self.comboBox.addItem(str(i))
+
+ for i in range(len(self.compunds)):
+ if i!=0:
+ self.comboBox_2.addItem(str(self.compunds[i]))
+
+ self.comboBox_2.addItem(str(self.compunds[0]))
+
+ self.lines = [line.rstrip('\n') for line in open(parentPath+'/python/utils/thermopackage.txt')]
+ for j in self.lines:
+ self.comboBox_3.addItem(str(j))
+
+ self.radioButton.setChecked(False)
+ self.radioButton_2.setChecked(False)
+
+ self.button_handler()
+ self.counter = 1
+
+ def button_handler(self):
+ self.radioButton.clicked.connect(lambda:self.T_xy())
+ self.radioButton_2.clicked.connect(lambda:self.P_xy())
+ self.pushButton_2.clicked.connect(lambda:self.plot())
+
+ def T_xy(self):
+ self.radioButton.setChecked(True)
+ self.radioButton_2.setChecked(False)
+ for i in reversed(range(self.formLayout.count())):
+ self.formLayout.itemAt(i).widget().setParent(None)
+
+ self.first = QLineEdit()
+ self.type = "P"
+ self.other = "T"
+ self.otherunit = "(K)"
+ self.formLayout.addRow(QLabel("P(Pa)"),self.first)
+ self.points = QLineEdit()
+ self.points.setText("40")
+ self.formLayout.addRow(QLabel("Number of data points"),self.points)
+
+ def P_xy(self):
+ self.radioButton_2.setChecked(True)
+ self.radioButton.setChecked(False)
+ for i in reversed(range(self.formLayout.count())):
+ self.formLayout.itemAt(i).widget().setParent(None)
+
+ self.first = QLineEdit()
+ self.type = "T"
+ self.other = "P"
+ self.otherunit = "(Pa)"
+ self.points = QLineEdit()
+ self.points.setText("40")
+ self.formLayout.addRow(QLabel("T(K)"),self.first)
+ self.formLayout.addRow(QLabel("Number of data points"),self.points)
+
+ def get_omc_path(self):
+ try:
+ self.omhome = os.environ.get('OPENMODELICAHOME')
+ if self.omhome is None:
+ self.omhome = os.path.split(os.path.split(os.path.realpath(spawn.find_executable("omc")))[0])[0]
+ elif os.path.exists('/opt/local/bin/omc'):
+ self.omhome = '/opt/local'
+ elif os.path.exists('/usr/bin/omc'):
+ self.omhome = '/usr'
+ return os.path.join(self.omhome, 'bin', 'omc')
+ except BaseException:
+ #print("The OpenModelica compiler is missing in the System path please install it" )
+ raise
+
+ def plot(self):
+ try:
+ val = int(self.first.text(),10)
+ except:
+ val = 0
+ try:
+ data_points = int(self.points.text(),10)
+ except:
+ data_points = 0
+
+ self.curr_path = os.getcwd()
+ self.sim_dir_path = os.path.join(self.curr_path,'./../Simulator')
+ self.Graphmo_path = os.path.join(self.sim_dir_path,'Graph.mo')
+ self.plot_mos_path = os.path.join(self.sim_dir_path,'PlotGraph.mos')
+
+ self.data = []
+
+ self.comp1 = self.comboBox.currentText()
+ self.comp2 = self.comboBox_2.currentText()
+ self.comp_1 = self.comboBox.currentText().split('(')[0]
+ self.comp_2 = self.comboBox_2.currentText().split('(')[0]
+
+ self.thermoPack = self.comboBox_3.currentText()
+
+ self.data.append("model Graph\n")
+ self.data.append("import data = Simulator.Files.ChemsepDatabase;\n")
+ self.data.append("parameter data."+self.comp_1+" comp1;\n")
+ self.data.append("parameter data."+self.comp_2+" comp2;\n")
+ self.data.append("extends BinaryEnvelopes."+self.thermoPack+"(Nc = 2, data_points = "+str(data_points)+ ", comp = { comp1, comp2 }, "+self.type+" = fill( "+str(val)+", "+str(data_points)+"));\n")
+ self.data.append("end Graph;")
+
+ with open(self.Graphmo_path, 'w') as txtfile:
+ for d in self.data:
+ txtfile.write(str(d))
+
+ with open(self.plot_mos_path, 'w') as mosFile:
+ mosFile.write("loadModel(Modelica);\n")
+ mosFile.write("loadFile(\"Simulator/package.mo\");\n")
+ mosFile.write("loadFile(\"BinaryEnvelopes.mo\");\n")
+ mosFile.write("loadFile(\"Graph.mo\");\n")
+ mosFile.write("simulate(Graph, outputFormat=\"csv\", stopTime=1.0, numberOfIntervals=1);\n")
+
+ self.resdata = []
+ self.omc_path = self.get_omc_path()
+ simpath = self.plot_mos_path
+ os.chdir(self.sim_dir_path)
+
+ process = Popen([self.omc_path, '-s',simpath], stdout=PIPE, stderr=PIPE)
+ self.stdout, self.stderr = process.communicate()
+
+ os.chdir(self.curr_path)
+
+ csvpath = os.path.join(self.sim_dir_path,'Graph_res.csv')
+
+ self.datay = []
+ self.datax1 = []
+ self.datax2 = []
+ self.rows = []
+
+ with open (csvpath,'r') as resultFile:
+ self.resdata = []
+ csvreader = csv.reader(resultFile,delimiter=',')
+ for row in csvreader:
+ self.resdata.append(row)
+ self.rows.append(row)
+
+ if self.type=='T':
+ for k in range(len(self.rows[0])):
+ if self.rows[0][k][0]=='P':
+ self.datay.append(float(self.rows[1][k]))
+ length = len(self.rows[0][k])
+ if self.rows[0][k][0]=='x' and self.rows[0][k][length-2]=='1':
+ self.datax1.append(float(self.rows[1][k]))
+ if self.rows[0][k][0]=='y' and self.rows[0][k][length-2]=='1':
+ self.datax2.append(float(self.rows[1][k]))
+ else:
+ for k in range(len(self.rows[0])):
+ if self.rows[0][k][0]=='T':
+ self.datay.append(float(self.rows[1][k]))
+ length = len(self.rows[0][k])
+ if self.rows[0][k][0]=='x' and self.rows[0][k][length-2]=='1':
+ self.datax1.append(float(self.rows[1][k]))
+
+ if self.rows[0][k][0]=='y' and self.rows[0][k][length-2]=='1':
+ self.datax2.append(float(self.rows[1][k]))
+
+ plt = pg.PlotWidget()
+ plt.showGrid(x=True,y=True)
+ plt.addLegend()
+ plt.setXRange(0,1)
+
+ c1 = plt.plot(self.datax1, self.datay,pen=pg.mkPen('b',width = 1), name='dew points')
+ c2 = plt.plot(self.datax2, self.datay,pen=pg.mkPen('r',width = 1), name='bubble points')
+ view_box = plt.plotItem.vb
+ self.tool_tip = ""
+
+ def press_event(evt):
+ a = 10
+ pos = evt
+ mousepoint = view_box.mapSceneToView(pos)
+ roi = pg.ROI(pos)
+ find_color = plt.mapToGlobal(pos.toPoint())
+
+ screen = QGuiApplication.primaryScreen()
+ image = screen.grabWindow(QApplication.desktop().winId()).toImage()
+ colour = QtGui.QColor(image.pixel(find_color.x(),find_color.y()))
+
+ if colour.red()==255 or colour.blue()==255:
+ self.lineEdit_x.setText(str(round(mousepoint.x(),3)))
+ self.lineEdit_y.setText(str(round(mousepoint.y(),3)))
+ self.tool_tip = str(round(mousepoint.x(),3)) + ", " + str(round(mousepoint.y(),3))
+ QApplication.setOverrideCursor(QCursor(QtCore.Qt.CrossCursor))
+ else:
+ self.lineEdit_x.setText("")
+ self.lineEdit_y.setText("")
+ self.tool_tip = ""
+ QApplication.setOverrideCursor(QCursor(QtCore.Qt.ArrowCursor))
+
+ def entered(items):
+ for i in items:
+ if i.__class__.__name__ =="LegendItem":
+ self.lineEdit_x.setText("")
+ self.lineEdit_y.setText("")
+ QApplication.setOverrideCursor(QCursor(QtCore.Qt.ArrowCursor))
+ else:
+ i.setToolTip(self.tool_tip)
+
+ plt.scene().sigMouseMoved.connect(press_event)
+ plt.scene().sigMouseHover.connect(entered)
+
+ plt.setLabel('left',self.other+self.otherunit,units = '')
+ plt.setLabel('bottom',self.comp1+'(mol. frac.)',units = '')
+
+ self.new_tab = plt
+ self.new_tab.setObjectName("Plot "+str(self.counter))
+
+ self.tabWidget.addTab(self.new_tab,"Plot "+str(self.counter))
+ self.counter+=1
diff --git a/src/main/python/utils/ComponentSelector.py b/src/main/python/utils/ComponentSelector.py
new file mode 100644
index 0000000..44a2696
--- /dev/null
+++ b/src/main/python/utils/ComponentSelector.py
@@ -0,0 +1,177 @@
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtGui import *
+from PyQt5.uic import loadUiType
+import os, sys
+import pandas as pd
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parent)
+
+from Simulator.Databases.Databases import ChemsepDatabase
+ui_dialog,_ = loadUiType(parentPath+'/ui/utils/ComponentSelector.ui')
+
+
+#df = pd.read_csv("compoundsDatabase.csv")
+
+compound_selected = [] #list storing components that are selected inintialised as empty
+
+class ComponentSelector(QDialog,ui_dialog):
+ def __init__(self,parent=None):
+ QDialog.__init__(self,parent)
+
+ self.setupUi(self)
+
+ self.dict1=dict()#empty dictionary which will store the obj and its compound
+ self.instance=[ChemsepDatabase()] #list of all the instances
+ self.lines=[]
+
+ for i in self.instance:
+ x=i.get_comp_name_list()
+ self.dict1[i]=x
+ self.lines+=x
+ #print(self.lines)
+
+ self.model = QStringListModel()
+ self.model.setStringList(self.lines)
+
+ self.completer = QCompleter()
+ self.completer.setCaseSensitivity(Qt.CaseInsensitive)
+ self.completer.setModel(self.model)
+
+ # QCompleter completes the text written in lineedit
+ self.lineEdit.setCompleter(self.completer)
+ self.compoundSelectButton.clicked.connect(self.compound_selection)
+ self.compoundSelectButton.setAutoDefault(False)
+ self.pushButton.clicked.connect(self.accept)
+ self.pushButton_2.clicked.connect(self.cancel)
+ self.pushButton_3.clicked.connect(self.remove_items)
+
+ def final_list(self,*list_name):
+ self.list_final=[]
+ #add multiple lists
+ for i in list_name:
+ self.list_final+=i
+ return (self.list_final)
+
+ def is_compound_selected(self):
+ if not compound_selected:
+ return False
+ else:
+ return True
+
+ #attrib:
+ #CAS fro CAS Number
+ #CompoundID for Name
+ #Smiles for Molecular Formula
+ #MolecularWeight for Molecular Weight
+
+#the below function will match the entered compound and get the database obj
+ #of the corresponding database
+
+ def get_object(self,component):
+ for ele in self.dict1:
+ values=self.dict1[ele]
+ for ind in values:
+ if ind ==component:
+ return(ele)
+
+
+#the below finction removes the before added extra string from the cmpounds
+ def get_original_name(self,component,removing_attrib):
+ self.temp_comp= component.replace(removing_attrib,'')
+ return(self.temp_comp)
+
+ def compound_selection(self, *args):
+ if len(args) == 2:
+ self.comp = args[1] #helpful when loading saved data
+ else:
+ self.comp = self.lineEdit.text() #gets entered text
+ if self.comp in self.lines: #matches with the db
+ if self.comp not in compound_selected:
+ compound_selected.append(self.comp) # appending compound in the list
+ self.obj=self.get_object(self.comp) #obj will store the key of the dictionary
+ #and thus store the instance of the class to which the component belongs
+ self.removing_attrib='(' + self.obj.name + ')' #getting the attribute that is to be removed
+ self.comp=self.get_original_name(self.comp,self.removing_attrib)
+ #getting only air, water etc from air chemsep etc
+
+
+ self.prop_list=self.obj.get_comp_prop(self.comp) #getting prop of the comp
+ #obj is the required class object
+ # self.creating_mo_file()
+ self.final_mo()
+
+ self.lineEdit.clear()
+ #print(compound_selected)
+
+ self.CAS=self.obj.get_value(self.comp,'CAS')
+ self.name=self.comp
+ self.molecular_formula=self.obj.get_value(self.comp, 'StructureFormula')
+ self.molecular_weight=self.obj.get_value(self.comp, 'MolecularWeight')
+
+ dict={'CAS':self.CAS,'Name':self.name,'Molecular Formula':self.molecular_formula,'Molecular Weight':self.molecular_weight}
+ #converted everything to a dictionary which will be passes to addtable
+ #function as a parameter.
+ #print(dict)
+ self.add_to_table(dict)
+ else:
+ self.show_error()
+
+ @staticmethod
+ def set_compounds(compounds):
+ # compound_selected = compounds
+ for i in compounds:
+ compound_selected.append(i)
+
+ def add_to_table(self,a):
+ try:
+ row_position = self.tableWidget.rowCount()
+ self.tableWidget.insertRow(row_position)
+ self.tableWidget.setItem(row_position , 0, QTableWidgetItem(str(a['CAS'])))
+ self.tableWidget.setItem(row_position , 1, QTableWidgetItem(str(a['Name'])))
+ self.tableWidget.setItem(row_position , 2, QTableWidgetItem(str(a['Molecular Formula'])))
+ self.tableWidget.setItem(row_position , 3, QTableWidgetItem(str(a['Molecular Weight'])))
+ except Exception as e:
+ exc_type, exc_obj, exc_tb = sys.exc_info()
+ fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
+ #print(exc_type, fname, exc_tb.tb_lineno)
+
+ def add_compounds_to_list(self,comp): # which list?
+ self.item = QListWidgetItem()
+ self.item.setText(comp)
+ self.listWidget.addItem(self.item)
+
+ def remove_items(self):
+ try:
+ item = self.tableWidget.item(self.tableWidget.currentRow(),1).text() + '(chemsep)'
+ self.tableWidget.removeRow(self.tableWidget.currentRow())
+ compound_selected.remove(item)
+ except Exception as e:
+ print(e)
+
+ def show_error(self):
+ QMessageBox.about(self, 'Important', "Selected Compound is not Available")
+
+ def cancel(self):
+ compound_selected.clear()
+ self.tableWidget.setRowCount(0)
+ self.reject()
+
+ def get_compounds(self):
+ return compound_selected
+
+ def final_mo(self):
+ self.f_mo=open(parentPath+'/Simulator/database.mo','w+')
+ self.f_mo.write('package database\n')
+ for line in self.prop_list:
+ self.f_mo.write(line)
+ self.f_mo.write('\n')
+ self.f_mo.write('\nend database;')
+ self.f_mo.close()
+
+ def accept(self):
+ #self.parent().container.update_compounds()
+ return super().accept()
+ \ No newline at end of file
diff --git a/src/main/python/utils/Container.py b/src/main/python/utils/Container.py
new file mode 100644
index 0000000..139346c
--- /dev/null
+++ b/src/main/python/utils/Container.py
@@ -0,0 +1,264 @@
+from collections import defaultdict
+import datetime
+import pickle
+import os,sys
+
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+from python.OMChem.Flowsheet import Flowsheet
+from python.utils.ComponentSelector import *
+from python.utils.Graphics import NodeItem, Graphics, dock_widget_lst
+from python.DockWidgets.DockWidget import DockWidget
+
+class Container():
+ def __init__(self,msgbrowser, graphicsView):
+ self.unit_operations = []
+ self.thermo_package = None
+ self.compounds = None
+ self.flowsheet = None
+ self.conn = defaultdict(list)
+ self.op=defaultdict(list)
+ self.ip=defaultdict(list)
+ self.msg = msgbrowser
+ self.graphicsView = graphicsView
+ self.msg.setText("")
+ self.opl=[]
+ self.result=[]
+ self.graphics = Graphics(self.unit_operations, self.graphicsView)
+ self.scene = self.graphics.get_scene()
+
+ def current_time(self):
+ now = datetime.datetime.now()
+ time = str(now.hour) + ":" + str(now.minute) + ":" +str(now.second)
+ return time
+
+ def add_unit_operation(self, obj):
+ box = None
+ self.obj = obj
+ self.scene = self.graphics.get_scene()
+ box = self.graphics.create_node_item(self.obj, self)
+ if box is not None:
+ self.scene.addItem(box)
+ box.setPos(2500-30, 2500-30)
+
+ if(obj in self.unit_operations):
+ pass
+ else:
+ self.unit_operations.append(obj)
+ data = self.unit_operations[:]
+ data.append(compound_selected)
+ #push('Undo', data)
+ self.msg.append("<span style=\"color:blue\">["+str(self.current_time())+"]<b> "+obj.name+" </b>is instantiated .""</span>")
+
+ '''
+ Deletes the selected item from the canvas and also the objects created for that type.
+ '''
+ def delete(self,l):
+ for item in l:
+ self.scene.removeItem(item)
+ for i in dock_widget_lst:
+ if i.name == item.name:
+ i.hide()
+ del i
+ break
+
+ if hasattr(item,'input'):
+ for x in item.input:
+ if x.new_line:
+ self.scene.removeItem(x.new_line)
+ del x.new_line
+ if x.other_line:
+ self.scene.removeItem(x.other_line)
+ del x.other_line
+ if hasattr(item,'output'):
+ for x in item.output:
+ if x.new_line:
+ self.scene.removeItem(x.new_line)
+ del x.new_line
+ if x.other_line:
+ self.scene.removeItem(x.other_line)
+ del x.other_line
+ if hasattr(item,'obj'):
+ self.unit_operations.remove(item.obj)
+ for k in list(self.conn):
+ if item.obj==k:
+ del self.conn[k]
+ elif item.obj in self.conn[k]:
+ self.conn[k].remove(item.obj)
+ self.msg.append("<span style=\"color:blue\">["+str(self.current_time())+"]<b> "+item.obj.name+" </b>is deleted .""</span>")
+ del item.obj
+ del item
+
+ # clean_file('Redo')
+ # data = self.unit_operations[:]
+ # data.append(compound_selected)
+ # push('Undo', data)
+
+ def fetch_object(self,name):
+ for i in self.unit_operations:
+ if(i.name==name):
+ return i
+
+ def add_compounds(self,comp):
+ self.compounds = comp
+
+ def update_compounds(self):
+ self.graphics.update_compounds()
+
+ def add_thermo_package(self,thermo):
+ self.thermo_package = thermo
+
+ def msg_browser(self):
+ std = self.flowsheet.stdout.decode("utf-8")
+ if(std):
+ stdout = str(std)
+ stdout = stdout.replace("\n","<br/>")
+ self.msg.append("<span style=\"color:green\">"+stdout+"</span>")
+
+ stde = self.flowsheet.stderr.decode("utf-8")
+ if(stde):
+ stdout = str(stde)
+ stdout = stdout.replace("\n","<br/>")
+ self.msg.append("<span style=\"color:red\">"+stdout+"</span>")
+
+ def simulate(self,mode):
+
+ self.disableInterfaceforSimulation(True)
+ toAppend = ''
+ for i in self.graphics.scene.items():
+ showConnectionWarning = False
+ if isinstance(i, NodeItem):
+ try:
+ i.dock_widget.clear_results()
+ except AttributeError:
+ pass
+
+ for ip in i.input:
+ if len(ip.in_lines) == 0:
+ showConnectionWarning = True
+ for op in i.output:
+ if len(op.out_lines) == 0:
+ showConnectionWarning = True
+ if showConnectionWarning:
+ if toAppend != '':
+ toAppend+='<br>'
+ toAppend+="<span style=\"color:#999900\">Warning: "+i.name+" - Missing Socket Connection(s).</span>"
+
+ #print("SIMULATE")
+ #print(mode)
+ self.compounds = compound_selected
+ self.flowsheet = Flowsheet()
+ self.flowsheet.add_compound_list([c[:c.index('(')] for c in self.compounds])
+ #print("######## connection master#########\n",self.conn)
+ for i in self.unit_operations :
+ self.flowsheet.add_unit_operations(i)
+
+
+ if mode=='SM':
+ self.msg.append("<span>["+str(self.current_time())+"] Simulating in <b>Sequential</b> mode ... </span>")
+ self.msg.append(toAppend)
+ self.flowsheet.simulate_SM(self.ip,self.op)
+ self.msg_browser()
+ self.result=self.flowsheet.result_data
+
+ elif mode=='EQN':
+ self.msg.append("<span>["+str(self.current_time())+"] Simulating in <b>equation</b> mode ... </span>")
+ self.msg.append(toAppend)
+ self.flowsheet.simulate_EQN(self.msg)
+ self.result=self.flowsheet.result_data
+
+ if(len(self.result)== 4):
+ #self.msg_browser()
+ self.msg.append("<span style=\"color:green\">["+str(self.current_time())+"] Simulation <b>Successful.</b></span>")
+ else:
+ self.msg.append("<span style=\"color:red\">["+str(self.current_time())+"] Simulation <b>Failed.</b></span>")
+ #print("under Eqn mode simulation")
+
+ if(len(self.result)== 4):
+ DockWidget.show_result(NodeItem.get_dock_widget())
+
+ for i in self.graphics.scene.items():
+ if (isinstance(i, NodeItem) and i.type == 'MaterialStream'):
+ i.update_tooltip_selectedVar()
+ no_input_lines = len(i.input[0].in_lines)
+ no_output_lines = len(i.output[0].out_lines)
+ if(no_input_lines>0): #Checks if material stream is input or output stream if it is output stream it continues
+ i.obj.disableInputDataTab(i.dock_widget)
+
+ self.disableInterfaceforSimulation(False)
+
+ def enableToolbar(self,status):
+ self.graphicsView.parent().parent().actionNew.setProperty('enabled',status)
+ self.graphicsView.parent().parent().actionZoomIn.setProperty('enabled',status)
+ self.graphicsView.parent().parent().actionZoomOut.setProperty('enabled',status)
+ self.graphicsView.parent().parent().actionResetZoom.setProperty('enabled',status)
+ self.graphicsView.parent().parent().actionEquationOriented.setProperty('enabled',status)
+ self.graphicsView.parent().parent().actionTerminate.setProperty('enabled',not status)
+ self.graphicsView.parent().parent().actionSelectCompounds.setProperty('enabled',status)
+
+ def disableInterfaceforSimulation(self,status):
+ self.graphicsView.parent().parent().menubar.setProperty('enabled',not status)
+ self.enableToolbar(not status)
+ self.graphicsView.parent().parent().dockWidget.setProperty('enabled',not status)
+ self.graphicsView.setInteractive(not status)
+ if status:
+ QApplication.instance().setOverrideCursor(QCursor(Qt.WaitCursor))
+ else:
+ QApplication.instance().restoreOverrideCursor()
+ QApplication.instance().setOverrideCursor(QCursor(Qt.ArrowCursor))
+
+def flat_list(lst):
+ flat_lst=[]
+ for sublist in lst:
+ for item in sublist:
+ flat_lst.append(item)
+ return flat_lst
+
+def push(file_name, data):
+ with open(f"{file_name}.dat", "ab") as obj:
+ pickle.dump(data, obj)
+
+def clean_file(file_name):
+ with open(f"{file_name}.dat", "wb") as clean:
+ pass
+
+def pop(file_name):
+ last_command = None
+ if os.stat(f"{file_name}.dat").st_size != 0:
+ commands = []
+ with open(f"{file_name}.dat", "rb") as objs:
+ while True:
+ try:
+ command = pickle.load(objs)
+ commands.append(command)
+ except EOFError:
+ break
+
+ last_command = commands[-1]
+ commands.remove(commands[-1])
+ if len(commands) != 0:
+ with open(f"{file_name}.dat", "wb") as updated_data:
+ for i in range(len(commands)):
+ pickle.dump(commands[i], updated_data)
+ else:
+ clean_file(file_name)
+
+ return last_command
+
+def get_last_list(file_name):
+ commands = []
+ if os.stat(f"{file_name}.dat").st_size != 0:
+ with open(f"{file_name}.dat", "rb") as objs:
+ while True:
+ try:
+ command = pickle.load(objs)
+ commands.append(command)
+ except EOFError:
+ break
+ if len(commands) is not 0:
+ return commands[-1]
+ else:
+ return None
diff --git a/src/main/python/utils/Graphics.py b/src/main/python/utils/Graphics.py
new file mode 100644
index 0000000..eb9b3b9
--- /dev/null
+++ b/src/main/python/utils/Graphics.py
@@ -0,0 +1,694 @@
+from PyQt5.QtCore import *
+from PyQt5.QtWidgets import *
+from PyQt5.QtGui import *
+import PyQt5.QtGui as QtGui
+import PyQt5.QtCore as QtCore
+import PyQt5.QtWidgets as QtWidgets
+from PyQt5.QtWidgets import QLineEdit
+import os, sys
+
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+from python.DockWidgets.DockWidget import *
+from python.DockWidgets.DockWidgetMaterialStream import *
+from python.DockWidgets.DockWidgetDistillationColumn import *
+from python.DockWidgets.DockWidgetShortcutColumn import *
+from python.DockWidgets.DockWidgetMixer import *
+from python.DockWidgets.DockWidgetSplitter import *
+from python.DockWidgets.DockWidgetFlash import *
+from python.DockWidgets.DockWidgetCompoundSeparator import *
+from python.DockWidgets.DockWidgetCompressorExpander import *
+from python.utils.Container import *
+from python.utils.Streams import *
+from python.utils.UnitOperations import *
+from python.utils.ComponentSelector import *
+
+class Graphics(QDialog, QtWidgets.QGraphicsItem):
+
+ def __init__(self, unit_operations, graphicsView):
+ QDialog.__init__(self)
+ QtWidgets.QGraphicsItem.__init__(self)
+ self.scene = QGraphicsScene()
+ self.scene.setItemIndexMethod(QGraphicsScene.BspTreeIndex)
+ self.graphicsView = graphicsView
+ self.pos = None
+ self.unit_operations = unit_operations
+ self.graphicsView.horizontalScrollBarVal = self.graphicsView.horizontalScrollBar().value()
+
+ def get_scene(self):
+ return self.scene
+
+ def create_node_item(self,unit_operation, container):
+ tempItem = NodeItem(unit_operation, container, self.graphicsView)
+ if tempItem.ok:
+ return tempItem
+ else:
+ return None
+
+ def update_compounds(self):
+ for i in self.graphicsView.items():
+ if isinstance(i, NodeItem):
+ i.update_compounds()
+
+ def load_canvas(self, obj, container):
+ stm = ['MaterialStream','EngStm']
+ for i in obj:
+ if i in self.unit_operations:
+ pass
+ else:
+ self.unit_operations.append(i)
+ type(i).counter += 1
+ #print(self.unit_operations)
+ new_box = self.create_node_item(i, container)
+ new_box.setPos(i.pos.toPoint().x(), i.pos.toPoint().y())
+ self.scene.addItem(new_box)
+
+ for i in obj:
+ if i.type == "MaterialStream":
+ pass
+ #print(eval(i.type))
+ elif i.type not in stm:
+ ip = i.input_stms
+ op = i.output_stms
+ for k, v in ip.items():
+ pointA = NodeItem.get_instances(v.name)
+ pointB = NodeItem.get_instances(i.name)
+ rect = pointA.output[0].boundingRect()
+ pointAA = QtCore.QPointF(rect.x() + rect.width()/(2), rect.y() + rect.height()/(2))
+ pointAA = pointA.output[0].mapToScene(pointAA)
+ socketB = next((s for s in pointB.input if k == s.id))
+ rectB = socketB.boundingRect()
+ pointBB = QtCore.QPointF(rectB.x() + rectB.width()/(2), rectB.y() + rectB.height()/(2))
+ pointBB = socketB.mapToScene(pointBB)
+ self.new_line = NodeLine(pointAA, pointBB, 'in')
+ self.new_line.source = pointA.output[0]
+ self.new_line.target = socketB
+ pointA.output[0].out_lines.append(self.new_line)
+ socketB.in_lines.append(self.new_line)
+ pointA.output[0].other_line = self.new_line
+ socketB.other_line = self.new_line
+ self.scene.addItem(self.new_line)
+ self.new_line.updatePath()
+ for k, v in op.items():
+ pointA = NodeItem.get_instances(i.name)
+ pointB = NodeItem.get_instances(v.name)
+ socketA = next(s for s in pointA.output if k == s.id)
+ rect = socketA.boundingRect()
+ pointAA = QtCore.QPointF(rect.x() + rect.width()/(2), rect.y() + rect.height()/(2))
+ pointAA = socketA.mapToScene(pointAA)
+ rectB = pointB.input[0].boundingRect()
+ pointBB = QtCore.QPointF(rectB.x() + rectB.width()/(2), rectB.y() + rectB.height()/(2))
+ pointBB = pointB.input[0].mapToScene(pointBB)
+ self.new_line = NodeLine(pointAA, pointBB, 'out')
+ self.new_line.source = socketA
+ self.new_line.target = pointB.input[0]
+ socketA.out_lines.append(self.new_line)
+ pointB.input[0].in_lines.append(self.new_line)
+ socketA.other_line = self.new_line
+ pointB.input[0].other_line = self.new_line
+ self.scene.addItem(self.new_line)
+ self.new_line.updatePath()
+
+
+class NodeLine(QtWidgets.QGraphicsPathItem):
+ def __init__(self, pointA, pointB , socket):
+ super(NodeLine, self).__init__()
+ self._pointA = pointA
+ self._pointB = pointB
+ self.socket = socket
+ self._source = None
+ self._target = None
+ self.setZValue(-1)
+ self.setBrush(QtGui.QColor(0,70,70,120))
+ self.pen = QtGui.QPen()
+ self.pen.setStyle(QtCore.Qt.SolidLine)
+ self.pen.setWidth(2)
+ self.pen.setColor(QtGui.QColor(0,70,70,220))
+ self.setPen(self.pen)
+
+ def updatePath(self):
+
+ if (self._pointB.x() - self._pointA.x()) < 30:
+ path = QtGui.QPainterPath()
+ midptx = (self.pointA.x() + 13)
+
+ ctrl1_1 = QtCore.QPointF(self.pointA.x(), self.pointA.y())
+ ctrl2_1 = QtCore.QPointF(self.pointA.x(), self.pointA.y())
+ pt1 = QtCore.QPointF(midptx , self.pointA.y())
+ path.moveTo(pt1)
+ path.cubicTo(ctrl1_1, ctrl2_1, pt1)
+
+ if abs(self.pointB.x()-midptx) > 150:
+ ctrl1_2 = QtCore.QPointF(midptx, self.pointA.y())
+ ctrl2_2 = QtCore.QPointF(midptx, self.pointA.y())
+ pt2 = QtCore.QPointF(midptx , self.pointA.y()+100)
+ path.cubicTo(ctrl1_2, ctrl2_2, pt2)
+ path.moveTo(pt2)
+
+ ctrl1_3 = QtCore.QPointF(midptx, self.pointA.y()+100)
+ ctrl2_3 = QtCore.QPointF(midptx, self.pointA.y()+100)
+ pt3 = QtCore.QPointF(self.pointB.x()-13, self.pointA.y()+100)
+ path.cubicTo(ctrl1_3, ctrl2_3, pt3)
+ path.moveTo(pt3)
+
+ ctrl1_4 = QtCore.QPointF(self.pointB.x()-13, self.pointA.y()+100)
+ ctrl2_4 = QtCore.QPointF(self.pointB.x()-13, self.pointA.y()+100)
+ pt4 = QtCore.QPointF(self.pointB.x()-13, self.pointB.y())
+ path.cubicTo(ctrl1_4, ctrl2_4, pt4)
+ path.moveTo(pt4)
+
+ ctrl1_5 = QtCore.QPointF(self.pointB.x()-13, self.pointB.y())
+ ctrl2_5 = QtCore.QPointF(self.pointB.x()-13, self.pointB.y())
+ pt5 = QtCore.QPointF(self.pointB.x(), self.pointB.y())
+ path.cubicTo(ctrl1_5, ctrl2_5, pt5)
+ path.moveTo(pt5)
+
+ self.setPath(path)
+ return
+ else:
+ ctrl1_2 = QtCore.QPointF(midptx, self.pointA.y())
+ ctrl2_2 = QtCore.QPointF(midptx, self.pointA.y())
+ pt2 = QtCore.QPointF(midptx , max(self.pointB.y(), self.pointA.y())-(abs(self.pointA.y()-self.pointB.y())/2))
+ path.cubicTo(ctrl1_2, ctrl2_2, pt2)
+ path.moveTo(pt2)
+
+ ctrl1_3 = QtCore.QPointF(midptx, max(self.pointB.y(), self.pointA.y())-(abs(self.pointA.y()-self.pointB.y())/2))
+ ctrl2_3 = QtCore.QPointF(midptx, max(self.pointB.y(), self.pointA.y())-(abs(self.pointA.y()-self.pointB.y())/2))
+ pt3 = QtCore.QPointF(self.pointB.x()-13, max(self.pointB.y(), self.pointA.y())-(abs(self.pointA.y()-self.pointB.y())/2))
+ path.cubicTo(ctrl1_3, ctrl2_3, pt3)
+ path.moveTo(pt3)
+
+ ctrl1_4 = QtCore.QPointF(self.pointB.x()-13, max(self.pointB.y(), self.pointA.y())-(abs(self.pointA.y()-self.pointB.y())/2))
+ ctrl2_4 = QtCore.QPointF(self.pointB.x()-13, max(self.pointB.y(), self.pointA.y())-(abs(self.pointA.y()-self.pointB.y())/2))
+ pt4 = QtCore.QPointF(self.pointB.x()-13, self.pointB.y())
+ path.cubicTo(ctrl1_4, ctrl2_4, pt4)
+ path.moveTo(pt4)
+
+ ctrl1_5 = QtCore.QPointF(self.pointB.x()-13, self.pointB.y())
+ ctrl2_5 = QtCore.QPointF(self.pointB.x()-13, self.pointB.y())
+ pt5 = QtCore.QPointF(self.pointB.x(), self.pointB.y())
+ path.cubicTo(ctrl1_5, ctrl2_5, pt5)
+ path.moveTo(pt5)
+
+ self.setPath(path)
+ return
+
+ path = QtGui.QPainterPath()
+ path.moveTo(self.pointA)
+ midptx = 0.5*(self.pointA.x() + self.pointB.x())
+
+ ctrl1_1 = QtCore.QPointF(self.pointA.x(), self.pointA.y())
+ ctrl2_1 = QtCore.QPointF(self.pointA.x(), self.pointA.y())
+ pt1 = QtCore.QPointF(midptx , self.pointA.y())
+ path.cubicTo(ctrl1_1, ctrl2_1, pt1)
+ path.moveTo(pt1)
+
+ ctrl1_2 = QtCore.QPointF(midptx, self.pointA.y())
+ ctrl2_2 = QtCore.QPointF(midptx, self.pointA.y())
+ pt2 = QtCore.QPointF(midptx , self.pointB.y())
+ path.cubicTo(ctrl1_2, ctrl2_2, pt2)
+ path.moveTo(pt2)
+
+ ctrl1_3 = QtCore.QPointF(midptx, self.pointB.y())
+ ctrl2_3 = QtCore.QPointF(midptx, self.pointB.y())
+ path.cubicTo(ctrl1_3, ctrl2_3, self.pointB)
+ path.moveTo(self.pointB)
+ self.setPath(path)
+
+ def paint(self, painter, option, widget):
+ painter.setPen(self.pen)
+ painter.drawPath(self.path())
+
+ @property
+ def pointA(self):
+ return self._pointA
+
+ @pointA.setter
+ def pointA(self, point):
+ self._pointA = point
+ self.updatePath()
+
+ @property
+ def pointB(self):
+ return self._pointB
+
+ @pointB.setter
+ def pointB(self, point):
+ self._pointB = point
+ self.updatePath()
+
+ @property
+ def source(self):
+ return self._source
+
+ @source.setter
+ def source(self, widget):
+ self._source = widget
+
+ @property
+ def target(self):
+ return self._target
+
+ @target.setter
+ def target(self, widget):
+ self._target = widget
+
+ def __delete__(self,instance):
+ del self._source
+ del self._target
+ del self._pointA
+ del self._pointB
+
+class NodeSocket(QtWidgets.QGraphicsItem):
+ def __init__(self, rect, parent, socketType, id):
+ super(NodeSocket, self).__init__(parent)
+ self.rect = rect
+ self.type = socketType
+ self.parent=parent
+ self.id = id
+ self.setAcceptHoverEvents(True)
+ self.new_line=None
+ self.other_line=None
+
+ # Brush
+ self.brush = QtGui.QBrush(Qt.transparent)
+ # Pen
+ self.pen = QtGui.QPen(Qt.NoPen)
+
+ # Lines
+ self.out_lines = []
+ self.in_lines = []
+
+ def shape(self):
+ path = QtGui.QPainterPath()
+ path.addEllipse(self.boundingRect())
+ return path
+
+ def boundingRect(self):
+ return QtCore.QRectF(self.rect)
+
+ def paint(self, painter, option, widget):
+
+ painter.setPen(self.pen)
+ painter.drawEllipse(self.rect.x(),self.rect.y(),self.rect.height(),self.rect.width())
+ painter.setBrush(self.brush)
+ painter.drawEllipse(self.rect.x()+2,self.rect.y()+2,(self.rect.height()/3)*2,(self.rect.width()/3)*2)
+
+ def mousePressEvent(self, event):
+ cursor = QCursor( Qt.ArrowCursor )
+ QApplication.instance().setOverrideCursor(cursor)
+
+ if self.type == 'op'and len(self.out_lines) == 0:
+ rect = self.boundingRect()
+ pointA = QtCore.QPointF(rect.x() + rect.width()/(2), rect.y() + rect.height()/(2))
+ pointA = self.mapToScene(pointA)
+ pointB = self.mapToScene(event.pos())
+ self.new_line = NodeLine(pointA, pointB ,'op')
+ self.out_lines.append(self.new_line)
+ self.scene().addItem(self.new_line)
+ elif self.type == 'in' and len(self.in_lines) == 0:
+ rect = self.boundingRect()
+ pointA = self.mapToScene(event.pos())
+ pointB = QtCore.QPointF(rect.x() + rect.width()/(2), rect.y() + rect.height()/(2))
+ pointB = self.mapToScene(pointB)
+ self.new_line = NodeLine(pointA, pointB, 'in')
+ self.in_lines.append(self.new_line)
+ self.scene().addItem(self.new_line)
+ else:
+ super(NodeSocket, self).mousePressEvent(event)
+
+ def mouseMoveEvent(self, event):
+
+ if self.type == 'op':
+ item = self.scene().itemAt(event.scenePos().toPoint(),QtGui.QTransform())
+ if(isinstance(item,NodeSocket)):
+ QApplication.instance().setOverrideCursor(QCursor( Qt.PointingHandCursor))
+ else:
+ QApplication.instance().restoreOverrideCursor()
+ QApplication.instance().setOverrideCursor(QCursor( Qt.ArrowCursor))
+ pointB = self.mapToScene(event.pos())
+ self.new_line.pointB = pointB
+ if self.other_line:
+ self.other_line.pointB=pointB
+ elif self.type == 'in':
+ pointA = self.mapToScene(event.pos())
+ self.new_line.pointA = pointA
+ if self.other_line:
+ self.other_line.pointA=pointA
+ else:
+ super(NodeSocket, self).mouseMoveEvent(event)
+
+ def mouseReleaseEvent(self, event):
+ cursor = QCursor( Qt.ArrowCursor )
+ QApplication.instance().setOverrideCursor(cursor)
+
+ item = self.scene().itemAt(event.scenePos().toPoint(),QtGui.QTransform())
+ stm = ['MaterialStream','EngStm']
+ item.other_line=self.new_line
+ if self.type == 'op' and item.type == 'in' and len(item.in_lines) == 0:
+ self.new_line.source = self
+ self.new_line.target = item
+ item.in_lines.append(self.new_line)
+ self.new_line.pointB = item.get_center()
+ #print(type(self.new_line.source))
+ if self.new_line.source.parent.obj.type not in stm:
+ self.new_line.source.parent.obj.add_connection(0, self.new_line.source.id, self.new_line.target.parent.obj)
+ if self.new_line.target.parent.obj.type not in stm:
+ self.new_line.target.parent.obj.add_connection(1, self.new_line.target.id, self.new_line.source.parent.obj) # Input stream if flag is 1
+
+ sc = self.new_line.source.parent
+ tg = self.new_line.target.parent
+ if(sc.obj.type == 'MaterialStream'):
+ sc_no_input_lines = len(sc.input[0].in_lines)
+ if(sc_no_input_lines > 0):
+ sc.obj.disableInputDataTab(sc.dock_widget)
+ if(tg.obj.type == 'MaterialStream'):
+ tg_no_input_lines = len(tg.input[0].in_lines)
+ if(tg_no_input_lines > 0):
+ tg.obj.disableInputDataTab(tg.dock_widget)
+
+ elif self.type =='in' and item.type == 'op' and len(item.out_lines) == 0:
+ self.new_line.source = item
+ self.new_line.target = self
+ item.out_lines.append(self.new_line)
+ self.new_line.pointA = item.get_center()
+ #print(type(self.new_line.source))
+ if self.new_line.source.parent.obj.type not in stm:
+ self.new_line.source.parent.obj.add_connection(0, self.new_line.source.id, self.new_line.target.parent.obj)
+ if self.new_line.target.parent.obj.type not in stm:
+ self.new_line.target.parent.obj.add_connection(1, self.new_line.target.id, self.new_line.source.parent.obj)
+
+ sc = self.new_line.source.parent
+ tg = self.new_line.target.parent
+ if(sc.obj.type == 'MaterialStream'):
+ sc_no_input_lines = len(sc.input[0].in_lines)
+ if(sc_no_input_lines > 0):
+ sc.obj.disableInputDataTab(sc.dock_widget)
+ if(tg.obj.type == 'MaterialStream'):
+ tg_no_input_lines = len(tg.input[0].in_lines)
+ if(tg_no_input_lines > 0):
+ tg.obj.disableInputDataTab(tg.dock_widget)
+
+ else:
+ self.scene().removeItem(self.new_line)
+ if(self.new_line in self.in_lines):
+ self.in_lines.remove(self.new_line)
+ if(self.new_line in self.out_lines):
+ self.out_lines.remove(self.new_line)
+ del self.new_line
+ super(NodeSocket, self).mouseReleaseEvent(event)
+
+ try:
+ data = get_last_list('Undo')
+ comp_selected = data[-1]
+ data.remove(comp_selected)
+ for i in range(len(data)):
+ if data[i].name == self.new_line.source.parent.obj.name:
+ data[i] = self.new_line.source.parent.obj
+ elif data[i].name == self.new_line.target.parent.obj.name:
+ data[i] = self.new_line.target.parent.obj
+ data.append(comp_selected)
+ push('Undo', data)
+ except Exception as e:
+ print(e)
+
+ def get_center(self):
+ rect = self.boundingRect()
+ center = QtCore.QPointF(rect.x() + rect.width()/(2), rect.y() + rect.height()/(2))
+ center = self.mapToScene(center)
+ return center
+
+ def hoverEnterEvent(self, event):
+ cursor = QCursor( Qt.PointingHandCursor)
+ QApplication.instance().setOverrideCursor(cursor)
+
+ def hoverLeaveEvent(self, event):
+ cursor = QCursor( Qt.ArrowCursor )
+ QApplication.instance().setOverrideCursor(cursor)
+
+ def show(self):
+ # set pen to show
+ self.pen = QPen(QtGui.QColor(0,70,70,220), 1, Qt.SolidLine)
+ self.brush = QBrush(QtGui.QColor(140,199,198,255))
+
+ def hide(self):
+ # set pen to transparent
+ self.pen = QPen(Qt.NoPen)
+ self.brush = QBrush(Qt.transparent)
+
+# all created node items will be put inside this list
+# it is used for recreating the node lines by returning the node item object based on unit operation object's name
+lst = []
+dock_widget_lst = []
+stack = []
+
+class NodeItem(QtWidgets.QGraphicsItem):
+
+ @staticmethod
+ def get_instances(namee):
+ for i in lst:
+ if i.name == namee:
+ return i
+
+ @staticmethod
+ def get_dock_widget():
+ return dock_widget_lst
+
+ def __init__(self,unit_operation, container, graphicsView):
+ l = ['Splitter','Mixer', 'DistillationColumn', 'Flash', 'CompoundSeparator', 'ShortcutColumn']
+ stm = ['MaterialStream', 'EnergyStream']
+ super(NodeItem, self).__init__()
+ self.obj = unit_operation
+ self.container = container
+ self.graphicsView = graphicsView
+ self.setAcceptHoverEvents(True)
+ self.name = self.obj.name
+ self.type = self.obj.type
+ self.ok = True
+ if (self.obj.modes_list):
+ default_tooltip = f"{self.name}\n\n"
+ default_tooltip_dict = self.obj.param_getter_tooltip(self.obj.mode)
+ for i, j in default_tooltip_dict.items():
+ if j is not None:
+ default_tooltip = default_tooltip + f" {i} : {j}\n"
+ self.setToolTip(default_tooltip)
+
+ if self.obj.type == 'Mixer' and not self.obj.saved:
+ combob_values = map(str,list(range(2,5)))
+ text, self.ok = QInputDialog.getItem(self.container.graphicsView, 'Mixer', 'Select number of inputs:',
+ combob_values, False)
+
+ if self.ok:
+ self.nin = int(text)
+ self.obj.no_of_inputs = self.nin
+ self.obj.variables['NI']['value'] = self.nin
+
+ elif self.obj.type == 'DistillationColumn'and not self.obj.saved:
+ combob_values = map(str,list(range(1,9)))
+ text, self.ok = QInputDialog.getItem(self.container.graphicsView, 'DistillationColumn', 'Select number of input(s):',
+ combob_values, False)
+
+ if self.ok:
+ self.nin = int(text)
+ self.obj.no_of_inputs = self.nin
+ self.obj.variables['Ni']['value'] = self.nin
+
+ self.nin = self.obj.no_of_inputs
+ self.nop = self.obj.no_of_outputs
+
+ self.dock_widget = None
+ lst.append(self)
+ if self.obj.type in l:
+ self.dock_widget = eval("DockWidget"+self.obj.type)(self.obj.name,self.obj.type,self.obj,self.container)
+ elif self.obj.type in stm:
+ self.dock_widget = eval("DockWidget"+self.obj.type)(self.obj.name,self.obj.type,self.obj,self.container)
+ elif self.obj.type == "AdiabaticCompressor" or self.obj.type == "AdiabaticExpander":
+ self.dock_widget = eval("DockWidgetCompressorExpander")(self.obj.name,self.obj.type,self.obj,self.container)
+ else:
+ self.dock_widget = DockWidget(self.obj.name,self.obj.type,self.obj,self.container)
+ dock_widget_lst.append(self.dock_widget)
+ self.main_window= findMainWindow(self)
+ self.dock_widget.setFixedWidth(360)
+ self.dock_widget.setFixedHeight(640)
+ self.dock_widget.DockWidgetFeature(QDockWidget.AllDockWidgetFeatures)
+ self.main_window.addDockWidget(Qt.LeftDockWidgetArea, self.dock_widget)
+
+ # updating input values
+ if self.dock_widget.obj.type != 'MaterialStream':
+ pass
+ try:
+ self.dock_widget.obj.param_setter(self.dock_widget.obj.param_getter(self.dock_widget.obj.mode))
+ except Exception as e:
+ print(e)
+ # self.dock_widget.param()
+
+ self.dock_widget.hide()
+
+ self.pic=QtGui.QPixmap(parentPath+"/resources/base/Icons/"+self.type+".png")
+ self.rect = QtCore.QRect(0,0,self.pic.width(),self.pic.height())
+ self.text = QGraphicsTextItem(self)
+ f = QFont()
+ f.setPointSize(8)
+ self.text.setFont(f)
+ self.text.setDefaultTextColor(QtGui.QColor(0,70,70,220))
+ self.text.setParentItem(self)
+ self.text.setPos(self.rect.width()-(self.rect.width()*0.9), self.rect.height())
+ self.text.setPlainText(self.name)
+
+ self.setFlag(QtWidgets.QGraphicsPixmapItem.ItemIsMovable)
+ self.setFlag(QtWidgets.QGraphicsPixmapItem.ItemIsSelectable)
+ self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
+
+ # Brush
+ self.brush = QtGui.QBrush()
+ self.brush.setStyle(QtCore.Qt.SolidPattern)
+ self.brush.setColor(QtGui.QColor(80,0,90,255))
+ # Pen
+ self.pen = QtGui.QPen()
+ self.pen.setStyle(QtCore.Qt.SolidLine)
+ self.pen.setWidth(1)
+ self.pen.setColor(QtGui.QColor(20,20,20,255))
+
+ self.sel_pen = QtGui.QPen()
+ self.sel_pen.setStyle(QtCore.Qt.SolidLine)
+ self.sel_pen.setWidth(1)
+ self.sel_pen.setColor(QtGui.QColor(220,220,220,255))
+
+ # initializing the node sockets
+ self.input , self.output = self.initialize_sockets(self.type)
+
+ def shape(self):
+ path = QtGui.QPainterPath()
+ path.addRect(self.boundingRect())
+ return path
+
+ def boundingRect(self):
+ return QtCore.QRectF(self.rect)
+
+ def paint(self, painter, option, widget):
+ if self.isSelected():
+ painter.setPen(self.sel_pen)
+ painter.drawRect(QtCore.QRectF(self.rect))
+ else:
+ painter.setPen(self.pen)
+ painter.drawPixmap(self.rect,self.pic)
+
+ def initialize_sockets(self,type):
+ if(self.type=="Flash" or self.type=="CompoundSeparator"):
+ input = [NodeSocket(QtCore.QRect(1,(self.rect.height()*x/(self.nin+1)-6),4*3,4*3), self, 'in', x) for x in range(1,self.nin+1) ]
+ output = [NodeSocket(QtCore.QRect(self.rect.width()-13,(self.rect.height()*x*1/(self.nop+1))-4,4*3,4*3), self, 'op', x) for x in range(1,self.nop+1)]
+ return input,output
+ elif(self.type=="AdiabaticCompressor" or self.type=="AdiabaticExpander" or self.type =="Mixer" or self.type =="Splitter" or self.type =="Valve" ):
+ input = [NodeSocket(QtCore.QRect(-6.5, (self.rect.height()*x/(self.nin+1))-6,4*3,4*3), self, 'in', x) for x in range(1,self.nin+1) ]
+ output = [NodeSocket(QtCore.QRect(self.rect.width()-6.5,(self.rect.height()*x/(self.nop+1))-6,4*3,4*3), self, 'op', x) for x in range(1,self.nop+1)]
+ return input,output
+ elif(self.type=="Cooler" or self.type=="Heater"):
+ input = [NodeSocket(QtCore.QRect(-0.5, (self.rect.height()*x/(self.nin+1))-6,4*3,4*3), self, 'in', x) for x in range(1,self.nin+1) ]
+ output = [NodeSocket(QtCore.QRect(self.rect.width()-12.0,(self.rect.height()*x/(self.nop+1))-6,4*3,4*3), self, 'op', x) for x in range(1,self.nop+1)]
+ return input,output
+ elif(self.type=="CentrifugalPump"):
+ input = [NodeSocket(QtCore.QRect(-6.5,(self.rect.height()*x/(self.nin+1))-11, 4*3,4*3), self, 'in', x) for x in range(1,self.nin+1) ]
+ output = [NodeSocket(QtCore.QRect(self.rect.width()-6.5,-5.5,4*3,4*3), self, 'op', x) for x in range(1,self.nop+1)]
+ return input,output
+ elif(self.type=="DistillationColumn" or self.type=="ShortcutColumn"):
+ input = [NodeSocket(QtCore.QRect(-6.5,(self.rect.height()*x/(self.nin+1)-4),4*3,4*3), self, 'in', x) for x in range(1,self.nin+1) ]
+ output = [NodeSocket(QtCore.QRect(self.rect.width()-9.5,(self.rect.height()*1.44*x/(self.nop+1))-59,4*3,4*3), self, 'op', x) for x in range(1,self.nop+1)]
+ return input,output
+ elif(self.type=="MaterialStream"):
+ input = [NodeSocket(QtCore.QRect(-6.5,(self.rect.height()*x/(self.nin+1)-6),4*3,4*3), self, 'in', x) for x in range(1,self.nin+1) ]
+ output = [NodeSocket(QtCore.QRect(self.rect.width()-6.5,(self.rect.height()*x/(self.nin+1)-6),4*3,4*3), self, 'op', x) for x in range(1,self.nop+1)]
+ return input,output
+
+ def mouseMoveEvent(self, event):
+ super(NodeItem, self).mouseMoveEvent(event)
+ items = self.graphicsView.items()
+ for i in items:
+ if(type(i) == NodeItem):
+ for op in i.output:
+ for line in op.out_lines:
+ line.pointA = line.source.get_center()
+ line.pointB = line.target.get_center()
+ for ip in i.input:
+ for line in ip.in_lines:
+ line.pointA = line.source.get_center()
+ line.pointB = line.target.get_center()
+ self.pos = event.scenePos()
+ self.obj.set_pos(self.pos)
+
+ def mouseDoubleClickEvent(self, event):
+
+ self.graphicsView.horizontalScrollBarVal = self.graphicsView.horizontalScrollBar().value()
+ self.graphicsView.setInteractive(False)
+ if len(stack):
+ stack[-1].hide()
+ self.dock_widget.show()
+ stack.append(self.dock_widget)
+ self.graphicsView.setInteractive(True)
+
+ def update_tooltip(self):
+ default_tooltip = f"{self.name}\n\n"
+ default_tooltip_dict = self.obj.param_getter_tooltip(self.obj.mode)
+ for i, j in default_tooltip_dict.items():
+ if j is not None:
+ default_tooltip = default_tooltip + f" {i} : {j}\n"
+ self.setToolTip(default_tooltip)
+
+ def update_tooltip_selectedVar(self):
+ default_tooltip = f"{self.name}\n\n"
+ default_tooltip_dict = self.obj.param_getter_tooltip_selectedVar()
+ for i, j in default_tooltip_dict.items():
+ if j is not None:
+ default_tooltip = default_tooltip + f" {i} : {j}\n"
+ self.setToolTip(default_tooltip)
+
+ def update_compounds(self):
+ try:
+ self.obj.update_compounds()
+ self.dock_widget.update_compounds()
+ except AttributeError:
+ pass
+
+ def hoverEnterEvent(self, event):
+ super(NodeItem,self).hoverEnterEvent(event)
+ for i in self.graphicsView.items():
+ if(isinstance(i,NodeItem)):
+ for ip in i.input:
+ ip.show()
+ for op in i.output:
+ op.show()
+
+ def hoverLeaveEvent(self, event):
+ super(NodeItem,self).hoverLeaveEvent(event)
+ for i in self.graphicsView.items():
+ if(isinstance(i,NodeItem)):
+ for ip in i.input:
+ ip.hide()
+ for op in i.output:
+ op.hide()
+
+ def itemChange(self, change, value):
+ newPos = value
+ if change == self.ItemPositionChange and self.scene():
+ rect = self.container.graphicsView.sceneRect()
+ width = self.boundingRect().width()
+ height = self.boundingRect().height()
+ eWH1 = QPointF(newPos.x()+width,newPos.y()+height)
+ eWH2 = QPointF(newPos.x()-width,newPos.y()-height)
+ if not rect.__contains__(eWH1) or not rect.__contains__(eWH2) :
+ newPos.setX(min(rect.right()-width-40, max(newPos.x(), rect.left())))
+ newPos.setY(min(rect.bottom()-height-35, max(newPos.y(), rect.top())))
+ self.obj.set_pos(newPos)
+ return super(NodeItem,self).itemChange(change, newPos)
+
+def findMainWindow(self):
+ '''
+ Global function to find the (open) QMainWindow in application
+ '''
+ app = QApplication.instance()
+ for widget in app.topLevelWidgets():
+ if isinstance(widget, QMainWindow):
+ return widget
+ return None
diff --git a/src/main/python/utils/Streams.py b/src/main/python/utils/Streams.py
new file mode 100644
index 0000000..fa557e6
--- /dev/null
+++ b/src/main/python/utils/Streams.py
@@ -0,0 +1,476 @@
+import json
+import sys,os
+
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+from PyQt5.QtCore import *
+from python.utils.ComponentSelector import compound_selected
+
+class MaterialStream():
+ counter = 1
+ def __init__(self, compound_names = []):
+
+ self.name = 'MaterialStream' + str(MaterialStream.counter)
+ self.type = 'MaterialStream'
+
+ self.compound_names = compound_names
+ self.count = MaterialStream.counter
+ self.thermo_package ="RaoultsLaw"
+ self.mode1 = "P"
+ self.mode2 = "T"
+
+ self.mode1_val = ""
+ self.mode2_val = ""
+ self.OM_data_init = ''
+ self.OM_data_eqn = ''
+ self.no_of_inputs = 1
+ self.no_of_outputs = 1
+ self.x = 2500-30
+ self.y = 2500-30
+ self.pos = QPointF(self.x, self.y)
+ MaterialStream.counter+=1
+ self.start_dict = {}
+ self.eqn_dict = {}
+ self.modes_list = ["PT", "PH", "PVF", "TVF", "PS"]
+ self.saved = False
+ self.mode = self.modes_list[0]
+
+ self.variables = {
+ 'P' : {'name':'Pressure', 'value':101325, 'unit':'Pa'},
+ 'T' : {'name':'Temperature', 'value':300, 'unit':'K'},
+
+ 'xvap' : {'name':'Vapour Mole Fraction', 'value':None, 'unit':''},
+ 'H_p[1]' : {'name':'Mixture Molar Enthalpy', 'value':None, 'unit':'J/mol'},
+ 'S_p[1]' : {'name':'Mixture Molar Entropy', 'value':None, 'unit':'J/mol.K'},
+ 'F_p[1]' : {'name':'Mixture Molar Flow', 'value':100, 'unit':'mol/s'},
+ 'Fm_p[1]' : {'name':'Mixture Mass Flow', 'value':None, 'unit':'g/s'},
+
+ 'H_p[2]' : {'name':'Liquid Molar Enthalpy', 'value':None, 'unit':'J/mol'},
+ 'S_p[2]' : {'name':'Liquid Molar Entropy', 'value':None, 'unit':'J/mol.K'},
+ 'F_p[2]' : {'name':'Liquid Molar Flow', 'value':None, 'unit':'mol/s'},
+
+ 'H_p[3]' : {'name':'Vapour Molar Enthalpy', 'value':None, 'unit':'J/mol'},
+ 'S_p[3]' : {'name':'Vapour Molar Entropy', 'value':None, 'unit':'J/mol.K'},
+ 'F_p[3]' : {'name':'Vapour Molar Flow', 'value':None, 'unit':'mol/s'},
+
+ 'x_pc' : {'name':'Mole Fraction', 'value':[], 'unit':''},
+ 'xm_pc' : {'name':'Mass Fraction', 'value':None, 'unit':''},
+
+ 'F_pc' : {'name':'Mole Flow', 'value':100, 'unit':'mol/s'},
+ 'Fm_pc' : {'name':'Mass Flow', 'value':None, 'unit':'g/s'},
+ }
+ self.init_variables()
+
+ def update_compounds(self):
+ self.compound_names = compound_selected
+
+ def init_variables(self):
+ Nc = len(self.compound_names)
+ for i, val in enumerate(self.compound_names):
+ self.variables['x_pc[1,'+ str(i+1)+']'] = {'name':val + ' Mixture Mole Fraction', 'value':round(1/Nc,4), 'unit':''}
+ self.variables['xm_pc[1,'+ str(i+1)+']'] = {'name':val + ' Mixture Mass Fraction', 'value':None, 'unit':''}
+ self.variables['F_pc[1,'+ str(i+1)+']'] = {'name':val + ' Mixture Mole Flow', 'value':None, 'unit':'mol/s'}
+ self.variables['Fm_pc[1,'+ str(i+1)+']'] = {'name':val + ' Mixture Mass Flow', 'value':None, 'unit':'g/s'}
+
+ self.variables['x_pc[2,'+ str(i+1)+']'] = {'name':[val + ' Liquid Mole Fraction'], 'value':None, 'unit':''}
+ self.variables['xm_pc[2,'+ str(i+1)+']'] = {'name':[val + ' Liquid Mass Fraction'], 'value':None, 'unit':''}
+ self.variables['F_pc[2,'+ str(i+1)+']'] = {'name':[val + ' Liquid Mole Flow'], 'value':None, 'unit':'mol/s'}
+ self.variables['Fm_pc[2,'+ str(i+1)+']'] = {'name':[val + ' Liquid Mass Flow'], 'value':None, 'unit':'g/s'}
+
+ self.variables['x_pc[3,'+ str(i+1)+']'] = {'name':[val + ' Vapour Mole Fraction'], 'value':None, 'unit':''}
+ self.variables['xm_pc[3,'+ str(i+1)+']'] = {'name':[val + ' Vapour Mass Fraction'], 'value':None, 'unit':''}
+ self.variables['F_pc[3,'+ str(i+1)+']'] = {'name':[val + ' Vapour Mole Flow'], 'value':None, 'unit':'mol/s'}
+ self.variables['Fm_pc[3,'+ str(i+1)+']'] = {'name':[val + ' Vapour Mass Flow'], 'value':None, 'unit':'g/s'}
+
+ for i in self.compound_names:
+ self.variables[i] = {'value':''}
+
+ def param_getter_tooltip(self,mode):
+ dict = {}
+
+ temp = []
+ for i, val in enumerate(self.compound_names):
+ try:
+ temp.append(self.variables['x_pc[1,' + str(i+1) + ']']['value'])
+ except:
+ pass
+ self.variables['x_pc']['value'] = temp
+
+ if(mode=="PT"):
+ self.mode1 = 'P'
+ self.mode2 = 'T'
+ mode1_n = self.variables['P']['name']
+ mode2_n = self.variables['T']['name']
+ dict = {mode1_n:str(self.variables['P']['value'])+' '+self.variables['P']['unit'],
+ mode2_n:str(self.variables['T']['value'])+' '+self.variables['T']['unit']}
+ elif(mode=="PH"):
+ self.mode1 = 'P'
+ self.mode2 = 'H_p[1]'
+ mode1_n = self.variables['P']['name']
+ mode2_n = self.variables['H_p[1]']['name']
+
+ dict = {mode1_n:str(self.variables['P']['value'])+' '+self.variables['P']['unit'],
+ mode2_n:str(self.variables['H_p[1]']['value'])+' '+self.variables['H_p[1]']['unit']}
+ elif(mode=="PVF"):
+ self.mode1 = 'P'
+ self.mode2 = 'xvap'
+ mode1_n = self.variables['P']['name']
+ mode2_n = self.variables['xvap']['name']
+
+ dict = {mode1_n:str(self.variables['P']['value'])+' '+self.variables['P']['unit'],
+ mode2_n:str(self.variables['xvap']['value'])+' '+self.variables['xvap']['unit']}
+ elif(mode=="TVF"):
+ self.mode1 = 'T'
+ self.mode2 = 'xvap'
+ mode1_n = self.variables['T']['name']
+ mode2_n = self.variables['xvap']['name']
+ dict = {mode1_n:str(self.variables['T']['value'])+' '+self.variables['T']['unit'],
+ mode2_n:str(self.variables['xvap']['value'])+' '+self.variables['xvap']['unit']}
+
+ elif(mode=="PS"):
+ self.mode1 = 'P'
+ self.mode2 = 'S_p[1]'
+ mode1_n = self.variables['P']['name']
+ mode2_n = self.variables['S_p[1]']['name']
+
+ dict = {mode1_n:str(self.variables['P']['value'])+' '+self.variables['P']['unit'],
+ mode2_n:str(self.variables['S_p[1]']['value'])+' '+self.variables['S_p[1]']['unit']}
+
+ dict['Mole Flow'] = str(self.variables['F_p[1]']['value'])+' '+self.variables['F_p[1]']['unit']
+ dict[self.variables['x_pc']['name']] = str(self.variables['x_pc']['value'])+' '+self.variables['x_pc']['unit']
+ dict['Thermo Package'] = self.thermo_package
+ return dict
+
+ def param_getter_tooltip_selectedVar(self):
+ dict = {}
+
+ pressure_name = self.variables['P']['name']
+ pressure_val = self.variables['P']['value']
+ pressure_unit = self.variables['P']['unit']
+ temp_name = self.variables['T']['name']
+ temp_val = self.variables['T']['value']
+ temp_unit = self.variables['T']['unit']
+ mixMolEntal_name = self.variables['H_p[1]']['name']
+ mixMolEntal_val = self.variables['H_p[1]']['value']
+ if mixMolEntal_val != None:
+ mixMolEntal_val = round(float(self.variables['H_p[1]']['value']),4)
+ mixMolEntal_unit = self.variables['H_p[1]']['unit']
+ mixMolEntro_name = self.variables['S_p[1]']['name']
+ mixMolEntro_val = self.variables['S_p[1]']['value']
+ if mixMolEntro_val != None:
+ mixMolEntro_val = round(float(self.variables['S_p[1]']['value']),4)
+ mixMolEntro_unit = self.variables['S_p[1]']['unit']
+ vapMolFrac_name = self.variables['xvap']['name']
+ vapMolFrac_val = self.variables['xvap']['value']
+ vapMolFrac_unit = self.variables['xvap']['unit']
+ mixMolFlo_name = self.variables['F_p[1]']['name']
+ mixMolFlo_val = self.variables['F_p[1]']['value']
+ mixMolFlo_unit = self.variables['F_p[1]']['unit']
+ mixMassFlo_name = self.variables['Fm_p[1]']['name']
+ mixMassFlo_val = self.variables['Fm_p[1]']['value']
+ if mixMassFlo_val != None:
+ mixMassFlo_val = round(float(self.variables['Fm_p[1]']['value']),4)
+ mixMassFlo_unit = self.variables['Fm_p[1]']['unit']
+
+ dict = {pressure_name:str(pressure_val)+' '+pressure_unit,
+ temp_name:str(temp_val)+' '+temp_unit,
+ vapMolFrac_name:str(vapMolFrac_val)+' '+vapMolFrac_unit,
+ mixMolEntal_name:str(mixMolEntal_val)+' '+mixMolEntal_unit,
+ mixMolEntro_name:str(mixMolEntro_val)+' '+mixMolEntro_unit,
+ mixMolFlo_name:str(mixMolFlo_val)+' '+mixMolFlo_unit,
+ mixMassFlo_name:str(mixMassFlo_val)+' '+mixMassFlo_unit}
+ return dict
+
+ def param_getter(self,mode):
+ dict = {}
+
+ temp = []
+ for i, val in enumerate(self.compound_names):
+ try:
+ temp.append(self.variables['x_pc[1,' + str(i+1) + ']']['value'])
+ except:
+ pass
+ self.variables['x_pc']['value'] = temp
+
+ pressure_val = self.variables['P']['value']
+ temp_val = self.variables['T']['value']
+ mixMolFlo_val = self.variables['F_p[1]']['value']
+ mixMolEntal_val = self.variables['H_p[1]']['value']
+ vapMolFrac_val = self.variables['xvap']['value']
+ mixMolEntro_val = self.variables['S_p[1]']['value']
+
+ if pressure_val != None:
+ pressure_val = round(float(self.variables['P']['value']),4)
+ if temp_val != None:
+ temp_val = round(float(self.variables['T']['value']),4)
+ if mixMolFlo_val != None:
+ mixMolFlo_val = round(float(self.variables['F_p[1]']['value']),4)
+ if mixMolEntal_val != None:
+ mixMolEntal_val = round(float(self.variables['H_p[1]']['value']),4)
+ if vapMolFrac_val != None:
+ vapMolFrac_val = round(float(self.variables['xvap']['value']),4)
+ if mixMolEntro_val != None:
+ mixMolEntro_val = round(float(self.variables['S_p[1]']['value']),4)
+ if(mode=="PT"):
+ self.mode1 = 'P'
+ self.mode2 = 'T'
+
+ dict = {self.mode1:pressure_val, self.mode2:temp_val,
+ "MolFlow":mixMolFlo_val,"x_pc":self.variables['x_pc']['value'],
+ "Thermo Package": self.thermo_package}
+ #print('dictionary is :' + str(dict))
+
+ elif(mode=="PH"):
+ self.mode1 = 'P'
+ self.mode2 = 'H_p[1]'
+ dict = {self.mode1:pressure_val, self.mode2:mixMolEntal_val,
+ "MolFlow":mixMolFlo_val, "x_pc":self.variables['x_pc']['value'],
+ "Thermo Package": self.thermo_package}
+ elif(mode=="PVF"):
+ self.mode1 = 'P'
+ self.mode2 = 'xvap'
+ dict = {self.mode1:pressure_val, self.mode2:vapMolFrac_val,
+ "MolFlow":mixMolFlo_val, "x_pc":self.variables['x_pc']['value'],
+ "Thermo Package": self.thermo_package}
+ elif(mode=="TVF"):
+ self.mode1 = 'T'
+ self.mode2 = 'xvap'
+ dict = {self.mode1:temp_val, self.mode2:vapMolFrac_val,
+ "MolFlow":mixMolFlo_val, "x_pc":self.variables['x_pc']['value'],
+ "Thermo Package": self.thermo_package}
+ elif(mode=="PS"):
+ self.mode1 = 'P'
+ self.mode2 = 'S_p[1]'
+ dict = {self.mode1:pressure_val, self.mode2: mixMolEntro_val,
+ "MolFlow":mixMolFlo_val, "x_pc":self.variables['x_pc']['value'],
+ "Thermo Package": self.thermo_package}
+
+ return dict
+
+ def param_setter(self,dict):
+ self.variables['x_pc']['value'] = dict['x_pc'].split(",")
+ #print('xpc is :' + str(self.variables['x_pc']['value']))
+ self.thermo_package = dict['Thermo Package']
+ self.variables['F_p[1]']['value'] = dict['MolFlow']
+ self.variables[self.mode1]['value'] = dict[self.mode1]
+ self.variables[self.mode2]['value'] = dict[self.mode2]
+
+ for i in range(len(self.compound_names)):
+ if self.variables['x_pc']['value'][i]:
+ self.variables['x_pc[1,'+str(i+1)+']']['value'] = self.variables['x_pc']['value'][i]
+ else:
+ self.variables['x_pc[1,'+str(i+1)+']']['value'] = None
+ self.variables['xm_pc[1,'+str(i+1)+']']['value'] = self.variables['xm_pc']['value']
+
+ self.variables['F_pc[1,'+str(i+1)+']']['value'] = None
+ self.variables['Fm_pc[1,'+str(i+1)+']']['value'] = None
+ for i in range(0,len(self.compound_names)):
+ self.variables['x_pc[2,'+str(i+1)+']']['value'] = None
+ self.variables['xm_pc[2,'+str(i+1)+']']['value'] = None
+ self.variables['F_pc[2,'+str(i+1)+']']['value'] = None
+ self.variables['Fm_pc[2,'+str(i+1)+']']['value'] = None
+
+ self.variables['x_pc[3,'+str(i+1)+']']['value'] = None
+ self.variables['xm_pc[3,'+str(i+1)+']']['value'] = None
+ self.variables['F_pc[3,'+str(i+1)+']']['value'] = None
+ self.variables['Fm_pc[3,'+str(i+1)+']']['value'] = None
+
+ def set_pos(self,pos):
+ self.pos = pos
+
+ def get_min_eqn_values(self):
+ x_pclist = []
+ for i in range(0,len(self.compound_names)):
+ x_pclist.append(self.variables['x_pc[1,'+str(i+1)+']']['value'])
+ x_pc = json.dumps(x_pclist)
+ x_pc = x_pc.replace('[','{')
+ x_pc = x_pc.replace(']','}')
+ x_pc = x_pc.replace('"','')
+
+ if self.variables[self.mode1]['value']:
+ self.eqn_dict[self.mode1] = self.variables[self.mode1]['value']
+ if self.variables[self.mode2]['value']:
+ self.eqn_dict[self.mode2] = self.variables[self.mode2]['value']
+ if self.variables['x_pc']['value']:
+ self.eqn_dict['x_pc[1,:]'] = x_pc
+ if self.variables['F_pc']['value']:
+ self.eqn_dict['F_p[1]'] = self.variables['F_p[1]']['value']
+
+ def get_start_values(self):
+ try:
+ if self.variables[self.mode1]['value']:
+ self.start_dict[self.mode1] = self.variables[self.mode1]['value']
+
+ if self.variables[self.mode2]['value']:
+ self.start_dict[self.mode2] = self.variables[self.mode2]['value']
+
+
+ if self.variables['x_pc[2,1]']['value'] != None:
+ x_pcarr = []
+ for i in range(1,4):
+ cmf = []
+ for j in range(1,len(self.compound_names)+1):
+ cmf.append(str(self.variables['x_pc['+str(i)+','+str(j)+']']['value']))
+ x_pcarr.append(cmf)
+ x_pcstr = json.dumps(x_pcarr)
+ x_pcstr = x_pcstr.replace('[','{')
+ x_pcstr = x_pcstr.replace(']','}')
+ x_pcstr = x_pcstr.replace('"','')
+ self.start_dict['x_pc'] = x_pcstr
+
+ if self.variables['xm_pc[2,1]']['value'] != None:
+ xm_pcarr = []
+ for i in range(1,4):
+ cmf = []
+ for j in range(1,len(self.compound_names)+1):
+ cmf.append(str(self.variables['xm_pc['+str(i)+','+str(j)+']']['value']))
+ xm_pcarr.append(cmf)
+ xm_pcstr = json.dumps(x_pcarr)
+ xm_pcstr = xm_pcstr.replace('[','{')
+ xm_pcstr = xm_pcstr.replace(']','}')
+ xm_pcstr = xm_pcstr.replace('"','')
+ self.start_dict['xm_pc'] = xm_pcstr
+
+ if self.variables['Fm_pc[2,1]']['value'] != None:
+ Fm_pcarr = []
+ for i in range(1,4):
+ cmf = []
+ for j in range(1,len(self.compound_names)+1):
+ cmf.append(str(self.variables['Fm_pc['+str(i)+','+str(j)+']']['value']))
+ Fm_pcarr.append(cmf)
+ Fm_pcstr = json.dumps(x_pcarr)
+ Fm_pcstr = Fm_pcstr.replace('[','{')
+ Fm_pcstr = Fm_pcstr.replace(']','}')
+ Fm_pcstr = Fm_pcstr.replace('"','')
+ self.start_dict['Fm_pc'] = Fm_pcstr
+
+ if self.variables['F_pc[2,1]']['value'] != None:
+ F_pcarr = []
+ for i in range(1,4):
+ cmf = []
+ for j in range(1,len(self.compound_names)+1):
+ cmf.append(str(self.variables['F_pc['+str(i)+','+str(j)+']']['value']))
+ F_pcarr.append(cmf)
+ F_pcstr = json.dumps(F_pcarr)
+ F_pcstr = F_pcstr.replace('[','{')
+ F_pcstr = F_pcstr.replace(']','}')
+ F_pcstr = F_pcstr.replace('"','')
+ self.start_dict['F_pc'] = F_pcstr
+
+ if self.variables['MW_p[2]']['value'] != None:
+ MW_pArr = []
+ for i in range(1,4):
+ MW_pArr.append(self.variables['MW_p['+str(i)+']']['value'])
+ MW_pStr = json.dumps(MW_pArr)
+ MW_pStr = MW_pStr.replace('[','{')
+ MW_pStr = MW_pStr.replace(']','}')
+ MW_pStr = MW_pStr.replace('"','')
+ self.start_dict['MW_p'] = MW_pStr
+
+ if self.variables['F_p[2]']['value'] != None:
+ F_pArr = []
+ for i in range(1,4):
+ F_pArr.append(self.variables['F_p['+str(i)+']']['value'])
+ F_pStr = json.dumps(F_pArr)
+ F_pStr = F_pStr.replace('[','{')
+ F_pStr = F_pStr.replace(']','}')
+ F_pStr = F_pStr.replace('"','')
+ self.start_dict['F_p'] = F_pStr
+
+ if self.variables['Cp_p[2]']['value'] != None:
+ Cp_pArr = []
+ for i in range(1,4):
+ Cp_pArr.append(self.variables['Cp_p['+str(i)+']']['value'])
+ Cp_pStr = json.dumps(Cp_pArr)
+ Cp_pStr = Cp_pStr.replace('[','{')
+ Cp_pStr = Cp_pStr.replace(']','}')
+ Cp_pStr = Cp_pStr.replace('"','')
+ self.start_dict['Cp_p'] = Cp_pStr
+
+ if self.variables['H_p[2]']['value'] != None:
+ H_pArr = []
+ for i in range(1,4):
+ H_pArr.append(self.variables['H_p['+str(i)+']']['value'])
+ H_pStr = json.dumps(H_pArr)
+ H_pStr = H_pStr.replace('[','{')
+ H_pStr = H_pStr.replace(']','}')
+ H_pStr = H_pStr.replace('"','')
+ self.start_dict['H_p'] = H_pStr
+
+
+ if self.variables['S_p[2]']['value'] != None:
+ S_pArr = []
+ for i in range(1,4):
+ S_pArr.append(self.variables['S_p['+str(i)+']']['value'])
+ S_pStr = json.dumps(S_pArr)
+ S_pStr = S_pStr.replace('[','{')
+ S_pStr = S_pStr.replace(']','}')
+ S_pStr = S_pStr.replace('"','')
+ self.start_dict['S_p'] = S_pStr
+
+ if self.variables['Fm_p[2]']['value'] != None:
+ Fm_pArr = []
+ for i in range(1,4):
+ Fm_pArr.append(self.variables['Fm_p['+str(i)+']']['value'])
+ Fm_pStr = json.dumps(Fm_pArr)
+ Fm_pStr = Fm_pStr.replace('[','{')
+ Fm_pStr = Fm_pStr.replace(']','}')
+ Fm_pStr = Fm_pStr.replace('"','')
+ self.start_dict['Fm_p'] = Fm_pStr
+
+ except Exception as e:
+ exc_type, exc_obj, exc_tb = sys.exc_info()
+ # print(exc_type,exc_tb.tb_lineno)
+ # print(e)
+ # print('error')
+
+ def OM_Flowsheet_Initialize(self,addedcomp):
+ self.OM_data_init = ''
+ self.OM_data_init = self.OM_data_init + ("model ms"+str(self.count)+"\n")
+ self.OM_data_init = self.OM_data_init + ("extends Simulator.Streams.MaterialStream;\n" )
+ self.OM_data_init = self.OM_data_init + ("extends Simulator.Files.ThermodynamicPackages."+self.thermo_package+";\n")
+ self.OM_data_init = self.OM_data_init + ("end ms"+str(self.count)+";\n")
+ comp_count = len(addedcomp)
+
+ self.OM_data_init = self.OM_data_init + "ms"+str(self.count) +" " + self.name +"(Nc = " + str(comp_count)
+ self.OM_data_init = self.OM_data_init + ",C = {"
+ C = str(addedcomp).strip('[').strip(']')
+ C = C.replace("'","")
+ self.OM_data_init = self.OM_data_init + C + "},"
+
+ self.OM_data_init = self.OM_data_init[:-1]
+ self.OM_data_init = self.OM_data_init + ');\n'
+ return self.OM_data_init
+
+ def OM_Flowsheet_Equation(self,addedcomp,method):
+ self.OM_data_eqn = ''
+ self.comp_count = len(addedcomp)
+ if method == 'Eqn':
+ self.eqn_dict = {}
+ self.get_min_eqn_values()
+ if method == 'SM':
+ self.eqn_dict = {}
+ self.get_min_eqn_values()
+
+ for key,value in self.eqn_dict.items():
+ self.OM_data_eqn = self.OM_data_eqn + self.name + '.'+ key + ' = ' + str(value) + ';\n'
+ return self.OM_data_eqn
+
+ def disableInputDataTab(self,dockwidget):
+ #setting the value of input data tab in dock widget and disabling them
+ dockwidget.comboBox.setDisabled(True)
+ dockwidget.input_dict['P'].setText(str(round(float(self.variables['P']['value']),4)))
+ dockwidget.input_dict['P'].setDisabled(True)
+ dockwidget.input_dict['T'].setText(str(round(float(self.variables['T']['value']),4)))
+ dockwidget.input_dict['T'].setDisabled(True)
+ dockwidget.input_dict['MolFlow'].setText(str(round(float(self.variables['F_p[1]']['value']),4)))
+ dockwidget.input_dict['MolFlow'].setDisabled(True)
+ dockwidget.cbTP.setCurrentText(str(self.thermo_package))
+ dockwidget.cbTP.setDisabled(True)
+ dockwidget.pushButton_2.setDisabled(True)
+ for index,k in enumerate(dockwidget.x_pclist):
+ k.setText(str(round(float(self.variables['x_pc[1,'+ str(index+1)+']']['value']),4)))
+ k.setDisabled(True)
diff --git a/src/main/python/utils/UnitOperations.py b/src/main/python/utils/UnitOperations.py
new file mode 100644
index 0000000..86a1ad7
--- /dev/null
+++ b/src/main/python/utils/UnitOperations.py
@@ -0,0 +1,739 @@
+import os,sys
+import json
+current = os.path.dirname(os.path.realpath(__file__))
+parent = os.path.dirname(current)
+parentPath = os.path.dirname(parent)
+sys.path.append(parentPath)
+
+from python.OMChem.Flowsheet import Flowsheet
+from python.OMChem.EngStm import EngStm
+from python.utils.ComponentSelector import *
+from python.utils.Container import *
+from PyQt5.QtCore import *
+
+class UnitOperation():
+ counter = 1
+ def __init__(self):
+ self.OM_data_eqn = ''
+ self.OM_data_init = ''
+ self.input_stms = {}
+ self.output_stms = {}
+ self.compounds = [c[:c.index('(')] for c in compound_selected]
+ self.name = ''
+ self.mode = None
+ self.mode_val = None
+ self.type = ''
+ self.no_of_inputs = 1
+ self.no_of_outputs = 1
+ self.x = 2500-30
+ self.y = 2500-30
+ self.pos = QPointF(self.x, self.y)
+ self.count = UnitOperation.counter
+ self.variables = {}
+ self.modes_list = []
+ self.parameters = []
+ self.extra = []
+ self.for_naming = []
+ self.multidict = []
+ self.thermo_pack_req = False
+ self.thermo_package = 'RaoultsLaw'
+ self.saved = False
+
+ def param_getter(self,mode=None):
+ params = {}
+ if mode == None and self.modes_list:
+ self.mode = self.modes_list[0]
+ else:
+ self.mode = mode
+ params[self.mode] = None
+ for i in self.parameters:
+ params[i] = self.variables[i]['value']
+
+ return params
+
+ def param_getter_tooltip(self,mode=None):
+ params = {}
+ if mode == None and self.modes_list:
+ self.mode = self.modes_list[0]
+ else:
+ self.mode = mode
+ params[self.mode] = None
+ for i in self.parameters:
+ params[self.variables[i]['name']] = str(self.variables[i]['value'])+' '+self.variables[i]['unit']
+
+ return params
+
+ def param_setter(self,params):
+ #print("param_setter ", params)
+ try:
+ self.mode = list(params.keys())[0]
+ except Exception as e:
+ print(e)
+ for k,v in params.items():
+ if k == 'Thermo Package':
+ self.thermo_package = v
+ elif k != self.mode:
+ self.k = v
+ self.variables[k]['value'] = v
+ else:
+ self.variables[k]['value'] = v
+ self.mode_val = params[self.mode]
+
+
+ def add_connection(self,flag,sourceId, UnitOpr):
+ if flag==1: # Input stream if flag is 1
+ self.input_stms[sourceId] = UnitOpr
+ else :
+ self.output_stms[sourceId] = UnitOpr
+
+ def set_pos(self,pos):
+ self.pos = pos
+
+ def update_compounds(self):
+ self.compounds = [c[:c.index('(')] for c in compound_selected]
+
+ def OM_Flowsheet_Initialize(self):
+ self.OM_data_init = ''
+
+ if(self.thermo_pack_req):
+ if len(self.extra)>1:
+ for i in range(len(self.extra)):
+ latest = ''
+ for j in range(self.extra[i]):
+ if self.extra[i][j]!='.':
+ latest += self.extra[i][j]
+ self.for_naming[i] = latest
+
+ if(self.thermo_pack_req):
+ if len(self.extra)==1:
+ for i in self.extra:
+ self.OM_data_init += ('model '+i+str(self.counter)+'\n')
+ self.OM_data_init += ('extends Simulator.UnitOperations.'+i+';\n')
+ self.OM_data_init += ('extends Simulator.Files.ThermodynamicPackages.'+self.thermo_package+';\n')
+ self.OM_data_init += ('end '+i+str(self.counter)+';\n')
+
+ self.OM_data_init += i+str(self.counter) + ' ' + self.name + '(Nc = ' + str(len(self.compounds))
+ else:
+ for i in range(len(self.extra)):
+ if i!=(len(self.extra)-1):
+ self.OM_data_init += ('model '+self.for_naming[i]+str(self.counter)+'\n')
+ self.OM_data_init += ('extends Simulator.UnitOperations.'+self.extra[i]+';\n')
+ self.OM_data_init += ('extends Simulator.Files.ThermodynamicPackages.'+self.thermo_package+';\n')
+ self.OM_data_init += ('end '+self.for_naming[i]+str(self.counter)+';\n')
+ else:
+ self.OM_data_init += ('model '+self.for_naming[i]+str(self.counter)+'\n')
+ self.OM_data_init += ('extends Simulator.UnitOperations.'+self.extra[i]+';\n')
+ for j in range(len(self.extra)-1):
+ self.OM_data_init += (self.for_naming[j] + str(self.counter) +' ' + self.for_naming[j] + '#' + self.multidict[j] + ';\n')
+
+ self.OM_data_init += ('end '+self.for_naming[i]+str(self.counter)+';\n')
+
+ self.OM_data_init += self.for_naming[i] + str(self.counter) + ' ' + self.for_naming + '(Nc = ' + str(len(self.compounds))
+
+ C = str(self.compounds).strip('[').strip(']')
+ C = C.replace("'", "")
+ self.OM_data_init += ',C = {' + C + '}'
+
+ for k in self.parameters:
+ if(k == 'HKey_x_pc' or k == 'LKey_x_pc'):
+ continue
+ self.OM_data_init += ', '
+ self.OM_data_init += k + ' = ' + (json.dumps(self.variables[k]['value']) if json.dumps(self.variables[k]['value']).replace('"', '').replace('_', '').isalpha()
+ else json.dumps(self.variables[k]['value']).replace('[', '{').replace(']', '}').replace('"', ''))
+
+ self.OM_data_init += ');\n'
+
+ else:
+ self.OM_data_init += 'Simulator.UnitOperations.' + self.type + ' ' + self.name + '(Nc = ' + str(len(self.compounds))
+ C = str(self.compounds).strip('[').strip(']')
+ C = C.replace("'", "")
+ self.OM_data_init += ',C = {' + C + '}'
+
+ for k in self.parameters:
+ self.OM_data_init += ', '
+ self.OM_data_init += k + ' = ' + (json.dumps(self.variables[k]['value']) if json.dumps(self.variables[k]['value']).replace('"', '').replace('_', '').isalpha()
+ else json.dumps(self.variables[k]['value']).replace('[', '{').replace(']', '}').replace('"', ''))
+
+ self.OM_data_init += ');\n'
+ return self.OM_data_init
+
+
+ def OM_Flowsheet_Equation(self):
+ self.OM_data_eqn = ''
+
+ if len(self.input_stms)>1 or self.type == 'Mixer':
+ strcount = 1
+ for strm in self.input_stms.values():
+ self.OM_data_eqn += ('connect(' + strm.name + '.Out,' + self.name + '.In[' + str(strcount) + ']);\n')
+ strcount += 1
+ else:
+ #print(self.input_stms)
+ self.OM_data_eqn += ('connect(' + self.name + '.In,' + self.input_stms[1].name + '.Out);\n')
+
+ if len(self.output_stms)>1:
+ strcount = 1
+ for strm in self.output_stms.values():
+ self.OM_data_eqn += ('connect(' + strm.name + '.In,' + self.name + '.Out[' + str(strcount) + ']);\n')
+ strcount += 1
+ else:
+ #print("self.output_stms ", self.output_stms)
+ try:
+ self.OM_data_eqn += ('connect(' + self.name + '.Out,' + self.output_stms[1].name + '.In);\n')
+ except:
+ pass
+ if self.mode:
+ self.OM_data_eqn += (self.name + '.' + self.mode + '=' + str(self.mode_val) + ';\n')
+
+ return self.OM_data_eqn
+
+class ShortcutColumn(UnitOperation):
+ def __init__(self, CompNames = [], name='ShortcutColumn'):
+ UnitOperation.__init__(self)
+ self.name = name + str(ShortcutColumn.counter)
+ self.type = 'ShortcutColumn'
+ self.no_of_inputs = 1
+ self.no_of_outputs = 2
+ self.EngStm1 = EngStm(name='EngStm1'+self.name)
+ self.EngStm2 = EngStm(name='EngStm2'+self.name)
+ self.count = ShortcutColumn.counter
+
+ self.extra = ['ShortcutColumn']
+ self.for_naming = ['ShortcutColumn']
+ self.thermo_pack_req = True
+
+ self.parameters = ['HKey', 'LKey', 'HKey_x_pc', 'LKey_x_pc', 'Ctype', 'Pcond', 'Preb', 'RR']
+ self.result_parameters = ['RRmin', 'Ntmin', 'Nt', 'Intray', 'Fliqstrip', 'Fliqrec', 'Fvapstrip', 'Fvaprec', 'Qc', 'Qr']
+ type(self).counter += 1
+
+ self.variables = {
+ 'HKey' : {'name':'Heavy Key', 'value': 0, 'unit':''},
+ 'LKey' : {'name':'Light Key', 'value': 0, 'unit':''},
+ 'HKey_x_pc' : {'name':'Heavy Key Mole Fraction', 'value':0.01, 'unit':''},
+ 'LKey_x_pc' : {'name':'Light Key Mole Fraction', 'value':0.01, 'unit':''},
+ 'Ctype' : {'name':'Condenser Type', 'value':'Total', 'unit':''},
+ 'thermo_package' : {'name':'Thermo Package', 'value':'Raoults_Law', 'unit':''},
+ 'Pcond' : {'name':'Condenser Pressure', 'value':101325, 'unit':'Pa'},
+ 'Preb' : {'name':'Reboiler Pressure', 'value':101325, 'unit':'Pa'},
+ 'RR' : {'name':'Reflux Ratio', 'value':1.5, 'unit':''},
+
+ 'RRmin' : {'name':'Minimum Reflux Ratio', 'value': None , 'unit':''},
+ 'Ntmin' : {'name':'Minimum Number of Stages', 'value': None, 'unit':''},
+ 'Nt' : {'name':'Actual Number of Stages', 'value': None, 'unit':''},
+ 'Intray' : {'name':'Optimal Feed Stage', 'value': None, 'unit':''},
+ 'Fliqstrip' : {'name':'Stripping Liquid', 'value': None, 'unit':'mol/s'},
+ 'Fliqrec' : {'name':'Rectification Liquid', 'value': None, 'unit':'mol/s'},
+ 'Fvapstrip' : {'name':'Stripping Vapor', 'value': None, 'unit':'mol/s'},
+ 'Fvaprec' : {'name':'Recification Vapour', 'value': None, 'unit':'mol/s'},
+ 'Qc' : {'name':'Conderser Duty', 'value': None, 'unit':'W'},
+ 'Qr' : {'name':'Reboiler Duty', 'value': None, 'unit':'W'},
+
+ }
+
+ def update_compounds(self):
+ self.compounds = [c[:c.index('(')] for c in compound_selected]
+
+ def param_setter(self,params):
+ #print("param_setter ", params)
+ self.variables['HKey']['value'] = self.compounds.index(params[0]) + 1
+ self.variables['LKey']['value'] = self.compounds.index(params[1]) + 1
+ self.variables['HKey_x_pc']['value'] = params[2]
+ self.variables['LKey_x_pc']['value'] = params[3]
+ self.variables['Ctype']['value'] = params[4]
+ self.variables['Pcond']['value'] = params[5]
+ self.variables['Preb']['value'] = params[6]
+ self.variables['RR']['value'] = params[7]
+ self.variables['thermo_package']['value'] = params[8]
+
+ def OM_Flowsheet_Equation(self):
+ self.OM_data_eqn = ''
+
+ self.OM_data_eqn += ('connect(' + self.name + '.In,' + self.input_stms[1].name + '.Out);\n')
+
+ strcount = 1
+ for strm in self.output_stms.values():
+ self.OM_data_eqn += ('connect(' + strm.name + '.In,' + self.name + '.Out' + str(strcount) + ');\n')
+ strcount += 1
+
+ self.OM_data_eqn += (self.name + '.x_pc[2, ' + self.name + '.HKey] = ' + str(self.variables['HKey_x_pc']['value']) + ';\n')
+ self.OM_data_eqn += (self.name + '.x_pc[3, ' + self.name + '.LKey] = ' + str(self.variables['LKey_x_pc']['value']) + ';\n')
+
+ return self.OM_data_eqn
+
+class DistillationColumn(UnitOperation):
+ def __init__(self,name='DistillationColumn'):
+ UnitOperation.__init__(self)
+ self.name = name + str(DistillationColumn.counter)
+ self.type = 'DistillationColumn'
+ self.no_of_inputs = 1
+ self.no_of_outputs = 2
+ self.EngStm1 = EngStm(name='EngStm1'+self.name)
+ self.EngStm2 = EngStm(name='EngStm2'+self.name)
+ self.count = DistillationColumn.counter
+ self.thermo_pack_req = True
+ self.modes_list = []
+ self.parameters = ['Nt', 'Ni', 'Ctype', 'Pcond', 'condmode', 'C_comp', 'C_Spec', 'Preb', 'rebmode', 'rebcomp', 'R_Spec']
+ self.result_parameters = ['Cduty.Q', 'Rduty.Q']
+ self.Cspec_list = ['Reflux Ratio','Product Molar Flow (mol/s)', 'Temperature (K)', 'Compound Molar Fraction', 'Compound Molar Flow (mol/s)']
+ self.Rspec_list = ['Product Molar Flow (mol/s)', 'Temperature (K)', 'Compound Molar Fraction', 'Compound Molar Flow (mol/s)']
+
+ type(self).counter += 1
+ self.variables = {
+ 'Ni' : {'name':'Number of Input', 'value':1, 'unit':''},
+ 'RR' : {'name':'Reflux Ratio', 'value':None, 'unit':''},
+ 'T' : {'name':'Temperature', 'value':300, 'unit':'K'},
+ 'Nout' : {'name':'No of Sidedraws', 'value':None, 'unit':''},
+ 'Nt' : {'name':'No of Stages', 'value':12, 'unit':''},
+ 'InT_s' : {'name':'Feed Stage', 'value':[], 'unit':''},
+ 'thermo_package' : {'name':'Thermo Package', 'value':'Raoults_Law', 'unit':''},
+ 'Ctype' : {'name':'Condenser Type', 'value':'Total', 'unit':''},
+ 'Pcond' : {'name':'Condenser Pressure', 'value':101325, 'unit':'Pa'},
+ 'Preb' : {'name':'Reboiler Pressure', 'value':101325, 'unit':'Pa'},
+ 'C_Spec': {'name':'Condenser Specification', 'type':self.Cspec_list[0], 'value':'', 'comp':compound_selected[0], 'unit':''},
+ 'R_Spec': {'name':'Reboiler Specification', 'type':self.Rspec_list[0], 'value':'', 'comp':compound_selected[0], 'unit':''},
+ 'Cduty.Q': {'name':'Condenser Duty', 'value': '', 'unit':'W'},
+ 'Rduty.Q': {'name':'Reboiler Duty', 'value': '', 'unit': 'W'},
+ 'Stages.T': {'name':'Stagewise Temperature', 'value':[], 'unit':'K'},
+ 'Stages.x_pc': {'name': 'Stagewise Component Mole Fraction', 'value':[],'unit':''}
+ }
+
+ def update_compounds(self):
+ self.compounds = [c[:c.index('(')] for c in compound_selected]
+
+ def param_setter(self,params):
+ #print("param_setter ", params)
+ temp = 0
+ self.variables['Nt']['value'] = params[0]
+ for i in range(self.variables['Ni']['value']):
+ self.variables['InT_s']['value'].append(params[i+1])
+ temp = i + 1
+
+ self.variables['Ctype']['value'] = params[temp+1]
+ self.variables['Pcond']['value'] = params[temp+2]
+ self.variables['C_Spec']['type'] = params[temp+3]
+ if 'Compound' in self.variables['C_Spec']['type']:
+ self.variables['C_Spec']['comp'] = params[temp+4]
+ # C_Spec variable value won't be updated to class here. It will be updated in result
+ self.variables['C_Spec']['value'] = params[temp+5]
+ for var in self.variables:
+ if self.variables[var]['name'] == self.variables['C_Spec']['type']:
+ self.variables[var]['value'] = params[temp+5]
+
+ self.variables['Preb']['value'] = params[temp+6]
+ # R_Spec variable value won't be updated to class here. It will be updated in result
+ self.variables['R_Spec']['type'] = params[temp+7]
+ if 'Compound' in self.variables['R_Spec']['type']:
+ self.variables['R_Spec']['comp'] = params[temp+8]
+ self.variables['R_Spec']['value'] = params[temp+9]
+ self.variables['thermo_package']['value'] = params[temp+10]
+ #print(self.variables)
+
+ def OM_Flowsheet_Initialize(self):
+ self.OM_data_init = ''
+ self.OM_data_init = self.OM_data_init + 'model Condenser\n'
+ self.OM_data_init = self.OM_data_init + 'extends Simulator.UnitOperations.DistillationColumn.Cond;\n'
+ self.OM_data_init = self.OM_data_init + 'extends Simulator.Files.ThermodynamicPackages.' + self.thermo_package + ';\n'
+ self.OM_data_init = self.OM_data_init + 'end Condenser;\n'
+ self.OM_data_init = self.OM_data_init + 'model Tray\n'
+ self.OM_data_init = self.OM_data_init + 'extends Simulator.UnitOperations.DistillationColumn.DistTray;\n'
+ self.OM_data_init = self.OM_data_init + 'extends Simulator.Files.ThermodynamicPackages.' + self.thermo_package + ';\n'
+ self.OM_data_init = self.OM_data_init + 'end Tray;\n'
+ self.OM_data_init = self.OM_data_init + 'model Reboiler\n'
+ self.OM_data_init = self.OM_data_init + 'extends Simulator.UnitOperations.DistillationColumn.Reb;\n'
+ self.OM_data_init = self.OM_data_init + 'extends Simulator.Files.ThermodynamicPackages.' + self.thermo_package + ';\n'
+ self.OM_data_init = self.OM_data_init + 'end Reboiler;\n'
+ self.OM_data_init = self.OM_data_init + ("model distCol" + str(self.count) + "\n")
+ self.OM_data_init = self.OM_data_init + ("extends Simulator.UnitOperations.DistillationColumn.DistCol;\n")
+ self.OM_data_init = self.OM_data_init + (
+ "Condenser condenser(Nc = Nc, C = C, Ctype =Ctype, Bin = Bin_t[1], T(start = 300));\n")
+ self.OM_data_init = self.OM_data_init + (
+ "Reboiler reboiler(Nc = Nc, C = C, Bin = Bin_t[Nt]);\n")
+ self.OM_data_init = self.OM_data_init + (
+ "Tray tray[Nt - 2](each Nc = Nc, each C = C, Bin = Bin_t[2:Nt - 1]);\n")
+ self.OM_data_init = self.OM_data_init + ("end distCol" + str(self.count) + ";\n")
+ comp_count = len(self.compounds)
+ self.OM_data_init = self.OM_data_init + (
+ "distCol" + str(self.count) + " " + self.name + "(Nc = " + str(comp_count))
+ self.OM_data_init = self.OM_data_init + (", C= C")
+
+ self.OM_data_init = self.OM_data_init + "," + (
+ "Nt=" + str(self.variables['Nt']['value']) + "," + "Ni="
+ + str(self.variables['Ni']['value']) + ",InT_s=" + "{" +
+ str(self.variables['InT_s']['value']).strip('[').strip(']') + "}" + ',Ctype ="' +
+ self.variables['Ctype']['value'] + '");\n')
+ return self.OM_data_init
+
+ def OM_Flowsheet_Equation(self):
+ self.OM_data_eqn = ''
+ self.OM_data_eqn = self.OM_data_eqn + (
+ 'connect(' + self.name + '.Dist' + ", " + self.output_stms[1].name + '.In);\n')
+ self.OM_data_eqn = self.OM_data_eqn + (
+ 'connect(' + self.name + '.Bot' + ", " + self.output_stms[2].name + '.In);\n')
+ for i in range(len(self.input_stms)):
+ self.OM_data_eqn = self.OM_data_eqn + (
+ 'connect(' + self.input_stms[i +1].name + '.Out' + ", " + self.name + '.In_s[' + str(
+ i + 1) + ']);\n')
+ # ['Product Molar Flow (mol/s)', 'Temperature (K)', 'Compound Molar Fraction',
+ # 'Compound Molar Flow (mol/s)']
+ if self.variables['C_Spec']['type'] == "Reflux Ratio":
+ self.OM_data_eqn = self.OM_data_eqn + (
+ self.name + '.' + 'RR' + '=' + str(self.variables['RR']['value']) + ';\n')
+ elif self.variables['C_Spec']['type'] == "Product Molar Flow (mol/s)":
+ self.OM_data_eqn = self.OM_data_eqn + (self.output_stms[1].name + '.' + 'F_p[1] = ' + str(
+ self.variables['C_Spec']['value']) + ';\n')
+ elif self.variables['C_Spec']['type'] == "Temperature (K)":
+ self.OM_data_eqn = self.OM_data_eqn + (self.output_stms[1].name + '.' + 'T = ' + str(
+ self.variables['C_Spec']['value']) + ';\n')
+ elif self.variables['C_Spec']['type'] == "Compound Molar Fraction":
+ self.OM_data_eqn = self.OM_data_eqn + (self.output_stms[1].name + '.x_pc[1,:' +
+ str(self.compounds.index(self.variables['C_Spec']['comp']) + 1) + '] = ' + str(
+ self.variables['C_Spec']['value']) + ';\n')
+ elif self.variables['C_Spec']['type'] == "Compound Molar Flow (mol/s)":
+ self.OM_data_eqn = self.OM_data_eqn + (self.output_stms[1].name + '.F_pc[1,:' +
+ str(self.compounds.index(self.variables['C_Spec']['comp']) + 1) + '] = ' + str(
+ self.variables['C_Spec']['value']) + ';\n')
+ else:
+ self.OM_data_eqn = self.OM_data_eqn + (
+ self.name + '.Condenser.' + self.mode + '=' + str(self.modeVal) + ';\n')
+
+ if self.variables['R_Spec']['type'] == "Product Molar Flow (mol/s)":
+ self.OM_data_eqn = self.OM_data_eqn + (self.output_stms[2].name + '.' + 'F_p[1] = ' + str(
+ self.variables['R_Spec']['value']) + ';\n')
+ elif self.variables['R_Spec']['type'] == "Temperature (K)":
+ self.OM_data_eqn = self.OM_data_eqn + (self.output_stms[2].name + '.' + 'T = ' + str(
+ self.variables['R_Spec']['value']) + ';\n')
+ elif self.variables['R_Spec']['type'] == "Compound Molar Fraction":
+ self.OM_data_eqn = self.OM_data_eqn + (self.output_stms[2].name + '.x_pc[1,:' +
+ str(self.compounds.index(self.variables['R_Spec']['comp']) + 1) + '] = ' + str(
+ self.variables['R_Spec']['value']) + ';\n')
+ elif self.variables['R_Spec']['type'] == "Compound Molar Flow (mol/s)":
+ self.OM_data_eqn = self.OM_data_eqn + (self.output_stms[2].name + '.F_pc[1,:' +
+ str(self.compounds.index(self.variables['R_Spec']['comp']) + 1) + '] = ' + str(
+ self.variables['R_Spec']['value']) + ';\n')
+
+
+ self.OM_data_eqn = self.OM_data_eqn + self.name + '.reboiler.P=' + str(
+ self.variables['Preb']['value']) + ';\n'
+ self.OM_data_eqn = self.OM_data_eqn + self.name + '.condenser.P=' + str(
+ self.variables['Pcond']['value']) + ';\n'
+ return self.OM_data_eqn
+
+class ConvertionReactor(UnitOperation):
+ def __init__(self,name='',Nr=None,b=None,X=None,Z=None,a=[],operation=None,Tdef=None):
+ UnitOperation.__init__(self)
+ self.name = name
+ self.type = 'ConvertionReactor'
+
+ self.Nr = str(Nr)
+ self.b = str(b)
+ self.X = str(X)
+ self.Z = str(Z)
+ self.a = json.dumps(a).replace('[','{').replace(']','}')
+ self.operation = str(operation)
+ self.Tdef = str(Tdef)
+
+class CompoundSeparator(UnitOperation):
+ def __init__(self, name='CompoundSeparator'):
+ UnitOperation.__init__(self)
+ self.name = name + str(CompoundSeparator.counter)
+ self.type = 'CompoundSeparator'
+ self.no_of_inputs = 1
+ self.no_of_outputs = 2
+
+ self.SepFact_modes = ['Molar_Flow (mol/s)', 'Mass_Flow (g/s)', 'Inlet_Molar_Flow_Percent', 'Outlet_Molar_Flow_Percent']
+
+ type(self).counter += 1
+ self.variables = {
+ 'SepStrm' : {'name':'Separation Stream', 'value':1, 'unit':''},
+ 'SepVal_c' : {'name':'Separation Value', 'value':['']*len(self.compounds), 'unit':''},
+ 'SepFact_c' : {'name':'Separaction Factor', 'value':['']*len(self.compounds), 'unit':''},
+ }
+
+ def init_variables(self):
+ self.variables = {
+ 'SepStrm' : {'name':'Separation Stream', 'value':1, 'unit':''},
+ 'SepVal_c' : {'name':'Separation Value', 'value':['']*len(self.compounds), 'unit':''},
+ 'SepFact_c' : {'name':'Separaction Factor', 'value':['']*len(self.compounds), 'unit':''},
+ }
+ def update_compounds(self):
+ self.compounds = [c[:c.index('(')] for c in compound_selected]
+
+ def param_setter(self,params):
+ #print("param_setter CompSep ", params)
+
+ if (params[0]):
+ self.variables['SepStrm']['value'] = 1
+ else:
+ self.variables['SepStrm']['value'] = 2
+ for index, i in enumerate(range(2, len(params))):
+ if (i %2 != 0):
+ self.variables['SepVal_c']['value'][index//2] = float(params[i])
+ else:
+ self.variables['SepFact_c']['value'][index//2] = params[i]
+
+ def OM_Flowsheet_Initialize(self):
+ SepStrm = str(self.variables['SepStrm']['value'])
+ SepFact = []
+ for i in range(len(self.compounds)):
+ SepFact.append(self.variables['SepFact_c']['value'][i].split(' ')[0])
+ SepFact = json.dumps(SepFact).replace('[', '{').replace(']', '}')
+ self.OM_data_init = ''
+ comp_count = len(self.compounds)
+ self.OM_data_init = self.OM_data_init + (
+ "Simulator.UnitOperations.CompoundSeparator " + self.name + "(Nc = " + str(comp_count))
+ self.OM_data_init = self.OM_data_init + (", C = {")
+ comp = str(self.compounds).strip('[').strip(']')
+ comp = comp.replace("'", "")
+ self.OM_data_init = self.OM_data_init + comp + ("},")
+ self.OM_data_init = self.OM_data_init + ("SepFact_c = " + SepFact + ",SepStrm = " + SepStrm + ");\n")
+
+ return self.OM_data_init
+
+
+ def OM_Flowsheet_Equation(self):
+ SepVal = json.dumps(self.variables['SepVal_c']['value']).replace('[','{').replace(']','}')
+ self.OM_data_eqn = ''
+
+ self.OM_data_eqn += ('connect(' + self.name + '.In,' + self.input_stms[1].name + '.Out);\n')
+
+ strcount = 1
+ for strm in self.output_stms.values():
+ self.OM_data_eqn += ('connect(' + strm.name + '.In,' + self.name + '.Out' + str(strcount) + ');\n')
+ strcount += 1
+
+ self.OM_data_eqn += (self.name + '.SepVal_c ' + '=' + SepVal + ';\n')
+
+ return self.OM_data_eqn
+
+class Flash(UnitOperation):
+ def __init__(self,name='Flash'):
+ UnitOperation.__init__(self)
+ self.name = name + str(Flash.counter)
+ self.type = 'Flash'
+ self.extra = ['Flash']
+ self.for_naming = ['Flash']
+ self.no_of_inputs = 1
+ self.no_of_outputs = 2
+ self.count = Flash.counter
+ self.thermo_pack_req = True
+ self.parameters = ['BTdef', 'Tdef', 'BPdef', 'Pdef']
+
+ type(self).counter += 1
+ self.variables = {
+ 'thermo_package' : {'name':'Thermo Package', 'value':None, 'unit':''},
+ 'BTdef' : {'name':'Separation Temperature Boolean', 'value':False, 'unit':''},
+ 'BPdef' : {'name':'Separation Pressure Boolean', 'value':False, 'unit':''},
+ 'Tdef' : {'name':'Separation Temperature', 'value':298.15, 'unit':'K'},
+ 'Pdef' : {'name':'Separation Pressure', 'value':101325, 'unit':'Pa'}
+ }
+
+ def update_compounds(self):
+ self.compounds = [c[:c.index('(')] for c in compound_selected]
+
+ def param_setter(self,params):
+ #print("param_setter ", params)
+ self.variables['thermo_package']['value'] = params[0]
+ self.variables['BTdef']['value'] = params[1]
+ self.variables['Tdef']['value'] = params[2]
+ self.variables['BPdef']['value'] = params[3]
+ self.variables['Pdef']['value'] = params[4]
+
+ def OM_Flowsheet_Equation(self):
+ self.OM_data_eqn = ''
+
+ self.OM_data_eqn += ('connect(' + self.name + '.In,' + self.input_stms[1].name + '.Out);\n')
+
+ strcount = 1
+ for strm in self.output_stms.values():
+ self.OM_data_eqn += ('connect(' + strm.name + '.In,' + self.name + '.Out' + str(strcount) + ');\n')
+ strcount += 1
+
+ return self.OM_data_eqn
+
+class CentrifugalPump(UnitOperation):
+ def __init__(self,name='CentrifugalPump'):
+ UnitOperation.__init__(self)
+ self.name = name + str(CentrifugalPump.counter)
+ self.type = 'CentrifugalPump'
+ self.modes_list = ['Pdel', 'Pout', 'Q'] #"enFlo"
+ self.parameters = ['Eff']
+
+ type(self).counter += 1
+ self.variables = {
+ 'Eff' : {'name':'Efficiency', 'value':1, 'unit':''},
+ 'Pdel' : {'name':'Pressure Increase', 'value':None, 'unit':'Pa'},
+ 'Pout' : {'name':'Outlet Pressure', 'value':None, 'unit':'Pa'},
+ 'Q' : {'name':'Power Required', 'value':None, 'unit':'W'},
+ }
+
+class Valve(UnitOperation):
+ def __init__(self,name='Valve'):
+ UnitOperation.__init__(self)
+ self.name = name + str(Valve.counter)
+ self.type = 'Valve'
+ self.modes_list = ['Pdel', 'Pout']
+
+ type(self).counter += 1
+ self.variables = {
+ 'Pdel' : {'name':'Pressure Drop', 'value':None, 'unit':'Pa'},
+ 'Pout' : {'name':'Outlet Pressure', 'value':None, 'unit':'Pa'}
+ }
+
+class Splitter(UnitOperation):
+ def __init__(self,name='Splitter'):
+ UnitOperation.__init__(self)
+ self.name = name + str(Splitter.counter)
+ self.type = 'Splitter'
+ self.no_of_outputs = 2
+
+ self.CalcType_modes = ['Split_Ratio', 'Molar_Flow', 'Mass_Flow']
+
+ self.parameters = ['No', 'CalcType', 'SpecVal_s']
+ type(self).counter += 1
+
+ self.variables = {
+ 'No' : {'name':'No. of Output', 'value':2, 'unit':''},
+ 'CalcType' : {'name':'Calculation Type', 'value':self.CalcType_modes[0], 'unit':''},
+ 'SpecVal_s' : {'name':'Specification Value', 'value':[0.5,0.5], 'unit':''}
+ }
+
+ specval = self.variables['SpecVal_s']['value']
+ self.specval = json.dumps(specval).replace('[','{').replace(']','}')
+
+ def update_compounds(self):
+ self.compounds = [c[:c.index('(')] for c in compound_selected]
+
+ def param_setter(self,params):
+ #print("param_setter ", params)
+ self.variables['No']['value'] = int(params[0])
+ self.variables['CalcType']['value'] = params[1]
+ self.variables['SpecVal_s']['value'] = [float(params[2]), float(params[3])]
+ if self.variables['CalcType']['value'] == 'Molar_Flow':
+ self.variables['SpecVal_s']['unit'] = 'mol/s'
+ elif self.variables['CalcType']['value'] == 'Mass_Flow':
+ self.variables['SpecVal_s']['unit'] = 'g/s'
+ else:
+ self.variables['SpecVal_s']['unit'] = ''
+
+class Mixer(UnitOperation):
+
+ def __init__(self,name='Mixer'):
+ UnitOperation.__init__(self)
+ self.name = name + str(Mixer.counter)
+ self.type = 'Mixer'
+ self.no_of_inputs = 2
+
+ self.Pout_modes = ['Inlet_Minimum', 'Inlet_Average', 'Inlet_Maximum']
+ self.parameters = ['NI', 'outPress']
+ type(self).counter += 1
+
+ self.variables = {
+ 'NI' : {'name':'Number of Input', 'value':6, 'unit':''},
+ 'outPress' : {'name':'Outlet Pressure', 'value':'Inlet_Average', 'unit':''},
+ }
+
+ def update_compounds(self):
+ self.compounds = [c[:c.index('(')] for c in compound_selected]
+
+ def param_setter(self, params):
+ self.variables['NI']['value'] = int(params[0])
+ self.variables['outPress']['value'] = params[1]
+
+class Heater(UnitOperation):
+
+ def __init__(self, name='Heater'):
+ UnitOperation.__init__(self)
+ self.name = name + str(type(self).counter)
+ self.type = 'Heater'
+ self.no_of_inputs = 1
+ self.no_of_outputs = 1
+ self.modes_list = ['Q','Tout','xvapout','Tdel']
+ self.parameters = ['Pdel', 'Eff']
+ self.extra = None
+ self.for_naming = None
+ type(self).counter += 1
+
+ self.variables = {
+ 'Pdel' : {'name':'Pressure Drop', 'value':0, 'unit':'Pa'},
+ 'Eff' : {'name':'Efficiency', 'value':1, 'unit':''},
+ 'Tout' : {'name':'Outlet Temperature', 'value':298.15, 'unit':'K'},
+ 'Tdel' : {'name':'Temperature Increase', 'value':0, 'unit':'K'},
+ 'Q' : {'name':'Heat Added', 'value':0, 'unit':'W'},
+ 'xvapout': {'name':'Outlet Vapour', 'value':None, 'unit':''}
+ }
+
+class Cooler(UnitOperation):
+
+ def __init__(self, name='Cooler'):
+ UnitOperation.__init__(self)
+ self.name = name + str(type(self).counter)
+ self.type = 'Cooler'
+ self.no_of_inputs = 1
+ self.no_of_outputs = 1
+ self.modes_list = ['Q','Tout','Tdel','xvap']
+ self.extra = None
+ self.for_naming = None
+ self.parameters = ['Pdel', 'Eff']
+ type(self).counter += 1
+
+ self.variables = {
+ 'Pdel' : {'name':'Pressure Drop', 'value':0, 'unit':'Pa'},
+ 'Eff' : {'name':'Efficiency', 'value':1, 'unit':''},
+ 'Tout' : {'name':'Outlet Temperature', 'value':298.15, 'unit':'K'},
+ 'Tdel' : {'name':'Temperature Increase', 'value':0, 'unit':'K'},
+ 'Q' : {'name':'Heat Added', 'value':0, 'unit':'W'},
+ 'xvap' : {'name':'Vapour Phase Mole Fraction', 'value':None, 'unit':'g/s'},
+ }
+
+class AdiabaticCompressor(UnitOperation):
+
+ def __init__(self, name='AdiabaticCompressor'):
+ UnitOperation.__init__(self)
+ self.name = name + str(type(self).counter)
+ self.type = 'AdiabaticCompressor'
+ self.no_of_inputs = 1
+ self.no_of_outputs = 1
+ self.modes_list = ["Pdel","Pout","Q"]
+ self.extra = ['AdiabaticCompressor']
+ self.for_naming = ['AdiabaticCompressor']
+ self.thermo_pack_req = True
+ self.thermo_package ="RaoultsLaw"
+ self.parameters = ['Eff']
+ type(self).counter += 1
+ self.variables = {
+ 'Pdel' : {'name':'Pressure Increase', 'value':0, 'unit':'Pa'},
+ 'Tdel' : {'name':'Temperature Increase', 'value':0, 'unit':'K'},
+ 'Pout' : {'name':'Outlet Pressure', 'value':101325, 'unit':'Pa'},
+ 'Tout' : {'name':'Outlet Temperature', 'value':298.15, 'unit':'K'},
+ 'Q' : {'name':'Heat Added', 'value':0, 'unit':'W'},
+ 'Eff' : {'name':'Efficiency', 'value':1, 'unit':''}
+ }
+
+ def update_compounds(self):
+ self.compounds = [c[:c.index('(')] for c in compound_selected]
+
+class AdiabaticExpander(UnitOperation):
+
+ def __init__(self, name='AdiabaticExpander'):
+ UnitOperation.__init__(self)
+ self.name = name + str(type(self).counter)
+ self.type = 'AdiabaticExpander'
+ self.no_of_inputs = 1
+ self.no_of_outputs = 1
+ self.modes_list = ["Pdel","Pout","Q"]
+ self.extra = ['AdiabaticExpander']
+ self.for_naming = ['AdiabaticExpander']
+ self.thermo_pack_req = True
+ self.thermo_package ="RaoultsLaw"
+ self.parameters = ['Eff']
+ type(self).counter += 1
+ self.variables = {
+ 'Pdel' : {'name':'Pressure Drop', 'value':0, 'unit':'Pa'},
+ 'Tdel' : {'name':'Temperature Increase', 'value':0, 'unit':'K'},
+ 'Pout' : {'name':'Outlet Pressure', 'value':101325, 'unit':'Pa'},
+ 'Tout' : {'name':'Outlet Temperature', 'value':298.15, 'unit':'K'},
+ 'Q' : {'name':'Heat Added', 'value':0, 'unit':'W'},
+ 'Eff' : {'name':'Efficiency', 'value':1, 'unit':''}
+ }
+
+ def update_compounds(self):
+ self.compounds = [c[:c.index('(')] for c in compound_selected] \ No newline at end of file
diff --git a/src/main/python/utils/__init__.py b/src/main/python/utils/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/main/python/utils/__init__.py
diff --git a/src/main/python/utils/__pycache__/Bin_Phase_env.cpython-37.pyc b/src/main/python/utils/__pycache__/Bin_Phase_env.cpython-37.pyc
new file mode 100644
index 0000000..35c4753
--- /dev/null
+++ b/src/main/python/utils/__pycache__/Bin_Phase_env.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/utils/__pycache__/ComponentSelector.cpython-37.pyc b/src/main/python/utils/__pycache__/ComponentSelector.cpython-37.pyc
new file mode 100644
index 0000000..b6bceec
--- /dev/null
+++ b/src/main/python/utils/__pycache__/ComponentSelector.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/utils/__pycache__/Container.cpython-37.pyc b/src/main/python/utils/__pycache__/Container.cpython-37.pyc
new file mode 100644
index 0000000..98797d2
--- /dev/null
+++ b/src/main/python/utils/__pycache__/Container.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/utils/__pycache__/Graphics.cpython-37.pyc b/src/main/python/utils/__pycache__/Graphics.cpython-37.pyc
new file mode 100644
index 0000000..7426c2f
--- /dev/null
+++ b/src/main/python/utils/__pycache__/Graphics.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/utils/__pycache__/Streams.cpython-37.pyc b/src/main/python/utils/__pycache__/Streams.cpython-37.pyc
new file mode 100644
index 0000000..18287f2
--- /dev/null
+++ b/src/main/python/utils/__pycache__/Streams.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/utils/__pycache__/UnitOperations.cpython-37.pyc b/src/main/python/utils/__pycache__/UnitOperations.cpython-37.pyc
new file mode 100644
index 0000000..ac4d056
--- /dev/null
+++ b/src/main/python/utils/__pycache__/UnitOperations.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/utils/__pycache__/__init__.cpython-37.pyc b/src/main/python/utils/__pycache__/__init__.cpython-37.pyc
new file mode 100644
index 0000000..a687f51
--- /dev/null
+++ b/src/main/python/utils/__pycache__/__init__.cpython-37.pyc
Binary files differ
diff --git a/src/main/python/utils/thermopackage.txt b/src/main/python/utils/thermopackage.txt
new file mode 100644
index 0000000..f9155f5
--- /dev/null
+++ b/src/main/python/utils/thermopackage.txt
@@ -0,0 +1,6 @@
+RaoultsLaw
+NRTL
+UNIQUAC
+UNIFAC
+PengRobinson
+GraysonStreed \ No newline at end of file