23namespace dolfinx::fem::impl
63template <dolfinx::scalar T, std::
floating_po
int U>
66 std::array<std::size_t, 2> Xshape, std::size_t value_size,
67 std::size_t num_argument_dofs,
68 md::mdspan<
const std::int32_t, md::dextents<std::size_t, 2>> x_dofmap,
70 md::mdspan<
const T, md::dextents<std::size_t, 2>> coeffs,
71 std::span<const T> constants,
fem::MDSpan2 auto entities,
72 std::span<const std::uint32_t> cell_info,
74 md::mdspan<
const std::uint8_t, md::dextents<std::size_t, 2>> perms)
76 static_assert(entities.rank() == 1 or entities.rank() == 2);
79 std::vector<U> coord_dofs(3 * x_dofmap.extent(1));
82 int size0 = Xshape[0] * value_size;
83 std::vector<T> values_local(size0 * num_argument_dofs, 0);
84 std::size_t offset = values_local.size();
86 const T* coeffs_data = coeffs.data_handle();
87 const std::size_t cstride = coeffs.extent(1);
89 for (std::size_t e = 0; e < entities.extent(0); ++e)
91 std::ranges::fill(values_local, 0);
92 if constexpr (entities.rank() == 1)
94 std::int32_t entity = entities(e);
95 auto x_dofs = md::submdspan(x_dofmap, entity, md::full_extent);
96 for (std::size_t i = 0; i < x_dofs.size(); ++i)
98 std::copy_n(std::next(x.begin(), 3 * x_dofs[i]), 3,
99 std::next(coord_dofs.begin(), 3 * i));
101 fn(values_local.data(), coeffs_data + e * cstride, constants.data(),
102 coord_dofs.data(),
nullptr,
nullptr,
nullptr);
104 P0(values_local, cell_info, entity, size0);
108 std::int32_t entity = entities(e, 0);
109 std::int32_t local_entity = entities(e, 1);
110 std::uint8_t perm = perms.empty() ? 0 : perms(entity, local_entity);
111 auto x_dofs = md::submdspan(x_dofmap, entity, md::full_extent);
112 for (std::size_t i = 0; i < x_dofs.size(); ++i)
114 std::copy_n(std::next(x.begin(), 3 * x_dofs[i]), 3,
115 std::next(coord_dofs.begin(), 3 * i));
117 fn(values_local.data(), coeffs_data + e * cstride, constants.data(),
118 coord_dofs.data(), &local_entity, &perm,
nullptr);
119 P0(values_local, cell_info, entity, size0);
122 for (std::size_t j = 0; j < values_local.size(); ++j)
123 values[e * offset + j] = values_local[j];
159template <dolfinx::scalar T, std::
floating_po
int U>
162 std::array<std::size_t, 2> Xshape, std::size_t value_size,
163 md::mdspan<
const T, md::dextents<std::size_t, 2>> coeffs,
170 std::function<void(std::span<T>, std::span<const std::uint32_t>, std::int32_t,
173 = [](std::span<T>, std::span<const std::uint32_t>, std::int32_t, int)
178 std::shared_ptr<const mesh::Topology> topology =
mesh.topology();
180 std::size_t num_argument_dofs = 1;
181 std::span<const std::uint32_t> cell_info;
184 num_argument_dofs = element->second;
185 if (element->first.get().needs_dof_transformations())
187 mesh.topology_mutable()->create_entity_permutations();
188 cell_info = std::span(topology->get_cell_permutation_info());
190 = element->first.get().template dof_transformation_right_fn<T>(
196 md::mdspan<const std::uint8_t, md::dextents<std::size_t, 2>> facet_perms;
197 if constexpr (std::remove_cvref_t<
decltype(entities)>::rank() == 2)
200 int num_facets_per_cell
202 mesh.topology_mutable()->create_entity_permutations();
203 const std::vector<std::uint8_t>& p
204 =
mesh.topology()->get_facet_permutations();
205 facet_perms = md::mdspan(p.data(), p.size() / num_facets_per_cell,
206 num_facets_per_cell);
209 mesh.geometry().dofmaps().front(),
210 mesh.geometry().x(), coeffs, constants, entities,
211 cell_info, post_dof_transform, facet_perms);
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 assembler.h:66