10#include "FunctionSpace.h"
13#include <basix/mdspan.hpp>
16#include <dolfinx/common/types.h>
17#include <dolfinx/mesh/EntityMap.h>
18#include <dolfinx/mesh/Mesh.h>
19#include <dolfinx/mesh/Topology.h>
34template <dolfinx::scalar T>
36template <dolfinx::scalar T, std::
floating_po
int U>
70 throw std::invalid_argument(
"Unknown integral type.");
76template <dolfinx::scalar T, std::
floating_po
int U = scalar_value_t<T>>
84 template <
typename K,
typename V,
typename W>
85 requires std::is_convertible_v<
86 std::remove_cvref_t<K>,
87 std::function<void(T*,
const T*,
const T*,
const U*,
88 const int*,
const std::uint8_t*,
void*)>>
89 and std::is_convertible_v<std::remove_cvref_t<V>,
90 std::vector<std::int32_t>>
91 and std::is_convertible_v<std::remove_cvref_t<W>,
100 std::function<void(T*,
const T*,
const T*,
const U*,
const int*,
101 const std::uint8_t*,
void*)>
140template <dolfinx::scalar T, std::
floating_po
int U = dolfinx::scalar_value_t<T>>
175 template <
typename X>
176 requires std::is_convertible_v<
177 std::remove_cvref_t<X>,
178 std::map<std::tuple<IntegralType, int, int>,
189 const std::vector<std::reference_wrapper<const mesh::EntityMap>>&
191 : _function_spaces(V), _integrals(std::forward<X>(integrals)),
197 throw std::invalid_argument(
"Form Mesh is null.");
203 const int tdim = topology.
dim();
210 &topology](
IntegralType type, std::span<const std::int32_t> entities,
217 topology0, topology, md::mdspan(entities.data(), entities.size()),
223 throw std::invalid_argument(
224 "Vertex integrals are not supported for a form with an argument "
225 "or coefficient on another mesh. Supported types are cell, "
226 "exterior facet, interior facet and ridge.");
237 md::mdspan<
const std::int32_t,
238 md::extents<std::size_t, md::dynamic_extent, 2>>(
239 entities.data(), entities.size() / 2, 2),
246 std::vector<std::int32_t> e(entities.begin(), entities.end());
247 for (std::size_t i = 0; i < cells.size(); ++i)
252 _edata.reserve(_function_spaces.size());
253 for (
auto& space : _function_spaces)
256 std::map<std::tuple<IntegralType, int, int>,
257 std::variant<std::vector<std::int32_t>,
258 std::span<const std::int32_t>>>
261 if (
auto mesh0 = space->mesh(); mesh0 == _mesh)
263 for (
auto& [key, integral] : _integrals)
264 vdata.insert({key, std::span(integral.entities)});
272 for (
auto& [key, itg] : _integrals)
274 auto [type, idx, kernel_idx] = key;
276 {key, map_entities(type, itg.entities, topology0, emap)});
280 _edata.push_back(std::move(vdata));
283 for (
auto& [key, integral] : _integrals)
285 auto [type, idx, kernel_idx] = key;
286 for (
int c : integral.coeffs)
288 if (
auto mesh0 =
coefficients.at(c)->function_space()->mesh();
291 _cdata.insert({{type, idx, c}, std::span(integral.entities)});
301 map_entities(type, integral.entities, topology0, emap)});
322 Form(
Form&& form)
noexcept =
default;
332 Form& operator=(
const Form& form) =
delete;
346 int rank()
const {
return _function_spaces.size(); }
350 std::shared_ptr<const mesh::Mesh<geometry_type>>
mesh()
const
357 const std::vector<std::shared_ptr<const FunctionSpace<geometry_type>>>&
360 return _function_spaces;
376 auto it = _integrals.find({type, idx, kernel_idx});
377 if (it == _integrals.end())
378 throw std::out_of_range(
"Requested integral kernel not found.");
379 return it->second.kernel;
386 std::set<IntegralType> types;
387 for (
auto& [key, integral] : _integrals)
388 types.insert(std::get<0>(key));
407 auto it = std::ranges::find_if(_integrals,
410 auto [t, idx_, kernel_idx] = x.first;
411 return t == type and idx_ == idx;
413 if (it == _integrals.end())
414 throw std::out_of_range(
"Could not find active coefficient list.");
415 return it->second.coeffs;
436 return std::ranges::count_if(_integrals,
437 [type, kernel_idx](
auto& x)
439 auto [t, id, k_idx] = x.first;
440 return t == type and k_idx == kernel_idx;
479 int kernel_idx)
const
481 auto it = _integrals.find({type, idx, kernel_idx});
482 if (it == _integrals.end())
483 throw std::out_of_range(
"Requested domain not found.");
484 return it->second.entities;
523 int kernel_idx)
const
525 auto it = _edata.at(
rank).find({type, idx, kernel_idx});
526 if (it == _edata.at(
rank).end())
527 throw std::out_of_range(
"Requested domain for argument not found.");
529 return std::visit([](
const auto& v) -> std::span<const std::int32_t>
530 {
return v; }, it->second);
550 auto it = _cdata.find({type, idx, c});
551 if (it == _cdata.end())
552 throw std::out_of_range(
"No domain for requested integral.");
553 return std::visit([](
const auto& v) -> std::span<const std::int32_t>
554 {
return v; }, it->second);
560 std::shared_ptr<const Function<scalar_type, geometry_type>>>&
563 return _coefficients;
579 std::vector<int> n{0};
580 n.reserve(_coefficients.size() + 1);
581 for (
auto& c : _coefficients)
584 throw std::runtime_error(
"Not all form coefficients have been set.");
585 n.push_back(n.back() + c->function_space()->element()->space_dimension());
592 const std::vector<std::shared_ptr<const Constant<scalar_type>>>&
600 std::vector<std::shared_ptr<const FunctionSpace<geometry_type>>>
604 std::map<std::tuple<IntegralType, int, int>,
609 std::shared_ptr<const mesh::Mesh<geometry_type>> _mesh;
612 std::vector<std::shared_ptr<const Function<scalar_type, geometry_type>>>
616 std::vector<std::shared_ptr<const Constant<scalar_type>>> _constants;
619 bool _needs_facet_permutations;
631 std::vector<std::map<
632 std::tuple<IntegralType, int, int>,
633 std::variant<std::vector<std::int32_t>, std::span<const std::int32_t>>>>
649 std::tuple<IntegralType, int, int>,
650 std::variant<std::vector<std::int32_t>, std::span<const std::int32_t>>>
Constant (in space) value which can be attached to a Form.
Definition Constant.h:22
This class represents a finite element function space defined by a mesh, a finite element,...
Definition FunctionSpace.h:36
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:52
int dim() const noexcept
Topological dimension of the mesh.
Definition Topology.cpp:898
Finite element method functionality.
Definition assemble_expression_impl.h:28
IntegralType
Type of integral.
Definition Form.h:41
@ 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
constexpr int integral_entity_dim(IntegralType type, int tdim)
Topological dimension of the mesh entities an integral of the given type is over.
Definition Form.h:55
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 entities of a topology to the cells of a related topology, e.g. the integration entities of a for...
Definition EntityMap.h:253
void check_entity_cell_mapping(const Topology &topology_c, const Topology &topology, int dim)
Check that entities of a topology can be mapped to cells of a related topology.
Definition EntityMap.cpp:54
Represents integral data, containing the kernel, and a list of entities to integrate over and the ind...
Definition Form.h:78
integral_data(K &&kernel, V &&entities, W &&coeffs)
Create a structure to hold integral data.
Definition Form.h:93
std::function< void(T *, const T *, const T *, const U *, const int *, const std::uint8_t *, void *)> kernel
The integration kernel.
Definition Form.h:102
std::vector< int > coeffs
Indices of coefficients (from the form) that are in this integral.
Definition Form.h:110
std::vector< std::int32_t > entities
The entities to integrate over for this integral. These are the entities in 'full' mesh.
Definition Form.h:106