Skip to content
Snippets Groups Projects
Commit 3c591666 authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Add a temporary mesh transformation function

This is just a test to plug builtin-functions into the language.
One can write
``
m1 = transform(m0, f);
``
where `m0` and `m1` are meshes (m0 being initialized) and `f` is a function.

By now the function is not used, its type is not checked the only validated info
is that it is actually a function...

For validation purpose, one distorts the mesh using a C++ code.
parent a5635de3
Branches
Tags
1 merge request!37Feature/language
...@@ -78,6 +78,20 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData ...@@ -78,6 +78,20 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData
} }
}; };
auto get_function_argument_to_function_id_converter = [&]() -> std::unique_ptr<IFunctionArgumentConverter> {
switch (argument_node_sub_data_type.m_data_type) {
case ASTNodeDataType::function_t: {
return std::make_unique<FunctionArgumentConverter<FunctionId, FunctionId>>(argument_number);
}
// LCOV_EXCL_START
default: {
throw parse_error("unexpected error: invalid argument type for function",
std::vector{argument_node_sub_data_type.m_parent_node.begin()});
}
// LCOV_EXCL_STOP
}
};
auto get_function_argument_converter_for_argument_type = [&]() { auto get_function_argument_converter_for_argument_type = [&]() {
switch (parameter_type) { switch (parameter_type) {
case ASTNodeDataType::bool_t: { case ASTNodeDataType::bool_t: {
...@@ -97,6 +111,9 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData ...@@ -97,6 +111,9 @@ ASTNodeBuiltinFunctionExpressionBuilder::_getArgumentConverter(const ASTNodeData
} }
case ASTNodeDataType::type_id_t: { case ASTNodeDataType::type_id_t: {
return get_function_argument_to_type_id_converter(); return get_function_argument_to_type_id_converter();
}
case ASTNodeDataType::function_t: {
return get_function_argument_to_function_id_converter();
} }
// LCOV_EXCL_START // LCOV_EXCL_START
default: { default: {
...@@ -118,9 +135,9 @@ ASTNodeBuiltinFunctionExpressionBuilder::_storeArgumentProcessor( ...@@ -118,9 +135,9 @@ ASTNodeBuiltinFunctionExpressionBuilder::_storeArgumentProcessor(
const std::vector<ASTNodeDataType>& parameter_type_list, const std::vector<ASTNodeDataType>& parameter_type_list,
const ASTNodeDataTypeFlattener::FlattenedDataTypeList& flattened_datatype_list, const ASTNodeDataTypeFlattener::FlattenedDataTypeList& flattened_datatype_list,
const size_t argument_number, const size_t argument_number,
BuiltinFunctionProcessor& _processor) BuiltinFunctionProcessor& processor)
{ {
_processor.addArgumentConverter(this->_getArgumentConverter(parameter_type_list[argument_number], processor.addArgumentConverter(this->_getArgumentConverter(parameter_type_list[argument_number],
flattened_datatype_list[argument_number], flattened_datatype_list[argument_number],
argument_number)); argument_number));
} }
...@@ -130,7 +147,7 @@ void ...@@ -130,7 +147,7 @@ void
ASTNodeBuiltinFunctionExpressionBuilder::_buildArgumentProcessors( ASTNodeBuiltinFunctionExpressionBuilder::_buildArgumentProcessors(
const std::vector<ASTNodeDataType>& parameter_type_list, const std::vector<ASTNodeDataType>& parameter_type_list,
ASTNode& node, ASTNode& node,
BuiltinFunctionProcessor& _processor) BuiltinFunctionProcessor& processor)
{ {
ASTNode& argument_nodes = *node.children[1]; ASTNode& argument_nodes = *node.children[1];
...@@ -148,7 +165,7 @@ ASTNodeBuiltinFunctionExpressionBuilder::_buildArgumentProcessors( ...@@ -148,7 +165,7 @@ ASTNodeBuiltinFunctionExpressionBuilder::_buildArgumentProcessors(
} }
for (size_t i = 0; i < arguments_number; ++i) { for (size_t i = 0; i < arguments_number; ++i) {
this->_storeArgumentProcessor(parameter_type_list, flattened_datatype_list, i, _processor); this->_storeArgumentProcessor(parameter_type_list, flattened_datatype_list, i, processor);
} }
} }
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <Demangle.hpp> #include <Demangle.hpp>
#include <PugsTraits.hpp> #include <PugsTraits.hpp>
#include <FunctionTable.hpp>
template <typename T> template <typename T>
inline ASTNodeDataType ast_node_data_type_from = ASTNodeDataType::undefined_t; inline ASTNodeDataType ast_node_data_type_from = ASTNodeDataType::undefined_t;
...@@ -53,7 +55,7 @@ class BuiltinFunctionEmbedder : public IBuiltinFunctionEmbedder ...@@ -53,7 +55,7 @@ class BuiltinFunctionEmbedder : public IBuiltinFunctionEmbedder
template <size_t I> template <size_t I>
PUGS_INLINE void PUGS_INLINE void
_copy_value(ArgsTuple& t, const std::vector<DataVariant>& v) const _copyValue(ArgsTuple& t, const std::vector<DataVariant>& v) const
{ {
std::visit( std::visit(
[&](auto&& v_i) { [&](auto&& v_i) {
...@@ -72,6 +74,10 @@ class BuiltinFunctionEmbedder : public IBuiltinFunctionEmbedder ...@@ -72,6 +74,10 @@ class BuiltinFunctionEmbedder : public IBuiltinFunctionEmbedder
} else { } else {
throw std::runtime_error("unexpected argument types while casting: expecting EmbeddedData"); throw std::runtime_error("unexpected argument types while casting: expecting EmbeddedData");
} }
} else if constexpr (std::is_same_v<Ti_Type, FunctionId> and std::is_same_v<Vi_Type, uint64_t>) {
std::get<I>(t) = FunctionId{v_i};
throw std::runtime_error(
"WIP: should get better descriptor, FunctionId should at least refer to the symbol table.");
} else { } else {
std::ostringstream os; std::ostringstream os;
os << "unexpected argument types while casting " << demangle<Vi_Type>() << " -> " << demangle<Ti_Type>() os << "unexpected argument types while casting " << demangle<Vi_Type>() << " -> " << demangle<Ti_Type>()
...@@ -84,10 +90,10 @@ class BuiltinFunctionEmbedder : public IBuiltinFunctionEmbedder ...@@ -84,10 +90,10 @@ class BuiltinFunctionEmbedder : public IBuiltinFunctionEmbedder
template <size_t... I> template <size_t... I>
PUGS_INLINE void PUGS_INLINE void
_copy_from_vector(ArgsTuple& t, const std::vector<DataVariant>& v, std::index_sequence<I...>) const _copyFromVector(ArgsTuple& t, const std::vector<DataVariant>& v, std::index_sequence<I...>) const
{ {
Assert(sizeof...(Args) == v.size()); Assert(sizeof...(Args) == v.size());
(_copy_value<I>(t, v), ...); (_copyValue<I>(t, v), ...);
} }
template <size_t I> template <size_t I>
...@@ -146,7 +152,7 @@ class BuiltinFunctionEmbedder : public IBuiltinFunctionEmbedder ...@@ -146,7 +152,7 @@ class BuiltinFunctionEmbedder : public IBuiltinFunctionEmbedder
ArgsTuple t; ArgsTuple t;
using IndexSequence = std::make_index_sequence<N>; using IndexSequence = std::make_index_sequence<N>;
this->_copy_from_vector(t, x, IndexSequence{}); this->_copyFromVector(t, x, IndexSequence{});
if constexpr (std::is_arithmetic_v<FX>) { if constexpr (std::is_arithmetic_v<FX>) {
return {std::apply(m_f, t)}; return {std::apply(m_f, t)};
} else if constexpr (std::is_same_v<FX, void>) { } else if constexpr (std::is_same_v<FX, void>) {
......
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
#include <iostream> #include <iostream>
struct FunctionId
{
uint64_t m_function_id;
};
class FunctionDescriptor class FunctionDescriptor
{ {
std::unique_ptr<ASTNode> m_domain_mapping_node; std::unique_ptr<ASTNode> m_domain_mapping_node;
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#include <BuiltinFunctionEmbedder.hpp> #include <BuiltinFunctionEmbedder.hpp>
#include <TypeDescriptor.hpp> #include <TypeDescriptor.hpp>
#include <FunctionTable.hpp>
#include <GmshReader.hpp> #include <GmshReader.hpp>
#include <Connectivity.hpp> #include <Connectivity.hpp>
...@@ -13,6 +15,9 @@ ...@@ -13,6 +15,9 @@
template <> template <>
inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<IMesh>> = {ASTNodeDataType::type_id_t, "mesh"}; inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<IMesh>> = {ASTNodeDataType::type_id_t, "mesh"};
template <>
inline ASTNodeDataType ast_node_data_type_from<FunctionId> = {ASTNodeDataType::function_t};
MeshModule::MeshModule() MeshModule::MeshModule()
{ {
this->_addTypeDescriptor( this->_addTypeDescriptor(
...@@ -27,4 +32,49 @@ MeshModule::MeshModule() ...@@ -27,4 +32,49 @@ MeshModule::MeshModule()
}} }}
)); ));
this
->_addBuiltinFunction("transform",
std::make_shared<
BuiltinFunctionEmbedder<std::shared_ptr<IMesh>, std::shared_ptr<IMesh>, FunctionId>>(
std::function<std::shared_ptr<IMesh>(std::shared_ptr<IMesh>, FunctionId)>{
[](std::shared_ptr<IMesh> p_mesh, FunctionId function_id) -> std::shared_ptr<IMesh> {
switch (p_mesh->dimension()) {
case 1: {
throw std::runtime_error("not implemented in 1d");
break;
}
case 2: {
throw std::runtime_error("not implemented in 2d");
break;
}
case 3: {
std::cout << "Using function " << function_id.m_function_id << '\n';
using MeshType = Mesh<Connectivity3D>;
const MeshType& given_mesh = dynamic_cast<const MeshType&>(*p_mesh);
NodeValue<const TinyVector<3>> given_xr = given_mesh.xr();
NodeValue<TinyVector<3>> xr(given_mesh.connectivity());
parallel_for(
given_mesh.numberOfNodes(), PUGS_LAMBDA(const NodeId& r) {
const TinyVector<3> shift{0, 0.05, 0.05};
const auto x = given_xr[r] - shift;
const double c = std::cos(0.01 * x[0]);
const double s = std::sin(0.01 * x[0]);
const TinyVector<3> transformed{x[0], x[1] * c + x[2] * s, -x[1] * s + x[2] * c};
xr[r] = transformed + shift;
});
return std::make_shared<MeshType>(given_mesh.shared_connectivity(), xr);
}
default: {
return nullptr;
}
}
}}
));
} }
...@@ -17,31 +17,35 @@ VTKModule::VTKModule() ...@@ -17,31 +17,35 @@ VTKModule::VTKModule()
std::function<void(std::shared_ptr<IMesh>, std::string)>{ std::function<void(std::shared_ptr<IMesh>, std::string)>{
[](std::shared_ptr<IMesh> p_mesh, std::string filename) -> void { [](std::shared_ptr<IMesh> p_mesh, std::string filename) -> void {
VTKWriter writer(filename, 0); VTKWriter writer(filename, 0.1);
static double time = 0;
switch (p_mesh->dimension()) { switch (p_mesh->dimension()) {
case 1: { case 1: {
using MeshType = Mesh<Connectivity<1>>; using MeshType = Mesh<Connectivity<1>>;
const MeshType& mesh = dynamic_cast<const MeshType&>(*p_mesh); const MeshType& mesh = dynamic_cast<const MeshType&>(*p_mesh);
writer.write(mesh, OutputNamedItemValueSet{}, 0); writer.write(mesh, OutputNamedItemValueSet{}, time, true);
break; break;
} }
case 2: { case 2: {
using MeshType = Mesh<Connectivity<2>>; using MeshType = Mesh<Connectivity<2>>;
const MeshType& mesh = dynamic_cast<const MeshType&>(*p_mesh); const MeshType& mesh = dynamic_cast<const MeshType&>(*p_mesh);
writer.write(mesh, OutputNamedItemValueSet{}, 0); writer.write(mesh, OutputNamedItemValueSet{}, time, true);
break; break;
} }
case 3: { case 3: {
using MeshType = Mesh<Connectivity<3>>; using MeshType = Mesh<Connectivity<3>>;
const MeshType& mesh = dynamic_cast<const MeshType&>(*p_mesh); const MeshType& mesh = dynamic_cast<const MeshType&>(*p_mesh);
writer.write(mesh, OutputNamedItemValueSet{}, 0); writer.write(mesh, OutputNamedItemValueSet{}, time, true);
break; break;
} }
} }
time++;
} }
})); }));
......
...@@ -43,6 +43,13 @@ class Mesh final : public IMesh ...@@ -43,6 +43,13 @@ class Mesh final : public IMesh
return *m_connectivity; return *m_connectivity;
} }
PUGS_INLINE
const auto&
shared_connectivity() const
{
return m_connectivity;
}
PUGS_INLINE PUGS_INLINE
size_t size_t
numberOfNodes() const numberOfNodes() const
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment