Reference documentation for deal.II version 9.3.3
\(\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\}}\)
fe_pyramid_p.cc
Go to the documentation of this file.
1// ---------------------------------------------------------------------
2//
3// Copyright (C) 2020 - 2021 by the deal.II authors
4//
5// This file is part of the deal.II library.
6//
7// The deal.II library is free software; you can use it, redistribute
8// it, and/or modify it under the terms of the GNU Lesser General
9// Public License as published by the Free Software Foundation; either
10// version 2.1 of the License, or (at your option) any later version.
11// The full text of the license can be found in the file LICENSE.md at
12// the top level directory of deal.II.
13//
14// ---------------------------------------------------------------------
15
16#include <deal.II/base/config.h>
17
20
21#include <deal.II/fe/fe_dgq.h>
24#include <deal.II/fe/fe_q.h>
27#include <deal.II/fe/fe_tools.h>
29
31
32namespace
33{
38 get_dpo_vector_fe_pyramid_p(const unsigned int degree)
39 {
42 if (degree == 1)
43 {
44 dpo.dofs_per_object_exclusive = {{1}, {0}, {0, 0, 0, 0, 0}, {0}};
45 dpo.dofs_per_object_inclusive = {{1}, {2}, {4, 3, 3, 3, 3}, {5}};
46 dpo.object_index = {{}, {5}, {5}, {5}};
47 dpo.first_object_index_on_face = {{}, {4, 3, 3, 3, 3}, {4, 3, 3, 3, 3}};
48 }
49 else
50 {
51 Assert(false, ExcNotImplemented());
52 }
53
54 return dpo;
55 }
56
61 get_dpo_vector_fe_pyramid_dgp(const unsigned int degree)
62 {
63 unsigned int n_dofs = 0;
64
65 if (degree == 1)
66 n_dofs = 5;
67 else
68 Assert(false, ExcNotImplemented());
69
70 return internal::expand(3, {{0, 0, 0, n_dofs}}, ReferenceCells::Pyramid);
71 }
72} // namespace
73
74
75template <int dim, int spacedim>
77 const unsigned int degree,
79 const typename FiniteElementData<dim>::Conformity conformity)
80 : ::FE_Poly<dim, spacedim>(
82 FiniteElementData<dim>(dpos,
84 1,
85 degree,
86 conformity),
87 std::vector<bool>(
88 FiniteElementData<dim>(dpos, ReferenceCells::Pyramid, 1, degree)
89 .dofs_per_cell,
90 true),
91 std::vector<ComponentMask>(
92 FiniteElementData<dim>(dpos, ReferenceCells::Pyramid, 1, degree)
93 .dofs_per_cell,
94 std::vector<bool>(1, true)))
95{
96 AssertDimension(dim, 3);
97
98
99 if (degree == 1)
100 {
101 this->unit_support_points.emplace_back(-1.0, -1.0, 0.0);
102 this->unit_support_points.emplace_back(+1.0, -1.0, 0.0);
103 this->unit_support_points.emplace_back(-1.0, +1.0, 0.0);
104 this->unit_support_points.emplace_back(+1.0, +1.0, 0.0);
105 this->unit_support_points.emplace_back(+0.0, +0.0, 1.0);
106 }
107}
108
109
110
111template <int dim, int spacedim>
113 : FE_PyramidPoly<dim, spacedim>(degree,
114 get_dpo_vector_fe_pyramid_p(degree),
115 FiniteElementData<dim>::H1)
116{}
117
118
119
120template <int dim, int spacedim>
121std::unique_ptr<FiniteElement<dim, spacedim>>
123{
124 return std::make_unique<FE_PyramidP<dim, spacedim>>(*this);
125}
126
127
128
129template <int dim, int spacedim>
130std::string
132{
133 std::ostringstream namebuf;
134 namebuf << "FE_PyramidP<" << dim << ">(" << this->degree << ")";
135
136 return namebuf.str();
137}
138
139
140
141template <int dim, int spacedim>
144 const FiniteElement<dim, spacedim> &fe_other,
145 const unsigned int codim) const
146{
147 Assert(codim <= dim, ExcImpossibleInDim(dim));
148
149 // vertex/line/face domination
150 // (if fe_other is derived from FE_SimplexDGP)
151 // ------------------------------------
152 if (codim > 0)
153 if (dynamic_cast<const FE_SimplexDGP<dim, spacedim> *>(&fe_other) !=
154 nullptr)
155 // there are no requirements between continuous and discontinuous
156 // elements
158
159 // vertex/line/face domination
160 // (if fe_other is not derived from FE_SimplexDGP)
161 // & cell domination
162 // ----------------------------------------
163 if (const FE_PyramidP<dim, spacedim> *fe_pp_other =
164 dynamic_cast<const FE_PyramidP<dim, spacedim> *>(&fe_other))
165 {
166 if (this->degree < fe_pp_other->degree)
168 else if (this->degree == fe_pp_other->degree)
170 else
172 }
173 else if (const FE_SimplexP<dim, spacedim> *fe_p_other =
174 dynamic_cast<const FE_SimplexP<dim, spacedim> *>(&fe_other))
175 {
176 if (this->degree < fe_p_other->degree)
178 else if (this->degree == fe_p_other->degree)
180 else
182 }
183 else if (const FE_Q<dim, spacedim> *fe_q_other =
184 dynamic_cast<const FE_Q<dim, spacedim> *>(&fe_other))
185 {
186 if (this->degree < fe_q_other->degree)
188 else if (this->degree == fe_q_other->degree)
190 else
192 }
193 else if (const FE_Nothing<dim, spacedim> *fe_nothing =
194 dynamic_cast<const FE_Nothing<dim, spacedim> *>(&fe_other))
195 {
196 if (fe_nothing->is_dominating())
198 else
199 // the FE_Nothing has no degrees of freedom and it is typically used
200 // in a context where we don't require any continuity along the
201 // interface
203 }
204
205 Assert(false, ExcNotImplemented());
207}
208
209
210
211template <int dim, int spacedim>
212std::vector<std::pair<unsigned int, unsigned int>>
214 const FiniteElement<dim, spacedim> &fe_other) const
215{
216 (void)fe_other;
217
218 Assert((dynamic_cast<const FE_SimplexP<dim, spacedim> *>(&fe_other)) ||
219 (dynamic_cast<const FE_Q<dim, spacedim> *>(&fe_other)),
221
222 return {{0, 0}};
223}
224
225
226
227template <int dim, int spacedim>
228std::vector<std::pair<unsigned int, unsigned int>>
230 const FiniteElement<dim, spacedim> &fe_other) const
231{
232 (void)fe_other;
233
234 Assert((dynamic_cast<const FE_SimplexP<dim, spacedim> *>(&fe_other)) ||
235 (dynamic_cast<const FE_Q<dim, spacedim> *>(&fe_other)),
237
238 std::vector<std::pair<unsigned int, unsigned int>> result;
239
240 for (unsigned int i = 0; i < this->degree - 1; ++i)
241 result.emplace_back(i, i);
242
243 return result;
244}
245
246
247
248template <int dim, int spacedim>
249std::vector<std::pair<unsigned int, unsigned int>>
251 const FiniteElement<dim, spacedim> &fe_other,
252 const unsigned int face_no) const
253{
254 (void)fe_other;
255
256
257 AssertIndexRange(face_no, 5);
258
259 if (face_no == 0)
260 {
261 Assert((dynamic_cast<const FE_Q<dim, spacedim> *>(&fe_other)),
263 }
264 else
265 {
266 Assert((dynamic_cast<const FE_SimplexP<dim, spacedim> *>(&fe_other)),
268 }
269
270 std::vector<std::pair<unsigned int, unsigned int>> result;
271
272 for (unsigned int i = 0; i < this->n_dofs_per_quad(face_no); ++i)
273 result.emplace_back(i, i);
274
275 return result;
276}
277
278
279
280template <int dim, int spacedim>
282 : FE_PyramidPoly<dim, spacedim>(degree,
283 get_dpo_vector_fe_pyramid_dgp(degree),
284 FiniteElementData<dim>::L2)
285{}
286
287
288
289template <int dim, int spacedim>
290std::unique_ptr<FiniteElement<dim, spacedim>>
292{
293 return std::make_unique<FE_PyramidDGP<dim, spacedim>>(*this);
294}
295
296
297
298template <int dim, int spacedim>
299std::string
301{
302 std::ostringstream namebuf;
303 namebuf << "FE_PyramidDGP<" << dim << ">(" << this->degree << ")";
304
305 return namebuf.str();
306}
307
308// explicit instantiations
309#include "fe_pyramid_p.inst"
310
std::string get_name() const override
FE_PyramidDGP(const unsigned int degree)
std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
FE_PyramidP(const unsigned int degree)
std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
std::vector< std::pair< unsigned int, unsigned int > > hp_quad_dof_identities(const FiniteElement< dim, spacedim > &fe_other, const unsigned int face_no=0) const override
std::string get_name() const override
FiniteElementDomination::Domination compare_for_domination(const FiniteElement< dim, spacedim > &fe_other, const unsigned int codim) const override
FE_PyramidPoly(const unsigned int degree, const internal::GenericDoFsPerObject &dpos, const typename FiniteElementData< dim >::Conformity conformity)
Definition: fe_pyramid_p.cc:76
Definition: fe_q.h:549
const unsigned int degree
Definition: fe_base.h:435
std::vector< Point< dim > > unit_support_points
Definition: fe.h:2442
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:402
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:403
static ::ExceptionBase & ExcNotImplemented()
#define Assert(cond, exc)
Definition: exceptions.h:1465
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1622
#define AssertIndexRange(index, range)
Definition: exceptions.h:1690
void L2(Vector< number > &result, const FEValuesBase< dim > &fe, const std::vector< double > &input, const double factor=1.)
Definition: l2.h:160
constexpr const ReferenceCell Pyramid
internal::GenericDoFsPerObject expand(const unsigned int dim, const std::vector< unsigned int > &dofs_per_object, const ::ReferenceCell reference_cell)
Definition: fe_data.cc:25
STL namespace.
std::vector< std::vector< unsigned int > > object_index
Definition: fe_base.h:188
std::vector< std::vector< unsigned int > > first_object_index_on_face
Definition: fe_base.h:193
std::vector< std::vector< unsigned int > > dofs_per_object_inclusive
Definition: fe_base.h:183
std::vector< std::vector< unsigned int > > dofs_per_object_exclusive
Definition: fe_base.h:178