Reference documentation for deal.II version 9.0.0
tria_objects.cc
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2006 - 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 #include <deal.II/base/memory_consumption.h>
17 #include <deal.II/grid/tria_objects.h>
18 #include <deal.II/grid/tria.h>
19 #include <deal.II/grid/tria_iterator.h>
20 #include <deal.II/grid/tria_accessor.h>
21 
22 #include <algorithm>
23 #include <functional>
24 
25 
26 
27 DEAL_II_NAMESPACE_OPEN
28 
29 namespace internal
30 {
31  namespace TriangulationImplementation
32  {
33  template <class G>
34  void
35  TriaObjects<G>::reserve_space (const unsigned int new_objects_in_pairs,
36  const unsigned int new_objects_single)
37  {
38  Assert(new_objects_in_pairs%2==0, ExcInternalError());
39 
40  next_free_single=0;
41  next_free_pair=0;
42  reverse_order_next_free_single=false;
43 
44  // count the number of objects, of unused single objects and of
45  // unused pairs of objects
46  unsigned int n_objects=0;
47  unsigned int n_unused_pairs=0;
48  unsigned int n_unused_singles=0;
49  for (unsigned int i=0; i<used.size(); ++i)
50  {
51  if (used[i])
52  ++n_objects;
53  else if (i+1<used.size())
54  {
55  if (used[i+1])
56  {
57  ++n_unused_singles;
58  if (next_free_single==0)
59  next_free_single=i;
60  }
61  else
62  {
63  ++n_unused_pairs;
64  if (next_free_pair==0)
65  next_free_pair=i;
66  ++i;
67  }
68  }
69  else
70  ++n_unused_singles;
71  }
72  Assert(n_objects+2*n_unused_pairs+n_unused_singles==used.size(),
74 
75  // how many single objects are needed in addition to
76  // n_unused_objects?
77  const int additional_single_objects=
78  new_objects_single-n_unused_singles;
79 
80  unsigned int new_size=
81  used.size() + new_objects_in_pairs - 2*n_unused_pairs;
82  if (additional_single_objects>0)
83  new_size+=additional_single_objects;
84 
85  // only allocate space if necessary
86  if (new_size>cells.size())
87  {
88  cells.reserve (new_size);
89  cells.insert (cells.end(),
90  new_size-cells.size(),
91  G ());
92 
93  used.reserve (new_size);
94  used.insert (used.end(),
95  new_size-used.size(),
96  false);
97 
98  user_flags.reserve (new_size);
99  user_flags.insert (user_flags.end(),
100  new_size-user_flags.size(),
101  false);
102 
103  const unsigned int factor = GeometryInfo<G::dimension>::max_children_per_cell / 2;
104  children.reserve (factor*new_size);
105  children.insert (children.end(),
106  factor*new_size-children.size(),
107  -1);
108 
109  if (G::dimension > 1)
110  {
111  refinement_cases.reserve (new_size);
112  refinement_cases.insert (refinement_cases.end(),
113  new_size - refinement_cases.size(),
115  }
116 
117  // first reserve, then resize. Otherwise the std library can decide to allocate
118  // more entries.
119  boundary_or_material_id.reserve (new_size);
120  boundary_or_material_id.resize (new_size);
121 
122  user_data.reserve (new_size);
123  user_data.resize (new_size);
124 
125  manifold_id.reserve (new_size);
126  manifold_id.insert (manifold_id.end(),
127  new_size-manifold_id.size(),
129 
130  }
131 
132  if (n_unused_singles==0)
133  {
134  next_free_single=new_size-1;
135  reverse_order_next_free_single=true;
136  }
137  }
138 
139 
140  template <>
141  template <int dim, int spacedim>
142  typename ::Triangulation<dim,spacedim>::raw_hex_iterator
143  TriaObjects<TriaObject<3> >::next_free_hex (const ::Triangulation<dim,spacedim> &tria,
144  const unsigned int level)
145  {
146  // TODO: Think of a way to ensure that we are using the correct triangulation, i.e. the one containing *this.
147 
148  int pos=next_free_pair,
149  last=used.size()-1;
150  for (; pos<last; ++pos)
151  if (!used[pos])
152  {
153  // this should be a pair slot
154  Assert(!used[pos+1], ExcInternalError());
155  break;
156  }
157  if (pos>=last)
158  // no free slot
159  return tria.end_hex();
160  else
161  next_free_pair=pos+2;
162 
163  return typename ::Triangulation<dim,spacedim>::raw_hex_iterator(&tria,level,pos);
164  }
165 
166 
167  void
168  TriaObjectsHex::reserve_space (const unsigned int new_hexes)
169  {
170  const unsigned int new_size = new_hexes +
171  std::count_if (used.begin(),
172  used.end(),
173  std::bind (std::equal_to<bool>(), std::placeholders::_1, true));
174 
175  // see above...
176  if (new_size>cells.size())
177  {
178  cells.reserve (new_size);
179  cells.insert (cells.end(),
180  new_size-cells.size(),
181  TriaObject<3> ());
182 
183  used.reserve (new_size);
184  used.insert (used.end(),
185  new_size-used.size(),
186  false);
187 
188  user_flags.reserve (new_size);
189  user_flags.insert (user_flags.end(),
190  new_size-user_flags.size(),
191  false);
192 
193  children.reserve (4*new_size);
194  children.insert (children.end(),
195  4*new_size-children.size(),
196  -1);
197 
198  // for the following fields, we know exactly how many elements
199  // we need, so first reserve then resize (resize itself, at least
200  // with some compiler libraries, appears to round up the size it
201  // actually reserves)
202  boundary_or_material_id.reserve (new_size);
203  boundary_or_material_id.resize (new_size);
204 
205  manifold_id.reserve (new_size);
206  manifold_id.insert (manifold_id.end(),
207  new_size-manifold_id.size(),
209 
210  user_data.reserve (new_size);
211  user_data.resize (new_size);
212 
214  face_orientations.insert (face_orientations.end(),
216  - face_orientations.size(),
217  true);
218 
219  refinement_cases.reserve (new_size);
220  refinement_cases.insert (refinement_cases.end(),
221  new_size-refinement_cases.size(),
223 
224  face_flips.reserve (new_size * GeometryInfo<3>::faces_per_cell);
225  face_flips.insert (face_flips.end(),
227  - face_flips.size(),
228  false);
229  face_rotations.reserve (new_size * GeometryInfo<3>::faces_per_cell);
230  face_rotations.insert (face_rotations.end(),
232  - face_rotations.size(),
233  false);
234  }
236  }
237 
238 
239  void
240  TriaObjectsQuad3D::reserve_space (const unsigned int new_quads_in_pairs,
241  const unsigned int new_quads_single)
242  {
243  Assert(new_quads_in_pairs%2==0, ExcInternalError());
244 
246  next_free_pair=0;
248 
249  // count the number of objects, of unused single objects and of
250  // unused pairs of objects
251  unsigned int n_quads=0;
252  unsigned int n_unused_pairs=0;
253  unsigned int n_unused_singles=0;
254  for (unsigned int i=0; i<used.size(); ++i)
255  {
256  if (used[i])
257  ++n_quads;
258  else if (i+1<used.size())
259  {
260  if (used[i+1])
261  {
262  ++n_unused_singles;
263  if (next_free_single==0)
265  }
266  else
267  {
268  ++n_unused_pairs;
269  if (next_free_pair==0)
270  next_free_pair=i;
271  ++i;
272  }
273  }
274  else
275  ++n_unused_singles;
276  }
277  Assert(n_quads+2*n_unused_pairs+n_unused_singles==used.size(),
278  ExcInternalError());
279 
280  // how many single quads are needed in addition to n_unused_quads?
281  const int additional_single_quads=
282  new_quads_single-n_unused_singles;
283 
284  unsigned int new_size=
285  used.size() + new_quads_in_pairs - 2*n_unused_pairs;
286  if (additional_single_quads>0)
287  new_size+=additional_single_quads;
288 
289  // see above...
290  if (new_size>cells.size())
291  {
292  // reseve space for the base class
293  TriaObjects<TriaObject<2> >::reserve_space(new_quads_in_pairs,new_quads_single);
294  // reserve the field of the derived class
296  line_orientations.insert (line_orientations.end(),
298  - line_orientations.size(),
299  true);
300  }
301 
302  if (n_unused_singles==0)
303  {
304  next_free_single=new_size-1;
306  }
307  }
308 
309 
310  template <>
311  void
312  TriaObjects<TriaObject<1> >::monitor_memory (const unsigned int) const
313  {
314  Assert (cells.size() == used.size(),
315  ExcMemoryInexact (cells.size(), used.size()));
316  Assert (cells.size() == user_flags.size(),
317  ExcMemoryInexact (cells.size(), user_flags.size()));
318  Assert (cells.size() == children.size(),
319  ExcMemoryInexact (cells.size(), children.size()));
320  Assert (cells.size() == boundary_or_material_id.size(),
321  ExcMemoryInexact (cells.size(), boundary_or_material_id.size()));
322  Assert (cells.size() == manifold_id.size(),
323  ExcMemoryInexact (cells.size(), manifold_id.size()));
324  Assert (cells.size() == user_data.size(),
325  ExcMemoryInexact (cells.size(), user_data.size()));
326  }
327 
328 
329  template <>
330  void
331  TriaObjects<TriaObject<2> >::monitor_memory (const unsigned int) const
332  {
333  Assert (cells.size() == used.size(),
334  ExcMemoryInexact (cells.size(), used.size()));
335  Assert (cells.size() == user_flags.size(),
336  ExcMemoryInexact (cells.size(), user_flags.size()));
337  Assert (2*cells.size() == children.size(),
338  ExcMemoryInexact (cells.size(), children.size()));
339  Assert (cells.size() == refinement_cases.size(),
340  ExcMemoryInexact (cells.size(), refinement_cases.size()));
341  Assert (cells.size() == boundary_or_material_id.size(),
342  ExcMemoryInexact (cells.size(), boundary_or_material_id.size()));
343  Assert (cells.size() == manifold_id.size(),
344  ExcMemoryInexact (cells.size(), manifold_id.size()));
345  Assert (cells.size() == user_data.size(),
346  ExcMemoryInexact (cells.size(), user_data.size()));
347  }
348 
349 
350  void
351  TriaObjectsHex::monitor_memory (const unsigned int) const
352  {
353  Assert (cells.size() == used.size(),
354  ExcMemoryInexact (cells.size(), used.size()));
355  Assert (cells.size() == user_flags.size(),
356  ExcMemoryInexact (cells.size(), user_flags.size()));
357  Assert (4*cells.size() == children.size(),
358  ExcMemoryInexact (cells.size(), children.size()));
359  Assert (cells.size() == boundary_or_material_id.size(),
361  Assert (cells.size() == manifold_id.size(),
362  ExcMemoryInexact (cells.size(), manifold_id.size()));
363  Assert (cells.size() == user_data.size(),
364  ExcMemoryInexact (cells.size(), user_data.size()));
366  == face_orientations.size(),
368  face_orientations.size()));
370  == face_flips.size(),
372  face_flips.size()));
374  == face_rotations.size(),
376  face_rotations.size()));
377  }
378 
379 
380  void
381  TriaObjectsQuad3D::monitor_memory (const unsigned int) const
382  {
383  // check that we have not allocated too much memory. note that bool
384  // vectors allocate their memory in chunks of whole integers, so they
385  // may over-allocate by up to as many elements as an integer has bits
387  == line_orientations.size(),
389  line_orientations.size()));
391 
392  }
393 
394 
395  template <typename G>
396  void
398  {
399  cells.clear();
400  children.clear();
401  refinement_cases.clear();
402  used.clear();
403  user_flags.clear();
404  boundary_or_material_id.clear();
405  manifold_id.clear();
406  user_data.clear();
407  user_data_type = data_unknown;
408  }
409 
410 
411  void
413  {
415  face_orientations.clear();
416  face_flips.clear();
417  face_rotations.clear();
418  }
419 
420 
421  void
423  {
425  line_orientations.clear();
426  }
427 
428 
429  template <typename G>
430  std::size_t
432  {
433  return (MemoryConsumption::memory_consumption (cells) +
437  MemoryConsumption::memory_consumption (boundary_or_material_id) +
439  MemoryConsumption::memory_consumption (refinement_cases) +
440  user_data.capacity() * sizeof(UserData) + sizeof(user_data));
441  }
442 
443 
444  std::size_t
446  {
451  }
452 
453 
454  std::size_t
456  {
459  }
460 
461 
462 
463 // explicit instantiations
464  template class TriaObjects<TriaObject<1> >;
465  template class TriaObjects<TriaObject<2> >;
466 
467 #include "tria_objects.inst"
468  }
469 }
470 
471 DEAL_II_NAMESPACE_CLOSE
472 
void reserve_space(const unsigned int new_objs)
const types::manifold_id flat_manifold_id
Definition: types.h:237
static ::ExceptionBase & ExcMemoryInexact(int arg1, int arg2)
void monitor_memory(const unsigned int true_dimension) const
void monitor_memory(const unsigned int true_dimension) const
#define Assert(cond, exc)
Definition: exceptions.h:1142
void reserve_space(const unsigned int new_objs_in_pairs, const unsigned int new_objs_single=0)
Definition: tria_objects.cc:35
std::vector< RefinementCase< TriaObject< 3 > ::dimension > > refinement_cases
Definition: tria_objects.h:94
void reserve_space(const unsigned int new_quads_in_pairs, const unsigned int new_quads_single=0)
std::enable_if< std::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
static ::ExceptionBase & ExcInternalError()