LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
mesh_function_transfer.h
1#ifndef LF_REFINEMENT_MESH_FUNCTION_TRANSFER_H
2#define LF_REFINEMENT_MESH_FUNCTION_TRANSFER_H
3
4#include <lf/mesh/utils/utils.h>
5#include <lf/refinement/mesh_hierarchy.h>
6
7#include <Eigen/Dense>
8#include <type_traits>
9
10namespace lf::refinement {
11
17template <typename MF>
19 using mf_t = std::remove_cv_t<std::remove_reference_t<MF>>;
20 static_assert(lf::mesh::utils::isMeshFunction<mf_t>,
21 "MF is not a valid MeshFunction");
22
23 // Metafunction to determine whether MF provides a `getMesh` method
24 template <typename MF_TEST,
25 typename = decltype(std::declval<MF_TEST>().getMesh())>
26 static std::true_type has_getMesh_impl(int);
27 template <typename MF_TEST>
28 static std::false_type has_getMesh_impl(...);
29 static constexpr bool provides_getMesh =
30 decltype(has_getMesh_impl<mf_t>(int{})){}; // NOLINT
31
32 public:
43 lf::base::size_type level_coarse,
44 lf::base::size_type level_fine)
45 : mh_(mh), mf_(mf), level_coarse_(level_coarse), level_fine_(level_fine) {
46 // Assert that the `level_coarse` parameter does not point to the finest
47 // mesh
48 LF_ASSERT_MSG(
49 level_coarse < mh.NumLevels() - 1,
50 "level_coarse must not point to the finest mesh in the hierarchy");
51 // Assert that the `level_fine` parameter points to a finer mesh than
52 // `level_coarse`
53 LF_ASSERT_MSG(level_fine > level_coarse,
54 "level_fine must be bigger than level_fine");
55 LF_ASSERT_MSG(
56 level_fine < mh.NumLevels(),
57 "level_fine must point to a valid mesh in the mesh hierarchy");
58 // If the mesh function is defined over an FE space, assert the correctness
59 // of the `level_coarse` parameter
60 if constexpr (provides_getMesh) { // NOLINT
61 LF_ASSERT_MSG(mh.getMesh(level_coarse) == mf.getMesh(),
62 "Invalid level_coarse provided");
63 }
64 }
65
73 decltype(auto) operator()(const lf::mesh::Entity &e,
74 const Eigen::MatrixXd &local) const {
75 const auto *rel_geom = mh_.GeometryInParent(level_fine_, e);
76 const auto *parent = mh_.ParentEntity(level_fine_, e);
77 auto local_parent = rel_geom->Global(local);
78 for (lf::base::size_type lvl = level_fine_ - 1; lvl > level_coarse_;
79 --lvl) {
80 rel_geom = mh_.GeometryInParent(lvl, *parent);
81 parent = mh_.ParentEntity(lvl, *parent);
82 local_parent = rel_geom->Global(local_parent);
83 }
84 return mf_(*parent, local_parent);
85 }
86
91 [[nodiscard]] std::shared_ptr<const lf::mesh::Mesh> getMesh() const {
92 return mh_.getMesh(level_coarse_ + 1);
93 }
94
95 private:
97 const MF &mf_;
100};
101
102template <typename MF>
106
107} // namespace lf::refinement
108
109#endif // LF_REFINEMENT_MESH_FUNCTION_TRANSFER_H
Interface class representing a topological entity in a cellular complex
Definition: entity.h:39
A MeshFunction representing interpolation on a lf::refinement::MeshHierarchy.
static std::false_type has_getMesh_impl(...)
MeshFunctionTransfer(const lf::refinement::MeshHierarchy &mh, const MF &mf, lf::base::size_type level_coarse, lf::base::size_type level_fine)
Constructor.
const lf::refinement::MeshHierarchy & mh_
std::remove_cv_t< std::remove_reference_t< MF > > mf_t
std::shared_ptr< const lf::mesh::Mesh > getMesh() const
Access the underlying Mesh.
static std::true_type has_getMesh_impl(int)
A hierarchy of nested 2D hybrid meshes created by refinement.
std::shared_ptr< const mesh::Mesh > getMesh(size_type level) const
access the mesh on a particular level
size_type NumLevels() const
number of meshes contained in the hierarchy, 1 for a single mesh
const lf::mesh::Entity * ParentEntity(size_type level, const lf::mesh::Entity &e) const
Retrieve the parent of an entity contained in a mesh of a refinement hierarchy.
const lf::geometry::Geometry * GeometryInParent(size_type level, const lf::mesh::Entity &e) const
shape of child entity in parent's reference coordinates
unsigned int size_type
general type for variables related to size of arrays
Definition: base.h:24
tools for regular or local refinement of 2D hybrid meshes
MeshFunctionTransfer(const lf::refinement::MeshHierarchy &, const MF &, lf::base::size_type, lf::base::size_type) -> MeshFunctionTransfer< MF >