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

Annotation of /trunk/pygtk/integrator.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 669 - (hide annotations) (download) (as text)
Wed Jun 21 07:00:45 2006 UTC (18 years, 1 month 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 johnpye 669 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