diff --git a/CMakeLists.txt b/CMakeLists.txt index 45c69b7a0d8744a1fde62b53170e7f3f8ef303c2..97a94a4eff3e7b956a219ca9399b5221157d6500 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -528,6 +528,7 @@ target_link_libraries( PugsLanguageAlgorithms PugsMesh PugsAlgebra + PugsScheme PugsUtils PugsLanguageUtils kokkos diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1b21f79a7545c442be5448792132acbdf840947a..e9c207b2fc2f256c6e17a35afbafcb82521dea75 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,5 +15,8 @@ add_subdirectory(algebra) # Pugs mesh add_subdirectory(mesh) +# Pugs mesh +add_subdirectory(scheme) + # Pugs output #add_subdirectory(output) diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp index 542690a4ffcfb73ba174f0014b358548208d830f..e691e248adb885410d7a50d8994734517d4fc921 100644 --- a/src/language/modules/SchemeModule.cpp +++ b/src/language/modules/SchemeModule.cpp @@ -5,10 +5,13 @@ #include <language/utils/TypeDescriptor.hpp> #include <mesh/Mesh.hpp> #include <scheme/DirichletBoundaryConditionDescriptor.hpp> +#include <scheme/DiscreteFunctionInterpoler.hpp> #include <scheme/FourierBoundaryConditionDescriptor.hpp> #include <scheme/FreeBoundaryConditionDescriptor.hpp> #include <scheme/IBoundaryConditionDescriptor.hpp> #include <scheme/IBoundaryDescriptor.hpp> +#include <scheme/IDiscreteFunction.hpp> +#include <scheme/IDiscreteFunctionDescriptor.hpp> #include <scheme/NamedBoundaryDescriptor.hpp> #include <scheme/NeumannBoundaryConditionDescriptor.hpp> #include <scheme/NumberedBoundaryDescriptor.hpp> @@ -18,9 +21,33 @@ SchemeModule::SchemeModule() { + this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const IDiscreteFunction>>); + this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const IDiscreteFunctionDescriptor>>); + this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const IBoundaryDescriptor>>); this->_addTypeDescriptor(ast_node_data_type_from<std::shared_ptr<const IBoundaryConditionDescriptor>>); + this->_addBuiltinFunction("P0", std::make_shared< + BuiltinFunctionEmbedder<std::shared_ptr<const IDiscreteFunctionDescriptor>()>>( + []() -> std::shared_ptr<const IDiscreteFunctionDescriptor> { + return std::make_shared<DiscreteFunctionDescriptorP0>(); + } + + )); + + this->_addBuiltinFunction( + "interpolate", + std::make_shared<BuiltinFunctionEmbedder<std::shared_ptr< + const IDiscreteFunction>(std::shared_ptr<const IMesh>, std::shared_ptr<const IDiscreteFunctionDescriptor>, + const FunctionSymbolId&)>>( + [](std::shared_ptr<const IMesh> mesh, + std::shared_ptr<const IDiscreteFunctionDescriptor> discrete_function_descriptor, + const FunctionSymbolId& function_id) -> std::shared_ptr<const IDiscreteFunction> { + return DiscreteFunctionInterpoler{mesh, discrete_function_descriptor, function_id}.interpolate(); + } + + )); + this->_addBuiltinFunction("boundaryName", std::make_shared< BuiltinFunctionEmbedder<std::shared_ptr<const IBoundaryDescriptor>(const std::string&)>>( diff --git a/src/language/modules/SchemeModule.hpp b/src/language/modules/SchemeModule.hpp index 96418b1693d377641f9bd096d263d5d17c6b929d..3cfbb254a8f6e2ac36d16c1a78e53f3f995f56fc 100644 --- a/src/language/modules/SchemeModule.hpp +++ b/src/language/modules/SchemeModule.hpp @@ -15,6 +15,16 @@ template <> inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const IBoundaryConditionDescriptor>> = ASTNodeDataType::build<ASTNodeDataType::type_id_t>("boundary_condition"); +class IDiscreteFunction; +template <> +inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const IDiscreteFunction>> = + ASTNodeDataType::build<ASTNodeDataType::type_id_t>("Vh"); + +class IDiscreteFunctionDescriptor; +template <> +inline ASTNodeDataType ast_node_data_type_from<std::shared_ptr<const IDiscreteFunctionDescriptor>> = + ASTNodeDataType::build<ASTNodeDataType::type_id_t>("Vh_type"); + class SchemeModule : public BuiltinModule { public: diff --git a/src/scheme/CMakeLists.txt b/src/scheme/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..1467393f2cbcbd9e31dd495e2905e9be478a1d78 --- /dev/null +++ b/src/scheme/CMakeLists.txt @@ -0,0 +1,5 @@ +# ------------------- Source files -------------------- + +add_library( + PugsScheme + DiscreteFunctionInterpoler.cpp) diff --git a/src/scheme/DiscreteFunctionInterpoler.cpp b/src/scheme/DiscreteFunctionInterpoler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55348a4084f9267d78a8ee2e36a4abb70965e220 --- /dev/null +++ b/src/scheme/DiscreteFunctionInterpoler.cpp @@ -0,0 +1,55 @@ +#include <scheme/DiscreteFunctionInterpoler.hpp> + +#include <language/utils/InterpolateItemValue.hpp> +#include <mesh/Connectivity.hpp> +#include <mesh/Mesh.hpp> +#include <mesh/MeshData.hpp> +#include <mesh/MeshDataManager.hpp> +#include <utils/Exceptions.hpp> + +template <typename DataType> +class DiscreteFunctionP0 : public IDiscreteFunction +{ + private: + CellValue<DataType> m_cell_value; + + public: + DiscreteFunctionP0(const CellValue<DataType>& cell_value) : m_cell_value{cell_value} {} + DiscreteFunctionP0(CellValue<DataType>&& cell_value) : m_cell_value{std::move(cell_value)} {} + ~DiscreteFunctionP0() = default; +}; + +template <size_t Dimension> +std::shared_ptr<IDiscreteFunction> +DiscreteFunctionInterpoler::_interpolate() const +{ + using MeshType = Mesh<Connectivity<Dimension>>; + const MeshType& mesh = dynamic_cast<const MeshType&>(*m_mesh); + + using MeshDataType = MeshData<Dimension>; + MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(mesh); + + return std::make_shared<DiscreteFunctionP0<double>>( + InterpolateItemValue<double(TinyVector<Dimension>)>::template interpolate<ItemType::cell>(m_function_id, + mesh_data.xj())); +} + +std::shared_ptr<IDiscreteFunction> +DiscreteFunctionInterpoler::interpolate() const +{ + switch (m_mesh->dimension()) { + case 1: { + return this->_interpolate<1>(); + } + case 2: { + return this->_interpolate<2>(); + } + case 3: { + return this->_interpolate<3>(); + } + default: { + throw UnexpectedError("invalid dimension"); + } + } + return nullptr; +} diff --git a/src/scheme/DiscreteFunctionInterpoler.hpp b/src/scheme/DiscreteFunctionInterpoler.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8f679c7637d85fc9c499f27f2273a5bc3b69de16 --- /dev/null +++ b/src/scheme/DiscreteFunctionInterpoler.hpp @@ -0,0 +1,36 @@ +#ifndef DISCRETE_FUNCTION_INTERPOLER_HPP +#define DISCRETE_FUNCTION_INTERPOLER_HPP + +#include <language/utils/FunctionSymbolId.hpp> +#include <mesh/IMesh.hpp> +#include <scheme/IDiscreteFunction.hpp> +#include <scheme/IDiscreteFunctionDescriptor.hpp> + +#include <memory> + +class DiscreteFunctionInterpoler +{ + private: + std::shared_ptr<const IMesh> m_mesh; + std::shared_ptr<const IDiscreteFunctionDescriptor> m_discrete_function_descriptor; + const FunctionSymbolId m_function_id; + + template <size_t Dimension> + std::shared_ptr<IDiscreteFunction> _interpolate() const; + + public: + std::shared_ptr<IDiscreteFunction> interpolate() const; + + DiscreteFunctionInterpoler(const std::shared_ptr<const IMesh>& mesh, + const std::shared_ptr<const IDiscreteFunctionDescriptor>& discrete_function_descriptor, + const FunctionSymbolId& function_id) + : m_mesh{mesh}, m_discrete_function_descriptor{discrete_function_descriptor}, m_function_id{function_id} + {} + + DiscreteFunctionInterpoler(const DiscreteFunctionInterpoler&) = delete; + DiscreteFunctionInterpoler(DiscreteFunctionInterpoler&&) = delete; + + ~DiscreteFunctionInterpoler() = default; +}; + +#endif // DISCRETE_FUNCTION_INTERPOLER_HPP diff --git a/src/scheme/IDiscreteFunction.hpp b/src/scheme/IDiscreteFunction.hpp new file mode 100644 index 0000000000000000000000000000000000000000..3eea07af9530bc1f52213b4610fff028a7d9a306 --- /dev/null +++ b/src/scheme/IDiscreteFunction.hpp @@ -0,0 +1,16 @@ +#ifndef I_DISCRETE_FUNCTION_HPP +#define I_DISCRETE_FUNCTION_HPP + +class IDiscreteFunction +{ + public: + IDiscreteFunction() = default; + + IDiscreteFunction(const IDiscreteFunction&) = default; + + IDiscreteFunction(IDiscreteFunction&&) noexcept = default; + + virtual ~IDiscreteFunction() noexcept = default; +}; + +#endif // I_DISCRETE_FUNCTION_HPP diff --git a/src/scheme/IDiscreteFunctionDescriptor.hpp b/src/scheme/IDiscreteFunctionDescriptor.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c2b795d6dc924a595d95f19de17c1e3da025683e --- /dev/null +++ b/src/scheme/IDiscreteFunctionDescriptor.hpp @@ -0,0 +1,41 @@ +#ifndef I_DISCRETE_FUNCTION_DESCRIPTOR_HPP +#define I_DISCRETE_FUNCTION_DESCRIPTOR_HPP + +enum class DiscreteFunctionDescriptorType +{ + P0 +}; + +class IDiscreteFunctionDescriptor +{ + public: + virtual DiscreteFunctionDescriptorType type() const = 0; + + IDiscreteFunctionDescriptor() noexcept = default; + + IDiscreteFunctionDescriptor(const IDiscreteFunctionDescriptor&) = default; + + IDiscreteFunctionDescriptor(IDiscreteFunctionDescriptor&&) noexcept = default; + + virtual ~IDiscreteFunctionDescriptor() noexcept = default; +}; + +class DiscreteFunctionDescriptorP0 : public IDiscreteFunctionDescriptor +{ + public: + DiscreteFunctionDescriptorType + type() const final + { + return DiscreteFunctionDescriptorType::P0; + } + + DiscreteFunctionDescriptorP0() noexcept = default; + + DiscreteFunctionDescriptorP0(const DiscreteFunctionDescriptorP0& other) = default; + + DiscreteFunctionDescriptorP0(DiscreteFunctionDescriptorP0&& other) noexcept = default; + + ~DiscreteFunctionDescriptorP0() noexcept = default; +}; + +#endif // I_DISCRETE_FUNCTION_DESCRIPTOR_HPP diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b2c9f5015a442538ec23f8d421fb07fa93153480..06518e70d327fc29760ad6ac2c38142bd2afa138 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -113,6 +113,7 @@ target_link_libraries (unit_tests PugsLanguage PugsMesh PugsAlgebra + PugsScheme PugsUtils kokkos ${PARMETIS_LIBRARIES} @@ -134,7 +135,9 @@ target_link_libraries (mpi_unit_tests PugsMesh PugsAlgebra PugsUtils - PugsLanguageUtils PugsUtils + PugsLanguageUtils + PugsScheme + PugsUtils PugsAlgebra PugsMesh kokkos