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

Contents of /trunk/pygtk/ascpy.i

Parent Directory Parent Directory | Revision Log Revision Log


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

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