ExaDG
Loading...
Searching...
No Matches
finite_element.h
1/* ______________________________________________________________________
2 *
3 * ExaDG - High-Order Discontinuous Galerkin for the Exa-Scale
4 *
5 * Copyright (C) 2023 by the ExaDG authors
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * ______________________________________________________________________
20 */
21
22#ifndef INCLUDE_EXADG_OPERATORS_FINITE_ELEMENT_H_
23#define INCLUDE_EXADG_OPERATORS_FINITE_ELEMENT_H_
24
25// deal.II
26#include <deal.II/fe/fe_dgq.h>
27#include <deal.II/fe/fe_q.h>
28#include <deal.II/fe/fe_simplex_p.h>
29#include <deal.II/fe/fe_system.h>
30
31// ExaDG
32#include <exadg/grid/grid_data.h>
33#include <exadg/utilities/exceptions.h>
34
35namespace ExaDG
36{
43template<int dim>
44std::shared_ptr<dealii::FiniteElement<dim>>
45create_finite_element(ElementType const & element_type,
46 bool const is_dg,
47 unsigned int const n_components,
48 unsigned int const degree)
49{
50 std::shared_ptr<dealii::FiniteElement<dim>> fe;
51
52 // For n_components = 1, we would not need FESystem around the finite element. We do this
53 // nevertheless in order to use the same code path for all cases, since this is not a
54 // performance-critical part of the code.
55
56 if(is_dg)
57 {
58 if(element_type == ElementType::Hypercube)
59 {
60 fe = std::make_shared<dealii::FESystem<dim>>(dealii::FE_DGQ<dim>(degree), n_components);
61 }
62 else if(element_type == ElementType::Simplex)
63 {
64 fe =
65 std::make_shared<dealii::FESystem<dim>>(dealii::FE_SimplexDGP<dim>(degree), n_components);
66 }
67 else
68 {
69 AssertThrow(false, ExcNotImplemented());
70 }
71 }
72 else
73 {
74 if(element_type == ElementType::Hypercube)
75 {
76 fe = std::make_shared<dealii::FESystem<dim>>(dealii::FE_Q<dim>(degree), n_components);
77 }
78 else if(element_type == ElementType::Simplex)
79 {
80 fe = std::make_shared<dealii::FESystem<dim>>(dealii::FE_SimplexP<dim>(degree), n_components);
81 }
82 else
83 {
84 AssertThrow(false, ExcNotImplemented());
85 }
86 }
87
88 return fe;
89}
90
91inline unsigned int
92get_dofs_per_element(ExaDG::ElementType const element_type,
93 bool const is_dg,
94 unsigned int const n_components,
95 unsigned int const degree,
96 unsigned int const dim)
97{
98 unsigned int scalar_dofs_per_element = 1;
99
100 unsigned int n_points_1d = degree;
101
102 if(is_dg)
103 n_points_1d += 1;
104
105 if(element_type == ElementType::Hypercube)
106 {
107 scalar_dofs_per_element = dealii::Utilities::pow(n_points_1d, dim);
108 }
109 else if(element_type == ElementType::Simplex)
110 {
111 for(unsigned int d = 0; d < dim; ++d)
112 scalar_dofs_per_element = (scalar_dofs_per_element * (n_points_1d + d)) / (d + 1);
113 }
114 else
115 {
116 AssertThrow(false, ExcNotImplemented());
117 }
118
119 return scalar_dofs_per_element * n_components;
120}
121
122} // namespace ExaDG
123
124
125
126#endif /* INCLUDE_EXADG_OPERATORS_FINITE_ELEMENT_H_ */
Definition driver.cpp:33
std::shared_ptr< dealii::FiniteElement< dim > > create_finite_element(ElementType const &element_type, bool const is_dg, unsigned int const n_components, unsigned int const degree)
Definition finite_element.h:45