Wildmeshing Toolkit
CollapseNewAttributeStrategy.cpp
Go to the documentation of this file.
2 #include <fmt/format.h>
4 
8 
9 namespace wmtk::operations {
10 template <typename T>
12 {
13  return m_will_throw;
14 }
15 template <typename T>
17 {
18  return fmt::format("CollapseNewAttributeStrategy[{}]", m_handle.name());
19 }
20 
21 template <typename T>
24 {
25  switch (optype) {
26  default: [[fallthrough]];
28  if constexpr (std::is_same_v<T, double> || std::is_same_v<T, Rational>) {
29  return standard_collapse_strategy(CollapseBasicStrategy::Mean);
30  } else {
31  return standard_collapse_strategy(CollapseBasicStrategy::CopyTuple);
32  }
34  return [](const VecType& a, const VecType& b, const std::bitset<2>& bs) -> VecType {
35  if (!bs[1] && bs[0]) {
36  return b;
37  } else {
38  return a;
39  }
40  };
42  return [](const VecType& a, const VecType& b, const std::bitset<2>& bs) -> VecType {
43  if (!bs[0] && bs[1]) {
44  return a;
45  } else {
46  return b;
47  }
48  };
50  return [](const VecType& a, const VecType& b, const std::bitset<2>& bs) -> VecType {
51  if (bs[0] == bs[1]) {
52  return (a + b) / T(2);
53  } else if (bs[0]) {
54  return a;
55 
56  } else {
57  return b;
58  }
59  };
61  return [](const VecType&, const VecType&, const std::bitset<2>&) -> VecType {
62  throw std::runtime_error("Collapse should have a new attribute");
63  };
64  case CollapseBasicStrategy::None: return {};
65  }
66  return {};
67 }
68 
69 template <>
72 {
73  switch (optype) {
74  default: [[fallthrough]];
76  return standard_collapse_strategy(CollapseBasicStrategy::Mean);
78  return [](const VecType& a, const VecType& b, const std::bitset<2>& bs) -> VecType {
79  if (!bs[1] && bs[0]) {
80  return b;
81  } else {
82  return a;
83  }
84  };
86  return [](const VecType& a, const VecType& b, const std::bitset<2>& bs) -> VecType {
87  if (!bs[0] && bs[1]) {
88  return a;
89  } else {
90  return b;
91  }
92  };
94  return [](const VecType& a, const VecType& b, const std::bitset<2>& bs) -> VecType {
95  if (bs[0] == bs[1]) {
96  return (a + b) / Rational(2, true);
97  } else if (bs[0]) {
98  return a;
99 
100  } else {
101  return b;
102  }
103  };
105  return [](const VecType&, const VecType&, const std::bitset<2>&) -> VecType {
106  throw std::runtime_error("Collapse should have a new attribute");
107  };
108  case CollapseBasicStrategy::None: return {};
109  }
110  return {};
111 }
112 
113 
114 template <typename T>
117  : m_handle(h)
118  , m_collapse_op(nullptr)
119 {
120  assert(h.holds<T>());
121 
122  auto& mesh = m_handle.mesh();
123  if (mesh.is_free()) {
125  } else {
127  }
128 
130  m_topo_info =
131  std::make_unique<edge_mesh::CollapseNewAttributeTopoInfo>(static_cast<EdgeMesh&>(mesh));
133  m_topo_info =
134  std::make_unique<tri_mesh::CollapseNewAttributeTopoInfo>(static_cast<TriMesh&>(mesh));
136  m_topo_info =
137  std::make_unique<tet_mesh::CollapseNewAttributeTopoInfo>(static_cast<TetMesh&>(mesh));
138  } else {
139  throw std::runtime_error("Invalid mesh");
140  }
141 }
142 
143 template <typename T>
145  Mesh& m,
146  const ReturnData& data,
147  const OperationInOutData& op_datas) const
148 {
149  if (!bool(m_collapse_op)) {
150  return;
151  }
152  assert(!mesh().is_free()); // attribute new is not valid on free meshes
153 
154  if (op_datas.find(&mesh()) == op_datas.end()) return;
155  assert(&mesh() == &m);
156  const std::vector<std::tuple<simplex::NavigatableSimplex, Tuple>>& tuple_pairs =
157  op_datas.at(&mesh());
158 
159  const PrimitiveType pt = primitive_type();
160  auto acc = m.create_accessor(m_handle.as<T>());
161 
162  for (const auto& tuple_pair : tuple_pairs) {
163  const simplex::NavigatableSimplex& input_simplex = std::get<0>(tuple_pair);
164  const Tuple& output_tuple = std::get<1>(tuple_pair);
165 
166 
167  const auto& return_data_variant = data.get_variant(mesh(), input_simplex);
168 
169  // for (const PrimitiveType pt : wmtk::utils::primitive_below(mesh().top_simplex_type()))
170  {
171  auto merged_simps =
172  m_topo_info->merged_simplices(return_data_variant, input_simplex.tuple(), pt);
173  auto new_simps = m_topo_info->new_simplices(return_data_variant, output_tuple, pt);
174 
175 
176  assert(merged_simps.size() == new_simps.size());
177 
178  for (size_t s = 0; s < merged_simps.size(); ++s) {
179  assign_collapsed(acc, merged_simps[s], new_simps[s]);
180  }
181  }
182  }
183 }
184 
185 
186 template <typename T>
189  const std::array<Tuple, 2>& input_simplices,
190  const Tuple& final_simplex) const
191 {
192  if (!bool(m_collapse_op)) {
193  return;
194  }
195  assert(acc.primitive_type() == primitive_type());
196  auto old_values = m_handle.mesh().parent_scope([&]() {
197  return std::make_tuple(
198  acc.const_vector_attribute(input_simplices[0]),
199  acc.const_vector_attribute(input_simplices[1]));
200  });
201 
202  const auto old_pred = this->evaluate_predicate(acc.primitive_type(), input_simplices);
203 
204  VecType a, b;
205  std::tie(a, b) = old_values;
206  auto new_value = acc.vector_attribute(final_simplex);
207 
208 
209  new_value = m_collapse_op(a, b, old_pred);
210 }
211 
212 
213 template <typename T>
215 {
216  m_collapse_op = std::move(f);
217  m_will_throw = false;
218 }
219 template <typename T>
221 {
222  set_strategy(standard_collapse_strategy(optype));
223  m_will_throw = optype == CollapseBasicStrategy::Throw;
224 }
225 
226 
227 template <typename T>
229 {
230  return m_handle.mesh();
231 }
232 template <typename T>
234 {
235  return m_handle.primitive_type();
236 }
237 template <typename T>
239 {
240  m_handle = wmtk::attribute::MeshAttributeHandle(m, m_handle.as<T>());
241 }
242 template <typename T>
244  const attribute::MeshAttributeHandle& handle) const
245 {
246  return handle == m_handle;
247 }
248 
253 
254 } // namespace wmtk::operations
bool is_free() const
Definition: Mesh.hpp:987
attribute::Accessor< T, Mesh, D > create_accessor(const attribute::MeshAttributeHandle &handle)
PrimitiveType top_simplex_type() const
Definition: Mesh.hpp:996
A CachingAccessor that uses tuples for accessing attributes instead of indices.
Definition: Accessor.hpp:25
MapResult< D > vector_attribute(const ArgType &t)
PrimitiveType primitive_type() const
ConstMapResult< D > const_vector_attribute(const ArgType &t) const
wmtk::multimesh::operations::OperationInOutData OperationInOutData
wmtk::multimesh::operations::CollapseReturnData ReturnData
CollapseNewAttributeStrategy(const wmtk::attribute::MeshAttributeHandle &h)
void update(Mesh &m, const ReturnData &ret_data, const OperationInOutData &tuples) const override
bool matches_attribute(const attribute::MeshAttributeHandle &) const override
std::unique_ptr< CollapseNewAttributeTopoInfo > m_topo_info
static CollapseFuncType standard_collapse_strategy(CollapseBasicStrategy optype)
std::function< VecType(const VecType &, const VecType &, const std::bitset< 2 > &)> CollapseFuncType
void assign_collapsed(wmtk::attribute::Accessor< T > &acc, const std::array< Tuple, 2 > &input_simplices, const Tuple &final_simplex) const