Flow123d  release_2.2.0-914-gf1a3a4f
finite_element.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 finite_element.hh
15  * @brief Abstract class for description of finite elements.
16  * @author Jan Stebel
17  */
18 
19 #ifndef FINITE_ELEMENT_HH_
20 #define FINITE_ELEMENT_HH_
21 
22 #include <armadillo>
23 #include <map>
24 #include <vector>
25 #include <boost/assign/list_of.hpp>
26 #include "fem/update_flags.hh"
27 
28 
29 
30 template<unsigned int dim, unsigned int spacedim> class FESystem;
31 template<unsigned int dim, unsigned int spacedim> class FESideValues;
32 template<unsigned int dim, unsigned int spacedim> class FEValues;
33 template<unsigned int dim, unsigned int spacedim> class FEValuesBase;
34 template<unsigned int dim, unsigned int spacedim> class FEValuesData;
35 template<unsigned int dim, unsigned int spacedim> class FE_P_disc;
36 template<unsigned int dim> class Quadrature;
37 
38 
39 
40 
41 
42 // Possible types are: value, gradient, cell integral, ...
43 enum DofType { Value = 1 };
44 
45 /**
46  * Class Dof is a general description of functionals (degrees of freedom)
47  * determining the finite element. We assume that the Dof is defined as
48  * a linear combination of components of function value at a given point:
49  *
50  * Dof_value = a_1.f_1(x) + ... + a_n.f_n(x),
51  *
52  * where (a_1, ... , a_n) are given by @p coefs, x is the support point
53  * given by barycentric @p coords and (f_1, ..., f_n) is a generally
54  * vector-valued function. For the simplest Dof, i.e. value of a scalar
55  * function at point p, we set
56  *
57  * @p coords = p, @p coefs = { 1 }.
58  * The member @p dim denotes the affiliation of Dof to n-face:
59  * Nodal dofs have dim = 0,
60  * Dofs on lines: dim = 1,
61  * Dofs on triangles: dim = 2,
62  * Dofs in tetrahedron: dim = 3.
63  * It means that when a node, line or triangle is shared by adjacent cells,
64  * also the Dofs on this n-face are shared by the cells. Therefore
65  * for DG finite elements we set for all dofs the highest possible dimension.
66  *
67  * The class implements the method evaluate() which computes the Dof value
68  * for a basis function from given FunctionSpace.
69  */
70 class Dof {
71 public:
72 
73  Dof(unsigned int dim_,
74  unsigned int n_face_idx_,
75  arma::vec coords_,
76  arma::vec coefs_,
77  DofType type_)
78 
79  : dim(dim_),
80  n_face_idx(n_face_idx_),
81  coords(coords_),
82  coefs(coefs_),
83  type(type_)
84  {}
85 
86  /// Evaulate dof for basis function of given function space.
87  template<class FS>
88  const double evaluate(const FS &function_space,
89  unsigned int basis_idx) const;
90 
91  /// Association to n-face of given dimension (point, line, triangle, tetrahedron.
92  unsigned int dim;
93 
94  /// Index of n-face to which the dof is associated.
95  unsigned int n_face_idx;
96 
97  /// Barycentric coordinates.
98  arma::vec coords;
99 
100  /// Coefficients of linear combination of function value components.
101  arma::vec coefs;
102 
103  /**
104  * Currently we consider only type=Value, possibly we could have Gradient,
105  * CellIntegral, FaceIntegral or other types.
106  */
108 };
109 
110 
111 /**
112  * FunctionSpace is an abstract class that is used to describe finite elements.
113  * It is determined by the dimension of the field of definition (@p space_dim_),
114  * by the dimension of the range (@p n_components_) and by the values and
115  * gradients of a basis functions.
116  *
117  * Combining FunctionSpace with Dof(s), the FiniteElement class constructs the
118  * shape functions, i.e. basis of FunctionSpace for which the Dof(s) attain
119  * the value 0 or 1.
120  */
122 public:
123 
124  FunctionSpace(unsigned int space_dim,
125  unsigned int n_components)
126 
127  : space_dim_(space_dim),
128  n_components_(n_components)
129  {}
130 
131 
132  /**
133  * @brief Value of the @p i th basis function at point @p point.
134  * @param basis_index Index of the basis function.
135  * @param point Point coordinates.
136  * @param comp_index Index of component (>0 for vector-valued functions).
137  */
138  virtual const double basis_value(unsigned int basis_index,
139  const arma::vec &point,
140  unsigned int comp_index = 0
141  ) const = 0;
142 
143  /**
144  * @brief Gradient of the @p i th basis function at point @p point.
145  * @param basis_index Index of the basis function.
146  * @param point Point coordinates.
147  * @param comp_index Index of component (>0 for vector-valued functions).
148  */
149  virtual const arma::vec basis_grad(unsigned int basis_index,
150  const arma::vec &point,
151  unsigned int comp_index = 0
152  ) const = 0;
153 
154  /// Dimension of function space (number of basis functions).
155  virtual const unsigned int dim() const = 0;
156 
157  /// Getter for space dimension.
158  const unsigned int space_dim() const { return space_dim_; }
159 
160  /// Getter for number of components.
161  const unsigned int n_components() const { return n_components_; }
162 
163  virtual ~FunctionSpace() {}
164 
165 protected:
166 
167  /// Space dimension of function arguments (i.e. 1, 2 or 3).
168  unsigned int space_dim_;
169 
170  /// Number of components of function values.
171  unsigned int n_components_;
172 };
173 
174 
175 /**
176  * Types of FiniteElement: scalar, vector-valued, tensor-valued or mixed system.
177  *
178  * The type also indicates how the shape functions and their gradients are transformed
179  * from reference element to arbitrary element. In particular:
180  *
181  * TYPE OBJECT EXPRESSION
182  * -----------------------------------------------------------
183  * FEScalar value ref_value
184  * grad J^{-T} * ref_grad
185  * -----------------------------------------------------------
186  * FEVectorContravariant value J * ref_value
187  * grad J^{-T} * ref_grad * J^T
188  * -----------------------------------------------------------
189  * FEVectorPiola value J * ref_value / |J|
190  * grad J^{-T} * ref_grad * J^T / |J|
191  * -----------------------------------------------------------
192  * FETensor value not implemented
193  * grad not implemented
194  * -----------------------------------------------------------
195  * FEMixedSystem value depends on sub-elements
196  * grad depends on sub-elements
197  *
198  * Note that we use columnwise gradients, i.e. gradient of each component is a column vector.
199  */
200 enum FEType {
201  FEScalar = 0,
204  FETensor = 3,
206 };
207 
208 /**
209  * @brief Structure for storing the precomputed finite element data.
210  */
212 {
213 public:
214  /**
215  * @brief Precomputed values of basis functions at the quadrature points.
216  *
217  * Dimensions: (no. of quadrature points)
218  * x (no. of dofs)
219  * x (no. of components in ref. cell)
220  */
222 
223  /**
224  * @brief Precomputed gradients of basis functions at the quadrature points.
225  *
226  * Dimensions: (no. of quadrature points)
227  * x (no. of dofs)
228  * x ((dim of. ref. cell)x(no. of components in ref. cell))
229  */
231 };
232 
233 
234 /**
235  * @brief Abstract class for the description of a general finite element on
236  * a reference simplex in @p dim dimensions.
237  *
238  * The finite element is determined by a @p function_space_ and a set
239  * of @p dofs_. Further it must be set whether the finite element
240  * @p is_primitive_, which means that even if the functions in
241  * @p function_space_ are vector-valued, the basis functions have
242  * only one nonzero component (this is typical for tensor-product FE,
243  * e.g. vector-valued polynomial FE, but not for Raviart-Thomas FE).
244  *
245  * Description of dofs:
246  *
247  * The reference cell consists of lower dimensional entities (points,
248  * lines, triangles). Each dof is associated to one of these
249  * entities. If the entity is shared by 2 or more neighbouring cells
250  * in the mesh then this dof is shared by the finite elements on all
251  * of these cells. If a dof is associated to the cell itself then it
252  * is not shared with neighbouring cells.
253  *
254  *
255  * Shape functions:
256  *
257  * Sometimes it is convenient to describe the function space using
258  * a basis (called the raw basis) that is different from the set of
259  * shape functions for the finite element (the actual basis). For
260  * this reason we define the support points which play the role of
261  * nodal functionals associated to the particular dofs. To convert
262  * between the two bases one can use the @p node_matrix, which is
263  * constructed by the method compute_node_matrix(). In the case of
264  * non-Lagrangean finite elements the dofs are not associated to
265  * nodal functionals but e.g. to derivatives or averages. For that
266  * reason we distinguish between the unit support points which are
267  * uniquely associated to the dofs and the generalized support
268  * points that are auxiliary for the calculation of the dof
269  * functionals.
270  *
271  *
272  */
273 template<unsigned int dim, unsigned int spacedim>
274 class FiniteElement {
275 public:
276 
277  /**
278  * @brief Constructor.
279  */
280  FiniteElement();
281 
282  /**
283  * @brief Returns the number of degrees of freedom needed by the finite
284  * element.
285  */
286  const unsigned int n_dofs() const { return dofs_.size(); }
287 
288  /**
289  * @brief Calculates the value of the @p comp-th component of
290  * the @p i-th raw basis function at the
291  * point @p p on the reference element.
292  *
293  * @param i Number of the basis function.
294  * @param p Point of evaluation.
295  * @param comp Number of vector component.
296  */
297  virtual double basis_value(const unsigned int i,
298  const arma::vec::fixed<dim> &p, const unsigned int comp = 0) const;
299 
300  /**
301  * @brief Calculates the @p comp-th component of the gradient
302  * of the @p i-th raw basis function at the point @p p on the
303  * reference element.
304  *
305  * @param i Number of the basis function.
306  * @param p Point of evaluation.
307  * @param comp Number of vector component.
308  */
309  virtual arma::vec::fixed<dim> basis_grad(const unsigned int i,
310  const arma::vec::fixed<dim> &p, const unsigned int comp = 0) const;
311 
312  /// Returns numer of components of the basis function.
313  virtual unsigned int n_components() const { return function_space_->n_components(); }
314 
315  /// Returns @p i -th degree of freedom.
316  Dof dof(unsigned int i) const { return dofs_[i]; }
317 
318  /**
319  * @brief Destructor.
320  */
321  virtual ~FiniteElement();
322 
323 protected:
324 
325  /**
326  * @brief Clears all internal structures.
327  */
328  void init(bool primitive = true, FEType type = FEScalar);
329 
330  /**
331  * @brief Initialize vectors with information about components of basis functions.
332  */
333  void setup_components();
334 
335  /**
336  * @brief Calculates the data on the reference cell.
337  *
338  * @param q Quadrature rule.
339  * @param flags Update flags.
340  */
341  virtual FEInternalData *initialize(const Quadrature<dim> &q);
342 
343  /**
344  * @brief Decides which additional quantities have to be computed
345  * for each cell.
346  *
347  * @param flags Computed update flags.
348  */
349  virtual UpdateFlags update_each(UpdateFlags flags);
350 
351  /**
352  * @brief Computes the shape function values and gradients on the actual cell
353  * and fills the FEValues structure.
354  *
355  * @param q Quadrature rule.
356  * @param data Precomputed finite element data.
357  * @param fv_data Data to be computed.
358  */
359  virtual void fill_fe_values(const Quadrature<dim> &q,
360  FEInternalData &data,
361  FEValuesData<dim,spacedim> &fv_data);
362 
363  /**
364  * @brief Initializes the @p node_matrix for computing the coefficients
365  * of the shape functions in the raw basis of @p functions_space_.
366  * This is done by evaluating the @p dofs_ for the basis function
367  * and by inverting the resulting matrix.
368  */
369  virtual void compute_node_matrix();
370 
371  /**
372  * @brief Indicates whether the basis functions have one or more
373  * nonzero components (scalar FE spaces are always primitive).
374  */
375  inline const bool is_primitive() const { return is_primitive_; }
376 
377  /**
378  * @brief Returns the component index for vector valued finite elements.
379  * @param sys_idx Index of shape function.
380  */
381  unsigned int system_to_component_index(unsigned sys_idx) const
382  { return component_indices_[sys_idx]; }
383 
384  /**
385  * @brief Returns the mask of nonzero components for given basis function.
386  * @param sys_idx Index of basis function.
387  */
388  const std::vector<bool> &get_nonzero_components(unsigned int sys_idx) const
389  { return nonzero_components_[sys_idx]; }
390 
391 
392 
393  /// Type of FiniteElement.
395 
396  /**
397  * @brief Primitive FE is using componentwise shape functions,
398  * i.e. only one component is nonzero for each shape function.
399  */
401 
402  /// Indices of nonzero components of shape functions (for primitive FE).
404 
405  /// Footprints of nonzero components of shape functions.
407 
408  /**
409  * @brief Matrix that determines the coefficients of the raw basis
410  * functions from the values at the support points.
411  */
412  arma::mat node_matrix;
413 
414  /// Function space defining the FE.
416 
417  /// Set of degrees of freedom (functionals) defining the FE.
419 
420 
421  friend class FESystem<dim,spacedim>;
422  friend class FEValuesBase<dim,spacedim>;
423  friend class FEValues<dim,spacedim>;
424  friend class FESideValues<dim,spacedim>;
425  friend class FE_P_disc<dim,spacedim>;
426 };
427 
428 
429 
430 
431 #endif /* FINITE_ELEMENT_HH_ */
const unsigned int space_dim() const
Getter for space dimension.
FEType type_
Type of FiniteElement.
UpdateFlags
Enum type UpdateFlags indicates which quantities are to be recomputed on each finite element cell...
Definition: update_flags.hh:67
arma::vec coords
Barycentric coordinates.
std::vector< Dof > dofs_
Set of degrees of freedom (functionals) defining the FE.
DofType type
FunctionSpace(unsigned int space_dim, unsigned int n_components)
const bool is_primitive() const
Indicates whether the basis functions have one or more nonzero components (scalar FE spaces are alway...
unsigned int n_components_
Number of components of function values.
unsigned int dim
Association to n-face of given dimension (point, line, triangle, tetrahedron.
std::vector< std::vector< bool > > nonzero_components_
Footprints of nonzero components of shape functions.
Dof dof(unsigned int i) const
Returns i -th degree of freedom.
FEType
Enum type UpdateFlags indicates which quantities are to be recomputed on each finite element cell...
unsigned int n_face_idx
Index of n-face to which the dof is associated.
Base class for quadrature rules on simplices in arbitrary dimensions.
Definition: fe_values.hh:32
Discontinuous Lagrangean finite element on dim dimensional simplex.
Definition: fe_p.hh:106
unsigned int system_to_component_index(unsigned sys_idx) const
Returns the component index for vector valued finite elements.
std::vector< unsigned int > component_indices_
Indices of nonzero components of shape functions (for primitive FE).
bool is_primitive_
Primitive FE is using componentwise shape functions, i.e. only one component is nonzero for each shap...
Compound finite element on dim dimensional simplex.
Definition: fe_system.hh:36
std::vector< std::vector< arma::mat > > ref_shape_grads
Precomputed gradients of basis functions at the quadrature points.
const unsigned int n_components() const
Getter for number of components.
Class FEValuesData holds the arrays of data computed by Mapping and FiniteElement.
Definition: fe_values.hh:48
const std::vector< bool > & get_nonzero_components(unsigned int sys_idx) const
Returns the mask of nonzero components for given basis function.
const double evaluate(const FS &function_space, unsigned int basis_idx) const
Evaulate dof for basis function of given function space.
DofType
Calculates finite element data on the actual cell.
Definition: fe_values.hh:450
const unsigned int n_dofs() const
Returns the number of degrees of freedom needed by the finite element.
Dof(unsigned int dim_, unsigned int n_face_idx_, arma::vec coords_, arma::vec coefs_, DofType type_)
Structure for storing the precomputed finite element data.
std::vector< std::vector< arma::vec > > ref_shape_values
Precomputed values of basis functions at the quadrature points.
unsigned int space_dim_
Space dimension of function arguments (i.e. 1, 2 or 3).
FunctionSpace * function_space_
Function space defining the FE.
Abstract class for the description of a general finite element on a reference simplex in dim dimensio...
Definition: dofhandler.hh:30
Base class for FEValues and FESideValues.
Definition: fe_values.hh:34
arma::mat node_matrix
Matrix that determines the coefficients of the raw basis functions from the values at the support poi...
arma::vec coefs
Coefficients of linear combination of function value components.
virtual unsigned int n_components() const
Returns numer of components of the basis function.
Calculates finite element data on a side.
Definition: fe_values.hh:495
virtual ~FunctionSpace()