Wildmeshing Toolkit
MultiMeshManager.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <tuple>
4 #include <wmtk/Tuple.hpp>
8 // included to make a friend as this requires IDs
11 
12 // debug function that reads into this structure
14 
15 
16 namespace wmtk {
17 
18 class Mesh;
19 class HDF5Reader;
20 namespace operations {
21 class EdgeOperationData;
22 namespace utils {
23 class UpdateEdgeOperationMultiMeshMapFunctor;
24 }
25 } // namespace operations
26 namespace attribute {
27 template <typename T, typename MeshType, int Dim>
28 class Accessor;
29 }
30 namespace multimesh {
31 template <int64_t cell_dimension, typename NodeFunctor>
33 template <typename Visitor>
34 class MultiMeshSimplexVisitorExecutor;
35 
36 template <typename NodeFunctor>
37 class MultiMeshVisitor;
38 template <typename Visitor>
39 class MultiMeshVisitorExecutor;
40 
41 namespace utils {
42 class MapValidator;
43 }
44 
45 } // namespace multimesh
46 class Mesh;
47 namespace simplex {
48 class Simplex;
49 class SimplexCollection;
50 } // namespace simplex
51 } // namespace wmtk
52 namespace wmtk::multimesh {
57 {
58 public:
59  // utility function for mapping the same set of simplices (or a subset of equivalent simplices)
60  friend std::vector<std::array<Tuple, 2>> multimesh::same_simplex_dimension_surjection(
61  const Mesh& parent,
62  const Mesh& child,
63  const std::vector<int64_t>& parent_simplices);
64 
65  // let the visitor object access the internal details
66  template <int64_t cell_dimension, typename NodeFunctor>
68  friend class wmtk::Mesh;
69  template <typename Visitor>
72 
73  template <typename NodeFunctor>
75  template <typename Visitor>
77  friend class wmtk::HDF5Reader;
78 
79  friend class utils::MapValidator;
80 
81 
82  // @param the max dimension of the mesh we will get passed
83  MultiMeshManager(int64_t dimension);
89 
90  // attribute directly hashes its "children" components so it overrides "child_hashes"
91  std::map<std::string, const wmtk::utils::Hashable*> child_hashables() const override;
92  std::map<std::string, std::size_t> child_hashes() const override;
93 
94 
95  void detach_children();
96 
97  //=========================================================
98  // Storage of MultiMesh
99  //=========================================================
100 
101  /*
102  * @brief The set of attribute handles used by this manager (owned by this mesh)
103  *
104  * @returns a vector of attribute handles
105  */
106  std::vector<TypedAttributeHandle<int64_t>> map_handles() const;
111  bool is_root() const;
119  int64_t child_id() const;
120  // @brief a unique id for this mesh with respect to its multi-mesh tree
121  //
122  // This is guaranteed to be the sequence of mesh indices used to traverse from the root of the
123  // structure to this mesh (backwards)
124  std::vector<int64_t> absolute_id() const;
125 
126 
127  Mesh& get_mesh(Mesh& m, const std::vector<int64_t>& absolute_id);
128  const Mesh& get_mesh(const Mesh& m, const std::vector<int64_t>& absolute_id) const;
129 
130 
131  Mesh& get_child_mesh(Mesh& m, const std::vector<int64_t>& relative_id);
132  const Mesh& get_child_mesh(const Mesh& m, const std::vector<int64_t>& relative_id) const;
133 
142  void register_child_mesh(
143  Mesh& my_mesh,
144  const std::shared_ptr<Mesh>& child_mesh,
145  const std::vector<std::array<Tuple, 2>>& child_tuple_my_tuple_map);
146 
154  void deregister_child_mesh(Mesh& my_mesh, const std::shared_ptr<Mesh>& child_mesh_ptr);
155 
162  void update_child_handles(Mesh& my_mesh);
163 
164 
165  // bool are_maps_valid(const Mesh& my_mesh) const;
166 
167  //===========
168  //===========
169  // Map functions
170  //===========
171  //===========
172  // Note that when we map a M-tuple from a K-complex to a J-complex there are different
173  // relationships necessary if K == J
174  // if M == K then this is unique
175  // if M < K then this is many to many
176  // if K < J
177  // if M == K then it is one to many
178  // if M < K then it is many to many
179  //
180  // Note also that functions that end with _tuple or _tuples willl return tuples rather than
181  // simplices
182 
183  //===========
184  // simplex::Simplex maps
185  //===========
204  std::vector<simplex::Simplex>
205  map(const Mesh& my_mesh, const Mesh& other_mesh, const simplex::Simplex& my_simplex) const;
218  std::vector<Tuple> lub_map_tuples(
219  const Mesh& my_mesh,
220  const Mesh& other_mesh,
221  const simplex::Simplex& my_simplex) const;
222 
223 
234  std::vector<simplex::Simplex>
235  lub_map(const Mesh& my_mesh, const Mesh& other_mesh, const simplex::Simplex& my_simplex) const;
254  std::vector<Tuple> map_tuples(
255  const Mesh& my_mesh,
256  const Mesh& other_mesh,
257  const simplex::Simplex& my_simplex) const;
258 
272  simplex::Simplex map_to_parent(const Mesh& my_mesh, const simplex::Simplex& my_simplex) const;
287  Tuple map_to_parent_tuple(const Mesh& my_mesh, const simplex::Simplex& my_simplex) const;
288 
289 
299  simplex::Simplex map_to_root(const Mesh& my_mesh, const simplex::Simplex& my_simplex) const;
310  Tuple map_to_root_tuple(const Mesh& my_mesh, const simplex::Simplex& my_simplex) const;
311 
322  std::vector<simplex::Simplex> map_to_child(
323  const Mesh& my_mesh,
324  const Mesh& child_mesh,
325  const simplex::Simplex& my_simplex) const;
326  std::vector<Tuple> map_to_child_tuples(
327  const Mesh& my_mesh,
328  const Mesh& child_mesh,
329  const simplex::Simplex& my_simplex) const;
330 
331 
332  bool can_map(const Mesh& my_mesh, const Mesh& other_mesh, const simplex::Simplex& my_simplex)
333  const;
334  bool can_map_child(
335  const Mesh& my_mesh,
336  const Mesh& other_mesh,
337  const simplex::Simplex& my_simplex) const;
338 
339  /* @brief obtains the root mesh of this multi-mesh tree
340  *
341  * @param my_mesh the mesh that this structure is owned by
342  */
343  const Mesh& get_root_mesh(const Mesh& my_mesh) const;
344  /* @brief obtains the root mesh of this multi-mesh tree
345  *
346  * @param my_mesh the mesh that this structure is owned by
347  */
348  Mesh& get_root_mesh(Mesh& my_mesh);
349  std::vector<std::shared_ptr<Mesh>> get_child_meshes() const;
350 
351  void serialize(MeshWriter& writer, const Mesh* local_root = nullptr) const;
352 
353  bool has_child_mesh_in_dimension(int64_t dimension) const
354  {
355  return m_has_child_mesh_in_dimension[dimension];
356  }
357 
358  bool has_child_mesh() const;
359 
360 protected:
361  // Storage of a child mesh (a pointer from the mesh + the map from this mesh -> the child)
362  struct ChildData
363  {
364  std::shared_ptr<Mesh> mesh;
365  // store the map from the manager's mesh to the child mesh (on the top
366  // level simplex of the mesh)
367  // encoded by a pair of two tuples, from a tuple in current mesh to a tuple in
368  // child_mesh
370  };
371 
372 protected:
373  Mesh* m_parent = nullptr;
374  // only valid if this is the child of some other mesh
375  // store the map to the base_tuple of the my_mesh
377 
378  // the index of this mesh with respect to its parent's m_children
379  int64_t m_child_id = -1;
380 
381 
382  // Child Meshes
383  std::vector<ChildData> m_children;
384 
385  // indicates which kind of child mesh the parent mesh has
386  std::vector<bool> m_has_child_mesh_in_dimension;
387 
388 protected: // protected to enable unit testing
389  //===========
390  // Tuple maps
391  //===========
392 
393  // generic mapping function that maps a tuple from "this" mesh to its parent. We don't actually
394  // need the simplex parent of the tuple being mapped up so we can throw away the simplex-nes
395  Tuple map_tuple_to_parent_tuple(const Mesh& my_mesh, const Tuple& my_tuple) const;
396 
397  Tuple map_tuple_to_root_tuple(const Mesh& my_mesh, const Tuple& my_tuple) const;
398 
399  // wrapper for implementing converting tuple to a child using the internal map data
400  std::vector<Tuple> map_to_child_tuples(
401  const Mesh& my_mesh,
402  const ChildData& child_data,
403  const simplex::Simplex& simplex) const;
404 
405  // wrapper for implementing converting tuple to a child using the internal map data
406  std::vector<Tuple> map_to_child_tuples(
407  const Mesh& my_mesh,
408  int64_t child_id,
409  const simplex::Simplex& simplex) const;
410 
411 
412  // utility static function for mapping a tuple between the source and target given a specified
413  // map accessor
415  const Mesh& source_mesh,
416  const Mesh& target_mesh,
417  const wmtk::attribute::Accessor<int64_t>& source_to_target_map_accessor,
418  const Tuple& source_tuple);
419 
420  const std::vector<ChildData>& children() const { return m_children; }
421  std::vector<ChildData>& children() { return m_children; }
422 
423  // uility for consistently specifying the name of the attribute used to map this mesh to its
424  // parent
425  static std::string parent_to_child_map_attribute_name(int64_t index);
426  // uility for consistently specifying the name of the attribute used to map this mesh to its
427  // parent
428  static std::string child_to_parent_map_attribute_name();
429 
430  // returns {parent_to_child, child_to_parent} accessors
431  std::array<wmtk::attribute::Accessor<int64_t>, 2> get_map_accessors(
432  Mesh& my_mesh,
433  ChildData& c);
434  // returns {parent_to_child, child_to_parent} accessors
435  std::array<const wmtk::attribute::Accessor<int64_t>, 2> get_map_const_accessors(
436  const Mesh& my_mesh,
437  const ChildData& c) const;
438 
439 
440  //===========
441  // Utilities for updating maps after operations
442  //===========
443  // updates the map tuples to children for a particular dimension.
444  // for eeach simplex we store its global index and all variations of that face using a
445  // consistent set of subsimplices wrt the tuple representation If the new tuple has a
446  // representation
447  //
448  // it cannot handle map updates of its faces?
450  Mesh& my_mesh,
451  PrimitiveType primitive_type,
452  const std::vector<std::tuple<int64_t, std::vector<Tuple>>>& simplices_to_update,
453  const std::vector<std::tuple<int64_t, std::array<int64_t, 2>>>& split_cell_maps = {});
454 
456  Mesh& my_mesh,
457  PrimitiveType primitive_type,
458  const operations::EdgeOperationData& operation_data);
459 
460 
461  // uses the available parameters to find a tuple that is equivalent to old_smiplex but using
462  // still-existing top level simplices. by equivalent each sub-simplex of old_simplex's tuple
463  // maps to the same thing as the returned tuple
464  std::optional<Tuple> find_valid_tuple(
465  Mesh& my_mesh,
466  const simplex::Simplex& old_simplex,
467  const int64_t old_gid,
468  const std::vector<Tuple>& tuple_alternatives,
469  const std::vector<std::tuple<int64_t, std::array<int64_t, 2>>>& split_cell_maps = {}) const;
470 
471  // returns a tuple such that every subsmipelx in old_simplex's tuple maps to the same smiplex as
472  std::optional<Tuple> find_valid_tuple_from_alternatives(
473  Mesh& my_mesh,
474  PrimitiveType primitive_type,
475  const std::vector<Tuple>& tuple_alternatives) const;
476 
477  // returns a tuple such that every subsmipelx in old_simplex's tuple maps to the same smiplex as
478  // before
479  std::optional<Tuple> find_valid_tuple_from_split(
480  Mesh& my_mesh,
481  const simplex::Simplex& old_simplex,
482  const int64_t old_gid,
483  const std::vector<Tuple>& tuple_alternatives,
484  const std::vector<std::tuple<int64_t, std::array<int64_t, 2>>>& split_cell_maps) const;
485 
486  std::optional<Tuple> try_updating_map_tuple_from_split(
487  Mesh& my_mesh,
488  const simplex::Simplex& old_simplex, // map tuple is contained in this
489  const int64_t old_gid,
490  const std::vector<Tuple>& tuple_alternatives,
491  const std::tuple<int64_t, std::array<int64_t, 2>>& split_cell_maps) const;
492 
493 
494  static std::optional<Tuple> find_tuple_from_gid(
495  const Mesh& my_mesh,
496  PrimitiveType primitive_type,
497  const std::vector<Tuple>& tuples,
498  int64_t gid);
499 
500  // helper for updating multimap used in the update multimesh edge functor
501  static int64_t child_global_cid(
502  const wmtk::attribute::Accessor<int64_t>& parent_to_child,
503  int64_t parent_gid);
504  // helper for updating multimap used in the update multimesh edge functor
505  static int64_t parent_global_cid(
506  const wmtk::attribute::Accessor<int64_t>& child_to_parent,
507  int64_t child_gid);
508  // helper for updating multimap used in the update multimesh edge functor
509  static int64_t parent_local_fid(
510  const wmtk::attribute::Accessor<int64_t>& child_to_parent,
511  int64_t child_gid);
512 
513 
514  // ===============================================================================
515  // ===============================================================================
516  // ===============================================================================
517  // ===============================================================================
518 
519 
520  // internal function for mapping up a multimesh tree by a certain number of edges
521  //
522  // @return the mesh found at the top and the tuple that was found
523  std::pair<const Mesh&, Tuple>
524  map_up_to_tuples(const Mesh& my_mesh, const simplex::Simplex& simplex, int64_t depth) const;
525 
526  // internal function for mapping down a multimesh tree by following a sequence of ids
527  //
528  // @return the mesh found at the top and the tuple that was found
529  std::vector<Tuple> map_down_relative_tuples(
530  const Mesh& my_mesh,
531  const simplex::Simplex& my_simplex,
532  const std::vector<int64_t>& local_id_path) const;
533 
534 
535 public:
536  static std::vector<int64_t> least_upper_bound_id(
537  const std::vector<int64_t>& a,
538  const std::vector<int64_t>& b);
539  static std::vector<int64_t> relative_id(
540  const std::vector<int64_t>& parent,
541  const std::vector<int64_t>& child);
542 
543 public:
544  std::vector<int64_t> relative_id(const Mesh& my_mesh, const Mesh& parent_mesh) const;
545 
546  static bool is_child(const std::vector<int64_t>& child, const std::vector<int64_t>& parent);
547  bool is_child(const Mesh& my_mesh, const Mesh& parent_mesh) const;
548 
549 private:
550  // this is defined internally but is preferablly invoked through the multimesh free function
551  static std::vector<std::array<Tuple, 2>> same_simplex_dimension_surjection(
552  const Mesh& parent,
553  const Mesh& child,
554  const std::vector<int64_t>& parent_simplices);
555 
556 public:
566 public:
567  // remove after bug fix
568  void check_map_valid(const Mesh& my_mesh) const;
569 
570  void check_child_map_valid(const Mesh& my_mesh, const ChildData& child_data) const;
571 };
572 } // namespace wmtk::multimesh
Handle that represents attributes for some mesh.
Implementation details for how the Mesh class implements multiple meshes.
void check_map_valid(const Mesh &my_mesh) const
update all the hashes of the top-simplces of the parent mesh around a vertex hashes of the parent tup...
Tuple map_to_root_tuple(const Mesh &my_mesh, const simplex::Simplex &my_simplex) const
maps a simplex from this mesh to the root mesh
const std::vector< ChildData > & children() const
int64_t child_id() const
Specifies the child id of this mesh if it a child mesh in a mult-mesh tree.
bool has_child_mesh_in_dimension(int64_t dimension) const
static int64_t child_global_cid(const wmtk::attribute::Accessor< int64_t > &parent_to_child, int64_t parent_gid)
std::optional< Tuple > find_valid_tuple_from_split(Mesh &my_mesh, const simplex::Simplex &old_simplex, const int64_t old_gid, const std::vector< Tuple > &tuple_alternatives, const std::vector< std::tuple< int64_t, std::array< int64_t, 2 >>> &split_cell_maps) const
static std::vector< std::array< Tuple, 2 > > same_simplex_dimension_surjection(const Mesh &parent, const Mesh &child, const std::vector< int64_t > &parent_simplices)
static int64_t parent_local_fid(const wmtk::attribute::Accessor< int64_t > &child_to_parent, int64_t child_gid)
bool can_map_child(const Mesh &my_mesh, const Mesh &other_mesh, const simplex::Simplex &my_simplex) const
MultiMeshManager(const MultiMeshManager &o)
std::map< std::string, const wmtk::utils::Hashable * > child_hashables() const override
const Mesh & get_root_mesh(const Mesh &my_mesh) const
std::vector< ChildData > m_children
MultiMeshManager(MultiMeshManager &&o)
void register_child_mesh(Mesh &my_mesh, const std::shared_ptr< Mesh > &child_mesh, const std::vector< std::array< Tuple, 2 >> &child_tuple_my_tuple_map)
register a another mesh as a child of this mesh.
std::optional< Tuple > find_valid_tuple_from_alternatives(Mesh &my_mesh, PrimitiveType primitive_type, const std::vector< Tuple > &tuple_alternatives) const
Mesh & get_mesh(Mesh &m, const std::vector< int64_t > &absolute_id)
static bool is_child(const std::vector< int64_t > &child, const std::vector< int64_t > &parent)
void deregister_child_mesh(Mesh &my_mesh, const std::shared_ptr< Mesh > &child_mesh_ptr)
Deregister a child mesh.
static int64_t parent_global_cid(const wmtk::attribute::Accessor< int64_t > &child_to_parent, int64_t child_gid)
static Tuple map_tuple_between_meshes(const Mesh &source_mesh, const Mesh &target_mesh, const wmtk::attribute::Accessor< int64_t > &source_to_target_map_accessor, const Tuple &source_tuple)
bool is_root() const
Specifies whether this structure is the root of a multi-mesh tree.
std::vector< int64_t > absolute_id() const
static std::vector< int64_t > least_upper_bound_id(const std::vector< int64_t > &a, const std::vector< int64_t > &b)
static std::string parent_to_child_map_attribute_name(int64_t index)
static std::string child_to_parent_map_attribute_name()
std::optional< Tuple > try_updating_map_tuple_from_split(Mesh &my_mesh, const simplex::Simplex &old_simplex, const int64_t old_gid, const std::vector< Tuple > &tuple_alternatives, const std::tuple< int64_t, std::array< int64_t, 2 >> &split_cell_maps) const
std::vector< simplex::Simplex > map(const Mesh &my_mesh, const Mesh &other_mesh, const simplex::Simplex &my_simplex) const
maps a simplex from this mesh to any other mesh
void serialize(MeshWriter &writer, const Mesh *local_root=nullptr) const
std::vector< std::shared_ptr< Mesh > > get_child_meshes() const
std::vector< Tuple > map_down_relative_tuples(const Mesh &my_mesh, const simplex::Simplex &my_simplex, const std::vector< int64_t > &local_id_path) const
std::vector< bool > m_has_child_mesh_in_dimension
TypedAttributeHandle< int64_t > map_to_parent_handle
MultiMeshManager & operator=(const MultiMeshManager &o)
static std::vector< int64_t > relative_id(const std::vector< int64_t > &parent, const std::vector< int64_t > &child)
std::vector< TypedAttributeHandle< int64_t > > map_handles() const
std::map< std::string, std::size_t > child_hashes() const override
std::vector< Tuple > lub_map_tuples(const Mesh &my_mesh, const Mesh &other_mesh, const simplex::Simplex &my_simplex) const
maps a simplex from this mesh to any other mesh using the LUB as the root
void update_child_handles(Mesh &my_mesh)
Clean up child data after deleting attributes.
std::vector< ChildData > & children()
std::array< wmtk::attribute::Accessor< int64_t >, 2 > get_map_accessors(Mesh &my_mesh, ChildData &c)
Tuple map_tuple_to_root_tuple(const Mesh &my_mesh, const Tuple &my_tuple) const
void update_map_tuple_hashes(Mesh &my_mesh, PrimitiveType primitive_type, const std::vector< std::tuple< int64_t, std::vector< Tuple >>> &simplices_to_update, const std::vector< std::tuple< int64_t, std::array< int64_t, 2 >>> &split_cell_maps={})
simplex::Simplex map_to_root(const Mesh &my_mesh, const simplex::Simplex &my_simplex) const
maps a simplex from this mesh to the root mesh
simplex::Simplex map_to_parent(const Mesh &my_mesh, const simplex::Simplex &my_simplex) const
optimized map from a simplex from this mesh to its direct parent
MultiMeshManager & operator=(MultiMeshManager &&o)
std::array< const wmtk::attribute::Accessor< int64_t >, 2 > get_map_const_accessors(const Mesh &my_mesh, const ChildData &c) const
std::vector< Tuple > map_tuples(const Mesh &my_mesh, const Mesh &other_mesh, const simplex::Simplex &my_simplex) const
maps a simplex from this mesh to any other mesh
static std::optional< Tuple > find_tuple_from_gid(const Mesh &my_mesh, PrimitiveType primitive_type, const std::vector< Tuple > &tuples, int64_t gid)
Tuple map_to_parent_tuple(const Mesh &my_mesh, const simplex::Simplex &my_simplex) const
optimized map from a simplex from this mesh to its direct parent
void check_child_map_valid(const Mesh &my_mesh, const ChildData &child_data) const
bool can_map(const Mesh &my_mesh, const Mesh &other_mesh, const simplex::Simplex &my_simplex) const
std::vector< Tuple > map_to_child_tuples(const Mesh &my_mesh, const Mesh &child_mesh, const simplex::Simplex &my_simplex) const
Mesh & get_child_mesh(Mesh &m, const std::vector< int64_t > &relative_id)
std::optional< Tuple > find_valid_tuple(Mesh &my_mesh, const simplex::Simplex &old_simplex, const int64_t old_gid, const std::vector< Tuple > &tuple_alternatives, const std::vector< std::tuple< int64_t, std::array< int64_t, 2 >>> &split_cell_maps={}) const
std::vector< simplex::Simplex > map_to_child(const Mesh &my_mesh, const Mesh &child_mesh, const simplex::Simplex &my_simplex) const
optimized map fromsimplex from this mesh to one of its direct children
std::pair< const Mesh &, Tuple > map_up_to_tuples(const Mesh &my_mesh, const simplex::Simplex &simplex, int64_t depth) const
Tuple map_tuple_to_parent_tuple(const Mesh &my_mesh, const Tuple &my_tuple) const
void update_maps_from_edge_operation(Mesh &my_mesh, PrimitiveType primitive_type, const operations::EdgeOperationData &operation_data)
std::vector< simplex::Simplex > lub_map(const Mesh &my_mesh, const Mesh &other_mesh, const simplex::Simplex &my_simplex) const
maps a simplex from this mesh to any other mesh using the LUB as the root
std::pair< std::shared_ptr< Mesh >, std::shared_ptr< Mesh > > multimesh(const MultiMeshType &type, Mesh &parent, std::shared_ptr< Mesh > child, const attribute::MeshAttributeHandle parent_position_handle, const std::string &tag_name, const int64_t tag_value, const int64_t primitive)
Definition: multimesh.cpp:15
MultiMeshVisitor(NodeFunctor &&) -> MultiMeshVisitor< NodeFunctor >
std::vector< std::array< Tuple, 2 > > same_simplex_dimension_surjection(const Mesh &parent, const Mesh &child, const std::vector< int64_t > &parent_simplices)
MultiMeshSimplexVisitor(std::integral_constant< int64_t, cell_dimension >, NodeFunctor &&) -> MultiMeshSimplexVisitor< cell_dimension, NodeFunctor >
Definition: Accessor.hpp:6
TypedAttributeHandle< int64_t > map_handle