Wildmeshing Toolkit
Loading...
Searching...
No Matches
extract_child_mesh_from_tag.cpp
Go to the documentation of this file.
2#include <map>
3#include <numeric>
4#include <wmtk/EdgeMesh.hpp>
5#include <wmtk/Mesh.hpp>
7#include <wmtk/PointMesh.hpp>
8#include <wmtk/Primitive.hpp>
9#include <wmtk/TetMesh.hpp>
10#include <wmtk/TriMesh.hpp>
14#include <wmtk/utils/Logger.hpp>
15#include "internal/TupleTag.hpp"
16
17namespace wmtk::multimesh::utils {
18
19
20template <typename T>
21
23 Mesh& m,
25 const T& tag_value,
26 bool child_is_free)
27{
28 auto tags = m.create_const_accessor(tag_handle);
29 const PrimitiveType pt = tag_handle.primitive_type();
30
31 std::vector<Tuple> tagged_tuples;
32 for (const Tuple& t : m.get_all(pt)) {
33 if (tags.const_scalar_attribute(t) == tag_value) {
34 tagged_tuples.emplace_back(t);
35 }
36 }
37
38 auto run_edge = [&]() {
39 std::map<int64_t, int64_t> parent_to_child_vertex_map;
40 // int64_t child_vertex_count = 0;
41
42 RowVectors2l edge_mesh_matrix;
43 edge_mesh_matrix.resize(tagged_tuples.size(), 2);
44
45 for (size_t i = 0; i < tagged_tuples.size(); ++i) {
46 const std::array<int64_t, 2> vs = {
47 {m.id(tagged_tuples[i], PrimitiveType::Vertex),
48 m.id(
49 m.switch_tuple(tagged_tuples[i], PrimitiveType::Vertex),
51
52
53 // check and add v0, v1 to the vertex map
54 for (int k = 0; k < 2; k++) {
55 size_t size = parent_to_child_vertex_map.size();
56 parent_to_child_vertex_map.try_emplace(vs[k], size);
57 edge_mesh_matrix(i, k) = parent_to_child_vertex_map[vs[k]];
58 }
59 }
60
61 std::shared_ptr<EdgeMesh> child_ptr = std::make_shared<EdgeMesh>();
62 auto& child = *child_ptr;
63 child.initialize(edge_mesh_matrix);
64 return child_ptr;
65 };
66
67 auto run_face = [&]() {
68 std::map<int64_t, int64_t> parent_to_child_vertex_map;
69 int64_t child_vertex_count = 0;
70
71 RowVectors3l tri_mesh_matrix;
72 tri_mesh_matrix.resize(tagged_tuples.size(), 3);
73 for (int64_t i = 0; i < tagged_tuples.size(); ++i) {
74 // TODO: check if this break the orientation of the map
75 const std::array<int64_t, 3> vs = {
76 {m.id(tagged_tuples[i], PrimitiveType::Vertex),
77 m.id(
78 m.switch_tuple(tagged_tuples[i], PrimitiveType::Vertex),
80 m.id(
82 tagged_tuples[i],
83 {PrimitiveType::Edge, PrimitiveType::Vertex}),
85
86 // check and add v0, v1, v2 to the vertex map
87 for (int k = 0; k < 3; k++) {
88 size_t size = parent_to_child_vertex_map.size();
89 parent_to_child_vertex_map.try_emplace(vs[k], size);
90 tri_mesh_matrix(i, k) = parent_to_child_vertex_map.at(vs[k]);
91 }
92 }
93 std::shared_ptr<TriMesh> child_ptr = std::make_shared<TriMesh>();
94 auto& child = *child_ptr;
95 child.initialize(tri_mesh_matrix);
96
97 return child_ptr;
98 };
99
100 auto run_tet = [&]() {
101 std::map<int64_t, int64_t> parent_to_child_vertex_map;
102 int64_t child_vertex_count = 0;
103
104 RowVectors4l tet_mesh_matrix;
105
106 tet_mesh_matrix.resize(tagged_tuples.size(), 4);
107 for (int64_t i = 0; i < tagged_tuples.size(); ++i) {
108 const std::array<int64_t, 4> vs = {
109 {m.id(tagged_tuples[i], PrimitiveType::Vertex),
110 m.id(
111 m.switch_tuple(tagged_tuples[i], PrimitiveType::Vertex),
113 m.id(
115 tagged_tuples[i],
116 {PrimitiveType::Triangle, PrimitiveType::Edge, PrimitiveType::Vertex}),
118 m.id(
120 tagged_tuples[i],
121 {PrimitiveType::Edge, PrimitiveType::Vertex}),
123
124 for (int k = 0; k < 4; ++k) {
125 size_t size = parent_to_child_vertex_map.size();
126 parent_to_child_vertex_map.try_emplace(vs[k], size);
127 tet_mesh_matrix(i, k) = parent_to_child_vertex_map[vs[k]];
128 }
129 }
130
131 // TODO: use TV matrix instead of switches
132
133
134 std::shared_ptr<TetMesh> child_ptr = std::make_shared<TetMesh>();
135 auto& child = *child_ptr;
136 child.initialize(tet_mesh_matrix);
137 return child_ptr;
138 };
139
140
141 std::shared_ptr<Mesh> child_mesh_ptr;
142
143 if (child_is_free) {
144 switch (pt) {
145 case PrimitiveType::Vertex: throw("not implemented");
146 case PrimitiveType::Edge: {
147 std::shared_ptr<EdgeMesh> meshptr = std::make_shared<EdgeMesh>();
148 meshptr->initialize_free(tagged_tuples.size());
149 child_mesh_ptr = meshptr;
150 break;
151 }
153 std::shared_ptr<TriMesh> meshptr = std::make_shared<TriMesh>();
154 meshptr->initialize_free(tagged_tuples.size());
155 child_mesh_ptr = meshptr;
156 break;
157 }
159 std::shared_ptr<TetMesh> meshptr = std::make_shared<TetMesh>();
160 meshptr->initialize_free(tagged_tuples.size());
161 child_mesh_ptr = meshptr;
162 break;
163 }
164 default: throw("invalid child mesh type");
165 }
166
167 } else {
168 switch (pt) {
169 case PrimitiveType::Vertex: throw("not implemented");
170 case PrimitiveType::Edge: {
171 child_mesh_ptr = run_edge();
172 break;
173 }
175 child_mesh_ptr = run_face();
176 break;
177 }
179 child_mesh_ptr = run_tet();
180 break;
181 }
182 default: throw("invalid child mesh type");
183 }
184 }
185
186 assert(bool(child_mesh_ptr));
187 auto& child = *child_mesh_ptr;
188
189 std::vector<std::array<Tuple, 2>> child_to_parent_map(tagged_tuples.size());
190 assert(tagged_tuples.size() == child.capacity(pt));
191
192 const auto child_top_dimension_tuples = child.get_all(pt);
193
194 for (size_t i = 0; i < tagged_tuples.size(); ++i) {
195 child_to_parent_map[i] = {{child_top_dimension_tuples[i], tagged_tuples[i]}};
196 }
197
198 m.register_child_mesh(child_mesh_ptr, child_to_parent_map);
199 return child_mesh_ptr;
200}
201
203 Mesh& m,
204 const std::string& tag,
205 const int64_t tag_value,
206 const PrimitiveType pt,
207 bool child_is_free)
208{
209 assert(m.top_simplex_type() >= pt);
210 auto tag_handle = m.get_attribute_handle<int64_t>(tag, pt).as<int64_t>();
211 return extract_and_register_child_mesh_from_tag_handle(m, tag_handle, tag_value, child_is_free);
212}
213
215 Mesh& m,
217 const int64_t tag_value,
218 bool child_is_free)
219{
221 m,
222 tag_handle,
223 tag_value,
224 child_is_free);
225}
226
230 bool child_is_free)
231{
232 return std::visit(
233 [&](auto&& handle) noexcept -> std::shared_ptr<Mesh> {
234 using HandleType = typename std::decay_t<decltype(handle)>;
235 using T = typename HandleType::Type;
236 if constexpr (wmtk::attribute::MeshAttributeHandle::template handle_type_is_basic<
237 HandleType>()) {
238 return std::visit(
239 [&](auto&& value) noexcept -> std::shared_ptr<Mesh> {
240 if constexpr (std::is_convertible_v<std::decay_t<decltype(value)>, T>) {
243 tag_handle.mesh(),
244 handle,
245 T(value),
246 child_is_free);
247 } else {
249 "Tried to use a tag value that was not convertible to "
250 "the tag attribute type");
251 return {};
252 }
253 },
254 tag_value);
255 } else {
256 log_and_throw_error("Tried to use a non-primitive meshattributehandle when "
257 "extracting a child mesh fro ma tag");
258 }
259 return nullptr;
260 },
261 tag_handle.handle());
262}
263
264} // namespace wmtk::multimesh::utils
attribute::MeshAttributeHandle get_attribute_handle(const std::string &name, const PrimitiveType ptype) const
Definition Mesh.hpp:903
const attribute::Accessor< T, Mesh, D > create_const_accessor(const attribute::MeshAttributeHandle &handle) const
int64_t id(const Tuple &tuple, PrimitiveType type) const
return the global id of the Tuple of the given dimension
Definition Mesh.hpp:1006
std::vector< Tuple > get_all(PrimitiveType type) const
Generate a vector of Tuples from global vertex/edge/triangle/tetrahedron index.
Definition Mesh.cpp:18
Tuple switch_tuples(const Tuple &tuple, const ContainerType &op_sequence) const
Definition Mesh.hpp:953
void register_child_mesh(const std::shared_ptr< Mesh > &child_mesh_ptr, const std::vector< std::array< Tuple, 2 > > &map_tuples)
register a mesh as the child of this mesh
virtual Tuple switch_tuple(const Tuple &tuple, PrimitiveType type) const =0
switch the orientation of the Tuple of the given dimension
PrimitiveType top_simplex_type() const
Definition Mesh.hpp:982
The Tuple is the basic navigation tool in our mesh data structure.
Definition Tuple.hpp:19
std::variant< char, int64_t, double, wmtk::Rational, std::tuple< char, wmtk::Rational, double > > ValueVariant
Handle that represents attributes for some mesh.
static std::shared_ptr< Mesh > extract_and_register_child_mesh_from_tag_handle(Mesh &m, const wmtk::attribute::TypedAttributeHandle< T > &tag_handle, const T &tag_value, bool child_is_free)
std::shared_ptr< Mesh > extract_and_register_child_mesh_from_tag_handle(Mesh &m, const wmtk::attribute::TypedAttributeHandle< int64_t > &tag_handle, const int64_t tag_value, bool child_is_free)
extract a child mesh based on the tag handle and the tag value, and register it to the input (parent)...
std::shared_ptr< Mesh > extract_and_register_child_mesh_from_tag(Mesh &m, const std::string &tag, const int64_t tag_value, const PrimitiveType pt, bool child_is_free)
extract a child mesh based on the given tag and tag value, and register it to the input (parent) mesh
RowVectors< int64_t, 3 > RowVectors3l
Definition Types.hpp:47
void log_and_throw_error(const std::string &msg)
Definition Logger.cpp:101
RowVectors< int64_t, 4 > RowVectors4l
Definition Types.hpp:48
RowVectors< int64_t, 2 > RowVectors2l
Definition Types.hpp:46