Reference documentation for deal.II version 8.5.0
dof_handler.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2017 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__dof_handler_h
17 #define dealii__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/smartpointer.h>
24 #include <deal.II/base/index_set.h>
25 #include <deal.II/base/iterator_range.h>
26 #include <deal.II/base/std_cxx11/shared_ptr.h>
27 #include <deal.II/dofs/block_info.h>
28 #include <deal.II/dofs/dof_iterator_selector.h>
29 #include <deal.II/dofs/number_cache.h>
30 #include <deal.II/dofs/dof_faces.h>
31 #include <deal.II/dofs/dof_levels.h>
32 #include <deal.II/dofs/function_map.h>
33 
34 #include <boost/serialization/split_member.hpp>
35 
36 #include <vector>
37 #include <map>
38 #include <set>
39 
40 DEAL_II_NAMESPACE_OPEN
41 
42 template <int dim, int spacedim> class FiniteElement;
43 template <int dim, int spacedim> class Triangulation;
44 
45 namespace internal
46 {
47  namespace DoFHandler
48  {
49  struct Implementation;
50 
51  namespace Policy
52  {
53  template <int dim, int spacedim> class PolicyBase;
54  struct Implementation;
55  }
56  }
57 
58  namespace DoFAccessor
59  {
60  struct Implementation;
61  }
62 
63  namespace DoFCellAccessor
64  {
65  struct Implementation;
66  }
67 }
68 
69 
190 template <int dim, int spacedim=dim>
191 class DoFHandler : public Subscriptor
192 {
193  typedef ::internal::DoFHandler::Iterators<DoFHandler<dim,spacedim>, false> ActiveSelector;
194  typedef ::internal::DoFHandler::Iterators<DoFHandler<dim,spacedim>, true> LevelSelector;
195 public:
196  typedef typename ActiveSelector::CellAccessor cell_accessor;
197  typedef typename ActiveSelector::FaceAccessor face_accessor;
198 
199  typedef typename ActiveSelector::line_iterator line_iterator;
200  typedef typename ActiveSelector::active_line_iterator active_line_iterator;
201 
202  typedef typename ActiveSelector::quad_iterator quad_iterator;
203  typedef typename ActiveSelector::active_quad_iterator active_quad_iterator;
204 
205  typedef typename ActiveSelector::hex_iterator hex_iterator;
206  typedef typename ActiveSelector::active_hex_iterator active_hex_iterator;
207 
228  typedef typename ActiveSelector::active_cell_iterator active_cell_iterator;
229 
256  typedef typename ActiveSelector::cell_iterator cell_iterator;
257 
258  typedef typename ActiveSelector::face_iterator face_iterator;
259  typedef typename ActiveSelector::active_face_iterator active_face_iterator;
260 
261  typedef typename LevelSelector::CellAccessor level_cell_accessor;
262  typedef typename LevelSelector::FaceAccessor level_face_accessor;
263 
264  typedef typename LevelSelector::cell_iterator level_cell_iterator;
265  typedef typename LevelSelector::face_iterator level_face_iterator;
266 
267 
271  static const unsigned int dimension = dim;
272 
276  static const unsigned int space_dimension = spacedim;
277 
288 
298  static const unsigned int default_fe_index = 0;
299 
305  DoFHandler ();
306 
311 
315  virtual ~DoFHandler ();
316 
322  const FiniteElement<dim,spacedim> &fe);
323 
344  virtual void distribute_dofs (const FiniteElement<dim,spacedim> &fe);
345 
352  virtual void distribute_mg_dofs (const FiniteElement<dim, spacedim> &fe);
353 
359  bool has_level_dofs() const;
360 
375  bool has_active_dofs() const;
376 
384 
390  virtual void clear ();
391 
421  void renumber_dofs (const std::vector<types::global_dof_index> &new_numbers);
422 
427  void renumber_dofs (const unsigned int level,
428  const std::vector<types::global_dof_index> &new_numbers);
429 
458  unsigned int max_couplings_between_dofs () const;
459 
472  unsigned int max_couplings_between_boundary_dofs () const;
473 
474  /*--------------------------------------*/
475 
480  /*
481  * @{
482  */
483 
487  cell_iterator begin (const unsigned int level = 0) const;
488 
501  active_cell_iterator begin_active(const unsigned int level = 0) const;
502 
507  cell_iterator end () const;
508 
513  cell_iterator end (const unsigned int level) const;
514 
520  active_cell_iterator end_active (const unsigned int level) const;
521 
522 
527  level_cell_iterator begin_mg (const unsigned int level = 0) const;
528 
533  level_cell_iterator end_mg (const unsigned int level) const;
534 
539  level_cell_iterator end_mg () const;
540 
556 
599 
612 
628  IteratorRange<cell_iterator> cell_iterators_on_level (const unsigned int level) const;
629 
646 
663  IteratorRange<level_cell_iterator> mg_cell_iterators_on_level (const unsigned int level) const;
664 
665  /*
666  * @}
667  */
668 
669 
670  /*---------------------------------------*/
671 
672 
690 
698  types::global_dof_index n_dofs (const unsigned int level) const;
699 
704 
714  template<typename number>
716  n_boundary_dofs (const std::map<types::boundary_id, const Function<spacedim,number>*> &boundary_ids) const;
717 
723  n_boundary_dofs (const std::set<types::boundary_id> &boundary_ids) const;
724 
740  const BlockInfo &block_info() const;
741 
742 
756  unsigned int n_locally_owned_dofs() const;
757 
763  const IndexSet &locally_owned_dofs() const;
764 
769  const IndexSet &locally_owned_mg_dofs(const unsigned int level) const;
770 
771 
780  const std::vector<IndexSet> &
782 
783  const std::vector<IndexSet> &
784  locally_owned_mg_dofs_per_processor (const unsigned int level) const;
785 
798  const std::vector<types::global_dof_index> &
800 
804  const FiniteElement<dim,spacedim> &get_fe () const;
805 
811  const Triangulation<dim,spacedim> &get_tria () const DEAL_II_DEPRECATED;
812 
816  const Triangulation<dim,spacedim> &get_triangulation () const;
817 
826  virtual std::size_t memory_consumption () const;
827 
832  template <class Archive>
833  void save (Archive &ar, const unsigned int version) const;
834 
839  template <class Archive>
840  void load (Archive &ar, const unsigned int version);
841 
842  BOOST_SERIALIZATION_SPLIT_MEMBER()
843 
866  types::global_dof_index,
867  << "The given list of new dof indices is not consecutive: "
868  << "the index " << arg1 << " does not exist.");
874  int,
875  << "The given level " << arg1
876  << " is not in the valid range!");
887  int,
888  << "You tried to do something on level " << arg1
889  << ", but this level is empty.");
890 
891 
892 private:
899  DoFHandler (const DoFHandler &);
900 
907  DoFHandler &operator = (const DoFHandler &);
908 
909 
914 
918  SmartPointer<const Triangulation<dim,spacedim>,DoFHandler<dim,spacedim> >
920 
929  SmartPointer<const FiniteElement<dim,spacedim>,DoFHandler<dim,spacedim> >
931 
936  std_cxx11::shared_ptr<::internal::DoFHandler::Policy::PolicyBase<dim,spacedim> > policy;
937 
945  ::internal::DoFHandler::NumberCache number_cache;
946 
950  std::vector<::internal::DoFHandler::NumberCache> mg_number_cache;
951 
959  {
960  public:
964  MGVertexDoFs ();
965 
969  ~MGVertexDoFs ();
970 
976  void init (const unsigned int coarsest_level,
977  const unsigned int finest_level,
978  const unsigned int dofs_per_vertex);
979 
983  unsigned int get_coarsest_level () const;
984 
988  unsigned int get_finest_level () const;
989 
995  get_index (const unsigned int level,
996  const unsigned int dof_number) const;
997 
1002  void set_index (const unsigned int level,
1003  const unsigned int dof_number,
1004  const types::global_dof_index index);
1005 
1009  DeclException0 (ExcNoMemory);
1010 
1011  private:
1015  unsigned int coarsest_level;
1016 
1020  unsigned int finest_level;
1021 
1027 
1034  };
1035 
1036  void clear_mg_space ();
1037 
1041  void clear_space ();
1042 
1043  void reserve_space ();
1044 
1045  template <int structdim>
1046  types::global_dof_index get_dof_index (const unsigned int obj_level,
1047  const unsigned int obj_index,
1048  const unsigned int fe_index,
1049  const unsigned int local_index) const;
1050 
1051  template<int structdim>
1052  void set_dof_index (const unsigned int obj_level,
1053  const unsigned int obj_index,
1054  const unsigned int fe_index,
1055  const unsigned int local_index,
1056  const types::global_dof_index global_index) const;
1057 
1061  std::vector<types::global_dof_index> vertex_dofs;
1062 
1067  std::vector<MGVertexDoFs> mg_vertex_dofs;
1068 
1073  std::vector<::internal::DoFHandler::DoFLevel<dim>*> levels;
1074 
1075  std::vector<::internal::DoFHandler::DoFLevel<dim>*> mg_levels;
1076 
1083 
1085 
1089  template <int, class, bool> friend class DoFAccessor;
1090  template <class, bool> friend class DoFCellAccessor;
1091  friend struct ::internal::DoFAccessor::Implementation;
1092  friend struct ::internal::DoFCellAccessor::Implementation;
1093 
1094  friend struct ::internal::DoFHandler::Implementation;
1095  friend struct ::internal::DoFHandler::Policy::Implementation;
1096 
1097  // explicitly check for sensible template arguments, but not on windows
1098  // because MSVC creates bogus warnings during normal compilation
1099 #ifdef DEAL_II_WITH_CXX11
1100 #ifndef DEAL_II_MSVC
1101  static_assert (dim<=spacedim,
1102  "The dimension <dim> of a DoFHandler must be less than or "
1103  "equal to the space dimension <spacedim> in which it lives.");
1104 #endif
1105 #endif
1106 };
1107 
1108 
1109 
1110 
1111 /* -------------- declaration of explicit specializations ------------- */
1112 
1113 #ifndef DOXYGEN
1114 
1116 template <> types::global_dof_index DoFHandler<1>::n_boundary_dofs (const std::set<types::boundary_id> &) const;
1117 
1118 template <> void DoFHandler<1>::renumber_dofs(unsigned int,const std::vector<types::global_dof_index> &new_numbers);
1119 template <> void DoFHandler<2>::renumber_dofs(unsigned int,const std::vector<types::global_dof_index> &new_numbers);
1120 template <> void DoFHandler<3>::renumber_dofs(unsigned int,const std::vector<types::global_dof_index> &new_numbers);
1121 
1122 
1123 /* ----------------------- Inline functions ---------------------------------- */
1124 
1125 
1126 template <int dim, int spacedim>
1127 inline
1128 bool
1130 {
1131  return mg_number_cache.size()>0;
1132 }
1133 
1134 template <int dim, int spacedim>
1135 inline
1136 bool
1138 {
1139  return number_cache.n_global_dofs>0;
1140 }
1141 
1142 template <int dim, int spacedim>
1143 inline
1146 {
1147  return number_cache.n_global_dofs;
1148 }
1149 
1150 template<int dim, int spacedim>
1151 inline
1153 {
1154  Assert(has_level_dofs(), ExcMessage("n_dofs(level) can only be called after distribute_mg_dofs()"));
1155  Assert (level < mg_number_cache.size (), ExcInvalidLevel (level));
1156  return mg_number_cache[level].n_global_dofs;
1157 }
1158 
1159 
1160 template <int dim, int spacedim>
1161 unsigned int
1163 {
1164  return number_cache.n_locally_owned_dofs;
1165 }
1166 
1167 
1168 template <int dim, int spacedim>
1169 const IndexSet &
1171 {
1172  return number_cache.locally_owned_dofs;
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(level < this->get_triangulation().n_global_levels(), ExcMessage("invalid level in locally_owned_mg_dofs"));
1180  return mg_number_cache[level].locally_owned_dofs;
1181 }
1182 
1183 template <int dim, int spacedim>
1184 const std::vector<types::global_dof_index> &
1186 {
1187  return number_cache.n_locally_owned_dofs_per_processor;
1188 }
1189 
1190 
1191 template <int dim, int spacedim>
1192 const std::vector<IndexSet> &
1194 {
1195  return number_cache.locally_owned_dofs_per_processor;
1196 }
1197 
1198 template <int dim, int spacedim>
1199 const std::vector<IndexSet> &
1201 {
1202  Assert(level < this->get_triangulation().n_global_levels(), ExcMessage("invalid level in locally_owned_mg_dofs_per_processor"));
1203  return mg_number_cache[level].locally_owned_dofs_per_processor;
1204 }
1205 
1206 
1207 template <int dim, int spacedim>
1208 inline
1211 {
1212  Assert(selected_fe!=0, ExcMessage("You are trying to access the DoFHandler's FiniteElement object before it has been initialized."));
1213  return *selected_fe;
1214 }
1215 
1216 
1217 
1218 template <int dim, int spacedim>
1219 inline
1222 {
1223  Assert(tria != 0, ExcNotInitialized());
1224  return *tria;
1225 }
1226 
1227 
1228 
1229 template <int dim, int spacedim>
1230 inline
1233 {
1234  Assert(tria != 0, ExcNotInitialized());
1235  return *tria;
1236 }
1237 
1238 
1239 
1240 template <int dim, int spacedim>
1241 inline
1242 const BlockInfo &
1244 {
1245  return block_info_object;
1246 }
1247 
1248 
1249 template <int dim, int spacedim>
1250 template <typename number>
1253 {
1254  // extract the set of boundary ids and forget about the function object pointers
1255  std::set<types::boundary_id> boundary_ids_only;
1256  for (typename std::map<types::boundary_id, const Function<spacedim,number>*>::const_iterator
1257  p = boundary_ids.begin();
1258  p != boundary_ids.end(); ++p)
1259  boundary_ids_only.insert (p->first);
1260 
1261  // then just hand everything over to the other function that does the work
1262  return n_boundary_dofs(boundary_ids_only);
1263 }
1264 
1265 
1266 
1267 namespace internal
1268 {
1276  template<int dim, int spacedim>
1277  std::string policy_to_string(const ::internal::DoFHandler::Policy::PolicyBase<dim,spacedim> &policy);
1278 }
1279 
1280 
1281 template <int dim, int spacedim>
1282 template <class Archive>
1283 void DoFHandler<dim,spacedim>::save (Archive &ar,
1284  const unsigned int) const
1285 {
1286  ar &block_info_object;
1287  ar &vertex_dofs;
1288  ar &number_cache;
1289  ar &levels;
1290  ar &faces;
1291 
1292  // write out the number of triangulation cells and later check during
1293  // loading that this number is indeed correct; same with something that
1294  // identifies the FE and the policy
1295  unsigned int n_cells = tria->n_cells();
1296  std::string fe_name = selected_fe->get_name();
1297  std::string policy_name = internal::policy_to_string(*policy);
1298 
1299  ar &n_cells &fe_name &policy_name;
1300 }
1301 
1302 
1303 template <int dim, int spacedim>
1304 template <class Archive>
1305 void DoFHandler<dim,spacedim>::load (Archive &ar,
1306  const unsigned int)
1307 {
1308  ar &block_info_object;
1309  ar &vertex_dofs;
1310  ar &number_cache;
1311 
1312  // boost::serialization can restore pointers just fine, but if the
1313  // pointer object still points to something useful, that object is not
1314  // destroyed and we end up with a memory leak. consequently, first delete
1315  // previous content before re-loading stuff
1316  for (unsigned int i=0; i<levels.size(); ++i)
1317  delete levels[i];
1318  levels.resize (0);
1319  delete faces;
1320  faces = 0;
1321 
1322  ar &levels;
1323  ar &faces;
1324 
1325  // these are the checks that correspond to the last block in the save()
1326  // function
1327  unsigned int n_cells;
1328  std::string fe_name;
1329  std::string policy_name;
1330 
1331  ar &n_cells &fe_name &policy_name;
1332 
1333  AssertThrow (n_cells == tria->n_cells(),
1334  ExcMessage ("The object being loaded into does not match the triangulation "
1335  "that has been stored previously."));
1336  AssertThrow (fe_name == selected_fe->get_name(),
1337  ExcMessage ("The finite element associated with this DoFHandler does not match "
1338  "the one that was associated with the DoFHandler previously stored."));
1339  AssertThrow (policy_name == internal::policy_to_string(*policy),
1340  ExcMessage (std::string ("The policy currently associated with this DoFHandler (")
1341  + internal::policy_to_string(*policy)
1342  +std::string(") does not match the one that was associated with the "
1343  "DoFHandler previously stored (")
1344  + policy_name
1345  + ")."));
1346 }
1347 
1348 
1349 template<int dim, int spacedim>
1350 inline
1352  const unsigned int level,
1353  const unsigned int dof_number) const
1354 {
1355  Assert ((level >= coarsest_level) && (level <= finest_level), ExcInvalidLevel (level));
1356  return indices[indices_offset[level - coarsest_level] + dof_number];
1357 }
1358 
1359 
1360 template<int dim, int spacedim>
1361 inline
1363  const unsigned int level,
1364  const unsigned int dof_number,
1365  const types::global_dof_index index)
1366 {
1367  Assert ((level >= coarsest_level) && (level <= finest_level), ExcInvalidLevel (level));
1368  indices[indices_offset[level - coarsest_level] + dof_number] = index;
1369 }
1370 
1371 #endif // DOXYGEN
1372 
1373 DEAL_II_NAMESPACE_CLOSE
1374 
1375 #endif
unsigned int max_couplings_between_boundary_dofs() const
std::vector< MGVertexDoFs > mg_vertex_dofs
Definition: dof_handler.h:1067
active_cell_iterator end_active(const unsigned int level) const
Definition: dof_handler.cc:778
active_cell_iterator begin_active(const unsigned int level=0) const
Definition: dof_handler.cc:740
Iterator points to a valid object.
std::vector<::internal::DoFHandler::NumberCache > mg_number_cache
Definition: dof_handler.h:950
std_cxx11::shared_ptr<::internal::DoFHandler::Policy::PolicyBase< dim, spacedim > > policy
Definition: dof_handler.h:936
types::global_dof_index * indices
Definition: dof_handler.h:1026
static const unsigned int dimension
Definition: dof_handler.h:271
const BlockInfo & block_info() const
void set_index(const unsigned int level, const unsigned int dof_number, const types::global_dof_index index)
static const unsigned int spacedim
static::ExceptionBase & ExcRenumberingIncomplete()
static::ExceptionBase & ExcInvalidLevel(int arg1)
level_cell_iterator begin_mg(const unsigned int level=0) const
Definition: dof_handler.cc:790
const Triangulation< dim, spacedim > & get_tria() const 1
virtual void clear()
const Triangulation< dim, spacedim > & get_triangulation() const
SmartPointer< const FiniteElement< dim, spacedim >, DoFHandler< dim, spacedim > > selected_fe
Definition: dof_handler.h:930
std::vector<::internal::DoFHandler::DoFLevel< dim > * > levels
Definition: dof_handler.h:1073
ActiveSelector::active_cell_iterator active_cell_iterator
Definition: dof_handler.h:228
SmartPointer< const Triangulation< dim, spacedim >, DoFHandler< dim, spacedim > > tria
Definition: dof_handler.h:919
STL namespace.
bool has_level_dofs() const
static::ExceptionBase & ExcNotInitialized()
#define AssertThrow(cond, exc)
Definition: exceptions.h:369
const std::vector< types::global_dof_index > & n_locally_owned_dofs_per_processor() const
::internal::DoFHandler::NumberCache number_cache
Definition: dof_handler.h:945
unsigned int max_couplings_between_dofs() const
void initialize(const Triangulation< dim, spacedim > &tria, const FiniteElement< dim, spacedim > &fe)
Definition: dof_handler.cc:697
virtual void distribute_mg_dofs(const FiniteElement< dim, spacedim > &fe)
static::ExceptionBase & ExcInvalidBoundaryIndicator()
BlockInfo block_info_object
Definition: dof_handler.h:913
IteratorRange< active_cell_iterator > active_cell_iterators_on_level(const unsigned int level) const
Definition: dof_handler.cc:869
static::ExceptionBase & ExcFacesHaveNoLevel()
static::ExceptionBase & ExcMessage(std::string arg1)
level_cell_iterator end_mg() const
Definition: dof_handler.cc:816
ActiveSelector::cell_iterator cell_iterator
Definition: dof_handler.h:256
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:564
Definition: types.h:30
unsigned int global_dof_index
Definition: types.h:88
types::global_dof_index * indices_offset
Definition: dof_handler.h:1033
#define Assert(cond, exc)
Definition: exceptions.h:313
types::global_dof_index n_dofs() const
static const unsigned int default_fe_index
Definition: dof_handler.h:298
const Triangulation< dim, spacedim > * tria
unsigned int n_locally_owned_dofs() const
static::ExceptionBase & ExcGridsDoNotMatch()
#define DeclException0(Exception0)
Definition: exceptions.h:541
types::global_dof_index get_index(const unsigned int level, const unsigned int dof_number) const
::internal::DoFHandler::DoFFaces< dim > * faces
Definition: dof_handler.h:1082
cell_iterator end() const
Definition: dof_handler.cc:756
virtual ~DoFHandler()
Definition: dof_handler.cc:688
IteratorRange< cell_iterator > cell_iterators_on_level(const unsigned int level) const
Definition: dof_handler.cc:858
const IndexSet & locally_owned_mg_dofs(const unsigned int level) const
IteratorRange< cell_iterator > cell_iterators() const
Definition: dof_handler.cc:825
void renumber_dofs(const std::vector< types::global_dof_index > &new_numbers)
void initialize_local_block_info()
bool has_active_dofs() const
static::ExceptionBase & ExcEmptyLevel(int arg1)
static const unsigned int dim
cell_iterator begin(const unsigned int level=0) const
Definition: dof_handler.cc:728
void save(Archive &ar, const unsigned int version) const
IteratorRange< level_cell_iterator > mg_cell_iterators() const
Definition: dof_handler.cc:846
types::global_dof_index n_boundary_dofs() const
Definition: dof_handler.cc:975
unsigned int coarsest_level
Definition: dof_handler.h:1015
void clear_space()
IteratorRange< level_cell_iterator > mg_cell_iterators_on_level(const unsigned int level) const
Definition: dof_handler.cc:880
virtual void distribute_dofs(const FiniteElement< dim, spacedim > &fe)
void load(Archive &ar, const unsigned int version)
A small class collecting the different BlockIndices involved in global, multilevel and local computat...
Definition: block_info.h:93
static::ExceptionBase & ExcNewNumbersNotConsecutive(types::global_dof_index arg1)
unsigned char boundary_id
Definition: types.h:110
static const unsigned int space_dimension
Definition: dof_handler.h:276
virtual std::size_t memory_consumption() const
const types::global_dof_index invalid_dof_index
Definition: types.h:184
const IndexSet & locally_owned_dofs() const
const std::vector< IndexSet > & locally_owned_dofs_per_processor() const
const Triangulation< dim, spacedim > & get_triangulation() const
IteratorRange< active_cell_iterator > active_cell_iterators() const
Definition: dof_handler.cc:835
static const types::global_dof_index invalid_dof_index
Definition: dof_handler.h:287
std::vector< types::global_dof_index > vertex_dofs
Definition: dof_handler.h:1061
const FiniteElement< dim, spacedim > & get_fe() const
int level() const