def test_unit_square(self): p = np.array([[0, 0], [1, 0], [1, 1], [0, 1]]).T d = cg.dist_pointset(p) s2 = np.sqrt(2) known = np.array([[0, 1, s2, 1], [1, 0, 1, s2], [s2, 1, 0, 1], [1, s2, 1, 0]]) assert np.allclose(d, known)
def test_3d(self): p = np.array([[0, 0, 0], [0, 1, 0], [1, 0, 0]]).T d = cg.dist_pointset(p) known = np.array([[0, 1, 1], [1, 0, np.sqrt(2)], [1, np.sqrt(2), 0]]) assert np.allclose(d, known)
def merge_1d_grids(g, h, global_ind_offset=0, tol=1e-4): """ Merge two 1d grids with non-matching nodes to a single grid. The grids should have common start and endpoints. They can be into 3d space in a genreal way. The function is primarily intended for merging non-conforming DFN grids. Parameters: g: 1d tensor grid. h: 1d tensor grid glob_ind_offset (int, defaults to 0): Off set for the global point index of the new grid. tol (double, defaults to 1e-4): Tolerance for when two nodes are merged into one. Returns: TensorGrid: New tensor grid, containing the combined node definition. int: New global ind offset, increased by the number of cells in the combined grid. np.array (int): Indices of common nodes (after sorting) of g and the new grid. np.array (int): Indices of common nodes (after sorting) of h and the new grid. np.array (int): Permutation indices that sort the node coordinates of g. The common indices between g and the new grid are found as new_grid.nodes[:, g_in_combined] = g.nodes[:, sorted] np.array (int): Permutation indices that sort the node coordinates of h. The common indices between h and the new grid are found as new_grid.nodes[:, h_in_combined] = h.nodes[:, sorted] """ # Nodes of the two 1d grids, combine them gp = g.nodes hp = h.nodes combined = np.hstack((gp, hp)) num_g = gp.shape[1] num_h = hp.shape[1] # Keep track of where we put the indices of the original grids g_in_full = np.arange(num_g) h_in_full = num_g + np.arange(num_h) # The tolerance should not be larger than the smallest distance between # two points on any of the grids. diff_gp = np.min(cg.dist_pointset(gp, True)) diff_hp = np.min(cg.dist_pointset(hp, True)) min_diff = np.minimum(tol, 0.5 * np.minimum(diff_gp, diff_hp)) # Uniquify points combined_unique, _, new_2_old = unique_columns_tol(combined, tol=min_diff) # Follow locations of the original grid points g_in_unique = new_2_old[g_in_full] h_in_unique = new_2_old[h_in_full] # The combined nodes must be sorted along their natural line. # Find the dimension with the largest spatial extension, and sort those # coordinates max_coord = combined_unique.max(axis=1) min_coord = combined_unique.min(axis=1) dx = max_coord - min_coord sort_dim = np.argmax(dx) sort_ind = np.argsort(combined_unique[sort_dim]) combined_sorted = combined_unique[:, sort_ind] # Follow the position of the orginial nodes through sorting _, g_sorted = ismember_rows(g_in_unique, sort_ind) _, h_sorted = ismember_rows(h_in_unique, sort_ind) num_new_grid = combined_sorted.shape[1] # Create a new 1d grid. # First use a 1d coordinate to initialize topology new_grid = TensorGrid(np.arange(num_new_grid)) # Then set the right, 3d coordinates new_grid.nodes = cg.make_collinear(combined_sorted) # Set global point indices new_grid.global_point_ind = global_ind_offset + np.arange(num_new_grid) global_ind_offset += num_new_grid return new_grid, global_ind_offset, g_sorted, h_sorted, np.arange(num_g),\ np.arange(num_h)
def test_zero_diagonal(self): sz = 5 p = np.random.rand(3, sz) d = cg.dist_pointset(p) self.assertTrue(np.allclose(np.diagonal(d), np.zeros(sz)))
def test_single_point(self): p = np.random.rand(2) d = cg.dist_pointset(p) self.assertTrue(d.shape == (1, 1)) self.assertTrue(d[0, 0] == 0)
def test_symmetry(self): p = np.random.rand(3, 7) d = cg.dist_pointset(p) self.assertTrue(np.allclose(d, d.T))
def test_single_point(self): p = np.random.rand(2) d = cg.dist_pointset(p) assert d.shape == (1, 1) assert d[0, 0] == 0