DOLFINx 0.8.0
DOLFINx C++ interface
Loading...
Searching...
No Matches
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 "Topology.h"
10#include <algorithm>
11#include <dolfinx/common/IndexMap.h>
12#include <dolfinx/common/log.h>
13#include <dolfinx/common/utils.h>
14#include <dolfinx/graph/AdjacencyList.h>
15#include <dolfinx/io/cells.h>
16#include <memory>
17#include <span>
18#include <utility>
19#include <vector>
20
21namespace dolfinx::mesh
22{
23
31template <typename T>
33{
34public:
45 template <typename U, typename V>
46 requires std::is_convertible_v<std::remove_cvref_t<U>,
47 std::vector<std::int32_t>>
48 and std::is_convertible_v<std::remove_cvref_t<V>,
49 std::vector<T>>
50 MeshTags(std::shared_ptr<const Topology> topology, int dim, U&& indices,
51 V&& values)
52 : _topology(topology), _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 Topology> topology() const { return _topology; }
111
113 std::string name = "mesh_tags";
114
115private:
116 // Associated topology
117 std::shared_ptr<const Topology> _topology;
118
119 // Topological dimension of tagged topology 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
137template <typename T>
138MeshTags<T> create_meshtags(std::shared_ptr<const Topology> topology, int dim,
140 std::span<const T> values)
141{
142 LOG(INFO)
143 << "Building MeshTags object from tagged entities (defined by vertices).";
144
145 // Compute the indices of the topology entities (index is set to -1 if
146 // it can't be found)
147 assert(topology);
148 const std::vector<std::int32_t> indices
149 = entities_to_index(*topology, dim, entities.array());
150 if (indices.size() != values.size())
151 {
152 throw std::runtime_error(
153 "Duplicate mesh entities when building MeshTags object.");
154 }
155
156 // Sort the indices and values by indices
157 auto [indices_sorted, values_sorted] = common::sort_unique(indices, values);
158
159 // Remove any entities that were not found (these have an index of -1)
160 auto it0 = std::lower_bound(indices_sorted.begin(), indices_sorted.end(), 0);
161 std::size_t pos0 = std::distance(indices_sorted.begin(), it0);
162 indices_sorted.erase(indices_sorted.begin(), it0);
163 values_sorted.erase(values_sorted.begin(),
164 std::next(values_sorted.begin(), pos0));
165
166 return MeshTags<T>(topology, dim, std::move(indices_sorted),
167 std::move(values_sorted));
168}
169} // namespace dolfinx::mesh
Definition AdjacencyList.h:28
const std::vector< T > & array() const
Return contiguous array of links for all nodes (const version)
Definition AdjacencyList.h:129
MeshTags associate values with mesh topology entities.
Definition MeshTags.h:33
std::span< const std::int32_t > indices() const
Definition MeshTags.h:101
~MeshTags()=default
Destructor.
MeshTags(const MeshTags &tags)=default
Copy constructor.
MeshTags(MeshTags &&tags)=default
Move constructor.
MeshTags & operator=(MeshTags &&tags)=default
Move assignment.
std::span< const T > values() const
Values attached to topology entities.
Definition MeshTags.h:104
std::string name
Name.
Definition MeshTags.h:113
MeshTags(std::shared_ptr< const Topology > topology, int dim, U &&indices, V &&values)
Create a MeshTag from entities of given dimension on a mesh.
Definition MeshTags.h:50
int dim() const
Return topological dimension of tagged entities.
Definition MeshTags.h:107
MeshTags & operator=(const MeshTags &tags)=default
Move assignment.
std::shared_ptr< const Topology > topology() const
Return topology.
Definition MeshTags.h:110
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)
Definition utils.h:28
Mesh data structures and algorithms on meshes.
Definition DofMap.h:32
MeshTags< T > create_meshtags(std::shared_ptr< const Topology > topology, int dim, const graph::AdjacencyList< std::int32_t > &entities, std::span< const T > values)
Create MeshTags from arrays.
Definition MeshTags.h:138
std::vector< std::int32_t > entities_to_index(const Topology &topology, int dim, std::span< const std::int32_t > entities)
Get entity indices for entities defined by their vertices.
Definition Topology.cpp:1430