def test_full_mesh_refine(): knots = np.array([[0, 0, 1, 1], [0, 0, 1, 1]], dtype=np.float64) deg = [1, 1] dim = 2 T = HierarchicalSpace(knots, deg, dim) np.testing.assert_equal(T.nfuncs_level, {0: 4}) cells = {} rectangle = np.array([[0, 1 + np.spacing(1)], [0, 1 + np.spacing(1)]], dtype=np.float64) cells[0] = T.refine_in_rectangle(rectangle, 0) T = refine(T, cells) np.testing.assert_equal(T.nfuncs_level, { 0: 0, 1: 9, }) cells[1] = T.refine_in_rectangle(rectangle, 1) T = refine(T, cells) np.testing.assert_equal(T.nfuncs_level, {0: 0, 1: 0, 2: 25}) cells[2] = T.refine_in_rectangle(rectangle, 2) T = refine(T, cells) np.testing.assert_equal(T.nfuncs_level, {0: 0, 1: 0, 2: 0, 3: 81})
def refine(hspace: HierarchicalSpace, marked_entities, type='cells') -> HierarchicalSpace: """ Refines the hierarchical space based on the type of marked entities. :param hspace: hierarchical space :param marked_entities: indices of the marked entities, in this case, cells :param type: defaults to cells, not implemented 'function'-refinement yet. :return: a refined hierarchical space """ logging.info(""" Refining hierarchical space =========================== space.nlevels = {} hmesh.nlevels = {} """.format(hspace.nlevels, hspace.mesh.nlevels)) marked_cells = marked_entities new_cells = hspace.mesh.refine(marked_cells) marked_functions = hspace.functions_to_deactivate_from_cells(marked_cells) hspace.refine(marked_functions, new_cells) logging.info(""" After refinement, the space has =============================== space.nfuncs = {} space.nelems = {} """.format(hspace.nfuncs, hspace.mesh.nel)) return hspace
def refine(hspace: HierarchicalSpace, marked_entities, type='cells') -> HierarchicalSpace: """ Refines the hierarchical space based on the type of marked entities. :param hspace: :param marked_entities: :param type: :return: """ logging.info(""" Refining hierarchical space =========================== space.nlevels = {} hmesh.nlevels = {} """.format(hspace.nlevels, hspace.mesh.nlevels)) marked_cells = marked_entities new_cells = hspace.mesh.refine(marked_cells) marked_functions = hspace.functions_to_deactivate_from_cells(marked_cells) hspace.refine(marked_functions, new_cells) logging.info(""" After refinement, the space has =============================== space.nfuncs = {} space.nelems = {} """.format(hspace.nfuncs, hspace.mesh.nel)) return hspace
def test_projection_matrix_bilinear(): knots = [[0, 0, 1, 2, 3, 3], [0, 0, 1, 2, 3, 3]] d = [1, 1] dim = 2 T = HierarchicalSpace(knots, d, dim) cells = {0: [1]} T = refine(T, cells) C = T.compute_full_projection_matrix(0) assert C.shape == (49, 16)
def test_functions_to_deactivate_from_cells(): knots = [[0, 0, 1, 2, 2], [0, 0, 1, 2, 2]] d = 2 degrees = [1, 1] T = HierarchicalSpace(knots, degrees, d) marked_cells = {0: [0]} new_cells = T.mesh.refine(marked_cells) marked_functions = T.functions_to_deactivate_from_cells(marked_cells) np.testing.assert_equal(marked_functions, {0: [0]})
def test_change_of_basis_matrix_linear(): knots = [[0, 0, 1 / 3, 2 / 3, 1, 1]] d = [1] dim = 1 T = HierarchicalSpace(knots, d, dim) cells = {0: [1]} T = refine(T, cells) C = T.get_basis_conversion_matrix(0) np.testing.assert_allclose( C.toarray(), np.array([[1, 0, 0, 0], [0.5, 0.5, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0.5, 0.5], [0, 0, 0, 1]]))
def test_subdivision_matrix_linear(): knots = [[0, 0, 1 / 3, 2 / 3, 1, 1]] d = [1] dim = 1 T = HierarchicalSpace(knots, d, dim) cells = {0: [1]} T = refine(T, cells) C = T.create_subdivision_matrix('full') np.testing.assert_allclose(C[0].toarray(), np.eye(4)) np.testing.assert_allclose( C[1].toarray(), np.array([[1, 0, 0, 0, 0], [0.5, 0.5, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 0, 0, 1], [0, 0, 1, 0, 0], [0, 0, 0.5, 0.5, 0], [0, 0, 0, 1, 0]]))
def test_invariant_refinement(): knots = [ [0] * 4 + [1 / 3, 2 / 3] + [1] * 4, [0] * 4 + [1 / 3, 2 / 3] + [1] * 4, ] deg = [3, 3] dim = 2 t = HierarchicalSpace(knots, deg, dim) m = hierarchical_mass_matrix(t).toarray() # symmetry np.testing.assert_allclose(m, m.T) # partition of unity np.testing.assert_allclose(np.sum(m, axis=(0, 1)), np.ones(m.shape[1])) cells = {0: [0, 1]} t = refine(t, cells) m = hierarchical_mass_matrix(t).toarray() # symmetry np.testing.assert_allclose(m, m.T) # partition of unity np.testing.assert_allclose(np.sum(m, axis=(0, 1)), np.ones(m.shape[1])) cells[1] = [0, 1, 2, 3] t = refine(t, cells) m = hierarchical_mass_matrix(t).toarray() # symmetry np.testing.assert_allclose(m, m.T) # partition of unity np.testing.assert_allclose(np.sum(m, axis=(0, 1)), np.ones(m.shape[1]))
def test_stiffness_matrix_subregion(): knots = [[0, 0, 0, 0, 1, 1, 1, 1], [0, 0, 0, 0, 1, 1, 1, 1]] domain = np.array([[0, 1.0], [0, 1]]) deg = [3, 3] dim = 2 T = HierarchicalSpace(knots, deg, dim) m = hierarchical_mass_matrix(T).toarray().ravel() m_local = local_mass_matrix(T, level=0, element_indices=[0]).toarray().ravel() a = hierarchical_stiffness_matrix(T).toarray().ravel() a_local = local_stiffness_matrix(T, level=0, element_indices=[0]).toarray().ravel() assert np.all(np.in1d(m_local, m)) assert np.all(np.in1d(a_local, a)) m = hierarchical_mass_matrix(T).toarray().ravel() m_local = local_mass_matrix(T, level=0, element_indices=[0]).toarray().ravel() a = hierarchical_stiffness_matrix(T).toarray().ravel() a_local = local_stiffness_matrix(T, level=0, element_indices=[0]).toarray().ravel() assert np.all(np.in1d(m_local, m)) assert np.all(np.in1d(a_local, a))
def test_active_funcs_per_level(): knots = [[0, 0, 1, 1], [0, 0, 1, 1]] d = 2 degrees = [1, 1] T = HierarchicalSpace(knots, degrees, d) np.testing.assert_equal(T.afunc_level, {0: [0, 1, 2, 3]})
def test_partition_of_unity(): knots = [[0, 0, 0, 1, 2, 3, 3, 3], [0, 0, 0, 1, 2, 3, 3, 3]] d = 2 degrees = [2, 2] T = HierarchicalSpace(knots, degrees, d) marked_cells = {0: [0, 1, 2, 3]} T = refine(T, marked_cells) marked_cells = {0: [0, 1, 2, 3], 1: [0, 1, 2]} T = refine(T, marked_cells) C = create_subdivision_matrix(T) N = 5 x = np.linspace(0, 3, N) y = np.linspace(0, 3, N) z = np.zeros((N, N)) c = C[T.nlevels - 1] c = c.toarray() for i in range(T.nfuncs): u = np.zeros(T.nfuncs) u[i] = 1 u_fine = c @ u f = T.spaces[T.nlevels - 1].construct_function(u_fine) for i in range(N): for j in range(N): z[i, j] += f(np.array([x[i], y[j]])) np.testing.assert_allclose(z, 1)
def test_projection_matrix_linear(): knots = [[0, 0, 1, 2, 3, 3]] d = [1] dim = 1 T = HierarchicalSpace(knots, d, dim) cells = {0: [1]} T = refine(T, cells) C = T.compute_full_projection_matrix(0) assert C.shape == (7, 4) np.testing.assert_allclose( C.toarray(), np.array([[1, 0, 0, 0], [0.5, 0.5, 0, 0], [0, 1, 0, 0], [0, 0.5, 0.5, 0], [0, 0, 1, 0], [0, 0, 0.5, 0.5], [0, 0, 0, 1]]))
def test_linear_mass_matrix(): knots = [[0, 0, 1 / 3, 2 / 3, 1, 1]] deg = [1] dim = 1 T = HierarchicalSpace(knots, deg, dim) cells = {0: [1]} T = refine(T, cells) M = hierarchical_mass_matrix(T) assert T.nfuncs_level == {0: 4, 1: 1} assert T.nfuncs == 5 assert M.shape == (5, 5) expected_M = np.array([[ 0.11111111, 0.05555556, 0., 0., 0., ], [0.05555556, 0.16666667, 0., 0, 0.02777778], [0., 0., 0.16666667, 0.05555556, 0.02777778], [0., 0., 0.05555556, 0.11111111, 0.], [0., 0.02777778, 0.02777778, 0., 0.11111111]]) np.testing.assert_allclose(M.toarray(), expected_M)
def test_stiffness_matrix_single_basis_func(): knots = [[0, 1, 2], [0, 1, 2]] deg = [1, 1] dim = 2 T = HierarchicalSpace(knots, deg, dim) a = hierarchical_stiffness_matrix(T).toarray() np.testing.assert_allclose(a, 8 / 3)
def test_active_funcs_per_level_refine(): knots = [[0, 0, 1, 2, 2], [0, 0, 1, 2, 2]] d = 2 degrees = [1, 1] T = HierarchicalSpace(knots, degrees, d) cells = {0: [0]} T = refine(T, cells) np.testing.assert_equal(T.nfuncs_level, {0: 8, 1: 4})
def test_local_mass_matrix_univariate(): knots = [[0, 1, 2]] deg = [1] dim = 1 T = HierarchicalSpace(knots, deg, dim) M = local_mass_matrix(T, 0) assert M.shape == (1, 1) np.testing.assert_allclose(M.toarray(), 2 / 3)
def test_local_mass_matrix_univariate_refined(): knots = [[0, 0, 1 / 3, 2 / 3, 1, 1]] deg = [1] dim = 1 T = HierarchicalSpace(knots, deg, dim) cell = {0: [1]} T = refine(T, cell) m0 = local_mass_matrix(T, 0) m1 = local_mass_matrix(T, 1) assert m0.shape == (4, 4) assert m1.shape == (7, 7)
def create_subdivision_matrix(hspace: HierarchicalSpace) -> dict: """ Returns hspace.nlevels-1 matrices used for representing coarse B-splines in terms of the finer B-splines. :param hspace: HierarchicalSpace containing the needed information :return: a dictionary mapping """ mesh = hspace.mesh C = {} C[0] = sp.identity(hspace.spaces[0].nfuncs, format='lil') C[0] = C[0][:, hspace.afunc_level[0]] for level in range(1, hspace.nlevels): I = sp.identity(hspace.spaces[level].nfuncs, format='lil') aux = sp.lil_matrix(hspace.get_basis_conversion_matrix(level - 1)) C[level] = sp.hstack( [aux @ C[level - 1], I[:, hspace.afunc_level[level]]]) return C
Refining hierarchical space =========================== space.nlevels = {} hmesh.nlevels = {} """.format(hspace.nlevels, hspace.mesh.nlevels)) marked_cells = marked_entities new_cells = hspace.mesh.refine(marked_cells) marked_functions = hspace.functions_to_deactivate_from_cells(marked_cells) hspace.refine(marked_functions, new_cells) logging.info(""" After refinement, the space has =============================== space.nfuncs = {} space.nelems = {} """.format(hspace.nfuncs, hspace.mesh.nel)) return hspace if __name__ == '__main__': knots = [[0, 0, 1, 2, 3, 3], [0, 0, 1, 2, 3, 3]] d = 2 degrees = [1, 1] T = HierarchicalSpace(knots, degrees, d) marked_cells = {0: [0, 1, 2, 3, 4, 5, 6]} T = refine(T, marked_cells) marked_cells = {0: [0, 1, 2, 3, 4, 5, 6], 1: [0, 1, 2, 3, 4, 5, 6]} T = refine(T, marked_cells) T.mesh.plot_cells() print(T)
def test_bilinear_mass_and_stiffness_matrix(): knots = [[0, 0, 1 / 3, 2 / 3, 1, 1], [0, 0, 1 / 3, 2 / 3, 1, 1]] deg = [1, 1] dim = 2 t = HierarchicalSpace(knots, deg, dim) cells = {0: [1]} t = refine(t, cells) m = hierarchical_mass_matrix(t) expected_m = np.array([ [ 0.012346, 0.006173, 0.000000, 0.000000, 0.006173, 0.003086, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 ], [ 0.006173, 0.018519, 0.000000, 0.000000, 0.003086, 0.009452, 0.000193, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.001929, 0.002315 ], [ 0.000000, 0.000000, 0.018519, 0.006173, 0.000000, 0.000193, 0.009452, 0.003086, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.001929, 0.002315 ], [ 0.000000, 0.000000, 0.006173, 0.012346, 0.000000, 0.000000, 0.003086, 0.006173, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 ], [ 0.006173, 0.003086, 0.000000, 0.000000, 0.024691, 0.012346, 0.000000, 0.000000, 0.006173, 0.003086, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 ], [ 0.003086, 0.009452, 0.000193, 0.000000, 0.012346, 0.046682, 0.009645, 0.000000, 0.003086, 0.012346, 0.003086, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000386, 0.003858 ], [ 0.000000, 0.000193, 0.009452, 0.003086, 0.000000, 0.009645, 0.046682, 0.012346, 0.000000, 0.003086, 0.012346, 0.003086, 0.000000, 0.000000, 0.000000, 0.000000, 0.000386, 0.003858 ], [ 0.000000, 0.000000, 0.003086, 0.006173, 0.000000, 0.000000, 0.012346, 0.024691, 0.000000, 0.000000, 0.003086, 0.006173, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000 ], [ 0.000000, 0.000000, 0.000000, 0.000000, 0.006173, 0.003086, 0.000000, 0.000000, 0.024691, 0.012346, 0.000000, 0.000000, 0.006173, 0.003086, 0.000000, 0.000000, 0.000000, 0.000000 ], [ 0.000000, 0.000000, 0.000000, 0.000000, 0.003086, 0.012346, 0.003086, 0.000000, 0.012346, 0.049383, 0.012346, 0.000000, 0.003086, 0.012346, 0.003086, 0.000000, 0.000000, 0.000000 ], [ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.003086, 0.012346, 0.003086, 0.000000, 0.012346, 0.049383, 0.012346, 0.000000, 0.003086, 0.012346, 0.003086, 0.000000, 0.000000 ], [ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.003086, 0.006173, 0.000000, 0.000000, 0.012346, 0.024691, 0.000000, 0.000000, 0.003086, 0.006173, 0.000000, 0.000000 ], [ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.006173, 0.003086, 0.000000, 0.000000, 0.012346, 0.006173, 0.000000, 0.000000, 0.000000, 0.000000 ], [ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.003086, 0.012346, 0.003086, 0.000000, 0.006173, 0.024691, 0.006173, 0.000000, 0.000000, 0.000000 ], [ 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.003086, 0.012346, 0.003086, 0.000000, 0.006173, 0.024691, 0.006173, 0.000000, 0.000000 ], [ .000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.003086, 0.006173, 0.000000, 0.000000, 0.006173, 0.012346, 0.000000, 0.000000 ], [ .000000, 0.001929, 0.001929, 0.000000, 0.000000, 0.000386, 0.000386, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.006173, 0.003086 ], [ .000000, 0.002315, 0.002315, 0.000000, 0.000000, 0.003858, 0.003858, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.003086, 0.012346 ], ]) np.testing.assert_allclose(m.toarray(), expected_m, atol=1.0e-5)