DUBeat  1.0.1
High-order discontinuous Galerkin methods and applications to cardiac electrophysiology
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 
47 template <unsigned int dim>
48 class FaceHandlerDG : public VolumeHandlerDG<dim>
49 {
50 private:
52  unsigned int edge;
53 
55  const double tol = 1e-10;
56 
59 
64  std::unique_ptr<dealii::FEFaceValues<dim>> fe_face_values;
65 
66 public:
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
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 
127 template <unsigned int dim>
128 void
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 
140 template <unsigned int dim>
141 dealii::Point<dim>
142 FaceHandlerDG<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 
154 template <unsigned int dim>
155 dealii::Point<dim>
156 FaceHandlerDG<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 
169 template <unsigned int dim>
170 double
171 FaceHandlerDG<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 
183 template <unsigned int dim>
184 int
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 
216 template <unsigned int dim>
217 dealii::Tensor<1, dim>
219 {
220  AssertThrow(this->initialized,
221  dealii::StandardExceptions::ExcNotInitialized());
222 
223  return fe_face_values->normal_vector(0);
224 }
225 
228 template <>
229 double
231 {
232  AssertThrow(this->initialized,
233  dealii::StandardExceptions::ExcNotInitialized());
234 
235  return this->cell->face(edge)->measure();
236 }
237 
241 template <>
242 double
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.
typename ActiveSelector::active_cell_iterator active_cell_iterator