LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
Loading...
Searching...
No Matches
mesh_hierarchy.h
1#ifndef INCG_LF_REFINEMENT_HIER_H_
2#define INCG_LF_REFINEMENT_HIER_H_
3
10#include <iostream>
11
12#include "hybrid2d_refinement_pattern.h"
13
14namespace lf::refinement {
15
34
50 explicit EdgeChildInfo() = default;
54 std::vector<glb_idx_t> child_edge_idx;
56 std::vector<glb_idx_t> child_point_idx;
57};
58
73 explicit CellChildInfo() = default;
75 sub_idx_t anchor_{idx_nil};
76 std::vector<glb_idx_t> child_cell_idx;
77 std::vector<glb_idx_t> child_edge_idx;
78 std::vector<glb_idx_t> child_point_idx;
79};
80
87struct ParentInfo {
88 explicit ParentInfo() = default;
89 // Data members
91 nullptr};
92 glb_idx_t parent_index{
93 idx_nil};
94 sub_idx_t child_number{idx_nil};
97 std::unique_ptr<const lf::geometry::Geometry> rel_ref_geo_{nullptr};
98};
99
117 public:
133 MeshHierarchy(const std::shared_ptr<mesh::Mesh> &base_mesh,
134 std::unique_ptr<mesh::MeshFactory> mesh_factory);
135 MeshHierarchy(const MeshHierarchy &) = delete;
139
143 [[nodiscard]] size_type NumLevels() const { return meshes_.size(); }
144
151 [[nodiscard]] std::shared_ptr<const mesh::Mesh> getMesh(
152 size_type level) const {
153 LF_VERIFY_MSG(level < meshes_.size(),
154 "Level " << level << " outside scope");
155 return meshes_.at(level);
156 }
160 [[nodiscard]] std::shared_ptr<mesh::Mesh> getMesh(size_type level) {
161 LF_VERIFY_MSG(level < meshes_.size(),
162 "Level " << level << " outside scope");
163 return meshes_.at(level);
164 }
165
172 [[nodiscard]] std::vector<std::shared_ptr<const mesh::Mesh>> getMeshes()
173 const {
174 return {meshes_.begin(), meshes_.end()};
175 }
176
185 [[nodiscard]] const std::vector<PointChildInfo> &PointChildInfos(
186 size_type level) const {
187 LF_VERIFY_MSG(level < NumLevels(), "Illegal level " << level);
188 return point_child_infos_[level];
189 }
198 [[nodiscard]] const std::vector<EdgeChildInfo> &EdgeChildInfos(
199 size_type level) const {
200 LF_VERIFY_MSG(level < NumLevels(), "Illegal level " << level);
201 return edge_child_infos_[level];
202 }
211 [[nodiscard]] const std::vector<CellChildInfo> &CellChildInfos(
212 size_type level) const {
213 LF_VERIFY_MSG(level < NumLevels(), "Illegal level " << level);
214 return cell_child_infos_[level];
215 }
225 [[nodiscard]] const std::vector<ParentInfo> &ParentInfos(size_type level,
226 dim_t codim) const {
227 LF_VERIFY_MSG(level < NumLevels(), "Illegal level " << level);
228 LF_VERIFY_MSG(codim < 3, "Codim = " << codim << " illegal");
229 return parent_infos_[level][codim];
230 }
238 [[nodiscard]] const std::vector<sub_idx_t> &RefinementEdges(
239 size_type level) const {
240 LF_VERIFY_MSG(level < NumLevels(), "Illegal level " << level);
241 return refinement_edges_[level];
242 }
243
278 template <typename Marker>
279 void MarkEdges(Marker &&marker);
280
305 void RefineMarked();
312 void Coarsen();
350 [[nodiscard]] const lf::geometry::Geometry *GeometryInParent(
351 size_type level, const lf::mesh::Entity &e) const;
352
362 [[nodiscard]] const lf::mesh::Entity *ParentEntity(
363 size_type level, const lf::mesh::Entity &e) const;
364
379 std::ostream &PrintInfo(std::ostream &o, unsigned ctrl = 0) const;
380
381 virtual ~MeshHierarchy() = default;
382
383 private:
407 void PerformRefinement();
408
420
422 std::vector<std::shared_ptr<mesh::Mesh>> meshes_;
424 std::unique_ptr<mesh::MeshFactory> mesh_factory_;
426 std::vector<std::vector<PointChildInfo>> point_child_infos_;
428 std::vector<std::vector<EdgeChildInfo>> edge_child_infos_;
430 std::vector<std::vector<CellChildInfo>> cell_child_infos_;
432 std::vector<std::array<std::vector<ParentInfo>, 3>> parent_infos_;
434 std::vector<std::vector<bool>> edge_marked_;
436 std::vector<std::vector<sub_idx_t>> refinement_edges_;
437
444 [[nodiscard]] static sub_idx_t LongestEdge(const lf::mesh::Entity &T);
445
446 public:
451 static std::shared_ptr<spdlog::logger> &Logger();
452};
453
454template <typename Marker>
455void MeshHierarchy::MarkEdges(Marker &&marker) {
456 // Retrieve the finest mesh in the hierarchy
457 const mesh::Mesh &finest_mesh(*meshes_.back());
458
459 LF_VERIFY_MSG(edge_marked_.back().size() == finest_mesh.NumEntities(1),
460 "Length mismatch for edge flag array");
461
462 // Run through the edges = entities of co-dimension 1
463 for (const mesh::Entity *edge : finest_mesh.Entities(1)) {
464 const glb_idx_t edge_index = finest_mesh.Index(*edge);
465 (edge_marked_.back())[edge_index] = marker(finest_mesh, *edge);
466 }
467} // end MeshHierarchy::MarkEdges
468
482std::shared_ptr<MeshHierarchy> GenerateMeshHierarchyByUniformRefinemnt(
483 const std::shared_ptr<lf::mesh::Mesh> &mesh_p, lf::base::size_type ref_lev,
484 RefPat ref_pat = RefPat::rp_regular);
485
496template <typename POSPRED>
498 public:
501 default;
503 const EntityCenterPositionSelector &) = default;
505 EntityCenterPositionSelector &&) noexcept = default;
511 explicit EntityCenterPositionSelector(POSPRED pos_pred)
512 : pos_pred_(std::move(pos_pred)) {}
517 bool operator()(const lf::mesh::Entity &ent) const {
518 const lf::base::RefEl ref_el_type = ent.RefEl();
519 // Obtain shape of entity
520 const lf::geometry::Geometry *geo_ptr = ent.Geometry();
521 LF_ASSERT_MSG(geo_ptr != nullptr, "Missing geometry for " << ent);
522 switch (ref_el_type) {
524 const Eigen::MatrixXd pos(geo_ptr->Global(kpoint_center_));
525 return pos_pred_(pos);
526 }
528 const Eigen::MatrixXd pos(geo_ptr->Global(kedge_center_));
529 return pos_pred_(pos);
530 }
531 case lf::base::RefEl::kTria(): {
532 const Eigen::MatrixXd pos(geo_ptr->Global(ktria_center_));
533 return pos_pred_(pos);
534 }
535 case lf::base::RefEl::kQuad(): {
536 const Eigen::MatrixXd pos(geo_ptr->Global(kquad_center_));
537 return pos_pred_(pos);
538 }
539 default: {
540 LF_ASSERT_MSG(false, "Illegal entity type");
541 break;
542 }
543 } // end switch
544 return false;
545 }
546
547 virtual ~EntityCenterPositionSelector() = default;
548
549 private:
551 POSPRED pos_pred_;
552
553 static const Eigen::MatrixXd kpoint_center_;
554 static const Eigen::MatrixXd kedge_center_;
555 static const Eigen::MatrixXd ktria_center_;
556 static const Eigen::MatrixXd kquad_center_;
557};
558
559template <typename POSPRED>
561 Eigen::MatrixXd::Zero(0, 1);
562
563template <typename POSPRED>
565 (Eigen::MatrixXd(1, 1) << 0.5).finished();
566
567template <typename POSPRED>
569 (Eigen::MatrixXd(2, 1) << 0.33, 0.33).finished();
570
571template <typename POSPRED>
573 (Eigen::MatrixXd(2, 1) << 0.5, 0.5).finished();
574
575} // namespace lf::refinement
576
577#endif
Represents a reference element with all its properties.
Definition ref_el.h:109
static constexpr RefEl kSegment()
Returns the (1-dimensional) reference segment.
Definition ref_el.h:153
static constexpr RefEl kPoint()
Returns the (0-dimensional) reference point.
Definition ref_el.h:144
static constexpr RefEl kTria()
Returns the reference triangle.
Definition ref_el.h:161
static constexpr RefEl kQuad()
Returns the reference quadrilateral.
Definition ref_el.h:169
Interface class for shape information on a mesh cell in the spirit of parametric finite element metho...
virtual Eigen::MatrixXd Global(const Eigen::MatrixXd &local) const =0
Map a number of points in local coordinates into the global coordinate system.
Interface class representing a topological entity in a cellular complex
Definition entity.h:42
virtual const geometry::Geometry * Geometry() const =0
Describes the geometry of this entity.
virtual base::RefEl RefEl() const =0
Describes the reference element type of this entity.
Abstract interface for objects representing a single mesh.
virtual std::span< const Entity *const > Entities(unsigned codim) const =0
All entities of a given codimension.
virtual size_type NumEntities(unsigned codim) const =0
The number of Entities that have the given codimension.
virtual size_type Index(const Entity &e) const =0
Acess to the index of a mesh entity of any co-dimension.
Utility class: selection of entities according to the position of their midpoint.
EntityCenterPositionSelector(EntityCenterPositionSelector &&) noexcept=default
static const Eigen::MatrixXd ktria_center_
bool operator()(const lf::mesh::Entity &ent) const
Operator testing location of "center".
static const Eigen::MatrixXd kpoint_center_
EntityCenterPositionSelector(const EntityCenterPositionSelector &)=default
static const Eigen::MatrixXd kquad_center_
static const Eigen::MatrixXd kedge_center_
A hierarchy of nested 2D hybrid meshes created by refinement.
MeshHierarchy(const MeshHierarchy &)=delete
std::vector< std::shared_ptr< const mesh::Mesh > > getMeshes() const
Provides array of shared pointers to meshes contained in the hierarchy.
MeshHierarchy(const std::shared_ptr< mesh::Mesh > &base_mesh, std::unique_ptr< mesh::MeshFactory > mesh_factory)
Initialize mesh hierarchy with an existing coarsest mesh.
const std::vector< EdgeChildInfo > & EdgeChildInfos(size_type level) const
Obtain refinement information for all edges.
std::unique_ptr< mesh::MeshFactory > mesh_factory_
The mesh factory to be used to creating a new mesh.
void RefineRegular(RefPat ref_pat=RefPat::rp_regular)
Perform regular or barycentric uniform refinement of the finest mesh in the hierarchy.
std::shared_ptr< const mesh::Mesh > getMesh(size_type level) const
access the mesh on a particular level
void RefineMarked()
Conduct local refinement of the mesh splitting all marked edges.
std::vector< std::shared_ptr< mesh::Mesh > > meshes_
the meshes managed by the MeshHierarchy object
std::vector< std::vector< sub_idx_t > > refinement_edges_
Information about local refinement edges of triangles.
const std::vector< CellChildInfo > & CellChildInfos(size_type level) const
Obtain refinement information for all.
std::vector< std::vector< CellChildInfo > > cell_child_infos_
information about children of cells for each level
std::vector< std::array< std::vector< ParentInfo >, 3 > > parent_infos_
information about parent entities on each level
const std::vector< ParentInfo > & ParentInfos(size_type level, dim_t codim) const
Fetch information about parents.
std::ostream & PrintInfo(std::ostream &o, unsigned ctrl=0) const
Output of information about the mesh hierarchy.
std::vector< std::vector< bool > > edge_marked_
Information about marked edges.
virtual ~MeshHierarchy()=default
void MarkEdges(Marker &&marker)
Mark the edges of a mesh based on a predicate.
std::shared_ptr< mesh::Mesh > getMesh(size_type level)
access the mesh on a particular level
const std::vector< sub_idx_t > & RefinementEdges(size_type level) const
Access refinement edge indices.
std::vector< std::vector< PointChildInfo > > point_child_infos_
information about children of nodes for each level
MeshHierarchy & operator=(MeshHierarchy &&)=delete
void Coarsen()
Destroy the mesh on the finest level unless it is the base mesh
static std::shared_ptr< spdlog::logger > & Logger()
Is used by MeshHierarchy to log additional information for debugging purposes.
void PerformRefinement()
Create new mesh according to refinement pattern provided for entities.
MeshHierarchy(MeshHierarchy &&)=delete
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.
MeshHierarchy & operator=(const MeshHierarchy &)=delete
const std::vector< PointChildInfo > & PointChildInfos(size_type level) const
Obtain refinement information for all points.
const lf::geometry::Geometry * GeometryInParent(size_type level, const lf::mesh::Entity &e) const
shape of child entity in parent's reference coordinates
std::vector< std::vector< EdgeChildInfo > > edge_child_infos_
information about children of edges for each level
void initGeometryInParent()
Initialization of rel_ref_geo fields of ParentInfo structures.
static sub_idx_t LongestEdge(const lf::mesh::Entity &T)
Finds the index of the longest edge of a triangle.
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
std::shared_ptr< MeshHierarchy > GenerateMeshHierarchyByUniformRefinemnt(const std::shared_ptr< lf::mesh::Mesh > &mesh_p, lf::base::size_type ref_lev, RefPat ref_pat)
Generated a sequence of nested 2D hybrid mehes by regular or barycentric refinement.
const unsigned int idx_nil
RefPat
(possibly incomplete) list of refinement patterns for triangles/quadrilaterals
Information about the refinement status of a cell.
std::vector< glb_idx_t > child_point_idx
std::vector< glb_idx_t > child_cell_idx
std::vector< glb_idx_t > child_edge_idx
Information about the refinement status of an edge.
std::vector< glb_idx_t > child_edge_idx
global indices of child edges in fine mesh
std::vector< glb_idx_t > child_point_idx
global indices of interior child points in fine mesh
RefPat ref_pat_
type of refinement edge has undergone, see RefPat
Information about possible parent entities.
std::unique_ptr< const lf::geometry::Geometry > rel_ref_geo_
const mesh::Entity * parent_ptr
Information about the refinement status of a point.
RefPat ref_pat
a flag indicating whether the point is to be duplicated (rp_copy)
glb_idx_t child_point_idx
global index of the child point