Flow123d  release_3.0.0-906-g65cc372
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  /**
195  * Returns total number of sides appropriate to Edge that owns actual cell side.
196  *
197  * return empty range if no element connected to Edge is local
198  */
199  unsigned int n_edge_sides() const;
200 
201  /// Iterates to next local element.
202  inline virtual void inc() {
203  side_idx_++;
204  }
205 
206  /// Comparison of accessors.
207  bool operator==(const DHCellSide& other) {
208  return (side_idx_ == other.side_idx_);
209  }
210 
211 private:
212  /// Appropriate DHCellAccessor.
214  /// Index of side.
215  unsigned int side_idx_;
216 
217  friend class DHEdgeSide;
218 };
219 
220 
221 /**
222  * @brief Class allows to iterate over sides of edge.
223  *
224  * Iterator is defined by:
225  * - DOF handler
226  * - global index of Edge (constant value)
227  * - index of Side in Edge (iterated value)
228  *
229  * Note: Class is used only internally. Appropriate range method (DHCellSide::edge_sides) uses convertible iterators
230  * and returns corresponding DHCellSide.
231  */
232 class DHEdgeSide {
233 public:
234  /// Default invalid accessor.
235  DHEdgeSide() : dof_handler_(nullptr), edge_idx_(0) {}
236 
237  /**
238  * Valid accessor allows iterate over sides.
239  */
240  DHEdgeSide(const DHCellSide &cell_side, unsigned int side_idx)
241  : dof_handler_(cell_side.dh_cell_accessor_.dof_handler_),
242  edge_idx_(cell_side.dh_cell_accessor_.elm()->edge_idx(cell_side.side_idx_)),
243  side_idx_(side_idx)
244  {}
245 
246  /// Check validity of accessor (see default constructor)
247  inline bool is_valid() const {
248  return (dof_handler_!=nullptr);
249  }
250 
251  /// Iterates to next edge side.
252  inline void inc() {
253  side_idx_++;
254  }
255 
256  /// Comparison of accessors.
257  bool operator==(const DHEdgeSide& other) {
258  return (edge_idx_ == other.edge_idx_) && (side_idx_ == other.side_idx_);
259  }
260 
261  /// This class is implicitly convertible to DHCellSide.
262  operator DHCellSide() const {
263  SideIter side = dof_handler_->mesh()->edges[edge_idx_].side(side_idx_);
265  return DHCellSide(cell, side->side_idx());
266  }
267 
268 private:
269  /// Pointer to the DOF handler owning the element.
271  /// Global index of Edge.
272  unsigned int edge_idx_;
273  /// Index of side owned by Edge.
274  unsigned int side_idx_;
275 };
276 
277 
278 /**
279  * @brief Class allows to iterate over sides of neighbour.
280  *
281  * Class returns only local cells (owns + ghosts), non-local cells are skipped.
282  *
283  * Iterator is defined by:
284  * - DOF handler cell accessor
285  * - index of Neighbour on cell (iterated value)
286  * - maximal index of Neighbour (allow to skip non-local cells)
287  *
288  * Note: Class is used only internally. Appropriate range method (DHCellAccessor::neighb_sides) uses convertible
289  * iterators and returns corresponding DHCellSide.
290  */
292 public:
293  /// Default invalid accessor.
295 
296  /**
297  * @brief Valid accessor allows iterate over neighbor sides.
298  *
299  * @param dh_cell Element of lower dim.
300  * @param neighb_idx Index of neighbour.
301  * @param max_idx Maximal index of neighbour, method inc() doesn't set neighb_idx_ on higher value.
302  */
303  DHNeighbSide(const DHCellAccessor &dh_cell, unsigned int neighb_idx, unsigned int max_idx)
304  : dh_cell_(dh_cell), neighb_idx_(neighb_idx), max_idx_(max_idx)
305  {
306  // Skip non-local cells
307  while ( (neighb_idx_<max_idx_) && not_local_cell() ) {
308  neighb_idx_++;
309  }
310  }
311 
312  /// Check validity of accessor (see default constructor of DHCellAccessor)
313  inline bool is_valid() const {
314  return dh_cell_.is_valid();
315  }
316 
317  /// Iterates to next neighbour side.
318  inline void inc() {
319  // Skip non-local cells
320  do {
321  neighb_idx_++;
322  if (neighb_idx_>=max_idx_) break; //stop condition at the end item of range
323  } while ( not_local_cell() );
324  }
325 
326  /// Comparison of accessors.
327  bool operator==(const DHNeighbSide& other) {
328  return (neighb_idx_ == other.neighb_idx_);
329  }
330 
331  /// This class is implicitly convertible to DHCellSide.
332  operator DHCellSide() const {
333  SideIter side = dh_cell_.elm()->neigh_vb[neighb_idx_]->side();
335  return DHCellSide(cell, side->side_idx());
336  }
337 
338 private:
339  /// Check if cell side of neighbour is not local (allow skip invalid accessors).
340  inline bool not_local_cell() {
341  return ( dh_cell_.dof_handler_->global_to_local_el_idx_.end() ==
342  dh_cell_.dof_handler_->global_to_local_el_idx_.find((LongIdx)dh_cell_.elm()->neigh_vb[neighb_idx_]->side()->elem_idx()) );
343  }
344 
345  /// Appropriate cell accessor.
347  /// Index into neigh_vb array
348  unsigned int neighb_idx_;
349  /// Maximal index into neigh_vb array
350  unsigned int max_idx_;
351 };
352 
353 
354 /*************************************************************************************
355  * Implementation of inlined methods.
356  */
357 
358 inline unsigned int DHCellAccessor::get_dof_indices(std::vector<int> &indices) const
359 {
361  unsigned int ndofs = 0;
363  for (unsigned int k=0; k<ndofs; k++)
365 
366  return ndofs;
367 }
368 
369 
371 {
372  unsigned int ndofs = 0;
374  for (unsigned int k=0; k<ndofs; k++)
375  indices[k] = dof_handler_->cell_starts[loc_ele_idx_]+k;
376 
377  return ndofs;
378 }
379 
380 
381 inline unsigned int DHCellAccessor::n_dofs() const
382 {
383  switch (this->dim()) {
384  case 1:
385  return fe<1>()->n_dofs();
386  break;
387  case 2:
388  return fe<2>()->n_dofs();
389  break;
390  case 3:
391  return fe<3>()->n_dofs();
392  break;
393  }
394  return 0; // only fix compiler warning
395 }
396 
397 
398 inline const Dof &DHCellAccessor::cell_dof(unsigned int idof) const
399 {
400  switch (this->dim())
401  {
402  case 1:
403  return fe<1>()->dof(idof);
404  break;
405  case 2:
406  return fe<2>()->dof(idof);
407  break;
408  case 3:
409  return fe<3>()->dof(idof);
410  break;
411  }
412 }
413 
414 
416  auto bgn_it = make_iter<DHCellSide>( DHCellSide(*this, 0) );
417  auto end_it = make_iter<DHCellSide>( DHCellSide(*this, dim()+1) );
418  return Range<DHCellSide>(bgn_it, end_it);
419 }
420 
421 
423  unsigned int upper_bound = this->elm()->n_neighs_vb();
424  auto bgn_it = make_iter<DHNeighbSide, DHCellSide>( DHNeighbSide(*this, 0, upper_bound) );
425  auto end_it = make_iter<DHNeighbSide, DHCellSide>( DHNeighbSide(*this, upper_bound, upper_bound) );
426  return RangeConvert<DHNeighbSide, DHCellSide>(bgn_it, end_it);
427 }
428 
429 
431  return RangeConvert<DHEdgeSide, DHCellSide>(make_iter<DHEdgeSide, DHCellSide>( DHEdgeSide( *this, 0) ),
432  make_iter<DHEdgeSide, DHCellSide>( DHEdgeSide( *this, n_edge_sides()) ));
433 }
434 
435 
436 inline unsigned int DHCellSide::n_edge_sides() const {
437  unsigned int edge_idx = dh_cell_accessor_.elm()->edge_idx(side_idx_);
438  Edge *edg = &dh_cell_accessor_.dof_handler_->mesh()->edges[edge_idx];
439  for (int sid=0; sid<edg->n_sides; sid++)
440  if ( dh_cell_accessor_.dof_handler_->el_is_local(edg->side(sid)->element().idx()) ) return edg->n_sides;
441  return 0;
442 }
443 
444 
445 
446 #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
unsigned int n_edge_sides() const
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
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