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