Wildmeshing Toolkit
Loading...
Searching...
No Matches
MultiMeshManager.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <tuple>
4#include <optional>
5#include <wmtk/Tuple.hpp>
7// included to make a friend as this requires IDs
9
10// debug function that reads into this structure
12
13
14namespace wmtk {
15
16class Mesh;
17class HDF5Reader;
18namespace operations {
19class EdgeOperationData;
20namespace utils {
21class UpdateEdgeOperationMultiMeshMapFunctor;
22}
23} // namespace operations
24namespace attribute {
25}
26namespace multimesh {
27template <int64_t cell_dimension, typename NodeFunctor>
29template <typename Visitor>
30class MultiMeshSimplexVisitorExecutor;
31
32template <typename NodeFunctor>
34template <typename Visitor>
35class MultiMeshVisitorExecutor;
36
37namespace utils {
38class MapValidator;
39}
40
41} // namespace multimesh
42class Mesh;
43namespace simplex {
44class Simplex;
45class SimplexCollection;
46} // namespace simplex
47} // namespace wmtk
48namespace wmtk::multimesh {
53{
54public:
55
56 // let the visitor object access the internal details
57 template <int64_t cell_dimension, typename NodeFunctor>
59 friend class wmtk::Mesh;
60 template <typename Visitor>
63
64 template <typename NodeFunctor>
66 template <typename Visitor>
68 friend class wmtk::HDF5Reader;
69
70 friend class utils::MapValidator;
71
72
73 // @param the max dimension of the mesh we will get passed
74 MultiMeshManager(int64_t dimension);
80
81 // attribute directly hashes its "children" components so it overrides "child_hashes"
82 std::map<std::string, const wmtk::utils::Hashable*> child_hashables() const override;
83 std::map<std::string, std::size_t> child_hashes() const override;
84
85
86 void detach_children();
87
88 //=========================================================
89 // Storage of MultiMesh
90 //=========================================================
91
92 /*
93 * @brief The set of attribute handles used by this manager (owned by this mesh)
94 *
95 * @returns a vector of attribute handles
96 */
97 std::vector<TypedAttributeHandle<int64_t>> map_handles() const;
102 bool is_root() const;
110 int64_t child_id() const;
111 // @brief a unique id for this mesh with respect to its multi-mesh tree
112 //
113 // This is guaranteed to be the sequence of mesh indices used to traverse from the root of the
114 // structure to this mesh (backwards)
115 std::vector<int64_t> absolute_id() const;
116
117
118 Mesh& get_mesh(Mesh& m, const std::vector<int64_t>& absolute_id);
119 const Mesh& get_mesh(const Mesh& m, const std::vector<int64_t>& absolute_id) const;
120
121
122 Mesh& get_child_mesh(Mesh& m, const std::vector<int64_t>& relative_id);
123 const Mesh& get_child_mesh(const Mesh& m, const std::vector<int64_t>& relative_id) const;
124
134 Mesh& my_mesh,
135 const std::shared_ptr<Mesh>& child_mesh,
136 const std::vector<std::array<Tuple, 2>>& child_tuple_my_tuple_map);
137
145 void deregister_child_mesh(Mesh& my_mesh, const std::shared_ptr<Mesh>& child_mesh_ptr);
146
153 void update_child_handles(Mesh& my_mesh);
154
155
156 // bool are_maps_valid(const Mesh& my_mesh) const;
157
158 //===========
159 //===========
160 // Map functions
161 //===========
162 //===========
163 // Note that when we map a M-tuple from a K-complex to a J-complex there are different
164 // relationships necessary if K == J
165 // if M == K then this is unique
166 // if M < K then this is many to many
167 // if K < J
168 // if M == K then it is one to many
169 // if M < K then it is many to many
170 //
171 // Note also that functions that end with _tuple or _tuples willl return tuples rather than
172 // simplices
173
174 //===========
175 // simplex::Simplex maps
176 //===========
195 std::vector<simplex::Simplex>
196 map(const Mesh& my_mesh, const Mesh& other_mesh, const simplex::Simplex& my_simplex) const;
209 std::vector<Tuple> lub_map_tuples(
210 const Mesh& my_mesh,
211 const Mesh& other_mesh,
212 const simplex::Simplex& my_simplex) const;
213
214
225 std::vector<simplex::Simplex>
226 lub_map(const Mesh& my_mesh, const Mesh& other_mesh, const simplex::Simplex& my_simplex) const;
245 std::vector<Tuple> map_tuples(
246 const Mesh& my_mesh,
247 const Mesh& other_mesh,
248 const simplex::Simplex& my_simplex) const;
249
263 simplex::Simplex map_to_parent(const Mesh& my_mesh, const simplex::Simplex& my_simplex) const;
278 Tuple map_to_parent_tuple(const Mesh& my_mesh, const simplex::Simplex& my_simplex) const;
279
280
290 simplex::Simplex map_to_root(const Mesh& my_mesh, const simplex::Simplex& my_simplex) const;
301 Tuple map_to_root_tuple(const Mesh& my_mesh, const simplex::Simplex& my_simplex) const;
302
313 std::vector<simplex::Simplex> map_to_child(
314 const Mesh& my_mesh,
315 const Mesh& child_mesh,
316 const simplex::Simplex& my_simplex) const;
317 std::vector<Tuple> map_to_child_tuples(
318 const Mesh& my_mesh,
319 const Mesh& child_mesh,
320 const simplex::Simplex& my_simplex) const;
321
322
323 bool can_map(const Mesh& my_mesh, const Mesh& other_mesh, const simplex::Simplex& my_simplex)
324 const;
325 bool can_map_child(
326 const Mesh& my_mesh,
327 const Mesh& other_mesh,
328 const simplex::Simplex& my_simplex) const;
329
330 /* @brief obtains the root mesh of this multi-mesh tree
331 *
332 * @param my_mesh the mesh that this structure is owned by
333 */
334 const Mesh& get_root_mesh(const Mesh& my_mesh) const;
335 /* @brief obtains the root mesh of this multi-mesh tree
336 *
337 * @param my_mesh the mesh that this structure is owned by
338 */
339 Mesh& get_root_mesh(Mesh& my_mesh);
340 std::vector<std::shared_ptr<Mesh>> get_child_meshes() const;
341
342 void serialize(MeshWriter& writer, const Mesh* local_root = nullptr) const;
343
344 bool has_child_mesh_in_dimension(int64_t dimension) const
345 {
346 return m_has_child_mesh_in_dimension[dimension];
347 }
348
349 bool has_child_mesh() const;
350
351protected:
352 // Storage of a child mesh (a pointer from the mesh + the map from this mesh -> the child)
354 {
355 std::shared_ptr<Mesh> mesh;
356 // store the map from the manager's mesh to the child mesh (on the top
357 // level simplex of the mesh)
358 // encoded by a pair of two tuples, from a tuple in current mesh to a tuple in
359 // child_mesh
361 };
362
363protected:
364 Mesh* m_parent = nullptr;
365 // only valid if this is the child of some other mesh
366 // store the map to the base_tuple of the my_mesh
368
369 // the index of this mesh with respect to its parent's m_children
370 int64_t m_child_id = -1;
371
372
373 // Child Meshes
374 std::vector<ChildData> m_children;
375
376 // indicates which kind of child mesh the parent mesh has
378
379protected: // protected to enable unit testing
380 //===========
381 // Tuple maps
382 //===========
383
384 // generic mapping function that maps a tuple from "this" mesh to its parent. We don't actually
385 // need the simplex parent of the tuple being mapped up so we can throw away the simplex-nes
386 Tuple map_tuple_to_parent_tuple(const Mesh& my_mesh, const Tuple& my_tuple) const;
387
388 Tuple map_tuple_to_root_tuple(const Mesh& my_mesh, const Tuple& my_tuple) const;
389
390 // wrapper for implementing converting tuple to a child using the internal map data
391 std::vector<Tuple> map_to_child_tuples(
392 const Mesh& my_mesh,
393 const ChildData& child_data,
394 const simplex::Simplex& simplex) const;
395
396 // wrapper for implementing converting tuple to a child using the internal map data
397 std::vector<Tuple> map_to_child_tuples(
398 const Mesh& my_mesh,
399 int64_t child_id,
400 const simplex::Simplex& simplex) const;
401
402
403 // utility static function for mapping a tuple between the source and target given a specified
404 // map accessor
406 const Mesh& source_mesh,
407 const Mesh& target_mesh,
408 const wmtk::attribute::Accessor<int64_t>& source_to_target_map_accessor,
409 const Tuple& source_tuple);
410
411 const std::vector<ChildData>& children() const { return m_children; }
412 std::vector<ChildData>& children() { return m_children; }
413
414 // uility for consistently specifying the name of the attribute used to map this mesh to its
415 // parent
416 static std::string parent_to_child_map_attribute_name(int64_t index);
417 // uility for consistently specifying the name of the attribute used to map this mesh to its
418 // parent
419 static std::string child_to_parent_map_attribute_name();
420
421 // returns {parent_to_child, child_to_parent} accessors
422 std::array<wmtk::attribute::Accessor<int64_t>, 2> get_map_accessors(
423 Mesh& my_mesh,
424 ChildData& c);
425 // returns {parent_to_child, child_to_parent} accessors
426 std::array<const wmtk::attribute::Accessor<int64_t>, 2> get_map_const_accessors(
427 const Mesh& my_mesh,
428 const ChildData& c) const;
429
430
431 //===========
432 // Utilities for updating maps after operations
433 //===========
434 // updates the map tuples to children for a particular dimension.
435 // for eeach simplex we store its global index and all variations of that face using a
436 // consistent set of subsimplices wrt the tuple representation If the new tuple has a
437 // representation
438 //
439 // it cannot handle map updates of its faces?
441 Mesh& my_mesh,
442 PrimitiveType primitive_type,
443 const std::vector<std::tuple<int64_t, std::vector<Tuple>>>& simplices_to_update,
444 const std::vector<std::tuple<int64_t, std::array<int64_t, 2>>>& split_cell_maps = {});
445
447 Mesh& my_mesh,
448 PrimitiveType primitive_type,
449 const operations::EdgeOperationData& operation_data);
450
451
452 // uses the available parameters to find a tuple that is equivalent to old_smiplex but using
453 // still-existing top level simplices. by equivalent each sub-simplex of old_simplex's tuple
454 // maps to the same thing as the returned tuple
455 std::optional<Tuple> find_valid_tuple(
456 Mesh& my_mesh,
457 const simplex::Simplex& old_simplex,
458 const int64_t old_gid,
459 const std::vector<Tuple>& tuple_alternatives,
460 const std::vector<std::tuple<int64_t, std::array<int64_t, 2>>>& split_cell_maps = {}) const;
461
462 // returns a tuple such that every subsmipelx in old_simplex's tuple maps to the same smiplex as
463 std::optional<Tuple> find_valid_tuple_from_alternatives(
464 Mesh& my_mesh,
465 PrimitiveType primitive_type,
466 const std::vector<Tuple>& tuple_alternatives) const;
467
468 // returns a tuple such that every subsmipelx in old_simplex's tuple maps to the same smiplex as
469 // before
470 std::optional<Tuple> find_valid_tuple_from_split(
471 Mesh& my_mesh,
472 const simplex::Simplex& old_simplex,
473 const int64_t old_gid,
474 const std::vector<Tuple>& tuple_alternatives,
475 const std::vector<std::tuple<int64_t, std::array<int64_t, 2>>>& split_cell_maps) const;
476
478 Mesh& my_mesh,
479 const simplex::Simplex& old_simplex, // map tuple is contained in this
480 const int64_t old_gid,
481 const std::vector<Tuple>& tuple_alternatives,
482 const std::tuple<int64_t, std::array<int64_t, 2>>& split_cell_maps) const;
483
484
485 static std::optional<Tuple> find_tuple_from_gid(
486 const Mesh& my_mesh,
487 PrimitiveType primitive_type,
488 const std::vector<Tuple>& tuples,
489 int64_t gid);
490
491 // helper for updating multimap used in the update multimesh edge functor
492 static int64_t child_global_cid(
493 const wmtk::attribute::Accessor<int64_t>& parent_to_child,
494 int64_t parent_gid);
495 // helper for updating multimap used in the update multimesh edge functor
496 static int64_t parent_global_cid(
497 const wmtk::attribute::Accessor<int64_t>& child_to_parent,
498 int64_t child_gid);
499 // helper for updating multimap used in the update multimesh edge functor
500 static int64_t parent_local_fid(
501 const wmtk::attribute::Accessor<int64_t>& child_to_parent,
502 int64_t child_gid);
503
504
505 // ===============================================================================
506 // ===============================================================================
507 // ===============================================================================
508 // ===============================================================================
509
510
511 // internal function for mapping up a multimesh tree by a certain number of edges
512 //
513 // @return the mesh found at the top and the tuple that was found
514 std::pair<const Mesh&, Tuple>
515 map_up_to_tuples(const Mesh& my_mesh, const simplex::Simplex& simplex, int64_t depth) const;
516
517 // internal function for mapping down a multimesh tree by following a sequence of ids
518 //
519 // @return the mesh found at the top and the tuple that was found
520 std::vector<Tuple> map_down_relative_tuples(
521 const Mesh& my_mesh,
522 const simplex::Simplex& my_simplex,
523 const std::vector<int64_t>& local_id_path) const;
524
525
526public:
527 static std::vector<int64_t> least_upper_bound_id(
528 const std::vector<int64_t>& a,
529 const std::vector<int64_t>& b);
530 static std::vector<int64_t> relative_id(
531 const std::vector<int64_t>& parent,
532 const std::vector<int64_t>& child);
533
534public:
535 std::vector<int64_t> relative_id(const Mesh& my_mesh, const Mesh& parent_mesh) const;
536
537 static bool is_child(const std::vector<int64_t>& child, const std::vector<int64_t>& parent);
538 bool is_child(const Mesh& my_mesh, const Mesh& parent_mesh) const;
539
540 // this is defined internally but is preferablly invoked through the multimesh free function
541 static std::vector<std::array<Tuple, 2>> same_simplex_dimension_surjection(
542 const Mesh& parent,
543 const Mesh& child,
544 const std::vector<int64_t>& parent_simplices);
545
546public:
556public:
557 // remove after bug fix
558 void check_map_valid(const Mesh& my_mesh) const;
559
560 void check_child_map_valid(const Mesh& my_mesh, const ChildData& child_data) const;
561};
562} // namespace wmtk::multimesh
The Tuple is the basic navigation tool in our mesh data structure.
Definition Tuple.hpp:19
An Accessor that uses tuples for accessing attributes instead of indices.
Definition Accessor.hpp:28
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
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)
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)
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)
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::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
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)
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
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)
std::vector< ChildData > & children()
static std::string child_to_parent_map_attribute_name()
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={})
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::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
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
const std::vector< ChildData > & children() const
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::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
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.
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 >
MultiMeshSimplexVisitor(std::integral_constant< int64_t, cell_dimension >, NodeFunctor &&) -> MultiMeshSimplexVisitor< cell_dimension, NodeFunctor >