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

Contents of /trunk/pygtk/ascpy.i

Parent Directory Parent Directory | Revision Log Revision Log


Revision 871 - (show annotations) (download)
Thu Oct 5 09:30:08 2006 UTC (14 years, 3 months ago) by johnpye
File size: 12316 byte(s)
Changed the way that SWIG accesses the C++ 'Registry' class in the case of Python (trying to make it language neutral)
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 %pythoncode {
418 def getSetValue(self):
419 if self.isSetInt():
420 return self.getSetIntValue()
421 elif self.isSetString():
422 return self.getSetStringValue()
423 elif self.isSetEmpty():
424 return set()
425 else:
426 raise RuntimeError("getSetValue: unknown set type");
427
428 def getValue(self):
429 # print "GETTING VALUE OF %s" % self.getName()
430 if self.isCompound():
431 return ""
432 elif self.isRelation():
433 return self.getResidual()
434 elif self.isWhen():
435 return "WHEN"
436 elif self.isSet():
437 _s = set(self.getSetValue());
438 #for _v in self.getSetValue():
439 # _s.add( _v )
440 return _s
441
442 elif ( self.isAtom() or self.isFund() ) and not self.isDefined():
443 return "undefined"
444 elif self.isReal():
445 return self.getRealValueAndUnits()
446 elif self.isBool():
447 return self.getBoolValue()
448 elif self.isInt():
449 return self.getIntValue()
450 elif self.isSymbol():
451 return self.getSymbolValue()
452 else:
453 return "UNKNOWN TYPE" #raise RuntimeError("Unknown value model type="+self.getType().getName().toString()+", instance kind=".getKindStr())
454
455 def getRealValueAndUnits(self):
456 if not self.isReal():
457 raise TypeError
458 if self.isDimensionless():
459 return self.getRealValue();
460 _u = self.getType().getPreferredUnits();
461 if _u == None:
462 return str(self.getRealValue()) + ' ' + self.getDimensions().getDefaultUnits().getName().toString()
463 return _u.getConvertedValue(self.getRealValue())
464
465 def setFixedValue(self,val):
466 if not self.isFixed():
467 self.setFixed();
468 # getReporter().reportError("Setting value of %s to %s" % (self.getName().toString(),val))
469 self.setRealValue(val);
470 }
471 }
472
473 %include "registry.h"
474 %extend Registry{
475 void set(const char *key, PyObject *obj){
476 self->setPyObject(key,obj);
477 }
478 }
479
480 %include "solver.i"
481
482 class ExtMethod{
483 public:
484 ExtMethod(const ExtMethod &);
485 const char *getName() const;
486 const char *getHelp() const;
487 const unsigned long getNumInputs() const;
488 const unsigned long getNumOutputs() const;
489 };
490
491 %include "plot.i"
492
493 class Curve : public Instanc{
494
495 public:
496 std::vector<double> x;
497 std::vector<double> y;
498 const std::string getLegend() const;
499
500 };

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