Line data Source code
1 : /*
2 : * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Andreas Vogel
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 :
34 : #ifndef __H__UG_BRIDGE__BRIDGES__USER_DATA__USER_DATA__
35 : #define __H__UG_BRIDGE__BRIDGES__USER_DATA__USER_DATA__
36 :
37 : #include <stdarg.h>
38 : #include <string>
39 : #include "registry/registry.h"
40 :
41 :
42 :
43 :
44 : #ifndef USE_LUAJIT
45 : extern "C" {
46 : #include "externals/lua/lua.h"
47 : }
48 : #else
49 : #include <lua.hpp>
50 : #endif
51 :
52 :
53 :
54 : #include "lua_util.h"
55 :
56 : #include "common/common.h"
57 : #include "common/math/ugmath.h"
58 : #include "lib_disc/spatial_disc/user_data/user_data.h"
59 : #include "lib_disc/spatial_disc/user_data/std_glob_pos_data.h"
60 : #include "lib_disc/spatial_disc/user_data/user_function.h"
61 : #include "lib_disc/spatial_disc/user_data/linker/linker.h"
62 : #include "lua_traits.h"
63 :
64 : #include "bindings/lua/lua_function_handle.h"
65 :
66 : #ifdef USE_LUA2C
67 : #include "bindings/lua/compiler/lua_compiler.h"
68 : #endif
69 :
70 : namespace ug
71 : {
72 :
73 : ////////////////////////////////////////////////////////////////////////////////
74 : // LuaUserData
75 : ////////////////////////////////////////////////////////////////////////////////
76 :
77 : /// returns true if callback exists
78 : bool CheckLuaCallbackName(const char* name);
79 :
80 : // predeclaration
81 : template <typename TData, int dim, typename TRet = void>
82 : class LuaUserDataFactory;
83 :
84 : /// provides data specified in the lua script
85 : /**
86 : * This class implements the UserData interface to provide data at arbitrary
87 : * points. A Lua callback is used to evaluate the data.
88 : *
89 : * NOTE: If the LuaUserData has been created by the LuaUserDataFactory, then
90 : * the fromFactory flag is set to true internally and while deconstruction
91 : * of the instance LuaUserDataFactory::remove is called.
92 : */
93 : template <typename TData, int dim, typename TRet = void>
94 : class LuaUserData
95 : : public StdGlobPosData<LuaUserData<TData, dim, TRet>, TData, dim, TRet>
96 : {
97 : /// friend class
98 : friend class LuaUserDataFactory<TData, dim, TRet>;
99 :
100 : public:
101 : /// Constructor
102 : /**
103 : * Creates a LuaUserData that uses a Lua function to evaluate some data.
104 : * NOTE: The Lua callback function is called once with dummy parameters
105 : * in order to check the correct return values.
106 : *
107 : * @param luaCallback Name of Lua Callback Function
108 : */
109 : ///{
110 : LuaUserData(const char* luaCallback);
111 : LuaUserData(LuaFunctionHandle handle);
112 : ///}
113 :
114 : /// destructor: frees lua callback, unregisters from LuaUserDataFactory if used
115 : virtual ~LuaUserData();
116 :
117 : /// returns string of required callback signature
118 : static std::string signature();
119 :
120 : /// returns name of UserData
121 : static std::string name();
122 :
123 : /// returns true if callback has correct return values
124 : static bool check_callback_returns(const char* callName,
125 : const bool bThrow = false);
126 :
127 : /// returns true if callback has correct return values
128 : static bool check_callback_returns(LuaFunctionHandle handle,
129 : const bool bThrow = false);
130 :
131 : /// returns true if callback has correct return values
132 : static bool check_callback_returns(lua_State* L, int callbackRef, const char* callName,
133 : const bool bThrow = false);
134 :
135 : /// evaluates the data at a given point and time
136 : inline TRet evaluate(TData& D, const MathVector<dim>& x, number time, int si) const;
137 :
138 : protected:
139 : /// sets that LuaUserData is created by LuaUserDataFactory
140 0 : void set_created_from_factory(bool bFromFactory) {m_bFromFactory = bFromFactory;}
141 :
142 : protected:
143 : /// callback name as string
144 : std::string m_callbackName;
145 :
146 : /// reference to lua function
147 : int m_callbackRef;
148 :
149 : #ifdef USE_LUA2C
150 : /// LUACompiler type for compiled LUA code
151 : bridge::LUACompiler m_luaComp;
152 : #endif
153 : /// flag, indicating if created from factory
154 : bool m_bFromFactory;
155 :
156 : /// lua state
157 : lua_State* m_L;
158 : };
159 :
160 : ////////////////////////////////////////////////////////////////////////////////
161 : // LuaUserDataFactory
162 : ////////////////////////////////////////////////////////////////////////////////
163 :
164 : /// Factory providing LuaUserData
165 : /**
166 : * This class is a singleton providing LuaUserData for a given callback name.
167 : * The factory creates a new LuaUserData and returns it as a SmartPtr if no
168 : * Data has been created with the same callback name before. It already a
169 : * LuaUserData using the same callback exists, then a SmartPtr to that instance
170 : * is returned. Internally, therefore plain pointers and reference counters
171 : * of the created SmartPtrs are stored and LuaUserData unregister from the
172 : * List of created LuaUserData in this factory when their destructor is called.
173 : *
174 : * \tparam TData Data produced by LuaUserData
175 : * \tparam dim world dimension
176 : * \tparam TRet bool flag or void
177 : */
178 : template <typename TData, int dim, typename TRet>
179 : class LuaUserDataFactory
180 : {
181 : friend class LuaUserData<TData,dim,TRet>;
182 :
183 : protected:
184 : /// private constructor, since singleton
185 : LuaUserDataFactory(){};
186 :
187 : // disallow copy
188 : LuaUserDataFactory(const LuaUserDataFactory&);
189 : LuaUserDataFactory& operator=(const LuaUserDataFactory&);
190 :
191 : /// singleton provider
192 0 : static LuaUserDataFactory<TData,dim,TRet>& instance()
193 : {
194 0 : static LuaUserDataFactory<TData,dim,TRet> inst;
195 0 : return inst;
196 : }
197 :
198 : /// returns new Data if not already created, already existing else
199 : static SmartPtr<LuaUserData<TData,dim,TRet> > provide_or_create(
200 : const std::string& name);
201 :
202 : /// removes the user data
203 : static void remove(const std::string& name);
204 :
205 : /// storage of already created data
206 : static std::map<std::string, std::pair<LuaUserData<TData,dim,TRet>*, int*> > m_mData;
207 :
208 : public:
209 : /**
210 : * Returns a LuaUserDataas a SmartPtr for a callback name. If a LuaUserData has
211 : * already been created by the factory it simply returns a new SmartPtr
212 : * without creation, else the LuaUserData is created. All LuaUserData
213 : * store internally, if they have been created by a factory, and if so
214 : * they unregister from the factory when their destructor is called.
215 : *
216 : * NOTE: In order to allow any garbage collection of the LuaUserData,
217 : * therefore this factory can not store the LuaUserData as a SmartPtr, but
218 : * as a plain pointer together with the reference counter.
219 : *
220 : * @param name lua callback name
221 : * @return LuaUserNumber as SmartPtr
222 : */
223 0 : static SmartPtr<LuaUserData<TData,dim,TRet> > create(const std::string& name)
224 : {
225 0 : return instance().provide_or_create(name);
226 : }
227 : };
228 :
229 : ////////////////////////////////////////////////////////////////////////////////
230 : // LuaUserFunction
231 : ////////////////////////////////////////////////////////////////////////////////
232 :
233 : /// maps several data values to an output data value using a lua callback
234 : /**
235 : * This class provides the evaluation of a user function, that is specified
236 : * in the script. Several data (of the same c++-type) can be used as input,
237 : * a data (of the same type) is returned.
238 : */
239 : template <typename TData, int dim, typename TDataIn>
240 : class LuaUserFunction
241 : : public StdDataLinker<LuaUserFunction<TData, dim, TDataIn>, TData, dim>
242 : {
243 : public:
244 : // type of base class
245 : typedef StdDataLinker<LuaUserFunction<TData, dim, TDataIn>, TData, dim> base_type;
246 : using base_type::set_input;
247 :
248 : public:
249 : /**
250 : * \brief constructor
251 : * \param luaCallback name of the Lua function to use as callback
252 : * \param numArgs number of arguments of the Lua callback
253 : * \{
254 : */
255 : LuaUserFunction(const char* luaCallback, size_t numArgs);
256 : LuaUserFunction(const char* luaCallback, size_t numArgs, bool bPosTimeNeed);
257 : LuaUserFunction(LuaFunctionHandle handle, size_t numArgs);
258 : LuaUserFunction(LuaFunctionHandle handle, size_t numArgs, bool bPosTimeNeed);
259 : /// \}
260 :
261 : /// destructor frees the reference
262 : virtual ~LuaUserFunction();
263 :
264 : /**
265 : * \brief sets the Lua function used to compute the derivative
266 : * \param arg this is the derivative with respect to the parameter index \c arg
267 : * \param luaCallback name of the Lua function to use as callback
268 : */
269 : void set_deriv(size_t arg, const char* luaCallback);
270 : void set_deriv(size_t arg, LuaFunctionHandle handle);
271 :
272 :
273 : /// set number of needed inputs
274 : void set_num_input(size_t num);
275 :
276 : /**
277 : * \brief set input value for paramter \c i
278 : * \param i parameter index this input is bind to
279 : * \{
280 : */
281 : void set_input(size_t i, SmartPtr<CplUserData<TDataIn, dim> > data);
282 : void set_input(size_t i, number val);
283 : /// \}
284 :
285 0 : void set_input_and_deriv(size_t i, SmartPtr<CplUserData<TDataIn, dim> > input, LuaFunctionHandle deriv)
286 0 : { set_input(i, input); set_deriv(i, deriv); }
287 :
288 : /// evaluates the data
289 : virtual void operator() (TData& out, int numArgs, ...) const;
290 :
291 : inline void evaluate (TData& value,
292 : const MathVector<dim>& globIP,
293 : number time, int si) const;
294 :
295 : template <int refDim>
296 : inline void evaluate(TData vValue[],
297 : const MathVector<dim> vGlobIP[],
298 : number time, int si,
299 : GridObject* elem,
300 : const MathVector<dim> vCornerCoords[],
301 : const MathVector<refDim> vLocIP[],
302 : const size_t nip,
303 : LocalVector* u,
304 : const MathMatrix<refDim, dim>* vJT = NULL) const;
305 :
306 : template <int refDim>
307 : void eval_and_deriv(TData vValue[],
308 : const MathVector<dim> vGlobIP[],
309 : number time, int si,
310 : GridObject* elem,
311 : const MathVector<dim> vCornerCoords[],
312 : const MathVector<refDim> vLocIP[],
313 : const size_t nip,
314 : LocalVector* u,
315 : bool bDeriv,
316 : int s,
317 : std::vector<std::vector<TData> > vvvDeriv[],
318 : const MathMatrix<refDim, dim>* vJT = NULL);
319 :
320 : protected:
321 : /// sets the Lua function used to compute the data
322 : void set_lua_value_callback(const char* luaCallback, size_t numArgs);
323 : void set_lua_value_callback(LuaFunctionHandle handle, size_t numArgs);
324 :
325 : /// frees the callback-reference, if a callback was set.
326 : void free_callback_ref();
327 :
328 : /// frees callback-references for derivate callbacks
329 : void free_deriv_callback_ref(size_t arg);
330 :
331 : /// evaluates the data at a given point and time
332 : void eval_value(TData& out, const std::vector<TDataIn>& dataIn,
333 : const MathVector<dim>& x, number time, int si) const;
334 :
335 : /// evaluates the data at a given point and time
336 : void eval_deriv(TData& out, const std::vector<TDataIn>& dataIn,
337 : const MathVector<dim>& x, number time, int si, size_t arg) const;
338 :
339 : protected:
340 : /// callback name as string
341 : std::string m_cbValueName;
342 : std::vector<std::string> m_cbDerivName;
343 :
344 : /// reference to lua function
345 : int m_cbValueRef;
346 : std::vector<int> m_cbDerivRef;
347 :
348 : /// lua state
349 : lua_State* m_L;
350 :
351 : /// number of arguments to use
352 : size_t m_numArgs;
353 :
354 : /// flag for position and time data
355 : bool m_bPosTimeNeed;
356 :
357 : /// LUACompiler types for compiled LUA code
358 : #ifdef USE_LUA2C
359 : bridge::LUACompiler m_luaComp;
360 : std::vector<bridge::LUACompiler > m_luaComp_Deriv;
361 : #endif
362 :
363 : protected:
364 : /// data input
365 : std::vector<SmartPtr<CplUserData<TDataIn, dim> > > m_vpUserData;
366 :
367 : /// data input casted to dependend data
368 : std::vector<SmartPtr<DependentUserData<TDataIn, dim> > > m_vpDependData;
369 :
370 : };
371 :
372 :
373 : /// this class maps a scalar value an output scalar value using a lua callback
374 0 : class LuaUserNumberNumberFunction
375 : {
376 : public:
377 : LuaUserNumberNumberFunction();
378 :
379 : void set_lua_callback(const char* luaCallback);
380 :
381 : number operator() ( int numArgs, ... ) const;
382 :
383 : protected:
384 : std::string m_callbackName;
385 : int m_callbackRef;
386 : lua_State* m_L;
387 : };
388 :
389 :
390 : ////////////////////////////////////////////////////////////////////////////////
391 : // LuaFunction
392 : ////////////////////////////////////////////////////////////////////////////////
393 :
394 : /**
395 : * \tparam TData Return value type
396 : * \tparam TDataIn Input daten type
397 : */
398 : template <typename TData, typename TDataIn>
399 : class LuaFunction : public IFunction<TData, TDataIn>
400 : {
401 : public:
402 : /// constructor
403 : LuaFunction();
404 0 : virtual ~LuaFunction() {};
405 :
406 : /// sets the Lua function used to compute the data
407 : /**
408 : * This function sets the lua callback. The name of the function is
409 : * passed as a string. Make sure, that the function name is defined
410 : * when executing the script.
411 : */
412 : void set_lua_callback(const char* luaCallback, size_t numArgs);
413 :
414 : /// evaluates the data
415 : virtual void operator() (TData& out, int numArgs, ...);
416 :
417 : protected:
418 : /// callback name as string
419 : std::string m_cbValueName;
420 :
421 : /// reference to lua function
422 : int m_cbValueRef;
423 :
424 : /// lua state
425 : lua_State* m_L;
426 :
427 : /// number of arguments to use
428 : size_t m_numArgs;
429 : };
430 :
431 :
432 :
433 : namespace bridge{
434 :
435 : void RegisterLuaUserData(Registry& reg, std::string grp);
436 :
437 : } // end namepace bridge
438 : } // end namespace ug
439 :
440 : #include "lua_user_data_impl.h"
441 :
442 : #endif /* __H__UG_BRIDGE__BRIDGES__USER_DATA__USER_DATA__ */
|