def tpfa_matrix(g, perm=None, faces=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 faces (np.array, int): Index of faces where TPFA should be applied. Defaults all faces in the grid. Returns ------- out: sparse matrix Two-point flux approximation matrix """ if perm is None: perm = second_order_tensor.SecondOrderTensor(g.dim, np.ones(g.num_cells)) bound = bc.BoundaryCondition(g, np.empty(0), '') trm, _ = tpfa.tpfa(g, perm, bound, faces) div = g.cell_faces.T return div * trm
def upwind_example2(**kwargs): ####################### # Simple 2d upwind problem with explicit Euler scheme in time coupled with # a Darcy problem ####################### T = 2 Nx, Ny = 10, 10 g = structured.CartGrid([Nx, Ny], [1, 1]) g.compute_geometry() kxx = np.ones(g.num_cells) perm = second_order_tensor.SecondOrderTensor(g.dim, kxx) def funp_ex(pt): return -np.sin(pt[0]) * np.sin(pt[1]) - pt[0] f = np.zeros(g.num_cells) b_faces = g.get_boundary_faces() bnd = bc.BoundaryCondition(g, b_faces, ['dir'] * b_faces.size) bnd_val = {'dir': funp_ex(g.face_centers[:, b_faces])} solver = dual.DualVEM() data = {'k': perm, 'f': f, 'bc': bnd, 'bc_val': bnd_val} D, rhs = solver.matrix_rhs(g, data) up = sps.linalg.spsolve(D, rhs) beta_n = solver.extractU(g, up) u, p = solver.extractU(g, up), solver.extractP(g, up) P0u = solver.projectU(g, u, data) export_vtk(g, "darcy", {"p": p, "P0u": P0u}) advect = upwind.Upwind() bnd_val = {'dir': np.hstack(([1], np.zeros(b_faces.size - 1)))} data = {'beta_n': beta_n, 'bc': bnd, 'bc_val': bnd_val} U, rhs = advect.matrix_rhs(g, data) data = {'deltaT': advect.cfl(g, data)} M, _ = mass_matrix.Mass().matrix_rhs(g, data) conc = np.zeros(g.num_cells) M_minus_U = M - U invM, _ = mass_matrix.InvMass().matrix_rhs(g, data) # Loop over the time Nt = int(T / data['deltaT']) time = np.empty(Nt) for i in np.arange(Nt): # Update the solution conc = invM.dot((M_minus_U).dot(conc) + rhs) time[i] = data['deltaT'] * i export_vtk(g, "conc_darcy", {"conc": conc}, time_step=i) export_pvd(g, "conc_darcy", time)
def test_uniform_flow_cart_2d(): nx = np.array([13, 13]) g = structured.CartGrid(nx) g.compute_geometry() kxx = np.ones(g.num_cells) perm = second_order_tensor.SecondOrderTensor(g.dim, kxx) bound_faces = np.argwhere(np.abs(g.cell_faces).sum(axis=1).A.ravel(1) == 1) bound = bc.BoundaryCondition(g, bound_faces, ['dir'] * bound_faces.size) flux = tpfa.tpfa(g, perm, bound)
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 = second_order_tensor.SecondOrderTensor(g.dim, kxx) bound_faces = np.array([0, 3, 12]) bound = bc.BoundaryCondition(g, bound_faces, ['dir'] * bound_faces.size) trm, bound_flux = tpfa.tpfa(g, perm, bound) div = g.cell_faces.T a = div * trm b = (div * bound_flux).A print(b) # 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 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 coarsening_example3(**kwargs): ####################### # Simple 2d coarsening based on tpfa for simplex grids # anisotropic permeability ####################### Nx = Ny = 7 g = simplex.StructuredTriangleGrid([Nx, Ny], [1, 1]) g.compute_geometry() if kwargs['visualize']: plot_grid(g, info="all", alpha=0) kxx = 3 * np.ones(g.num_cells) kyy = np.ones(g.num_cells) perm = second_order_tensor.SecondOrderTensor(g.dim, kxx=kxx, kyy=kyy) part = create_partition(tpfa_matrix(g, perm=perm)) g = generate_coarse_grid(g, part) g.compute_geometry(is_starshaped=True) if kwargs['visualize']: plot_grid(g, info="all", alpha=0) g = simplex.StructuredTriangleGrid([Nx, Ny], [1, 1]) g.compute_geometry() part = create_partition(tpfa_matrix(g, perm=perm), cdepth=3) g = generate_coarse_grid(g, part) g.compute_geometry(is_starshaped=True) if kwargs['visualize']: plot_grid(g, info="all", alpha=0) g = simplex.StructuredTriangleGrid([Nx, Ny], [1, 1]) g.compute_geometry() part = create_partition(tpfa_matrix(g, perm=perm), cdepth=2, epsilon=1e-2) g = generate_coarse_grid(g, part) g.compute_geometry(is_starshaped=True) if kwargs['visualize']: plot_grid(g, info="all", alpha=0) g = simplex.StructuredTriangleGrid([Nx, Ny], [1, 1]) g.compute_geometry() part = create_partition(tpfa_matrix(g, perm=perm), cdepth=2, epsilon=1) g = generate_coarse_grid(g, part) g.compute_geometry(is_starshaped=True) if kwargs['visualize']: plot_grid(g, info="all", alpha=0)
def mpfa_discr(self, g, bound): k = second_order_tensor.SecondOrderTensor(g.dim, np.ones(g.num_cells)) flux, bound_flux = mpfa.mpfa(g, k, bound, inverter='python') div_flow = fvutils.scalar_divergence(g) return flux, bound_flux, div_flow