From ba81ed72fd5ef7da1853307177784167c27da5d3 Mon Sep 17 00:00:00 2001 From: Nicolas Marsic <marsic@temf.tu-darmstadt.de> Date: Sun, 15 Nov 2020 17:38:38 +0100 Subject: [PATCH] Integrand and Dof/Test fully with C API --- lua/CMakeLists.txt | 5 +++ lua/LuaDof.cpp | 55 ++++++++++++++++++++++++++ lua/LuaDof.h | 21 ++++++++++ lua/LuaDofTest.cpp | 90 ++++++++++++++++++++++++++++++++++++++++++ lua/LuaDofTest.h | 26 ++++++++++++ lua/LuaFormulation.cpp | 49 ++++++----------------- lua/LuaFormulation.h | 3 -- lua/LuaIntegrand.cpp | 77 ++++++++++++++++++++++++++++++++++++ lua/LuaIntegrand.h | 25 ++++++++++++ lua/LuaTest.cpp | 55 ++++++++++++++++++++++++++ lua/LuaTest.h | 21 ++++++++++ 11 files changed, 386 insertions(+), 41 deletions(-) create mode 100644 lua/LuaDof.cpp create mode 100644 lua/LuaDof.h create mode 100644 lua/LuaDofTest.cpp create mode 100644 lua/LuaDofTest.h create mode 100644 lua/LuaIntegrand.cpp create mode 100644 lua/LuaIntegrand.h create mode 100644 lua/LuaTest.cpp create mode 100644 lua/LuaTest.h diff --git a/lua/CMakeLists.txt b/lua/CMakeLists.txt index 75a083ee..cbf1abc6 100644 --- a/lua/CMakeLists.txt +++ b/lua/CMakeLists.txt @@ -4,6 +4,11 @@ set(src LuaMesh.cpp LuaGroupOfElement.cpp LuaFunctionSpace.cpp + + LuaDofTest.cpp + LuaDof.cpp + LuaTest.cpp + LuaIntegrand.cpp LuaFormulation.cpp LuaSystem.cpp ) diff --git a/lua/LuaDof.cpp b/lua/LuaDof.cpp new file mode 100644 index 00000000..b471210c --- /dev/null +++ b/lua/LuaDof.cpp @@ -0,0 +1,55 @@ +#include "LuaDof.h" + +#ifdef HAVE_LUA + +extern "C"{ +#include "lauxlib.h" +} + +using namespace sf; +using namespace std; + + +const struct luaL_Reg libsf_Dof_f[] = { + {"Dof", lua_Dof_new}, + {NULL, NULL} +}; + +const struct luaL_Reg libsf_Dof_m[] = { + {"__mul", lua_Dof_associate}, + {"__tostring", lua_Dof_toString}, + {"__gc", lua_Dof_delete}, + {NULL, NULL} +}; + +extern "C" int luaopen_libsf_dof(lua_State *L){ + luaL_newmetatable(L, "sf.Dof"); // Metatable + lua_pushvalue(L, -1); // --> duplicate + lua_setfield(L, -2, "__index"); // --> __index + luaL_setfuncs(L, libsf_Dof_m, 0); // Methods + luaL_newlib(L, libsf_Dof_f); // Library + + return 1; +} + + +int lua_Dof_new(lua_State *L){ + return lua_DofTest_new(L, "sf.Dof"); +} + +int lua_Dof_delete(lua_State *L){ + return lua_DofTest_delete(L, "sf.Dof"); +} + +int lua_Dof_associate(lua_State *L){ + lua_DofTest **dof = (lua_DofTest**)luaL_checkudata(L, 1, "sf.Dof"); + lua_DofTest **test = (lua_DofTest**)luaL_checkudata(L, 2, "sf.Test"); + + return lua_DofTest_associate(L, *dof, *test); +} + +int lua_Dof_toString(lua_State *L){ + return lua_DofTest_toString(L, "sf.Dof"); +} + +#endif diff --git a/lua/LuaDof.h b/lua/LuaDof.h new file mode 100644 index 00000000..216e0c4f --- /dev/null +++ b/lua/LuaDof.h @@ -0,0 +1,21 @@ +#ifndef _LUADOF_H_ +#define _LUADOF_H_ + +#include "SmallFemConfig.h" +#ifdef HAVE_LUA + +#include "LuaDofTest.h" +extern "C"{ +#include "lua.h" +} + +extern "C" int luaopen_libsf_dof(lua_State *L); + +int lua_Dof_new(lua_State *L); +int lua_Dof_delete(lua_State *L); + +int lua_Dof_associate(lua_State *L); +int lua_Dof_toString(lua_State *L); + +#endif +#endif diff --git a/lua/LuaDofTest.cpp b/lua/LuaDofTest.cpp new file mode 100644 index 00000000..428f1bfd --- /dev/null +++ b/lua/LuaDofTest.cpp @@ -0,0 +1,90 @@ +#include "LuaDofTest.h" + +#ifdef HAVE_LUA + +#include "LuaFunctionSpace.h" +#include "LuaIntegrand.h" +extern "C"{ +#include "lauxlib.h" +} + +using namespace sf; +using namespace std; + + +int lua_DofTest_new(lua_State *L, string type){ + // Take FunctionSpace // + FunctionSpace **fs = + (FunctionSpace**)luaL_checkudata(L, 1, "sf.FunctionSpace"); + + // Dof or Test // + lua_DofTest dt; + dt.functionspace = *fs; + dt.derivative = false; + + return lua_DofTest_new(L, &dt, type); +} + +int lua_DofTest_new(lua_State *L, lua_DofTest *dt, string type){ + // Sanity // + if((type.compare("sf.Dof") != 0 && type.compare("sf.Test") != 0) + || dt == NULL) + luaL_error(L, "lua_DofTest_new: incoherent state =/!"); + + // New // + lua_DofTest **lua = (lua_DofTest**)lua_newuserdata(L, sizeof(lua_DofTest*)); + *lua = new lua_DofTest; + + (*lua)->functionspace = dt->functionspace; + (*lua)->derivative = dt->derivative; + + luaL_getmetatable(L, type.c_str()); + lua_setmetatable(L, -2); + + // Done // + return 1; +} + +int lua_DofTest_delete(lua_State *L, string type){ + lua_DofTest **lua = (lua_DofTest**)luaL_checkudata(L, 1, type.c_str()); + if(*lua) + delete *lua; + + return 0; +} + +int lua_DofTest_associate(lua_State *L, lua_DofTest *dof, lua_DofTest *test){ + lua_Integrand **lua = + (lua_Integrand**)lua_newuserdata(L, sizeof(lua_Integrand*)); + *lua = new lua_Integrand; + (*lua)->dof = dof; + (*lua)->test = test; + + luaL_getmetatable(L, "sf.Integrand"); + lua_setmetatable(L, -2); + + return 1; +} + +int lua_DofTest_toString(lua_State *L, string type){ + lua_DofTest **lua = (lua_DofTest**)luaL_checkudata(L, 1, type.c_str()); + lua_pushstring(L, lua_DofTest_toString(*lua).c_str()); + + return 1; +} + +string lua_DofTest_toString(lua_DofTest *dt){ + stringstream str; + str << lua_FunctionSpace_toString(dt->functionspace) + << " | " + << "Derivative: "; + + if(dt->derivative) + str << "True"; + else + str << "False"; + + return str.str(); +} + +#endif diff --git a/lua/LuaDofTest.h b/lua/LuaDofTest.h new file mode 100644 index 00000000..31c66601 --- /dev/null +++ b/lua/LuaDofTest.h @@ -0,0 +1,26 @@ +#ifndef _LUADOFTEST_H_ +#define _LUADOFTEST_H_ + +#include "SmallFemConfig.h" +#ifdef HAVE_LUA + +#include "FunctionSpace.h" +extern "C"{ +#include "lua.h" +} + +typedef struct{ + sf::FunctionSpace *functionspace; + bool derivative; +} lua_DofTest; + +int lua_DofTest_new(lua_State *L, std::string type); +int lua_DofTest_new(lua_State *L, lua_DofTest *dt, std::string type); +int lua_DofTest_delete(lua_State *L, std::string type); + +int lua_DofTest_associate(lua_State *L, lua_DofTest *dof, lua_DofTest *test); +int lua_DofTest_toString(lua_State *L, std::string type); +std::string lua_DofTest_toString(lua_DofTest *dt); + +#endif +#endif diff --git a/lua/LuaFormulation.cpp b/lua/LuaFormulation.cpp index b806332f..e95872fa 100644 --- a/lua/LuaFormulation.cpp +++ b/lua/LuaFormulation.cpp @@ -2,6 +2,7 @@ #ifdef HAVE_LUA +#include "LuaIntegrand.h" extern "C"{ #include "lauxlib.h" } @@ -55,7 +56,9 @@ int lua_Formulation_new(lua_State *L){ FunctionSpace *field; bool isFieldDerived; FunctionSpace *test; bool isTestDerived; - lua_Formulation_getIntegrand(L, &field, &isFieldDerived, &test, &isTestDerived); + lua_Formulation_getIntegrand(L, + &field, &isFieldDerived, + &test, &isTestDerived); lua_remove(L, -1); // Get quadrature order (optional) // @@ -123,49 +126,19 @@ void lua_Formulation_getDomain(lua_State *L, } -void lua_Formulation_getIntegrand(lua_State *L, - FunctionSpace **fs, bool *derivative, - string type){ - // Function space // - lua_pushstring(L, "functionspace"); - lua_gettable(L, -2); - if(lua_isnoneornil(L, -1)) - luaL_error(L, "%s: no function space (functionspace) given", type.c_str()); - - FunctionSpace **lua = - (FunctionSpace**)luaL_testudata(L, -1, "sf.FunctionSpace"); - if(lua == NULL) - luaL_error(L, "%s: the given function space (functionspace) is invalid", - type.c_str()); - *fs = *lua; - lua_remove(L, -1); - - // Derivative // - lua_pushstring(L, "derivative"); - lua_gettable(L, -2); - if(lua_isnoneornil(L, -1)) - luaL_error(L, "%s: no derivative given", type.c_str()); - - if(!lua_isboolean(L, -1)) - luaL_error(L, "%s: derivative must be a boolean", type.c_str()); - *derivative = lua_toboolean(L, -1); - lua_remove(L, -1); -} - void lua_Formulation_getIntegrand(lua_State *L, FunctionSpace **dofFs, bool *dofD, FunctionSpace **testFs, bool *testD){ + // Get integrand // + lua_Integrand **lua = (lua_Integrand**)luaL_checkudata(L, -1, "sf.Integrand"); + // Get ansatz part // - lua_pushstring(L, "dof"); - lua_gettable(L, -2); - lua_Formulation_getIntegrand(L, dofFs, dofD, "Dof"); - lua_remove(L, -1); + *dofFs = (*lua)->dof->functionspace; + *dofD = (*lua)->dof->derivative; // Get test part // - lua_pushstring(L, "test"); - lua_gettable(L, -2); - lua_Formulation_getIntegrand(L, testFs, testD, "Test"); - lua_remove(L, -1); + *testFs = (*lua)->test->functionspace; + *testD = (*lua)->test->derivative; } #endif diff --git a/lua/LuaFormulation.h b/lua/LuaFormulation.h index e671f224..5f4a3a55 100644 --- a/lua/LuaFormulation.h +++ b/lua/LuaFormulation.h @@ -18,9 +18,6 @@ int lua_Formulation_delete(lua_State *L); void lua_Formulation_getDomain(lua_State *L, std::vector<const sf::GroupOfElement*>& vGoe); -void lua_Formulation_getIntegrand(lua_State *L, - sf::FunctionSpace **fs, bool *derivative, - std::string type); void lua_Formulation_getIntegrand(lua_State *L, sf::FunctionSpace **dofFs, bool *dofD, sf::FunctionSpace **testFs, bool *testD); diff --git a/lua/LuaIntegrand.cpp b/lua/LuaIntegrand.cpp new file mode 100644 index 00000000..c7fbfdf0 --- /dev/null +++ b/lua/LuaIntegrand.cpp @@ -0,0 +1,77 @@ +#include "LuaIntegrand.h" + +#ifdef HAVE_LUA + +extern "C"{ +#include "lauxlib.h" +} + +using namespace sf; +using namespace std; + + +const struct luaL_Reg libsf_Integrand_f[] = { + {"derivative", lua_Integrand_derivative}, + {NULL, NULL} +}; + +const struct luaL_Reg libsf_Integrand_m[] = { + {"__tostring", lua_Integrand_toString}, + {"__gc", lua_Integrand_delete}, + {NULL, NULL} +}; + +extern "C" int luaopen_libsf_integrand(lua_State *L){ + luaL_newmetatable(L, "sf.Integrand"); // Metatable + lua_pushvalue(L, -1); // --> duplicate + lua_setfield(L, -2, "__index"); // --> __index + luaL_setfuncs(L, libsf_Integrand_m, 0); // Methods + luaL_newlib(L, libsf_Integrand_f); // Library + + return 1; +} + + +int lua_Integrand_delete(lua_State *L){ + lua_Integrand **lua = (lua_Integrand**)luaL_checkudata(L, 1, "sf.Integrand"); + if(*lua) + delete *lua; + + return 0; +} + +int lua_Integrand_toString(lua_State *L){ + lua_Integrand **lua = (lua_Integrand**)luaL_checkudata(L, 1, "sf.Integrand"); + + stringstream str; + str << "Integrand: " << endl + << " * Dof - " << lua_DofTest_toString((*lua)->dof) << endl + << " * Test - " << lua_DofTest_toString((*lua)->test); + + lua_pushstring(L, str.str().c_str()); + return 1; +} + +int lua_Integrand_derivative(lua_State *L){ + lua_DofTest **dof = (lua_DofTest**)luaL_testudata(L, 1, "sf.Dof"); + lua_DofTest **test = (lua_DofTest**)luaL_testudata(L, 1, "sf.Test"); + + string type; + lua_DofTest *item = NULL; + if(dof){ + type = "sf.Dof"; + item = *dof; + } + else if(test){ + type = "sf.Test"; + item = *test; + } + else{ + luaL_error(L, "Integrand: derivative takes a Dof or a Test as argument"); + } + + item->derivative = true; + return lua_DofTest_new(L, item, type); +} + +#endif diff --git a/lua/LuaIntegrand.h b/lua/LuaIntegrand.h new file mode 100644 index 00000000..816069c7 --- /dev/null +++ b/lua/LuaIntegrand.h @@ -0,0 +1,25 @@ +#ifndef _LUAINTEGRAND_H_ +#define _LUAINTEGRAND_H_ + +#include "SmallFemConfig.h" +#ifdef HAVE_LUA + +#include "LuaDof.h" +extern "C"{ +#include "lua.h" +} + +extern "C" int luaopen_libsf_integrand(lua_State *L); + +typedef struct{ + lua_DofTest *dof; + lua_DofTest *test; +} lua_Integrand; + +int lua_Integrand_delete(lua_State *L); +int lua_Integrand_toString(lua_State *L); + +int lua_Integrand_derivative(lua_State *L); + +#endif +#endif diff --git a/lua/LuaTest.cpp b/lua/LuaTest.cpp new file mode 100644 index 00000000..38756420 --- /dev/null +++ b/lua/LuaTest.cpp @@ -0,0 +1,55 @@ +#include "LuaTest.h" + +#ifdef HAVE_LUA + +extern "C"{ +#include "lauxlib.h" +} + +using namespace sf; +using namespace std; + + +const struct luaL_Reg libsf_Test_f[] = { + {"Test", lua_Test_new}, + {NULL, NULL} +}; + +const struct luaL_Reg libsf_Test_m[] = { + {"__mul", lua_Test_associate}, + {"__tostring", lua_Test_toString}, + {"__gc", lua_Test_delete}, + {NULL, NULL} +}; + +extern "C" int luaopen_libsf_test(lua_State *L){ + luaL_newmetatable(L, "sf.Test"); // Metatable + lua_pushvalue(L, -1); // --> duplicate + lua_setfield(L, -2, "__index"); // --> __index + luaL_setfuncs(L, libsf_Test_m, 0); // Methods + luaL_newlib(L, libsf_Test_f); // Library + + return 1; +} + + +int lua_Test_new(lua_State *L){ + return lua_DofTest_new(L, "sf.Test"); +} + +int lua_Test_delete(lua_State *L){ + return lua_DofTest_delete(L, "sf.Test"); +} + +int lua_Test_associate(lua_State *L){ + lua_DofTest **test = (lua_DofTest**)luaL_checkudata(L, 1, "sf.Test"); + lua_DofTest **dof = (lua_DofTest**)luaL_checkudata(L, 2, "sf.Dof"); + + return lua_DofTest_associate(L, *dof, *test); +} + +int lua_Test_toString(lua_State *L){ + return lua_DofTest_toString(L, "sf.Test"); +} + +#endif diff --git a/lua/LuaTest.h b/lua/LuaTest.h new file mode 100644 index 00000000..5adadd3f --- /dev/null +++ b/lua/LuaTest.h @@ -0,0 +1,21 @@ +#ifndef _LUATEST_H_ +#define _LUATEST_H_ + +#include "SmallFemConfig.h" +#ifdef HAVE_LUA + +#include "LuaDofTest.h" +extern "C"{ +#include "lua.h" +} + +extern "C" int luaopen_libsf_test(lua_State *L); + +int lua_Test_new(lua_State *L); +int lua_Test_delete(lua_State *L); + +int lua_Test_associate(lua_State *L); +int lua_Test_toString(lua_State *L); + +#endif +#endif -- GitLab