Flow123d  release_3.0.0-859-g84487d0
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  * Cell accessor allow iterate over DOF handler cells.
33  *
34  * Iterating is possible over different ranges of local and ghost elements.
35  */
37 public:
38  /**
39  * Default invalid accessor.
40  */
42  : dof_handler_(NULL)
43  {}
44 
45  /**
46  * DOF cell accessor.
47  */
48  DHCellAccessor(const DOFHandlerMultiDim *dof_handler, unsigned int loc_idx)
49  : dof_handler_(dof_handler), loc_ele_idx_(loc_idx)
50  {}
51 
52  /// Return local index to element (index of DOF handler).
53  inline unsigned int local_idx() const {
54  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");
55  return loc_ele_idx_;
56  }
57 
58  /// Return serial idx to element of loc_ele_idx_.
59  inline unsigned int elm_idx() const {
60  unsigned int ds_lsize = dof_handler_->el_ds_->lsize();
61  if (local_idx()<ds_lsize) return dof_handler_->mesh()->get_el_4_loc()[loc_ele_idx_]; //own elements
62  else return dof_handler_->ghost_4_loc[loc_ele_idx_-ds_lsize]; //ghost elements
63  }
64 
65  /// Return ElementAccessor to element of loc_ele_idx_.
66  inline const ElementAccessor<3> elm() const {
67  return dof_handler_->mesh()->element_accessor( elm_idx() );
68  }
69 
70  /**
71  * @brief Fill vector of the global indices of dofs associated to the cell.
72  *
73  * @param indices Vector of dof indices on the cell.
74  */
75  unsigned int get_dof_indices(std::vector<int> &indices) const;
76 
77  /**
78  * @brief Returns the indices of dofs associated to the cell on the local process.
79  *
80  * @param indices Array of dof indices on the cell.
81  */
82  unsigned int get_loc_dof_indices(std::vector<LongIdx> &indices) const;
83 
84  /// Return number of dofs on given cell.
85  unsigned int n_dofs() const;
86 
87  /**
88  * @brief Return dof on a given cell.
89  * @param idof Number of dof on the cell.
90  */
91  const Dof &cell_dof(unsigned int idof) const;
92 
93  /// Return dimension of element appropriate to cell.
94  inline unsigned int dim() const {
95  return elm().dim();
96  }
97 
98  /**
99  * @brief Returns finite element object for given space dimension.
100  */
101  template<unsigned int dim>
103  ElementAccessor<3> elm_acc = this->elm();
104  return dof_handler_->ds_->fe<dim>(elm_acc);
105  }
106 
107  /// Check validity of accessor (see default constructor)
108  inline bool is_valid() const {
109  return dof_handler_ != NULL;
110  }
111 
112  /// Returns range of cell sides
114 
115  /// Returns range of neighbour cells of higher dimension
117 
118  /// Iterates to next local element.
119  inline void inc() {
120  loc_ele_idx_++;
121  }
122 
123  /// Comparison of accessors.
124  bool operator==(const DHCellAccessor& other) {
125  return (loc_ele_idx_ == other.loc_ele_idx_);
126  }
127 
128 private:
129  /// Pointer to the DOF handler owning the element.
131  /// Index into DOFHandler::el_4_loc array.
132  unsigned int loc_ele_idx_;
133 
134  friend class DHCellSide;
135 };
136 
137 
138 /**
139  * Side accessor allows to iterate over sides of DOF handler cell.
140  *
141  * Descendants of class allow to iterate over different ranges trough methods:
142  * - edge_sides: iterate over all Cells (of same dim) connected to the side
143  * - neighb_sides: iterate over all sides of the cells of higher dimension
144  */
145 class DHCellSide {
146 public:
147 
148  /**
149  * Default invalid accessor.
150  *
151  * Create invalid \p dh_cell_accessor_.
152  */
154 
155  /**
156  * DOF cell side accessor.
157  */
158  DHCellSide(const DHCellAccessor &dh_cell_accessor, unsigned int side_idx)
159  : dh_cell_accessor_(dh_cell_accessor), side_idx_(side_idx) {}
160 
161  /// Check validity of accessor (see default constructor)
162  inline virtual bool is_valid() const {
163  return dh_cell_accessor_.is_valid();
164  }
165 
166  /// Return Side of given cell and side_idx.
167  inline virtual const Side * side() const {
168  ASSERT( this->is_valid() );
169  return new Side( const_cast<const Mesh*>(dh_cell_accessor_.dof_handler_->mesh()), dh_cell_accessor_.elm_idx(), side_idx_ );
170  }
171 
172  /// Return DHCellAccessor appropriate to the side.
173  inline const DHCellAccessor cell() const {
174  auto cell = dh_cell_accessor_.dof_handler_->cell_accessor_from_element( this->side()->elem_idx() );
175  unsigned int loc_idx = cell.local_idx();
176  return DHCellAccessor(dh_cell_accessor_.dof_handler_, loc_idx);
177  }
178 
179  /// Return dimension of element appropriate to the side.
180  inline unsigned int dim() const {
181  return cell().dim();
182  }
183 
184  /// Returns range of all sides looped over common Edge.
185  Range<DHEdgeSide> edge_sides() const;
186 
187  /// Iterates to next local element.
188  inline virtual void inc() {
189  side_idx_++;
190  }
191 
192  /// Comparison of accessors.
193  bool operator==(const DHCellSide& other) {
194  return (side_idx_ == other.side_idx_);
195  }
196 
197 private:
198  /// Appropriate DHCellAccessor.
200  /// Index of side.
201  unsigned int side_idx_;
202 };
203 
204 
205 /**
206  * Class allows to iterate over sides of edge.
207  *
208  * Iterator provides same behavior as parent class through side() method.
209  */
210 class DHEdgeSide {
211 public:
212  /**
213  * Default invalid accessor.
214  */
216 
217  /**
218  * Valid accessor allows iterate over sides.
219  */
220  DHEdgeSide(const DHCellSide &cell_side, unsigned int side_idx)
221  : cell_side_(cell_side), side_idx_(side_idx)
222  {}
223 
224  /// Check validity of accessor (see default constructor)
225  inline bool is_valid() const {
226  return cell_side_.is_valid();
227  }
228 
229  /// Return DHCellSide according to this object.
230  inline DHCellSide cell_side() const {
231  return cell_side_;
232  }
233 
234  /// Iterates to next edge side.
235  inline void inc() {
236  side_idx_++;
237  }
238 
239  /// Comparison of accessors.
240  bool operator==(const DHEdgeSide& other) {
241  return (side_idx_ == other.side_idx_);
242  }
243 
244  inline unsigned int side_idx() { return side_idx_; }
245 
246 private:
247  /// Appropriate side accessor.
249  /// Pointer to the DOF handler owning the element.
250  unsigned int edge_idx_;
251  /// Index of side owned by Edge.
252  unsigned int side_idx_;
253 };
254 
255 
256 /**
257  * Class allows to iterate over sides of neighbour.
258  *
259  * Iterator provides same behavior as parent class through side() method.
260  */
262 public:
263  /**
264  * Default invalid accessor.
265  */
267 
268  /**
269  * Valid accessor allows iterate over neighbor sides.
270  */
271  DHNeighbSide(const DHCellAccessor &dh_cell, unsigned int neighb_idx)
272  : dh_cell_(dh_cell), neighb_idx_(neighb_idx)
273  {}
274 
275  /// Check validity of accessor (see default constructor)
276  inline bool is_valid() const {
277  return dh_cell_.is_valid();
278  }
279 
280  /// Return DHCellSide according to this object.
281  inline DHCellSide cell_side() const {
282  ASSERT( this->is_valid() );
283  unsigned int side_idx = dh_cell_.elm()->neigh_vb[neighb_idx_]->side()->side_idx();
284  return DHCellSide(dh_cell_, side_idx);
285  }
286 
287  /// Iterates to next edge side.
288  inline void inc() {
289  neighb_idx_++;
290  }
291 
292  /// Comparison of accessors.
293  bool operator==(const DHNeighbSide& other) {
294  return (neighb_idx_ == other.neighb_idx_);
295  }
296 
297 private:
298  /// Appropriate cell accessor.
300  /// Index into neigh_vb array
301  unsigned int neighb_idx_;
302 };
303 
304 
305 /*************************************************************************************
306  * Implementation of inlined methods.
307  */
308 
309 inline unsigned int DHCellAccessor::get_dof_indices(std::vector<int> &indices) const
310 {
312  unsigned int ndofs = 0;
314  for (unsigned int k=0; k<ndofs; k++)
316 
317  return ndofs;
318 }
319 
320 
322 {
323  unsigned int ndofs = 0;
325  for (unsigned int k=0; k<ndofs; k++)
326  indices[k] = dof_handler_->cell_starts[loc_ele_idx_]+k;
327 
328  return ndofs;
329 }
330 
331 
332 inline unsigned int DHCellAccessor::n_dofs() const
333 {
334  switch (this->dim()) {
335  case 1:
336  return fe<1>()->n_dofs();
337  break;
338  case 2:
339  return fe<2>()->n_dofs();
340  break;
341  case 3:
342  return fe<3>()->n_dofs();
343  break;
344  }
345  return 0; // only fix compiler warning
346 }
347 
348 
349 inline const Dof &DHCellAccessor::cell_dof(unsigned int idof) const
350 {
351  switch (this->dim())
352  {
353  case 1:
354  return fe<1>()->dof(idof);
355  break;
356  case 2:
357  return fe<2>()->dof(idof);
358  break;
359  case 3:
360  return fe<3>()->dof(idof);
361  break;
362  }
363 }
364 
365 
367  auto bgn_it = make_iter<DHCellSide>( DHCellSide(*this, 0) );
368  auto end_it = make_iter<DHCellSide>( DHCellSide(*this, dim()+1) );
369  return Range<DHCellSide>(bgn_it, end_it);
370 }
371 
372 
374  auto bgn_it = make_iter<DHNeighbSide>( DHNeighbSide(*this, 0) );
375  auto end_it = make_iter<DHNeighbSide>( DHNeighbSide(*this, this->elm()->n_neighs_vb()) );
376  return Range<DHNeighbSide>(bgn_it, end_it);
377 }
378 
379 
381  unsigned int edge_idx = dh_cell_accessor_.elm()->edge_idx(side_idx_);
382  return Range<DHEdgeSide>(make_iter<DHEdgeSide>( DHEdgeSide( *this, 0) ),
383  make_iter<DHEdgeSide>( DHEdgeSide( *this, dh_cell_accessor_.dof_handler_->mesh()->edges[edge_idx].n_sides) ));
384 }
385 
386 
387 #endif /* DH_CELL_ACCESSOR_HH_ */
Definition: sides.h:39
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...
DHCellSide cell_side() const
Return DHCellSide according to this object.
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:599
Range< DHEdgeSide > edge_sides() const
Returns range of all sides looped over common Edge.
DHCellSide cell_side() const
Return DHCellSide according to this object.
void inc()
Iterates to next local element.
unsigned int dim() const
Return dimension of element appropriate to the side.
Range< DHNeighbSide > neighb_sides() const
Returns range of neighbour cells of higher dimension.
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.
Range helper class.
Definition: mesh.h:52
Distribution * el_ds_
Distribution of elements.
Definition: dofhandler.hh:404
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.
bool is_valid() const
Check validity of accessor (see default constructor)
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 n_dofs() const
Return number of dofs on given cell.
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.
DHCellSide cell_side_
Appropriate side accessor.
bool is_valid() const
Check validity of accessor (see default constructor)
std::vector< LongIdx > cell_starts
Starting indices for element dofs.
Definition: dofhandler.hh:380
const ElementAccessor< 3 > elm() const
Return ElementAccessor to element of loc_ele_idx_.
unsigned int neighb_idx_
Index into neigh_vb array.
void inc()
Iterates to next edge side.
std::vector< LongIdx > dof_indices
Dof numbers on local and ghost elements.
Definition: dofhandler.hh:388
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:413
friend class DHCellSide
unsigned int edge_idx_
Pointer to the DOF handler owning the element.
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.
#define ASSERT_LT(a, b)
Definition of comparative assert macro (Less Than)
Definition: asserts.hh:295
virtual void inc()
Iterates to next local element.
DHNeighbSide(const DHCellAccessor &dh_cell, unsigned int neighb_idx)
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:354
unsigned int side_idx_
Index of side.
virtual const Side * side() const
Return Side of given cell and side_idx.
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
bool operator==(const DHEdgeSide &other)
Comparison of accessors.
bool operator==(const DHCellAccessor &other)
Comparison of 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.
unsigned int side_idx()
LongIdx * get_el_4_loc() const
Definition: mesh.h:174
unsigned int loc_ele_idx_
Index into DOFHandler::el_4_loc array.
#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