Wildmeshing Toolkit
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 
17 namespace wmtk::multimesh::utils {
18 
19 
20 template <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(
81  m.switch_tuples(
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(
114  m.switch_tuples(
115  tagged_tuples[i],
116  {PrimitiveType::Triangle, PrimitiveType::Edge, PrimitiveType::Vertex}),
118  m.id(
119  m.switch_tuples(
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>) {
241  return internal::TupleTag::
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:918
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:1021
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:968
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:997
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
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