DOLFINx 0.12.0.0
DOLFINx C++
Loading...
Searching...
No Matches
EntityMap.h
1// Copyright (C) 2025-2026 Jørgen S. Dokken and Joseph P. Dean
2//
3// This file is part of DOLFINx (https://www.fenicsproject.org)
4//
5// SPDX-License-Identifier: LGPL-3.0-or-later
6
7#pragma once
8
9#include "Topology.h"
10#include <concepts>
11#include <dolfinx/common/IndexMap.h>
12#include <format>
13#include <ranges>
14#include <span>
15#include <vector>
16
17namespace dolfinx::mesh
18{
22{
23public:
36 template <typename U>
37 requires std::is_convertible_v<std::remove_cvref_t<U>,
38 std::vector<std::int32_t>>
39 EntityMap(std::shared_ptr<const Topology> topology,
40 std::shared_ptr<const Topology> sub_topology, int dim,
42 : _dim(dim), _topology(topology),
43 _sub_topology_to_topology(std::forward<U>(sub_topology_to_topology)),
44 _sub_topology(sub_topology)
45 {
46 auto e_imap = sub_topology->index_map(_dim);
47 if (!e_imap)
48 {
49 throw std::runtime_error(std::format(
50 "No index map for entities, call `Topology::create_entities({})",
51 _dim));
52 }
53
54 std::size_t num_ents = e_imap->size_local() + e_imap->num_ghosts();
55 if (num_ents != _sub_topology_to_topology.size())
56 {
57 throw std::runtime_error(
58 "Size mismatch between `sub_topology_to_topology` and index map.");
59 }
60 }
61
63 EntityMap(const EntityMap& map) = default;
64
66 EntityMap(EntityMap&& map) = default;
67
68 // Destructor
69 ~EntityMap() = default;
70
74 std::size_t dim() const;
75
78 std::shared_ptr<const Topology> topology() const;
79
82 std::shared_ptr<const Topology> sub_topology() const;
83
104 std::vector<std::int32_t> sub_topology_to_topology(CellRange auto&& entities,
105 bool inverse) const
106 {
107 if (!inverse)
108 {
109 // In this case, we want to map from entity indices in
110 // `_sub_topology` to corresponding entities in `_topology`. Hence,
111 // for each index in `entities`, we get the corresponding index in
112 // `_topology` using `_sub_topology_to_topology`
113 auto mapped
114 = std::forward<decltype(entities)>(entities)
115 | std::views::transform([this](std::int32_t i)
116 { return _sub_topology_to_topology[i]; });
117 return std::vector<std::int32_t>(mapped.begin(), mapped.end());
118 }
119 else
120 {
121 // In this case, we are mapping from entity indices in `_topology`
122 // to entity indices in `_sub_topology`. Hence, we first need to
123 // construct the "inverse" of `_sub_topology_to_topology`
124 std::unordered_map<std::int32_t, std::int32_t> topology_to_sub_topology;
125 topology_to_sub_topology.reserve(_sub_topology_to_topology.size());
126 for (std::size_t i = 0; i < _sub_topology_to_topology.size(); ++i)
127 {
128 topology_to_sub_topology.insert(
129 {_sub_topology_to_topology[i], static_cast<std::int32_t>(i)});
130 }
131
132 // For each entity index in `entities` (which are indices in
133 // `_topology`), get the corresponding entity in `_sub_topology`.
134 // Since `_sub_topology` consists of a subset of entities in
135 // `_topology`, there are entities in topology that may not exist in
136 // `_sub_topology`. If this is the case, mark those entities with
137 // -1.
138
139 auto mapped = std::forward<decltype(entities)>(entities)
140 | std::views::transform(
141 [&topology_to_sub_topology](std::int32_t i)
142 {
143 // Map the entity if it exists. If it doesn't, mark
144 // with -1.
145 auto it = topology_to_sub_topology.find(i);
146 return (it != topology_to_sub_topology.end())
147 ? it->second
148 : -1;
149 });
150 return std::vector<std::int32_t>(mapped.begin(), mapped.end());
151 }
152 }
153
154private:
155 // Dimension of the entities
156 std::size_t _dim;
157
158 // A topology
159 std::shared_ptr<const Topology> _topology;
160
161 // A list of `_dim`-dimensional entities in _topology, where
162 // `_sub_topology_to_topology[i]` is the index in `_topology` of the
163 // `i`th entity in `_sub_topology`
164 std::vector<std::int32_t> _sub_topology_to_topology;
165
166 // A second topology, consisting of a subset of entities in
167 // `_topology`
168 std::shared_ptr<const Topology> _sub_topology;
169};
170} // namespace dolfinx::mesh
EntityMap(EntityMap &&map)=default
Move constructor.
std::size_t dim() const
Get the topological dimension of the entities related by this EntityMap.
Definition EntityMap.cpp:16
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:104
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:39
EntityMap(const EntityMap &map)=default
Copy constructor.
std::shared_ptr< const Topology > sub_topology() const
Get the sub-topology.
Definition EntityMap.cpp:23
std::shared_ptr< const Topology > topology() const
Get the (parent) topology.
Definition EntityMap.cpp:18
Requirement on range of cell indices.
Definition Topology.h:32
Mesh data structures and algorithms on meshes.
Definition DofMap.h:32