18 #ifndef FIELD_PYTHON_IMPL_HH_
19 #define FIELD_PYTHON_IMPL_HH_
22 #include <boost/type_traits.hpp>
27 namespace it = Input::Type;
33 template <
int spacedim, class Value>
34 const Input::Type::Record &
FieldPython<spacedim, Value>::get_input_type()
39 "Python script given as in place string")
41 "Python script given as external file")
43 "Function in the given script that returns tuple containing components of the return type.\n"
44 "For NxM tensor values: tensor(row,col) = tuple( M*row + col ).")
49 template <
int spacedim,
class Value>
51 Input::register_class< FieldPython<spacedim, Value>,
unsigned int >(
"FieldPython") +
56 template <
int spacedim,
class Value>
60 #ifdef FLOW123D_HAVE_PYTHON
66 xprintf(
UsrErr,
"Flow123d compiled without support for Python, FieldPython can not be used.\n");
67 #endif // FLOW123D_HAVE_PYTHON
72 template <
int spacedim,
class Value>
75 #ifdef FLOW123D_HAVE_PYTHON
76 p_module_ = PythonLoader::load_module_from_string(
"python_field_"+func_name, python_source);
78 #endif // FLOW123D_HAVE_PYTHON
85 template <
int spacedim,
class Value>
89 set_python_field_from_string( *it, rec.
val<
string>(
"function") );
92 if (! it)
xprintf(
UsrErr,
"Either 'script_string' or 'script_file' has to be specified in PythonField initialization.");
93 set_python_field_from_file( *it, rec.
val<
string>(
"function") );
99 template <
int spacedim,
class Value>
102 #ifdef FLOW123D_HAVE_PYTHON
103 p_module_ = PythonLoader::load_module_from_file(
string(file_name) );
105 #endif // FLOW123D_HAVE_PYTHON
111 template <
int spacedim,
class Value>
114 #ifdef FLOW123D_HAVE_PYTHON
115 p_func_ = PythonLoader::get_callable(p_module_, func_name);
117 p_args_ = PyTuple_New( spacedim );
120 for(
unsigned int i = 0; i < spacedim; i++) {
121 p_value_ = PyFloat_FromDouble(
double(i) );
122 PyTuple_SetItem(p_args_, i, p_value_);
124 p_value_ = PyObject_CallObject(p_func_, p_args_);
125 PythonLoader::check_error();
127 if ( ! PyTuple_Check( p_value_)) {
129 ss <<
"Field '" << func_name <<
"' from the python module: " << PyModule_GetName(p_module_) <<
" doesn't return Tuple." << endl;
130 THROW( ExcMessage() << EI_Message( ss.str() ));
133 unsigned int size = PyTuple_Size( p_value_);
135 unsigned int value_size=this->value_.n_rows() * this->value_.n_cols();
136 if ( size != value_size) {
137 xprintf(
UsrErr,
"Field '%s' from the python module: %s returns %d components but should return %d components.\n"
138 ,func_name.c_str(), PyModule_GetName(p_module_), size, value_size);
141 #endif // FLOW123D_HAVE_PYTHON
148 template <
int spacedim,
class Value>
151 set_value(p,elm, this->value_);
152 return this->r_value_;
159 template <
int spacedim,
class Value>
164 for(
unsigned int i=0; i< point_list.size(); i++) {
165 Value envelope(value_list[i]);
166 OLD_ASSERT( envelope.n_rows()==this->value_.n_rows(),
167 "value_list[%d] has wrong number of rows: %d; should match number of components: %d\n",
168 i, envelope.n_rows(),this->value_.n_rows());
169 set_value(point_list[i], elm, envelope );
176 template <
int spacedim,
class Value>
179 #ifdef FLOW123D_HAVE_PYTHON
180 for(
unsigned int i = 0; i < spacedim; i++) {
181 p_value_ = PyFloat_FromDouble( p[i] );
182 PyTuple_SetItem(p_args_, i, p_value_);
184 p_value_ = PyObject_CallObject(p_func_, p_args_);
185 PythonLoader::check_error();
188 for(
unsigned int row=0; row < value.n_rows(); row++)
189 for(
unsigned int col=0; col < value.n_cols(); col++, pos++)
190 if ( boost::is_integral< typename Value::element_type >::value ) value(row,col) = PyLong_AsLong( PyTuple_GetItem( p_value_, pos ) );
191 else value(row,col) = PyFloat_AsDouble( PyTuple_GetItem( p_value_, pos ) );
193 #endif // FLOW123D_HAVE_PYTHON
199 template <
int spacedim,
class Value>
201 #ifdef FLOW123D_HAVE_PYTHON
206 #endif // FLOW123D_HAVE_PYTHON
void set_python_field_from_file(const FilePath &file_name, const string &func_name)
void set_func(const string &func_name)
void set_python_field_from_string(const string &python_source, const string &func_name)
virtual void value_list(const std::vector< Point > &point_list, const ElementAccessor< spacedim > &elm, std::vector< typename Value::return_type > &value_list)
void set_value(const Point &p, const ElementAccessor< spacedim > &elm, Value &value)
FieldPython(unsigned int n_comp=0)
Space< spacedim >::Point Point
Dedicated class for storing path to input and output files.
#define OLD_ASSERT_EQUAL(a, b)
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm)
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
virtual void init_from_input(const Input::Record &rec)