def triang_grid(nx=None): if nx is None: nx = np.array([2, 2]) g = pp.StructuredTriangleGrid(nx) g.compute_geometry() return g
def test_create_partition_2d_tri(self): g = pp.StructuredTriangleGrid([3, 2]) g.compute_geometry() part = co.create_partition(co.tpfa_matrix(g)) known = np.array([1, 1, 1, 0, 0, 1, 0, 2, 2, 0, 2, 2]) known_map = np.array([4, 3, 7, 5, 11, 8, 1, 2, 10, 6, 12, 9]) - 1 self.assertTrue(np.array_equal(part, known[known_map]))
def main(self, N): Nx = Ny = N # g = structured.CartGrid([Nx, Ny], [2, 2]) g = pp.StructuredTriangleGrid([Nx, Ny], [1, 1]) g.compute_geometry() # co.coarsen(g, 'by_volume') # Assign parameters data = self.add_data(g) # Choose and define the solvers solver_flow = pp.MVEM("flow") solver_flow.discretize(g, data) A_flow, b_flow = solver_flow.assemble_matrix_rhs(g, data) solver_source = pp.DualScalarSource("flow") solver_source.discretize(g, data) A_source, b_source = solver_source.assemble_matrix_rhs(g, data) up = sps.linalg.spsolve(A_flow + A_source, b_flow + b_source) u = solver_flow.extract_flux(g, up, data) p = solver_flow.extract_pressure(g, up, data) # P0u = solver_flow.project_flux(g, u, data, keyword="flow") diam = np.amax(g.cell_diameters()) return diam, self.error_p(g, p)
def test_upwind_2d_simplex_surf_darcy_flux_negative(self): g = pp.StructuredTriangleGrid([2, 1], [1, 1]) R = pp.map_geometry.rotation_matrix(-np.pi / 5.0, [1, 1, -1]) g.nodes = np.dot(R, g.nodes) g.compute_geometry() solver = pp.Upwind() dis = solver.darcy_flux(g, np.dot(R, [-1, 0, 0])) bf = g.tags["domain_boundary_faces"].nonzero()[0] bc = pp.BoundaryCondition(g, bf, bf.size * ["neu"]) specified_parameters = {"bc": bc, "darcy_flux": dis} data = pp.initialize_default_data(g, {}, "transport", specified_parameters) solver.discretize(g, data) M = solver.assemble_matrix_rhs(g, data)[0].todense() deltaT = solver.cfl(g, data) M_known = np.array([[1, 0, 0, -1], [-1, 0, 0, 0], [0, 0, 1, 0], [0, 0, -1, 1]]) deltaT_known = 1 / 6 rtol = 1e-15 atol = rtol self.assertTrue(np.allclose(M, M_known, rtol, atol)) self.assertTrue(np.allclose(deltaT, deltaT_known, rtol, atol))
def test_changing_bc(self): """ We test that we can change the boundary condition """ g = pp.StructuredTriangleGrid([2, 2], physdims=(1, 1)) g.compute_geometry() bc = pp.BoundaryConditionVectorial(g) k = pp.FourthOrderTensor(g.dim, np.ones(g.num_cells), np.ones(g.num_cells)) stress_neu, bound_stress_neu = pp.numerics.fv.mpsa.mpsa( g, k, bc, inverter="python") bc.is_dir[:, g.get_all_boundary_faces()] = True bc.is_neu[bc.is_dir] = False stress_dir, bound_stress_dir = pp.numerics.fv.mpsa.mpsa( g, k, bc, inverter="python") # Partiall should give same result as full faces = g.get_all_boundary_faces() stress, bound_stress = pp.numerics.fv.mpsa.mpsa_update_partial( stress_neu, bound_stress_neu, g, k, bc, faces=faces, inverter="python") self.assertTrue(np.allclose((stress - stress_dir).data, 0)) self.assertTrue(np.allclose((bound_stress - bound_stress_dir).data, 0))
def test_structured_triang(self): nx = 1 ny = 1 g = pp.StructuredTriangleGrid([nx, ny], physdims=[1, 1]) g.compute_geometry() bot = g.face_centers[1] < 1e-10 top = g.face_centers[1] > 1 - 1e-10 left = g.face_centers[0] < 1e-10 right = g.face_centers[0] > 1 - 1e-10 is_dir = left is_neu = top is_rob = right + bot bnd = pp.BoundaryConditionVectorial(g) bnd.is_neu[:] = False bnd.is_dir[:, is_dir] = True bnd.is_rob[:, is_rob] = True bnd.is_neu[:, is_neu] = True sc_top = pp.fvutils.SubcellTopology(g) bnd = pp.fvutils.boundary_to_sub_boundary(bnd, sc_top) bnd_excl = pp.fvutils.ExcludeBoundaries(sc_top, bnd, g.dim) rhs = pp.numerics.fv.mpsa.create_bound_rhs(bnd, bnd_excl, sc_top, g, True) hf2f = pp.fvutils.map_hf_2_f(sc_top.fno_unique, sc_top.subfno_unique, g.dim) rhs = rhs * hf2f.T rhs_known = np.array([ [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], ]) self.assertTrue(np.all(np.abs(rhs_known - rhs) < 1e-12))
def test_neu(self): g = pp.StructuredTriangleGrid([2, 2]) basis = np.random.rand(g.dim, g.dim, g.num_faces) bc = pp.BoundaryConditionVectorial(g, g.get_all_boundary_faces(), "neu") # Add a Dirichlet condition so the system is well defined bc.is_dir[:, g.get_boundary_faces()[0]] = True bc.is_neu[bc.is_dir] = False self.run_test(g, basis, bc)
def test_default_basis_2d(self): g = pp.StructuredTriangleGrid([1, 1]) bc = pp.BoundaryConditionVectorial(g) basis_known = np.array([ [[1.0, 1.0, 1.0, 1.0, 1.0], [0.0, 0.0, 0.0, 0.0, 0.0]], [[0.0, 0.0, 0.0, 0.0, 0.0], [1.0, 1.0, 1.0, 1.0, 1.0]], ]) self.assertTrue(np.allclose(bc.basis, basis_known))
def test_simplex_2d(self): g = pp.StructuredTriangleGrid(np.array([3, 2])) g.compute_geometry() c = np.array([0, 1, 3]) true_nodes = np.array([0, 1, 4, 5, 6]) true_faces = np.array([0, 1, 2, 4, 5, 10, 13]) h, sub_f, sub_n = pp.partition.extract_subgrid(g, c) assert np.array_equal(true_nodes, sub_n) assert np.array_equal(true_faces, sub_f) self.compare_grid_geometries(g, h, c, true_faces, true_nodes)
def test_structured_triang(self): nx = 1 ny = 1 g = pp.StructuredTriangleGrid([nx, ny], physdims=[1, 1]) g.compute_geometry() c = pp.FourthOrderTensor(2, np.ones(g.num_cells), np.ones(g.num_cells)) robin_weight = np.pi bot = g.face_centers[1] < 1e-10 top = g.face_centers[1] > 1 - 1e-10 left = g.face_centers[0] < 1e-10 right = g.face_centers[0] > 1 - 1e-10 dir_ind = np.ravel(np.argwhere(left)) neu_ind = np.ravel(np.argwhere(())) rob_ind = np.ravel(np.argwhere(right + top + bot)) names = ["dir"] * len(dir_ind) + ["rob"] * len(rob_ind) bnd_ind = np.hstack((dir_ind, rob_ind)) bnd = pp.BoundaryCondition(g, bnd_ind, names) def u_ex(x): return np.vstack((x[1], x[0])) def T_ex(faces): if np.size(faces) == 0: return np.atleast_2d(np.array([])) sigma = np.array([[0, 2], [2, 0]]) T_r = [np.dot(sigma, g.face_normals[:2, f]) for f in faces] return np.vstack(T_r).T u_bound = np.zeros((2, g.num_faces)) sgn_n = pp.numerics.fracture_deformation.sign_of_faces(g, neu_ind) sgn_r = pp.numerics.fracture_deformation.sign_of_faces(g, rob_ind) u_bound[:, dir_ind] = u_ex(g.face_centers[:, dir_ind]) u_bound[:, neu_ind] = T_ex(neu_ind) * sgn_n u_bound[:, rob_ind] = (T_ex(rob_ind) * sgn_r + robin_weight * u_ex(g.face_centers[:, rob_ind]) * g.face_areas[rob_ind]) u, T = self.solve_mpsa(g, c, robin_weight, bnd, u_bound) self.assertTrue(np.allclose(u, u_ex(g.cell_centers).ravel("F"))) self.assertTrue(np.allclose(T, T_ex(np.arange(g.num_faces)).ravel("F")))
def test_convergence_rt0_2d_iso_simplex_exact(self): p_ex = lambda pt: 2 * pt[0, :] - 3 * pt[1, :] - 9 u_ex = np.array([-1, 4, 0]) for i in np.arange(5): g = pp.StructuredTriangleGrid([3 + i] * 2, [1, 1]) g.compute_geometry() kxx = np.ones(g.num_cells) perm = pp.SecondOrderTensor(kxx=kxx, kyy=kxx, kzz=1) bf = g.get_boundary_faces() bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"]) bc_val = np.zeros(g.num_faces) bc_val[bf] = p_ex(g.face_centers[:, bf]) vect = np.vstack((g.cell_volumes, g.cell_volumes, np.zeros(g.num_cells))).ravel(order="F") solver = pp.RT0(keyword="flow") specified_parameters = { "bc": bc, "bc_values": bc_val, "second_order_tensor": perm, "vector_source": vect, } data = pp.initialize_default_data(g, {}, "flow", specified_parameters) solver.discretize(g, data) M, rhs = solver.assemble_matrix_rhs(g, data) up = sps.linalg.spsolve(M, rhs) p = solver.extract_pressure(g, up, data) err = np.sum(np.abs(p - p_ex(g.cell_centers))) self.assertTrue(np.isclose(err, 0)) _ = data[pp.DISCRETIZATION_MATRICES]["flow"][ solver.vector_proj_key] u = solver.extract_flux(g, up, data) P0u = solver.project_flux(g, u, data) err = np.sum( np.abs(P0u - np.tile(u_ex, g.num_cells).reshape((3, -1), order="F"))) self.assertTrue(np.isclose(err, 0))
def test_mvem_2d_simplex(self): g = pp.StructuredTriangleGrid([1, 1], [1, 1]) g.compute_geometry() kxx = np.ones(g.num_cells) perm = pp.SecondOrderTensor(kxx=kxx, kyy=kxx, kzz=1) bf = g.get_boundary_faces() bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"]) vect = np.vstack( (2 * g.cell_volumes, 3 * g.cell_volumes, np.zeros(g.num_cells)) ).ravel(order="F") b = self._matrix(g, perm, bc, vect) b_known = np.array( [-1.33333333, -1.16666667, 0.33333333, 1.16666667, 1.33333333, 0.0, 0.0] ) self.assertTrue(np.allclose(b, b_known))
def test_simplex_2d(self): nx = 1 ny = 1 g = pp.StructuredTriangleGrid([nx, ny], physdims=[1, 1]) g.compute_geometry() g = make_true_2d(g) sc_top = pp.fvutils.SubcellTopology(g) D_g, CC = pp.numerics.fv.mpfa.reconstruct_presssure(g, sc_top, eta=0) D_g_known = np.array( [ [-1 / 6, -1 / 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0], [0, 0, -1 / 6, -1 / 3, 0, 0, 0, 0, 0, 0, 0, 0.0], [0, 0, 0, 0, 0, 0, -1 / 3, -1 / 6, 0, 0, 0, 0.0], [0, 0, 0, 0, 0, 0, 0, 0, -1 / 3, -1 / 6, 0, 0.0], [-1 / 12, 1 / 12, 0, 0, 0, 0, 1 / 12, -1 / 12, 0, 0, 0, 0], [0, 0, 0, 0, -1 / 12, 1 / 12, 0, 0, 0, 0, 1 / 12, -1 / 12], [0, 0, 1 / 3, 1 / 6, 0, 0, 0, 0, 0, 0, 0, 0.0], [0, 0, 0, 0, 1 / 3, 1 / 6, 0, 0, 0, 0, 0, 0.0], [0, 0, 0, 0, 0, 0, 0, 0, 1 / 6, 1 / 3, 0, 0.0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 / 6, 1 / 3], ] ) CC_known = np.array( [ [1, 0.0], [1, 0.0], [0, 1.0], [0, 1.0], [0.5, 0.5], [0.5, 0.5], [1, 0.0], [1, 0.0], [0, 1.0], [0, 1.0], ] ) self.assertTrue(np.all(np.abs(D_g - D_g_known).A < 1e-12)) self.assertTrue(np.all(np.abs(CC - CC_known) < 1e-12))
def test_mvem_2d_simplex_surf(self): g = pp.StructuredTriangleGrid([1, 1], [1, 1]) R = pp.map_geometry.rotation_matrix(-np.pi / 4.0, [1, 1, -1]) g.nodes = np.dot(R, g.nodes) g.compute_geometry() kxx = np.ones(g.num_cells) perm = pp.SecondOrderTensor(kxx=kxx, kyy=kxx, kzz=1) perm.rotate(R) bf = g.get_boundary_faces() bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"]) vect = np.vstack( (g.cell_volumes, 2 * g.cell_volumes, 0 * g.cell_volumes) ).ravel(order="F") b = self._matrix(g, perm, bc, vect) b_known = np.array( [-0.73570226, -0.82197528, -0.17254603, 0.82197528, 0.73570226, 0.0, 0.0] ) self.assertTrue(np.allclose(b, b_known))
def test_mixed_bc(self): """ We test that we can change the boundary condition in given direction """ g = pp.StructuredTriangleGrid([2, 2], physdims=(1, 1)) g.compute_geometry() bc = pp.BoundaryConditionVectorial(g) k = pp.FourthOrderTensor(g.dim, np.ones(g.num_cells), np.ones(g.num_cells)) stress_neu, bound_stress_neu, hf_cell_neu, hf_bound_neu = pp.numerics.fv.mpsa.mpsa( g, k, bc, hf_disp=True, inverter="python") faces = g.face_centers[0] > 1 - 1e-10 bc.is_rob[1, faces] = True bc.is_neu[bc.is_rob] = False # Full discretization stress_rob, bound_stress_rob, hf_cell_rob, hf_bound_rob = pp.numerics.fv.mpsa.mpsa( g, k, bc, hf_disp=True, inverter="python") # Partiall should give same ressult as full stress, bound_stress, hf_cell, hf_bound = pp.numerics.fv.mpsa.mpsa_update_partial( stress_neu, bound_stress_neu, g, k, bc, faces=faces, hf_cell=hf_cell_neu, hf_bound=hf_bound_neu, inverter="python", ) self.assertTrue(np.allclose((stress - stress_rob).data, 0)) self.assertTrue(np.allclose((bound_stress - bound_stress_rob).data, 0)) self.assertTrue(np.allclose((hf_cell - hf_cell_rob).data, 0)) self.assertTrue(np.allclose((hf_bound - hf_bound_rob).data, 0))
def simplex_grid(self, nx=[2, 2]): g = pp.StructuredTriangleGrid(nx) g.compute_geometry() return g
def test_rob(self): g = pp.StructuredTriangleGrid([2, 2]) basis = np.random.rand(g.dim, g.dim, g.num_faces) bc = pp.BoundaryConditionVectorial(g, g.get_all_boundary_faces(), "rob") self.run_test(g, basis, bc)
def test_neu(self): g = pp.StructuredTriangleGrid([1, 1]) basis = np.random.rand(g.dim, g.dim, g.num_faces) bc = pp.BoundaryConditionVectorial(g) self.run_test(g, basis, bc)
def make_grid(grid, grid_dims, domain, dim): if grid.lower() == "cart" or grid.lower() == "cartesian": return pp.CartGrid(grid_dims, domain) elif (grid.lower() == "simplex" and dim == 2) or grid.lower() == "triangular": return pp.StructuredTriangleGrid(grid_dims, domain)
def test_tag_2d_simplex(self): g = pp.StructuredTriangleGrid([3] * 2, [1] * 2) self.assertTrue( np.array_equal(g.tags["fracture_faces"], [False] * g.num_faces)) self.assertTrue( np.array_equal(g.tags["fracture_nodes"], [False] * g.num_nodes)) self.assertTrue( np.array_equal(g.tags["tip_faces"], [False] * g.num_faces)) self.assertTrue( np.array_equal(g.tags["tip_nodes"], [False] * g.num_nodes)) known = np.array( [ True, True, False, True, False, False, True, False, False, True, False, True, False, False, False, False, False, False, False, True, False, True, False, False, False, False, False, False, False, True, True, True, True, ], dtype=bool, ) self.assertTrue(np.array_equal(g.tags["domain_boundary_faces"], known)) known = np.array( [ True, True, True, True, True, False, False, True, True, False, False, True, True, True, True, True, ], dtype=bool, ) self.assertTrue(np.array_equal(g.tags["domain_boundary_nodes"], known))
def make_grid(grid, grid_dims, domain): if grid.lower() == "cart": return pp.CartGrid(grid_dims, domain) elif grid.lower() == "triangular": return pp.StructuredTriangleGrid(grid_dims, domain)
def test_convergence_mvem_2d_ani_simplex(self): rhs_ex = lambda pt: 14 p_ex = ( lambda pt: 2 * np.power(pt[0, :], 2) - 6 * np.power(pt[1, :], 2) + np.multiply(pt[0, :], pt[1, :]) ) u_ex_0 = lambda pt: -9 * pt[0, :] + 10 * pt[1, :] + 4 u_ex_1 = lambda pt: -6 * pt[0, :] + 23 * pt[1, :] + 5 p_errs_known = np.array( [ 0.2411784823808065, 0.13572349427526526, 0.08688469978140642, 0.060345813825004285, 0.044340156291519606, ] ) u_errs_known = np.array( [ 1.7264059760345327, 1.3416423116340397, 1.0925566034251672, 0.9198698104736416, 0.7936243780450764, ] ) for i, p_err_known, u_err_known in zip( np.arange(5), p_errs_known, u_errs_known ): g = pp.StructuredTriangleGrid([3 + i] * 2, [1, 1]) g.compute_geometry() kxx = 2 * np.ones(g.num_cells) kxy = np.ones(g.num_cells) perm = pp.SecondOrderTensor(kxx=kxx, kyy=kxx, kxy=kxy, kzz=1) bf = g.get_boundary_faces() bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"]) bc_val = np.zeros(g.num_faces) bc_val[bf] = p_ex(g.face_centers[:, bf]) # Minus sign to move to rhs source = np.multiply(g.cell_volumes, rhs_ex(g.cell_centers)) vect = np.vstack( (g.cell_volumes, 2 * g.cell_volumes, np.zeros(g.num_cells)) ).ravel(order="F") solver = pp.MVEM(keyword="flow") solver_rhs = pp.DualScalarSource(keyword="flow") specified_parameters = { "bc": bc, "bc_values": bc_val, "second_order_tensor": perm, "source": source, "vector_source": vect, } data = pp.initialize_default_data(g, {}, "flow", specified_parameters) solver.discretize(g, data) solver_rhs.discretize(g, data) M, rhs_bc = solver.assemble_matrix_rhs(g, data) _, rhs = solver_rhs.assemble_matrix_rhs(g, data) up = sps.linalg.spsolve(M, rhs_bc + rhs) p = solver.extract_pressure(g, up, data) err = np.sqrt( np.sum( np.multiply(g.cell_volumes, np.power(p - p_ex(g.cell_centers), 2)) ) ) self.assertTrue(np.isclose(err, p_err_known)) P = data[pp.DISCRETIZATION_MATRICES]["flow"][solver.vector_proj_key] u = solver.extract_flux(g, up, data) P0u = solver.project_flux(g, u, data) uu_ex_0 = u_ex_0(g.cell_centers) uu_ex_1 = u_ex_1(g.cell_centers) uu_ex_2 = np.zeros(g.num_cells) uu_ex = np.vstack((uu_ex_0, uu_ex_1, uu_ex_2)) err = np.sqrt( np.sum( np.multiply( g.cell_volumes, np.sum(np.power(P0u - uu_ex, 2), axis=0) ) ) ) self.assertTrue(np.isclose(err, u_err_known))
def test_convergence_mvem_2d_iso_simplex(self): a = 8 * np.pi ** 2 rhs_ex = lambda pt: np.multiply( np.sin(2 * np.pi * pt[0, :]), np.sin(2 * np.pi * pt[1, :]) ) p_ex = lambda pt: rhs_ex(pt) / a u_ex_0 = ( lambda pt: np.multiply( -np.cos(2 * np.pi * pt[0, :]), np.sin(2 * np.pi * pt[1, :]) ) * 2 * np.pi / a + 1 ) u_ex_1 = ( lambda pt: np.multiply( -np.sin(2 * np.pi * pt[0, :]), np.cos(2 * np.pi * pt[1, :]) ) * 2 * np.pi / a ) p_errs_known = np.array( [ 0.007347293666843033, 0.004057878042430692, 0.002576479539795832, 0.0017817307824819935, 0.0013057660031758425, ] ) u_errs_known = np.array( [ 0.024425617686195774, 0.016806807988931565, 0.012859109258624922, 0.010445238111710832, 0.00881184436169123, ] ) for i, p_err_known, u_err_known in zip( np.arange(5), p_errs_known, u_errs_known ): g = pp.StructuredTriangleGrid([3 + i] * 2, [1, 1]) g.compute_geometry() kxx = np.ones(g.num_cells) perm = pp.SecondOrderTensor(kxx=kxx, kyy=kxx, kzz=1) bf = g.get_boundary_faces() bc = pp.BoundaryCondition(g, bf, bf.size * ["dir"]) bc_val = np.zeros(g.num_faces) bc_val[bf] = p_ex(g.face_centers[:, bf]) # Minus sign to move to rhs source = np.multiply(g.cell_volumes, rhs_ex(g.cell_centers)) vect = np.vstack( (g.cell_volumes, np.zeros(g.num_cells), np.zeros(g.num_cells)) ).ravel(order="F") solver = pp.MVEM(keyword="flow") solver_rhs = pp.DualScalarSource(keyword="flow") specified_parameters = { "bc": bc, "bc_values": bc_val, "second_order_tensor": perm, "source": source, "vector_source": vect, } data = pp.initialize_default_data(g, {}, "flow", specified_parameters) solver.discretize(g, data) solver_rhs.discretize(g, data) M, rhs_bc = solver.assemble_matrix_rhs(g, data) _, rhs = solver_rhs.assemble_matrix_rhs(g, data) up = sps.linalg.spsolve(M, rhs_bc + rhs) p = solver.extract_pressure(g, up, data) err = np.sqrt( np.sum( np.multiply(g.cell_volumes, np.power(p - p_ex(g.cell_centers), 2)) ) ) self.assertTrue(np.isclose(err, p_err_known)) _ = data[pp.DISCRETIZATION_MATRICES]["flow"][solver.vector_proj_key] u = solver.extract_flux(g, up, data) P0u = solver.project_flux(g, u, data) uu_ex_0 = u_ex_0(g.cell_centers) uu_ex_1 = u_ex_1(g.cell_centers) uu_ex_2 = np.zeros(g.num_cells) uu_ex = np.vstack((uu_ex_0, uu_ex_1, uu_ex_2)) err = np.sqrt( np.sum( np.multiply( g.cell_volumes, np.sum(np.power(P0u - uu_ex, 2), axis=0) ) ) ) self.assertTrue(np.isclose(err, u_err_known))
self.assertTrue(mg.num_cells == 1) self.assertTrue(mg.num_sides() == 1) self.assertTrue(np.all(mg.primary_to_mortar_avg().A == [0, 1, 0])) self.assertTrue(np.all(mg.primary_to_mortar_int().A == [0, 1, 0])) self.assertTrue(np.all(mg.secondary_to_mortar_avg().A == [0, 1])) self.assertTrue(np.all(mg.secondary_to_mortar_int().A == [0, 1])) @pytest.mark.parametrize( "g", [ pp.PointGrid([0, 0, 0]), pp.CartGrid([2]), pp.CartGrid([2, 2]), pp.CartGrid([2, 2, 2]), pp.StructuredTriangleGrid([2, 2]), pp.StructuredTetrahedralGrid([1, 1, 1]), ], ) def test_pickle_grid(g): """Test that grids can be pickled. Write, read and compare.""" fn = "tmp.grid" pickle.dump(g, open(fn, "wb")) g_read = pickle.load(open(fn, "rb")) test_utils.compare_grids(g, g_read) test_utils.delete_file(fn) @pytest.mark.parametrize("g",[ pp.PointGrid([0, 0, 0]),