Line data Source code
1 : /*
2 : * SPDX-FileCopyrightText: Copyright (c) 2014-2025: G-CSC, Goethe University Frankfurt
3 : * SPDX-License-Identifier: LicenseRef-UG4-LGPL-3.0
4 : *
5 : * Author: Arne Naegel, Andreas Kreienbuehl
6 : *
7 : * This file is part of UG4.
8 : *
9 : * UG4 is free software: you can redistribute it and/or modify it under the
10 : * terms of the GNU Lesser General Public License version 3 (as published by the
11 : * Free Software Foundation) with the following additional attribution
12 : * requirements (according to LGPL/GPL v3 §7):
13 : *
14 : * (1) The following notice must be displayed in the Appropriate Legal Notices
15 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
16 : *
17 : * (2) The following notice must be displayed at a prominent place in the
18 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
19 : *
20 : * (3) The following bibliography is recommended for citation and must be
21 : * preserved in all covered files:
22 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
23 : * parallel geometric multigrid solver on hierarchically distributed grids.
24 : * Computing and visualization in science 16, 4 (2013), 151-164"
25 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
26 : * flexible software system for simulating pde based models on high performance
27 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
28 : *
29 : * This program is distributed in the hope that it will be useful,
30 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 : * GNU Lesser General Public License for more details.
33 : */
34 :
35 : #ifndef __H__LIMEX__AUX_OUTPUT_OBSERVER_HPP__
36 : #define __H__LIMEX__AUX_OUTPUT_OBSERVER_HPP__
37 :
38 : #include "lib_disc/time_disc/time_integrator_observers/time_integrator_observer_interface.h"
39 : #include "lib_disc/io/vtkoutput.h"
40 :
41 : namespace ug {
42 :
43 : #if 0
44 : template <typename TData, typename TDataIn1, typename TDataIn2>
45 : class LuaFunction2 // : public IFunction<TData, TDataIn1, typename TDataIn2>
46 : {
47 : public:
48 : /// constructor
49 : LuaFunction2();
50 : virtual ~LuaFunction2() {};
51 :
52 : /// sets the Lua function used to compute the data
53 : /**
54 : * This function sets the lua callback. The name of the function is
55 : * passed as a string. Make sure, that the function name is defined
56 : * when executing the script.
57 : */
58 : void set_lua_callback(const char* luaCallback, size_t numArgs);
59 :
60 : /// evaluates the data
61 : virtual void operator() (TData& out, int numArgs1, int numArgs2,...);
62 :
63 : protected:
64 : /// callback name as string
65 : std::string m_cbValueName;
66 :
67 : /// reference to lua function
68 : int m_cbValueRef;
69 :
70 : /// lua state
71 : lua_State* m_L;
72 :
73 : /// number of arguments to use
74 : size_t m_numArgs;
75 : };
76 :
77 :
78 : template <typename TData, typename TDataIn1, typename TDataIn2>
79 : LuaFunction2<TData,TDataIn1,TDataIn2>::LuaFunction2() : m_numArgs(0)
80 : {
81 : m_L = ug::script::GetDefaultLuaState();
82 : m_cbValueRef = LUA_NOREF;
83 : }
84 :
85 : template <typename TData, typename TDataIn1, typename TDataIn2>
86 : void LuaFunction2<TData,TDataIn1,TDataIn2>::set_lua_callback(const char* luaCallback, size_t numArgs)
87 : {
88 : // store name (string) of callback
89 : m_cbValueName = luaCallback;
90 :
91 : // obtain a reference
92 : lua_getglobal(m_L, m_cbValueName.c_str());
93 :
94 : // make sure that the reference is valid
95 : if(lua_isnil(m_L, -1)){
96 : UG_THROW("LuaFunction::set_lua_callback(...):"
97 : "Specified lua callback does not exist: " << m_cbValueName);
98 : }
99 :
100 : // store reference to lua function
101 : m_cbValueRef = luaL_ref(m_L, LUA_REGISTRYINDEX);
102 :
103 : // remember number of arguments to be used
104 : m_numArgs = numArgs;
105 : }
106 : #endif
107 :
108 : /*
109 : SmartUserDataWrapper* CreateNewUserData(lua_State* L, const SmartPtr<void>& ptr,
110 : const char* metatableName)
111 : {
112 : // create the userdata
113 : SmartUserDataWrapper* udata = (SmartUserDataWrapper*)lua_newuserdata(L,
114 : sizeof(SmartUserDataWrapper));
115 : new(udata) SmartUserDataWrapper;
116 :
117 : // associate the object with the userdata.
118 : udata->smartPtr = ptr;
119 : udata->type = SMART_POINTER;
120 :
121 : // associate the metatable (userdata is already on the stack)
122 : luaL_getmetatable(L, metatableName);
123 : lua_setmetatable(L, -2);
124 :
125 : return udata;
126 : }
127 : */
128 : /*
129 : template <typename TData, typename TDataIn1, typename TDataIn2>
130 : void LuaFunction2<TData,TDataIn1,TDataIn2>::operator() (TData& out, int numArgs1, SmartPtr<TDataIn1> valsArgs1[],
131 : int numArgs2, ...)
132 : {
133 : PROFILE_CALLBACK_BEGIN(operatorBracket);
134 :
135 : UG_ASSERT((numArgs1+numArgs2) == (int)m_numArgs, "Number of arguments mismatched.");
136 :
137 : // push the callback function on the stack
138 : lua_rawgeti(m_L, LUA_REGISTRYINDEX, m_cbValueRef);
139 :
140 : // get list of arguments
141 : va_list ap;
142 : va_start(ap, numArgs2);
143 :
144 : // read all arguments and push them to the lua stack
145 : for(int i = 0; i < numArgs1; ++i)
146 : {
147 :
148 : CreateNewUserData(m_L, &valArgs1[i], "");
149 :
150 : }
151 : for(int i = 0; i < numArgs2; ++i)
152 : {
153 : TDataIn2 val = va_arg(ap, TDataIn2);
154 : lua_traits<TDataIn2>::push(m_L, val);
155 : }
156 :
157 :
158 : // end read in of parameters
159 : va_end(ap);
160 :
161 : // compute total args size
162 : size_t argSize = lua_traits<TDataIn1>::size * numArgs1;
163 : argSize += lua_traits<TDataIn2>::size * numArgs2;
164 :
165 : // compute total return size
166 : size_t retSize = lua_traits<TData>::size;
167 :
168 : // call lua function
169 : if(lua_pcall(m_L, argSize, retSize, 0) != 0)
170 : UG_THROW("LuaFunction::operator(...): Error while "
171 : "running callback '" << m_cbValueName << "',"
172 : " lua message: "<< lua_tostring(m_L, -1));
173 :
174 : try{
175 : // read return value
176 : lua_traits<TData>::read(m_L, out);
177 : UG_COND_THROW(IsFiniteAndNotTooBig(out)==false, out);
178 : }
179 : UG_CATCH_THROW("LuaFunction::operator(...): Error while running "
180 : "callback '" << m_cbValueName << "'");
181 :
182 : // pop values
183 : lua_pop(m_L, retSize);
184 :
185 : PROFILE_CALLBACK_END();
186 : }
187 : */
188 :
189 : template<class TDomain, class TAlgebra>
190 : class PlotRefOutputObserver
191 : : public ITimeIntegratorObserver<TDomain, TAlgebra>
192 : {
193 : public:
194 : typedef ITimeIntegratorObserver<TDomain, TAlgebra> base_type;
195 : typedef GridFunction<TDomain, TAlgebra> grid_function_type;
196 : typedef VTKOutput<TDomain::dim> vtk_type;
197 :
198 : PlotRefOutputObserver(SmartPtr<UserData<number, grid_function_type::dim> > spExactSol)
199 : { m_spReference = spExactSol; }
200 :
201 : #ifdef UG_FOR_LUA
202 0 : PlotRefOutputObserver(const char *ExactSol)
203 0 : : m_sp_vtk(SPNULL)
204 0 : { m_spReference = make_sp(new LuaUserData<number, grid_function_type::dim>(ExactSol)); }
205 :
206 0 : PlotRefOutputObserver(const char *ExactSol, SmartPtr<vtk_type> vtk)
207 0 : : m_sp_vtk(vtk)
208 0 : { m_spReference = make_sp(new LuaUserData<number, grid_function_type::dim>(ExactSol)); }
209 :
210 : #endif
211 :
212 0 : virtual ~PlotRefOutputObserver()
213 0 : {}
214 :
215 : // TODO: replace by call 'func (SmartPtr<G> u, int step, number dt, number t)'
216 0 : bool step_process(SmartPtr<grid_function_type> uNew, /* SmartPtr<grid_function_type> uOld, */ int step, number time, number dt) OVERRIDE
217 : {
218 0 : UG_LOG("L2Error(\t"<< time << "\t) = \t" << L2Error(m_spReference, uNew, "c", time, 4) << std::endl);
219 0 : if (m_sp_vtk.valid())
220 : {
221 0 : SmartPtr<grid_function_type> ref = uNew->clone();
222 0 : Interpolate<grid_function_type> (m_spReference, ref, "c", time);
223 : m_sp_vtk->print("MyReference", *ref, step, time);
224 : return true;
225 : }
226 :
227 : return false;
228 :
229 : }
230 :
231 : protected:
232 : // TODO: replace by appropriate call-back
233 : SmartPtr<UserData<number, grid_function_type::dim> > m_spReference;
234 : SmartPtr<vtk_type> m_sp_vtk;
235 : };
236 :
237 : /// Integration observer: Output using Lua callback
238 : /**!
239 : * TODO: should be replaced by LUA observer!
240 : */
241 : template<class TDomain, class TAlgebra>
242 : class IntegrationOutputObserver
243 : : public ITimeIntegratorObserver<TDomain, TAlgebra>
244 : {
245 : public:
246 : typedef ITimeIntegratorObserver<TDomain, TAlgebra> base_type;
247 : typedef GridFunction<TDomain, TAlgebra> grid_function_type;
248 : typedef VTKOutput<TDomain::dim> vtk_type;
249 : protected:
250 : struct IntegralSpecs
251 : {
252 0 : IntegralSpecs(const char* cmp, const char* subsets, int quadOrder, const char *idString) :
253 0 : m_cmp(cmp), m_subsets(subsets), m_quadOrder(quadOrder), m_idString(idString)
254 0 : {};
255 : std::string m_cmp;
256 : std::string m_subsets;
257 : int m_quadOrder;
258 : std::string m_idString;
259 : };
260 :
261 : public:
262 0 : IntegrationOutputObserver() : m_vIntegralData()
263 : {}
264 :
265 0 : virtual ~IntegrationOutputObserver()
266 0 : {}
267 :
268 : // TODO: replace by call 'func (SmartPtr<G> u, int step, number dt, number t)'
269 0 : bool step_process(SmartPtr<grid_function_type> uNew, /*SmartPtr<grid_function_type> uOld,*/ int step, number time, number dt) OVERRIDE
270 : {
271 :
272 0 : for (typename std::vector<IntegralSpecs>::iterator it = m_vIntegralData.begin();
273 0 : it!=m_vIntegralData.end(); ++it)
274 : {
275 0 : number value=Integral(uNew, it->m_cmp.c_str(), it->m_subsets.c_str(), it->m_quadOrder);
276 : UG_LOG("Integral(\t"<< it->m_idString << "\t"<< time << "\t)=\t" << value << std::endl);
277 : }
278 :
279 0 : return true;
280 :
281 :
282 : }
283 :
284 :
285 0 : void add_integral_specs(const char* cmp, const char* subsets, int quadOrder, const char* idString)
286 : {
287 0 : m_vIntegralData.push_back(IntegralSpecs(cmp, subsets, quadOrder, idString));
288 0 : }
289 :
290 : protected:
291 :
292 : std::vector<IntegralSpecs> m_vIntegralData;
293 : //const char* cmp,
294 : // const char* subsets,
295 : // int quadOrder
296 : };
297 :
298 : } // namespace ug
299 :
300 : #endif /* __H__LIMEX__AUX_OUTPUT_OBSERVER_HPP__ */
|