DOLFINx 0.12.0.0
DOLFINx C++
Loading...
Searching...
No Matches
CoordinateElement.h
1// Copyright (C) 2018-2026 Garth N. Wells, Chris N. Richardson and Jørgen S.
2// Dokken
3//
4// This file is part of DOLFINx (https://www.fenicsproject.org)
5//
6// SPDX-License-Identifier: LGPL-3.0-or-later
7
8#pragma once
9
10#include "ElementDofLayout.h"
11#include <algorithm>
12#include <array>
13#include <basix/element-families.h>
14#include <basix/mdspan.hpp>
15#include <cmath>
16#include <concepts>
17#include <cstdint>
18#include <dolfinx/common/math.h>
19#include <dolfinx/mesh/cell_types.h>
20#include <limits>
21#include <memory>
22#include <span>
23
24namespace basix
25{
26template <std::floating_point T>
28}
29
30namespace dolfinx::fem
31{
37template <std::floating_point T>
39{
40public:
43 explicit CoordinateElement(
44 std::shared_ptr<const basix::FiniteElement<T>> element);
45
55 explicit CoordinateElement(mesh::CellType celltype, int degree,
56 basix::element::lagrange_variant type
57 = basix::element::lagrange_variant::unset,
58 bool discontinuous = false);
59
61 ~CoordinateElement() = default;
62
66
69 int degree() const;
70
77 int dim() const;
78
80 basix::element::lagrange_variant variant() const;
81
85 std::uint64_t hash() const;
86
95 std::array<std::size_t, 4> tabulate_shape(std::size_t nd,
96 std::size_t num_points) const;
97
106 void tabulate(int nd, std::span<const T> X, std::array<std::size_t, 2> shape,
107 std::span<T> basis) const;
108
125 void permute_subentity_closure(std::span<std::int32_t> d,
126 std::uint32_t cell_info,
127 mesh::CellType entity_type,
128 int entity_index) const;
129
138 template <typename U, typename V, typename W>
139 static void compute_jacobian(const U& dphi, const V& cell_geometry, W&& J)
140 {
141 math::dot(cell_geometry, dphi, J, true);
142 }
143
147 template <typename U, typename V>
148 static void compute_jacobian_inverse(const U& J, V&& K)
149 {
150 int gdim = J.extent(0);
151 int tdim = K.extent(0);
152 if (gdim == tdim)
153 math::inv(J, K);
154 else
155 math::pinv(J, K);
156 }
157
163 template <typename U>
164 static double
165 compute_jacobian_determinant(const U& J, std::span<typename U::value_type> w)
166 {
167 static_assert(U::rank() == 2, "Must be rank 2");
168 if (J.extent(0) == J.extent(1))
169 return math::det(J);
170 else
171 {
172 assert(w.size() >= 2 * J.extent(0) * J.extent(1));
173 using X = typename U::element_type;
174 using mdspan2_t = md::mdspan<X, md::dextents<std::size_t, 2>>;
175 mdspan2_t B(w.data(), J.extent(1), J.extent(0));
176 mdspan2_t BA(w.data() + J.extent(0) * J.extent(1), B.extent(0),
177 J.extent(1));
178 for (std::size_t i = 0; i < B.extent(0); ++i)
179 for (std::size_t j = 0; j < B.extent(1); ++j)
180 B(i, j) = J(j, i);
181
182 // Zero working memory of BA
183 std::fill_n(BA.data_handle(), BA.size(), 0);
184 math::dot(B, J, BA);
185 return std::sqrt(math::det(BA));
186 }
187 }
188
191
199 template <typename U, typename V, typename W>
200 static void push_forward(U&& x, const V& cell_geometry, const W& phi)
201 {
202 for (std::size_t i = 0; i < x.extent(0); ++i)
203 for (std::size_t j = 0; j < x.extent(1); ++j)
204 x(i, j) = 0;
205
206 // Compute x = phi * cell_geometry;
207 math::dot(phi, cell_geometry, x);
208 }
209
220 template <typename U, typename V, typename W>
221 static void pull_back_affine(U&& X, const V& K, std::array<T, 3> x0,
222 const W& x)
223 {
224 assert(X.extent(0) == x.extent(0));
225 assert(X.extent(1) == K.extent(0));
226 assert(x.extent(1) == K.extent(1));
227 for (std::size_t i = 0; i < X.extent(0); ++i)
228 for (std::size_t j = 0; j < X.extent(1); ++j)
229 X(i, j) = 0;
230
231 // Calculate X for each point
232 for (std::size_t p = 0; p < x.extent(0); ++p)
233 for (std::size_t i = 0; i < K.extent(0); ++i)
234 for (std::size_t j = 0; j < K.extent(1); ++j)
235 X(p, i) += K(i, j) * (x(p, j) - x0[j]);
236 }
237
239 template <typename X>
240 using mdspan2_t = md::mdspan<X, md::dextents<std::size_t, 2>>;
241
257 mdspan2_t<const T> cell_geometry,
258 std::span<T> working_array, double tol,
259 int maxit) const;
260
270 std::size_t pull_back_working_size(std::size_t gdim) const;
271
277 void permute(std::span<std::int32_t> dofs, std::uint32_t cell_perm) const;
278
284 void permute_inv(std::span<std::int32_t> dofs, std::uint32_t cell_perm) const;
285
291 bool needs_dof_permutations() const;
292
295 bool is_affine() const noexcept { return _is_affine; }
296
306 bool is_discontinuous() const;
307
308private:
309 // Flag denoting affine map
310 bool _is_affine;
311
312 // Basix Element
313 std::shared_ptr<const basix::FiniteElement<T>> _element;
314};
315} // namespace dolfinx::fem
Definition CoordinateElement.h:27
ElementDofLayout create_dof_layout() const
Compute and return the dof layout.
Definition CoordinateElement.cpp:80
void permute_subentity_closure(std::span< std::int32_t > d, std::uint32_t cell_info, mesh::CellType entity_type, int entity_index) const
Given the closure DOFs of a cell sub-entity in reference ordering, this function computes the permut...
Definition CoordinateElement.cpp:69
static void compute_jacobian(const U &dphi, const V &cell_geometry, W &&J)
Definition CoordinateElement.h:139
void tabulate(int nd, std::span< const T > X, std::array< std::size_t, 2 > shape, std::span< T > basis) const
Evaluate basis values and derivatives at set of points.
Definition CoordinateElement.cpp:60
CoordinateElement(std::shared_ptr< const basix::FiniteElement< T > > element)
Create a coordinate element from a Basix element.
Definition CoordinateElement.cpp:23
void permute_inv(std::span< std::int32_t > dofs, std::uint32_t cell_perm) const
Reverses a DOF permutation.
Definition CoordinateElement.cpp:200
basix::element::lagrange_variant variant() const
Variant of the element.
Definition CoordinateElement.cpp:230
std::size_t pull_back_working_size(std::size_t gdim) const
Compute the working array size required for pull back.
Definition CoordinateElement.cpp:251
mesh::CellType cell_shape() const
Cell shape.
Definition CoordinateElement.cpp:46
static void compute_jacobian_inverse(const U &J, V &&K)
Compute the inverse of the Jacobian.
Definition CoordinateElement.h:148
~CoordinateElement()=default
Destructor.
bool is_discontinuous() const
Check if the element is the discontinuous version of the coordinate element.
Definition CoordinateElement.cpp:244
std::uint64_t hash() const
Element hash.
Definition CoordinateElement.cpp:237
void pull_back_nonaffine(mdspan2_t< T > X, mdspan2_t< const T > x, mdspan2_t< const T > cell_geometry, std::span< T > working_array, double tol, int maxit) const
Compute reference coordinates X for physical coordinates x for a non-affine map.
Definition CoordinateElement.cpp:88
std::array< std::size_t, 4 > tabulate_shape(std::size_t nd, std::size_t num_points) const
Shape of array to fill when calling tabulate.
Definition CoordinateElement.cpp:53
int degree() const
The polynomial degree of the element.
Definition CoordinateElement.cpp:216
void permute(std::span< std::int32_t > dofs, std::uint32_t cell_perm) const
Permute a list of DOF numbers on a cell.
Definition CoordinateElement.cpp:192
md::mdspan< X, md::dextents< std::size_t, 2 > > mdspan2_t
mdspan typedef
Definition CoordinateElement.h:240
int dim() const
The dimension of the coordinate element space.
Definition CoordinateElement.cpp:223
bool is_affine() const noexcept
Check if geometry map is affine.
Definition CoordinateElement.h:295
static void push_forward(U &&x, const V &cell_geometry, const W &phi)
Compute physical coordinates x for points X in the reference configuration.
Definition CoordinateElement.h:200
static double compute_jacobian_determinant(const U &J, std::span< typename U::value_type > w)
Compute the determinant of the Jacobian.
Definition CoordinateElement.h:165
bool needs_dof_permutations() const
Indicates whether the geometry DOF numbers on each cell need permuting.
Definition CoordinateElement.cpp:208
static void pull_back_affine(U &&X, const V &K, std::array< T, 3 > x0, const W &x)
Compute reference coordinates X for physical coordinates x for an affine map. For the affine case,...
Definition CoordinateElement.h:221
Definition ElementDofLayout.h:31
Finite element method functionality.
Definition assemble_expression_impl.h:24
CellType
Cell type identifier.
Definition cell_types.h:24