mirror of
https://github.com/CoolProp/CoolProp.git
synced 2026-01-10 14:38:11 -05:00
478 lines
16 KiB
Python
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()
|