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

Contents of /trunk/pygtk/ascpy.i

Parent Directory Parent Directory | Revision Log Revision Log


Revision 869 - (show annotations) (download)
Wed Oct 4 14:03:46 2006 UTC (15 years, 8 months ago) by johnpye
File size: 12277 byte(s)
'hello world' works from external python module, correctly hooks into 'browser' object.
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 %rename(set) Registry::setPyObject;
115
116
117 // Grab a Python function object as a Python object.
118 %typemap(in) PyObject *pyfunc {
119 if (!PyCallable_Check($input)) {
120 PyErr_SetString(PyExc_TypeError, "Need a callable object!");
121 return NULL;
122 }
123 $1 = $input;
124 }
125
126 //----------------------------
127 // REPORTER: callbacks to python
128 class Reporter{
129 private:
130 ~Reporter();
131 Reporter();
132 public:
133 // use 'getReporter' instead of 'Reporter::Instance()' in python
134 void setErrorCallback(error_reporter_callback_t callback, void *client_data);
135 void setPythonErrorCallback(PyObject *pyfunc);
136 void clearPythonErrorCallback();
137 };
138
139 %extend Reporter {
140 void reportError(const char *msg){
141 ERROR_REPORTER_NOLINE(ASC_USER_ERROR,"%s", msg);
142 }
143 void reportNote(const char *msg){
144 ERROR_REPORTER_NOLINE(ASC_USER_NOTE,"%s",msg);
145 }
146 void reportWarning(const char *msg){
147 ERROR_REPORTER_NOLINE(ASC_USER_WARNING,"%s",msg);
148 }
149 void reportSuccess(const char *msg){
150 ERROR_REPORTER_NOLINE(ASC_USER_SUCCESS,"%s",msg);
151 }
152 }
153
154 // There are problems with Instance(), so use this instead:
155 Reporter *getReporter();
156
157 //----------------------------------------
158 // UNITS AND DIMENSIONS
159
160
161 class UnitsM;
162
163 class Dimensions{
164 public:
165 static const unsigned MAX_DIMS;
166 static const std::string getBaseUnit(const unsigned &);
167
168 const bool operator==(const Dimensions &) const;
169 const bool operator!=(const Dimensions &) const;
170 const bool operator<(const Dimensions &) const;
171 Dimensions(const Dimensions &);
172 const bool isWild() const;
173 const bool isDimensionless() const;
174 const short getFractionNumerator(const unsigned &) const;
175 const short getFractionDenominator(const unsigned &) const;
176 };
177
178 class UnitsM{
179 public:
180 UnitsM(const char *);
181 const SymChar getName() const; // the units description string eg 'bar' or 'kJ/kg/K'
182 const Dimensions getDimensions() const;
183 const double getConversion() const; // multiplication factor to convert eg feet to SI (metres)
184 };
185
186 %extend UnitsM{
187 %pythoncode{
188 def getConvertedValue(self,si_value):
189 _u_value = si_value / self.getConversion()
190 return str(_u_value) + " " + self.getName().toString();
191 }
192 }
193
194 /*
195 This function creates default (SI) units for any dimension given. Most
196 of the time you will want to use custom units in place of these, eg
197 'N' instead of 'kg*m/s^2'.
198 */
199 %extend Dimensions{
200 %pythoncode {
201
202 def getDefaultUnits(self):
203 if self.isDimensionless():
204 return Units("");
205
206 if self.isWild():
207 return Units("?");
208
209 # create a string representation of the current dimensions
210 numparts=[]
211 denparts=[]
212 for i in range(0, self.MAX_DIMS):
213 baseunit = self.getBaseUnit(i);
214 num = self.getFractionNumerator(i)
215 den = self.getFractionDenominator(i)
216 if num > 0:
217 if den == 1:
218 if num == 1:
219 numparts.append(baseunit)
220 else:
221 numparts.append("%s^%d" % (baseunit, num) )
222 else:
223 numparts.append("%s^(%d/%d)" % (baseunit, num, den) )
224 elif num < 0:
225 if den == 1:
226 if num == -1:
227 denparts.append(baseunit)
228 else:
229 denparts.append("%s^%d" % (baseunit, -num) )
230 else:
231 denparts.append("%s^(%d/%d)" % (baseunit, -num, den) )
232
233 if len(numparts):
234 str = "*".join(numparts)
235 else:
236 str = "1"
237
238 if len(denparts):
239 str = str + "/" + "/".join(denparts)
240
241 return Units(str)
242
243 }
244 }
245
246 /*
247 some python code for nice unicode unit strings, need to extend the units.c code as well though.
248
249 elif num == 2:
250 numparts.append(baseunit + ur'\u00b2')
251 elif num == 3:
252 numparts.append(baseunit + ur'\u00b3')
253
254 str = ur'\u00b7'.join(numparts)
255 */
256 //----------------------------
257
258 class Library{
259 public:
260 Library(const char *defaultpath=NULL);
261 ~Library();
262
263 void load(char *filename);
264 void listModules(const int &module_type=0);
265 Type &findType(const char *name);
266 std::vector<Module> getModules();
267 std::vector<Type> getModuleTypes(const Module &);
268 std::vector<ExtMethod> getExtMethods();
269 void clear();
270 };
271
272 class SymChar{
273 public:
274 SymChar(const std::string &);
275 const char *toString() const;
276 };
277 %extend SymChar{
278 const char *__repr__(){
279 return self->toString();
280 }
281 }
282
283 class Module{
284 public:
285 const char *getName() const;
286 const char *getFilename() const;
287 const struct tm *getMtime() const;
288 };
289
290 class Method{
291 public:
292 const char *getName() const;
293 };
294
295 // Renamed in python as 'Name'
296 class Nam{
297 public:
298 Nam(const SymChar &);
299 const std::string getName() const;
300 };
301
302 %include "compiler.h"
303 /* we can always disown Compiler * as it's a singleton */
304 %apply SWIGTYPE *DISOWN { Compiler * };
305
306 class Type{
307 public:
308 const SymChar getName();
309 const int getParameterCount();
310 Simulation getSimulation(const char *name);
311 std::vector<Method> getMethods();
312 const bool isRefinedSolverVar() const;
313 const bool isRefinedReal() const;
314 const Dimensions getDimensions() const;
315 const bool hasParameters() const;
316 };
317 %extend Type{
318 const char *__repr__(){
319 return self->getName().toString();
320 }
321
322 %pythoncode{
323 def getPreferredUnits(self):
324 if not self.isRefinedReal():
325 return None
326
327 _pref = preferences.Preferences()
328 #print "Checking for preferred units for %s" % self.getName()
329 _u = _pref.getPreferredUnits(self.getName().toString())
330 if _u == None:
331 # no preferred units set
332 return None
333 _units = Units(_u);
334
335 if _units.getDimensions() != self.getDimensions():
336 getReporter().reportWarning("Preferred units '%s' for type '%s' are not dimensionally correct: ignoring." % (_u, self.getName()) );
337 return None
338
339 return _units;
340 }
341 }
342
343 typedef enum{
344 ASCXX_VAR_STATUS_UNKNOWN=0, ASCXX_VAR_FIXED, ASCXX_VAR_UNSOLVED, ASCXX_VAR_ACTIVE, ASCXX_VAR_SOLVED
345 } VarStatus;
346
347 class Instanc{
348 private:
349 Instanc();
350 public:
351 Instanc(Instance *);
352 Instanc(Instance *, SymChar &name);
353 ~Instanc();
354 std::vector<Instanc> getChildren();
355 const std::string getKindStr() const;
356 const SymChar &getName();
357 const Type getType() const;
358 const bool isAtom() const;
359 const bool isFixed() const;
360 const bool isActive() const;
361 const bool isFund() const;
362 const bool isConst() const;
363 const bool isAssigned() const;
364 const bool isCompound() const;
365 const bool isRelation() const;
366 const bool isLogicalRelation() const;
367 const bool isWhen() const;
368 const bool isSet() const; // a set (group) of things
369 const bool isSetInt() const;
370 const bool isSetString() const;
371 const bool isSetEmpty() const;
372 const bool isDefined() const;
373 const bool isBool() const;
374 const bool isInt() const;
375 const bool isSymbol() const;
376 const bool isReal() const;
377 const bool isModel() const;
378
379 const double getRealValue() const;
380 const bool isDimensionless() const;
381 const Dimensions getDimensions() const;
382 const bool getBoolValue() const;
383 const long getIntValue() const;
384 const SymChar getSymbolValue() const;
385 const std::string getValueAsString() const; ///< Use carefully: rounding will occur for doubles!
386
387 const std::string getRelationAsString(const Instanc &relative_to) const;
388 const double getResidual() const;
389
390 Plot getPlot() const;
391
392 const bool isPlottable() const;
393 const ASCXX_Set<long> getSetValue<long>() const;
394 const ASCXX_Set<SymChar> getSetValue<SymChar>() const;
395 const bool isChildless() const;
396 void setFixed(const bool &val=true);
397 void setRealValue(const double &val);
398 void setRealValueWithUnits(const double &, const char *);
399 void setBoolValue(const bool &val);
400 void setSymbolValue(const SymChar &sym);
401 void write();
402
403 const VarStatus getVarStatus() const;
404
405 void setLowerBound(const double &);
406 void setUpperBound(const double &);
407 void setNominal(const double &);
408 const double getLowerBound() const;
409 const double getUpperBound() const;
410 const double getNominal() const;
411
412 const std::vector<Instanc> getClique() const;
413 };
414
415 %extend Instanc{
416 const char *__repr__(){
417 return self->getName().toString();
418 }
419 %pythoncode {
420 def getSetValue(self):
421 if self.isSetInt():
422 return self.getSetIntValue()
423 elif self.isSetString():
424 return self.getSetStringValue()
425 elif self.isSetEmpty():
426 return set()
427 else:
428 raise RuntimeError("getSetValue: unknown set type");
429
430 def getValue(self):
431 # print "GETTING VALUE OF %s" % self.getName()
432 if self.isCompound():
433 return ""
434 elif self.isRelation():
435 return self.getResidual()
436 elif self.isWhen():
437 return "WHEN"
438 elif self.isSet():
439 _s = set(self.getSetValue());
440 #for _v in self.getSetValue():
441 # _s.add( _v )
442 return _s
443
444 elif ( self.isAtom() or self.isFund() ) and not self.isDefined():
445 return "undefined"
446 elif self.isReal():
447 return self.getRealValueAndUnits()
448 elif self.isBool():
449 return self.getBoolValue()
450 elif self.isInt():
451 return self.getIntValue()
452 elif self.isSymbol():
453 return self.getSymbolValue()
454 else:
455 return "UNKNOWN TYPE" #raise RuntimeError("Unknown value model type="+self.getType().getName().toString()+", instance kind=".getKindStr())
456
457 def getRealValueAndUnits(self):
458 if not self.isReal():
459 raise TypeError
460 if self.isDimensionless():
461 return self.getRealValue();
462 _u = self.getType().getPreferredUnits();
463 if _u == None:
464 return str(self.getRealValue()) + ' ' + self.getDimensions().getDefaultUnits().getName().toString()
465 return _u.getConvertedValue(self.getRealValue())
466
467 def setFixedValue(self,val):
468 if not self.isFixed():
469 self.setFixed();
470 # getReporter().reportError("Setting value of %s to %s" % (self.getName().toString(),val))
471 self.setRealValue(val);
472 }
473 }
474
475 %include "config.h"
476 %include "registry.h"
477
478 %include "solver.i"
479
480 class ExtMethod{
481 public:
482 ExtMethod(const ExtMethod &);
483 const char *getName() const;
484 const char *getHelp() const;
485 const unsigned long getNumInputs() const;
486 const unsigned long getNumOutputs() const;
487 };
488
489 %include "plot.i"
490
491 class Curve : public Instanc{
492
493 public:
494 std::vector<double> x;
495 std::vector<double> y;
496 const std::string getLegend() const;
497
498 };

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