1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2009 - 2019 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 #ifndef dealii_fe_poly_face_templates_h
17 #define dealii_fe_poly_face_templates_h
18
19
20 #include <deal.II/base/config.h>
21
22 #include <deal.II/base/polynomial_space.h>
23 #include <deal.II/base/qprojector.h>
24
25 #include <deal.II/fe/fe_poly_face.h>
26 #include <deal.II/fe/fe_values.h>
27
28
29 DEAL_II_NAMESPACE_OPEN
30
31 template <class PolynomialType, int dim, int spacedim>
FE_PolyFace(const PolynomialType & poly_space,const FiniteElementData<dim> & fe_data,const std::vector<bool> & restriction_is_additive_flags)32 FE_PolyFace<PolynomialType, dim, spacedim>::FE_PolyFace(
33 const PolynomialType & poly_space,
34 const FiniteElementData<dim> &fe_data,
35 const std::vector<bool> & restriction_is_additive_flags)
36 : FiniteElement<dim, spacedim>(
37 fe_data,
38 restriction_is_additive_flags,
39 std::vector<ComponentMask>(1, ComponentMask(1, true)))
40 , poly_space(poly_space)
41 {
42 AssertDimension(dim, PolynomialType::dimension + 1);
43 }
44
45
46 template <class PolynomialType, int dim, int spacedim>
47 unsigned int
get_degree()48 FE_PolyFace<PolynomialType, dim, spacedim>::get_degree() const
49 {
50 return this->degree;
51 }
52
53
54 //---------------------------------------------------------------------------
55 // Auxiliary functions
56 //---------------------------------------------------------------------------
57
58
59 template <class PolynomialType, int dim, int spacedim>
60 UpdateFlags
requires_update_flags(const UpdateFlags flags)61 FE_PolyFace<PolynomialType, dim, spacedim>::requires_update_flags(
62 const UpdateFlags flags) const
63 {
64 UpdateFlags out = flags & update_values;
65 if (flags & update_gradients)
66 out |= update_gradients | update_covariant_transformation;
67 if (flags & update_hessians)
68 out |= update_hessians | update_covariant_transformation;
69 if (flags & update_normal_vectors)
70 out |= update_normal_vectors | update_JxW_values;
71
72 return out;
73 }
74
75
76 //---------------------------------------------------------------------------
77 // Fill data of FEValues
78 //---------------------------------------------------------------------------
79 template <class PolynomialType, int dim, int spacedim>
80 void
fill_fe_values(const typename Triangulation<dim,spacedim>::cell_iterator &,const CellSimilarity::Similarity,const Quadrature<dim> &,const Mapping<dim,spacedim> &,const typename Mapping<dim,spacedim>::InternalDataBase &,const dealii::internal::FEValuesImplementation::MappingRelatedData<dim,spacedim> &,const typename FiniteElement<dim,spacedim>::InternalDataBase &,dealii::internal::FEValuesImplementation::FiniteElementRelatedData<dim,spacedim> &)81 FE_PolyFace<PolynomialType, dim, spacedim>::fill_fe_values(
82 const typename Triangulation<dim, spacedim>::cell_iterator &,
83 const CellSimilarity::Similarity,
84 const Quadrature<dim> &,
85 const Mapping<dim, spacedim> &,
86 const typename Mapping<dim, spacedim>::InternalDataBase &,
87 const dealii::internal::FEValuesImplementation::MappingRelatedData<dim,
88 spacedim>
89 &,
90 const typename FiniteElement<dim, spacedim>::InternalDataBase &,
91 dealii::internal::FEValuesImplementation::FiniteElementRelatedData<dim,
92 spacedim>
93 &) const
94 {
95 // Do nothing, since we do not have values in the interior. Since
96 // FEValues initializes the output variables for this function
97 // with invalid values, this means that we simply leave them at
98 // the invalid values -- typically, signaling NaNs. This means
99 // that when you later look at those components of shape
100 // functions or solution vectors that correspond to the
101 // face element, you will see signaling_NaNs. This simply means
102 // that you should not use them -- the shape functions and the
103 // solution do not actually live inside the cell, and so any
104 // attempt at evaluating it there *should* yield an invalid
105 // result.
106 }
107
108
109
110 template <class PolynomialType, int dim, int spacedim>
111 void
fill_fe_face_values(const typename Triangulation<dim,spacedim>::cell_iterator &,const unsigned int face_no,const Quadrature<dim-1> & quadrature,const Mapping<dim,spacedim> &,const typename Mapping<dim,spacedim>::InternalDataBase &,const dealii::internal::FEValuesImplementation::MappingRelatedData<dim,spacedim> &,const typename FiniteElement<dim,spacedim>::InternalDataBase & fe_internal,dealii::internal::FEValuesImplementation::FiniteElementRelatedData<dim,spacedim> & output_data)112 FE_PolyFace<PolynomialType, dim, spacedim>::fill_fe_face_values(
113 const typename Triangulation<dim, spacedim>::cell_iterator &,
114 const unsigned int face_no,
115 const Quadrature<dim - 1> &quadrature,
116 const Mapping<dim, spacedim> &,
117 const typename Mapping<dim, spacedim>::InternalDataBase &,
118 const dealii::internal::FEValuesImplementation::MappingRelatedData<dim,
119 spacedim>
120 &,
121 const typename FiniteElement<dim, spacedim>::InternalDataBase &fe_internal,
122 dealii::internal::FEValuesImplementation::FiniteElementRelatedData<dim,
123 spacedim>
124 &output_data) const
125 {
126 // convert data object to internal
127 // data for this class. fails with
128 // an exception if that is not
129 // possible
130 Assert(dynamic_cast<const InternalData *>(&fe_internal) != nullptr,
131 ExcInternalError());
132 const InternalData &fe_data = static_cast<const InternalData &>(fe_internal);
133
134 if (fe_data.update_each & update_values)
135 for (unsigned int i = 0; i < quadrature.size(); ++i)
136 {
137 for (unsigned int k = 0; k < this->n_dofs_per_cell(); ++k)
138 output_data.shape_values(k, i) = 0.;
139 switch (dim)
140 {
141 case 3:
142 {
143 // Fill data for quad shape functions
144 if (this->n_dofs_per_quad(face_no) != 0)
145 {
146 const unsigned int foffset =
147 this->get_first_quad_index(face_no);
148 for (unsigned int k = 0; k < this->n_dofs_per_quad(face_no);
149 ++k)
150 output_data.shape_values(foffset + k, i) =
151 fe_data
152 .shape_values[k + this->get_first_face_quad_index(
153 face_no)][i];
154 }
155 }
156 DEAL_II_FALLTHROUGH;
157
158 case 2:
159 {
160 // Fill data for line shape functions
161 if (this->n_dofs_per_line() != 0)
162 {
163 const unsigned int foffset = this->get_first_line_index();
164 for (unsigned int line = 0;
165 line < GeometryInfo<dim>::lines_per_face;
166 ++line)
167 {
168 for (unsigned int k = 0; k < this->n_dofs_per_line();
169 ++k)
170 output_data.shape_values(
171 foffset +
172 GeometryInfo<dim>::face_to_cell_lines(face_no,
173 line) *
174 this->n_dofs_per_line() +
175 k,
176 i) =
177 fe_data.shape_values
178 [k + (line * this->n_dofs_per_line()) +
179 this->get_first_face_line_index(face_no)][i];
180 }
181 }
182 }
183 DEAL_II_FALLTHROUGH;
184
185 case 1:
186 {
187 // Fill data for vertex shape functions
188 if (this->n_dofs_per_vertex() != 0)
189 for (unsigned int lvertex = 0;
190 lvertex < GeometryInfo<dim>::vertices_per_face;
191 ++lvertex)
192 output_data.shape_values(
193 GeometryInfo<dim>::face_to_cell_vertices(face_no,
194 lvertex),
195 i) = fe_data.shape_values[lvertex][i];
196 break;
197 }
198 }
199 }
200 }
201
202
203 template <class PolynomialType, int dim, int spacedim>
204 void
fill_fe_subface_values(const typename Triangulation<dim,spacedim>::cell_iterator &,const unsigned int face_no,const unsigned int sub_no,const Quadrature<dim-1> & quadrature,const Mapping<dim,spacedim> &,const typename Mapping<dim,spacedim>::InternalDataBase &,const dealii::internal::FEValuesImplementation::MappingRelatedData<dim,spacedim> &,const typename FiniteElement<dim,spacedim>::InternalDataBase & fe_internal,dealii::internal::FEValuesImplementation::FiniteElementRelatedData<dim,spacedim> & output_data)205 FE_PolyFace<PolynomialType, dim, spacedim>::fill_fe_subface_values(
206 const typename Triangulation<dim, spacedim>::cell_iterator &,
207 const unsigned int face_no,
208 const unsigned int sub_no,
209 const Quadrature<dim - 1> &quadrature,
210 const Mapping<dim, spacedim> &,
211 const typename Mapping<dim, spacedim>::InternalDataBase &,
212 const dealii::internal::FEValuesImplementation::MappingRelatedData<dim,
213 spacedim>
214 &,
215 const typename FiniteElement<dim, spacedim>::InternalDataBase &fe_internal,
216 dealii::internal::FEValuesImplementation::FiniteElementRelatedData<dim,
217 spacedim>
218 &output_data) const
219 {
220 // convert data object to internal
221 // data for this class. fails with
222 // an exception if that is not
223 // possible
224 Assert(dynamic_cast<const InternalData *>(&fe_internal) != nullptr,
225 ExcInternalError());
226 const InternalData &fe_data = static_cast<const InternalData &>(fe_internal);
227
228 const unsigned int foffset = fe_data.shape_values.size() * face_no;
229 const unsigned int offset = sub_no * quadrature.size();
230
231 if (fe_data.update_each & update_values)
232 {
233 for (unsigned int k = 0; k < this->n_dofs_per_cell(); ++k)
234 for (unsigned int i = 0; i < quadrature.size(); ++i)
235 output_data.shape_values(k, i) = 0.;
236 for (unsigned int k = 0; k < fe_data.shape_values.size(); ++k)
237 for (unsigned int i = 0; i < quadrature.size(); ++i)
238 output_data.shape_values(foffset + k, i) =
239 fe_data.shape_values[k][i + offset];
240 }
241
242 Assert(!(fe_data.update_each & update_gradients), ExcNotImplemented());
243 Assert(!(fe_data.update_each & update_hessians), ExcNotImplemented());
244 }
245
246 DEAL_II_NAMESPACE_CLOSE
247
248 #endif
249