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

Contents of /trunk/pygtk/ascpy.i

Parent Directory Parent Directory | Revision Log Revision Log


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

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