Flow123d  DF_patch_fevalues-8016b85
generic_assembly.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 generic_assembly.hh
15  * @brief
16  */
17 
18 #ifndef GENERIC_ASSEMBLY_HH_
19 #define GENERIC_ASSEMBLY_HH_
20 
22 #include "fields/eval_subset.hh"
23 #include "fields/eval_points.hh"
25 #include "fem/fe_values.hh"
26 #include "tools/revertable_list.hh"
27 #include "system/sys_profiler.hh"
28 
29 
30 
31 /// Allow set mask of active integrals.
33  no_intg = 0,
34  bulk = 0x0001,
35  edge = 0x0002,
36  coupling = 0x0004,
37  boundary = 0x0008
38 };
39 
40 
41 /// Set of all used integral necessary in assemblation
43  std::array<std::shared_ptr<BulkIntegral>, 3> bulk_; ///< Bulk integrals of elements of dimensions 1, 2, 3
44  std::array<std::shared_ptr<EdgeIntegral>, 3> edge_; ///< Edge integrals between elements of dimensions 1, 2, 3
45  std::array<std::shared_ptr<CouplingIntegral>, 2> coupling_; ///< Coupling integrals between elements of dimensions 1-2, 2-3
46  std::array<std::shared_ptr<BoundaryIntegral>, 3> boundary_; ///< Boundary integrals betwwen elements of dimensions 1, 2, 3 and boundaries
47 };
48 
49 
50 /**
51  * Common interface class for all Assembly classes.
52  */
54 {
55 public:
56  /**
57  * Helper structzre holds data of cell (bulk) integral
58  *
59  * Data is specified by cell and subset index in EvalPoint object
60  */
62  /// Default constructor
64 
65  /// Constructor with data mebers initialization
66  BulkIntegralData(DHCellAccessor dhcell, unsigned int subset_idx)
67  : cell(dhcell), subset_index(subset_idx) {}
68 
69  /// Copy constructor
71  : cell(other.cell), subset_index(other.subset_index) {}
72 
73  DHCellAccessor cell; ///< Specified cell (element)
74  unsigned int subset_index; ///< Index (order) of subset in EvalPoints object
75  };
76 
77  /**
78  * Helper structzre holds data of edge integral
79  *
80  * Data is specified by side and subset index in EvalPoint object
81  */
83  /// Default constructor
86 
87  /// Copy constructor
90 
91  /// Constructor with data mebers initialization
93  : edge_side_range(range), subset_index(subset_idx) {}
94 
95  RangeConvert<DHEdgeSide, DHCellSide> edge_side_range; ///< Specified cell side (element)
96  unsigned int subset_index; ///< Index (order) of subset in EvalPoints object
97  };
98 
99  /**
100  * Helper structzre holds data of neighbour (coupling) integral
101  *
102  * Data is specified by cell, side and their subset indices in EvalPoint object
103  */
105  /// Default constructor
107 
108  /// Constructor with data mebers initialization
109  CouplingIntegralData(DHCellAccessor dhcell, unsigned int bulk_idx, DHCellSide dhside, unsigned int side_idx)
110  : cell(dhcell), bulk_subset_index(bulk_idx), side(dhside), side_subset_index(side_idx) {}
111 
112  /// Copy constructor
115 
117  unsigned int bulk_subset_index; ///< Index (order) of lower dim subset in EvalPoints object
118  DHCellSide side; ///< Specified cell side (higher dim element)
119  unsigned int side_subset_index; ///< Index (order) of higher dim subset in EvalPoints object
120  };
121 
122  /**
123  * Helper structzre holds data of boundary integral
124  *
125  * Data is specified by side and subset indices of side and appropriate boundary element in EvalPoint object
126  */
128  /// Default constructor
130 
131  /// Constructor with data mebers initialization
132  BoundaryIntegralData(unsigned int bdr_idx, DHCellSide dhside, unsigned int side_idx)
133  : bdr_subset_index(bdr_idx), side(dhside), side_subset_index(side_idx) {}
134 
135  /// Copy constructor
138 
139  // We don't need hold ElementAccessor of boundary element, side.cond().element_accessor() provides it.
140  unsigned int bdr_subset_index; ///< Index (order) of subset on boundary element in EvalPoints object
141  DHCellSide side; ///< Specified cell side (bulk element)
142  unsigned int side_subset_index; ///< Index (order) of subset on side of bulk element in EvalPoints object
143  };
144 
147  virtual void assemble(std::shared_ptr<DOFHandlerMultiDim> dh) = 0;
148 
149  /// Getter to EvalPoints object
150  inline std::shared_ptr<EvalPoints> eval_points() const {
151  return eval_points_;
152  }
153 
154 protected:
155  AssemblyIntegrals integrals_; ///< Holds integral objects.
156  std::shared_ptr<EvalPoints> eval_points_; ///< EvalPoints object shared by all integrals
157  ElementCacheMap element_cache_map_; ///< ElementCacheMap according to EvalPoints
158 };
159 
160 
161 /**
162  * @brief Generic class of assemblation.
163  *
164  * Class
165  * - holds assemblation structures (EvalPoints, Integral objects, Integral data table).
166  * - associates assemblation objects specified by dimension
167  * - provides general assemble method
168  * - provides methods that allow construction of element patches
169  */
170 template < template<IntDim...> class DimAssembly>
172 {
173 public:
174  /// Constructor
175  GenericAssembly( typename DimAssembly<1>::EqFields *eq_fields, typename DimAssembly<1>::EqData *eq_data)
176  : multidim_assembly_(eq_fields, eq_data),
177  min_edge_sides_(2),
178  bulk_integral_data_(20, 10),
179  edge_integral_data_(12, 6),
182  {
183  eval_points_ = std::make_shared<EvalPoints>();
184  // first step - create integrals, then - initialize cache and initialize subobject of dimensions
185  multidim_assembly_[1_d]->create_integrals(eval_points_, integrals_);
186  multidim_assembly_[2_d]->create_integrals(eval_points_, integrals_);
187  multidim_assembly_[3_d]->create_integrals(eval_points_, integrals_);
189  multidim_assembly_[1_d]->initialize(&element_cache_map_);
190  multidim_assembly_[2_d]->initialize(&element_cache_map_);
191  multidim_assembly_[3_d]->initialize(&element_cache_map_);
192  active_integrals_ = multidim_assembly_[1_d]->n_active_integrals();
193  }
194 
195  /// Getter to set of assembly objects
197  return multidim_assembly_;
198  }
199 
200  void set_min_edge_sides(unsigned int val) {
201  min_edge_sides_ = val;
202  }
203 
204  /**
205  * @brief General assemble methods.
206  *
207  * Loops through local cells and calls assemble methods of assembly
208  * object of each cells over space dimension.
209  *
210  * TODO:
211  * - make estimate of the cache fill for combination of (integral_type x element dimension)
212  * - add next cell to patch if current_patch_size + next_element_size <= fixed_cache_size
213  * - avoid reverting the integral data lists.
214  */
215  void assemble(std::shared_ptr<DOFHandlerMultiDim> dh) override {
216  START_TIMER( DimAssembly<1>::name() );
217  this->reallocate_cache();
218  multidim_assembly_[1_d]->begin();
219 
220  bool add_into_patch = false; // control variable
221  for(auto cell_it = dh->local_range().begin(); cell_it != dh->local_range().end(); )
222  {
223 
224  if (!add_into_patch) {
226  add_into_patch = true;
227  }
228 
229  START_TIMER("add_integrals_to_patch");
230  this->add_integrals_of_computing_step(*cell_it);
231  END_TIMER("add_integrals_to_patch");
232 
239  this->assemble_integrals(dh);
240  add_into_patch = false;
241  } else {
248  this->assemble_integrals(dh);
249  add_into_patch = false;
250  }
251  ++cell_it;
252  }
253  }
254  if (add_into_patch) {
255  this->assemble_integrals(dh);
256  }
257 
258  multidim_assembly_[1_d]->end();
259  END_TIMER( DimAssembly<1>::name() );
260  }
261 
262  /// Return ElementCacheMap
263  inline const ElementCacheMap &cache_map() const {
264  return element_cache_map_;
265  }
266 
267 private:
268  /// Call assemblations when patch is filled
269  void assemble_integrals(std::shared_ptr<DOFHandlerMultiDim> dh) {
270  START_TIMER("create_patch");
272  END_TIMER("create_patch");
273  START_TIMER("patch_reinit");
274  patch_reinit(dh);
275  END_TIMER("patch_reinit");
276  START_TIMER("cache_update");
277  multidim_assembly_[1_d]->eq_fields_->cache_update(element_cache_map_); // TODO replace with sub FieldSet
278  END_TIMER("cache_update");
280 
281  {
282  START_TIMER("assemble_volume_integrals");
283  multidim_assembly_[1_d]->assemble_cell_integrals(bulk_integral_data_);
284  multidim_assembly_[2_d]->assemble_cell_integrals(bulk_integral_data_);
285  multidim_assembly_[3_d]->assemble_cell_integrals(bulk_integral_data_);
286  END_TIMER("assemble_volume_integrals");
287  }
288 
289  {
290  START_TIMER("assemble_fluxes_boundary");
291  multidim_assembly_[1_d]->assemble_boundary_side_integrals(boundary_integral_data_);
292  multidim_assembly_[2_d]->assemble_boundary_side_integrals(boundary_integral_data_);
293  multidim_assembly_[3_d]->assemble_boundary_side_integrals(boundary_integral_data_);
294  END_TIMER("assemble_fluxes_boundary");
295  }
296 
297  {
298  START_TIMER("assemble_fluxes_elem_elem");
299  multidim_assembly_[1_d]->assemble_edge_integrals(edge_integral_data_);
300  multidim_assembly_[2_d]->assemble_edge_integrals(edge_integral_data_);
301  multidim_assembly_[3_d]->assemble_edge_integrals(edge_integral_data_);
302  END_TIMER("assemble_fluxes_elem_elem");
303  }
304 
305  {
306  START_TIMER("assemble_fluxes_elem_side");
307  multidim_assembly_[2_d]->assemble_neighbour_integrals(coupling_integral_data_);
308  multidim_assembly_[3_d]->assemble_neighbour_integrals(coupling_integral_data_);
309  END_TIMER("assemble_fluxes_elem_side");
310  }
311  // clean integral data
317  }
318 
319  void patch_reinit(std::shared_ptr<DOFHandlerMultiDim> dh) {
321  std::array<PatchElementsList, 3> patch_elements;
322 
323  for (unsigned int i=0; i<elm_idx_vec.size(); ++i) {
324  // Skip invalid element indices.
325  if ( elm_idx_vec[i] == std::numeric_limits<unsigned int>::max() ) continue;
326 
327  ElementAccessor<3> elm(dh->mesh(), elm_idx_vec[i]);
328  patch_elements[elm.dim()-1].push_back(std::make_pair(elm, i));
329  }
330  multidim_assembly_[1_d]->patch_reinit(patch_elements[0]);
331  multidim_assembly_[2_d]->patch_reinit(patch_elements[1]);
332  multidim_assembly_[3_d]->patch_reinit(patch_elements[2]);
333  }
334 
335  /**
336  * Add data of integrals to appropriate structure and register elements to ElementCacheMap.
337  *
338  * Types of used integrals must be set in data member \p active_integrals_.
339  */
342  if (cell.is_own()) { // Not ghost
343  this->add_volume_integral(cell);
344  }
345 
346  for( DHCellSide cell_side : cell.side_range() ) {
348  if (cell.is_own()) // Not ghost
349  if ( (cell_side.side().edge().n_sides() == 1) && (cell_side.side().is_boundary()) ) {
350  this->add_boundary_integral(cell_side);
351  continue;
352  }
354  if ( (cell_side.n_edge_sides() >= min_edge_sides_) && (cell_side.edge_sides().begin()->element().idx() == cell.elm_idx())) {
355  this->add_edge_integral(cell_side);
356  }
357  }
358 
360  bool add_low = true;
361  for( DHCellSide neighb_side : cell.neighb_sides() ) { // cell -> elm lower dim, neighb_side -> elm higher dim
362  if (cell.dim() != neighb_side.dim()-1) continue;
363  this->add_coupling_integral(cell, neighb_side, add_low);
364  add_low = false;
365  }
366  }
367  }
368 
369  /// Add data of volume integral to appropriate data structure.
370  inline void add_volume_integral(const DHCellAccessor &cell) {
371  uint subset_idx = integrals_.bulk_[cell.dim()-1]->get_subset_idx();
372  bulk_integral_data_.emplace_back(cell, subset_idx);
373 
374  unsigned int reg_idx = cell.elm().region_idx().idx();
375  // Different access than in other integrals: We can't use range method CellIntegral::points
376  // because it passes element_patch_idx as argument that is not known during patch construction.
377  for (uint i=uint( eval_points_->subset_begin(cell.dim(), subset_idx) );
378  i<uint( eval_points_->subset_end(cell.dim(), subset_idx) ); ++i) {
379  element_cache_map_.add_eval_point(reg_idx, cell.elm_idx(), i, cell.local_idx());
380  }
381  }
382 
383  /// Add data of edge integral to appropriate data structure.
384  inline void add_edge_integral(const DHCellSide &cell_side) {
385  auto range = cell_side.edge_sides();
386  edge_integral_data_.emplace_back(range, integrals_.edge_[range.begin()->dim()-1]->get_subset_idx());
387 
388  for( DHCellSide edge_side : range ) {
389  unsigned int reg_idx = edge_side.element().region_idx().idx();
390  for (auto p : integrals_.edge_[range.begin()->dim()-1]->points(edge_side, &element_cache_map_) ) {
391  element_cache_map_.add_eval_point(reg_idx, edge_side.elem_idx(), p.eval_point_idx(), edge_side.cell().local_idx());
392  }
393  }
394  }
395 
396  /// Add data of coupling integral to appropriate data structure.
397  inline void add_coupling_integral(const DHCellAccessor &cell, const DHCellSide &ngh_side, bool add_low) {
398  coupling_integral_data_.emplace_back(cell, integrals_.coupling_[cell.dim()-1]->get_subset_low_idx(), ngh_side,
399  integrals_.coupling_[cell.dim()-1]->get_subset_high_idx());
400 
401  unsigned int reg_idx_low = cell.elm().region_idx().idx();
402  unsigned int reg_idx_high = ngh_side.element().region_idx().idx();
403  for (auto p : integrals_.coupling_[cell.dim()-1]->points(ngh_side, &element_cache_map_) ) {
404  element_cache_map_.add_eval_point(reg_idx_high, ngh_side.elem_idx(), p.eval_point_idx(), ngh_side.cell().local_idx());
405 
406  if (add_low) {
407  auto p_low = p.lower_dim(cell); // equivalent point on low dim cell
408  element_cache_map_.add_eval_point(reg_idx_low, cell.elm_idx(), p_low.eval_point_idx(), cell.local_idx());
409  }
410  }
411  }
412 
413  /// Add data of boundary integral to appropriate data structure.
414  inline void add_boundary_integral(const DHCellSide &bdr_side) {
415  boundary_integral_data_.emplace_back(integrals_.boundary_[bdr_side.dim()-1]->get_subset_low_idx(), bdr_side,
416  integrals_.boundary_[bdr_side.dim()-1]->get_subset_high_idx());
417 
418  unsigned int reg_idx = bdr_side.element().region_idx().idx();
419  for (auto p : integrals_.boundary_[bdr_side.dim()-1]->points(bdr_side, &element_cache_map_) ) {
420  element_cache_map_.add_eval_point(reg_idx, bdr_side.elem_idx(), p.eval_point_idx(), bdr_side.cell().local_idx());
421 
422  BulkPoint p_bdr = p.point_bdr(bdr_side.cond().element_accessor()); // equivalent point on boundary element
423  unsigned int bdr_reg = bdr_side.cond().element_accessor().region_idx().idx();
424  // invalid local_idx value, DHCellAccessor of boundary element doesn't exist
425  element_cache_map_.add_eval_point(bdr_reg, bdr_side.cond().bc_ele_idx(), p_bdr.eval_point_idx(), -1);
426  }
427  }
428 
429  /// Calls cache_reallocate method on
430  inline void reallocate_cache() {
431  multidim_assembly_[1_d]->eq_fields_->cache_reallocate(this->element_cache_map_, multidim_assembly_[1_d]->used_fields_);
432  // DebugOut() << "Order of evaluated fields (" << DimAssembly<1>::name() << "):" << multidim_assembly_[1_d]->eq_fields_->print_dependency();
433  }
434 
435 
436  /// Assembly object
438 
439  /// Holds mask of active integrals.
441 
442  /**
443  * Minimal number of sides on edge.
444  *
445  * Edge integral is created and calculated if number of sides is greater or equal than this value. Default value
446  * is 2 and can be changed
447  */
448  unsigned int min_edge_sides_;
449 
450  // Following variables hold data of all integrals depending of actual computed element.
451  // TODO sizes of arrays should be set dynamically, depend on number of elements in ElementCacheMap,
452  RevertableList<BulkIntegralData> bulk_integral_data_; ///< Holds data for computing bulk integrals.
453  RevertableList<EdgeIntegralData> edge_integral_data_; ///< Holds data for computing edge integrals.
454  RevertableList<CouplingIntegralData> coupling_integral_data_; ///< Holds data for computing couplings integrals.
455  RevertableList<BoundaryIntegralData> boundary_integral_data_; ///< Holds data for computing boundary integrals.
456 };
457 
458 
459 #endif /* GENERIC_ASSEMBLY_HH_ */
uint bc_ele_idx()
Definition: accessors.hh:374
ElementAccessor< 3 > element_accessor()
Base point accessor class.
Definition: eval_subset.hh:55
unsigned int eval_point_idx() const
Return index in EvalPoints object.
Definition: eval_subset.hh:84
static unsigned int get()
Return number of stored elements.
Cell accessor allow iterate over DOF handler cells.
const ElementAccessor< 3 > elm() const
Return ElementAccessor to element of loc_ele_idx_.
RangeConvert< DHNeighbSide, DHCellSide > neighb_sides() const
Returns range of neighbour cell of lower dimension corresponding to cell of higher dimension.
bool is_own() const
Return true if accessor represents own element (false for ghost element)
unsigned int dim() const
Return dimension of element appropriate to cell.
Range< DHCellSide > side_range() const
Returns range of cell sides.
unsigned int elm_idx() const
Return serial idx to element of loc_ele_idx_.
unsigned int local_idx() const
Return local index to element (index of DOF handler).
Side accessor allows to iterate over sides of DOF handler cell.
unsigned int elem_idx() const
Boundary cond() const
const DHCellAccessor & cell() const
Return DHCellAccessor appropriate to the side.
RangeConvert< DHEdgeSide, DHCellSide > edge_sides() const
Returns range of all sides looped over common Edge.
unsigned int dim() const
Return dimension of element appropriate to the side.
ElementAccessor< 3 > element() const
Class allows to iterate over sides of edge.
unsigned int dim() const
Definition: accessors.hh:188
RegionIdx region_idx() const
Definition: accessors.hh:201
Directing class of FieldValueCache.
unsigned int get_simd_rounded_size()
Returns number of eval. points with addition of max simd duplicates due to regions.
void start_elements_update()
Start update of cache.
void finish_elements_update()
Finish update after reading data to cache.
void clear_element_eval_points_map()
Reset all items of elements_eval_points_map.
void create_patch()
Create patch of cached elements before reading data to cache.
RevertableList< EvalPointData > eval_point_data_
void add_eval_point(unsigned int i_reg, unsigned int i_ele, unsigned int i_eval_point, unsigned int dh_loc_idx)
void init(std::shared_ptr< EvalPoints > eval_points)
Init cache.
const std::vector< unsigned int > & elm_idx_vec(bool bdr=false) const
Return vector of bulk/boundary element idx.
ElementCacheMap element_cache_map_
ElementCacheMap according to EvalPoints.
std::shared_ptr< EvalPoints > eval_points_
EvalPoints object shared by all integrals.
std::shared_ptr< EvalPoints > eval_points() const
Getter to EvalPoints object.
AssemblyIntegrals integrals_
Holds integral objects.
virtual void assemble(std::shared_ptr< DOFHandlerMultiDim > dh)=0
Generic class of assemblation.
MixedPtr< DimAssembly, 1 > multidim_assembly_
Assembly object.
RevertableList< EdgeIntegralData > edge_integral_data_
Holds data for computing edge integrals.
void assemble(std::shared_ptr< DOFHandlerMultiDim > dh) override
General assemble methods.
unsigned int min_edge_sides_
void add_boundary_integral(const DHCellSide &bdr_side)
Add data of boundary integral to appropriate data structure.
const ElementCacheMap & cache_map() const
Return ElementCacheMap.
void add_volume_integral(const DHCellAccessor &cell)
Add data of volume integral to appropriate data structure.
void add_edge_integral(const DHCellSide &cell_side)
Add data of edge integral to appropriate data structure.
RevertableList< BoundaryIntegralData > boundary_integral_data_
Holds data for computing boundary integrals.
int active_integrals_
Holds mask of active integrals.
RevertableList< CouplingIntegralData > coupling_integral_data_
Holds data for computing couplings integrals.
void set_min_edge_sides(unsigned int val)
void patch_reinit(std::shared_ptr< DOFHandlerMultiDim > dh)
void assemble_integrals(std::shared_ptr< DOFHandlerMultiDim > dh)
Call assemblations when patch is filled.
void reallocate_cache()
Calls cache_reallocate method on.
GenericAssembly(typename DimAssembly< 1 >::EqFields *eq_fields, typename DimAssembly< 1 >::EqData *eq_data)
Constructor.
void add_coupling_integral(const DHCellAccessor &cell, const DHCellSide &ngh_side, bool add_low)
Add data of coupling integral to appropriate data structure.
void add_integrals_of_computing_step(DHCellAccessor cell)
MixedPtr< DimAssembly, 1 > multidim_assembly() const
Getter to set of assembly objects.
RevertableList< BulkIntegralData > bulk_integral_data_
Holds data for computing bulk integrals.
unsigned int idx() const
Returns a global index of the region.
Definition: region.hh:81
Class FEValues calculates finite element data on the actual cells such as shape function values,...
Iter< Object > make_iter(Object obj)
ActiveIntegrals
Allow set mask of active integrals.
@ coupling
@ boundary
@ no_intg
@ bulk
@ edge
unsigned int uint
unsigned int IntDim
A dimension index type.
Definition: mixed.hh:19
Definitions of particular quadrature rules on simplices.
Set of all used integral necessary in assemblation.
std::array< std::shared_ptr< BulkIntegral >, 3 > bulk_
Bulk integrals of elements of dimensions 1, 2, 3.
std::array< std::shared_ptr< CouplingIntegral >, 2 > coupling_
Coupling integrals between elements of dimensions 1-2, 2-3.
std::array< std::shared_ptr< BoundaryIntegral >, 3 > boundary_
Boundary integrals betwwen elements of dimensions 1, 2, 3 and boundaries.
std::array< std::shared_ptr< EdgeIntegral >, 3 > edge_
Edge integrals between elements of dimensions 1, 2, 3.
unsigned int side_subset_index
Index (order) of subset on side of bulk element in EvalPoints object.
BoundaryIntegralData(unsigned int bdr_idx, DHCellSide dhside, unsigned int side_idx)
Constructor with data mebers initialization.
BoundaryIntegralData(const BoundaryIntegralData &other)
Copy constructor.
unsigned int bdr_subset_index
Index (order) of subset on boundary element in EvalPoints object.
DHCellSide side
Specified cell side (bulk element)
BulkIntegralData(DHCellAccessor dhcell, unsigned int subset_idx)
Constructor with data mebers initialization.
DHCellAccessor cell
Specified cell (element)
unsigned int subset_index
Index (order) of subset in EvalPoints object.
BulkIntegralData(const BulkIntegralData &other)
Copy constructor.
unsigned int bulk_subset_index
Index (order) of lower dim subset in EvalPoints object.
CouplingIntegralData(DHCellAccessor dhcell, unsigned int bulk_idx, DHCellSide dhside, unsigned int side_idx)
Constructor with data mebers initialization.
unsigned int side_subset_index
Index (order) of higher dim subset in EvalPoints object.
CouplingIntegralData(const CouplingIntegralData &other)
Copy constructor.
DHCellSide side
Specified cell side (higher dim element)
EdgeIntegralData(const EdgeIntegralData &other)
Copy constructor.
RangeConvert< DHEdgeSide, DHCellSide > edge_side_range
Specified cell side (element)
unsigned int subset_index
Index (order) of subset in EvalPoints object.
EdgeIntegralData(RangeConvert< DHEdgeSide, DHCellSide > range, unsigned int subset_idx)
Constructor with data mebers initialization.
std::size_t revert_temporary()
Erase temporary part of data.
std::size_t make_permanent()
Finalize temporary part of data.
void reset()
Clear the list.
std::size_t emplace_back(Args &&... args)
#define END_TIMER(tag)
Ends a timer with specified tag.
#define START_TIMER(tag)
Starts a timer with specified tag.