mirror of
https://github.com/Cantera/cantera.git
synced 2025-02-25 18:55:29 -06:00
Add current version of MixMaster to the Cython package
Note that this currently doesn't work at all, due to both Python 3 compatibility issues as well as the changes to the Cantera Python API
This commit is contained in:
@@ -30,6 +30,8 @@ def add_dependencies(mod, ext):
|
||||
localenv.Depends(ext, f)
|
||||
|
||||
for f in (mglob(localenv, 'cantera/test', 'py') +
|
||||
mglob(localenv, 'cantera/mixmaster', 'py') +
|
||||
mglob(localenv, 'cantera/mixmaster/Units', 'py') +
|
||||
mglob(localenv, 'cantera/examples/tutorial', 'py') +
|
||||
mglob(localenv, 'cantera/examples/equilibrium', 'py') +
|
||||
mglob(localenv, 'cantera/examples/kinetics', 'py') +
|
||||
|
||||
244
interfaces/cython/cantera/mixmaster/CompositionFrame.py
Normal file
244
interfaces/cython/cantera/mixmaster/CompositionFrame.py
Normal file
@@ -0,0 +1,244 @@
|
||||
from Tkinter import *
|
||||
from Cantera import *
|
||||
|
||||
from SpeciesInfo import SpeciesInfo
|
||||
#from KineticsFrame import KineticsFrame
|
||||
|
||||
_CUTOFF = 1.e-15
|
||||
_ATOL = 1.e-15
|
||||
_RTOL = 1.e-7
|
||||
|
||||
class CompFrame(Frame):
|
||||
def __init__(self,master):
|
||||
Frame.__init__(self,master)
|
||||
self.config(relief=FLAT, bd=4)
|
||||
self.top = self.master.top
|
||||
self.controls=Frame(self)
|
||||
self.hide = IntVar()
|
||||
self.hide.set(0)
|
||||
self.comp = IntVar()
|
||||
self.comp.set(0)
|
||||
self.controls.grid(column=1,row=0,sticky=W+E+N)
|
||||
self.makeControls()
|
||||
mf = self.master
|
||||
|
||||
def makeControls(self):
|
||||
Radiobutton(self.controls,text='Moles',
|
||||
variable=self.comp,value=0,
|
||||
command=self.show).grid(column=0,row=0,sticky=W)
|
||||
Radiobutton(self.controls,text='Mass',
|
||||
variable=self.comp,value=1,
|
||||
command=self.show).grid(column=0,row=1,sticky=W)
|
||||
Radiobutton(self.controls,text='Concentration',
|
||||
variable=self.comp,value=2,
|
||||
command=self.show).grid(column=0,row=2,sticky=W)
|
||||
Button(self.controls,text='Clear',
|
||||
command=self.zero).grid(column=0,row=4,sticky=W+E)
|
||||
Button(self.controls,text='Normalize',
|
||||
command=self.norm).grid(column=0,row=5,sticky=W+E)
|
||||
Checkbutton(self.controls,text='Hide Missing\nSpecies',
|
||||
variable=self.hide,onvalue=1,
|
||||
offvalue=0,command=self.master.redo).grid(column=0,
|
||||
row=3,
|
||||
sticky=W)
|
||||
|
||||
def norm(self):
|
||||
mf = self.master
|
||||
mf.update()
|
||||
|
||||
data = mf.comp
|
||||
sum = 0.0
|
||||
for sp in data:
|
||||
sum += sp
|
||||
for i in range(len(mf.comp)):
|
||||
mf.comp[i] /= sum
|
||||
self.show()
|
||||
|
||||
def set(self):
|
||||
c = self.comp.get()
|
||||
mix = self.top.mix
|
||||
mf = self.master
|
||||
g = mix.g
|
||||
if c == 0:
|
||||
mix.setMoles(mf.comp)
|
||||
|
||||
elif c == 1:
|
||||
mix.setMass(mf.comp)
|
||||
|
||||
elif c == 2:
|
||||
pass
|
||||
self.top.thermo.setState()
|
||||
self.top.kinetics.show()
|
||||
|
||||
def show(self):
|
||||
mf = self.master
|
||||
mf.active = self
|
||||
c = self.comp.get()
|
||||
mix = self.top.mix
|
||||
g = mix.g
|
||||
if c == 0:
|
||||
mf.var.set("Moles")
|
||||
#mf.data = spdict(mix.g, mix.moles())
|
||||
mf.comp = mix.moles()
|
||||
|
||||
elif c == 1:
|
||||
mf.var.set("Mass")
|
||||
#mf.data = spdict(mix.g,mix.mass())
|
||||
mf.comp = mix.mass()
|
||||
|
||||
elif c == 2:
|
||||
mf.var.set("Concentration")
|
||||
mf.comp = mix.concentrations()
|
||||
#mf.data = spdict(mix,mix,mf.comp)
|
||||
|
||||
for s in mf.variable.keys():
|
||||
try:
|
||||
k = g.speciesIndex(s)
|
||||
if mf.comp[k] > _CUTOFF:
|
||||
mf.variable[s].set(mf.comp[k])
|
||||
else:
|
||||
mf.variable[s].set(0.0)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def zero(self):
|
||||
mf = self.master
|
||||
mf.comp *= 0.0
|
||||
self.show()
|
||||
|
||||
|
||||
|
||||
class MixtureFrame(Frame):
|
||||
def __init__(self,master,top):
|
||||
Frame.__init__(self,master)
|
||||
self.config(relief=GROOVE, bd=4)
|
||||
self.top = top
|
||||
self.top.mixframe = self
|
||||
self.g = self.top.mix.g
|
||||
#self.scroll = Scrollbar(self)
|
||||
self.entries=Frame(self)
|
||||
#self.scroll.config(command=self.entries.xview)
|
||||
#self.scroll.grid(column=0,row=1)
|
||||
self.var = StringVar()
|
||||
self.var.set("Moles")
|
||||
self.comp = array(self.top.mix.moles())
|
||||
self.names = self.top.mix.speciesNames()
|
||||
self.nsp = len(self.names)
|
||||
#self.data = self.top.mix.moleDict()
|
||||
self.makeControls()
|
||||
self.makeEntries()
|
||||
self.entries.bind('<Double-l>',self.minimize)
|
||||
self.ctype = 0
|
||||
self.newcomp = 0
|
||||
|
||||
def makeControls(self):
|
||||
self.c = CompFrame(self)
|
||||
#self.k = KineticsFrame(self)
|
||||
self.active = self.c
|
||||
self.c.grid(column=1,row=0,sticky=E+W+N+S)
|
||||
#self.k.grid(column=2,row=0,sticky=E+W+N+S)
|
||||
|
||||
def update(self):
|
||||
self.newcomp = 0
|
||||
for s in self.variable.keys():
|
||||
k = self.g.speciesIndex(s)
|
||||
current = self.comp[k]
|
||||
val = self.variable[s].get()
|
||||
dv = abs(val - current)
|
||||
if dv > _RTOL*abs(current) + _ATOL:
|
||||
self.comp[k] = val
|
||||
self.newcomp = 1
|
||||
|
||||
def show(self):
|
||||
self.active.show()
|
||||
## for k in range(self.nsp):
|
||||
## sp = self.names[k]
|
||||
## if self.comp[k] > _CUTOFF:
|
||||
## self.variable[sp].set(self.comp[k])
|
||||
## else:
|
||||
## self.variable[sp].set(0.0)
|
||||
|
||||
def redo(self):
|
||||
self.update()
|
||||
self.entries.destroy()
|
||||
self.entries=Frame(self)
|
||||
self.makeEntries()
|
||||
|
||||
def minimize(self,Event=None):
|
||||
self.c.hide.set(1)
|
||||
self.redo()
|
||||
self.c.grid_forget()
|
||||
self.entries.bind("<Double-1>",self.maximize)
|
||||
|
||||
def maximize(self,Event=None):
|
||||
self.c.hide.set(0)
|
||||
self.redo()
|
||||
self.c.grid(column=1,row=0,sticky=E+W+N+S)
|
||||
self.entries.bind("<Double-1>",self.minimize)
|
||||
|
||||
def up(self, x):
|
||||
self.update()
|
||||
if self.newcomp:
|
||||
self.c.set()
|
||||
self.c.show()
|
||||
self.top.update()
|
||||
#thermo.showState()
|
||||
#self.top.kinetics.show()
|
||||
|
||||
def makeEntries(self):
|
||||
self.entries.grid(row=0,column=0,sticky=W+N+S+E)
|
||||
self.entries.config(relief=FLAT,bd=4)
|
||||
DATAKEYS = self.top.species
|
||||
self.variable = {}
|
||||
|
||||
n=0
|
||||
ncol = 3
|
||||
col = 0
|
||||
row = 60
|
||||
|
||||
equil = 0
|
||||
if self.top.thermo:
|
||||
equil = self.top.thermo.equil.get()
|
||||
|
||||
for sp in DATAKEYS:
|
||||
s = sp # self.top.species[sp]
|
||||
k = s.index
|
||||
if row > 25:
|
||||
row = 0
|
||||
col = col + 2
|
||||
l = Label(self.entries,text='Species')
|
||||
l.grid(column=col,row=row,sticky=E+W)
|
||||
e1 = Entry(self.entries)
|
||||
e1.grid(column=col+1,row=row,sticky=E+W)
|
||||
e1['textvariable'] = self.var
|
||||
e1.config(state=DISABLED)
|
||||
e1.config(bg='lightyellow',relief=RIDGE)
|
||||
row = row + 1
|
||||
|
||||
spname = s.name
|
||||
val = self.comp[k]
|
||||
if not self.c.hide.get() or val: showit = 1
|
||||
else: showit = 0
|
||||
|
||||
l=SpeciesInfo(self.entries,species=s,
|
||||
text=spname,relief=FLAT,justify=RIGHT,
|
||||
fg='darkblue')
|
||||
entry1 = Entry(self.entries)
|
||||
self.variable[spname] = DoubleVar()
|
||||
self.variable[spname].set(self.comp[k])
|
||||
entry1['textvariable']=self.variable[spname]
|
||||
entry1.bind('<Any-Leave>',self.up)
|
||||
if showit:
|
||||
l.grid(column= col ,row=row,sticky=E)
|
||||
entry1.grid(column=col+1,row=row)
|
||||
n=n+1
|
||||
row = row + 1
|
||||
if equil == 1:
|
||||
entry1.config(state=DISABLED,bg='lightgray')
|
||||
## if self.c.hide.get():
|
||||
## b=Button(self.entries,height=1,command=self.maximize)
|
||||
## else:
|
||||
## b=Button(self.entries,command=self.minimize)
|
||||
## b.grid(column=col,columnspan=2, row=row+1)
|
||||
213
interfaces/cython/cantera/mixmaster/ControlPanel.py
Normal file
213
interfaces/cython/cantera/mixmaster/ControlPanel.py
Normal file
@@ -0,0 +1,213 @@
|
||||
from types import *
|
||||
from Tkinter import *
|
||||
from ScrolledText import ScrolledText
|
||||
#import datawindow
|
||||
#import filewindow
|
||||
|
||||
def ff():
|
||||
print ' hi '
|
||||
|
||||
class ControlWindow(Frame):
|
||||
fncs = [ff]*10
|
||||
|
||||
def __init__(self, title, master=None):
|
||||
self.app = master
|
||||
Frame.__init__(self,master)
|
||||
self.grid(row=0,column=0,sticky=E+W+N+S)
|
||||
self.master.title(title)
|
||||
|
||||
|
||||
def addButtons(self, label, funcs):
|
||||
self.buttonholder = Frame(self, relief=FLAT, bd=2)
|
||||
self.buttonholder.pack(side=TOP,anchor=W)
|
||||
b = Label(self.buttonholder,text=label)
|
||||
b.pack(side=LEFT,fill=X)
|
||||
for f in funcs:
|
||||
b=Button(self.buttonholder,
|
||||
text=f[0],command=f[1], padx=1,pady=1)
|
||||
b.pack(side=LEFT,fill=X)
|
||||
|
||||
def disableButtons(self, *buttons):
|
||||
for button in self.buttonholder.slaves():
|
||||
if (button.cget('text') in buttons):
|
||||
try:
|
||||
button.config(state=DISABLED)
|
||||
except:
|
||||
pass
|
||||
|
||||
def enableButtons(self, *buttons):
|
||||
for button in self.buttonholder.slaves():
|
||||
if (button.cget('text') in buttons):
|
||||
try:
|
||||
button.config(state=NORMAL)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def newFrame(self, label, var):
|
||||
fr = Frame(self, relief = RIDGE, bd = 2)
|
||||
fr.pack(side=TOP,fill=X)
|
||||
c = Checkbutton(fr, variable=var)
|
||||
c.pack(side = LEFT, fill = X)
|
||||
b = Label(fr,text=label,foreground="NavyBlue")
|
||||
b.pack(side=LEFT,fill=X)
|
||||
return fr
|
||||
|
||||
##creates a new Toplevel object
|
||||
##options: transient=<callback for window close>,
|
||||
## placement=(<screen x-coord>, <screen y-coord>)
|
||||
def newWindow(self, master, title, **options):
|
||||
new = Toplevel(master)
|
||||
new.title(title)
|
||||
#new.config(takefocus=0)
|
||||
if 'transient' in options.keys():
|
||||
new.transient(master)
|
||||
if options['transient']:
|
||||
new.protocol('WM_DELETE_WINDOW', options['transient'])
|
||||
if 'placement' in options.keys():
|
||||
new.geometry("+%d+%d" % tuple(options['placement']))
|
||||
return new
|
||||
|
||||
##routes mouse and keyboard events to the window and
|
||||
##waits for it to close before returning
|
||||
def makemodal(self, window):
|
||||
window.focus_set()
|
||||
window.grab_set()
|
||||
window.wait_window()
|
||||
return
|
||||
|
||||
|
||||
def PlotMenu(self, fr, label, funcs):
|
||||
filebutton = Menubutton(fr,text=label, padx=3,pady=1)
|
||||
filebutton.pack(side=LEFT)
|
||||
filemenu = Menu(filebutton,tearoff=TRUE)
|
||||
i = 0
|
||||
for f in funcs:
|
||||
filemenu.add_command(label=f[0], command=f[1])
|
||||
i = i + 1
|
||||
filebutton['menu']=filemenu
|
||||
return filemenu
|
||||
|
||||
def testevent(event):
|
||||
print 'event ',event.value
|
||||
|
||||
def make_menu(name, menubar, list):
|
||||
nc = len(name)
|
||||
button=Menubutton(menubar, text=name, width=nc+4, padx=3,pady=1)
|
||||
button.pack(side=LEFT)
|
||||
menu = Menu(button,tearoff=FALSE)
|
||||
m = menu
|
||||
i = 0
|
||||
for entry in list:
|
||||
i += 1
|
||||
if entry == 'separator':
|
||||
menu.add_separator({})
|
||||
elif type(entry)==ListType:
|
||||
for num in entry:
|
||||
menu.entryconfig(num,state=DISABLED)
|
||||
elif type(entry[1]) != ListType:
|
||||
if i == 20:
|
||||
i = 0
|
||||
submenu = Menu(button,tearoff=FALSE)
|
||||
m.add_cascade(label='More...',
|
||||
menu=submenu)
|
||||
m = submenu
|
||||
if len(entry) == 2 or entry[2] == 'command':
|
||||
m.add_command(label=entry[0],
|
||||
command=entry[1])
|
||||
elif entry[2] == 'check':
|
||||
entry[3].set(0)
|
||||
if len(entry) >= 5: val = entry[4]
|
||||
else: val = 1
|
||||
m.add_checkbutton(label=entry[0],
|
||||
command=entry[1],
|
||||
variable = entry[3],
|
||||
onvalue=val)
|
||||
else:
|
||||
submenu=make_menu(entry[0], menu, entry[1])
|
||||
m.add_cascade(label=entry[0],
|
||||
menu=submenu)
|
||||
button['menu']=menu
|
||||
return button
|
||||
|
||||
def menuitem_state(button, *statelist):
|
||||
for menu in button.children.keys():
|
||||
if isinstance(button.children[menu], Menu):
|
||||
for (commandnum, onoff) in statelist:
|
||||
if onoff==0:
|
||||
button.children[menu].entryconfig(commandnum,state=DISABLED)
|
||||
if onoff==1:
|
||||
button.children[menu].entryconfig(commandnum,state=NORMAL)
|
||||
else:
|
||||
pass
|
||||
|
||||
class ArgumentWindow(Toplevel):
|
||||
import tkMessageBox
|
||||
def __init__(self, sim, **options):
|
||||
Toplevel.__init__(self, sim.cwin)
|
||||
self.resizable(FALSE,FALSE)
|
||||
self.protocol("WM_DELETE_WINDOW", lambda:0) #self.cancelled)
|
||||
self.transient(sim.cwin)
|
||||
if 'placement' in options.keys():
|
||||
self.geometry("+%d+%d" % tuple(options['placement']))
|
||||
self.title('Thermal Model Initialization')
|
||||
self.sim = sim
|
||||
|
||||
self.make_options()
|
||||
|
||||
buttonframe = Frame(self)
|
||||
buttonframe.pack(side=BOTTOM)
|
||||
b1=Button(buttonframe, text='OK', command=self.callback)
|
||||
b1.pack(side=LEFT)
|
||||
#b2=Button(buttonframe, text='Cancel', command=self.cancelled)
|
||||
#b2.pack(side=LEFT)
|
||||
self.bind("<Return>", self.callback)
|
||||
#self.bind("<Escape>", self.cancelled)
|
||||
|
||||
self.initial_focus = self
|
||||
self.initial_focus.focus_set()
|
||||
#self.wait_window(self)
|
||||
|
||||
def make_options(self):
|
||||
pass
|
||||
|
||||
### must override this function ###
|
||||
### with the entry forms ###
|
||||
### be sure to use pack or a ###
|
||||
### frame that is packed into self ###
|
||||
|
||||
def getArguments(self):
|
||||
pass
|
||||
|
||||
### must override this function ###
|
||||
### with the validation checking ###
|
||||
### must return None if error, ###
|
||||
### and non_null if ok ###
|
||||
|
||||
|
||||
def callback(self, event=None):
|
||||
g=self.getArguments()
|
||||
if not g:
|
||||
self.initial_focus.focus_set()
|
||||
return
|
||||
self.withdraw()
|
||||
self.update_idletasks()
|
||||
|
||||
self.assign(g)
|
||||
self.cancelled()
|
||||
|
||||
def assign(self, obj):
|
||||
pass
|
||||
|
||||
### must override this function ###
|
||||
### to do the assignment in sim ###
|
||||
|
||||
def cancelled(self,event=None):
|
||||
self.sim.cwin.focus_set()
|
||||
self.destroy()
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
t = Tk()
|
||||
ControlWindow(t).mainloop()
|
||||
359
interfaces/cython/cantera/mixmaster/DataFrame.py
Normal file
359
interfaces/cython/cantera/mixmaster/DataFrame.py
Normal file
@@ -0,0 +1,359 @@
|
||||
import os, math, string
|
||||
from Tkinter import *
|
||||
from Cantera import *
|
||||
from Cantera.num import *
|
||||
from Cantera import num
|
||||
from tkFileDialog import askopenfilename
|
||||
from GraphFrame import Graph
|
||||
from DataGraph import DataGraph, plotLimits
|
||||
from ControlPanel import make_menu
|
||||
|
||||
|
||||
U_LOC = 1
|
||||
V_LOC = 2
|
||||
T_LOC = 3
|
||||
P_LOC = 4
|
||||
Y_LOC = 5
|
||||
|
||||
def testit(e = None):
|
||||
pass
|
||||
|
||||
class DataFrame(Frame):
|
||||
|
||||
def __init__(self,master,top):
|
||||
# if master==None:
|
||||
self.master = Toplevel()
|
||||
self.master.protocol("WM_DELETE_WINDOW",self.hide)
|
||||
#else:
|
||||
# self.master = master
|
||||
|
||||
#self.vis = vis
|
||||
Frame.__init__(self,self.master)
|
||||
self.config(relief=GROOVE, bd=4)
|
||||
self.top = top
|
||||
self.mix = self.top.mix
|
||||
self.g = self.top.mix.g
|
||||
self.data = None
|
||||
self.zdata = None
|
||||
self.ydata = None
|
||||
self.plt = None
|
||||
#self.pltwhat = None
|
||||
self.datasets = []
|
||||
self.vars = []
|
||||
self.whichsoln = IntVar()
|
||||
self.loc = IntVar()
|
||||
# self.loc.set(1)
|
||||
self.lastloc = T_LOC # self.loc.get()
|
||||
self.datafile = StringVar()
|
||||
self.solnid = StringVar()
|
||||
self.gr = Frame(self)
|
||||
self.n = IntVar()
|
||||
|
||||
self.scframe = Frame(self)
|
||||
self.sc = Scale(self.scframe, variable = self.n,
|
||||
orient='horizontal',digits=0,
|
||||
length=300,resolution=1,command=self.updateplot)
|
||||
self.sc.config(cnf={'from':0,'to':1})
|
||||
Label(self.scframe,text='Grid Point').grid(column=0,row=0)
|
||||
self.sc.grid(row=0,column=1)
|
||||
self.sc.bind('<ButtonRelease-1>',self.updateState)
|
||||
self.gr.grid(row=4,column=0,columnspan=10)
|
||||
|
||||
self.grid(column=0,row=10)
|
||||
self.makeMenu()
|
||||
self.hide()
|
||||
|
||||
|
||||
def makeMenu(self):
|
||||
self.menubar = Frame(self, relief=GROOVE,bd=2)
|
||||
self.menubar.grid(row=0,column=0,sticky=N+W+E,columnspan=10)
|
||||
f = [('Open...',self.browseForDatafile)]
|
||||
#make_menu('File',self.menubar,items)
|
||||
make_menu('File',self.menubar,f)
|
||||
make_menu('Dataset',self.menubar,self.datasets)
|
||||
make_menu('Plot',self.menubar,self.vars)
|
||||
|
||||
|
||||
def browseForDatafile(self, e=None):
|
||||
pathname = askopenfilename(
|
||||
filetypes=[("Data Files", ("*.xml","*.csv","*.dat")),
|
||||
("All Files", "*.*")])
|
||||
if pathname:
|
||||
self.datafile.set(pathname)
|
||||
self.show()
|
||||
self.getSoln()
|
||||
|
||||
def getSoln(self):
|
||||
fname = os.path.basename(self.datafile.get())
|
||||
ff = os.path.splitext(fname)
|
||||
self.datasets = []
|
||||
if len(ff) == 2 and (ff[1] == '.xml' or ff[1] == '.ctml'):
|
||||
|
||||
x = XML.XML_Node('root',src=self.datafile.get())
|
||||
c = x.child('ctml')
|
||||
self.solns = c.children('simulation')
|
||||
if len(self.solns) > 1:
|
||||
i = 0
|
||||
for soln in self.solns:
|
||||
self.datasets.append((soln['id'],self.pickSoln,
|
||||
'check',self.whichsoln,i))
|
||||
i += 1
|
||||
self.solnid.set(self.solns[-1]['id'])
|
||||
self.soln = self.solns[-1]
|
||||
|
||||
self.importData()
|
||||
|
||||
elif len(ff) == 2 and (ff[1] == '.csv' or ff[1] == '.CSV'):
|
||||
self.importCSV()
|
||||
|
||||
self.makeMenu()
|
||||
if self.loc.get() <= 0:
|
||||
self.loc.set(self.lastloc)
|
||||
|
||||
|
||||
def importCSV(self):
|
||||
self.lastloc = self.loc.get()
|
||||
if self.lastloc <= 0: self.lastloc = T_LOC
|
||||
self.vars = []
|
||||
self.zdata = None
|
||||
self.ydata = None
|
||||
if self.plt:
|
||||
self.plt.destroy()
|
||||
|
||||
f = open(self.datafile.get(),'r')
|
||||
lines = f.readlines()
|
||||
vars = string.split(lines[0],',')
|
||||
nlines = len(lines)
|
||||
self.np = nlines - 1
|
||||
nv = len(vars)
|
||||
vv = []
|
||||
for n in range(nv):
|
||||
nm = vars[n].split()
|
||||
if n < nv - 1 or (len(nm) > 0 and nm[0].isalnum()):
|
||||
vv.append(nm[0])
|
||||
else:
|
||||
break
|
||||
nv = len(vv)
|
||||
vars = vv
|
||||
fdata = zeros((nv, self.np),'d')
|
||||
for n in range(self.np):
|
||||
v = string.split(lines[n+1],',')
|
||||
for j in range(nv):
|
||||
try:
|
||||
fdata[j,n] = float(v[j])
|
||||
except:
|
||||
fdata[j,n] = 0.0
|
||||
|
||||
self.nsp = self.g.nSpecies()
|
||||
self.y = zeros(self.nsp,'d')
|
||||
self.data = zeros((self.nsp+6,self.np),'d')
|
||||
self.data[0,:] = fdata[0,:]
|
||||
self.label = ['-']*(self.nsp+6)
|
||||
self.label[0] = vars[0]
|
||||
w = []
|
||||
for n in range(1,nv-1):
|
||||
try:
|
||||
k = self.g.speciesIndex(vars[n])
|
||||
except:
|
||||
k = -1
|
||||
v2 = vars[n]
|
||||
if v2 == 'T':
|
||||
self.data[T_LOC,:] = fdata[n,:]
|
||||
self.label[T_LOC] = vars[n]
|
||||
w.append(('T', self.newplot, 'check', self.loc, T_LOC))
|
||||
elif v2 == 'P':
|
||||
self.data[P_LOC,:] = fdata[n,:]
|
||||
self.label[P_LOC] = vars[n]
|
||||
w.append((vars[n], self.newplot, 'check', self.loc, P_LOC))
|
||||
elif v2 == 'u':
|
||||
self.data[U_LOC,:] = fdata[n,:]
|
||||
self.label[U_LOC] = vars[n]
|
||||
w.append((vars[n], self.newplot, 'check', self.loc, U_LOC))
|
||||
elif v2 == 'V':
|
||||
self.data[V_LOC,:] = fdata[n,:]
|
||||
self.label[V_LOC] = vars[n]
|
||||
w.append((vars[n], self.newplot, 'check', self.loc, V_LOC))
|
||||
elif k >= 0:
|
||||
self.data[k+Y_LOC,:] = fdata[n,:]
|
||||
self.label[k+Y_LOC] = vars[n]
|
||||
w.append((vars[n], self.newplot, 'check', self.loc, k + Y_LOC))
|
||||
|
||||
if self.data[P_LOC,0] == 0.0:
|
||||
self.data[P_LOC,:] = ones(self.np,'d')*OneAtm
|
||||
print 'Warning: no pressure data. P set to 1 atm.'
|
||||
|
||||
self.sc.config(cnf={'from':0,'to':self.np-1})
|
||||
if self.loc.get() <= 0:
|
||||
self.loc.set(self.lastloc)
|
||||
self.updateplot()
|
||||
|
||||
self.vars = w
|
||||
#self.makeMenu()
|
||||
self.scframe.grid(row=5,column=0,columnspan=10)
|
||||
|
||||
|
||||
def pickSoln(self):
|
||||
self.solnid.set(self.solns[self.whichsoln.get()]['id'])
|
||||
self.soln = self.solns[self.whichsoln.get()]
|
||||
# self.t.destroy()
|
||||
self.importData()
|
||||
|
||||
|
||||
def importData(self):
|
||||
|
||||
self.lastloc = self.loc.get()
|
||||
if self.lastloc <= 0: self.lastloc = T_LOC
|
||||
self.vars = []
|
||||
self.zdata = None
|
||||
self.ydata = None
|
||||
if self.plt:
|
||||
self.plt.destroy()
|
||||
|
||||
self.nsp = self.g.nSpecies()
|
||||
self.label = ['-']*(self.nsp + 6)
|
||||
|
||||
self.y = zeros(self.nsp,'d')
|
||||
gdata = self.soln.child('flowfield/grid_data')
|
||||
xp = self.soln.child('flowfield').children('float')
|
||||
p = 0.0
|
||||
for x in xp:
|
||||
if x['title'] == 'pressure':
|
||||
p = float(x.value())
|
||||
fa = gdata.children('floatArray')
|
||||
self.np = int(fa[0]['size'])
|
||||
|
||||
self.data = zeros((self.nsp+6,self.np),'d')
|
||||
w = []
|
||||
for f in fa:
|
||||
t = f['title']
|
||||
try:
|
||||
k = self.g.speciesIndex(t)
|
||||
except:
|
||||
k = -1
|
||||
v = XML.getFloatArray(f)
|
||||
if t == 'z' or t == 't':
|
||||
self.data[0,:] = v
|
||||
self.label[0] = t
|
||||
elif k >= 0:
|
||||
self.data[k + Y_LOC] = v
|
||||
self.label[k + Y_LOC] = t
|
||||
w.append((t, self.newplot, 'check', self.loc, k + Y_LOC))
|
||||
elif t == 'T':
|
||||
self.data[T_LOC,:] = v
|
||||
self.label[T_LOC] = t
|
||||
w.append((t, self.newplot, 'check', self.loc, T_LOC))
|
||||
elif t == 'u':
|
||||
self.data[U_LOC,:] = v
|
||||
self.label[U_LOC] = t
|
||||
w.append((t, self.newplot, 'check', self.loc, U_LOC))
|
||||
elif t == 'V':
|
||||
self.data[V_LOC,:] = v
|
||||
self.label[V_LOC] = t
|
||||
w.append((t, self.newplot, 'check', self.loc, V_LOC))
|
||||
|
||||
self.data[P_LOC,:] = ones(self.np,'d')*p
|
||||
self.label[P_LOC] = 'P (Pa)'
|
||||
self.sc.config(cnf={'from':0,'to':self.np-1})
|
||||
if self.loc.get() <= 0:
|
||||
self.loc.set(self.lastloc)
|
||||
self.updateplot()
|
||||
|
||||
self.vars = w
|
||||
self.scframe.grid(row=5,column=0,columnspan=10)
|
||||
|
||||
|
||||
def hide(self):
|
||||
#self.vis.set(0)
|
||||
self.master.withdraw()
|
||||
#if self.pltwhat: self.pltwhat.withdraw()
|
||||
|
||||
def show(self, e=None):
|
||||
self.master.deiconify()
|
||||
|
||||
def updateState(self, e=None):
|
||||
n = self.n.get()
|
||||
if self.plt: self.plt.update()
|
||||
|
||||
for k in range(self.nsp):
|
||||
self.y[k] = self.data[k+Y_LOC,n]
|
||||
|
||||
self.top.thermo.checkTPBoxes()
|
||||
self.mix.setMass(self.y)
|
||||
self.mix.set(temperature = self.data[T_LOC,n],
|
||||
pressure = self.data[P_LOC,n])
|
||||
|
||||
self.top.update()
|
||||
|
||||
def newplot(self,e=0):
|
||||
loc = self.loc.get()
|
||||
self.zdata = self.data[0,:]
|
||||
self.ydata = self.data[loc,:]
|
||||
npts = len(self.zdata)
|
||||
|
||||
ylog = 0
|
||||
if loc >= Y_LOC:
|
||||
for n in range(npts):
|
||||
if self.ydata[n] <= 0.0:
|
||||
#print n, self.ydata[n]
|
||||
self.ydata[n] = 1.0e-20
|
||||
self.ydata = num.log10(self.ydata)
|
||||
ylog = 1
|
||||
|
||||
self.gdata = []
|
||||
zmin = self.zdata[0]
|
||||
zmax = self.zdata[-1]
|
||||
for n in range(npts):
|
||||
self.gdata.append((self.zdata[n],self.ydata[n]))
|
||||
|
||||
ymin, ymax, dtick = plotLimits(self.ydata)
|
||||
if loc > 0:
|
||||
self.plt = DataGraph(self.gr,self.data, 0, loc,
|
||||
title='',
|
||||
label=(self.label[0],self.label[loc]),
|
||||
logscale=(0,ylog),
|
||||
pixelX=500,pixelY=400)
|
||||
self.plt.canvas.config(bg='white')
|
||||
self.plt.grid(row=1,column=0,columnspan=2,sticky=W+E)
|
||||
n = self.n.get()
|
||||
self.gdot = self.plt.plot(n,'red')
|
||||
|
||||
def updateplot(self,event=None):
|
||||
if self.data == None: return
|
||||
|
||||
if self.zdata == None:
|
||||
self.newplot()
|
||||
|
||||
n = self.n.get()
|
||||
self.pnt = self.zdata[n], self.ydata[n]
|
||||
if hasattr(self, 'gdot'):
|
||||
self.plt.delete(self.gdot)
|
||||
self.gdot = self.plt.plot(n,'red')
|
||||
|
||||
|
||||
def plotLimits(self, xy):
|
||||
ymax = -1.e10
|
||||
ymin = 1.e10
|
||||
for x, y in xy:
|
||||
if y > ymax: ymax = y
|
||||
if y < ymin: ymin = y
|
||||
|
||||
dy = abs(ymax - ymin)
|
||||
if dy < 0.2*ymin:
|
||||
ymin = ymin*.9
|
||||
ymax = ymax*1.1
|
||||
dy = abs(ymax - ymin)
|
||||
else:
|
||||
ymin = ymin - 0.1*dy
|
||||
ymax = ymax + 0.1*dy
|
||||
dy = abs(ymax - ymin)
|
||||
|
||||
p10 = math.floor(math.log10(0.1*dy))
|
||||
fctr = math.pow(10.0, p10)
|
||||
mm = [2.0, 2.5, 2.0]
|
||||
i = 0
|
||||
while dy/fctr > 5:
|
||||
fctr = mm[i % 3]*fctr
|
||||
i = i + 1
|
||||
ymin = fctr*math.floor(ymin/fctr)
|
||||
ymax = fctr*(math.floor(ymax/fctr + 1))
|
||||
return (ymin, ymax, fctr)
|
||||
229
interfaces/cython/cantera/mixmaster/DataGraph.py
Normal file
229
interfaces/cython/cantera/mixmaster/DataGraph.py
Normal file
@@ -0,0 +1,229 @@
|
||||
|
||||
from Tkinter import *
|
||||
import math
|
||||
from Cantera.num import *
|
||||
|
||||
def plotLimits(ypts, f=0.0, ndiv=5, logscale=0):
|
||||
"""Return plot limits that"""
|
||||
if logscale:
|
||||
threshold = 1.0e-19
|
||||
else:
|
||||
threshold = -1.0e20
|
||||
ymax = -1.e20
|
||||
ymin = 1.e20
|
||||
for y in ypts:
|
||||
if y > ymax: ymax = y
|
||||
if y < ymin and y > threshold: ymin = y
|
||||
|
||||
dy = abs(ymax - ymin)
|
||||
|
||||
if logscale:
|
||||
ymin = math.floor(math.log10(ymin))
|
||||
ymax = math.floor(math.log10(ymax))+1
|
||||
fctr = 1.0
|
||||
|
||||
## if dy < 0.2*ymin:
|
||||
## ymin = ymin*.9
|
||||
## ymax = ymax*1.1
|
||||
## dy = abs(ymax - ymin)
|
||||
## else:
|
||||
else:
|
||||
ymin = ymin - f*dy
|
||||
ymax = ymax + f*dy
|
||||
dy = abs(ymax - ymin)
|
||||
|
||||
try:
|
||||
p10 = math.floor(math.log10(0.1*dy))
|
||||
fctr = math.pow(10.0, p10)
|
||||
except:
|
||||
return (ymin -1.0, ymax + 1.0, 1.0)
|
||||
mm = [2.0, 2.5, 2.0]
|
||||
i = 0
|
||||
while dy/fctr > ndiv:
|
||||
fctr = mm[i % 3]*fctr
|
||||
i = i + 1
|
||||
ymin = fctr*math.floor(ymin/fctr)
|
||||
ymax = fctr*(math.floor(ymax/fctr+0.999))
|
||||
|
||||
return (ymin, ymax, fctr)
|
||||
|
||||
|
||||
class DataGraph(Frame):
|
||||
def __init__(self,master,
|
||||
data, ix=0, iy=0,
|
||||
title='',
|
||||
label = ('x-axis','y-axis'),
|
||||
logscale = (0,0),
|
||||
pixelX=500,
|
||||
pixelY=500):
|
||||
self.logscale = logscale
|
||||
self.data = data
|
||||
self.ix = ix
|
||||
self.iy = iy
|
||||
self.minX, self.maxX, self.dx = plotLimits(data[ix,:],
|
||||
logscale=self.logscale[0])
|
||||
self.minY, self.maxY, self.dy = plotLimits(data[iy,:],
|
||||
logscale=self.logscale[1])
|
||||
|
||||
Frame.__init__(self,master, relief=RIDGE, bd=2)
|
||||
self.title = Label(self,text=' ')
|
||||
self.title.grid(row=0,column=1,sticky=W+E)
|
||||
self.graph_w, self.graph_h = pixelX - 120, pixelY - 70
|
||||
self.origin = (100, 20)
|
||||
self.canvas = Canvas(self,
|
||||
width=pixelX,
|
||||
height=pixelY,
|
||||
relief=SUNKEN,bd=1)
|
||||
id = self.canvas.create_rectangle(self.origin[0],self.origin[1],
|
||||
pixelX-20,pixelY-50)
|
||||
self.canvas.grid(row=1,column=1,rowspan=2,sticky=N+S+E+W)
|
||||
self.last_points=[]
|
||||
self.ticks(self.minX, self.maxX, self.dx,
|
||||
self.minY, self.maxY, self.dy, 10)
|
||||
self.screendata()
|
||||
self.draw()
|
||||
self.canvas.create_text(self.origin[0] + self.graph_w/2,
|
||||
self.origin[1] + self.graph_h + 30,
|
||||
text=label[0],anchor=N)
|
||||
self.canvas.create_text(self.origin[0] - 50,
|
||||
self.origin[1] + self.graph_h/2,
|
||||
text=label[1],anchor=E)
|
||||
|
||||
|
||||
def writeValue(self, y):
|
||||
yval = '%15.4f' % (y)
|
||||
self.title.config(text = yval)
|
||||
|
||||
def delete(self, ids):
|
||||
for id in ids:
|
||||
self.canvas.delete(id)
|
||||
|
||||
def screendata(self):
|
||||
self.xdata = array(self.data[self.ix,:])
|
||||
self.ydata = array(self.data[self.iy,:])
|
||||
npts = len(self.ydata)
|
||||
if self.logscale[0] > 0:
|
||||
self.xdata = log10(self.xdata)
|
||||
if self.logscale[1] > 0:
|
||||
self.ydata = log10(self.ydata)
|
||||
f = float(self.graph_w)/(self.maxX-self.minX)
|
||||
self.xdata = (self.xdata - self.minX)*f + self.origin[0]
|
||||
f = float(self.graph_h)/(self.maxY-self.minY)
|
||||
self.ydata = (self.maxY - self.ydata)*f + self.origin[1]
|
||||
|
||||
def toscreen(self,x,y):
|
||||
if self.logscale[0] > 0:
|
||||
x = log10(x)
|
||||
if self.logscale[1] > 0:
|
||||
y = log10(y)
|
||||
f = float(self.graph_w)/(self.maxX-self.minX)
|
||||
xx = (x - self.minX)*f + self.origin[0]
|
||||
f = float(self.graph_h)/(self.maxY-self.minY)
|
||||
yy = (self.maxY - y)*f + self.origin[1]
|
||||
return (xx, yy)
|
||||
|
||||
def move(self, id, newpos, oldpos):
|
||||
dxpt = (newpos[0] - oldpos[0])/(self.maxX-self.minX)*self.graph_w
|
||||
dypt = -(newpos[1] - oldpos[1])/(self.maxY-self.minY)*self.graph_h
|
||||
self.canvas.move(id, dxpt, dypt)
|
||||
self.writeValue(newpos[1])
|
||||
|
||||
def plot(self,n,color='black'):
|
||||
xpt, ypt = self.toscreen(self.data[self.ix,n],
|
||||
self.data[self.iy,n])
|
||||
#xpt = (x-self.minX)/(self.maxX-self.minX)*float(self.graph_w) + self.origin[0]
|
||||
#ypt = (self.maxY-y)/(self.maxY-self.minY)*float(self.graph_h) + self.origin[1]
|
||||
id_ycross = self.canvas.create_line(xpt,self.graph_h+self.origin[1],xpt,self.origin[1],fill = 'gray')
|
||||
id_xcross = self.canvas.create_line(self.origin[0],ypt,self.graph_w+self.origin[0],ypt,fill = 'gray')
|
||||
id = self.canvas.create_oval(xpt-2,ypt-2,xpt+2,ypt+2,fill=color)
|
||||
#self.writeValue(y)
|
||||
s = '(%g, %g)' % (self.data[self.ix,n],self.data[self.iy,n])
|
||||
if n > 0 and self.data[self.iy,n] > self.data[self.iy,n-1]:
|
||||
idt = self.canvas.create_text(xpt+5,ypt+5,text=s,anchor=NW)
|
||||
else:
|
||||
idt = self.canvas.create_text(xpt+5,ypt-5,text=s,anchor=SW)
|
||||
|
||||
return [id,id_xcross,id_ycross, idt]
|
||||
|
||||
def draw(self,color='red'):
|
||||
npts = len(self.xdata)
|
||||
for n in range(1,npts):
|
||||
self.canvas.create_line(self.xdata[n-1],self.ydata[n-1],
|
||||
self.xdata[n],self.ydata[n],fill=color)
|
||||
|
||||
def addLabel(self, y, orient=0):
|
||||
if orient==0:
|
||||
xpt, ypt = self.toscreen(y, 1.0)
|
||||
ypt = self.origin[1] + self.graph_h + 5
|
||||
self.canvas.create_text(xpt,ypt,text=y,anchor=N)
|
||||
else:
|
||||
xpt, ypt = self.toscreen(self.minX, y)
|
||||
xpt = self.origin[0] - 5
|
||||
self.canvas.create_text(xpt,ypt,text=y,anchor=E)
|
||||
def addLegend(self,text,color=None):
|
||||
m=Message(self,text=text,width=self.graph_w-10)
|
||||
m.pack(side=BOTTOM)
|
||||
if color:
|
||||
m.config(fg=color)
|
||||
|
||||
def pauseWhenFinished(self):
|
||||
self.wait_window()
|
||||
|
||||
def minorTicks(self, x0, x1, y, n, size, orient=0):
|
||||
xtick = x0
|
||||
dx = (x1 - x0)/float(n)
|
||||
if orient == 0:
|
||||
while xtick <= x1:
|
||||
xx, yy = self.toscreen(xtick, y)
|
||||
self.canvas.create_line(xx,yy,
|
||||
xx,yy-size)
|
||||
xtick += dx
|
||||
else:
|
||||
while xtick <= x1:
|
||||
xx, yy = self.toscreen(y, xtick)
|
||||
self.canvas.create_line(xx,yy,
|
||||
xx+size,yy)
|
||||
xtick += dx
|
||||
|
||||
|
||||
def ticks(self, xmin, xmax, dx, ymin, ymax, dy, size):
|
||||
|
||||
if self.logscale[0]:
|
||||
xmin = math.pow(10.0,xmin)
|
||||
xmax = math.pow(10.0,xmax)
|
||||
if self.logscale[1]:
|
||||
ymin = math.pow(10.0,ymin)
|
||||
ymax = math.pow(10.0,ymax)
|
||||
|
||||
n = 5
|
||||
ytick = ymin
|
||||
while ytick <= ymax:
|
||||
xx, yy = self.toscreen(xmin, ytick)
|
||||
self.canvas.create_line(xx, yy, xx + size,yy)
|
||||
self.addLabel(ytick,1)
|
||||
xx, yy = self.toscreen(xmax, ytick)
|
||||
self.canvas.create_line(xx, yy, xx - size,yy)
|
||||
ytick0 = ytick
|
||||
if self.logscale[1]:
|
||||
ytick *= 10.0
|
||||
n = 10
|
||||
else: ytick = ytick + dy
|
||||
if ytick <= ymax:
|
||||
self.minorTicks(ytick0, ytick, xmin, n, 5, 1)
|
||||
self.minorTicks(ytick0, ytick, xmax, n, -5, 1)
|
||||
|
||||
n = 5
|
||||
xtick = xmin
|
||||
while xtick <= xmax:
|
||||
xx, yy = self.toscreen(xtick, ymin)
|
||||
self.canvas.create_line(xx, yy, xx, yy - size)
|
||||
self.addLabel(xtick,0)
|
||||
xx, yy = self.toscreen(xtick, ymax)
|
||||
self.canvas.create_line(xx, yy, xx, yy + size)
|
||||
if self.logscale[0]:
|
||||
xtick *= 10.0
|
||||
n = 10
|
||||
else: xtick = xtick + dx
|
||||
if xtick <= xmax:
|
||||
self.minorTicks(xtick - dx, xtick, ymin, n, 5, 0)
|
||||
self.minorTicks(xtick - dx, xtick, ymax, n, -5, 0)
|
||||
193
interfaces/cython/cantera/mixmaster/Edit.py
Normal file
193
interfaces/cython/cantera/mixmaster/Edit.py
Normal file
@@ -0,0 +1,193 @@
|
||||
from Tkinter import *
|
||||
|
||||
from ElementFrame import getElements
|
||||
from utilities import handleError
|
||||
from Cantera import *
|
||||
from config import *
|
||||
from SpeciesFrame import getSpecies
|
||||
|
||||
def testit():
|
||||
pass
|
||||
|
||||
class EditFrame(Frame):
|
||||
|
||||
def redraw(self):
|
||||
try:
|
||||
self.eframe.destroy()
|
||||
self.sframe.destroy()
|
||||
self.rframe.destroy()
|
||||
except:
|
||||
pass
|
||||
self.addElementFrame()
|
||||
self.addSpeciesFrame()
|
||||
self.addReactionFrame()
|
||||
|
||||
def __init__(self, master, app):
|
||||
Frame.__init__(self, master)
|
||||
self.mix = app.mix
|
||||
print self.mix, dir(self.mix)
|
||||
self.app = app
|
||||
self.master = master
|
||||
self.master.title("Cantera Mechanism Editor")
|
||||
self.redraw()
|
||||
|
||||
def addReactionFrame(self):
|
||||
self.rframe = Frame(self)
|
||||
self.rframe.config(relief=GROOVE,bd=4)
|
||||
self.rframe.grid(row=2,column=0,columnspan=10,sticky=E+W)
|
||||
b=Button(self.rframe,text='Reactions',command=testit)
|
||||
b.grid(column=5, row=0)
|
||||
|
||||
def addElementFrame(self):
|
||||
self.eframe = Frame(self)
|
||||
self.eframe.config(relief=GROOVE,bd=4)
|
||||
self.eframe.grid(row=0,column=0,columnspan=10,sticky=E+W)
|
||||
self.element_labels = []
|
||||
n = 0
|
||||
for el in self.mix._mech.elementNames():
|
||||
x = Label(self.eframe,text=el,fg='darkblue')
|
||||
x.grid(column = n, row=0)
|
||||
self.element_labels.append(x)
|
||||
n = n + 1
|
||||
b=Button(self.eframe,text='Element',command=self.chooseElements, default=ACTIVE)
|
||||
b.grid(column=0, row=1, columnspan=10)
|
||||
|
||||
|
||||
def addSpeciesFrame(self):
|
||||
self.sframe = Frame(self)
|
||||
self.sframe.config(relief=GROOVE,bd=4)
|
||||
self.sframe.grid(row=1,column=0,columnspan=10,sticky=E+W)
|
||||
r = 0
|
||||
c = 0
|
||||
splist = self.app.species
|
||||
self.spcheck = []
|
||||
self.spec = []
|
||||
for i in range(self.app.mech.nSpecies()):
|
||||
self.spec.append(IntVar())
|
||||
self.spec[i].set(1)
|
||||
self.spcheck.append( Checkbutton(self.sframe,
|
||||
text=splist[i].name,
|
||||
variable=self.spec[i],
|
||||
onvalue = 1, offvalue = 0) )
|
||||
self.spcheck[i].grid(row = r, column = c, sticky = N+W)
|
||||
self.spcheck[i].bind("<Button-3>", self.editSpecies)
|
||||
c = c + 1
|
||||
if c > 4:
|
||||
c, r = 0, r + 1
|
||||
|
||||
def getspecies(self):
|
||||
print getSpecies(self.mix.speciesNames(),
|
||||
self.mix.speciesNames())
|
||||
|
||||
def editSpecies(self, event=None):
|
||||
e = Toplevel(event.widget.master)
|
||||
w = event.widget
|
||||
txt = w.cget('text')
|
||||
sp = self.app.mix.species[txt]
|
||||
|
||||
# name, etc.
|
||||
e1 = Frame(e, relief=FLAT)
|
||||
self.addEntry(e1,'Name',0,0,sp.name)
|
||||
self.addEntry(e1,'ID Tag',1,0,sp.id)
|
||||
self.addEntry(e1,'Phase',2,0,sp.phase)
|
||||
e1.grid(row=0,column=0)
|
||||
|
||||
# elements
|
||||
elframe = Frame(e)
|
||||
elframe.grid(row=1,column=0)
|
||||
Label(elframe,text='Elemental Composition').grid(row=0,column=0,columnspan=2,sticky=E+W)
|
||||
|
||||
i = 0
|
||||
for el in self.app.mech.elementNames():
|
||||
self.addEntry(elframe,el,i,0,self.mech.nAtoms(sp, el))
|
||||
i = i + 1
|
||||
|
||||
# thermo
|
||||
thframe = Frame(e)
|
||||
thframe.grid(row=0,rowspan=2,column=1)
|
||||
thframe.config(relief=GROOVE,bd=4)
|
||||
i = 0
|
||||
Label(thframe,text='Thermodynamic Properties').grid(row=0,
|
||||
column=0, columnspan=4, sticky=E+W)
|
||||
if isinstance(sp.thermoParam(),NasaPolynomial):
|
||||
Label(thframe,text='Parametrization:').grid(row=1,column=1)
|
||||
self.addEntry(thframe,'',2,0,'NasaPolynomial')
|
||||
Label(thframe,text='Temperatures (min, mid, max):').grid(row=3,column=1)
|
||||
self.addEntry(thframe,'',4,0,`sp.minTemp`)
|
||||
self.addEntry(thframe,'',5,0,`sp.midTemp`)
|
||||
self.addEntry(thframe,'',6,0,`sp.maxTemp`)
|
||||
low = Frame(thframe)
|
||||
low.config(relief=GROOVE,bd=4)
|
||||
low.grid(row=1,rowspan=6,column=3,columnspan=2)
|
||||
Label(low,text='Coefficients for the Low\n Temperature Range').grid(row=0,column=0,columnspan=2,sticky=E+W)
|
||||
c = sp.thermoParam().coefficients(sp.minTemp)
|
||||
for j in range(7):
|
||||
self.addEntry(low,'a'+`j`,j+3,0,`c[j]`)
|
||||
high = Frame(thframe)
|
||||
high.config(relief=GROOVE,bd=4)
|
||||
high.grid(row=1,rowspan=6,column=5,columnspan=2)
|
||||
Label(high,text='Coefficients for the High\n Temperature Range').grid(row=0,column=0,columnspan=2,sticky=E+W)
|
||||
c = sp.thermoParam().coefficients(sp.maxTemp)
|
||||
for j in range(7):
|
||||
self.addEntry(high,'a'+`j`,j+3,0,`c[j]`)
|
||||
|
||||
com = Frame(e)
|
||||
com.grid(row=10,column=0,columnspan=5)
|
||||
ok = Button(com,text='OK',default=ACTIVE)
|
||||
ok.grid(row=0,column=0)
|
||||
ok.bind('<1>',self.modifySpecies)
|
||||
Button(com,text='Cancel',command=e.destroy).grid(row=0,column=1)
|
||||
self.especies = e
|
||||
|
||||
def modifySpecies(self,event=None):
|
||||
button = event.widget
|
||||
e = self.especies
|
||||
for fr in e.children.values():
|
||||
for item in fr.children.values():
|
||||
try:
|
||||
print item.cget('selection')
|
||||
except:
|
||||
pass
|
||||
e.destroy()
|
||||
|
||||
def addEntry(self,master,name,row,column,text):
|
||||
if name:
|
||||
Label(master, text=name).grid(row=row, column=column)
|
||||
nm = Entry(master)
|
||||
nm.grid(row=row, column=column+1)
|
||||
nm.insert(END,text)
|
||||
|
||||
def chooseElements(self):
|
||||
oldel = self.mix.g.elementNames()
|
||||
newel = getElements(self.mix.g.elementNames())
|
||||
removeList = []
|
||||
for el in oldel:
|
||||
if not el in newel:
|
||||
removeList.append(el)
|
||||
#self.app.mech.removeElements(removeList)
|
||||
addList = []
|
||||
for el in newel:
|
||||
if not el in oldel:
|
||||
addList.append(el)
|
||||
#self.app.mech.addElements(addList)
|
||||
try:
|
||||
self.redraw()
|
||||
self.app.makeWindows()
|
||||
except:
|
||||
handleError('Edit err')
|
||||
|
||||
self.app.mix = IdealGasMixture(self.app.mech)
|
||||
self.mix = self.app.mix
|
||||
nn = self.mix.speciesList[0].name
|
||||
self.mix.set(temperature = 300.0, pressure = 101325.0, moles = {nn:1.0})
|
||||
for label in self.element_labels:
|
||||
label.destroy()
|
||||
self.element_labels = []
|
||||
n = 0
|
||||
for el in self.mix._mech.elementList():
|
||||
x = Label(self.eframe,text=el.symbol(),fg='darkblue')
|
||||
x.grid(column = n, row=0)
|
||||
self.element_labels.append(x)
|
||||
n = n + 1
|
||||
|
||||
self.app.makeWindows()
|
||||
182
interfaces/cython/cantera/mixmaster/ElementFrame.py
Normal file
182
interfaces/cython/cantera/mixmaster/ElementFrame.py
Normal file
@@ -0,0 +1,182 @@
|
||||
#
|
||||
# function getElements displays a periodic table, and returns a list of
|
||||
# the selected elements
|
||||
#
|
||||
|
||||
from Tkinter import *
|
||||
from types import *
|
||||
import tkMessageBox
|
||||
import string
|
||||
|
||||
from Cantera import *
|
||||
|
||||
# (row,column) positions in the periodic table
|
||||
_pos = {'H':(1,1), 'He':(1,18),
|
||||
'Li':(2,1), 'Be':(2,2),
|
||||
'B':(2,13), 'C':(2,14), 'N':(2,15), 'O':(2,16), 'F':(2,17), 'Ne':(2,18),
|
||||
'Na':(3,1), 'Mg':(3,2),
|
||||
'Al':(3,13), 'Si':(3,14), 'P':(3,15), 'S':(3,16), 'Cl':(3,17), 'Ar':(3,18),
|
||||
'K':(4,1), 'Ca':(4,2),
|
||||
'Sc':(4,3), 'Ti':(4,4), 'V':(4,5), 'Cr':(4,6), 'Mn':(4,7), 'Fe':(4,8),
|
||||
'Co':(4,9), 'Ni':(4,10), 'Cu':(4,11), 'Zn':(4,12),
|
||||
'Ga':(4,13), 'Ge':(4,14), 'As':(4,15), 'Se':(4,16), 'Br':(4,17), 'Kr':(4,18),
|
||||
'Rb':(5,1), 'Sr':(5,2),
|
||||
'Y':(5,3), 'Zr':(5,4), 'Nb':(5,5), 'Mo':(5,6), 'Tc':(5,7), 'Ru':(5,8),
|
||||
'Rh':(5,9), 'Pd':(5,10), 'Ag':(5,11), 'Cd':(5,12),
|
||||
'In':(5,13), 'Sn':(5,14), 'Sb':(5,15), 'Te':(5,16), 'I':(5,17), 'Xe':(5,18)
|
||||
}
|
||||
|
||||
class PeriodicTable(Frame):
|
||||
|
||||
def __init__(self, master, selected=[]):
|
||||
Frame.__init__(self,master)
|
||||
self.master = master
|
||||
self.control = Frame(self)
|
||||
self.control.config(relief=GROOVE,bd=4)
|
||||
Button(self.control, text = 'Display',command=self.show).pack(fill=X,pady=3, padx=10)
|
||||
Button(self.control, text = 'Clear',command=self.clear).pack(fill=X,pady=3, padx=10)
|
||||
Button(self.control, text = ' OK ',command=self.get).pack(side=BOTTOM,
|
||||
fill=X,pady=3, padx=10)
|
||||
Button(self.control, text = 'Cancel',command=self.master.quit).pack(side=BOTTOM,
|
||||
fill=X,pady=3, padx=10)
|
||||
self.entries = Frame(self)
|
||||
self.entries.pack(side=LEFT)
|
||||
self.control.pack(side=RIGHT,fill=Y)
|
||||
self.c = {}
|
||||
self.element = {}
|
||||
self.selected = selected
|
||||
n=0
|
||||
ncol = 8
|
||||
for el in _pos.keys():
|
||||
self.element[el] = Frame(self.entries)
|
||||
self.element[el].config(relief=GROOVE, bd=4, bg=self.color(el))
|
||||
self.c[el] = Button(self.element[el],text=el,bg=self.color(el),width=3,relief=FLAT)
|
||||
self.c[el].pack()
|
||||
self.c[el].bind("<Button-1>",self.setColors)
|
||||
self.element[el].grid(row=_pos[el][0]-1, column = _pos[el][1]-1,sticky=W+N+E+S)
|
||||
n = n + 1
|
||||
Label(self.entries,text='select the elements to be included, and then press OK.\nTo view the properties of the selected elements, press Display ').grid(row=0, column=2, columnspan=10, sticky=W)
|
||||
|
||||
|
||||
def select(self, el):
|
||||
e = string.capitalize(el)
|
||||
self.c[e]['relief'] = RAISED
|
||||
self.c[e]['bg'] = self.color(e, sel=1)
|
||||
|
||||
def deselect(self, el):
|
||||
e = string.capitalize(el)
|
||||
self.c[e]['relief'] = FLAT
|
||||
self.c[e]['bg'] = self.color(e, sel=0)
|
||||
|
||||
def selectElements(self,ellist):
|
||||
for el in ellist:
|
||||
ename = el
|
||||
self.select(ename)
|
||||
|
||||
def setColors(self,event):
|
||||
el = event.widget['text']
|
||||
if event.widget['relief'] == RAISED:
|
||||
event.widget['relief'] = FLAT
|
||||
back = self.color(el, sel=0)
|
||||
elif event.widget['relief'] == FLAT:
|
||||
event.widget['relief'] = RAISED
|
||||
back = self.color(el, sel=1)
|
||||
event.widget['bg'] = back
|
||||
|
||||
def color(self, el, sel=0):
|
||||
_normal = ['#88dddd','#dddd88','#dd8888']
|
||||
_selected = ['#aaffff','#ffffaa','#ffaaaa']
|
||||
row, column = _pos[el]
|
||||
if sel: list = _selected
|
||||
else: list = _normal
|
||||
if column < 3:
|
||||
return list[0]
|
||||
elif column > 12:
|
||||
return list[1]
|
||||
else:
|
||||
return list[2]
|
||||
|
||||
def show(self):
|
||||
elnames = _pos.keys()
|
||||
elnames.sort()
|
||||
selected = []
|
||||
for el in elnames:
|
||||
if self.c[el]['relief'] == RAISED:
|
||||
selected.append(periodicTable[el])
|
||||
showElementProperties(selected)
|
||||
|
||||
def get(self):
|
||||
self.selected = []
|
||||
names = _pos.keys()
|
||||
names.sort()
|
||||
for el in names:
|
||||
if self.c[el]['relief'] == RAISED:
|
||||
self.selected.append(periodicTable[el])
|
||||
#self.master.quit()'
|
||||
self.master.destroy()
|
||||
|
||||
def clear(self):
|
||||
for el in _pos.keys():
|
||||
self.c[el]['bg'] = self.color(el, sel=0)
|
||||
self.c[el]['relief'] = FLAT
|
||||
|
||||
class ElementPropertyFrame(Frame):
|
||||
def __init__(self,master,ellist):
|
||||
Frame.__init__(self,master)
|
||||
n = 1
|
||||
ellist.sort()
|
||||
Label(self,text='Name').grid(column=0,row=0,sticky=W+S,padx=10,pady=10)
|
||||
Label(self,text='Atomic \nNumber').grid(column=1,row=0,sticky=W+S,padx=10,pady=10)
|
||||
Label(self,
|
||||
text='Atomic \nWeight').grid(column=2,
|
||||
row=0,
|
||||
sticky=W+S,
|
||||
padx=10,
|
||||
pady=10)
|
||||
for el in ellist:
|
||||
Label(self,
|
||||
text=el.name).grid(column=0,
|
||||
row=n,
|
||||
sticky=W,
|
||||
padx=10)
|
||||
Label(self,
|
||||
text=`el.atomicNumber`).grid(column=1,
|
||||
row=n,
|
||||
sticky=W,
|
||||
padx=10)
|
||||
Label(self,
|
||||
text=`el.atomicWeight`).grid(column=2,
|
||||
row=n,
|
||||
sticky=W,
|
||||
padx=10)
|
||||
n = n + 1
|
||||
|
||||
|
||||
# utility functions
|
||||
|
||||
def getElements(ellist=None):
|
||||
master = Toplevel()
|
||||
master.title('Periodic Table of the Elements')
|
||||
t = PeriodicTable(master)
|
||||
if ellist: t.selectElements(ellist)
|
||||
t.pack()
|
||||
t.focus_set()
|
||||
t.grab_set()
|
||||
t.wait_window()
|
||||
try:
|
||||
master.destroy()
|
||||
except TclError:
|
||||
pass
|
||||
return t.selected
|
||||
|
||||
|
||||
# display table of selected element properties in a window
|
||||
def showElementProperties(ellist):
|
||||
m = Tk()
|
||||
m.title('Element Properties')
|
||||
elem = []
|
||||
ElementPropertyFrame(m, ellist).pack()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print getElements()
|
||||
128
interfaces/cython/cantera/mixmaster/GraphFrame.py
Normal file
128
interfaces/cython/cantera/mixmaster/GraphFrame.py
Normal file
@@ -0,0 +1,128 @@
|
||||
|
||||
from Tkinter import *
|
||||
import math
|
||||
|
||||
class Graph(Frame):
|
||||
def __init__(self,master,title,minX,maxX,minY,maxY,pixelX=250,pixelY=250):
|
||||
Frame.__init__(self,master, relief=RIDGE, bd=2)
|
||||
# self.pack()
|
||||
self.title = Label(self,text=' ')
|
||||
self.title.grid(row=0,column=1,sticky=W+E)
|
||||
self.graph_w, self.graph_h = pixelX, pixelY
|
||||
self.maxX, self.maxY = maxX, maxY #float(math.floor(maxX + 1)), \
|
||||
#float(math.floor(maxY + 1))
|
||||
self.minX, self.minY = minX, minY # float(math.floor(minX)), float(math.floor(minY))
|
||||
self.canvas = Canvas(self,
|
||||
width=self.graph_w,
|
||||
height=self.graph_h,
|
||||
relief=SUNKEN,bd=1)
|
||||
ymintext = "%8.1f" % (self.minY)
|
||||
ymaxtext = "%8.1f" % (self.maxY)
|
||||
self.ml=Label(self, text=ymintext)
|
||||
self.mr=Label(self, text=ymaxtext)
|
||||
self.ml.grid(row=2,column=0,sticky=S+E)
|
||||
self.mr.grid(row=1,column=0,sticky=N+E)
|
||||
self.canvas.grid(row=1,column=1,rowspan=2,sticky=N+S+E+W)
|
||||
self.last_points=[]
|
||||
|
||||
|
||||
def writeValue(self, y):
|
||||
yval = '%15.4f' % (y)
|
||||
self.title.config(text = yval)
|
||||
|
||||
def delete(self, ids):
|
||||
for id in ids:
|
||||
self.canvas.delete(id)
|
||||
|
||||
def move(self, id, newpos, oldpos):
|
||||
dxpt = (newpos[0] - oldpos[0])/(self.maxX-self.minX)*self.graph_w
|
||||
dypt = -(newpos[1] - oldpos[1])/(self.maxY-self.minY)*self.graph_h
|
||||
self.canvas.move(id, dxpt, dypt)
|
||||
self.writeValue(newpos[1])
|
||||
|
||||
def plot(self,x,y,color='black'):
|
||||
xpt = (x-self.minX)/(self.maxX-self.minX)*float(self.graph_w) + 1.5
|
||||
ypt = (self.maxY-y)/(self.maxY-self.minY)*float(self.graph_h) - 1.5
|
||||
id_ycross = self.canvas.create_line(xpt,self.graph_h,xpt,0,fill = 'gray')
|
||||
id_xcross = self.canvas.create_line(0,ypt,self.graph_w,ypt,fill = 'gray')
|
||||
id = self.canvas.create_oval(xpt-2,ypt-2,xpt+2,ypt+2,fill=color)
|
||||
self.writeValue(y)
|
||||
return [id,id_xcross,id_ycross]
|
||||
|
||||
def reset(self,minX,maxX,minY,maxY):
|
||||
self.maxX, self.maxY = maxX, maxY
|
||||
self.minX, self.minY = minX, minY
|
||||
self.canvas.destroy()
|
||||
self.canvas = Canvas(self,
|
||||
width=self.graph_w,
|
||||
height=self.graph_h,
|
||||
relief=SUNKEN,bd=1)
|
||||
self.canvas.create_text(4,2,text=self.maxY,anchor=NW)
|
||||
self.canvas.create_text(4,self.graph_h,text=self.minY,anchor=SW)
|
||||
self.ml["text"] = `minX`
|
||||
self.mr["text"] = `maxX`
|
||||
self.canvas.pack()
|
||||
self.last_points = []
|
||||
|
||||
def join(self,point_list):
|
||||
i = 0
|
||||
for pt in point_list:
|
||||
x, y, color = pt
|
||||
if self.last_points == []:
|
||||
last_x, last_y, last_color = pt
|
||||
else:
|
||||
last_x, last_y, last_color = self.last_points[i]
|
||||
i = i + 1
|
||||
xpt = (x - self.minX)/(float(self.maxX - self.minX)/self.graph_w) + 1.5
|
||||
ypt = (self.maxY-y)/(float(self.maxY - self.minY)/self.graph_h) - 1.5
|
||||
last_xpt = (last_x - self.minX)/(float(self.maxX - self.minX)/self.graph_w) + 1.5
|
||||
last_ypt = (self.maxY-last_y)/(float(self.maxY - self.minY)/self.graph_h) - 1.5
|
||||
self.canvas.create_line(last_xpt,last_ypt,
|
||||
xpt,ypt,fill=color)
|
||||
self.last_points = point_list
|
||||
self.canvas.update()
|
||||
return
|
||||
|
||||
|
||||
def addLegend(self,text,color=None):
|
||||
m=Message(self,text=text,width=self.graph_w-10)
|
||||
m.pack(side=BOTTOM)
|
||||
if color:
|
||||
m.config(fg=color)
|
||||
|
||||
def pauseWhenFinished(self):
|
||||
self.wait_window()
|
||||
|
||||
|
||||
if __name__=='__main__':
|
||||
root= Tk()
|
||||
g = Graph(root,'graph1',0,10,0.01,120)
|
||||
h = Graph(root,'graph2',0,15,0,20000)
|
||||
g.pack(side=LEFT)
|
||||
h.pack(side=RIGHT)
|
||||
|
||||
#root.protocol("WM_DELETE_WINDOW", root.destroy())
|
||||
j = Graph(root,'Graph',0,1000,0,2000)
|
||||
j.pack()
|
||||
|
||||
j.plot(0, 0, color='red')
|
||||
j.last_points = [ (0, 0, 'red') ]
|
||||
for i in range(100):
|
||||
j.join( [ ( (i*10),(i*10+500), 'red' ) ] )
|
||||
|
||||
|
||||
g.addLegend('An example of the GraphFrame')
|
||||
h.addLegend('This is where the legend goes')
|
||||
for i in range(100):
|
||||
if root:
|
||||
x,y = float(i)/10, i
|
||||
g.plot(x,y,color='red')
|
||||
h.plot(i,i**2)#(0,0)
|
||||
#h.join([(i,i**2,'black')])
|
||||
else:
|
||||
break
|
||||
|
||||
#print("finished")
|
||||
g.pauseWhenFinished()
|
||||
h.pauseWhenFinished()
|
||||
print g
|
||||
123
interfaces/cython/cantera/mixmaster/ImportFrame.py
Normal file
123
interfaces/cython/cantera/mixmaster/ImportFrame.py
Normal file
@@ -0,0 +1,123 @@
|
||||
import os, math
|
||||
from Tkinter import *
|
||||
from Cantera import *
|
||||
#from Cantera.ck2ctml import ck2ctml
|
||||
from tkFileDialog import askopenfilename
|
||||
|
||||
class ImportFrame(Frame):
|
||||
def __init__(self,top):
|
||||
self.master = Toplevel()
|
||||
self.master.title('Convert and Import CK File')
|
||||
self.master.protocol("WM_DELETE_WINDOW",self.hide)
|
||||
|
||||
Frame.__init__(self,self.master)
|
||||
self.config(relief=GROOVE, bd=4)
|
||||
self.top = top
|
||||
self.infile = StringVar()
|
||||
|
||||
Label(self,text="Input File").grid(row=0,column=0)
|
||||
Entry(self, width=40,
|
||||
textvariable=self.infile).grid(column=1,row=0)
|
||||
Button(self, text='Browse',
|
||||
command=self.browseForInput).grid(row=0,column=2)
|
||||
|
||||
self.thermo = StringVar()
|
||||
Label(self,text="Thermodynamic Database").grid(row=1,column=0)
|
||||
Entry(self, width=40,
|
||||
textvariable=self.thermo).grid(column=1,row=1)
|
||||
Button(self, text='Browse',
|
||||
command=self.browseForThermo).grid(row=1,column=2)
|
||||
|
||||
|
||||
self.transport = StringVar()
|
||||
Label(self,text="Transport Database").grid(row=2,column=0)
|
||||
Entry(self, width=40,
|
||||
textvariable=self.transport).grid(column=1,row=2)
|
||||
Button(self, text='Browse',
|
||||
command=self.browseForTransport).grid(row=2,column=2)
|
||||
|
||||
bframe = Frame(self)
|
||||
bframe.config(relief=GROOVE, bd=1)
|
||||
bframe.grid(row=100,column=0)
|
||||
Button(bframe, text='OK', width=8, command=self.importfile).grid(row=0,column=0)
|
||||
self.grid(column=0,row=0)
|
||||
Button(bframe, text='Cancel', width=8, command=self.hide).grid(row=0,column=1)
|
||||
self.grid(column=0,row=0)
|
||||
self.hide()
|
||||
|
||||
def browseForInput(self, e=None):
|
||||
pathname = askopenfilename(
|
||||
filetypes=[("Reaction Mechanism Files",
|
||||
("*.inp","*.mech","*.ck2")),
|
||||
("All Files", "*.*")])
|
||||
if pathname:
|
||||
self.infile.set(pathname)
|
||||
self.show()
|
||||
|
||||
def browseForThermo(self, e=None):
|
||||
pathname = askopenfilename(
|
||||
filetypes=[("Thermodynamic Databases",
|
||||
("*.dat","*.inp","*.therm")),
|
||||
("All Files", "*.*")])
|
||||
if pathname:
|
||||
self.thermo.set(pathname)
|
||||
self.show()
|
||||
|
||||
def browseForTransport(self, e=None):
|
||||
pathname = askopenfilename(
|
||||
filetypes=[("Transport Databases", "*.dat"),
|
||||
("All Files", "*.*")])
|
||||
if pathname:
|
||||
self.transport.set(pathname)
|
||||
self.show()
|
||||
|
||||
|
||||
def importfile(self):
|
||||
ckfile = self.infile.get()
|
||||
thermdb = self.thermo.get()
|
||||
trandb = self.transport.get()
|
||||
p = os.path.normpath(os.path.dirname(ckfile))
|
||||
fname = os.path.basename(ckfile)
|
||||
ff = os.path.splitext(fname)
|
||||
nm = ""
|
||||
if len(ff) > 1: nm = ff[0]
|
||||
else: nm = ff
|
||||
outfile = p+os.sep+nm+'.xml'
|
||||
try:
|
||||
print 'not supported.'
|
||||
#ck2ctml(infile = ckfile, thermo = thermdb,
|
||||
# transport = trandb, outfile = outfile,
|
||||
# id = nm)
|
||||
self.hide()
|
||||
return
|
||||
|
||||
except:
|
||||
print 'Errors were encountered. See log file ck2ctml.log'
|
||||
self.hide()
|
||||
return
|
||||
|
||||
self.top.loadmech(nm,outfile,1)
|
||||
self.hide()
|
||||
|
||||
## cmd = 'ck2ctml -i '+ckfile+' -o '+outfile
|
||||
## if thermdb <> "":
|
||||
## cmd += ' -t '+thermdb
|
||||
## if trandb <> "":
|
||||
## cmd += ' -tr '+trandb
|
||||
## cmd += ' -id '+nm
|
||||
## ok = os.system(cmd)
|
||||
## if ok == 0:
|
||||
## self.top.loadmech(nm,outfile,1)
|
||||
|
||||
|
||||
def hide(self):
|
||||
#self.vis.set(0)
|
||||
self.master.withdraw()
|
||||
|
||||
def show(self):
|
||||
#v = self.vis.get()
|
||||
#if v == 0:
|
||||
# self.hide()
|
||||
# return
|
||||
|
||||
self.master.deiconify()
|
||||
417
interfaces/cython/cantera/mixmaster/KineticsFrame.py
Normal file
417
interfaces/cython/cantera/mixmaster/KineticsFrame.py
Normal file
@@ -0,0 +1,417 @@
|
||||
import os, math
|
||||
from Tkinter import *
|
||||
from Cantera import *
|
||||
|
||||
from SpeciesInfo import SpeciesInfo
|
||||
from Cantera import rxnpath
|
||||
import webbrowser
|
||||
|
||||
_CUTOFF = 1.e-15
|
||||
_ATOL = 1.e-15
|
||||
_RTOL = 1.e-7
|
||||
|
||||
def showsvg():
|
||||
f = open('_rp_svg.html','w')
|
||||
f.write('<embed src="rxnpath.svg" name="rxnpath" height=500\n')
|
||||
f.write('type="image/svg-xml" pluginspage="http://www.adobe.com/svg/viewer/install/">\n')
|
||||
f.close()
|
||||
webbrowser.open('file:///'+os.getcwd()+'/_rp_svg.html')
|
||||
|
||||
def showpng():
|
||||
f = open('_rp_png.html','w')
|
||||
f.write('<img src="rxnpath.png" height=500/>\n')
|
||||
f.close()
|
||||
webbrowser.open('file:///'+os.getcwd()+'/_rp_png.html')
|
||||
|
||||
|
||||
class KineticsFrame(Frame):
|
||||
def __init__(self,master):
|
||||
Frame.__init__(self,master)
|
||||
self.config(relief=FLAT, bd=4)
|
||||
self.top = self.master.top
|
||||
self.controls=Frame(self)
|
||||
self.hide = IntVar()
|
||||
self.hide.set(0)
|
||||
self.comp = IntVar()
|
||||
self.comp.set(2)
|
||||
self.controls.grid(column=1,row=0,sticky=W+E+N)
|
||||
self.makeControls()
|
||||
mf = self.master
|
||||
|
||||
def makeControls(self):
|
||||
Radiobutton(self.controls,text='Creation Rates',
|
||||
variable=self.comp,value=0,
|
||||
command=self.show).grid(column=0,row=0,sticky=W)
|
||||
Radiobutton(self.controls,text='Destruction Rates',
|
||||
variable=self.comp,value=1,
|
||||
command=self.show).grid(column=0,row=1,sticky=W)
|
||||
Radiobutton(self.controls,text='Net Production Rates',
|
||||
variable=self.comp,value=2,
|
||||
command=self.show).grid(column=0,row=2,sticky=W)
|
||||
|
||||
def show(self):
|
||||
mf = self.master
|
||||
mf.active = self
|
||||
c = self.comp.get()
|
||||
mix = self.top.mix
|
||||
g = mix.g
|
||||
if c == 0:
|
||||
mf.var.set("Creation Rates")
|
||||
#mf.data = spdict(mix.g, mix.moles())
|
||||
mf.comp = g.creationRates()
|
||||
|
||||
elif c == 1:
|
||||
mf.var.set("Destruction Rates")
|
||||
#mf.data = spdict(mix.g,mix.mass())
|
||||
mf.comp = g.destructionRates()
|
||||
|
||||
elif c == 2:
|
||||
mf.var.set("Net Production Rates")
|
||||
mf.comp = g.netProductionRates()
|
||||
#mf.data = spdict(mix,mix,mf.comp)
|
||||
|
||||
for s in mf.variable.keys():
|
||||
try:
|
||||
k = g.speciesIndex(s)
|
||||
if mf.comp[k] > _CUTOFF or -mf.comp[k] > _CUTOFF:
|
||||
mf.variable[s].set(mf.comp[k])
|
||||
else:
|
||||
mf.variable[s].set(0.0)
|
||||
except:
|
||||
pass
|
||||
|
||||
class SpeciesKineticsFrame(Frame):
|
||||
def __init__(self,master,top):
|
||||
Frame.__init__(self,master)
|
||||
self.config(relief=GROOVE, bd=4)
|
||||
self.top = top
|
||||
self.top.kinetics = self
|
||||
self.g = self.top.mix.g
|
||||
self.entries=Frame(self)
|
||||
self.var = StringVar()
|
||||
self.var.set("Net Production Rates")
|
||||
self.names = self.top.mix.speciesNames()
|
||||
self.nsp = len(self.names)
|
||||
self.comp = [0.0]*self.nsp
|
||||
self.makeControls()
|
||||
self.makeEntries()
|
||||
self.entries.bind('<Double-l>',self.minimize)
|
||||
self.ctype = 0
|
||||
|
||||
def makeControls(self):
|
||||
self.c = KineticsFrame(self)
|
||||
#self.rr = ReactionKineticsFrame(self, self.top)
|
||||
self.c.grid(column=1,row=0,sticky=E+W+N+S)
|
||||
#self.rr.grid(column=0,row=1,sticky=E+W+N+S)
|
||||
|
||||
def show(self):
|
||||
self.c.show()
|
||||
|
||||
def redo(self):
|
||||
self.update()
|
||||
self.entries.destroy()
|
||||
self.entries=Frame(self)
|
||||
self.makeEntries()
|
||||
|
||||
def minimize(self,Event=None):
|
||||
self.c.hide.set(1)
|
||||
self.redo()
|
||||
self.c.grid_forget()
|
||||
self.entries.bind("<Double-1>",self.maximize)
|
||||
|
||||
def maximize(self,Event=None):
|
||||
self.c.hide.set(0)
|
||||
self.redo()
|
||||
self.c.grid(column=1,row=0,sticky=E+W+N+S)
|
||||
self.entries.bind("<Double-1>",self.minimize)
|
||||
|
||||
def up(self, x):
|
||||
self.update()
|
||||
|
||||
def makeEntries(self):
|
||||
self.entries.grid(row=0,column=0,sticky=W+N+S+E)
|
||||
self.entries.config(relief=FLAT,bd=4)
|
||||
DATAKEYS = self.top.species
|
||||
self.variable = {}
|
||||
|
||||
n=0
|
||||
ncol = 3
|
||||
col = 0
|
||||
row = 60
|
||||
|
||||
for sp in DATAKEYS:
|
||||
s = sp
|
||||
k = s.index
|
||||
if row > 15:
|
||||
row = 0
|
||||
col = col + 2
|
||||
l = Label(self.entries,text='Species')
|
||||
l.grid(column=col,row=row,sticky=E+W)
|
||||
e1 = Entry(self.entries)
|
||||
e1.grid(column=col+1,row=row,sticky=E+W)
|
||||
e1['textvariable'] = self.var
|
||||
e1.config(state=DISABLED)
|
||||
e1.config(bg='lightyellow',relief=RIDGE)
|
||||
row = row + 1
|
||||
|
||||
spname = s.name
|
||||
val = self.comp[k]
|
||||
if not self.c.hide.get() or val: showit = 1
|
||||
else: showit = 0
|
||||
|
||||
l=SpeciesInfo(self.entries,species=s,
|
||||
text=spname,relief=FLAT,justify=RIGHT,
|
||||
fg='darkblue')
|
||||
entry1 = Entry(self.entries)
|
||||
self.variable[spname] = DoubleVar()
|
||||
self.variable[spname].set(self.comp[k])
|
||||
entry1['textvariable']=self.variable[spname]
|
||||
entry1.bind('<Any-Leave>',self.up)
|
||||
if showit:
|
||||
l.grid(column= col ,row=row,sticky=E)
|
||||
entry1.grid(column=col+1,row=row)
|
||||
n=n+1
|
||||
row = row + 1
|
||||
entry1.config(state=DISABLED,bg='lightgray')
|
||||
|
||||
|
||||
class ReactionKineticsFrame(Frame):
|
||||
def __init__(self,vis,top):
|
||||
self.master = Toplevel()
|
||||
self.master.protocol("WM_DELETE_WINDOW",self.hide)
|
||||
self.vis = vis
|
||||
Frame.__init__(self,self.master)
|
||||
self.config(relief=GROOVE, bd=4)
|
||||
self.top = top
|
||||
self.g = self.top.mix.g
|
||||
nr = self.g.nReactions()
|
||||
self.eqs=Text(self,width=40,height=30)
|
||||
self.data = []
|
||||
self.start = DoubleVar()
|
||||
if nr > 30:
|
||||
self.end = self.start.get()+30
|
||||
else:
|
||||
self.end = self.start.get()+nr
|
||||
|
||||
for i in range(4):
|
||||
self.data.append(Text(self,width=15,height=30))
|
||||
|
||||
for n in range(nr):
|
||||
s = self.g.reactionEqn(n)
|
||||
self.eqs.insert(END,s+'\n')
|
||||
self.eqs.grid(column=0,row=1,sticky=W+E+N)
|
||||
for i in range(4):
|
||||
self.data[i].grid(column=i+1,row=1,sticky=W+E+N)
|
||||
Label(self, text='Reaction').grid(column=0,row=0,sticky=W+E+N)
|
||||
Label(self, text='Fwd ROP').grid(column=1,row=0,sticky=W+E+N)
|
||||
Label(self, text='Rev ROP').grid(column=2,row=0,sticky=W+E+N)
|
||||
Label(self, text='Net ROP').grid(column=3,row=0,sticky=W+E+N)
|
||||
Label(self, text='Kp').grid(column=4,row=0,sticky=W+E+N)
|
||||
|
||||
self.scfr = Frame(self)
|
||||
self.scfr.config(relief=GROOVE,bd=4)
|
||||
|
||||
## self.sc = Scrollbar(self.scfr,command=self.show,
|
||||
## variable = self.start,
|
||||
## orient='horizontal',length=400)
|
||||
self.sc = Scale(self.scfr,command=self.show,
|
||||
variable=self.start,
|
||||
orient='vertical',length=400)
|
||||
# self.sc.config(cnf={'from':0,'to':nr},variable = self.start)
|
||||
#self.sc.bind('<Any-Enter>',self.couple)
|
||||
#self.scfr.bind('<Any-Leave>',self.decouple)
|
||||
self.sc.pack(side=RIGHT,fill=Y)
|
||||
self.scfr.grid(row=0,column=6,rowspan=10,sticky=N+E+W)
|
||||
self.grid(column=0,row=0)
|
||||
|
||||
self.hide()
|
||||
|
||||
## def decouple(self,event=None):
|
||||
## d = DoubleVar()
|
||||
## xx = self.start.get()
|
||||
## d.set(xx)
|
||||
## self.sc.config(variable = d)
|
||||
|
||||
## def couple(self,event=None):
|
||||
## self.sc.config(variable = self.start)
|
||||
|
||||
def hide(self):
|
||||
# self.vis.set(0)
|
||||
self.master.withdraw()
|
||||
|
||||
def show(self,e=None,b=None,c=None):
|
||||
v = self.vis.get()
|
||||
print e,b,c
|
||||
#if v == 0:
|
||||
# self.hide()
|
||||
# return
|
||||
|
||||
self.master.deiconify()
|
||||
nr = self.g.nReactions()
|
||||
frop = self.g.fwdRatesOfProgress()
|
||||
rrop = self.g.revRatesOfProgress()
|
||||
kp = self.g.equilibriumConstants()
|
||||
self.data[0].delete(1.0,END)
|
||||
self.data[1].delete(1.0,END)
|
||||
self.data[2].delete(1.0,END)
|
||||
self.data[3].delete(1.0,END)
|
||||
self.eqs.delete(1.0,END)
|
||||
|
||||
n0 = int(self.start.get())
|
||||
nn = nr - n0
|
||||
if nn > 30: nn = 30
|
||||
for n in range(n0, nn+n0):
|
||||
s = '%12.5e \n' % (frop[n],)
|
||||
self.data[0].insert(END,s)
|
||||
s = '%12.5e \n' % (rrop[n],)
|
||||
self.data[1].insert(END,s)
|
||||
s = '%12.5e \n' % (frop[n] - rrop[n],)
|
||||
self.data[2].insert(END,s)
|
||||
s = '%12.5e \n' % (kp[n],)
|
||||
self.data[3].insert(END,s)
|
||||
self.eqs.insert(END, self.g.reactionEqn(n)+'\n')
|
||||
|
||||
class ReactionPathFrame(Frame):
|
||||
|
||||
def __init__(self,top):
|
||||
self.master = Toplevel()
|
||||
self.master.protocol("WM_DELETE_WINDOW",self.hide)
|
||||
#self.vis = vis
|
||||
Frame.__init__(self,self.master)
|
||||
self.config(relief=GROOVE, bd=4)
|
||||
self.grid(column=0,row=0)
|
||||
self.top = top
|
||||
self.g = self.top.mix.g
|
||||
self.el = IntVar()
|
||||
self.el.set(0)
|
||||
self.thresh = DoubleVar()
|
||||
|
||||
scframe = Frame(self)
|
||||
self.sc = Scale(scframe,variable = self.thresh,
|
||||
orient='horizontal',digits=3,length=300,resolution=0.01)
|
||||
self.sc.config(cnf={'from':-6,'to':0})
|
||||
Label(scframe,text='log10 Threshold').grid(column=0,row=0)
|
||||
self.sc.grid(row=0,column=1,columnspan=10)
|
||||
self.sc.bind('<ButtonRelease-1>',self.show)
|
||||
scframe.grid(row=3,column=0,columnspan=10)
|
||||
|
||||
enames = self.g.elementNames()
|
||||
self.nel = len(enames)
|
||||
|
||||
i = 1
|
||||
eframe = Frame(self)
|
||||
Label(eframe,text='Element').grid(column=0,row=0,sticky=W)
|
||||
for e in enames:
|
||||
Radiobutton(eframe,text=e,
|
||||
variable=self.el,value=i-1,
|
||||
command=self.show).grid(column=i,row=0,sticky=W)
|
||||
i += 1
|
||||
eframe.grid(row=0,column=0)
|
||||
|
||||
self.detailed = IntVar()
|
||||
Checkbutton(self, text = 'Show details', variable=self.detailed,
|
||||
command=self.show).grid(column=1,row=0)
|
||||
self.net = IntVar()
|
||||
Checkbutton(self, text = 'Show net flux',
|
||||
variable=self.net,
|
||||
command=self.show).grid(column=2,row=0)
|
||||
self.local = StringVar()
|
||||
Label(self,text='Species').grid(column=1,row=1,sticky=E)
|
||||
sp = Entry(self, textvariable=self.local,
|
||||
width=15)
|
||||
sp.grid(column=2,row=1)
|
||||
sp.bind('<Any-Leave>',self.show)
|
||||
|
||||
self.b = rxnpath.PathBuilder(self.g)
|
||||
|
||||
self.fmt = StringVar()
|
||||
self.fmt.set('svg')
|
||||
i = 1
|
||||
fmtframe = Frame(self)
|
||||
fmtframe.config(relief=GROOVE, bd=4)
|
||||
self.browser = IntVar()
|
||||
self.browser.set(0)
|
||||
Checkbutton(fmtframe, text = 'Display in Web Browser',
|
||||
variable=self.browser,
|
||||
command=self.show).grid(column=0,columnspan=6,row=0)
|
||||
Label(fmtframe,text='Format').grid(column=0,row=1,sticky=W)
|
||||
for e in ['svg', 'png', 'gif', 'jpg']:
|
||||
Radiobutton(fmtframe,text=e,
|
||||
variable=self.fmt,value=e,
|
||||
command=self.show).grid(column=i,row=1,sticky=W)
|
||||
i += 1
|
||||
fmtframe.grid(row=5,column=0,columnspan=10,sticky=E+W)
|
||||
|
||||
self.cv = Canvas(self,relief=SUNKEN,bd=1)
|
||||
self.cv.grid(column=0,row=4,sticky=W+E+N,columnspan=10)
|
||||
|
||||
pframe = Frame(self)
|
||||
pframe.config(relief=GROOVE, bd=4)
|
||||
self.dot = StringVar()
|
||||
self.dot.set('dot -Tgif rxnpath.dot > rxnpath.gif')
|
||||
Label(pframe,text='DOT command:').grid(column=0,row=0,sticky=W)
|
||||
Entry(pframe,width=60,textvariable=self.dot).grid(column=0,
|
||||
row=1,sticky=W)
|
||||
pframe.grid(row=6,column=0,columnspan=10,sticky=E+W)
|
||||
|
||||
self.thresh.set(-2.0)
|
||||
self.hide()
|
||||
|
||||
def hide(self):
|
||||
#self.vis.set(0)
|
||||
self.master.withdraw()
|
||||
|
||||
def show(self,e=None):
|
||||
|
||||
self.master.deiconify()
|
||||
el = self.g.elementName(self.el.get())
|
||||
det = 'false'
|
||||
if self.detailed.get() == 1: det = 'true'
|
||||
flow = 'one_way'
|
||||
if self.net.get() == 1: flow = 'net'
|
||||
self.d = rxnpath.PathDiagram(arrow_width=-2,
|
||||
flow_type=flow,
|
||||
detailed = det,
|
||||
threshold=math.pow(10.0,
|
||||
self.thresh.get()))
|
||||
node = self.local.get()
|
||||
try:
|
||||
k = self.g.speciesIndex(node)
|
||||
self.d.displayOnly(k)
|
||||
except:
|
||||
self.d.displayOnly()
|
||||
|
||||
self.b.build(element = el, diagram = self.d,
|
||||
dotfile = 'rxnpath.dot', format = 'dot')
|
||||
#self.b.build(element = el, diagram = self.d,
|
||||
# dotfile = 'rxnpath.txt', format = 'plain')
|
||||
|
||||
if self.browser.get() == 1:
|
||||
fmt = self.fmt.get()
|
||||
os.system('dot -T'+fmt+' rxnpath.dot > rxnpath.'+fmt)
|
||||
if fmt == 'svg': showsvg()
|
||||
elif fmt == 'png': showpng()
|
||||
else:
|
||||
path = 'file:///'+os.getcwd()+'/rxnpath.'+fmt
|
||||
webbrowser.open(path)
|
||||
try:
|
||||
self.cv.delete(self.image)
|
||||
except:
|
||||
pass
|
||||
self.cv.configure(width=0, height=0)
|
||||
else:
|
||||
os.system(self.dot.get())
|
||||
self.rp = None
|
||||
try:
|
||||
self.cv.delete(self.image)
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
self.rp = PhotoImage(file='rxnpath.gif')
|
||||
self.cv.configure(width=self.rp.width(),
|
||||
height=self.rp.height())
|
||||
|
||||
self.image = self.cv.create_image(0,0,anchor=NW,
|
||||
image=self.rp)
|
||||
except:
|
||||
pass
|
||||
81
interfaces/cython/cantera/mixmaster/MechManager.py
Normal file
81
interfaces/cython/cantera/mixmaster/MechManager.py
Normal file
@@ -0,0 +1,81 @@
|
||||
from Cantera import *
|
||||
from Tkinter import *
|
||||
from ControlPanel import ControlWindow
|
||||
from ControlPanel import make_menu, menuitem_state
|
||||
#from Cantera.Examples.Tk import _mechdir
|
||||
import os
|
||||
|
||||
# automatically-loaded mechanisms
|
||||
_autoload = [
|
||||
(' GRI-Mech 3.0', 'gri30.cti'),
|
||||
(' Air', 'air.cti'),
|
||||
(' H/O/Ar', 'h2o2.cti')
|
||||
]
|
||||
|
||||
def testit():
|
||||
pass
|
||||
|
||||
class MechManager(Frame):
|
||||
|
||||
def __init__(self,master,app):
|
||||
Frame.__init__(self,master)
|
||||
#self.config(relief=GROOVE, bd=4)
|
||||
self.app = app
|
||||
self.master = master
|
||||
self.mechindx = IntVar()
|
||||
self.mechindx.set(1)
|
||||
|
||||
#m = Label(self, text = 'Loaded Mechanisms')
|
||||
#m.grid(column=0,row=0)
|
||||
# m.bind('<Double-1>',self.show)
|
||||
# self.mechindx.set(0)
|
||||
self.mechanisms = []
|
||||
self.mlist = [ [] ]
|
||||
i = 1
|
||||
#for m in self.mechanisms:
|
||||
# self.mlist.append((m[0], self.setMechanism, 'check', self.mechindx, i))
|
||||
# i = i + 1
|
||||
#self.mlist.append([])
|
||||
|
||||
self.mechmenu = make_menu('Mixtures', self, self.mlist)
|
||||
self.mechmenu.grid(row=0,column=0,sticky=W)
|
||||
|
||||
self.mfr = None
|
||||
|
||||
def addMechanism(self, name, mech):
|
||||
self.mechanisms.append((name, mech))
|
||||
il = len(self.mechanisms)
|
||||
self.mlist[-1] = (name, self.setMechanism, 'check', self.mechindx, il)
|
||||
self.mlist.append([])
|
||||
|
||||
self.mechmenu = make_menu('Mixtures', self, self.mlist)
|
||||
self.mechindx.set(il)
|
||||
self.mechmenu.grid(row=0,column=0,sticky=W)
|
||||
|
||||
|
||||
def delMechanism(self, mech):
|
||||
self.mechanisms.remove(mech)
|
||||
self.show()
|
||||
|
||||
## def show(self,event=None):
|
||||
## print 'show'
|
||||
## if self.mfr:
|
||||
## self.mfr.destroy()
|
||||
## self.mfr = Frame(self)
|
||||
## self.mfr.grid(row=1,column=0)
|
||||
## self.mfr.config(relief=GROOVE, bd=4)
|
||||
## Label(self.mfr,text='jkl').grid(row=0,column=0)
|
||||
## i = 0
|
||||
## for name, mech in self.mechanisms:
|
||||
## Radiobutton(self.mfr, text=name, variable=self.mechindx,
|
||||
## value = i,
|
||||
## command=self.setMechanism).grid(row=i,column=0)
|
||||
## i = i + 1
|
||||
## print 'end'
|
||||
|
||||
|
||||
def setMechanism(self, event=None):
|
||||
i = self.mechindx.get()
|
||||
self.app.mech = self.mechanisms[i-1][1]
|
||||
self.app.makeMix()
|
||||
self.app.makeWindows()
|
||||
138
interfaces/cython/cantera/mixmaster/Mix.py
Normal file
138
interfaces/cython/cantera/mixmaster/Mix.py
Normal file
@@ -0,0 +1,138 @@
|
||||
from Cantera import GasConstant, OneAtm
|
||||
from Cantera.num import zeros, ones
|
||||
from utilities import handleError
|
||||
|
||||
def spdict(phase, x):
|
||||
nm = phase.speciesNames()
|
||||
data = {}
|
||||
for k in range(len(nm)):
|
||||
data[nm[k]] = x[k]
|
||||
return data
|
||||
|
||||
class Species:
|
||||
def __init__(self,g,name):
|
||||
self.g = g
|
||||
t = g.temperature()
|
||||
p = g.pressure()
|
||||
x = g.moleFractions()
|
||||
self.name = name
|
||||
self.symbol = name
|
||||
self.index = g.speciesIndex(name)
|
||||
self.minTemp = g.minTemp(self.index)
|
||||
self.maxTemp = g.maxTemp(self.index)
|
||||
self.molecularWeight = g.molecularWeights()[self.index]
|
||||
self.c = []
|
||||
self.e = g.elementNames()
|
||||
self.hf0 = self.enthalpy_RT(298.15)*GasConstant*298.15
|
||||
g.setState_TPX(t,p,x)
|
||||
for n in range(len(self.e)):
|
||||
na = g.nAtoms(self.index, n)
|
||||
if na > 0:
|
||||
self.c.append((self.e[n],na))
|
||||
|
||||
def composition(self):
|
||||
return self.c
|
||||
|
||||
def enthalpy_RT(self,t):
|
||||
self.g.setTemperature(t)
|
||||
return self.g.enthalpies_RT()[self.index]
|
||||
|
||||
def cp_R(self,t):
|
||||
self.g.setTemperature(t)
|
||||
return self.g.cp_R()[self.index]
|
||||
|
||||
def entropy_R(self,t):
|
||||
self.g.setTemperature(t)
|
||||
return self.g.entropies_R()[self.index]
|
||||
|
||||
class Mix:
|
||||
def __init__(self,g):
|
||||
self.g = g
|
||||
self._mech = g
|
||||
self.nsp = g.nSpecies()
|
||||
self._moles = zeros(self.nsp,'d')
|
||||
self.wt = g.molecularWeights()
|
||||
|
||||
def setMoles(self, m):
|
||||
self._moles = m
|
||||
self.g.setMoleFractions(self._moles)
|
||||
|
||||
def moles(self):
|
||||
return self._moles
|
||||
|
||||
def totalMoles(self):
|
||||
sum = 0.0
|
||||
for k in range(self.nsp):
|
||||
sum += self._moles[k]
|
||||
return sum
|
||||
|
||||
def totalMass(self):
|
||||
sum = 0.0
|
||||
for k in range(self.nsp):
|
||||
sum += self._moles[k]*self.wt[k]
|
||||
return sum
|
||||
|
||||
def moleDict(self):
|
||||
d = {}
|
||||
nm = self.g.speciesNames()
|
||||
for e in range(self.nsp):
|
||||
d[nm[e]] = self._moles[e]
|
||||
return d
|
||||
|
||||
def setMass(self, m):
|
||||
self.setMoles( m/self.wt)
|
||||
|
||||
def mass(self):
|
||||
return self.wt*self._moles
|
||||
|
||||
def speciesNames(self):
|
||||
return self.g.speciesNames()
|
||||
|
||||
def massDict(self):
|
||||
d = {}
|
||||
nm = self.g.speciesNames()
|
||||
for e in range(self.nsp):
|
||||
d[nm[e]] = self._moles[e]*self.wt[e]
|
||||
return d
|
||||
|
||||
def set(self, temperature = None, pressure = None,
|
||||
density = None, enthalpy = None,
|
||||
entropy = None, intEnergy = None, equil = 0):
|
||||
total_mass = self.totalMass()
|
||||
|
||||
if temperature and pressure:
|
||||
self.g.setState_TP(temperature, pressure)
|
||||
if equil:
|
||||
self.g.equilibrate('TP',solver=0)
|
||||
|
||||
elif temperature and density:
|
||||
self.g.setState_TR(temperature, density)
|
||||
if equil:
|
||||
self.g.equilibrate('TV',solver=0)
|
||||
|
||||
elif pressure and enthalpy:
|
||||
self.g.setState_HP(enthalpy, pressure)
|
||||
if equil:
|
||||
self.g.equilibrate('HP',solver=0)
|
||||
|
||||
elif pressure and entropy:
|
||||
self.g.setState_SP(entropy, pressure)
|
||||
if equil:
|
||||
self.g.equilibrate('SP',solver=0)
|
||||
|
||||
elif density and entropy:
|
||||
self.g.setState_SV(entropy, 1.0/density)
|
||||
if equil:
|
||||
self.g.equilibrate('SV',solver=0)
|
||||
|
||||
elif density and intEnergy:
|
||||
self.g.setState_UV(intEnergy, 1.0/density)
|
||||
if equil:
|
||||
self.g.equilibrate('UV',solver=0)
|
||||
|
||||
# else:
|
||||
# handleError('unsupported property pair', warning=1)
|
||||
|
||||
|
||||
total_moles = total_mass/self.g.meanMolecularWeight()
|
||||
self._moles = self.g.moleFractions()*total_moles
|
||||
114
interfaces/cython/cantera/mixmaster/NewFlowFrame.py
Normal file
114
interfaces/cython/cantera/mixmaster/NewFlowFrame.py
Normal file
@@ -0,0 +1,114 @@
|
||||
from Tkinter import *
|
||||
from Cantera import *
|
||||
|
||||
from SpeciesInfo import SpeciesInfo
|
||||
|
||||
_CUTOFF = 1.e-15
|
||||
_ATOL = 1.e-15
|
||||
_RTOL = 1.e-7
|
||||
|
||||
class NewFlowFrame(Frame):
|
||||
def __init__(self,master):
|
||||
Frame.__init__(self,master)
|
||||
self.config(relief=GROOVE, bd=4)
|
||||
self.app = self.master.app
|
||||
self.controls=Frame(self)
|
||||
self.hide = IntVar()
|
||||
self.hide.set(0)
|
||||
self.p = DoubleVar()
|
||||
#self.comp.set(1.0)
|
||||
self.controls.grid(column=1,row=0,sticky=W+E+N)
|
||||
#self.makeControls()
|
||||
mf = self.master
|
||||
|
||||
e1 = Entry(self)
|
||||
e1.grid(column=0,row=0,sticky=E+W)
|
||||
e1['textvariable'] = self.p
|
||||
#e1.config(state=ENABLED)
|
||||
e1.config(relief=RIDGE)
|
||||
|
||||
## def makeControls(self):
|
||||
## Radiobutton(self.controls,text='Moles',
|
||||
## variable=self.comp,value=0,command=self.show).grid(column=0,row=0,sticky=W)
|
||||
## Radiobutton(self.controls,text='Mass',variable=self.comp,value=1,command=self.show).grid(column=0,row=1,sticky=W)
|
||||
## Radiobutton(self.controls,text='Concentration',variable=self.comp,value=2,command=self.show).grid(column=0,row=2,sticky=W)
|
||||
## Button(self.controls,text='Clear',command=self.zero).grid(column=0,row=4,sticky=W+E)
|
||||
## Button(self.controls,text='Normalize',command=self.norm).grid(column=0,row=5,sticky=W+E)
|
||||
## Checkbutton(self.controls,text='Hide Missing\nSpecies',
|
||||
## variable=self.hide,onvalue=1,offvalue=0,command=self.master.redo).grid(column=0,row=3,sticky=W)
|
||||
|
||||
|
||||
## def makeControls(self):
|
||||
## self.c = CompFrame(self)
|
||||
## self.c.grid(column=1,row=0,sticky=E+W+N+S)
|
||||
|
||||
## def redo(self):
|
||||
## self.update()
|
||||
## self.entries.destroy()
|
||||
## self.entries=Frame(self)
|
||||
## self.makeEntries()
|
||||
|
||||
## def minimize(self,Event=None):
|
||||
## self.c.hide.set(1)
|
||||
## self.redo()
|
||||
## self.c.grid_forget()
|
||||
## self.entries.bind("<Double-1>",self.maximize)
|
||||
|
||||
## def maximize(self,Event=None):
|
||||
## self.c.hide.set(0)
|
||||
## self.redo()
|
||||
## self.c.grid(column=1,row=0,sticky=E+W+N+S)
|
||||
## self.entries.bind("<Double-1>",self.minimize)
|
||||
|
||||
|
||||
## def makeEntries(self):
|
||||
## self.entries.grid(row=0,column=0,sticky=W+N+S+E)
|
||||
## self.entries.config(relief=GROOVE,bd=4)
|
||||
## DATAKEYS = self.top.species
|
||||
## self.variable = {}
|
||||
|
||||
## n=0
|
||||
## ncol = 3
|
||||
## col = 0
|
||||
## row = 60
|
||||
|
||||
## presbox =
|
||||
|
||||
## for sp in DATAKEYS:
|
||||
## s = sp # self.top.species[sp]
|
||||
## k = s.index
|
||||
## if row > 15:
|
||||
## row = 0
|
||||
## col = col + 2
|
||||
## l = Label(self.entries,text='Species')
|
||||
## l.grid(column=col,row=row,sticky=E+W)
|
||||
## e1 = Entry(self.entries)
|
||||
## e1.grid(column=col+1,row=row,sticky=E+W)
|
||||
## e1['textvariable'] = self.var
|
||||
## e1.config(state=DISABLED)
|
||||
## e1.config(bg='lightyellow',relief=RIDGE)
|
||||
## row = row + 1
|
||||
|
||||
## spname = s.name
|
||||
## val = self.comp[k]
|
||||
## if not self.c.hide.get() or val: showit = 1
|
||||
## else: showit = 0
|
||||
|
||||
## l=SpeciesInfo(self.entries,species=s,
|
||||
## text=spname,relief=FLAT,justify=RIGHT,
|
||||
## fg='darkblue')
|
||||
## entry1 = Entry(self.entries)
|
||||
## self.variable[spname] = DoubleVar()
|
||||
## self.variable[spname].set(self.comp[k])
|
||||
## entry1['textvariable']=self.variable[spname]
|
||||
## entry1.bind('<Any-Leave>',self.up)
|
||||
## if showit:
|
||||
## l.grid(column= col ,row=row,sticky=E)
|
||||
## entry1.grid(column=col+1,row=row)
|
||||
## n=n+1
|
||||
## row = row + 1
|
||||
## if self.c.hide.get():
|
||||
## b=Button(self.entries,height=1,command=self.maximize)
|
||||
## else:
|
||||
## b=Button(self.entries,command=self.minimize)
|
||||
## b.grid(column=col,columnspan=2, row=row+1)
|
||||
174
interfaces/cython/cantera/mixmaster/SpeciesFrame.py
Normal file
174
interfaces/cython/cantera/mixmaster/SpeciesFrame.py
Normal file
@@ -0,0 +1,174 @@
|
||||
#
|
||||
# function getElements displays a periodic table, and returns a list of
|
||||
# the selected elements
|
||||
#
|
||||
|
||||
from Tkinter import *
|
||||
from types import *
|
||||
import tkMessageBox
|
||||
|
||||
from Cantera import *
|
||||
|
||||
class SpeciesFrame(Frame):
|
||||
|
||||
def __init__(self, master, speciesList = [], selected=[]):
|
||||
Frame.__init__(self,master)
|
||||
self.master = master
|
||||
self.control = Frame(self)
|
||||
self.species = {}
|
||||
for sp in speciesList:
|
||||
self.species[sp.name] = sp
|
||||
|
||||
self.control.config(relief=GROOVE,bd=4)
|
||||
Button(self.control, text = 'Display',command=self.show).pack(fill=X,pady=3, padx=10)
|
||||
Button(self.control, text = 'Clear',command=self.clear).pack(fill=X,pady=3, padx=10)
|
||||
Button(self.control, text = ' OK ',command=self.get).pack(side=BOTTOM,
|
||||
fill=X,pady=3, padx=10)
|
||||
Button(self.control, text = 'Cancel',command=self.master.quit).pack(side=BOTTOM,
|
||||
fill=X,pady=3, padx=10)
|
||||
self.entries = Frame(self)
|
||||
self.entries.pack(side=LEFT)
|
||||
self.control.pack(side=RIGHT,fill=Y)
|
||||
self.c = {}
|
||||
self.selected = selected
|
||||
n=0
|
||||
ncol = 8
|
||||
rw = 1
|
||||
col = 0
|
||||
list = self.species.values()
|
||||
list.sort()
|
||||
for sp in list:
|
||||
el = sp.name
|
||||
self.species[el] = Frame(self.entries)
|
||||
self.species[el].config(relief=GROOVE, bd=4, bg=self.color(el))
|
||||
self.c[el] = Button(self.species[el],text=el,bg=self.color(el),width=6,relief=FLAT)
|
||||
self.c[el].pack()
|
||||
self.c[el].bind("<Button-1>",self.setColors)
|
||||
self.species[el].grid(row= rw, column = col,sticky=W+N+E+S)
|
||||
col = col + 1
|
||||
if col > ncol:
|
||||
rw = rw + 1
|
||||
col = 0
|
||||
Label(self.entries,text='select the species to be included, and then press OK.\nTo view the properties of the selected species, press Display ').grid(row=0, column=2, columnspan=10, sticky=W)
|
||||
|
||||
|
||||
def select(self, el):
|
||||
self.c[el]['relief'] = RAISED
|
||||
self.c[el]['bg'] = self.color(el, sel=1)
|
||||
|
||||
def deselect(self, el):
|
||||
self.c[el]['relief'] = FLAT
|
||||
self.c[el]['bg'] = self.color(el, sel=0)
|
||||
|
||||
def selectSpecies(self,splist):
|
||||
for sp in splist:
|
||||
spname = sp.name
|
||||
self.select(spname)
|
||||
|
||||
def setColors(self,event):
|
||||
el = event.widget['text']
|
||||
if event.widget['relief'] == RAISED:
|
||||
event.widget['relief'] = FLAT
|
||||
back = self.color(el, sel=0)
|
||||
fore = '#ffffff'
|
||||
elif event.widget['relief'] == FLAT:
|
||||
event.widget['relief'] = RAISED
|
||||
fore = '#000000'
|
||||
back = self.color(el, sel=1)
|
||||
event.widget['bg'] = back
|
||||
event.widget['fg'] = fore
|
||||
|
||||
def color(self, el, sel=0):
|
||||
_normal = ['#88dddd','#005500','#dd8888']
|
||||
_selected = ['#aaffff','#88dd88','#ffaaaa']
|
||||
#row, column = _pos[el]
|
||||
if sel: list = _selected
|
||||
else: list = _normal
|
||||
return list[1]
|
||||
#if column < 3:
|
||||
# return list[0]
|
||||
#elif column > 12:
|
||||
# return list[1]
|
||||
#else:
|
||||
# return list[2]
|
||||
|
||||
def show(self):
|
||||
selected = []
|
||||
for sp in self.species.values():
|
||||
if self.c[sp.name]['relief'] == RAISED:
|
||||
selected.append(sp)
|
||||
#showElementProperties(selected)
|
||||
|
||||
def get(self):
|
||||
self.selected = []
|
||||
for sp in self.species.values():
|
||||
if self.c[sp.name]['relief'] == RAISED:
|
||||
self.selected.append(sp)
|
||||
#self.master.quit()'
|
||||
self.master.destroy()
|
||||
|
||||
def clear(self):
|
||||
for sp in self.species.values():
|
||||
self.c[sp]['bg'] = self.color(sp, sel=0)
|
||||
self.c[sp]['relief'] = FLAT
|
||||
|
||||
## class ElementPropertyFrame(Frame):
|
||||
## def __init__(self,master,ellist):
|
||||
## Frame.__init__(self,master)
|
||||
## n = 1
|
||||
## ellist.sort()
|
||||
## Label(self,text='Name').grid(column=0,row=0,sticky=W+S,padx=10,pady=10)
|
||||
## Label(self,text='Atomic \nNumber').grid(column=1,row=0,sticky=W+S,padx=10,pady=10)
|
||||
## Label(self,
|
||||
## text='Atomic \nWeight').grid(column=2,
|
||||
## row=0,
|
||||
## sticky=W+S,
|
||||
## padx=10,
|
||||
## pady=10)
|
||||
## for el in ellist:
|
||||
## Label(self,
|
||||
## text=el.name).grid(column=0,
|
||||
## row=n,
|
||||
## sticky=W,
|
||||
## padx=10)
|
||||
## Label(self,
|
||||
## text=`el.atomicNumber`).grid(column=1,
|
||||
## row=n,
|
||||
## sticky=W,
|
||||
## padx=10)
|
||||
## Label(self,
|
||||
## text=`el.atomicWeight`).grid(column=2,
|
||||
## row=n,
|
||||
## sticky=W,
|
||||
## padx=10)
|
||||
## n = n + 1
|
||||
|
||||
|
||||
# utility functions
|
||||
|
||||
def getSpecies(splist=[],selected=[]):
|
||||
master = Toplevel()
|
||||
master.title('Species')
|
||||
t = SpeciesFrame(master,splist,selected)
|
||||
if splist: t.selectSpecies(splist)
|
||||
t.pack()
|
||||
t.focus_set()
|
||||
t.grab_set()
|
||||
t.wait_window()
|
||||
try:
|
||||
master.destroy()
|
||||
except TclError:
|
||||
pass
|
||||
return t.selected
|
||||
|
||||
|
||||
# display table of selected element properties in a window
|
||||
def showElementProperties(ellist):
|
||||
m = Tk()
|
||||
m.title('Element Properties')
|
||||
elem = []
|
||||
ElementPropertyFrame(m, ellist).pack()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print getSpecies()
|
||||
242
interfaces/cython/cantera/mixmaster/SpeciesInfo.py
Normal file
242
interfaces/cython/cantera/mixmaster/SpeciesInfo.py
Normal file
@@ -0,0 +1,242 @@
|
||||
from Tkinter import *
|
||||
import re, math
|
||||
from Cantera import *
|
||||
from Units import temperature, specificEnergy, specificEntropy
|
||||
from UnitChooser import UnitVar
|
||||
from GraphFrame import Graph
|
||||
|
||||
def testit():
|
||||
pass
|
||||
|
||||
class SpeciesInfo(Label):
|
||||
def __init__(self,master,phase=None,species=None,**opt):
|
||||
Label.__init__(self,master,opt)
|
||||
self.sp = species
|
||||
self.phase = phase
|
||||
self.bind('<Double-1>', self.show)
|
||||
self.bind('<Button-3>', self.show)
|
||||
self.bind('<Any-Enter>', self.highlight)
|
||||
self.bind('<Any-Leave>', self.nohighlight)
|
||||
|
||||
|
||||
def highlight(self, event=None):
|
||||
self.config(fg='yellow')
|
||||
|
||||
def nohighlight(self, event=None):
|
||||
self.config(fg='darkblue')
|
||||
|
||||
def show(self, event):
|
||||
self.new=Toplevel()
|
||||
self.new.title(self.sp.symbol)
|
||||
#self.new.transient(self.master)
|
||||
self.new.bind("<Return>", self.update,"+")
|
||||
self.cpr = 0.0
|
||||
self.t = 0.0
|
||||
self.cpl = 0.0
|
||||
self.tl = 0.0
|
||||
self.cpp = [[(0.0, 0.0, 'red')]]
|
||||
|
||||
# elemental composition
|
||||
self.eframe = Frame(self.new)
|
||||
self.eframe.config(relief=GROOVE,bd=4)
|
||||
self.eframe.grid(row=0,column=0,columnspan=10,sticky=E+W)
|
||||
r = 1
|
||||
Label(self.eframe,text='Atoms:')\
|
||||
.grid(row=0,column=0,sticky=N+W)
|
||||
for el, c in self.sp.composition():
|
||||
Label(self.eframe,text=`int(c)`+' '+el).grid(row=0,column=r)
|
||||
r = r + 1
|
||||
|
||||
|
||||
# thermodynamic properties
|
||||
self.thermo = Frame(self.new)
|
||||
self.thermo.config(relief=GROOVE,bd=4)
|
||||
self.thermo.grid(row=1,column=0,columnspan=10,sticky=N+E+W)
|
||||
Label(self.thermo,text = 'Standard Heat of Formation at 298 K: ').grid(row=0, column=0, sticky=W)
|
||||
Label(self.thermo,text = '%8.2f kJ/mol' % (self.sp.hf0*1.0e-6)).grid(row=0, column=1, sticky=W)
|
||||
Label(self.thermo,text = 'Molar Mass: ').grid(row=1, column=0, sticky=W)
|
||||
Label(self.thermo,text = self.sp.molecularWeight).grid(row=1, column=1, sticky=W)
|
||||
labels = ['Temperature', 'c_p', 'Enthalpy', 'Entropy']
|
||||
units = [temperature, specificEntropy, specificEnergy, specificEntropy]
|
||||
whichone = [0, 1, 1, 1]
|
||||
|
||||
r = 2
|
||||
self.prop = []
|
||||
for prop in labels:
|
||||
Label(self.thermo,text=prop).grid(row=r,column=0,sticky=W)
|
||||
p = UnitVar(self.thermo,units[r-2],whichone[r-2])
|
||||
p.grid(row=r,column=1,sticky=W)
|
||||
p.v.config(state=DISABLED,bg='lightgray')
|
||||
self.prop.append(p)
|
||||
r = r + 1
|
||||
|
||||
tmin = self.sp.minTemp
|
||||
tmax = self.sp.maxTemp
|
||||
cp = self.sp.cp_R(tmin)
|
||||
hh = self.sp.enthalpy_RT(tmin)
|
||||
ss = self.sp.entropy_R(tmin)
|
||||
|
||||
self.prop[0].bind("<Any-Enter>", self.decouple)
|
||||
self.prop[0].bind("<Any-Leave>", self.update)
|
||||
self.prop[0].bind("<Key>", self.update)
|
||||
self.prop[0].v.config(state=NORMAL,bg='white')
|
||||
self.prop[0].set(300.0)
|
||||
|
||||
self.graphs = Frame(self.new)
|
||||
self.graphs.config(relief=GROOVE,bd=4)
|
||||
self.graphs.grid(row=2,column=0,columnspan=10,sticky=E+W)
|
||||
|
||||
self.cpdata = []
|
||||
self.hdata = []
|
||||
self.sdata = []
|
||||
t = tmin
|
||||
n = int((tmax - tmin)/100.0)
|
||||
while t <= tmax:
|
||||
self.cpdata.append((t,self.sp.cp_R(t)))
|
||||
self.hdata.append((t,self.sp.enthalpy_RT(t)))
|
||||
self.sdata.append((t,self.sp.entropy_R(t)))
|
||||
t = t + n
|
||||
|
||||
# specific heat
|
||||
|
||||
Label(self.graphs,text='c_p/R').grid(row=0,column=0,sticky=W+E)
|
||||
ymin, ymax, dtick = self.plotLimits(self.cpdata)
|
||||
self.cpg = Graph(self.graphs,'',tmin,tmax,ymin,ymax,
|
||||
pixelX=150,pixelY=150)
|
||||
self.cpg.canvas.config(bg='white')
|
||||
self.cpg.grid(row=1,column=0,columnspan=2,sticky=W+E)
|
||||
self.ticks(ymin, ymax, dtick, tmin, tmax, self.cpg)
|
||||
|
||||
# enthalpy
|
||||
Label(self.graphs,text='enthalpy/RT').grid(row=0,column=3,sticky=W+E)
|
||||
ymin, ymax, dtick = self.plotLimits(self.hdata)
|
||||
self.hg = Graph(self.graphs,'',tmin,tmax,ymin,ymax,
|
||||
pixelX=150,pixelY=150)
|
||||
self.hg.canvas.config(bg='white')
|
||||
self.hg.grid(row=1,column=3,columnspan=2,sticky=W+E)
|
||||
self.ticks(ymin, ymax, dtick, tmin, tmax, self.hg)
|
||||
|
||||
# entropy
|
||||
Label(self.graphs,text='entropy/R').grid(row=0,column=5,sticky=W+E)
|
||||
ymin, ymax, dtick = self.plotLimits(self.sdata)
|
||||
self.sg = Graph(self.graphs,'',tmin,tmax,ymin,ymax,
|
||||
pixelX=150,pixelY=150)
|
||||
self.sg.canvas.config(bg='white')
|
||||
self.sg.grid(row=1,column=5,columnspan=2,sticky=W+E)
|
||||
self.ticks(ymin, ymax, dtick, tmin, tmax, self.sg)
|
||||
|
||||
n = int((tmax - tmin)/100.0)
|
||||
t = tmin
|
||||
self.cpp = []
|
||||
|
||||
for t, cp in self.cpdata:
|
||||
self.cpg.join([(t,cp,'red')])
|
||||
for t, h in self.hdata:
|
||||
self.hg.join([(t,h,'green')])
|
||||
for t, s in self.sdata:
|
||||
self.sg.join([(t,s,'blue')])
|
||||
|
||||
self.cpdot = self.cpg.plot(tmin,cp,'red')
|
||||
self.hdot = self.hg.plot(tmin,hh,'green')
|
||||
self.sdot = self.sg.plot(tmin,ss,'blue')
|
||||
|
||||
b=Button(self.new,text=' OK ',command=self.finished, default=ACTIVE)
|
||||
#ed=Button(self.new,text='Edit',command=testit)
|
||||
b.grid(column=0, row=4,sticky=W)
|
||||
#ed.grid(column=1,row=4,sticky=W)
|
||||
|
||||
self.scfr = Frame(self.new)
|
||||
self.scfr.config(relief=GROOVE,bd=4)
|
||||
self.scfr.grid(row=3,column=0,columnspan=10,sticky=N+E+W)
|
||||
self.sc = Scale(self.scfr,command=self.update,variable = self.prop[0].x,
|
||||
orient='horizontal',digits=7,length=400)
|
||||
self.sc.config(cnf={'from':tmin,'to':tmax})
|
||||
self.sc.bind('<Any-Enter>',self.couple)
|
||||
self.scfr.bind('<Any-Leave>',self.decouple)
|
||||
self.sc.grid(row=0,column=0,columnspan=10)
|
||||
|
||||
def decouple(self,event=None):
|
||||
d = DoubleVar()
|
||||
xx = self.prop[0].get()
|
||||
d.set(xx)
|
||||
self.sc.config(variable = d)
|
||||
|
||||
def couple(self,event=None):
|
||||
self.sc.config(variable = self.prop[0].x)
|
||||
#self.update()
|
||||
|
||||
def update(self,event=None):
|
||||
try:
|
||||
tmp = self.prop[0].get()
|
||||
cnd = self.sp.cp_R(tmp)
|
||||
cc = cnd*GasConstant
|
||||
self.prop[1].set(cc)
|
||||
hnd = self.sp.enthalpy_RT(tmp)
|
||||
hh = hnd*tmp*GasConstant
|
||||
self.prop[2].set(hh)
|
||||
snd = self.sp.entropy_R(tmp)
|
||||
ss = snd*tmp*GasConstant
|
||||
self.prop[3].set(ss)
|
||||
|
||||
|
||||
self.cppoint = tmp, cnd
|
||||
self.hpoint = tmp, hnd
|
||||
self.spoint = tmp, snd
|
||||
if hasattr(self, 'cpdot'):
|
||||
self.cpg.delete(self.cpdot)
|
||||
self.cpdot = self.cpg.plot(self.cppoint[0], self.cppoint[1],'red')
|
||||
self.hg.delete(self.hdot)
|
||||
self.hdot = self.hg.plot(self.hpoint[0], self.hpoint[1],'green')
|
||||
self.sg.delete(self.sdot)
|
||||
self.sdot = self.sg.plot(self.spoint[0], self.spoint[1],'blue')
|
||||
except:
|
||||
pass
|
||||
|
||||
def plotLimits(self, xy):
|
||||
ymax = -1.e10
|
||||
ymin = 1.e10
|
||||
for x, y in xy:
|
||||
if y > ymax: ymax = y
|
||||
if y < ymin: ymin = y
|
||||
|
||||
dy = abs(ymax - ymin)
|
||||
if dy < 0.2*ymin:
|
||||
ymin = ymin*.9
|
||||
ymax = ymax*1.1
|
||||
dy = abs(ymax - ymin)
|
||||
else:
|
||||
ymin = ymin - 0.1*dy
|
||||
ymax = ymax + 0.1*dy
|
||||
dy = abs(ymax - ymin)
|
||||
|
||||
p10 = math.floor(math.log10(0.1*dy))
|
||||
fctr = math.pow(10.0, p10)
|
||||
mm = [2.0, 2.5, 2.0]
|
||||
i = 0
|
||||
while dy/fctr > 5:
|
||||
fctr = mm[i % 3]*fctr
|
||||
i = i + 1
|
||||
ymin = fctr*math.floor(ymin/fctr)
|
||||
ymax = fctr*(math.floor(ymax/fctr + 1))
|
||||
return (ymin, ymax, fctr)
|
||||
|
||||
def ticks(self, ymin, ymax, dtick, tmin, tmax, plot):
|
||||
ytick = ymin
|
||||
eps = 1.e-3
|
||||
while ytick <= ymax:
|
||||
if abs(ytick) < eps:
|
||||
plot.join([(tmin, ytick, 'gray')])
|
||||
plot.join([(tmax, ytick, 'gray')])
|
||||
plot.last_points = []
|
||||
else:
|
||||
plot.join([(tmin, ytick, 'gray')])
|
||||
plot.join([(tmin + 0.05*(tmax - tmin), ytick, 'gray')])
|
||||
plot.last_points = []
|
||||
plot.join([(2.0*tmax, ytick, 'gray')])
|
||||
plot.join([(tmax - 0.05*(tmax - tmin), ytick, 'gray')])
|
||||
plot.last_points = []
|
||||
|
||||
ytick = ytick + dtick
|
||||
|
||||
def finished(self,event=None):
|
||||
self.new.destroy()
|
||||
143
interfaces/cython/cantera/mixmaster/ThermoFrame.py
Normal file
143
interfaces/cython/cantera/mixmaster/ThermoFrame.py
Normal file
@@ -0,0 +1,143 @@
|
||||
|
||||
|
||||
from Cantera import *
|
||||
from Tkinter import *
|
||||
|
||||
from Units import temperature, pressure, density, specificEnergy, specificEntropy
|
||||
from UnitChooser import UnitVar
|
||||
from ThermoProp import ThermoProp
|
||||
from utilities import handleError
|
||||
|
||||
_PRESSURE = 1
|
||||
_TEMPERATURE = 0
|
||||
_DENSITY = 2
|
||||
_INTENERGY = 3
|
||||
_ENTHALPY = 4
|
||||
_ENTROPY = 5
|
||||
|
||||
class ThermoFrame(Frame):
|
||||
def __init__(self,master,top):
|
||||
Frame.__init__(self,master)
|
||||
self.config(relief=GROOVE, bd=4)
|
||||
self.top = top
|
||||
self.mix = self.top.mix
|
||||
self.warn = 0
|
||||
self.internal = Frame(self)
|
||||
self.internal.pack(side=LEFT,anchor=N+W,padx=2,pady=2)
|
||||
self.controls=Frame(self.internal)
|
||||
self.controls.pack(side=LEFT,anchor=N+W,padx=4,pady=5)
|
||||
|
||||
self.entries=Frame(self.internal)
|
||||
self.entries.pack(side=LEFT,anchor=N,padx=4,pady=2)
|
||||
self.makeEntries()
|
||||
self.makeControls()
|
||||
self.showState()
|
||||
|
||||
def makeControls(self):
|
||||
Button(self.controls,text='Set State', width=15,
|
||||
command=self.setState).grid(column=0,row=0)
|
||||
self.equil = IntVar()
|
||||
self.equil.set(0)
|
||||
Button(self.controls,text='Equilibrate', width=15,
|
||||
command=self.eqset).grid(column=0,row=1)
|
||||
## Radiobutton(self.controls,text='Frozen',variable = self.equil,
|
||||
## command=self.freeze,value=0).grid(column=0,row=2,sticky='W')
|
||||
## Radiobutton(self.controls,text='Equilibrium',
|
||||
## variable=self.equil,
|
||||
## command=self.eqset,value=1).grid(column=0,row=3,sticky='W')
|
||||
|
||||
def eqset(self):
|
||||
self.equil.set(1)
|
||||
self.setState()
|
||||
self.equil.set(0)
|
||||
#if self.top.mixframe:
|
||||
# self.top.mixframe.redo()
|
||||
|
||||
def freeze(self):
|
||||
self.equil.set(0)
|
||||
if self.top.mixframe:
|
||||
self.top.mixframe.redo()
|
||||
|
||||
def makeEntries(self):
|
||||
self.entries.pack()
|
||||
self.variable = {}
|
||||
self.prop = []
|
||||
props = ['Temperature', 'Pressure', 'Density',
|
||||
'Internal Energy', 'Enthalpy', 'Entropy']
|
||||
units = [temperature, pressure, density, specificEnergy,
|
||||
specificEnergy, specificEntropy]
|
||||
defaultunit = [0, 2, 0, 1, 1, 1]
|
||||
for i in range(len(props)):
|
||||
self.prop.append(ThermoProp(self.entries, self, i, props[i],
|
||||
0.0, units[i], defaultunit[i]))
|
||||
#self.prop[-1].entry.bind("<Any-Leave>",self.setState)
|
||||
self.last2 = self.prop[3]
|
||||
self.last1 = self.prop[2]
|
||||
self.prop[0].checked.set(1)
|
||||
self.prop[0].check()
|
||||
self.prop[1].checked.set(1)
|
||||
self.prop[1].check()
|
||||
self.showState()
|
||||
|
||||
def checkTPBoxes(self):
|
||||
if not self.prop[0].isChecked():
|
||||
self.prop[0].checked.set(1)
|
||||
self.prop[0].check()
|
||||
if not self.prop[1].isChecked():
|
||||
self.prop[1].checked.set(1)
|
||||
self.prop[1].check()
|
||||
|
||||
def showState(self):
|
||||
self.prop[_TEMPERATURE].set(self.mix.g.temperature())
|
||||
self.prop[_PRESSURE].set(self.mix.g.pressure())
|
||||
self.prop[_DENSITY].set(self.mix.g.density())
|
||||
self.prop[_INTENERGY].set(self.mix.g.intEnergy_mass())
|
||||
self.prop[_ENTHALPY].set(self.mix.g.enthalpy_mass())
|
||||
self.prop[_ENTROPY].set(self.mix.g.entropy_mass())
|
||||
|
||||
def setState(self,event=None):
|
||||
if event:
|
||||
self.warn = 0
|
||||
else:
|
||||
self.warn = 1
|
||||
self.top.mixfr.update()
|
||||
i = self.equil.get()
|
||||
optlist = ['frozen','equilibrium']
|
||||
opt = [optlist[i]]
|
||||
|
||||
if self.prop[_PRESSURE].isChecked() \
|
||||
and self.prop[_TEMPERATURE].isChecked():
|
||||
self.mix.set(
|
||||
temperature = self.prop[_TEMPERATURE].get(),
|
||||
pressure = self.prop[_PRESSURE].get(),
|
||||
equil=i)
|
||||
|
||||
elif self.prop[_DENSITY].isChecked() \
|
||||
and self.prop[_TEMPERATURE].isChecked():
|
||||
self.mix.set(
|
||||
temperature = self.prop[_TEMPERATURE].get(),
|
||||
density = self.prop[_DENSITY].get(),
|
||||
equil=i)
|
||||
|
||||
elif self.prop[_ENTROPY].isChecked() \
|
||||
and self.prop[_PRESSURE].isChecked():
|
||||
self.mix.set(pressure = self.prop[_PRESSURE].get(),
|
||||
entropy = self.prop[_ENTROPY].get(),
|
||||
equil=i)
|
||||
|
||||
elif self.prop[_ENTHALPY].isChecked() \
|
||||
and self.prop[_PRESSURE].isChecked():
|
||||
self.mix.set(pressure = self.prop[_PRESSURE].get(),
|
||||
enthalpy = self.prop[_ENTHALPY].get(),
|
||||
equil=i)
|
||||
|
||||
elif self.prop[_INTENERGY].isChecked() \
|
||||
and self.prop[_DENSITY].isChecked():
|
||||
self.mix.set(density = self.prop[_DENSITY].get(),
|
||||
intEnergy = self.prop[_INTENERGY].get(),
|
||||
equil=i)
|
||||
else:
|
||||
if self.warn > 0:
|
||||
handleError("unsupported property pair")
|
||||
|
||||
self.top.update()
|
||||
66
interfaces/cython/cantera/mixmaster/ThermoProp.py
Normal file
66
interfaces/cython/cantera/mixmaster/ThermoProp.py
Normal file
@@ -0,0 +1,66 @@
|
||||
from Tkinter import *
|
||||
from UnitChooser import UnitVar
|
||||
|
||||
_tv = ['Temperature','Internal Energy','Enthalpy']
|
||||
_pv = ['Pressure', 'Density']
|
||||
|
||||
def badpair(a,b):
|
||||
if a.name in _tv:
|
||||
if not b.name in _pv:
|
||||
return 1
|
||||
else:
|
||||
if not b.name in _tv:
|
||||
return 1
|
||||
|
||||
class ThermoProp:
|
||||
def __init__(self, master, thermoframe, row, name, value, units, defaultunit=0):
|
||||
self.value = DoubleVar()
|
||||
self.thermoframe = thermoframe
|
||||
self.entry = UnitVar(master,units,defaultunit)
|
||||
self.entry.grid(column=1,row=row,sticky=W)
|
||||
self.entry.v.config(state=DISABLED,bg='lightgray')
|
||||
self.checked=IntVar()
|
||||
self.checked.set(0)
|
||||
self.name = name
|
||||
self.c=Checkbutton(master,
|
||||
text=name,
|
||||
variable=self.checked,
|
||||
onvalue=1,
|
||||
offvalue=0,
|
||||
command=self.check
|
||||
)
|
||||
self.c.grid(column=0,row=row, sticky=W+N)
|
||||
|
||||
def check(self):
|
||||
if self == self.thermoframe.last1:
|
||||
self.checked.set(1)
|
||||
return
|
||||
elif self == self.thermoframe.last2:
|
||||
self.checked.set(1)
|
||||
self.thermoframe.last2 = self.thermoframe.last1
|
||||
self.thermoframe.last1 = self
|
||||
return
|
||||
# elif badpair(self, self.thermoframe.last1):
|
||||
# self.checked.set(0)
|
||||
# return
|
||||
|
||||
self._check()
|
||||
self.thermoframe.last2.checked.set(0)
|
||||
self.thermoframe.last2._check()
|
||||
self.thermoframe.last2 = self.thermoframe.last1
|
||||
self.thermoframe.last1 = self
|
||||
|
||||
def _check(self):
|
||||
if self.isChecked():
|
||||
self.entry.v.config(state=NORMAL,bg='white')
|
||||
else:
|
||||
self.entry.v.config(state=DISABLED,bg='lightgray')
|
||||
|
||||
def isChecked(self):
|
||||
return self.checked.get()
|
||||
|
||||
def set(self, value):
|
||||
self.entry.set(value)
|
||||
|
||||
def get(self):
|
||||
return self.entry.get()
|
||||
34
interfaces/cython/cantera/mixmaster/TransportFrame.py
Normal file
34
interfaces/cython/cantera/mixmaster/TransportFrame.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from Tkinter import *
|
||||
|
||||
class TransportFrame(Frame):
|
||||
def show(self, i, frame, row, col):
|
||||
if self.checked[i].get():
|
||||
frame.grid(row=row,column=col,sticky=N+E+S+W)
|
||||
else:
|
||||
frame.grid_forget()
|
||||
|
||||
def showcomp(self):
|
||||
self.show(0, self.top.mixfr, 8, 0)
|
||||
|
||||
def showthermo(self):
|
||||
self.show(1, self.top.thermo, 7, 0)
|
||||
|
||||
def __init__(self,master,top):
|
||||
self.top = top
|
||||
self.c = []
|
||||
self.checked = []
|
||||
Frame.__init__(self,master)
|
||||
self.config(relief=GROOVE, bd=4)
|
||||
lbl = ['multicomponent', 'mixture-averaged']
|
||||
cmds = [self.showcomp, self.showthermo]
|
||||
for i in range(2):
|
||||
self.checked.append(IntVar())
|
||||
self.checked[i].set(0)
|
||||
self.c.append(Checkbutton(self,
|
||||
text=lbl[i],
|
||||
variable=self.checked[i],
|
||||
onvalue=1,
|
||||
offvalue=0,
|
||||
command=cmds[i]
|
||||
))
|
||||
self.c[i].grid(column=i,row=0, sticky=W+N)
|
||||
82
interfaces/cython/cantera/mixmaster/UnitChooser.py
Normal file
82
interfaces/cython/cantera/mixmaster/UnitChooser.py
Normal file
@@ -0,0 +1,82 @@
|
||||
from Tkinter import *
|
||||
import re
|
||||
|
||||
class UnitVar(Frame):
|
||||
def __init__(self,master,unitmod,defaultunit=0):
|
||||
Frame.__init__(self,master)
|
||||
self.x = DoubleVar()
|
||||
self.xsi = 0.0
|
||||
self.x.set(0.0)
|
||||
self.unitmod = unitmod
|
||||
try:
|
||||
self.unitlist = self.unitmod.units
|
||||
except:
|
||||
self.unitlist = []
|
||||
unitlist=dir(self.unitmod)
|
||||
for it in unitlist:
|
||||
if it[0] != '_':
|
||||
self.unitlist.append(it)
|
||||
self.v = Entry(self,textvariable=self.x)
|
||||
self.s = StringVar()
|
||||
tmp = re.sub('__',' / ',self.unitlist[defaultunit])
|
||||
self.s.set(tmp)
|
||||
self.conv = eval('self.unitmod.'+re.sub(' / ','__',self.s.get())).value
|
||||
self.u = Label(self)
|
||||
self.u.config(textvariable=self.s,fg='darkblue')
|
||||
self.u.bind('<Double-1>', self.select)
|
||||
self.u.bind('<Any-Enter>',self.highlight)
|
||||
self.u.bind('<Any-Leave>',self.nohighlight)
|
||||
self.v.grid(row=0,column=0)
|
||||
self.u.grid(row=0,column=1)
|
||||
|
||||
def highlight(self, event=None):
|
||||
self.u.config(fg='yellow')
|
||||
|
||||
def nohighlight(self, event=None):
|
||||
self.u.config(fg='darkblue')
|
||||
|
||||
def select(self, event):
|
||||
self.new=Toplevel()
|
||||
self.new.title("Units")
|
||||
self.new.transient(self.master)
|
||||
self.new.bind("<Return>", self.finished,"+")
|
||||
|
||||
r=0
|
||||
c=0
|
||||
for each in self.unitlist:
|
||||
if each[0] != '_' and each[:1] != '__' and each != 'SI':
|
||||
each = re.sub('__',' / ',each)
|
||||
Radiobutton(self.new,
|
||||
text=each,
|
||||
variable=self.u['textvariable'],
|
||||
value=each,
|
||||
command=self.update,
|
||||
).grid(column=c, row=r, sticky=W)
|
||||
r=r+1
|
||||
if (r>10):
|
||||
r=0
|
||||
c=c+1
|
||||
r=r+1
|
||||
|
||||
b=Button(self.new,text='OK',command=self.finished, default=ACTIVE)
|
||||
b.grid(column=c, row=r)
|
||||
|
||||
self.new.grab_set()
|
||||
self.new.focus_set()
|
||||
self.new.wait_window()
|
||||
|
||||
def finished(self,event=None):
|
||||
self.new.destroy()
|
||||
|
||||
def update(self):
|
||||
self.xsi = self.x.get() * self.conv
|
||||
self.conv = eval('self.unitmod.'+re.sub(' / ','__',self.s.get())).value
|
||||
self.x.set(self.xsi/self.conv)
|
||||
|
||||
def get(self):
|
||||
self.xsi = self.x.get() * self.conv
|
||||
return self.xsi
|
||||
|
||||
def set(self,value):
|
||||
self.xsi = value
|
||||
self.x.set(value/self.conv)
|
||||
113
interfaces/cython/cantera/mixmaster/Units/SI.py
Normal file
113
interfaces/cython/cantera/mixmaster/Units/SI.py
Normal file
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env python
|
||||
from unit import unit, dimensionless
|
||||
|
||||
#
|
||||
# The basic SI units
|
||||
#
|
||||
meter = unit(1.0, (1, 0, 0, 0, 0, 0, 0))
|
||||
kilogram = unit(1.0, (0, 1, 0, 0, 0, 0, 0))
|
||||
second = unit(1.0, (0, 0, 1, 0, 0, 0, 0))
|
||||
ampere = unit(1.0, (0, 0, 0, 1, 0, 0, 0))
|
||||
kelvin = unit(1.0, (0, 0, 0, 0, 1, 0, 0))
|
||||
mole = unit(1.0, (0, 0, 0, 0, 0, 1, 0))
|
||||
candela = unit(1.0, (0, 0, 0, 0, 0, 0, 1))
|
||||
|
||||
#
|
||||
# The 21 derived SI units with special names
|
||||
#
|
||||
radian = dimensionless # plane angle
|
||||
steradian = dimensionless # solid angle
|
||||
|
||||
hertz = 1/second # frequency
|
||||
|
||||
newton = meter*kilogram/second**2 # force
|
||||
pascal = newton/meter**2 # pressure
|
||||
joule = newton*meter # work, heat
|
||||
watt = joule/second # power, radiant flux
|
||||
|
||||
coulomb = ampere*second # electric charge
|
||||
volt = watt/ampere # electric potential difference
|
||||
farad = coulomb/volt # capacitance
|
||||
ohm = volt/ampere # electric resistance
|
||||
siemens = ampere/volt # electric conductance
|
||||
weber = volt*second # magnetic flux
|
||||
tesla = weber/meter**2 # magnetic flux density
|
||||
henry = weber/ampere # inductance
|
||||
|
||||
celsius = kelvin # Celsius temperature
|
||||
|
||||
lumen = candela*steradian # luminous flux
|
||||
lux = lumen/meter**2 # illuminance
|
||||
|
||||
becquerel = 1/second # radioactivity
|
||||
gray = joule/kilogram # absorbed dose
|
||||
sievert = joule/kilogram # dose equivalent
|
||||
|
||||
#
|
||||
# The prefixes
|
||||
#
|
||||
|
||||
yotta = 1e24
|
||||
zetta = 1e21
|
||||
exa = 1e18
|
||||
peta = 1e15
|
||||
tera = 1e12
|
||||
giga = 1e9
|
||||
mega = 1e6
|
||||
kilo = 1000
|
||||
hecto = 100
|
||||
deka = 10
|
||||
deci = .1
|
||||
centi = .01
|
||||
milli = .001
|
||||
micro = 1e-6
|
||||
nano = 1e-9
|
||||
pico = 1e-12
|
||||
femto = 1e-15
|
||||
atto = 1e-18
|
||||
zepto = 1e-21
|
||||
yocto = 1e-24
|
||||
|
||||
|
||||
#
|
||||
# Test
|
||||
#
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
print "The 7 base SI units:"
|
||||
print " meter: %s" % meter
|
||||
print " kilogram: %s" % kilogram
|
||||
print " second: %s" % second
|
||||
print " ampere: %s" % ampere
|
||||
print " kelvin: %s" % kelvin
|
||||
print " mole: %s" % mole
|
||||
print " candela: %s" % candela
|
||||
print
|
||||
print "The 21 SI derived units with special names:"
|
||||
print " radian: %s" % radian
|
||||
print " steradian: %s" % steradian
|
||||
print " hertz: %s" % hertz
|
||||
|
||||
print " newton: %s" % newton
|
||||
print " pascal: %s" % pascal
|
||||
print " joule: %s" % joule
|
||||
print " watt: %s" % watt
|
||||
|
||||
print " coulomb: %s" % coulomb
|
||||
print " volt: %s" % volt
|
||||
print " farad: %s" % farad
|
||||
print " ohm: %s" % ohm
|
||||
print " siemens: %s" % siemens
|
||||
print " weber: %s" % weber
|
||||
print " tesla: %s" % tesla
|
||||
print " henry: %s" % henry
|
||||
|
||||
print " degree Celsius: %s" % celsius
|
||||
|
||||
print " lumen: %s" % lumen
|
||||
print " lux: %s" % lux
|
||||
|
||||
print " becquerel: %s" % becquerel
|
||||
print " gray: %s" % gray
|
||||
print " sievert: %s" % sievert
|
||||
18
interfaces/cython/cantera/mixmaster/Units/area.py
Normal file
18
interfaces/cython/cantera/mixmaster/Units/area.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from length import meter, centimeter, inch, foot, mile
|
||||
|
||||
#
|
||||
# Definitions of common area units
|
||||
# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics",
|
||||
# fourth edition, John Willey and Sons, 1993
|
||||
|
||||
square_meter = meter**2
|
||||
square_centimeter = centimeter**2
|
||||
|
||||
square_foot = foot**2
|
||||
square_inch = inch**2
|
||||
square_mile = mile**2
|
||||
|
||||
acre = 43560 * square_foot
|
||||
hectare = 1000 * square_meter
|
||||
|
||||
barn = 1e-28 * square_meter
|
||||
11
interfaces/cython/cantera/mixmaster/Units/density.py
Normal file
11
interfaces/cython/cantera/mixmaster/Units/density.py
Normal file
@@ -0,0 +1,11 @@
|
||||
import SI, math
|
||||
|
||||
#
|
||||
# Definitions of common density units
|
||||
# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics",
|
||||
# fourth edition, John Willey and Sons, 1993
|
||||
units = ['kg__m3', 'g__m3', 'g__cm3']
|
||||
|
||||
kg__m3 = SI.kilogram/(SI.meter * SI.meter * SI.meter)
|
||||
g__m3 = 1.e-3*kg__m3
|
||||
g__cm3 = 1.e3*kg__m3
|
||||
18
interfaces/cython/cantera/mixmaster/Units/energy.py
Normal file
18
interfaces/cython/cantera/mixmaster/Units/energy.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from SI import joule
|
||||
|
||||
#
|
||||
# Definitions of common energy units
|
||||
# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics",
|
||||
# fourth edition, John Willey and Sons, 1993
|
||||
|
||||
|
||||
Btu = 1055 * joule
|
||||
erg = 1e-7 * joule
|
||||
foot_pound = 1.356 * joule
|
||||
horse_power_hour = 2.685e6 * joule
|
||||
|
||||
calorie = 4.186 * joule
|
||||
Calorie = 1000 * calorie
|
||||
kilowatt_hour = 3.6e6 * joule
|
||||
|
||||
electron_volt = 1.602e-19 * joule
|
||||
6
interfaces/cython/cantera/mixmaster/Units/force.py
Normal file
6
interfaces/cython/cantera/mixmaster/Units/force.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from SI import meter
|
||||
|
||||
#
|
||||
# Definitions of common force units
|
||||
# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics",
|
||||
# fourth edition, John Willey and Sons, 1993
|
||||
26
interfaces/cython/cantera/mixmaster/Units/length.py
Normal file
26
interfaces/cython/cantera/mixmaster/Units/length.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from SI import meter
|
||||
from SI import nano, milli, centi, kilo
|
||||
|
||||
#
|
||||
# Definitions of common length units
|
||||
# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics",
|
||||
# fourth edition, John Willey and Sons, 1993
|
||||
|
||||
|
||||
nanometer = nano * meter
|
||||
millimeter = milli * meter
|
||||
centimeter = centi * meter
|
||||
kilometer = kilo * meter
|
||||
|
||||
inch = 2.540 * centimeter
|
||||
foot = 12 * inch
|
||||
yard = 3 * foot
|
||||
mile = 5280 * foot
|
||||
|
||||
fathom = 6 * foot
|
||||
nautical_mile = 6076 * foot
|
||||
|
||||
angstrom = 1e-10 * meter
|
||||
fermi = 1e-15 * meter
|
||||
light_year = 9.460e12 * kilometer
|
||||
parsec = 3.084e13 * kilometer
|
||||
14
interfaces/cython/cantera/mixmaster/Units/mass.py
Normal file
14
interfaces/cython/cantera/mixmaster/Units/mass.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from SI import kilogram
|
||||
|
||||
#
|
||||
# Definitions of common mass units
|
||||
# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics",
|
||||
# fourth edition, John Willey and Sons, 1993
|
||||
|
||||
gram = 1e-3 * kilogram
|
||||
|
||||
metric_ton = 1000 * kilogram
|
||||
|
||||
ounce = 28.35 * gram
|
||||
pound = 16 * ounce
|
||||
ton = 2000 * pound
|
||||
9
interfaces/cython/cantera/mixmaster/Units/power.py
Normal file
9
interfaces/cython/cantera/mixmaster/Units/power.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from SI import watt, kilo
|
||||
|
||||
#
|
||||
# Definitions of common power units
|
||||
# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics",
|
||||
# fourth edition, John Willey and Sons, 1993
|
||||
|
||||
kilowatt = kilo * watt
|
||||
horsepower = 745.7 * watt
|
||||
13
interfaces/cython/cantera/mixmaster/Units/pressure.py
Normal file
13
interfaces/cython/cantera/mixmaster/Units/pressure.py
Normal file
@@ -0,0 +1,13 @@
|
||||
import SI
|
||||
|
||||
#
|
||||
# Definitions of common pressure units
|
||||
# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics",
|
||||
# fourth edition, John Willey and Sons, 1993
|
||||
|
||||
|
||||
bar = 1e5 * SI.pascal
|
||||
mbar = 100 * SI.pascal
|
||||
Pa = SI.pascal
|
||||
torr = 133.3 * SI.pascal
|
||||
atm = 1.01325e5 * SI.pascal
|
||||
14
interfaces/cython/cantera/mixmaster/Units/specificEnergy.py
Normal file
14
interfaces/cython/cantera/mixmaster/Units/specificEnergy.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import SI, energy, mass
|
||||
|
||||
#
|
||||
# Definitions of common energy units
|
||||
# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics",
|
||||
# fourth edition, John Willey and Sons, 1993
|
||||
units = ['J__kg', 'kJ__kg', 'Btu__lbm', 'cal__g', 'kcal__g', 'kcal__kg']
|
||||
|
||||
J__kg = SI.joule/SI.kilogram
|
||||
kJ__kg = 1000.0*J__kg
|
||||
Btu__lbm = energy.Btu/mass.pound
|
||||
cal__g = energy.calorie/mass.gram
|
||||
kcal__g = 1000.0*cal__g
|
||||
kcal__kg = cal__g
|
||||
@@ -0,0 +1,7 @@
|
||||
import SI, energy, mass
|
||||
|
||||
units = ['J__kg_K', 'kJ__kg_K', 'cal__g_K']
|
||||
|
||||
J__kg_K = SI.joule/(SI.kilogram * SI.kelvin)
|
||||
kJ__kg_K = 1000.0*J__kg_K
|
||||
cal__g_K = energy.calorie/(mass.gram * SI.kelvin)
|
||||
10
interfaces/cython/cantera/mixmaster/Units/speed.py
Normal file
10
interfaces/cython/cantera/mixmaster/Units/speed.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from time import hour
|
||||
from length import nautical_mile
|
||||
|
||||
#
|
||||
# Definitions of common speed units
|
||||
# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics",
|
||||
# fourth edition, John Willey and Sons, 1993
|
||||
|
||||
|
||||
knot = nautical_mile/hour
|
||||
4
interfaces/cython/cantera/mixmaster/Units/temperature.py
Normal file
4
interfaces/cython/cantera/mixmaster/Units/temperature.py
Normal file
@@ -0,0 +1,4 @@
|
||||
import SI
|
||||
|
||||
K = SI.kelvin
|
||||
R = (9.0/5.0)*K
|
||||
11
interfaces/cython/cantera/mixmaster/Units/time.py
Normal file
11
interfaces/cython/cantera/mixmaster/Units/time.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from SI import second
|
||||
|
||||
#
|
||||
# Definitions of common time units
|
||||
# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics",
|
||||
# fourth edition, John Willey and Sons, 1993
|
||||
|
||||
minute = 60 * second
|
||||
hour = 60 * minute
|
||||
day = 24 * hour
|
||||
year = 365.25 * day
|
||||
107
interfaces/cython/cantera/mixmaster/Units/unit.py
Normal file
107
interfaces/cython/cantera/mixmaster/Units/unit.py
Normal file
@@ -0,0 +1,107 @@
|
||||
import operator
|
||||
|
||||
class unit:
|
||||
|
||||
_zero = (0,) * 7
|
||||
_negativeOne = (-1, ) * 7
|
||||
|
||||
_labels = ('m', 'kg', 's', 'A', 'K', 'mol', 'cd')
|
||||
|
||||
|
||||
def __init__(self, value, derivation):
|
||||
self.value = value
|
||||
self.derivation = derivation
|
||||
return
|
||||
|
||||
|
||||
def __add__(self, other):
|
||||
if not self.derivation == other.derivation:
|
||||
raise ImcompatibleUnits(self, other)
|
||||
|
||||
return unit(self.value + other.value, self.derivation)
|
||||
|
||||
|
||||
def __sub__(self, other):
|
||||
if not self.derivation == other.derivation:
|
||||
raise ImcompatibleUnits(self, other)
|
||||
|
||||
return unit(self.value - other.value, self.derivation)
|
||||
|
||||
|
||||
def __mul__(self, other):
|
||||
if type(other) == type(0) or type(other) == type(0.0):
|
||||
return unit(other*self.value, self.derivation)
|
||||
|
||||
value = self.value * other.value
|
||||
derivation = tuple(map(operator.add, self.derivation, other.derivation))
|
||||
|
||||
return unit(value, derivation)
|
||||
|
||||
|
||||
def __div__(self, other):
|
||||
if type(other) == type(0) or type(other) == type(0.0):
|
||||
return unit(self.value/other, self.derivation)
|
||||
|
||||
value = self.value / other.value
|
||||
derivation = tuple(map(operator.sub, self.derivation, other.derivation))
|
||||
|
||||
return unit(value, derivation)
|
||||
|
||||
|
||||
def __pow__(self, other):
|
||||
if type(other) != type(0) and type(other) != type(0.0):
|
||||
raise BadOperation
|
||||
|
||||
value = self.value ** other
|
||||
derivation = tuple(map(operator.mul, [other]*7, self.derivation))
|
||||
|
||||
return unit(value, derivation)
|
||||
|
||||
|
||||
def __pos__(self): return self
|
||||
|
||||
|
||||
def __neg__(self): return unit(-self.value, self.derivation)
|
||||
|
||||
|
||||
def __abs__(self): return unit(abs(self.value), self.derivation)
|
||||
|
||||
|
||||
def __invert__(self):
|
||||
value = 1./self.value
|
||||
derivation = tuple(map(operator.mul, self._negativeOne, self.derivation))
|
||||
return unit(value, derivation)
|
||||
|
||||
|
||||
def __rmul__(self, other):
|
||||
return unit.__mul__(self, other)
|
||||
|
||||
def __rdiv__(self, other):
|
||||
if type(other) != type(0) and type(other) != type(0.0):
|
||||
raise BadOperation(self, other)
|
||||
|
||||
value = other/self.value
|
||||
derivation = tuple(map(operator.mul, self._negativeOne, self.derivation))
|
||||
|
||||
return unit(value, derivation)
|
||||
|
||||
|
||||
def __float__(self):
|
||||
return self.value
|
||||
#if self.derivation == self._zero: return self.value
|
||||
#raise BadConversion(self)
|
||||
|
||||
|
||||
def __str__(self):
|
||||
str = "%g" % self.value
|
||||
for i in range(0, 7):
|
||||
exponent = self.derivation[i]
|
||||
if exponent == 0: continue
|
||||
if exponent == 1:
|
||||
str = str + " %s" % (self._labels[i])
|
||||
else:
|
||||
str = str + " %s^%d" % (self._labels[i], exponent)
|
||||
|
||||
return str
|
||||
|
||||
dimensionless = unit(1, unit._zero)
|
||||
18
interfaces/cython/cantera/mixmaster/Units/volume.py
Normal file
18
interfaces/cython/cantera/mixmaster/Units/volume.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from length import meter, centimeter, foot, inch
|
||||
|
||||
#
|
||||
# Definitions of common volume units
|
||||
# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics",
|
||||
# fourth edition, John Willey and Sons, 1993
|
||||
|
||||
cubic_meter = meter**3
|
||||
cubic_centimeter = centimeter**3
|
||||
cubic_foot = foot**3
|
||||
cubic_inch = inch**3
|
||||
|
||||
liter = 1000 * cubic_centimeter
|
||||
|
||||
us_fluid_ounce = 231./128 * cubic_inch
|
||||
us_pint = 16 * us_fluid_ounce
|
||||
us_fluid_quart = 2 * us_pint
|
||||
us_fluid_gallon = 4 * us_fluid_quart
|
||||
4
interfaces/cython/cantera/mixmaster/__init__.py
Normal file
4
interfaces/cython/cantera/mixmaster/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
# from Cantera import *
|
||||
|
||||
from main import MixMaster
|
||||
5
interfaces/cython/cantera/mixmaster/config.py
Normal file
5
interfaces/cython/cantera/mixmaster/config.py
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
from Cantera import *
|
||||
|
||||
# thermo parametrizations
|
||||
#from Cantera.Species.Thermo.NasaPolynomial import NasaPolynomial
|
||||
55
interfaces/cython/cantera/mixmaster/flowpanel.py
Normal file
55
interfaces/cython/cantera/mixmaster/flowpanel.py
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
|
||||
# functionality imports
|
||||
from Tkinter import *
|
||||
|
||||
from Cantera.gui import menu, newflow
|
||||
|
||||
class App:
|
||||
def __init__(self, master):
|
||||
|
||||
try:
|
||||
self.root = master.root
|
||||
except:
|
||||
self.root = master
|
||||
|
||||
self.frame = Frame(master)
|
||||
self.frame.grid(row = 0, column = 0)
|
||||
|
||||
self.makemenu(self.frame)
|
||||
|
||||
self.quitbutton = Button(self.frame, text = "Quit",
|
||||
command = self.frame.quit)
|
||||
self.quitbutton.grid(row = 1, column = 0)
|
||||
|
||||
self.newbutton = Button(self.frame, text = "New...",
|
||||
command = self.notyet)
|
||||
self.newbutton.grid(row = 1, column = 1)
|
||||
|
||||
def notyet(self):
|
||||
print 'not yet!'
|
||||
|
||||
|
||||
def newflow(self):
|
||||
n = newflow.NewFlowDialog(self.root)
|
||||
|
||||
def makemenu(self,frame):
|
||||
self.menubar = Frame(frame, relief=FLAT, bd=0)
|
||||
self.menubar.grid(row = 0, column = 0)
|
||||
|
||||
self.filemenu = menu.make_menu('File', self.menubar,
|
||||
[('New...', self.newflow),
|
||||
('Open...', self.notyet),
|
||||
('Save As...', self.notyet),
|
||||
'separator',
|
||||
('Exit', frame.quit),
|
||||
[]
|
||||
])
|
||||
|
||||
|
||||
|
||||
root = Tk()
|
||||
|
||||
app = App(root)
|
||||
|
||||
root.mainloop()
|
||||
1186
interfaces/cython/cantera/mixmaster/gri30.py
Normal file
1186
interfaces/cython/cantera/mixmaster/gri30.py
Normal file
File diff suppressed because it is too large
Load Diff
325
interfaces/cython/cantera/mixmaster/main.py
Normal file
325
interfaces/cython/cantera/mixmaster/main.py
Normal file
@@ -0,0 +1,325 @@
|
||||
#############################################################################
|
||||
#
|
||||
# MixMaster
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
# options
|
||||
_app_title = 'MixMaster'
|
||||
_app_version = '1.0'
|
||||
|
||||
|
||||
# functionality imports
|
||||
from Tkinter import *
|
||||
import tkMessageBox
|
||||
import sys, os, string
|
||||
|
||||
# Cantera imports
|
||||
from Cantera import *
|
||||
from Cantera.num import zeros
|
||||
import utilities
|
||||
from Cantera.gases import IdealGasMix
|
||||
|
||||
# local imports
|
||||
from TransportFrame import TransportFrame
|
||||
from CompositionFrame import MixtureFrame
|
||||
from ThermoFrame import ThermoFrame
|
||||
from ImportFrame import ImportFrame
|
||||
from DataFrame import DataFrame
|
||||
from KineticsFrame import SpeciesKineticsFrame, ReactionKineticsFrame, ReactionPathFrame
|
||||
#from Edit import EditFrame
|
||||
from MechManager import MechManager, _autoload
|
||||
from UnitChooser import UnitVar
|
||||
from ControlPanel import ControlWindow
|
||||
from ControlPanel import make_menu, menuitem_state
|
||||
from Mix import Mix, Species
|
||||
|
||||
def testit():
|
||||
return
|
||||
|
||||
|
||||
class MixMaster:
|
||||
|
||||
def stop(self):
|
||||
sys.exit(0)
|
||||
|
||||
def openmech(self):
|
||||
from tkFileDialog import askopenfilename
|
||||
pathname = askopenfilename(filetypes=[("Cantera Input Files", "*.cti"),
|
||||
("XML Files", "*.xml *.ctml"),
|
||||
("All Files", "*.*")])
|
||||
if pathname:
|
||||
self.loadmech('', pathname)
|
||||
|
||||
|
||||
def loadmech(self, mechname, pathname, mw=1):
|
||||
|
||||
p = os.path.normpath(os.path.dirname(pathname))
|
||||
self.fname = os.path.basename(pathname)
|
||||
ff = os.path.splitext(self.fname)
|
||||
|
||||
try:
|
||||
self.mech = IdealGasMix(pathname)
|
||||
self.mechname = ff[0]
|
||||
|
||||
except:
|
||||
utilities.handleError('could not create gas mixture object: '
|
||||
+ff[0]+'\n')
|
||||
self.mechname = 'Error'
|
||||
return
|
||||
|
||||
self.makeMix()
|
||||
|
||||
if not mechname:
|
||||
mechname = self.mechname
|
||||
|
||||
self.mechframe.addMechanism(mechname, self.mech)
|
||||
if mw==1:
|
||||
self.makeWindows()
|
||||
|
||||
|
||||
def addWindow(self, name, w):
|
||||
"""Add a new window, or replace an existing one."""
|
||||
wstate = ''
|
||||
if self._windows.has_key(name):
|
||||
try:
|
||||
wstate = self._windows[name].master.state()
|
||||
self._windows[name].master.destroy()
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
wstate = 'withdrawn'
|
||||
self._windows[name] = w
|
||||
self._vis[name] = IntVar()
|
||||
if wstate == 'withdrawn':
|
||||
self._windows[name].master.withdraw()
|
||||
else:
|
||||
self._windows[name].show()
|
||||
|
||||
|
||||
|
||||
def update(self):
|
||||
"""Update all windows to reflect the current mixture state."""
|
||||
for w in self._windows.keys():
|
||||
try:
|
||||
m = self._windows[w].master
|
||||
if m.state() != 'withdrawn':
|
||||
self._windows[w].show()
|
||||
except:
|
||||
pass
|
||||
self.thermo.showState()
|
||||
self.mixfr.show()
|
||||
|
||||
|
||||
|
||||
def makeMix(self):
|
||||
self.mix = Mix(self.mech)
|
||||
nsp = self.mech.nSpecies()
|
||||
self.species = []
|
||||
nm = self.mech.speciesNames()
|
||||
|
||||
for k in range(nsp):
|
||||
self.species.append(Species(self.mech, nm[k]))
|
||||
|
||||
x = self.mech.moleFractions()
|
||||
self.mix.setMoles(x)
|
||||
self.mix.set(temperature = self.mech.temperature(),
|
||||
pressure = self.mech.pressure())
|
||||
|
||||
|
||||
|
||||
def __init__(self, master=None):
|
||||
"""
|
||||
Create a new Application instance.
|
||||
Usually this is only called once.
|
||||
"""
|
||||
if master:
|
||||
self.master = master
|
||||
else:
|
||||
t = Tk()
|
||||
self.master = t
|
||||
|
||||
self._windows = {}
|
||||
self._vis = {}
|
||||
self.windows = []
|
||||
|
||||
self.cwin = ControlWindow(_app_title,self.master)
|
||||
self.cwin.master.resizable(FALSE,FALSE)
|
||||
|
||||
self.menubar = Frame(self.cwin, relief=GROOVE,bd=2)
|
||||
self.menubar.grid(row=0,column=0,sticky=N+W+E)
|
||||
|
||||
self.mixfr = None
|
||||
self.thermo = None
|
||||
self.transport = None
|
||||
self.kinetics = None
|
||||
self.rxndata = None
|
||||
self.rxnpaths = None
|
||||
self.edit = None
|
||||
self.fname = None
|
||||
|
||||
self.mechframe = MechManager(self.cwin, self)
|
||||
self.mechframe.grid(row=1,column=0,sticky=N+W)
|
||||
|
||||
fileitems = [('Load Mixture...', self.openmech),
|
||||
('Import Mechanism File...',self.importfile),
|
||||
'separator',
|
||||
('Load Data File...',self.showdata),
|
||||
'separator',
|
||||
('Exit', self.stop),
|
||||
[]
|
||||
]
|
||||
self.filemenu = make_menu('File', self.menubar, fileitems)
|
||||
|
||||
|
||||
self.vtherm = IntVar()
|
||||
self.vcomp = IntVar()
|
||||
self.vtran = IntVar()
|
||||
self.vkin = IntVar()
|
||||
self.vrxn = IntVar()
|
||||
self.vrxn.set(0)
|
||||
self.vtherm.set(1)
|
||||
self.vedit = IntVar()
|
||||
|
||||
|
||||
dataitems = [(' Import Flame Data', testit),
|
||||
(' Import CSV Data', testit),
|
||||
[]]
|
||||
#self.datamenu = make_menu('Data', self.menubar, dataitems)
|
||||
|
||||
|
||||
#toolitems = [(' Convert...', self.importfile),
|
||||
# []]
|
||||
#self.toolmenu = make_menu('Tools', self.menubar, toolitems)
|
||||
|
||||
|
||||
w = [(' Thermodynamic State', self.showthermo, 'check', self.vtherm),
|
||||
(' Composition', self.showcomp, 'check', self.vcomp),
|
||||
'separator',
|
||||
(' Kinetics', self.showkinetics, 'check', self.vkin),
|
||||
(' Reactions...', self.showrxns),
|
||||
(' Reaction Paths...', self.showrpaths),
|
||||
[]]
|
||||
|
||||
self.viewmenu = make_menu('Windows', self.menubar, w)
|
||||
|
||||
self.helpmenu = make_menu('Help', self.menubar,
|
||||
[('About '+_app_title+'...', self.aboutmix),
|
||||
('About Cantera...', testit),
|
||||
[]
|
||||
|
||||
])
|
||||
|
||||
# load the preloaded mechanisms
|
||||
for m in _autoload:
|
||||
self.loadmech(m[0],m[1],0)
|
||||
|
||||
self.makeWindows()
|
||||
self.addWindow('import',ImportFrame(self))
|
||||
|
||||
self.vtherm.set(1)
|
||||
self.showthermo()
|
||||
## self.vcomp.set(1)
|
||||
## self.showcomp()
|
||||
|
||||
self.master.iconify()
|
||||
self.master.update()
|
||||
self.master.deiconify()
|
||||
self.cwin.mainloop()
|
||||
|
||||
|
||||
def importfile(self):
|
||||
#self.vimport.set(1)
|
||||
w = self._windows['import']
|
||||
w.show()
|
||||
|
||||
|
||||
def makeWindows(self):
|
||||
# if self.mixfr:
|
||||
for w in self.windows:
|
||||
try:
|
||||
w.destroy()
|
||||
except:
|
||||
pass
|
||||
|
||||
fr = [MixtureFrame, ThermoFrame, TransportFrame]
|
||||
|
||||
self.mixfr = MixtureFrame(self.cwin, self)
|
||||
self.thermo = ThermoFrame(self.cwin, self)
|
||||
|
||||
# self.transport = TransportFrame(self.cwin, self)
|
||||
self.kinetics = SpeciesKineticsFrame(self.cwin, self)
|
||||
|
||||
self.addWindow('rxndata',ReactionKineticsFrame(self.vrxn, self))
|
||||
self.addWindow('rxnpaths',ReactionPathFrame(self))
|
||||
self.addWindow('dataset',DataFrame(None, self))
|
||||
|
||||
|
||||
#self.edit = EditFrame(t, self)
|
||||
|
||||
self.windows = [self.mixfr,
|
||||
self.thermo, self.transport,
|
||||
self.kinetics]
|
||||
|
||||
self.showthermo()
|
||||
self.showcomp()
|
||||
#self.showtransport()
|
||||
self.showkinetics()
|
||||
#self.showrxns()
|
||||
#self.showrpaths()
|
||||
#self.showdata()
|
||||
|
||||
if self.mech:
|
||||
self.mechframe.grid(row=1,column=0)
|
||||
else:
|
||||
self.mechframe.grid_forget()
|
||||
#self.showedit()
|
||||
|
||||
def show(self, frame, vis, row, col):
|
||||
if vis:
|
||||
frame.grid(row=row,column=col,sticky=N+E+S+W)
|
||||
else:
|
||||
frame.grid_forget()
|
||||
|
||||
def showthermo(self):
|
||||
if self.thermo:
|
||||
self.show(self.thermo, self.vtherm.get(), 7, 0)
|
||||
|
||||
def showcomp(self):
|
||||
if self.mixfr:
|
||||
self.show(self.mixfr, self.vcomp.get(), 8, 0)
|
||||
|
||||
def showkinetics(self):
|
||||
if self.kinetics:
|
||||
self.show(self.kinetics, self.vkin.get(), 10, 0)
|
||||
|
||||
def showrxns(self):
|
||||
self._windows['rxndata'].show()
|
||||
|
||||
def showrpaths(self):
|
||||
self._windows['rxnpaths'].show()
|
||||
|
||||
def showdata(self):
|
||||
self._windows['dataset'].browseForDatafile()
|
||||
|
||||
def aboutmix(self):
|
||||
|
||||
m = tkMessageBox.showinfo(title = 'About MixMaster',
|
||||
message = """
|
||||
MixMaster
|
||||
|
||||
version """+_app_version+"""
|
||||
|
||||
written by:
|
||||
|
||||
Prof. David G. Goodwin
|
||||
California Institute of Technology
|
||||
|
||||
copyright 2003
|
||||
California Institute of Technology
|
||||
""")
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
MixMaster()
|
||||
31
interfaces/cython/cantera/mixmaster/menu.py
Normal file
31
interfaces/cython/cantera/mixmaster/menu.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from Tkinter import *
|
||||
|
||||
def make_menu(name, menubar, list):
|
||||
from types import *
|
||||
button=Menubutton(menubar, text=name, padx=3,pady=1)
|
||||
button.pack(side=LEFT, anchor=W)
|
||||
menu = Menu(button,tearoff=FALSE)
|
||||
for entry in list:
|
||||
if entry == 'separator':
|
||||
menu.add_separator({})
|
||||
elif type(entry)==ListType:
|
||||
for num in entry:
|
||||
menu.entryconfig(num,state=DISABLED)
|
||||
elif type(entry[1]) != ListType:
|
||||
if len(entry) == 2 or entry[2] == 'command':
|
||||
menu.add_command(label=entry[0],
|
||||
command=entry[1])
|
||||
elif entry[2] == 'check':
|
||||
entry[3].set(0)
|
||||
if len(entry) >= 5: val = entry[4]
|
||||
else: val = 1
|
||||
menu.add_checkbutton(label=entry[0],
|
||||
command=entry[1], variable = entry[3],
|
||||
onvalue=val)
|
||||
else:
|
||||
submenu=make_menu(entry[0],menu, entry[1])
|
||||
menu.add_cascade(label=entry[0],
|
||||
menu=submenu)
|
||||
|
||||
button['menu']=menu
|
||||
return button
|
||||
130
interfaces/cython/cantera/mixmaster/newflow.py
Normal file
130
interfaces/cython/cantera/mixmaster/newflow.py
Normal file
@@ -0,0 +1,130 @@
|
||||
|
||||
from Tkinter import *
|
||||
from tkFileDialog import askopenfilename
|
||||
import tkMessageBox
|
||||
|
||||
from Cantera.gases import IdealGasMix
|
||||
from Cantera import *
|
||||
|
||||
class NewFlowDialog:
|
||||
|
||||
def __init__(self, parent):
|
||||
|
||||
top = self.top = Toplevel(parent)
|
||||
|
||||
pl = Label(top, text='Pressure')
|
||||
pl.grid(row = 0, column = 0)
|
||||
|
||||
geom = Frame(top, bd=2, relief=GROOVE)
|
||||
geom.grid(row = 1, column = 0)
|
||||
lb = Listbox(geom)
|
||||
for item in ["One-Dimensional", "Stagnation"]:
|
||||
lb.insert(END, item)
|
||||
lb.grid(row = 0, column = 0)
|
||||
glb = Listbox(geom)
|
||||
for item in ["Axisymmetric","2D"]:
|
||||
glb.insert(END, item)
|
||||
glb.grid(row = 1, column = 0)
|
||||
|
||||
# ------------- pressure input ----------------
|
||||
|
||||
self.p = DoubleVar()
|
||||
self.pbox = Entry(top, textvariable = self.p)
|
||||
self.pbox.grid(row = 0, column = 1)
|
||||
|
||||
|
||||
|
||||
# ------------- gas file name input -----------
|
||||
|
||||
|
||||
gasf = Frame(top, bd=2, relief=GROOVE)
|
||||
gasf.grid(row = 4, column = 0, columnspan=2)
|
||||
gl = Label(gasf, text='Gas Mixture Specification')
|
||||
gl.grid(row = 0, column = 0)
|
||||
|
||||
|
||||
self.infile = StringVar()
|
||||
Label(gasf, text='Mixture Input File').grid(row = 1, column = 0)
|
||||
Entry(gasf, textvariable = self.infile).grid(row = 1, column = 1)
|
||||
Button(gasf, text='Browse..', command=self.getinfile).grid(row = 1,
|
||||
column = 2)
|
||||
|
||||
self.spfile = StringVar()
|
||||
Label(gasf, text='Species Database').grid(row = 2, column = 0)
|
||||
Entry(gasf, textvariable = self.spfile).grid(row = 2, column = 1)
|
||||
Button(gasf, text='Browse..', command=self.getspfile).grid(row = 2,
|
||||
column = 2)
|
||||
|
||||
|
||||
self.trfile = StringVar()
|
||||
Label(gasf, text='Transport Database').grid(row = 3, column = 0)
|
||||
Entry(gasf, textvariable = self.trfile).grid(row = 3, column = 1)
|
||||
Button(gasf, text='Browse..', command=self.gettrfile).grid(row = 3,
|
||||
column = 2)
|
||||
|
||||
|
||||
# ------------- grid -------------------------
|
||||
|
||||
gf = Frame(top, bd=2, relief=GROOVE)
|
||||
gf.grid(row = 5, column = 0, columnspan=2)
|
||||
|
||||
gr = Label(gf, text='Initial Grid')
|
||||
gr.grid(row = 0, column = 0)
|
||||
|
||||
self.zleft = DoubleVar()
|
||||
self.zright = DoubleVar()
|
||||
ll = Label(gf, text='Left boundary at ')
|
||||
rl = Label(gf, text='Right boundary at ')
|
||||
lbb = Entry(gf, textvariable = self.zleft)
|
||||
rbb = Entry(gf, textvariable = self.zright)
|
||||
ll.grid(row = 1, column = 0)
|
||||
rl.grid(row = 2, column = 0)
|
||||
lbb.grid(row = 1, column = 1)
|
||||
rbb.grid(row = 2, column = 1)
|
||||
|
||||
ok = Button(top, text = 'OK', command=self.ok)
|
||||
ok.grid(row = 20, column = 20)
|
||||
|
||||
|
||||
|
||||
def ok(self):
|
||||
p = self.p.get()
|
||||
try:
|
||||
infile = self.infile.get()
|
||||
spfile = self.spfile.get()
|
||||
trfile = self.trfile.get()
|
||||
if spfile and trfile:
|
||||
self.gas = IdealGasMix(import_file = infile,
|
||||
thermo_db = spfile,
|
||||
transport_db = trfile)
|
||||
elif spfile:
|
||||
self.gas = IdealGasMix(import_file = infile,
|
||||
thermo_db = spfile)
|
||||
else:
|
||||
self.gas = IdealGasMix(import_file = infile)
|
||||
|
||||
except:
|
||||
tkMessageBox.showerror('Create Gas',
|
||||
'Error reading file %s. See log file for more information.' % infile)
|
||||
|
||||
#self.flow = Flow1D(flow_type = ftype, flow_geom = fgeom,
|
||||
# pressure = p, grid = gr, gas = g)
|
||||
self.top.destroy()
|
||||
|
||||
def getinfile(self):
|
||||
pathname = askopenfilename(filetypes=[
|
||||
("Input Files", "*.xml *.inp"),
|
||||
("All Files", "*.*")])
|
||||
self.infile.set(pathname)
|
||||
|
||||
def getspfile(self):
|
||||
pathname = askopenfilename(filetypes=[
|
||||
("Species Data Files", "*.xml *.dat"),
|
||||
("All Files", "*.*")])
|
||||
self.spfile.set(pathname)
|
||||
|
||||
def gettrfile(self):
|
||||
pathname = askopenfilename(filetypes=[
|
||||
("Transport Data Files", "*.xml *.dat"),
|
||||
("All Files", "*.*")])
|
||||
self.trfile.set(pathname)
|
||||
39
interfaces/cython/cantera/mixmaster/utilities.py
Normal file
39
interfaces/cython/cantera/mixmaster/utilities.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import string
|
||||
import os, sys
|
||||
import types, traceback
|
||||
|
||||
try:
|
||||
from Tkinter import Tk
|
||||
import tkMessageBox
|
||||
_hasTk = 1
|
||||
except:
|
||||
_hasTk = 0
|
||||
|
||||
|
||||
def write_CSV(f,x):
|
||||
"""write list x to file f in comma-separated-value format."""
|
||||
for e in x:
|
||||
f.write( `e`+',')
|
||||
f.write('\n')
|
||||
|
||||
|
||||
def _print_value(name, value, unitstr):
|
||||
print string.rjust(name, 15)+ \
|
||||
string.rjust('%10.5e' %value, 15) + ' ' + \
|
||||
string.ljust(unitstr,5),
|
||||
|
||||
def hasTk():
|
||||
try:
|
||||
import tkMessageBox
|
||||
return 1
|
||||
except:
|
||||
return 0
|
||||
|
||||
def handleError(message = '<error>', window = None,
|
||||
fatal = 0, warning = 0, options = None):
|
||||
if warning:
|
||||
tkMessageBox.showwarning(title = 'Warning', message = message,
|
||||
parent = window)
|
||||
else:
|
||||
m = tkMessageBox.showerror(title = 'Error', message = message,
|
||||
parent = window)
|
||||
@@ -22,6 +22,8 @@ setup(name="Cantera",
|
||||
'cantera.data',
|
||||
'cantera.test',
|
||||
'cantera.test.data',
|
||||
'cantera.mixmaster',
|
||||
'cantera.mixmaster.Units',
|
||||
'cantera.examples'],
|
||||
scripts=[@py_ctml_writer@,
|
||||
@py_ck2cti@],
|
||||
|
||||
Reference in New Issue
Block a user