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