/[ascend]/trunk/pygtk/ascpy.i
ViewVC logotype

Contents of /trunk/pygtk/ascpy.i

Parent Directory Parent Directory | Revision Log Revision Log


Revision 735 - (show annotations) (download)
Wed Jul 5 02:42:19 2006 UTC (17 years, 10 months ago) by johnpye
File size: 11892 byte(s)
Improved implementation of 'diagnose' window in PyGTK interface.
You can now view solver-side details about variables and relations, see the '(i)' icons.
1 /* : set syntax=cpp : */
2 /*
3 SWIG interface routines to read a file into the library
4 */
5
6 %module(directors=1) ascpy
7
8 %include <python/std_string.i>
9 %include <python/std_except.i>
10 %include <python/std_vector.i>
11 %include <python/std_map.i>
12
13 %{
14 #include "library.h"
15 #include "type.h"
16 #include "instance.h"
17 #include "variable.h"
18 #include "relation.h"
19 #include "name.h"
20 #include "reporter.h"
21 #include "simulation.h"
22 #include "solver.h"
23 #include "symchar.h"
24 #include "set.h"
25 #include "dimensions.h"
26 #include "units.h"
27 #include "extmethod.h"
28 #include "plot.h"
29 #include "curve.h"
30 #include "solverparameters.h"
31 #include "solverstatus.h"
32 #include "solverreporter.h"
33 #include "incidencematrix.h"
34 %}
35
36 // All STL runtime_errors caught to Python
37
38 %exception {
39 try {
40 $action
41 }
42 catch (std::range_error &e) {
43 SWIG_exception(SWIG_IndexError,e.what());
44 }
45 catch (std::runtime_error &e) {
46 SWIG_exception(SWIG_RuntimeError,e.what());
47 }
48 }
49
50 // Import the preferences module
51 %pythoncode {
52 import preferences;
53 }
54
55 // Set-valued instance variable
56 %pythoncode {
57 class SetIter:
58 def __init__(self,set):
59 self.set=set
60 self.index=0
61 def next(self):
62 if self.index==self.set.length():
63 raise StopIteration
64 self.index = self.index + 1
65 return self.set[self.index]
66 }
67
68 template<class T>
69 class ASCXX_Set{
70 private:
71 ASCXX_Set();
72 public:
73 const T at(const unsigned long&) const;
74 const unsigned long length() const;
75 };
76 %extend ASCXX_Set<long>{
77 %pythoncode {
78 def __getitem__(self, index):
79 return self.at(index)
80 def __iter__(self):
81 return SetIter(self)
82 }
83 }
84 %extend ASCXX_Set<SymChar>{
85 %pythoncode {
86 def __getitem__(self, index):
87 return self.at(index)
88 def __iter__(self):
89 return SetIter(self)
90 }
91 }
92
93
94 %template(ModuleVector) std::vector<Module>;
95 %template(TypeVector) std::vector<Type>;
96 %template(MethodVector) std::vector<Method>;
97 %template(InstancVector) std::vector<Instanc>;
98 %template(ExtMethodVector) std::vector<ExtMethod>;
99 %template(SetInt) ASCXX_Set<long>;
100 %template(SetString) ASCXX_Set<SymChar>;
101 %template(DoubleVector) std::vector<double>;
102 %template(IntVector) std::vector<int>;
103 %template(CurveVector) std::vector<Curve>;
104 %template(StringVector) std::vector<std::string>;
105 %template(IntStringMap) std::map<int,std::string>;
106
107 %rename(Instance) Instanc;
108 %rename(Name) Nam;#include "incidencematrix.h"
109 %rename(getSetIntValue) Instanc::getSetValue<long>;
110 %rename(getSetStringValue) Instanc::getSetValue<SymChar>;
111 %rename(Units) UnitsM;
112
113
114 // Grab a Python function object as a Python object.
115 %typemap(in) PyObject *pyfunc {
116 if (!PyCallable_Check($input)) {
117 PyErr_SetString(PyExc_TypeError, "Need a callable object!");
118 return NULL;
119 }
120 $1 = $input;
121 }
122
123 //----------------------------
124 // REPORTER: callbacks to python
125 class Reporter{
126 private:
127 ~Reporter();
128 Reporter();
129 public:
130 // use 'getReporter' instead of 'Reporter::Instance()' in python
131 void setErrorCallback(error_reporter_callback_t callback, void *client_data);
132 void setPythonErrorCallback(PyObject *pyfunc);
133 void clearPythonErrorCallback();
134 };
135
136 %extend Reporter {
137 void reportError(const char *msg){
138 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"%s", msg);
139 }
140 void reportNote(const char *msg){
141 ERROR_REPORTER_NOLINE(ASC_USER_NOTE,"%s",msg);
142 }
143 void reportWarning(const char *msg){
144 ERROR_REPORTER_NOLINE(ASC_USER_WARNING,"%s",msg);
145 }
146 void reportSuccess(const char *msg){
147 ERROR_REPORTER_NOLINE(ASC_USER_SUCCESS,"%s",msg);
148 }
149 }
150
151 // There are problems with Instance(), so use this instead:
152 Reporter *getReporter();
153
154 //----------------------------------------
155 // UNITS AND DIMENSIONS
156
157
158 class UnitsM;
159
160 class Dimensions{
161 public:
162 static const unsigned MAX_DIMS;
163 static const std::string getBaseUnit(const unsigned &);
164
165 const bool operator==(const Dimensions &) const;
166 const bool operator!=(const Dimensions &) const;
167 const bool operator<(const Dimensions &) const;
168 Dimensions(const Dimensions &);
169 const bool isWild() const;
170 const bool isDimensionless() const;
171 const short getFractionNumerator(const unsigned &) const;
172 const short getFractionDenominator(const unsigned &) const;
173 };
174
175 class UnitsM{
176 public:
177 UnitsM(const char *);
178 const SymChar getName() const; // the units description string eg 'bar' or 'kJ/kg/K'
179 const Dimensions getDimensions() const;
180 const double getConversion() const; // multiplication factor to convert eg feet to SI (metres)
181 };
182
183 %extend UnitsM{
184 %pythoncode{
185 def getConvertedValue(self,si_value):
186 _u_value = si_value / self.getConversion()
187 return str(_u_value) + " " + self.getName().toString();
188 }
189 }
190
191 /*
192 This function creates default (SI) units for any dimension given. Most
193 of the time you will want to use custom units in place of these, eg
194 'N' instead of 'kg*m/s^2'.
195 */
196 %extend Dimensions{
197 %pythoncode {
198
199 def getDefaultUnits(self):
200 if self.isDimensionless():
201 return Units("");
202
203 if self.isWild():
204 return Units("?");
205
206 # create a string representation of the current dimensions
207 numparts=[]
208 denparts=[]
209 for i in range(0, self.MAX_DIMS):
210 baseunit = self.getBaseUnit(i);
211 num = self.getFractionNumerator(i)
212 den = self.getFractionDenominator(i)
213 if num > 0:
214 if den == 1:
215 if num == 1:
216 numparts.append(baseunit)
217 else:
218 numparts.append("%s^%d" % (baseunit, num) )
219 else:
220 numparts.append("%s^(%d/%d)" % (baseunit, num, den) )
221 elif num < 0:
222 if den == 1:
223 if num == -1:
224 denparts.append(baseunit)
225 else:
226 denparts.append("%s^%d" % (baseunit, -num) )
227 else:
228 denparts.append("%s^(%d/%d)" % (baseunit, -num, den) )
229
230 if len(numparts):
231 str = "*".join(numparts)
232 else:
233 str = "1"
234
235 if len(denparts):
236 str = str + "/" + "/".join(denparts)
237
238 return Units(str)
239
240 }
241 }
242
243 /*
244 some python code for nice unicode unit strings, need to extend the units.c code as well though.
245
246 elif num == 2:
247 numparts.append(baseunit + ur'\u00b2')
248 elif num == 3:
249 numparts.append(baseunit + ur'\u00b3')
250
251 str = ur'\u00b7'.join(numparts)
252 */
253 //----------------------------
254
255 class Library{
256 public:
257 Library(const char *defaultpath=NULL);
258 ~Library();
259
260 void load(char *filename);
261 void listModules(const int &module_type=0);
262 Type &findType(const char *name);
263 std::vector<Module> getModules();
264 std::vector<Type> getModuleTypes(const Module &);
265 std::vector<ExtMethod> getExtMethods();
266 void clear();
267 };
268
269 class SymChar{
270 public:
271 SymChar(const std::string &);
272 const char *toString() const;
273 };
274 %extend SymChar{
275 const char *__repr__(){
276 return self->toString();
277 }
278 }
279
280 class Module{
281 public:
282 const char *getName() const;
283 const char *getFilename() const;
284 const struct tm *getMtime() const;
285 };
286
287 class Method{
288 public:
289 const char *getName() const;
290 };
291
292 // Renamed in python as 'Name'
293 class Nam{
294 public:
295 Nam(const SymChar &);
296 const std::string getName() const;
297 };
298
299 class Type{
300 public:
301 const SymChar getName();
302 const int getParameterCount();
303 Simulation getSimulation(const char *name);
304 std::vector<Method> getMethods();
305 const bool isRefinedSolverVar() const;
306 const bool isRefinedReal() const;
307 const Dimensions getDimensions() const;
308 const bool hasParameters() const;
309 };
310 %extend Type{
311 const char *__repr__(){
312 return self->getName().toString();
313 }
314
315 %pythoncode{
316 def getPreferredUnits(self):
317 if not self.isRefinedReal():
318 return None
319
320 _pref = preferences.Preferences()
321 #print "Checking for preferred units for %s" % self.getName()
322 _u = _pref.getPreferredUnits(self.getName().toString())
323 if _u == None:
324 # no preferred units set
325 return None
326 _units = Units(_u);
327
328 if _units.getDimensions() != self.getDimensions():
329 getReporter().reportWarning("Preferred units '%s' for type '%s' are not dimensionally correct: ignoring." % (_u, self.getName()) );
330 return None
331
332 return _units;
333 }
334 }
335
336 typedef enum{
337 ASCXX_VAR_STATUS_UNKNOWN=0, ASCXX_VAR_FIXED, ASCXX_VAR_UNSOLVED, ASCXX_VAR_ACTIVE, ASCXX_VAR_SOLVED
338 } VarStatus;
339
340 class Instanc{
341 private:
342 Instanc();
343 public:
344 Instanc(Instance *);
345 Instanc(Instance *, SymChar &name);
346 ~Instanc();
347 std::vector<Instanc> getChildren();
348 const std::string getKindStr() const;
349 const SymChar &getName();
350 const Type getType() const;
351 const bool isAtom() const;
352 const bool isFixed() const;
353 const bool isFund() const;
354 const bool isConst() const;
355 const bool isAssigned() const;
356 const bool isCompound() const;
357 const bool isRelation() const;
358 const bool isWhen() const;
359 const bool isSet() const; // a set (group) of things
360 const bool isSetInt() const;
361 const bool isSetString() const;
362 const bool isSetEmpty() const;
363 const bool isDefined() const;
364 const bool isBool() const;
365 const bool isInt() const;
366 const bool isSymbol() const;
367 const bool isReal() const;
368 const double getRealValue() const;
369 const bool isDimensionless() const;
370 const Dimensions getDimensions() const;
371 const bool getBoolValue() const;
372 const long getIntValue() const;
373 const SymChar getSymbolValue() const;
374 const std::string getValueAsString() const; ///< Use carefully: rounding will occur for doubles!
375
376 const std::string getRelationAsString(const Instanc &relative_to) const;
377 const double getResidual() const;
378
379 Plot getPlot() const;
380
381 const bool isPlottable() const;
382 const ASCXX_Set<long> getSetValue<long>() const;
383 const ASCXX_Set<SymChar> getSetValue<SymChar>() const;
384 const bool isChildless() const;
385 void setFixed(const bool &val=true);
386 void setRealValue(const double &val);
387 void setRealValueWithUnits(const double &, const char *);
388 void setBoolValue(const bool &val);
389 void write();
390
391 const VarStatus getVarStatus() const;
392
393 void setLowerBound(const double &);
394 void setUpperBound(const double &);
395 void setNominal(const double &);
396 const double getLowerBound() const;
397 const double getUpperBound() const;
398 const double getNominal() const;
399
400 const std::vector<Instanc> getClique() const;
401 };
402
403 %extend Instanc{
404 const char *__repr__(){
405 return self->getName().toString();
406 }
407 %pythoncode {
408 def getSetValue(self):
409 if self.isSetInt():
410 return self.getSetIntValue()
411 elif self.isSetString():
412 return self.getSetStringValue()
413 elif self.isSetEmpty():
414 return set()
415 else:
416 raise RuntimeError("getSetValue: unknown set type");
417
418 def getValue(self):
419 # print "GETTING VALUE OF %s" % self.getName()
420 if self.isCompound():
421 return ""
422 elif self.isRelation():
423 return self.getResidual()
424 elif self.isWhen():
425 return "WHEN"
426 elif self.isSet():
427 _s = set(self.getSetValue());
428 #for _v in self.getSetValue():
429 # _s.add( _v )
430 return _s
431
432 elif ( self.isAtom() or self.isFund() ) and not self.isDefined():
433 return "undefined"
434 elif self.isReal():
435 return self.getRealValueAndUnits()
436 elif self.isBool():
437 return self.getBoolValue()
438 elif self.isInt():
439 return self.getIntValue()
440 elif self.isSymbol():
441 return self.getSymbolValue()
442 else:
443 return "UNKNOWN TYPE" #raise RuntimeError("Unknown value model type="+self.getType().getName().toString()+", instance kind=".getKindStr())
444
445 def getRealValueAndUnits(self):
446 if not self.isReal():
447 raise TypeError
448 if self.isDimensionless():
449 return self.getRealValue();
450 _u = self.getType().getPreferredUnits();
451 if _u == None:
452 return str(self.getRealValue()) + ' ' + self.getDimensions().getDefaultUnits().getName().toString()
453 return _u.getConvertedValue(self.getRealValue())
454
455 def setFixedValue(self,val):
456 if not self.isFixed():
457 self.setFixed();
458 # getReporter().reportError("Setting value of %s to %s" % (self.getName().toString(),val))
459 self.setRealValue(val);
460 }
461 }
462
463 %include "solver.i"
464
465 class ExtMethod{
466 public:
467 ExtMethod(const ExtMethod &);
468 const char *getName() const;
469 const char *getHelp() const;
470 const unsigned long getNumInputs() const;
471 const unsigned long getNumOutputs() const;
472 };
473
474 %include "plot.i"
475
476 class Curve : public Instanc{
477
478 public:
479 std::vector<double> x;
480 std::vector<double> y;
481 const std::string getLegend() const;
482
483 };

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