Wildmeshing Toolkit
Mesh_attributes.cpp
Go to the documentation of this file.
1 #include <numeric>
2 #include "Mesh.hpp"
3 
5 #include <wmtk/utils/Logger.hpp>
6 
7 #include "Primitive.hpp"
8 
9 namespace wmtk {
10 template <typename T>
12  const std::string& name,
13  PrimitiveType ptype,
14  int64_t size,
15  bool replace,
16  T default_value)
17 {
19  *this,
20  register_attribute_typed<T>(name, ptype, size, replace, default_value));
21  return attr;
22 }
23 
24 template <typename T>
26  const std::string& name,
27  PrimitiveType ptype,
28  int64_t size,
29  bool replace,
30  T default_value)
31 {
32  auto attr =
33  m_attribute_manager.register_attribute<T>(name, ptype, size, replace, default_value);
34  return attr;
35 }
36 
37 template <typename T>
39 {
41 }
42 
43 std::vector<int64_t> Mesh::request_simplex_indices(PrimitiveType type, int64_t count)
44 {
45  // passses back a set of new consecutive ids. in hte future this could do
46  // something smarter for re-use but that's probably too much work
47  int64_t current_capacity = capacity(type);
48 
49  // enable newly requested simplices
50  attribute::Accessor<char> flag_accessor = get_flag_accessor(type);
51  int64_t max_size = flag_accessor.reserved_size();
52 
53  if (current_capacity + count > max_size) {
54  logger().warn(
55  "Requested more {} simplices than available (have {}, wanted {}, can only have at most "
56  "{}",
57  primitive_type_name(type),
58  current_capacity,
59  count,
60  max_size);
61  return {};
62  }
63 
64  std::vector<int64_t> ret(count);
65  std::iota(ret.begin(), ret.end(), current_capacity);
66 
67 
68  int64_t new_capacity = current_capacity + ret.size();
69  assert(ret.back() + 1 == current_capacity + ret.size());
70  size_t primitive_id = get_primitive_type_id(type);
71 
72  m_attribute_manager.m_capacities[primitive_id] = new_capacity;
73 
74  attribute::CachingAccessor<char>& flag_accessor_indices = flag_accessor.index_access();
75 
76  for (const int64_t simplex_index : ret) {
77  // wmtk::logger().trace("Activating {}-simplex {}", primitive_id, simplex_index);
78  flag_accessor_indices.scalar_attribute(simplex_index) |= 0x1;
79  }
80 
81  return ret;
82 }
83 
84 int64_t Mesh::capacity(PrimitiveType type) const
85 {
87 }
88 
90 {
92 }
93 void Mesh::reserve_attributes(PrimitiveType type, int64_t size)
94 {
96 }
97 void Mesh::set_capacities(std::vector<int64_t> capacities)
98 {
99  m_attribute_manager.set_capacities(std::move(capacities));
100 }
101 
102 // reserves extra attributes than necessary right now
104 {
106 }
107 // reserves extra attributes than necessary right now
108 void Mesh::reserve_more_attributes(const std::vector<int64_t>& sizes)
109 {
110  assert(top_cell_dimension() + 1 == sizes.size());
111  for (int64_t j = 0; j < sizes.size(); ++j) {
113  }
114 }
116 {
118 }
119 void Mesh::guarantee_at_least_attributes(const std::vector<int64_t>& sizes)
120 {
121  assert(top_cell_dimension() + 1 == sizes.size());
122  for (int64_t j = 0; j < sizes.size(); ++j) {
124  }
125 }
127 {
129 }
130 void Mesh::guarantee_more_attributes(const std::vector<int64_t>& sizes)
131 {
132  assert(top_cell_dimension() + 1 == sizes.size());
133  for (int64_t j = 0; j < sizes.size(); ++j) {
135  }
136 }
137 
138 namespace {
139 std::vector<attribute::MeshAttributeHandle::HandleVariant> variant_diff(
140  std::vector<attribute::MeshAttributeHandle::HandleVariant>& a,
141  std::vector<attribute::MeshAttributeHandle::HandleVariant>& b)
142 {
143  std::vector<attribute::MeshAttributeHandle::HandleVariant> ret;
144  std::sort(a.begin(), a.end());
145 
146  std::sort(b.begin(), b.end());
147 
148  std::set_difference(a.begin(), a.end(), b.begin(), b.end(), std::inserter(ret, ret.begin()));
149  return ret;
150 }
151 } // namespace
152 std::vector<attribute::MeshAttributeHandle::HandleVariant> Mesh::custom_attributes() const
153 {
155  auto builtins = builtin_attributes();
156 
157  return variant_diff(all, builtins);
158 }
159 
162 {
163  return m_attribute_manager.get_name(handle);
164 }
166 {
168 }
169 
171  const std::vector<attribute::MeshAttributeHandle::HandleVariant>& keep_attributes)
172 {
173  auto a = this->custom_attributes();
174  auto b = keep_attributes;
175  m_attribute_manager.clear_attributes(variant_diff(a, b));
177 }
178 void Mesh::clear_attributes(const std::vector<attribute::MeshAttributeHandle>& keep_attributes)
179 {
180  std::map<Mesh*, std::vector<attribute::MeshAttributeHandle::HandleVariant>> keeps_t;
181  for (const auto& attr : keep_attributes) {
182  keeps_t[const_cast<Mesh*>(&attr.mesh())].emplace_back(attr.handle());
183  }
184  for (auto& [mptr, handles] : keeps_t) {
185  mptr->clear_attributes(handles);
186  }
187 }
189 {
190  assert(this == &to_delete.mesh());
191 
192  delete_attribute(to_delete.handle());
193 }
194 
196 {
198 }
200 {
202 }
203 
205 {
206  return m_attribute_manager.create_scope(*this);
207 }
208 
209 std::tuple<std::vector<std::vector<int64_t>>, std::vector<std::vector<int64_t>>> Mesh::consolidate()
210 {
211  // Number of dimensions
212  int64_t tcp = top_cell_dimension() + 1;
213 
214  // Store the map from new indices to old. First index is dimensions, second simplex id
215  std::vector<std::vector<int64_t>> new2old(tcp);
216  // Store the map from old indices to new. First index is dimensions, second simplex id
217  std::vector<std::vector<int64_t>> old2new(tcp);
218 
219  // Initialize both maps
220  for (int64_t d = 0; d < tcp; d++) {
221  attribute::Accessor<char> flag_accessor =
223  for (int64_t i = 0; i < capacity(wmtk::get_primitive_type_from_id(d)); ++i) {
224  if (flag_accessor.index_access().scalar_attribute(i) & 1) {
225  old2new[d].push_back(new2old[d].size());
226  new2old[d].push_back(old2new[d].size() - 1); // -1 since we just pushed into it
227  } else {
228  old2new[d].push_back(-1);
229  }
230  }
231  }
232 
233  // Use new2oldmap to compact all attributes
234  auto run = [&](auto&& mesh_attrs) {
235  for (int64_t d = 0; d < mesh_attrs.size(); ++d) {
236  auto& ma = mesh_attrs[d];
237  const auto& n2o = new2old[d];
238  ma.reserve(n2o.size());
239 
240  for (auto& h : ma.active_attributes()) {
241  ma.attribute(h).consolidate(n2o);
242  }
243  }
244  };
247 
249 
251 
252  // Update the attribute size in the manager
253  for (int64_t d = 0; d < tcp; d++) {
254  m_attribute_manager.m_capacities[d] = new2old[d].size();
255  }
256 
257  // Apply old2new to attributes containing indices
258  std::vector<std::vector<TypedAttributeHandle<int64_t>>> handle_indices =
260 
261  for (int64_t d = 0; d < tcp; d++) {
262  for (int64_t i = 0; i < handle_indices[d].size(); ++i) {
263  attribute::Accessor<int64_t> accessor = create_accessor<int64_t>(handle_indices[d][i]);
264  accessor.attribute().index_remap(old2new[d]);
265  }
266  }
267 
268  {
269  constexpr static int64_t TUPLE_SIZE = multimesh::utils::TUPLE_SIZE; // in terms of int64_t
270  constexpr static int64_t GLOBAL_ID_INDEX = multimesh::utils::GLOBAL_ID_INDEX;
271  const static std::vector<Eigen::Index> image_map_offsets{
272  Eigen::Index(TUPLE_SIZE + GLOBAL_ID_INDEX)};
273  const static std::vector<Eigen::Index> domain_map_offsets{Eigen::Index(GLOBAL_ID_INDEX)};
274  size_t dim = get_primitive_type_id(top_simplex_type());
275  const auto& top_map = old2new[dim];
276  if (auto parent_ptr = m_multi_mesh_manager.m_parent; parent_ptr != nullptr) {
277  {
278  int64_t child_id = m_multi_mesh_manager.m_child_id;
279  const auto& child_data = parent_ptr->m_multi_mesh_manager.m_children[child_id];
280  const auto handle = child_data.map_handle;
281  auto acc = parent_ptr->create_accessor(handle);
282  auto& attr = acc.attribute();
283  attr.index_remap(top_map, image_map_offsets);
284  }
285 
286  {
287  const auto handle = m_multi_mesh_manager.map_to_parent_handle;
288  auto acc = create_accessor(handle);
289  auto& attr = acc.attribute();
290  attr.index_remap(top_map, domain_map_offsets);
291  }
292  }
293 
294  for (const auto& child_data : m_multi_mesh_manager.m_children) {
295  {
296  const auto handle = child_data.map_handle;
297  auto acc = create_accessor(handle);
298  auto& attr = acc.attribute();
299  attr.index_remap(top_map, domain_map_offsets);
300  }
301  {
302  const auto handle = child_data.mesh->m_multi_mesh_manager.map_to_parent_handle;
303  auto acc = child_data.mesh->create_accessor(handle);
304  auto& attr = acc.attribute();
305  attr.index_remap(top_map, image_map_offsets);
306  }
307  }
308  }
309 
310  // Return both maps for custom attribute remapping
311  return {new2old, old2new};
312 }
313 std::vector<attribute::MeshAttributeHandle::HandleVariant> Mesh::builtin_attributes() const
314 {
315  std::vector<attribute::MeshAttributeHandle::HandleVariant> data;
316  for (const auto& vec : connectivity_attributes()) {
317  std::copy(vec.begin(), vec.end(), std::back_inserter(data));
318  }
319 
320  data.emplace_back(m_cell_hash_handle);
321  std::copy(m_flag_handles.begin(), m_flag_handles.end(), std::back_inserter(data));
322 
323  auto mm_handles = m_multi_mesh_manager.map_handles();
324  std::copy(mm_handles.begin(), mm_handles.end(), std::back_inserter(data));
325  return data;
326 }
327 
328 
330 Mesh::register_attribute<char>(const std::string&, PrimitiveType, int64_t, bool, char);
332 Mesh::register_attribute<int64_t>(const std::string&, PrimitiveType, int64_t, bool, int64_t);
334 Mesh::register_attribute<double>(const std::string&, PrimitiveType, int64_t, bool, double);
336 Mesh::register_attribute<Rational>(const std::string&, PrimitiveType, int64_t, bool, Rational);
337 
338 
340 Mesh::register_attribute_typed(const std::string&, PrimitiveType, int64_t, bool, char);
342 Mesh::register_attribute_typed(const std::string&, PrimitiveType, int64_t, bool, int64_t);
344 Mesh::register_attribute_typed(const std::string&, PrimitiveType, int64_t, bool, double);
346 Mesh::register_attribute_typed(const std::string&, PrimitiveType, int64_t, bool, Rational);
347 
348 template const int64_t& Mesh::get_attribute_default_value(
349  const TypedAttributeHandle<int64_t>& handle) const;
350 template const char& Mesh::get_attribute_default_value(
351  const TypedAttributeHandle<char>& handle) const;
352 template const double& Mesh::get_attribute_default_value(
353  const TypedAttributeHandle<double>& handle) const;
355  const TypedAttributeHandle<wmtk::Rational>& handle) const;
356 } // namespace wmtk
void set_capacities(std::vector< int64_t > capacities)
void clear_attributes()
std::vector< attribute::MeshAttributeHandle::HandleVariant > builtin_attributes() const
std::vector< attribute::MeshAttributeHandle::HandleVariant > custom_attributes() const
attribute::MeshAttributeHandle register_attribute(const std::string &name, PrimitiveType type, int64_t size, bool replace=false, T default_value=T(0))
int64_t capacity(PrimitiveType type) const
read in the m_capacities return the upper bound for the number of entities of the given dimension
attribute::TypedAttributeHandle< T > register_attribute_typed(const std::string &name, PrimitiveType type, int64_t size, bool replace=false, T default_value=T(0))
std::vector< TypedAttributeHandle< char > > m_flag_handles
0x1 == true = simplex is active (simplex exists) all flag default to 0
Definition: Mesh.hpp:864
void guarantee_more_attributes(PrimitiveType type, int64_t size)
void reserve_more_attributes(PrimitiveType type, int64_t size)
void update_child_handles()
Update the child handles after clearing attributes.
void guarantee_at_least_attributes(PrimitiveType type, int64_t size)
multimesh::MultiMeshManager m_multi_mesh_manager
Definition: Mesh.hpp:841
multimesh::attribute::AttributeScopeHandle create_scope()
int64_t top_cell_dimension() const
Definition: Mesh.hpp:992
void reserve_attributes_to_fit()
reserve space for all attributes data types for all dimensional simplices
attribute::AttributeScopeHandle create_single_mesh_scope()
std::string get_attribute_name(const TypedAttributeHandle< T > &handle) const
Definition: Mesh.hpp:949
attribute::Accessor< T, Mesh, D > create_accessor(const attribute::MeshAttributeHandle &handle)
virtual std::vector< std::vector< TypedAttributeHandle< int64_t > > > connectivity_attributes() const =0
Returns a vector of vectors of attribute handles.
void delete_attribute(const attribute::MeshAttributeHandle &to_delete)
PrimitiveType top_simplex_type() const
Definition: Mesh.hpp:996
virtual std::tuple< std::vector< std::vector< int64_t > >, std::vector< std::vector< int64_t > > > consolidate()
Consolidate the attributes, moving all valid simplexes at the beginning of the corresponding vector.
std::vector< int64_t > request_simplex_indices(PrimitiveType type, int64_t count)
TypedAttributeHandle< int64_t > m_cell_hash_handle
Definition: Mesh.hpp:868
const attribute::Accessor< char > get_flag_accessor(PrimitiveType type) const
Definition: Mesh.cpp:158
void reserve_attributes(PrimitiveType type, int64_t size)
attribute::AttributeManager m_attribute_manager
Definition: Mesh.hpp:839
const T & get_attribute_default_value(const TypedAttributeHandle< T > &handle) const
A CachingAccessor that uses tuples for accessing attributes instead of indices.
Definition: Accessor.hpp:25
CachingBaseType & index_access()
Definition: Accessor.hpp:95
Attribute< T > & attribute()
int64_t reserved_size() const
std::vector< MeshAttributes< double > > m_double_attributes
AttributeScopeHandle create_scope(Mesh &m)
std::vector< MeshAttributes< char > > m_char_attributes
void set_capacities(std::vector< int64_t > capacities)
void guarantee_at_least_attributes(int64_t dimension, int64_t size)
const T & get_attribute_default_value(const TypedAttributeHandle< T > &handle) const
std::vector< int64_t > m_capacities
std::vector< MeshAttributes< Rational > > m_rational_attributes
void clear_attributes(const std::vector< attribute::MeshAttributeHandle::HandleVariant > &custom_attributes)
Remove all custom attributes besides the one passed in.
void guarantee_more_attributes(int64_t dimension, int64_t size)
std::vector< MeshAttributeHandle::HandleVariant > get_all_attributes() const
void reserve_more_attributes(int64_t dimension, int64_t size)
std::string get_name(const TypedAttributeHandle< T > &attr) const
TypedAttributeHandle< T > register_attribute(const std::string &name, PrimitiveType type, int64_t size, bool replace, T default_value)
void delete_attribute(const attribute::MeshAttributeHandle::HandleVariant &to_delete)
void reserve_attributes(int64_t dimension, int64_t size)
std::vector< MeshAttributes< int64_t > > m_long_attributes
This handle is a wrapper for the MeshManager scope funtions.
An accessor for cached attribute values.
T & scalar_attribute(const int64_t index)
std::variant< TypedAttributeHandle< char >, TypedAttributeHandle< int64_t >, TypedAttributeHandle< double >, TypedAttributeHandle< wmtk::Rational > > HandleVariant
Handle that represents attributes for some mesh.
std::vector< ChildData > m_children
TypedAttributeHandle< int64_t > map_to_parent_handle
std::vector< TypedAttributeHandle< int64_t > > map_handles() const
Definition: Accessor.hpp:6
std::string_view primitive_type_name(PrimitiveType t)
constexpr PrimitiveType get_primitive_type_from_id(int8_t id)
Get the primitive type corresponding to its unique integer id.
constexpr int8_t get_primitive_type_id(PrimitiveType t)
Get a unique integer id corresponding to each primitive type.
spdlog::logger & logger()
Retrieves the current logger.
Definition: Logger.cpp:58