DUBeat 1.0.1
High-order discontinuous Galerkin methods and applications to cardiac electrophysiology
Loading...
Searching...
No Matches
face_handler_DG.hpp
Go to the documentation of this file.
1/********************************************************************************
2 Copyright (C) 2024 by the DUBeat authors.
3
4 This file is part of DUBeat.
5
6 DUBeat is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 DUBeat is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with DUBeat. If not, see <http://www.gnu.org/licenses/>.
18********************************************************************************/
19
27#ifndef FACE_HANDLER_DG_HPP_
28#define FACE_HANDLER_DG_HPP_
29
30#include <deal.II/base/quadrature_lib.h>
31#include <deal.II/base/tensor.h>
32
33#include <deal.II/fe/fe.h>
34#include <deal.II/fe/fe_q.h>
35
36#include <cmath>
37#include <memory>
38#include <utility>
39
41#include "volume_handler_DG.hpp"
42
47template <unsigned int dim>
48class FaceHandlerDG : public VolumeHandlerDG<dim>
49{
50private:
52 unsigned int edge;
53
55 const double tol = 1e-10;
56
59
64 std::unique_ptr<dealii::FEFaceValues<dim>> fe_face_values;
65
66public:
68 FaceHandlerDG<dim>(const unsigned int degree)
69 : VolumeHandlerDG<dim>(degree)
71 , fe_face_values(std::make_unique<dealii::FEFaceValues<dim>>(
72 *(this->mapping),
73 *(this->fe_dg),
75 dealii::update_quadrature_points | dealii::update_normal_vectors |
76 dealii::update_JxW_values | dealii::update_jacobians))
77 {}
78
81
84
87
89 void
90 reinit(const typename dealii::DoFHandler<dim>::active_cell_iterator &new_cell,
91 const unsigned int new_edge);
92
95 dealii::Point<dim>
96 quadrature_real(const unsigned int q) const override;
97
100 dealii::Point<dim>
101 quadrature_ref(const unsigned int q) const override;
102
105 double
106 quadrature_weight(const unsigned int q) const override;
107
110 int
112 const unsigned int q,
113 const FaceHandlerDG<dim> &FaceHandlerDG_neigh) const;
114
116 dealii::Tensor<1, dim>
117 get_normal() const;
118
120 double
121 get_measure() const;
122
124 virtual ~FaceHandlerDG() = default;
125};
126
127template <unsigned int dim>
128void
130 const typename dealii::DoFHandler<dim>::active_cell_iterator &new_cell,
131 const unsigned int new_edge)
132{
133 this->cell = new_cell;
134 edge = new_edge;
135 fe_face_values->reinit(new_cell, new_edge);
136 this->fe_values->reinit(new_cell);
137 this->initialized = true;
138}
139
140template <unsigned int dim>
141dealii::Point<dim>
142FaceHandlerDG<dim>::quadrature_real(const unsigned int q) const
143{
144 AssertThrow(this->initialized,
145 dealii::StandardExceptions::ExcNotInitialized());
146
147 AssertThrow(q < pow(this->n_quad_points_1D, dim - 1),
148 dealii::StandardExceptions::ExcMessage(
149 "Index of quadrature point outside the limit."));
150
151 return fe_face_values->quadrature_point(q);
152}
153
154template <unsigned int dim>
155dealii::Point<dim>
156FaceHandlerDG<dim>::quadrature_ref(const unsigned int q) const
157{
158 AssertThrow(this->initialized,
159 dealii::StandardExceptions::ExcNotInitialized());
160
161 AssertThrow(q < pow(this->n_quad_points_1D, dim - 1),
162 dealii::StandardExceptions::ExcMessage(
163 "Index of quadrature point outside the limit."));
164
165 return this->mapping->transform_real_to_unit_cell(this->cell,
166 quadrature_real(q));
167}
168
169template <unsigned int dim>
170double
171FaceHandlerDG<dim>::quadrature_weight(const unsigned int q) const
172{
173 AssertThrow(this->initialized,
174 dealii::StandardExceptions::ExcNotInitialized());
175
176 AssertThrow(q < pow(this->n_quad_points_1D, dim - 1),
177 dealii::StandardExceptions::ExcMessage(
178 "Index of quadrature point outside the limit."));
179
180 return QGLpoints_face.weight(q);
181}
182
183template <unsigned int dim>
184int
186 const unsigned int q,
187 const FaceHandlerDG<dim> &FaceHandlerDG_neigh) const
188{
189 AssertThrow(this->initialized,
190 dealii::StandardExceptions::ExcNotInitialized());
191
192 AssertThrow(q < pow(this->n_quad_points_1D, dim - 1),
193 dealii::StandardExceptions::ExcMessage(
194 "Index of quadrature point outside the limit."));
195
196 const unsigned int n_quad_points_face =
197 static_cast<int>(std::pow(this->n_quad_points_1D, dim - 1));
198 const dealii::Point<dim> P_q = quadrature_real(q);
199
200 int quad = -1;
201 for (unsigned int nq = 0; nq < n_quad_points_face; ++nq)
202 {
203 const dealii::Point<dim> P_nq = FaceHandlerDG_neigh.quadrature_real(nq);
204
205 // If the distance between P_nq and P_q is negligible, then we have found
206 // the corresponding quadrature point on the neighbor element.
207 if ((P_nq - P_q).norm() < tol)
208 {
209 quad = nq;
210 }
211 }
212
213 return quad;
214}
215
216template <unsigned int dim>
217dealii::Tensor<1, dim>
219{
220 AssertThrow(this->initialized,
221 dealii::StandardExceptions::ExcNotInitialized());
222
223 return fe_face_values->normal_vector(0);
224}
225
228template <>
229double
231{
232 AssertThrow(this->initialized,
233 dealii::StandardExceptions::ExcNotInitialized());
234
235 return this->cell->face(edge)->measure();
236}
237
241template <>
242double
244{
245 AssertThrow(this->initialized,
246 dealii::StandardExceptions::ExcNotInitialized());
247
248 const auto face = this->cell->face(edge);
249
250 // Semi-perimeter of the triangle.
251 const double semi_per = (face->line(0)->measure() + face->line(1)->measure() +
252 face->line(2)->measure()) /
253 2;
254
255 // Erone's formula.
256 return std::sqrt(semi_per * (semi_per - face->line(0)->measure()) *
257 (semi_per - face->line(1)->measure()) *
258 (semi_per - face->line(2)->measure()));
259}
260
261#endif /* FACE_HANDLER_DG_HPP_*/
Class for the main operations on the faces of a discontinuous Galerkin element.
virtual ~FaceHandlerDG()=default
Destructor.
dealii::Point< dim > quadrature_ref(const unsigned int q) const override
Return the -th spatial quadrature point position on the reference element.
const double tol
Default tolerance.
dealii::Tensor< 1, dim > get_normal() const
Outward normal vector on the current element and face.
unsigned int edge
Index of the actual face.
double quadrature_weight(const unsigned int q) const override
Return the quadrature weight associated to the -th quadrature point.
double get_measure() const
Measure of face.
dealii::Point< dim > quadrature_real(const unsigned int q) const override
Return the -th spatial quadrature point position on the actual element.
std::unique_ptr< dealii::FEFaceValues< dim > > fe_face_values
Internal FEM basis class for face elements.
const QGaussLegendreSimplex< dim - 1 > QGLpoints_face
Quadrature formula for face elements.
int corresponding_neigh_index(const unsigned int q, const FaceHandlerDG< dim > &FaceHandlerDG_neigh) const
To manually obtain the associated quadrature point index in the neighbor element on the shared face.
void reinit(const typename dealii::DoFHandler< dim >::active_cell_iterator &new_cell, const unsigned int new_edge)
Reinit objects on the current new_cell and new_edge.
Class representing the Gauss-Legendre quadrature formula on simplex elements.
Class for the main operations on a discontinuous Galerkin volume element.
const std::unique_ptr< dealii::MappingFE< dim > > mapping
Mapping of the discretized space, needed for geometrical reference-to-actual operations.
const unsigned int n_quad_points_1D
Number of quadrature points in one dimensional elements.
const std::unique_ptr< dealii::FE_SimplexDGP< dim > > fe_dg
Internal Lagrangian basis class.