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