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