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 : #include <iostream>
34 : #include <sstream>
35 : #include <string>
36 :
37 : // include bridge
38 : #include "bridge/bridge.h"
39 : #include "bridge/util.h"
40 :
41 : #include "lua_user_data.h"
42 :
43 : using namespace std;
44 :
45 : namespace ug
46 : {
47 :
48 :
49 : /// returns true if callback exists
50 0 : bool CheckLuaCallbackName(const char* name)
51 : {
52 : // get lua state
53 0 : lua_State* L = ug::script::GetDefaultLuaState();
54 :
55 : // obtain a reference
56 0 : lua_getglobal(L, name);
57 :
58 : // check if reference is valid
59 0 : if(lua_isnil(L, -1)) return false;
60 0 : else return true;
61 : }
62 :
63 :
64 0 : LuaUserNumberNumberFunction::LuaUserNumberNumberFunction()
65 : {
66 0 : m_L = ug::script::GetDefaultLuaState();
67 0 : m_callbackRef = LUA_NOREF;
68 0 : }
69 :
70 0 : void LuaUserNumberNumberFunction::set_lua_callback(const char* luaCallback)
71 : {
72 0 : m_callbackName = luaCallback;
73 : // store the callback function in the registry and obtain a reference.
74 0 : lua_getglobal(m_L, m_callbackName.c_str());
75 :
76 : // make sure that the reference is valid
77 0 : if(lua_isnil(m_L, -1)){
78 0 : UG_THROW("ERROR in LuaUserNumberNumberFunction::set_lua_callback(...):"
79 : "Specified callback does not exist: " << m_callbackName);
80 : }
81 :
82 0 : m_callbackRef = luaL_ref(m_L, LUA_REGISTRYINDEX);
83 0 : }
84 :
85 0 : number LuaUserNumberNumberFunction::operator() (int numArgs, ...) const
86 : {
87 : // push the callback function on the stack
88 0 : lua_rawgeti(m_L, LUA_REGISTRYINDEX, m_callbackRef);
89 :
90 : va_list ap;
91 0 : va_start(ap, numArgs);
92 :
93 0 : for(int i = 0; i < numArgs; ++i)
94 : {
95 0 : number val = va_arg(ap, number);
96 0 : lua_pushnumber(m_L, val);
97 : // UG_LOG("Push value i=" << i << ": " << val<<"\n");
98 : }
99 :
100 0 : va_end(ap);
101 :
102 :
103 0 : if(lua_pcall(m_L, numArgs, 1, 0) != 0)
104 : {
105 0 : UG_THROW("ERROR in 'LuaUserNumberNumberFunction::operator(...)': Error while "
106 : "running callback '" << m_callbackName << "',"
107 : " lua message: "<< lua_tostring(m_L, -1) << "\n");
108 : }
109 :
110 0 : number c = ReturnValueToNumber(m_L, -1);
111 0 : lua_pop(m_L, 1);
112 :
113 0 : return c;
114 : }
115 :
116 :
117 :
118 :
119 : namespace bridge{
120 : namespace LuaUserData{
121 :
122 :
123 : template <typename TData, int dim>
124 9 : void RegisterLuaUserDataType(Registry& reg, string type, string grp)
125 : {
126 9 : string suffix = GetDimensionSuffix<dim>();
127 9 : string tag = GetDimensionTag<dim>();
128 :
129 : // LuaUser"Type"
130 : {
131 : typedef ug::LuaUserData<TData, dim> T;
132 : typedef CplUserData<TData, dim> TBase;
133 9 : string name = string("LuaUser").append(type).append(suffix);
134 27 : reg.add_class_<T, TBase>(name, grp)
135 18 : .template add_constructor<void (*)(const char*)>("Callback")
136 18 : .template add_constructor<void (*)(LuaFunctionHandle)>("handle")
137 9 : .set_construct_as_smart_pointer(true);
138 36 : reg.add_class_to_group(name, string("LuaUser").append(type), tag);
139 : }
140 :
141 : // LuaCondUser"Type"
142 : {
143 : typedef ug::LuaUserData<TData, dim, bool> T;
144 : typedef CplUserData<TData, dim, bool> TBase;
145 9 : string name = string("LuaCondUser").append(type).append(suffix);
146 27 : reg.add_class_<T, TBase>(name, grp)
147 18 : .template add_constructor<void (*)(const char*)>("Callback")
148 18 : .template add_constructor<void (*)(LuaFunctionHandle)>("handle")
149 9 : .set_construct_as_smart_pointer(true);
150 36 : reg.add_class_to_group(name, string("LuaCondUser").append(type), tag);
151 : }
152 9 : }
153 :
154 : /**
155 : * Class exporting the functionality. All functionality that is to
156 : * be used in scripts or visualization must be registered here.
157 : */
158 : struct Functionality
159 : {
160 :
161 : /**
162 : * Function called for the registration of Dimension dependent parts.
163 : * All Functions and Classes depending on the Dimension
164 : * are to be placed here when registering. The method is called for all
165 : * available Dimension types, based on the current build options.
166 : *
167 : * @param reg registry
168 : * @param parentGroup group for sorting of functionality
169 : */
170 : template <int dim>
171 3 : static void Dimension(Registry& reg, string grp)
172 : {
173 3 : string suffix = GetDimensionSuffix<dim>();
174 3 : string tag = GetDimensionTag<dim>();
175 :
176 6 : RegisterLuaUserDataType<number, dim>(reg, "Number", grp);
177 6 : RegisterLuaUserDataType<MathVector<dim>, dim>(reg, "Vector", grp);
178 6 : RegisterLuaUserDataType<MathMatrix<dim,dim>, dim>(reg, "Matrix", grp);
179 :
180 : // LuaUserFunctionNumber
181 : {
182 : typedef LuaUserFunction<number, dim, number> T;
183 : typedef DependentUserData<number, dim> TBase;
184 3 : string name = string("LuaUserFunctionNumber").append(suffix);
185 9 : reg.add_class_<T, TBase>(name, grp)
186 6 : .template add_constructor<void (*)(const char*, int)>("LuaCallbackName#NumberOfArguments")
187 6 : .template add_constructor<void (*)(const char*, int, bool)>("LuaCallbackName#NumberOfArguments#PosTimeFlag")
188 6 : .template add_constructor<void (*)(LuaFunctionHandle, int)>("LuaCallbackName#NumberOfArguments")
189 6 : .template add_constructor<void (*)(LuaFunctionHandle, int, bool)>("LuaCallbackName#NumberOfArguments#PosTimeFlag")
190 6 : .add_method("set_deriv", static_cast<void (T::*)(size_t, const char*)>(&T::set_deriv))
191 6 : .add_method("set_deriv", static_cast<void (T::*)(size_t, LuaFunctionHandle)>(&T::set_deriv))
192 6 : .add_method("set_input", static_cast<void (T::*)(size_t, SmartPtr<CplUserData<number, dim> >)>(&T::set_input))
193 6 : .add_method("set_input", static_cast<void (T::*)(size_t, number)>(&T::set_input))
194 6 : .add_method("set_input_and_deriv", &T::set_input_and_deriv)
195 3 : .set_construct_as_smart_pointer(true);
196 9 : reg.add_class_to_group(name, "LuaUserFunctionNumber", tag);
197 : }
198 :
199 : // LuaUserFunctionMatrixNumber
200 : {
201 : typedef LuaUserFunction<MathMatrix<dim,dim>, dim, number> T;
202 : typedef DependentUserData<MathMatrix<dim,dim>, dim> TBase;
203 3 : string name = string("LuaUserFunctionMatrixNumber").append(suffix);
204 9 : reg.add_class_<T, TBase>(name, grp)
205 6 : .template add_constructor<void (*)(const char*, int)>("LuaCallbackName#NumberOfArguments")
206 6 : .template add_constructor<void (*)(const char*, int, bool)>("LuaCallbackName#NumberOfArguments#PosTimeFlag")
207 6 : .template add_constructor<void (*)(LuaFunctionHandle, int)>("LuaCallbackName#NumberOfArguments")
208 6 : .template add_constructor<void (*)(LuaFunctionHandle, int, bool)>("LuaCallbackName#NumberOfArguments#PosTimeFlag")
209 6 : .add_method("set_deriv", static_cast<void (T::*)(size_t, const char*)>(&T::set_deriv))
210 6 : .add_method("set_input", static_cast<void (T::*)(size_t, SmartPtr<CplUserData<number, dim> >)>(&T::set_input))
211 6 : .add_method("set_input", static_cast<void (T::*)(size_t, number)>(&T::set_input))
212 3 : .set_construct_as_smart_pointer(true);
213 9 : reg.add_class_to_group(name, "LuaUserFunctionMatrixNumber", tag);
214 : }
215 :
216 : // LuaUserFunctionVectorNumber
217 : {
218 : typedef LuaUserFunction<MathVector<dim>, dim, number > T;
219 : typedef DependentUserData<MathVector<dim>, dim> TBase;
220 3 : string name = string("LuaUserFunctionVectorNumber").append(suffix);
221 9 : reg.add_class_<T, TBase>(name, grp)
222 6 : .template add_constructor<void (*)(const char*, int)>("LuaCallbackName#NumberOfArguments")
223 6 : .template add_constructor<void (*)(const char*, int, bool)>("LuaCallbackName#NumberOfArguments#PosTimeFlag")
224 6 : .template add_constructor<void (*)(LuaFunctionHandle, int)>("LuaCallbackName#NumberOfArguments")
225 6 : .template add_constructor<void (*)(LuaFunctionHandle, int, bool)>("LuaCallbackName#NumberOfArguments#PosTimeFlag")
226 6 : .add_method("set_deriv", static_cast<void (T::*)(size_t, const char*)>(&T::set_deriv))
227 6 : .add_method("set_input", static_cast<void (T::*)(size_t, SmartPtr<CplUserData<number, dim> >)>(&T::set_input))
228 6 : .add_method("set_input", static_cast<void (T::*)(size_t, number)>(&T::set_input))
229 3 : .set_construct_as_smart_pointer(true);
230 9 : reg.add_class_to_group(name, "LuaUserFunctionVectorNumber", tag);
231 : }
232 : /*
233 : // LuaUserFunctionNumberVector
234 : {
235 : typedef LuaUserFunction<number, dim, MathVector<dim> > T;
236 : typedef DependentUserData<number, dim> TBase;
237 : string name = string("LuaUserFunctionNumberVector").append(suffix);
238 : reg.add_class_<T, TBase>(name, grp)
239 : .template add_constructor<void (*)(const char*, int)>("LuaCallbackName, NumberOfArguments")
240 : .template add_constructor<void (*)(const char*, int, bool)>("LuaCallbackName, NumberOfArguments, PosTimeFlag")
241 : .add_method("set_deriv", &T::set_deriv)
242 : .add_method("set_input", static_cast<void (T::*)(size_t, SmartPtr<CplUserData<number, dim> >)>(&T::set_input))
243 : .add_method("set_input", static_cast<void (T::*)(size_t, number)>(&T::set_input))
244 : .set_construct_as_smart_pointer(true);
245 : reg.add_class_to_group(name, "LuaUserFunctionNumberVector", tag);
246 : }
247 : */
248 3 : }
249 :
250 : /**
251 : * Function called for the registration of Domain and Algebra independent parts.
252 : * All Functions and Classes not depending on Domain and Algebra
253 : * are to be placed here when registering.
254 : *
255 : * @param reg registry
256 : * @param parentGroup group for sorting of functionality
257 : */
258 1 : static void Common(Registry& reg, string grp)
259 : {
260 :
261 : // LuaUserNumberNumberFunction
262 : {
263 : typedef LuaUserNumberNumberFunction T;
264 3 : reg.add_class_<T>("LuaUserNumberNumberFunction", grp)
265 1 : .add_constructor()
266 2 : .add_method("set_lua_callback", &T::set_lua_callback)
267 1 : .set_construct_as_smart_pointer(true);
268 : }
269 :
270 : // LuaFunctionNumber
271 : {
272 : typedef LuaFunction<number, number> T;
273 : typedef IFunction<number, number> TBase;
274 3 : reg.add_class_<T, TBase>("LuaFunctionNumber", grp)
275 1 : .add_constructor()
276 2 : .add_method("set_lua_callback", &T::set_lua_callback)
277 1 : .set_construct_as_smart_pointer(true);
278 : }
279 :
280 1 : } // Common
281 : }; // end Functionality
282 : }// end LuaUserData
283 :
284 1 : void RegisterLuaUserData(Registry& reg, string grp)
285 : {
286 : typedef LuaUserData::Functionality Functionality;
287 :
288 : try{
289 2 : RegisterCommon<Functionality>(reg,grp);
290 1 : RegisterDimensionDependent<Functionality>(reg,grp);
291 : }
292 0 : UG_REGISTRY_CATCH_THROW(grp);
293 1 : }
294 :
295 : }// namespace bridge
296 : }// namespace ug
|