Wildmeshing Toolkit
RegularSpace.cpp
Go to the documentation of this file.
1 #include "RegularSpace.hpp"
2 
3 #include <wmtk/Scheduler.hpp>
8 #include <wmtk/simplex/faces.hpp>
10 #include <wmtk/utils/Logger.hpp>
12 
13 #include <deque>
14 
16 
18 {
19 public:
22  int64_t m_val;
23 
25  Mesh& m,
26  const attribute::MeshAttributeHandle& attribute,
27  PrimitiveType ptype,
28  int64_t val)
29  : m_accessor(m.create_accessor<int64_t>(attribute))
30  , m_ptype(ptype)
31  , m_val(val)
32  {}
33 
35 };
36 
38  Mesh& mesh,
39  const std::vector<attribute::MeshAttributeHandle>& label_attributes,
40  const std::vector<int64_t>& values,
41  const std::vector<attribute::MeshAttributeHandle>& pass_through_attributes)
42  : m_mesh(mesh)
43  , m_label_attributes(label_attributes)
44  , m_values(values)
45  , m_pass_through_attributes(pass_through_attributes)
46 {
47  assert(m_label_attributes.size() == m_values.size());
48 }
49 
51 {
52  using namespace operations;
53 
54  std::vector<attribute::MeshAttributeHandle> todo_handles;
55  for (size_t i = 0; i < m_label_attributes.size(); ++i) {
56  attribute::MeshAttributeHandle todo_handle =
57  m_mesh.register_attribute<int64_t>("todo", m_label_attributes[i].primitive_type(), 1);
58  todo_handles.emplace_back(todo_handle);
59  }
60 
61  std::deque<TagAttribute> tag_attributes;
62  for (size_t i = 0; i < m_label_attributes.size(); ++i) {
63  tag_attributes.emplace_back(
64  m_mesh,
66  m_label_attributes[i].primitive_type(),
67  m_values[i]);
68  }
69 
70  // make sure tag vector is complete and sorted in descending order
71  for (size_t i = 0; i < tag_attributes.size(); ++i) {
72  TagAttribute& a = tag_attributes[i];
74  log_and_throw_error("Tag array must be sorted in descending order starting with "
75  "the top simplex type up to vertex.");
76  }
77  }
78 
79 
80  // tag all faces of attributes
81  for (size_t attr_it = 0; attr_it < tag_attributes.size() - 1; ++attr_it) {
82  const TagAttribute& ta = tag_attributes[attr_it];
83  for (const Tuple& t : m_mesh.get_all(ta.m_ptype)) {
84  if (ta.m_accessor.const_scalar_attribute(t) != ta.m_val) {
85  continue; // t is not tagged
86  }
87 
88  const PrimitiveType face_ptype =
91  m_mesh,
93  face_ptype);
94 
95  TagAttribute& face_ta = tag_attributes[attr_it + 1];
96  for (const Tuple& f : faces) {
97  face_ta.m_accessor.scalar_attribute(f) = face_ta.m_val;
98  }
99  }
100  }
101 
102  // split untagged simplices that have only tagged faces
103  for (size_t attr_it = 0; attr_it < tag_attributes.size() - 1; ++attr_it) {
104  const TagAttribute& ta = tag_attributes[attr_it];
105 
106  attribute::MeshAttributeHandle& todo_handle = todo_handles[attr_it];
107  auto todo_acc = m_mesh.create_accessor<int64_t>(todo_handle);
108 
109  for (const Tuple& t : m_mesh.get_all(ta.m_ptype)) {
110  if (ta.m_accessor.const_scalar_attribute(t) == ta.m_val) {
111  continue; // t is tagged
112  }
113 
114  const PrimitiveType face_ptype =
117  m_mesh,
119  face_ptype);
120 
121  const TagAttribute& face_ta = tag_attributes[attr_it + 1];
122 
123  bool all_faces_are_tagged = true;
124 
125  for (const Tuple& f : faces) {
126  if (face_ta.m_accessor.const_scalar_attribute(f) != face_ta.m_val) {
127  all_faces_are_tagged = false;
128  break;
129  }
130  }
131 
132  if (all_faces_are_tagged) {
133  todo_acc.scalar_attribute(t) = 1;
134  }
135  }
136 
138  log_and_throw_error("Regular space component not implemented for TetMeshes.");
139  }
140 
141  // split simplex because all its faces are tagged
142  Scheduler scheduler;
143  switch (ta.m_ptype) {
144  case PrimitiveType::Edge: { // edge split
145  EdgeSplit op_split(m_mesh);
146  op_split.add_invariant(std::make_shared<TodoInvariant>(
147  m_mesh,
148  std::get<attribute::TypedAttributeHandle<int64_t>>(todo_handle.handle())));
149 
150  // todos
151  for (const attribute::MeshAttributeHandle& h : todo_handles) {
153  h,
154  SplitBasicStrategy::None,
155  SplitRibBasicStrategy::None);
156  }
157  // labels
159  op_split.set_new_attribute_strategy(h);
160  }
161  // pass_through
162  for (const auto& attr : m_pass_through_attributes) {
163  op_split.set_new_attribute_strategy(attr);
164  }
165 
166  while (true) {
167  const auto stats = scheduler.run_operation_on_all(op_split);
168  if (stats.number_of_successful_operations() == 0) {
169  break;
170  }
171  }
172 
173  break;
174  }
175  case PrimitiveType::Triangle: { // face split
176  composite::TriFaceSplit op_face_split(m_mesh);
177  op_face_split.add_invariant(std::make_shared<TodoInvariant>(
178  m_mesh,
179  std::get<attribute::TypedAttributeHandle<int64_t>>(todo_handle.handle())));
180 
181  // todos
182  for (const attribute::MeshAttributeHandle& h : todo_handles) {
183  op_face_split.split().set_new_attribute_strategy(
184  h,
185  SplitBasicStrategy::None,
186  SplitRibBasicStrategy::None);
187  op_face_split.collapse().set_new_attribute_strategy(h, CollapseBasicStrategy::None);
188  }
189  // labels
191  op_face_split.split().set_new_attribute_strategy(h);
192  op_face_split.collapse().set_new_attribute_strategy(h);
193  }
194  // pass_through
195  for (const auto& attr : m_pass_through_attributes) {
196  op_face_split.split().set_new_attribute_strategy(attr);
197  op_face_split.collapse().set_new_attribute_strategy(attr);
198  }
199 
200  while (true) {
201  const auto stats = scheduler.run_operation_on_all(op_face_split);
202  if (stats.number_of_successful_operations() == 0) {
203  break;
204  }
205  }
206 
207  break;
208  }
210  log_and_throw_error("Regular space component not implemented for TetMeshes.");
211  }
212  default: log_and_throw_error("unknown primitive type: {}", ta.m_ptype); break;
213  }
214  }
215 }
216 
217 
218 } // namespace wmtk::components::internal
attribute::MeshAttributeHandle register_attribute(const std::string &name, PrimitiveType type, int64_t size, bool replace=false, T default_value=T(0))
std::vector< Tuple > get_all(PrimitiveType type) const
Generate a vector of Tuples from global vertex/edge/triangle/tetrahedron index.
Definition: Mesh.cpp:18
int64_t top_cell_dimension() const
Definition: Mesh.hpp:992
attribute::Accessor< T, Mesh, D > create_accessor(const attribute::MeshAttributeHandle &handle)
PrimitiveType top_simplex_type() const
Definition: Mesh.hpp:996
SchedulerStats run_operation_on_all(operations::Operation &op)
Definition: Scheduler.cpp:33
T & scalar_attribute(const ArgType &t)
T const_scalar_attribute(const ArgType &t) const
Definition: Accessor.hxx:112
std::vector< attribute::MeshAttributeHandle > m_pass_through_attributes
std::vector< attribute::MeshAttributeHandle > m_label_attributes
RegularSpace(Mesh &mesh, const std::vector< attribute::MeshAttributeHandle > &label_attributes, const std::vector< int64_t > &values, const std::vector< attribute::MeshAttributeHandle > &pass_through_attributes)
wmtk::attribute::Accessor< int64_t > m_accessor
TagAttribute(Mesh &m, const attribute::MeshAttributeHandle &attribute, PrimitiveType ptype, int64_t val)
void set_new_attribute_strategy(const attribute::MeshAttributeHandle &attribute, const std::shared_ptr< const operations::BaseCollapseNewAttributeStrategy > &other)
void set_new_attribute_strategy(const attribute::MeshAttributeHandle &attribute, const std::shared_ptr< const operations::BaseSplitNewAttributeStrategy > &other)
Definition: EdgeSplit.cpp:85
void add_invariant(std::shared_ptr< Invariant > invariant)
Definition: Operation.hpp:48
The return tuple is the new vertex, pointing to the original vertex.
std::vector< Tuple > faces_single_dimension_tuples(const Mesh &mesh, const Simplex &simplex, const PrimitiveType face_type)
SimplexCollection faces(const Mesh &mesh, const Simplex &simplex, const bool sort_and_clean)
Returns all faces of a simplex.
Definition: faces.cpp:10
constexpr PrimitiveType get_primitive_type_from_id(int8_t id)
Get the primitive type corresponding to its unique integer id.
void log_and_throw_error(const std::string &msg)
Definition: Logger.cpp:101
constexpr int8_t get_primitive_type_id(PrimitiveType t)
Get a unique integer id corresponding to each primitive type.