cantera/apps/MixMaster/KineticsFrame.py
2003-04-14 17:57:48 +00:00

356 lines
9.6 KiB
Python

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
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=nr)
self.data = []
for i in range(4):
self.data.append(Text(self,width=15,height=nr))
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)
# Button(self, text='View Reaction Paths', command=self.viewRxnPaths).grid(column=0,row=2,sticky=W+E+N)
self.grid(column=0,row=0)
self.hide()
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()
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)
for n in range(nr):
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)
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()
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')
if self.browser.get() == 1:
fmt = self.fmt.get()
os.system('dot -T'+fmt+' rxnpath.dot > rxnpath.'+fmt)
webbrowser.open('rxnpath.'+fmt)
try:
self.cv.delete(self.image)
except:
pass
else:
os.system(self.dot.get())
self.rp = PhotoImage(file='rxnpath.gif')
try:
self.cv.delete(self.image)
except:
pass
self.cv.configure(width=self.rp.width(),
height=self.rp.height())
self.image = self.cv.create_image(0,0,anchor=NW,
image=self.rp)