Reference documentation for deal.II version 8.1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
dof_handler.h
1 // ---------------------------------------------------------------------
2 // @f$Id: dof_handler.h 31932 2013-12-08 02:15:54Z heister @f$
3 //
4 // Copyright (C) 1998 - 2013 by the deal.II authors
5 //
6 // This file is part of the deal.II library.
7 //
8 // The deal.II library is free software; you can use it, redistribute
9 // it, and/or modify it under the terms of the GNU Lesser General
10 // Public License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 // The full text of the license can be found in the file LICENSE at
13 // the top level of the deal.II distribution.
14 //
15 // ---------------------------------------------------------------------
16 
17 #ifndef __deal2__dof_handler_h
18 #define __deal2__dof_handler_h
19 
20 
21 
22 #include <deal.II/base/config.h>
24 #include <deal.II/base/smartpointer.h>
25 #include <deal.II/base/index_set.h>
26 #include <deal.II/base/std_cxx1x/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/function_map.h>
31 
32 #include <boost/serialization/split_member.hpp>
33 
34 #include <vector>
35 #include <map>
36 #include <set>
37 
38 DEAL_II_NAMESPACE_OPEN
39 
40 namespace internal
41 {
42  namespace DoFHandler
43  {
44  template <int dim> class DoFLevel;
45  template <int dim> class DoFFaces;
46 
47  struct Implementation;
48 
49  namespace Policy
50  {
51  template <int dim, int spacedim> class PolicyBase;
52  struct Implementation;
53  }
54  }
55 
56  namespace DoFAccessor
57  {
58  struct Implementation;
59  }
60 
61  namespace DoFCellAccessor
62  {
63  struct Implementation;
64  }
65 }
66 
67 
182 template <int dim, int spacedim=dim>
183 class DoFHandler : public Subscriptor
184 {
185  typedef ::internal::DoFHandler::Iterators<DoFHandler<dim,spacedim>, false> ActiveSelector;
186  typedef ::internal::DoFHandler::Iterators<DoFHandler<dim,spacedim>, true> LevelSelector;
187 public:
188  typedef typename ActiveSelector::CellAccessor cell_accessor;
189  typedef typename ActiveSelector::FaceAccessor face_accessor;
190 
191  typedef typename ActiveSelector::line_iterator line_iterator;
192  typedef typename ActiveSelector::active_line_iterator active_line_iterator;
193 
194  typedef typename ActiveSelector::quad_iterator quad_iterator;
195  typedef typename ActiveSelector::active_quad_iterator active_quad_iterator;
196 
197  typedef typename ActiveSelector::hex_iterator hex_iterator;
198  typedef typename ActiveSelector::active_hex_iterator active_hex_iterator;
199 
200  typedef typename ActiveSelector::active_cell_iterator active_cell_iterator;
201 
202  typedef typename ActiveSelector::face_iterator face_iterator;
203  typedef typename ActiveSelector::active_face_iterator active_face_iterator;
204 
205  typedef typename LevelSelector::CellAccessor level_cell_accessor;
206  typedef typename LevelSelector::FaceAccessor level_face_accessor;
207 
208  typedef typename LevelSelector::cell_iterator level_cell_iterator;
209  typedef typename LevelSelector::face_iterator level_face_iterator;
210 
211  typedef typename ActiveSelector::cell_iterator cell_iterator;
212 
217  typedef typename ::FunctionMap<spacedim>::type FunctionMap;
218 
223  static const unsigned int dimension = dim;
224 
229  static const unsigned int space_dimension = spacedim;
230 
247 
268  static const unsigned int default_fe_index = 0;
269 
278  DoFHandler ();
279 
285 
289  virtual ~DoFHandler ();
290 
299  const FiniteElement<dim,spacedim> &fe);
300 
323  virtual void distribute_dofs (const FiniteElement<dim,spacedim> &fe);
324 
330  virtual void distribute_mg_dofs (const FiniteElement<dim, spacedim> &fe);
331 
340  bool has_level_dofs() const;
341 
349  bool has_active_dofs() const;
362 
369  virtual void clear ();
370 
439  void renumber_dofs (const std::vector<types::global_dof_index> &new_numbers);
440 
446  void renumber_dofs (const unsigned int level,
447  const std::vector<types::global_dof_index> &new_numbers);
448 
495  unsigned int max_couplings_between_dofs () const;
496 
510  unsigned int max_couplings_between_boundary_dofs () const;
511 
512  /*--------------------------------------*/
513 
522  cell_iterator begin (const unsigned int level = 0) const;
523 
536  active_cell_iterator begin_active(const unsigned int level = 0) const;
537 
545  cell_iterator end () const;
546 
553  cell_iterator end (const unsigned int level) const;
554 
560  active_cell_iterator end_active (const unsigned int level) const;
561 
562 
568  level_cell_iterator begin_mg (const unsigned int level = 0) const;
569 
575  level_cell_iterator end_mg (const unsigned int level) const;
576 
584  level_cell_iterator end_mg () const;
585 
586 
588 
589  /*---------------------------------------*/
590 
591 
624 
637  types::global_dof_index n_dofs (const unsigned int level) const;
638 
644 
659  n_boundary_dofs (const FunctionMap &boundary_indicators) const;
660 
670  n_boundary_dofs (const std::set<types::boundary_id> &boundary_indicators) const;
671 
698  const BlockInfo &block_info() const;
699 
700 
731  unsigned int n_locally_owned_dofs() const;
732 
741  const IndexSet &locally_owned_dofs() const;
742 
748  const IndexSet &locally_owned_mg_dofs(const unsigned int level) const;
749 
750 
767  const std::vector<IndexSet> &
769 
770  const std::vector<IndexSet> &
771  locally_owned_mg_dofs_per_processor (const unsigned int level) const;
772 
799  const std::vector<types::global_dof_index> &
801 
807  const FiniteElement<dim,spacedim> &get_fe () const;
808 
814  const Triangulation<dim,spacedim> &get_tria () const;
815 
828  virtual std::size_t memory_consumption () const;
829 
835  template <class Archive>
836  void save (Archive &ar, const unsigned int version) const;
837 
843  template <class Archive>
844  void load (Archive &ar, const unsigned int version);
845 
846  BOOST_SERIALIZATION_SPLIT_MEMBER()
847 
848 
856  DeclException0 (ExcRenumberingIncomplete);
861  DeclException0 (ExcGridsDoNotMatch);
866  DeclException0 (ExcInvalidBoundaryIndicator);
871  DeclException1 (ExcNewNumbersNotConsecutive,
872  types::global_dof_index,
873  << "The given list of new dof indices is not consecutive: "
874  << "the index " << arg1 << " does not exist.");
879  DeclException1 (ExcInvalidLevel,
880  int,
881  << "The given level " << arg1
882  << " is not in the valid range!");
887  DeclException0 (ExcFacesHaveNoLevel);
893  DeclException1 (ExcEmptyLevel,
894  int,
895  << "You tried to do something on level " << arg1
896  << ", but this level is empty.");
897 
898 
899 protected:
905 
911  std::vector<types::global_dof_index> vertex_dofs;
912 
913 
914 
919  SmartPointer<const Triangulation<dim,spacedim>,DoFHandler<dim,spacedim> >
921 
934  SmartPointer<const FiniteElement<dim,spacedim>,DoFHandler<dim,spacedim> >
936 
942  std_cxx1x::shared_ptr<::internal::DoFHandler::Policy::PolicyBase<dim,spacedim> > policy;
943 
955  ::internal::DoFHandler::NumberCache number_cache;
956 
960  std::vector<::internal::DoFHandler::NumberCache> mg_number_cache;
961 
962 private:
963 
973  DoFHandler (const DoFHandler &);
974 
984  DoFHandler &operator = (const DoFHandler &);
985 
994  {
995  public:
999  MGVertexDoFs ();
1000 
1004  ~MGVertexDoFs ();
1005 
1011  void init (const unsigned int coarsest_level,
1012  const unsigned int finest_level,
1013  const unsigned int dofs_per_vertex);
1014 
1019  unsigned int get_coarsest_level () const;
1020 
1025  unsigned int get_finest_level () const;
1026 
1032  get_index (const unsigned int level,
1033  const unsigned int dof_number) const;
1034 
1040  void set_index (const unsigned int level,
1041  const unsigned int dof_number,
1042  const types::global_dof_index index);
1043 
1047  DeclException0 (ExcNoMemory);
1048 
1049  private:
1053  unsigned int coarsest_level;
1054 
1058  unsigned int finest_level;
1059 
1066 
1073  };
1074 
1075  void clear_mg_space ();
1076 
1080  void clear_space ();
1081 
1082  void reserve_space ();
1083 
1084  template <int structdim>
1085  types::global_dof_index get_dof_index (const unsigned int obj_level, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index) const;
1086 
1087  template<int structdim>
1088  void set_dof_index (const unsigned int obj_level, const unsigned int obj_index, const unsigned int fe_index, const unsigned int local_index, const types::global_dof_index global_index) const;
1089 
1097  std::vector<::internal::DoFHandler::DoFLevel<dim>*> levels;
1098 
1099  std::vector<::internal::DoFHandler::DoFLevel<dim>*> mg_levels;
1100 
1110 
1112 
1113  std::vector<MGVertexDoFs> mg_vertex_dofs;
1114 
1118  template <int, class, bool> friend class DoFAccessor;
1119  template <class, bool> friend class DoFCellAccessor;
1120  friend struct ::internal::DoFAccessor::Implementation;
1121  friend struct ::internal::DoFCellAccessor::Implementation;
1122 
1123  friend struct ::internal::DoFHandler::Implementation;
1124  friend struct ::internal::DoFHandler::Policy::Implementation;
1125 };
1126 
1127 
1128 
1129 
1130 /* -------------- declaration of explicit specializations ------------- */
1131 
1132 #ifndef DOXYGEN
1133 
1136 template <> types::global_dof_index DoFHandler<1>::n_boundary_dofs (const std::set<types::boundary_id> &) const;
1137 
1138 template <> void DoFHandler<1>::renumber_dofs(unsigned int,const std::vector<types::global_dof_index> &new_numbers);
1139 template <> void DoFHandler<2>::renumber_dofs(unsigned int,const std::vector<types::global_dof_index> &new_numbers);
1140 template <> void DoFHandler<3>::renumber_dofs(unsigned int,const std::vector<types::global_dof_index> &new_numbers);
1141 
1142 
1143 /* ----------------------- Inline functions ---------------------------------- */
1144 
1145 
1146 template <int dim, int spacedim>
1147 inline
1148 bool
1150 {
1151  return mg_number_cache.size()>0;
1152 }
1153 
1154 template <int dim, int spacedim>
1155 inline
1156 bool
1158 {
1159  return number_cache.n_global_dofs>0;
1160 }
1161 
1162 template <int dim, int spacedim>
1163 inline
1166 {
1167  return number_cache.n_global_dofs;
1168 }
1169 
1170 template<int dim, int spacedim>
1171 inline
1173 {
1174  Assert(has_level_dofs(), ExcMessage("n_dofs(level) can only be called after distribute_mg_dofs()"));
1175  Assert (level < mg_number_cache.size (), ExcInvalidLevel (level));
1176  return mg_number_cache[level].n_global_dofs;
1177 }
1178 
1179 
1180 template <int dim, int spacedim>
1181 unsigned int
1183 {
1184  return number_cache.n_locally_owned_dofs;
1185 }
1186 
1187 
1188 template <int dim, int spacedim>
1189 const IndexSet &
1191 {
1192  return number_cache.locally_owned_dofs;
1193 }
1194 
1195 template <int dim, int spacedim>
1196 const IndexSet &
1197 DoFHandler<dim, spacedim>::locally_owned_mg_dofs(const unsigned int level) const
1198 {
1199  Assert(level < this->get_tria().n_global_levels(), ExcMessage("invalid level in locally_owned_mg_dofs"));
1200  return mg_number_cache[level].locally_owned_dofs;
1201 }
1202 
1203 template <int dim, int spacedim>
1204 const std::vector<types::global_dof_index> &
1206 {
1207  return number_cache.n_locally_owned_dofs_per_processor;
1208 }
1209 
1210 
1211 template <int dim, int spacedim>
1212 const std::vector<IndexSet> &
1214 {
1215  return number_cache.locally_owned_dofs_per_processor;
1216 }
1217 
1218 template <int dim, int spacedim>
1219 const std::vector<IndexSet> &
1221 {
1222  Assert(level < this->get_tria().n_global_levels(), ExcMessage("invalid level in locally_owned_mg_dofs_per_processor"));
1223  return mg_number_cache[level].locally_owned_dofs_per_processor;
1224 }
1225 
1226 
1227 template <int dim, int spacedim>
1228 inline
1231 {
1232  Assert(selected_fe!=0, ExcNotInitialized());
1233  return *selected_fe;
1234 }
1235 
1236 
1237 template <int dim, int spacedim>
1238 inline
1241 {
1242  Assert(tria != 0, ExcNotInitialized());
1243  return *tria;
1244 }
1245 
1246 
1247 template <int dim, int spacedim>
1248 inline
1249 const BlockInfo &
1251 {
1252  return block_info_object;
1253 }
1254 
1255 
1256 namespace internal
1257 {
1265  template<int dim, int spacedim>
1266  std::string policy_to_string(const ::internal::DoFHandler::Policy::PolicyBase<dim,spacedim> &policy);
1267 
1268 }
1269 
1270 
1271 template <int dim, int spacedim>
1272 template <class Archive>
1273 void DoFHandler<dim,spacedim>::save (Archive &ar,
1274  const unsigned int) const
1275 {
1276  ar &block_info_object;
1277  ar &vertex_dofs;
1278  ar &number_cache;
1279  ar &levels;
1280  ar &faces;
1281 
1282  // write out the number of triangulation cells and later check
1283  // during loading that this number is indeed correct; same with something that
1284  // identifies the FE and the policy
1285  unsigned int n_cells = tria->n_cells();
1286  std::string fe_name = selected_fe->get_name();
1287  std::string policy_name = internal::policy_to_string(*policy);
1288 
1289  ar &n_cells &fe_name &policy_name;
1290 }
1291 
1292 
1293 template <int dim, int spacedim>
1294 template <class Archive>
1295 void DoFHandler<dim,spacedim>::load (Archive &ar,
1296  const unsigned int)
1297 {
1298  ar &block_info_object;
1299  ar &vertex_dofs;
1300  ar &number_cache;
1301 
1302  // boost::serialization can restore pointers just fine, but if the
1303  // pointer object still points to something useful, that object is
1304  // not destroyed and we end up with a memory leak. consequently,
1305  // first delete previous content before re-loading stuff
1306  for (unsigned int i=0; i<levels.size(); ++i)
1307  delete levels[i];
1308  levels.resize (0);
1309  delete faces;
1310  faces = 0;
1311 
1312  ar &levels;
1313  ar &faces;
1314 
1315  // these are the checks that correspond to the last block in the save() function
1316  unsigned int n_cells;
1317  std::string fe_name;
1318  std::string policy_name;
1319 
1320  ar &n_cells &fe_name &policy_name;
1321 
1322  AssertThrow (n_cells == tria->n_cells(),
1323  ExcMessage ("The object being loaded into does not match the triangulation "
1324  "that has been stored previously."));
1325  AssertThrow (fe_name == selected_fe->get_name(),
1326  ExcMessage ("The finite element associated with this DoFHandler does not match "
1327  "the one that was associated with the DoFHandler previously stored."));
1328  AssertThrow (policy_name == internal::policy_to_string(*policy),
1329  ExcMessage (std::string ("The policy currently associated with this DoFHandler (")
1330  + internal::policy_to_string(*policy)
1331  +std::string(") does not match the one that was associated with the "
1332  "DoFHandler previously stored (")
1333  + policy_name
1334  + ")."));
1335 }
1336 
1337 
1338 template<int dim, int spacedim>
1339 inline
1341  const unsigned int level,
1342  const unsigned int dof_number) const
1343 {
1344  Assert ((level >= coarsest_level) && (level <= finest_level), ExcInvalidLevel (level));
1345  return indices[indices_offset[level - coarsest_level] + dof_number];
1346 }
1347 
1348 
1349 template<int dim, int spacedim>
1350 inline
1352  const unsigned int level,
1353  const unsigned int dof_number,
1354  const types::global_dof_index index)
1355 {
1356  Assert ((level >= coarsest_level) && (level <= finest_level), ExcInvalidLevel (level));
1357  indices[indices_offset[level - coarsest_level] + dof_number] = index;
1358 }
1359 
1360 #endif // DOXYGEN
1361 
1362 DEAL_II_NAMESPACE_CLOSE
1363 
1364 #endif
unsigned int max_couplings_between_boundary_dofs() const
DeclException1(ExcNewNumbersNotConsecutive, types::global_dof_index,<< "The given list of new dof indices is not consecutive: "<< "the index "<< arg1<< " does not exist.")
virtual void distribute_dofs(const FiniteElement< dim, spacedim > &fe)
::FunctionMap< spacedim >::type FunctionMap
Definition: dof_handler.h:217
std::vector<::internal::DoFHandler::NumberCache > mg_number_cache
Definition: dof_handler.h:960
active_cell_iterator begin_active(const unsigned int level=0) const
types::global_dof_index * indices
Definition: dof_handler.h:1065
static const unsigned int dimension
Definition: dof_handler.h:223
const BlockInfo & block_info() const
void set_index(const unsigned int level, const unsigned int dof_number, const types::global_dof_index index)
::ExceptionBase & ExcMessage(std::string arg1)
const Triangulation< dim, spacedim > * tria
cell_iterator end() const
virtual ~DoFHandler()
virtual void clear()
SmartPointer< const FiniteElement< dim, spacedim >, DoFHandler< dim, spacedim > > selected_fe
Definition: dof_handler.h:935
std::vector<::internal::DoFHandler::DoFLevel< dim > * > levels
Definition: dof_handler.h:1097
SmartPointer< const Triangulation< dim, spacedim >, DoFHandler< dim, spacedim > > tria
Definition: dof_handler.h:920
bool has_level_dofs() const
#define AssertThrow(cond, exc)
Definition: exceptions.h:362
const std::vector< types::global_dof_index > & n_locally_owned_dofs_per_processor() const
::internal::DoFHandler::NumberCache number_cache
Definition: dof_handler.h:955
unsigned int max_couplings_between_dofs() const
void initialize(const Triangulation< dim, spacedim > &tria, const FiniteElement< dim, spacedim > &fe)
BlockInfo block_info_object
Definition: dof_handler.h:904
cell_iterator begin(const unsigned int level=0) const
unsigned int global_dof_index
Definition: types.h:100
types::global_dof_index * indices_offset
Definition: dof_handler.h:1072
#define Assert(cond, exc)
Definition: exceptions.h:299
types::global_dof_index n_dofs() const
static const unsigned int default_fe_index
Definition: dof_handler.h:268
unsigned int n_locally_owned_dofs() const
types::global_dof_index get_index(const unsigned int level, const unsigned int dof_number) const
level_cell_iterator begin_mg(const unsigned int level=0) const
::internal::DoFHandler::DoFFaces< dim > * faces
Definition: dof_handler.h:1109
virtual std::size_t memory_consumption() const
const IndexSet & locally_owned_mg_dofs(const unsigned int level) const
void renumber_dofs(const std::vector< types::global_dof_index > &new_numbers)
void initialize_local_block_info()
bool has_active_dofs() const
void save(Archive &ar, const unsigned int version) const
types::global_dof_index n_boundary_dofs() const
active_cell_iterator end_active(const unsigned int level) const
unsigned int coarsest_level
Definition: dof_handler.h:1053
void clear_space()
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
::ExceptionBase & ExcNotInitialized()
static const unsigned int space_dimension
Definition: dof_handler.h:229
level_cell_iterator end_mg() const
const types::global_dof_index invalid_dof_index
Definition: types.h:217
const Triangulation< dim, spacedim > & get_tria() const
const IndexSet & locally_owned_dofs() const
const std::vector< IndexSet > & locally_owned_dofs_per_processor() const
virtual void distribute_mg_dofs(const FiniteElement< dim, spacedim > &fe)
DeclException0(ExcRenumberingIncomplete)
std_cxx1x::shared_ptr<::internal::DoFHandler::Policy::PolicyBase< dim, spacedim > > policy
Definition: dof_handler.h:942
static const types::global_dof_index invalid_dof_index
Definition: dof_handler.h:246
std::vector< types::global_dof_index > vertex_dofs
Definition: dof_handler.h:911
const FiniteElement< dim, spacedim > & get_fe() const