DOLFINx
DOLFINx C++ interface
MeshTags.h
1 // Copyright (C) 2020-2022 Michal Habera and Garth N. Wells
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 "Geometry.h"
10 #include "Mesh.h"
11 #include "Topology.h"
12 #include <algorithm>
13 #include <dolfinx/common/IndexMap.h>
14 #include <dolfinx/common/log.h>
15 #include <dolfinx/common/utils.h>
16 #include <dolfinx/graph/AdjacencyList.h>
17 #include <dolfinx/graph/partition.h>
18 #include <dolfinx/io/cells.h>
19 #include <memory>
20 #include <utility>
21 #include <vector>
22 #include <xtl/xspan.hpp>
23 
24 namespace dolfinx::mesh
25 {
26 
34 template <typename T>
35 class MeshTags
36 {
37 public:
46  template <typename U, typename V>
47  MeshTags(const std::shared_ptr<const Mesh>& mesh, int dim, U&& indices,
48  V&& values)
49  : _mesh(mesh), _dim(dim), _indices(std::forward<U>(indices)),
50  _values(std::forward<V>(values))
51  {
52  if (_indices.size() != _values.size())
53  {
54  throw std::runtime_error(
55  "Indices and values arrays must have same size.");
56  }
57 #ifndef NDEBUG
58  if (!std::is_sorted(_indices.begin(), _indices.end()))
59  throw std::runtime_error("MeshTag data is not sorted");
60  if (std::adjacent_find(_indices.begin(), _indices.end()) != _indices.end())
61  throw std::runtime_error("MeshTag data has duplicates");
62 #endif
63  }
64 
66  MeshTags(const MeshTags& tags) = default;
67 
69  MeshTags(MeshTags&& tags) = default;
70 
72  ~MeshTags() = default;
73 
75  MeshTags& operator=(const MeshTags& tags) = default;
76 
78  MeshTags& operator=(MeshTags&& tags) = default;
79 
83  std::vector<std::int32_t> find(const T value) const
84  {
85  int n = std::count(_values.begin(), _values.end(), value);
86  std::vector<std::int32_t> indices(n);
87  int counter = 0;
88  for (std::int32_t i = 0; i < _values.size(); ++i)
89  {
90  if (_values[i] == value)
91  indices[counter++] = _indices[i];
92  }
93  return indices;
94  }
95 
98  const std::vector<std::int32_t>& indices() const { return _indices; }
99 
101  const std::vector<T>& values() const { return _values; }
102 
104  int dim() const { return _dim; }
105 
107  std::shared_ptr<const Mesh> mesh() const { return _mesh; }
108 
110  std::string name = "mesh_tags";
111 
112 private:
113  // Associated mesh
114  std::shared_ptr<const Mesh> _mesh;
115 
116  // Topological dimension of tagged mesh entities
117  int _dim;
118 
119  // Local-to-process indices of tagged entities
120  std::vector<std::int32_t> _indices;
121 
122  // Values attached to entities
123  std::vector<T> _values;
124 };
125 
135 template <typename T>
136 MeshTags<T> create_meshtags(const std::shared_ptr<const Mesh>& mesh, int dim,
137  const graph::AdjacencyList<std::int32_t>& entities,
138  const xtl::span<const T>& values)
139 {
140  LOG(INFO)
141  << "Building MeshTgas object from tagged entities (defined by vertices).";
142 
143  assert(mesh);
144 
145  // Compute the indices of the mesh entities (index is set to -1 if it
146  // can't be found)
147  const std::vector<std::int32_t> indices
148  = entities_to_index(mesh->topology(), dim, entities);
149  if (indices.size() != values.size())
150  {
151  throw std::runtime_error(
152  "Duplicate mesh entities when building MeshTags object.");
153  }
154 
155  // Sort the indices and values by indices
156  auto [indices_sorted, values_sorted] = common::sort_unique(indices, values);
157 
158  // Remove any entities that were not found (these have andindex of -1)
159  auto it0 = std::lower_bound(indices_sorted.begin(), indices_sorted.end(), 0);
160  std::size_t pos0 = std::distance(indices_sorted.begin(), it0);
161  indices_sorted.erase(indices_sorted.begin(), it0);
162  values_sorted.erase(values_sorted.begin(),
163  std::next(values_sorted.begin(), pos0));
164 
165  return MeshTags<T>(mesh, dim, std::move(indices_sorted),
166  std::move(values_sorted));
167 }
168 } // namespace dolfinx::mesh
This class provides a static adjacency list data structure. It is commonly used to store directed gra...
Definition: AdjacencyList.h:46
MeshTags associate values with mesh entities.
Definition: MeshTags.h:36
std::shared_ptr< const Mesh > mesh() const
Return mesh.
Definition: MeshTags.h:107
~MeshTags()=default
Destructor.
const std::vector< std::int32_t > & indices() const
Indices of tagged mesh entities (local-to-process). The indices are sorted.
Definition: MeshTags.h:98
MeshTags(const MeshTags &tags)=default
Copy constructor.
MeshTags & operator=(MeshTags &&tags)=default
Move assignment.
MeshTags(MeshTags &&tags)=default
Move constructor.
MeshTags(const std::shared_ptr< const Mesh > &mesh, int dim, U &&indices, V &&values)
Create a MeshTag from entities of given dimension on a mesh.
Definition: MeshTags.h:47
MeshTags & operator=(const MeshTags &tags)=default
Move assignment.
std::string name
Name.
Definition: MeshTags.h:110
int dim() const
Return topological dimension of tagged entities.
Definition: MeshTags.h:104
const std::vector< T > & values() const
Values attached to mesh entities.
Definition: MeshTags.h:101
std::vector< std::int32_t > find(const T value) const
Find all entities with a given tag value.
Definition: MeshTags.h:83
std::pair< std::vector< typename U::value_type >, std::vector< typename V::value_type > > sort_unique(const U &indices, const V &values)
Sort two arrays based on the values in array indices. Any duplicate indices and the corresponding val...
Definition: utils.h:39
Mesh data structures and algorithms on meshes.
Definition: DofMap.h:30
std::vector< std::int32_t > entities_to_index(const Topology &topology, int dim, const graph::AdjacencyList< std::int32_t > &entities)
Get entity indices for entities defined by their vertices.
Definition: Topology.cpp:1191
MeshTags< T > create_meshtags(const std::shared_ptr< const Mesh > &mesh, int dim, const graph::AdjacencyList< std::int32_t > &entities, const xtl::span< const T > &values)
Create MeshTags from arrays.
Definition: MeshTags.h:136