DOLFINx 0.12.0.0
DOLFINx C++
Loading...
Searching...
No Matches
traits.h
1// Copyright (C) 2024-2026 Joseph P. Dean and Garth N. Wells
2// This file is part of DOLFINx (https://www.fenicsproject.org)
3//
4// SPDX-License-Identifier: LGPL-3.0-or-later
5
6#pragma once
7
8#include <array>
9#include <basix/mdspan.hpp>
10#include <concepts>
11#include <cstdint>
12#include <dolfinx/common/types.h>
13#include <ranges>
14#include <span>
15#include <type_traits>
16
17namespace dolfinx::fem
18{
20template <class U, class T>
22 = std::is_invocable_v<U, std::span<T>, std::span<const std::uint32_t>,
23 std::int32_t, int>;
24
33template <typename F>
34constexpr bool is_transform_set(const F& fn)
35{
36 // A reference to a function is never null, and converting one to
37 // bool warns under -Waddress rather than answering the question.
38 if constexpr (std::is_function_v<F>)
39 return true;
40 else if constexpr (requires { static_cast<bool>(fn); })
41 return static_cast<bool>(fn);
42 else
43 return true;
44}
45
50template <class U, class T, class G = dolfinx::scalar_value_t<T>>
51concept FEkernel = std::is_invocable_v<U, T*, const T*, const T*, const G*,
52 const int*, const std::uint8_t*, void*>;
53
55template <class T>
56concept MDSpan2
57 = std::is_convertible_v<
58 std::remove_cvref_t<T>,
59 md::mdspan<const std::int32_t, md::dextents<std::size_t, 2>>>
60 or std::is_convertible_v<
61 std::remove_cvref_t<T>,
62 md::mdspan<const std::int32_t, md::dextents<std::size_t, 1>>>;
63
67template <class T>
70 and std::same_as<typename std::remove_cvref_t<T>::value_type,
71 std::int32_t>;
72
76template <class T, class U>
78 = std::floating_point<U> and dolfinx::MDSpanRank2<T>
79 and std::same_as<typename std::remove_cvref_t<T>::value_type, U>;
80
86template <class C>
87concept IndexList
88 = std::ranges::random_access_range<C> and std::ranges::sized_range<C>
89 and std::same_as<std::ranges::range_value_t<C>, std::int32_t>
90 and requires(const std::remove_reference_t<C>& cells, std::size_t i) {
91 { cells[i] } -> std::convertible_to<std::int32_t>;
92 };
93
99template <class D, std::floating_point U>
100 requires MDSpan2Int32<D>
102{
105
108 md::mdspan<const U, md::extents<std::size_t, md::dynamic_extent, 3>> x;
109};
110
126template <class D, class B, class E>
128{
131
133 B bs;
134
137};
138
141template <class T>
142concept DofMapPackBase = requires(const std::remove_cvref_t<T>& t) {
143 requires MDSpan2Int32<decltype(t.map)>;
144 { t.bs } -> std::convertible_to<int>;
145};
147
153template <class T>
155 = DofMapPackBase<T> and requires(const std::remove_cvref_t<T>& t) {
156 requires std::ranges::view<std::remove_cvref_t<decltype(t.entities)>>;
157 requires IndexList<std::remove_cvref_t<decltype(t.entities)>>;
158 };
159
163template <class T>
165 = DofMapPackBase<T> and requires(const std::remove_cvref_t<T>& t) {
166 { t.entities(0, 0) } -> std::convertible_to<std::int32_t>;
167 };
168
172template <class T>
174 = DofMapPackBase<T> and requires(const std::remove_cvref_t<T>& t) {
175 { t.entities(0, 0, 0) } -> std::convertible_to<std::int32_t>;
176 };
177
185template <class P, class D, class B, class E>
187{
190
194 const P& transform;
195
198 std::span<const std::uint32_t> cell_info;
199};
200
203template <class A, class T>
204concept FormArgumentBase = requires(const std::remove_cvref_t<A>& a) {
205 requires DofTransformKernel<std::remove_cvref_t<decltype(a.transform)>, T>;
206 { a.cell_info } -> std::convertible_to<std::span<const std::uint32_t>>;
207};
209
212template <class A, class T>
214 = FormArgumentBase<A, T> and requires(const std::remove_cvref_t<A>& a) {
215 requires DofMapPackCells<decltype(a.dofmap)>;
216 };
217
220template <class A, class T>
222 = FormArgumentBase<A, T> and requires(const std::remove_cvref_t<A>& a) {
223 requires DofMapPackEntities<decltype(a.dofmap)>;
224 };
225
228template <class A, class T>
230 = FormArgumentBase<A, T> and requires(const std::remove_cvref_t<A>& a) {
231 requires DofMapPackFacets<decltype(a.dofmap)>;
232 };
233
235template <class B>
236inline constexpr bool is_scratch_buffer_type = false;
237
238template <class T, std::size_t N>
239inline constexpr bool is_scratch_buffer_type<std::array<T, N>> = true;
240
241template <class T, std::size_t N>
242inline constexpr bool is_scratch_buffer_type<std::span<T, N>> = true;
244
252template <class B, class T>
254 = is_scratch_buffer_type<std::remove_cvref_t<B>>
255 and std::ranges::contiguous_range<B> and std::ranges::output_range<B, T>
256 and std::same_as<std::ranges::range_value_t<B>, T> and requires(B& b) {
257 { b.data() } -> std::same_as<T*>;
258 { b.size() } -> std::convertible_to<std::size_t>;
259 };
260
264template <class V, class T>
266 = std::same_as<typename std::remove_cvref_t<V>::value_type, T>
267 and requires(std::remove_cvref_t<V>& v, std::int32_t i) {
268 { v[i] } -> std::convertible_to<T&>;
269 };
270
271namespace impl
272{
275using mdspan2_t = md::mdspan<const std::int32_t, md::dextents<std::size_t, 2>>;
276
284template <class D>
285inline constexpr std::size_t static_dofs_per_cell
286 = std::remove_cvref_t<D>::static_extent(1);
287
299template <class XD, std::floating_point U>
300void gather_cell_coordinates(GeometryPack<XD, U> geometry, std::int32_t cell,
301 U* cdofs)
302{
303 const auto x_dofmap = geometry.dofmap;
304 const std::size_t ndofs_x = x_dofmap.extent(1);
305 const std::int32_t* xdofs
306 = x_dofmap.data_handle() + static_cast<std::ptrdiff_t>(cell) * ndofs_x;
307 const U* x = geometry.x.data_handle();
308 for (std::size_t i = 0; i < ndofs_x; ++i)
309 {
310 const U* src = x + static_cast<std::ptrdiff_t>(xdofs[i]) * 3;
311 for (std::size_t k = 0; k < 3; ++k)
312 cdofs[3 * i + k] = src[k];
313 }
314}
315
326template <class F>
327void dispatch_bs(int bs, F&& f)
328{
329 switch (bs)
330 {
331 case 1:
332 return f(std::integral_constant<int, 1>{});
333 case 3:
334 return f(std::integral_constant<int, 3>{});
335 default:
336 return f(bs);
337 }
338}
339
351template <class F>
352void dispatch_bs(int bs0, int bs1, F&& f)
353{
354 if (bs0 == bs1)
355 {
356 switch (bs0)
357 {
358 case 1:
359 return f(std::integral_constant<int, 1>{},
360 std::integral_constant<int, 1>{});
361 case 3:
362 return f(std::integral_constant<int, 3>{},
363 std::integral_constant<int, 3>{});
364 }
365 }
366
367 return f(bs0, bs1);
368}
369} // namespace impl
370} // namespace dolfinx::fem
mdspan/mdarray namespace
Definition types.h:60
Concept for the container that assembled values are accumulated into, indexed by a process-local degr...
Definition traits.h:266
Concept for the degree-of-freedom map data passed to the cell assembly kernel, whose entities are a l...
Definition traits.h:155
Concept for the degree-of-freedom map data passed to the entity assembly kernel, whose entities are i...
Definition traits.h:165
Concept for the degree-of-freedom map data passed to the interior facet assembly kernel,...
Definition traits.h:174
DOF transform kernel concept.
Definition traits.h:22
Finite element cell kernel concept.
Definition traits.h:51
Concept for the form argument data passed to the cell assembly kernels.
Definition traits.h:214
Concept for the form argument data passed to the entity assembly kernels.
Definition traits.h:222
Concept for the form argument data passed to the interior facet assembly kernels.
Definition traits.h:230
Concept for a randomly-indexable list of process-local indices, as used for the cell lists passed to ...
Definition traits.h:88
Concept for a rank-2 mdspan of a floating-point type.
Definition traits.h:78
Concept for a rank-2 mdspan of 32-bit indices.
Definition traits.h:69
Concept for mdspan of rank 1 or 2.
Definition traits.h:57
Concept for the mutable scratch buffers passed to the assembly kernels.
Definition traits.h:254
Finite element method functionality.
Definition assemble_expression_impl.h:22
@ cell
Cell.
Definition Form.h:44
constexpr bool is_transform_set(const F &fn)
Whether a DofTransformKernel fn should be invoked.
Definition traits.h:34
Geometry data structures and algorithms.
Definition BoundingBoxTree.h:24
Degree-of-freedom map data for one form argument, as passed to the assembly kernels.
Definition traits.h:128
B bs
Dofmap block size.
Definition traits.h:133
E entities
Entity indices in this argument's mesh.
Definition traits.h:136
D map
Dofmap, shape (num_cells, num_dofs_per_cell).
Definition traits.h:130
Data for one form argument (test or trial function) passed to the assembly kernels.
Definition traits.h:187
std::span< const std::uint32_t > cell_info
Definition traits.h:198
DofMapPack< D, B, E > dofmap
Dofmap, block size and entity indices for this argument.
Definition traits.h:189
const P & transform
Definition traits.h:194
Mesh geometry data passed to the assembly kernels.
Definition traits.h:102
D dofmap
Geometry dofmap, shape (num_cells, num_nodes_per_cell).
Definition traits.h:104
md::mdspan< const U, md::extents< std::size_t, md::dynamic_extent, 3 > > x
Definition traits.h:108