OOFEM  2.4
OOFEM.org - Object Oriented Finite Element Solver
pythonexpression.C
Go to the documentation of this file.
1 /*
2  *
3  * ##### ##### ###### ###### ### ###
4  * ## ## ## ## ## ## ## ### ##
5  * ## ## ## ## #### #### ## # ##
6  * ## ## ## ## ## ## ## ##
7  * ## ## ## ## ## ## ## ##
8  * ##### ##### ## ###### ## ##
9  *
10  *
11  * OOFEM : Object Oriented Finite Element Code
12  *
13  * Copyright (C) 1993 - 2013 Borek Patzak
14  *
15  *
16  *
17  * Czech Technical University, Faculty of Civil Engineering,
18  * Department of Structural Mechanics, 166 29 Prague, Czech Republic
19  *
20  * This library is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU Lesser General Public
22  * License as published by the Free Software Foundation; either
23  * version 2.1 of the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28  * Lesser General Public License for more details.
29  *
30  * You should have received a copy of the GNU Lesser General Public
31  * License along with this library; if not, write to the Free Software
32  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33  */
34 
35 #include <Python.h>
36 
37 #include "pythonexpression.h"
38 #include "dynamicinputrecord.h"
39 #include "classfactory.h"
40 #include "error.h"
41 
42 #include <sstream>
43 
44 // Defines the name for the return variable;
45 #define RETURN_VARIABLE "ret"
46 
47 namespace oofem {
48 REGISTER_Function(PythonExpression);
49 
51 
53 {
55  Py_DECREF(this->main_dict);
56 }
57 
60 {
61  IRResultType result;
62 
66 
67  this->f = Py_CompileString(fExpression.c_str(), "internal", Py_eval_input);
68  this->dfdt = Py_CompileString(dfdtExpression.c_str(), "internal", Py_eval_input);
69  this->d2fdt2 = Py_CompileString(d2fdt2Expression.c_str(), "internal", Py_eval_input);
70 
72  if ( !main_dict ) {
73  PyObject *main_module = PyImport_AddModule("__main__");
74  this->main_dict = PyModule_GetDict(main_module);
75  }
76 
77  return Function :: initializeFrom(ir);
78 }
79 
80 
81 void
83 {
88 }
89 
90 
91 PyObject *
92 PythonExpression :: getDict(std :: map< std :: string, FunctionArgument > &valDict)
93 {
94  PyObject *local_dict = PyDict_New();
95  for ( const auto &named_arg: valDict ) {
96  const FunctionArgument &arg = named_arg.second;
97  PyObject *tmp;
98  if ( arg.type == FunctionArgument :: FAT_double ) {
99  tmp = PyFloat_FromDouble(arg.val0);
100  } else if ( arg.type == FunctionArgument :: FAT_FloatArray ) {
101  tmp = PyList_New( arg.val1.giveSize() );
102  for ( int i = 0; i < arg.val1.giveSize(); ++i ) {
103  PyList_SET_ITEM( tmp, i, PyFloat_FromDouble( arg.val1.at(i) ) );
104  }
105  } else if ( arg.type == FunctionArgument :: FAT_int ) {
106  tmp = PyLong_FromLong(arg.val2);
107  } else if ( arg.type == FunctionArgument :: FAT_IntArray ) {
108  tmp = PyList_New( arg.val3.giveSize() );
109  for ( int i = 0; i < arg.val3.giveSize(); ++i ) {
110  PyList_SET_ITEM( tmp, i, PyLong_FromLong( arg.val3.at(i) ) );
111  }
112  } else {
113  tmp = NULL;
114  OOFEM_ERROR("Unsupported FunctionArgumentType");
115  }
116  PyDict_SetItemString(local_dict, named_arg.first.c_str(), tmp);
117  }
118  return local_dict;
119 }
120 
121 
122 void
123 PythonExpression :: getArray(FloatArray &answer, PyObject *func, std :: map< std :: string, FunctionArgument > &valDict)
124 {
125  PyObject *local_dict = getDict(valDict);
126  PyObject *dummy = PyEval_EvalCode( ( PyCodeObject * ) func, main_dict, local_dict );
127  PyObject *ret = PyDict_GetItemString(local_dict, RETURN_VARIABLE);
128  if ( PyList_Check(ret) ) {
129  int size = PyList_GET_SIZE(ret);
130  answer.resize(size);
131  for ( int i = 0; i < size; ++i ) {
132  answer(i) = PyFloat_AS_DOUBLE( PyList_GET_ITEM(ret, i) );
133  }
134  } else {
135  answer = {PyFloat_AS_DOUBLE(ret) };
136  }
137  Py_DECREF(local_dict);
138  Py_DECREF(dummy);
139  Py_DECREF(ret);
140 }
141 
142 
143 void
144 PythonExpression :: evaluate(FloatArray &answer, std :: map< std :: string, FunctionArgument > &valDict)
145 {
146  this->getArray(answer, this->f, valDict);
147 }
148 
149 
150 void
151 PythonExpression :: evaluateVelocity(FloatArray &answer, std :: map< std :: string, FunctionArgument > &valDict)
152 {
153  this->getArray(answer, this->dfdt, valDict);
154 }
155 
156 
157 void
158 PythonExpression :: evaluateAcceleration(FloatArray &answer, std :: map< std :: string, FunctionArgument > &valDict)
159 {
160  this->getArray(answer, this->d2fdt2, valDict);
161 }
162 
163 
164 double
166 {
167  PyObject *local_dict = PyDict_New();
168  PyDict_SetItemString( local_dict, "t", PyFloat_FromDouble(time) );
169  PyObject *dummy = PyEval_EvalCode( ( PyCodeObject * ) func, main_dict, local_dict );
170  double val = 0.;
171  PyObject *ret = PyDict_GetItemString(local_dict, RETURN_VARIABLE);
172  if ( PyFloat_Check(ret) ) {
173  val = PyFloat_AS_DOUBLE(ret);
174  } else if ( PyList_Check(ret) ) {
175  if ( PyList_GET_SIZE(ret) != 1 ) {
176  OOFEM_ERROR("Result from python is not a real float!");
177  } else {
178  val = PyFloat_AS_DOUBLE( PyList_GET_ITEM(ret, 0) );
179  }
180  } else {
181  OOFEM_ERROR("Result from python is not a real float!");
182  }
183 
184  Py_DECREF(local_dict);
185  Py_DECREF(dummy);
186  Py_DECREF(ret);
187  return val;
188 }
189 
190 
192 {
193  return this->getScalar(this->f, time);
194 }
195 
197 {
198  return this->getScalar(this->dfdt, time);
199 }
200 
201 
203 {
204  return this->getScalar(this->d2fdt2, time);
205 }
206 } // end namespace oofem
void setField(int item, InputFieldType id)
#define RETURN_VARIABLE
Class and object Domain.
Definition: domain.h:115
virtual double evaluateAccelerationAtTime(double t)
Returns the second time derivative of the function at given time.
_object PyObject
PythonExpression(int n, Domain *d)
Constructor.
std::string dfdtExpression
Expression for first time derivative.
double & at(int i)
Coefficient access function.
Definition: floatarray.h:131
virtual double evaluateAtTime(double t)
Returns the value of the function at given time.
virtual ~PythonExpression()
Destructor.
#define _IFT_PythonExpression_f
Expression with return variable named "ret".
REGISTER_Function(CalculatorFunction)
virtual void giveInputRecord(DynamicInputRecord &input)
Setups the input record string of receiver.
Definition: femcmpnn.C:77
int & at(int i)
Coefficient access function.
Definition: intarray.h:103
double getScalar(PyObject *func, double time)
Helper function to run given function for given time.
Wrapper for values of varying types.
Definition: function.h:60
PyObject * getDict(std::map< std::string, FunctionArgument > &valDict)
Helper function to convert the std::map to a Python dictionary.
std::string fExpression
Expression for the function value.
std::string d2fdt2Expression
Expression for second time derivative.
virtual void evaluateAcceleration(FloatArray &answer, std::map< std::string, FunctionArgument > &valDict)
virtual void evaluateVelocity(FloatArray &answer, std::map< std::string, FunctionArgument > &valDict)
virtual IRResultType initializeFrom(InputRecord *ir)
Reads the fields.
#define OOFEM_ERROR(...)
Definition: error.h:61
virtual void giveInputRecord(DynamicInputRecord &ir)
Setups the input record string of receiver.
virtual IRResultType initializeFrom(InputRecord *ir)
Initializes receiver according to object description stored in input record.
Definition: femcmpnn.C:89
void getArray(FloatArray &answer, PyObject *func, std::map< std::string, FunctionArgument > &valDict)
Helper function to run given function for given value dictionary.
virtual double evaluateVelocityAtTime(double t)
Returns the first time derivative of the function at given time.
FunctionArgumentType type
Determines which of the types the instance points towards.
Definition: function.h:71
Class representing vector of real numbers.
Definition: floatarray.h:82
virtual void evaluate(FloatArray &answer, std::map< std::string, FunctionArgument > &valDict)
Abstract base class representing a function with vector input and output.
Definition: function.h:88
IRResultType
Type defining the return values of InputRecord reading operations.
Definition: irresulttype.h:47
Class representing the general Input Record.
Definition: inputrecord.h:101
Class representing the a dynamic Input Record.
#define _IFT_PythonExpression_dfdt
Velocity with return variable named "ret".
#define IR_GIVE_OPTIONAL_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:78
int giveSize() const
Definition: intarray.h:203
int giveSize() const
Returns the size of receiver.
Definition: floatarray.h:218
the oofem namespace is to define a context or scope in which all oofem names are defined.
#define IR_GIVE_FIELD(__ir, __value, __id)
Macro facilitating the use of input record reading methods.
Definition: inputrecord.h:69
#define _IFT_PythonExpression_d2fdt2
Acceleration with return variable named "ret".
void resize(int s)
Resizes receiver towards requested size.
Definition: floatarray.C:631

This page is part of the OOFEM documentation. Copyright (c) 2011 Borek Patzak
Project e-mail: info@oofem.org
Generated at Tue Jan 2 2018 20:07:30 for OOFEM by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2011