LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
Loading...
Searching...
No Matches
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 <mesh::utils::MeshFunction MF>
19 using mf_t = std::remove_cv_t<std::remove_reference_t<MF>>;
20
21 // Metafunction to determine whether MF provides a `getMesh` method
22 template <typename MF_TEST,
23 typename = decltype(std::declval<MF_TEST>().getMesh())>
24 static std::true_type has_getMesh_impl(int);
25 template <typename MF_TEST>
26 static std::false_type has_getMesh_impl(...);
27 static constexpr bool provides_getMesh =
28 decltype(has_getMesh_impl<mf_t>(int{})){}; // NOLINT
29
30 public:
41 lf::base::size_type level_coarse,
42 lf::base::size_type level_fine)
43 : mh_(mh), mf_(mf), level_coarse_(level_coarse), level_fine_(level_fine) {
44 // Assert that the `level_coarse` parameter does not point to the finest
45 // mesh
46 LF_ASSERT_MSG(
47 level_coarse < mh.NumLevels() - 1,
48 "level_coarse must not point to the finest mesh in the hierarchy");
49 // Assert that the `level_fine` parameter points to a finer mesh than
50 // `level_coarse`
51 LF_ASSERT_MSG(level_fine > level_coarse,
52 "level_fine must be bigger than level_fine");
53 LF_ASSERT_MSG(
54 level_fine < mh.NumLevels(),
55 "level_fine must point to a valid mesh in the mesh hierarchy");
56 // If the mesh function is defined over an FE space, assert the correctness
57 // of the `level_coarse` parameter
58 if constexpr (provides_getMesh) { // NOLINT
59 LF_ASSERT_MSG(mh.getMesh(level_coarse) == mf.getMesh(),
60 "Invalid level_coarse provided");
61 }
62 }
63
71 decltype(auto) operator()(const lf::mesh::Entity &e,
72 const Eigen::MatrixXd &local) const {
73 const auto *rel_geom = mh_.GeometryInParent(level_fine_, e);
74 const auto *parent = mh_.ParentEntity(level_fine_, e);
75 auto local_parent = rel_geom->Global(local);
76 for (lf::base::size_type lvl = level_fine_ - 1; lvl > level_coarse_;
77 --lvl) {
78 rel_geom = mh_.GeometryInParent(lvl, *parent);
79 parent = mh_.ParentEntity(lvl, *parent);
80 local_parent = rel_geom->Global(local_parent);
81 }
82 return mf_(*parent, local_parent);
83 }
84
89 [[nodiscard]] std::shared_ptr<const lf::mesh::Mesh> getMesh() const {
90 return mh_.getMesh(level_coarse_ + 1);
91 }
92
93 private:
95 const MF &mf_;
98};
99
100template <typename MF>
104
105} // namespace lf::refinement
106
107#endif // LF_REFINEMENT_MESH_FUNCTION_TRANSFER_H
Interface class representing a topological entity in a cellular complex
Definition entity.h:42
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 types.h:20
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 >