11#include "FunctionSpace.h"
14#include <basix/mdspan.hpp>
15#include <dolfinx/common/IndexMap.h>
16#include <dolfinx/mesh/Geometry.h>
17#include <dolfinx/mesh/Mesh.h>
18#include <dolfinx/mesh/Topology.h>
23namespace dolfinx::fem::impl
31template <dolfinx::scalar T, std::
floating_po
int U>
34 md::mdspan<
const U, md::extents<std::size_t, md::dynamic_extent, 3>> x,
35 std::span<const std::int32_t> cells,
const FEkernel<T, U>
auto& fn,
36 std::span<const T> constants,
37 md::mdspan<
const T, md::dextents<std::size_t, 2>> coeffs,
38 std::span<std::type_identity_t<U>> cdofs_b)
44 assert(cdofs_b.size() >= 3 * x_dofmap.extent(1));
47 for (std::size_t index = 0; index <
cells.size(); ++index)
49 std::int32_t c =
cells[index];
52 auto x_dofs = md::submdspan(x_dofmap, c, md::full_extent);
53 for (std::size_t i = 0; i < x_dofs.size(); ++i)
54 std::copy_n(&x(x_dofs[i], 0), 3, std::next(cdofs_b.begin(), 3 * i));
56 fn(&value, &coeffs(index, 0), constants.data(), cdofs_b.data(),
nullptr,
78template <dolfinx::scalar T, std::
floating_po
int U>
81 md::mdspan<
const U, md::extents<std::size_t, md::dynamic_extent, 3>> x,
82 md::mdspan<
const std::int32_t,
83 md::extents<std::size_t, md::dynamic_extent, 2>>
85 const FEkernel<T, U>
auto& fn, std::span<const T> constants,
86 md::mdspan<
const T, md::dextents<std::size_t, 2>> coeffs,
87 md::mdspan<
const std::uint8_t, md::dextents<std::size_t, 2>> perms,
88 std::span<std::type_identity_t<U>> cdofs_b)
94 assert(cdofs_b.size() >= 3 * x_dofmap.extent(1));
97 for (std::size_t f = 0; f < entities.extent(0); ++f)
99 std::int32_t
cell = entities(f, 0);
100 std::int32_t local_entity = entities(f, 1);
103 auto x_dofs = md::submdspan(x_dofmap,
cell, md::full_extent);
104 for (std::size_t i = 0; i < x_dofs.size(); ++i)
105 std::copy_n(&x(x_dofs[i], 0), 3, std::next(cdofs_b.begin(), 3 * i));
108 std::uint8_t perm = perms.empty() ? 0 : perms(
cell, local_entity);
109 fn(&value, &coeffs(f, 0), constants.data(), cdofs_b.data(), &local_entity,
122template <dolfinx::scalar T, std::
floating_po
int U>
123T assemble_interior_facets(
125 md::mdspan<
const U, md::extents<std::size_t, md::dynamic_extent, 3>> x,
126 md::mdspan<
const std::int32_t,
127 md::extents<std::size_t, md::dynamic_extent, 2, 2>>
129 const FEkernel<T, U>
auto& fn, std::span<const T> constants,
130 md::mdspan<
const T, md::extents<std::size_t, md::dynamic_extent, 2,
133 md::mdspan<
const std::uint8_t, md::dextents<std::size_t, 2>> perms,
134 std::span<std::type_identity_t<U>> cdofs_b)
141 assert(cdofs_b.size() >= 2 * 3 * x_dofmap.extent(1));
142 auto cdofs0 = cdofs_b.first(3 * x_dofmap.extent(1));
143 auto cdofs1 = cdofs_b.last(3 * x_dofmap.extent(1));
146 for (std::size_t f = 0; f < facets.extent(0); ++f)
148 std::array
cells = {facets(f, 0, 0), facets(f, 1, 0)};
149 std::array local_facet = {facets(f, 0, 1), facets(f, 1, 1)};
152 auto x_dofs0 = md::submdspan(x_dofmap, cells[0], md::full_extent);
153 for (std::size_t i = 0; i < x_dofs0.size(); ++i)
154 std::copy_n(&x(x_dofs0[i], 0), 3, std::next(cdofs0.begin(), 3 * i));
155 auto x_dofs1 = md::submdspan(x_dofmap, cells[1], md::full_extent);
156 for (std::size_t i = 0; i < x_dofs1.size(); ++i)
157 std::copy_n(&x(x_dofs1[i], 0), 3, std::next(cdofs1.begin(), 3 * i));
159 std::array perm = perms.empty()
160 ? std::array<std::uint8_t, 2>{0, 0}
161 : std::array{perms(cells[0], local_facet[0]),
162 perms(cells[1], local_facet[1])};
163 fn(&value, &coeffs(f, 0, 0), constants.data(), cdofs_b.data(),
164 local_facet.data(), perm.data(),
nullptr);
171template <dolfinx::scalar T, std::
floating_po
int U>
173 const fem::Form<T, U>& M, mdspan2_t x_dofmap,
174 md::mdspan<
const U, md::extents<std::size_t, md::dynamic_extent, 3>> x,
175 std::span<const T> constants,
176 const std::map<std::pair<IntegralType, int>,
177 std::pair<std::span<const T>,
int>>& coefficients,
178 std::size_t cell_type_idx)
180 std::shared_ptr<const mesh::Mesh<U>> mesh = M.mesh();
183 std::vector<U> cdofs_b(2 * 3 * x_dofmap.extent(1));
191 std::span<const std::int32_t>
cells
193 assert(
cells.size() * cstride == coeffs.size());
194 value += impl::assemble_cells(
195 x_dofmap, x, cells, fn, constants,
196 md::mdspan(coeffs.data(),
cells.size(), cstride), cdofs_b);
199 md::mdspan<const std::uint8_t, md::dextents<std::size_t, 2>> facet_perms;
200 if (M.needs_facet_permutations())
202 mesh::CellType cell_type = mesh->topology()->cell_types()[cell_type_idx];
203 int num_facets_per_cell
206 mesh->topology_mutable()->create_entity_permutations();
207 const std::vector<std::uint8_t>& p
208 = mesh->topology()->get_facet_permutations();
209 facet_perms = md::mdspan(p.data(), p.size() / num_facets_per_cell,
210 num_facets_per_cell);
218 auto& [coeffs, cstride]
222 constexpr std::size_t num_adjacent_cells = 2;
224 constexpr std::size_t shape1 = 2 * num_adjacent_cells;
226 assert((facets.size() / shape1) * 2 * cstride == coeffs.size());
227 value += impl::assemble_interior_facets(
229 md::mdspan<
const std::int32_t,
230 md::extents<std::size_t, md::dynamic_extent, 2, 2>>(
231 facets.data(), facets.size() / shape1, 2, 2),
233 md::mdspan<
const T, md::extents<std::size_t, md::dynamic_extent, 2,
234 md::dynamic_extent>>(
235 coeffs.data(), facets.size() / shape1, 2, cstride),
236 facet_perms, cdofs_b);
242 md::mdspan<const std::uint8_t, md::dextents<std::size_t, 2>> perms
245 : md::mdspan<const std::uint8_t, md::dextents<std::size_t, 2>>{};
247 for (
int i = 0; i < M.num_integrals(itg_type, cell_type_idx); ++i)
249 auto fn = M.kernel(itg_type, i, cell_type_idx);
251 auto& [coeffs, cstride] = coefficients.at({itg_type, i});
253 std::span entities = M.domain(itg_type, i, cell_type_idx);
256 assert((entities.size() / 2) * cstride == coeffs.size());
257 value += impl::assemble_entities(
259 md::mdspan<
const std::int32_t,
260 md::extents<std::size_t, md::dynamic_extent, 2>>(
261 entities.data(), entities.size() / 2, 2),
263 md::mdspan(coeffs.data(), entities.size() / 2, cstride), perms,
Functions supporting finite element method operations.
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:45
@ interior_facet
Interior facet.
Definition Form.h:44
@ ridge
Ridge.
Definition Form.h:46
@ cell
Cell.
Definition Form.h:42
@ exterior_facet
Exterior facet.
Definition Form.h:43
CellType
Cell type identifier.
Definition cell_types.h:22
int cell_num_entities(CellType type, int dim)
Number of entities of dimension.
Definition cell_types.cpp:92