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.SecondOrderTensor(3, kxx=kxx, kyy=kxx, kzz=1) else: perm = tensor.SecondOrderTensor(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.tags['domain_boundary_faces'].nonzero()[0] 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 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 bc(self): b_faces = self.grid().get_domain_boundary_faces() labels = np.array(["neu"] * b_faces.size) if self.grid().dim == 3: if b_faces.size == 0: return BoundaryCondition(self.grid(), np.empty(0), np.empty(0)) labels[self.b_pressure] = "dir" return BoundaryCondition(self.grid(), b_faces, labels)
def add_data_advection(gb, domain, tol): # Porosity phi_m = 1e-1 phi_f = 9 * 1e-1 # Density rho_w = 1e3 # kg m^{-3} rho_s = 2 * 1e3 # kg m^{-3} # heat capacity c_w = 4 * 1e3 # J kg^{-1} K^{-1} c_s = 8 * 1e2 # J kg^{-1} K^{-1} c_m = phi_m * rho_w * c_w + (1 - phi_m) * rho_s * c_s c_f = phi_f * rho_w * c_w + (1 - phi_f) * rho_s * c_s for g, d in gb: param = d["param"] rock = g.dim == gb.dim_max() source = np.zeros(g.num_cells) param.set_source("transport", source) param.set_porosity(1) param.set_discharge(d["discharge"]) bound_faces = g.tags["domain_boundary_faces"].nonzero()[0] 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]] = 1 param.set_bc("transport", BoundaryCondition(g, bound_faces, labels)) param.set_bc_val("transport", bc_val) else: param.set_bc("transport", BoundaryCondition(g, np.empty(0), np.empty(0))) d["param"] = param # Assign coupling discharge gb.add_edge_prop("param") for e, d in gb.edges_props(): g = gb.sorted_nodes_of_edge(e)[1] discharge = gb.node_prop(g, "param").get_discharge() d["param"] = Parameters(g) d["param"].set_discharge(discharge)
def add_data(gb, domain): """ Define the permeability, apertures, boundary conditions """ gb.add_node_props(['param', 'is_tangent']) tol = 1e-3 a = 1e-2 for g, d in gb: param = Parameters(g) # Permeability d['is_tangential'] = True if g.dim == 2: kxx = 1e-14 * np.ones(g.num_cells) else: kxx = 1e-8 * np.ones(g.num_cells) perm = tensor.SecondOrderTensor(g.dim, kxx) 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.tags['domain_boundary_faces'].nonzero()[0] 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) aperture = np.power(a, gb.dim_max() - gn[0].dim) d['kn'] = 1e-10 * np.ones(gn[0].num_cells) / aperture
def add_data_darcy(gb, domain, tol): gb.add_node_props(["param"]) kf = 1e-4 for g, d in gb: param = Parameters(g) kxx = np.ones(g.num_cells) * np.power(kf, g.dim < gb.dim_max()) perm = tensor.SecondOrderTensor(g.dim, kxx) param.set_tensor("flow", perm) param.set_source("flow", np.zeros(g.num_cells)) aperture = np.power(1e-2, gb.dim_max() - g.dim) param.set_aperture(np.ones(g.num_cells) * aperture) bound_faces = np.argwhere(g.tags["domain_boundary_faces"]).ravel("F") 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( np.logical_or(np.logical_or(top, bottom), left), right) labels = np.array(["neu"] * bound_faces.size) labels[boundary] = ["dir"] bc_val = np.zeros(g.num_faces) bc_dir = bound_faces[boundary] bc_val[bc_dir] = np.sum(g.face_centers[:, bc_dir], axis=0) * aperture 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_props("kn") for e, d in gb.edges(): g_l = gb.nodes_of_edge(e)[0] aperture = np.power(1e-2, gb.dim_max() - g_l.dim) * np.ones(g_l.num_cells) mg = d["mortar_grid"] check_P = mg.low_to_mortar_avg() gamma = check_P * aperture d["kn"] = kf * np.ones(mg.num_cells) / gamma
def add_data_darcy(gb, domain, tol): gb.add_node_props(['param', 'if_tangent']) apert = 1e-2 km = 7.5 * 1e-10 # 2.5*1e-11 kf = 5 * 1e-5 for g, d in gb: param = Parameters(g) d['if_tangent'] = True if g.dim == gb.dim_max(): kxx = km else: kxx = kf perm = tensor.SecondOrderTensor(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.tags['domain_boundary_faces'].nonzero()[0] if bound_faces.size != 0: bound_face_centers = g.face_centers[:, bound_faces] top = bound_face_centers[2, :] > domain['zmax'] - tol bottom = bound_face_centers[2, :] < domain['zmin'] + tol boundary = np.logical_or(top, bottom) labels = np.array(['neu'] * bound_faces.size) labels[boundary] = ['dir'] bc_val = np.zeros(g.num_faces) p = np.abs(domain['zmax'] - domain['zmin']) * 1e3 * 9.81 bc_val[bound_faces[bottom]] = p 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 / gb.node_prop(g, 'param').get_aperture()
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.SecondOrderTensor(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.tags["domain_boundary_faces"].nonzero()[0] 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 add_data(gb, 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(g.dim, kxx)) # Source term param.set_source("flow", np.zeros(g.num_cells)) # Boundaries bound_faces = g.get_domain_boundary_faces() if bound_faces.size != 0: bound_face_centers = g.face_centers[:, bound_faces] bottom = bound_face_centers[2, :] < -0.5 + tol top = bound_face_centers[2, :] > 0.5 - tol front = bound_face_centers[1, :] < 0 + tol labels = np.array(['neu'] * bound_faces.size) labels[np.logical_or(bottom, top)] = 'dir' labels[front] = 'dir' bc_val = np.zeros(g.num_faces) bc_val[bound_faces[front]] = 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 discharge 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_darcy(gb, domain, tol): gb.add_node_props(['param']) kf = 1e-4 for g, d in gb: param = Parameters(g) kxx = np.ones(g.num_cells) * np.power(kf, g.dim < gb.dim_max()) perm = tensor.SecondOrder(g.dim, kxx) param.set_tensor("flow", perm) param.set_source("flow", np.zeros(g.num_cells)) aperture = np.power(1e-2, gb.dim_max() - g.dim) param.set_aperture(np.ones(g.num_cells) * aperture) 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(np.logical_or(np.logical_or(top, bottom), left), right) labels = np.array(['neu'] * bound_faces.size) labels[boundary] = ['dir'] bc_val = np.zeros(g.num_faces) bc_dir = bound_faces[boundary] bc_val[bc_dir] = np.sum( g.face_centers[:, bc_dir], axis=0) * aperture 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(1e-2, gb.dim_max() - gn[0].dim) d['kn'] = np.ones(gn[0].num_cells) / aperture * kf
def test_upwind_2d_simplex_discharge_negative(self): g = simplex.StructuredTriangleGrid([2, 1], [1, 1]) g.compute_geometry() solver = upwind.Upwind() param = Parameters(g) dis = solver.discharge(g, [-1, 0, 0]) bf = g.get_boundary_faces() bc = BoundaryCondition(g, bf, bf.size * ['neu']) param.set_bc(solver, bc) data = {'param': param, 'discharge': dis} M = solver.matrix_rhs(g, data)[0].todense() deltaT = solver.cfl(g, data) M_known = np.array([[ 1, 0, 0,-1], [-1, 0, 0, 0], [ 0, 0, 1, 0], [ 0, 0,-1, 1]]) deltaT_known = 1/6 rtol = 1e-15 atol = rtol assert np.allclose(M, M_known, rtol, atol) assert np.allclose(deltaT, deltaT_known, rtol, atol)
def bc(self): bound_faces = self.grid().get_domain_boundary_faces() if bound_faces.size == 0: return BoundaryCondition(self.grid(), np.empty(0), np.empty(0)) bound_face_centers = self.grid().face_centers[:, bound_faces] top = bound_face_centers[2, :] > self.domain['zmax'] - self.tol bottom = bound_face_centers[2, :] < self.domain['zmin'] + self.tol boundary = np.logical_or(top, bottom) labels = np.array(['neu'] * bound_faces.size) labels[boundary] = ['dir'] return BoundaryCondition(self.grid(), bound_faces, labels)
def test_upwind_coupling_3d_2d_left_right(self): f = np.array([[ 0, 1, 1, 0], [ 0, 0, 1, 1], [.5, .5, .5, .5]]) gb = meshing.cart_grid( [f], [1, 1, 2], **{'physdims': [1, 1, 1]}) gb.compute_geometry() gb.assign_node_ordering() tol = 1e-3 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, [1, 0, 0], aperture) bound_faces = g.get_boundary_faces() bound_face_centers = g.face_centers[:, bound_faces] left = bound_face_centers[0, :] < tol right = bound_face_centers[0, :] > 1 - 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] = 1 param.set_bc('transport', BoundaryCondition(g, bound_faces, labels)) param.set_bc_val('transport', bc_val) 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 U, rhs = solver.matrix_rhs(gb) deltaT = solver.cfl(gb) U_known = np.array([[.5, 0, 0], [0, .5, 0], [0, 0, 1e-2]]) rhs_known = np.array([.5, .5, 1e-2]) deltaT_known = 5*1e-1 rtol = 1e-15 atol = rtol assert np.allclose(U.todense(), U_known, rtol, atol) assert np.allclose(rhs, rhs_known, rtol, atol) assert np.allclose(deltaT, deltaT_known, rtol, atol)
def test_upwind_1d_discharge_negative_bc_dir(self): g = structured.CartGrid(3, 1) g.compute_geometry() solver = upwind.Upwind() param = Parameters(g) dis = solver.discharge(g, [-2, 0, 0]) bf = g.tags["domain_boundary_faces"].nonzero()[0] bc = BoundaryCondition(g, bf, bf.size * ["dir"]) bc_val = 3 * np.ones(g.num_faces).ravel("F") param.set_bc(solver, bc) param.set_bc_val(solver, bc_val) data = {"param": param, "discharge": dis} M, rhs = solver.matrix_rhs(g, data) deltaT = solver.cfl(g, data) M_known = np.array([[2, -2, 0], [0, 2, -2], [0, 0, 2]]) rhs_known = np.array([0, 0, 6]) deltaT_known = 1 / 12 rtol = 1e-15 atol = rtol self.assertTrue(np.allclose(M.todense(), M_known, rtol, atol)) self.assertTrue(np.allclose(rhs, rhs_known, rtol, atol)) self.assertTrue(np.allclose(deltaT, deltaT_known, rtol, atol))
def test_upwind_2d_simplex_surf_discharge_positive(self): g = simplex.StructuredTriangleGrid([2, 1], [1, 1]) R = cg.rot(np.pi / 2., [1, 1, 0]) g.nodes = np.dot(R, g.nodes) g.compute_geometry() solver = upwind.Upwind() param = Parameters(g) dis = solver.discharge(g, np.dot(R, [1, 0, 0])) bf = g.tags["domain_boundary_faces"].nonzero()[0] bc = BoundaryCondition(g, bf, bf.size * ["neu"]) param.set_bc(solver, bc) data = {"param": param, "discharge": dis} M = solver.matrix_rhs(g, data)[0].todense() deltaT = solver.cfl(g, data) M_known = np.array([[1, -1, 0, 0], [0, 1, 0, 0], [0, 0, 0, -1], [-1, 0, 0, 1]]) deltaT_known = 1 / 6 rtol = 1e-15 atol = rtol self.assertTrue(np.allclose(M, M_known, rtol, atol)) self.assertTrue(np.allclose(deltaT, deltaT_known, rtol, atol))
def set_params(self, gb): for g, d in gb: param = Parameters(g) perm = tensor.SecondOrderTensor(g.dim, kxx=np.ones(g.num_cells)) param.set_tensor("flow", perm) aperture = np.power(1e-3, gb.dim_max() - g.dim) param.set_aperture(aperture * np.ones(g.num_cells)) if g.dim == 2: bound_faces = np.array([0, 10]) labels = np.array(["dir"] * bound_faces.size) param.set_bc("flow", BoundaryCondition(g, bound_faces, labels)) bv = np.zeros(g.num_faces) bound_faces = 10 bv[bound_faces] = 1 param.set_bc_val("flow", bv) d["param"] = param gb.add_edge_props("kn") kn = 1e7 for e, d in gb.edges(): mg = d["mortar_grid"] d["kn"] = kn * np.ones(mg.num_cells)
def add_data(g): """ Define the permeability, apertures, boundary conditions """ param = Parameters(g) # Permeability kxx = np.array([permeability(*pt) for pt in g.cell_centers.T]) param.set_tensor("flow", tensor.SecondOrderTensor(3, kxx)) # 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.tags['domain_boundary_faces'].nonzero()[0] 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_upwind_2d_cart_surf_discharge_negative(self): g = structured.CartGrid([3, 2], [1, 1]) R = cg.rot(np.pi/6., [1,1,0]) g.nodes = np.dot(R, g.nodes) g.compute_geometry(is_embedded=True) solver = upwind.Upwind() param = Parameters(g) dis = solver.discharge(g, np.dot(R, [-1, 0, 0])) bf = g.get_boundary_faces() bc = BoundaryCondition(g, bf, bf.size * ['neu']) param.set_bc(solver, bc) data = {'param': param, 'discharge': dis} M = solver.matrix_rhs(g, data)[0].todense() deltaT = solver.cfl(g, data) M_known = 0.5 * np.array([[ 0,-1, 0, 0, 0, 0], [ 0, 1,-1, 0, 0, 0], [ 0, 0, 1, 0, 0, 0], [ 0, 0, 0, 0,-1, 0], [ 0, 0, 0, 0, 1,-1], [ 0, 0, 0, 0, 0, 1]]) deltaT_known = 1/6 rtol = 1e-15 atol = rtol assert np.allclose(M, M_known, rtol, atol) assert np.allclose(deltaT, deltaT_known, rtol, atol)
def set_params(self, gb): for g, d in gb: param = Parameters(g) perm = tensor.SecondOrderTensor(g.dim, kxx=np.ones(g.num_cells)) param.set_tensor("flow", perm) aperture = np.power(1e-6, gb.dim_max() - g.dim) param.set_aperture(aperture * np.ones(g.num_cells)) yf = g.face_centers[1] bound_faces = [ np.where(np.abs(yf - 1) < 1e-4)[0], np.where(np.abs(yf) < 1e-4)[0], ] bound_faces = np.hstack((bound_faces[0], bound_faces[1])) labels = np.array(["dir"] * bound_faces.size) param.set_bc("flow", BoundaryCondition(g, bound_faces, labels)) bv = np.zeros(g.num_faces) bound_faces = np.where(np.abs(yf - 1) < 1e-4)[0] bv[bound_faces] = 1 param.set_bc_val("flow", bv) d["param"] = param gb.add_edge_props("kn") kn = 1e7 for e, d in gb.edges(): mg = d["mortar_grid"] d["kn"] = kn * np.ones(mg.num_cells)
def test_upwind_1d_discharge_negative(self): g = structured.CartGrid(3, 1) g.compute_geometry() solver = upwind.Upwind() param = Parameters(g) dis = solver.discharge(g, [-2, 0, 0]) bf = g.get_boundary_faces() bc = BoundaryCondition(g, bf, bf.size * ['neu']) param.set_bc(solver, bc) data = {'param': param, 'discharge': dis} M = solver.matrix_rhs(g, data)[0].todense() deltaT = solver.cfl(g, data) M_known = np.array([[0,-2, 0], [0, 2,-2], [0, 0, 2]]) deltaT_known = 1/12 rtol = 1e-15 atol = rtol assert np.allclose(M, M_known, rtol, atol) assert np.allclose(deltaT, deltaT_known, rtol, atol)
def get_bc_mechanics(self): """ Stiffness matrix, defined as fourth order tensor """ if hasattr(self, '_bc_mechanics'): return self._bc_mechanics else: return BoundaryCondition(self.g)
def test_upwind_2d_cart_discharge_positive(self): g = structured.CartGrid([3, 2], [1, 1]) g.compute_geometry() solver = upwind.Upwind() param = Parameters(g) dis = solver.discharge(g, [2, 0, 0]) bf = g.tags['domain_boundary_faces'].nonzero()[0] bc = BoundaryCondition(g, bf, bf.size * ['neu']) param.set_bc(solver, bc) data = {'param': param, 'discharge': dis} M = solver.matrix_rhs(g, data)[0].todense() deltaT = solver.cfl(g, data) M_known = np.array([[1, 0, 0, 0, 0, 0], [-1, 1, 0, 0, 0, 0], [0, -1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, -1, 1, 0], [0, 0, 0, 0, -1, 0]]) deltaT_known = 1 / 12 rtol = 1e-15 atol = rtol assert np.allclose(M, M_known, rtol, atol) assert np.allclose(deltaT, deltaT_known, rtol, atol)
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.SecondOrderTensor(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 test_upwind_1d_discharge_negative_bc_neu(self): g = structured.CartGrid(3, 1) g.compute_geometry() solver = upwind.Upwind() param = Parameters(g) dis = solver.discharge(g, [-2, 0, 0]) bf = g.tags['domain_boundary_faces'].nonzero()[0] bc = BoundaryCondition(g, bf, bf.size * ['neu']) bc_val = np.array([2, 0, 0, -2]).ravel('F') param.set_bc(solver, bc) param.set_bc_val(solver, bc_val) data = {'param': param, 'discharge': dis} M, rhs = solver.matrix_rhs(g, data) deltaT = solver.cfl(g, data) M_known = np.array([[0, -2, 0], [0, 2, -2], [0, 0, 2]]) rhs_known = np.array([-2, 0, 2]) deltaT_known = 1 / 12 rtol = 1e-15 atol = rtol assert np.allclose(M.todense(), M_known, rtol, atol) assert np.allclose(rhs, rhs_known, rtol, atol) assert np.allclose(deltaT, deltaT_known, rtol, atol)
def test_upwind_2d_simplex_surf_discharge_negative(self): g = simplex.StructuredTriangleGrid([2, 1], [1, 1]) R = cg.rot(-np.pi / 5., [1, 1, -1]) g.nodes = np.dot(R, g.nodes) g.compute_geometry(is_embedded=True) solver = upwind.Upwind() param = Parameters(g) dis = solver.discharge(g, np.dot(R, [-1, 0, 0])) bf = g.tags['domain_boundary_faces'].nonzero()[0] bc = BoundaryCondition(g, bf, bf.size * ['neu']) param.set_bc(solver, bc) data = {'param': param, 'discharge': dis} M = solver.matrix_rhs(g, data)[0].todense() deltaT = solver.cfl(g, data) M_known = np.array([[1, 0, 0, -1], [-1, 0, 0, 0], [0, 0, 1, 0], [0, 0, -1, 1]]) deltaT_known = 1 / 6 rtol = 1e-15 atol = rtol assert np.allclose(M, M_known, rtol, atol) assert np.allclose(deltaT, deltaT_known, rtol, atol)
def test_upwind_example1(self, if_export=False): ####################### # Simple 2d upwind problem with implicit Euler scheme in time ####################### T = 1 Nx, Ny = 10, 1 g = structured.CartGrid([Nx, Ny], [1, 1]) g.compute_geometry() advect = upwind.Upwind("transport") param = Parameters(g) dis = advect.discharge(g, [1, 0, 0]) b_faces = g.get_all_boundary_faces() bc = BoundaryCondition(g, b_faces, ["dir"] * b_faces.size) bc_val = np.hstack(([1], np.zeros(g.num_faces - 1))) param.set_bc("transport", bc) param.set_bc_val("transport", bc_val) data = {"param": param, "discharge": dis} data["deltaT"] = advect.cfl(g, data) U, rhs = advect.matrix_rhs(g, data) M, _ = mass_matrix.MassMatrix().matrix_rhs(g, data) conc = np.zeros(g.num_cells) # Perform an LU factorization to speedup the solver IE_solver = sps.linalg.factorized((M + U).tocsc()) # Loop over the time Nt = int(T / data["deltaT"]) time = np.empty(Nt) folder = "example1" save = Exporter(g, "conc_IE", folder) for i in np.arange(Nt): # Update the solution # Backward and forward substitution to solve the system conc = IE_solver(M.dot(conc) + rhs) time[i] = data["deltaT"] * i if if_export: save.write_vtk({"conc": conc}, time_step=i) if if_export: save.write_pvd(time) known = np.array([ 0.99969927, 0.99769441, 0.99067741, 0.97352474, 0.94064879, 0.88804726, 0.81498958, 0.72453722, 0.62277832, 0.51725056, ]) assert np.allclose(conc, known)
def test_upwind_3d_cart_discharge_positive(self): g = structured.CartGrid([2, 2, 2], [1, 1, 1]) g.compute_geometry() solver = upwind.Upwind() param = Parameters(g) dis = solver.discharge(g, [1, 0, 0]) bf = g.tags["domain_boundary_faces"].nonzero()[0] bc = BoundaryCondition(g, bf, bf.size * ["neu"]) param.set_bc(solver, bc) data = {"param": param, "discharge": dis} M = solver.matrix_rhs(g, data)[0].todense() deltaT = solver.cfl(g, data) M_known = 0.25 * np.array([ [1, 0, 0, 0, 0, 0, 0, 0], [-1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, -1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, -1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 0, -1, 0], ]) deltaT_known = 1 / 4 rtol = 1e-15 atol = rtol self.assertTrue(np.allclose(M, M_known, rtol, atol)) self.assertTrue(np.allclose(deltaT, deltaT_known, rtol, atol))
def add_data(gb, 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.SecondOrderTensor(g.dim, kxx)) # Source term param.set_source("flow", np.zeros(g.num_cells)) # Boundaries bound_faces = g.tags["domain_boundary_faces"].nonzero()[0] if bound_faces.size != 0: bound_face_centers = g.face_centers[:, bound_faces] bottom = bound_face_centers[0, :] < tol labels = np.array(["neu"] * bound_faces.size) labels[bottom] = "dir" bc_val = np.zeros(g.num_faces) mask = bound_face_centers[2, :] < 0.3 + tol bc_val[bound_faces[np.logical_and(bottom, mask)]] = 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 discharge 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, tol): """ Define the permeability, apertures, boundary conditions """ gb.add_node_props(["param"]) # Aavatsmark_transmissibilities only for tpfa intra-dimensional coupling for g, d in gb: d["Aavatsmark_transmissibilities"] = True if g.dim < 2: continue param = Parameters(g) # Permeability kxx = np.array([perm(*pt) for pt in g.cell_centers.T]) param.set_tensor("flow", tensor.SecondOrderTensor(3, kxx)) # Source term frac_id = d["frac_id"][0] source = np.array([source_f[frac_id](*pt) for pt in g.cell_centers.T]) param.set_source("flow", g.cell_volumes * source) # Boundaries bound_faces = g.tags["domain_boundary_faces"].nonzero()[0] if bound_faces.size != 0: bound_face_centers = g.face_centers[:, bound_faces] labels = np.array(["dir"] * bound_faces.size) bc_val = np.zeros(g.num_faces) bc = [sol_f[frac_id](*pt) for pt in bound_face_centers.T] bc_val[bound_faces] = np.array(bc) 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_prop("Aavatsmark_transmissibilities") for _, d in gb.edges_props(): d["Aavatsmark_transmissibilities"] = True
def bc(self): bound_faces = self.grid().tags["domain_boundary_faces"].nonzero()[0] if bound_faces.size == 0: return BoundaryCondition(self.grid(), np.empty(0), np.empty(0)) bound_face_centers = self.grid().face_centers[:, bound_faces] top = bound_face_centers[2, :] > self.domain["zmax"] - self.tol bottom = bound_face_centers[2, :] < self.domain["zmin"] + self.tol boundary = np.logical_or(top, bottom) labels = np.array(["neu"] * bound_faces.size) labels[boundary] = ["dir"] return BoundaryCondition(self.grid(), bound_faces, labels)