diff options
Diffstat (limited to 'src/main/python')
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 Binary files differnew file mode 100644 index 0000000..0feb70b --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DistillationColumnStagewiseResults.cpython-36.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DistillationColumnStagewiseResults.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DistillationColumnStagewiseResults.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..d8c43f1 --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DistillationColumnStagewiseResults.cpython-37.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidget.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidget.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..853e89a --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidget.cpython-36.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidget.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidget.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..90c3ef9 --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidget.cpython-37.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetCompoundSeparator.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetCompoundSeparator.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..355cf3a --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetCompoundSeparator.cpython-36.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetCompoundSeparator.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetCompoundSeparator.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..eed70e1 --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetCompoundSeparator.cpython-37.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetCompressorExpander.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetCompressorExpander.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..88102aa --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetCompressorExpander.cpython-36.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetCompressorExpander.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetCompressorExpander.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..05d0157 --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetCompressorExpander.cpython-37.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetDistillationColumn.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetDistillationColumn.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..f5eccbb --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetDistillationColumn.cpython-36.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetDistillationColumn.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetDistillationColumn.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..a3cba32 --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetDistillationColumn.cpython-37.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetFlash.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetFlash.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..34d90b2 --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetFlash.cpython-36.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetFlash.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetFlash.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..08f6dae --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetFlash.cpython-37.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetMaterialStream.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetMaterialStream.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..1181e13 --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetMaterialStream.cpython-36.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetMaterialStream.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetMaterialStream.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..abc5f50 --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetMaterialStream.cpython-37.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetMixer.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetMixer.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..1fc6df4 --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetMixer.cpython-36.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetMixer.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetMixer.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..2974d48 --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetMixer.cpython-37.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetShortcutColumn.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetShortcutColumn.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..99d84d1 --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetShortcutColumn.cpython-36.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetShortcutColumn.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetShortcutColumn.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..46cd536 --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetShortcutColumn.cpython-37.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetSplitter.cpython-36.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetSplitter.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..6c8bb16 --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetSplitter.cpython-36.pyc diff --git a/src/main/python/DockWidgets/__pycache__/DockWidgetSplitter.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/DockWidgetSplitter.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..d23e668 --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/DockWidgetSplitter.cpython-37.pyc diff --git a/src/main/python/DockWidgets/__pycache__/__init__.cpython-37.pyc b/src/main/python/DockWidgets/__pycache__/__init__.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..9a9342e --- /dev/null +++ b/src/main/python/DockWidgets/__pycache__/__init__.cpython-37.pyc 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 Binary files differnew file mode 100644 index 0000000..a5f5a78 --- /dev/null +++ b/src/main/python/OMChem/__pycache__/EngStm.cpython-36.pyc diff --git a/src/main/python/OMChem/__pycache__/EngStm.cpython-37.pyc b/src/main/python/OMChem/__pycache__/EngStm.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..d065cdb --- /dev/null +++ b/src/main/python/OMChem/__pycache__/EngStm.cpython-37.pyc diff --git a/src/main/python/OMChem/__pycache__/Flowsheet.cpython-36.pyc b/src/main/python/OMChem/__pycache__/Flowsheet.cpython-36.pyc Binary files differnew file mode 100644 index 0000000..4039084 --- /dev/null +++ b/src/main/python/OMChem/__pycache__/Flowsheet.cpython-36.pyc diff --git a/src/main/python/OMChem/__pycache__/Flowsheet.cpython-37.pyc b/src/main/python/OMChem/__pycache__/Flowsheet.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..1a76d03 --- /dev/null +++ b/src/main/python/OMChem/__pycache__/Flowsheet.cpython-37.pyc diff --git a/src/main/python/OMChem/__pycache__/__init__.cpython-37.pyc b/src/main/python/OMChem/__pycache__/__init__.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..ee871fe --- /dev/null +++ b/src/main/python/OMChem/__pycache__/__init__.cpython-37.pyc 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 Binary files differnew file mode 100644 index 0000000..35c4753 --- /dev/null +++ b/src/main/python/utils/__pycache__/Bin_Phase_env.cpython-37.pyc diff --git a/src/main/python/utils/__pycache__/ComponentSelector.cpython-37.pyc b/src/main/python/utils/__pycache__/ComponentSelector.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..b6bceec --- /dev/null +++ b/src/main/python/utils/__pycache__/ComponentSelector.cpython-37.pyc diff --git a/src/main/python/utils/__pycache__/Container.cpython-37.pyc b/src/main/python/utils/__pycache__/Container.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..98797d2 --- /dev/null +++ b/src/main/python/utils/__pycache__/Container.cpython-37.pyc diff --git a/src/main/python/utils/__pycache__/Graphics.cpython-37.pyc b/src/main/python/utils/__pycache__/Graphics.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..7426c2f --- /dev/null +++ b/src/main/python/utils/__pycache__/Graphics.cpython-37.pyc diff --git a/src/main/python/utils/__pycache__/Streams.cpython-37.pyc b/src/main/python/utils/__pycache__/Streams.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..18287f2 --- /dev/null +++ b/src/main/python/utils/__pycache__/Streams.cpython-37.pyc diff --git a/src/main/python/utils/__pycache__/UnitOperations.cpython-37.pyc b/src/main/python/utils/__pycache__/UnitOperations.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..ac4d056 --- /dev/null +++ b/src/main/python/utils/__pycache__/UnitOperations.cpython-37.pyc diff --git a/src/main/python/utils/__pycache__/__init__.cpython-37.pyc b/src/main/python/utils/__pycache__/__init__.cpython-37.pyc Binary files differnew file mode 100644 index 0000000..a687f51 --- /dev/null +++ b/src/main/python/utils/__pycache__/__init__.cpython-37.pyc 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 |