Select Git revision
MeshModule.cpp
-
Stéphane Del Pino authored
Now modules are defined in their own directory (language/modules)
Stéphane Del Pino authoredNow modules are defined in their own directory (language/modules)
MeshModule.cpp 4.71 KiB
#include <language/modules/MeshModule.hpp>
#include <language/BuiltinFunctionEmbedder.hpp>
#include <language/FunctionTable.hpp>
#include <language/PugsFunctionAdapter.hpp>
#include <language/SymbolTable.hpp>
#include <language/TypeDescriptor.hpp>
#include <language/node_processor/ExecutionPolicy.hpp>
#include <mesh/Connectivity.hpp>
#include <mesh/GmshReader.hpp>
#include <mesh/Mesh.hpp>
#include <utils/Exceptions.hpp>
#include <Kokkos_Core.hpp>
#include <array>
#include <cstdio>
template <>
inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<IMesh>> = {ASTNodeDataType::type_id_t, "mesh"};
template <typename T>
class MeshTransformation;
template <typename OutputType, typename... InputType>
class MeshTransformation<OutputType(InputType...)> : public PugsFunctionAdapter<OutputType(InputType...)>
{
static constexpr size_t Dimension = OutputType::Dimension;
using Adapter = PugsFunctionAdapter<OutputType(InputType...)>;
public:
static inline std::shared_ptr<Mesh<Connectivity<Dimension>>>
transform(const FunctionSymbolId& function_symbol_id, std::shared_ptr<const IMesh> p_mesh)
{
using MeshType = Mesh<Connectivity<Dimension>>;
const MeshType& given_mesh = dynamic_cast<const MeshType&>(*p_mesh);
const auto flatten_args = Adapter::getFlattenArgs(function_symbol_id);
auto& expression = Adapter::getFunctionExpression(function_symbol_id);
auto convert_result = Adapter::getResultConverter(expression.m_data_type);
Array<ExecutionPolicy> context_list = Adapter::getContextList(expression);
NodeValue<const OutputType> given_xr = given_mesh.xr();
NodeValue<OutputType> xr(given_mesh.connectivity());
using execution_space = typename Kokkos::DefaultExecutionSpace::execution_space;
Kokkos::Experimental::UniqueToken<execution_space, Kokkos::Experimental::UniqueTokenScope::Global> tokens;
parallel_for(given_mesh.numberOfNodes(), [=, &expression, &flatten_args, &tokens](NodeId r) {
const int32_t t = tokens.acquire();
auto& execution_policy = context_list[t];
Adapter::convertArgs(execution_policy.currentContext(), flatten_args, given_xr[r]);
auto result = expression.execute(execution_policy);
xr[r] = convert_result(std::move(result));
tokens.release(t);
});
return std::make_shared<MeshType>(given_mesh.shared_connectivity(), xr);
}
};
MeshModule::MeshModule()
{
this->_addTypeDescriptor(
std::make_shared<TypeDescriptor>(ast_node_data_type_from<std::shared_ptr<IMesh>>.typeName()));
this->_addBuiltinFunction("readGmsh", std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<IMesh>, std::string>>(
std::function<std::shared_ptr<IMesh>(std::string)>{
[](const std::string& file_name) -> std::shared_ptr<IMesh> {
GmshReader gmsh_reader(file_name);
return gmsh_reader.mesh();
}}
));
this->_addBuiltinFunction("transform",
std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr<IMesh>, std::shared_ptr<IMesh>,
FunctionSymbolId>>(
std::function<std::shared_ptr<IMesh>(std::shared_ptr<IMesh>, FunctionSymbolId)>{
[](std::shared_ptr<IMesh> p_mesh,
const FunctionSymbolId& function_id) -> std::shared_ptr<IMesh> {
switch (p_mesh->dimension()) {
case 1: {
using TransformT = TinyVector<1>(TinyVector<1>);
return MeshTransformation<TransformT>::transform(function_id, p_mesh);
}
case 2: {
using TransformT = TinyVector<2>(TinyVector<2>);
return MeshTransformation<TransformT>::transform(function_id, p_mesh);
}
case 3: {
using TransformT = TinyVector<3>(TinyVector<3>);
return MeshTransformation<TransformT>::transform(function_id, p_mesh);
}
default: {
throw UnexpectedError("invalid mesh dimension");
}
}
}}
));
}