11#include "FiniteElement.h"
14#include "FunctionSpace.h"
18#include <basix/mdspan.hpp>
22#include <dolfinx/mesh/EntityMap.h>
23#include <dolfinx/mesh/Mesh.h>
24#include <dolfinx/mesh/Topology.h>
41template <dolfinx::scalar T, std::
floating_po
int U>
53template <dolfinx::scalar T, std::
floating_po
int U>
54std::span<const std::uint32_t>
55get_cell_orientation_info(
const Function<T, U>& coefficient)
57 std::span<const std::uint32_t> cell_info;
58 auto element = coefficient.function_space()->element();
60 if (element->needs_dof_transformations())
62 auto mesh = coefficient.function_space()->mesh();
63 mesh->topology_mutable()->create_cell_permutations();
64 cell_info = std::span(mesh->topology()->get_cell_permutation_info());
89template <dolfinx::scalar T>
91 std::span<const T> v, std::span<const std::uint32_t> cell_info,
92 const DofMap& dofmap,
auto transform,
bool transform_set)
95 for (std::size_t i = 0; i < dofs.size(); ++i)
96 std::copy_n(v.data() + bs * dofs[i], bs, coeffs.data() + bs * i);
99 transform(coeffs, cell_info,
cell, 1);
118template <dolfinx::scalar T, std::
floating_po
int U>
121 std::span<const std::uint32_t> cell_info,
122 auto cells, std::int32_t offset)
124 static_assert(cells.rank() == 1);
127 std::span<const T> v = u.
x()->array();
131 int space_dim = element->space_dimension();
137 const int bs = dofmap.
bs();
148 auto pack_for_bs = [&cells, &c, &cstride, &offset, &space_dim, &v, &cell_info,
149 &dofmap, &transformation, transform_set](
auto bs)
151 for (std::size_t e = 0; e < cells.extent(0); ++e)
153 if (std::int32_t
cell = cells(e);
cell >= 0)
155 auto cell_coeff = c.subspan(e * cstride + offset, space_dim);
156 pack_impl(cell_coeff,
cell, bs, v, cell_info, dofmap, transformation,
165 pack_for_bs(std::integral_constant<int, 1>());
168 pack_for_bs(std::integral_constant<int, 2>());
171 pack_for_bs(std::integral_constant<int, 3>());
187template <dolfinx::scalar T, std::
floating_po
int U>
188std::pair<std::vector<T>,
int>
192 std::size_t num_entities = 0;
194 if (
const std::vector<std::shared_ptr<
const Function<T, U>>>& coefficients
196 !coefficients.empty())
199 cstride = offsets.back();
211 num_entities = form.
domain(integral_type, idx, 0).size();
216 return {std::vector<T>(num_entities * cstride), cstride};
224template <dolfinx::scalar T, std::
floating_po
int U>
225std::map<std::pair<IntegralType, int>, std::pair<std::vector<T>,
int>>
228 std::map<std::pair<IntegralType, int>, std::pair<std::vector<T>,
int>> coeffs;
235 for (
int idx = 0; idx < n; ++idx)
237 coeffs.emplace_hint(coeffs.end(), std::pair{type, idx},
266template <dolfinx::scalar T, std::
floating_po
int U>
268 std::map<std::pair<IntegralType, int>,
269 std::pair<std::vector<T>,
int>>& coeffs)
271 const std::vector<std::shared_ptr<const Function<T, U>>>& coefficients
275 for (
auto& [integral_key, coeff_data] : coeffs)
277 auto [integral_type, idx] = integral_key;
278 std::vector<T>& c = coeff_data.first;
279 int cstride = coeff_data.second;
280 if (!coefficients.empty())
282 switch (integral_type)
288 const int form_tdim = form.
mesh()->topology()->dim();
294 auto mesh = coefficients[coeff]->function_space()->mesh();
301 if (
int codim = form_tdim -
mesh->topology()->dim(); codim > 0)
303 throw std::invalid_argument(
304 "Should not be packing coefficients with "
305 "codim>0 in a cell integral");
308 std::span<const std::int32_t> cells_b
310 md::mdspan cells(cells_b.data(), cells_b.size());
311 std::span<const std::uint32_t> cell_info
312 = impl::get_cell_orientation_info(*coefficients[coeff]);
313 impl::pack_coefficient_entity(std::span(c), cstride,
314 *coefficients[coeff], cell_info, cells,
325 auto mesh = coefficients[coeff]->function_space()->mesh();
326 std::span<const std::int32_t> facets_b
328 md::mdspan<
const std::int32_t,
329 md::extents<std::size_t, md::dynamic_extent, 4>>
330 facets(facets_b.data(), facets_b.size() / 4, 4);
332 std::span<const std::uint32_t> cell_info
333 = impl::get_cell_orientation_info(*coefficients[coeff]);
344 auto cells0 = md::submdspan(facets, md::full_extent, 0);
345 impl::pack_coefficient_entity(std::span(c), 2 * cstride,
346 *coefficients[coeff], cell_info, cells0,
350 auto cells1 = md::submdspan(facets, md::full_extent, 2);
351 impl::pack_coefficient_entity(std::span(c), 2 * cstride,
352 *coefficients[coeff], cell_info, cells1,
353 offsets[coeff] + offsets[coeff + 1]);
367 auto mesh = coefficients[coeff]->function_space()->mesh();
370 std::span<const std::int32_t> entities_b
372 md::mdspan<
const std::int32_t,
373 md::extents<std::size_t, md::dynamic_extent, 2>>
374 entities(entities_b.data(), entities_b.size() / 2, 2);
375 std::span<const std::uint32_t> cell_info
376 = impl::get_cell_orientation_info(*coefficients[coeff]);
377 impl::pack_coefficient_entity(
378 std::span(c), cstride, *coefficients[coeff], cell_info,
379 md::submdspan(entities, md::full_extent, 0), offsets[coeff]);
384 throw std::invalid_argument(
385 "Could not pack coefficient. Integral type not supported.");
406template <dolfinx::scalar T, std::
floating_po
int U>
408 const std::vector<std::reference_wrapper<
const Function<T, U>>>& coeffs,
410 const std::vector<std::reference_wrapper<const dolfinx::mesh::EntityMap>>&
412 std::span<const int> offsets, std::span<T> c)
415 assert(!offsets.empty());
416 const int cstride = offsets.back();
418 if (c.size() < entities.extent(0) * offsets.back())
419 throw std::invalid_argument(
"Coefficient packing span is too small.");
423 for (std::size_t coeff = 0; coeff < coeffs.size(); ++coeff)
426 std::shared_ptr<const mesh::Mesh<U>> mesh_c
427 = coeffs[coeff].get().function_space()->mesh();
430 std::vector<std::int32_t> coefficient_cells;
431 if (&topology_c == &topology)
434 topology_c, topology, entities, std::nullopt);
441 topology_c, topology, entities, std::cref(emap));
444 std::span<const std::uint32_t> cell_info
445 = impl::get_cell_orientation_info(coeffs[coeff].get());
446 md::mdspan cells(coefficient_cells.data(), coefficient_cells.size());
447 impl::pack_coefficient_entity(std::span(c), cstride, coeffs[coeff].get(),
448 cell_info, cells, offsets[coeff]);
463 std::int32_t size = std::accumulate(
464 c.cbegin(), c.cend(), 0, [](std::int32_t sum,
auto& constant)
465 { return sum + constant.get().value.size(); });
468 std::vector<T> constant_values(size);
469 std::int32_t offset = 0;
470 for (
auto& constant : c)
472 std::ranges::copy(constant.get().value,
473 std::next(constant_values.begin(), offset));
474 offset += constant.get().value.size();
477 return constant_values;
485 requires std::convertible_to<
487 typename std::decay_t<U>::geometry_type>>
488 or std::convertible_to<
490 typename std::decay_t<U>::geometry_type>>
493 using T =
typename std::decay_t<U>::scalar_type;
494 std::vector<std::reference_wrapper<const Constant<T>>> c;
495 c.reserve(u.constants().size());
496 std::ranges::transform(u.constants(), std::back_inserter(c),
Degree-of-freedom map representations and tools.
Constant (in space) value which can be attached to a Form.
Definition Constant.h:22
Degree-of-freedom map.
Definition DofMap.h:73
std::span< const std::int32_t > cell_dofs(std::int32_t c) const
Local-to-global mapping of dofs on a cell.
Definition DofMap.h:127
int bs() const noexcept
Return the block size for the dofmap.
Definition DofMap.cpp:189
An Expression represents a mathematical expression evaluated at a pre-defined points on a reference c...
Definition Expression.h:43
std::shared_ptr< const FunctionSpace< geometry_type > > function_space() const
Access the function space.
Definition Function.h:145
std::shared_ptr< const la::Vector< value_type > > x() const
Underlying vector (const version).
Definition Function.h:151
A bidirectional map relating entities in one topology to another.
Definition EntityMap.h:36
A Mesh consists of a set of connected and numbered mesh topological entities, and geometry data.
Definition Mesh.h:25
Topology stores the topology of a mesh, consisting of mesh entities and connectivity (incidence relat...
Definition Topology.h:49
Concept for mdspan of rank 1 or 2.
Definition traits.h:57
Finite element method functionality.
Definition assemble_expression_impl.h:28
@ transpose
Transpose.
Definition FiniteElement.h:34
void pack_coefficients(const Form< T, U > &form, std::map< std::pair< IntegralType, int >, std::pair< std::vector< T >, int > > &coeffs)
Pack coefficients of a Form.
Definition pack.h:267
std::pair< std::vector< T >, int > allocate_coefficient_storage(const Form< T, U > &form, IntegralType integral_type, int idx)
Allocate storage for coefficients of a pair (integral_type, idx) from a Form.
Definition pack.h:189
IntegralType
Type of integral.
Definition Form.h:43
@ 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
constexpr bool is_transform_set(const F &fn)
Whether a DofTransformKernel fn should be invoked.
Definition traits.h:34
std::vector< T > pack_constants(const std::vector< std::reference_wrapper< const fem::Constant< T > > > &c)
Pack constants of an Expression or Form into a single array ready for assembly.
Definition pack.h:459
Mesh data structures and algorithms on meshes.
Definition DofMap.h:32
const EntityMap & find_entity_map(std::span< const std::reference_wrapper< const EntityMap > > entity_maps, const Topology &topology0, const Topology &topology1)
Find the entity map relating two topologies.
Definition EntityMap.cpp:31
std::vector< std::int32_t > extract_cells_from_entities(const Topology &topology_c, const Topology &topology, E entities, std::optional< std::reference_wrapper< const EntityMap > > entity_map)
Map integration entities of a topology to the cells of a related topology.
Definition EntityMap.h:231
void pack_impl(std::span< T > coeffs, std::int32_t cell, auto bs, std::span< const T > v, std::span< const std::uint32_t > cell_info, const DofMap &dofmap, auto transform, bool transform_set)
Gather a single coefficient's degrees-of-freedom for a single cell and apply its DOF transformation.
Definition pack.h:90
void pack_coefficient_entity(std::span< T > c, int cstride, const Function< T, U > &u, std::span< const std::uint32_t > cell_info, auto cells, std::int32_t offset)
Pack a single coefficient for a set of active entities.
Definition pack.h:119