Reference documentation for deal.II version 9.0.0
dof_handler.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2005 - 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 #ifndef dealii_hp_dof_handler_h
17 #define dealii_hp_dof_handler_h
18 
19 
20 
21 #include <deal.II/base/config.h>
22 #include <deal.II/base/exceptions.h>
23 #include <deal.II/base/template_constraints.h>
24 #include <deal.II/base/smartpointer.h>
25 #include <deal.II/base/iterator_range.h>
26 #include <deal.II/dofs/function_map.h>
27 #include <deal.II/dofs/dof_accessor.h>
28 #include <deal.II/dofs/dof_iterator_selector.h>
29 #include <deal.II/dofs/number_cache.h>
30 #include <deal.II/hp/fe_collection.h>
31 #include <deal.II/hp/dof_faces.h>
32 #include <deal.II/hp/dof_level.h>
33 
34 #include <vector>
35 #include <map>
36 #include <set>
37 
38 DEAL_II_NAMESPACE_OPEN
39 
40 template <int dim, int spacedim> class Triangulation;
41 
42 namespace internal
43 {
44  namespace DoFHandlerImplementation
45  {
46  struct Implementation;
47 
48  namespace Policy
49  {
50  template <int dim, int spacedim> class PolicyBase;
51  struct Implementation;
52  }
53  }
54 
55  namespace hp
56  {
57  class DoFLevel;
58 
59  namespace DoFHandlerImplementation
60  {
61  struct Implementation;
62  }
63  }
64 }
65 
66 namespace internal
67 {
68  namespace DoFAccessorImplementation
69  {
70  struct Implementation;
71  }
72 
73  namespace DoFCellAccessorImplementation
74  {
75  struct Implementation;
76  }
77 }
78 
79 
80 
81 namespace hp
82 {
83 
163  template <int dim, int spacedim=dim>
164  class DoFHandler : public Subscriptor
165  {
166  typedef ::internal::DoFHandlerImplementation::Iterators<DoFHandler<dim,spacedim>, false> ActiveSelector;
167  typedef ::internal::DoFHandlerImplementation::Iterators<DoFHandler<dim,spacedim>, true> LevelSelector;
168  public:
169  typedef typename ActiveSelector::CellAccessor cell_accessor;
170  typedef typename ActiveSelector::FaceAccessor face_accessor;
171 
172  typedef typename ActiveSelector::line_iterator line_iterator;
173  typedef typename ActiveSelector::active_line_iterator active_line_iterator;
174 
175  typedef typename ActiveSelector::quad_iterator quad_iterator;
176  typedef typename ActiveSelector::active_quad_iterator active_quad_iterator;
177 
178  typedef typename ActiveSelector::hex_iterator hex_iterator;
179  typedef typename ActiveSelector::active_hex_iterator active_hex_iterator;
180 
185 #ifndef _MSC_VER
186  typedef typename ActiveSelector::active_cell_iterator active_cell_iterator;
187 #else
189 #endif
190 
191  typedef typename LevelSelector::cell_iterator level_cell_iterator;
192 
197 #ifndef _MSC_VER
198  typedef typename ActiveSelector::cell_iterator cell_iterator;
199 #else
201 #endif
202 
207  typedef typename ActiveSelector::face_iterator face_iterator;
208 
213  typedef typename ActiveSelector::active_face_iterator active_face_iterator;
214 
215  typedef typename LevelSelector::CellAccessor level_cell_accessor;
216  typedef typename LevelSelector::FaceAccessor level_face_accessor;
217 
218  typedef typename LevelSelector::face_iterator level_face_iterator;
219 
223  static const unsigned int dimension = dim;
224 
228  static const unsigned int space_dimension = spacedim;
229 
241  DEAL_II_DEPRECATED
243 
254  static const unsigned int default_fe_index = numbers::invalid_unsigned_int;
255 
256 
260  DoFHandler ();
261 
266 
273  DoFHandler (const DoFHandler &) = delete;
274 
278  virtual ~DoFHandler ();
279 
286  DoFHandler &operator = (const DoFHandler &) = delete;
287 
294 
320  virtual void distribute_dofs (const hp::FECollection<dim,spacedim> &fe);
321 
326  void set_active_fe_indices (const std::vector<unsigned int> &active_fe_indices);
327 
333  void get_active_fe_indices (std::vector<unsigned int> &active_fe_indices) const;
334 
340  virtual void clear ();
341 
394  void renumber_dofs (const std::vector<types::global_dof_index> &new_numbers);
395 
413  unsigned int max_couplings_between_dofs () const;
414 
427  unsigned int max_couplings_between_boundary_dofs () const;
428 
436  cell_iterator begin (const unsigned int level = 0) const;
437 
450  active_cell_iterator begin_active(const unsigned int level = 0) const;
451 
456  cell_iterator end () const;
457 
462  cell_iterator end (const unsigned int level) const;
463 
469  active_cell_iterator end_active (const unsigned int level) const;
470 
486 
529 
545  IteratorRange<cell_iterator> cell_iterators_on_level (const unsigned int level) const;
546 
563 
564  /*
565  * @}
566  */
567 
568  /*---------------------------------------*/
569 
570 
596 
602  types::global_dof_index n_dofs(const unsigned int level) const;
603 
608 
621  template <typename number>
623  n_boundary_dofs (const std::map<types::boundary_id, const Function<spacedim,number>*> &boundary_ids) const;
624 
630  n_boundary_dofs (const std::set<types::boundary_id> &boundary_ids) const;
631 
651 
657  const IndexSet &locally_owned_dofs() const;
658 
672  const std::vector<IndexSet> &
674 
691  const std::vector<types::global_dof_index> &
693 
700  const IndexSet &locally_owned_mg_dofs(const unsigned int level) const;
701 
708  const std::vector<IndexSet> &
709  locally_owned_mg_dofs_per_processor (const unsigned int level) const;
710 
717  DEAL_II_DEPRECATED
718  const hp::FECollection<dim,spacedim> &get_fe () const;
719 
725  get_fe (const unsigned int index) const;
726 
732 
738 
747  virtual std::size_t memory_consumption () const;
748 
753  template <class Archive>
754  void save(Archive &ar, const unsigned int version) const;
755 
760  template <class Archive>
761  void load(Archive &ar, const unsigned int version);
762 
763  BOOST_SERIALIZATION_SPLIT_MEMBER()
764 
765 
781  int,
782  << "The matrix has the wrong dimension " << arg1);
791  types::global_dof_index,
792  << "The given list of new dof indices is not consecutive: "
793  << "the index " << arg1 << " does not exist.");
798  int, int,
799  << "The mesh contains a cell with an active_fe_index of "
800  << arg1 << ", but the finite element collection only has "
801  << arg2 << " elements");
806  int,
807  << "The given level " << arg1
808  << " is not in the valid range!");
817  int,
818  << "You tried to do something on level " << arg1
819  << ", but this level is empty.");
820 
821  private:
822 
826  SmartPointer<const Triangulation<dim,spacedim>,DoFHandler<dim,spacedim> > tria;
827 
831  hp::FECollection<dim,spacedim> fe_collection;
832 
837  std::unique_ptr<::internal::DoFHandlerImplementation::Policy::PolicyBase<dim,spacedim> > policy;
838 
839 
844 
848  void clear_space ();
849 
850  template <int structdim>
851  types::global_dof_index get_dof_index (const unsigned int obj_level,
852  const unsigned int obj_index,
853  const unsigned int fe_index,
854  const unsigned int local_index) const;
855 
856  template <int structdim>
857  void set_dof_index (const unsigned int obj_level,
858  const unsigned int obj_index,
859  const unsigned int fe_index,
860  const unsigned int local_index,
861  const types::global_dof_index global_index) const;
862 
870  void create_active_fe_table ();
871 
879  void pre_refinement_action ();
880  void post_refinement_action ();
881 
886  std::vector<std::unique_ptr<::internal::hp::DoFLevel> > levels;
887 
892  std::unique_ptr<::internal::hp::DoFIndicesOnFaces<dim> > faces;
893 
901  ::internal::DoFHandlerImplementation::NumberCache number_cache;
902 
908  std::vector<::internal::DoFHandlerImplementation::NumberCache> mg_number_cache;
909 
922  std::vector<types::global_dof_index> vertex_dofs;
923 
936  std::vector<unsigned int> vertex_dof_offsets;
937 
944  std::vector<std::unique_ptr<std::vector<bool> > > has_children;
945 
950  std::vector<boost::signals2::connection> tria_listeners;
951 
955  template <int, class, bool> friend class ::DoFAccessor;
956  template <class, bool> friend class ::DoFCellAccessor;
957  friend struct ::internal::DoFAccessorImplementation::Implementation;
958  friend struct ::internal::DoFCellAccessorImplementation::Implementation;
959 
964  template <int> friend class ::internal::hp::DoFIndicesOnFacesOrEdges;
965  friend struct ::internal::hp::DoFHandlerImplementation::Implementation;
966  friend struct ::internal::DoFHandlerImplementation::Policy::Implementation;
967  };
968 
969 
970 
971 #ifndef DOXYGEN
972 
973 
974  /* ----------------------- Inline functions ---------------------------------- */
975 
976 
977  template <int dim, int spacedim>
978  template <typename number>
981  {
982  // extract the set of boundary ids and forget about the function object pointers
983  std::set<types::boundary_id> boundary_ids_only;
984  for (typename std::map<types::boundary_id, const Function<spacedim,number>*>::const_iterator
985  p = boundary_ids.begin();
986  p != boundary_ids.end(); ++p)
987  boundary_ids_only.insert (p->first);
988 
989  // then just hand everything over to the other function that does the work
990  return n_boundary_dofs(boundary_ids_only);
991  }
992 }
993 
994 
995 namespace internal
996 {
1004  template <int dim, int spacedim>
1005  std::string policy_to_string(const ::internal::DoFHandlerImplementation::Policy::PolicyBase<dim,spacedim> &policy);
1006 }
1007 
1008 
1009 namespace hp
1010 {
1011  template <int dim, int spacedim>
1012  template <class Archive>
1013  void DoFHandler<dim, spacedim>::save(Archive &ar, unsigned int) const
1014  {
1015  ar &vertex_dofs;
1016  ar &vertex_dof_offsets;
1017  ar &number_cache;
1018  ar &mg_number_cache;
1019 
1020  // some versions of gcc have trouble with loading vectors of
1021  // std::unique_ptr objects because std::unique_ptr does not
1022  // have a copy constructor. do it one level at a time
1023  const unsigned int n_levels = levels.size();
1024  ar &n_levels;
1025  for (unsigned int i = 0; i < n_levels; ++i)
1026  ar &levels[i];
1027 
1028  // boost dereferences a nullptr when serializing a nullptr
1029  // at least up to 1.65.1. This causes problems with clang-5.
1030  // Therefore, work around it.
1031  bool faces_is_nullptr = (faces.get()==nullptr);
1032  ar &faces_is_nullptr;
1033  if (!faces_is_nullptr)
1034  ar &faces;
1035 
1036  // the same issue as above
1037  const unsigned int n_has_children = has_children.size();
1038  ar &n_has_children;
1039  for (unsigned int i = 0; i < n_has_children; ++i)
1040  ar &has_children[i];
1041 
1042  // write out the number of triangulation cells and later check during
1043  // loading that this number is indeed correct; same with something that
1044  // identifies the policy
1045  const unsigned int n_cells = tria->n_cells();
1046  std::string policy_name = ::internal::policy_to_string(*policy);
1047 
1048  ar &n_cells &policy_name;
1049  }
1050 
1051 
1052 
1053  template <int dim, int spacedim>
1054  template <class Archive>
1055  void DoFHandler<dim, spacedim>::load(Archive &ar, unsigned int)
1056  {
1057  ar &vertex_dofs;
1058  ar &vertex_dof_offsets;
1059  ar &number_cache;
1060  ar &mg_number_cache;
1061 
1062  // boost::serialization can restore pointers just fine, but if the
1063  // pointer object still points to something useful, that object is not
1064  // destroyed and we end up with a memory leak. consequently, first delete
1065  // previous content before re-loading stuff
1066  levels.clear ();
1067  has_children.clear ();
1068  faces.reset ();
1069 
1070  // some versions of gcc have trouble with loading vectors of
1071  // std::unique_ptr objects because std::unique_ptr does not
1072  // have a copy constructor. do it one level at a time
1073  unsigned int size;
1074  ar &size;
1075  levels.resize(size);
1076  for (unsigned int i = 0; i < size; ++i)
1077  {
1078  std::unique_ptr<::internal::hp::DoFLevel> level;
1079  ar &level;
1080  levels[i] = std::move(level);
1081  }
1082 
1083  //Workaround for nullptr, see in save().
1084  bool faces_is_nullptr = true;
1085  ar &faces_is_nullptr;
1086  if (!faces_is_nullptr)
1087  ar &faces;
1088 
1089  // the same issue as above
1090  ar &size;
1091  has_children.resize(size);
1092  for (unsigned int i = 0; i < size; ++i)
1093  {
1094  std::unique_ptr<std::vector<bool> > has_children_on_level;
1095  ar &has_children_on_level;
1096  has_children[i] = std::move(has_children_on_level);
1097  }
1098 
1099  // these are the checks that correspond to the last block in the save()
1100  // function
1101  unsigned int n_cells;
1102  std::string policy_name;
1103 
1104  ar &n_cells &policy_name;
1105 
1106  AssertThrow (n_cells == tria->n_cells(),
1107  ExcMessage ("The object being loaded into does not match the triangulation "
1108  "that has been stored previously."));
1109  AssertThrow (policy_name == ::internal::policy_to_string(*policy),
1110  ExcMessage ("The policy currently associated with this DoFHandler ("
1111  + ::internal::policy_to_string(*policy)
1112  + ") does not match the one that was associated with the "
1113  "DoFHandler previously stored ("
1114  + policy_name
1115  + ")."));
1116  }
1117 
1118  template <int dim, int spacedim>
1119  inline
1122  {
1123  return number_cache.n_global_dofs;
1124  }
1125 
1126 
1127 
1128  template <int dim, int spacedim>
1129  inline
1131  DoFHandler<dim,spacedim>::n_dofs (const unsigned int) const
1132  {
1133  Assert(false, ExcNotImplemented());
1135  }
1136 
1137 
1138 
1139  template <int dim, int spacedim>
1142  {
1143  return number_cache.n_locally_owned_dofs;
1144  }
1145 
1146 
1147 
1148  template <int dim, int spacedim>
1149  const IndexSet &
1151  {
1152  return number_cache.locally_owned_dofs;
1153  }
1154 
1155 
1156 
1157  template <int dim, int spacedim>
1158  const std::vector<types::global_dof_index> &
1160  {
1161  return number_cache.n_locally_owned_dofs_per_processor;
1162  }
1163 
1164 
1165 
1166  template <int dim, int spacedim>
1167  const std::vector<IndexSet> &
1169  {
1170  return number_cache.locally_owned_dofs_per_processor;
1171  }
1172 
1173 
1174 
1175  template <int dim, int spacedim>
1176  const IndexSet &
1177  DoFHandler<dim, spacedim>::locally_owned_mg_dofs (const unsigned int level) const
1178  {
1179  Assert(false, ExcNotImplemented());
1180  (void)level;
1181  Assert(level < this->get_triangulation().n_global_levels(),
1182  ExcMessage("invalid level in locally_owned_mg_dofs"));
1183  return mg_number_cache[0].locally_owned_dofs;
1184  }
1185 
1186 
1187  template <int dim, int spacedim>
1188  const std::vector<IndexSet> &
1190  {
1191  Assert(false, ExcNotImplemented());
1192  (void)level;
1193  Assert(level < this->get_triangulation().n_global_levels(),
1194  ExcMessage("invalid level in locally_owned_mg_dofs_per_processor"));
1195  return mg_number_cache[0].locally_owned_dofs_per_processor;
1196  }
1197 
1198 
1199 
1200  template <int dim, int spacedim>
1201  inline
1204  {
1205  Assert (fe_collection.size() > 0,
1206  ExcMessage ("No finite element collection is associated with "
1207  "this DoFHandler"));
1208  return fe_collection;
1209  }
1210 
1211 
1212 
1213  template <int dim, int spacedim>
1214  inline
1217  (const unsigned int number) const
1218  {
1219  Assert (fe_collection.size() > 0,
1220  ExcMessage ("No finite element collection is associated with "
1221  "this DoFHandler"));
1222  return fe_collection[number];
1223  }
1224 
1225 
1226 
1227  template <int dim, int spacedim>
1228  inline
1231  {
1232  Assert (fe_collection.size() > 0,
1233  ExcMessage ("No finite element collection is associated with "
1234  "this DoFHandler"));
1235  return fe_collection;
1236  }
1237 
1238 
1239 
1240  template <int dim, int spacedim>
1241  inline
1244  {
1245  Assert(tria != nullptr,
1246  ExcMessage("This DoFHandler object has not been associated "
1247  "with a triangulation."));
1248  return *tria;
1249  }
1250 
1251 #endif
1252 
1253 }
1254 
1255 DEAL_II_NAMESPACE_CLOSE
1256 
1257 #endif
cell_iterator begin(const unsigned int level=0) const
Definition: dof_handler.cc:996
IteratorRange< active_cell_iterator > active_cell_iterators_on_level(const unsigned int level) const
void get_active_fe_indices(std::vector< unsigned int > &active_fe_indices) const
const std::vector< IndexSet > & locally_owned_mg_dofs_per_processor(const unsigned int level) const
types::global_dof_index n_locally_owned_dofs() const
virtual void distribute_dofs(const hp::FECollection< dim, spacedim > &fe)
static const unsigned int invalid_unsigned_int
Definition: types.h:173
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:358
static ::ExceptionBase & ExcInvalidFEIndex(int arg1, int arg2)
void renumber_dofs(const std::vector< types::global_dof_index > &new_numbers)
std::vector<::internal::DoFHandlerImplementation::NumberCache > mg_number_cache
Definition: dof_handler.h:908
virtual std::size_t memory_consumption() const
void set_active_fe_indices(const std::vector< unsigned int > &active_fe_indices)
::internal::DoFHandlerImplementation::NumberCache number_cache
Definition: dof_handler.h:901
static ::ExceptionBase & ExcGridsDoNotMatch()
std::vector< std::unique_ptr<::internal::hp::DoFLevel > > levels
Definition: dof_handler.h:886
unsigned int boundary_id
Definition: types.h:110
const std::vector< types::global_dof_index > & n_locally_owned_dofs_per_processor() const
std::vector< std::unique_ptr< std::vector< bool > > > has_children
Definition: dof_handler.h:944
void pre_refinement_action()
active_cell_iterator begin_active(const unsigned int level=0) const
std::unique_ptr<::internal::hp::DoFIndicesOnFaces< dim > > faces
Definition: dof_handler.h:892
static ::ExceptionBase & ExcFunctionNotUseful()
void setup_policy_and_listeners()
static ::ExceptionBase & ExcNewNumbersNotConsecutive(types::global_dof_index arg1)
STL namespace.
std::unique_ptr<::internal::DoFHandlerImplementation::Policy::PolicyBase< dim, spacedim > > policy
Definition: dof_handler.h:837
#define AssertThrow(cond, exc)
Definition: exceptions.h:1221
std::vector< boost::signals2::connection > tria_listeners
Definition: dof_handler.h:950
virtual void clear()
hp::FECollection< dim, spacedim > fe_collection
Definition: dof_handler.h:831
static const unsigned int dimension
Definition: dof_handler.h:223
ActiveSelector::active_cell_iterator active_cell_iterator
Definition: dof_handler.h:186
static const unsigned int default_fe_index
Definition: dof_handler.h:254
const hp::FECollection< dim, spacedim > & get_fe() const
static ::ExceptionBase & ExcNoFESelected()
static ::ExceptionBase & ExcMessage(std::string arg1)
static const unsigned int space_dimension
Definition: dof_handler.h:228
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:346
Definition: types.h:30
unsigned int global_dof_index
Definition: types.h:88
#define Assert(cond, exc)
Definition: exceptions.h:1142
static ::ExceptionBase & ExcFacesHaveNoLevel()
IteratorRange< active_cell_iterator > active_cell_iterators() const
const IndexSet & locally_owned_dofs() const
ActiveSelector::face_iterator face_iterator
Definition: dof_handler.h:207
void save(Archive &ar, const unsigned int version) const
const std::vector< IndexSet > & locally_owned_dofs_per_processor() const
#define DeclException0(Exception0)
Definition: exceptions.h:323
unsigned int max_couplings_between_boundary_dofs() const
ActiveSelector::cell_iterator cell_iterator
Definition: dof_handler.h:198
static ::ExceptionBase & ExcInvalidLevel(int arg1)
const hp::FECollection< dim, spacedim > & get_fe_collection() const
static ::ExceptionBase & ExcInvalidBoundaryIndicator()
Definition: hp.h:102
types::global_dof_index n_boundary_dofs() const
active_cell_iterator end_active(const unsigned int level) const
SmartPointer< const Triangulation< dim, spacedim >, DoFHandler< dim, spacedim > > tria
Definition: dof_handler.h:826
ActiveSelector::active_face_iterator active_face_iterator
Definition: dof_handler.h:213
void initialize(const Triangulation< dim, spacedim > &tria, const hp::FECollection< dim, spacedim > &fe)
const Triangulation< dim, spacedim > & get_triangulation() const
unsigned int max_couplings_between_dofs() const
void load(Archive &ar, const unsigned int version)
virtual ~DoFHandler()
Definition: dof_handler.cc:976
static ::ExceptionBase & ExcMatrixHasWrongSize(int arg1)
types::global_dof_index n_dofs() const
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
static ::ExceptionBase & ExcNotImplemented()
const types::global_dof_index invalid_dof_index
Definition: types.h:187
void create_active_fe_table()
std::vector< types::global_dof_index > vertex_dofs
Definition: dof_handler.h:922
const IndexSet & locally_owned_mg_dofs(const unsigned int level) const
cell_iterator end() const
IteratorRange< cell_iterator > cell_iterators() const
std::vector< unsigned int > vertex_dof_offsets
Definition: dof_handler.h:936
static ::ExceptionBase & ExcEmptyLevel(int arg1)
DoFHandler & operator=(const DoFHandler &)=delete
static const types::global_dof_index invalid_dof_index
Definition: dof_handler.h:242