Flow123d  release_3.0.0-906-g65cc372
dofhandler.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file dofhandler.hh
15  * @brief Declaration of class which handles the ordering of degrees of freedom (dof) and mappings between local and global dofs.
16  * @author Jan Stebel
17  */
18 
19 #ifndef DOFHANDLER_HH_
20 #define DOFHANDLER_HH_
21 
22 #include <vector> // for vector
23 #include <unordered_map> // for unordered_map
24 #include "mesh/side_impl.hh"
25 #include "mesh/mesh.h"
26 #include "mesh/accessors.hh"
27 #include "mesh/long_idx.hh" // for LongIdx
28 #include "mesh/range_wrapper.hh"
30 #include "fem/discrete_space.hh" // for DiscreteSpace
31 #include "la/vector_mpi.hh" // for VectorMPI
32 #include "petscvec.h" // for Vec
33 
34 template<unsigned int dim> class FiniteElement;
35 class DHCellAccessor;
36 class Mesh;
37 class Distribution;
38 class Dof;
39 
40 
41 /**
42  * Class DOFHandlerBase provides an abstract interface for various dof handlers:
43  * - basic handler for a given spatial dimension
44  * - multi-dimensional handler for all spatial dimensions (1D-3D)
45  * - handler for a specific region / part of mesh
46  */
48 public:
49 
50  /**
51  * @brief Constructor.
52  * @param _mesh The mesh.
53  */
55  : n_global_dofs_(0), lsize_(0), loffset_(0), max_elem_dofs_(0), mesh_(&_mesh), dof_ds_(0) {}
56 
57  /**
58  * @brief Getter for the number of all mesh dofs required by the given
59  * finite element.
60  */
61  const unsigned int n_global_dofs() const { return n_global_dofs_; }
62 
63  /**
64  * @brief Returns the number of dofs on the current process.
65  */
66  const unsigned int lsize() const { return lsize_; }
67 
68  /**
69  * @brief Returns max. number of dofs on one element.
70  */
71  const unsigned int max_elem_dofs() const { return max_elem_dofs_; }
72 
73  std::shared_ptr<Distribution> distr() const { return dof_ds_; }
74 
75  /**
76  * @brief Returns the mesh.
77  */
78  Mesh *mesh() const { return mesh_; }
79 
80  /**
81  * @brief Fill vector of the global indices of dofs associated to the @p cell.
82  *
83  * @param cell The cell.
84  * @param indices Vector of dof indices on the cell.
85  */
86  virtual unsigned int get_dof_indices(const ElementAccessor<3> &cell, std::vector<LongIdx> &indices) const = 0;
87 
88  /**
89  * @brief Fill vector of the indices of dofs associated to the @p cell on the local process.
90  *
91  * @param cell The cell.
92  * @param indices Vector of dof indices on the cell.
93  */
94  virtual unsigned int get_loc_dof_indices(const ElementAccessor<3> &cell, std::vector<LongIdx> &indices) const =0;
95 
96  /**
97  * @brief Compute hash value of DOF handler.
98  */
99  virtual std::size_t hash() const =0;
100 
101  /// Destructor.
102  virtual ~DOFHandlerBase();
103 
104 protected:
105 
106  /**
107  * @brief Number of global dofs assigned by the handler.
108  */
109  unsigned int n_global_dofs_;
110 
111  /**
112  * @brief Number of dofs associated to local process.
113  */
114  unsigned int lsize_;
115 
116  /**
117  * @brief Index of the first dof on the local process.
118  */
119  unsigned int loffset_;
120 
121  /// Max. number of dofs per element.
122  unsigned int max_elem_dofs_;
123 
124  /**
125  * @brief Pointer to the mesh to which the dof handler is associated.
126  */
128 
129  /**
130  * @brief Distribution of dofs associated to local process.
131  */
132  std::shared_ptr<Distribution> dof_ds_;
133 
134 };
135 
136 
137 
138 
139 /**
140  * @brief Provides the numbering of the finite element degrees of freedom
141  * on the computational mesh.
142  *
143  * Class DOFHandlerMultiDim distributes the degrees of freedom (dof) for
144  * a particular triplet of 1d, 2d and 3d finite elements on the computational mesh
145  * and provides mappings between local and global dofs.
146  * The template parameter @p dim denotes the spatial dimension of
147  * the reference finite element.
148  *
149  * Currently the functionality is restricted to finite elements with internal and nodal dofs,
150  * i.e. the neighboring elements can share only dofs on nodes.
151  */
153 public:
154 
155  /**
156  * @brief Constructor.
157  * @param _mesh The mesh.
158  * @param make_elem_part Allow switch off make_element_partitioning, necessary for boundary DOF handler.
159  */
160  DOFHandlerMultiDim(Mesh &_mesh, bool make_elem_part = true);
161 
162 
163  /**
164  * @brief Distributes degrees of freedom on the mesh needed
165  * for the given discrete space.
166  *
167  * By default, the dof handler is parallel, meaning that each
168  * processor has access to dofs on the local elements and on one
169  * layer of ghost elements (owned by neighbouring elements).
170  * This can be changed by setting @p sequential to true.
171  *
172  * @param ds The discrete space consisting of finite elements for each mesh element.
173  * @param sequential If true then each processor will have information about all dofs.
174  */
175  void distribute_dofs(std::shared_ptr<DiscreteSpace> ds);
176 
177  /** @brief Returns sequential version of the current dof handler.
178  *
179  * Collective on all processors.
180  */
181  std::shared_ptr<DOFHandlerMultiDim> sequential();
182 
183  /**
184  * @brief Returns scatter context from parallel to sequential vectors.
185  *
186  * For sequential dof handler it returns null pointer.
187  * Collective on all processors.
188  */
189  std::shared_ptr<VecScatter> sequential_scatter();
190 
191  /**
192  * @brief Allocates PETSc vector according to the dof distribution.
193  */
194  VectorMPI create_vector();
195 
196  /**
197  * @brief Returns the global indices of dofs associated to the @p cell.
198  *
199  * @param cell The cell.
200  * @param indices Array of dof indices on the cell.
201  */
202  unsigned int get_dof_indices(const ElementAccessor<3> &cell,
203  std::vector<LongIdx> &indices) const override;
204 
205  /**
206  * @brief Returns the indices of dofs associated to the @p cell on the local process.
207  *
208  * @param cell The cell.
209  * @param indices Array of dof indices on the cell.
210  */
211  unsigned int get_loc_dof_indices(const ElementAccessor<3> &cell,
212  std::vector<LongIdx> &indices) const override;
213 
214  /**
215  * @brief Returns the global index of local edge.
216  *
217  * @param loc_edg Local index of edge.
218  */
219  inline LongIdx edge_index(int loc_edg) const { return edg_4_loc[loc_edg]; }
220 
221  /**
222  * @brief Returns the global index of local neighbour.
223  *
224  * @param loc_nb Local index of neighbour.
225  */
226  inline LongIdx nb_index(int loc_nb) const { return nb_4_loc[loc_nb]; }
227 
228  /**
229  * @brief Returns number of local edges.
230  */
231  inline unsigned int n_loc_edges() const { return edg_4_loc.size(); }
232 
233  /**
234  * @brief Returns number of local neighbours.
235  */
236  inline unsigned int n_loc_nb() const { return nb_4_loc.size(); }
237 
238  /// Output structure of dof handler.
239  void print() const;
240 
241  /**
242  * Implements @p DOFHandlerBase::hash.
243  */
244  std::size_t hash() const override;
245 
246  /// Returns range of DOF handler cells (only range of own without ghost cells)
247  Range<DHCellAccessor> own_range() const;
248 
249  /// Returns range over own and ghost cells of DOF handler
250  Range<DHCellAccessor> local_range() const;
251 
252  /// Returns range over ghosts DOF handler cells
253  Range<DHCellAccessor> ghost_range() const;
254 
255  /// Return DHCellAccessor appropriate to ElementAccessor of given idx
256  const DHCellAccessor cell_accessor_from_element(unsigned int elm_idx) const;
257 
258  /// Return pointer to discrete space for which the handler distributes dofs.
259  std::shared_ptr<DiscreteSpace> ds() const { return ds_; }
260 
261 
262  /// Destructor.
263  ~DOFHandlerMultiDim() override;
264 
265 
266 
267  friend class DHCellAccessor;
268  friend class DHCellSide;
269  friend class DHNeighbSide;
270 
271 private:
272 
273  /**
274  * Returns true if element is on local process.
275  * @param index Global element index.
276  */
277  bool el_is_local(int index) const;
278 
279  /**
280  * @brief Prepare parallel distribution of elements, edges and neighbours.
281  */
282  void make_elem_partitioning();
283 
284  /**
285  * @brief Initialize vector of starting indices for elements.
286  */
287  void init_cell_starts();
288 
289  /**
290  * @brief Initialize auxiliary vector of starting indices of nodal/edge dofs.
291  *
292  * @param node_dof_starts Vector of nodal starting indices (output).
293  * @param edge_dof_starts Vector of edge starting indices (output).
294  */
295  void init_dof_starts(std::vector<LongIdx> &node_dof_starts,
296  std::vector<LongIdx> &edge_dof_starts);
297 
298  /**
299  * @brief Initialize node_status and edge_status.
300  *
301  * Set VALID_NFACE for nodes/edges owned by local elements and
302  * INVALID_NFACE for nodes/edges owned by ghost elements.
303  *
304  * @param node_status Vector of nodal status (output).
305  * @param edge_status Vector of edge status (output).
306  */
307  void init_status(std::vector<short int> &node_status,
308  std::vector<short int> &edge_status);
309 
310  /**
311  * @brief Obtain dof numbers on ghost elements from other processor.
312  * @param proc Neighbouring processor.
313  * @param dofs Array where dofs are stored (output).
314  */
315  void receive_ghost_dofs(unsigned int proc,
316  std::vector<LongIdx> &dofs);
317 
318  /**
319  * @brief Send dof numbers to other processor.
320  * @param proc Neighbouring processor.
321  */
322  void send_ghost_dofs(unsigned int proc);
323 
324  /**
325  * @brief Update dofs on local elements from ghost element dofs.
326  *
327  * @param proc Neighbouring processor.
328  * @param update_cells Vector of global indices of elements which need to be updated
329  * from ghost elements.
330  * @param dofs Vector of dof indices on ghost elements from processor @p proc.
331  * @param node_dof_starts Vector of starting indices of nodal dofs.
332  * @param node_dofs Vector of nodal dof indices (output).
333  * @param edge_dof_starts Vector of starting indices of edge dofs.
334  * @param edge_dofs Vector of edge dof indices (output).
335  */
336  void update_local_dofs(unsigned int proc,
337  const std::vector<bool> &update_cells,
338  const std::vector<LongIdx> &dofs,
339  const std::vector<LongIdx> &node_dof_starts,
340  std::vector<LongIdx> &node_dofs,
341  const std::vector<LongIdx> &edge_dof_starts,
342  std::vector<LongIdx> &edge_dofs);
343 
344  /**
345  * @brief Communicate local dof indices to all processors and create new sequential dof handler.
346  *
347  * Collective on all processors.
348  */
349  void create_sequential();
350 
351 
352  /**
353  * Flags used during distribution of dofs to mark n-face and dof status.
354  *
355  * INVALID_NFACE means that on this node/edge/side/cell the current processor
356  * will not distribute dofs.
357  * VALID_NFACE means that on this node/edge/side/cell the current processor
358  * will distribute dofs.
359  * ASSIGNED_NFACE means that dofs on this n-face are already distributed.
360  *
361  * INVALID_DOF marks dofs whose global number has to be set by neighbouring processor.
362  */
363  static const int INVALID_NFACE = 1;
364  static const int VALID_NFACE = 2;
365  static const int ASSIGNED_NFACE = 3;
366  static const int INVALID_DOF = -1;
367 
368 
369  /// Pointer to the discrete space for which the handler distributes dofs.
370  std::shared_ptr<DiscreteSpace> ds_;
371 
372  /// Indicator for parallel/sequential dof handler.
374 
375  /// Sequential dof handler associated to the current (parallel) one.
376  std::shared_ptr<DOFHandlerMultiDim> dh_seq_;
377 
378  /// Scatter context for parallel to sequential vectors.
379  std::shared_ptr<VecScatter> scatter_to_seq_;
380 
381  /**
382  * @brief Starting indices for local (owned+ghost) element dofs.
383  *
384  * E.g. dof_indices[cell_starts[idx]] = dof number for first dof on the
385  * cell with local index idx within the parallel structure. To use with
386  * DHCellAccessor use the following:
387  *
388  * DHCellAccessor<3> cell;
389  * ...
390  * // i-th dof number on the cell
391  * dof_indices[cell_starts[cell.local_idx()]+i] = ...
392  *
393  * For sequential dof handler, dofs from all elements are stored and
394  * elements are ordered as in mesh_->get_row_4_el().
395  */
397 
398  /**
399  * @brief Dof numbers on local and ghost elements.
400  *
401  * Dofs are ordered accordingly with cell_starts and local dof order
402  * given by the finite element. See cell_starts for more description.
403  */
405 
406  /**
407  * @brief Maps local and ghost dof indices to global ones.
408  *
409  * First lsize_ entries correspond to dofs owned by local processor,
410  * the remaining entries are ghost dofs sorted by neighbouring processor id.
411  */
413 
414  /**
415  * @brief Maps global element index into local/ghost index (obsolete).
416  */
417  std::unordered_map<LongIdx,LongIdx> global_to_local_el_idx_;
418 
419  /// Distribution of elements
421 
422  /// Local edge index -> global edge index
424 
425  /// Local neighbour index -> global neighbour index
427 
428  /// Indices of ghost cells (neighbouring with local elements).
430 
431  /// Processors of ghost elements.
432  set<unsigned int> ghost_proc;
433 
434  /// Arrays of ghost cells for each neighbouring processor.
436 
437 };
438 
439 
440 
441 
442 #endif /* DOFHANDLER_HH_ */
int LongIdx
Define type that represents indices of large arrays (elements, nodes, dofs etc.)
Definition: long_idx.hh:22
virtual ~DOFHandlerBase()
Destructor.
Definition: dofhandler.cc:34
const unsigned int lsize() const
Returns the number of dofs on the current process.
Definition: dofhandler.hh:66
Class allows to iterate over sides of neighbour.
FMT_API void print(std::FILE *f, CStringRef format_str, ArgList args)
Definition: format.cc:489
Distribution * el_ds_
Distribution of elements.
Definition: dofhandler.hh:420
Definition: mesh.h:76
Template Iter serves as general template for internal iterators.
Cell accessor allow iterate over DOF handler cells.
std::vector< LongIdx > local_to_global_dof_idx_
Maps local and ghost dof indices to global ones.
Definition: dofhandler.hh:412
unsigned int n_loc_nb() const
Returns number of local neighbours.
Definition: dofhandler.hh:236
std::shared_ptr< Distribution > dof_ds_
Distribution of dofs associated to local process.
Definition: dofhandler.hh:132
Mesh * mesh() const
Returns the mesh.
Definition: dofhandler.hh:78
std::shared_ptr< DOFHandlerMultiDim > dh_seq_
Sequential dof handler associated to the current (parallel) one.
Definition: dofhandler.hh:376
unsigned int lsize_
Number of dofs associated to local process.
Definition: dofhandler.hh:114
map< unsigned int, vector< LongIdx > > ghost_proc_el
Arrays of ghost cells for each neighbouring processor.
Definition: dofhandler.hh:435
virtual unsigned int get_dof_indices(const ElementAccessor< 3 > &cell, std::vector< LongIdx > &indices) const =0
Fill vector of the global indices of dofs associated to the cell.
std::vector< LongIdx > cell_starts
Starting indices for local (owned+ghost) element dofs.
Definition: dofhandler.hh:396
const unsigned int max_elem_dofs() const
Returns max. number of dofs on one element.
Definition: dofhandler.hh:71
Mesh * mesh_
Pointer to the mesh to which the dof handler is associated.
Definition: dofhandler.hh:127
Range helper class.
std::vector< LongIdx > dof_indices
Dof numbers on local and ghost elements.
Definition: dofhandler.hh:404
Provides the numbering of the finite element degrees of freedom on the computational mesh...
Definition: dofhandler.hh:152
vector< LongIdx > nb_4_loc
Local neighbour index -> global neighbour index.
Definition: dofhandler.hh:426
virtual unsigned int get_loc_dof_indices(const ElementAccessor< 3 > &cell, std::vector< LongIdx > &indices) const =0
Fill vector of the indices of dofs associated to the cell on the local process.
unsigned int max_elem_dofs_
Max. number of dofs per element.
Definition: dofhandler.hh:122
vector< LongIdx > ghost_4_loc
Indices of ghost cells (neighbouring with local elements).
Definition: dofhandler.hh:429
std::unordered_map< LongIdx, LongIdx > global_to_local_el_idx_
Maps global element index into local/ghost index (obsolete).
Definition: dofhandler.hh:417
Declaration of class which provides the finite element for every mesh cell.
unsigned int n_loc_edges() const
Returns number of local edges.
Definition: dofhandler.hh:231
virtual std::size_t hash() const =0
Compute hash value of DOF handler.
std::shared_ptr< Distribution > distr() const
Definition: dofhandler.hh:73
LongIdx edge_index(int loc_edg) const
Returns the global index of local edge.
Definition: dofhandler.hh:219
vector< LongIdx > edg_4_loc
Local edge index -> global edge index.
Definition: dofhandler.hh:423
unsigned int loffset_
Index of the first dof on the local process.
Definition: dofhandler.hh:119
set< unsigned int > ghost_proc
Processors of ghost elements.
Definition: dofhandler.hh:432
std::shared_ptr< DiscreteSpace > ds_
Pointer to the discrete space for which the handler distributes dofs.
Definition: dofhandler.hh:370
unsigned int n_global_dofs_
Number of global dofs assigned by the handler.
Definition: dofhandler.hh:109
Abstract class for the description of a general finite element on a reference simplex in dim dimensio...
bool is_parallel_
Indicator for parallel/sequential dof handler.
Definition: dofhandler.hh:373
DOFHandlerBase(Mesh &_mesh)
Constructor.
Definition: dofhandler.hh:54
std::shared_ptr< VecScatter > scatter_to_seq_
Scatter context for parallel to sequential vectors.
Definition: dofhandler.hh:379
LongIdx nb_index(int loc_nb) const
Returns the global index of local neighbour.
Definition: dofhandler.hh:226
Implementation of range helper class.
Side accessor allows to iterate over sides of DOF handler cell.
const unsigned int n_global_dofs() const
Getter for the number of all mesh dofs required by the given finite element.
Definition: dofhandler.hh:61
std::shared_ptr< DiscreteSpace > ds() const
Return pointer to discrete space for which the handler distributes dofs.
Definition: dofhandler.hh:259