11#include <basix/finite-element.h>
14#include <dolfinx/mesh/cell_types.h>
35template <std::
floating_po
int T>
38 std::reference_wrapper<const basix::FiniteElement<T>>
47template <
typename U,
typename V,
typename W>
55template <std::
floating_po
int T>
113 std::array<std::size_t, 2> pshape,
239 const std::vector<std::vector<std::vector<
int>>>&
244 const std::vector<std::vector<std::vector<
int>>>&
264 std::array<std::
size_t, 2> shape,
int order) const;
276 std::pair<std::vector<
geometry_type>, std::array<std::
size_t, 4>>
332 std::pair<std::vector<
geometry_type>, std::array<std::
size_t, 2>>
344 std::pair<std::vector<
geometry_type>, std::array<std::
size_t, 2>>
359 std::pair<std::vector<
geometry_type>, std::array<std::
size_t, 2>>
432 template <typename U>
433 std::function<
void(std::span<U>, std::span<const std::uint32_t>, std::int32_t,
440 return [](std::span<U>, std::span<const std::uint32_t>, std::int32_t, int)
446 if (!_sub_elements.empty())
448 if (!_reference_value_shape)
450 std::vector<std::function<void(
451 std::span<U>, std::span<const std::uint32_t>, std::int32_t, int)>>
453 std::vector<int> dims;
454 for (std::size_t i = 0; i < _sub_elements.size(); ++i)
456 sub_element_fns.push_back(
457 _sub_elements[i]->template dof_transformation_fn<U>(ttype));
458 dims.push_back(_sub_elements[i]->space_dimension());
461 return [dims, sub_element_fns](std::span<U> data,
462 std::span<const std::uint32_t> cell_info,
463 std::int32_t cell, int block_size)
465 std::size_t offset = 0;
466 for (std::size_t e = 0; e < sub_element_fns.size(); ++e)
468 const std::size_t width = dims[e] * block_size;
469 sub_element_fns[e](data.subspan(offset, width), cell_info, cell,
475 else if (!scalar_element)
478 std::function<void(std::span<U>, std::span<const std::uint32_t>,
482 return [ebs, sub_fn](std::span<U> data,
483 std::span<const std::uint32_t> cell_info,
484 std::int32_t
cell,
int data_block_size)
485 { sub_fn(data, cell_info,
cell, ebs * data_block_size); };
492 return [
this](std::span<U> data, std::span<const std::uint32_t> cell_info,
496 return [
this](std::span<U> data, std::span<const std::uint32_t> cell_info,
500 return [
this](std::span<U> data, std::span<const std::uint32_t> cell_info,
504 return [
this](std::span<U> data, std::span<const std::uint32_t> cell_info,
508 throw std::runtime_error(
"Unknown transformation type");
535 template <
typename U>
536 std::function<void(std::span<U>, std::span<const std::uint32_t>, std::int32_t,
539 bool scalar_element =
false)
const
541 if (!needs_dof_transformations())
544 return [](std::span<U>, std::span<const std::uint32_t>, std::int32_t, int)
549 else if (!_sub_elements.empty())
551 if (!_reference_value_shape)
553 std::vector<std::function<void(
554 std::span<U>, std::span<const std::uint32_t>, std::int32_t,
int)>>
556 for (std::size_t i = 0; i < _sub_elements.size(); ++i)
558 sub_element_fns.push_back(
559 _sub_elements[i]->
template dof_transformation_right_fn<U>(ttype));
562 return [
this, sub_element_fns](std::span<U> data,
563 std::span<const std::uint32_t> cell_info,
564 std::int32_t
cell,
int block_size)
566 std::size_t offset = 0;
567 for (std::size_t e = 0; e < sub_element_fns.size(); ++e)
569 sub_element_fns[e](data.subspan(offset, data.size() - offset),
570 cell_info,
cell, block_size);
571 offset += _sub_elements[e]->space_dimension();
575 else if (!scalar_element)
582 std::function<void(std::span<U>, std::span<const std::uint32_t>,
584 sub_fn = _sub_elements[0]->template dof_transformation_fn<U>(ttype);
585 return [
this, sub_fn](std::span<U> data,
586 std::span<const std::uint32_t> cell_info,
587 std::int32_t
cell,
int data_block_size)
589 const int ebs = block_size();
590 const std::size_t dof_count = data.size() / data_block_size;
591 for (
int block = 0; block < data_block_size; ++block)
593 sub_fn(data.subspan(block * dof_count, dof_count), cell_info,
cell,
603 return [
this](std::span<U> data, std::span<const std::uint32_t> cell_info,
604 std::int32_t
cell,
int n)
605 { Tt_inv_apply_right(data, cell_info[
cell], n); };
607 return [
this](std::span<U> data, std::span<const std::uint32_t> cell_info,
608 std::int32_t
cell,
int n)
609 { Tt_apply_right(data, cell_info[
cell], n); };
611 return [
this](std::span<U> data, std::span<const std::uint32_t> cell_info,
612 std::int32_t
cell,
int n)
613 { Tinv_apply_right(data, cell_info[
cell], n); };
615 return [
this](std::span<U> data, std::span<const std::uint32_t> cell_info,
616 std::int32_t
cell,
int n)
617 { T_apply_right(data, cell_info[
cell], n); };
619 throw std::runtime_error(
"Unknown transformation type");
659 template <
typename U>
660 void T_apply(std::span<U> data, std::uint32_t cell_permutation,
int n)
const
663 _element->T_apply(data, n, cell_permutation);
675 template <
typename U>
680 _element->Tt_inv_apply(data, n, cell_permutation);
692 template <
typename U>
693 void Tt_apply(std::span<U> data, std::uint32_t cell_permutation,
int n)
const
696 _element->Tt_apply(data, n, cell_permutation);
707 template <
typename U>
708 void Tinv_apply(std::span<U> data, std::uint32_t cell_permutation,
712 _element->Tinv_apply(data, n, cell_permutation);
723 template <
typename U>
728 _element->T_apply_right(data, n, cell_permutation);
740 template <
typename U>
745 _element->Tinv_apply_right(data, n, cell_permutation);
757 template <
typename U>
762 _element->Tt_apply_right(data, n, cell_permutation);
774 template <
typename U>
779 _element->Tt_inv_apply_right(data, n, cell_permutation);
798 void permute(std::span<std::int32_t> doflist,
799 std::uint32_t cell_permutation)
const;
817 void permute_inv(std::span<std::int32_t> doflist,
818 std::uint32_t cell_permutation)
const;
834 std::function<void(std::span<std::int32_t>, std::uint32_t)>
842 std::optional<std::vector<std::size_t>> _value_shape;
852 std::string _signature;
858 std::vector<std::shared_ptr<const FiniteElement<geometry_type>>>
863 std::optional<std::vector<std::size_t>> _reference_value_shape;
866 std::unique_ptr<basix::FiniteElement<geometry_type>> _element;
872 bool _needs_dof_permutations;
873 bool _needs_dof_transformations;
875 std::vector<std::vector<std::vector<int>>> _entity_dofs;
876 std::vector<std::vector<std::vector<int>>> _entity_closure_dofs;
880 std::pair<std::vector<geometry_type>, std::array<std::size_t, 2>> _points;
Model of a finite element.
Definition FiniteElement.h:57
bool symmetric() const
Does the element represent a symmetric 2-tensor?
Definition FiniteElement.cpp:353
FiniteElement & operator=(const FiniteElement &element)=delete
Copy assignment.
const std::vector< std::shared_ptr< const FiniteElement< geometry_type > > > & sub_elements() const noexcept
Get subelements (if any)
Definition FiniteElement.cpp:396
void Tinv_apply(std::span< U > data, std::uint32_t cell_permutation, int n) const
Apply the inverse of the operator applied by T_apply().
Definition FiniteElement.h:708
std::span< const std::size_t > value_shape() const
Value shape of the finite element field.
Definition FiniteElement.cpp:309
std::pair< std::vector< geometry_type >, std::array< std::size_t, 2 > > create_interpolation_operator(const FiniteElement &from) const
Create a matrix that maps degrees of freedom from one element to this element (interpolation).
Definition FiniteElement.cpp:496
void T_apply(std::span< U > data, std::uint32_t cell_permutation, int n) const
Transform basis functions from the reference element ordering and orientation to the globally consist...
Definition FiniteElement.h:660
basix::maps::type map_type() const
Get the map type used by the element.
Definition FiniteElement.cpp:425
int space_dimension() const noexcept
Dimension of the finite element function space (the number of degrees-of-freedom for the element).
Definition FiniteElement.cpp:291
void tabulate(std::span< geometry_type > values, std::span< const geometry_type > X, std::array< std::size_t, 2 > shape, int order) const
Evaluate derivatives of the basis functions up to given order at points in the reference cell.
Definition FiniteElement.cpp:365
void Tt_inv_apply_right(std::span< U > data, std::uint32_t cell_permutation, int n) const
Right(post)-apply the transpose inverse of the operator applied by T_apply().
Definition FiniteElement.h:775
FiniteElement & operator=(FiniteElement &&element)=default
Move assignment.
bool needs_dof_transformations() const noexcept
Check if DOF transformations are needed for this element.
Definition FiniteElement.cpp:539
FiniteElement(const FiniteElement &element)=delete
Copy constructor.
void Tt_inv_apply(std::span< U > data, std::uint32_t cell_permutation, int n) const
Apply the inverse transpose of the operator applied by T_apply().
Definition FiniteElement.h:676
std::pair< std::vector< geometry_type >, std::array< std::size_t, 2 > > interpolation_points() const
Points on the reference cell at which an expression needs to be evaluated in order to interpolate the...
Definition FiniteElement.cpp:464
std::shared_ptr< const FiniteElement< geometry_type > > extract_sub_element(const std::vector< int > &component) const
Extract sub finite element for component.
Definition FiniteElement.cpp:403
void T_apply_right(std::span< U > data, std::uint32_t cell_permutation, int n) const
Right(post)-apply the operator applied by T_apply().
Definition FiniteElement.h:724
std::string signature() const noexcept
String identifying the finite element.
Definition FiniteElement.cpp:285
bool needs_dof_permutations() const noexcept
Check if DOF permutations are needed for this element.
Definition FiniteElement.cpp:545
const std::vector< std::vector< std::vector< int > > > & entity_dofs() const noexcept
Local DOFs associated with each sub-entity of the cell.
Definition FiniteElement.cpp:340
bool is_mixed() const noexcept
Check if element is a mixed element.
Definition FiniteElement.cpp:389
int reference_value_size() const
Value size of the base (non-blocked) finite element field.
Definition FiniteElement.cpp:318
int value_size() const
Value size of the finite element field.
Definition FiniteElement.cpp:297
std::function< void(std::span< U >, std::span< const std::uint32_t >, std::int32_t, int)> dof_transformation_fn(doftransform ttype, bool scalar_element=false) const
Return a function that applies a DOF transformation operator to some data (see T_apply()).
Definition FiniteElement.h:435
bool operator!=(const FiniteElement &e) const
Check if two elements are not equivalent.
Definition FiniteElement.cpp:273
~FiniteElement()=default
Destructor.
T geometry_type
Geometry type of the Mesh that the FunctionSpace is defined on.
Definition FiniteElement.h:60
const basix::FiniteElement< geometry_type > & basix_element() const
Return underlying Basix element (if it exists).
Definition FiniteElement.cpp:413
std::function< void(std::span< std::int32_t >, std::uint32_t)> dof_permutation_fn(bool inverse=false, bool scalar_element=false) const
Return a function that applies a degree-of-freedom permutation to some data.
FiniteElement(FiniteElement &&element)=default
Move constructor.
int num_sub_elements() const noexcept
Number of sub elements (for a mixed or blocked element).
Definition FiniteElement.cpp:383
void Tt_apply(std::span< U > data, std::uint32_t cell_permutation, int n) const
Apply the transpose of the operator applied by T_apply().
Definition FiniteElement.h:693
const std::vector< std::vector< std::vector< int > > > & entity_closure_dofs() const noexcept
Local DOFs associated with the closure of each sub-entity of the cell.
Definition FiniteElement.cpp:347
std::pair< std::vector< geometry_type >, std::array< std::size_t, 2 > > interpolation_operator() const
Definition FiniteElement.cpp:483
int block_size() const noexcept
Block size of the finite element function space.
Definition FiniteElement.cpp:359
std::span< const std::size_t > reference_value_shape() const
Value shape of the base (non-blocked) finite element field.
Definition FiniteElement.cpp:330
void Tt_apply_right(std::span< U > data, std::uint32_t cell_permutation, int n) const
Right(post)-apply the transpose of the operator applied by T_apply().
Definition FiniteElement.h:758
FiniteElement(const basix::FiniteElement< geometry_type > &element, std::optional< std::vector< std::size_t > > value_shape=std::nullopt, bool symmetric=false)
Create a finite element from a Basix finite element.
Definition FiniteElement.cpp:111
std::function< void(std::span< U >, std::span< const std::uint32_t >, std::int32_t, int)> dof_transformation_right_fn(doftransform ttype, bool scalar_element=false) const
Return a function that applies DOF transformation to some transposed data (see T_apply_right()).
Definition FiniteElement.h:538
mesh::CellType cell_type() const noexcept
Cell shape that the element is defined on.
Definition FiniteElement.cpp:279
bool interpolation_ident() const noexcept
Definition FiniteElement.cpp:451
void Tinv_apply_right(std::span< U > data, std::uint32_t cell_permutation, int n) const
Right(post)-apply the inverse of the operator applied by T_apply().
Definition FiniteElement.h:741
bool operator==(const FiniteElement &e) const
Check if two elements are equivalent.
Definition FiniteElement.cpp:261
bool map_ident() const noexcept
Definition FiniteElement.cpp:437
Finite element method functionality.
Definition assemble_matrix_impl.h:26
BasixElementData(U element, V bs, W symmetry) -> BasixElementData< typename std::remove_cvref< U >::type::scalar_type >
Type deduction helper.
doftransform
DOF transformation type.
Definition FiniteElement.h:26
@ inverse_transpose
Transpose inverse.
CellType
Cell type identifier.
Definition cell_types.h:22
Basix element holder.
Definition FiniteElement.h:37
std::optional< std::vector< std::size_t > > value_shape
Value shape. Can only be set for scalar element.
Definition FiniteElement.h:41
bool symmetry
Definition FiniteElement.h:42
std::reference_wrapper< const basix::FiniteElement< T > > element
Finite element.
Definition FiniteElement.h:39