def permeability(self): if self.grid().dim == 3: kxx = self.km * np.ones(self.grid().num_cells) return tensor.SecondOrder(self.grid().dim, kxx=kxx, kyy=kxx, kzz=kxx) elif self.grid().dim == 2: if self.grid().frac_num == self.special_fracture: kxx = self.kf_high * np.ones(self.grid().num_cells) else: kxx = self.kf_low * np.ones(self.grid().num_cells) return tensor.SecondOrder(self.grid().dim, kxx=kxx, kyy=kxx, kzz=1) else: # g.dim == 1 neigh = self.gb.node_neighbors(self.grid(), only_higher=True) frac_num = np.array([gh.frac_num for gh in neigh]) if np.any(frac_num == self.special_fracture): if np.any(frac_num == 1): kxx = self.kf_high * np.ones(self.grid().num_cells) else: kxx = self.kf_low * np.ones(self.grid().num_cells) else: kxx = self.kf_low * np.ones(self.grid().num_cells) return tensor.SecondOrder(self.grid().dim, kxx=kxx, kyy=1, kzz=1)
def add_data(gb, domain, kf): """ Define the permeability, apertures, boundary conditions """ gb.add_node_props(['param']) tol = 1e-5 a = 1e-4 for g, d in gb: param = Parameters(g) # Permeability kxx = np.ones(g.num_cells) * np.power(kf, g.dim < gb.dim_max()) if g.dim == 2: perm = tensor.SecondOrder(3, kxx=kxx, kyy=kxx, kzz=1) else: perm = tensor.SecondOrder(3, kxx=kxx, kyy=1, kzz=1) if g.dim == 1: R = cg.project_line_matrix(g.nodes, reference=[1, 0, 0]) perm.rotate(R) param.set_tensor("flow", perm) # Source term param.set_source("flow", np.zeros(g.num_cells)) # Assign apertures aperture = np.power(a, gb.dim_max() - g.dim) param.set_aperture(np.ones(g.num_cells) * aperture) # Boundaries bound_faces = g.get_boundary_faces() if bound_faces.size != 0: bound_face_centers = g.face_centers[:, bound_faces] left = bound_face_centers[0, :] < domain['xmin'] + tol right = bound_face_centers[0, :] > domain['xmax'] - tol labels = np.array(['neu'] * bound_faces.size) labels[right] = 'dir' bc_val = np.zeros(g.num_faces) bc_val[bound_faces[left]] = -aperture \ * g.face_areas[bound_faces[left]] bc_val[bound_faces[right]] = 1 param.set_bc("flow", BoundaryCondition(g, bound_faces, labels)) param.set_bc_val("flow", bc_val) else: param.set_bc("flow", BoundaryCondition(g, np.empty(0), np.empty(0))) d['param'] = param # Assign coupling permeability gb.add_edge_prop('kn') for e, d in gb.edges_props(): gn = gb.sorted_nodes_of_edge(e) aperture = np.power(a, gb.dim_max() - gn[0].dim) d['kn'] = np.ones(gn[0].num_cells) * kf / aperture
def permeability(self): dim = self.grid().dim if dim == 3: kxx = self.km * np.ones(self.grid().num_cells) kxx[self.low_zones()] = self.km_low return tensor.SecondOrder(dim, kxx=kxx, kyy=kxx, kzz=kxx) elif dim == 2: kxx = self.kf * np.ones(self.grid().num_cells) return tensor.SecondOrder(dim, kxx=kxx, kyy=kxx, kzz=1) else: # dim == 1 kxx = self.kf * np.ones(self.grid().num_cells) return tensor.SecondOrder(dim, kxx=kxx, kyy=1, kzz=1)
def add_data(gb, domain): """ Define the permeability, apertures, boundary conditions """ gb.add_node_props(['param']) tol = 1e-3 a = 1e-2 for g, d in gb: param = Parameters(g) # Permeability if g.dim == 2: perm = tensor.SecondOrder(g.dim, 1e-14 * np.ones(g.num_cells)) else: perm = tensor.SecondOrder(g.dim, 1e-8 * np.ones(g.num_cells)) param.set_tensor("flow", perm) # Source term param.set_source("flow", np.zeros(g.num_cells)) # Assign apertures aperture = np.power(a, gb.dim_max() - g.dim) param.set_aperture(np.ones(g.num_cells) * aperture) # Boundaries bound_faces = g.get_boundary_faces() if bound_faces.size != 0: bound_face_centers = g.face_centers[:, bound_faces] left = bound_face_centers[0, :] < domain['xmin'] + tol right = bound_face_centers[0, :] > domain['xmax'] - tol labels = np.array(['neu'] * bound_faces.size) labels[np.logical_or(left, right)] = 'dir' bc_val = np.zeros(g.num_faces) bc_val[bound_faces[left]] = 1013250 param.set_bc("flow", BoundaryCondition(g, bound_faces, labels)) param.set_bc_val("flow", bc_val) else: param.set_bc("flow", BoundaryCondition(g, np.empty(0), np.empty(0))) d['param'] = param # Assign coupling permeability gb.add_edge_prop('kn') for e, d in gb.edges_props(): gn = gb.sorted_nodes_of_edge(e) d['kn'] = 1e-8 * np.ones(gn[0].num_cells)
def update_perm(gb, k_hor, k_ver, k_intersection): """ Reassign permeabilities in the fractures. """ for g, d in gb: if g.dim > 1: continue if np.isclose(g.cell_centers[0, 0], .5): perm = tensor.SecondOrder(3, k_ver * np.ones(g.num_cells)) if np.isclose(g.cell_centers[1, 0], .5) and g.dim == 1: perm = tensor.SecondOrder(3, k_hor * np.ones(g.num_cells)) if g.dim == 0: perm = tensor.SecondOrder(3, k_intersection * np.ones(g.num_cells)) d['param'].set_tensor('flow', perm)
def test_mpfa_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 = mpfa.Mpfa(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 permeability(self): if self.grid().dim == 3: kxx = np.ones(self.grid().num_cells) \ * np.power(1e4, 3 > self.grid().dim) return tensor.SecondOrder(3, kxx) else: return anisotropy(self.grid(), d, y)
def anisotropy(g, deg, yfactor): """ Set anisotropic permeability in the 2d matrix. """ # Get rotational tensor R k = 1e3 perm_x = k perm_y = k / yfactor perm_z = k rad = deg * np.pi / 180 v = np.array([0, 0, 1]) R = cg.rot(rad, v) # Set up orthogonal permeability tensor and rotate it k_orth = np.array([[perm_x, 0, 0], [0, perm_y, 0], [0, 0, perm_z]]) k = np.dot(np.dot(R, k_orth), R.T) kf = np.ones(g.num_cells) kxx = kf * k[0, 0] kyy = kf * k[1, 1] kxy = kf * k[0, 1] kxz = kf * k[0, 2] kyz = kf * k[1, 2] kzz = kf * k[2, 2] perm = tensor.SecondOrder(3, kxx=kxx, kyy=kyy, kzz=kzz, kxy=kxy, kxz=kxz, kyz=kyz) return perm
def tpfa_matrix(g, perm=None): """ Compute a two-point flux approximation matrix useful related to a call of create_partition. Parameters ---------- g: the grid perm: (optional) permeability, the it is not given unitary tensor is assumed Returns ------- out: sparse matrix Two-point flux approximation matrix """ if isinstance(g, grid_bucket.GridBucket): g = g.get_grids(lambda g_: g_.dim == g.dim_max())[0] if perm is None: perm = tensor.SecondOrder(g.dim, np.ones(g.num_cells)) solver = tpfa.Tpfa() param = Parameters(g) param.set_tensor(solver, perm) param.set_bc(solver, BoundaryCondition(g, np.empty(0), '')) return solver.matrix_rhs(g, {'param': param})[0]
def darcy_dual_hybridVEM_example0(**kwargs): ####################### # Simple 2d Darcy problem with known exact solution ####################### Nx = Ny = 25 g = structured.CartGrid([Nx, Ny], [1, 1]) g.compute_geometry() kxx = np.ones(g.num_cells) perm = tensor.SecondOrder(g.dim, kxx) f = np.ones(g.num_cells) b_faces = g.get_boundary_faces() bnd = bc.BoundaryCondition(g, b_faces, ['dir'] * b_faces.size) bnd_val = np.zeros(g.num_faces) solver = hybrid.HybridDualVEM() data = {'perm': perm, 'source': f, 'bc': bnd, 'bc_val': bnd_val} H, rhs = solver.matrix_rhs(g, data) l = sps.linalg.spsolve(H, rhs) u, p = solver.compute_up(g, l, data) P0u = dual.DualVEM().project_u(g, u) if kwargs['visualize']: plot_grid(g, p, P0u) norms = np.array([error.norm_L2(g, p), error.norm_L2(g, P0u)]) norms_known = np.array([0.041554943620853595, 0.18738227880674516]) assert np.allclose(norms, norms_known)
def test_no_dynamics_2d(self): g_list = setup_grids.setup_2d() for g in g_list: discr = biot.Biot() bound_faces = g.get_boundary_faces() bound = bc.BoundaryCondition(g, bound_faces.ravel('F'), ['dir'] * bound_faces.size) mu = np.ones(g.num_cells) c = tensor.FourthOrder(g.dim, mu, mu) k = tensor.SecondOrder(g.dim, np.ones(g.num_cells)) bound_val = np.zeros(g.num_faces) param = Parameters(g) param.set_bc('flow', bound) param.set_bc('mechanics', bound) param.set_tensor('flow', k) param.set_tensor('mechanics', c) param.set_bc_val('mechanics', np.tile(bound_val, g.dim)) param.set_bc_val('flow', bound_val) param.porosity = np.ones(g.num_cells) param.biot_alpha = 1 data = {'param': param, 'inverter': 'python', 'dt': 1} A, b = discr.matrix_rhs(g, data) sol = np.linalg.solve(A.todense(), b) assert np.isclose(sol, np.zeros(g.num_cells * (g.dim + 1))).all()
def add_data(g): """ Define the permeability, apertures, boundary conditions """ param = Parameters(g) # Permeability param.set_tensor("flow", tensor.SecondOrder(g.dim, np.ones(g.num_cells))) # Source term source = np.array([rhs(*pt) for pt in g.cell_centers.T]) param.set_source("flow", g.cell_volumes * source) # Boundaries bound_faces = g.get_boundary_faces() bound_face_centers = g.face_centers[:, bound_faces] labels = np.array(['dir'] * bound_faces.size) bc_val = np.zeros(g.num_faces) bc_val[bound_faces] = np.array( [solution(*pt) for pt in bound_face_centers.T]) param.set_bc("flow", BoundaryCondition(g, bound_faces, labels)) param.set_bc_val("flow", bc_val) return {'param': param}
def test_mpfa_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 = mpfa.Mpfa(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 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': 1 * 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(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.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_1d_elimination_3d_2d_1d(self): """ 3d case with a single 1d 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]]) gb = meshing.cart_grid([f1, f2], [2, 2, 2], **{'physdims': [1, 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) 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) p = sps.linalg.spsolve(A, rhs) p_cond, _, _, _ = condensation.solve_static_condensation(\ A, rhs, gb, dim=1) solver_coupler.split(gb, "pressure", p) solver_coupler.split(gb, "p_cond", p_cond) tol = 1e-5 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 anisotropy(gb, deg, yfactor): """ Set anisotropic permeability in the 2d matrix. """ for g, d in gb: if g.dim == 2: # Get rotational tensor R perm_x = 1 perm_y = 1 / yfactor perm_z = 1 rad = deg * np.pi / 180 v = np.array([0, 0, 1]) R = cg.rot(rad, v) # Set up orthogonal tensor and rotate it k_orth = np.array([[perm_x, 0, 0], [0, perm_y, 0], [0, 0, perm_z]]) k = np.dot(np.dot(R, k_orth), R.T) kf = np.ones(g.num_cells) kxx = kf * k[0, 0] kyy = kf * k[1, 1] kxy = kf * k[0, 1] kxz = kf * k[0, 2] kyz = kf * k[1, 2] kzz = kf * k[2, 2] perm = tensor.SecondOrder(3, kxx=kxx, kyy=kyy, kzz=kzz, kxy=kxy, kxz=kxz, kyz=kyz) d['param'].set_tensor('flow', perm) d['hybrid_correction'] = True
def setup_cart_2d(nx): 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] gb = meshing.cart_grid(fracs, nx, physdims=[1, 1]) 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 add_data(gb, domain, direction, tol): """ Define the permeability, apertures, boundary conditions """ gb.add_node_props(["param", "Aavatsmark_transmissibilities"]) for g, d in gb: param = Parameters(g) d["Aavatsmark_transmissibilities"] = True if g.dim == 2: # Permeability kxx = np.ones(g.num_cells) param.set_tensor("flow", tensor.SecondOrder(3, kxx)) # Source term param.set_source("flow", np.zeros(g.num_cells)) # Boundaries bound_faces = g.get_boundary_faces() if bound_faces.size != 0: bound_face_centers = g.face_centers[:, bound_faces] if direction == "left_right": left = bound_face_centers[0, :] < domain["xmin"] + tol right = bound_face_centers[0, :] > domain["xmax"] - tol bc_dir = np.logical_or(left, right) bc_one = right elif direction == "bottom_top": bottom = bound_face_centers[2, :] < domain["zmin"] + tol top = bound_face_centers[2, :] > domain["zmax"] - tol bc_dir = np.logical_or(top, bottom) bc_one = top elif direction == "back_front": back = bound_face_centers[1, :] < domain["ymin"] + tol front = bound_face_centers[1, :] > domain["ymax"] - tol bc_dir = np.logical_or(back, front) bc_one = front labels = np.array(["neu"] * bound_faces.size) labels[bc_dir] = "dir" bc_val = np.zeros(g.num_faces) bc_val[bound_faces[bc_one]] = 1 param.set_bc("flow", BoundaryCondition(g, bound_faces, labels)) param.set_bc_val("flow", bc_val) else: param.set_bc("flow", BoundaryCondition(g, np.empty(0), np.empty(0))) d["param"] = param gb.add_edge_props(["param", "Aavatsmark_transmissibilities"]) for e, d in gb.edges_props(): g_h = gb.sorted_nodes_of_edge(e)[1] d["param"] = Parameters(g_h) d["Aavatsmark_transmissibilities"] = True
def add_data(gb, domain, kf, mesh_value): """ Define the permeability, apertures, boundary conditions and sources """ gb.add_node_props(['param']) tol = 1e-5 a = 1e-4 for g, d in gb: param = Parameters(g) # Assign apertures a_dim = np.power(a, gb.dim_max() - g.dim) aperture = np.ones(g.num_cells) * a_dim param.set_aperture(aperture) # Permeability # Use fracture value in the fractures, i.e., the lower dimensional grids k_frac = np.power(kf, g.dim < gb.dim_max()) p = tensor.SecondOrder(3, np.ones(g.num_cells) * k_frac) param.set_tensor('flow', p) param.set_tensor('flow', p) # Source term param.set_source('flow', np.zeros(g.num_cells)) # Boundaries bound_faces = g.get_boundary_faces() if bound_faces.size == 0: continue bound_face_centers = g.face_centers[:, bound_faces] left = bound_face_centers[0, :] < domain['xmin'] + tol right = bound_face_centers[0, :] > domain['xmax'] - tol labels = np.array(['neu'] * bound_faces.size) labels[right] = 'dir' bc_val = np.zeros(g.num_faces) if g.dim == 2: # Account for the double inflow on the matrix-fracture overlap left_mid = np.array( np.absolute(g.face_centers[1, bound_faces[left]] - 0.5) < mesh_value) bc_val[bound_faces[left]] = -g.face_areas[bound_faces[left]] \ + left_mid * .5 * a else: bc_val[bound_faces[left]] = -g.face_areas[bound_faces[left]] * a bc_val[bound_faces[right]] = np.ones(np.sum(right)) param.set_bc('flow', bc.BoundaryCondition(g, bound_faces, labels)) param.set_bc_val('flow', bc_val) d['param'] = param
def setup_cart_2d(nx): g = structured.CartGrid(nx) g.compute_geometry() kxx = np.ones(g.num_cells) perm = tensor.SecondOrder(g.dim, kxx) return g, perm
def test_tpfa_cart_2d(): """ Apply TPFA on Cartesian grid, should obtain Laplacian stencil. """ # Set up 3 X 3 Cartesian grid nx = np.array([3, 3]) g = structured.CartGrid(nx) g.compute_geometry() kxx = np.ones(g.num_cells) perm = tensor.SecondOrder(g.dim, kxx) bound_faces = np.array([0, 3, 12]) bound = bc.BoundaryCondition(g, bound_faces, ['dir'] * bound_faces.size) discr = tpfa.Tpfa() d = _assign_params(g, perm, bound) discr.discretize(g, d) trm, bound_flux = d['flux'], d['bound_flux'] div = g.cell_faces.T a = div * trm b = -(div * bound_flux).A # 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 assert np.all(b[mid, :] == 0) # The first cell should have two Dirichlet bnds assert a[0, 0] == 6 assert a[0, 1] == -1 assert a[0, 3] == -1 assert b[0, 0] == 2 assert b[0, 12] == 2 # Cell 3 has one Dirichlet, one Neumann face print(a) assert a[2, 2] == 4 assert a[2, 1] == -1 assert a[2, 5] == -1 assert b[2, 3] == 2 assert b[2, 14] == -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 assert b[1, 13] == -1 return a
def permeability(self): if np.isclose(self.grid().cell_centers[0, 0], .5): k = 1e-6 elif self.grid().dim == 2: k = 1e6 else: k = 1 return tensor.SecondOrder(3, k * np.ones(self.grid().num_cells))
def permeability(self): if self.grid().dim == 2: k = 1 elif np.in1d(self.data['node_number'], [4, 5]): k = 1e-4 elif np.in1d(self.data['node_number'], [11, 13, 14, 15]): k = 2 / np.sum(1.0 / np.array([1e4, 1e-4])) else: k = 1e4 return tensor.SecondOrder(3, np.ones(self.grid().num_cells) * k)
def darcy_dual_hybridVEM_example3(**kwargs): ####################### # Simple 3d Darcy problem with known exact solution ####################### Nx = Ny = Nz = 7 g = structured.CartGrid([Nx, Ny, Nz], [1, 1, 1]) g.compute_geometry() kxx = np.ones(g.num_cells) perm = tensor.SecondOrder(g.dim, kxx) def funP_ex(pt): return np.sin(2*np.pi*pt[0])*np.sin(2*np.pi*pt[1])\ * np.sin(2*np.pi*pt[2]) def funU_ex(pt): return [-2*np.pi*np.cos(2*np.pi*pt[0])\ * np.sin(2*np.pi*pt[1])*np.sin(2*np.pi*pt[2]), -2*np.pi*np.sin(2*np.pi*pt[0])\ * np.cos(2*np.pi*pt[1])*np.sin(2*np.pi*pt[2]), -2*np.pi*np.sin(2*np.pi*pt[0])\ * np.sin(2*np.pi*pt[1])*np.cos(2*np.pi*pt[2])] def fun(pt): return 12 * np.pi**2 * funP_ex(pt) f = np.array([fun(pt) for pt in g.cell_centers.T]) b_faces = g.get_boundary_faces() bnd = bc.BoundaryCondition(g, b_faces, ['dir'] * b_faces.size) bnd_val = np.zeros(g.num_faces) bnd_val[b_faces] = funP_ex(g.face_centers[:, b_faces]) solver = hybrid.HybridDualVEM() data = {'perm': perm, 'source': f, 'bc': bnd, 'bc_val': bnd_val} H, rhs = solver.matrix_rhs(g, data) l = sps.linalg.spsolve(H, rhs) u, p = solver.compute_up(g, l, data) P0u = dual.DualVEM().project_u(g, u) if kwargs['visualize']: plot_grid(g, p, P0u) p_ex = error.interpolate(g, funP_ex) u_ex = error.interpolate(g, funU_ex) np.set_printoptions(linewidth=999999) np.set_printoptions(precision=16) errors = np.array( [error.error_L2(g, p, p_ex), error.error_L2(g, P0u, u_ex)]) errors_known = np.array([0.1010936831876412, 0.0680593765009036]) assert np.allclose(errors, errors_known)
def project_u(self, g, u, data): """ Project the velocity computed with a dual vem solver to obtain a piecewise constant vector field, one triplet for each cell. Parameters ---------- g : grid, or a subclass, with geometry fields computed. u : array (g.num_faces) Velocity at each face. Return ------ P0u : ndarray (3, g.num_faces) Velocity at each cell. """ # Allow short variable names in backend function # pylint: disable=invalid-name if g.dim == 0: return np.zeros(3).reshape((3, 1)) # The velocity field already has permeability effects incorporated, # thus we assign a unit permeability to be passed to self.massHdiv k = tensor.SecondOrder(g.dim, kxx=np.ones(g.num_cells)) param = data['param'] a = param.get_aperture() faces, cells, sign = sps.find(g.cell_faces) index = np.argsort(cells) faces, sign = faces[index], sign[index] c_centers, f_normals, f_centers, R, dim, _ = cg.map_grid(g) # In the virtual cell approach the cell diameters should involve the # apertures, however to keep consistency with the hybrid-dimensional # approach and with the related hypotheses we avoid. diams = g.cell_diameters() P0u = np.zeros((3, g.num_cells)) for c in np.arange(g.num_cells): loc = slice(g.cell_faces.indptr[c], g.cell_faces.indptr[c + 1]) faces_loc = faces[loc] Pi_s = self.massHdiv(a[c] * k.perm[0:g.dim, 0:g.dim, c], c_centers[:, c], g.cell_volumes[c], f_centers[:, faces_loc], f_normals[:, faces_loc], sign[loc], diams[c])[1] # extract the velocity for the current cell P0u[dim, c] = np.dot(Pi_s, u[faces_loc]) / diams[c] * a[c] P0u[:, c] = np.dot(R.T, P0u[:, c]) return P0u
def perm(g): if np.isclose(g.cell_centers[2, 0], .6) or g.dim == 0: kxx = np.ones(g.num_cells) * 1e-5 elif g.dim < 3: kxx = np.ones(g.num_cells) * 1e5 else: kxx = np.ones(g.num_cells) * 1e-2 kxx[g.cell_centers[1, :] < .5] = 1e-3 return tensor.SecondOrder(3, kxx)
def test_elliptic_data_given_values(self): """ test that the elliptic data initialize the correct data. """ p = np.random.rand(3, 10) g = simplex.TetrahedralGrid(p) # Set values bc_val = np.pi * np.ones(g.num_faces) dir_faces = g.get_boundary_faces() bc_cond = bc.BoundaryCondition(g, dir_faces, ['dir'] * dir_faces.size) porosity = 1 / np.pi * np.ones(g.num_cells) apperture = 0.5 * np.ones(g.num_cells) kxx = 2 * np.ones(g.num_cells) kyy = 3 * np.ones(g.num_cells) K = tensor.SecondOrder(g.dim, kxx, kyy) source = 42 * np.ones(g.num_cells) # Assign to parameter param = Parameters(g) param.set_bc_val('flow', bc_val) param.set_bc('flow', bc_cond) param.set_porosity(porosity) param.set_aperture(apperture) param.set_tensor('flow', K) param.set_source('flow', source) # Define EllipticData class class Data(EllipticDataAssigner): def __init__(self, g, data): EllipticDataAssigner.__init__(self, g, data) def bc(self): return bc_cond def bc_val(self): return bc_val def porosity(self): return porosity def aperture(self): return apperture def permeability(self): return K def source(self): return source elliptic_data = dict() Data(g, elliptic_data) elliptic_param = elliptic_data['param'] check_parameters(elliptic_param, param)
def add_data(gb): """ Define the permeability, apertures, boundary conditions, source term """ gb.add_node_props(['param']) for g, d in gb: # initialize Parameter class params = data.Parameters(g) # Permeability kxx = np.ones(g.num_cells) if all(g.cell_centers[0, :] < 0.0001): perm = tensor.SecondOrder(3, kxx / 100, kxx, kxx) else: perm = tensor.SecondOrder(3, kxx * np.power(100, g.dim < 3)) params.set_tensor('flow', perm) # Source term params.set_source('flow', np.zeros(g.num_cells)) # Boundaries bound_faces = g.get_boundary_faces() top = np.argwhere(g.face_centers[1, :] > 1 - 1e-5) bot = np.argwhere(g.face_centers[1, :] < -1 + 1e-5) left = np.argwhere(g.face_centers[0, :] < -1 + 1e-5) dir_bound = np.concatenate((top, bot)) bound = bc.BoundaryCondition(g, dir_bound.ravel(), ['dir'] * dir_bound.size) d_bound = np.zeros(g.num_faces) d_bound[dir_bound] = g.face_centers[1, dir_bound] d_bound[left] = -1 * g.face_centers[0, left] params.set_bc('flow', bound) params.set_bc_val('flow', d_bound.ravel('F')) # Assign apertures params.apertures = np.ones(g.num_cells) * np.power(1e-2, 3 - g.dim) d['param'] = params
def add_data_darcy(gb, domain, tol): gb.add_node_props(['param', 'is_tangent']) apert = 1e-2 km = 7.5 * 1e-11 kf_t = 1e-5 * km kf_n = 1e-5 * km for g, d in gb: param = Parameters(g) rock = g.dim == gb.dim_max() kxx = km if rock else kf_t d['is_tangential'] = True perm = tensor.SecondOrder(g.dim, kxx * np.ones(g.num_cells)) param.set_tensor("flow", perm) param.set_source("flow", np.zeros(g.num_cells)) param.set_aperture(np.power(apert, gb.dim_max() - g.dim)) bound_faces = g.get_boundary_faces() if bound_faces.size != 0: bound_face_centers = g.face_centers[:, bound_faces] top = bound_face_centers[1, :] > domain['ymax'] - tol bottom = bound_face_centers[1, :] < domain['ymin'] + tol left = bound_face_centers[0, :] < domain['xmin'] + tol right = bound_face_centers[0, :] > domain['xmax'] - tol boundary = np.logical_or(left, right) labels = np.array(['neu'] * bound_faces.size) labels[boundary] = ['dir'] bc_val = np.zeros(g.num_faces) bc_val[bound_faces[left]] = 30 * 1e6 param.set_bc("flow", BoundaryCondition(g, bound_faces, labels)) param.set_bc_val("flow", bc_val) else: param.set_bc("flow", BoundaryCondition(g, np.empty(0), np.empty(0))) d['param'] = param # Assign coupling permeability gb.add_edge_prop('kn') for e, d in gb.edges_props(): g = gb.sorted_nodes_of_edge(e)[0] d['kn'] = kf_n / gb.node_prop(g, 'param').get_aperture()
def darcy_dual_hybridVEM_example2(**kwargs): ####################### # Simple 2d Darcy problem on a surface with known exact solution ####################### Nx = Ny = 25 g = simplex.StructuredTriangleGrid([Nx, Ny], [1, 1]) R = cg.rot(np.pi / 6., [0, 1, 1]) g.nodes = np.dot(R, g.nodes) g.compute_geometry(is_embedded=True) T = cg.tangent_matrix(g.nodes) kxx = np.ones(g.num_cells) perm = tensor.SecondOrder(g.dim, kxx) def funP_ex(pt): return np.pi * pt[0] - 6 * pt[1] + np.exp(1) * pt[2] - 4 def funU_ex(pt): return np.dot(T, [-np.pi, 6, -np.exp(1)]) def fun(pt): return 0 f = np.array([fun(pt) for pt in g.cell_centers.T]) b_faces = g.get_boundary_faces() bnd = bc.BoundaryCondition(g, b_faces, ['dir'] * b_faces.size) bnd_val = np.zeros(g.num_faces) bnd_val[b_faces] = funP_ex(g.face_centers[:, b_faces]) solver = hybrid.HybridDualVEM() data = {'perm': perm, 'source': f, 'bc': bnd, 'bc_val': bnd_val} H, rhs = solver.matrix_rhs(g, data) l = sps.linalg.spsolve(H, rhs) u, p = solver.compute_up(g, l, data) P0u = dual.DualVEM().project_u(g, u) if kwargs['visualize']: plot_grid(g, p, P0u) p_ex = error.interpolate(g, funP_ex) u_ex = error.interpolate(g, funU_ex) errors = np.array( [error.error_L2(g, p, p_ex), error.error_L2(g, P0u, u_ex)]) errors_known = np.array([0, 0]) assert np.allclose(errors, errors_known)