1#ifndef PROJECTS_DPG_PRODUCT_FE_SPACE_H
2#define PROJECTS_DPG_PRODUCT_FE_SPACE_H
12#include <lf/base/base.h>
14#include <lf/uscalfe/uscalfe.h>
19#include "product_dofhandler.h"
57template <
typename SCALAR>
93 std::shared_ptr<const
lf::mesh::
Mesh> mesh_p,
95 std::shared_ptr<const
lf::fe::ScalarReferenceFiniteElement<SCALAR>>>
98 std::shared_ptr<const
lf::fe::ScalarReferenceFiniteElement<SCALAR>>>
101 std::shared_ptr<const
lf::fe::ScalarReferenceFiniteElement<SCALAR>>>
104 std::shared_ptr<const
lf::fe::ScalarReferenceFiniteElement<SCALAR>>>
118 [[nodiscard]] std::shared_ptr<const lf::mesh::Mesh>
Mesh()
const {
119 LF_ASSERT_MSG(
mesh_p_ !=
nullptr,
"Invalid FE space, no mesh");
127 LF_ASSERT_MSG(
mesh_p_ !=
nullptr,
"Invalid FE space, no mesh");
128 LF_ASSERT_MSG(
dofh_p_ !=
nullptr,
"Invalid FE space, no dofhandler");
162 std::shared_ptr<const lf::uscalfe::UniformScalarFESpace<SCALAR>>
164 return std::make_shared<lf::uscalfe::UniformScalarFESpace<SCALAR>>(
174 std::shared_ptr<const lf::mesh::Mesh>
mesh_p_;
179 std::shared_ptr<const lf::fe::ScalarReferenceFiniteElement<SCALAR>>>
182 std::shared_ptr<const lf::fe::ScalarReferenceFiniteElement<SCALAR>>>
185 std::shared_ptr<const lf::fe::ScalarReferenceFiniteElement<SCALAR>>>
188 std::shared_ptr<const lf::fe::ScalarReferenceFiniteElement<SCALAR>>>
199 std::unique_ptr<ProductUniformFEDofHandler>
dofh_p_;
209template <
typename SCALAR>
212 LF_ASSERT_MSG(mesh_p_ !=
nullptr,
"No mesh");
213 LF_ASSERT_MSG(mesh_p_->DimMesh() == 2,
"Only 2D cells");
220 LF_ASSERT_MSG(numComponents_ != 0,
"0 components FE space.");
221 LF_ASSERT_MSG(numComponents_ == rfs_tria_v_.size() &&
222 numComponents_ == rfs_quad_v_.size() &&
223 numComponents_ == rfs_edge_v_.size() &&
224 numComponents_ == rfs_point_v_.size(),
225 "Missmatch in number of shape functions passed for different "
230 num_rsf_tria_.resize(numComponents_);
231 num_rsf_quad_.resize(numComponents_);
232 num_rsf_edge_.resize(numComponents_);
233 num_rsf_node_.resize(numComponents_);
236 for (
size_type component = 0; component < numComponents_; component++) {
237 num_rsf_tria_[component] = 0;
238 num_rsf_quad_[component] = 0;
239 num_rsf_edge_[component] = 0;
240 num_rsf_node_[component] = 0;
242 if (rfs_tria_v_[component] !=
nullptr) {
245 "wrong type for triangle in component" << component);
247 num_rsf_node_[component] =
248 rfs_tria_v_[component]->NumRefShapeFunctions(2);
249 num_rsf_edge_[component] =
250 rfs_tria_v_[component]->NumRefShapeFunctions(1);
251 num_rsf_tria_[component] =
252 rfs_tria_v_[component]->NumRefShapeFunctions(0);
254 if (rfs_quad_v_[component] !=
nullptr) {
257 "Wrong type for quad in component " << component);
259 num_rsf_node_[component] =
260 rfs_quad_v_[component]->NumRefShapeFunctions(2);
261 num_rsf_edge_[component] =
262 rfs_quad_v_[component]->NumRefShapeFunctions(1);
263 num_rsf_quad_[component] =
264 rfs_quad_v_[component]->NumRefShapeFunctions(0);
266 if (rfs_edge_v_[component] !=
nullptr) {
269 "Wrong type for edge in component " << component);
270 num_rsf_node_[component] =
271 rfs_edge_v_[component]->NumRefShapeFunctions(1);
272 num_rsf_edge_[component] =
273 rfs_edge_v_[component]->NumRefShapeFunctions(0);
279 if ((rfs_tria_v_[component] !=
nullptr) &&
280 (rfs_quad_v_[component] !=
nullptr)) {
281 LF_ASSERT_MSG((rfs_tria_v_[component]->NumRefShapeFunctions(2)) ==
282 (rfs_quad_v_[component]->NumRefShapeFunctions(2)),
283 "#RSF missmatch on nodes in component"
285 << rfs_tria_v_[component]->NumRefShapeFunctions(2)
287 << rfs_quad_v_[component]->NumRefShapeFunctions(2));
288 LF_ASSERT_MSG((rfs_tria_v_[component]->NumRefShapeFunctions(1)) ==
289 (rfs_quad_v_[component]->NumRefShapeFunctions(1)),
290 "#RSF missmatch on edges in component"
292 << rfs_tria_v_[component]->NumRefShapeFunctions(1)
294 << rfs_quad_v_[component]->NumRefShapeFunctions(1));
296 if ((rfs_tria_v_[component] !=
nullptr) &&
297 (rfs_edge_v_[component] !=
nullptr)) {
298 LF_ASSERT_MSG((rfs_tria_v_[component]->NumRefShapeFunctions(2)) ==
299 (rfs_edge_v_[component]->NumRefShapeFunctions(1)),
300 "#RSF missmatch on nodes in component"
302 << rfs_tria_v_[component]->NumRefShapeFunctions(2)
304 << rfs_edge_v_[component]->NumRefShapeFunctions(1));
305 LF_ASSERT_MSG((rfs_tria_v_[component]->NumRefShapeFunctions(1)) ==
306 (rfs_edge_v_[component]->NumRefShapeFunctions(0)),
307 "#RSF missmatch on edges in component"
309 << rfs_tria_v_[component]->NumRefShapeFunctions(1)
311 << rfs_edge_v_[component]->NumRefShapeFunctions(0));
313 if ((rfs_quad_v_[component] !=
nullptr) &&
314 (rfs_edge_v_[component] !=
nullptr)) {
315 LF_ASSERT_MSG((rfs_quad_v_[component]->NumRefShapeFunctions(2)) ==
316 (rfs_edge_v_[component]->NumRefShapeFunctions(1)),
317 "#RSF missmatch on nodes in component"
319 << rfs_quad_v_[component]->NumRefShapeFunctions(2)
321 << rfs_edge_v_[component]->NumRefShapeFunctions(1));
322 LF_ASSERT_MSG((rfs_quad_v_[component]->NumRefShapeFunctions(1)) ==
323 (rfs_edge_v_[component]->NumRefShapeFunctions(0)),
324 "#RSF missmatch on edges in component"
326 << rfs_quad_v_[component]->NumRefShapeFunctions(1)
328 << rfs_edge_v_[component]->NumRefShapeFunctions(0));
335 std::vector<dof_map_t> rsf_layouts(numComponents_);
336 for (
size_type component = 0; component < numComponents_; component++) {
337 rsf_layouts[component] = {
343 dofh_p_ = std::make_unique<ProductUniformFEDofHandler>(mesh_p_, rsf_layouts);
346template <
typename SCALAR>
352 switch (ref_el_type) {
354 return rfs_point_v_[component].get();
359 return rfs_edge_v_[component].get();
364 return rfs_tria_v_[component].get();
370 return rfs_quad_v_[component].get();
373 LF_ASSERT_MSG(
false,
"Illegal entity type");
379template <
typename SCALAR>
384 switch (ref_el_type) {
386 return num_rsf_node_[component];
389 return num_rsf_edge_[component];
392 return num_rsf_tria_[component];
395 return num_rsf_quad_[component];
397 dafault : { LF_ASSERT_MSG(
false,
"Illegal entity type"); }
Represents a reference element with all its properties.
static constexpr RefEl kSegment()
Returns the (1-dimensional) reference segment.
static constexpr RefEl kPoint()
Returns the (0-dimensional) reference point.
static constexpr RefEl kTria()
Returns the reference triangle.
static constexpr RefEl kQuad()
Returns the reference quadrilateral.
Interface class for parametric scalar valued finite elements.
Contains functionality for the implementation of DPG methods.
lf::uscalfe::size_type size_type
Type for vector length/matrix sizes.