diff options
-rw-r--r-- | Graphics.py | 4 | ||||
-rw-r--r-- | OMChem/Flowsheet.py | 68 | ||||
-rw-r--r-- | container.py | 26 | ||||
-rw-r--r-- | helper.py | 22 | ||||
-rw-r--r-- | main.ui | 13 | ||||
-rw-r--r-- | mainApp.py | 24 |
6 files changed, 98 insertions, 59 deletions
diff --git a/Graphics.py b/Graphics.py index 3184019..99b4f46 100644 --- a/Graphics.py +++ b/Graphics.py @@ -217,7 +217,7 @@ class NodeSocket(QtWidgets.QGraphicsItem): self.newLine.pointB = item.getCenter() if self.newLine.source.parent.obj.type not in stm: self.newLine.source.parent.obj.add_connection(0,self.newLine.target.parent.obj) - if self.newLine.target.parent.obj not in stm: + if self.newLine.target.parent.obj.type not in stm: self.newLine.target.parent.obj.add_connection(1,self.newLine.source.parent.obj) elif (self.type =='in') and (item.type == 'op'): self.newLine.source = item @@ -226,7 +226,7 @@ class NodeSocket(QtWidgets.QGraphicsItem): self.newLine.pointA = item.getCenter() if self.newLine.source.parent.obj.type not in stm: self.newLine.source.parent.obj.add_connection(0,self.newLine.target.parent.obj) - if self.newLine.target.parent.obj not in stm: + if self.newLine.target.parent.obj.type not in stm: self.newLine.target.parent.obj.add_connection(1,self.newLine.source.parent.obj) else: self.scene().removeItem(self.newLine) diff --git a/OMChem/Flowsheet.py b/OMChem/Flowsheet.py index 6b6c9ad..a35f686 100644 --- a/OMChem/Flowsheet.py +++ b/OMChem/Flowsheet.py @@ -14,9 +14,9 @@ class Flowsheet(): self.compounds = [] self.interface = '' self.omc_path = None - self.curr_path = os.getcwd() - self.sim_dir_path = os.path.join(self.curr_path, self.sim_name) - self.Flomo_path = os.path.join(self.sim_dir_path,'Flowsheet.mo') + 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.resdata = [] @@ -32,14 +32,14 @@ class Flowsheet(): elif os.path.exists('/opt/local/bin/omc'): self.omhome = '/opt/local' elif os.path.exists('/usr/bin/omc'): - self.omhome = '/usr' + 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 add_UnitOpn(self,unitop): - self.UnitOpn.append(unitop) + self.UnitOpn.append(unitop) def remove_UnitOpn(self,unitop): self.UnitOpn.remove(unitop) @@ -47,7 +47,6 @@ class Flowsheet(): def add_comp_list(self,comp): self.compounds = comp - def send_for_simulationEqn(self): self.resdata = [] self.omc_path = self.get_omc_path() @@ -57,13 +56,13 @@ class Flowsheet(): simpath = self.eqn_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() + self.process = Popen([self.omc_path, '-s',simpath], stdout=PIPE, stderr=PIPE) + self.stdout, self.stderr = self.process.communicate() #s = subprocess.check_output([self.omc_path, '-s',simpath]) #print(s) #print("############### StdOut ################") print(self.stdout) - os.chdir(self.curr_path) + os.chdir(self.root_dir) #os.system(self.omc_path + ' -s ' + simpath) print("Hello") if self.sim_method == 'Eqn': @@ -86,8 +85,8 @@ class Flowsheet(): self.omc_path = self.get_omc_path() os.chdir(self.sim_dir_path) #os.system(self.omc_path + ' -s ' + unitop.name+'.mos') - process = Popen([self.omc_path, '-s',unitop.name,'.mos'], stdout=PIPE, stderr=PIPE) - stdout, stderr = process.communicate() + self.process = Popen([self.omc_path, '-s',unitop.name,'.mos'], stdout=PIPE, stderr=PIPE) + stdout, stderr = self.process.communicate() #s = subprocess.check_output([self.omc_path, '-s',simpath]) #print(s) print("############### StdOut ################") @@ -106,38 +105,35 @@ class Flowsheet(): # if self.sim_method == 'SM': - # for unitop in self.UnitOpn: - # self.resdata = [] - # if unitop.type != 'MatStm': - # 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.resdata.append(row) - # self.ExtData() + # for unitop in self.UnitOpn: + # self.resdata = [] + # if unitop.type != 'MatStm': + # 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.resdata.append(row) + # self.ExtData() # if self.interface == 'OMPython': - # omc = OMCSession() - # omc.sendExpression("loadModel(Modelica)") - # omc.sendExpression("loadFile(\"Simulator.mo\")") - # omc.sendExpression("loadFile(\"Flowsheet.mo\")") - # execsim = omc.sendExpression("simulate(Flowsheet, outputFormat=\"csv\", stopTime=1.0, numberOfIntervals=1)") + # omc = OMCSession() + # omc.sendExpression("loadModel(Modelica)") + # omc.sendExpression("loadFile(\"Simulator.mo\")") + # omc.sendExpression("loadFile(\"Flowsheet.mo\")") + # execsim = omc.sendExpression("simulate(Flowsheet, outputFormat=\"csv\", stopTime=1.0, numberOfIntervals=1)") # else: - # os.system(self.omc_path + ' -s ') + # os.system(self.omc_path + ' -s ') def ExtData(self): for unit in self.UnitOpn: if unit[0].type == 'MatStm': -# for key, value in unit[0].Prop.items(): - - propertyname = unit[0].name + '.' + key if propertyname in self.resdata[0]: ind = self.resdata[0].index(propertyname) @@ -270,7 +266,7 @@ class Flowsheet(): with open(self.eqn_mos_path, 'w') as mosFile: mosFile.write('loadModel(Modelica);\n') - mosFile.write("loadFile(\"Simulator/package.mo\");\n") + mosFile.write("loadFile(\"Simulator\package.mo\");\n") mosFile.write("loadFile(\"Flowsheet.mo\");\n") mosFile.write("simulate(Flowsheet, outputFormat=\"csv\", stopTime=1.0, numberOfIntervals=1);\n") @@ -315,7 +311,7 @@ class Flowsheet(): print("################################11") for unitop in self.unit: - os.chdir(self.curr_path) + os.chdir(self.root_dir) self.data = [] if unitop.type not in ['MatStm','EngStm']: inpstms = unitop.InputStms @@ -395,9 +391,9 @@ class Flowsheet(): #os.system(self.omc_path + ' -s ' + unitop[0].name.lower()+"SEQ"+'.mos') print("SIM directory Path 1 ###",self.sim_dir_path) sim = os.path.join(self.sim_dir_path,unitop.name.lower()+'.mos') - process = Popen([self.omc_path, '-s',sim], stdout=PIPE, stderr=PIPE) - self.stdout, self.stderr = process.communicate() - os.chdir(self.curr_path) + self.process = Popen([self.omc_path, '-s',sim], stdout=PIPE, stderr=PIPE) + self.stdout, self.stderr = self.process.communicate() + os.chdir(self.root_dir) #s = subprocess.check_output([self.omc_path, '-s',simpath]) #print(s) print("############### StdOut ################") @@ -414,7 +410,7 @@ class Flowsheet(): for row in csvreader: self.resdata.append(row) - os.chdir(self.curr_path) + os.chdir(self.root_dir) if type(inpstms) is list: for stm in inpstms: for key, value in stm.Prop.items(): diff --git a/container.py b/container.py index dd3cf89..3652031 100644 --- a/container.py +++ b/container.py @@ -26,6 +26,7 @@ class Container(): self.unitOp = [] self.thermoPackage = None self.compounds = None + self.flowsheet = None self.conn = defaultdict(list) self.op=defaultdict(list) self.ip=defaultdict(list) @@ -99,14 +100,14 @@ class Container(): - def msgBrowser(self,f): - std = f.stdout.decode("utf-8") + def msgBrowser(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 = f.stderr.decode("utf-8") + stde = self.flowsheet.stderr.decode("utf-8") if(stde): stdout = str(stde) stdout = stdout.replace("\n","<br/>") @@ -117,25 +118,24 @@ class Container(): print(mode) self.compounds = compound_selected #self.connection() - f = Flowsheet() - f.add_comp_list(self.compounds) + self.flowsheet = Flowsheet() + self.flowsheet.add_comp_list(self.compounds) print("######## connection master#########\n",self.conn) for i in self.unitOp : print("here",i) - f.add_UnitOpn(i) - + self.flowsheet.add_UnitOpn(i) if mode=='SM': self.msg.append("<span>["+str(self.currentTime())+"] Simulating in <b>Sequential</b> mode ... </span>") - f.simulateSM(self.ip,self.op) - self.msgBrowser(f) - self.result=f.resdata + self.flowsheet.simulateSM(self.ip,self.op) + self.msgBrowser() + self.result=self.flowsheet.resdata print("under SEQ mode simulation") elif mode=='EQN': self.msg.append("<span>["+str(self.currentTime())+"] Simulating in <b>equation</b> mode ... </span>") - f.simulateEQN() - self.msgBrowser(f) - self.result=f.resdata + self.flowsheet.simulateEQN() + self.msgBrowser() + self.result=self.flowsheet.resdata print("under Eqn mode simulation") def flatlist(lst): @@ -18,7 +18,7 @@ from component_selector import * class HeaterClass(): - counter = 1; + counter = 1 def __init__(self,name='Heater',pressDrop = None, eff = None): self.OM_data_eqn = '' @@ -37,6 +37,13 @@ class HeaterClass(): self.y = 2500-30 self.addedcomp = None self.extra = None + self.Prop = { + 'pressDrop':None, + 'eff':None, + 'outT':None, + 'tempInc':None, + 'heatAdd':None, + } HeaterClass.counter+=1 def modesList(self): @@ -82,7 +89,7 @@ class HeaterClass(): class CoolerClass(): - counter = 1; + counter = 1 def __init__(self,name='Cooler',pressDrop = None, eff = None): self.OM_data_eqn = '' @@ -101,6 +108,13 @@ class CoolerClass(): self.y = 2500-30 self.addedcomp = None self.extra = None + self.Prop = { + 'pressDrop':None, + 'eff':None, + 'outT':None, + 'tempDrop':None, + 'heatRem':None, + } HeaterClass.counter+=1 def modesList(self): @@ -148,7 +162,7 @@ class CoolerClass(): class AdiaCompClass(): - counter = 1; + counter = 1 def __init__(self,name='AdiaComp', eff = None): self.OM_data_eqn = '' @@ -207,7 +221,7 @@ class AdiaCompClass(): return Inst class AdiaExpClass(): - counter = 1; + counter = 1 def __init__(self,name='AdiaExp', eff = None): self.OM_data_eqn = '' @@ -148,7 +148,7 @@ <x>0</x> <y>0</y> <width>1068</width> - <height>21</height> + <height>26</height> </rect> </property> <widget class="QMenu" name="menuFile"> @@ -178,6 +178,8 @@ </property> <addaction name="actionEquation_oriented"/> <addaction name="actionSequential_mode"/> + <addaction name="separator"/> + <addaction name="actionTerminate"/> </widget> <widget class="QMenu" name="menuComponds"> <property name="title"> @@ -256,8 +258,8 @@ <rect> <x>0</x> <y>0</y> - <width>221</width> - <height>956</height> + <width>222</width> + <height>978</height> </rect> </property> <layout class="QVBoxLayout" name="verticalLayout_5"> @@ -1194,6 +1196,11 @@ <string>Open</string> </property> </action> + <action name="actionTerminate"> + <property name="text"> + <string>Terminate</string> + </property> + </action> </widget> <resources/> <connections/> @@ -27,7 +27,9 @@ import datetime from container import Container from Graphics import Graphics import pickle +import threading import os +import ctypes import sys ui,_ = loadUiType('main.ui') @@ -53,6 +55,7 @@ class MainApp(QMainWindow,ui): # Initializing attributes self.zoomcount = 0 + self.thrd = None # Creating instances of classes for the main app self.Container = Container(self.textBrowser) @@ -104,6 +107,7 @@ class MainApp(QMainWindow,ui): # self.actionRedo.triggered.connect(self.undoStack.redo) self.actionSave_2.triggered.connect(self.save) self.actionOpen.triggered.connect(self.open) + self.actionTerminate.triggered.connect(self.terminate) ''' Handles all the buttons of different components. @@ -154,12 +158,30 @@ class MainApp(QMainWindow,ui): selected by the user. ''' def simulate(self,mode): - self.Container.simulate(mode) + self.thrd = threading.Thread(target=self.Container.simulate, args=(mode,)) + self.thrd.start() + # self.Container.simulate(mode) self.dockWidget_2.show() self.res = resdockWidget(self.Container) self.addDockWidget(Qt.LeftDockWidgetArea, self.res) self.res.show() + 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.currentTime())+"]<b> Terminating the simulation </b></span>") + 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 ''' |