/[ascend]/trunk/pygtk/integrator.py
ViewVC logotype

Contents of /trunk/pygtk/integrator.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 669 - (show annotations) (download) (as text)
Wed Jun 21 07:00:45 2006 UTC (13 years, 7 months ago) by johnpye
File MIME type: text/x-python
File size: 6536 byte(s)
Merged changes from DAE branch (revisions 702 to 819) back into trunk.
This adds the Integration API to the ASCEND solver (in base/generic).
Also provides pre-alpha support for 'IDA' from the SUNDIALS suite, a DAE solver.
Many other minor code clean-ups, including adoption of new 'ASC_NEW' and friends (to replace 'ascmalloc')
Added some very sketchy stuff providing 'DIFF(...)' syntax, although it is anticipated that this will be removed.
1 import ascpy
2 import time
3 import gtk
4 import gtk.glade
5 import time
6 from varentry import *
7 from preferences import *
8 from integratorreporter import *
9
10 class IntegratorError(RuntimeError):
11 def __init__(self,msg):
12 self.msg = msg
13 def __str__(self):
14 return "Input Error: %s" % self.msg;
15
16 class IntegratorWindow:
17 def __init__(self,browser,sim):
18 # create a new integrator straight away
19 self.integrator = ascpy.Integrator(sim)
20 self.engines = self.integrator.getEngines()
21
22 self.browser=browser
23 self.prefs = Preferences()
24
25 # locate all the widgets
26 _xml = gtk.glade.XML(browser.glade_file,"integratorwin")
27 _xml.signal_autoconnect(self)
28
29 self.window = _xml.get_widget("integratorwin")
30 self.window.set_transient_for(self.browser.window)
31
32 self.engineselect = _xml.get_widget("engineselect")
33 self.beginentry = _xml.get_widget("beginentry")
34 self.durationentry = _xml.get_widget("durationentry")
35 self.nstepsentry = _xml.get_widget("nstepsentry")
36 self.timedistributionselect = _xml.get_widget("timedistributionselect")
37
38 self.settings = {
39 # input field: [pref name, default value, export-to-integrator function]
40 "initialstep": [1,lambda x:self.integrator.setInitialSubStep(float(x))]
41 ,"minstep":[0.001,lambda x:self.integrator.setMinSubStep(float(x))]
42 ,"maxstep":[1000,lambda x:self.integrator.setMaxSubStep(float(x))]
43 ,"maxsteps":[100,lambda x:self.integrator.setMaxSubSteps(int(x))]
44 }
45
46 self.integratorentries={}
47 for _k in self.settings.keys():
48 _w = _xml.get_widget(_k+"entry")
49 if not _w:
50 raise RuntimeError("Couldn't find entry for"+_k)
51 self.integratorentries[_k]=_w
52
53 # fill values from user preferences, system values, etc
54 self.fill_values()
55
56 def fill_values(self):
57 _enginestore = gtk.ListStore(str)
58 self.engineselect.set_model(_enginestore)
59 _cell = gtk.CellRendererText()
60 self.engineselect.pack_start(_cell, True)
61 self.engineselect.add_attribute(_cell, 'text', 1)
62
63 _engpref = self.prefs.getStringPref("Integrator","engine","LSODE")
64 _engindex = 0
65 _i = 0
66 if len(self.engines):
67 for k in self.engines:
68 _row = _enginestore.append()
69 _enginestore.set(_row,0,self.engines[k])
70 if self.engines[k]==_engpref:
71 _engindex=_i
72 _i += 1
73
74 # set preferred integrator
75 self.engineselect.set_active(_engindex)
76 self.engineselect.set_sensitive(True)
77 else:
78 _row = _enginestore.append()
79 _enginestore.set(_row,0,"No integrators available")
80 self.engineselect.set_active(0)
81 self.engineselect.set_sensitive(False)
82
83
84 # set preferred timesteps etc
85 for _k,_v in self.settings.iteritems():
86 self.integratorentries[_k].set_text(self.prefs.getStringPref("Integrator",_k,str(_v[0])))
87
88 # get the current time value as the beginentry...
89 print "SEARCHING FOR TIME VAR..."
90 if self.integrator.findIndependentVar():
91 print "FOUND time var..."
92 _t = self.integrator.getCurrentTime();
93 print "Found time = %f" % _t
94 self.beginentry.set_text(str(_t))
95 else:
96 self.browser.reporter.reportNote("No indep var found");
97 self.beginentry.set_text("0")
98
99 self.durationentry.set_text("10")
100 self.nstepsentry.set_text("100")
101 self.timedistributionselect.set_active(0)
102
103 def on_integratorcancel_clicked(self,*args):
104 self.browser.reporter.reportNote("CANCELLING");
105 self.window.response(gtk.RESPONSE_CANCEL)
106
107 def on_entry_key_press_event(self,widget,event):
108 keyname = gtk.gdk.keyval_name(event.keyval)
109 if keyname=="Return":
110 self.window.response(gtk.RESPONSE_OK)
111 return True
112 elif keyname=="Escape":
113 self.window.response(gtk.RESPONSE_CANCEL)
114 return True;
115 return False;
116
117 def run(self):
118 # focus the engine select box when we start...
119 self.engineselect.grab_focus()
120
121 # loop around unitil either cancelled or valid entries are input
122 _ok = False
123 while True:
124 try:
125 _res = self.window.run()
126 if _res == gtk.RESPONSE_OK:
127 self.check_inputs()
128 _ok=True
129 break
130 elif _res == gtk.RESPONSE_CANCEL or _res == gtk.RESPONSE_NONE:
131 self.browser.reporter.reportNote("CANCEL event received");
132 break
133 except IntegratorError,e:
134 self.browser.reporter.reportError(str(e))
135 # continue
136
137 if _ok:
138 _res = self.integrator.analyse()
139 if _res:
140 # if we're all ok, create the reporter window and close this one
141 _integratorreporter = IntegratorReporterPython(self.browser,self.integrator)
142 self.integrator.setReporter(_integratorreporter)
143 self.window.destroy()
144 return _integratorreporter # means proceed to solve
145
146 self.window.destroy()
147 return None # can't solve
148
149 def color_entry(self,entry,color):
150 # colour an input box if it doesn't have acceptable contents
151 # error messages would be reported by the 'errors panel' in the main win
152 entry.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
153 entry.modify_bg(gtk.STATE_ACTIVE, gtk.gdk.color_parse(color))
154 entry.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
155 entry.modify_base(gtk.STATE_ACTIVE, gtk.gdk.color_parse(color))
156
157 def check_inputs(self):
158 # set the timesteps (samples)
159 _val = {}
160 for _k,_v in {
161 self.beginentry:[lambda x:float(x),"begin"]
162 , self.durationentry:[lambda x:float(x),"duration"]
163 , self.nstepsentry:[lambda x:int(x),"num"]
164 }.iteritems():
165 _val[_v[1]]=_v[0](_k.get_text())
166
167 self.integrator.setLinearTimesteps(ascpy.Units("s"), _val["begin"], (_val["begin"]+_val["duration"]), _val["num"]);
168 self.begin=_val["begin"]
169 self.duration=_val["duration"]
170
171 # set substep parameters (ie settings common to any integrator engine)
172 _failed=False
173 for _k,_v in self.settings.iteritems():
174 try:
175 _f = self.integratorentries[_k];
176 # pass the substep setting to the integrator
177 _v[1](_f.get_text())
178 self.color_entry(_f,"white")
179 except ValueError,e:
180 self.color_entry(_f,"#FFBBBB")
181 _failed=True
182
183 if _failed:
184 raise IntegratorError("Invalid step parameter(s)");
185
186 for _k,_v in self.settings.iteritems():
187 # store those inputs for next time
188 _f = self.integratorentries[_k];
189 self.prefs.setStringPref("Integrator",_k,str(_f.get_text()))
190
191 # set engine (and check that it's OK with this system)
192 engine=self.engineselect.get_active()
193 if engine==-1:
194 self.color_entry(self.engineselect,"#FFBBBB")
195 raise IntegratorError("No engine selected")
196
197 self.color_entry(self.engineselect,"white")
198
199 self.prefs.setStringPref("Integrator","engine",self.engines.values()[engine])
200
201 _res = self.integrator.setEngine(self.engines.keys()[engine])
202 if not _res:
203 raise IntegratorError("Invalid engine selected")
204

Properties

Name Value
svn:executable *

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22