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 <span>
21#include <utility>
22#include <vector>
23
24namespace dolfinx::mesh
25{
26
34template <typename T>
36{
37public:
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
112private:
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
135template <typename T>
136MeshTags<T> create_meshtags(const std::shared_ptr<const Mesh>& mesh, int dim,
138 const std::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:26
MeshTags associate values with mesh entities.
Definition: MeshTags.h:36
~MeshTags()=default
Destructor.
std::shared_ptr< const Mesh > mesh() const
Return mesh.
Definition: MeshTags.h:107
const std::vector< T > & values() const
Values attached to mesh entities.
Definition: MeshTags.h:101
MeshTags(const MeshTags &tags)=default
Copy constructor.
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=(MeshTags &&tags)=default
Move assignment.
std::string name
Name.
Definition: MeshTags.h:110
const std::vector< std::int32_t > & indices() const
Indices of tagged mesh entities (local-to-process). The indices are sorted.
Definition: MeshTags.h:98
int dim() const
Return topological dimension of tagged entities.
Definition: MeshTags.h:104
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: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
MeshTags< T > create_meshtags(const std::shared_ptr< const Mesh > &mesh, int dim, const graph::AdjacencyList< std::int32_t > &entities, const std::span< const T > &values)
Create MeshTags from arrays.
Definition: MeshTags.h:136
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:1201