def test_mono_equals_multi(self): """ test that the mono_dimensional elliptic solver gives the same answer as the grid bucket elliptic """ g = CartGrid([10, 10]) g.compute_geometry() gb = meshing.cart_grid([], [10, 10]) param_g = Parameters(g) def bc_val(g): left = g.face_centers[0] < 1e-6 right = g.face_centers[0] > 10 - 1e-6 bc_val = np.zeros(g.num_faces) bc_val[left] = -1 bc_val[right] = 1 return bc_val def bc_labels(g): bound_faces = g.tags['domain_boundary_faces'].nonzero()[0] bound_face_centers = g.face_centers[:, bound_faces] left = bound_face_centers[0] < 1e-6 right = bound_face_centers[0] > 10 - 1e-6 labels = np.array(['neu'] * bound_faces.size) labels[np.logical_or(right, left)] = 'dir' bc_labels = bc.BoundaryCondition(g, bound_faces, labels) return bc_labels param_g.set_bc_val('flow', bc_val(g)) param_g.set_bc('flow', bc_labels(g)) gb.add_node_props(['param']) for sub_g, d in gb: d['param'] = Parameters(sub_g) d['param'].set_bc_val('flow', bc_val(g)) d['param'].set_bc('flow', bc_labels(sub_g)) problem_mono = elliptic.EllipticModel(g, {'param': param_g}) problem_mult = elliptic.EllipticModel(gb) p_mono = problem_mono.solve() p_mult = problem_mult.solve() assert np.allclose(p_mono, p_mult)
def test_upwind_2d_beta_positive(self): f = np.array([[2, 2], [0, 2]]) gb = meshing.cart_grid([f], [4, 2]) gb.assign_node_ordering() gb.compute_geometry() solver = upwind.UpwindMixedDim('transport') gb.add_node_props(['param']) for g, d in gb: param = Parameters(g) aperture = np.ones(g.num_cells)*np.power(1e-2, gb.dim_max() - g.dim) param.set_aperture(aperture) d['discharge'] = solver.discr.discharge(g, [2, 0, 0], aperture) bf = g.get_boundary_faces() bc = BoundaryCondition(g, bf, bf.size * ['neu']) param.set_bc('transport', bc) d['param'] = param # Assign coupling discharge gb.add_edge_prop('param') for e, d in gb.edges_props(): g_h = gb.sorted_nodes_of_edge(e)[1] discharge = gb.node_prop(g_h,'discharge') d['param'] = Parameters(g_h) d['discharge'] = discharge M = solver.matrix_rhs(gb)[0].todense() M_known = np.array([[ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0.], [-2, 2, 0, 0, 0, 0, 0, 0, 0, 0.], [ 0, 0, 2, 0, 0, 0, 0, 0, 0, -2.], [ 0, 0, -2, 0, 0, 0, 0, 0, 0, 0.], [ 0, 0, 0, 0, 2, 0, 0, 0, 0, 0.], [ 0, 0, 0, 0, -2, 2, 0, 0, 0, 0.], [ 0, 0, 0, 0, 0, 0, 2, 0, -2, 0.], [ 0, 0, 0, 0, 0, 0, -2, 0, 0, 0.], [ 0, 0, 0, 0, 0, -2, 0, 0, 2, 0.], [ 0, -2, 0, 0, 0, 0, 0, 0, 0, 2.]]) rtol = 1e-15 atol = rtol assert np.allclose(M, M_known, rtol, atol)
def test_mortar_grid_1d_equally_refine_mortar_grids(self): f1 = np.array([[0, 1], [.5, .5]]) gb = meshing.cart_grid([f1], [2, 2], **{"physdims": [1, 1]}) gb.compute_geometry() gb.assign_node_ordering() for e, d in gb.edges(): mg = d["mortar_grid"] new_side_grids = { s: refinement.remesh_1d(g, num_nodes=4) for s, g in mg.side_grids.items() } mortars.update_mortar_grid(mg, new_side_grids, 1e-4) high_to_mortar_known = ( 1. / 3. * np.matrix( [ [0., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 1., 1., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 2., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 2., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 1.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 2.], ] ) ) low_to_mortar_known = ( 1. / 3. * np.matrix( [[0., 2.], [1., 1.], [2., 0.], [0., 2.], [1., 1.], [2., 0.]] ) ) self.assertTrue( np.allclose(high_to_mortar_known, mg.high_to_mortar_int.todense()) ) self.assertTrue( np.allclose(low_to_mortar_known, mg.low_to_mortar_int.todense()) )
def test_zero_force(self): """ if nothing is touched nothing should happen """ f = np.array([[0, 0, 1], [0, 1, 1], [1, 1, 1], [1, 0, 1]]).T g = meshing.cart_grid([f], [4, 4, 2]).grids_of_dimension(3)[0] data = {"param": Parameters(g)} bound = bc.BoundaryConditionVectorial(g, g.get_all_boundary_faces(), "dir") data["param"].set_bc("mechanics", bound) solver = StaticModel(g, data) d = solver.solve() solver.traction("T") self.assertTrue(np.all(d == 0)) self.assertTrue(np.all(data["T"] == 0))
def test_src_2d(self): """ test that the mono_dimensional elliptic solver gives the same answer as the grid bucket elliptic """ gb = meshing.cart_grid([], [10, 10]) for sub_g, d in gb: if sub_g.dim == 2: d['transport_data'] = InjectionDomain(sub_g, d) else: d['transport_data'] = MatrixDomain(sub_g, d) problem = SourceProblem(gb, physics='transport') problem.solve() dE = change_in_energy(problem) assert np.abs(dE - 10) < 1e-6
def define_grid(): """ Make cartesian grids and a bucket. One horizontal and one vertical 1d fracture in a 2d matrix domain. """ f_1 = np.array([[.5, .5, .5, .5], [.25, .75, .75, .25], [.25, .25, .75, .75]]) f_2 = np.array([[0.2, .8, .8, 0.2], [.5, .5, .5, .5], [.25, .25, .75, .75]]) fracs = [f_1, f_2] mesh_kwargs = {'physdims': np.array([1, 1, 1])} nx = [20, 20, 20] gb = meshing.cart_grid(fracs, np.array(nx), **mesh_kwargs) gb.assign_node_ordering() return gb
def test_coarse_grid_3d_2d(self): f = np.array([[2., 2., 2., 2.], [0., 2., 2., 0.], [0., 0., 2., 2.]]) gb = meshing.cart_grid([f], [4, 2, 2]) gb.compute_geometry() g = gb.get_grids(lambda g: g.dim == gb.dim_max())[0] part = np.zeros(g.num_cells) part[g.cell_centers[0, :] < 2.] = 1 co.generate_coarse_grid(gb, part) # Test known_indices = np.array([1, 3, 0, 2, 1, 3, 0, 2]) known = np.array([1, 4, 7, 10, 44, 45, 46, 47]) for _, d in gb.edges(): indices, faces, _ = sps.find(d['face_cells']) assert np.array_equal(indices, known_indices) assert np.array_equal(faces, known)
def test_mortar_grid_1d_refine_1d_grid_2(self): """ Refine the 1D grid so that it is no longer matching the 2D grid. """ f1 = np.array([[0, 1], [.5, .5]]) gb = meshing.cart_grid([f1], [2, 2], **{"physdims": [1, 1]}) gb.compute_geometry() meshing.create_mortar_grids(gb) gb.assign_node_ordering() for e, d in gb.edges(): # refine the 1d-physical grid old_g = gb.nodes_of_edge(e)[0] new_g = refinement.remesh_1d(old_g, num_nodes=4) new_g.compute_geometry() gb.update_nodes(old_g, new_g) mg = d["mortar_grid"] mortars.update_physical_low_grid(mg, new_g, 1e-4) high_to_mortar_known = np.matrix([ [0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 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., 1.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0.], ]) low_to_mortar_known = (1. / 3. * np.matrix( [[0., 1., 2.], [2., 1., 0.], [0., 1., 2.], [2., 1., 0.]])) self.assertTrue( np.allclose(high_to_mortar_known, mg.high_to_mortar_int.todense())) # The ordering of the cells in the new 1d grid may be flipped on # some systems; therefore allow two configurations self.assertTrue( np.logical_or( np.allclose(low_to_mortar_known, mg.low_to_mortar_int.todense()), np.allclose(low_to_mortar_known, mg.low_to_mortar_int.todense()[::-1]), ))
def setup_3d(nx, simplex_grid=False): f1 = np.array( [[0.2, 0.2, 0.8, 0.8], [0.2, 0.8, 0.8, 0.2], [0.5, 0.5, 0.5, 0.5]]) f2 = np.array( [[0.2, 0.8, 0.8, 0.2], [0.5, 0.5, 0.5, 0.5], [0.2, 0.2, 0.8, 0.8]]) f3 = np.array( [[0.5, 0.5, 0.5, 0.5], [0.2, 0.8, 0.8, 0.2], [0.2, 0.2, 0.8, 0.8]]) fracs = [f1, f2, f3] if not simplex_grid: gb = meshing.cart_grid(fracs, nx, physdims=[1, 1, 1]) else: mesh_kwargs = {} mesh_size = .3 mesh_kwargs['mesh_size'] = {'mode': 'constant', 'value': mesh_size, 'bound_value': 2 * mesh_size} domain = {'xmin': 0, 'ymin': 0, 'xmax': 1, 'ymax': 1} gb = meshing.simplex_grid(fracs, domain, **mesh_kwargs) gb.add_node_props(['param']) for g, d in gb: a = 0.01 / np.max(nx) a = np.power(a, gb.dim_max() - g.dim) param = Parameters(g) param.set_aperture(a) # BoundaryCondition left = g.face_centers[0] < 1e-6 top = g.face_centers[2] > 1 - 1e-6 dir_faces = np.argwhere(left) bc_cond = bc.BoundaryCondition(g, dir_faces, ['dir'] * dir_faces.size) bc_val = np.zeros(g.num_faces) bc_val[dir_faces] = 3 bc_val[top] = 2.4 param.set_bc('flow', bc_cond) param.set_bc_val('flow', bc_val) # Source and sink src = np.zeros(g.num_cells) src[0] = np.pi src[-1] = -np.pi param.set_source('flow', src) d['param'] = param return gb
def test_create_partition_2d_1d_test4(self): f = np.array([[1., 1.], [1., 2.]]) gb = meshing.cart_grid([f], [2, 2]) gb.compute_geometry() seeds = co.generate_seeds(gb) known_seeds = np.array([2, 3]) assert np.array_equal(seeds, known_seeds) part = co.create_partition(co.tpfa_matrix(gb), seeds=seeds) co.generate_coarse_grid(gb, part) # Test known_indices = np.array([0, 0]) known = np.array([4, 10]) for _, d in gb.edges(): indices, faces, _ = sps.find(d['face_cells']) assert np.array_equal(faces, known) assert np.array_equal(indices, known_indices)
def setup_2d_1d(nx, simplex_grid=False): frac1 = np.array([[0.2, 0.8], [0.5, 0.5]]) frac2 = np.array([[0.5, 0.5], [0.8, 0.2]]) fracs = [frac1, frac2] if not simplex_grid: gb = meshing.cart_grid(fracs, nx, physdims=[1, 1]) else: mesh_kwargs = {"mesh_size_frac": .2, "mesh_size_min": .02} domain = {"xmin": 0, "ymin": 0, "xmax": 1, "ymax": 1} gb = meshing.simplex_grid(fracs, domain, **mesh_kwargs) gb.compute_geometry() gb.assign_node_ordering() gb.add_node_props(["param"]) for g, d in gb: kxx = np.ones(g.num_cells) perm = tensor.SecondOrderTensor(3, kxx) a = 0.01 / np.max(nx) a = np.power(a, gb.dim_max() - g.dim) param = Parameters(g) param.set_tensor("flow", perm) param.set_aperture(a) if g.dim == 2: bound_faces = g.tags["domain_boundary_faces"].nonzero()[0] bound = bc.BoundaryCondition(g, bound_faces.ravel("F"), ["dir"] * bound_faces.size) bc_val = np.zeros(g.num_faces) bc_val[bound_faces] = g.face_centers[1, bound_faces] param.set_bc("flow", bound) param.set_bc_val("flow", bc_val) d["param"] = param gb.add_edge_props("kn") for e, d in gb.edges(): g = gb.nodes_of_edge(e)[0] mg = d["mortar_grid"] check_P = mg.low_to_mortar_avg() d["kn"] = 1 / (check_P * gb.node_props(g, "param").get_aperture()) return gb
def test_cell_global2loc_1_frac(self): f = np.array([[0, 1], [1, 1]]) gb = meshing.cart_grid([f], [2, 2]) gb.cell_global2loc() glob = np.arange(5) # test grids for g, d in gb: if g.dim == 2: loc = np.array([0, 1, 2, 3]) elif g.dim == 1: loc = np.array([4]) else: self.assertTrue(False) R = d["cell_global2loc"] self.assertTrue(np.all(R * glob == loc)) # test mortars glob = np.array([0, 1]) for _, d in gb.edges(): loc = np.array([0, 1]) R = d["cell_global2loc"] self.assertTrue(np.all(R * glob == loc))
def setup_2d_1d(nx, simplex_grid=False): frac1 = np.array([[0.2, 0.8], [0.5, 0.5]]) frac2 = np.array([[0.5, 0.5], [0.8, 0.2]]) fracs = [frac1, frac2] if not simplex_grid: gb = meshing.cart_grid(fracs, nx, physdims=[1, 1]) else: mesh_kwargs = {'mesh_size_frac': .2, 'mesh_size_min': .02} domain = {'xmin': 0, 'ymin': 0, 'xmax': 1, 'ymax': 1} gb = meshing.simplex_grid(fracs, domain, **mesh_kwargs) gb.compute_geometry() gb.assign_node_ordering() gb.add_node_props(['param']) for g, d in gb: kxx = np.ones(g.num_cells) perm = tensor.SecondOrderTensor(3, kxx) a = 0.01 / np.max(nx) a = np.power(a, gb.dim_max() - g.dim) param = Parameters(g) param.set_tensor('flow', perm) param.set_aperture(a) if g.dim == 2: bound_faces = g.tags['domain_boundary_faces'].nonzero()[0] bound = bc.BoundaryCondition(g, bound_faces.ravel('F'), ['dir'] * bound_faces.size) bc_val = np.zeros(g.num_faces) bc_val[bound_faces] = g.face_centers[1, bound_faces] param.set_bc('flow', bound) param.set_bc_val('flow', bc_val) d['param'] = param gb.add_edge_props('kn') for e, d in gb.edges(): g = gb.nodes_of_edge(e)[0] d['kn'] = 1 / gb.node_props(g, 'param').get_aperture() return gb
def setup_2d_1d(nx, simplex_grid=False): frac1 = np.array([[0.2, 0.8], [0.5, 0.5]]) frac2 = np.array([[0.5, 0.5], [0.8, 0.2]]) fracs = [frac1, frac2] if not simplex_grid: gb = meshing.cart_grid(fracs, nx, physdims=[1, 1]) else: mesh_kwargs = {} mesh_size = .3 mesh_kwargs['mesh_size'] = { 'mode': 'constant', 'value': mesh_size, 'bound_value': 2 * mesh_size } domain = {'xmin': 0, 'ymin': 0, 'xmax': 1, 'ymax': 1} gb = meshing.simplex_grid(fracs, domain, **mesh_kwargs) gb.compute_geometry() gb.assign_node_ordering() gb.add_node_props(['param']) for g, d in gb: kxx = np.ones(g.num_cells) perm = tensor.SecondOrder(gb.dim_max(), kxx) a = 0.01 / np.max(nx) a = np.power(a, gb.dim_max() - g.dim) param = Parameters(g) param.set_tensor('flow', perm) param.set_aperture(a) if g.dim == 2: bound_faces = g.get_boundary_faces() bound = bc.BoundaryCondition(g, bound_faces.ravel('F'), ['dir'] * bound_faces.size) bc_val = g.face_centers[1] param.set_bc('flow', bound) param.set_bc_val('flow', bc_val) d['param'] = param return gb
def test_tpfa_coupling_3d_2d_1d_0d_dir(self): f1 = np.array([[ 0, 1, 1, 0], [ 0, 0, 1, 1], [.5, .5, .5, .5]]) f2 = np.array([[.5, .5, .5, .5], [ 0, 1, 1, 0], [ 0, 0, 1, 1]]) f3 = np.array([[ 0, 1, 1, 0], [.5, .5, .5, .5], [ 0, 0, 1, 1]]) gb = meshing.cart_grid([f1, f2, f3], [2, 2, 2], **{'physdims': [1, 1, 1]}) gb.compute_geometry() gb.assign_node_ordering() # Remove flag for dual cell_centers1 = np.array([[ 0.25 , 0.75 , 0.25 , 0.75], [ 0.25 , 0.25 , 0.75 , 0.75], [ 0.5 , 0.5 , 0.5 , 0.5 ]]) cell_centers2 = np.array([[ 0.5 , 0.5 , 0.5 , 0.5 ], [ 0.25 , 0.25 , 0.75 , 0.75], [ 0.75 , 0.25 , 0.75 , 0.25]]) cell_centers3 = np.array([[ 0.25 , 0.75 , 0.25 , 0.75], [ 0.5 , 0.5 , 0.5 , 0.5 ], [ 0.25 , 0.25 , 0.75 , 0.75]]) cell_centers4 = np.array([[ 0.5 ], [ 0.25], [ 0.5 ]]) cell_centers5 = np.array([[ 0.5 ], [ 0.75], [ 0.5 ]]) cell_centers6 = np.array([[ 0.75], [ 0.5 ], [ 0.5 ]]) cell_centers7 = np.array([[ 0.25], [ 0.5 ], [ 0.5 ]]) cell_centers8 = np.array([[ 0.5 ], [ 0.5 ], [ 0.25]]) cell_centers9 = np.array([[ 0.5 ], [ 0.5 ], [ 0.75]]) for g, d in gb: if np.allclose(g.cell_centers[:, 0], cell_centers1[:, 0]): d['node_number'] = 1 elif np.allclose(g.cell_centers[:, 0], cell_centers2[:, 0]): d['node_number'] = 2 elif np.allclose(g.cell_centers[:, 0], cell_centers3[:, 0]): d['node_number'] = 3 elif np.allclose(g.cell_centers[:, 0], cell_centers4[:, 0]): d['node_number'] = 4 elif np.allclose(g.cell_centers[:, 0], cell_centers5[:, 0]): d['node_number'] = 5 elif np.allclose(g.cell_centers[:, 0], cell_centers6[:, 0]): d['node_number'] = 6 elif np.allclose(g.cell_centers[:, 0], cell_centers7[:, 0]): d['node_number'] = 7 elif np.allclose(g.cell_centers[:, 0], cell_centers8[:, 0]): d['node_number'] = 8 elif np.allclose(g.cell_centers[:, 0], cell_centers9[:, 0]): d['node_number'] = 9 else: pass tol = 1e-3 solver = tpfa.Tpfa() gb.add_node_props(['param']) a = 1e-2 for g, d in gb: param = Parameters(g) aperture = np.ones(g.num_cells)*np.power(a, gb.dim_max() - g.dim) param.set_aperture(aperture) p = tensor.SecondOrder(3,np.ones(g.num_cells)* np.power(1e3, g.dim<gb.dim_max())) param.set_tensor('flow', p) bound_faces = g.get_boundary_faces() bound_face_centers = g.face_centers[:, bound_faces] left = bound_face_centers[0, :] > 1 - tol right = bound_face_centers[0, :] < tol labels = np.array(['neu'] * bound_faces.size) labels[np.logical_or(left, right)] = ['dir'] bc_val = np.zeros(g.num_faces) bc_dir = bound_faces[np.logical_or(left, right)] bc_val[bc_dir] = g.face_centers[0,bc_dir] param.set_bc(solver, bc.BoundaryCondition(g, bound_faces, labels)) param.set_bc_val(solver, bc_val) d['param'] = param coupling_conditions = tpfa.TpfaCoupling(solver) solver_coupler = coupler.Coupler(solver, coupling_conditions) A, rhs = solver_coupler.matrix_rhs(gb) A_known, rhs_known, p_known = \ matrix_rhs_pressure_for_test_tpfa_coupling_3d_2d_1d_0d() p = sps.linalg.spsolve(A, rhs) rtol = 1e-6 atol = rtol assert np.allclose(A.todense(), A_known, rtol, atol) assert np.allclose(rhs, rhs_known, rtol, atol) assert np.allclose(p, p_known, rtol, atol)
def test_tpfa_coupling_2d_1d_left_right_cross_dir_neu(self): f1 = np.array([[0, 2], [.5, .5]]) f2 = np.array([[.5, .5], [0, 2]]) gb = meshing.cart_grid( [f1, f2], [2, 2], **{'physdims': [1, 1]}) gb.compute_geometry() gb.assign_node_ordering() # Enforce node orderning because of Python 3.5 and 2.7. # Don't do it in general. cell_centers_1 = np.array([[ 7.50000000e-01, 2.500000000e-01], [ 5.00000000e-01, 5.00000000e-01], [ -5.55111512e-17, 5.55111512e-17]]) cell_centers_2 = np.array([[ 5.00000000e-01, 5.00000000e-01], [ 7.50000000e-01, 2.500000000e-01], [ -5.55111512e-17, 5.55111512e-17]]) for g, d in gb: if g.dim == 1: if np.allclose(g.cell_centers, cell_centers_1): d['node_number'] = 1 elif np.allclose(g.cell_centers, cell_centers_2): d['node_number'] = 2 else: raise ValueError('Grid not found') tol = 1e-3 solver = tpfa.Tpfa() gb.add_node_props(['param']) a = 1e-2 for g, d in gb: param = Parameters(g) a_dim = np.power(a, gb.dim_max() - g.dim) aperture = np.ones(g.num_cells)*a_dim param.set_aperture(aperture) kxx = np.ones(g.num_cells) * np.power(1e3, g.dim<gb.dim_max()) #print(kxx, 'dim', g.dim) p = tensor.SecondOrder(3,kxx,kyy=kxx,kzz=kxx) #print(p.perm) param.set_tensor('flow', p) bound_faces = g.get_boundary_faces() bound_face_centers = g.face_centers[:, bound_faces] right = bound_face_centers[0, :] > 1 - tol left = bound_face_centers[0, :] < tol labels = np.array(['neu'] * bound_faces.size) labels[right] = ['dir'] bc_val = np.zeros(g.num_faces) bc_dir = bound_faces[right] bc_neu = bound_faces[left] bc_val[bc_dir] = g.face_centers[0,bc_dir] bc_val[bc_neu] = -g.face_areas[bc_neu]*a_dim param.set_bc(solver, bc.BoundaryCondition(g, bound_faces, labels)) param.set_bc_val(solver, bc_val) d['param'] = param coupling_conditions = tpfa.TpfaCoupling(solver) solver_coupler = coupler.Coupler(solver, coupling_conditions) A, rhs = solver_coupler.matrix_rhs(gb) A_known, rhs_known = matrix_rhs_for_2d_1d_cross() rtol = 1e-6 atol = rtol assert np.allclose(A.todense(), A_known, rtol, atol) assert np.allclose(rhs, rhs_known, rtol, atol)
def test_tpfa_coupling_2d_1d_left_right_dir_neu(self): """ Grid: 2 x 2 cells in matrix + 2 cells in the fracture from left to right. Dirichlet + inflow + no-flow, conductive fracture. Tests pressure solution as well as matrix and rhs. """ f = np.array([[0, 1], [.5, .5]]) gb = meshing.cart_grid( [f], [2, 2], **{'physdims': [1, 1]}) gb.compute_geometry() gb.assign_node_ordering() tol = 1e-3 solver = tpfa.Tpfa(physics='flow') gb.add_node_props(['param']) a = 1e-2 for g, d in gb: param = Parameters(g) a_dim = np.power(a, gb.dim_max() - g.dim) aperture = np.ones(g.num_cells)*a_dim param.set_aperture(aperture) p = tensor.SecondOrder(3,np.ones(g.num_cells)* np.power(1e3, g.dim<gb.dim_max())) param.set_tensor('flow', p) bound_faces = g.get_boundary_faces() bound_face_centers = g.face_centers[:, bound_faces] right = bound_face_centers[0, :] > 1 - tol left = bound_face_centers[0, :] < tol labels = np.array(['neu'] * bound_faces.size) labels[right] = ['dir'] bc_val = np.zeros(g.num_faces) bc_dir = bound_faces[right] bc_neu = bound_faces[left] bc_val[bc_dir] = g.face_centers[0,bc_dir] bc_val[bc_neu] = -g.face_areas[bc_neu]*a_dim param.set_bc(solver, bc.BoundaryCondition(g, bound_faces, labels)) param.set_bc_val(solver, bc_val) d['param'] = param coupling_conditions = tpfa.TpfaCoupling(solver) solver_coupler = coupler.Coupler(solver, coupling_conditions) A, rhs = solver_coupler.matrix_rhs(gb) A_known = np.array(\ [[ 2.99996, -1. , 0. , 0. , 0. , -1.99996], [ -1. , 4.99996, 0. , 0. , -1.99996, 0. ], [ 0. , 0. , 2.99996, -1. , 0. , -1.99996], [ 0. , 0. , -1. , 4.99996, -1.99996, 0. ], [ 0. , -1.99996, 0. , -1.99996, 63.99992, -20. ], [ -1.99996, 0. , -1.99996, 0. , -20. , 23.99992]] ) rhs_known = np.array([ 5.00000000e-01, 2.00000000e+00, 5.00000000e-01, 2.00000000e+00, 4.00000000e+01, 1.00000000e-02]) p_known = np.array([ 1.21984244, 1.05198918, 1.21984244, 1.05198918, 1.02005108, 1.05376576]) p = sps.linalg.spsolve(A, rhs) rtol = 1e-6 atol = rtol assert np.allclose(A.todense(), A_known, rtol, atol) assert np.allclose(rhs, rhs_known, rtol, atol) assert np.allclose(p, p_known, rtol, atol)
def test_tpfa_coupling_2d_1d_left_right_dir(self): """ Grid: 2 x 2 cells in matrix + 2 cells in the fracture from left to right. Dirichlet + no-flow, conductive fracture. """ f = np.array([[0, 1], [.5, .5]]) gb = meshing.cart_grid( [f], [2, 2], **{'physdims': [1, 1]}) gb.compute_geometry() gb.assign_node_ordering() tol = 1e-3 solver = tpfa.Tpfa(physics='flow') gb.add_node_props(['param']) a = 1e-2 for g, d in gb: param = Parameters(g) aperture = np.ones(g.num_cells)*np.power(a, gb.dim_max() - g.dim) param.set_aperture(aperture) p = tensor.SecondOrder(3,np.ones(g.num_cells)* np.power(1e3, g.dim<gb.dim_max())) param.set_tensor('flow', p) bound_faces = g.get_boundary_faces() bound_face_centers = g.face_centers[:, bound_faces] left = bound_face_centers[0, :] > 1 - tol right = bound_face_centers[0, :] < tol labels = np.array(['neu'] * bound_faces.size) labels[np.logical_or(left, right)] = ['dir'] bc_val = np.zeros(g.num_faces) bc_dir = bound_faces[np.logical_or(left, right)] bc_val[bc_dir] = g.face_centers[0,bc_dir] param.set_bc(solver, bc.BoundaryCondition(g, bound_faces, labels)) param.set_bc_val(solver, bc_val) d['param'] = param coupling_conditions = tpfa.TpfaCoupling(solver) solver_coupler = coupler.Coupler(solver, coupling_conditions) A, rhs = solver_coupler.matrix_rhs(gb) A_known = np.array( [[ 4.99996, -1. , 0. , 0. , 0. , -1.99996], [ -1. , 4.99996, 0. , 0. , -1.99996, 0. ], [ 0. , 0. , 4.99996, -1. , 0. , -1.99996], [ 0. , 0. , -1. , 4.99996, -1.99996, 0. ], [ 0. , -1.99996, 0. , -1.99996, 63.99992, -20. ], [ -1.99996, 0. , -1.99996, 0. , -20. , 63.99992]]) rhs_known = np.array([ 0., 2., 0., 2., 40., 0.]) rtol = 1e-6 atol = rtol assert np.allclose(A.todense(), A_known, rtol, atol) assert np.allclose(rhs, rhs_known, rtol, atol)
def test_coarse_grid_2d_1d_cross(self): # NOTE: Since for python 2.7 and 3.5 the meshes in gridbucket may have # non-fixed order, we need to exclude this test. if sys.version_info >= (3, 6): part = np.zeros(36) part[[0, 1, 2, 6, 7]] = 1 part[[8, 14, 13]] = 2 part[[12, 18, 19]] = 3 part[[24, 30, 31, 32]] = 4 part[[21, 22, 23, 27, 28, 29, 33, 34, 35]] = 5 part[[9]] = 6 part[[15, 16, 17]] = 7 part[[9, 10]] = 8 part[[20, 26, 25]] = 9 part[[3, 4, 5, 11]] = 10 f1 = np.array([[3., 3.], [1., 5.]]) f2 = np.array([[1., 5.], [3., 3.]]) gb = meshing.cart_grid([f1, f2], [6, 6]) gb.compute_geometry() cell_centers_1 = np.array( \ [[3.00000000e+00, 3.00000000e+00, 3.00000000e+00, 3.00000000e+00], [4.50000000e+00, 3.50000000e+00, 2.50000000e+00, 1.50000000e+00], [-1.66533454e-16, -5.55111512e-17, 5.55111512e-17, 1.66533454e-16]]) cell_centers_2 = np.array( \ [[4.50000000e+00, 3.50000000e+00, 2.50000000e+00, 1.50000000e+00], [3.00000000e+00, 3.00000000e+00, 3.00000000e+00, 3.00000000e+00], [-1.66533454e-16, -5.55111512e-17, 5.55111512e-17, 1.66533454e-16]]) co.generate_coarse_grid(gb, part) # Test for e_d in gb.edges(): faces = sps.find(e_d[1]['face_cells'])[1] if (e_d[0][0].dim == 0 and e_d[0][1].dim == 1) \ or \ (e_d[0][0].dim == 1 and e_d[0][1].dim == 0): known = [2, 5] if (e_d[0][0].dim == 1 and e_d[0][1].dim == 2) \ or \ (e_d[0][0].dim == 2 and e_d[0][1].dim == 1): g = e_d[0][0] if e_d[0][0].dim == 1 else e_d[0][1] if np.allclose(g.cell_centers, cell_centers_1): known = [5, 10, 14, 18, 52, 53, 54, 55] elif np.allclose(g.cell_centers, cell_centers_2): known = [37, 38, 39, 40, 56, 57, 58, 59] else: raise ValueError('Grid not found') assert np.array_equal(faces, known)
def test_0d_elimination_2d_1d_cross(self): """ Simplest case possible: 2d case with two fractures intersecting in a single 0d grid at the center of the domain. """ f1 = np.array([[0, 1], [.5, .5]]) f2 = np.array([[.5, .5], [0, 1]]) gb = meshing.cart_grid([f1, f2], [2, 2], **{'physdims': [1, 1]}) gb.compute_geometry() gb.assign_node_ordering() tol = 1e-3 solver = tpfa.Tpfa() gb.add_node_props(['param']) a = 1e-2 for g, d in gb: param = Parameters(g) a_dim = np.power(a, gb.dim_max() - g.dim) aperture = np.ones(g.num_cells) * a_dim param.set_aperture(aperture) kxx = np.ones(g.num_cells) * np.power(1e3, g.dim < gb.dim_max()) p = tensor.SecondOrderTensor(3, kxx, kyy=kxx, kzz=kxx) param.set_tensor('flow', p) bound_faces = g.tags['domain_boundary_faces'].nonzero()[0] if bound_faces.size != 0: bound_face_centers = g.face_centers[:, bound_faces] right = bound_face_centers[0, :] > 1 - tol left = bound_face_centers[0, :] < tol labels = np.array(['neu'] * bound_faces.size) labels[right] = ['dir'] bc_val = np.zeros(g.num_faces) bc_dir = bound_faces[right] bc_neu = bound_faces[left] bc_val[bc_dir] = g.face_centers[0, bc_dir] bc_val[bc_neu] = -g.face_areas[bc_neu] * a_dim param.set_bc(solver, bc.BoundaryCondition(g, bound_faces, labels)) param.set_bc_val(solver, bc_val) else: param.set_bc("flow", bc.BoundaryCondition(g, np.empty(0), np.empty(0))) d['param'] = param coupling_conditions = tpfa.TpfaCoupling(solver) solver_coupler = coupler.Coupler(solver, coupling_conditions) A, rhs = solver_coupler.matrix_rhs(gb) p = sps.linalg.spsolve(A, rhs) p_cond, _, _, _ = condensation.solve_static_condensation(A, rhs, gb, dim=0) solver_coupler.split(gb, 'pressure', p) solver_coupler.split(gb, "p_cond", p_cond) tol = 1e-10 assert ((np.amax(np.absolute(p - p_cond))) < tol) assert (np.sum( error.error_L2(g, d['pressure'], d['p_cond']) for g, d in gb) < tol)
def test_non_zero_bc_val(self): """ We mixed bc_val on domain boundary and fracture displacement in x-direction. """ frac = np.array([[1,1,1], [1,2,1], [2,2,1], [2,1,1]]).T physdims = np.array([3,3,2]) g = meshing.cart_grid([frac], [3,3,2], physdims=physdims).grids_of_dimension(3)[0] data = {'param': Parameters(g)} # Define boundary conditions bc_val = np.zeros((g.dim, g.num_faces)) frac_slip = np.zeros((g.dim, g.num_faces)) frac_bnd = g.has_face_tag(FaceTag.FRACTURE) dom_bnd = g.has_face_tag(FaceTag.DOMAIN_BOUNDARY) frac_slip[0, frac_bnd] = np.ones(np.sum(frac_bnd)) bc_val[:, dom_bnd] = g.face_centers[:, dom_bnd] bound = bc.BoundaryCondition(g, g.get_boundary_faces(), 'dir') data['param'].set_bc('mechanics', bound) data['param'].set_bc_val('mechanics', bc_val.ravel('F')) data['param'].set_slip_distance(frac_slip.ravel('F')) solver = mpsa.FracturedMpsa() A, b = solver.matrix_rhs(g, data) u = np.linalg.solve(A.A, b) u_f = solver.extract_frac_u(g, u) u_c = solver.extract_u(g, u) u_c = u_c.reshape((3, -1), order='F') # Test traction frac_faces = g.frac_pairs frac_left = frac_faces[0] frac_right = frac_faces[1] T = solver.traction(g, data, u) T = T.reshape((3, -1),order='F') T_left = T[:, frac_left] T_right = T[:, frac_right] assert np.allclose(T_left, T_right) # we have u_lhs - u_rhs = 1 so u_lhs should be positive mid_ind = int(round(u_f.size/2)) u_left = u_f[:mid_ind] u_right = u_f[mid_ind:] true_diff = np.atleast_2d(np.array([1,0,0])).T u_left = u_left.reshape((3, -1), order='F') u_right = u_right.reshape((3, -1), order='F') assert np.all(np.abs(u_left - u_right - true_diff) < 1e-10) # should have a positive displacement for all cells assert np.all(u_c > 0)
def test_create_partition_2d_1d_cross_test7(self): # NOTE: Since for python 2.7 and 3.5 the meshes in gridbucket may have # non-fixed order, we need to exclude this test. if sys.version_info >= (3, 6): N = 20 f1 = np.array([[N / 2., N / 2.], [1., N - 1.]]) f2 = np.array([[1., N - 1.], [N / 2., N / 2.]]) gb = meshing.cart_grid([f1, f2], [N, N]) gb.compute_geometry() seeds = co.generate_seeds(gb) known_seeds = np.array([29, 30, 369, 370, 181, 198, 201, 218]) assert np.array_equal(np.sort(seeds), np.sort(known_seeds)) part = co.create_partition(co.tpfa_matrix(gb), cdepth=3, seeds=seeds) co.generate_coarse_grid(gb, part) cell_centers_1 = np.array( \ [[1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01], [1.85000000e+01, 1.75000000e+01, 1.65000000e+01, 1.55000000e+01, 1.45000000e+01, 1.35000000e+01, 1.25000000e+01, 1.15000000e+01, 1.05000000e+01, 9.50000000e+00, 8.50000000e+00, 7.50000000e+00, 6.50000000e+00, 5.50000000e+00, 4.50000000e+00, 3.50000000e+00, 2.50000000e+00, 1.50000000e+00], [-9.43689571e-16, -8.32667268e-16, -7.21644966e-16, -6.10622664e-16, -4.99600361e-16, -3.88578059e-16, -2.77555756e-16, -1.66533454e-16, -5.55111512e-17, 5.55111512e-17, 1.66533454e-16, 2.77555756e-16, 3.88578059e-16, 4.99600361e-16, 6.10622664e-16, 7.21644966e-16, 8.32667268e-16, 9.43689571e-16]]) cell_centers_2 = np.array( \ [[1.85000000e+01, 1.75000000e+01, 1.65000000e+01, 1.55000000e+01, 1.45000000e+01, 1.35000000e+01, 1.25000000e+01, 1.15000000e+01, 1.05000000e+01, 9.50000000e+00, 8.50000000e+00, 7.50000000e+00, 6.50000000e+00, 5.50000000e+00, 4.50000000e+00, 3.50000000e+00, 2.50000000e+00, 1.50000000e+00], [1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01, 1.00000000e+01], [-9.43689571e-16, -8.32667268e-16, -7.21644966e-16, -6.10622664e-16, -4.99600361e-16, -3.88578059e-16, -2.77555756e-16, -1.66533454e-16, -5.55111512e-17, 5.55111512e-17, 1.66533454e-16, 2.77555756e-16, 3.88578059e-16, 4.99600361e-16, 6.10622664e-16, 7.21644966e-16, 8.32667268e-16, 9.43689571e-16]]) # Test for e_d in gb.edges(): indices, faces, _ = sps.find(e_d[1]['face_cells']) if (e_d[0][0].dim == 0 and e_d[0][1].dim == 1) \ or \ (e_d[0][0].dim == 1 and e_d[0][1].dim == 0): known = [9, 19] known_indices = [0, 0] if (e_d[0][0].dim == 1 and e_d[0][1].dim == 2) \ or \ (e_d[0][0].dim == 2 and e_d[0][1].dim == 1): g = e_d[0][0] if e_d[0][0].dim == 1 else e_d[0][1] if np.allclose(g.cell_centers, cell_centers_1): known = [ 10, 18, 28, 37, 46, 54, 62, 71, 77, 84, 91, 99, 108, 116, 124, 134, 143, 151, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345 ] known_indices = [ 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] elif np.allclose(g.cell_centers, cell_centers_2): known = [ 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363 ] known_indices = [ 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ] else: raise ValueError('Grid not found') assert np.array_equal(faces, np.array(known)) assert np.array_equal(indices, np.array(known_indices))
def test_coarse_grid_3d_2d_cross(self): # NOTE: Since for python 2.7 and 3.5 the meshes in gridbucket may have # non-fixed order, we need to exclude this test. if sys.version_info >= (3, 6): f1 = np.array([[3., 3., 3., 3.], [1., 5., 5., 1.], [1., 1., 5., 5.]]) f2 = np.array([[1., 5., 5., 1.], [1., 1., 5., 5.], [3., 3., 3., 3.]]) gb = meshing.cart_grid([f1, f2], [6, 6, 6]) gb.compute_geometry() g = gb.get_grids(lambda g: g.dim == gb.dim_max())[0] part = np.zeros(g.num_cells) p1, p2 = g.cell_centers[0, :] < 3., g.cell_centers[2, :] < 3. part[np.logical_and(p1, p2)] = 1 part[np.logical_and(p1, np.logical_not(p2))] = 2 part[np.logical_and(np.logical_not(p1), p2)] = 3 part[np.logical_and(np.logical_not(p1), np.logical_not(p2))] = 4 co.generate_coarse_grid(gb, part) cell_centers_1 = np.array( \ [[3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3.], [1.5, 1.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 3.5, 3.5, 3.5, 3.5, 4.5, 4.5, 4.5, 4.5], [4.5, 3.5, 2.5, 1.5, 4.5, 3.5, 2.5, 1.5, 4.5, 3.5, 2.5, 1.5, 4.5, 3.5, 2.5, 1.5]]) cell_centers_2 = np.array( \ [[1.5, 2.5, 3.5, 4.5, 1.5, 2.5, 3.5, 4.5, 1.5, 2.5, 3.5, 4.5, 1.5, 2.5, 3.5, 4.5], [1.5, 1.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 3.5, 3.5, 3.5, 3.5, 4.5, 4.5, 4.5, 4.5], [3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3., 3.]]) # Test for e_d in gb.edges(): indices, faces, _ = sps.find(e_d[1]['face_cells']) if (e_d[0][0].dim == 1 and e_d[0][1].dim == 2) \ or \ (e_d[0][0].dim == 2 and e_d[0][1].dim == 1): known_indices = [3, 2, 1, 0, 3, 2, 1, 0] known = [2, 7, 12, 17, 40, 41, 42, 43] if (e_d[0][0].dim == 2 and e_d[0][1].dim == 3) \ or \ (e_d[0][0].dim == 3 and e_d[0][1].dim == 2): g = e_d[0][0] if e_d[0][0].dim == 2 else e_d[0][1] if np.allclose(g.cell_centers, cell_centers_1): known_indices = [ 3, 7, 11, 15, 2, 6, 10, 14, 1, 5, 9, 13, 0, 4, 8, 12, 3, 7, 11, 15, 2, 6, 10, 14, 1, 5, 9, 13, 0, 4, 8, 12 ] known = [ 22, 25, 28, 31, 40, 43, 46, 49, 58, 61, 64, 67, 76, 79, 82, 85, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303 ] elif np.allclose(g.cell_centers, cell_centers_2): known_indices = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ] known = [ 223, 224, 225, 226, 229, 230, 231, 232, 235, 236, 237, 238, 241, 242, 243, 244, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319 ] else: raise ValueError('Grid not found') assert np.array_equal(indices, np.array(known_indices)) assert np.array_equal(faces, np.array(known))
def test_tpfa_coupling_2d_1d_bottom_top_dir_neu(self): """ Grid: 1 x 2 cells in matrix + 1 cell in the fracture from left to right. Dirichlet + inflow + no-flow, blocking fracture. """ f = np.array([[0, 1], [.5, .5]]) gb = meshing.cart_grid( [f], [1, 2], **{'physdims': [1, 1]}) gb.compute_geometry() gb.assign_node_ordering() tol = 1e-3 solver = tpfa.Tpfa(physics='flow') solver = tpfa.Tpfa(physics='flow') gb.add_node_props(['param']) a = 1e-2 for g, d in gb: param = Parameters(g) a_dim = np.power(a, gb.dim_max() - g.dim) aperture = np.ones(g.num_cells)*a_dim param.set_aperture(aperture) p = tensor.SecondOrder(3,np.ones(g.num_cells)* np.power(1e-3, g.dim<gb.dim_max())) param.set_tensor('flow', p) bound_faces = g.get_boundary_faces() bound_face_centers = g.face_centers[:, bound_faces] top = bound_face_centers[1, :] > 1 - tol bottom = bound_face_centers[1, :] < tol labels = np.array(['neu'] * bound_faces.size) labels[bottom] = ['dir'] bc_val = np.zeros(g.num_faces) bc_dir = bound_faces[bottom] bc_neu = bound_faces[top] bc_val[bc_dir] = g.face_centers[1,bc_dir] bc_val[bc_neu] = -g.face_areas[bc_neu]*a_dim param.set_bc(solver, bc.BoundaryCondition(g, bound_faces, labels)) param.set_bc_val(solver, bc_val) d['param'] = param coupling_conditions = tpfa.TpfaCoupling(solver) solver_coupler = coupler.Coupler(solver, coupling_conditions) A, rhs = solver_coupler.matrix_rhs(gb) A_known = np.array([[ 4.19047619, 0. , -0.19047619], [ 0. , 0.19047619, -0.19047619], [-0.19047619, -0.19047619, 0.38095238]]) rhs_known = np.array([0, 1, 0]) rtol = 1e-6 atol = rtol assert np.allclose(A.todense(), A_known, rtol, atol) assert np.allclose(rhs, rhs_known, rtol, atol)
def test_0d_elimination_3d_2d_1d_0d(self): """ 3d case with a single 0d grid. """ f1 = np.array([[0, 1, 1, 0], [0, 0, 1, 1], [.5, .5, .5, .5]]) f2 = np.array([[.5, .5, .5, .5], [0, 1, 1, 0], [0, 0, 1, 1]]) f3 = np.array([[0, 1, 1, 0], [.5, .5, .5, .5], [0, 0, 1, 1]]) gb = meshing.cart_grid([f1, f2, f3], [2, 2, 2], **{'physdims': [1, 1, 1]}) gb.compute_geometry() gb.assign_node_ordering() cell_centers1 = np.array([[0.25, 0.75, 0.25, 0.75], [0.25, 0.25, 0.75, 0.75], [0.5, 0.5, 0.5, 0.5]]) cell_centers2 = np.array([[0.5, 0.5, 0.5, 0.5], [0.25, 0.25, 0.75, 0.75], [0.75, 0.25, 0.75, 0.25]]) cell_centers3 = np.array([[0.25, 0.75, 0.25, 0.75], [0.5, 0.5, 0.5, 0.5], [0.25, 0.25, 0.75, 0.75]]) cell_centers4 = np.array([[0.5], [0.25], [0.5]]) cell_centers5 = np.array([[0.5], [0.75], [0.5]]) cell_centers6 = np.array([[0.75], [0.5], [0.5]]) cell_centers7 = np.array([[0.25], [0.5], [0.5]]) cell_centers8 = np.array([[0.5], [0.5], [0.25]]) cell_centers9 = np.array([[0.5], [0.5], [0.75]]) for g, d in gb: if np.allclose(g.cell_centers[:, 0], cell_centers1[:, 0]): d['node_number'] = 1 elif np.allclose(g.cell_centers[:, 0], cell_centers2[:, 0]): d['node_number'] = 2 elif np.allclose(g.cell_centers[:, 0], cell_centers3[:, 0]): d['node_number'] = 3 elif np.allclose(g.cell_centers[:, 0], cell_centers4[:, 0]): d['node_number'] = 4 elif np.allclose(g.cell_centers[:, 0], cell_centers5[:, 0]): d['node_number'] = 5 elif np.allclose(g.cell_centers[:, 0], cell_centers6[:, 0]): d['node_number'] = 6 elif np.allclose(g.cell_centers[:, 0], cell_centers7[:, 0]): d['node_number'] = 7 elif np.allclose(g.cell_centers[:, 0], cell_centers8[:, 0]): d['node_number'] = 8 elif np.allclose(g.cell_centers[:, 0], cell_centers9[:, 0]): d['node_number'] = 9 else: pass tol = 1e-3 solver = tpfa.Tpfa() gb.add_node_props(['param']) a = 1e-2 for g, d in gb: param = Parameters(g) aperture = np.ones(g.num_cells) * np.power(a, gb.dim_max() - g.dim) param.set_aperture(aperture) p = tensor.SecondOrderTensor( 3, np.ones(g.num_cells) * np.power(1e3, g.dim < gb.dim_max())) param.set_tensor('flow', p) bound_faces = g.tags['domain_boundary_faces'].nonzero()[0] if bound_faces.size != 0: bound_face_centers = g.face_centers[:, bound_faces] left = bound_face_centers[0, :] > 1 - tol right = bound_face_centers[0, :] < tol labels = np.array(['neu'] * bound_faces.size) labels[np.logical_or(left, right)] = ['dir'] bc_val = np.zeros(g.num_faces) bc_dir = bound_faces[np.logical_or(left, right)] bc_val[bc_dir] = g.face_centers[0, bc_dir] param.set_bc(solver, bc.BoundaryCondition(g, bound_faces, labels)) param.set_bc_val(solver, bc_val) else: param.set_bc("flow", bc.BoundaryCondition(g, np.empty(0), np.empty(0))) d['param'] = param coupling_conditions = tpfa.TpfaCoupling(solver) solver_coupler = coupler.Coupler(solver, coupling_conditions) A, rhs = solver_coupler.matrix_rhs(gb) p = sps.linalg.spsolve(A, rhs) p_cond, _, _, _ = condensation.solve_static_condensation(A, rhs, gb, dim=0) solver_coupler.split(gb, 'pressure', p) solver_coupler.split(gb, "p_cond", p_cond) tol = 1e-10 assert ((np.amax(np.absolute(p - p_cond))) < tol) assert (np.sum( error.error_L2(g, d['pressure'], d['p_cond']) for g, d in gb) < tol)
def test_tag_2d_1d_cart(self): f1 = np.array([[0, 1], [.5, .5]]) gb = meshing.cart_grid([f1], [4, 4], **{"physdims": [1, 1]}) for g, _ in gb: if g.dim == 1: 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 = [0, 4] computed = np.where(g.tags["domain_boundary_faces"])[0] self.assertTrue(np.array_equal(computed, known)) known = [0, 4] computed = np.where(g.tags["domain_boundary_nodes"])[0] self.assertTrue(np.array_equal(computed, known)) if g.dim == 2: known = [28, 29, 30, 31, 40, 41, 42, 43] computed = np.where(g.tags["fracture_faces"])[0] self.assertTrue(np.array_equal(computed, known)) known = [10, 11, 12, 13, 14, 15, 16, 17, 18, 19] computed = np.where(g.tags["fracture_nodes"])[0] print(computed, known) self.assertTrue(np.array_equal(computed, known)) 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 = [ 0, 4, 5, 9, 10, 14, 15, 19, 20, 21, 22, 23, 36, 37, 38, 39 ] computed = np.where(g.tags["domain_boundary_faces"])[0] self.assertTrue(np.array_equal(computed, known)) known = [ 0, 1, 2, 3, 4, 5, 9, 10, 11, 18, 19, 20, 24, 25, 26, 27, 28, 29, ] computed = np.where(g.tags["domain_boundary_nodes"])[0] self.assertTrue(np.array_equal(computed, known))
def test_mono_equals_multi(self): """ test that the mono_dimensional elliptic solver gives the same answer as the grid bucket elliptic """ g = CartGrid([10, 10]) g.compute_geometry() gb = meshing.cart_grid([], [10, 10]) param_g = Parameters(g) def bc_val(g): left = g.face_centers[0] < 1e-6 right = g.face_centers[0] > 10 - 1e-6 bc_val = np.zeros(g.num_faces) bc_val[left] = -1 bc_val[right] = 1 return bc_val def bc_labels(g): bound_faces = g.get_boundary_faces() bound_face_centers = g.face_centers[:, bound_faces] left = bound_face_centers[0] < 1e-6 right = bound_face_centers[0] > 10 - 1e-6 labels = np.array(['neu'] * bound_faces.size) labels[np.logical_or(right, left)] = 'dir' bc_labels = bc.BoundaryCondition(g, bound_faces, labels) return bc_labels param_g.set_bc_val('flow', bc_val(g)) param_g.set_bc('flow', bc_labels(g)) gb.add_node_props(['param']) for sub_g, d in gb: d['param'] = Parameters(sub_g) d['param'].set_bc_val('flow', bc_val(sub_g)) d['param'].set_bc('flow', bc_labels(sub_g)) problem_mono = elliptic.DualEllipticModel(g, {'param': param_g}) problem_mult = elliptic.DualEllipticModel(gb) up_mono = problem_mono.solve() up_mult = problem_mult.solve() assert np.allclose(up_mono, up_mult) g_gb = next(problem_mult.grid().nodes()) problem_mono.pressure('pressure') problem_mult.split() problem_mult.pressure('pressure') assert np.allclose(problem_mono.data()['pressure'], problem_mult.grid().node_prop(g_gb, 'pressure')) problem_mono.discharge('u') problem_mult.discharge('u') assert np.allclose(problem_mono.data()['u'], problem_mult.grid().node_prop(g_gb, 'u')) problem_mono.project_discharge('P0u') problem_mult.project_discharge('P0u') problem_mono.save(['pressure', 'P0u']) problem_mult.save(['pressure', 'P0u']) assert np.allclose(problem_mono.data()['P0u'], problem_mult.grid().node_prop(g_gb, 'P0u'))
def test_tag_2d_1d_cart_complex(self): f1 = np.array([[0, 1], [.5, .5]]) f2 = np.array([[.5, .5], [.25, .75]]) gb = meshing.cart_grid([f1, f2], [4, 4], **{"physdims": [1, 1]}) for g, _ in gb: if g.dim == 0: self.assertTrue(np.sum(g.tags["fracture_faces"]) == 0) self.assertTrue(np.sum(g.tags["fracture_nodes"]) == 0) self.assertTrue(np.sum(g.tags["tip_faces"]) == 0) self.assertTrue(np.sum(g.tags["tip_nodes"]) == 0) self.assertTrue(np.sum(g.tags["domain_boundary_faces"]) == 0) self.assertTrue(np.sum(g.tags["domain_boundary_nodes"]) == 0) if g.dim == 1 and g.nodes[1, 0] == 0.5: known = [2, 5] computed = np.where(g.tags["fracture_faces"])[0] self.assertTrue(np.array_equal(known, computed)) known = [2, 3] computed = np.where(g.tags["fracture_nodes"])[0] self.assertTrue(np.array_equal(known, computed)) 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 = [0, 4] computed = np.where(g.tags["domain_boundary_faces"])[0] self.assertTrue(np.array_equal(computed, known)) known = [0, 5] computed = np.where(g.tags["domain_boundary_nodes"])[0] self.assertTrue(np.array_equal(computed, known)) if g.dim == 1 and g.nodes[0, 0] == 0.5: known = [1, 3] computed = np.where(g.tags["fracture_faces"])[0] self.assertTrue(np.array_equal(known, computed)) known = [1, 2] computed = np.where(g.tags["fracture_nodes"])[0] self.assertTrue(np.array_equal(known, computed)) known = [0, 2] computed = np.where(g.tags["tip_faces"])[0] self.assertTrue(np.array_equal(known, computed)) known = [0, 3] computed = np.where(g.tags["tip_nodes"])[0] self.assertTrue(np.array_equal(known, computed)) self.assertTrue(np.sum(g.tags["domain_boundary_faces"]) == 0) self.assertTrue(np.sum(g.tags["domain_boundary_nodes"]) == 0) if g.dim == 2: known = [7, 12, 28, 29, 30, 31, 40, 41, 42, 43, 44, 45] computed = np.where(g.tags["fracture_faces"])[0] self.assertTrue(np.array_equal(computed, known)) known = [7, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 24] computed = np.where(g.tags["fracture_nodes"])[0] self.assertTrue(np.array_equal(computed, known)) 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 = [ 0, 4, 5, 9, 10, 14, 15, 19, 20, 21, 22, 23, 36, 37, 38, 39 ] computed = np.where(g.tags["domain_boundary_faces"])[0] self.assertTrue(np.array_equal(computed, known)) known = [ 0, 1, 2, 3, 4, 5, 9, 10, 11, 20, 21, 22, 26, 27, 28, 29, 30, 31, ] computed = np.where(g.tags["domain_boundary_nodes"])[0] self.assertTrue(np.array_equal(computed, known))
def test_x_intersection_2d(self): """ Check that the faces has correct tags for a 2D grid. """ f_1 = np.array([[0, 2], [1, 1]]) f_2 = np.array([[1, 1], [0, 2]]) f_set = [f_1, f_2] nx = [3, 3] grids = meshing.cart_grid(f_set, nx, physdims=nx) # 2D grid: g_2d = grids.grids_of_dimension(2)[0] f_tags_2d = np.array([ False, True, False, False, # first row False, True, False, False, # Second row False, False, False, False, # third row False, False, False, # Bottom column True, True, False, # Second column False, False, False, # Third column False, False, False, # Top column True, True, True, True, ]) # Added faces d_tags_2d = np.array([ True, False, False, True, # first row True, False, False, True, # Second row True, False, False, True, # third row True, True, True, # Bottom column False, False, False, # Second column False, False, False, # Third column True, True, True, # Top column False, False, False, False, ]) # Added Faces t_tags_2d = np.zeros(f_tags_2d.size, dtype=bool) self.assertTrue(np.all(g_2d.tags["tip_faces"] == t_tags_2d)) self.assertTrue(np.all(g_2d.tags["fracture_faces"] == f_tags_2d)) self.assertTrue( np.all(g_2d.tags["domain_boundary_faces"] == d_tags_2d)) # 1D grids: for g_1d in grids.grids_of_dimension(1): f_tags_1d = np.array([False, True, False, True]) if g_1d.face_centers[0, 0] > 0.1: t_tags_1d = np.array([True, False, False, False]) d_tags_1d = np.array([False, False, True, False]) else: t_tags_1d = np.array([False, False, True, False]) d_tags_1d = np.array([True, False, False, False]) self.assertTrue(np.all(g_1d.tags["tip_faces"] == t_tags_1d)) self.assertTrue(np.all(g_1d.tags["fracture_faces"] == f_tags_1d)) self.assertTrue( np.all(g_1d.tags["domain_boundary_faces"] == d_tags_1d))
def test_mortar_grid_2d(self): f = np.array([[0, 1, 1, 0], [0, 0, 1, 1], [0.5, 0.5, 0.5, 0.5]]) gb = meshing.cart_grid([f], [2] * 3, **{"physdims": [1] * 3}) gb.compute_geometry() meshing.create_mortar_grids(gb) gb.assign_node_ordering() for e, d in gb.edges(): mg = d["mortar_grid"] indices_known = np.array([0, 1, 2, 3, 4, 5, 6, 7]) self.assertTrue( np.array_equal(mg.master_to_mortar_int().indices, indices_known)) indptr_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, 1, 2, 3, 4, 4, 4, 4, 4, 5, 6, 7, 8, ]) self.assertTrue( np.array_equal(mg.master_to_mortar_int().indptr, indptr_known)) data_known = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]) self.assertTrue( np.array_equal(mg.master_to_mortar_int().data, data_known)) indices_known = np.array([0, 4, 1, 5, 2, 6, 3, 7]) self.assertTrue( np.array_equal(mg.slave_to_mortar_int().indices, indices_known)) indptr_known = np.array([0, 2, 4, 6, 8]) self.assertTrue( np.array_equal(mg.slave_to_mortar_int().indptr, indptr_known)) data_known = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]) self.assertTrue( np.array_equal(mg.slave_to_mortar_int().data, data_known))