DUBeat 1.0.1
High-order discontinuous Galerkin methods and applications to cardiac electrophysiology
Loading...
Searching...
No Matches
dof_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 DOF_HANDLER_DG_HPP_
28#define DOF_HANDLER_DG_HPP_
29
30#include <deal.II/base/quadrature.h>
31
32#include <deal.II/dofs/dof_handler.h>
33
34#include <deal.II/fe/fe.h>
35#include <deal.II/fe/mapping_q1_eulerian.h>
36
37#include <deal.II/lac/trilinos_vector.h>
38
39#include <cmath>
40#include <map>
41#include <vector>
42
43#include "DUBValues.hpp"
44#include "source/init.hpp"
45
46
47using ActiveSelector = dealii::internal::DoFHandlerImplementation::
48 Iterators<lifex::dim, lifex::dim, false>;
49using active_cell_iterator = typename ActiveSelector::active_cell_iterator;
50
64template <class basis>
65class DoFHandlerDG : public dealii::DoFHandler<lifex::dim>
66{
67private:
69 unsigned int degree;
70
72 std::map<active_cell_iterator, std::vector<unsigned int>> dof_map;
73
74public:
77 : dealii::DoFHandler<lifex::dim>()
78 , degree(0)
79 {}
80
83
85 DoFHandlerDG<basis>(const DoFHandlerDG<basis> &DOFHandlerDG) = default;
86
89
91 unsigned int
92 n_dofs_per_cell() const;
93
95 unsigned int
96 n_dofs() const;
97
101 void
102 distribute_dofs(const dealii::FE_SimplexDGP<lifex::dim> &fe);
103
106 void
107 distribute_dofs(const unsigned int degree);
108
110 std::vector<lifex::types::global_dof_index>
112
115 dealii::IndexSet
116 locally_owned_dofs() const;
117};
118
119template <class basis>
120unsigned int
122{
123 AssertThrow(degree > 0,
124 dealii::StandardExceptions::ExcMessage(
125 "Dofs have not been distributed yet. Please, use "
126 "distribute_dofs before."));
127
128 // The analytical formula is:
129 // n_dof_per_cell = (p+1)*(p+2)*...(p+d) / d!,
130 // where p is the space order and d the space dimension..
131
132 unsigned int denominator = 1;
133 unsigned int nominator = 1;
134
135 for (unsigned int i = 1; i <= lifex::dim; i++)
136 {
137 denominator *= i;
138 nominator *= degree + i;
139 }
140
141 return (int)(nominator / denominator);
142}
143
144template <class basis>
145unsigned int
147{
148 AssertThrow(degree > 0,
149 dealii::StandardExceptions::ExcMessage(
150 "Dofs have not been distributed yet. Please, use "
151 "distribute_dofs before."));
152
153 unsigned int n_cells = 0;
154
155 for (const auto &cell : this->active_cell_iterators())
156 n_cells++;
157
158 // The global nuber of dofs is the number of dofs per cell times the total
159 // number of cells since every cell has the same number of dofs.
160 return n_cells * n_dofs_per_cell();
161}
162
163
166template <>
167void
169 const dealii::FE_SimplexDGP<lifex::dim> &fe)
170{
171 AssertThrow(fe.degree < 3,
172 dealii::StandardExceptions::ExcMessage(
173 "deal.II library does not provide yet FEM spaces with "
174 "polynomial order > 2."));
175 degree = fe.degree;
176 dealii::DoFHandler<lifex::dim>::distribute_dofs(fe);
177}
178
182template <>
183void
185 const dealii::FE_SimplexDGP<lifex::dim> &fe)
186{
187 AssertThrow(fe.degree < 3,
188 dealii::StandardExceptions::ExcMessage(
189 "deal.II library does not provide yet FEM spaces with "
190 "polynomial order > 2."));
191 dealii::DoFHandler<lifex::dim>::distribute_dofs(fe);
192 degree = fe.degree;
193
194 std::vector<lifex::types::global_dof_index> dof_indices(
195 this->n_dofs_per_cell());
196 dof_map.clear();
197
198 for (const auto &cell : this->active_cell_iterators())
199 {
200 // In the dof_map, for every cell we assign the global dofs.
201 cell->get_dof_indices(dof_indices);
202 dof_map.emplace(cell, dof_indices);
203 }
204}
205
208template <>
209void
211 const unsigned int degree)
212{
213 AssertThrow(
214 degree,
215 dealii::StandardExceptions::ExcMessage(
216 "deal.II library does not provide yet the Lagrangian DG basis with "
217 "polynomial order > 2."));
218 dealii::FE_SimplexDGP<lifex::dim> fe(degree);
219 this->distribute_dofs(fe);
220}
221
222
227template <>
228void
229DoFHandlerDG<DUBValues<lifex::dim>>::distribute_dofs(const unsigned int degree)
230{
231 this->degree = degree;
232 unsigned int n_dofs_per_cell = this->n_dofs_per_cell();
233 dof_map.clear();
234 unsigned int n = 0;
235 for (const auto &cell : this->active_cell_iterators())
236 {
237 std::vector<unsigned int> local_dofs;
238
239 for (unsigned int i = 0; i < n_dofs_per_cell; ++i)
240 local_dofs.push_back(n + i);
241
242 dof_map.emplace(cell, local_dofs);
243
244 n = n + n_dofs_per_cell;
245 }
246}
247
250template <>
251std::vector<lifex::types::global_dof_index>
253 active_cell_iterator cell) const
254{
255 std::vector<lifex::types::global_dof_index> dof_indices(
256 this->n_dofs_per_cell());
257 cell->get_dof_indices(dof_indices);
258 return dof_indices;
259}
260
261
264template <>
265std::vector<lifex::types::global_dof_index>
267 active_cell_iterator cell) const
268{
269 std::vector<lifex::types::global_dof_index> dof_indices(
270 this->n_dofs_per_cell());
271 dof_indices = dof_map.at(cell);
272 return dof_indices;
273}
274
275template <class basis>
276dealii::IndexSet
278{
279 dealii::IndexSet owned_dofs(this->n_dofs());
280 // For the time being, this function returns all the dofs.
281 owned_dofs.add_range(0, this->n_dofs());
282 return owned_dofs;
283}
284
285
286#endif /* DOF_HANDLER_DG_HPP_*/
Class to work with global and local degrees of freedom and their mapping.
void distribute_dofs(const dealii::FE_SimplexDGP< lifex::dim > &fe)
Distribute dofs through the elements.
void distribute_dofs(const unsigned int degree)
Same method but avoids to use FiniteElement classes that might be invalid with higher order polynomia...
unsigned int n_dofs() const
Return copy of n_dofs.
unsigned int n_dofs_per_cell() const
Return copy of n_dofs_per_cell.
unsigned int degree
Polynomial space degree.
std::map< active_cell_iterator, std::vector< unsigned int > > dof_map
Local to global dof map.
dealii::IndexSet locally_owned_dofs() const
Return a set of all the locally owned dofs (for the time being, it is equivalent to return all the do...
std::vector< lifex::types::global_dof_index > get_dof_indices(active_cell_iterator cell) const
Returns the global dofs referred to the input cell.
typename ActiveSelector::active_cell_iterator active_cell_iterator
dealii::internal::DoFHandlerImplementation::Iterators< lifex::dim, lifex::dim, false > ActiveSelector