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

Contents of /trunk/pygtk/ascpy.i

Parent Directory Parent Directory | Revision Log Revision Log


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