Note: this is documentation for an old release. View the latest documentation at docs.fenicsproject.org/v0.1.0/v0.9.0/cpp
DOLFINx  0.1.0
DOLFINx C++ interface
FiniteElement.h
1 // Copyright (C) 2008-2020 Anders Logg and Garth N. Wells
2 //
3 // This file is part of DOLFINx (https://www.fenicsproject.org)
4 //
5 // SPDX-License-Identifier: LGPL-3.0-or-later
6 
7 #pragma once
8 
9 #include <basix/finite-element.h>
10 #include <dolfinx/common/types.h>
11 #include <dolfinx/mesh/cell_types.h>
12 #include <functional>
13 #include <memory>
14 #include <numeric>
15 #include <vector>
16 #include <xtl/xspan.hpp>
17 
18 struct ufc_finite_element;
19 
20 namespace dolfinx::fem
21 {
25 {
26 public:
29  explicit FiniteElement(const ufc_finite_element& ufc_element);
30 
32  FiniteElement(const FiniteElement& element) = delete;
33 
35  FiniteElement(FiniteElement&& element) = default;
36 
38  virtual ~FiniteElement() = default;
39 
41  FiniteElement& operator=(const FiniteElement& element) = delete;
42 
44  FiniteElement& operator=(FiniteElement&& element) = default;
45 
48  std::string signature() const noexcept;
49 
52  mesh::CellType cell_shape() const noexcept;
53 
56  int space_dimension() const noexcept;
57 
62  int block_size() const noexcept;
63 
66  int value_size() const noexcept;
67 
71  int reference_value_size() const noexcept;
72 
75  int value_rank() const noexcept;
76 
78  int value_dimension(int i) const;
79 
82  std::string family() const noexcept;
83 
85  // reference_values[num_points][num_dofs][reference_value_size]
86  void evaluate_reference_basis(xt::xtensor<double, 3>& values,
87  const xt::xtensor<double, 2>& X) const;
88 
91  // reference_value_derivatives[num_points][num_dofs][reference_value_size][num_derivatives]
92  // void
93  // evaluate_reference_basis_derivatives(std::vector<double>& reference_values,
94  // int order,
95  // const xt::xtensor<double, 2>& X)
96  // const;
97 
99  void transform_reference_basis(xt::xtensor<double, 3>& values,
100  const xt::xtensor<double, 3>& reference_values,
101  const xt::xtensor<double, 3>& J,
102  const xtl::span<const double>& detJ,
103  const xt::xtensor<double, 3>& K) const;
104 
107  std::vector<double>& values, std::size_t order,
108  const std::vector<double>& reference_values, const array2d<double>& X,
109  const std::vector<double>& J, const xtl::span<const double>& detJ,
110  const std::vector<double>& K) const;
111 
114  int num_sub_elements() const noexcept;
115 
117  const std::vector<std::shared_ptr<const FiniteElement>>&
118  sub_elements() const noexcept;
119 
121  std::size_t hash() const noexcept;
122 
124  std::shared_ptr<const FiniteElement>
125  extract_sub_element(const std::vector<int>& component) const;
126 
133  bool interpolation_ident() const noexcept;
134 
141  const xt::xtensor<double, 2>& interpolation_points() const;
142 
160  template <typename T>
161  constexpr void interpolate(const xt::xtensor<T, 2>& values,
162  xtl::span<T> dofs) const
163  {
164  if (!_element)
165  {
166  throw std::runtime_error("No underlying element for interpolation. "
167  "Cannot interpolate mixed elements directly.");
168  }
169 
170  const std::size_t rows = _space_dim / _bs;
171  assert(_space_dim % _bs == 0);
172  assert(dofs.size() == rows);
173 
174  // Compute dofs = Pi * x (matrix-vector multiply)
175  const xt::xtensor<double, 2>& Pi = _element->interpolation_matrix();
176  assert(Pi.size() % rows == 0);
177  const std::size_t cols = Pi.size() / rows;
178  for (std::size_t i = 0; i < rows; ++i)
179  {
180  // Can be replaced with std::transform_reduce once GCC 8 series dies.
181  // Dot product between row i of the matrix and 'values'
182  dofs[i] = std::inner_product(std::next(Pi.data(), i * cols),
183  std::next(Pi.data(), i * cols + cols),
184  values.data(), T(0.0));
185  }
186  }
187 
192  bool needs_permutation_data() const noexcept;
193 
199  template <typename T>
200  void apply_dof_transformation(xtl::span<T> data,
201  std::uint32_t cell_permutation,
202  int block_size) const
203  {
204  assert(_element);
205  _element->apply_dof_transformation(data, block_size, cell_permutation);
206  }
207 
213  template <typename T>
215  xtl::span<T> data, std::uint32_t cell_permutation, int block_size) const
216  {
217  assert(_element);
218  _element->apply_inverse_transpose_dof_transformation(data, block_size,
219  cell_permutation);
220  }
221 
224  template <typename T>
225  void
226  map_pull_back(const xt::xtensor<T, 3>& u, const xt::xtensor<double, 3>& J,
227  const xtl::span<const double>& detJ,
228  const xt::xtensor<double, 3>& K, xt::xtensor<T, 3>& U) const
229  {
230  assert(_element);
231  _element->map_pull_back_m(u, J, detJ, K, U);
232  }
233 
234 private:
235  std::string _signature, _family;
236 
237  mesh::CellType _cell_shape;
238 
239  int _tdim, _space_dim, _value_size, _reference_value_size;
240 
241  // List of sub-elements (if any)
242  std::vector<std::shared_ptr<const FiniteElement>> _sub_elements;
243 
244  // Simple hash of the signature string
245  std::size_t _hash;
246 
247  // Dimension of each value space
248  std::vector<int> _value_dimension;
249 
250  // Block size for VectorElements and TensorElements. This gives the
251  // number of DOFs colocated at each point.
252  int _bs;
253 
254  // True if element needs dof permutation
255  bool _needs_permutation_data;
256 
257  // Basix Element (nullptr for mixed elements)
258  std::unique_ptr<basix::FiniteElement> _element;
259 };
260 } // namespace dolfinx::fem
dolfinx::fem::FiniteElement::FiniteElement
FiniteElement(const ufc_finite_element &ufc_element)
Create finite element from UFC finite element.
Definition: FiniteElement.cpp:64
dolfinx::fem::FiniteElement::block_size
int block_size() const noexcept
Block size of the finite element function space. For VectorElements and TensorElements,...
Definition: FiniteElement.cpp:148
dolfinx::fem::FiniteElement::interpolation_ident
bool interpolation_ident() const noexcept
Check if interpolation into the finite element space is an identity operation given the evaluation on...
Definition: FiniteElement.cpp:222
dolfinx::fem::FiniteElement::extract_sub_element
std::shared_ptr< const FiniteElement > extract_sub_element(const std::vector< int > &component) const
Extract sub finite element for component.
Definition: FiniteElement.cpp:212
dolfinx::fem::FiniteElement::value_dimension
int value_dimension(int i) const
Return the dimension of the value space for axis i.
Definition: FiniteElement.cpp:150
dolfinx::fem::FiniteElement::interpolation_points
const xt::xtensor< double, 2 > & interpolation_points() const
Points on the reference cell at which an expression need to be evaluated in order to interpolate the ...
Definition: FiniteElement.cpp:228
dolfinx::fem::FiniteElement::transform_reference_basis
void transform_reference_basis(xt::xtensor< double, 3 > &values, const xt::xtensor< double, 3 > &reference_values, const xt::xtensor< double, 3 > &J, const xtl::span< const double > &detJ, const xt::xtensor< double, 3 > &K) const
Evaluate all basis function derivatives of given order at given points in reference cell.
Definition: FiniteElement.cpp:187
dolfinx::mesh::CellType
CellType
Cell type identifier.
Definition: cell_types.h:21
dolfinx::fem::FiniteElement::map_pull_back
void map_pull_back(const xt::xtensor< T, 3 > &u, const xt::xtensor< double, 3 > &J, const xtl::span< const double > &detJ, const xt::xtensor< double, 3 > &K, xt::xtensor< T, 3 > &U) const
Pull physical data back to the reference element. This passes the inputs directly into Basix's map_pu...
Definition: FiniteElement.h:226
dolfinx::fem::FiniteElement::reference_value_size
int reference_value_size() const noexcept
The value size, e.g. 1 for a scalar function, 2 for a 2D vector for the reference element.
Definition: FiniteElement.cpp:138
dolfinx::fem::FiniteElement::apply_inverse_transpose_dof_transformation
void apply_inverse_transpose_dof_transformation(xtl::span< T > data, std::uint32_t cell_permutation, int block_size) const
Apply inverse transpose permutation to some data.
Definition: FiniteElement.h:214
dolfinx::fem::FiniteElement::num_sub_elements
int num_sub_elements() const noexcept
Get the number of sub elements (for a mixed element)
Definition: FiniteElement.cpp:197
dolfinx::fem::FiniteElement::transform_reference_basis_derivatives
void transform_reference_basis_derivatives(std::vector< double > &values, std::size_t order, const std::vector< double > &reference_values, const array2d< double > &X, const std::vector< double > &J, const xtl::span< const double > &detJ, const std::vector< double > &K) const
Push basis function (derivatives) forward to physical element.
dolfinx::fem::FiniteElement
Finite Element, containing the dof layout on a reference element, and various methods for evaluating ...
Definition: FiniteElement.h:24
dolfinx::fem::FiniteElement::hash
std::size_t hash() const noexcept
Return simple hash of the signature string.
Definition: FiniteElement.cpp:209
dolfinx::fem::FiniteElement::value_size
int value_size() const noexcept
The value size, e.g. 1 for a scalar function, 2 for a 2D vector.
Definition: FiniteElement.cpp:136
dolfinx::fem::FiniteElement::space_dimension
int space_dimension() const noexcept
Dimension of the finite element function space.
Definition: FiniteElement.cpp:134
dolfinx::fem::FiniteElement::family
std::string family() const noexcept
The finite element family.
Definition: FiniteElement.cpp:158
dolfinx::fem::FiniteElement::interpolate
constexpr void interpolate(const xt::xtensor< T, 2 > &values, xtl::span< T > dofs) const
Definition: FiniteElement.h:161
dolfinx::fem::FiniteElement::apply_dof_transformation
void apply_dof_transformation(xtl::span< T > data, std::uint32_t cell_permutation, int block_size) const
Apply permutation to some data.
Definition: FiniteElement.h:200
dolfinx::fem::FiniteElement::operator=
FiniteElement & operator=(const FiniteElement &element)=delete
Copy assignment.
dolfinx::fem::FiniteElement::~FiniteElement
virtual ~FiniteElement()=default
Destructor.
dolfinx::fem::FiniteElement::needs_permutation_data
bool needs_permutation_data() const noexcept
Definition: FiniteElement.cpp:240
dolfinx::fem::FiniteElement::value_rank
int value_rank() const noexcept
Rank of the value space.
Definition: FiniteElement.cpp:143
dolfinx::fem::FiniteElement::cell_shape
mesh::CellType cell_shape() const noexcept
Cell shape.
Definition: FiniteElement.cpp:129
dolfinx::fem::FiniteElement::evaluate_reference_basis
void evaluate_reference_basis(xt::xtensor< double, 3 > &values, const xt::xtensor< double, 2 > &X) const
Evaluate all basis functions at given points in reference cell.
Definition: FiniteElement.cpp:160
dolfinx::fem::FiniteElement::signature
std::string signature() const noexcept
String identifying the finite element.
Definition: FiniteElement.cpp:127
dolfinx::fem::FiniteElement::sub_elements
const std::vector< std::shared_ptr< const FiniteElement > > & sub_elements() const noexcept
Subelements (if any)
Definition: FiniteElement.cpp:203
dolfinx::fem
Finite element method functionality.
Definition: assemble_matrix_impl.h:22
dolfinx::array2d
This class provides a dynamic 2-dimensional row-wise array data structure.
Definition: array2d.h:20