29 m.m_multi_mesh_manager.m_parent =
nullptr;
30 m.m_multi_mesh_manager.m_child_id = -1;
38 const Mesh& source_mesh,
39 const Mesh& target_mesh,
41 const Tuple& source_tuple)
43 assert(source_mesh.
is_valid(source_tuple));
48 std::min(source_mesh_primitive_type, target_mesh_primitive_type);
49 Tuple source_mesh_target_tuple = source_tuple;
50 auto [source_mesh_base_tuple, target_mesh_base_tuple] =
53 if (source_mesh_base_tuple.is_null() || target_mesh_base_tuple.is_null()) {
61 if (source_mesh_base_tuple.m_global_cid != source_mesh_target_tuple.
m_global_cid) {
63 assert(source_mesh_primitive_type > target_mesh_primitive_type);
67 for (
const Tuple& t : equivalent_tuples) {
68 if (t.m_global_cid == source_mesh_base_tuple.m_global_cid) {
72 if (t.m_local_fid == source_mesh_base_tuple.m_local_fid) {
73 source_mesh_target_tuple = t;
76 source_mesh_target_tuple =
81 source_mesh_target_tuple = t;
90 if (source_mesh_target_tuple.
m_local_fid != source_mesh_base_tuple.m_local_fid) {
91 source_mesh_target_tuple =
97 source_mesh_base_tuple.m_global_cid ==
98 source_mesh_target_tuple
105 source_mesh_base_tuple,
106 source_mesh_target_tuple,
107 source_mesh_primitive_type,
108 target_mesh_base_tuple,
109 target_mesh_primitive_type);
114 : m_has_child_mesh_in_dimension(dimension, false)
126 std::map<std::string, const wmtk::utils::Hashable*> ret;
128 assert(
bool(c.mesh));
129 auto id = c.mesh->absolute_multi_mesh_id();
130 std::string name = fmt::format(
"child_map_[{}]", fmt::join(
id,
","));
131 ret[name] = c.mesh.get();
145 ret[
"parent_map"] = 0;
149 const std::hash<TypedAttributeHandle<int64_t>> attr_hasher;
152 assert(
bool(c.mesh));
153 auto id = c.mesh->absolute_multi_mesh_id();
154 std::string name = fmt::format(
"child_map_[{}]", fmt::join(
id,
","));
155 ret[name] = attr_hasher(c.map_handle);
168 throw std::runtime_error(
"Tried to access the child id of a mesh that is in fact a root");
186 if (&parent == &my_mesh) {
198 if (&parent_mesh == &my_mesh) {
212 const std::shared_ptr<Mesh>& child_mesh_ptr,
213 const std::vector<std::array<Tuple, 2>>& child_tuple_my_tuple_map)
216 assert(
bool(child_mesh_ptr));
218 Mesh& child_mesh = *child_mesh_ptr;
221 const int64_t new_child_id = int64_t(
m_children.size());
227 child_primitive_type,
228 wmtk::multimesh::utils::TWO_TUPLE_SIZE,
230 wmtk::multimesh::utils::DEFAULT_TUPLES_VALUES);
235 child_primitive_type,
236 wmtk::multimesh::utils::TWO_TUPLE_SIZE,
238 wmtk::multimesh::utils::DEFAULT_TUPLES_VALUES);
241 auto child_to_parent_accessor = child_mesh.
create_accessor(child_to_parent_handle);
242 auto parent_to_child_accessor = my_mesh.
create_accessor(parent_to_child_handle);
256 for (
const auto& [child_tuple, my_tuple] : child_tuple_my_tuple_map) {
258 assert(child_mesh_ptr->is_valid(child_tuple));
260 parent_to_child_accessor,
261 child_to_parent_accessor,
269 const std::shared_ptr<Mesh>& child_mesh_ptr)
271 Mesh& child_mesh = *child_mesh_ptr;
281 auto& parent_to_child_handle = child_data.
map_handle;
283 assert(child_data.
mesh == child_mesh_ptr);
290 .remove_attributes({parent_to_child_handle.base_handle()});
294 .remove_attributes({child_to_parent_handle.base_handle()});
311 std::vector<wmtk::attribute::TypedAttributeHandle<int64_t>> handles;
316 handles.emplace_back(cd.map_handle);
361 const std::vector<int64_t>& relative_id)
const
365 const Mesh* cur_mesh = &my_mesh;
369 int64_t child_index = *it;
372 cur_mesh = cd.
mesh.get();
398 std::vector<std::shared_ptr<Mesh>> ret;
401 ret.emplace_back(cd.mesh);
408 const Mesh& other_mesh,
411 const auto ret_tups =
map_tuples(my_mesh, other_mesh, my_simplex);
419 const Mesh& other_mesh,
422 if (&my_mesh == &other_mesh) {
425 const auto ret_tups =
lub_map_tuples(my_mesh, other_mesh, my_simplex);
442 const Mesh* cur_mesh = &my_mesh;
443 for (int64_t d = 0; d < depth; ++d) {
446 assert(cur_mesh !=
nullptr);
452 return std::pair<const Mesh&, Tuple>(*cur_mesh, cur_tuple);
458 const std::vector<int64_t>& relative_id)
const
464 std::vector<Tuple> tuples;
465 tuples.emplace_back(my_simplex.
tuple());
466 const Mesh* cur_mesh = &my_mesh;
470 int64_t child_index = *it;
474 std::vector<Tuple> new_tuples;
475 for (
const Tuple& t : tuples) {
482 new_tuples.insert(new_tuples.end(), n.begin(), n.end());
485 tuples = std::move(new_tuples);
486 cur_mesh = cd.
mesh.get();
499 const Mesh& other_mesh,
505 int64_t depth = my_id.size();
510 return root_ref.m_multi_mesh_manager.map_down_relative_tuples(root_ref, simplex, other_id);
515 const Mesh& other_mesh,
518 if (&my_mesh == &other_mesh) {
519 return {my_simplex.
tuple()};
525 int64_t depth = my_id.size() - lub_id.size();
527 auto [local_root_ref, tuple] =
map_up_to_tuples(my_mesh, my_simplex, depth);
532 auto other_relative_id =
relative_id(lub_id, other_id);
533 return local_root_ref.m_multi_mesh_manager.map_down_relative_tuples(
603 const Mesh& child_mesh = *child_data.
mesh;
607 const auto map_handle = child_data.
map_handle;
621 for (
Tuple& tuple : tuples) {
628 [](
const Tuple& t) ->
bool { return t.is_null(); }),
638 const Mesh& child_mesh,
656 const Mesh& child_mesh,
671 const std::vector<int64_t>& parent_simplices)
676 throw std::runtime_error(
677 "Cannot use same_simplex_dimension_bijection on meshes with simplex dimensions");
681 int64_t size = child.
capacity(primitive_type);
682 assert(size == int64_t(parent_simplices.size()));
683 std::vector<std::array<Tuple, 2>> ret;
689 for (int64_t index = 0; index < size; ++index) {
692 if ((parent_flag_accessor.const_scalar_attribute(pt) & 1) == 0) {
695 if ((child_flag_accessor.const_scalar_attribute(ct) & 1) == 0) {
699 ret.emplace_back(std::array<Tuple, 2>{{ct, pt}});
706 return fmt::format(
"map_to_child_{}", index);
714 const auto& parent_to_child_handle = c.
map_handle;
717 return std::array<wmtk::attribute::Accessor<int64_t>, 2>{
727 const auto& parent_to_child_handle = c.
map_handle;
730 return std::array<const wmtk::attribute::Accessor<int64_t>, 2>{
736 return "map_to_parent";
743 for (int64_t index = 0; index < int64_t(
children().size()); ++index) {
744 const auto& child_data =
children()[index];
745 assert(
bool(child_data.mesh));
746 assert(child_data.mesh->absolute_multi_mesh_id().front() == index);
753 const Mesh& child_mesh = *child_data.
mesh;
754 const auto parent_to_child_handle = child_data.
map_handle;
759 assert(child_mesh.
has_attribute<int64_t>(c_to_p_name, map_type));
760 auto child_to_parent_handle =
764 auto all_child_tuples = child_mesh.
get_all(map_type);
766 for (
const Tuple& child_tuple : all_child_tuples) {
768 "[{} -> {}] Checking child tuple {}",
773 auto [child_tuple_from_child, parent_tuple_from_child] =
776 child_to_parent_handle,
782 "[{} -> {}] Checking asserts from child {} {} (input tuple was {})",
788 assert(child_mesh.
is_valid(child_tuple_from_child));
789 assert(child_mesh.
is_valid(child_tuple_from_child));
790 assert(my_mesh.
is_valid(parent_tuple_from_child));
795 auto [parent_tuple_from_parent, child_tuple_from_parent] =
798 parent_to_child_handle,
799 parent_tuple_from_child);
801 "[{} -> {}] Checking asserts from child {} {}",
808 (child_tuple_from_child == child_tuple_from_parent &&
809 parent_tuple_from_child == parent_tuple_from_parent));
816 Tuple cur_child_tuple = child_tuple_from_child;
817 Tuple cur_parent_tuple = parent_tuple_from_child;
819 auto child_to_parent_accessor =
821 for (
int i = 0; i < 3; i++) {
826 Tuple child_tuple_opp =
828 Tuple parent_tuple_opp =
834 child_to_parent_accessor,
849 auto parent_to_child_accessor =
852 const Tuple parent_tuple_opp =
858 parent_to_child_accessor,
871 const std::vector<int64_t>& a,
872 const std::vector<int64_t>& b)
874 std::vector<int64_t> ret;
875 size_t size = std::min(a.size(), b.size());
876 for (
size_t j = 0; j < size; ++j) {
878 ret.emplace_back(a[j]);
886 const std::vector<int64_t>& parent,
887 const std::vector<int64_t>& child)
890 std::vector<int64_t> ret;
891 std::copy(child.begin() + parent.size(), child.end(), std::back_inserter(ret));
895 const std::vector<int64_t>& child,
896 const std::vector<int64_t>& parent)
898 if (parent.size() > child.size()) {
901 for (
size_t j = 0; j < parent.size(); ++j) {
902 if (parent[j] != child[j]) {
912 c.mesh->serialize(writer, local_root);
928 const Mesh& other_mesh,
936 return root.m_multi_mesh_manager.can_map_child(root, other_mesh, root_simplex);
940 const Mesh& other_mesh,
949 int64_t depth = my_id.size();
954 return !root_ref.m_multi_mesh_manager.map_down_relative_tuples(root_ref, simplex, other_id)
std::vector< int64_t > absolute_multi_mesh_id() const
returns a unique identifier for this mesh within a single multimesh structure
attribute::MeshAttributeHandle get_attribute_handle(const std::string &name, const PrimitiveType ptype) const
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))
const attribute::Accessor< T, Mesh, D > create_const_accessor(const attribute::MeshAttributeHandle &handle) const
bool is_boundary(const simplex::Simplex &tuple) const
check if a simplex lies on a boundary or not
virtual Tuple tuple_from_id(const PrimitiveType type, const int64_t gid) const =0
internal function that returns the tuple of requested type, and has the global index cid
std::vector< Tuple > get_all(PrimitiveType type) const
Generate a vector of Tuples from global vertex/edge/triangle/tetrahedron index.
const attribute::Accessor< char > get_const_flag_accessor(PrimitiveType type) const
multimesh::MultiMeshManager m_multi_mesh_manager
Tuple switch_tuples(const Tuple &tuple, const ContainerType &op_sequence) const
bool has_attribute(const std::string &name, const PrimitiveType ptype) const
virtual bool is_valid(const Tuple &tuple) const
check validity of tuple including its hash
int64_t top_cell_dimension() const
virtual Tuple switch_tuple(const Tuple &tuple, PrimitiveType type) const =0
switch the orientation of the Tuple of the given dimension
attribute::Accessor< T, Mesh, D > create_accessor(const attribute::MeshAttributeHandle &handle)
Mesh & get_multi_mesh_root()
returns a reference to the root of a multimesh tree
PrimitiveType top_simplex_type() const
const attribute::Accessor< char > get_flag_accessor(PrimitiveType type) const
attribute::AttributeManager m_attribute_manager
std::vector< MeshAttributes< T > > & get()
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.
static std::vector< std::array< Tuple, 2 > > same_simplex_dimension_surjection(const Mesh &parent, const Mesh &child, const std::vector< int64_t > &parent_simplices)
bool can_map_child(const Mesh &my_mesh, const Mesh &other_mesh, const simplex::Simplex &my_simplex) const
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
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.
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 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::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
bool has_child_mesh() 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
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
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
MultiMeshManager(int64_t dimension)
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
Tuple map_tuple_to_parent_tuple(const Mesh &my_mesh, const Tuple &my_tuple) const
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
const Tuple & tuple() const
PrimitiveType primitive_type() const
std::map< std::string, std::size_t > child_hashes() const override
static std::string as_string(const Tuple &t)
std::tuple< Tuple, Tuple > read_tuple_map_attribute(const wmtk::attribute::Accessor< int64_t, MeshType > &accessor, const Tuple &source_tuple)
Tuple transport_tuple(const Tuple &base_source, const Tuple &base_target, PrimitiveType base_primitive_type, const Tuple &source, PrimitiveType primitive_type)
void symmetric_write_tuple_map_attributes(wmtk::attribute::Accessor< int64_t, MeshA > &a_to_b, wmtk::attribute::Accessor< int64_t, MeshB > &b_to_a, const Tuple &a_tuple, const Tuple &b_tuple)
std::tuple< Tuple, Tuple > read_tuple_map_attribute_slow(const Mesh &source_mesh, TypedAttributeHandle< int64_t > map_handle, const Tuple &source_tuple)
std::vector< Simplex > tuple_vector_to_homogeneous_simplex_vector(const Mesh &m, const std::vector< Tuple > &tups, PrimitiveType primitive)
std::vector< Tuple > make_unique_tuples(const Mesh &m, const std::vector< Tuple > &ts, PrimitiveType primitive)
void top_dimension_cofaces_tuples(const PointMesh &mesh, const Simplex &simplex, SimplexCollection &collection)
std::vector< Tuple > cofaces_single_dimension_tuples(const Mesh &mesh, const Simplex &my_simplex, PrimitiveType cofaces_type)
std::size_t vector_hash(const std::vector< size_t > &data)
spdlog::logger & logger()
Retrieves the current logger.
std::shared_ptr< Mesh > mesh
TypedAttributeHandle< int64_t > map_handle