Reference documentation for deal.II version 9.1.0-pre
tria_objects.h
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.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_tria_objects_h
17 #define dealii_tria_objects_h
18 
19 #include <deal.II/base/config.h>
20 
21 #include <deal.II/base/exceptions.h>
22 #include <deal.II/base/geometry_info.h>
23 
24 #include <deal.II/grid/tria_object.h>
25 
26 #include <vector>
27 
28 DEAL_II_NAMESPACE_OPEN
29 
30 // TODO: This should all be cleaned up. Currently, only a single
31 // function in the library makes use of the odd specializations, and
32 // this function is Triangulation::execute_refinement() in 3D. I
33 // assume, that the other refinement functions would profit from using
34 // next_free_single_object() and next_free_pair_object, but they seem
35 // to get around it.
36 
37 // TODO: The TriaObjects class contains a std::vector<G>. This is only an
38 // efficient storage scheme if G is relatively well packed, i.e. it's not a
39 // bool and then an integer and then a double, etc. Verify that this is
40 // actually the case.
41 
42 template <int dim, int spacedim>
43 class Triangulation;
44 template <class Accessor>
45 class TriaRawIterator;
46 template <int, int, int>
47 class TriaAccessor;
48 
49 namespace internal
50 {
51  namespace TriangulationImplementation
52  {
65  template <typename G>
66  class TriaObjects
67  {
68  public:
72  TriaObjects();
73 
78  std::vector<G> cells;
79 
91  std::vector<int> children;
92 
98  std::vector<RefinementCase<G::dimension>> refinement_cases;
99 
108  std::vector<bool> used;
109 
119  std::vector<bool> user_flags;
120 
121 
127  {
128  union
129  {
130  types::boundary_id boundary_id;
131  types::material_id material_id;
132  };
133 
134 
139 
143  static std::size_t
145 
150  template <class Archive>
151  void
152  serialize(Archive &ar, const unsigned int version);
153  };
154 
169  std::vector<BoundaryOrMaterialId> boundary_or_material_id;
170 
175  std::vector<types::manifold_id> manifold_id;
176 
187  void
188  reserve_space(const unsigned int new_objs_in_pairs,
189  const unsigned int new_objs_single = 0);
190 
202  template <int dim, int spacedim>
204  next_free_single_object(const ::Triangulation<dim, spacedim> &tria);
205 
217  template <int dim, int spacedim>
219  next_free_pair_object(const ::Triangulation<dim, spacedim> &tria);
220 
225  template <int dim, int spacedim>
226  typename ::Triangulation<dim, spacedim>::raw_hex_iterator
227  next_free_hex(const ::Triangulation<dim, spacedim> &tria,
228  const unsigned int level);
229 
233  void
234  clear();
235 
250  bool
251  face_orientation(const unsigned int cell, const unsigned int face) const;
252 
253 
257  void *&
258  user_pointer(const unsigned int i);
259 
263  const void *
264  user_pointer(const unsigned int i) const;
265 
269  unsigned int &
270  user_index(const unsigned int i);
271 
275  unsigned int
276  user_index(const unsigned int i) const;
277 
281  void
282  clear_user_data(const unsigned int i);
283 
288  void
289  clear_user_data();
290 
294  void
296 
302  void
303  monitor_memory(const unsigned int true_dimension) const;
304 
309  std::size_t
310  memory_consumption() const;
311 
316  template <class Archive>
317  void
318  serialize(Archive &ar, const unsigned int version);
319 
325  int,
326  int,
327  << "The containers have sizes " << arg1 << " and " << arg2
328  << ", which is not as expected.");
329 
338 
339  protected:
343  unsigned int next_free_single;
344 
348  unsigned int next_free_pair;
349 
354 
358  struct UserData
359  {
360  union
361  {
364  void *p;
367  unsigned int i;
368  };
369 
374  {
375  p = nullptr;
376  }
377 
382  template <class Archive>
383  void
384  serialize(Archive &ar, const unsigned int version);
385  };
386 
391  {
398  };
399 
400 
405  std::vector<UserData> user_data;
406 
413  };
414 
421  class TriaObjectsHex : public TriaObjects<TriaObject<3>>
422  {
423  public:
431  bool
432  face_orientation(const unsigned int cell, const unsigned int face) const;
433 
434 
457  std::vector<bool> face_orientations;
458 
462  std::vector<bool> face_flips;
463 
467  std::vector<bool> face_rotations;
468 
475  void
476  reserve_space(const unsigned int new_objs);
477 
481  void
482  clear();
483 
489  void
490  monitor_memory(const unsigned int true_dimension) const;
491 
496  std::size_t
497  memory_consumption() const;
498 
503  template <class Archive>
504  void
505  serialize(Archive &ar, const unsigned int version);
506  };
507 
508 
515  class TriaObjectsQuad3D : public TriaObjects<TriaObject<2>>
516  {
517  public:
525  bool
526  face_orientation(const unsigned int cell, const unsigned int face) const;
527 
528 
533  std::vector<bool> line_orientations;
534 
542  void
543  reserve_space(const unsigned int new_quads_in_pairs,
544  const unsigned int new_quads_single = 0);
545 
549  void
550  clear();
551 
557  void
558  monitor_memory(const unsigned int true_dimension) const;
559 
564  std::size_t
565  memory_consumption() const;
566 
571  template <class Archive>
572  void
573  serialize(Archive &ar, const unsigned int version);
574  };
575 
576  //----------------------------------------------------------------------//
577 
578 
579  template <typename G>
581  {
582  material_id = numbers::invalid_material_id;
583  }
584 
585 
586 
587  template <typename G>
588  std::size_t
590  {
591  return sizeof(BoundaryOrMaterialId);
592  }
593 
594 
595 
596  template <typename G>
597  template <class Archive>
598  void
600  Archive &ar,
601  const unsigned int /*version*/)
602  {
603  // serialize this
604  // structure by
605  // writing and
606  // reading the larger
607  // of the two values,
608  // in order to make
609  // sure we get all
610  // bits
611  if (sizeof(material_id) > sizeof(boundary_id))
612  ar &material_id;
613  else
614  ar &boundary_id;
615  }
616 
617 
618  template <typename G>
619  inline bool
621  const unsigned int) const
622  {
623  return true;
624  }
625 
626 
627  template <typename G>
628  inline void *&
629  TriaObjects<G>::user_pointer(const unsigned int i)
630  {
634 
635  Assert(i < user_data.size(), ExcIndexRange(i, 0, user_data.size()));
636  return user_data[i].p;
637  }
638 
639 
640  template <typename G>
641  inline const void *
642  TriaObjects<G>::user_pointer(const unsigned int i) const
643  {
647 
648  Assert(i < user_data.size(), ExcIndexRange(i, 0, user_data.size()));
649  return user_data[i].p;
650  }
651 
652 
653  template <typename G>
654  inline unsigned int &
655  TriaObjects<G>::user_index(const unsigned int i)
656  {
660 
661  Assert(i < user_data.size(), ExcIndexRange(i, 0, user_data.size()));
662  return user_data[i].i;
663  }
664 
665 
666  template <typename G>
667  inline void
668  TriaObjects<G>::clear_user_data(const unsigned int i)
669  {
670  Assert(i < user_data.size(), ExcIndexRange(i, 0, user_data.size()));
671  user_data[i].i = 0;
672  }
673 
674 
675  template <typename G>
677  : next_free_single(numbers::invalid_unsigned_int)
678  , next_free_pair(numbers::invalid_unsigned_int)
681  {}
682 
683 
684  template <typename G>
685  inline unsigned int
686  TriaObjects<G>::user_index(const unsigned int i) const
687  {
691 
692  Assert(i < user_data.size(), ExcIndexRange(i, 0, user_data.size()));
693  return user_data[i].i;
694  }
695 
696 
697  template <typename G>
698  inline void
700  {
702  for (unsigned int i = 0; i < user_data.size(); ++i)
703  user_data[i].p = nullptr;
704  }
705 
706 
707  template <typename G>
708  inline void
710  {
711  user_flags.assign(user_flags.size(), false);
712  }
713 
714 
715  template <typename G>
716  template <class Archive>
717  void
718  TriaObjects<G>::UserData::serialize(Archive &ar, const unsigned int)
719  {
720  // serialize this as an integer
721  ar &i;
722  }
723 
724 
725 
726  template <typename G>
727  template <class Archive>
728  void
729  TriaObjects<G>::serialize(Archive &ar, const unsigned int)
730  {
731  ar &cells &children;
732  ar & refinement_cases;
733  ar & used;
734  ar & user_flags;
736  ar & manifold_id;
739  }
740 
741 
742  template <class Archive>
743  void
744  TriaObjectsHex::serialize(Archive &ar, const unsigned int version)
745  {
746  this->TriaObjects<TriaObject<3>>::serialize(ar, version);
747 
748  ar &face_orientations &face_flips &face_rotations;
749  }
750 
751 
752  template <class Archive>
753  void
754  TriaObjectsQuad3D::serialize(Archive &ar, const unsigned int version)
755  {
756  this->TriaObjects<TriaObject<2>>::serialize(ar, version);
757 
758  ar &line_orientations;
759  }
760 
761 
762  //----------------------------------------------------------------------//
763 
764  inline bool
765  TriaObjectsHex::face_orientation(const unsigned int cell,
766  const unsigned int face) const
767  {
768  Assert(cell < face_orientations.size() / GeometryInfo<3>::faces_per_cell,
769  ExcIndexRange(0,
770  cell,
771  face_orientations.size() /
775 
776  return face_orientations[cell * GeometryInfo<3>::faces_per_cell + face];
777  }
778 
779  //----------------------------------------------------------------------//
780 
781  inline bool
782  TriaObjectsQuad3D::face_orientation(const unsigned int cell,
783  const unsigned int face) const
784  {
785  return line_orientations[cell * GeometryInfo<2>::faces_per_cell + face];
786  }
787 
788 
789  //----------------------------------------------------------------------//
790 
791  template <class G>
792  template <int dim, int spacedim>
795  const ::Triangulation<dim, spacedim> &tria)
796  {
797  // TODO: Think of a way to ensure that we are using the correct
798  // triangulation, i.e. the one containing *this.
799 
800  int pos = next_free_single, last = used.size() - 1;
802  {
803  // first sweep forward, only use really single slots, do not use
804  // pair slots
805  for (; pos < last; ++pos)
806  if (!used[pos])
807  if (used[++pos])
808  {
809  // this was a single slot
810  pos -= 1;
811  break;
812  }
813  if (pos >= last)
814  {
816  next_free_single = used.size() - 1;
817  pos = used.size() - 1;
818  }
819  else
820  next_free_single = pos + 1;
821  }
822 
824  {
825  // second sweep, use all slots, even
826  // in pairs
827  for (; pos >= 0; --pos)
828  if (!used[pos])
829  break;
830  if (pos > 0)
831  next_free_single = pos - 1;
832  else
833  // no valid single object anymore
834  return ::TriaRawIterator<
836  }
837 
838  return ::TriaRawIterator<
840  }
841 
842 
843 
844  template <class G>
845  template <int dim, int spacedim>
848  const ::Triangulation<dim, spacedim> &tria)
849  {
850  // TODO: Think of a way to ensure that we are using the correct
851  // triangulation, i.e. the one containing *this.
852 
853  int pos = next_free_pair, last = used.size() - 1;
854  for (; pos < last; ++pos)
855  if (!used[pos])
856  if (!used[++pos])
857  {
858  // this was a pair slot
859  pos -= 1;
860  break;
861  }
862  if (pos >= last)
863  // no free slot
864  return ::TriaRawIterator<
866  else
867  next_free_pair = pos + 2;
868 
869  return ::TriaRawIterator<
871  }
872 
873 
874 
875  // declaration of explicit specializations
876 
877  template <>
878  void
879  TriaObjects<TriaObject<2>>::monitor_memory(const unsigned int) const;
880 
881  } // namespace TriangulationImplementation
882 } // namespace internal
883 
884 
885 
886 DEAL_II_NAMESPACE_CLOSE
887 
888 #endif
::TriaRawIterator<::TriaAccessor< G::dimension, dim, spacedim > > next_free_pair_object(const ::Triangulation< dim, spacedim > &tria)
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:420
static::ExceptionBase & ExcMemoryInexact(int arg1, int arg2)
::TriaRawIterator<::TriaAccessor< G::dimension, dim, spacedim > > next_free_single_object(const ::Triangulation< dim, spacedim > &tria)
void serialize(Archive &ar, const unsigned int version)
Definition: tria_objects.h:729
unsigned int material_id
Definition: types.h:134
void serialize(Archive &ar, const unsigned int version)
Definition: tria_objects.h:754
static::ExceptionBase & ExcIndexRange(int arg1, int arg2, int arg3)
unsigned int & user_index(const unsigned int i)
Definition: tria_objects.h:655
bool face_orientation(const unsigned int cell, const unsigned int face) const
Definition: tria_objects.h:620
std::vector< BoundaryOrMaterialId > boundary_or_material_id
Definition: tria_objects.h:169
void monitor_memory(const unsigned int true_dimension) const
#define Assert(cond, exc)
Definition: exceptions.h:1227
#define DeclException0(Exception0)
Definition: exceptions.h:385
bool face_orientation(const unsigned int cell, const unsigned int face) const
Definition: tria_objects.h:765
void reserve_space(const unsigned int new_objs_in_pairs, const unsigned int new_objs_single=0)
Definition: tria_objects.cc:36
std::vector< RefinementCase< G::dimension > > refinement_cases
Definition: tria_objects.h:98
std::vector< types::manifold_id > manifold_id
Definition: tria_objects.h:175
void serialize(Archive &ar, const unsigned int version)
Definition: tria_objects.h:744
bool face_orientation(const unsigned int cell, const unsigned int face) const
Definition: tria_objects.h:782
typename::Triangulation< dim, spacedim >::raw_hex_iterator next_free_hex(const ::Triangulation< dim, spacedim > &tria, const unsigned int level)
const types::material_id invalid_material_id
Definition: types.h:196
unsigned int boundary_id
Definition: types.h:111
void serialize(Archive &ar, const unsigned int version)
Definition: tria_objects.h:718