8 #ifndef FIELD_PYTHON_IMPL_HH_
9 #define FIELD_PYTHON_IMPL_HH_
12 #include <boost/type_traits.hpp>
17 namespace it = Input::Type;
19 template <
int spacedim,
class Value>
24 template <
int spacedim,
class Value>
33 "Python script given as in place string")
35 "Python script given as external file")
37 "Function in the given script that returns tuple containing components of the return type.\n"
38 "For NxM tensor values: tensor(row,col) = tuple( M*row + col ).");
45 template <
int spacedim,
class Value>
55 xprintf(
UsrErr,
"Flow123d compiled without support for Python, FieldPython can not be used.\n");
61 template <
int spacedim,
class Value>
65 p_module_ = PythonLoader::load_module_from_string(
"python_field_"+func_name, python_source);
74 template <
int spacedim,
class Value>
78 set_python_field_from_string( *it, rec.
val<
string>(
"function") );
81 if (! it)
xprintf(
UsrErr,
"Either 'script_string' or 'script_file' has to be specified in PythonField initialization.");
82 set_python_field_from_file( *it, rec.
val<
string>(
"function") );
88 template <
int spacedim,
class Value>
92 p_module_ = PythonLoader::load_module_from_file(
string(file_name) );
100 template <
int spacedim,
class Value>
104 char func_char[func_name.size()+2];
105 std::strcpy(func_char, func_name.c_str());
106 p_func_ = PyObject_GetAttrString(p_module_, func_char );
108 if (PyErr_Occurred()) PyErr_Print();
109 xprintf(
UsrErr,
"Field '%s' not found in the python module: %s\n", func_name.c_str(), PyModule_GetName(p_module_) );
111 Py_XDECREF(p_module_);
114 if (! PyCallable_Check(p_func_)) {
115 xprintf(
UsrErr,
"Field '%s' from the python module: %s is not callable.\n", func_name.c_str(), PyModule_GetName(p_module_) );
117 Py_XDECREF(p_module_);
121 p_args_ = PyTuple_New( spacedim );
124 for(
unsigned int i = 0; i < spacedim; i++) {
125 p_value_ = PyFloat_FromDouble(
double(i) );
126 PyTuple_SetItem(p_args_, i, p_value_);
128 p_value_ = PyObject_CallObject(p_func_, p_args_);
130 if (p_value_ == NULL) {
133 xprintf(
Err,
"Failed to call field '%s' from the python module: %s\n", func_name.c_str(), PyModule_GetName(p_module_) );
136 if ( ! PyTuple_Check( p_value_)) {
137 xprintf(
UsrErr,
"Field '%s' from the python module: %s doesn't return Tuple.\n", func_name.c_str(), PyModule_GetName(p_module_) );
140 unsigned int size = PyTuple_Size( p_value_);
142 unsigned int value_size=this->value_.n_rows() * this->value_.n_cols();
143 if ( size != value_size) {
144 xprintf(
UsrErr,
"Field '%s' from the python module: %s returns %d components but should return %d components.\n"
145 ,func_name.c_str(), PyModule_GetName(p_module_), size, value_size);
148 #endif // HAVE_PYTHON
155 template <
int spacedim,
class Value>
158 set_value(p,elm, this->value_);
159 return this->r_value_;
166 template <
int spacedim,
class Value>
171 for(
unsigned int i=0; i< point_list.size(); i++) {
172 Value envelope(value_list[i]);
173 set_value(point_list[i], elm, envelope );
181 template <
int spacedim,
class Value>
185 for(
unsigned int i = 0; i < spacedim; i++) {
186 p_value_ = PyFloat_FromDouble( p[i] );
187 PyTuple_SetItem(p_args_, i, p_value_);
189 p_value_ = PyObject_CallObject(p_func_, p_args_);
191 if (p_value_ == NULL) {
197 for(
unsigned int row=0; row < value.n_rows(); row++)
198 for(
unsigned int col=0; col < value.n_cols(); col++, pos++)
199 if ( boost::is_integral< typename Value::element_type >::value ) value(row,col) = PyLong_AsLong( PyTuple_GetItem( p_value_, pos ) );
200 else value(row,col) = PyFloat_AsDouble( PyTuple_GetItem( p_value_, pos ) );
202 #endif // HAVE_PYTHON
208 template <
int spacedim,
class Value>
215 #endif // HAVE_PYTHON