Reference documentation for deal.II version GIT 29f9da0a34 2023-12-07 10:00:01+00:00
\(\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 - 2022 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,
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  ComponentMask(std::vector<bool>(1, true))))
95 {
96  AssertDimension(dim, 3);
97 
98  if (degree == 1)
99  {
100  for (const auto i : this->reference_cell().vertex_indices())
101  this->unit_support_points.emplace_back(
102  this->reference_cell().template vertex<dim>(i));
103 
104  this->unit_face_support_points.resize(this->reference_cell().n_faces());
105 
106  for (const auto f : this->reference_cell().face_indices())
107  {
108  const auto face_reference_cell =
110 
111  for (const auto i : face_reference_cell.vertex_indices())
112  this->unit_face_support_points[f].emplace_back(
113  face_reference_cell.template vertex<dim - 1>(i));
114  }
115  }
116  else
117  Assert(false, ExcNotImplemented());
118 }
119 
120 
121 
122 template <int dim, int spacedim>
123 void
126  const std::vector<Vector<double>> &support_point_values,
127  std::vector<double> &nodal_values) const
128 {
129  AssertDimension(support_point_values.size(),
130  this->get_unit_support_points().size());
131  AssertDimension(support_point_values.size(), nodal_values.size());
132  AssertDimension(this->dofs_per_cell, nodal_values.size());
133 
134  for (unsigned int i = 0; i < this->dofs_per_cell; ++i)
135  {
136  AssertDimension(support_point_values[i].size(), 1);
137 
138  nodal_values[i] = support_point_values[i](0);
139  }
140 }
141 
142 
143 
144 template <int dim, int spacedim>
145 FE_PyramidP<dim, spacedim>::FE_PyramidP(const unsigned int degree)
146  : FE_PyramidPoly<dim, spacedim>(degree,
147  get_dpo_vector_fe_pyramid_p(degree),
148  FiniteElementData<dim>::H1)
149 {}
150 
151 
152 
153 template <int dim, int spacedim>
154 std::unique_ptr<FiniteElement<dim, spacedim>>
156 {
157  return std::make_unique<FE_PyramidP<dim, spacedim>>(*this);
158 }
159 
160 
161 
162 template <int dim, int spacedim>
163 std::string
165 {
166  std::ostringstream namebuf;
167  namebuf << "FE_PyramidP<" << dim << ">(" << this->degree << ")";
168 
169  return namebuf.str();
170 }
171 
172 
173 
174 template <int dim, int spacedim>
177  const FiniteElement<dim, spacedim> &fe_other,
178  const unsigned int codim) const
179 {
180  Assert(codim <= dim, ExcImpossibleInDim(dim));
181 
182  // vertex/line/face domination
183  // (if fe_other is derived from FE_SimplexDGP)
184  // ------------------------------------
185  if (codim > 0)
186  if (dynamic_cast<const FE_SimplexDGP<dim, spacedim> *>(&fe_other) !=
187  nullptr)
188  // there are no requirements between continuous and discontinuous
189  // elements
191 
192  // vertex/line/face domination
193  // (if fe_other is not derived from FE_SimplexDGP)
194  // & cell domination
195  // ----------------------------------------
196  if (const FE_PyramidP<dim, spacedim> *fe_pp_other =
197  dynamic_cast<const FE_PyramidP<dim, spacedim> *>(&fe_other))
198  {
199  if (this->degree < fe_pp_other->degree)
201  else if (this->degree == fe_pp_other->degree)
203  else
205  }
206  else if (const FE_SimplexP<dim, spacedim> *fe_p_other =
207  dynamic_cast<const FE_SimplexP<dim, spacedim> *>(&fe_other))
208  {
209  if (this->degree < fe_p_other->degree)
211  else if (this->degree == fe_p_other->degree)
213  else
215  }
216  else if (const FE_Q<dim, spacedim> *fe_q_other =
217  dynamic_cast<const FE_Q<dim, spacedim> *>(&fe_other))
218  {
219  if (this->degree < fe_q_other->degree)
221  else if (this->degree == fe_q_other->degree)
223  else
225  }
226  else if (const FE_Nothing<dim, spacedim> *fe_nothing =
227  dynamic_cast<const FE_Nothing<dim, spacedim> *>(&fe_other))
228  {
229  if (fe_nothing->is_dominating())
231  else
232  // the FE_Nothing has no degrees of freedom and it is typically used
233  // in a context where we don't require any continuity along the
234  // interface
236  }
237 
238  Assert(false, ExcNotImplemented());
240 }
241 
242 
243 
244 template <int dim, int spacedim>
245 std::vector<std::pair<unsigned int, unsigned int>>
247  const FiniteElement<dim, spacedim> &fe_other) const
248 {
249  (void)fe_other;
250 
251  Assert((dynamic_cast<const FE_SimplexP<dim, spacedim> *>(&fe_other)) ||
252  (dynamic_cast<const FE_Q<dim, spacedim> *>(&fe_other)),
254 
255  return {{0, 0}};
256 }
257 
258 
259 
260 template <int dim, int spacedim>
261 std::vector<std::pair<unsigned int, unsigned int>>
263  const FiniteElement<dim, spacedim> &fe_other) const
264 {
265  (void)fe_other;
266 
267  Assert((dynamic_cast<const FE_SimplexP<dim, spacedim> *>(&fe_other)) ||
268  (dynamic_cast<const FE_Q<dim, spacedim> *>(&fe_other)),
270 
271  std::vector<std::pair<unsigned int, unsigned int>> result;
272 
273  for (unsigned int i = 0; i < this->degree - 1; ++i)
274  result.emplace_back(i, i);
275 
276  return result;
277 }
278 
279 
280 
281 template <int dim, int spacedim>
282 std::vector<std::pair<unsigned int, unsigned int>>
284  const FiniteElement<dim, spacedim> &fe_other,
285  const unsigned int face_no) const
286 {
287  (void)fe_other;
288 
289 
290  AssertIndexRange(face_no, 5);
291 
292  if (face_no == 0)
293  {
294  Assert((dynamic_cast<const FE_Q<dim, spacedim> *>(&fe_other)),
296  }
297  else
298  {
299  Assert((dynamic_cast<const FE_SimplexP<dim, spacedim> *>(&fe_other)),
301  }
302 
303  std::vector<std::pair<unsigned int, unsigned int>> result;
304 
305  for (unsigned int i = 0; i < this->n_dofs_per_quad(face_no); ++i)
306  result.emplace_back(i, i);
307 
308  return result;
309 }
310 
311 
312 
313 template <int dim, int spacedim>
315  : FE_PyramidPoly<dim, spacedim>(degree,
316  get_dpo_vector_fe_pyramid_dgp(degree),
317  FiniteElementData<dim>::L2)
318 {}
319 
320 
321 
322 template <int dim, int spacedim>
323 std::unique_ptr<FiniteElement<dim, spacedim>>
325 {
326  return std::make_unique<FE_PyramidDGP<dim, spacedim>>(*this);
327 }
328 
329 
330 
331 template <int dim, int spacedim>
332 std::string
334 {
335  std::ostringstream namebuf;
336  namebuf << "FE_PyramidDGP<" << dim << ">(" << this->degree << ")";
337 
338  return namebuf.str();
339 }
340 
341 // explicit instantiations
342 #include "fe_pyramid_p.inst"
343 
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
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.h:551
const unsigned int degree
Definition: fe_data.h:453
ReferenceCell reference_cell() const
std::vector< std::vector< Point< dim - 1 > > > unit_face_support_points
Definition: fe.h:2447
std::vector< Point< dim > > unit_support_points
Definition: fe.h:2440
ReferenceCell face_reference_cell(const unsigned int face_no) const
Definition: vector.h:110
#define DEAL_II_NAMESPACE_OPEN
Definition: config.h:477
#define DEAL_II_NAMESPACE_CLOSE
Definition: config.h:478
unsigned int vertex_indices[2]
#define Assert(cond, exc)
Definition: exceptions.h:1631
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcImpossibleInDim(int arg1)
#define AssertDimension(dim1, dim2)
Definition: exceptions.h:1820
#define AssertIndexRange(index, range)
Definition: exceptions.h:1888
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
std::vector< std::vector< unsigned int > > object_index
Definition: fe_data.h:198
std::vector< std::vector< unsigned int > > first_object_index_on_face
Definition: fe_data.h:203
std::vector< std::vector< unsigned int > > dofs_per_object_inclusive
Definition: fe_data.h:193
std::vector< std::vector< unsigned int > > dofs_per_object_exclusive
Definition: fe_data.h:188