1 // SWIG file PointToFieldFunction.i 2 3 %{ 4 #include "openturns/PointToFieldFunction.hxx" 5 #include "openturns/PythonPointToFieldFunction.hxx" 6 7 namespace OT { 8 9 template <> 10 struct traitsPythonType< OT::PointToFieldFunction > 11 { 12 typedef _PyObject_ Type; 13 }; 14 15 template <> 16 inline 17 bool 18 canConvert< _PyObject_, OT::PointToFieldFunction >(PyObject * pyObj) 19 { 20 void * ptr = 0; 21 if (SWIG_IsOK(SWIG_ConvertPtr(pyObj, &ptr, SWIGTYPE_p_OT__PointToFieldFunction, SWIG_POINTER_NO_NULL))) { 22 OT::PointToFieldFunction * p_nmf = reinterpret_cast< OT::PointToFieldFunction * >(ptr); 23 return p_nmf != NULL; 24 } else if (SWIG_IsOK(SWIG_ConvertPtr(pyObj, &ptr, SWIGTYPE_p_OT__PointToFieldFunctionImplementation, SWIG_POINTER_NO_NULL))) { 25 OT::PointToFieldFunctionImplementation * p_impl = reinterpret_cast< OT::PointToFieldFunctionImplementation * >(ptr); 26 return p_impl != NULL; 27 } else { 28 return PyCallable_Check(pyObj); 29 } 30 } 31 32 template <> 33 inline 34 OT::PointToFieldFunction 35 convert< _PyObject_, OT::PointToFieldFunction >(PyObject * pyObj) 36 { 37 void * ptr = 0; 38 if ( SWIG_IsOK(SWIG_ConvertPtr(pyObj, &ptr, SWIGTYPE_p_OT__PointToFieldFunction, SWIG_POINTER_NO_NULL))) { 39 OT::PointToFieldFunction * p_nmf = reinterpret_cast< OT::PointToFieldFunction * >(ptr); 40 return *p_nmf; 41 } else if ( SWIG_IsOK(SWIG_ConvertPtr(pyObj, &ptr, SWIGTYPE_p_OT__PointToFieldFunctionImplementation, SWIG_POINTER_NO_NULL))) { 42 OT::PointToFieldFunctionImplementation * p_impl = reinterpret_cast< OT::PointToFieldFunctionImplementation * >(ptr); 43 return *p_impl; 44 } else if (!PyCallable_Check(pyObj)) { 45 throw OT::InvalidArgumentException(HERE) << "Argument is not a callable object (function or class) - can not be convertible to a PointToFieldFunction"; 46 } 47 OT::PointToFieldFunction pythonFunction(new OT::PythonPointToFieldFunction(pyObj)); 48 return pythonFunction; 49 } 50 51 } /* namespace OT */ 52 53 %} 54 55 %include PointToFieldFunction_doc.i 56 57 OTTypedInterfaceObjectHelper(PointToFieldFunction) 58 59 %include openturns/PointToFieldFunction.hxx 60 61 namespace OT { 62 %extend PointToFieldFunction { 63 64 PointToFieldFunction(PyObject * pyObj) 65 { 66 void * ptr = 0; 67 if (SWIG_IsOK(SWIG_ConvertPtr(pyObj, &ptr, SWIGTYPE_p_OT__Object, 0))) 68 { 69 throw OT::InvalidArgumentException(HERE) << "Argument should be a pure python object"; 70 } 71 return new OT::PointToFieldFunction(OT::convert<OT::_PyObject_, OT::PointToFieldFunction>(pyObj)); 72 } 73 74 PointToFieldFunction(const PointToFieldFunction & other) { return new OT::PointToFieldFunction( other ); } 75 76 }} 77 78 %pythoncode %{ 79 # We have to make sure the submodule is loaded with absolute path 80 import openturns.typ 81 82 class OpenTURNSPythonPointToFieldFunction(object): 83 """ 84 Override PointToFieldFunction from Python. 85 86 Parameters 87 ---------- 88 inputDim : positive int 89 Dimension of the input vector d 90 outputMesh : :class:`~openturns.Mesh` 91 The output mesh 92 outputDim : positive int 93 Dimension of the output field values d' 94 95 Notes 96 ----- 97 You have to overload the function: 98 _exec(X): single evaluation, X is a :class:`~openturns.Field`, 99 returns a :class:`~openturns.Field` 100 101 Examples 102 -------- 103 >>> import openturns as ot 104 >>> class FUNC(ot.OpenTURNSPythonPointToFieldFunction): 105 ... def __init__(self): 106 ... mesh = ot.RegularGrid(0.0, 0.1, 11) 107 ... super(FUNC, self).__init__(2, mesh, 2) 108 ... self.setInputDescription(['R', 'S']) 109 ... self.setOutputDescription(['T', 'U']) 110 ... def _exec(self, X): 111 ... size = self.getOutputMesh().getVerticesNumber() 112 ... Y = [ot.Point(X)*i for i in range(size)] 113 ... return Y 114 >>> F = FUNC() 115 """ 116 def __init__(self, inputDim, outputMesh, outputDim): 117 try: 118 self.__inputDim = int(inputDim) 119 except: 120 raise TypeError('inputDim argument is not an integer.') 121 if not isinstance(outputMesh, openturns.geom.Mesh): 122 raise TypeError('outputMesh argument is not a Mesh.') 123 self.__outputMesh = outputMesh 124 try: 125 self.__outputDim = int(outputDim) 126 except: 127 raise TypeError('outputDim argument is not an integer.') 128 self.__descIn = ['x' + str(i) for i in range(inputDim)] 129 self.__descOut = ['y' + str(i) for i in range(outputDim)] 130 131 def setInputDescription(self, descIn): 132 if (len(descIn) != self.__inputDim): 133 raise ValueError('Input description size does NOT match input dimension') 134 self.__descIn = descIn 135 136 def getInputDescription(self): 137 return self.__descIn 138 139 def setOutputDescription(self, descOut): 140 if (len(descOut) != self.__outputDim): 141 raise ValueError('Output description size does NOT match output dimension') 142 self.__descOut = descOut 143 144 def getOutputDescription(self): 145 return self.__descOut 146 147 def getInputDimension(self): 148 return self.__inputDim 149 150 def getOutputDimension(self): 151 return self.__outputDim 152 153 def getOutputMesh(self): 154 return self.__outputMesh 155 156 def __str__(self): 157 return 'OpenTURNSPythonPointToFieldFunction( %s #%d ) -> %s #%d' % (self.__descIn, self.__inputDim, self.__descOut, self.__outputDim) 158 159 def __repr__(self): 160 return self.__str__() 161 162 def __call__(self, X): 163 Y = None 164 try: 165 pt = openturns.typ.Point(X) 166 except: 167 try: 168 sp = openturns.typ.Sample(X) 169 except: 170 raise TypeError('Expect a Point or a Sample as argument') 171 else: 172 Y = self._exec_sample(sp) 173 else: 174 Y = self._exec(pt) 175 return Y 176 177 def _exec(self, X): 178 raise RuntimeError('You must define a method _exec(X) -> Y, where X is a Point object and Y a Field object') 179 180 def _exec_sample(self, X): 181 res = ProcessSample(self.getOutputMesh(), 0, self.getOutputDimension()) 182 for i in range(len(X)): 183 res.add(self._exec(X[i])) 184 return res 185 186 def _exec_point_on_exec_sample(self, X): 187 """Implement exec from exec_sample.""" 188 return self._exec_sample([X])[0] 189 190 class PythonPointToFieldFunction(PointToFieldFunction): 191 """ 192 Override PointToFieldFunction from Python. 193 194 Parameters 195 ---------- 196 inputDim : positive int 197 Dimension of the input vector d 198 outputMesh : :class:`~openturns.Mesh` 199 The output mesh 200 outputDim : positive int 201 Dimension of the output field values d' 202 func : a callable python object 203 called on a :class:`~openturns.Field` object. 204 Returns a :class:`~openturns.Field`. 205 Default is None. 206 207 Examples 208 -------- 209 >>> import openturns as ot 210 >>> mesh = ot.RegularGrid(0.0, 0.1, 11) 211 >>> def myPyFunc(X): 212 ... size = 11 213 ... Y = [ot.Point(X)*i for i in range(size)] 214 ... return Y 215 >>> inputDim = 2 216 >>> outputDim = 2 217 >>> myFunc = ot.PythonPointToFieldFunction(inputDim, mesh, outputDim, myPyFunc) 218 219 Evaluation on a vector: 220 221 >>> Yfield = myFunc([1.1, 2.2]) 222 """ 223 def __new__(self, inputDim, outputMesh, outputDim, func=None): 224 if func is None: 225 raise RuntimeError('func not provided.') 226 instance = OpenTURNSPythonPointToFieldFunction(inputDim, outputMesh, outputDim) 227 if func is not None: 228 if not callable(func): 229 raise RuntimeError('func argument is not callable.') 230 instance._exec = func 231 return PointToFieldFunction(instance) 232 233 234 %} 235