def build_parent_level_leaf(key, leaves_set, colleagues_parents, parent_colleagues, depth): """ Build the portion of the interaction list that is expected at the parent level of a node. Contributes to the U and X lists for leaf keys. Parameters: ---------- key : np.int64 Key for the current node being considered. leaves_set : set(np.int64) colleagues_parents : np.array(np.int64) The (unique) parents of the node's colleagues. parent_colleagues : np.array(np.int64) The colleagues of the node's parents. depth : np.int64 Returns: -------- (np.int64, np.array(dtype=np.int64)) Four-tuple (u_ptr, u, x_ptr, x), where 'u_ptr' is the length of the U list contributions at this level. """ # U List (P2P) cp_in_tree = np.zeros_like(colleagues_parents) i = 0 for cp in colleagues_parents: if cp in leaves_set: cp_in_tree[i] = cp i += 1 cp_in_tree = cp_in_tree[:i] adj_idxs = morton.are_adjacent_vec(key, cp_in_tree, depth) adjacent = cp_in_tree[adj_idxs == 1] # X List (P2L) pc_in_tree = np.zeros_like(parent_colleagues) i = 0 for pc in parent_colleagues: if pc in leaves_set: pc_in_tree[i] = pc i += 1 pc_in_tree = pc_in_tree[:i] not_adj_idxs = morton.are_adjacent_vec(key, pc_in_tree, depth) not_adjacent = pc_in_tree[not_adj_idxs == 0] return len(adjacent), adjacent, len(not_adjacent), not_adjacent
def build_current_level_non_leaf(key, complete_set, parent_colleagues_children, depth): """ Build the portion of the interaction list that is expected at the level of a node. Contributes to the V lists for non-leaf keys. Parameters: ----------- key : np.int64 Key for the current node being considered. complete_set : set(np.int64) parent_colleagues_children : np.array(np.int64) The children of a node's parent's colleagues. depth : np.int64 Returns: -------- (np.int64, np.array(dtype=np.int64)) Tuple (v_ptr, v), where 'v_ptr' is the length of the V list contributions at this level. """ # V List (M2L) pcc_in_tree = np.zeros_like(parent_colleagues_children) i = 0 for pcc in parent_colleagues_children: if pcc in complete_set: pcc_in_tree[i] = pcc i += 1 pcc_in_tree = pcc_in_tree[:i] adj_idxs = morton.are_adjacent_vec(key, pcc_in_tree, depth) not_adjacent = pcc_in_tree[adj_idxs == 0] return len(not_adjacent), not_adjacent
def test_find_interaction_lists(balanced): """ Currently only tests interaction lists for nodes at leaf level, mainly checking that the constraints on their level, and adjacency are satisfied. """ depth = tree.find_depth(balanced) complete = tree.complete_tree(balanced) u, x, v, w = tree.find_interaction_lists(balanced, complete, depth) for i in range(len(complete)): key = complete[i] if key in balanced: # Check all u list members are adjacent u_i = u[i][u[i] != -1] u_adj_idxs = morton.are_adjacent_vec(key, u_i, depth) assert np.all(u_adj_idxs == 1) # Check all x list members are at the right level, and not adjacent x_i = x[i][x[i] != -1] x_nadj_idxs = morton.are_adjacent_vec(key, x_i, depth) assert np.all(x_nadj_idxs == 0) x_levels = morton.find_level(x_i) assert np.all( x_levels == morton.find_level(morton.find_parent(key))) # Check all w list members are at right level, and not adjacent w_i = w[i][w[i] != -1] w_nadj_idxs = morton.are_adjacent_vec(key, w_i, depth) assert np.all(w_nadj_idxs == 0) w_levels = morton.find_level(w_i) assert np.all(w_levels == (morton.find_level(key) - 1)) # Check all v list members are at right level, and not adjacent v_i = v[i][v[i] != -1] v_nadj_idxs = morton.are_adjacent_vec(key, v_i, depth) assert np.all(v_nadj_idxs == 0) v_levels = morton.find_level(v_i) assert np.all(v_levels == morton.find_level(key))
def find_dense_v_list(key, depth): """ Find the V list of a key if it were in a non-adaptive tree. """ parent = morton.find_parent(key) parent_neighbours = morton.find_neighbours(parent) parent_neigbhours_children = morton.find_children_vec( parent_neighbours).ravel() are_adj = morton.are_adjacent_vec(key, parent_neigbhours_children, depth) return parent_neigbhours_children[are_adj == 0]
def test_find_dense_v_list(): x0 = np.array([0.5, 0.5, 0.5]) r0 = 0.5 depth = 3 key = morton.encode_point(x0, depth, x0, r0) v_list = tree.find_dense_v_list(key, depth) are_adj = morton.are_adjacent_vec(key, v_list, depth) # Test that v list members are not adjacent to the key assert np.all(are_adj == 0) # Test that v list members are the same level as the key assert np.all(morton.find_level(v_list) == morton.find_level(key)) # Test that the v list is dense assert len(v_list) == 189
def build_child_level_leaf(key, leaves_set, colleagues_children, depth): """ Build the portion of the interaction list that is expected at the level of a node's children. Contributes to the U and W lists for leaf keys. Parameters: ----------- key : np.int64 Key for the current node being considered. leaves_set : set(np.int64) colleagues_children : np.array(np.int64) The children of a node's colleagues. depth : np.int64 Returns: -------- (np.int64, np.array(dtype=np.int64)) Four-tuple (u_ptr, u, w_ptr, w), where 'u_ptr' is the length of the U list contributions at this level. """ # U List (P2P) i = 0 cc_in_tree = np.zeros_like(colleagues_children) for cc in colleagues_children: if cc in leaves_set: cc_in_tree[i] = cc i += 1 cc_in_tree = cc_in_tree[:i] adj_idxs = morton.are_adjacent_vec(key, cc_in_tree, depth) adjacent = cc_in_tree[adj_idxs == 1] # W List (M2P) not_adjacent = cc_in_tree[adj_idxs == 0] return len(adjacent), adjacent, len(not_adjacent), not_adjacent