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 __init__(self, gb, folder, tol): self.model = "flow" self.gb = gb self.data = None self.assembler = None # discretization operator name self.discr_name = "flux" self.discr = pp.RT0(self.model) self.mass_name = "mass" self.mass = pp.MixedMassMatrix(self.model) self.coupling_name = self.discr_name + "_coupling" self.coupling = pp.RobinCoupling(self.model, self.discr) self.source_name = "source" self.source = pp.DualScalarSource(self.model) # master variable name self.variable = "flow_variable" self.mortar = "lambda_" + self.variable # post process variables self.pressure = "pressure" self.flux = "darcy_flux" # it has to be this one self.P0_flux = "P0_darcy_flux" # tolerance self.tol = tol # exporter self.save = pp.Exporter(self.gb, "solution", folder=folder)
def solve_vem(gb, folder, discr_3d=None): # Choose and define the solvers and coupler flow_discretization = pp.MVEM("flow") source_discretization = pp.DualScalarSource("flow") run_flow(gb, flow_discretization, source_discretization, folder, is_FV=False, discr_3d=discr_3d)
def test_convergence_rt0_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 errs_known = np.array([ 0.00128247705764, 0.000770088925769, 0.00050939369071, 0.000360006145403, 0.000267209318912, ]) for i, err_known in zip(np.arange(5), errs_known): g = pp.simplex.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)) solver = pp.RT0(keyword="flow") solver_rhs = pp.DualScalarSource(keyword="flow") specified_parameters = { "bc": bc, "bc_values": bc_val, "second_order_tensor": perm, "source": source, } 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, err_known))
def test_convergence_rt0_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, :])) errs_known = np.array([ 0.014848639601, 0.00928479234915, 0.00625096095775, 0.00446722560521, 0.00334170283883, ]) for i, err_known in zip(np.arange(5), errs_known): g = pp.simplex.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)) solver = pp.RT0(keyword="flow") solver_rhs = pp.DualScalarSource(keyword="flow") specified_parameters = { "bc": bc, "bc_values": bc_val, "second_order_tensor": perm, "source": source, } 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, err_known))
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))
def test_upwind_example_3(self, if_export=False): ####################### # Simple 2d upwind problem with explicit Euler scheme in time coupled with # a Darcy problem ####################### T = 2 Nx, Ny = 10, 10 def funp_ex(pt): return -np.sin(pt[0]) * np.sin(pt[1]) - pt[0] g = pp.CartGrid([Nx, Ny], [1, 1]) g.compute_geometry() # Permeability perm = pp.SecondOrderTensor(kxx=np.ones(g.num_cells)) # Boundaries b_faces = g.get_all_boundary_faces() bc = pp.BoundaryCondition(g, b_faces, ["dir"] * b_faces.size) bc_val = np.zeros(g.num_faces) bc_val[b_faces] = funp_ex(g.face_centers[:, b_faces]) specified_parameters = { "bc": bc, "bc_values": bc_val, "second_order_tensor": perm, } data = pp.initialize_default_data(g, {}, "flow", specified_parameters) solver = pp.MVEM("flow") solver.discretize(g, data) D_flow, b_flow = solver.assemble_matrix_rhs(g, data) solver_source = pp.DualScalarSource("flow") solver_source.discretize(g, data) D_source, b_source = solver_source.assemble_matrix_rhs(g, data) up = sps.linalg.spsolve(D_flow + D_source, b_flow + b_source) _, u = solver.extract_pressure(g, up, data), solver.extract_flux(g, up, data) # Darcy_Flux dis = u # Boundaries bc = pp.BoundaryCondition(g, b_faces, ["dir"] * b_faces.size) bc_val = np.hstack(([1], np.zeros(g.num_faces - 1))) specified_parameters = {"bc": bc, "bc_values": bc_val, "darcy_flux": dis} data = pp.initialize_default_data(g, {}, "transport", specified_parameters) # Advect solver advect = pp.Upwind("transport") advect.discretize(g, data) U, rhs = advect.assemble_matrix_rhs(g, data) time_step = advect.cfl(g, data) rhs = time_step * rhs U = time_step * U data[pp.PARAMETERS]["transport"]["time_step"] = time_step mass = pp.MassMatrix("transport") mass.discretize(g, data) M, _ = mass.assemble_matrix_rhs(g, data) conc = np.zeros(g.num_cells) M_minus_U = M - U inv_mass = pp.InvMassMatrix("transport") inv_mass.discretize(g, data) invM, _ = inv_mass.assemble_matrix_rhs(g, data) # Loop over the time Nt = int(T / time_step) time = np.empty(Nt) for i in np.arange(Nt): # Update the solution conc = invM.dot((M_minus_U).dot(conc) + rhs) time[i] = time_step * i known = np.array( [ 9.63168200e-01, 8.64054875e-01, 7.25390695e-01, 5.72228235e-01, 4.25640080e-01, 2.99387331e-01, 1.99574336e-01, 1.26276876e-01, 7.59011550e-02, 4.33431230e-02, 3.30416807e-02, 1.13058617e-01, 2.05372538e-01, 2.78382057e-01, 3.14035373e-01, 3.09920132e-01, 2.75024694e-01, 2.23163145e-01, 1.67386939e-01, 1.16897527e-01, 1.06111312e-03, 1.11951850e-02, 3.87907727e-02, 8.38516119e-02, 1.36617802e-01, 1.82773271e-01, 2.10446545e-01, 2.14651936e-01, 1.97681518e-01, 1.66549151e-01, 3.20751341e-05, 9.85780113e-04, 6.07062715e-03, 1.99393042e-02, 4.53237556e-02, 8.00799828e-02, 1.17199623e-01, 1.47761481e-01, 1.64729339e-01, 1.65390555e-01, 9.18585872e-07, 8.08267622e-05, 8.47227168e-04, 4.08879583e-03, 1.26336029e-02, 2.88705048e-02, 5.27841497e-02, 8.10459333e-02, 1.07956484e-01, 1.27665318e-01, 2.51295298e-08, 6.29844122e-06, 1.09361990e-04, 7.56743783e-04, 3.11384414e-03, 9.04446601e-03, 2.03443897e-02, 3.75208816e-02, 5.89595194e-02, 8.11457277e-02, 6.63498510e-10, 4.73075468e-07, 1.33728945e-05, 1.30243418e-04, 7.01905707e-04, 2.55272292e-03, 6.96686157e-03, 1.52290448e-02, 2.78607282e-02, 4.40402650e-02, 1.71197497e-11, 3.47118057e-08, 1.57974045e-06, 2.13489614e-05, 1.48634295e-04, 6.68104990e-04, 2.18444135e-03, 5.58646819e-03, 1.17334966e-02, 2.09744728e-02, 4.37822313e-13, 2.52373622e-09, 1.83589660e-07, 3.40553325e-06, 3.02948532e-05, 1.66504215e-04, 6.45119867e-04, 1.90731440e-03, 4.53436628e-03, 8.99977737e-03, 1.12627412e-14, 1.84486857e-10, 2.13562387e-08, 5.39492977e-07, 6.08223906e-06, 4.05535296e-05, 1.84731221e-04, 6.25871542e-04, 1.66459389e-03, 3.59980231e-03, ] ) assert np.allclose(conc, known)