Flow123d  release_3.0.0-1111-g6aae175
dh_cell_accessor.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 dh_cell_accessor.hh
15  * @brief
16  * @author David Flanderka
17  */
18 
19 #ifndef DH_CELL_ACCESSOR_HH_
20 #define DH_CELL_ACCESSOR_HH_
21 
22 #include "mesh/accessors.hh"
23 #include "mesh/sides.h"
24 #include "mesh/neighbours.h"
25 #include "fem/dofhandler.hh"
26 
27 class DHCellSide;
28 class DHNeighbSide;
29 class DHEdgeSide;
30 
31 /**
32  * @brief Cell accessor allow iterate over DOF handler cells.
33  *
34  * Iterating is possible over different ranges of local and ghost elements.
35  *
36  * Iterator is defined by:
37  * - DOF handler
38  * - local index of DOF cell (iterated value)
39  */
41 public:
42  /// Default invalid accessor.
44  : dof_handler_(NULL)
45  {}
46 
47  /**
48  * DOF cell accessor.
49  */
50  DHCellAccessor(const DOFHandlerMultiDim *dof_handler, unsigned int loc_idx)
51  : dof_handler_(dof_handler), loc_ele_idx_(loc_idx)
52  {}
53 
54  /// Return local index to element (index of DOF handler).
55  inline unsigned int local_idx() const {
56  ASSERT_LT_DBG(loc_ele_idx_, dof_handler_->global_to_local_el_idx_.size()).error("Local element index is out of range!\n");
57  return loc_ele_idx_;
58  }
59 
60  /// Return serial idx to element of loc_ele_idx_.
61  inline unsigned int elm_idx() const {
62  unsigned int ds_lsize = dof_handler_->el_ds_->lsize();
63  if (local_idx()<ds_lsize) return dof_handler_->mesh()->get_el_4_loc()[loc_ele_idx_]; //own elements
64  else return dof_handler_->ghost_4_loc[loc_ele_idx_-ds_lsize]; //ghost elements
65  }
66 
67  /// Return ElementAccessor to element of loc_ele_idx_.
68  inline const ElementAccessor<3> elm() const {
69  return dof_handler_->mesh()->element_accessor( elm_idx() );
70  }
71 
72  /**
73  * @brief Fill vector of the global indices of dofs associated to the cell.
74  *
75  * @param indices Vector of dof indices on the cell.
76  */
77  unsigned int get_dof_indices(std::vector<int> &indices) const
78  { return dof_handler_->get_dof_indices( *this, indices ); }
79 
80  /**
81  * @brief Returns the indices of dofs associated to the cell on the local process.
82  *
83  * @param indices Array of dof indices on the cell.
84  */
85  unsigned int get_loc_dof_indices(std::vector<LongIdx> &indices) const
86  { return dof_handler_->get_loc_dof_indices( *this, indices ); }
87 
88  /// Return number of dofs on given cell.
89  unsigned int n_dofs() const;
90 
91  /**
92  * @brief Return dof on a given cell.
93  * @param idof Number of dof on the cell.
94  */
95  const Dof &cell_dof(unsigned int idof) const;
96 
97  /// Return dimension of element appropriate to cell.
98  inline unsigned int dim() const {
99  return elm().dim();
100  }
101 
102  /**
103  * @brief Returns finite element object for given space dimension.
104  */
105  template<unsigned int dim>
107  ElementAccessor<3> elm_acc = this->elm();
108  return dof_handler_->ds_->fe<dim>(elm_acc);
109  }
110 
111  /// Check validity of accessor (see default constructor)
112  inline bool is_valid() const {
113  return dof_handler_ != NULL;
114  }
115 
116  /// Returns range of cell sides
118 
119  /// Returns range of neighbour cell of lower dimension corresponding to cell of higher dimension
121 
122  /// Return true if accessor represents own element (false for ghost element)
123  inline bool is_own() const {
124  return (loc_ele_idx_ < dof_handler_->el_ds_->lsize());
125  }
126 
127  /// Iterates to next local element.
128  inline void inc() {
129  loc_ele_idx_++;
130  }
131 
132  /// Comparison of accessors.
133  bool operator==(const DHCellAccessor& other) {
134  return (loc_ele_idx_ == other.loc_ele_idx_);
135  }
136 
137 private:
138  /// Pointer to the DOF handler owning the element.
140  /// Index into DOFHandler::el_4_loc array.
141  unsigned int loc_ele_idx_;
142 
143  friend class DHCellSide;
144  friend class DHEdgeSide;
145  friend class DHNeighbSide;
146 };
147 
148 
149 /**
150  * @brief Side accessor allows to iterate over sides of DOF handler cell.
151  *
152  * Iterator is defined by:
153  * - DOF handler cell
154  * - index of Side in DOF cell (iterated value)
155  */
156 class DHCellSide {
157 public:
158 
159  /**
160  * @brief Default invalid accessor.
161  *
162  * Create invalid \p dh_cell_accessor_.
163  */
165 
166  /**
167  * DOF cell side accessor.
168  */
169  DHCellSide(const DHCellAccessor &dh_cell_accessor, unsigned int side_idx)
170  : dh_cell_accessor_(dh_cell_accessor), side_idx_(side_idx) {}
171 
172  /// Check validity of accessor (see default constructor)
173  inline virtual bool is_valid() const {
174  return dh_cell_accessor_.is_valid();
175  }
176 
177  /// Return Side of given cell and side_idx.
178  inline const Side * side() const {
179  ASSERT( this->is_valid() );
180  return new Side( const_cast<const Mesh*>(dh_cell_accessor_.dof_handler_->mesh()), dh_cell_accessor_.elm_idx(), side_idx_ );
181  }
182 
183  /// Return DHCellAccessor appropriate to the side.
184  inline const DHCellAccessor cell() const {
185  return dh_cell_accessor_;
186  }
187 
188  /// Return dimension of element appropriate to the side.
189  inline unsigned int dim() const {
190  return cell().dim();
191  }
192 
193  /// Returns range of all sides looped over common Edge.
194  RangeConvert<DHEdgeSide, DHCellSide> edge_sides() const;
195 
196  /**
197  * Returns total number of sides appropriate to Edge that owns actual cell side.
198  *
199  * return empty range if no element connected to Edge is local
200  */
201  unsigned int n_edge_sides() const;
202 
203  /// Iterates to next local element.
204  inline virtual void inc() {
205  side_idx_++;
206  }
207 
208  /// Comparison of accessors.
209  bool operator==(const DHCellSide& other) {
210  return (side_idx_ == other.side_idx_);
211  }
212 
213 private:
214  /// Appropriate DHCellAccessor.
216  /// Index of side.
217  unsigned int side_idx_;
218 
219  friend class DHEdgeSide;
220 };
221 
222 
223 /**
224  * @brief Class allows to iterate over sides of edge.
225  *
226  * Iterator is defined by:
227  * - DOF handler
228  * - global index of Edge (constant value)
229  * - index of Side in Edge (iterated value)
230  *
231  * Note: Class is used only internally. Appropriate range method (DHCellSide::edge_sides) uses convertible iterators
232  * and returns corresponding DHCellSide.
233  */
234 class DHEdgeSide {
235 public:
236  /// Default invalid accessor.
237  DHEdgeSide() : dof_handler_(nullptr), edge_idx_(0) {}
238 
239  /**
240  * Valid accessor allows iterate over sides.
241  */
242  DHEdgeSide(const DHCellSide &cell_side, unsigned int side_idx)
243  : dof_handler_(cell_side.dh_cell_accessor_.dof_handler_),
244  edge_idx_(cell_side.dh_cell_accessor_.elm()->edge_idx(cell_side.side_idx_)),
245  side_idx_(side_idx)
246  {}
247 
248  /// Check validity of accessor (see default constructor)
249  inline bool is_valid() const {
250  return (dof_handler_!=nullptr);
251  }
252 
253  /// Iterates to next edge side.
254  inline void inc() {
255  side_idx_++;
256  }
257 
258  /// Comparison of accessors.
259  bool operator==(const DHEdgeSide& other) {
260  return (edge_idx_ == other.edge_idx_) && (side_idx_ == other.side_idx_);
261  }
262 
263  /// This class is implicitly convertible to DHCellSide.
264  operator DHCellSide() const {
265  SideIter side = dof_handler_->mesh()->edges[edge_idx_].side(side_idx_);
267  return DHCellSide(cell, side->side_idx());
268  }
269 
270 private:
271  /// Pointer to the DOF handler owning the element.
273  /// Global index of Edge.
274  unsigned int edge_idx_;
275  /// Index of side owned by Edge.
276  unsigned int side_idx_;
277 };
278 
279 
280 /**
281  * @brief Class allows to iterate over sides of neighbour.
282  *
283  * Class returns only local cells (owns + ghosts), non-local cells are skipped.
284  *
285  * Iterator is defined by:
286  * - DOF handler cell accessor
287  * - index of Neighbour on cell (iterated value)
288  * - maximal index of Neighbour (allow to skip non-local cells)
289  *
290  * Note: Class is used only internally. Appropriate range method (DHCellAccessor::neighb_sides) uses convertible
291  * iterators and returns corresponding DHCellSide.
292  */
294 public:
295  /// Default invalid accessor.
297 
298  /**
299  * @brief Valid accessor allows iterate over neighbor sides.
300  *
301  * @param dh_cell Element of lower dim.
302  * @param neighb_idx Index of neighbour.
303  * @param max_idx Maximal index of neighbour, method inc() doesn't set neighb_idx_ on higher value.
304  */
305  DHNeighbSide(const DHCellAccessor &dh_cell, unsigned int neighb_idx, unsigned int max_idx)
306  : dh_cell_(dh_cell), neighb_idx_(neighb_idx), max_idx_(max_idx)
307  {
308  // Skip non-local cells
309  while ( (neighb_idx_<max_idx_) && not_local_cell() ) {
310  neighb_idx_++;
311  }
312  }
313 
314  /// Check validity of accessor (see default constructor of DHCellAccessor)
315  inline bool is_valid() const {
316  return dh_cell_.is_valid();
317  }
318 
319  /// Iterates to next neighbour side.
320  inline void inc() {
321  // Skip non-local cells
322  do {
323  neighb_idx_++;
324  if (neighb_idx_>=max_idx_) break; //stop condition at the end item of range
325  } while ( not_local_cell() );
326  }
327 
328  /// Comparison of accessors.
329  bool operator==(const DHNeighbSide& other) {
330  return (neighb_idx_ == other.neighb_idx_);
331  }
332 
333  /// This class is implicitly convertible to DHCellSide.
334  operator DHCellSide() const {
335  SideIter side = dh_cell_.elm()->neigh_vb[neighb_idx_]->side();
337  return DHCellSide(cell, side->side_idx());
338  }
339 
340 private:
341  /// Check if cell side of neighbour is not local (allow skip invalid accessors).
342  inline bool not_local_cell() {
343  return ( dh_cell_.dof_handler_->global_to_local_el_idx_.end() ==
344  dh_cell_.dof_handler_->global_to_local_el_idx_.find((LongIdx)dh_cell_.elm()->neigh_vb[neighb_idx_]->side()->elem_idx()) );
345  }
346 
347  /// Appropriate cell accessor.
349  /// Index into neigh_vb array
350  unsigned int neighb_idx_;
351  /// Maximal index into neigh_vb array
352  unsigned int max_idx_;
353 };
354 
355 
356 /*************************************************************************************
357  * Implementation of inlined methods.
358  */
359 
360 
361 inline unsigned int DHCellAccessor::n_dofs() const
362 {
363  switch (this->dim()) {
364  case 1:
365  return fe<1>()->n_dofs();
366  break;
367  case 2:
368  return fe<2>()->n_dofs();
369  break;
370  case 3:
371  return fe<3>()->n_dofs();
372  break;
373  }
374  return 0; // only fix compiler warning
375 }
376 
377 
378 inline const Dof &DHCellAccessor::cell_dof(unsigned int idof) const
379 {
380  switch (this->dim())
381  {
382  case 1:
383  return fe<1>()->dof(idof);
384  break;
385  case 2:
386  return fe<2>()->dof(idof);
387  break;
388  case 3:
389  return fe<3>()->dof(idof);
390  break;
391  }
392 }
393 
394 
396  auto bgn_it = make_iter<DHCellSide>( DHCellSide(*this, 0) );
397  auto end_it = make_iter<DHCellSide>( DHCellSide(*this, dim()+1) );
398  return Range<DHCellSide>(bgn_it, end_it);
399 }
400 
401 
403  unsigned int upper_bound = this->elm()->n_neighs_vb();
404  auto bgn_it = make_iter<DHNeighbSide, DHCellSide>( DHNeighbSide(*this, 0, upper_bound) );
405  auto end_it = make_iter<DHNeighbSide, DHCellSide>( DHNeighbSide(*this, upper_bound, upper_bound) );
406  return RangeConvert<DHNeighbSide, DHCellSide>(bgn_it, end_it);
407 }
408 
409 
411  return RangeConvert<DHEdgeSide, DHCellSide>(make_iter<DHEdgeSide, DHCellSide>( DHEdgeSide( *this, 0) ),
412  make_iter<DHEdgeSide, DHCellSide>( DHEdgeSide( *this, n_edge_sides()) ));
413 }
414 
415 
416 inline unsigned int DHCellSide::n_edge_sides() const {
417  unsigned int edge_idx = dh_cell_accessor_.elm()->edge_idx(side_idx_);
418  Edge *edg = &dh_cell_accessor_.dof_handler_->mesh()->edges[edge_idx];
419  for (int sid=0; sid<edg->n_sides; sid++)
420  if ( dh_cell_accessor_.dof_handler_->el_is_local(edg->side(sid)->element().idx()) ) return edg->n_sides;
421  return 0;
422 }
423 
424 
425 
426 #endif /* DH_CELL_ACCESSOR_HH_ */
Definition: sides.h:39
int LongIdx
Define type that represents indices of large arrays (elements, nodes, dofs etc.)
Definition: long_idx.hh:22
virtual bool is_valid() const
Check validity of accessor (see default constructor)
const Dof & cell_dof(unsigned int idof) const
Return dof on a given cell.
Range< DHCellSide > side_range() const
Returns range of cell sides.
Declaration of class which handles the ordering of degrees of freedom (dof) and mappings between loca...
Class allows to iterate over sides of neighbour.
const DOFHandlerMultiDim * dof_handler_
Pointer to the DOF handler owning the element.
unsigned int elm_idx() const
Return serial idx to element of loc_ele_idx_.
const DHCellAccessor cell_accessor_from_element(unsigned int elm_idx) const
Return DHCellAccessor appropriate to ElementAccessor of given idx.
Definition: dofhandler.cc:690
void inc()
Iterates to next local element.
unsigned int dim() const
Return dimension of element appropriate to the side.
unsigned int side_idx() const
Definition: side_impl.hh:82
DHCellAccessor dh_cell_accessor_
Appropriate DHCellAccessor.
unsigned int get_loc_dof_indices(std::vector< LongIdx > &indices) const
Returns the indices of dofs associated to the cell on the local process.
Distribution * el_ds_
Distribution of elements.
Definition: dofhandler.hh:422
unsigned int dim() const
Return dimension of element appropriate to cell.
unsigned int local_idx() const
Return local index to element (index of DOF handler).
FiniteElement< dim > * fe() const
Returns finite element object for given space dimension.
Cell accessor allow iterate over DOF handler cells.
bool is_valid() const
Check validity of accessor (see default constructor of DHCellAccessor)
const Side * side() const
Return Side of given cell and side_idx.
int n_sides
Definition: edges.h:36
Definition: edges.h:26
const DOFHandlerMultiDim * dof_handler_
Pointer to the DOF handler owning the element.
unsigned int side_idx_
Index of side owned by Edge.
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
bool is_valid() const
Check validity of accessor (see default constructor)
Mesh * mesh() const
Returns the mesh.
Definition: dofhandler.hh:78
unsigned int max_idx_
Maximal index into neigh_vb array.
bool is_own() const
Return true if accessor represents own element (false for ghost element)
unsigned int n_dofs() const
Return number of dofs on given cell.
ElementAccessor< 3 > element() const
Definition: side_impl.hh:53
virtual ElementAccessor< 3 > element_accessor(unsigned int idx) const
Create and return ElementAccessor to element of given idx.
Definition: mesh.cc:726
bool operator==(const DHCellSide &other)
Comparison of accessors.
DHNeighbSide(const DHCellAccessor &dh_cell, unsigned int neighb_idx, unsigned int max_idx)
Valid accessor allows iterate over neighbor sides.
bool is_valid() const
Check validity of accessor (see default constructor)
const ElementAccessor< 3 > elm() const
Return ElementAccessor to element of loc_ele_idx_.
unsigned int neighb_idx_
Index into neigh_vb array.
DHNeighbSide()
Default invalid accessor.
RangeConvert< DHEdgeSide, DHCellSide > edge_sides() const
Returns range of all sides looped over common Edge.
void inc()
Iterates to next neighbour side.
Range helper class.
DHCellAccessor()
Default invalid accessor.
RangeConvert< DHNeighbSide, DHCellSide > neighb_sides() const
Returns range of neighbour cell of lower dimension corresponding to cell of higher dimension...
Provides the numbering of the finite element degrees of freedom on the computational mesh...
Definition: dofhandler.hh:152
DHCellAccessor(const DOFHandlerMultiDim *dof_handler, unsigned int loc_idx)
vector< LongIdx > ghost_4_loc
Indices of ghost cells (neighbouring with local elements).
Definition: dofhandler.hh:431
unsigned int n_edge_sides() const
std::unordered_map< LongIdx, LongIdx > global_to_local_el_idx_
Maps global element index into local/ghost index (obsolete).
Definition: dofhandler.hh:419
friend class DHCellSide
unsigned int edge_idx_
Global index of Edge.
DHEdgeSide()
Default invalid accessor.
const DHCellAccessor cell() const
Return DHCellAccessor appropriate to the side.
void inc()
Iterates to next edge side.
bool operator==(const DHNeighbSide &other)
Comparison of accessors.
unsigned int get_loc_dof_indices(const DHCellAccessor &cell, std::vector< LongIdx > &indices) const override
Returns the indices of dofs associated to the cell on the local process.
Definition: dofhandler.cc:556
DHCellSide()
Default invalid accessor.
std::vector< Edge > edges
Vector of MH edges, this should not be part of the geometrical mesh.
Definition: mesh.h:252
virtual void inc()
Iterates to next local element.
friend class DHNeighbSide
DHEdgeSide(const DHCellSide &cell_side, unsigned int side_idx)
DHCellAccessor dh_cell_
Appropriate cell accessor.
std::shared_ptr< DiscreteSpace > ds_
Pointer to the discrete space for which the handler distributes dofs.
Definition: dofhandler.hh:372
unsigned int elem_idx() const
Definition: side_impl.hh:87
unsigned int side_idx_
Index of side.
unsigned int get_dof_indices(const DHCellAccessor &cell, std::vector< LongIdx > &indices) const override
Returns the global indices of dofs associated to the cell.
Definition: dofhandler.cc:544
Abstract class for the description of a general finite element on a reference simplex in dim dimensio...
unsigned int dim() const
Definition: accessors.hh:87
friend class DHEdgeSide
bool operator==(const DHEdgeSide &other)
Comparison of accessors.
unsigned int n_neighs_vb() const
Return number of neighbours.
Definition: elements.h:70
bool operator==(const DHCellAccessor &other)
Comparison of accessors.
unsigned int idx() const
Return local idx of element in boundary / bulk part of element vector.
Definition: accessors.hh:111
bool not_local_cell()
Check if cell side of neighbour is not local (allow skip invalid accessors).
DHCellSide(const DHCellAccessor &dh_cell_accessor, unsigned int side_idx)
unsigned int get_dof_indices(std::vector< int > &indices) const
Fill vector of the global indices of dofs associated to the cell.
LongIdx * get_el_4_loc() const
Definition: mesh.h:170
SideIter side(const unsigned int i) const
Definition: edges.h:31
unsigned int loc_ele_idx_
Index into DOFHandler::el_4_loc array.
Side accessor allows to iterate over sides of DOF handler cell.
Class allows to iterate over sides of edge.
#define ASSERT_LT_DBG(a, b)
Definition of comparative assert macro (Less Than) only for debug mode.
Definition: asserts.hh:299
unsigned int lsize(int proc) const
get local size