Reference documentation for deal.II version 9.3.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\}}\)
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>
22 #include <deal.II/fe/fe_nothing.h>
24 #include <deal.II/fe/fe_q.h>
27 #include <deal.II/fe/fe_tools.h>
28 #include <deal.II/fe/fe_wedge_p.h>
29 
31 
32 namespace
33 {
38  get_dpo_vector_fe_pyramid_p(const unsigned int degree)
39  {
41 
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 
75 template <int dim, int spacedim>
77  const unsigned int degree,
78  const internal::GenericDoFsPerObject & dpos,
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 
111 template <int dim, int spacedim>
112 FE_PyramidP<dim, spacedim>::FE_PyramidP(const unsigned int degree)
113  : FE_PyramidPoly<dim, spacedim>(degree,
114  get_dpo_vector_fe_pyramid_p(degree),
115  FiniteElementData<dim>::H1)
116 {}
117 
118 
119 
120 template <int dim, int spacedim>
121 std::unique_ptr<FiniteElement<dim, spacedim>>
123 {
124  return std::make_unique<FE_PyramidP<dim, spacedim>>(*this);
125 }
126 
127 
128 
129 template <int dim, int spacedim>
130 std::string
132 {
133  std::ostringstream namebuf;
134  namebuf << "FE_PyramidP<" << dim << ">(" << this->degree << ")";
135 
136  return namebuf.str();
137 }
138 
139 
140 
141 template <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 
211 template <int dim, int spacedim>
212 std::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 
227 template <int dim, int spacedim>
228 std::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 
248 template <int dim, int spacedim>
249 std::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 
280 template <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 
289 template <int dim, int spacedim>
290 std::unique_ptr<FiniteElement<dim, spacedim>>
292 {
293  return std::make_unique<FE_PyramidDGP<dim, spacedim>>(*this);
294 }
295 
296 
297 
298 template <int dim, int spacedim>
299 std::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::vector< std::vector< unsigned int > > dofs_per_object_inclusive
Definition: fe_base.h:183
constexpr const ReferenceCell Pyramid
std::vector< std::vector< unsigned int > > object_index
Definition: fe_base.h:188
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1622
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
FE_PyramidPoly(const unsigned int degree, const internal::GenericDoFsPerObject &dpos, const typename FiniteElementData< dim >::Conformity conformity)
Definition: fe_pyramid_p.cc:76
internal::GenericDoFsPerObject expand(const unsigned int dim, const std::vector< unsigned int > &dofs_per_object, const ::ReferenceCell reference_cell)
Definition: fe_data.cc:25
std::vector< std::vector< unsigned int > > dofs_per_object_exclusive
Definition: fe_base.h:178
#define AssertIndexRange(index, range)
Definition: exceptions.h:1690
STL namespace.
unsigned int n_dofs_per_quad(unsigned int face_no=0) const
FE_PyramidDGP(const unsigned int degree)
std::vector< Point< dim > > unit_support_points
Definition: fe.h:2442
Definition: fe_q.h:548
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
std::unique_ptr< FiniteElement< dim, spacedim > > clone() const override
#define Assert(cond, exc)
Definition: exceptions.h:1465
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:395
std::vector< std::pair< unsigned int, unsigned int > > hp_vertex_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
std::string get_name() const override
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:394
FE_PyramidP(const unsigned int degree)
std::vector< std::vector< unsigned int > > first_object_index_on_face
Definition: fe_base.h:193
static ::ExceptionBase & ExcNotImplemented()
std::string get_name() const override
std::vector< std::pair< unsigned int, unsigned int > > hp_line_dof_identities(const FiniteElement< dim, spacedim > &fe_other) const override
FiniteElementDomination::Domination compare_for_domination(const FiniteElement< dim, spacedim > &fe_other, const unsigned int codim) const override