Files
CoolProp/wrappers/Python/CoolProp/GUI/CoolPropGUI.py
2019-01-12 20:45:25 -07:00

478 lines
16 KiB
Python

import wx
import wx.grid
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as WXCanvas
from matplotlib.backends.backend_wxagg import NavigationToolbar2Wx as WXToolbar
import matplotlib as mpl
import CoolProp as CP
from CoolProp.Plots.Plots import Ph, Ts
from CoolProp.Plots import PsychChart
import numpy as np
# Munge the system path if necessary to add the lib folder (only really needed
# for packaging using cx_Freeze)
#if os.path.exists('lib') and os.path.abspath(os.path.join(os.curdir,'lib')) not in os.:
class PlotPanel(wx.Panel):
def __init__(self, parent, **kwargs):
wx.Panel.__init__(self, parent, **kwargs)
sizer = wx.BoxSizer(wx.VERTICAL)
self.figure = mpl.figure.Figure(dpi=100)
self.canvas = WXCanvas(self, -1, self.figure)
self.ax = self.figure.add_axes((0.15,0.15,0.8,0.8))
#self.toolbar = WXToolbar(self.canvas)
#self.toolbar.Realize()
sizer.Add(self.canvas,1,wx.EXPAND)
#sizer.Add(self.toolbar)
self.SetSizer(sizer)
sizer.Layout()
class TSPlotFrame(wx.Frame):
def __init__(self, Fluid):
wx.Frame.__init__(self, None,title='T-s plot: '+Fluid)
sizer = wx.BoxSizer(wx.HORIZONTAL)
self.PP = PlotPanel(self, size = (-1,-1))
sizer.Add(self.PP, 1, wx.EXPAND)
self.SetSizer(sizer)
Ts(str(Fluid),
axis = self.PP.ax,
Tmin = CP.CoolProp.Props(str(Fluid),'Ttriple')+0.01)
sizer.Layout()
self.add_menu()
def add_menu(self):
# Menu Bar
self.MenuBar = wx.MenuBar()
self.File = wx.Menu()
mnuItem = wx.MenuItem(self.File, -1, "Edit...", "", wx.ITEM_NORMAL)
self.File.AppendItem(mnuItem)
self.MenuBar.Append(self.File, "File")
self.SetMenuBar(self.MenuBar)
class PsychOptions(wx.Dialog):
def __init__(self,parent):
wx.Dialog.__init__(self,parent)
self.build_contents()
self.layout()
def build_contents(self):
self.p_label = wx.StaticText(self,label='Pressure [kPa (absolute)]')
self.p = wx.TextCtrl(self,value = '101.325')
self.Tmin_label = wx.StaticText(self,label='Minimum dry bulb temperature [\xb0 C]')
self.Tmin = wx.TextCtrl(self,value = '-10')
self.Tmax_label = wx.StaticText(self,label='Maximum dry bulb temperature [\xb0 C]')
self.Tmax = wx.TextCtrl(self,value = '60')
self.GoButton = wx.Button(self,label='Accept')
self.GoButton.Bind(wx.EVT_BUTTON,self.OnAccept)
def OnAccept(self, event):
self.EndModal(wx.ID_OK)
def layout(self):
sizer = wx.FlexGridSizer(cols = 2)
sizer.AddMany([self.p_label,self.p,self.Tmin_label,self.Tmin,self.Tmax_label,self.Tmax])
sizer.Add(self.GoButton)
sizer.Layout()
self.Fit()
class PsychPlotFrame(wx.Frame):
def __init__(self,Tmin = 263.15,Tmax=333.15,p = 101.325, **kwargs):
wx.Frame.__init__(self, None, title='Psychrometric plot', **kwargs)
sizer = wx.BoxSizer(wx.HORIZONTAL)
self.PP = PlotPanel(self)
self.PP.figure.delaxes(self.PP.ax)
self.PP.ax = self.PP.figure.add_axes((0.1,0.1,0.85,0.85))
sizer.Add(self.PP, 1, wx.EXPAND)
self.SetSizer(sizer)
PsychChart.p = p
PsychChart.Tdb = np.linspace(Tmin,Tmax)
SL = PsychChart.SaturationLine()
SL.plot(self.PP.ax)
RHL = PsychChart.HumidityLines([0.05,0.1,0.15,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9])
RHL.plot(self.PP.ax)
HL = PsychChart.EnthalpyLines(range(-20,100,10))
HL.plot(self.PP.ax)
PF = PsychChart.PlotFormatting()
PF.plot(self.PP.ax)
sizer.Layout()
self.add_menu()
self.PP.toolbar = WXToolbar(self.PP.canvas)
self.PP.toolbar.Realize()
self.PP.GetSizer().Add(self.PP.toolbar)
self.PP.Layout()
def add_menu(self):
# Menu Bar
self.MenuBar = wx.MenuBar()
self.File = wx.Menu()
mnuItem = wx.MenuItem(self.File, -1, "Edit...", "", wx.ITEM_NORMAL)
self.File.AppendItem(mnuItem)
self.MenuBar.Append(self.File, "File")
self.SetMenuBar(self.MenuBar)
class PHPlotFrame(wx.Frame):
def __init__(self, Fluid):
wx.Frame.__init__(self, None,title='p-h plot: '+Fluid)
sizer = wx.BoxSizer(wx.HORIZONTAL)
self.PP = PlotPanel(self, size = (-1,-1))
sizer.Add(self.PP, 1, wx.EXPAND)
self.SetSizer(sizer)
Ph(str(Fluid),
axis = self.PP.ax,
Tmin = CP.CoolProp.Props(str(Fluid),'Ttriple')+0.01)
sizer.Layout()
self.add_menu()
def add_menu(self):
# Menu Bar
self.MenuBar = wx.MenuBar()
self.File = wx.Menu()
mnuItem = wx.MenuItem(self.File, -1, "Edit...", "", wx.ITEM_NORMAL)
self.File.AppendItem(mnuItem)
self.MenuBar.Append(self.File, "File")
self.SetMenuBar(self.MenuBar)
def overlay_points(self):
pass
def overlay_cycle(self):
pass
class SimpleGrid(wx.grid.Grid):
def __init__(self, parent, ncol = 20, nrow = 8):
wx.grid.Grid.__init__(self, parent)
self.CreateGrid(ncol, nrow)
[self.SetCellValue(i,j,'0.0') for i in range(20) for j in range(8)]
class SaturationTableDialog(wx.Dialog):
def __init__(self, parent):
wx.Dialog.__init__(self,parent)
self.FluidLabel = wx.StaticText(self,label = "Fluid")
self.FluidCombo = wx.ComboBox(self)
self.FluidCombo.AppendItems(sorted(CP.__fluids__))
self.FluidCombo.SetEditable(False)
self.TtripleLabel = wx.StaticText(self,label = "Critical Temperature [K]")
self.TtripleValue = wx.TextCtrl(self)
self.TtripleValue.Enable(False)
self.TcritLabel = wx.StaticText(self,label = "Critical Temperature [K]")
self.TcritValue = wx.TextCtrl(self)
self.TcritValue.Enable(False)
self.NvalsLabel = wx.StaticText(self,label = "Number of values")
self.NvalsValue = wx.TextCtrl(self)
self.TminLabel = wx.StaticText(self,label = "Minimum Temperature [K]")
self.TminValue = wx.TextCtrl(self)
self.TmaxLabel = wx.StaticText(self,label = "Maximum Temperature [K]")
self.TmaxValue = wx.TextCtrl(self)
self.Accept = wx.Button(self, label ="Accept")
sizer = wx.FlexGridSizer(cols = 2)
sizer.AddMany([self.FluidLabel,self.FluidCombo,
self.TtripleLabel,self.TtripleValue,
self.TcritLabel, self.TcritValue])
sizer.AddSpacer(10)
sizer.AddSpacer(10)
sizer.AddMany([self.NvalsLabel,self.NvalsValue,
self.TminLabel, self.TminValue,
self.TmaxLabel, self.TmaxValue])
sizer.Add(self.Accept)
self.Bind(wx.EVT_COMBOBOX, self.OnSelectFluid)
self.Bind(wx.EVT_BUTTON, self.OnAccept)
self.SetSizer(sizer)
sizer.Layout()
self.Fit()
#Bind a key-press event to all objects to get Esc
children = self.GetChildren()
for child in children:
child.Bind(wx.EVT_KEY_UP, self.OnKeyPress)
def OnKeyPress(self,event = None):
""" cancel if Escape key is pressed """
event.Skip()
if event.GetKeyCode() == wx.WXK_ESCAPE:
self.EndModal(wx.ID_CANCEL)
def get_values(self):
Fluid = str(self.FluidCombo.GetStringSelection())
if Fluid:
N = float(self.NvalsValue.GetValue())
Tmin = float(self.TminValue.GetValue())
Tmax = float(self.TmaxValue.GetValue())
Tvals = np.linspace(Tmin, Tmax, N)
return Fluid, Tvals
else:
return '',[]
def OnCheckTmin(self):
pass
def OnCheckTmax(self):
pass
def OnAccept(self, event = None):
self.EndModal(wx.ID_OK)
def OnSelectFluid(self, event = None):
Fluid = str(self.FluidCombo.GetStringSelection())
if Fluid:
Tcrit = CP.CoolProp.Props(Fluid,'Tcrit')
Ttriple = CP.CoolProp.Props(Fluid,'Ttriple')
self.TcritValue.SetValue(str(Tcrit))
self.TtripleValue.SetValue(str(Ttriple))
self.NvalsValue.SetValue('100')
self.TminValue.SetValue(str(Ttriple + 0.01))
self.TmaxValue.SetValue(str(Tcrit - 0.01))
class SaturationTable(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent)
self.Fluid, self.Tvals = self.OnSelect()
if self.Fluid:
self.tbl = SimpleGrid(self,
ncol = len(self.Tvals)
)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.tbl,1,wx.EXPAND)
self.SetSizer(sizer)
sizer.Layout()
self.build()
self.add_menu()
else:
self.Destroy()
def OnSelect(self, event = None):
dlg = SaturationTableDialog(None)
if dlg.ShowModal() == wx.ID_OK:
Fluid,Tvals = dlg.get_values()
cancel = False
else:
cancel = True
dlg.Destroy()
if not cancel:
return Fluid,Tvals
else:
return None,None
def build(self):
self.SetTitle('Saturation Table: '+self.Fluid)
self.tbl.SetColLabelValue(0, "Temperature\n[K]")
self.tbl.SetColLabelValue(1, "Liquid Pressure\n[kPa]")
self.tbl.SetColLabelValue(2, "Vapor Pressure\n[kPa]")
self.tbl.SetColLabelValue(3, "Liquid Density\n[kg/m3]")
self.tbl.SetColLabelValue(4, "Vapor Density\n[kg/m3]")
for i,T in enumerate(self.Tvals):
Fluid = self.Fluid
pL = CP.CoolProp.Props('P','T',T,'Q',0,Fluid)
pV = CP.CoolProp.Props('P','T',T,'Q',1,Fluid)
rhoL = CP.CoolProp.Props('D','T',T,'Q',0,Fluid)
rhoV = CP.CoolProp.Props('D','T',T,'Q',1,Fluid)
self.tbl.SetCellValue(i,0,str(T))
self.tbl.SetCellValue(i,1,str(pL))
self.tbl.SetCellValue(i,2,str(pV))
self.tbl.SetCellValue(i,3,str(rhoL))
self.tbl.SetCellValue(i,4,str(rhoV))
def add_menu(self):
# Menu Bar
self.MenuBar = wx.MenuBar()
self.File = wx.Menu()
mnuItem0 = wx.MenuItem(self.File, -1, "Select All \tCtrl+A", "", wx.ITEM_NORMAL)
mnuItem1 = wx.MenuItem(self.File, -1, "Copy selected data \tCtrl+C", "", wx.ITEM_NORMAL)
mnuItem2 = wx.MenuItem(self.File, -1, "Copy table w/ headers \tCtrl+H", "", wx.ITEM_NORMAL)
self.File.AppendItem(mnuItem0)
self.File.AppendItem(mnuItem1)
self.File.AppendItem(mnuItem2)
self.MenuBar.Append(self.File, "Edit")
self.Bind(wx.EVT_MENU, lambda event: self.tbl.SelectAll(), mnuItem0)
self.Bind(wx.EVT_MENU, self.OnCopy, mnuItem1)
self.Bind(wx.EVT_MENU, self.OnCopyHeaders, mnuItem2)
self.SetMenuBar(self.MenuBar)
def OnCopy(self, event = None):
# Number of rows and cols
rows = self.tbl.GetSelectionBlockBottomRight()[0][0] - self.tbl.GetSelectionBlockTopLeft()[0][0] + 1
cols = self.tbl.GetSelectionBlockBottomRight()[0][1] - self.tbl.GetSelectionBlockTopLeft()[0][1] + 1
# data variable contain text that must be set in the clipboard
data = ''
# For each cell in selected range append the cell value in the data variable
# Tabs '\t' for cols and '\r' for rows
for r in range(rows):
for c in range(cols):
data = data + str(self.tbl.GetCellValue(self.tbl.GetSelectionBlockTopLeft()[0][0] + r, self.tbl.GetSelectionBlockTopLeft()[0][1] + c))
if c < cols - 1:
data = data + '\t'
data = data + '\n'
# Create text data object
clipboard = wx.TextDataObject()
# Set data object value
clipboard.SetText(data)
# Put the data in the clipboard
if wx.TheClipboard.Open():
wx.TheClipboard.SetData(clipboard)
wx.TheClipboard.Close()
else:
wx.MessageBox("Can't open the clipboard", "Error")
event.Skip()
def OnCopyHeaders(self, event = None):
self.tbl.SelectAll()
# Number of rows and cols
rows = self.tbl.GetSelectionBlockBottomRight()[0][0] - self.tbl.GetSelectionBlockTopLeft()[0][0] + 1
cols = self.tbl.GetSelectionBlockBottomRight()[0][1] - self.tbl.GetSelectionBlockTopLeft()[0][1] + 1
# data variable contain text that must be set in the clipboard
data = ''
#Add the headers
for c in range(cols):
data += str(self.tbl.GetColLabelValue(c).replace('\n',' '))
if c < cols - 1:
data += '\t'
data = data + '\n'
# For each cell in selected range append the cell value in the data variable
# Tabs '\t' for cols and '\r' for rows
for r in range(rows):
for c in range(cols):
data = data + str(self.tbl.GetCellValue(self.tbl.GetSelectionBlockTopLeft()[0][0] + r, self.tbl.GetSelectionBlockTopLeft()[0][1] + c))
if c < cols - 1:
data = data + '\t'
data = data + '\n'
# Create text data object
clipboard = wx.TextDataObject()
# Set data object value
clipboard.SetText(data)
# Put the data in the clipboard
if wx.TheClipboard.Open():
wx.TheClipboard.SetData(clipboard)
wx.TheClipboard.Close()
else:
wx.MessageBox("Can't open the clipboard", "Error")
event.Skip()
class MainFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None)
self.build()
def build(self):
# Menu Bar
self.MenuBar = wx.MenuBar()
self.plots = wx.Menu()
self.PHPlot = wx.Menu()
self.TSPlot = wx.Menu()
self.tables = wx.Menu()
self.PsychPlot = wx.MenuItem(self.plots,-1,'Psychrometric Plot')
self.SatTable = wx.MenuItem(self.tables, -1,' Saturation Table', "", wx.ITEM_NORMAL)
for Fluid in sorted(CP.__fluids__):
mnuItem = wx.MenuItem(self.PHPlot, -1, Fluid, "", wx.ITEM_NORMAL)
self.PHPlot.AppendItem(mnuItem)
self.Bind(wx.EVT_MENU, lambda event: self.OnPHPlot(event, mnuItem), mnuItem)
mnuItem = wx.MenuItem(self.TSPlot, -1, Fluid, "", wx.ITEM_NORMAL)
self.TSPlot.AppendItem(mnuItem)
self.Bind(wx.EVT_MENU, lambda event: self.OnTSPlot(event, mnuItem), mnuItem)
self.MenuBar.Append(self.plots, "Plots")
self.plots.AppendItem(self.PsychPlot)
self.plots.AppendMenu(-1,'p-h plot', self.PHPlot)
self.plots.AppendMenu(-1,'T-s plot', self.TSPlot)
self.MenuBar.Append(self.tables, "Tables")
self.tables.AppendItem(self.SatTable)
self.Bind(wx.EVT_MENU, self.OnSatTable, self.SatTable)
self.Bind(wx.EVT_MENU, self.OnPsychPlot, self.PsychPlot)
self.SetMenuBar(self.MenuBar)
def OnPsychPlot(self, event=None):
#Load the options
dlg = PsychOptions(None)
if dlg.ShowModal() == wx.ID_OK:
Tmin = float(dlg.Tmin.GetValue())+273.15
Tmax = float(dlg.Tmax.GetValue())+273.15
p = float(dlg.p.GetValue())
PPF = PsychPlotFrame(Tmin = Tmin, Tmax = Tmax, p = p, size = (1000,700))
PPF.Show()
dlg.Destroy()
def OnSatTable(self,event):
TBL = SaturationTable(None)
TBL.Show()
def OnPHPlot(self, event, mnuItem):
#Make a p-h plot instance in a new frame
#Get the label (Fluid name)
Fluid = self.PHPlot.FindItemById(event.Id).Label
PH = PHPlotFrame(Fluid)
PH.Show()
def OnTSPlot(self, event, mnuItem):
#Make a p-h plot instance in a new frame
#Get the label (Fluid name)
Fluid = self.TSPlot.FindItemById(event.Id).Label
TS = TSPlotFrame(Fluid)
TS.Show()
if __name__=='__main__':
app = wx.App(False)
wx.InitAllImageHandlers()
frame = MainFrame()
frame.Show(True)
app.MainLoop()