def test_uniform_flow_cart_2d_pert(): # Randomly perturbed grid, with random linear pressure field g, perm = setup_cart_2d(np.array([10, 10])) dx = 1 pert = .4 g.nodes = g.nodes + dx * pert * \ (0.5 - np.random.rand(g.nodes.shape[0], g.num_nodes)) # Cancel perturbations in z-coordinate. g.nodes[2, :] = 0 g.compute_geometry() bound_faces = np.argwhere( np.abs(g.cell_faces).sum(axis=1).A.ravel('F') == 1) bound = bc.BoundaryCondition(g, bound_faces.ravel('F'), ['dir'] * bound_faces.size) # Python inverter is most efficient for small problems flux, bound_flux = mpfa.mpfa(g, perm, bound, inverter='python') div = g.cell_faces.T a = div * flux pr_bound, pr_cell, gx, gy = setup_random_pressure_field(g) rhs = div * bound_flux * pr_bound pr = np.linalg.solve(a.todense(), -rhs) p_diff = pr - pr_cell assert np.max(np.abs(p_diff)) < 1e-8
def test_uniform_flow_cart_2d_structured_pert(): g, perm = setup_cart_2d(np.array([2, 2])) g.nodes[0, 4] = 1.5 g.compute_geometry() bound_faces = g.tags['domain_boundary_faces'].nonzero()[0] bound = bc.BoundaryCondition(g, bound_faces.ravel('F'), ['dir'] * bound_faces.size) # Python inverter is most efficient for small problems flux, bound_flux = mpfa.mpfa(g, perm, bound, inverter='python') div = g.cell_faces.T a = div * flux xf = np.zeros_like(g.face_centers) xf[:, bound_faces.ravel()] = g.face_centers[:, bound_faces.ravel()] xc = g.cell_centers pr_bound = xf.sum(axis=0) pr_cell = xc.sum(axis=0) rhs = div * bound_flux * pr_bound pr = np.linalg.solve(a.todense(), -rhs) p_diff = pr - pr_cell assert np.max(np.abs(p_diff)) < 1e-8
def setup(self): g = CartGrid([5, 5]) g.compute_geometry() perm = PermTensor(g.dim, np.ones(g.num_cells)) bnd = bc.BoundaryCondition(g) flux, bound_flux, _, _ = mpfa.mpfa(g, perm, bnd, inverter="python") return g, perm, bnd, flux, bound_flux
def test_one_cell_a_time_node_keyword(self): # Update one and one cell, and verify that the result is the same as # with a single computation. # The test is similar to what will happen with a memory-constrained # splitting. g = CartGrid([3, 3]) g.compute_geometry() # Assign random permeabilities, for good measure np.random.seed(42) kxx = np.random.random(g.num_cells) kyy = np.random.random(g.num_cells) # Ensure positive definiteness kxy = np.random.random(g.num_cells) * kxx * kyy perm = PermTensor(2, kxx=kxx, kyy=kyy, kxy=kxy) flux = sps.csr_matrix((g.num_faces, g.num_cells)) bound_flux = sps.csr_matrix((g.num_faces, g.num_faces)) faces_covered = np.zeros(g.num_faces, np.bool) bnd = bc.BoundaryCondition(g) cn = g.cell_nodes() for ci in range(g.num_cells): ind = np.zeros(g.num_cells) ind[ci] = 1 nodes = np.squeeze(np.where(cn * ind > 0)) partial_flux, partial_bound, _, _, active_faces = mpfa.mpfa_partial( g, perm, bnd, nodes=nodes, inverter="python") if np.any(faces_covered): partial_flux[faces_covered, :] *= 0 partial_bound[faces_covered, :] *= 0 faces_covered[active_faces] = True flux += partial_flux bound_flux += partial_bound flux_full, bound_flux_full, _, _ = mpfa.mpfa(g, perm, bnd, inverter="python") self.assertTrue((flux_full - flux).max() < 1e-8) self.assertTrue((flux_full - flux).min() > -1e-8) self.assertTrue((bound_flux - bound_flux_full).max() < 1e-8) self.assertTrue((bound_flux - bound_flux_full).min() > -1e-8)
def test_uniform_flow_cart_2d(): # Structured Cartesian grid g, perm = setup_cart_2d(np.array([10, 10])) bound_faces = np.argwhere( np.abs(g.cell_faces).sum(axis=1).A.ravel('F') == 1) bound = bc.BoundaryCondition(g, bound_faces.ravel('F'), ['dir'] * bound_faces.size) # Python inverter is most efficient for small problems flux, bound_flux = mpfa.mpfa(g, perm, bound, inverter='python') div = g.cell_faces.T a = div * flux pr_bound, pr_cell, gx, gy = setup_random_pressure_field(g) rhs = div * bound_flux * pr_bound pr = np.linalg.solve(a.todense(), -rhs) p_diff = pr - pr_cell assert np.max(np.abs(p_diff)) < 1e-8
def test_laplacian_stencil_cart_2d(): """ Apply MPFA on Cartesian grid, should obtain Laplacian stencil. """ # Set up 3 X 3 Cartesian grid g, perm = setup_cart_2d(np.array([3, 3])) bnd_faces = np.array([0, 3, 12]) bound = bc.BoundaryCondition(g, bnd_faces, ['dir'] * bnd_faces.size) # Python inverter is most efficient for small problems flux, bound_flux = mpfa.mpfa(g, perm, bound, inverter='python') div = g.cell_faces.T A = div * flux # Checks on interior cell mid = 4 assert A[mid, mid] == 4 assert A[mid - 1, mid] == -1 assert A[mid + 1, mid] == -1 assert A[mid - 3, mid] == -1 assert A[mid + 3, mid] == -1 # The first cell should have two Dirichlet bnds assert A[0, 0] == 6 assert A[0, 1] == -1 assert A[0, 3] == -1 # Cell 3 has one Dirichlet, one Neumann face assert A[2, 2] == 4 assert A[2, 1] == -1 assert A[2, 5] == -1 # Cell 2 has one Neumann face assert A[1, 1] == 3 assert A[1, 0] == -1 assert A[1, 2] == -1 assert A[1, 4] == -1 return A