LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
Loading...
Searching...
No Matches
quad.cc
1
9#include "quad.h"
10
11#include "point.h"
12#include "segment.h"
13
14namespace lf::mesh::hybrid2d {
16 std::unique_ptr<geometry::Geometry>&& geometry,
17 const Point* corner0, const Point* corner1,
18 const Point* corner2, const Point* corner3,
19 const Segment* edge0, const Segment* edge1,
20 const Segment* edge2, const Segment* edge3)
21 : index_(index),
22 geometry_(std::move(geometry)),
23 nodes_({corner0, corner1, corner2, corner3}),
24 edges_({edge0, edge1, edge2, edge3}),
25 edge_ori_(),
26 this_(this) {
27 LF_VERIFY_MSG(corner0 != nullptr, "Invalid pointer to corner 0");
28 LF_VERIFY_MSG(corner1 != nullptr, "Invalid pointer to corner 1");
29 LF_VERIFY_MSG(corner2 != nullptr, "Invalid pointer to corner 2");
30 LF_VERIFY_MSG(corner3 != nullptr, "Invalid pointer to corner 3");
31 LF_VERIFY_MSG(edge0 != nullptr, "Invalid pointer to edge 0");
32 LF_VERIFY_MSG(edge1 != nullptr, "Invalid pointer to edge 1");
33 LF_VERIFY_MSG(edge2 != nullptr, "Invalid pointer to edge 2");
34 LF_VERIFY_MSG(edge3 != nullptr, "Invalid pointer to edge 3");
35 if (geometry_) {
36 LF_VERIFY_MSG(geometry_->DimLocal() == 2,
37 "Geometry must describe a 2D cell");
38 LF_VERIFY_MSG(geometry_->RefEl() == base::RefEl::kQuad(),
39 "Cell geometry must fit a quad");
40 }
41
42 // Consistency check: make sure that sub-entities of sub-entities
43 // agree with sub-sub-entities
44
46 // Run through all edges
47 for (int ed_loc_idx = 0; ed_loc_idx < 4; ed_loc_idx++) {
48 // Pointer to current edge
49 const Segment* ed_ptr = edges_.at(ed_loc_idx);
50 // Check for segement type
51 LF_VERIFY_MSG(ed_ptr->RefEl() == lf::base::RefEl::kSegment(),
52 "Wrong type for edge " << ed_loc_idx);
53 // Fetch nodes from current edge
54 auto ed_nodes = ed_ptr->SubEntities(1);
55
56 // Obtain local indices of endpoints of edge
57 const size_type loc_idx_p0 =
58 ref_el_quad.SubSubEntity2SubEntity(1, ed_loc_idx, 1, 0);
59 const size_type loc_idx_p1 =
60 ref_el_quad.SubSubEntity2SubEntity(1, ed_loc_idx, 1, 1);
61 const Point* p0_ptr = nodes_.at(loc_idx_p0);
62 const Point* p1_ptr = nodes_.at(loc_idx_p1);
63
64 // Verify that the nodes of the quadrilateral are nodes of the edge as well
65 LF_VERIFY_MSG((ed_nodes[0] == p0_ptr) || (ed_nodes[0] == p1_ptr),
66 "Node 0 of edge " << ed_loc_idx << " not a quad node");
67 LF_VERIFY_MSG((ed_nodes[1] == p0_ptr) || (ed_nodes[1] == p1_ptr),
68 "Node 1 of edge " << ed_loc_idx << " not a quad node");
69 }
70
71 // Finally set relative orientations for the edges. Edge i has positive
72 // orientation, if its first node agrees with vertex i
73 for (int ed_loc_idx = 0; ed_loc_idx < 4; ed_loc_idx++) {
74 // Fetch nodes of current edge
75 auto ed_nodes = edges_[ed_loc_idx]->SubEntities(1);
76 edge_ori_[ed_loc_idx] = (ed_nodes[0] == nodes_[ed_loc_idx])
78 : lf::mesh::Orientation::negative;
79 }
80
81} // end constructor
82
83// Access to sub-entities
84std::span<const mesh::Entity* const> Quadrilateral::SubEntities(
85 unsigned rel_codim) const {
86 auto l = [&](auto i) -> const mesh::Entity& { return **i; };
87 switch (rel_codim) {
88 case 2:
89 return {reinterpret_cast<const Entity* const*>(nodes_.data()), 4};
90 case 1:
91 return {reinterpret_cast<const Entity* const*>(edges_.data()), 4};
92 case 0:
93 return {&this_, 1};
94 default:
95 LF_VERIFY_MSG(
96 false, "Quadrilateral: rel_codim " << rel_codim << " out of range");
97 }
98}
99} // namespace lf::mesh::hybrid2d
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 kQuad()
Returns the reference quadrilateral.
Definition ref_el.h:169
Interface class representing a topological entity in a cellular complex
Definition entity.h:42
A node object for a 2D hybrid mesh.
Definition point.h:28
mesh::Mesh::size_type size_type
Definition quad.h:29
std::array< const Point *, 4 > nodes_
Definition quad.h:119
std::span< const Entity *const > SubEntities(unsigned rel_codim) const override
Access to all subentities selected by relative co-dimension.
Definition quad.cc:84
std::array< const Segment *, 4 > edges_
Definition quad.h:120
Quadrilateral()=default
default constructors, needed by std::vector
An edge object for a 2D hybrid mesh.
Definition segment.h:29
@ kQuad
Returns the reference quadrilateral.
An alternative implementation of a hybrid2d mesh manager that uses Pointers to store sub-entity relat...
Definition hybrid2d.h:11
Orientation
Relative orientation of a sub-entity.
Definition entity.h:22
Definition assemble.h:31