1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2009 - 2018 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 
17 #include <deal.II/fe/fe_nothing.h>
18 
19 #include <memory>
20 
21 DEAL_II_NAMESPACE_OPEN
22 
23 
24 template <int dim, int spacedim>
FE_Nothing(const unsigned int n_components,const bool dominate)25 FE_Nothing<dim, spacedim>::FE_Nothing(const unsigned int n_components,
26                                       const bool         dominate)
27   : FiniteElement<dim, spacedim>(
28       FiniteElementData<dim>(std::vector<unsigned>(dim + 1, 0),
29                              n_components,
30                              0,
31                              FiniteElementData<dim>::unknown),
32       std::vector<bool>(),
33       std::vector<ComponentMask>())
34   , dominate(dominate)
35 {
36   // in most other elements we have to set up all sorts of stuff
37   // here. there isn't much that we have to do here; in particular,
38   // we can simply leave the restriction and prolongation matrices
39   // empty since their proper size is in fact zero given that the
40   // element here has no degrees of freedom
41 }
42 
43 
44 template <int dim, int spacedim>
45 std::unique_ptr<FiniteElement<dim, spacedim>>
clone() const46 FE_Nothing<dim, spacedim>::clone() const
47 {
48   return std::make_unique<FE_Nothing<dim, spacedim>>(*this);
49 }
50 
51 
52 
53 template <int dim, int spacedim>
54 std::string
get_name() const55 FE_Nothing<dim, spacedim>::get_name() const
56 {
57   std::ostringstream namebuf;
58   namebuf << "FE_Nothing<" << dim << ">(";
59   if (this->n_components() > 1)
60     {
61       namebuf << this->n_components();
62       if (dominate)
63         namebuf << ", dominating";
64     }
65   else if (dominate)
66     namebuf << "dominating";
67   namebuf << ")";
68   return namebuf.str();
69 }
70 
71 
72 
73 template <int dim, int spacedim>
74 UpdateFlags
requires_update_flags(const UpdateFlags flags) const75 FE_Nothing<dim, spacedim>::requires_update_flags(const UpdateFlags flags) const
76 {
77   return flags;
78 }
79 
80 
81 
82 template <int dim, int spacedim>
83 double
shape_value(const unsigned int,const Point<dim> &) const84 FE_Nothing<dim, spacedim>::shape_value(const unsigned int /*i*/,
85                                        const Point<dim> & /*p*/) const
86 {
87   Assert(false, ExcMessage("This element has no shape functions."));
88   return 0;
89 }
90 
91 
92 
93 template <int dim, int spacedim>
94 std::unique_ptr<typename FiniteElement<dim, spacedim>::InternalDataBase>
get_data(const UpdateFlags,const Mapping<dim,spacedim> &,const Quadrature<dim> &,dealii::internal::FEValuesImplementation::FiniteElementRelatedData<dim,spacedim> &) const95 FE_Nothing<dim, spacedim>::get_data(
96   const UpdateFlags /*update_flags*/,
97   const Mapping<dim, spacedim> & /*mapping*/,
98   const Quadrature<dim> & /*quadrature*/,
99   dealii::internal::FEValuesImplementation::FiniteElementRelatedData<dim,
100                                                                      spacedim>
101     & /*output_data*/) const
102 {
103   // Create a default data object.  Normally we would then
104   // need to resize things to hold the appropriate numbers
105   // of dofs, but in this case all data fields are empty.
106   return std::make_unique<
107     typename FiniteElement<dim, spacedim>::InternalDataBase>();
108 }
109 
110 
111 
112 template <int dim, int spacedim>
113 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> &) const114 FE_Nothing<dim, spacedim>::fill_fe_values(
115   const typename Triangulation<dim, spacedim>::cell_iterator &,
116   const CellSimilarity::Similarity,
117   const Quadrature<dim> &,
118   const Mapping<dim, spacedim> &,
119   const typename Mapping<dim, spacedim>::InternalDataBase &,
120   const dealii::internal::FEValuesImplementation::MappingRelatedData<dim,
121                                                                      spacedim>
122     &,
123   const typename FiniteElement<dim, spacedim>::InternalDataBase &,
124   dealii::internal::FEValuesImplementation::FiniteElementRelatedData<dim,
125                                                                      spacedim>
126     &) const
127 {
128   // leave data fields empty
129 }
130 
131 
132 
133 template <int dim, int spacedim>
134 void
fill_fe_face_values(const typename Triangulation<dim,spacedim>::cell_iterator &,const unsigned int,const Quadrature<dim-1> &,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> &) const135 FE_Nothing<dim, spacedim>::fill_fe_face_values(
136   const typename Triangulation<dim, spacedim>::cell_iterator &,
137   const unsigned int,
138   const Quadrature<dim - 1> &,
139   const Mapping<dim, spacedim> &,
140   const typename Mapping<dim, spacedim>::InternalDataBase &,
141   const dealii::internal::FEValuesImplementation::MappingRelatedData<dim,
142                                                                      spacedim>
143     &,
144   const typename FiniteElement<dim, spacedim>::InternalDataBase &,
145   dealii::internal::FEValuesImplementation::FiniteElementRelatedData<dim,
146                                                                      spacedim>
147     &) const
148 {
149   // leave data fields empty
150 }
151 
152 
153 
154 template <int dim, int spacedim>
155 void
fill_fe_subface_values(const typename Triangulation<dim,spacedim>::cell_iterator &,const unsigned int,const unsigned int,const Quadrature<dim-1> &,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> &) const156 FE_Nothing<dim, spacedim>::fill_fe_subface_values(
157   const typename Triangulation<dim, spacedim>::cell_iterator &,
158   const unsigned int,
159   const unsigned int,
160   const Quadrature<dim - 1> &,
161   const Mapping<dim, spacedim> &,
162   const typename Mapping<dim, spacedim>::InternalDataBase &,
163   const dealii::internal::FEValuesImplementation::MappingRelatedData<dim,
164                                                                      spacedim>
165     &,
166   const typename FiniteElement<dim, spacedim>::InternalDataBase &,
167   dealii::internal::FEValuesImplementation::FiniteElementRelatedData<dim,
168                                                                      spacedim>
169     &) const
170 {
171   // leave data fields empty
172 }
173 
174 
175 
176 template <int dim, int spacedim>
177 bool
is_dominating() const178 FE_Nothing<dim, spacedim>::is_dominating() const
179 {
180   return dominate;
181 }
182 
183 
184 
185 template <int dim, int spacedim>
186 bool
187 FE_Nothing<dim, spacedim>::
operator ==(const FiniteElement<dim,spacedim> & f) const188 operator==(const FiniteElement<dim, spacedim> &f) const
189 {
190   // Compare fields stored in the base class
191   if (!(this->FiniteElement<dim, spacedim>::operator==(f)))
192     return false;
193 
194   // Then make sure the other object is really of type FE_Nothing,
195   // and compare the data that has been passed to both objects'
196   // constructors.
197   if (const FE_Nothing<dim, spacedim> *f_nothing =
198         dynamic_cast<const FE_Nothing<dim, spacedim> *>(&f))
199     return ((dominate == f_nothing->dominate) &&
200             (this->components == f_nothing->components));
201   else
202     return false;
203 }
204 
205 
206 
207 template <int dim, int spacedim>
208 FiniteElementDomination::Domination
compare_for_domination(const FiniteElement<dim,spacedim> & fe,const unsigned int codim) const209 FE_Nothing<dim, spacedim>::compare_for_domination(
210   const FiniteElement<dim, spacedim> &fe,
211   const unsigned int                  codim) const
212 {
213   Assert(codim <= dim, ExcImpossibleInDim(dim));
214   (void)codim;
215 
216   if (!dominate)
217     // if FE_Nothing does not dominate, there are no requirements
218     return FiniteElementDomination::no_requirements;
219   else if (dynamic_cast<const FE_Nothing<dim> *>(&fe) != nullptr)
220     // if it does and the other is FE_Nothing, either can dominate
221     return FiniteElementDomination::either_element_can_dominate;
222   else
223     // otherwise we dominate whatever fe is provided
224     return FiniteElementDomination::this_element_dominates;
225 }
226 
227 
228 template <int dim, int spacedim>
229 std::vector<std::pair<unsigned int, unsigned int>>
hp_vertex_dof_identities(const FiniteElement<dim,spacedim> &) const230 FE_Nothing<dim, spacedim>::hp_vertex_dof_identities(
231   const FiniteElement<dim, spacedim> & /*fe_other*/) const
232 {
233   // the FE_Nothing has no
234   // degrees of freedom, so there
235   // are no equivalencies to be
236   // recorded
237   return std::vector<std::pair<unsigned int, unsigned int>>();
238 }
239 
240 
241 template <int dim, int spacedim>
242 std::vector<std::pair<unsigned int, unsigned int>>
hp_line_dof_identities(const FiniteElement<dim,spacedim> &) const243 FE_Nothing<dim, spacedim>::hp_line_dof_identities(
244   const FiniteElement<dim, spacedim> & /*fe_other*/) const
245 {
246   // the FE_Nothing has no
247   // degrees of freedom, so there
248   // are no equivalencies to be
249   // recorded
250   return std::vector<std::pair<unsigned int, unsigned int>>();
251 }
252 
253 
254 template <int dim, int spacedim>
255 std::vector<std::pair<unsigned int, unsigned int>>
hp_quad_dof_identities(const FiniteElement<dim,spacedim> &,const unsigned int) const256 FE_Nothing<dim, spacedim>::hp_quad_dof_identities(
257   const FiniteElement<dim, spacedim> & /*fe_other*/,
258   const unsigned int) const
259 {
260   // the FE_Nothing has no
261   // degrees of freedom, so there
262   // are no equivalencies to be
263   // recorded
264   return std::vector<std::pair<unsigned int, unsigned int>>();
265 }
266 
267 
268 template <int dim, int spacedim>
269 bool
hp_constraints_are_implemented() const270 FE_Nothing<dim, spacedim>::hp_constraints_are_implemented() const
271 {
272   return true;
273 }
274 
275 
276 
277 template <int dim, int spacedim>
278 void
get_interpolation_matrix(const FiniteElement<dim,spacedim> &,FullMatrix<double> & interpolation_matrix) const279 FE_Nothing<dim, spacedim>::get_interpolation_matrix(
280   const FiniteElement<dim, spacedim> & /*source_fe*/,
281   FullMatrix<double> &interpolation_matrix) const
282 {
283   // Since this element has no dofs,
284   // the interpolation matrix is necessarily empty.
285   (void)interpolation_matrix;
286 
287   Assert(interpolation_matrix.m() == 0,
288          ExcDimensionMismatch(interpolation_matrix.m(), 0));
289   Assert(interpolation_matrix.n() == 0,
290          ExcDimensionMismatch(interpolation_matrix.n(), 0));
291 }
292 
293 
294 
295 template <int dim, int spacedim>
296 void
get_face_interpolation_matrix(const FiniteElement<dim,spacedim> &,FullMatrix<double> & interpolation_matrix,const unsigned int) const297 FE_Nothing<dim, spacedim>::get_face_interpolation_matrix(
298   const FiniteElement<dim, spacedim> & /*source_fe*/,
299   FullMatrix<double> &interpolation_matrix,
300   const unsigned int) const
301 {
302   // since this element has no face dofs, the
303   // interpolation matrix is necessarily empty
304   (void)interpolation_matrix;
305 
306   Assert(interpolation_matrix.m() == 0,
307          ExcDimensionMismatch(interpolation_matrix.m(), 0));
308   Assert(interpolation_matrix.n() == 0,
309          ExcDimensionMismatch(interpolation_matrix.m(), 0));
310 }
311 
312 
313 template <int dim, int spacedim>
314 void
get_subface_interpolation_matrix(const FiniteElement<dim,spacedim> &,const unsigned int,FullMatrix<double> & interpolation_matrix,const unsigned int) const315 FE_Nothing<dim, spacedim>::get_subface_interpolation_matrix(
316   const FiniteElement<dim, spacedim> & /*source_fe*/,
317   const unsigned int /*index*/,
318   FullMatrix<double> &interpolation_matrix,
319   const unsigned int) const
320 {
321   // since this element has no face dofs, the
322   // interpolation matrix is necessarily empty
323 
324   (void)interpolation_matrix;
325   Assert(interpolation_matrix.m() == 0,
326          ExcDimensionMismatch(interpolation_matrix.m(), 0));
327   Assert(interpolation_matrix.n() == 0,
328          ExcDimensionMismatch(interpolation_matrix.m(), 0));
329 }
330 
331 
332 
333 // explicit instantiations
334 #include "fe_nothing.inst"
335 
336 
337 DEAL_II_NAMESPACE_CLOSE
338