deal.II version 9.7.0
\(\newcommand{\dealvcentcolon}{\mathrel{\mathop{:}}}\) \(\newcommand{\dealcoloneq}{\dealvcentcolon\mathrel{\mkern-1.2mu}=}\) \(\newcommand{\jump}[1]{\left[\!\left[ #1 \right]\!\right]}\) \(\newcommand{\average}[1]{\left\{\!\left\{ #1 \right\}\!\right\}}\)
Loading...
Searching...
No Matches
fe_q_dg0.cc
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2//
3// SPDX-License-Identifier: LGPL-2.1-or-later
4// Copyright (C) 2012 - 2025 by the deal.II authors
5//
6// This file is part of the deal.II library.
7//
8// Part of the source code is dual licensed under Apache-2.0 WITH
9// LLVM-exception OR LGPL-2.1-or-later. Detailed license information
10// governing the source code and code contributions can be found in
11// LICENSE.md and CONTRIBUTING.md at the top level directory of deal.II.
12//
13// ------------------------------------------------------------------------
14
15
19
21
22#include <deal.II/fe/fe_dgq.h>
24#include <deal.II/fe/fe_q_dg0.h>
25
26#include <memory>
27#include <sstream>
28#include <vector>
29
31
32
33template <int dim, int spacedim>
35 : FE_Q_Base<dim, spacedim>(TensorProductPolynomialsConst<dim>(
36 Polynomials::generate_complete_Lagrange_basis(
37 QGaussLobatto<1>(degree + 1).get_points())),
39 1,
40 degree,
41 FiniteElementData<dim>::L2),
43{
44 Assert(degree > 0,
45 ExcMessage("This element can only be used for polynomial degrees "
46 "greater than zero"));
47
48 this->initialize(QGaussLobatto<1>(degree + 1).get_points());
49
50 // adjust unit support point for discontinuous node
51 Point<dim> point;
52 for (unsigned int d = 0; d < dim; ++d)
53 point[d] = 0.5;
54 this->unit_support_points.push_back(point);
56}
57
58
59
60template <int dim, int spacedim>
62 : FE_Q_Base<dim, spacedim>(
64 Polynomials::generate_complete_Lagrange_basis(points.get_points())),
65 FiniteElementData<dim>(get_dpo_vector(points.size() - 1),
66 1,
67 points.size() - 1,
68 FiniteElementData<dim>::L2),
69 get_riaf_vector(points.size() - 1))
70{
71 const int degree = points.size() - 1;
72 Assert(degree > 0,
73 ExcMessage("This element can only be used for polynomial degrees "
74 "at least zero"));
75
76 this->initialize(points.get_points());
77
78 // adjust unit support point for discontinuous node
79 Point<dim> point;
80 for (unsigned int d = 0; d < dim; ++d)
81 point[d] = 0.5;
82 this->unit_support_points.push_back(point);
84}
85
86
87
88template <int dim, int spacedim>
89std::string
91{
92 // note that the FETools::get_fe_by_name function depends on the
93 // particular format of the string this function returns, so they have to be
94 // kept in synch
95
96 std::ostringstream namebuf;
97 bool type = true;
98 const unsigned int n_points = this->degree + 1;
99 std::vector<double> points(n_points);
100 const unsigned int dofs_per_cell = this->n_dofs_per_cell();
101 const std::vector<Point<dim>> &unit_support_points =
102 this->unit_support_points;
103 unsigned int index = 0;
104
105 // Decode the support points in one coordinate direction.
106 for (unsigned int j = 0; j < dofs_per_cell; ++j)
107 {
108 if ((dim > 1) ? (unit_support_points[j][1] == 0 &&
109 ((dim > 2) ? unit_support_points[j][2] == 0 : true)) :
110 true)
111 {
112 if (index == 0)
113 points[index] = unit_support_points[j][0];
114 else if (index == 1)
115 points[n_points - 1] = unit_support_points[j][0];
116 else
117 points[index - 1] = unit_support_points[j][0];
118
119 ++index;
120 }
121 }
122 // Do not consider the discontinuous node for dimension 1
123 Assert(index == n_points || (dim == 1 && index == n_points + 1),
125 "Could not decode support points in one coordinate direction."));
126
127 // Check whether the support points are equidistant.
128 for (unsigned int j = 0; j < n_points; ++j)
129 if (std::fabs(points[j] - static_cast<double>(j) / this->degree) > 1e-15)
130 {
131 type = false;
132 break;
133 }
134
135 if (type == true)
136 {
137 if (this->degree > 2)
138 namebuf << "FE_Q_DG0<" << Utilities::dim_string(dim, spacedim)
139 << ">(QIterated(QTrapezoid()," << this->degree << "))";
140 else
141 namebuf << "FE_Q_DG0<" << Utilities::dim_string(dim, spacedim) << ">("
142 << this->degree << ")";
143 }
144 else
145 {
146 // Check whether the support points come from QGaussLobatto.
147 const QGaussLobatto<1> points_gl(n_points);
148 type = true;
149 for (unsigned int j = 0; j < n_points; ++j)
150 if (points[j] != points_gl.point(j)[0])
151 {
152 type = false;
153 break;
154 }
155 if (type == true)
156 namebuf << "FE_Q_DG0<" << Utilities::dim_string(dim, spacedim) << ">("
157 << this->degree << ")";
158 else
159 namebuf << "FE_Q_DG0<" << Utilities::dim_string(dim, spacedim)
160 << ">(QUnknownNodes(" << this->degree << "))";
161 }
162 return namebuf.str();
163}
164
165
166
167template <int dim, int spacedim>
168std::unique_ptr<FiniteElement<dim, spacedim>>
170{
171 return std::make_unique<FE_Q_DG0<dim, spacedim>>(*this);
172}
173
174
175
176template <int dim, int spacedim>
177void
179 const std::vector<Vector<double>> &support_point_values,
180 std::vector<double> &nodal_dofs) const
181{
182 Assert(support_point_values.size() == this->unit_support_points.size(),
183 ExcDimensionMismatch(support_point_values.size(),
184 this->unit_support_points.size()));
185 Assert(nodal_dofs.size() == this->n_dofs_per_cell(),
186 ExcDimensionMismatch(nodal_dofs.size(), this->n_dofs_per_cell()));
187 Assert(support_point_values[0].size() == this->n_components(),
188 ExcDimensionMismatch(support_point_values[0].size(),
189 this->n_components()));
190
191 for (unsigned int i = 0; i < this->n_dofs_per_cell() - 1; ++i)
192 {
193 const std::pair<unsigned int, unsigned int> index =
195 nodal_dofs[i] = support_point_values[i](index.first);
196 }
197
198 // We don't need the discontinuous function for local interpolation
199 nodal_dofs.back() = 0.;
200}
201
202
203
204template <int dim, int spacedim>
205void
207 const FiniteElement<dim, spacedim> &x_source_fe,
208 FullMatrix<double> &interpolation_matrix) const
209{
210 // this is only implemented, if the source FE is also a Q_DG0 element
211 using FEQDG0 = FE_Q_DG0<dim, spacedim>;
212
214 (x_source_fe.get_name().find("FE_Q_DG0<") == 0) ||
215 (dynamic_cast<const FEQDG0 *>(&x_source_fe) != nullptr),
217
218 Assert(interpolation_matrix.m() == this->n_dofs_per_cell(),
219 ExcDimensionMismatch(interpolation_matrix.m(),
220 this->n_dofs_per_cell()));
221 Assert(interpolation_matrix.n() == x_source_fe.n_dofs_per_cell(),
222 ExcDimensionMismatch(interpolation_matrix.m(),
223 x_source_fe.n_dofs_per_cell()));
224
226 x_source_fe, interpolation_matrix);
227}
228
229
230
231template <int dim, int spacedim>
232std::vector<bool>
234{
235 std::vector<bool> riaf(Utilities::fixed_power<dim>(deg + 1) + 1, false);
236 riaf.back() = true;
237 return riaf;
238}
239
240
241
242template <int dim, int spacedim>
243std::vector<unsigned int>
245{
246 std::vector<unsigned int> dpo(dim + 1, 1U);
247 for (unsigned int i = 1; i < dpo.size(); ++i)
248 dpo[i] = dpo[i - 1] * (deg - 1);
249
250 dpo[dim]++; // we need an additional DG0-node for a dim-dimensional object
251 return dpo;
252}
253
254
255
256template <int dim, int spacedim>
257bool
259 const unsigned int shape_index,
260 const unsigned int face_index) const
261{
262 // discontinuous function has support on all faces
263 if (shape_index == this->n_dofs_per_cell() - 1)
264 return true;
265 else
267 face_index);
268}
269
270
271
272template <int dim, int spacedim>
273std::pair<Table<2, bool>, std::vector<unsigned int>>
275{
276 Table<2, bool> constant_modes(2, this->n_dofs_per_cell());
277
278 // 1 represented by FE_Q part
279 for (unsigned int i = 0; i < this->n_dofs_per_cell() - 1; ++i)
280 constant_modes(0, i) = true;
281
282 // 1 represented by DG0 part
283 constant_modes(1, this->n_dofs_per_cell() - 1) = true;
284
285 return std::pair<Table<2, bool>, std::vector<unsigned int>>(
286 constant_modes, std::vector<unsigned int>(2, 0));
287}
288
289
290
291template <int dim, int spacedim>
294 const FiniteElement<dim, spacedim> &fe_other,
295 const unsigned int codim) const
296{
297 Assert(codim <= dim, ExcImpossibleInDim(dim));
298
299 // vertex/line/face domination
300 // (if fe_other is derived from FE_DGQ)
301 // ------------------------------------
302 if (codim > 0)
303 if (dynamic_cast<const FE_DGQ<dim, spacedim> *>(&fe_other) != nullptr)
304 // there are no requirements between continuous and discontinuous elements
306
307 // vertex/line/face domination
308 // (if fe_other is not derived from FE_DGQ)
309 // & cell domination
310 // ----------------------------------------
311 if (const FE_Q_DG0<dim, spacedim> *fe_dg0_other =
312 dynamic_cast<const FE_Q_DG0<dim, spacedim> *>(&fe_other))
313 {
314 if (this->degree < fe_dg0_other->degree)
316 else if (this->degree == fe_dg0_other->degree)
318 else
320 }
321 else if (const FE_Nothing<dim> *fe_nothing =
322 dynamic_cast<const FE_Nothing<dim> *>(&fe_other))
323 {
324 if (fe_nothing->is_dominating())
326 else
327 // the FE_Nothing has no degrees of freedom and it is typically used
328 // in a context where we don't require any continuity along the
329 // interface
331 }
332
335}
336
337
338// explicit instantiations
339#include "fe/fe_q_dg0.inst"
340
virtual void get_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const override
void initialize(const std::vector< Point< 1 > > &support_points_1d)
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const override
FE_Q_Base(const ScalarPolynomialsBase< dim > &poly_space, const FiniteElementData< dim > &fe_data, const std::vector< bool > &restriction_is_additive_flags)
virtual void get_interpolation_matrix(const FiniteElement< dim, spacedim > &source, FullMatrix< double > &matrix) const override
Definition fe_q_dg0.cc:206
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
Definition fe_q_dg0.cc:169
virtual std::pair< Table< 2, bool >, std::vector< unsigned int > > get_constant_modes() const override
Definition fe_q_dg0.cc:274
FE_Q_DG0(const unsigned int p)
Definition fe_q_dg0.cc:34
virtual std::string get_name() const override
Definition fe_q_dg0.cc:90
static std::vector< bool > get_riaf_vector(const unsigned int degree)
Definition fe_q_dg0.cc:233
virtual bool has_support_on_face(const unsigned int shape_index, const unsigned int face_index) const override
Definition fe_q_dg0.cc:258
virtual void convert_generalized_support_point_values_to_dof_values(const std::vector< Vector< double > > &support_point_values, std::vector< double > &nodal_values) const override
Definition fe_q_dg0.cc:178
virtual FiniteElementDomination::Domination compare_for_domination(const FiniteElement< dim, spacedim > &fe_other, const unsigned int codim=0) const override final
Definition fe_q_dg0.cc:293
static std::vector< unsigned int > get_dpo_vector(const unsigned int degree)
Definition fe_q_dg0.cc:244
const unsigned int degree
Definition fe_data.h:452
unsigned int n_dofs_per_cell() const
unsigned int n_components() const
const unsigned int dofs_per_cell
Definition fe_data.h:436
virtual std::string get_name() const =0
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
FiniteElement(const FiniteElementData< dim > &fe_data, const std::vector< bool > &restriction_is_additive_flags, const std::vector< ComponentMask > &nonzero_components)
std::vector< Point< dim > > unit_support_points
Definition fe.h:2562
size_type n() const
size_type m() const
Definition point.h:113
const std::vector< Point< dim > > & get_points() const
unsigned int size() const
#define DEAL_II_NAMESPACE_OPEN
Definition config.h:40
#define DEAL_II_NAMESPACE_CLOSE
Definition config.h:41
#define DEAL_II_NOT_IMPLEMENTED()
#define Assert(cond, exc)
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
#define AssertDimension(dim1, dim2)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
static ::ExceptionBase & ExcInterpolationNotImplemented()
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
std::string dim_string(const int dim, const int spacedim)
Definition utilities.cc:551
constexpr T fixed_power(const T t)
Definition utilities.h:943