Flow123d  DF_patch_fevalues-e45dfbd
assembly_base.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 assembly_base.hh
15  * @brief
16  */
17 
18 #ifndef ASSEMBLY_BASE_HH_
19 #define ASSEMBLY_BASE_HH_
20 
21 
24 #include "fields/eval_points.hh"
26 #include "fem/update_flags.hh"
27 
28 
29 
30 /**
31  * Base class define empty methods, these methods can be overwite in descendants.
32  */
33 template <unsigned int dim>
35 {
36 public:
41 
42  /// Constructor
43  AssemblyBase(unsigned int quad_order) {
44  quad_ = new QGauss(dim, 2*quad_order);
45  quad_low_ = new QGauss(dim-1, 2*quad_order);
46  }
47 
48  /// Destructor
49  virtual ~AssemblyBase() {
50  delete quad_;
51  delete quad_low_;
52  }
53 
54  /// Assembles the volume integrals on cell.
55  virtual inline void cell_integral(FMT_UNUSED DHCellAccessor cell, FMT_UNUSED unsigned int element_patch_idx) {}
56 
57  /// Assembles the fluxes on the boundary.
58  virtual inline void boundary_side_integral(FMT_UNUSED DHCellSide cell_side) {}
59 
60  /// Assembles the fluxes between sides on the edge.
61  virtual inline void edge_integral(FMT_UNUSED RangeConvert<DHEdgeSide, DHCellSide> edge_side_range) {}
62 
63  /// Assembles the fluxes between elements of different dimensions.
64  virtual inline void dimjoin_intergral(FMT_UNUSED DHCellAccessor cell_lower_dim, FMT_UNUSED DHCellSide neighb_side) {}
65 
66  /// Method prepares object before assemblation (e.g. balance, ...).
67  virtual void begin() {}
68 
69  /// Method finishes object after assemblation (e.g. balance, ...).
70  virtual void end() {}
71 
72  /// Method prepares object before computing on patch (typically reinitialize PatchFEValues objects).
73  virtual void patch_reinit(FMT_UNUSED PatchElementsList patch_elements) {}
74 
75  /// Getter of active_integrals.
76  inline int n_active_integrals() const {
77  return active_integrals_;
78  }
79 
80  /// Create integrals according to dim of assembly object
81  void create_integrals(std::shared_ptr<EvalPoints> eval_points, AssemblyIntegrals &integrals) {
83  ASSERT_PERMANENT_PTR(quad_).error("Data member 'quad_' must be initialized if you use bulk integral!\n");
84  integrals_.bulk_ = eval_points->add_bulk<dim>(*quad_);
85  integrals.bulk_[dim-1] = integrals_.bulk_;
86  }
88  ASSERT_PERMANENT_PTR(quad_low_).error("Data member 'quad_low_' must be initialized if you use edge integral!\n");
89  integrals_.edge_ = eval_points->add_edge<dim>(*quad_low_);
90  integrals.edge_[dim-1] = integrals_.edge_;
91  }
92  if ((dim>1) && (active_integrals_ & ActiveIntegrals::coupling)) {
93  ASSERT_PERMANENT_PTR(quad_).error("Data member 'quad_' must be initialized if you use coupling integral!\n");
94  ASSERT_PERMANENT_PTR(quad_low_).error("Data member 'quad_low_' must be initialized if you use coupling integral!\n");
95  integrals_.coupling_ = eval_points->add_coupling<dim>(*quad_low_);
96  integrals.coupling_[dim-2] = integrals_.coupling_;
97  }
99  ASSERT_PERMANENT_PTR(quad_).error("Data member 'quad_' must be initialized if you use boundary integral!\n");
100  ASSERT_PERMANENT_PTR(quad_low_).error("Data member 'quad_low_' must be initialized if you use boundary integral!\n");
101  integrals_.boundary_ = eval_points->add_boundary<dim>(*quad_low_);
102  integrals.boundary_[dim-1] = integrals_.boundary_;
103  }
104  }
105 
106  /// Return BulkPoint range of appropriate dimension
107  inline Range< BulkPoint > bulk_points(unsigned int element_patch_idx) const {
108  return integrals_.bulk_->points(element_patch_idx, element_cache_map_);
109  }
110 
111  /// Return EdgePoint range of appropriate dimension
112  inline Range< EdgePoint > edge_points(const DHCellSide &cell_side) const {
113  ASSERT( cell_side.dim() > 0 ).error("Invalid cell dimension, must be 1, 2 or 3!\n");
114  return integrals_.edge_->points(cell_side, element_cache_map_);
115  }
116 
117  /// Return CouplingPoint range of appropriate dimension
118  inline Range< CouplingPoint > coupling_points(const DHCellSide &cell_side) const {
119  ASSERT( cell_side.dim() > 1 ).error("Invalid cell dimension, must be 2 or 3!\n");
120  return integrals_.coupling_->points(cell_side, element_cache_map_);
121  }
122 
123  /// Return BoundaryPoint range of appropriate dimension
124  inline Range< BoundaryPoint > boundary_points(const DHCellSide &cell_side) const {
125  ASSERT( cell_side.dim() > 0 ).error("Invalid cell dimension, must be 1, 2 or 3!\n");
126  return integrals_.boundary_->points(cell_side, element_cache_map_);
127  }
128 
129  /// Assembles the cell integrals for the given dimension.
130  virtual inline void assemble_cell_integrals(const RevertableList<BulkIntegralData> &bulk_integral_data) {
131  for (unsigned int i=0; i<bulk_integral_data.permanent_size(); ++i) {
132  if (bulk_integral_data[i].cell.dim() != dim) continue;
133  this->cell_integral(bulk_integral_data[i].cell, element_cache_map_->position_in_cache(bulk_integral_data[i].cell.elm_idx()));
134  }
135  // Possibly optimization but not so fast as we would assume (needs change interface of cell_integral)
136  /*for (unsigned int i=0; i<element_cache_map_->n_elements(); ++i) {
137  unsigned int elm_start = element_cache_map_->element_chunk_begin(i);
138  if (element_cache_map_->eval_point_data(elm_start).i_eval_point_ != 0) continue;
139  this->cell_integral(i, element_cache_map_->eval_point_data(elm_start).dh_loc_idx_);
140  }*/
141  }
142 
143  /// Assembles the boundary side integrals for the given dimension.
144  inline void assemble_boundary_side_integrals(const RevertableList<BoundaryIntegralData> &boundary_integral_data) {
145  for (unsigned int i=0; i<boundary_integral_data.permanent_size(); ++i) {
146  if (boundary_integral_data[i].side.dim() != dim) continue;
147  this->boundary_side_integral(boundary_integral_data[i].side);
148  }
149  }
150 
151  /// Assembles the edge integrals for the given dimension.
152  inline void assemble_edge_integrals(const RevertableList<EdgeIntegralData> &edge_integral_data) {
153  for (unsigned int i=0; i<edge_integral_data.permanent_size(); ++i) {
154  auto range = edge_integral_data[i].edge_side_range;
155  if (range.begin()->dim() != dim) continue;
156  this->edge_integral(edge_integral_data[i].edge_side_range);
157  }
158  }
159 
160  /// Assembles the neighbours integrals for the given dimension.
161  inline void assemble_neighbour_integrals(const RevertableList<CouplingIntegralData> &coupling_integral_data) {
162  for (unsigned int i=0; i<coupling_integral_data.permanent_size(); ++i) {
163  if (coupling_integral_data[i].side.dim() != dim) continue;
164  this->dimjoin_intergral(coupling_integral_data[i].cell, coupling_integral_data[i].side);
165  }
166  }
167 
168 protected:
169  /// Set of integral of given dimension necessary in assemblation
170  struct DimIntegrals {
171  std::shared_ptr<BulkIntegral> bulk_; ///< Bulk integrals of elements
172  std::shared_ptr<EdgeIntegral> edge_; ///< Edge integrals between elements of same dimensions
173  std::shared_ptr<CouplingIntegral> coupling_; ///< Coupling integrals between elements of dimensions dim and dim-1
174  std::shared_ptr<BoundaryIntegral> boundary_; ///< Boundary integrals betwwen side and boundary element of dim-1
175  };
176 
177  /**
178  * Default constructor.
179  *
180  * Be aware if you use this constructor. Quadrature objects must be initialized manually in descendant.
181  */
183  : quad_(nullptr), quad_low_(nullptr) {}
184 
185  /// Print update flags to string format.
186  std::string print_update_flags(UpdateFlags u) const {
187  std::stringstream s;
188  s << u;
189  return s.str();
190  }
191 
192  Quadrature *quad_; ///< Quadrature used in assembling methods.
193  Quadrature *quad_low_; ///< Quadrature used in assembling methods (dim-1).
194  int active_integrals_; ///< Holds mask of active integrals.
195  DimIntegrals integrals_; ///< Set of used integrals.
196  ElementCacheMap *element_cache_map_; ///< ElementCacheMap shared with GenericAssembly object.
197 };
198 
199 
200 #endif /* ASSEMBLY_BASE_HH_ */
#define ASSERT(expr)
Definition: asserts.hh:351
#define ASSERT_PERMANENT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:337
virtual void assemble_cell_integrals(const RevertableList< BulkIntegralData > &bulk_integral_data)
Assembles the cell integrals for the given dimension.
Range< BulkPoint > bulk_points(unsigned int element_patch_idx) const
Return BulkPoint range of appropriate dimension.
virtual void boundary_side_integral(FMT_UNUSED DHCellSide cell_side)
Assembles the fluxes on the boundary.
virtual void patch_reinit(FMT_UNUSED PatchElementsList patch_elements)
Method prepares object before computing on patch (typically reinitialize PatchFEValues objects).
virtual void end()
Method finishes object after assemblation (e.g. balance, ...).
virtual ~AssemblyBase()
Destructor.
virtual void cell_integral(FMT_UNUSED DHCellAccessor cell, FMT_UNUSED unsigned int element_patch_idx)
Assembles the volume integrals on cell.
Range< EdgePoint > edge_points(const DHCellSide &cell_side) const
Return EdgePoint range of appropriate dimension.
GenericAssemblyBase::CouplingIntegralData CouplingIntegralData
Quadrature * quad_
Quadrature used in assembling methods.
void create_integrals(std::shared_ptr< EvalPoints > eval_points, AssemblyIntegrals &integrals)
Create integrals according to dim of assembly object.
void assemble_edge_integrals(const RevertableList< EdgeIntegralData > &edge_integral_data)
Assembles the edge integrals for the given dimension.
DimIntegrals integrals_
Set of used integrals.
virtual void begin()
Method prepares object before assemblation (e.g. balance, ...).
std::string print_update_flags(UpdateFlags u) const
Print update flags to string format.
Quadrature * quad_low_
Quadrature used in assembling methods (dim-1).
GenericAssemblyBase::BulkIntegralData BulkIntegralData
void assemble_neighbour_integrals(const RevertableList< CouplingIntegralData > &coupling_integral_data)
Assembles the neighbours integrals for the given dimension.
Range< CouplingPoint > coupling_points(const DHCellSide &cell_side) const
Return CouplingPoint range of appropriate dimension.
virtual void dimjoin_intergral(FMT_UNUSED DHCellAccessor cell_lower_dim, FMT_UNUSED DHCellSide neighb_side)
Assembles the fluxes between elements of different dimensions.
virtual void edge_integral(FMT_UNUSED RangeConvert< DHEdgeSide, DHCellSide > edge_side_range)
Assembles the fluxes between sides on the edge.
int active_integrals_
Holds mask of active integrals.
Range< BoundaryPoint > boundary_points(const DHCellSide &cell_side) const
Return BoundaryPoint range of appropriate dimension.
AssemblyBase(unsigned int quad_order)
Constructor.
void assemble_boundary_side_integrals(const RevertableList< BoundaryIntegralData > &boundary_integral_data)
Assembles the boundary side integrals for the given dimension.
GenericAssemblyBase::EdgeIntegralData EdgeIntegralData
int n_active_integrals() const
Getter of active_integrals.
ElementCacheMap * element_cache_map_
ElementCacheMap shared with GenericAssembly object.
GenericAssemblyBase::BoundaryIntegralData BoundaryIntegralData
Cell accessor allow iterate over DOF handler cells.
Side accessor allows to iterate over sides of DOF handler cell.
unsigned int dim() const
Return dimension of element appropriate to the side.
Directing class of FieldValueCache.
unsigned int position_in_cache(unsigned mesh_elm_idx, bool bdr=false) const
Return position of element stored in ElementCacheMap.
Symmetric Gauss-Legendre quadrature formulae on simplices.
Base class for quadrature rules on simplices in arbitrary dimensions.
Definition: quadrature.hh:48
Range helper class.
@ coupling
@ boundary
@ bulk
@ edge
#define FMT_UNUSED
Definition: posix.h:75
Definitions of particular quadrature rules on simplices.
Set of integral of given dimension necessary in assemblation.
std::shared_ptr< EdgeIntegral > edge_
Edge integrals between elements of same dimensions.
std::shared_ptr< CouplingIntegral > coupling_
Coupling integrals between elements of dimensions dim and dim-1.
std::shared_ptr< BulkIntegral > bulk_
Bulk integrals of elements.
std::shared_ptr< BoundaryIntegral > boundary_
Boundary integrals betwwen side and boundary element of dim-1.
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.
std::size_t permanent_size() const
Return permanent size of list.
Enum type UpdateFlags indicates which quantities are to be recomputed on each finite element cell.
UpdateFlags
Enum type UpdateFlags indicates which quantities are to be recomputed on each finite element cell.
Definition: update_flags.hh:68