28 m.m_multi_mesh_manager.m_parent =
nullptr;
29 m.m_multi_mesh_manager.m_child_id = -1;
37 const Mesh& source_mesh,
38 const Mesh& target_mesh,
40 const Tuple& source_tuple)
42 assert(source_mesh.
is_valid(source_tuple));
47 std::min(source_mesh_primitive_type, target_mesh_primitive_type);
48 Tuple source_mesh_target_tuple = source_tuple;
49 auto [source_mesh_base_tuple, target_mesh_base_tuple] =
52 if (source_mesh_base_tuple.is_null() || target_mesh_base_tuple.is_null()) {
60 if (source_mesh_base_tuple.global_cid() != source_mesh_target_tuple.
global_cid()) {
62 assert(source_mesh_primitive_type > target_mesh_primitive_type);
66 for (
const Tuple& t : equivalent_tuples) {
67 if (t.global_cid() == source_mesh_base_tuple.global_cid()) {
71 if (t.local_fid() == source_mesh_base_tuple.local_fid()) {
72 source_mesh_target_tuple = t;
75 source_mesh_target_tuple =
80 source_mesh_target_tuple = t;
89 if (source_mesh_target_tuple.
local_fid() != source_mesh_base_tuple.local_fid()) {
90 source_mesh_target_tuple =
96 source_mesh_base_tuple.global_cid() ==
97 source_mesh_target_tuple
104 source_mesh_base_tuple,
105 source_mesh_target_tuple,
106 source_mesh_primitive_type,
107 target_mesh_base_tuple,
108 target_mesh_primitive_type);
113 : m_has_child_mesh_in_dimension(dimension, false)
125 std::map<std::string, const wmtk::utils::Hashable*> ret;
127 assert(
bool(c.mesh));
128 auto id = c.mesh->absolute_multi_mesh_id();
129 std::string name = fmt::format(
"child_map_[{}]", fmt::join(
id,
","));
130 ret[name] = c.mesh.get();
144 ret[
"parent_map"] = 0;
148 const std::hash<TypedAttributeHandle<int64_t>> attr_hasher;
151 assert(
bool(c.mesh));
152 auto id = c.mesh->absolute_multi_mesh_id();
153 std::string name = fmt::format(
"child_map_[{}]", fmt::join(
id,
","));
154 ret[name] = attr_hasher(c.map_handle);
167 throw std::runtime_error(
"Tried to access the child id of a mesh that is in fact a root");
185 if (&parent == &my_mesh) {
197 if (&parent_mesh == &my_mesh) {
211 const std::shared_ptr<Mesh>& child_mesh_ptr,
212 const std::vector<std::array<Tuple, 2>>& child_tuple_my_tuple_map)
215 assert(
bool(child_mesh_ptr));
217 Mesh& child_mesh = *child_mesh_ptr;
220 const int64_t new_child_id = int64_t(
m_children.size());
226 child_primitive_type,
227 wmtk::multimesh::utils::TWO_TUPLE_SIZE,
229 wmtk::multimesh::utils::DEFAULT_TUPLES_VALUES);
234 child_primitive_type,
235 wmtk::multimesh::utils::TWO_TUPLE_SIZE,
237 wmtk::multimesh::utils::DEFAULT_TUPLES_VALUES);
240 auto child_to_parent_accessor = child_mesh.
create_accessor(child_to_parent_handle);
241 auto parent_to_child_accessor = my_mesh.
create_accessor(parent_to_child_handle);
255 for (
const auto& [child_tuple, my_tuple] : child_tuple_my_tuple_map) {
257 assert(child_mesh_ptr->is_valid(child_tuple));
259 parent_to_child_accessor,
260 child_to_parent_accessor,
268 const std::shared_ptr<Mesh>& child_mesh_ptr)
270 Mesh& child_mesh = *child_mesh_ptr;
280 auto& parent_to_child_handle = child_data.
map_handle;
282 assert(child_data.
mesh == child_mesh_ptr);
289 .remove_attributes({parent_to_child_handle.base_handle()});
293 .remove_attributes({child_to_parent_handle.base_handle()});
310 std::vector<wmtk::attribute::TypedAttributeHandle<int64_t>> handles;
315 handles.emplace_back(cd.map_handle);
360 const std::vector<int64_t>& relative_id)
const
364 const Mesh* cur_mesh = &my_mesh;
368 int64_t child_index = *it;
371 cur_mesh = cd.
mesh.get();
397 std::vector<std::shared_ptr<Mesh>> ret;
400 ret.emplace_back(cd.mesh);
407 const Mesh& other_mesh,
410 const auto ret_tups =
map_tuples(my_mesh, other_mesh, my_simplex);
418 const Mesh& other_mesh,
421 if (&my_mesh == &other_mesh) {
424 const auto ret_tups =
lub_map_tuples(my_mesh, other_mesh, my_simplex);
441 const Mesh* cur_mesh = &my_mesh;
442 for (int64_t d = 0; d < depth; ++d) {
445 assert(cur_mesh !=
nullptr);
451 return std::pair<const Mesh&, Tuple>(*cur_mesh, cur_tuple);
457 const std::vector<int64_t>& relative_id)
const
463 std::vector<Tuple> tuples;
464 tuples.emplace_back(my_simplex.
tuple());
465 const Mesh* cur_mesh = &my_mesh;
469 int64_t child_index = *it;
473 std::vector<Tuple> new_tuples;
474 for (
const Tuple& t : tuples) {
481 new_tuples.insert(new_tuples.end(), n.begin(), n.end());
484 tuples = std::move(new_tuples);
485 cur_mesh = cd.
mesh.get();
498 const Mesh& other_mesh,
504 int64_t depth = my_id.size();
509 return root_ref.m_multi_mesh_manager.map_down_relative_tuples(root_ref, simplex, other_id);
514 const Mesh& other_mesh,
517 if (&my_mesh == &other_mesh) {
518 return {my_simplex.
tuple()};
524 int64_t depth = my_id.size() - lub_id.size();
526 auto [local_root_ref, tuple] =
map_up_to_tuples(my_mesh, my_simplex, depth);
531 auto other_relative_id =
relative_id(lub_id, other_id);
532 return local_root_ref.m_multi_mesh_manager.map_down_relative_tuples(
602 const Mesh& child_mesh = *child_data.
mesh;
606 const auto map_handle = child_data.
map_handle;
620 for (
Tuple& tuple : tuples) {
627 [](
const Tuple& t) ->
bool { return t.is_null(); }),
637 const Mesh& child_mesh,
655 const Mesh& child_mesh,
670 const std::vector<int64_t>& parent_simplices)
675 throw std::runtime_error(
676 "Cannot use same_simplex_dimension_bijection on meshes with simplex dimensions");
680 int64_t size = child.
capacity(primitive_type);
681 assert(size == int64_t(parent_simplices.size()));
682 std::vector<std::array<Tuple, 2>> ret;
688 for (int64_t index = 0; index < size; ++index) {
691 if (!(parent_flag_accessor.is_active(pt))) {
694 if (!(child_flag_accessor.is_active(ct))) {
698 ret.emplace_back(std::array<Tuple, 2>{{ct, pt}});
705 return fmt::format(
"map_to_child_{}", index);
713 const auto& parent_to_child_handle = c.
map_handle;
716 return std::array<wmtk::attribute::Accessor<int64_t>, 2>{
726 const auto& parent_to_child_handle = c.
map_handle;
729 return std::array<const wmtk::attribute::Accessor<int64_t>, 2>{
735 return "map_to_parent";
742 for (int64_t index = 0; index < int64_t(
children().size()); ++index) {
743 const auto& child_data =
children()[index];
744 assert(
bool(child_data.mesh));
745 assert(child_data.mesh->absolute_multi_mesh_id().front() == index);
752 const Mesh& child_mesh = *child_data.
mesh;
753 const auto parent_to_child_handle = child_data.
map_handle;
758 assert(child_mesh.
has_attribute<int64_t>(c_to_p_name, map_type));
759 auto child_to_parent_handle =
763 auto all_child_tuples = child_mesh.
get_all(map_type);
765 for (
const Tuple& child_tuple : all_child_tuples) {
767 "[{} -> {}] Checking child tuple {}",
770 child_tuple.as_string());
772 auto [child_tuple_from_child, parent_tuple_from_child] =
775 child_to_parent_handle,
781 "[{} -> {}] Checking asserts from child {} {} (input tuple was {})",
784 child_tuple_from_child.as_string(),
785 child_tuple_from_child.as_string(),
786 child_tuple.as_string());
787 assert(child_mesh.
is_valid(child_tuple_from_child));
788 assert(child_mesh.
is_valid(child_tuple_from_child));
789 assert(my_mesh.
is_valid(parent_tuple_from_child));
794 auto [parent_tuple_from_parent, child_tuple_from_parent] =
797 parent_to_child_handle,
798 parent_tuple_from_child);
800 "[{} -> {}] Checking asserts from child {} {}",
803 parent_tuple_from_parent.as_string(),
804 child_tuple_from_parent.as_string());
807 (child_tuple_from_child == child_tuple_from_parent &&
808 parent_tuple_from_child == parent_tuple_from_parent));
815 Tuple cur_child_tuple = child_tuple_from_child;
816 Tuple cur_parent_tuple = parent_tuple_from_child;
818 auto child_to_parent_accessor =
820 for (
int i = 0; i < 3; i++) {
825 Tuple child_tuple_opp =
827 Tuple parent_tuple_opp =
833 child_to_parent_accessor,
848 auto parent_to_child_accessor =
851 const Tuple parent_tuple_opp =
857 parent_to_child_accessor,
870 const std::vector<int64_t>& a,
871 const std::vector<int64_t>& b)
873 std::vector<int64_t> ret;
874 size_t size = std::min(a.size(), b.size());
875 for (
size_t j = 0; j < size; ++j) {
877 ret.emplace_back(a[j]);
885 const std::vector<int64_t>& parent,
886 const std::vector<int64_t>& child)
889 std::vector<int64_t> ret;
890 std::copy(child.begin() + parent.size(), child.end(), std::back_inserter(ret));
894 const std::vector<int64_t>& child,
895 const std::vector<int64_t>& parent)
897 if (parent.size() > child.size()) {
900 for (
size_t j = 0; j < parent.size(); ++j) {
901 if (parent[j] != child[j]) {
911 c.mesh->serialize(writer, local_root);
927 const Mesh& other_mesh,
935 return root.m_multi_mesh_manager.can_map_child(root, other_mesh, root_simplex);
939 const Mesh& other_mesh,
948 int64_t depth = my_id.size();
953 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
const attribute::Accessor< T, Mesh, D > create_const_accessor(const attribute::MeshAttributeHandle &handle) 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))
bool is_boundary(const simplex::Simplex &tuple) const
check if a simplex lies on a boundary or not
attribute::Accessor< T, Mesh, D > create_accessor(const attribute::MeshAttributeHandle &handle)
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.
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
Mesh & get_multi_mesh_root()
returns a reference to the root of a multimesh tree
PrimitiveType top_simplex_type() const
const attribute::FlagAccessor< Mesh > get_const_flag_accessor(PrimitiveType type) const
const attribute::FlagAccessor< Mesh > get_flag_accessor(PrimitiveType type) const
attribute::AttributeManager m_attribute_manager
The Tuple is the basic navigation tool in our mesh data structure.
int64_t global_cid() const
A CachingAccessor that uses tuples for accessing attributes instead of indices.
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
int64_t child_id() const
Specifies the child id of this mesh if it a child mesh in a mult-mesh tree.
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
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()
friend std::vector< std::array< Tuple, 2 > > multimesh::same_simplex_dimension_surjection(const Mesh &parent, const Mesh &child, const std::vector< int64_t > &parent_simplices)
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
const std::vector< ChildData > & children() const
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
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
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
std::tuple< Tuple, Tuple > read_tuple_map_attribute_slow(const Mesh &source_mesh, TypedAttributeHandle< int64_t > map_handle, const Tuple &source_tuple)
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::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