11#include "FunctionSpace.h"
14#include <basix/mdspan.hpp>
16#include <dolfinx/common/IndexMap.h>
17#include <dolfinx/mesh/Geometry.h>
18#include <dolfinx/mesh/Mesh.h>
19#include <dolfinx/mesh/Topology.h>
23namespace dolfinx::fem::impl
45template <dolfinx::scalar T, MDSpan2Int32 XD, std::
floating_po
int U>
46T assemble_cells_scalar(
47 GeometryPack<XD, U> geometry,
const IndexList
auto& cells,
48 const FEkernel<T, U>
auto& kernel, std::span<const T> constants,
49 md::mdspan<
const T, md::dextents<std::size_t, 2>> coeffs,
50 ScratchBuffer<U>
auto cdofs_b)
53 if (std::ranges::empty(cells))
56 const auto x_dofmap = geometry.dofmap;
57 const auto ndofs_x = x_dofmap.extent(1);
58 assert(cdofs_b.size() == 3 *
static_cast<std::size_t
>(ndofs_x));
60 const T* coeffs_data = coeffs.data_handle();
61 const auto cstride = coeffs.extent(1);
64 const std::size_t num_cells = std::ranges::size(cells);
65 for (std::size_t index = 0; index < num_cells; ++index)
67 std::int32_t c =
cells[index];
69 gather_cell_coordinates(geometry, c, cdofs_b.data());
70 kernel(&value, coeffs_data + index * cstride, constants.data(),
71 cdofs_b.data(),
nullptr,
nullptr,
nullptr);
108template <dolfinx::scalar T, MDSpan2Int32 XD, std::
floating_po
int U>
109T assemble_entities_scalar(
110 GeometryPack<XD, U> geometry,
111 md::mdspan<
const std::int32_t,
112 md::extents<std::size_t, md::dynamic_extent, 2>>
114 const FEkernel<T, U>
auto& kernel, std::span<const T> constants,
115 md::mdspan<
const T, md::dextents<std::size_t, 2>> coeffs,
116 md::mdspan<
const std::uint8_t, md::dextents<std::size_t, 2>> perms,
117 ScratchBuffer<U>
auto cdofs_b)
120 if (entities.empty())
123 const auto x_dofmap = geometry.dofmap;
124 const auto ndofs_x = x_dofmap.extent(1);
125 assert(cdofs_b.size() == 3 *
static_cast<std::size_t
>(ndofs_x));
127 const T* coeffs_data = coeffs.data_handle();
128 const auto cstride = coeffs.extent(1);
131 for (std::size_t f = 0; f < entities.extent(0); ++f)
133 std::int32_t
cell = entities(f, 0);
134 std::int32_t local_entity = entities(f, 1);
136 gather_cell_coordinates(geometry,
cell, cdofs_b.data());
139 std::uint8_t perm = perms.empty() ? 0 : perms(
cell, local_entity);
140 kernel(&value, coeffs_data + f * cstride, constants.data(), cdofs_b.data(),
141 &local_entity, &perm,
nullptr);
170template <dolfinx::scalar T, MDSpan2Int32 XD, std::
floating_po
int U>
171T assemble_interior_facets_scalar(
172 GeometryPack<XD, U> geometry,
173 md::mdspan<
const std::int32_t,
174 md::extents<std::size_t, md::dynamic_extent, 2, 2>>
176 const FEkernel<T, U>
auto& kernel, std::span<const T> constants,
177 md::mdspan<
const T, md::extents<std::size_t, md::dynamic_extent, 2,
180 md::mdspan<
const std::uint8_t, md::dextents<std::size_t, 2>> perms,
181 ScratchBuffer<U>
auto cdofs_b)
188 const auto x_dofmap = geometry.dofmap;
189 const auto ndofs_x = x_dofmap.extent(1);
190 assert(cdofs_b.size() == 2 * 3 *
static_cast<std::size_t
>(ndofs_x));
191 U* cdofs0 = cdofs_b.data();
192 U* cdofs1 = cdofs_b.data() + 3 * ndofs_x;
194 const T* coeffs_data = coeffs.data_handle();
195 const auto cstride = 2 * coeffs.extent(2);
198 for (std::size_t f = 0; f < facets.extent(0); ++f)
200 std::array
cells = {facets(f, 0, 0), facets(f, 1, 0)};
201 std::array local_facet = {facets(f, 0, 1), facets(f, 1, 1)};
203 gather_cell_coordinates(geometry, cells[0], cdofs0);
204 gather_cell_coordinates(geometry, cells[1], cdofs1);
206 std::array perm = perms.empty()
207 ? std::array<std::uint8_t, 2>{0, 0}
208 : std::array{perms(cells[0], local_facet[0]),
209 perms(cells[1], local_facet[1])};
210 kernel(&value, coeffs_data + f * cstride, constants.data(), cdofs_b.data(),
211 local_facet.data(), perm.data(),
nullptr);
231template <dolfinx::scalar T, std::
floating_po
int U>
233 const fem::Form<T, U>& M, mdspan2_t x_dofmap,
234 md::mdspan<
const U, md::extents<std::size_t, md::dynamic_extent, 3>> x,
235 std::span<const T> constants,
236 const std::map<std::pair<IntegralType, int>,
237 std::pair<std::span<const T>,
int>>& coefficients,
238 std::size_t cell_type_idx)
240 std::shared_ptr<const mesh::Mesh<U>> mesh = M.mesh();
246 std::vector<U> cdofs_b(2 * 3 * x_dofmap.extent(1));
247 std::span cdofs_b1 = std::span(cdofs_b).first(3 * x_dofmap.extent(1));
248 GeometryPack geometry{x_dofmap, x};
256 std::span<const std::int32_t>
cells
258 assert(
cells.size() * cstride == coeffs.size());
259 value += impl::assemble_cells_scalar(
260 geometry, cells, fn, constants,
261 md::mdspan(coeffs.data(),
cells.size(), cstride), cdofs_b1);
264 md::mdspan<const std::uint8_t, md::dextents<std::size_t, 2>> facet_perms;
265 if (M.needs_facet_permutations())
267 facet_perms = impl::entity_permutations(
269 mesh->topology()->cell_types()[cell_type_idx]);
277 auto& [coeffs, cstride]
281 constexpr std::size_t num_adjacent_cells = 2;
283 constexpr std::size_t shape1 = 2 * num_adjacent_cells;
285 assert((facets.size() / shape1) * 2 * cstride == coeffs.size());
286 value += impl::assemble_interior_facets_scalar(
288 md::mdspan<
const std::int32_t,
289 md::extents<std::size_t, md::dynamic_extent, 2, 2>>(
290 facets.data(), facets.size() / shape1, 2, 2),
292 md::mdspan<
const T, md::extents<std::size_t, md::dynamic_extent, 2,
293 md::dynamic_extent>>(
294 coeffs.data(), facets.size() / shape1, 2, cstride),
295 facet_perms, std::span(cdofs_b));
301 const int num_itg = M.num_integrals(itg_type, cell_type_idx);
308 md::mdspan<const std::uint8_t, md::dextents<std::size_t, 2>> perms;
309 if (M.needs_facet_permutations())
311 perms = impl::entity_permutations(
312 *mesh->topology_mutable(), itg_type,
313 mesh->topology()->cell_types()[cell_type_idx]);
316 for (
int i = 0; i < num_itg; ++i)
318 auto fn = M.kernel(itg_type, i, cell_type_idx);
320 auto& [coeffs, cstride] = coefficients.at({itg_type, i});
322 std::span entities = M.domain(itg_type, i, cell_type_idx);
325 assert((entities.size() / 2) * cstride == coeffs.size());
326 value += impl::assemble_entities_scalar(
328 md::mdspan<
const std::int32_t,
329 md::extents<std::size_t, md::dynamic_extent, 2>>(
330 entities.data(), entities.size() / 2, 2),
332 md::mdspan(coeffs.data(), entities.size() / 2, cstride), perms,
void cells(la::SparsityPattern &pattern, const std::pair< R0, R1 > &cells, std::array< std::reference_wrapper< const DofMap >, 2 > dofmaps)
Iterate over cells and insert entries into sparsity pattern.
Definition sparsitybuild.h:37
@ vertex
Vertex.
Definition Form.h:47
@ interior_facet
Interior facet.
Definition Form.h:46
@ ridge
Ridge.
Definition Form.h:48
@ cell
Cell.
Definition Form.h:44
@ exterior_facet
Exterior facet.
Definition Form.h:45