Reference documentation for deal.II version 9.0.0
fe_collection.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2003 - 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 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 
90 
91  template <int dim, int spacedim>
93  {
94  push_back (fe);
95  }
96 
97 
98 
99  template <int dim, int spacedim>
101  FECollection (const std::vector<const FiniteElement<dim,spacedim>*> &fes)
102  {
103  Assert (fes.size() > 0,
104  ExcMessage ("Need to pass at least one finite element."));
105 
106  for (unsigned int i = 0; i < fes.size(); ++i)
107  push_back(*fes[i]);
108  }
109 
110 
111 
112  template <int dim, int spacedim>
114  {
115  // check that the new element has the right
116  // number of components. only check with
117  // the first element, since all the other
118  // elements have already passed the test
119  // against the first element
120  if (finite_elements.size() != 0)
121  Assert (new_fe.n_components() == finite_elements[0]->n_components(),
122  ExcMessage ("All elements inside a collection need to have the "
123  "same number of vector components!"));
124 
125  finite_elements.push_back (new_fe.clone());
126  }
127 
128 
129 
130  template <int dim, int spacedim>
134  {
135  Assert (size() > 0,
136  ExcMessage ("This collection contains no finite element."));
137 
138  // get the mask from the first element of the collection
139  const ComponentMask mask = (*this)[0].component_mask(scalar);
140 
141  // but then also verify that the other elements of the collection
142  // would return the same mask
143  for (unsigned int c=1; c<size(); ++c)
144  Assert (mask == (*this)[c].component_mask(scalar),
145  ExcInternalError());
146 
147  return mask;
148  }
149 
150 
151  template <int dim, int spacedim>
155  {
156  Assert (size() > 0,
157  ExcMessage ("This collection contains no finite element."));
158 
159  // get the mask from the first element of the collection
160  const ComponentMask mask = (*this)[0].component_mask(vector);
161 
162  // but then also verify that the other elements of the collection
163  // would return the same mask
164  for (unsigned int c=1; c<size(); ++c)
165  Assert (mask == (*this)[c].component_mask(vector),
166  ExcInternalError());
167 
168  return mask;
169  }
170 
171 
172  template <int dim, int spacedim>
176  {
177  Assert (size() > 0,
178  ExcMessage ("This collection contains no finite element."));
179 
180  // get the mask from the first element of the collection
181  const ComponentMask mask = (*this)[0].component_mask(sym_tensor);
182 
183  // but then also verify that the other elements of the collection
184  // would return the same mask
185  for (unsigned int c=1; c<size(); ++c)
186  Assert (mask == (*this)[c].component_mask(sym_tensor),
187  ExcInternalError());
188 
189  return mask;
190  }
191 
192 
193  template <int dim, int spacedim>
196  component_mask (const BlockMask &block_mask) const
197  {
198  Assert (size() > 0,
199  ExcMessage ("This collection contains no finite element."));
200 
201  // get the mask from the first element of the collection
202  const ComponentMask mask = (*this)[0].component_mask(block_mask);
203 
204  // but then also verify that the other elements of the collection
205  // would return the same mask
206  for (unsigned int c=1; c<size(); ++c)
207  Assert (mask == (*this)[c].component_mask(block_mask),
208  ExcMessage ("Not all elements of this collection agree on what "
209  "the appropriate mask should be."));
210 
211  return mask;
212  }
213 
214 
215  template <int dim, int spacedim>
216  BlockMask
219  {
220  Assert (size() > 0,
221  ExcMessage ("This collection contains no finite element."));
222 
223  // get the mask from the first element of the collection
224  const BlockMask mask = (*this)[0].block_mask(scalar);
225 
226  // but then also verify that the other elements of the collection
227  // would return the same mask
228  for (unsigned int c=1; c<size(); ++c)
229  Assert (mask == (*this)[c].block_mask(scalar),
230  ExcMessage ("Not all elements of this collection agree on what "
231  "the appropriate mask should be."));
232 
233  return mask;
234  }
235 
236 
237  template <int dim, int spacedim>
238  BlockMask
241  {
242  Assert (size() > 0,
243  ExcMessage ("This collection contains no finite element."));
244 
245  // get the mask from the first element of the collection
246  const BlockMask mask = (*this)[0].block_mask(vector);
247 
248  // but then also verify that the other elements of the collection
249  // would return the same mask
250  for (unsigned int c=1; c<size(); ++c)
251  Assert (mask == (*this)[c].block_mask(vector),
252  ExcMessage ("Not all elements of this collection agree on what "
253  "the appropriate mask should be."));
254 
255  return mask;
256  }
257 
258 
259  template <int dim, int spacedim>
260  BlockMask
263  {
264  Assert (size() > 0,
265  ExcMessage ("This collection contains no finite element."));
266 
267  // get the mask from the first element of the collection
268  const BlockMask mask = (*this)[0].block_mask(sym_tensor);
269 
270  // but then also verify that the other elements of the collection
271  // would return the same mask
272  for (unsigned int c=1; c<size(); ++c)
273  Assert (mask == (*this)[c].block_mask(sym_tensor),
274  ExcMessage ("Not all elements of this collection agree on what "
275  "the appropriate mask should be."));
276 
277  return mask;
278  }
279 
280 
281 
282  template <int dim, int spacedim>
283  BlockMask
285  block_mask (const ComponentMask &component_mask) const
286  {
287  Assert (size() > 0,
288  ExcMessage ("This collection contains no finite element."));
289 
290  // get the mask from the first element of the collection
291  const BlockMask mask = (*this)[0].block_mask(component_mask);
292 
293  // but then also verify that the other elements of the collection
294  // would return the same mask
295  for (unsigned int c=1; c<size(); ++c)
296  Assert (mask == (*this)[c].block_mask(component_mask),
297  ExcMessage ("Not all elements of this collection agree on what "
298  "the appropriate mask should be."));
299 
300  return mask;
301  }
302 
303 
304 
305  template <int dim, int spacedim>
306  unsigned int
308  {
309  Assert (finite_elements.size () > 0, ExcNoFiniteElements());
310 
311  const unsigned int nb = finite_elements[0]->n_blocks ();
312  for (unsigned int i=1; i<finite_elements.size(); ++i)
313  Assert (finite_elements[i]->n_blocks() == nb,
314  ExcMessage ("Not all finite elements in this collection have "
315  "the same number of components."));
316 
317  return nb;
318  }
319 
320 
321 
322  template <int dim, int spacedim>
323  std::size_t
325  {
326  std::size_t mem
327  = (sizeof(*this) +
328  MemoryConsumption::memory_consumption (finite_elements));
329  for (unsigned int i=0; i<finite_elements.size(); ++i)
330  mem += finite_elements[i]->memory_consumption();
331 
332  return mem;
333  }
334 }
335 
336 
337 
338 // explicit instantiations
339 #include "fe_collection.inst"
340 
341 
342 DEAL_II_NAMESPACE_CLOSE
ComponentMask component_mask(const FEValuesExtractors::Scalar &scalar) const
static const unsigned int invalid_unsigned_int
Definition: types.h:173
std::size_t memory_consumption() const
unsigned int find_least_face_dominating_fe(const std::set< unsigned int > &fes) const
std::vector< bool > component_mask
unsigned int size() const
virtual std::unique_ptr< FiniteElement< dim, spacedim > > clone() const =0
unsigned int n_blocks() const
static ::ExceptionBase & ExcMessage(std::string arg1)
BlockMask block_mask(const FEValuesExtractors::Scalar &scalar) const
void push_back(const FiniteElement< dim, spacedim > &new_fe)
#define Assert(cond, exc)
Definition: exceptions.h:1142
Definition: hp.h:102
std::vector< bool > block_mask
Definition: block_mask.h:207
unsigned int n_components() const
FECollection()=default
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
static ::ExceptionBase & ExcInternalError()