11#include <basix/mdspan.hpp>
15#include <dolfinx/common/IndexMap.h>
16#include <dolfinx/common/types.h>
17#include <dolfinx/graph/AdjacencyList.h>
27#include <unordered_map>
52 requires std::is_convertible_v<std::remove_cvref_t<U>,
53 std::vector<std::int32_t>>
62 throw std::invalid_argument(
"topology must not be null.");
64 throw std::invalid_argument(
"sub_topology must not be null.");
67 throw std::invalid_argument(
68 "dim out of range for topology/sub_topology.");
72 std::size_t num_ents = e_imap->size_local() + e_imap->num_ghosts();
73 if (num_ents != _sub_topology_to_topology.size())
75 throw std::invalid_argument(
76 "Size mismatch between `sub_topology_to_topology` and index map.");
102 std::shared_ptr<const Topology>
topology()
const;
131 std::size_t num_entities = std::ranges::size(entities);
139 = std::forward<decltype(entities)>(entities)
140 | std::views::transform([
this](std::int32_t i)
141 {
return _sub_topology_to_topology[i]; });
142 std::vector<std::int32_t> mapped_v;
143 mapped_v.reserve(num_entities);
144 std::ranges::copy(mapped, std::back_inserter(mapped_v));
152 std::unordered_map<std::int32_t, std::int32_t> topology_to_sub_topology;
153 topology_to_sub_topology.reserve(_sub_topology_to_topology.size());
154 for (std::size_t i = 0; i < _sub_topology_to_topology.size(); ++i)
156 topology_to_sub_topology.insert(
157 {_sub_topology_to_topology[i],
static_cast<std::int32_t
>(i)});
167 auto mapped = std::forward<decltype(entities)>(entities)
168 | std::views::transform(
169 [&topology_to_sub_topology](std::int32_t i)
173 auto it = topology_to_sub_topology.find(i);
174 return (it != topology_to_sub_topology.end())
178 std::vector<std::int32_t> mapped_v;
179 mapped_v.reserve(num_entities);
180 std::ranges::copy(mapped, std::back_inserter(mapped_v));
190 std::shared_ptr<const Topology> _topology;
195 std::vector<std::int32_t> _sub_topology_to_topology;
199 std::shared_ptr<const Topology> _sub_topology;
209 std::span<
const std::reference_wrapper<const EntityMap>> entity_maps,
210 const Topology& topology0,
const Topology& topology1);
227 requires(std::remove_cvref_t<E>::rank() == 1
228 or std::remove_cvref_t<E>::rank() == 2)
229 and std::same_as<
typename std::remove_cvref_t<E>::value_type,
233 std::optional<std::reference_wrapper<const EntityMap>> entity_map)
235 auto span_to_vector = [](
auto entities)
237 assert(entities.rank() == 1);
239 std::vector<std::int32_t> vec;
240 vec.reserve(entities.extent(0));
241 for (std::size_t i = 0; i < entities.extent(0); ++i)
242 vec.push_back(entities[i]);
246 if (&topology_c == &topology)
249 if constexpr (entities.rank() == 1)
250 return span_to_vector(entities);
253 return span_to_vector(md::submdspan(entities, md::full_extent, 0));
258 throw std::invalid_argument(
259 "An entity map is required when topology_c is not topology.");
261 const EntityMap& emap = entity_map->get();
262 const int tdim = topology.
dim();
263 const int codim = tdim - topology_c.
dim();
264 const bool inverse = emap.
sub_topology().get() == &topology_c;
265 if constexpr (entities.rank() == 1)
270 throw std::invalid_argument(
271 std::format(
"Cannot map cells of a topology of dimension {} to "
272 "cells of a topology of dimension {}.",
273 tdim, topology_c.
dim()));
282 auto cells = md::submdspan(entities, md::full_extent, 0);
291 throw std::invalid_argument(
292 "Unsupported mapping. Can only map from submesh to parent mesh.");
295 std::shared_ptr<const graph::AdjacencyList<std::int32_t>> c_to_e
299 throw std::runtime_error(
300 std::format(
"Topology connectivity from dimension {} to {} not "
302 tdim, tdim - codim));
305 std::vector<std::int32_t> sub_entities;
306 sub_entities.reserve(entities.extent(0));
307 for (std::size_t e = 0; e < entities.extent(0); ++e)
308 sub_entities.push_back(c_to_e->links(entities(e, 0))[entities(e, 1)]);
A bidirectional map relating entities in one topology to another.
Definition EntityMap.h:36
EntityMap(EntityMap &&map)=default
Move constructor.
std::vector< std::int32_t > sub_topology_to_topology(CellRange auto &&entities, bool inverse) const
Map entities between the sub-topology and the parent topology.
Definition EntityMap.h:128
~EntityMap()=default
Destructor.
EntityMap(std::shared_ptr< const Topology > topology, std::shared_ptr< const Topology > sub_topology, int dim, U &&sub_topology_to_topology)
Constructor of a bidirectional map relating entities of dimension dim in topology and sub_topology.
Definition EntityMap.h:54
EntityMap(const EntityMap &map)=default
Copy constructor.
int dim() const
Get the topological dimension of the entities related by this EntityMap.
Definition EntityMap.cpp:18
std::shared_ptr< const Topology > sub_topology() const
Get the sub-topology.
Definition EntityMap.cpp:25
std::shared_ptr< const Topology > topology() const
Get the (parent) topology.
Definition EntityMap.cpp:20
EntityMap & operator=(EntityMap &&map)=default
Move assignment.
Topology stores the topology of a mesh, consisting of mesh entities and connectivity (incidence relat...
Definition Topology.h:49
std::shared_ptr< const graph::AdjacencyList< std::int32_t > > connectivity(std::array< int, 2 > d0, std::array< int, 2 > d1) const
Get the connectivity from entities of topological dimension d0 to dimension d1.
Definition Topology.cpp:958
int dim() const noexcept
Topological dimension of the mesh.
Definition Topology.cpp:897
Requirement on range of cell indices.
Definition Topology.h:32
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