MOOSE - Multiscale Object Oriented Simulation Environment
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
moosemodule.cpp
Go to the documentation of this file.
1 // moosemodule.cpp ---
2 // For detailed log, see the git-log .
3 // Author : Subhasis Ray
4 // Maintainer : Dilawar Singh, Subhasis Ray
5 
6 #include <Python.h>
7 #include <structmember.h>
8 
9 #ifdef USE_NUMPY
10 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
11 #include <numpy/arrayobject.h>
12 #endif
13 
14 #include <iostream>
15 #include <typeinfo>
16 #include <cstring>
17 #include <map>
18 #include <ctime>
19 #include <csignal>
20 #include <exception>
21 
22 
23 #if USE_BOOST_ODE
24 #include <boost/format.hpp>
25 #endif
26 
27 #ifdef USE_MPI
28 #include <mpi.h>
29 #endif
30 
31 #include "../utility/print_function.hpp"
32 #include "../basecode/header.h"
33 #include "../basecode/global.h"
34 #include "../basecode/Id.h"
35 #include "../basecode/ObjId.h"
36 #include "../utility/utility.h"
37 #include "../shell/Shell.h"
38 #include "../shell/Wildcard.h"
39 
40 #include "moosemodule.h"
41 #include "global.h"
42 
43 using namespace std;
44 
45 #ifdef DO_UNIT_TESTS
46 
47 extern void testSync();
48 extern void testAsync();
49 
50 extern void testSyncArray(
51  unsigned int size,
52  unsigned int numThreads,
53  unsigned int method
54  );
55 
56 extern void testShell();
57 extern void testScheduling();
58 extern void testSchedulingProcess();
59 extern void testBuiltins();
60 extern void testBuiltinsProcess();
61 
62 extern void testMpiScheduling();
63 extern void testMpiBuiltins();
64 extern void testMpiShell();
65 extern void testMsg();
66 extern void testMpiMsg();
67 extern void testKinetics();
68 
69 #endif
70 
71 extern void mpiTests();
72 extern void processTests( Shell* );
73 extern void nonMpiTests(Shell *);
74 extern void test_moosemodule();
75 
76 
77 extern Id init(
78  int argc, char ** argv, bool& doUnitTests
79  , bool& doRegressionTests, unsigned int& benchmark
80  );
81 
82 extern void initMsgManagers();
83 extern void destroyMsgManagers();
84 
86  unsigned int size, unsigned int runsteps
87  );
88 
89 extern void mooseBenchmarks( unsigned int option );
90 
91 
92 /*-----------------------------------------------------------------------------
93  * Random number generator for this module.
94  *
95  * moose.seed( int ) sets the global seed __rng_seed__ declared in global.h as
96  * extern and defined in global.cpp. Various RNGs uses this seed to initialize
97  * themselves. If seed is not set by user, it uses std::random_device to
98  * initialize itself.
99  *-----------------------------------------------------------------------------*/
100 void pymoose_mtseed_( long int seed )
101 {
102  moose::mtseed( seed );
103 }
104 
105 double pymoose_mtrand_( void )
106 {
107  return moose::mtrand( );
108 }
109 
113 vector<ObjId> all_elements(Id id)
114 {
115  vector<ObjId> ret;
116  unsigned int ii = 0; // storage for dataIndex
117  unsigned int jj = 0; // storage for fieldIndex
118  unsigned int * iptr = &ii; // this will point to the fastest changing index
119  unsigned int length;
120  if (id.element()->hasFields())
121  {
122  iptr = &jj;
123  length = Field< unsigned int>::get(id, "numField");
124  }
125  else
126  {
127  length = id.element()->numData();
128  }
129  for (*iptr = 0; *iptr < length; ++(*iptr))
130  {
131  ret.push_back(ObjId(id, ii, jj));
132  }
133  return ret;
134 }
135 
136 
142 void handle_keyboard_interrupts( int signum )
143 {
144  LOG( moose::info, "Interrupt signal (" << signum << ") received.");
145 
146  // Get the shell and cleanup.
147  Shell* shell = reinterpret_cast<Shell*>(getShell(0, NULL).eref().data());
148  shell->cleanSimulation();
149  exit( signum );
150 }
151 
152 // IdType and ObjIdType are defined in vec.cpp and
153 // melement.cpp respectively.
154 extern PyTypeObject IdType;
155 extern PyTypeObject ObjIdType;
156 extern PyTypeObject moose_DestField;
157 extern PyTypeObject moose_LookupField;
158 extern PyTypeObject moose_ElementField;
159 
161 // Module globals
163 int verbosity = 1;
164 // static int isSingleThreaded = 0;
165 static int isInfinite = 0;
166 static unsigned int numNodes = 1;
167 static unsigned int numCores = 1;
168 static unsigned int myNode = 0;
169 // static unsigned int numProcessThreads = 0;
170 static int doUnitTests = 0;
171 static int doRegressionTests = 0;
172 static int quitFlag = 0;
173 
178 vector<int> pysequence_to_dimvec(PyObject * dims)
179 {
180  vector <int> vec_dims;
181  Py_ssize_t num_dims = 1;
182  long dim_value = 1;
183  if (dims)
184  {
185  // First try to use it as a tuple of dimensions
186  if (PyTuple_Check(dims))
187  {
188  num_dims = PyTuple_Size(dims);
189  for (Py_ssize_t ii = 0; ii < num_dims; ++ ii)
190  {
191  PyObject* dim = PyTuple_GetItem(dims, ii);
192  dim_value = PyInt_AsLong(dim);
193  if ((dim_value == -1) && PyErr_Occurred())
194  {
195  return vec_dims;
196  }
197  vec_dims.push_back((unsigned int)dim_value);
198  }
199  }
200  else if (PyInt_Check(dims)) // 1D array
201  {
202  dim_value = PyInt_AsLong(dims);
203  if (dim_value <= 0)
204  {
205  dim_value = 1;
206  }
207  vec_dims.push_back(dim_value);
208  }
209  }
210  else
211  {
212  vec_dims.push_back(dim_value);
213  }
214  return vec_dims;
215 }
216 
222 void * to_cpp(PyObject * object, char typecode)
223 {
224  switch(typecode)
225  {
226  case 'i':
227  {
228  int * ret = new int();
229  * ret = PyInt_AsLong(object);
230  return (void*)ret;
231  }
232  case 'l':
233  {
234  long v = PyInt_AsLong(object);
235  long * ret = new long();
236  *ret = v;
237  return (void*)ret;
238  }
239  case 'h':
240  {
241  short v = PyInt_AsLong(object);
242  short * ret = new short();
243  *ret = v;
244  return (void*)ret;
245  }
246  case 'f':
247  {
248  float v = (float)PyFloat_AsDouble(object);
249  if ( v == -1.0 && PyErr_Occurred())
250  {
251  PyErr_SetString(PyExc_TypeError, "Expected a sequence of floating point numbers.");
252  }
253  else
254  {
255  float * ret = new float();
256  *ret = v;
257  return (void*)ret;
258  }
259  }
260  case 'd':
261  {
262  double v = PyFloat_AsDouble(object);
263  if ( v == -1.0 && PyErr_Occurred())
264  {
265  PyErr_SetString(PyExc_TypeError, "Expected a sequence of floating point numbers.");
266  }
267  else
268  {
269  double * ret = new double();
270  *ret = v;
271  return (void*)ret;
272  }
273  }
274  case 's':
275  {
276  char* tmp = PyString_AsString(object);
277  if (tmp == NULL)
278  {
279  return NULL;
280  }
281  string * ret = new string(tmp);
282  return (void*)ret;
283  }
284  case 'I':
285  {
286  unsigned int v = PyInt_AsUnsignedLongMask(object);
287  unsigned int * ret = new unsigned int();
288  *ret = v;
289  return (void*)ret;
290  }
291  case 'k':
292  {
293  unsigned long v = PyInt_AsUnsignedLongMask(object);
294  unsigned long * ret = new unsigned long();
295  *ret = v;
296  return (void*)ret;
297  }
298  case 'x':
299  {
300  _Id * value = (_Id*)object;
301  if (value != NULL)
302  {
303  Id * ret = new Id();
304  * ret = value->id_;
305  return (void*)ret;
306  }
307  }
308  case 'y':
309  {
310  _ObjId * value = (_ObjId*)object;
311  if (value != NULL)
312  {
313  ObjId * ret = new ObjId();
314  * ret = value->oid_;
315  return (void*)ret;
316  }
317  }
318  case 'v':
319  return PySequenceToVector< int >(object, 'i');
320  case 'N':
321  return PySequenceToVector < unsigned int > (object, 'I');
322  case 'w':
323  return PySequenceToVector < short > (object, 'h');
324  case 'M':
325  return PySequenceToVector < long > (object, 'l');
326  case 'P':
327  return PySequenceToVector < unsigned long > (object, 'k');
328  case 'F':
329  return PySequenceToVector < float > (object, 'f');
330  case 'D':
331  return PySequenceToVector < double > (object, 'd');
332  case 'S':
333  return PySequenceToVector < string > (object, 's');
334  case 'Y':
335  return PySequenceToVector < ObjId > (object, 'y');
336  case 'X':
337  return PySequenceToVector < Id > (object, 'x');
338  case 'R':
339  return PySequenceToVectorOfVectors< double >(object, 'd');
340  case 'Q':
341  return PySequenceToVectorOfVectors< int >(object, 'i');
342  case 'T':
343  return PySequenceToVectorOfVectors< unsigned int > (object, 'I');
344  }
345  return NULL;
346 }
347 
348 
352 PyObject * to_py(void * obj, char typecode)
353 {
354  switch(typecode)
355  {
356  case 'd':
357  {
358  double * ptr = static_cast<double *>(obj);
359  assert(ptr != NULL);
360  return PyFloat_FromDouble(*ptr);
361  }
362  case 's': // handle only C++ string and NOT C char array because static cast cannot differentiate the two
363  {
364  string * ptr = static_cast< string * >(obj);
365  assert (ptr != NULL);
366  return PyString_FromString(ptr->c_str());
367  }
368  case 'x':
369  {
370  Id * ptr = static_cast< Id * >(obj);
371  assert(ptr != NULL);
372  _Id * id = PyObject_New(_Id, &IdType);
373  id->id_ = *ptr;
374  return (PyObject *)(id);
375  }
376  case 'y':
377  {
378  ObjId * ptr = static_cast< ObjId * >(obj);
379  assert(ptr != NULL);
380  _ObjId * oid = PyObject_New(_ObjId, &ObjIdType);
381  oid->oid_ = *ptr;
382  return (PyObject*)oid;
383  }
384  case 'l':
385  {
386  long * ptr = static_cast< long * >(obj);
387  assert(ptr != NULL);
388  return PyLong_FromLong(*ptr);
389  }
390  case 'k':
391  {
392  unsigned long * ptr = static_cast< unsigned long * >(obj);
393  assert(ptr != NULL);
394  return PyLong_FromUnsignedLong(*ptr);
395  }
396  case 'i': // integer
397  {
398  int * ptr = static_cast< int * >(obj);
399  assert(ptr != NULL);
400  return PyInt_FromLong(*ptr);
401  }
402  case 'I': // unsigned int
403  {
404  unsigned int * ptr = static_cast< unsigned int * >(obj);
405  assert(ptr != NULL);
406  return PyLong_FromUnsignedLong(*ptr);
407  }
408  case 'b': //bool
409  {
410  bool * ptr = static_cast< bool * >(obj);
411  assert(ptr != NULL);
412  if (*ptr)
413  {
414  Py_RETURN_TRUE;
415  }
416  else
417  {
418  Py_RETURN_FALSE;
419  }
420  }
421 #ifdef HAVE_LONG_LONG
422  case 'L': //long long
423  {
424  long long * ptr = static_cast< long long * > (obj);
425  assert(ptr != NULL);
426  return PyLong_FromLongLong(*ptr);
427  }
428  case 'K': // unsigned long long
429  {
430  unsigned long long * ptr = static_cast< unsigned long long * >(obj);
431  assert(ptr != NULL);
432  return PyLong_FromUnsignedLongLong(*ptr);
433  }
434 #endif // HAVE_LONG_LONG
435  case 'f': // float
436  {
437  float * ptr = static_cast< float* >(obj);
438  assert(ptr != NULL);
439  return PyFloat_FromDouble(*ptr);
440  }
441  case 'c': // char
442  {
443  char * ptr = static_cast< char * >(obj);
444  assert(ptr != NULL);
445  return Py_BuildValue("c", *ptr);
446  }
447  case 'h': //short
448  {
449  short * ptr = static_cast< short* >(obj);
450  assert(ptr != NULL);
451  return Py_BuildValue("h", *ptr);
452  }
453  case 'H': // unsigned short
454  {
455  unsigned short * ptr = static_cast< unsigned short * >(obj);
456  assert(ptr != NULL);
457  return Py_BuildValue("H", *ptr);
458  }
459  case 'D':
460  case 'v':
461  case 'M':
462  case 'X':
463  case 'Y':
464  case 'C':
465  case 'w':
466  case 'N':
467  case 'P':
468  case 'F':
469  case 'S':
470  case 'T':
471  case 'Q':
472  case 'R':
473  {
474  return to_pytuple(obj, innerType(typecode));
475  }
476  default:
477  {
478  PyErr_SetString(PyExc_TypeError, "unhandled data type");
479  return NULL;
480  }
481  } // switch(typecode)
482 } // to_py
483 
491 PyObject * convert_and_set_tuple_entry(PyObject * tuple, unsigned int index, void * vptr, char typecode)
492 {
493  PyObject * item = to_py(vptr, typecode);
494  if (item == NULL)
495  {
496  return NULL; // the error message would have been populated by to_cpp
497  }
498  if (PyTuple_SetItem(tuple, (Py_ssize_t)index, item) != 0)
499  {
500  PyErr_SetString(PyExc_RuntimeError, "convert_and_set_tuple_entry: could not set tuple entry.");
501  return NULL;
502  }
503 #ifndef NDEBUG
504  if (verbosity > 2)
505  {
506  cout << "Set tuple " << tuple << " entry " << index << " with " << item << endl;
507  }
508 #endif
509  return tuple;
510 }
511 
515 PyObject * to_pytuple(void * obj, char typecode)
516 {
517  PyObject * ret;
518  switch (typecode)
519  {
520  case 'd': // vector<double>
521  {
522  vector< double > * vec = static_cast< vector < double >* >(obj);
523  assert(vec != NULL);
524 #ifndef USE_NUMPY
525  ret = PyTuple_New((Py_ssize_t)vec->size());
526  for (unsigned int ii = 0; ii < vec->size(); ++ii)
527  {
528  if (0 != PyTuple_SetItem(ret, ii, PyFloat_FromDouble(vec->at(ii))))
529  {
530  Py_DECREF(ret);
531  return NULL;
532  }
533  }
534 #else
535  npy_intp size = (npy_intp)(vec->size());
536  ret = PyArray_SimpleNew(1, &size, NPY_DOUBLE);
537  assert(ret != NULL);
538  char * ptr = PyArray_BYTES((PyArrayObject*)ret);
539  memcpy(ptr, &(*vec)[0], vec->size() * sizeof(double));
540 #endif
541  return ret;
542  }
543  case 'i': // vector<int>
544  {
545  vector< int > * vec = static_cast< vector < int >* >(obj);
546  assert(vec != NULL);
547 #ifndef USE_NUMPY
548  ret = PyTuple_New((Py_ssize_t)vec->size());
549  for (unsigned int ii = 0; ii < vec->size(); ++ii)
550  {
551  if (0 != PyTuple_SetItem(ret, ii, PyInt_FromLong(vec->at(ii))))
552  {
553  Py_DECREF(ret);
554  return NULL;
555  }
556  }
557 #else
558  npy_intp size = (npy_intp)(vec->size());
559  ret = PyArray_SimpleNew(1, &size, NPY_INT);
560  assert(ret != NULL);
561  char * ptr = PyArray_BYTES((PyArrayObject*)ret);
562  memcpy(ptr, &(*vec)[0], size * sizeof(int));
563 #endif
564  return ret;
565  }
566  case 'I': // vector<unsigned int>
567  {
568  vector< int > * vec = static_cast< vector < int >* >(obj);
569  assert(vec != NULL);
570 #ifndef USE_NUMPY
571  ret = PyTuple_New((Py_ssize_t)vec->size());
572  for (unsigned int ii = 0; ii < vec->size(); ++ii)
573  {
574  if (0 != PyTuple_SetItem(ret, ii, PyLong_FromLong(vec->at(ii))))
575  {
576  Py_DECREF(ret);
577  return NULL;
578  }
579  }
580 #else
581  npy_intp size = (npy_intp)(vec->size());
582  ret = PyArray_SimpleNew(1, &size, NPY_UINT);
583  assert(ret != NULL);
584  char * ptr = PyArray_BYTES((PyArrayObject*)ret);
585  memcpy(ptr, &(*vec)[0], size * sizeof(unsigned int));
586 #endif
587  return ret;
588  }
589  case 'l': // vector<long>
590  {
591  vector< long > * vec = static_cast< vector < long >* >(obj);
592  assert(vec != NULL);
593 #ifndef USE_NUMPY
594  ret = PyTuple_New((Py_ssize_t)vec->size());
595  for (unsigned int ii = 0; ii < vec->size(); ++ii)
596  {
597  if (0 != PyTuple_SetItem(ret, ii, PyLong_FromLong(vec->at(ii))))
598  {
599  Py_DECREF(ret);
600  return NULL;
601  }
602  }
603 #else
604  npy_intp size = (npy_intp)(vec->size());
605  ret = PyArray_SimpleNew(1, &size, NPY_INT);
606  assert(ret != NULL);
607  char * ptr = PyArray_BYTES((PyArrayObject*)ret);
608  memcpy(ptr, &(*vec)[0], size * sizeof(long));
609 #endif
610  return ret;
611  }
612  case 'x': // vector<Id>
613  {
614  vector< Id > * vec = static_cast< vector < Id >* >(obj);
615  assert(vec != NULL);
616  ret = PyTuple_New((Py_ssize_t)vec->size());
617  assert(ret != NULL);
618  for (unsigned int ii = 0; ii < vec->size(); ++ii)
619  {
620  if (convert_and_set_tuple_entry(ret, ii, (void*)&vec->at(ii), typecode) == NULL)
621  {
622  return NULL;
623  }
624  }
625  break;
626  }
627  case 'y': // vector<ObjId>
628  {
629  vector< ObjId > * vec = static_cast< vector < ObjId >* >(obj);
630  assert(vec != NULL);
631  ret = PyTuple_New((Py_ssize_t)vec->size());
632  assert(ret != NULL);
633  for (unsigned int ii = 0; ii < vec->size(); ++ii)
634  {
635  if (convert_and_set_tuple_entry(ret, ii, (void*)&vec->at(ii), typecode) == NULL)
636  {
637  return NULL;
638  }
639  }
640  break;
641  }
642  case 'c': // vector<char>
643  {
644  vector< char > * vec = static_cast< vector < char >* >(obj);
645  assert(vec != NULL);
646  ret = PyTuple_New((Py_ssize_t)vec->size());
647  assert(ret != NULL);
648  for (unsigned int ii = 0; ii < vec->size(); ++ii)
649  {
650  if (convert_and_set_tuple_entry(ret, ii, (void*)&vec->at(ii), typecode) == NULL)
651  {
652  return NULL;
653  }
654  }
655  break;
656  }
657  case 'h': // vector<short>
658  {
659  vector< short > * vec = static_cast< vector < short >* >(obj);
660  assert(vec != NULL);
661  ret = PyTuple_New((Py_ssize_t)vec->size());
662  assert(ret != NULL);
663  for (unsigned int ii = 0; ii < vec->size(); ++ii)
664  {
665  if (convert_and_set_tuple_entry(ret, ii, (void*)&vec->at(ii), typecode) == NULL)
666  {
667  return NULL;
668  }
669  }
670  break;
671  }
672  case 'k': // vector<unsigned long>
673  {
674  vector< unsigned int > * vec = static_cast< vector < unsigned int >* >(obj);
675  assert(vec != NULL);
676 #ifndef USE_NUMPY
677  ret = PyTuple_New((Py_ssize_t)vec->size());
678  for (unsigned int ii = 0; ii < vec->size(); ++ii)
679  {
680  if (0 != PyTuple_SetItem(ret, ii, PyLong_FromUnsignedLong(vec->at(ii))))
681  {
682  Py_DECREF(ret);
683  return NULL;
684  }
685  }
686 #else
687  npy_intp size = (npy_intp)(vec->size());
688  ret = PyArray_SimpleNew(1, &size, NPY_UINT);
689  assert(ret != NULL);
690  char * ptr = PyArray_BYTES((PyArrayObject*)ret);
691  memcpy(ptr, &(*vec)[0], size * sizeof(unsigned int));
692 #endif
693  return ret;
694  }
695  case 'L': // vector<long long> - this is not used at present
696  {
697  vector< long long> * vec = static_cast< vector < long long>* >(obj);
698  assert(vec != NULL);
699  ret = PyTuple_New((Py_ssize_t)vec->size());
700 #ifndef USE_NUMPY
701  for (unsigned int ii = 0; ii < vec->size(); ++ii)
702  {
703  if (0 != PyTuple_SetItem(ret, ii, PyLong_FromLongLong(vec->at(ii))))
704  {
705  Py_DECREF(ret);
706  return NULL;
707  }
708  }
709 #else
710  npy_intp size = (npy_intp)(vec->size());
711  ret = PyArray_SimpleNew(1, &size, NPY_LONGLONG);
712  assert(ret != NULL);
713  char * ptr = PyArray_BYTES((PyArrayObject*)ret);
714  memcpy(ptr, &(*vec)[0], size * sizeof(long long));
715 #endif
716  return ret;
717  }
718  case 'K': // vector<unsigned long long> - this is not used at present
719  {
720  vector< unsigned long long> * vec = static_cast< vector < unsigned long long>* >(obj);
721  assert(vec != NULL);
722 #ifndef USE_NUMPY
723  ret = PyTuple_New((Py_ssize_t)vec->size());
724  for (unsigned int ii = 0; ii < vec->size(); ++ii)
725  {
726  if (0 != PyTuple_SetItem(ret, ii, PyLong_FromUnsignedLongLong(vec->at(ii))))
727  {
728  Py_DECREF(ret);
729  return NULL;
730  }
731  }
732 #else
733  npy_intp size = (npy_intp)(vec->size());
734  ret = PyArray_SimpleNew(1, &size, NPY_ULONGLONG);
735  assert(ret != NULL);
736  char * ptr = PyArray_BYTES((PyArrayObject*)ret);
737  memcpy(ptr, &(*vec)[0], size * sizeof(unsigned long long));
738 #endif
739  return ret;
740  }
741  case 'F': // vector<float>
742  {
743  vector< float > * vec = static_cast< vector < float >* >(obj);
744  assert(vec != NULL);
745 #ifndef USE_NUMPY
746  ret = PyTuple_New((Py_ssize_t)vec->size());
747  for (unsigned int ii = 0; ii < vec->size(); ++ii)
748  {
749  if (0 != PyTuple_SetItem(ret, ii, PyFloat_FromDouble(vec->at(ii))))
750  {
751  Py_DECREF(ret);
752  return NULL;
753  }
754  }
755 #else
756  npy_intp size = (npy_intp)(vec->size());
757  ret = PyArray_SimpleNew(1, &size, NPY_FLOAT);
758  assert(ret != NULL);
759  char * ptr = PyArray_BYTES((PyArrayObject*)ret);
760  memcpy(ptr, &(*vec)[0], size * sizeof(float));
761 #endif
762  return ret;
763  }
764  case 's': // vector<string>
765  {
766  vector< string > * vec = static_cast< vector < string >* >(obj);
767  assert(vec != NULL);
768  ret = PyTuple_New((Py_ssize_t)vec->size());
769  assert(ret != NULL);
770  for (unsigned int ii = 0; ii < vec->size(); ++ii)
771  {
772  string v = vec->at(ii);
773  if (convert_and_set_tuple_entry(ret, ii, (void*)&v, typecode) == NULL)
774  {
775  return NULL;
776  }
777  }
778  break;
779  }
780  case 'N': // vector< vector <unsigned int > >
781  {
782  vector< vector< unsigned int > > * vec = static_cast< vector < vector< unsigned int > >* >(obj);
783  assert(vec != NULL);
784  ret = PyTuple_New((Py_ssize_t)vec->size());
785  assert(ret != NULL);
786  for (unsigned int ii = 0; ii < vec->size(); ++ii)
787  {
788  if (convert_and_set_tuple_entry(ret, ii, (void*)&vec->at(ii), typecode) == NULL)
789  {
790  return NULL;
791  }
792  }
793  break;
794  }
795  case 'v': // vector< vector < int > >
796  {
797  vector< vector< int > > * vec = static_cast< vector < vector< int > >* >(obj);
798  assert(vec != NULL);
799  ret = PyTuple_New((Py_ssize_t)vec->size());
800  assert(ret != NULL);
801  for (unsigned int ii = 0; ii < vec->size(); ++ii)
802  {
803  if (convert_and_set_tuple_entry(ret, ii, (void*)&vec->at(ii), typecode) == NULL)
804  {
805  return NULL;
806  }
807  }
808  break;
809  }
810  case 'D': // vector< vector <double > >
811  {
812  vector< vector< double > > * vec = static_cast< vector < vector< double > >* >(obj);
813  assert(vec != NULL);
814  ret = PyTuple_New((Py_ssize_t)vec->size());
815  assert(ret != NULL);
816  for (unsigned int ii = 0; ii < vec->size(); ++ii)
817  {
818  if (convert_and_set_tuple_entry(ret, ii, (void*)&vec->at(ii), typecode) == NULL)
819  {
820  return NULL;
821  }
822  }
823  break;
824  }
825  default:
826  PyErr_SetString(PyExc_TypeError, "unhandled type");
827  return NULL;
828  }
829  return ret;
830 }
831 
832 // Global store of defined MOOSE classes.
833 map<string, PyTypeObject *>& get_moose_classes()
834 {
835  static map<string, PyTypeObject *> defined_classes;
836  return defined_classes;
837 }
838 
839 // Global storage for PyGetSetDef structs for LookupFields.
840 map<string, vector <PyGetSetDef> >& get_getsetdefs()
841 {
842  static map<string, vector <PyGetSetDef> > getset_defs;
843  return getset_defs;
844 }
845 
850 const map<string, string>& get_field_alias()
851 {
852  static map<string, string> alias;
853  if (alias.empty())
854  {
855  // alias["class_"] = "class";
856  alias["lambda_"] = "lambda";
857  }
858  return alias;
859 }
860 
861 
862 // Minimum number of arguments for setting destFinfo - 1-st
863 // the finfo name.
864 // Py_ssize_t minArgs = 1;
865 
866 // // Arbitrarily setting maximum on variable argument list. Read:
867 // // http://www.swig.org/Doc1.3/Varargs.html to understand why
868 // Py_ssize_t maxArgs = 10;
869 
870 
872 // Helper routines
874 
875 
880 vector <string> setup_runtime_env()
881 {
882  const map<string, string>& argmap = moose::getArgMap();
883  vector<string> args;
884  args.push_back("moose");
885  map<string, string>::const_iterator it;
886  // it = argmap.find("SINGLETHREADED");
887  // if (it != argmap.end()){
888  // istringstream(it->second) >> isSingleThreaded;
889  // if (isSingleThreaded){
890  // args.push_back("-s");
891  // }
892  // }
893  it = argmap.find("INFINITE");
894  if (it != argmap.end())
895  {
896  istringstream(it->second) >> isInfinite;
897  if (isInfinite)
898  {
899  args.push_back("-i");
900  }
901  }
902  it = argmap.find("NUMNODES");
903  if (it != argmap.end())
904  {
905  istringstream(it->second) >> numNodes;
906  args.push_back("-n");
907  args.push_back(it->second);
908  }
909  it = argmap.find("NUMCORES");
910  if (it != argmap.end())
911  {
912  istringstream(it->second) >> numCores;
913  }
914  // it = argmap.find("NUMPTHREADS");
915  // if (it != argmap.end()){
916  // istringstream(it->second) >> numProcessThreads;
917  // args.push_back("-t");
918  // args.push_back(it->second);
919  // }
920  it = argmap.find("QUIT");
921  if (it != argmap.end())
922  {
923  istringstream(it->second) >> quitFlag;
924  if (quitFlag)
925  {
926  args.push_back("-q");
927  }
928  }
929  it = argmap.find("VERBOSITY");
930  if (it != argmap.end())
931  {
932  istringstream(it->second) >> verbosity;
933  }
934  it = argmap.find("DOUNITTESTS");
935  if (it != argmap.end())
936  {
937  istringstream(it->second) >> doUnitTests;
938  }
939  it = argmap.find("DOREGRESSIONTESTS");
940  if (it != argmap.end())
941  {
942  istringstream(it->second) >> doRegressionTests;
943  }
944 
945  if (verbosity > 0)
946  {
947  cout << "ENVIRONMENT: " << endl
948  << "----------------------------------------" << endl
949  // << " SINGLETHREADED = " << isSingleThreaded << endl
950  << " INFINITE = " << isInfinite << endl
951  << " NUMNODES = " << numNodes << endl
952  // << " NUMPTHREADS = " << numProcessThreads << endl
953  << " VERBOSITY = " << verbosity << endl
954  << " DOUNITTESTS = " << doUnitTests << endl
955  << " DOREGRESSIONTESTS = " << doRegressionTests << endl
956  << "========================================" << endl;
957  }
958  return args;
959 }
960 
967 Id getShell(int argc, char ** argv)
968 {
969  static int inited = 0;
970  if (inited)
971  {
972  return Id(0);
973  }
974  bool dounit = doUnitTests != 0;
975  bool doregress = doRegressionTests != 0;
976  unsigned int doBenchmark = 0;
977  // Utilize the main::init function which has friend access to Id
978  Id shellId = init(argc, argv, dounit, doregress, doBenchmark );
979  inited = 1;
980  Shell * shellPtr = reinterpret_cast<Shell*>(shellId.eref().data());
981  if (dounit)
982  {
983  nonMpiTests( shellPtr ); // These tests do not need the process loop.
984  }
985  if ( shellPtr->myNode() == 0 )
986  {
987  if ( Shell::numNodes() > 1 )
988  {
989  // Use the last clock for the postmaster, so that it is called
990  // after everything else has been processed and all messages
991  // are ready to send out.
992  shellPtr->doUseClock( "/postmaster", "process", 9 );
993  shellPtr->doSetClock( 9, 1.0 ); // Use a sensible default.
994  }
995 #ifdef DO_UNIT_TESTS
996  if ( dounit )
997  {
998  mpiTests();
999  processTests( shellPtr );
1000  }
1001  // if ( doRegressionTests ) regressionTests();
1002 #endif
1003  // These are outside unit tests because they happen in optimized
1004  // mode, using a command-line argument. As soon as they are done
1005  // the system quits, in order to estimate timing.
1006  if ( doBenchmark != 0 )
1007  {
1008  mooseBenchmarks( doBenchmark );
1009  }
1010  }
1011  return shellId;
1012 }
1013 
1017 void finalize()
1018 {
1019  static bool finalized = false;
1020  if (finalized)
1021  {
1022  return;
1023  }
1024  finalized = true;
1025  Id shellId = getShell(0, NULL);
1026  // Clear the memory for PyGetSetDefs. The key
1027  // (name) was dynamically allocated using calloc. So was the
1028  // docstring.
1029  for (map<string, vector<PyGetSetDef> >::iterator it =
1030  get_getsetdefs().begin();
1031  it != get_getsetdefs().end();
1032  ++it)
1033  {
1034  vector <PyGetSetDef> &getsets = it->second;
1035  // for (unsigned int ii = 0; ii < getsets.size()-1; ++ii){ // the -1 is for the empty sentinel entry
1036  // free(getsets[ii].name);
1037  // Py_XDECREF(getsets[ii].closure);
1038  // }
1039  }
1040  get_getsetdefs().clear();
1041  // deallocate the class names calloc-ed at initialization.
1042  // for(map< string, PyTypeObject* >::iterator it = get_moose_classes().begin();
1043  // it != get_moose_classes().end(); ++it){
1044  // PyTypeObject * classObject = it->second;
1045  // free(classObject->tp_name); // skipping this as not sure whether this is useful - all gets deallocated at exit anyways.
1046  // }
1047  // get_moose_classes().clear();
1048 
1049  SHELLPTR->doQuit();
1052 
1053 #ifdef USE_MPI
1054  MPI_Finalize();
1055 #endif
1056 
1057 }
1058 
1059 
1064 const char ** getFinfoTypes()
1065 {
1066  static const char * finfoTypes[] = {"valueFinfo",
1067  "srcFinfo",
1068  "destFinfo",
1069  "lookupFinfo",
1070  "sharedFinfo",
1071  "fieldElementFinfo",
1072  0
1073  };
1074  return finfoTypes;
1075 }
1076 
1090 string getFieldType(string className, string fieldName)
1091 {
1092  string fieldType = "";
1093  const Cinfo * cinfo = Cinfo::find(className);
1094  if (cinfo == NULL)
1095  {
1096  if (verbosity > 0)
1097  {
1098  cerr << "Unknown class " << className << endl;
1099  }
1100  return fieldType;
1101  }
1102  const Finfo * finfo = cinfo->findFinfo(fieldName);
1103  if (finfo == NULL)
1104  {
1105  if (verbosity > 0)
1106  {
1107  cerr << "Unknown field " << fieldName << endl;
1108  }
1109  return fieldType;
1110  }
1111  fieldType = finfo->rttiType();
1112  return fieldType;
1113 }
1114 
1122 int parseFinfoType(string className, string finfoType, string fieldName, vector<string> & typeVec)
1123 {
1124  string typestring = getFieldType(className, fieldName);
1125  if (typestring.empty())
1126  {
1127  return -1;
1128  }
1129  moose::tokenize(typestring, ",", typeVec);
1130  if ((int)typeVec.size() > maxArgs)
1131  {
1132  return -1;
1133  }
1134  for (unsigned int ii = 0; ii < typeVec.size() ; ++ii)
1135  {
1136  char type_code = shortType(typeVec[ii]);
1137  if (type_code == 0)
1138  {
1139  return -1;
1140  }
1141  }
1142  return 0;
1143 }
1144 
1148 vector<string> getFieldNames(string className, string finfoType)
1149 {
1150  vector <string> ret;
1151  const Cinfo * cinfo = Cinfo::find(className);
1152  if (cinfo == NULL)
1153  {
1154  cerr << "Invalid class name." << endl;
1155  return ret;
1156  }
1157  // Finfo * (Cinfo:: * getFinfo)(unsigned int); // causes : warning: ISO C++ forbids taking the address of a bound member function to form a pointer to member function.
1158  if (finfoType == "valueFinfo" || finfoType == "value")
1159  {
1160  for (unsigned int ii = 0; ii < cinfo->getNumValueFinfo(); ++ii)
1161  {
1162  Finfo * finfo = cinfo->getValueFinfo(ii);
1163  ret.push_back(finfo->name());
1164  }
1165  }
1166  else if (finfoType == "srcFinfo" || finfoType == "src")
1167  {
1168  for (unsigned int ii = 0; ii < cinfo->getNumSrcFinfo(); ++ii)
1169  {
1170  Finfo * finfo = cinfo->getSrcFinfo(ii);
1171  ret.push_back(finfo->name());
1172  }
1173  }
1174  else if (finfoType == "destFinfo" || finfoType == "dest")
1175  {
1176  for (unsigned int ii = 0; ii < cinfo->getNumDestFinfo(); ++ii)
1177  {
1178  Finfo * finfo = cinfo->getDestFinfo(ii);
1179  ret.push_back(finfo->name());
1180  }
1181  }
1182  else if (finfoType == "lookupFinfo" || finfoType == "lookup")
1183  {
1184  for (unsigned int ii = 0; ii < cinfo->getNumLookupFinfo(); ++ii)
1185  {
1186  Finfo * finfo = cinfo->getLookupFinfo(ii);
1187  ret.push_back(finfo->name());
1188  }
1189  }
1190  else if (finfoType == "sharedFinfo" || finfoType == "shared")
1191  {
1192  for (unsigned int ii = 0; ii < cinfo->getNumSrcFinfo(); ++ii)
1193  {
1194  Finfo * finfo = cinfo->getSrcFinfo(ii);
1195  ret.push_back(finfo->name());
1196  }
1197  }
1198  else if (finfoType == "fieldElementFinfo" || finfoType == "fieldElement")
1199  {
1200  for (unsigned int ii = 0; ii < cinfo->getNumFieldElementFinfo(); ++ii)
1201  {
1202  Finfo * finfo = cinfo->getFieldElementFinfo(ii);
1203  ret.push_back(finfo->name());
1204  }
1205  }
1206  return ret;
1207 }
1208 
1216 int getFieldDict(string className, string finfoType,
1217  vector<string>& fieldNames, vector<string>&fieldTypes)
1218 {
1219  const Cinfo * cinfo = Cinfo::find(className);
1220  if (cinfo == NULL)
1221  {
1222  cerr << "Invalid class." << endl;
1223  return 0;
1224  }
1225  if (finfoType == "valueFinfo" || finfoType == "value")
1226  {
1227  for (unsigned int ii = 0; ii < cinfo->getNumValueFinfo(); ++ii)
1228  {
1229  Finfo * finfo = cinfo->getValueFinfo(ii);
1230  fieldNames.push_back(finfo->name());
1231  fieldTypes.push_back(finfo->rttiType());
1232  }
1233  }
1234  else if (finfoType == "srcFinfo" || finfoType == "src")
1235  {
1236  for (unsigned int ii = 0; ii < cinfo->getNumSrcFinfo(); ++ii)
1237  {
1238  Finfo * finfo = cinfo->getSrcFinfo(ii);
1239  fieldNames.push_back(finfo->name());
1240  fieldTypes.push_back(finfo->rttiType());
1241  }
1242  }
1243  else if (finfoType == "destFinfo" || finfoType == "dest")
1244  {
1245  for (unsigned int ii = 0; ii < cinfo->getNumDestFinfo(); ++ii)
1246  {
1247  Finfo * finfo = cinfo->getDestFinfo(ii);
1248  fieldNames.push_back(finfo->name());
1249  fieldTypes.push_back(finfo->rttiType());
1250  }
1251  }
1252  else if (finfoType == "lookupFinfo" || finfoType == "lookup")
1253  {
1254  for (unsigned int ii = 0; ii < cinfo->getNumLookupFinfo(); ++ii)
1255  {
1256  Finfo * finfo = cinfo->getLookupFinfo(ii);
1257  fieldNames.push_back(finfo->name());
1258  fieldTypes.push_back(finfo->rttiType());
1259  }
1260  }
1261  else if (finfoType == "sharedFinfo" || finfoType == "shared")
1262  {
1263  for (unsigned int ii = 0; ii < cinfo->getNumSrcFinfo(); ++ii)
1264  {
1265  Finfo * finfo = cinfo->getSrcFinfo(ii);
1266  fieldNames.push_back(finfo->name());
1267  fieldTypes.push_back(finfo->rttiType());
1268  }
1269  }
1270  else if (finfoType == "fieldElementFinfo" || finfoType == "field" || finfoType == "fieldElement")
1271  {
1272  for (unsigned int ii = 0; ii < cinfo->getNumFieldElementFinfo(); ++ii)
1273  {
1274  Finfo * finfo = cinfo->getFieldElementFinfo(ii);
1275  fieldNames.push_back(finfo->name());
1276  fieldTypes.push_back(finfo->rttiType());
1277  }
1278  }
1279  return 1;
1280 }
1281 
1283 // Field Type definition
1286 // ObjId functions.
1288 
1289 
1294 PyTypeObject * getBaseClass(PyObject * self)
1295 {
1296  extern PyTypeObject ObjIdType;
1297  string basetype_str = "";
1298  PyTypeObject * base = NULL;
1299  for (base = Py_TYPE(self);
1300  base != &ObjIdType; base = base->tp_base)
1301  {
1302  basetype_str = base->tp_name;
1303  size_t dot = basetype_str.find('.');
1304  basetype_str = basetype_str.substr(dot+1);
1305  if (get_moose_classes().find(basetype_str) !=
1306  get_moose_classes().end())
1307  {
1308  return base;
1309  }
1310  }
1311  return NULL;
1312 }
1313 
1315 // Module functions
1317 PyDoc_STRVAR(moose_getFieldNames_documentation,
1318  "getFieldNames(className, finfoType='valueFinfo') -> tuple\n"
1319  "\n"
1320  "Get a tuple containing the name of all the fields of `finfoType`\n"
1321  "kind.\n"
1322  "\n"
1323  "Parameters\n"
1324  "----------\n"
1325  "className : string\n"
1326  " Name of the class to look up.\n"
1327  "finfoType : string\n"
1328  " The kind of field "
1329  " `valueFinfo` - "
1330  " `srcFinfo` - "
1331  " `destFinfo` - "
1332  " `lookupFinfo`- "
1333  " `fieldElementFinfo` - \n"
1334  "\n"
1335  "Returns\n"
1336  "-------\n"
1337  "tuple\n"
1338  " Names of the fields of type `finfoType` in class `className`.\n"
1339  );
1340 
1341 PyObject * moose_getFieldNames(PyObject * dummy, PyObject * args)
1342 {
1343  char * className = NULL;
1344  char _finfoType[] = "valueFinfo";
1345  char * finfoType = _finfoType;
1346  if (!PyArg_ParseTuple(args, "s|s", &className, &finfoType))
1347  {
1348  return NULL;
1349  }
1350  vector <string> fieldNames = getFieldNames(className, finfoType);
1351  PyObject * ret = PyTuple_New(fieldNames.size());
1352 
1353  for (unsigned int ii = 0; ii < fieldNames.size(); ++ii)
1354  {
1355  if (PyTuple_SetItem(ret, ii, PyString_FromString(fieldNames[ii].c_str())) == -1)
1356  {
1357  Py_XDECREF(ret);
1358  return NULL;
1359  }
1360  }
1361  return ret;
1362 }
1363 
1364 PyDoc_STRVAR(moose_copy_documentation,
1365  "copy(src, dest, name, n, toGlobal, copyExtMsg) -> bool\n"
1366  "\n"
1367  "Make copies of a moose object.\n"
1368  "\n"
1369  "Parameters\n"
1370  "----------\n"
1371  "src : vec, element or str\n"
1372  " source object.\n"
1373  "dest : vec, element or str\n"
1374  " Destination object to copy into.\n"
1375  "name : str\n"
1376  " Name of the new object. If omitted, name of the original will be used.\n"
1377  "n : int\n"
1378  " Number of copies to make.\n"
1379  "toGlobal : int\n"
1380  " Relevant for parallel environments only. If false, the copies will\n"
1381  " reside on local node, otherwise all nodes get the copies.\n"
1382  "copyExtMsg : int\n"
1383  " If true, messages to/from external objects are also copied.\n"
1384  "\n"
1385  "Returns\n"
1386  "-------\n"
1387  "vec\n"
1388  " newly copied vec\n"
1389  );
1390 
1391 PyObject * moose_copy(PyObject * dummy, PyObject * args, PyObject * kwargs)
1392 {
1393  PyObject * src = NULL, * dest = NULL;
1394  char * newName = NULL;
1395  static const char * kwlist[] = {"src", "dest", "name", "n", "toGlobal", "copyExtMsg", NULL};
1396  unsigned int num=1, toGlobal=0, copyExtMsgs=0;
1397  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|sIII", const_cast<char**>(kwlist), &src, &dest, &newName, &num, &toGlobal, &copyExtMsgs))
1398  {
1399  return NULL;
1400  }
1401  Id _src;
1402  ObjId _dest;
1403  if (PyObject_IsInstance(src, (PyObject*)&IdType))
1404  {
1405  _src = ((_Id*)src)->id_;
1406  }
1407  else if (PyObject_IsInstance(src, (PyObject*)&ObjIdType))
1408  {
1409  _src = ((_ObjId*)src)->oid_.id;
1410  }
1411  else if (PyString_Check(src))
1412  {
1413  _src = Id(PyString_AsString(src));
1414  }
1415  else
1416  {
1417  PyErr_SetString(PyExc_TypeError, "Source must be instance of vec, element or string.");
1418  return NULL;
1419  }
1420  if (_src == Id())
1421  {
1422  PyErr_SetString(PyExc_ValueError, "Cannot make copy of moose shell.");
1423  return NULL;
1424  }
1425  if (PyObject_IsInstance(dest, (PyObject*)&IdType))
1426  {
1427  _dest = ObjId(((_Id*)dest)->id_);
1428  }
1429  else if (PyObject_IsInstance(dest, (PyObject*)&ObjIdType))
1430  {
1431  _dest = ((_ObjId*)dest)->oid_;
1432  }
1433  else if (PyString_Check(dest))
1434  {
1435  _dest = ObjId(PyString_AsString(dest));
1436  }
1437  else
1438  {
1439  PyErr_SetString(PyExc_TypeError, "destination must be instance of vec, element or string.");
1440  return NULL;
1441  }
1442  if (!Id::isValid(_src))
1443  {
1444  RAISE_INVALID_ID(NULL, "moose_copy: invalid source Id.");
1445  }
1446  else if (_dest.bad())
1447  {
1448  RAISE_INVALID_ID(NULL, "moose_copy: invalid destination.");
1449  }
1450  string name;
1451  if (newName == NULL)
1452  {
1453  // Use the original name if name is not specified.
1454  name = Field<string>::get(ObjId(_src, 0), "name");
1455  }
1456  else
1457  {
1458  name = string(newName);
1459  }
1460  _Id * tgt = PyObject_New(_Id, &IdType);
1461  tgt->id_ = SHELLPTR->doCopy(_src, _dest, name, num, toGlobal, copyExtMsgs);
1462  PyObject * ret = (PyObject*)tgt;
1463  return ret;
1464 }
1465 
1466 // Not sure what this function should return... ideally the Id of the
1467 // moved object - does it change though?
1468 PyObject * moose_move(PyObject * dummy, PyObject * args)
1469 {
1470  PyObject * src, * dest;
1471  if (!PyArg_ParseTuple(args, "OO:moose_move", &src, &dest))
1472  {
1473  return NULL;
1474  }
1475  Id _src;
1476  ObjId _dest;
1477  if (PyObject_IsInstance(src, (PyObject*)&IdType))
1478  {
1479  _src = ((_Id*)src)->id_;
1480  }
1481  else if (PyObject_IsInstance(src, (PyObject*)&ObjIdType))
1482  {
1483  _src = ((_ObjId*)src)->oid_.id;
1484  }
1485  else if (PyString_Check(src))
1486  {
1487  _src = Id(PyString_AsString(src));
1488  }
1489  else
1490  {
1491  PyErr_SetString(PyExc_TypeError, "Source must be instance of vec, element or string.");
1492  return NULL;
1493  }
1494  if (_src == Id())
1495  {
1496  PyErr_SetString(PyExc_ValueError, "Cannot make move moose shell.");
1497  return NULL;
1498  }
1499  if (PyObject_IsInstance(dest, (PyObject*)&IdType))
1500  {
1501  _dest = ObjId(((_Id*)dest)->id_);
1502  }
1503  else if (PyObject_IsInstance(dest, (PyObject*)&ObjIdType))
1504  {
1505  _dest = ((_ObjId*)dest)->oid_;
1506  }
1507  else if (PyString_Check(dest))
1508  {
1509  _dest = ObjId(PyString_AsString(dest));
1510  }
1511  else
1512  {
1513  PyErr_SetString(PyExc_TypeError, "destination must be instance of vec, element or string.");
1514  return NULL;
1515  }
1516  if (!Id::isValid(_src))
1517  {
1518  RAISE_INVALID_ID(NULL, "moose_copy: invalid source Id.");
1519  }
1520  else if (_dest.bad())
1521  {
1522  RAISE_INVALID_ID(NULL, "moose_copy: invalid destination.");
1523  }
1524  SHELLPTR->doMove(_src, _dest);
1525  Py_RETURN_NONE;
1526 }
1527 
1528 PyDoc_STRVAR(moose_delete_documentation,
1529  "delete(obj)->None\n"
1530  "\n"
1531  "Delete the underlying moose object. This does not delete any of the\n"
1532  "Python objects referring to this vec but does invalidate them. Any\n"
1533  "attempt to access them will raise a ValueError.\n"
1534  "\n"
1535  "Parameters\n"
1536  "----------\n"
1537  "id : vec\n"
1538  " vec of the object to be deleted.\n"
1539  "\n"
1540  "Returns\n"
1541  "-------\n"
1542  "None\n"
1543  );
1544 PyObject * moose_delete(PyObject * dummy, PyObject * args)
1545 {
1546  PyObject * obj;
1547  bool isId_ = false;
1548  bool isObjId_ = false;
1549  if (!PyArg_ParseTuple(args, "O:moose.delete", &obj))
1550  {
1551  return NULL;
1552  }
1553  // if (!PyObject_IsInstance(obj, (PyObject*)&IdType)){
1554  // PyErr_SetString(PyExc_TypeError, "vec instance expected");
1555  // return NULL;
1556  // }
1557  ObjId oid_;
1558  if (PyObject_IsInstance(obj, (PyObject*)&IdType))
1559  {
1560  oid_ = ((_Id*)obj)->id_;
1561  isId_ = true;
1562  }
1563  else if (PyObject_IsInstance(obj, (PyObject*)&ObjIdType))
1564  {
1565  oid_ = ((_ObjId*)obj)->oid_;
1566  isObjId_ = true;
1567  }
1568  else if (PyString_Check(obj))
1569  {
1570  oid_ = ObjId(PyString_AsString(obj));
1571  }
1572  else
1573  {
1574  PyErr_SetString(PyExc_ValueError, "cannot delete moose shell.");
1575  return NULL;
1576  }
1577  if (oid_ == ObjId())
1578  {
1579  PyErr_SetString(PyExc_ValueError, "cannot delete moose shell.");
1580  return NULL;
1581  }
1582  if ( oid_.bad() )
1583  {
1584  RAISE_INVALID_ID(NULL, "moose_delete");
1585  }
1586  deleteObjId(oid_);
1587  if (isId_)
1588  {
1589  ((_Id*)obj)->id_ = Id();
1590  }
1591  if (isObjId_)
1592  {
1593  ((_ObjId*)obj)->oid_ = ObjId(0, BADINDEX, BADINDEX);
1594  }
1595  // SHELLPTR->doDelete(((_Id*)obj)->id_);
1596  Py_RETURN_NONE;
1597 }
1598 
1599 PyDoc_STRVAR(moose_useClock_documentation,
1600  "useClock(tick, path, fn)\n\n"
1601  "schedule `fn` function of every object that matches `path` on tick no. `tick`.\n\n "
1602  "Most commonly the function is 'process'. NOTE: unlike earlier versions, now autoschedule is not available. You have to call useClock for every element that should be updated during the simulation.\n\n "
1603  "The sequence of clockticks with the same dt is according to their number. This is utilized for controlling the order of updates in various objects where it matters. The following convention should be observed when assigning clockticks to various components of a model:\n\n "
1604  "Clock ticks 0-3 are for electrical (biophysical) components, 4 and 5 are for chemical kinetics, 6 and 7 are for lookup tables and stimulus, 8 and 9 are for recording tables.\n\n "
1605  "Generally, `process` is the method to be assigned a clock tick. Notable exception is `init` method of Compartment class which is assigned tick 0.\n\n"
1606  " - 0 : Compartment: `init`\n"
1607  " - 1 : Compartment: `process`\n"
1608  " - 2 : HHChannel and other channels: `process`\n"
1609  " - 3 : CaConc : `process`\n"
1610  " - 4,5 : Elements for chemical kinetics : `process`\n"
1611  " - 6,7 : Lookup (tables), stimulus : `process`\n"
1612  " - 8,9 : Tables for plotting : `process`\n"
1613  " \n"
1614  "Parameters\n"
1615  "----------\n"
1616  "tick : int\n"
1617  " tick number on which the targets should be scheduled.\n"
1618  "path : str\n"
1619  " path of the target element(s). This can be a wildcard also.\n"
1620  "fn : str\n"
1621  " name of the function to be called on each tick. Commonly `process`.\n"
1622  "\n"
1623  "Examples\n"
1624  "--------\n"
1625  "In multi-compartmental neuron model a compartment's membrane potential (Vm) is dependent on its neighbours' membrane potential. Thus it must get the neighbour's present Vm before computing its own Vm in next time step. This ordering is achieved by scheduling the `init` function, which communicates membrane potential, on tick 0 and `process` function on tick 1.\n\n"
1626  " >>> moose.useClock(0, '/model/compartment_1', 'init')\n"
1627  " >>> moose.useClock(1, '/model/compartment_1', 'process')\n");
1628 
1629 PyObject * moose_useClock(PyObject * dummy, PyObject * args)
1630 {
1631  char * path, * field;
1632  unsigned int tick;
1633  if(!PyArg_ParseTuple(args, "Iss:moose_useClock", &tick, &path, &field))
1634  {
1635  return NULL;
1636  }
1637  SHELLPTR->doUseClock(string(path), string(field), tick);
1638  Py_RETURN_NONE;
1639 }
1640 
1641 
1642 PyDoc_STRVAR(moose_setClock_documentation,
1643  "setClock(tick, dt)\n"
1644  "\n"
1645  "set the ticking interval of `tick` to `dt`.\n"
1646  "\n"
1647  "A tick with interval `dt` will call the functions scheduled on that tick every `dt` timestep.\n"
1648  "\n"
1649  "Parameters\n"
1650  "----------\n"
1651  " tick : int\n"
1652  " tick number\n"
1653  " dt : double\n"
1654  " ticking interval\n");
1655 
1656 PyObject * moose_setClock(PyObject * dummy, PyObject * args)
1657 {
1658  unsigned int tick;
1659  double dt;
1660  if(!PyArg_ParseTuple(args, "Id:moose_setClock", &tick, &dt))
1661  {
1662  return NULL;
1663  }
1664  if (dt < 0)
1665  {
1666  PyErr_SetString(PyExc_ValueError, "dt must be positive.");
1667  return NULL;
1668  }
1669  SHELLPTR->doSetClock(tick, dt);
1670  Py_RETURN_NONE;
1671 }
1672 
1673 PyDoc_STRVAR(moose_start_documentation,
1674  "start(time, notify = False) -> None\n"
1675  "\n"
1676  "Run simulation for `t` time. Advances the simulator clock by `t`\n"
1677  "time. If 'notify = True', a message is written to terminal whenever \n"
1678  "10\% of simulation time is over. \n"
1679  "\n"
1680  "After setting up a simulation, YOU MUST CALL MOOSE.REINIT() before\n"
1681  "CALLING MOOSE.START() TO EXECUTE THE SIMULATION. Otherwise, the\n"
1682  "simulator behaviour will be undefined. Once moose.reinit() has been\n"
1683  "called, you can call moose.start(t) as many time as you like. This\n"
1684  "will continue the simulation from the last state for `t` time.\n"
1685  "\n"
1686  "Parameters\n"
1687  "----------\n"
1688  "t : float\n"
1689  " duration of simulation.\n"
1690  "notify: bool\n"
1691  " default False. If True, notify user whenever 10\% of simultion \n"
1692  " is over.\n"
1693  "\n"
1694  "Returns\n"
1695  "--------\n"
1696  " None\n"
1697  "\n"
1698  "See also\n"
1699  "--------\n"
1700  "moose.reinit : (Re)initialize simulation\n"
1701  "\n"
1702  );
1703 PyObject * moose_start(PyObject * dummy, PyObject * args )
1704 {
1705  double runtime = 0.0;
1706  bool notify = false;
1707 
1708  PyArg_ParseTuple(args, "d|I:moose_start", &runtime, &notify);
1709 
1710  if (runtime <= 0.0)
1711  {
1712  PyErr_SetString(PyExc_ValueError, "simulation runtime must be positive.");
1713  return NULL;
1714  }
1715 
1716  // This is from http://stackoverflow.com/questions/1641182/how-can-i-catch-a-ctrl-c-event-c
1717  struct sigaction sigHandler;
1718  sigHandler.sa_handler = handle_keyboard_interrupts;
1719  sigemptyset(&sigHandler.sa_mask);
1720  sigHandler.sa_flags = 0;
1721  sigaction(SIGINT, &sigHandler, NULL);
1722 
1723 #if 0
1724  // NOTE: (dilawar) Does not know if Py_BEGIN_ALLOW_THREADS is
1725  // neccessary.
1726  // Py_BEGIN_ALLOW_THREADS
1727  SHELLPTR->doStart(runtime);
1728  // Py_END_ALLOW_THREADS
1729  Py_RETURN_NONE;
1730 #endif
1731  SHELLPTR->doStart( runtime, notify );
1732  Py_RETURN_NONE;
1733 
1734 }
1735 
1736 PyDoc_STRVAR(moose_reinit_documentation,
1737  "reinit() -> None\n"
1738  "\n"
1739  "Reinitialize simulation.\n"
1740  "\n"
1741  "This function (re)initializes moose simulation. It must be called\n"
1742  "before you start the simulation (see moose.start). If you want to\n"
1743  "continue simulation after you have called moose.reinit() and\n"
1744  "moose.start(), you must NOT call moose.reinit() again. Calling\n"
1745  "moose.reinit() again will take the system back to initial setting\n"
1746  "(like clear out all data recording tables, set state variables to\n"
1747  "their initial values, etc.\n"
1748  "\n");
1749 PyObject * moose_reinit(PyObject * dummy, PyObject * args)
1750 {
1751  SHELLPTR->doReinit();
1752  Py_RETURN_NONE;
1753 }
1754 PyObject * moose_stop(PyObject * dummy, PyObject * args)
1755 {
1756  SHELLPTR->doStop();
1757  Py_RETURN_NONE;
1758 }
1759 PyObject * moose_isRunning(PyObject * dummy, PyObject * args)
1760 {
1761  return Py_BuildValue("i", SHELLPTR->isRunning());
1762 }
1763 
1764 PyObject * moose_exists(PyObject * dummy, PyObject * args)
1765 {
1766  char * path;
1767  if (!PyArg_ParseTuple(args, "s", &path))
1768  {
1769  return NULL;
1770  }
1771  return Py_BuildValue("i", Id(path) != Id() || string(path) == "/" || string(path) == "/root");
1772 }
1773 
1774 PyDoc_STRVAR(moose_loadModel_documentation,
1775  "loadModel(filename, modelpath, solverclass) -> vec\n"
1776  "\n"
1777  "Load model from a file to a specified path.\n"
1778  "\n"
1779  "Parameters\n"
1780  "----------\n"
1781  "filename : str\n"
1782  " model description file.\n"
1783  "modelpath : str\n"
1784  " moose path for the top level element of the model to be created.\n"
1785  "solverclass : str, optional\n"
1786  " solver type to be used for simulating the model.\n"
1787  "\n"
1788  "Returns\n"
1789  "-------\n"
1790  "vec\n"
1791  " loaded model container vec.\n"
1792  );
1793 
1794 PyObject * moose_loadModel(PyObject * dummy, PyObject * args)
1795 {
1796  char * fname = NULL, * modelpath = NULL, * solverclass = NULL;
1797 
1798  if(!PyArg_ParseTuple(args, "ss|s:moose_loadModel", &fname, &modelpath, &solverclass))
1799  {
1800  cout << "here in moose load";
1801  return NULL;
1802  }
1803  _Id * model = (_Id*)PyObject_New(_Id, &IdType);
1804  if (!solverclass)
1805  {
1806  model->id_ = SHELLPTR->doLoadModel(string(fname), string(modelpath));
1807  }
1808  else
1809  {
1810  model->id_ = SHELLPTR->doLoadModel(string(fname), string(modelpath), string(solverclass));
1811  }
1812  if (model->id_ == Id())
1813  {
1814  Py_XDECREF(model);
1815  PyErr_SetString(PyExc_IOError, "could not load model");
1816  return NULL;
1817  }
1818  PyObject * ret = reinterpret_cast<PyObject*>(model);
1819  return ret;
1820 }
1821 /*
1822 PyDoc_STRVAR(moose_saveModel_documentation,
1823  "saveModel(source, filename) -> None\n"
1824  "\n"
1825  "Save model rooted at `source` to file `filename`.\n"
1826  "\n"
1827  "Parameters\n"
1828  "----------\n"
1829  "source : vec/element/str\n"
1830  " root of the model tree\n"
1831  "\n"
1832  "filename : str\n"
1833  " destination file to save the model in.\n"
1834  "\n"
1835  "Returns\n"
1836  "-------\n"
1837  "None\n"
1838  "\n");
1839 
1840 PyObject * moose_saveModel(PyObject * dummy, PyObject * args)
1841 {
1842  char * filename = NULL;
1843  PyObject * source = NULL;
1844  Id model;
1845  if (!PyArg_ParseTuple(args, "Os: moose_saveModel", &source, &filename))
1846  {
1847  return NULL;
1848  }
1849  if (PyString_Check(source))
1850  {
1851 
1852  char * srcPath = PyString_AsString(source);
1853  if (!srcPath)
1854  {
1855  cout << " Niull ";
1856  return NULL;
1857  }
1858  assert(srcPath != NULL);
1859 
1860  model = Id(string(srcPath));
1861  }
1862  else if (Id_SubtypeCheck(source))
1863  {
1864  model = ((_Id*)source)->id_;
1865  }
1866  else if (ObjId_SubtypeCheck(source))
1867  {
1868  model = ((_ObjId*)source)->oid_.id;
1869  }
1870  else
1871  {
1872  PyErr_SetString(PyExc_TypeError, "moose_saveModel: need an vec, element or string for first argument.");
1873  return NULL;
1874  }
1875  SHELLPTR->doSaveModel(model, filename);
1876  Py_RETURN_NONE;
1877 }
1878 */
1879 PyObject * moose_setCwe(PyObject * dummy, PyObject * args)
1880 {
1881  PyObject * element = NULL;
1882  char * path = NULL;
1883  ObjId oid;
1884  if (PyTuple_Size(args) == 0)
1885  {
1886  oid = Id("/");
1887  }
1888  else if(PyArg_ParseTuple(args, "s:moose_setCwe", &path))
1889  {
1890  oid = ObjId(string(path));
1891  }
1892  else if (PyArg_ParseTuple(args, "O:moose_setCwe", &element))
1893  {
1894  PyErr_Clear();
1895  if (PyObject_IsInstance(element, (PyObject*)&IdType))
1896  {
1897  oid = (reinterpret_cast<_Id*>(element))->id_;
1898  }
1899  else if (PyObject_IsInstance(element, (PyObject*)&ObjIdType))
1900  {
1901  oid = (reinterpret_cast<_ObjId*>(element))->oid_;
1902  }
1903  else
1904  {
1905  PyErr_SetString(PyExc_NameError, "setCwe: Argument must be an vec or element");
1906  return NULL;
1907  }
1908  }
1909  else
1910  {
1911  return NULL;
1912  }
1913  if (oid.bad())
1914  {
1915  RAISE_INVALID_ID(NULL, "moose_setCwe");
1916  }
1917  SHELLPTR->setCwe(oid);
1918  Py_RETURN_NONE;
1919 }
1920 
1921 PyObject * moose_getCwe(PyObject * dummy, PyObject * args)
1922 {
1923  if (!PyArg_ParseTuple(args, ":moose_getCwe"))
1924  {
1925  return NULL;
1926  }
1927  // _Id * cwe = (_Id*)PyObject_New(_Id, &IdType);
1928  // cwe->id_ = SHELLPTR->getCwe();
1929  // PyObject * ret = (PyObject*)cwe;
1930  // return ret;
1931  return oid_to_element(SHELLPTR->getCwe());
1932 }
1933 
1934 PyDoc_STRVAR(moose_connect_documentation,
1935  "connect(src, srcfield, destobj, destfield[,msgtype]) -> bool\n"
1936  "\n"
1937  "Create a message between `src_field` on `src` object to `dest_field` on `dest` object.\n"
1938  "This function is used mainly, to say, connect two entities, and to denote what kind of give-and-take relationship they share."
1939  "It enables the 'destfield' (of the 'destobj') to acquire the data, from 'srcfield'(of the 'src')."
1940  "\n"
1941  "Parameters\n"
1942  "----------\n"
1943  "src : element/vec/string\n"
1944  " the source object (or its path) \n"
1945  " (the one that provides information)\n"
1946  "srcfield : str\n"
1947  " source field on self.(type of the information)\n"
1948  "destobj : element\n"
1949  " Destination object to connect to.\n"
1950  " (The one that need to get information)\n"
1951  "destfield : str\n"
1952  " field to connect to on `destobj`.\n"
1953  "msgtype : str\n"
1954  " type of the message. Can be \n"
1955  " `Single` - \n"
1956  " `OneToAll` - \n"
1957  " `AllToOne` - \n"
1958  " `OneToOne` - \n"
1959  " `Reduce` - \n"
1960  " `Sparse` - \n"
1961  " Default: `Single`.\n"
1962  "\n"
1963  "Returns\n"
1964  "-------\n"
1965  "msgmanager: melement\n"
1966  " message-manager for the newly created message.\n"
1967  "\n"
1968  "Examples\n"
1969  "--------\n"
1970  "Connect the output of a pulse generator to the input of a spike\n"
1971  "generator::\n"
1972  "\n"
1973  " >>> pulsegen = moose.PulseGen('pulsegen')\n"
1974  " >>> spikegen = moose.SpikeGen('spikegen')\n"
1975  " >>> pulsegen.connect('output', spikegen, 'Vm')\n"
1976  "\n"
1977  "See also\n"
1978  "--------\n"
1979  "moose.connect\n"
1980  );
1981 
1982 PyObject * moose_connect(PyObject * dummy, PyObject * args)
1983 {
1984  PyObject * srcPtr = NULL, * destPtr = NULL;
1985  char * srcField = NULL, * destField = NULL, * msgType = NULL;
1986  static char default_msg_type[] = "Single";
1987  if(!PyArg_ParseTuple(args, "OsOs|s:moose_connect", &srcPtr, &srcField, &destPtr, &destField, &msgType))
1988  {
1989  return NULL;
1990  }
1991  if (msgType == NULL)
1992  {
1993  msgType = default_msg_type;
1994  }
1995  ObjId dest, src;
1996  if (ObjId_SubtypeCheck(srcPtr))
1997  {
1998  _ObjId * _src = reinterpret_cast<_ObjId*>(srcPtr);
1999  src = _src->oid_;
2000  }
2001  else if (Id_SubtypeCheck(srcPtr))
2002  {
2003  _Id * _src = reinterpret_cast<_Id*>(srcPtr);
2004  src = ObjId(_src->id_);
2005  }
2006  else if (PyString_Check(srcPtr))
2007  {
2008  char * _src = PyString_AsString(srcPtr);
2009  src = ObjId(string(_src));
2010  }
2011  else
2012  {
2013  PyErr_SetString(PyExc_TypeError, "source does not resolve to an element.");
2014  return NULL;
2015  }
2016  if (ObjId_SubtypeCheck(destPtr))
2017  {
2018  _ObjId * _dest = reinterpret_cast<_ObjId*>(destPtr);
2019  dest = _dest->oid_;
2020  }
2021  else if (Id_SubtypeCheck(destPtr))
2022  {
2023  _Id * _dest = reinterpret_cast<_Id*>(destPtr);
2024  dest = ObjId(_dest->id_);
2025  }
2026  else if (PyString_Check(destPtr))
2027  {
2028  char * _dest = PyString_AsString(destPtr);
2029  dest = ObjId(string(_dest));
2030  }
2031  else
2032  {
2033  PyErr_SetString(PyExc_TypeError, "target does not resolve to an element.");
2034  return NULL;
2035  }
2036  if (!Id::isValid(dest.id) || !Id::isValid(src.id))
2037  {
2038  RAISE_INVALID_ID(NULL, "moose_connect");
2039  }
2040  ObjId mid = SHELLPTR->doAddMsg(msgType, src, string(srcField), dest, string(destField));
2041  if ( mid.bad() )
2042  {
2043  PyErr_SetString(PyExc_NameError, "check field names and type compatibility.");
2044  return NULL;
2045  }
2046  return oid_to_element(mid);
2047 }
2048 
2049 
2050 PyDoc_STRVAR(moose_getFieldDict_documentation,
2051  "getFieldDict(className, finfoType) -> dict\n"
2052  "\n"
2053  "Get dictionary of field names and types for specified class.\n"
2054  "\n"
2055  "Parameters\n"
2056  "----------\n"
2057  "className : str\n"
2058  " MOOSE class to find the fields of.\n"
2059  "finfoType : str (optional)\n"
2060  " Finfo type of the fields to find. If empty or not specified, all\n"
2061  " fields will be retrieved.\n"
2062  "\n"
2063  "Returns\n"
2064  "-------\n"
2065  "dict\n"
2066  " field names and their types.\n"
2067  "\n"
2068  "Notes\n"
2069  "-----\n"
2070  " This behaviour is different from `getFieldNames` where only\n"
2071  " `valueFinfo`s are returned when `finfoType` remains unspecified.\n"
2072  "\n"
2073  "Examples\n"
2074  "--------\n"
2075  "List all the source fields on class Neutral::\n"
2076  "\n"
2077  ">>> moose.getFieldDict('Neutral', 'srcFinfo')\n"
2078  " {'childMsg': 'int'}\n"
2079  "\n"
2080  "\n");
2081 PyObject * moose_getFieldDict(PyObject * dummy, PyObject * args)
2082 {
2083  char * className = NULL;
2084  char * fieldType = NULL;
2085  if (!PyArg_ParseTuple(args, "s|s:moose_getFieldDict", &className, &fieldType))
2086  {
2087  return NULL;
2088  }
2089  if (!className || (strlen(className) <= 0))
2090  {
2091  PyErr_SetString(PyExc_ValueError, "Expected non-empty class name.");
2092  return NULL;
2093  }
2094 
2095  Id classId = Id("/classes/" + string(className));
2096  if (classId == Id())
2097  {
2098  string msg = string(className);
2099  msg += " not a valid MOOSE class.";
2100  PyErr_SetString(PyExc_NameError, msg.c_str());
2101  return NULL;
2102  }
2103  static const char * finfoTypes [] = {"valueFinfo", "lookupFinfo", "srcFinfo", "destFinfo", "sharedFinfo", NULL};
2104  vector <string> fields, types;
2105  if (fieldType && strlen(fieldType) > 0)
2106  {
2107  if (getFieldDict(className, string(fieldType), fields, types) == 0)
2108  {
2109  PyErr_SetString(PyExc_ValueError, "Invalid finfo type.");
2110  return NULL;
2111  }
2112  }
2113  else
2114  {
2115  for (const char ** ptr = finfoTypes; *ptr != NULL; ++ptr)
2116  {
2117  if (getFieldDict(className, string(*ptr), fields, types) == 0)
2118  {
2119  string message = "No such finfo type: ";
2120  message += string(*ptr);
2121  PyErr_SetString(PyExc_ValueError, message.c_str());
2122  return NULL;
2123  }
2124  }
2125  }
2126  PyObject * ret = PyDict_New();
2127  if (!ret)
2128  {
2129  PyErr_SetString(PyExc_SystemError, "Could not allocate dictionary object.");
2130  return NULL;
2131  }
2132  for (unsigned int ii = 0; ii < fields.size(); ++ ii)
2133  {
2134  PyObject * value = Py_BuildValue("s", types[ii].c_str());
2135  if (value == NULL || PyDict_SetItemString(ret, fields[ii].c_str(), value) == -1)
2136  {
2137  Py_XDECREF(ret);
2138  Py_XDECREF(value);
2139  return NULL;
2140  }
2141  }
2142  return ret;
2143 }
2144 
2145 PyObject * moose_getField(PyObject * dummy, PyObject * args)
2146 {
2147  PyObject * pyobj;
2148  const char * field;
2149  const char * type;
2150  if (!PyArg_ParseTuple(args, "Oss:moose_getfield", &pyobj, &field, &type))
2151  {
2152  return NULL;
2153  }
2154  if (!PyObject_IsInstance(pyobj, (PyObject*)&ObjIdType))
2155  {
2156  PyErr_SetString(PyExc_TypeError, "moose.getField(element, fieldname, fieldtype): First argument must be an instance of element or its subclass");
2157  return NULL;
2158  }
2159  string fname(field), ftype(type);
2160  ObjId oid = ((_ObjId*)pyobj)->oid_;
2161  if (!Id::isValid(oid.id))
2162  {
2163  RAISE_INVALID_ID(NULL, "moose_getField");
2164  }
2165  // Let us do this version using brute force. Might be simpler than getattro.
2166  if (ftype == "char")
2167  {
2168  char value =Field<char>::get(oid, fname);
2169  return PyInt_FromLong(value);
2170  }
2171  else if (ftype == "double")
2172  {
2173  double value = Field<double>::get(oid, fname);
2174  return PyFloat_FromDouble(value);
2175  }
2176  else if (ftype == "float")
2177  {
2178  float value = Field<float>::get(oid, fname);
2179  return PyFloat_FromDouble(value);
2180  }
2181  else if (ftype == "int")
2182  {
2183  int value = Field<int>::get(oid, fname);
2184  return PyInt_FromLong(value);
2185  }
2186  else if (ftype == "string")
2187  {
2188  string value = Field<string>::get(oid, fname);
2189  return PyString_FromString(value.c_str());
2190  }
2191  else if (ftype == "unsigned int" || ftype == "unsigned" || ftype == "uint")
2192  {
2193  unsigned int value = Field<unsigned int>::get(oid, fname);
2194  return PyInt_FromLong(value);
2195  }
2196  else if (ftype == "Id")
2197  {
2198  _Id * value = (_Id*)PyObject_New(_Id, &IdType);
2199  value->id_ = Field<Id>::get(oid, fname);
2200  return (PyObject*) value;
2201  }
2202  else if (ftype == "ObjId")
2203  {
2204  _ObjId * value = (_ObjId*)PyObject_New(_ObjId, &ObjIdType);
2205  value->oid_ = Field<ObjId>::get(oid, fname);
2206  return (PyObject*)value;
2207  }
2208  else if (ftype == "vector<int>")
2209  {
2210  vector<int> value = Field< vector < int > >::get(oid, fname);
2211  PyObject * ret = PyTuple_New((Py_ssize_t)value.size());
2212 
2213  for (unsigned int ii = 0; ii < value.size(); ++ ii )
2214  {
2215  PyObject * entry = Py_BuildValue("i", value[ii]);
2216  if (!entry || PyTuple_SetItem(ret, (Py_ssize_t)ii, entry))
2217  {
2218  Py_XDECREF(ret);
2219  ret = NULL;
2220  break;
2221  }
2222  }
2223  return ret;
2224  }
2225  else if (ftype == "vector<double>")
2226  {
2227  vector<double> value = Field< vector < double > >::get(oid, fname);
2228  PyObject * ret = PyTuple_New((Py_ssize_t)value.size());
2229 
2230  for (unsigned int ii = 0; ii < value.size(); ++ ii )
2231  {
2232  PyObject * entry = Py_BuildValue("f", value[ii]);
2233  if (!entry || PyTuple_SetItem(ret, (Py_ssize_t)ii, entry))
2234  {
2235  Py_XDECREF(ret);
2236  ret = NULL;
2237  break;
2238  }
2239  }
2240  return ret;
2241  }
2242  else if (ftype == "vector<float>")
2243  {
2244  vector<float> value = Field< vector < float > >::get(oid, fname);
2245  PyObject * ret = PyTuple_New((Py_ssize_t)value.size());
2246 
2247  for (unsigned int ii = 0; ii < value.size(); ++ ii )
2248  {
2249  PyObject * entry = Py_BuildValue("f", value[ii]);
2250  if (!entry || PyTuple_SetItem(ret, (Py_ssize_t)ii, entry))
2251  {
2252  Py_XDECREF(ret);
2253  ret = NULL;
2254  break;
2255  }
2256  }
2257  return ret;
2258  }
2259  else if (ftype == "vector<string>")
2260  {
2261  vector<string> value = Field< vector < string > >::get(oid, fname);
2262  PyObject * ret = PyTuple_New((Py_ssize_t)value.size());
2263 
2264  for (unsigned int ii = 0; ii < value.size(); ++ ii )
2265  {
2266  PyObject * entry = Py_BuildValue("s", value[ii].c_str());
2267  if (!entry || PyTuple_SetItem(ret, (Py_ssize_t)ii, entry))
2268  {
2269  Py_XDECREF(ret);
2270  return NULL;
2271  }
2272  }
2273  return ret;
2274  }
2275  else if (ftype == "vector<Id>")
2276  {
2277  vector<Id> value = Field< vector < Id > >::get(oid, fname);
2278  PyObject * ret = PyTuple_New((Py_ssize_t)value.size());
2279 
2280  for (unsigned int ii = 0; ii < value.size(); ++ ii )
2281  {
2282  _Id * entry = PyObject_New(_Id, &IdType);
2283  entry->id_ = value[ii];
2284  if (PyTuple_SetItem(ret, (Py_ssize_t)ii, (PyObject*)entry))
2285  {
2286  Py_XDECREF(ret);
2287  return NULL;
2288  }
2289  }
2290  return ret;
2291  }
2292  else if (ftype == "vector<ObjId>")
2293  {
2294  vector<ObjId> value = Field< vector < ObjId > >::get(oid, fname);
2295  PyObject * ret = PyTuple_New((Py_ssize_t)value.size());
2296 
2297  for (unsigned int ii = 0; ii < value.size(); ++ ii )
2298  {
2299  _ObjId * entry = PyObject_New(_ObjId, &ObjIdType);
2300  entry->oid_ = value[ii];
2301  if (PyTuple_SetItem(ret, (Py_ssize_t)ii, (PyObject*)entry))
2302  {
2303  Py_XDECREF(ret);
2304  return NULL;
2305  }
2306  }
2307  return ret;
2308  }
2309  PyErr_SetString(PyExc_TypeError, "Field type not handled.");
2310  return NULL;
2311 }
2312 
2313 PyDoc_STRVAR(moose_seed_documentation,
2314  "moose.seed(seedvalue) -> seed \n"
2315  "\n"
2316  "Reseed MOOSE random number generator.\n"
2317  "\n"
2318  "Parameters\n"
2319  "----------\n"
2320  "seed : int\n"
2321  " Value to use for seeding. \n"
2322  " All RNGs in moose except rand functions in moose.Function \n"
2323  " expression use this seed.\n"
2324  " By default (when this function is not called) seed is initializecd \n"
2325  " to some random value using system random device (if available). \n"
2326  " \n"
2327  "\n"
2328  " default: random number generated using system random device\n"
2329  "\n"
2330  "Returns\n"
2331  "-------\n"
2332  "None\n"
2333  "\n"
2334  "See also\n"
2335  "--------\n"
2336  "moose.rand() : get a pseudorandom number in the [0,1) interval.\n"
2337  );
2338 
2339 PyObject * moose_seed(PyObject * dummy, PyObject * args)
2340 {
2341  long int seed = 0;
2342  if (!PyArg_ParseTuple(args, "|l", &seed))
2343  {
2344  return NULL;
2345  }
2346  pymoose_mtseed_(seed);
2347  Py_RETURN_NONE;
2348 }
2349 
2350 PyDoc_STRVAR(moose_rand_documentation,
2351  "moose.rand() -> [0,1)\n"
2352  "\n"
2353  "Returns\n"
2354  "-------\n"
2355  "float in [0, 1) real interval generated by MT19937.\n"
2356  "\n"
2357  "See also\n"
2358  "--------\n"
2359  "moose.seed() : reseed the random number generator.\n"
2360  "\n"
2361  "Notes\n"
2362  "-----\n"
2363  "MOOSE does not automatically seed the random number generator. You\n"
2364  "must explicitly call moose.seed() to create a new sequence of random\n"
2365  "numbers each time.\n"
2366  "\n");
2367 
2368 PyObject * moose_rand(PyObject * dummy)
2369 {
2370  return PyFloat_FromDouble(pymoose_mtrand_());
2371 }
2372 
2373 PyDoc_STRVAR(moose_wildcardFind_documentation,
2374  "moose.wildcardFind(expression) -> tuple of melements.\n"
2375  "\n"
2376  "Find an object by wildcard.\n"
2377  "\n"
2378  "Parameters\n"
2379  "----------\n"
2380  "expression : str\n"
2381  " MOOSE allows wildcard expressions of the form::\n"
2382  "\n"
2383  " {PATH}/{WILDCARD}[{CONDITION}]\n"
2384  "\n"
2385  " where {PATH} is valid path in the element tree.\n"
2386  " `{WILDCARD}` can be `#` or `##`.\n"
2387  "\n"
2388  " `#` causes the search to be restricted to the children of the\n"
2389  " element specified by {PATH}.\n"
2390  "\n"
2391  " `##` makes the search to recursively go through all the descendants\n"
2392  " of the {PATH} element.\n"
2393  " {CONDITION} can be::\n"
2394  "\n"
2395  " TYPE={CLASSNAME} : an element satisfies this condition if it is of\n"
2396  " class {CLASSNAME}.\n"
2397  " ISA={CLASSNAME} : alias for TYPE={CLASSNAME}\n"
2398  " CLASS={CLASSNAME} : alias for TYPE={CLASSNAME}\n"
2399  " FIELD({FIELDNAME}){OPERATOR}{VALUE} : compare field {FIELDNAME} with\n"
2400  " {VALUE} by {OPERATOR} where {OPERATOR} is a comparison operator (=,\n"
2401  " !=, >, <, >=, <=).\n"
2402  "\n"
2403  " For example, /mymodel/##[FIELD(Vm)>=-65] will return a list of all\n"
2404  " the objects under /mymodel whose Vm field is >= -65.\n"
2405  "\n"
2406  "Returns\n"
2407  "-------\n"
2408  "tuple\n"
2409  " all elements that match the wildcard.\n"
2410  "\n");
2411 
2412 PyObject * moose_wildcardFind(PyObject * dummy, PyObject * args)
2413 {
2414  vector <ObjId> objects;
2415  char * wildcard_path = NULL;
2416  if (!PyArg_ParseTuple(args, "s:moose.wildcardFind", &wildcard_path))
2417  {
2418  return NULL;
2419  }
2420  wildcardFind(string(wildcard_path), objects);
2421  PyObject * ret = PyTuple_New(objects.size());
2422  if (ret == NULL)
2423  {
2424  PyErr_SetString(PyExc_RuntimeError, "moose.wildcardFind: failed to allocate new tuple.");
2425  return NULL;
2426  }
2427 
2428  for (unsigned int ii = 0; ii < objects.size(); ++ii)
2429  {
2430  PyObject * entry = oid_to_element(objects[ii]);
2431  if (!entry)
2432  {
2433  Py_XDECREF(ret);
2434  PyErr_SetString(PyExc_RuntimeError, "moose.wildcardFind: failed to allocate new vec.");
2435  return NULL;
2436  }
2437  if (PyTuple_SetItem(ret, (Py_ssize_t)ii, entry))
2438  {
2439  Py_XDECREF(entry);
2440  Py_XDECREF(ret);
2441  return NULL;
2442  }
2443  }
2444  return ret;
2445 }
2450 PyObject * moose_quit(PyObject * dummy)
2451 {
2452  finalize();
2453  cout << "Quitting MOOSE." << endl;
2454  Py_RETURN_NONE;
2455 }
2456 
2461 int defineAllClasses(PyObject * module_dict)
2462 {
2463  static vector <Id> classes(Field< vector<Id> >::get(ObjId("/classes"),
2464  "children"));
2465  for (unsigned ii = 0; ii < classes.size(); ++ii)
2466  {
2467  const string& className = classes[ii].element()->getName();
2468  if (verbosity > 0)
2469  {
2470  cout << "\nCreating " << className << endl;
2471  }
2472  const Cinfo * cinfo = Cinfo::find(className);
2473  if (!cinfo)
2474  {
2475  cerr << "Error: no cinfo found with name " << className << endl;
2476  return 0;
2477  }
2478  if (!defineClass(module_dict, cinfo))
2479  {
2480  return 0;
2481  }
2482  }
2483  return 1;
2484 }
2493 PyDoc_STRVAR(moose_Class_documentation,
2494  "*-----------------------------------------------------------------*\n"
2495  "* This is Python generated documentation. *\n"
2496  "* Use moose.doc('classname') to display builtin documentation for *\n"
2497  "* class `classname`. *\n"
2498  "* Use moose.doc('classname.fieldname') to display builtin *\n"
2499  "* documentation for `field` in class `classname`. *\n"
2500  "*-----------------------------------------------------------------*\n"
2501  );
2502 
2503 int defineLookupFinfos(const Cinfo * cinfo)
2504 {
2505  const string & className = cinfo->name();
2506 #ifndef NDEBUG
2507  if (verbosity > 1)
2508  {
2509  cout << "\tDefining lookupFields for " << className << endl;
2510  }
2511 #endif
2512  unsigned int num = cinfo->getNumLookupFinfo();
2513  unsigned int currIndex = get_getsetdefs()[className].size();
2514  for (unsigned int ii = 0; ii < num; ++ii)
2515  {
2516  const string& name = const_cast<Cinfo*>(cinfo)->getLookupFinfo(ii)->name();
2517  PyGetSetDef getset;
2518  get_getsetdefs()[className].push_back(getset);
2519  get_getsetdefs()[className][currIndex].name = (char*)calloc(name.size() + 1, sizeof(char));
2520  strncpy(const_cast<char*>(get_getsetdefs()[className][currIndex].name)
2521  , const_cast<char*>(name.c_str()), name.size());
2522  get_getsetdefs()[className][currIndex].doc = (char*) "Lookup field";
2523  get_getsetdefs()[className][currIndex].get = (getter)moose_ObjId_get_lookupField_attr;
2524  PyObject * args = PyTuple_New(1);
2525  PyTuple_SetItem(args, 0, PyString_FromString(name.c_str()));
2526  get_getsetdefs()[className][currIndex].closure = (void*)args;
2527 #ifndef NDEBUG
2528  if (verbosity > 1)
2529  {
2530  cout << "\tDefined lookupField " << get_getsetdefs()[className][currIndex].name << endl;
2531  }
2532 #endif
2533 
2534  ++currIndex;
2535  }
2536  return 1;
2537 }
2538 
2539 
2540 int defineClass(PyObject * module_dict, const Cinfo * cinfo)
2541 {
2542  const string& className = cinfo->name();
2543  map <string, PyTypeObject * >::iterator existing =
2544  get_moose_classes().find(className);
2545  if (existing != get_moose_classes().end())
2546  {
2547  return 1;
2548  }
2549  const Cinfo* base = cinfo->baseCinfo();
2550 #ifndef NDEBUG
2551  if (verbosity > 1)
2552  {
2553  cout << "Defining class " << className << endl; //" with base=" << base->name() << endl;
2554  }
2555 #endif
2556  if (base && !defineClass(module_dict, base))
2557  {
2558  return 0;
2559  }
2560 
2561  string str = "moose." + className;
2562 
2563  PyTypeObject * new_class =
2564  (PyTypeObject*)PyType_Type.tp_alloc(&PyType_Type, 0);
2565 // Python3 does not like it without heaptype: aborts on import
2566 // Fatal Python error:
2567 // type_traverse() called for non-heap type 'moose.Neutral'
2568 #ifdef PY3K
2569  new_class->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
2570  PyHeapTypeObject* et = (PyHeapTypeObject*)new_class;
2571  et->ht_name = PyUnicode_FromString(className.c_str());
2572 #if PY_MINOR_VERSION >= 3
2573  et->ht_qualname = PyUnicode_FromString(str.c_str());
2574 #endif
2575 #else
2576  new_class->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
2577 #endif
2578  /*
2579  Thu Jul 9 09:58:09 IST 2015 - commenting out
2580  Py_TPFLAGS_HEAPTYPE because it causes segfault on accessing
2581  __class__ attribute of instances. Bug # 168. Another
2582  possible solution would be to catch __class__ request in
2583  tp_getattro and INCREF the class object when returning the
2584  same.
2585 
2586  ------
2587  should we avoid Py_TPFLAGS_HEAPTYPE as it imposes certain
2588  limitations:
2589  http://mail.python.org/pipermail/python-dev/2009-July/090921.html
2590  But otherwise somehow GC tries tp_traverse on these classes
2591  (even when I unset Py_TPFLAGS_HAVE_GC) and fails the
2592  assertion in debug build of Python:
2593 
2594  python: Objects/typeobject.c:2683: type_traverse: Assertion `type->tp_flags & Py_TPFLAGS_HEAPTYPE' failed.
2595 
2596  In released versions of Python there is a crash at
2597  Py_Finalize().
2598 
2599  Also if HEAPTYPE is true, then help(classname) causes a
2600  segmentation fault as it tries to convert the class object
2601  to a heaptype object (resulting in an invalid pointer). If
2602  heaptype is not set it uses tp_name to print the help.
2603  Py_SIZE(new_class) = sizeof(_ObjId);
2604  */
2605  new_class->tp_name = strdup(str.c_str());
2606  new_class->tp_doc = moose_Class_documentation;
2607 
2608  //strncpy(new_class->tp_doc, moose_Class_documentation, strlen(moose_Class_documentation));
2609  map<string, PyTypeObject *>::iterator base_iter =
2610  get_moose_classes().find(cinfo->getBaseClass());
2611  if (base_iter == get_moose_classes().end())
2612  {
2613  new_class->tp_base = &ObjIdType;
2614  }
2615  else
2616  {
2617  new_class->tp_base = base_iter->second;
2618  }
2619  Py_INCREF(new_class->tp_base);
2620  // Define all the lookupFields
2621  if (!defineLookupFinfos(cinfo))
2622  {
2623  return 0;
2624  }
2625  // Define the destFields
2626  if (!defineDestFinfos(cinfo))
2627  {
2628  return 0;
2629  }
2630 
2631  // Define the element fields
2632  if (!defineElementFinfos(cinfo))
2633  {
2634  return 0;
2635  }
2636  // #ifndef NDEBUG
2637  // cout << "Get set defs:" << className << endl;
2638  // for (unsigned int ii = 0; ii < get_getsetdefs()[className].size(); ++ii){
2639  // cout << ii;
2640  // if (get_getsetdefs()[className][ii].name != NULL){
2641  // cout << ": " << get_getsetdefs()[className][ii].name;
2642  // } else {
2643  // cout << "Empty";
2644  // }
2645  // cout << endl;
2646  // }
2647  // cout << "End getsetdefs: " << className << endl;
2648  // #endif
2649  // The getsetdef array must be terminated with empty objects.
2650  PyGetSetDef empty;
2651  empty.name = NULL;
2652  get_getsetdefs()[className].push_back(empty);
2653  get_getsetdefs()[className].back().name = NULL;
2654  new_class->tp_getset = &(get_getsetdefs()[className][0]);
2655  /*
2656  Cannot do this for HEAPTYPE ?? but pygobject.c does this in
2657  pygobject_register_class
2658  */
2659  if (PyType_Ready(new_class) < 0)
2660  {
2661  cerr << "Fatal error: Could not initialize class '" << className
2662  << "'" << endl;
2663  return 0;
2664  }
2665  get_moose_classes().insert(pair<string, PyTypeObject*> (className, new_class));
2666  Py_INCREF(new_class);
2667 
2668 #ifdef PY3K
2669  PyDict_SetItemString(new_class->tp_dict, "__module__", PyUnicode_InternFromString("moose"));
2670 #endif
2671  // string doc = const_cast<Cinfo*>(cinfo)->getDocs();
2672  // PyDict_SetItemString(new_class->tp_dict, "__doc__", PyString_FromString(" \0"));
2673  // PyDict_SetItemString(module_dict, className.c_str(), (PyObject *)new_class);
2674  return 1;
2675 }
2676 
2677 PyObject * moose_ObjId_get_destField_attr(PyObject * self, void * closure)
2678 {
2679  if (!PyObject_IsInstance(self, (PyObject*)&ObjIdType))
2680  {
2681  PyErr_SetString(PyExc_TypeError, "First argument must be an instance of element");
2682  return NULL;
2683  }
2684  _ObjId * obj = (_ObjId*)self;
2685  if (!Id::isValid(obj->oid_.id))
2686  {
2687  RAISE_INVALID_ID(NULL, "moose_ObjId_get_destField_attr");
2688  }
2689  char * name = NULL;
2690  if (!PyArg_ParseTuple((PyObject *)closure,
2691  "s:_get_destField: "
2692  "expected a string in getter closure.",
2693  &name))
2694  {
2695  return NULL;
2696  }
2697  PyObject * args = PyTuple_New(2);
2698 
2699  PyTuple_SetItem(args, 0, self);
2700  Py_INCREF(self); // compensate for reference stolen by PyTuple_SetItem
2701  PyTuple_SetItem(args, 1, PyString_FromString(name));
2702  _Field * ret = PyObject_New(_Field, &moose_DestField);
2703  if (moose_DestField.tp_init((PyObject*)ret, args, NULL) != 0)
2704  {
2705  Py_XDECREF((PyObject*)ret);
2706  ret = NULL;
2707  PyErr_SetString(PyExc_RuntimeError, "moose_ObjId_get_destField_attr: failed to init DestField object");
2708  }
2709  Py_DECREF(args);
2710  return (PyObject*)ret;
2711 }
2712 
2713 
2714 int defineDestFinfos(const Cinfo * cinfo)
2715 {
2716  const string& className = cinfo->name();
2717 #ifndef NDEBUG
2718  if (verbosity > 1)
2719  {
2720  cout << "\tCreating destField attributes for " << className << endl;
2721  }
2722 #endif
2723  vector <PyGetSetDef>& vec = get_getsetdefs()[className];
2724  /*
2725  We do not know the final number of user-accessible
2726  destFinfos as we have to ignore the destFinfos starting
2727  with get/set. So use a vector instead of C array.
2728  */
2729  size_t currIndex = vec.size();
2730  for (unsigned int ii = 0; ii < cinfo->getNumDestFinfo(); ++ii)
2731  {
2732  Finfo * destFinfo = const_cast<Cinfo*>(cinfo)->getDestFinfo(ii);
2733  const string& name = destFinfo->name();
2734  /*
2735  get_{xyz} and set_{xyz} are internal destFinfos for
2736  accessing valueFinfos. Ignore them.
2737 
2738  With the '_' removed from internal get/set for value
2739  fields, we cannot separate them out. - Subha Fri Jan 31
2740  16:43:51 IST 2014
2741 
2742  The policy changed in the past and hence the following were commented out.
2743  - Subha Tue May 26 00:25:28 EDT 2015
2744  */
2745  // if (name.find("get") == 0 || name.find("set") == 0){
2746  // continue;
2747  // }
2748  PyGetSetDef destFieldGetSet;
2749  vec.push_back(destFieldGetSet);
2750 
2751  vec[currIndex].name = strdup(name.c_str());
2752  vec[currIndex].doc = (char*) "Destination field";
2753  vec[currIndex].get = (getter)moose_ObjId_get_destField_attr;
2754  PyObject *args = PyTuple_New(1);
2755  if (!args || !vec[currIndex].name) {
2756  cerr << "moosemodule.cpp: defineDestFinfos: allocation failed\n";
2757  return 0;
2758  }
2759  PyTuple_SetItem(args, 0, PyString_FromString(name.c_str()));
2760  vec[currIndex].closure = (void*)args;
2761 
2762  //LOG( debug, "\tCreated destField " << vec[currIndex].name );
2763 
2764  ++currIndex;
2765  } // ! for
2766 
2767  return 1;
2768 }
2769 
2781 PyObject * moose_ObjId_get_lookupField_attr(PyObject * self,
2782  void * closure)
2783 {
2784  if (!PyObject_IsInstance(self, (PyObject*)&ObjIdType))
2785  {
2786  PyErr_SetString(PyExc_TypeError,
2787  "First argument must be an instance of element");
2788  return NULL;
2789  }
2790  _ObjId * obj = (_ObjId*)self;
2791  if (!Id::isValid(obj->oid_.id))
2792  {
2793  RAISE_INVALID_ID(NULL, "moose_ObjId_get_lookupField_attr");
2794  }
2795  char * name = NULL;
2796  if (!PyArg_ParseTuple((PyObject *)closure,
2797  "s:moose_ObjId_get_lookupField_attr: expected a string in getter closure.",
2798  &name))
2799  {
2800  return NULL;
2801  }
2802  assert(name);
2803  /* Create a new instance of LookupField `name` and set it as
2804  * an attribute of the object self. Create the argument for
2805  * init method of LookupField. This will be (fieldname, self) */
2806  PyObject * args = PyTuple_New(2);
2807  PyTuple_SetItem(args, 0, self);
2808  Py_INCREF(self); // compensate for stolen ref
2809  PyTuple_SetItem(args, 1, PyString_FromString(name));
2810  _Field * ret = PyObject_New(_Field, &moose_LookupField);
2811  if (moose_LookupField.tp_init((PyObject*)ret, args, NULL) != 0)
2812  {
2813  Py_XDECREF((PyObject*)ret);
2814  ret = NULL;
2815  PyErr_SetString(PyExc_RuntimeError,
2816  "moose_ObjId_get_lookupField_attr: failed to init LookupField object");
2817  }
2818  Py_DECREF(args);
2819  return (PyObject*)ret;
2820 }
2821 
2822 PyObject * moose_ObjId_get_elementField_attr(PyObject * self,
2823  void * closure)
2824 {
2825  // if (!PyObject_IsInstance(self, (PyObject*)&ObjIdType)){
2826  // PyErr_SetString(PyExc_TypeError,
2827  // "First argument must be an instance of element");
2828  // return NULL;
2829  // }
2830  _ObjId * obj = (_ObjId*)self;
2831  if (!Id::isValid(obj->oid_.id))
2832  {
2833  RAISE_INVALID_ID(NULL, "moose_ObjId_get_elementField_attr");
2834  }
2835  char * name = NULL;
2836  if (!PyArg_ParseTuple((PyObject *)closure,
2837  "s:moose_ObjId_get_elementField_attr: expected a string in getter closure.",
2838  &name))
2839  {
2840  return NULL;
2841  }
2842  // Create a new instance of ElementField `name` and set it as
2843  // an attribute of the object `self`.
2844  // 1. Create the argument for init method of ElementField. This
2845  // will be (fieldname, self)
2846  PyObject * args = PyTuple_New(2);
2847  PyTuple_SetItem(args, 0, self);
2848  Py_INCREF(self); // compensate for stolen ref
2849  PyTuple_SetItem(args, 1, PyString_FromString(name));
2850  _Field * ret = PyObject_New(_Field, &moose_ElementField);
2851 
2852  // 2. Now use this arg to actually create the element field.
2853  if (moose_ElementField.tp_init((PyObject*)ret, args, NULL) != 0)
2854  {
2855  Py_DECREF((PyObject*)ret);
2856  ret = NULL;
2857  PyErr_SetString(PyExc_RuntimeError, "moose_ObjId_get_elementField_attr: failed to init ElementField object");
2858  }
2859  Py_DECREF(args);
2860  return (PyObject*)ret;
2861 }
2862 
2863 int defineElementFinfos(const Cinfo * cinfo)
2864 {
2865  const string & className = cinfo->name();
2866 #ifndef NDEBUG
2867  if (verbosity > 1)
2868  {
2869  cout << "\tDefining elementFields for " << className << endl;
2870  }
2871 #endif
2872  unsigned int num = cinfo->getNumFieldElementFinfo();
2873  unsigned int currIndex = get_getsetdefs()[className].size();
2874  for (unsigned int ii = 0; ii < num; ++ii)
2875  {
2876  const string& name = const_cast<Cinfo*>(cinfo)->getFieldElementFinfo(ii)->name();
2877  PyGetSetDef getset;
2878  get_getsetdefs()[className].push_back(getset);
2879  get_getsetdefs()[className][currIndex].name = (char*)calloc(name.size() + 1, sizeof(char));
2880  strncpy(const_cast<char*>(get_getsetdefs()[className][currIndex].name)
2881  , const_cast<char*>(name.c_str()), name.size());
2882  get_getsetdefs()[className][currIndex].doc = (char*) "Element field";
2883  get_getsetdefs()[className][currIndex].get = (getter)moose_ObjId_get_elementField_attr;
2884  PyObject * args = PyTuple_New(1);
2885  PyTuple_SetItem(args, 0, PyString_FromString(name.c_str()));
2886  get_getsetdefs()[className][currIndex].closure = (void*)args;
2887 #ifndef NDEBUG
2888  if (verbosity > 1)
2889  {
2890  cout << "\tDefined elementField " << get_getsetdefs()[className][currIndex].name << endl;
2891  }
2892 #endif
2893 
2894  ++currIndex;
2895  }
2896  return 1;
2897 }
2898 
2899 PyObject * oid_to_element(ObjId oid)
2900 {
2901  string classname = Field<string>::get(oid, "className");
2902  map<string, PyTypeObject *>::iterator it = get_moose_classes().find(classname);
2903  if (it == get_moose_classes().end())
2904  {
2905  return NULL;
2906  }
2907  PyTypeObject * pyclass = it->second;
2908  _ObjId * new_obj = PyObject_New(_ObjId, pyclass);
2909  new_obj->oid_ = oid;
2910  // Py_XINCREF(new_obj); // why? PyObject_New initializes refcnt to 1
2911  return (PyObject*)new_obj;
2912 }
2913 
2914 PyDoc_STRVAR(moose_element_documentation,
2915  "moose.element(arg) -> moose object\n"
2916  "\n"
2917  "Convert a path or an object to the appropriate builtin moose class\n"
2918  "instance\n"
2919  "\n"
2920  "Parameters\n"
2921  "----------\n"
2922  "arg : str/vec/moose object\n"
2923  " path of the moose element to be converted or another element (possibly\n"
2924  " available as a superclass instance).\n"
2925  "\n"
2926  "Returns\n"
2927  "-------\n"
2928  "melement\n"
2929  " MOOSE element (object) corresponding to the `arg` converted to write subclass.\n"
2930  "\n");
2931 PyObject * moose_element(PyObject* dummy, PyObject * args)
2932 {
2933  char * path = NULL;
2934  PyObject * obj = NULL;
2935  ObjId oid;
2936  unsigned nid = 0, did = 0, fidx = 0;
2937  Id id;
2938  unsigned int numData = 0;
2939  if (PyArg_ParseTuple(args, "s", &path))
2940  {
2941  oid = ObjId(path);
2942  // cout << "Original Path " << path << ", Element Path: " << oid.path() << endl;
2943  if ( oid.bad() )
2944  {
2945  PyErr_SetString(PyExc_ValueError, ( std::string("moose_element: '")
2946  + std::string(path)
2947  + std::string("' does not exist!")
2948  ).c_str()
2949  );
2950  return NULL;
2951  }
2952  PyObject * new_obj = oid_to_element(oid);
2953  if (new_obj)
2954  {
2955  return new_obj;
2956  }
2957  PyErr_SetString(PyExc_TypeError, "moose_element: unknown class");
2958  return NULL;
2959  }
2960  PyErr_Clear();
2961  if (PyArg_ParseTuple(args, "I|II", &nid, &did, &fidx))
2962  {
2963  oid = ObjId(id, did, fidx);
2964  // Todo: test for validity
2965  PyObject * new_obj = oid_to_element(oid);
2966  if (!new_obj)
2967  {
2968  PyErr_SetString(PyExc_RuntimeError, "moose_element: not a moose class.");
2969  }
2970  return new_obj;
2971  }
2972  PyErr_Clear();
2973  if (!PyArg_ParseTuple(args, "O|II", &obj, &did, &fidx))
2974  {
2975  PyErr_SetString(PyExc_TypeError, "moose_element: argument must be a path or an existing element or an vec");
2976  return NULL;
2977  }
2978  // PyErr_Clear();
2979  if (PyObject_IsInstance(obj, (PyObject*)&ObjIdType))
2980  {
2981  oid = ((_ObjId*)obj)->oid_;
2982  }
2983  else if (PyObject_IsInstance(obj, (PyObject*)&IdType))
2984  {
2985  oid = ObjId(((_Id*)obj)->id_, did, fidx); // TODO: check for validity
2986  }
2987  else if (ElementField_SubtypeCheck(obj))
2988  {
2989  oid = ObjId(((_Id*)moose_ElementField_getId((_Field*)obj, NULL))->id_);
2990  }
2991  if (oid.bad())
2992  {
2993  PyErr_SetString(PyExc_TypeError, "moose_element: cannot convert to moose element.");
2994  return NULL;
2995  }
2996  PyObject * new_obj = oid_to_element(oid);
2997  if (!new_obj)
2998  {
2999  PyErr_SetString(PyExc_RuntimeError, "moose_element: not a moose class.");
3000  }
3001  return new_obj;
3002 }
3003 
3004 
3006 // Method definitions for MOOSE module
3008 static PyMethodDef MooseMethods[] =
3009 {
3010  {"element", (PyCFunction)moose_element, METH_VARARGS, moose_element_documentation},
3011  {"getFieldNames", (PyCFunction)moose_getFieldNames, METH_VARARGS, moose_getFieldNames_documentation},
3012  {"copy", (PyCFunction)moose_copy, METH_VARARGS|METH_KEYWORDS, moose_copy_documentation},
3013  {"move", (PyCFunction)moose_move, METH_VARARGS, "Move a vec object to a destination."},
3014  {"delete", (PyCFunction)moose_delete, METH_VARARGS, moose_delete_documentation},
3015  {"useClock", (PyCFunction)moose_useClock, METH_VARARGS, moose_useClock_documentation},
3016  {"setClock", (PyCFunction)moose_setClock, METH_VARARGS, moose_setClock_documentation},
3017  {"start", (PyCFunction)moose_start, METH_VARARGS, moose_start_documentation},
3018  {"reinit", (PyCFunction)moose_reinit, METH_VARARGS, moose_reinit_documentation},
3019  {"stop", (PyCFunction)moose_stop, METH_VARARGS, "Stop simulation"},
3020  {"isRunning", (PyCFunction)moose_isRunning, METH_VARARGS, "True if the simulation is currently running."},
3021  {"exists", (PyCFunction)moose_exists, METH_VARARGS, "True if there is an object with specified path."},
3022  {"loadModel", (PyCFunction)moose_loadModel, METH_VARARGS, moose_loadModel_documentation},
3023  //{"saveModel", (PyCFunction)moose_saveModel, METH_VARARGS, moose_saveModel_documentation},
3024  {"connect", (PyCFunction)moose_connect, METH_VARARGS, moose_connect_documentation},
3025  {"getCwe", (PyCFunction)moose_getCwe, METH_VARARGS, "Get the current working element. 'pwe' is an alias of this function."},
3026  {"setCwe", (PyCFunction)moose_setCwe, METH_VARARGS, "Set the current working element. 'ce' is an alias of this function"},
3027  {"getFieldDict", (PyCFunction)moose_getFieldDict, METH_VARARGS, moose_getFieldDict_documentation},
3028  {
3029  "getField", (PyCFunction)moose_getField, METH_VARARGS,
3030  "getField(element, field, fieldtype) -- Get specified field of specified type from object vec."
3031  },
3032  {"seed", (PyCFunction)moose_seed, METH_VARARGS, moose_seed_documentation},
3033  {"rand", (PyCFunction)moose_rand, METH_NOARGS, moose_rand_documentation},
3034  {"wildcardFind", (PyCFunction)moose_wildcardFind, METH_VARARGS, moose_wildcardFind_documentation},
3035  {
3036  "quit", (PyCFunction)moose_quit, METH_NOARGS, "Finalize MOOSE threads and quit MOOSE. This is made available for"
3037  " debugging purpose only. It will automatically get called when moose"
3038  " module is unloaded. End user should not use this function."
3039  },
3040 
3041  {NULL, NULL, 0, NULL} /* Sentinel */
3042 };
3043 
3044 
3045 
3047 // module initialization
3049 PyDoc_STRVAR(moose_module_documentation,
3050  "MOOSE = Multiscale Object-Oriented Simulation Environment.\n"
3051  "\n"
3052  "Moose is the core of a modern software platform for the simulation\n"
3053  "of neural systems ranging from subcellular components and\n"
3054  "biochemical reactions to complex models of single neurons, large\n"
3055  "networks, and systems-level processes.");
3056 
3057 #ifdef PY3K
3058 
3059 int moose_traverse(PyObject *m, visitproc visit, void *arg)
3060 {
3061  Py_VISIT(GETSTATE(m)->error);
3062  return 0;
3063 }
3064 
3065 int moose_clear(PyObject *m)
3066 {
3067  Py_CLEAR(GETSTATE(m)->error);
3068  // I did get a segmentation fault at exit (without running a reinit() or start()) after creating a compartment. After putting the finalize here it went away. But did not reoccur even after commenting it out. Will need closer debugging.
3069  // - Subha 2012-08-18, 00:36
3070  finalize();
3071  return 0;
3072 }
3073 
3074 
3075 static struct PyModuleDef MooseModuleDef =
3076 {
3077  PyModuleDef_HEAD_INIT,
3078  "moose", /* m_name */
3079  moose_module_documentation, /* m_doc */
3080  sizeof(struct module_state), /* m_size */
3081  MooseMethods, /* m_methods */
3082  0, /* m_reload */
3083  moose_traverse, /* m_traverse */
3084  moose_clear, /* m_clear */
3085  NULL /* m_free */
3086 };
3087 
3088 #define INITERROR return NULL
3089 #define MODINIT(name) PyInit_##name()
3090 #else // Python 2
3091 #define INITERROR return
3092 #define MODINIT(name) init##name()
3093 #endif
3094 
3095 PyMODINIT_FUNC MODINIT(_moose)
3096 {
3097  clock_t modinit_start = clock();
3098 
3099  //PyGILState_STATE gstate;
3100  //gstate = PyGILState_Ensure();
3101 
3102  // First of all create the Shell. We convert the environment
3103  // variables into c-like argv array
3104  vector<string> args = setup_runtime_env();
3105  int argc = args.size();
3106  char ** argv = (char**)calloc(args.size(), sizeof(char*));
3107  for (int ii = 0; ii < argc; ++ii)
3108  {
3109  argv[ii] = (char*)(calloc(args[ii].length()+1, sizeof(char)));
3110  strncpy(argv[ii], args[ii].c_str(), args[ii].length()+1);
3111  }
3112 
3113  // Should not call. No pthreads now. PyEval_InitThreads();
3114  Id shellId = getShell(argc, argv);
3115  for (int ii = 1; ii < argc; ++ii)
3116  {
3117  free(argv[ii]);
3118  }
3119  // Now initialize the module
3120 #ifdef PY3K
3121  PyObject * moose_module = PyModule_Create(&MooseModuleDef);
3122 #else
3123  PyObject *moose_module = Py_InitModule3("_moose",
3124  MooseMethods,
3125  moose_module_documentation);
3126 #endif
3127  if (moose_module == NULL)
3128  {
3129  INITERROR;
3130  }
3131  struct module_state * st = GETSTATE(moose_module);
3132  char error[] = "moose.Error";
3133  st->error = PyErr_NewException(error, NULL, NULL);
3134  if (st->error == NULL)
3135  {
3136  Py_XDECREF(moose_module);
3137  INITERROR;
3138  }
3139  int registered = Py_AtExit(&finalize);
3140  if (registered != 0)
3141  {
3142  cerr << "Failed to register finalize() to be called at exit. " << endl;
3143  }
3144 #ifdef USE_NUMPY
3145  import_array();
3146 #endif
3147  // Add Id type
3148  // Py_TYPE(&IdType) = &PyType_Type; // unnecessary - filled in by PyType_Ready
3149  IdType.tp_new = PyType_GenericNew;
3150  if (PyType_Ready(&IdType) < 0)
3151  {
3152  PyErr_Print();
3153  exit(-1);
3154  };
3155  Py_INCREF(&IdType);
3156  PyModule_AddObject(moose_module, "vec", (PyObject*)&IdType);
3157 
3158  // Add ObjId type
3159  // Py_TYPE(&ObjIdType) = &PyType_Type; // unnecessary - filled in by PyType_Ready
3160  ObjIdType.tp_new = PyType_GenericNew;
3161  if (PyType_Ready(&ObjIdType) < 0)
3162  {
3163  PyErr_Print();
3164  exit(-1);
3165  };
3166  Py_INCREF(&ObjIdType);
3167  PyModule_AddObject(moose_module, "melement", (PyObject*)&ObjIdType);
3168 
3169  // Add LookupField type
3170  // Py_TYPE(&moose_LookupField) = &PyType_Type; // unnecessary - filled in by PyType_Ready
3171  // moose_LookupField.tp_new = PyType_GenericNew;
3172  if (PyType_Ready(&moose_LookupField) < 0)
3173  {
3174  PyErr_Print();
3175  exit(-1);
3176  }
3177  Py_INCREF(&moose_LookupField);
3178  PyModule_AddObject(moose_module, "LookupField", (PyObject*)&moose_LookupField);
3179 
3180  if (PyType_Ready(&moose_ElementField) < 0)
3181  {
3182  PyErr_Print();
3183  exit(-1);
3184  }
3185  Py_INCREF(&moose_ElementField);
3186  PyModule_AddObject(moose_module, "ElementField", (PyObject*)&moose_ElementField);
3187  // Add DestField type
3188  // Py_TYPE(&moose_DestField) = &PyType_Type; // unnecessary - filled in by PyType_Ready
3189  // moose_DestField.tp_flags = Py_TPFLAGS_DEFAULT;
3190  // moose_DestField.tp_call = moose_DestField_call;
3191  // moose_DestField.tp_doc = DestField_documentation;
3192  // moose_DestField.tp_new = PyType_GenericNew;
3193  if (PyType_Ready(&moose_DestField) < 0)
3194  {
3195  PyErr_Print();
3196  exit(-1);
3197  }
3198  Py_INCREF(&moose_DestField);
3199  PyModule_AddObject(moose_module, "DestField", (PyObject*)&moose_DestField);
3200 
3201  // PyModule_AddIntConstant(moose_module, "SINGLETHREADED", isSingleThreaded);
3202  PyModule_AddIntConstant(moose_module, "NUMCORES", numCores);
3203  PyModule_AddIntConstant(moose_module, "NUMNODES", numNodes);
3204  // PyModule_AddIntConstant(moose_module, "NUMPTHREADS", numProcessThreads);
3205  PyModule_AddIntConstant(moose_module, "MYNODE", myNode);
3206  PyModule_AddIntConstant(moose_module, "INFINITE", isInfinite);
3207  PyModule_AddStringConstant(moose_module, "__version__", SHELLPTR->doVersion().c_str());
3208  PyModule_AddStringConstant(moose_module, "VERSION", SHELLPTR->doVersion().c_str());
3209  PyObject * module_dict = PyModule_GetDict(moose_module);
3210  clock_t defclasses_start = clock();
3211  if (!defineAllClasses(module_dict))
3212  {
3213  PyErr_Print();
3214  exit(-1);
3215  }
3216  for (map <string, PyTypeObject * >::iterator ii = get_moose_classes().begin();
3217  ii != get_moose_classes().end(); ++ii)
3218  {
3219  PyModule_AddObject(moose_module, ii->first.c_str(), (PyObject*)(ii->second));
3220  }
3221 
3222  clock_t defclasses_end = clock();
3223 
3224  LOG( moose::info, "`Time to define moose classes:"
3225  << (defclasses_end - defclasses_start) * 1.0 /CLOCKS_PER_SEC
3226  );
3227 
3228  //PyGILState_Release(gstate);
3229  clock_t modinit_end = clock();
3230 
3231  LOG( moose::info, "`Time to initialize module:"
3232  << (modinit_end - modinit_start) * 1.0 /CLOCKS_PER_SEC
3233  );
3234 
3235  if (doUnitTests)
3236  {
3237  test_moosemodule();
3238  }
3239 #ifdef PY3K
3240  return moose_module;
3241 #endif
3242 }
3243 
3244 
3246 // Main function
3248 
3249 // int main(int argc, char* argv[])
3250 // {
3251 // #ifdef PY3K
3252 // size_t len = strlen(argv[0]);
3253 // wchar_t * warg = (wchar_t*)calloc(sizeof(wchar_t), len);
3254 // mbstowcs(warg, argv[0], len);
3255 // #else
3256 // char * warg = argv[0];
3257 // #endif
3258 // for (int ii = 0; ii < argc; ++ii){
3259 // cout << "ARGV: " << argv[ii];
3260 // }
3261 // cout << endl;
3262 // Py_SetProgramName(warg);
3263 // Py_Initialize();
3264 // MODINIT(_moose);
3265 // #ifdef PY3K
3266 // free(warg);
3267 // #endif
3268 // return 0;
3269 // }
3270 
3271 //
3272 // moosemodule.cpp ends here
static unsigned int numCores
PyObject_HEAD Id id_
Definition: moosemodule.h:114
int wildcardFind(const string &path, vector< ObjId > &ret)
Definition: Wildcard.cpp:169
PyObject * deleteObjId(ObjId obj)
Definition: vec.cpp:522
const Cinfo * baseCinfo() const
Definition: Cinfo.cpp:216
PyObject * moose_exists(PyObject *dummy, PyObject *args)
void mtseed(unsigned int x)
Set the global seed or all rngs.
Definition: global.cpp:89
Finfo * getFieldElementFinfo(unsigned int i) const
Definition: Cinfo.cpp:523
PyObject * moose_start(PyObject *dummy, PyObject *args)
#define ObjId_SubtypeCheck(v)
Definition: moosemodule.h:98
char shortType(string)
char * data() const
Definition: Eref.cpp:41
uint32_t value
Definition: moosemodule.h:42
int defineElementFinfos(const Cinfo *cinfo)
#define SHELLPTR
Definition: moosemodule.h:105
void testAsync()
Definition: testAsync.cpp:1813
static void clearAllElements()
Definition: Id.cpp:202
const char ** getFinfoTypes()
finalize()
Finfo * getDestFinfo(unsigned int i) const
Definition: Cinfo.cpp:430
void initMsgManagers()
Finfo * getValueFinfo(unsigned int i) const
Definition: Cinfo.cpp:453
unsigned int getNumSrcFinfo() const
Definition: Cinfo.cpp:421
PyObject * moose_reinit(PyObject *dummy, PyObject *args)
#define GETSTATE(m)
Definition: moosemodule.h:67
PyObject * moose_delete(PyObject *dummy, PyObject *args)
PyTypeObject moose_ElementField
Definition: mfield.cpp:473
PyObject * moose_getFieldNames(PyObject *dummy, PyObject *args)
void mpiTests()
Definition: main.cpp:350
void doSetClock(unsigned int tickNum, double dt)
Definition: Shell.cpp:377
unsigned int getNumDestFinfo() const
Definition: Cinfo.cpp:444
bool bad() const
Definition: ObjId.cpp:18
PyObject * convert_and_set_tuple_entry(PyObject *tuple, unsigned int index, void *vptr, char typecode)
static void cleanSimulation()
Clean-up MOOSE before shutting down. This function is called whenever keyboard interrupt terminates t...
Definition: Shell.cpp:1015
PyObject * moose_getCwe(PyObject *dummy, PyObject *args)
Definition: SetGet.h:236
void finalize()
create_shell()
static DestFinfo dummy("dummy","This Finfo is a dummy. If you are reading this you have used an invalid index", 0)
map< string, PyTypeObject * > & get_moose_classes()
Id id
Definition: ObjId.h:98
PyObject * moose_getFieldDict(PyObject *dummy, PyObject *args)
unsigned int getNumValueFinfo() const
Definition: Cinfo.cpp:467
PyObject * moose_ObjId_get_destField_attr(PyObject *self, void *closure)
virtual string rttiType() const
Definition: Finfo.cpp:120
static const Cinfo * find(const std::string &name)
Definition: Cinfo.cpp:200
PyObject * moose_element(PyObject *dummy, PyObject *args)
void testMpiShell()
Definition: testShell.cpp:1833
vector< ObjId > all_elements(Id id)
#define INITERROR
Definition: ObjId.h:20
PyObject * error
Definition: moosemodule.h:26
PyObject * moose_setClock(PyObject *dummy, PyObject *args)
static int isInfinite
const map< string, string > & get_field_alias()
PyObject * moose_ObjId_get_elementField_attr(PyObject *self, void *closure)
Eref eref() const
Definition: Id.cpp:125
PyDoc_STRVAR(moose_getFieldNames_documentation,"getFieldNames(className, finfoType='valueFinfo') -> tuple\n""\n""Get a tuple containing the name of all the fields of `finfoType`\n""kind.\n""\n""Parameters\n""----------\n""className : string\n"" Name of the class to look up.\n""finfoType : string\n"" The kind of field "" `valueFinfo` - "" `srcFinfo` - "" `destFinfo` - "" `lookupFinfo`- "" `fieldElementFinfo` - \n""\n""Returns\n""-------\n""tuple\n"" Names of the fields of type `finfoType` in class `className`.\n")
const string & name() const
Definition: Finfo.cpp:80
void testBuiltinsProcess()
#define ElementField_SubtypeCheck(v)
Definition: moosemodule.h:101
#define RAISE_INVALID_ID(ret, msg)
Definition: moosemodule.h:71
PyObject * moose_ObjId_get_lookupField_attr(PyObject *self, void *closure)
PyObject_HEAD ObjId oid_
Definition: moosemodule.h:133
int defineClass(PyObject *module_dict, const Cinfo *cinfo)
PyObject * moose_quit(PyObject *dummy)
void testShell()
Definition: testShell.cpp:1818
PyObject * moose_setCwe(PyObject *dummy, PyObject *args)
void testMsg()
Definition: testMsg.cpp:370
void mooseBenchmarks(unsigned int option)
map< string, vector< PyGetSetDef > > & get_getsetdefs()
int defineDestFinfos(const Cinfo *cinfo)
double pymoose_mtrand_(void)
void * to_cpp(PyObject *object, char typecode)
void testMpiBuiltins()
static int doRegressionTests
const std::string & name() const
Definition: Cinfo.cpp:260
static PyMethodDef MooseMethods[]
PyObject * moose_stop(PyObject *dummy, PyObject *args)
void test_moosemodule()
int defineLookupFinfos(const Cinfo *cinfo)
static unsigned int myNode
PyTypeObject moose_DestField
Definition: mfield.cpp:333
void testSchedulingProcess()
void testMpiMsg()
Definition: testMsg.cpp:376
#define Id_SubtypeCheck(v)
Definition: moosemodule.h:96
PyObject * moose_connect(PyObject *dummy, PyObject *args)
void testMpiScheduling()
PyObject * moose_getField(PyObject *dummy, PyObject *args)
PyTypeObject ObjIdType
#define MODINIT(name)
Finfo * getLookupFinfo(unsigned int i) const
Definition: Cinfo.cpp:477
PyObject * moose_useClock(PyObject *dummy, PyObject *args)
void processTests(Shell *)
Definition: main.cpp:333
PyObject * to_pytuple(void *obj, char typecode)
unsigned int getNumFieldElementFinfo() const
Definition: Cinfo.cpp:537
vector< int > pysequence_to_dimvec(PyObject *dims)
Finfo * getSrcFinfo(unsigned int i) const
Definition: Cinfo.cpp:406
int verbosity
string getFieldType(string className, string fieldName)
const map< string, string > & getArgMap()
Definition: setupenv.cpp:41
static bool isValid(Id id)
Definition: Id.h:145
void nonMpiTests(Shell *)
Definition: main.cpp:297
string getBaseClass() const
Definition: Cinfo.cpp:391
int parseFinfoType(string className, string finfoType, string fieldName, vector< string > &typeVec)
void testScheduling()
vector< string > setup_runtime_env()
PyObject * moose_seed(PyObject *dummy, PyObject *args)
PyObject * moose_copy(PyObject *dummy, PyObject *args, PyObject *kwargs)
PyTypeObject moose_LookupField
Definition: mfield.cpp:252
char innerType(char)
Definition: types.cpp:104
static unsigned int numNodes
static char name[]
Definition: mfield.cpp:401
Id init(int argc, char **argv, bool &doUnitTests, bool &doRegressionTests, unsigned int &benchmark)
Definition: main.cpp:150
PyObject * moose_wildcardFind(PyObject *dummy, PyObject *args)
void tokenize(const string &str, const string &delimiters, vector< string > &tokens)
Definition: strutil.cpp:19
#define maxArgs
Definition: moosemodule.h:88
void handle_keyboard_interrupts(int signum)
Handle signal raised by user during simulation.
double mtrand(void)
Generate a random double between 0 and 1.
Definition: global.cpp:97
Definition: Id.h:17
Id getShell(int argc, char **argv)
setup_runtime_env()
void testBuiltins()
PyObject * to_py(void *obj, char typecode)
void destroyMsgManagers()
static unsigned int myNode()
void doUseClock(string path, string field, unsigned int tick)
Definition: Shell.cpp:382
PyTypeObject * getBaseClass(PyObject *self)
static A get(const ObjId &dest, const string &field)
Definition: SetGet.h:284
void speedTestMultiNodeIntFireNetwork(unsigned int size, unsigned int runsteps)
PyObject * moose_loadModel(PyObject *dummy, PyObject *args)
PyObject * moose_move(PyObject *dummy, PyObject *args)
static int doUnitTests
PyObject * moose_ElementField_getId(_Field *self, void *closure)
Definition: mfield.cpp:581
static unsigned int numNodes()
unsigned int getNumLookupFinfo() const
Definition: Cinfo.cpp:491
PyTypeObject IdType
Definition: vec.cpp:262
PyObject * oid_to_element(ObjId oid)
static char id[]
Definition: mfield.cpp:404
int getFieldDict(string className, string finfoType, vector< string > &fieldNames, vector< string > &fieldTypes)
unsigned int id_
Definition: Id.h:172
int defineAllClasses(PyObject *module_dict)
vector< string > getFieldNames(string className, string finfoType)
const unsigned int BADINDEX
Used by ObjId and Eref.
Definition: consts.cpp:25
void testKinetics()
Definition: Cinfo.h:18
static char path[]
Definition: mfield.cpp:403
static int quitFlag
void pymoose_mtseed_(long int seed)
PyObject * moose_isRunning(PyObject *dummy, PyObject *args)
PyObject * moose_rand(PyObject *dummy)
static void clearAllMsgs()
Definition: Msg.cpp:286
Definition: Shell.h:43
const Finfo * findFinfo(const string &name) const
Definition: Cinfo.cpp:224
Definition: Finfo.h:12