DOLFINx 0.12.0.0
DOLFINx C++
Loading...
Searching...
No Matches
assemble_expression_impl.h
1// Copyright (C) 2025-2026 Garth N. Wells and Jørgen S. Dokken
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 "FiniteElement.h"
10#include "traits.h"
11#include <algorithm>
12#include <basix/mdspan.hpp>
13#include <cassert>
14#include <cstdint>
15#include <dolfinx/common/IndexMap.h>
16#include <dolfinx/mesh/Geometry.h>
17#include <dolfinx/mesh/Mesh.h>
18#include <dolfinx/mesh/Topology.h>
19#include <functional>
20#include <memory>
21#include <optional>
22#include <span>
23#include <type_traits>
24#include <utility>
25#include <vector>
26
27namespace dolfinx::fem::impl
28{
70template <dolfinx::scalar T, std::floating_point U>
72 std::span<T> values, const fem::FEkernel<T, U> auto& fn,
73 std::array<std::size_t, 2> Xshape, std::size_t value_size,
74 std::size_t num_argument_dofs,
75 md::mdspan<const std::int32_t, md::dextents<std::size_t, 2>> x_dofmap,
76 std::span<const U> x,
77 md::mdspan<const T, md::dextents<std::size_t, 2>> coeffs,
78 std::span<const T> constants, fem::MDSpan2 auto entities,
79 std::span<const std::uint32_t> cell_info,
80 std::span<const std::int32_t> argument_cells,
81 const fem::DofTransformKernel<T> auto& P0,
82 md::mdspan<const std::uint8_t, md::dextents<std::size_t, 2>> perms)
83{
84 static_assert(entities.rank() == 1 or entities.rank() == 2);
85
86 // Create data structures used in evaluation
87 std::vector<U> coord_dofs(3 * x_dofmap.extent(1));
89 x_dofmap,
90 md::mdspan<const U, md::extents<std::size_t, md::dynamic_extent, 3>>(
91 x.data(), x.size() / 3, 3)};
92
93 // Iterate over cells and 'assemble' into values
94 int size0 = Xshape[0] * value_size;
95 std::vector<T> values_local(size0 * num_argument_dofs, 0);
96 std::size_t offset = values_local.size();
97
98 const T* coeffs_data = coeffs.data_handle();
99 const std::size_t cstride = coeffs.extent(1);
100
101 for (std::size_t e = 0; e < entities.extent(0); ++e)
102 {
103 std::ranges::fill(values_local, T(0));
104 if constexpr (entities.rank() == 1)
105 {
106 std::int32_t entity = entities(e);
107 gather_cell_coordinates(geometry, entity, coord_dofs.data());
108 fn(values_local.data(), coeffs_data + e * cstride, constants.data(),
109 coord_dofs.data(), nullptr, nullptr, nullptr);
110
111 P0(values_local, cell_info,
112 argument_cells.empty() ? entity : argument_cells[e], size0);
113 }
114 else
115 {
116 std::int32_t entity = entities(e, 0);
117 std::int32_t local_entity = entities(e, 1);
118 std::uint8_t perm = perms.empty() ? 0 : perms(entity, local_entity);
119 gather_cell_coordinates(geometry, entity, coord_dofs.data());
120 fn(values_local.data(), coeffs_data + e * cstride, constants.data(),
121 coord_dofs.data(), &local_entity, &perm, nullptr);
122 P0(values_local, cell_info,
123 argument_cells.empty() ? entity : argument_cells[e], size0);
124 }
125
126 for (std::size_t j = 0; j < values_local.size(); ++j)
127 values[e * offset + j] = values_local[j];
128 }
129}
130
168template <dolfinx::scalar T, std::floating_point U>
170 std::span<T> values, const fem::FEkernel<T, U> auto& fn,
171 std::array<std::size_t, 2> Xshape, std::size_t value_size,
172 md::mdspan<const T, md::dextents<std::size_t, 2>> coeffs,
173 std::span<const T> constants, const mesh::Mesh<U>& mesh,
174 fem::MDSpan2 auto entities,
175 std::optional<
176 std::pair<std::reference_wrapper<const FiniteElement<U>>, std::size_t>>
177 element,
178 std::span<const std::uint32_t> cell_info,
179 std::span<const std::int32_t> argument_cells)
180{
181 assert(argument_cells.empty() or argument_cells.size() == entities.extent(0));
182
183 std::function<void(std::span<T>, std::span<const std::uint32_t>, std::int32_t,
184 int)>
185 post_dof_transform
186 = [](std::span<T>, std::span<const std::uint32_t>, std::int32_t, int)
187 {
188 // Do nothing
189 };
190
191 std::size_t num_argument_dofs = 1;
192 if (element)
193 {
194 num_argument_dofs = element->second;
195 if (element->first.get().needs_dof_transformations())
196 {
197 post_dof_transform
198 = element->first.get().template dof_transformation_right_fn<T>(
200 }
201 }
202
203 // An expression has no notion of requiring a facet permutation.
204 md::mdspan<const std::uint8_t, md::dextents<std::size_t, 2>> facet_perms;
205 if constexpr (std::remove_cvref_t<decltype(entities)>::rank() == 2)
206 {
207 const int facet_dim = mesh.topology()->dim() - 1;
208 mesh::CellType cell_type = mesh.topology()->cell_types()[0];
209 int num_facets_per_cell = mesh::cell_num_entities(cell_type, facet_dim);
210 mesh.topology_mutable()->create_entity_permutations(facet_dim);
211 const std::vector<std::uint8_t>& p
212 = mesh.topology()->get_entity_permutations(facet_dim);
213 facet_perms = md::mdspan(p.data(), p.size() / num_facets_per_cell,
214 num_facets_per_cell);
215 }
216 tabulate_expression(values, fn, Xshape, value_size, num_argument_dofs,
217 mesh.geometry().dofmaps().front(), mesh.geometry().x(),
218 coeffs, constants, entities, cell_info, argument_cells,
219 post_dof_transform, facet_perms);
220}
221} // namespace dolfinx::fem::impl
Model of a finite element.
Definition FiniteElement.h:201
A Mesh consists of a set of connected and numbered mesh topological entities, and geometry data.
Definition Mesh.h:25
DOF transform kernel concept.
Definition traits.h:22
Finite element cell kernel concept.
Definition traits.h:51
Concept for mdspan of rank 1 or 2.
Definition traits.h:57
void tabulate_expression(std::span< T > values, const fem::Expression< T, U > &e, md::mdspan< const T, md::dextents< std::size_t, 2 > > coeffs, std::span< const T > constants, const mesh::Mesh< U > &mesh, fem::MDSpan2 auto entities, std::optional< std::pair< std::reference_wrapper< const FiniteElement< U > >, std::size_t > > element)
Evaluate an Expression on cells or facets.
Definition expression_evaluate.h:75
@ transpose
Transpose.
Definition FiniteElement.h:34
Geometry data structures and algorithms.
Definition BoundingBoxTree.h:26
Mesh data structures and algorithms on meshes.
Definition DofMap.h:32
CellType
Cell type identifier.
Definition cell_types.h:24
int cell_num_entities(CellType type, int dim)
Number of entities of dimension.
Definition cell_types.cpp:97
Mesh geometry data passed to the assembly kernels.
Definition traits.h:102