-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23 from SeisSol/lua
Add Lua support
- Loading branch information
Showing
9 changed files
with
261 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
!Any | ||
components: | ||
- !GroupFilter | ||
groups: [6,7,8] | ||
components: !ConstantMap | ||
map: | ||
rho: 2500.0 | ||
mu: 0.0 | ||
lambda: 1.96e10 | ||
- !LuaMap | ||
returns: ["rho", "mu", "lambda"] | ||
function: | | ||
function f (x) | ||
io.write(x[1], " ", x[2], " ", x[3], "\n") -- optional debug output | ||
return { | ||
rho = 1600. + 59.5 * (x[2] ^ (1./3.)), | ||
mu = 0, | ||
lambda = (260. + 30*math.sqrt(x[2]))^2. * (1600. + 59.5 * x[2] ^(1./3.) ) | ||
} | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#ifndef EASI_LUAMAP_H | ||
#define EASI_LUAMAP_H | ||
|
||
#ifdef EASI_USE_LUA | ||
#include <map> | ||
#include <set> | ||
#include <string> | ||
#include <vector> | ||
|
||
|
||
|
||
#include "easi/component/Map.h" | ||
#include "easi/util/FunctionWrapper.h" | ||
#include "easi/util/Matrix.h" | ||
|
||
// Forward declaration to avoid including all Lua headers | ||
struct lua_State; | ||
|
||
namespace easi { | ||
double getField(lua_State* L, const std::string& key); | ||
|
||
class LuaMap : public Map { | ||
public: | ||
void setMap(const std::set<std::string>& in, | ||
const std::set<std::string>& returns, | ||
const std::string& function); | ||
|
||
~LuaMap() override; | ||
protected: | ||
virtual Matrix<double> map(Matrix<double>& x) override; | ||
|
||
private: | ||
double executeLuaFunction(Matrix<double> x, unsigned coordIdx, unsigned funcIdx); | ||
std::string function; | ||
std::vector<std::string> idxToNameMap; | ||
lua_State* luaState; | ||
|
||
}; | ||
|
||
} // namespace easi | ||
|
||
#endif // EASI_USE_LUA | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
#include "easi/component/LuaMap.h" | ||
|
||
#ifdef EASI_USE_LUA | ||
extern "C" { | ||
#include <lua.h> | ||
#include <lualib.h> | ||
#include <lauxlib.h> | ||
} | ||
#include <cassert> | ||
#include <iostream> | ||
#include <ostream> | ||
#include <stdexcept> | ||
|
||
namespace easi { | ||
|
||
double getField(lua_State* L, const std::string& key) { | ||
lua_pushstring(L, key.data()); | ||
lua_gettable(L, -2); | ||
if (!lua_isnumber(L, -1)) { | ||
std::cerr | ||
<< "Tried key " | ||
<< key | ||
<< " but it did not return a number." | ||
<< std::endl; | ||
} | ||
const auto result = lua_tonumber(L, -1); | ||
lua_pop(L, 1); | ||
return result; | ||
} | ||
|
||
double LuaMap::executeLuaFunction(Matrix<double> x, | ||
unsigned coordIdx, | ||
unsigned funcIdx) { | ||
if (!luaState) { | ||
std::cout << "Init lua state" << std::endl; | ||
luaState = luaL_newstate(); | ||
luaL_openlibs(luaState); | ||
const auto status = luaL_dostring(luaState, function.data()); | ||
if (status) { | ||
std::cerr | ||
<< "Couldn't load script: " | ||
<< lua_tostring(luaState, -1); | ||
std::abort(); | ||
} | ||
} | ||
|
||
// Push function and arguments to stack | ||
lua_getglobal(luaState, "f"); // the function | ||
|
||
// Add table as input: x holds coordinates | ||
lua_newtable(luaState); | ||
for (int i = 0; i < 3; ++i) { | ||
lua_pushnumber(luaState, i+1); | ||
lua_pushnumber(luaState, x(coordIdx, i)); | ||
lua_rawset(luaState, -3); | ||
} | ||
|
||
if (lua_pcall(luaState, 1, 1, 0) != 0) { | ||
std::cerr | ||
<< "Error running function f " | ||
<< lua_tostring(luaState, -1) | ||
<< std::endl; | ||
} | ||
return getField(luaState, idxToNameMap[funcIdx]); | ||
} | ||
|
||
Matrix<double> LuaMap::map(Matrix<double>& x) { | ||
|
||
assert(x.cols() == dimDomain()); | ||
|
||
Matrix<double> y(x.rows(), dimCodomain()); | ||
for (unsigned i = 0; i < y.rows(); ++i) { | ||
for (unsigned j = 0; j < y.cols(); ++j) { | ||
y(i,j) = executeLuaFunction(x, i, j); | ||
} | ||
} | ||
return y; | ||
} | ||
|
||
void LuaMap::setMap(const std::set<std::string>& in, | ||
const std::set<std::string>& out, | ||
const std::string& newFunction) { | ||
setIn(in); | ||
setOut(out); | ||
function = newFunction; | ||
for (const auto& o : out) { | ||
idxToNameMap.push_back(o); | ||
} | ||
} | ||
|
||
LuaMap::~LuaMap() { | ||
if (luaState) { | ||
lua_close(luaState); | ||
} | ||
} | ||
|
||
|
||
|
||
} // namespace easi | ||
#endif // EASI_USE_LUA |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#include "easitest.h" | ||
#include <cmath> | ||
|
||
double rho(double y) { return 1600. + 59.5 * pow(y, 1. / 3.); } | ||
double lambda(double y) { return pow(260. + 30 * sqrt(y), 2.) * (1600. + 59.5 * pow(y, 1. / 3.)); } | ||
|
||
int main(int argc, char** argv) { | ||
assert(argc == 2); | ||
|
||
easi::Query query = createQuery<3>({{7, {0.0, 0.0, 0.0}}, | ||
{5, {0.0, 10.0, 0.0}}, | ||
{4, {0.0, 20.0, 0.0}}, | ||
{3, {0.0, 25.0, 0.0}}}); | ||
|
||
auto material = elasticModel(argv[1], query); | ||
|
||
assert(equal(material[0].rho, 2500.0)); | ||
assert(equal(material[0].mu, 0.0)); | ||
assert(equal(material[0].lambda, 1.96e10)); | ||
|
||
assert(equal(material[1].rho, rho(10.0))); | ||
assert(equal(material[1].mu, 0.0)); | ||
assert(equal(material[1].lambda, lambda(10.0))); | ||
|
||
assert(equal(material[2].rho, rho(20.0))); | ||
assert(equal(material[2].mu, 0.0)); | ||
assert(equal(material[2].lambda, lambda(20.0))); | ||
|
||
assert(equal(material[3].rho, rho(25.0))); | ||
assert(equal(material[3].mu, 0.0)); | ||
assert(equal(material[3].lambda, lambda(25.0))); | ||
|
||
return 0; | ||
} |