Reference documentation for deal.II version 8.5.1
fe_collection.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2003 - 2016 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 at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #include <deal.II/base/memory_consumption.h>
18 #include <deal.II/hp/fe_collection.h>
19 
20 DEAL_II_NAMESPACE_OPEN
21 
22 namespace hp
23 {
24  template <int dim, int spacedim>
25  unsigned int
26  FECollection<dim,spacedim>::find_least_face_dominating_fe (const std::set<unsigned int> &fes) const
27  {
28  // If the set of elements to be dominated contains only a single element X,
29  // then by definition the dominating set contains this single element X
30  // (because each element can dominate itself). There may also be others,
31  // say Y1...YN. Next you have to find one or more elements in the dominating
32  // set {X,Y1...YN} that is the weakest. Well, you can't find one that is
33  // weaker than X because if it were, it would not dominate X. In other words,
34  // X is guaranteed to be in the subset of {X,Y1...YN} of weakest dominating
35  // elements. Since we only guarantee that the function returns one of them,
36  // we may as well return X right away.
37  if (fes.size()==1)
38  return *fes.begin();
39 
40  const hp::FECollection<dim,spacedim> &fe_collection = *this;
41  std::set<unsigned int> candidate_fes;
42 
43  // first loop over all FEs and check which can dominate those given in @p fes:
44  for (unsigned int cur_fe = 0; cur_fe < fe_collection.size(); cur_fe++)
45  {
47  // check if cur_fe can dominate all FEs in @p fes:
48  for (std::set<unsigned int>::const_iterator it = fes.begin();
49  it!=fes.end(); ++it)
50  {
51  Assert (*it < fe_collection.size(),
52  ExcIndexRangeType<unsigned int> (*it, 0, fe_collection.size()));
53  domination = domination &
54  fe_collection[cur_fe].compare_for_face_domination
55  (fe_collection[*it]);
56  }
57 
58  // if we found dominating element, keep them in a set.
60  domination == FiniteElementDomination::either_element_can_dominate /*covers cases like {Q2,Q3,Q1,Q1} with fes={2,3}*/)
61  candidate_fes.insert(cur_fe);
62  }
63 
64  // among the ones we found, pick one that is dominated by all others and
65  // thus should represent the largest FE space.
66  if (candidate_fes.size() == 1)
67  {
68  return *candidate_fes.begin();
69  }
70  else
71  for (std::set<unsigned int>::const_iterator it = candidate_fes.begin(); it!=candidate_fes.end(); ++it)
72  {
74  for (std::set<unsigned int>::const_iterator ito = candidate_fes.begin(); ito!=candidate_fes.end(); ++ito)
75  if (it != ito)
76  {
77  domination = domination &
78  fe_collection[*it].compare_for_face_domination(fe_collection[*ito]);
79  }
80 
82  domination == FiniteElementDomination::either_element_can_dominate /*covers cases like candidate_fes={Q1,Q1}*/)
83  return *it;
84  }
85  // We couldn't find the FE, return invalid_unsigned_int :
87  }
88 
89  template <int dim, int spacedim>
91  {}
92 
93 
94 
95  template <int dim, int spacedim>
97  {
98  push_back (fe);
99  }
100 
101 
102 
103  template <int dim, int spacedim>
105  const FiniteElement<dim,spacedim> &fe2)
106  {
107  push_back(fe1);
108  push_back(fe2);
109  }
110 
111 
112 
113  template <int dim, int spacedim>
115  const FiniteElement<dim,spacedim> &fe2,
116  const FiniteElement<dim,spacedim> &fe3)
117  {
118  push_back(fe1);
119  push_back(fe2);
120  push_back(fe3);
121  }
122 
123 
124 
125  template <int dim, int spacedim>
127  const FiniteElement<dim,spacedim> &fe2,
128  const FiniteElement<dim,spacedim> &fe3,
129  const FiniteElement<dim,spacedim> &fe4)
130  {
131  push_back(fe1);
132  push_back(fe2);
133  push_back(fe3);
134  push_back(fe4);
135  }
136 
137 
138 
139  template <int dim, int spacedim>
141  const FiniteElement<dim,spacedim> &fe2,
142  const FiniteElement<dim,spacedim> &fe3,
143  const FiniteElement<dim,spacedim> &fe4,
144  const FiniteElement<dim,spacedim> &fe5)
145  {
146  push_back(fe1);
147  push_back(fe2);
148  push_back(fe3);
149  push_back(fe4);
150  push_back(fe5);
151  }
152 
153 
154 
155  template <int dim, int spacedim>
157  FECollection (const std::vector<const FiniteElement<dim,spacedim>*> &fes)
158  {
159  Assert (fes.size() > 0,
160  ExcMessage ("Need to pass at least one finite element."));
161 
162  for (unsigned int i = 0; i < fes.size(); ++i)
163  push_back(*fes[i]);
164  }
165 
166 
167 
168  template <int dim, int spacedim>
171  :
172  Subscriptor (),
173  // copy the array
174  // of shared
175  // pointers. nothing
176  // bad should
177  // happen -- they
178  // simply all point
179  // to the same
180  // objects, and the
181  // last one to die
182  // will delete the
183  // mappings
184  finite_elements (fe_collection.finite_elements)
185  {}
186 
187 
188 
189  template <int dim, int spacedim>
191  {
192  // check that the new element has the right
193  // number of components. only check with
194  // the first element, since all the other
195  // elements have already passed the test
196  // against the first element
197  if (finite_elements.size() != 0)
198  Assert (new_fe.n_components() == finite_elements[0]->n_components(),
199  ExcMessage ("All elements inside a collection need to have the "
200  "same number of vector components!"));
201 
202  finite_elements
203  .push_back (std_cxx11::shared_ptr<const FiniteElement<dim,spacedim> >(new_fe.clone()));
204  }
205 
206 
207 
208  template <int dim, int spacedim>
212  {
213  Assert (size() > 0,
214  ExcMessage ("This collection contains no finite element."));
215 
216  // get the mask from the first element of the collection
217  const ComponentMask mask = (*this)[0].component_mask(scalar);
218 
219  // but then also verify that the other elements of the collection
220  // would return the same mask
221  for (unsigned int c=1; c<size(); ++c)
222  Assert (mask == (*this)[c].component_mask(scalar),
223  ExcInternalError());
224 
225  return mask;
226  }
227 
228 
229  template <int dim, int spacedim>
233  {
234  Assert (size() > 0,
235  ExcMessage ("This collection contains no finite element."));
236 
237  // get the mask from the first element of the collection
238  const ComponentMask mask = (*this)[0].component_mask(vector);
239 
240  // but then also verify that the other elements of the collection
241  // would return the same mask
242  for (unsigned int c=1; c<size(); ++c)
243  Assert (mask == (*this)[c].component_mask(vector),
244  ExcInternalError());
245 
246  return mask;
247  }
248 
249 
250  template <int dim, int spacedim>
254  {
255  Assert (size() > 0,
256  ExcMessage ("This collection contains no finite element."));
257 
258  // get the mask from the first element of the collection
259  const ComponentMask mask = (*this)[0].component_mask(sym_tensor);
260 
261  // but then also verify that the other elements of the collection
262  // would return the same mask
263  for (unsigned int c=1; c<size(); ++c)
264  Assert (mask == (*this)[c].component_mask(sym_tensor),
265  ExcInternalError());
266 
267  return mask;
268  }
269 
270 
271  template <int dim, int spacedim>
274  component_mask (const BlockMask &block_mask) const
275  {
276  Assert (size() > 0,
277  ExcMessage ("This collection contains no finite element."));
278 
279  // get the mask from the first element of the collection
280  const ComponentMask mask = (*this)[0].component_mask(block_mask);
281 
282  // but then also verify that the other elements of the collection
283  // would return the same mask
284  for (unsigned int c=1; c<size(); ++c)
285  Assert (mask == (*this)[c].component_mask(block_mask),
286  ExcMessage ("Not all elements of this collection agree on what "
287  "the appropriate mask should be."));
288 
289  return mask;
290  }
291 
292 
293  template <int dim, int spacedim>
294  BlockMask
297  {
298  Assert (size() > 0,
299  ExcMessage ("This collection contains no finite element."));
300 
301  // get the mask from the first element of the collection
302  const BlockMask mask = (*this)[0].block_mask(scalar);
303 
304  // but then also verify that the other elements of the collection
305  // would return the same mask
306  for (unsigned int c=1; c<size(); ++c)
307  Assert (mask == (*this)[c].block_mask(scalar),
308  ExcMessage ("Not all elements of this collection agree on what "
309  "the appropriate mask should be."));
310 
311  return mask;
312  }
313 
314 
315  template <int dim, int spacedim>
316  BlockMask
319  {
320  Assert (size() > 0,
321  ExcMessage ("This collection contains no finite element."));
322 
323  // get the mask from the first element of the collection
324  const BlockMask mask = (*this)[0].block_mask(vector);
325 
326  // but then also verify that the other elements of the collection
327  // would return the same mask
328  for (unsigned int c=1; c<size(); ++c)
329  Assert (mask == (*this)[c].block_mask(vector),
330  ExcMessage ("Not all elements of this collection agree on what "
331  "the appropriate mask should be."));
332 
333  return mask;
334  }
335 
336 
337  template <int dim, int spacedim>
338  BlockMask
341  {
342  Assert (size() > 0,
343  ExcMessage ("This collection contains no finite element."));
344 
345  // get the mask from the first element of the collection
346  const BlockMask mask = (*this)[0].block_mask(sym_tensor);
347 
348  // but then also verify that the other elements of the collection
349  // would return the same mask
350  for (unsigned int c=1; c<size(); ++c)
351  Assert (mask == (*this)[c].block_mask(sym_tensor),
352  ExcMessage ("Not all elements of this collection agree on what "
353  "the appropriate mask should be."));
354 
355  return mask;
356  }
357 
358 
359 
360  template <int dim, int spacedim>
361  BlockMask
363  block_mask (const ComponentMask &component_mask) const
364  {
365  Assert (size() > 0,
366  ExcMessage ("This collection contains no finite element."));
367 
368  // get the mask from the first element of the collection
369  const BlockMask mask = (*this)[0].block_mask(component_mask);
370 
371  // but then also verify that the other elements of the collection
372  // would return the same mask
373  for (unsigned int c=1; c<size(); ++c)
374  Assert (mask == (*this)[c].block_mask(component_mask),
375  ExcMessage ("Not all elements of this collection agree on what "
376  "the appropriate mask should be."));
377 
378  return mask;
379  }
380 
381 
382 
383  template <int dim, int spacedim>
384  unsigned int
386  {
387  Assert (finite_elements.size () > 0, ExcNoFiniteElements());
388 
389  const unsigned int nb = finite_elements[0]->n_blocks ();
390  for (unsigned int i=1; i<finite_elements.size(); ++i)
391  Assert (finite_elements[i]->n_blocks() == nb,
392  ExcMessage ("Not all finite elements in this collection have "
393  "the same number of components."));
394 
395  return nb;
396  }
397 
398 
399 
400  template <int dim, int spacedim>
401  std::size_t
403  {
404  std::size_t mem
405  = (sizeof(*this) +
406  MemoryConsumption::memory_consumption (finite_elements));
407  for (unsigned int i=0; i<finite_elements.size(); ++i)
408  mem += finite_elements[i]->memory_consumption();
409 
410  return mem;
411  }
412 }
413 
414 
415 
416 // explicit instantiations
417 #include "fe_collection.inst"
418 
419 
420 DEAL_II_NAMESPACE_CLOSE
static const unsigned int invalid_unsigned_int
Definition: types.h:170
unsigned int find_least_face_dominating_fe(const std::set< unsigned int > &fes) const
std::vector< bool > component_mask
unsigned int size() const
static ::ExceptionBase & ExcMessage(std::string arg1)
#define Assert(cond, exc)
Definition: exceptions.h:313
Definition: hp.h:102
std_cxx11::enable_if< std_cxx11::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
std::vector< bool > block_mask
Definition: block_mask.h:207
unsigned int n_components() const
virtual FiniteElement< dim, spacedim > * clone() const =0
static ::ExceptionBase & ExcInternalError()