LehrFEM++ 1.0.0
A simple Finite Element Library for teaching
norms.h
1#ifndef THESIS_POST_PROCESSING_NORMS_H
2#define THESIS_POST_PROCESSING_NORMS_H
3
10#include <lf/fe/fe.h>
11#include <lf/mesh/entity.h>
12#include <lf/mesh/mesh.h>
13#include <lf/mesh/utils/utils.h>
14#include <lf/quad/quad.h>
15#include <lf/uscalfe/uscalfe.h>
16#include <utils.h>
17
18#include <functional>
19
20namespace projects::ipdg_stokes {
21
22namespace post_processing {
23
39template <typename MF, typename QR_SELECTOR>
40double L2norm(const std::shared_ptr<const lf::mesh::Mesh> &mesh, const MF &f,
41 const QR_SELECTOR &qr_selector) {
42 return std::sqrt(lf::fe::IntegrateMeshFunction(
43 *mesh, lf::mesh::utils::squaredNorm(f), qr_selector));
44}
45
67template <typename MF_F, typename MF_GRAD, typename QR_SELECTOR>
68double DGnorm(const std::shared_ptr<const lf::mesh::Mesh> &mesh, const MF_F &f,
69 const MF_GRAD &f_grad, const QR_SELECTOR &qr_selector) {
70 double norm2 = 0;
71 // Compute the DG norm on the elements
73 *mesh, lf::mesh::utils::squaredNorm(f_grad), qr_selector);
74 // Compute the norm on the edges
75 const auto boundary = lf::mesh::utils::flagEntitiesOnBoundary(mesh, 1);
76 using jump_t = std::remove_cv_t<decltype(
77 (std::declval<lf::mesh::utils::MeshFunctionReturnType<MF_F>>() *
78 std::declval<Eigen::Vector2d>().transpose())
79 .eval())>;
81 for (const auto entity : mesh->Entities(0)) {
82 const auto edges = entity->SubEntities(1);
83 const auto orientations = entity->RelativeOrientations();
84 const auto normals =
86 std::array<lf::quad::QuadRule, 3> quadrules;
87 std::array<Eigen::MatrixXd, 3> quadpoints;
88 for (int i = 0; i < 3; ++i) {
89 quadrules[i] = qr_selector(*edges[i]);
90 quadpoints[i] = Eigen::MatrixXd(2, quadrules[i].NumPoints());
91 }
92 quadpoints[0] << quadrules[0].Points(),
93 Eigen::VectorXd::Zero(quadrules[0].NumPoints());
94 quadpoints[1] << Eigen::VectorXd::Ones(quadrules[1].NumPoints()) -
95 quadrules[1].Points(),
96 quadrules[1].Points();
97 quadpoints[2] << Eigen::VectorXd::Zero(quadrules[2].NumPoints()),
98 Eigen::VectorXd::Ones(quadrules[2].NumPoints()) - quadrules[2].Points();
99 for (int i = 0; i < 3; ++i) {
100 const auto edge = edges[i];
101 const auto segment_eval = f(*entity, quadpoints[i]);
102 if (orientations[i] == lf::mesh::Orientation::positive) {
103 if (eval(*edge).size() == 0) {
104 eval(*edge).resize(segment_eval.size());
105 for (int j = 0; j < segment_eval.size(); ++j) {
106 eval(*edge)[j] = segment_eval[j] * normals.col(i).transpose();
107 }
108 } else {
109 for (int j = 0; j < segment_eval.size(); ++j) {
110 eval(*edge)[j] += segment_eval[j] * normals.col(i).transpose();
111 }
112 }
113 } else {
114 if (eval(*edge).size() == 0) {
115 eval(*edge).resize(segment_eval.size());
116 for (int j = 0; j < segment_eval.size(); ++j) {
117 eval(*edge)[j] = segment_eval[segment_eval.size() - j - 1] *
118 normals.col(i).transpose();
119 }
120 } else {
121 for (int j = 0; j < segment_eval.size(); ++j) {
122 eval(*edge)[j] += segment_eval[segment_eval.size() - j - 1] *
123 normals.col(i).transpose();
124 }
125 }
126 }
127 }
128 }
129 for (const auto edge : mesh->Entities(1)) {
130 if (!boundary(*edge)) {
131 const auto qr = qr_selector(*edge);
132 const auto geom = edge->Geometry();
133 const auto ie = geom->IntegrationElement(qr.Points());
134 const Eigen::VectorXd weights =
135 (qr.Weights().array() * ie.array()).matrix() /
137 const auto &p = eval(*edge);
138 for (int i = 0; i < p.size(); ++i) {
139 norm2 += weights[i] * p[i].squaredNorm();
140 }
141 }
142 }
143 return std::sqrt(norm2);
144}
145
146} // end namespace post_processing
147
148} // end namespace projects::ipdg_stokes
149
150#endif // THESIS_POST_PROCESSING_NORMS_H
A MeshDataSet that attaches data of type T to every entity of a mesh that has a specified codimension...
auto IntegrateMeshFunction(const lf::mesh::Mesh &mesh, const MF &mf, const QR_SELECTOR &qr_selector, const ENTITY_PREDICATE &ep=base::PredicateTrue{}, int codim=0) -> mesh::utils::MeshFunctionReturnType< MF >
Integrate a MeshFunction over a mesh (with quadrature rules)
Definition: fe_tools.h:111
double Volume(const Geometry &geo)
Compute the (approximate) volume (area) of a shape.
CodimMeshDataSet< bool > flagEntitiesOnBoundary(const std::shared_ptr< const Mesh > &mesh_p, lf::base::dim_t codim)
flag entities of a specific co-dimension located on the boundary
Eigen::Matrix< double, 2, 3 > computeOutwardNormals(const lf::mesh::Entity &entity)
Compute the outward pointing normals of a triangle.
Definition: utils.cc:7
double DGnorm(const std::shared_ptr< const lf::mesh::Mesh > &mesh, const MF_F &f, const MF_GRAD &f_grad, const QR_SELECTOR &qr_selector)
Compute the DG-norm of a vector valued function over a mesh.
Definition: norms.h:68
double L2norm(const std::shared_ptr< const lf::mesh::Mesh > &mesh, const MF &f, const QR_SELECTOR &qr_selector)
Compute the -norm of a vector valued function over a mesh.
Definition: norms.h:40