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

Contents of /trunk/pygtk/ascpy.i

Parent Directory Parent Directory | Revision Log Revision Log


Revision 774 - (show annotations) (download)
Fri Jul 14 08:01:48 2006 UTC (16 years, 2 months ago) by johnpye
File size: 12065 byte(s)
Added the ability to run methods on sub-models within a simulation. Use the right-click context menu.
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 %}
36
37 // All STL runtime_errors caught to Python
38
39 %exception {
40 try {
41 $action
42 }
43 catch (std::range_error &e) {
44 SWIG_exception(SWIG_IndexError,e.what());
45 }
46 catch (std::runtime_error &e) {
47 SWIG_exception(SWIG_RuntimeError,e.what());
48 }
49 }
50
51 // Import the preferences module
52 %pythoncode {
53 import preferences;
54 }
55
56 // Set-valued instance variable
57 %pythoncode {
58 class SetIter:
59 def __init__(self,set):
60 self.set=set
61 self.index=0
62 def next(self):
63 if self.index==self.set.length():
64 raise StopIteration
65 self.index = self.index + 1
66 return self.set[self.index]
67 }
68
69 template<class T>
70 class ASCXX_Set{
71 private:
72 ASCXX_Set();
73 public:
74 const T at(const unsigned long&) const;
75 const unsigned long length() const;
76 };
77 %extend ASCXX_Set<long>{
78 %pythoncode {
79 def __getitem__(self, index):
80 return self.at(index)
81 def __iter__(self):
82 return SetIter(self)
83 }
84 }
85 %extend ASCXX_Set<SymChar>{
86 %pythoncode {
87 def __getitem__(self, index):
88 return self.at(index)
89 def __iter__(self):
90 return SetIter(self)
91 }
92 }
93
94
95 %template(ModuleVector) std::vector<Module>;
96 %template(TypeVector) std::vector<Type>;
97 %template(MethodVector) std::vector<Method>;
98 %template(InstancVector) std::vector<Instanc>;
99 %template(ExtMethodVector) std::vector<ExtMethod>;
100 %template(SetInt) ASCXX_Set<long>;
101 %template(SetString) ASCXX_Set<SymChar>;
102 %template(DoubleVector) std::vector<double>;
103 %template(IntVector) std::vector<int>;
104 %template(CurveVector) std::vector<Curve>;
105 %template(StringVector) std::vector<std::string>;
106 %template(IntStringMap) std::map<int,std::string>;
107
108 %rename(Instance) Instanc;
109 %rename(Name) Nam;#include "incidencematrix.h"
110 %rename(getSetIntValue) Instanc::getSetValue<long>;
111 %rename(getSetStringValue) Instanc::getSetValue<SymChar>;
112 %rename(Units) UnitsM;
113
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 isFund() const;
359 const bool isConst() const;
360 const bool isAssigned() const;
361 const bool isCompound() const;
362 const bool isRelation() const;
363 const bool isWhen() const;
364 const bool isSet() const; // a set (group) of things
365 const bool isSetInt() const;
366 const bool isSetString() const;
367 const bool isSetEmpty() const;
368 const bool isDefined() const;
369 const bool isBool() const;
370 const bool isInt() const;
371 const bool isSymbol() const;
372 const bool isReal() const;
373 const bool isModel() const;
374
375 const double getRealValue() const;
376 const bool isDimensionless() const;
377 const Dimensions getDimensions() const;
378 const bool getBoolValue() const;
379 const long getIntValue() const;
380 const SymChar getSymbolValue() const;
381 const std::string getValueAsString() const; ///< Use carefully: rounding will occur for doubles!
382
383 const std::string getRelationAsString(const Instanc &relative_to) const;
384 const double getResidual() const;
385
386 Plot getPlot() const;
387
388 const bool isPlottable() const;
389 const ASCXX_Set<long> getSetValue<long>() const;
390 const ASCXX_Set<SymChar> getSetValue<SymChar>() const;
391 const bool isChildless() const;
392 void setFixed(const bool &val=true);
393 void setRealValue(const double &val);
394 void setRealValueWithUnits(const double &, const char *);
395 void setBoolValue(const bool &val);
396 void write();
397
398 const VarStatus getVarStatus() const;
399
400 void setLowerBound(const double &);
401 void setUpperBound(const double &);
402 void setNominal(const double &);
403 const double getLowerBound() const;
404 const double getUpperBound() const;
405 const double getNominal() const;
406
407 const std::vector<Instanc> getClique() const;
408 };
409
410 %extend Instanc{
411 const char *__repr__(){
412 return self->getName().toString();
413 }
414 %pythoncode {
415 def getSetValue(self):
416 if self.isSetInt():
417 return self.getSetIntValue()
418 elif self.isSetString():
419 return self.getSetStringValue()
420 elif self.isSetEmpty():
421 return set()
422 else:
423 raise RuntimeError("getSetValue: unknown set type");
424
425 def getValue(self):
426 # print "GETTING VALUE OF %s" % self.getName()
427 if self.isCompound():
428 return ""
429 elif self.isRelation():
430 return self.getResidual()
431 elif self.isWhen():
432 return "WHEN"
433 elif self.isSet():
434 _s = set(self.getSetValue());
435 #for _v in self.getSetValue():
436 # _s.add( _v )
437 return _s
438
439 elif ( self.isAtom() or self.isFund() ) and not self.isDefined():
440 return "undefined"
441 elif self.isReal():
442 return self.getRealValueAndUnits()
443 elif self.isBool():
444 return self.getBoolValue()
445 elif self.isInt():
446 return self.getIntValue()
447 elif self.isSymbol():
448 return self.getSymbolValue()
449 else:
450 return "UNKNOWN TYPE" #raise RuntimeError("Unknown value model type="+self.getType().getName().toString()+", instance kind=".getKindStr())
451
452 def getRealValueAndUnits(self):
453 if not self.isReal():
454 raise TypeError
455 if self.isDimensionless():
456 return self.getRealValue();
457 _u = self.getType().getPreferredUnits();
458 if _u == None:
459 return str(self.getRealValue()) + ' ' + self.getDimensions().getDefaultUnits().getName().toString()
460 return _u.getConvertedValue(self.getRealValue())
461
462 def setFixedValue(self,val):
463 if not self.isFixed():
464 self.setFixed();
465 # getReporter().reportError("Setting value of %s to %s" % (self.getName().toString(),val))
466 self.setRealValue(val);
467 }
468 }
469
470 %include "solver.i"
471
472 class ExtMethod{
473 public:
474 ExtMethod(const ExtMethod &);
475 const char *getName() const;
476 const char *getHelp() const;
477 const unsigned long getNumInputs() const;
478 const unsigned long getNumOutputs() const;
479 };
480
481 %include "plot.i"
482
483 class Curve : public Instanc{
484
485 public:
486 std::vector<double> x;
487 std::vector<double> y;
488 const std::string getLegend() const;
489
490 };

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