File: Topology.h

package info (click to toggle)
fenics-dolfinx 1%3A0.10.0.post4-1exp1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 6,028 kB
  • sloc: cpp: 36,535; python: 25,391; makefile: 226; sh: 171; xml: 55
file content (360 lines) | stat: -rw-r--r-- 15,148 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
// Copyright (C) 2006-2024 Anders Logg and Garth N. Wells
//
// This file is part of DOLFINx (https://www.fenicsproject.org)
//
// SPDX-License-Identifier:    LGPL-3.0-or-later

#pragma once

#include <array>
#include <cstdint>
#include <dolfinx/common/MPI.h>
#include <dolfinx/graph/AdjacencyList.h>
#include <map>
#include <memory>
#include <optional>
#include <span>
#include <tuple>
#include <utility>
#include <vector>

namespace dolfinx::common
{
class IndexMap;
}

namespace dolfinx::mesh
{
enum class CellType : std::int8_t;

/// @brief Topology stores the topology of a mesh, consisting of mesh
/// entities and connectivity (incidence relations for the mesh
/// entities).
///
/// A mesh entity e may be identified globally as a pair `e = (dim, i)`,
/// where dim is the topological dimension and i is the index of the
/// entity within that topological dimension.
///
/// @todo Rework memory management and associated API. Currently, the
/// caching policy is not clear.
class Topology
{
public:
  /// @brief Create a mesh topology.
  ///
  /// A Topology represents the connectivity of a mesh. Mesh entities,
  /// i.e. vertices, edges, faces and cells, are defined in terms of
  /// their vertices. Connectivity represents the relationships between
  /// entities, e.g. the cells that are connected to a given edge in the
  /// mesh.
  ///
  /// @param[in] cell_types Types of cells.
  /// @param[in] vertex_map Index map describing the distribution of
  /// mesh vertices.
  /// @param[in] cell_maps Index maps describing the distribution of
  /// mesh cells for each cell type in `cell_types`.
  /// @param[in] cells Cell-to-vertex connectivities for each cell type
  /// in `cell_types`.
  /// @param[in] original_cell_index Original indices for each cell in
  /// `cells`.
  Topology(
      std::vector<CellType> cell_types,
      std::shared_ptr<const common::IndexMap> vertex_map,
      std::vector<std::shared_ptr<const common::IndexMap>> cell_maps,
      std::vector<std::shared_ptr<graph::AdjacencyList<std::int32_t>>> cells,
      const std::optional<std::vector<std::vector<std::int64_t>>>&
          original_cell_index
      = std::nullopt);

  /// Copy constructor
  Topology(const Topology& topology) = default;

  /// Move constructor
  Topology(Topology&& topology) = default;

  /// Destructor
  ~Topology() = default;

  /// Assignment
  Topology& operator=(const Topology& topology) = delete;

  /// Assignment
  Topology& operator=(Topology&& topology) = default;

  /// @brief Topological dimension of the mesh.
  int dim() const noexcept;

  /// @brief Entity types in the topology for a given dimension.
  /// @param[in] dim Topological dimension.
  /// @return Entity types.
  const std::vector<CellType>& entity_types(int dim) const;

  /// @brief Cell type.
  ///
  /// This function is is for topologies with one cell type only.
  ///
  /// @return Cell type that the topology is for.
  CellType cell_type() const;

  /// @brief Get the index maps that described the parallel distribution
  /// of the mesh entities of a given topological dimension.
  ///
  /// @param[in] dim Topological dimension.
  /// @return Index maps, one for each cell type.
  std::vector<std::shared_ptr<const common::IndexMap>>
  index_maps(int dim) const;

  /// @brief Get the IndexMap that described the parallel distribution
  /// of the mesh entities.
  ///
  /// @param[in] dim Topological dimension
  /// @return Index map for the entities of dimension `dim`. Returns
  /// `nullptr` if index map has not been set.
  std::shared_ptr<const common::IndexMap> index_map(int dim) const;

  /// @brief Get the connectivity from entities of topological dimension
  /// `d0` to dimension `d1`.
  ///
  /// The entity type and incident entity type are each described by a
  /// pair `(dim, index)`. The index within a topological dimension
  /// `dim`, is that of the cell type given in `entity_types(dim)`.
  ///
  /// @param[in] d0 Pair of (topological dimension of entities, index of
  /// "entity type" within topological dimension).
  /// @param[in] d1 Pair of (topological dimension of entities, index of
  /// incident "entity type" within topological dimension).
  /// @return AdjacencyList of connectivity from entity type in `d0` to
  /// entity types in `d1`, or `nullptr` if not yet computed.
  std::shared_ptr<const graph::AdjacencyList<std::int32_t>>
  connectivity(std::array<int, 2> d0, std::array<int, 2> d1) const;

  /// @brief Return connectivity from entities of dimension `d0` to
  /// entities of dimension `d1`. Assumes only one entity type per
  /// dimension.
  ///
  /// @param[in] d0 Topological dimension.
  /// @param[in] d1 Topological dimension.
  /// @return The adjacency list that for each entity of dimension `d0`
  /// gives the list of incident entities of dimension `d1`. Returns
  /// `nullptr` if connectivity has not been computed.
  std::shared_ptr<const graph::AdjacencyList<std::int32_t>>
  connectivity(int d0, int d1) const;

  /// @brief Returns the permutation information.
  const std::vector<std::uint32_t>& get_cell_permutation_info() const;

  /// @brief Get the numbers that encode the number of permutations to
  /// apply to facets.
  ///
  /// The permutations are encoded so that:
  ///
  ///   - `n % 2` gives the number of reflections to apply
  ///   - `n // 2` gives the number of rotations to apply
  ///
  /// The data is stored in a flattened 2D array, so that `data[cell_index *
  /// facets_per_cell + facet_index]` contains the facet with index
  /// `facet_index` of the cell with index `cell_index`.
  /// @return The encoded permutation info
  /// @note An exception is raised if the permutations have not been
  /// computed
  const std::vector<std::uint8_t>& get_facet_permutations() const;

  /// @brief Get the types of cells in the topology
  /// @return The cell types
  std::vector<CellType> cell_types() const;

  /// @brief List of inter-process facets of a given type.
  ///
  /// "Inter-process" facets are facets that are connected (1) to a cell
  /// that is owned by the calling process (rank) and (2) to a cell that
  /// is owned by another process.
  ///
  /// Facets must have been computed for inter-process facet data to be
  /// available.
  ///
  ///  @param[in] index Index of facet type, following the order given
  ///  by ::entity_types.
  /// @return Indices of the inter-process facets.
  const std::vector<std::int32_t>& interprocess_facets(int index) const;

  /// @brief List of inter-process facets.
  ///
  /// "Inter-process" facets are facets that are connected (1) to a cell
  /// that is owned by the calling process (rank) and (2) to a cell that
  /// is owned by another process.
  ///
  /// @pre Inter-process facets are available only if facet topology has
  /// been computed.
  const std::vector<std::int32_t>& interprocess_facets() const;

  /// @brief Create entities of given topological dimension.
  /// @param[in] dim Topological dimension of entities to compute.
  /// @return True if entities are created, false if entities already
  /// existed.
  bool create_entities(int dim);

  /// @brief Create connectivity between given pair of dimensions, `d0
  /// -> d1`.
  /// @param[in] d0 Topological dimension.
  /// @param[in] d1 Topological dimension.
  void create_connectivity(int d0, int d1);

  /// @brief Compute entity permutations and reflections.
  void create_entity_permutations();

  /// Original cell index for each cell type
  std::vector<std::vector<std::int64_t>> original_cell_index;

  /// @brief Mesh MPI communicator.
  /// @return Communicator on which the topology is distributed.
  MPI_Comm comm() const;

private:
  // Cell types for entities in Topology, where _entity_types_new[d][i]
  // is the ith entity type of dimension d
  std::vector<std::vector<CellType>> _entity_types;

  // Parallel layout of entities for each dimension and cell type
  // flattened in the same layout as _entity_types above.
  // std::vector<std::shared_ptr<const common::IndexMap>> _index_map;

  // _index_maps[(d, i) is the index map for the ith entity type of
  // dimension d
  std::map<std::array<int, 2>, std::shared_ptr<const common::IndexMap>>
      _index_maps;

  // Connectivity between cell types _connectivity_new[(dim0, i0),
  // (dim1, i1)] is the connection from (dim0, i0) -> (dim1, i1),
  // where dim0 and dim1 are topological dimensions and i0 and i1
  // are the indices of cell types (following the order in _entity_types).
  std::map<std::pair<std::array<int, 2>, std::array<int, 2>>,
           std::shared_ptr<graph::AdjacencyList<std::int32_t>>>
      _connectivity;

  // The facet permutations (local facet, cell))
  // [cell0_0, cell0_1, ,cell0_2, cell1_0, cell1_1, ,cell1_2, ...,
  // celln_0, celln_1, ,celln_2,]
  std::vector<std::uint8_t> _facet_permutations;

  // Cell permutation info. See the documentation for
  // get_cell_permutation_info for documentation of how this is encoded.
  std::vector<std::uint32_t> _cell_permutations;

  // List of facets that are on the inter-process boundary for each
  // facet type. _interprocess_facets[i] is the inter-process facets of
  // facet type i.
  std::vector<std::vector<std::int32_t>> _interprocess_facets;
};

/// @brief Create a mesh topology.
///
/// This function creates a Topology from cells that have been already
/// distributed to the processes that own or ghost the cell.
///
/// @param[in] comm Communicator across which the topology will be
/// distributed.
/// @param[in] cell_types List of cell types in the topology.
/// @param[in] cells Cell topology (list of vertices for each cell) for
/// each cell type using global indices for the vertices. The cell type
/// for `cells[i]` is `cell_types[i]`, using row-major storage and where
/// the row `cells[i][j]` is the vertices for cell `j` of cell type `i`.
/// Each `cells[i]` contains cells that have been distributed to this
/// rank, e.g. via a graph partitioner. It must also contain all ghost
/// cells via facet, i.e. cells that are on a neighboring process and
/// which share a facet with a local cell. Ghost cells are the last `n`
/// entries in `cells[i]`, where `n` is given by the length of
/// `ghost_owners[i]`.
/// @param[in] original_cell_index Input cell index for each cell type,
/// e.g. the cell index in an input file. This index remains associated
/// with the cell after any re-ordering and parallel (re)distribution.
/// @param[in] ghost_owners Owning rank for ghost cells (ghost cells are
/// at end of each list of cells).
/// @param[in] boundary_vertices Vertices on the 'exterior' (boundary)
/// of the local topology. These vertices might appear on other
/// processes.
/// @return A distributed mesh topology.
Topology
create_topology(MPI_Comm comm, const std::vector<CellType>& cell_types,
                std::vector<std::span<const std::int64_t>> cells,
                std::vector<std::span<const std::int64_t>> original_cell_index,
                std::vector<std::span<const int>> ghost_owners,
                std::span<const std::int64_t> boundary_vertices);

/// @brief Create a mesh topology for a single cell type.
///
/// This function provides a simplified interface to ::create_topology
/// for the case that a mesh has one cell type only,
///
/// @param[in] comm Communicator across which the topology will be
/// distributed.
/// @param[in] cells Cell topology (list of vertices for each cell)
/// using global indices for the vertices. It contains cells that have
/// been distributed to this rank, e.g. via a graph partitioner. It must
/// also contain all ghost cells via facet, i.e. cells that are on a
/// neighboring process and which share a facet with a local cell. Ghost
/// cells are the last `n` entries in `cells`, where `n` is given by the
/// length of `ghost_owners`.
/// @param[in] original_cell_index Original global index associated with
/// each cell.
/// @param[in] ghost_owners Owning rank of each ghost cell (ghost cells
/// are always at the end of the list of `cells`).
/// @param[in] cell_type A vector with cell shapes.
/// @param[in] boundary_vertices Vertices on the 'exterior' (boundary)
/// of the local topology. These vertices might appear on other
/// processes.
/// @return A distributed mesh topology.
Topology create_topology(MPI_Comm comm, std::span<const std::int64_t> cells,
                         std::span<const std::int64_t> original_cell_index,
                         std::span<const int> ghost_owners, CellType cell_type,
                         std::span<const std::int64_t> boundary_vertices);

/// @brief Create a topology for a subset of entities of a given
/// topological dimension.
///
/// @param[in] topology Original (parent) topology.
/// @param[in] dim Topological dimension of the entities in the new
/// topology.
/// @param[in] entities Indices of entities in `topology` to include in
/// the new topology.
/// @return New topology of dimension `dim` with all entities in
/// `entities`, map from entities of dimension `dim` in new sub-topology
/// to entities in `topology`, and map from vertices in new sub-topology
/// to vertices in `topology`.
std::tuple<Topology, std::vector<int32_t>, std::vector<int32_t>>
create_subtopology(const Topology& topology, int dim,
                   std::span<const std::int32_t> entities);

/// @brief Get entity indices for entities defined by their vertices.
///
/// @warning This function may be removed in the future.
///
/// @param[in] topology Mesh topology.
/// @param[in] dim Topological dimension of the entities.
/// @param[in] entities Mesh entities defined by their vertices.
/// @return Index of the ith entity in `entities`, If an entity
/// cannot be found on this rank, -1 is returned as the index.
std::vector<std::int32_t>
entities_to_index(const Topology& topology, int dim,
                  std::span<const std::int32_t> entities);

/// @brief Compute a list of cell-cell connections for each possible combination
/// in the topology which have the same connecting facet type.
/// @param topology A mesh topology
/// @param facet_type Type of facet connection between cells
/// @return A list for each possible cell-cell connection, arranged
/// in the ordering given by `cell_types()` in the topology. i.e. if the cell
/// types are tet, prism, hex, and the facet_type is quadrilateral, then the
/// lists returned are: tet-tet (empty), tet-prism (empty), tet-hex (empty),
/// prism-tet (empty), prism-prism, prism-hex, hex-tet (empty), hex-prism,
/// hex-hex. Note there are empty lists for the invalid cases, and also that
/// there is currently redundant data, since the transpose is also computed,
/// i.e. prism-hex as well as hex-prism.
/// Each list contains a flattened array with data in the order (cell0, local
/// facet0, cell1, local facet1) for each connection between cells.
/// @note All facet-cell connectivity and cell-facet connectivity must be
/// computed beforehand in the topology.
/// @todo Remove redundant data.
std::vector<std::vector<std::int32_t>>
compute_mixed_cell_pairs(const Topology& topology, mesh::CellType facet_type);

} // namespace dolfinx::mesh