Flow123d  release_3.0.0-890-gfc7e296
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_->el_ds_->lsize()+dof_handler_->ghost_4_loc.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 
79  /**
80  * @brief Returns the indices of dofs associated to the cell on the local process.
81  *
82  * @param indices Array of dof indices on the cell.
83  */
84  unsigned int get_loc_dof_indices(std::vector<LongIdx> &indices) const;
85 
86  /// Return number of dofs on given cell.
87  unsigned int n_dofs() const;
88 
89  /**
90  * @brief Return dof on a given cell.
91  * @param idof Number of dof on the cell.
92  */
93  const Dof &cell_dof(unsigned int idof) const;
94 
95  /// Return dimension of element appropriate to cell.
96  inline unsigned int dim() const {
97  return elm().dim();
98  }
99 
100  /**
101  * @brief Returns finite element object for given space dimension.
102  */
103  template<unsigned int dim>
105  ElementAccessor<3> elm_acc = this->elm();
106  return dof_handler_->ds_->fe<dim>(elm_acc);
107  }
108 
109  /// Check validity of accessor (see default constructor)
110  inline bool is_valid() const {
111  return dof_handler_ != NULL;
112  }
113 
114  /// Returns range of cell sides
116 
117  /// Returns range of neighbour cell of lower dimension corresponding to cell of higher dimension
119 
120  /// Return true if accessor represents own element (false for ghost element)
121  inline bool is_own() const {
122  return (loc_ele_idx_ < dof_handler_->el_ds_->lsize());
123  }
124 
125  /// Iterates to next local element.
126  inline void inc() {
127  loc_ele_idx_++;
128  }
129 
130  /// Comparison of accessors.
131  bool operator==(const DHCellAccessor& other) {
132  return (loc_ele_idx_ == other.loc_ele_idx_);
133  }
134 
135 private:
136  /// Pointer to the DOF handler owning the element.
138  /// Index into DOFHandler::el_4_loc array.
139  unsigned int loc_ele_idx_;
140 
141  friend class DHCellSide;
142  friend class DHEdgeSide;
143  friend class DHNeighbSide;
144 };
145 
146 
147 /**
148  * @brief Side accessor allows to iterate over sides of DOF handler cell.
149  *
150  * Iterator is defined by:
151  * - DOF handler cell
152  * - index of Side in DOF cell (iterated value)
153  */
154 class DHCellSide {
155 public:
156 
157  /**
158  * @brief Default invalid accessor.
159  *
160  * Create invalid \p dh_cell_accessor_.
161  */
163 
164  /**
165  * DOF cell side accessor.
166  */
167  DHCellSide(const DHCellAccessor &dh_cell_accessor, unsigned int side_idx)
168  : dh_cell_accessor_(dh_cell_accessor), side_idx_(side_idx) {}
169 
170  /// Check validity of accessor (see default constructor)
171  inline virtual bool is_valid() const {
172  return dh_cell_accessor_.is_valid();
173  }
174 
175  /// Return Side of given cell and side_idx.
176  inline const Side * side() const {
177  ASSERT( this->is_valid() );
178  return new Side( const_cast<const Mesh*>(dh_cell_accessor_.dof_handler_->mesh()), dh_cell_accessor_.elm_idx(), side_idx_ );
179  }
180 
181  /// Return DHCellAccessor appropriate to the side.
182  inline const DHCellAccessor cell() const {
183  return dh_cell_accessor_;
184  }
185 
186  /// Return dimension of element appropriate to the side.
187  inline unsigned int dim() const {
188  return cell().dim();
189  }
190 
191  /// Returns range of all sides looped over common Edge.
192  RangeConvert<DHEdgeSide, DHCellSide> edge_sides() const;
193 
194  /// Iterates to next local element.
195  inline virtual void inc() {
196  side_idx_++;
197  }
198 
199  /// Comparison of accessors.
200  bool operator==(const DHCellSide& other) {
201  return (side_idx_ == other.side_idx_);
202  }
203 
204 private:
205  /// Appropriate DHCellAccessor.
207  /// Index of side.
208  unsigned int side_idx_;
209 
210  friend class DHEdgeSide;
211 };
212 
213 
214 /**
215  * @brief Class allows to iterate over sides of edge.
216  *
217  * Iterator is defined by:
218  * - DOF handler
219  * - global index of Edge (constant value)
220  * - index of Side in Edge (iterated value)
221  *
222  * Note: Class is used only internally. Appropriate range method (DHCellSide::edge_sides) uses convertible iterators
223  * and returns corresponding DHCellSide.
224  */
225 class DHEdgeSide {
226 public:
227  /// Default invalid accessor.
228  DHEdgeSide() : dof_handler_(nullptr), edge_idx_(0) {}
229 
230  /**
231  * Valid accessor allows iterate over sides.
232  */
233  DHEdgeSide(const DHCellSide &cell_side, unsigned int side_idx)
234  : dof_handler_(cell_side.dh_cell_accessor_.dof_handler_),
235  edge_idx_(cell_side.dh_cell_accessor_.elm()->edge_idx(cell_side.side_idx_)),
236  side_idx_(side_idx)
237  {}
238 
239  /// Check validity of accessor (see default constructor)
240  inline bool is_valid() const {
241  return (dof_handler_!=nullptr);
242  }
243 
244  /// Iterates to next edge side.
245  inline void inc() {
246  side_idx_++;
247  }
248 
249  /// Comparison of accessors.
250  bool operator==(const DHEdgeSide& other) {
251  return (edge_idx_ == other.edge_idx_) && (side_idx_ == other.side_idx_);
252  }
253 
254  /// This class is implicitly convertible to DHCellSide.
255  operator DHCellSide() const {
256  SideIter side = dof_handler_->mesh()->edges[edge_idx_].side(side_idx_);
258  return DHCellSide(cell, side->side_idx());
259  }
260 
261 private:
262  /// Pointer to the DOF handler owning the element.
264  /// Global index of Edge.
265  unsigned int edge_idx_;
266  /// Index of side owned by Edge.
267  unsigned int side_idx_;
268 };
269 
270 
271 /**
272  * @brief Class allows to iterate over sides of neighbour.
273  *
274  * Class returns only local cells (owns + ghosts), non-local cells are skipped.
275  *
276  * Iterator is defined by:
277  * - DOF handler cell accessor
278  * - index of Neighbour on cell (iterated value)
279  * - maximal index of Neighbour (allow to skip non-local cells)
280  *
281  * Note: Class is used only internally. Appropriate range method (DHCellAccessor::neighb_sides) uses convertible
282  * iterators and returns corresponding DHCellSide.
283  */
285 public:
286  /// Default invalid accessor.
288 
289  /**
290  * @brief Valid accessor allows iterate over neighbor sides.
291  *
292  * @param dh_cell Element of lower dim.
293  * @param neighb_idx Index of neighbour.
294  * @param max_idx Maximal index of neighbour, method inc() doesn't set neighb_idx_ on higher value.
295  */
296  DHNeighbSide(const DHCellAccessor &dh_cell, unsigned int neighb_idx, unsigned int max_idx)
297  : dh_cell_(dh_cell), neighb_idx_(neighb_idx), max_idx_(max_idx)
298  {
299  // Skip non-local cells
300  while ( (neighb_idx_<max_idx_) && (dh_cell_.dof_handler_->global_to_local_el_idx_.end() ==
301  dh_cell_.dof_handler_->global_to_local_el_idx_.find((LongIdx)dh_cell_.elm()->neigh_vb[neighb_idx_]->side()->elem_idx())) ) {
302  neighb_idx_++;
303  }
304  }
305 
306  /// Check validity of accessor (see default constructor of DHCellAccessor)
307  inline bool is_valid() const {
308  return dh_cell_.is_valid();
309  }
310 
311  /// Iterates to next neighbour side.
312  inline void inc() {
313  // Skip non-local cells
314  do {
315  neighb_idx_++;
316  if (neighb_idx_>=max_idx_) break; //stop condition at the end item of range
317  } while ( dh_cell_.dof_handler_->global_to_local_el_idx_.end() ==
318  dh_cell_.dof_handler_->global_to_local_el_idx_.find((LongIdx)dh_cell_.elm()->neigh_vb[neighb_idx_]->side()->elem_idx()) );
319  }
320 
321  /// Comparison of accessors.
322  bool operator==(const DHNeighbSide& other) {
323  return (neighb_idx_ == other.neighb_idx_);
324  }
325 
326  /// This class is implicitly convertible to DHCellSide.
327  operator DHCellSide() const {
328  SideIter side = dh_cell_.elm()->neigh_vb[neighb_idx_]->side();
330  return DHCellSide(cell, side->side_idx());
331  }
332 
333 private:
334  /// Appropriate cell accessor.
336  /// Index into neigh_vb array
337  unsigned int neighb_idx_;
338  /// Maximal index into neigh_vb array
339  unsigned int max_idx_;
340 };
341 
342 
343 /*************************************************************************************
344  * Implementation of inlined methods.
345  */
346 
347 inline unsigned int DHCellAccessor::get_dof_indices(std::vector<int> &indices) const
348 {
350  unsigned int ndofs = 0;
352  for (unsigned int k=0; k<ndofs; k++)
354 
355  return ndofs;
356 }
357 
358 
360 {
361  unsigned int ndofs = 0;
363  for (unsigned int k=0; k<ndofs; k++)
364  indices[k] = dof_handler_->cell_starts[loc_ele_idx_]+k;
365 
366  return ndofs;
367 }
368 
369 
370 inline unsigned int DHCellAccessor::n_dofs() const
371 {
372  switch (this->dim()) {
373  case 1:
374  return fe<1>()->n_dofs();
375  break;
376  case 2:
377  return fe<2>()->n_dofs();
378  break;
379  case 3:
380  return fe<3>()->n_dofs();
381  break;
382  }
383  return 0; // only fix compiler warning
384 }
385 
386 
387 inline const Dof &DHCellAccessor::cell_dof(unsigned int idof) const
388 {
389  switch (this->dim())
390  {
391  case 1:
392  return fe<1>()->dof(idof);
393  break;
394  case 2:
395  return fe<2>()->dof(idof);
396  break;
397  case 3:
398  return fe<3>()->dof(idof);
399  break;
400  }
401 }
402 
403 
405  auto bgn_it = make_iter<DHCellSide>( DHCellSide(*this, 0) );
406  auto end_it = make_iter<DHCellSide>( DHCellSide(*this, dim()+1) );
407  return Range<DHCellSide>(bgn_it, end_it);
408 }
409 
410 
412  unsigned int upper_bound = this->elm()->n_neighs_vb();
413  auto bgn_it = make_iter<DHNeighbSide, DHCellSide>( DHNeighbSide(*this, 0, upper_bound) );
414  auto end_it = make_iter<DHNeighbSide, DHCellSide>( DHNeighbSide(*this, upper_bound, upper_bound) );
415  return RangeConvert<DHNeighbSide, DHCellSide>(bgn_it, end_it);
416 }
417 
418 
420  unsigned int edge_idx = dh_cell_accessor_.elm()->edge_idx(side_idx_);
421  Edge *edg = &dh_cell_accessor_.dof_handler_->mesh()->edges[edge_idx];
422  unsigned int upper_bound = 0; // return empty range if no element connected to Edge is local
423  for (int sid=0; sid<edg->n_sides; sid++)
424  if ( dh_cell_accessor_.dof_handler_->el_is_local(edg->side(sid)->element().idx()) )
425  {
426  upper_bound = edg->n_sides;
427  break;
428  }
429 
430  return RangeConvert<DHEdgeSide, DHCellSide>(make_iter<DHEdgeSide, DHCellSide>( DHEdgeSide( *this, 0) ),
431  make_iter<DHEdgeSide, DHCellSide>( DHEdgeSide( *this, upper_bound) ));
432 }
433 
434 
435 #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:685
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:420
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)
std::vector< LongIdx > cell_starts
Starting indices for local (owned+ghost) element dofs.
Definition: dofhandler.hh:396
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.
std::vector< LongIdx > dof_indices
Dof numbers on local and ghost elements.
Definition: dofhandler.hh:404
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:429
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.
DHCellSide()
Default invalid accessor.
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than)
Definition: asserts.hh:295
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:370
unsigned int elem_idx() const
Definition: side_impl.hh:87
unsigned int side_idx_
Index of side.
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
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