From 84d49c6b1c9ee61399ec357f436d56eea2fceed5 Mon Sep 17 00:00:00 2001 From: ellis Date: Sun, 5 Mar 2017 20:36:26 -0600 Subject: [PATCH] InterpartitionAdj is consistent --- meshmode/mesh/__init__.py | 44 +++++++--------------------------- meshmode/mesh/processing.py | 48 +++++++++++++++---------------------- test/test_meshmode.py | 26 +++++++++++++------- 3 files changed, 44 insertions(+), 74 deletions(-) diff --git a/meshmode/mesh/__init__.py b/meshmode/mesh/__init__.py index dcefeb28..e78f54fb 100644 --- a/meshmode/mesh/__init__.py +++ b/meshmode/mesh/__init__.py @@ -382,50 +382,21 @@ class NodalAdjacency(Record): # }}} -# {{{ partition adjacency - -class InterPartitionAdjacency(): - """ - Describes adjacency information of elements between partitions. - """ - - def __init__(self): - self.elements = [] - self.element_faces = [] - self.neighbor_elems = [] - self.neighbor_faces = [] - self.neighbor_groups = [] - - def add_connection(self, elem, face, - neighbor_group, neighbor_elem, neighbor_face): - self.elems.append(elem) - self.elem_faces.append(face) - self.neighbor_groups.append(neighbor_group) - self.neighbor_elems.append(neighbor_elem) - self.neighbor_faces.append(neighbor_face) - - def get_neighbor(self, elem, face): - for idx in range(len(self.elements)): - if elem == self.elements[idx] and face == self.element_faces[idx]: - return (self.neighbor_groups[idx], - self.neighbor_elem[idx], - self.neighbor_faces[idx]) - +# {{{ partition adjacency -class OtherPossibility(): +class InterPartitionAdj(): """ + Interface is not final. """ def __init__(self): self.adjacent = dict() - def add_connection(self, tag, elem, face, - neighbor_group, neighbor_elem, neighbor_face): - self.adjacent[(tag, elem, face)] = \ - (neighbor_group, neighbor_elem, neighbor_face) + def add_connection(self, elem, face, neighbor_elem, neighbor_face): + self.adjacent[(elem, face)] = (neighbor_elem, neighbor_face) - def get_neighbor(self, tag, elem, face): - return self.adjacent[(tag, elem, face)] + def get_neighbor(self, elem, face): + return self.adjacent[(elem, face)] # }}} @@ -585,6 +556,7 @@ class Mesh(Record): will result in exceptions. Lastly, a data structure as described in :attr:`facial_adjacency_groups` may be passed. """ + el_nr = 0 node_nr = 0 diff --git a/meshmode/mesh/processing.py b/meshmode/mesh/processing.py index 06a96cbb..43b656ad 100644 --- a/meshmode/mesh/processing.py +++ b/meshmode/mesh/processing.py @@ -147,14 +147,9 @@ def partition_mesh(mesh, part_per_element, part_nr): from meshmode.mesh import BTAG_ALL - #from meshmode.mesh import InterPartitionAdjacency - #num_connection_tags = np.max(part_per_element) + 1 - #tags_to_part_adj = [] - #for _ in range(num_connection_tags): - # tags_to_part_adj.append(InterPartitionAdjacency()) - - from meshmode.mesh import OtherPossibility - part_adjacency = OtherPossibility() + #TODO This should probably be in the Mesh class. + from meshmode.mesh import InterPartitionAdj + part_mesh.interpartition_adj = InterPartitionAdj() for igrp in range(num_groups): part_group = part_mesh.groups[igrp] @@ -165,6 +160,7 @@ def partition_mesh(mesh, part_per_element, part_nr): elem = boundary_elems[elem_idx] face = boundary_faces[elem_idx] tags = -boundary_adj.neighbors[elem_idx] + # Is is reasonable to expect this assertation? assert tags >= 0, "Expected boundary tag in adjacency group." parent_elem = queried_elems[elem] parent_group_num = 0 @@ -178,32 +174,26 @@ def partition_mesh(mesh, part_per_element, part_nr): for idx in np.where(parent_facial_group.elements == parent_elem)[0]: if parent_facial_group.neighbors[idx] >= 0 and \ parent_facial_group.element_faces[idx] == face: - rank_neighbor = parent_facial_group.neighbors[idx] + rank_neighbor = (parent_facial_group.neighbors[idx] + + parent_grp_elem_base) rank_neighbor_face = parent_facial_group.neighbor_faces[idx] - - new_tag = part_per_element[rank_neighbor - + parent_grp_elem_base] + + n_part_nr = part_per_element[rank_neighbor] tags = tags & ~part_mesh.boundary_tag_bit(BTAG_ALL) - tags = tags | part_mesh.boundary_tag_bit(new_tag) + tags = tags | part_mesh.boundary_tag_bit(n_part_nr) boundary_adj.neighbors[elem_idx] = -tags - - #print("Boundary face", face, "of element", elem, - # "should be connected to element", rank_neighbor, - # "in partition", neighbor_part_num) - - #tags_to_part_adj[new_tag].add_connection( - # elem + part_group.element_nr_base, - # face, - # rank_neighbor + parent_grp_elem_base, - # rank_neighbor_face, - # parent_group_num) - - part_adjacency.add_connection(new_tag, + + # Find the neighbor element from the other partition + n_elem = np.count_nonzero( + part_per_element[:rank_neighbor] == n_part_nr) + + # TODO Test if this works with multiple groups + # Do I need to add the element number base? + part_mesh.interpartition_adj.add_connection( elem + part_group.element_nr_base, face, - rank_neighbor + parent_grp_elem_base, - rank_neighbor_face, - parent_group_num) + n_elem, + rank_neighbor_face) return (part_mesh, queried_elems) diff --git a/test/test_meshmode.py b/test/test_meshmode.py index 57775dd0..e51856d7 100644 --- a/test/test_meshmode.py +++ b/test/test_meshmode.py @@ -70,7 +70,7 @@ def test_partition_torus_mesh(): def test_partition_boxes_mesh(): n = 5 - num_parts = 3 + num_parts = 7 from meshmode.mesh.generation import generate_regular_rect_mesh mesh = generate_regular_rect_mesh(a=(0, 0, 0), b=(1, 1, 1), n=(n, n, n)) #TODO facial_adjacency_groups is not available from merge_disjoint_meshes. @@ -102,19 +102,27 @@ def test_partition_boxes_mesh(): [count_btag_all(new_meshes[i]) for i in range(num_parts)]), \ "part_mesh has the wrong number of BTAG_ALL boundaries" - for part_num in range(num_parts): - for f_groups in new_meshes[part_num].facial_adjacency_groups: + for part_nr in range(num_parts): + for f_groups in new_meshes[part_nr].facial_adjacency_groups: f_grp = f_groups[None] for idx in range(len(f_grp.elements)): + # Are all f_grp.neighbors guaranteed to be negative + # since I'm taking the boundary facial group? tag = -f_grp.neighbors[idx] - if tag >= 0: - elem = f_grp.elements[idx] - face = f_grp.element_faces[idx] - (n_part, n_elem, n_face) = ...get_neighbor(tag, elem, face) - assert (part_num, elem, face) = ...get_neighbor(n_part, n_elem, n_face) + elem = f_grp.elements[idx] + face = f_grp.element_faces[idx] + for n_part_nr in range(num_parts): + if tag >= 0 and \ + tag & new_meshes[part_nr].boundary_tag_bit(n_part_nr) != 0: + # Is this the best way to probe the tag? + # Can one tag have multiple partition neighbors? + (n_elem, n_face) = new_meshes[part_nr].\ + interpartition_adj.get_neighbor(elem, face) + assert (elem, face) == new_meshes[n_part_nr].\ + interpartition_adj.get_neighbor(n_elem, n_face),\ + "InterpartitionAdj is not consistent" - def count_btag_all(mesh): num_bnds = 0 for adj_dict in mesh.facial_adjacency_groups: -- GitLab