LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
Loading...
Searching...
No Matches
hierarchic_scalar_fe_space.h
1
9#ifndef LF_USCALFE_FE_SPACE_HP_H_
10#define LF_USCALFE_FE_SPACE_HP_H_
11
12#include <lf/mesh/utils/all_codim_mesh_data_set.h>
13
14#include "hierarchic_fe.h"
15#include "scalar_fe_space.h"
16
17namespace lf::fe {
18
47template <typename SCALAR>
48class HierarchicScalarFESpace : public ScalarFESpace<SCALAR> {
49 public:
50 using Scalar = SCALAR;
51
57 default;
58
65 const std::shared_ptr<const lf::mesh::Mesh> &mesh_p, unsigned degree)
67 [degree](const mesh::Entity &e) -> unsigned {
68 if (e.RefEl() == base::RefEl::kPoint()) {
69 return 1;
70 }
71 return degree;
72 }) {}
73
91 template <class F, class = std::enable_if_t<
92 std::is_invocable_v<F, const mesh::Entity &>>>
94 const std::shared_ptr<const lf::mesh::Mesh> &mesh_p, F &&degree_functor)
95 : ScalarFESpace<SCALAR>(),
96 mesh_p_(mesh_p),
97 ref_el_(mesh_p),
98 dofh_(mesh_p,
99 [&degree_functor](const mesh::Entity &e) -> base::size_type {
100 if (e.RefEl() == base::RefEl::kPoint()) {
101 return 1;
102 }
103 auto degree = degree_functor(e);
104 switch (e.RefEl()) {
106 return degree - 1;
107 case base::RefEl::kTria():
108 return degree <= 2 ? 0 : (degree - 2) * (degree - 1) / 2;
109 case base::RefEl::kQuad():
110 return (degree - 1) * (degree - 1);
111 default:
112 LF_VERIFY_MSG(false, "Something went wrong.");
113 }
114 }) {
115 Init(std::forward<F>(degree_functor));
116 }
117
121 [[nodiscard]] std::shared_ptr<const lf::mesh::Mesh> Mesh() const override {
122 LF_VERIFY_MSG(mesh_p_ != nullptr, "No valid FE space object: no mesh");
123 return mesh_p_;
124 }
125
129 [[nodiscard]] const lf::assemble::DofHandler &LocGlobMap() const override {
130 LF_VERIFY_MSG(Mesh() != nullptr, "No valid FE space object: no mesh");
131 return dofh_;
132 }
133
138 const lf::mesh::Entity &entity) const override {
139 return std::visit(
140 [](const auto &fe) -> ScalarReferenceFiniteElement<SCALAR> const * {
141 if constexpr (std::is_same_v<decltype(fe),
142 const std::monostate &>) { // NOLINT
143 LF_VERIFY_MSG(false,
144 "Something is wrong, no "
145 "ScalarReferenceFiniteElement found for "
146 "this entity.");
147 return nullptr; // make compiler happy.
148 } else { // NOLINT
149 return &fe;
150 }
151 },
152 ref_el_(entity));
153 }
154
159 const lf::mesh::Entity &entity) const override {
160 return ShapeFunctionLayout(entity)->NumRefShapeFunctions();
161 }
162
163 ~HierarchicScalarFESpace() override = default;
164
165 private:
166 /* Underlying mesh */
167 std::shared_ptr<const lf::mesh::Mesh> mesh_p_;
169 // Store the ScalarReferenceFiniteElement for every entity.
171 std::variant<std::monostate, FePoint<SCALAR>, FeHierarchicSegment<SCALAR>,
175
176 // R.H. Detailed comment needed for this function
177 template <class F>
178 void Init(F &&degree_functor) {
179 // Initialize all shape function layouts for nodes
180 const size_type num_rsf_node = 1;
181 for (const auto *entity : mesh_p_->Entities(2)) {
182 ref_el_(*entity) = FePoint<SCALAR>(1);
183 }
184 // Initialize all shape function layouts for the edges
185 for (const auto *entity : mesh_p_->Entities(1)) {
186 FeHierarchicSegment<SCALAR> fe(degree_functor(*entity), qr_cache_);
187
188 ref_el_(*entity) = std::move(fe);
189 }
190 // Initialize all shape function layouts for the cells
191 for (const auto *entity : mesh_p_->Entities(0)) {
192 switch (entity->RefEl()) {
193 case lf::base::RefEl::kTria(): {
194 const std::array<unsigned, 3> edge_degrees{
195 {degree_functor(*entity->SubEntities(1)[0]),
196 degree_functor(*entity->SubEntities(1)[1]),
197 degree_functor(*entity->SubEntities(1)[2])}};
198 FeHierarchicTria<SCALAR> fe(degree_functor(*entity), edge_degrees,
199 qr_cache_,
200 entity->RelativeOrientations());
201 ref_el_(*entity) = std::move(fe);
202 break;
203 }
204 case lf::base::RefEl::kQuad(): {
205 const std::array<unsigned, 4> edge_degrees{
206 {degree_functor(*entity->SubEntities(1)[0]),
207 degree_functor(*entity->SubEntities(1)[1]),
208 degree_functor(*entity->SubEntities(1)[2]),
209 degree_functor(*entity->SubEntities(1)[3])}};
210 FeHierarchicQuad<SCALAR> fe(degree_functor(*entity), edge_degrees,
211 qr_cache_,
212 entity->RelativeOrientations());
213 ref_el_(*entity) = std::move(fe);
214 break;
215 }
216 default:
217 LF_VERIFY_MSG(false, "Illegal entity type");
218 }
219 }
220 }
221};
222
223} // end namespace lf::fe
224
225#endif // LF_USCALFE_FE_SPACE_HP_H_
A general (interface) class for DOF handling, see Lecture Document Paragraph 2.7.4....
Definition dofhandler.h:112
Dof handler allowing variable local dof layouts.
Definition dofhandler.h:514
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
Hierarchic Finite Elements of arbitrary degree on quadrilaterals.
Hierarchic Finite Elements of arbitrary degree on segments.
Hierarchic Finite Elements of arbitrary degree on triangles.
Finite element on a point.
Definition fe_point.h:25
Finite Element Space that supports arbitrary, local degrees.
const lf::assemble::DofHandler & LocGlobMap() const override
access to associated local-to-global map
size_type NumRefShapeFunctions(const lf::mesh::Entity &entity) const override
number of interior shape functions associated to entities of various types
lf::mesh::utils::AllCodimMeshDataSet< std::variant< std::monostate, FePoint< SCALAR >, FeHierarchicSegment< SCALAR >, FeHierarchicTria< SCALAR >, FeHierarchicQuad< SCALAR > > > ref_el_
std::shared_ptr< const lf::mesh::Mesh > mesh_p_
HierarchicScalarFESpace(HierarchicScalarFESpace &&) noexcept=default
ScalarReferenceFiniteElement< SCALAR > const * ShapeFunctionLayout(const lf::mesh::Entity &entity) const override
access to shape function layout for cells
HierarchicScalarFESpace(const HierarchicScalarFESpace &)=delete
lf::assemble::DynamicFEDofHandler dofh_
std::shared_ptr< const lf::mesh::Mesh > Mesh() const override
access to underlying mesh
HierarchicScalarFESpace(const std::shared_ptr< const lf::mesh::Mesh > &mesh_p, F &&degree_functor)
Construct a new Hierarchic FESpace with (possibly) varying polynomial degrees.
~HierarchicScalarFESpace() override=default
Space of scalar valued finite element functions on a Mesh.
Interface class for parametric scalar valued finite elements.
Interface class representing a topological entity in a cellular complex
Definition entity.h:42
Assigns to every entity(all codims) in a mesh a value of type T
A cache for make_QuadRule()
Collects data structures and algorithms designed for scalar finite element methods primarily meant fo...
Definition fe.h:47
lf::assemble::size_type size_type
Definition fe.h:54
Definition assemble.h:31