Reference documentation for deal.II version 9.1.0-pre
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.md at
12 // the top level directory of deal.II.
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 
23 #include <deal.II/base/exceptions.h>
24 #include <deal.II/base/function.h>
25 #include <deal.II/base/iterator_range.h>
26 #include <deal.II/base/smartpointer.h>
27 #include <deal.II/base/template_constraints.h>
28 
29 #include <deal.II/dofs/deprecated_function_map.h>
30 #include <deal.II/dofs/dof_accessor.h>
31 #include <deal.II/dofs/dof_iterator_selector.h>
32 #include <deal.II/dofs/number_cache.h>
33 
34 #include <deal.II/hp/dof_faces.h>
35 #include <deal.II/hp/dof_level.h>
36 #include <deal.II/hp/fe_collection.h>
37 
38 #include <map>
39 #include <set>
40 #include <vector>
41 
42 DEAL_II_NAMESPACE_OPEN
43 
44 template <int dim, int spacedim>
45 class Triangulation;
46 
47 namespace internal
48 {
49  namespace DoFHandlerImplementation
50  {
51  struct Implementation;
52 
53  namespace Policy
54  {
55  template <int dim, int spacedim>
56  class PolicyBase;
57  struct Implementation;
58  } // namespace Policy
59  } // namespace DoFHandlerImplementation
60 
61  namespace hp
62  {
63  class DoFLevel;
64 
65  namespace DoFHandlerImplementation
66  {
67  struct Implementation;
68  }
69  } // namespace hp
70 } // namespace internal
71 
72 namespace internal
73 {
74  namespace DoFAccessorImplementation
75  {
76  struct Implementation;
77  }
78 
79  namespace DoFCellAccessorImplementation
80  {
81  struct Implementation;
82  }
83 } // namespace internal
84 
85 
86 
87 namespace hp
88 {
168  template <int dim, int spacedim = dim>
169  class DoFHandler : public Subscriptor
170  {
171  using ActiveSelector = ::internal::DoFHandlerImplementation::
172  Iterators<DoFHandler<dim, spacedim>, false>;
173  using LevelSelector = ::internal::DoFHandlerImplementation::
174  Iterators<DoFHandler<dim, spacedim>, true>;
175 
176  public:
177  using cell_accessor = typename ActiveSelector::CellAccessor;
178  using face_accessor = typename ActiveSelector::FaceAccessor;
179 
180  using line_iterator = typename ActiveSelector::line_iterator;
181  using active_line_iterator = typename ActiveSelector::active_line_iterator;
182 
183  using quad_iterator = typename ActiveSelector::quad_iterator;
184  using active_quad_iterator = typename ActiveSelector::active_quad_iterator;
185 
186  using hex_iterator = typename ActiveSelector::hex_iterator;
187  using active_hex_iterator = typename ActiveSelector::active_hex_iterator;
188 
193 #ifndef _MSC_VER
194  using active_cell_iterator = typename ActiveSelector::active_cell_iterator;
195 #else
198 #endif
199 
200  using level_cell_iterator = typename LevelSelector::cell_iterator;
201 
206 #ifndef _MSC_VER
207  using cell_iterator = typename ActiveSelector::cell_iterator;
208 #else
209  using cell_iterator =
211 #endif
212 
217  using face_iterator = typename ActiveSelector::face_iterator;
218 
223  using active_face_iterator = typename ActiveSelector::active_face_iterator;
224 
225  using level_cell_accessor = typename LevelSelector::CellAccessor;
226  using level_face_accessor = typename LevelSelector::FaceAccessor;
227 
228  using level_face_iterator = typename LevelSelector::face_iterator;
229 
233  static const unsigned int dimension = dim;
234 
238  static const unsigned int space_dimension = spacedim;
239 
251  DEAL_II_DEPRECATED
252  static const types::global_dof_index invalid_dof_index =
254 
265  static const unsigned int default_fe_index = numbers::invalid_unsigned_int;
266 
267 
271  DoFHandler();
272 
277 
284  DoFHandler(const DoFHandler &) = delete;
285 
289  virtual ~DoFHandler() override;
290 
297  DoFHandler &
298  operator=(const DoFHandler &) = delete;
299 
304  void
305  initialize(const Triangulation<dim, spacedim> & tria,
307 
333  virtual void
334  distribute_dofs(const hp::FECollection<dim, spacedim> &fe);
335 
340  void
341  set_active_fe_indices(const std::vector<unsigned int> &active_fe_indices);
342 
348  void
349  get_active_fe_indices(std::vector<unsigned int> &active_fe_indices) const;
350 
356  virtual void
357  clear();
358 
411  void
412  renumber_dofs(const std::vector<types::global_dof_index> &new_numbers);
413 
431  unsigned int
432  max_couplings_between_dofs() const;
433 
446  unsigned int
447  max_couplings_between_boundary_dofs() const;
448 
457  begin(const unsigned int level = 0) const;
458 
476  begin_active(const unsigned int level = 0) const;
477 
483  end() const;
484 
490  end(const unsigned int level) const;
491 
498  end_active(const unsigned int level) const;
499 
515  cell_iterators() const;
516 
559  active_cell_iterators() const;
560 
577  cell_iterators_on_level(const unsigned int level) const;
578 
595  active_cell_iterators_on_level(const unsigned int level) const;
596 
597  /*
598  * @}
599  */
600 
601  /*---------------------------------------*/
602 
603 
629  n_dofs() const;
630 
637  n_dofs(const unsigned int level) const;
638 
643  n_boundary_dofs() const;
644 
655  template <typename number>
657  n_boundary_dofs(
658  const std::map<types::boundary_id, const Function<spacedim, number> *>
659  &boundary_ids) const;
660 
666  n_boundary_dofs(const std::set<types::boundary_id> &boundary_ids) const;
667 
686  n_locally_owned_dofs() const;
687 
693  const IndexSet &
694  locally_owned_dofs() const;
695 
709  const std::vector<IndexSet> &
710  locally_owned_dofs_per_processor() const;
711 
727  const std::vector<types::global_dof_index> &
728  n_locally_owned_dofs_per_processor() const;
729 
736  const IndexSet &
737  locally_owned_mg_dofs(const unsigned int level) const;
738 
745  const std::vector<IndexSet> &
746  locally_owned_mg_dofs_per_processor(const unsigned int level) const;
747 
754  DEAL_II_DEPRECATED
756  get_fe() const;
757 
763  get_fe(const unsigned int index) const;
764 
770  get_fe_collection() const;
771 
777  get_triangulation() const;
778 
787  virtual std::size_t
788  memory_consumption() const;
789 
794  template <class Archive>
795  void
796  save(Archive &ar, const unsigned int version) const;
797 
802  template <class Archive>
803  void
804  load(Archive &ar, const unsigned int version);
805 
806  BOOST_SERIALIZATION_SPLIT_MEMBER()
807 
808 
815  DeclException0(ExcGridsDoNotMatch);
823  DeclException1(ExcMatrixHasWrongSize,
824  int,
825  << "The matrix has the wrong dimension " << arg1);
829  DeclException0(ExcFunctionNotUseful);
833  DeclException1(ExcNewNumbersNotConsecutive,
834  types::global_dof_index,
835  << "The given list of new dof indices is not consecutive: "
836  << "the index " << arg1 << " does not exist.");
840  DeclException2(ExcInvalidFEIndex,
841  int,
842  int,
843  << "The mesh contains a cell with an active_fe_index of "
844  << arg1 << ", but the finite element collection only has "
845  << arg2 << " elements");
849  DeclException1(ExcInvalidLevel,
850  int,
851  << "The given level " << arg1
852  << " is not in the valid range!");
860  DeclException1(ExcEmptyLevel,
861  int,
862  << "You tried to do something on level " << arg1
863  << ", but this level is empty.");
864 
865  private:
869  SmartPointer<const Triangulation<dim, spacedim>, DoFHandler<dim, spacedim>>
870  tria;
871 
875  hp::FECollection<dim, spacedim> fe_collection;
876 
881  std::unique_ptr<::internal::DoFHandlerImplementation::Policy::
882  PolicyBase<dim, spacedim>>
883  policy;
884 
885 
889  void
890  setup_policy_and_listeners();
891 
895  void
896  clear_space();
897 
898  template <int structdim>
899  types::global_dof_index
900  get_dof_index(const unsigned int obj_level,
901  const unsigned int obj_index,
902  const unsigned int fe_index,
903  const unsigned int local_index) const;
904 
905  template <int structdim>
906  void
907  set_dof_index(const unsigned int obj_level,
908  const unsigned int obj_index,
909  const unsigned int fe_index,
910  const unsigned int local_index,
911  const types::global_dof_index global_index) const;
912 
920  void
921  create_active_fe_table();
922 
930  void
931  pre_refinement_action();
932  void
933  post_refinement_action();
934 
939  std::vector<std::unique_ptr<::internal::hp::DoFLevel>> levels;
940 
945  std::unique_ptr<::internal::hp::DoFIndicesOnFaces<dim>> faces;
946 
954  ::internal::DoFHandlerImplementation::NumberCache number_cache;
955 
961  std::vector<::internal::DoFHandlerImplementation::NumberCache>
962  mg_number_cache;
963 
976  std::vector<types::global_dof_index> vertex_dofs;
977 
990  std::vector<unsigned int> vertex_dof_offsets;
991 
998  std::vector<std::unique_ptr<std::vector<bool>>> has_children;
999 
1004  std::vector<boost::signals2::connection> tria_listeners;
1005 
1009  template <int, class, bool>
1010  friend class ::DoFAccessor;
1011  template <class, bool>
1012  friend class ::DoFCellAccessor;
1013  friend struct ::internal::DoFAccessorImplementation::Implementation;
1014  friend struct ::internal::DoFCellAccessorImplementation::
1015  Implementation;
1016 
1021  template <int>
1022  friend class ::internal::hp::DoFIndicesOnFacesOrEdges;
1023  friend struct ::internal::hp::DoFHandlerImplementation::
1024  Implementation;
1025  friend struct ::internal::DoFHandlerImplementation::Policy::
1026  Implementation;
1027  };
1028 
1029 
1030 
1031 #ifndef DOXYGEN
1032 
1033 
1034  /* ----------------------- Inline functions ----------------------------------
1035  */
1036 
1037 
1038  template <int dim, int spacedim>
1039  template <typename number>
1042  const std::map<types::boundary_id, const Function<spacedim, number> *>
1043  &boundary_ids) const
1044  {
1045  // extract the set of boundary ids and forget about the function object
1046  // pointers
1047  std::set<types::boundary_id> boundary_ids_only;
1048  for (typename std::map<types::boundary_id,
1049  const Function<spacedim, number> *>::const_iterator
1050  p = boundary_ids.begin();
1051  p != boundary_ids.end();
1052  ++p)
1053  boundary_ids_only.insert(p->first);
1054 
1055  // then just hand everything over to the other function that does the work
1056  return n_boundary_dofs(boundary_ids_only);
1057  }
1058 }
1059 
1060 
1061 namespace internal
1062 {
1070  template <int dim, int spacedim>
1071  std::string
1072  policy_to_string(const ::internal::DoFHandlerImplementation::Policy::
1073  PolicyBase<dim, spacedim> &policy);
1074 } // namespace internal
1075 
1076 
1077 namespace hp
1078 {
1079  template <int dim, int spacedim>
1080  template <class Archive>
1081  void
1082  DoFHandler<dim, spacedim>::save(Archive &ar, unsigned int) const
1083  {
1084  ar &vertex_dofs;
1085  ar &vertex_dof_offsets;
1086  ar &number_cache;
1087  ar &mg_number_cache;
1088 
1089  // some versions of gcc have trouble with loading vectors of
1090  // std::unique_ptr objects because std::unique_ptr does not
1091  // have a copy constructor. do it one level at a time
1092  const unsigned int n_levels = levels.size();
1093  ar & n_levels;
1094  for (unsigned int i = 0; i < n_levels; ++i)
1095  ar &levels[i];
1096 
1097  // boost dereferences a nullptr when serializing a nullptr
1098  // at least up to 1.65.1. This causes problems with clang-5.
1099  // Therefore, work around it.
1100  bool faces_is_nullptr = (faces.get() == nullptr);
1101  ar & faces_is_nullptr;
1102  if (!faces_is_nullptr)
1103  ar &faces;
1104 
1105  // the same issue as above
1106  const unsigned int n_has_children = has_children.size();
1107  ar & n_has_children;
1108  for (unsigned int i = 0; i < n_has_children; ++i)
1109  ar &has_children[i];
1110 
1111  // write out the number of triangulation cells and later check during
1112  // loading that this number is indeed correct; same with something that
1113  // identifies the policy
1114  const unsigned int n_cells = tria->n_cells();
1115  std::string policy_name = ::internal::policy_to_string(*policy);
1116 
1117  ar &n_cells &policy_name;
1118  }
1119 
1120 
1121 
1122  template <int dim, int spacedim>
1123  template <class Archive>
1124  void
1125  DoFHandler<dim, spacedim>::load(Archive &ar, unsigned int)
1126  {
1127  ar &vertex_dofs;
1128  ar &vertex_dof_offsets;
1129  ar &number_cache;
1130  ar &mg_number_cache;
1131 
1132  // boost::serialization can restore pointers just fine, but if the
1133  // pointer object still points to something useful, that object is not
1134  // destroyed and we end up with a memory leak. consequently, first delete
1135  // previous content before re-loading stuff
1136  levels.clear();
1137  has_children.clear();
1138  faces.reset();
1139 
1140  // some versions of gcc have trouble with loading vectors of
1141  // std::unique_ptr objects because std::unique_ptr does not
1142  // have a copy constructor. do it one level at a time
1143  unsigned int size;
1144  ar & size;
1145  levels.resize(size);
1146  for (unsigned int i = 0; i < size; ++i)
1147  {
1148  std::unique_ptr<::internal::hp::DoFLevel> level;
1149  ar & level;
1150  levels[i] = std::move(level);
1151  }
1152 
1153  // Workaround for nullptr, see in save().
1154  bool faces_is_nullptr = true;
1155  ar & faces_is_nullptr;
1156  if (!faces_is_nullptr)
1157  ar &faces;
1158 
1159  // the same issue as above
1160  ar &size;
1161  has_children.resize(size);
1162  for (unsigned int i = 0; i < size; ++i)
1163  {
1164  std::unique_ptr<std::vector<bool>> has_children_on_level;
1165  ar & has_children_on_level;
1166  has_children[i] = std::move(has_children_on_level);
1167  }
1168 
1169  // these are the checks that correspond to the last block in the save()
1170  // function
1171  unsigned int n_cells;
1172  std::string policy_name;
1173 
1174  ar &n_cells &policy_name;
1175 
1176  AssertThrow(
1177  n_cells == tria->n_cells(),
1178  ExcMessage(
1179  "The object being loaded into does not match the triangulation "
1180  "that has been stored previously."));
1181  AssertThrow(policy_name == ::internal::policy_to_string(*policy),
1182  ExcMessage(
1183  "The policy currently associated with this DoFHandler (" +
1184  ::internal::policy_to_string(*policy) +
1185  ") does not match the one that was associated with the "
1186  "DoFHandler previously stored (" +
1187  policy_name + ")."));
1188  }
1189 
1190  template <int dim, int spacedim>
1193  {
1194  return number_cache.n_global_dofs;
1195  }
1196 
1197 
1198 
1199  template <int dim, int spacedim>
1201  DoFHandler<dim, spacedim>::n_dofs(const unsigned int) const
1202  {
1203  Assert(false, ExcNotImplemented());
1205  }
1206 
1207 
1208 
1209  template <int dim, int spacedim>
1212  {
1213  return number_cache.n_locally_owned_dofs;
1214  }
1215 
1216 
1217 
1218  template <int dim, int spacedim>
1219  const IndexSet &
1221  {
1222  return number_cache.locally_owned_dofs;
1223  }
1224 
1225 
1226 
1227  template <int dim, int spacedim>
1228  const std::vector<types::global_dof_index> &
1230  {
1231  return number_cache.n_locally_owned_dofs_per_processor;
1232  }
1233 
1234 
1235 
1236  template <int dim, int spacedim>
1237  const std::vector<IndexSet> &
1239  {
1240  return number_cache.locally_owned_dofs_per_processor;
1241  }
1242 
1243 
1244 
1245  template <int dim, int spacedim>
1246  const IndexSet &
1248  const unsigned int level) const
1249  {
1250  Assert(false, ExcNotImplemented());
1251  (void)level;
1252  Assert(level < this->get_triangulation().n_global_levels(),
1253  ExcMessage("invalid level in locally_owned_mg_dofs"));
1254  return mg_number_cache[0].locally_owned_dofs;
1255  }
1256 
1257 
1258  template <int dim, int spacedim>
1259  const std::vector<IndexSet> &
1261  const unsigned int level) const
1262  {
1263  Assert(false, ExcNotImplemented());
1264  (void)level;
1265  Assert(level < this->get_triangulation().n_global_levels(),
1266  ExcMessage("invalid level in locally_owned_mg_dofs_per_processor"));
1267  return mg_number_cache[0].locally_owned_dofs_per_processor;
1268  }
1269 
1270 
1271 
1272  template <int dim, int spacedim>
1273  inline const hp::FECollection<dim, spacedim> &
1275  {
1276  Assert(fe_collection.size() > 0,
1277  ExcMessage("No finite element collection is associated with "
1278  "this DoFHandler"));
1279  return fe_collection;
1280  }
1281 
1282 
1283 
1284  template <int dim, int spacedim>
1285  inline const FiniteElement<dim, spacedim> &
1286  DoFHandler<dim, spacedim>::get_fe(const unsigned int number) const
1287  {
1288  Assert(fe_collection.size() > 0,
1289  ExcMessage("No finite element collection is associated with "
1290  "this DoFHandler"));
1291  return fe_collection[number];
1292  }
1293 
1294 
1295 
1296  template <int dim, int spacedim>
1297  inline const hp::FECollection<dim, spacedim> &
1299  {
1300  Assert(fe_collection.size() > 0,
1301  ExcMessage("No finite element collection is associated with "
1302  "this DoFHandler"));
1303  return fe_collection;
1304  }
1305 
1306 
1307 
1308  template <int dim, int spacedim>
1309  inline const Triangulation<dim, spacedim> &
1311  {
1312  Assert(tria != nullptr,
1313  ExcMessage("This DoFHandler object has not been associated "
1314  "with a triangulation."));
1315  return *tria;
1316  }
1317 
1318 #endif
1319 
1320 } // namespace hp
1321 
1322 DEAL_II_NAMESPACE_CLOSE
1323 
1324 #endif
static const unsigned int invalid_unsigned_int
Definition: types.h:173
typename ActiveSelector::face_iterator face_iterator
Definition: dof_handler.h:217
#define DeclException2(Exception2, type1, type2, outsequence)
Definition: exceptions.h:420
STL namespace.
#define AssertThrow(cond, exc)
Definition: exceptions.h:1329
const Triangulation< dim, spacedim > & get_triangulation() const
const std::vector< types::global_dof_index > & n_locally_owned_dofs_per_processor() const
static::ExceptionBase & ExcFacesHaveNoLevel()
unsigned long long int global_dof_index
Definition: types.h:72
typename ActiveSelector::active_cell_iterator active_cell_iterator
Definition: dof_handler.h:194
static::ExceptionBase & ExcMessage(std::string arg1)
typename ActiveSelector::cell_iterator cell_iterator
Definition: dof_handler.h:207
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:408
Definition: types.h:31
#define Assert(cond, exc)
Definition: exceptions.h:1227
types::global_dof_index n_dofs() const
const hp::FECollection< dim, spacedim > & get_fe_collection() const
unsigned int n_locally_owned_dofs() const
#define DeclException0(Exception0)
Definition: exceptions.h:385
Definition: hp.h:102
const IndexSet & locally_owned_mg_dofs(const unsigned int level) const
const std::vector< IndexSet > & locally_owned_mg_dofs_per_processor(const unsigned int level) const
void save(Archive &ar, const unsigned int version) const
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
types::global_dof_index n_boundary_dofs() const
typename ActiveSelector::active_face_iterator active_face_iterator
Definition: dof_handler.h:223
void load(Archive &ar, const unsigned int version)
static::ExceptionBase & ExcInvalidBoundaryIndicator()
static::ExceptionBase & ExcNotImplemented()
const types::global_dof_index invalid_dof_index
Definition: types.h:188
const IndexSet & locally_owned_dofs() const
const std::vector< IndexSet > & locally_owned_dofs_per_processor() const
unsigned int boundary_id
Definition: types.h:111
static::ExceptionBase & ExcNoFESelected()