예제 #1
0
    def test_domain_cut_in_two(self):
        """
        test domain cut in two. We place 1 dirichlet on top. zero dirichlet on
        bottom and 0 neumann on sides. Further we place 1 displacement on
        fracture. this should give us displacement 1 on top cells and 0 on 
        bottom cells and zero traction on all faces
        """

        frac = np.array([[0,0,1], [0,3,1], [3,3,1], [3,0,1]]).T
        g = meshing.cart_grid([frac], [3,3,2]).grids_of_dimension(3)[0]
        data = {'param': Parameters(g)}

        tol = 1e-6
        frac_bnd = g.has_face_tag(FaceTag.FRACTURE)
        top = g.face_centers[2] > 2 - tol
        bot = g.face_centers[2] < tol

        dir_bound = top | bot | frac_bnd
        
        bound = bc.BoundaryCondition(g, dir_bound, 'dir') 

        bc_val = np.zeros((g.dim, g.num_faces))
        bc_val[:, top] = np.ones((g.dim, np.sum(top)))
        frac_slip = np.zeros((g.dim, g.num_faces))
        frac_slip[:, frac_bnd] = np.ones(np.sum(frac_bnd))


        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')
        T = solver.traction(g, data, u)

        top_cells = g.cell_centers[2] > 1

        mid_ind = int(round(u_f.size/2))
        u_left = u_f[:mid_ind]
        u_right = u_f[mid_ind:]



        assert np.allclose(u_left, 1)
        assert np.allclose(u_right, 0)        
        assert np.allclose(u_c[:, top_cells], 1)
        assert np.allclose(u_c[:, ~top_cells], 0)        
        assert np.allclose(T, 0)
예제 #2
0
    def test_uniform_strain(self):
        g_list = setup_grids.setup_2d()

        for g in g_list:
            bound_faces = np.argwhere(
                np.abs(g.cell_faces).sum(axis=1).A.ravel("F") == 1
            )
            bound = bc.BoundaryCondition(
                g, bound_faces.ravel("F"), ["dir"] * bound_faces.size
            )
            mu = 1
            l = 1
            constit = setup_stiffness(g, mu, l)

            # Python inverter is most efficient for small problems
            stress, bound_stress = mpsa.mpsa(g, constit, bound, inverter="python")

            div = fvutils.vector_divergence(g)
            a = div * stress

            xc = g.cell_centers
            xf = g.face_centers

            gx = np.random.rand(1)
            gy = np.random.rand(1)

            dc_x = np.sum(xc * gx, axis=0)
            dc_y = np.sum(xc * gy, axis=0)
            df_x = np.sum(xf * gx, axis=0)
            df_y = np.sum(xf * gy, axis=0)

            d_bound = np.zeros((g.dim, g.num_faces))
            d_bound[0, bound.is_dir] = df_x[bound.is_dir]
            d_bound[1, bound.is_dir] = df_y[bound.is_dir]

            rhs = div * bound_stress * d_bound.ravel("F")

            d = np.linalg.solve(a.todense(), -rhs)

            traction = stress * d + bound_stress * d_bound.ravel("F")

            s_xx = (2 * mu + l) * gx + l * gy
            s_xy = mu * (gx + gy)
            s_yx = mu * (gx + gy)
            s_yy = (2 * mu + l) * gy + l * gx

            n = g.face_normals
            traction_ex_x = s_xx * n[0] + s_xy * n[1]
            traction_ex_y = s_yx * n[0] + s_yy * n[1]

            self.assertTrue(np.max(np.abs(d[::2] - dc_x)) < 1e-8)
            self.assertTrue(np.max(np.abs(d[1::2] - dc_y)) < 1e-8)
            self.assertTrue(np.max(np.abs(traction[::2] - traction_ex_x)) < 1e-8)
            self.assertTrue(np.max(np.abs(traction[1::2] - traction_ex_y)) < 1e-8)
예제 #3
0
    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.tags["domain_boundary_faces"].nonzero()[0]
        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.SecondOrderTensor(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"]

        self.check_parameters(elliptic_param, param)
예제 #4
0
        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
예제 #5
0
        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
예제 #6
0
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_frac": mesh_size,
            "mesh_size_bound": 2 * mesh_size,
            "mesh_size_min": mesh_size / 20,
        }
        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

    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
예제 #7
0
def darcy_dualVEM_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.SecondOrderTensor(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_all_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 = dual.DualVEM()
    data = {"perm": perm, "source": f, "bc": bnd, "bc_val": bnd_val}
    D, rhs = solver.matrix_rhs(g, data)

    up = sps.linalg.spsolve(D, rhs)
    u, p = solver.extract_u(g, up), solver.extract_p(g, up)
    P0u = solver.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.1010936831876412, 0.0680593765009036])
    assert np.allclose(errors, errors_known)
예제 #8
0
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.SecondOrderTensor(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_all_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)
예제 #9
0
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_frac': mesh_size,
            'mesh_size_bound': 2 * mesh_size,
            'mesh_size_min': mesh_size / 20
        }
        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

    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
예제 #10
0
def darcy_dual_hybridVEM_example1(**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.SecondOrderTensor(g.dim, kxx)

    def funP_ex(pt):
        return np.sin(2 * np.pi * pt[0]) * np.sin(2 * np.pi * pt[1])

    def funU_ex(pt):
        return [
            -2 * np.pi * np.cos(2 * np.pi * pt[0]) * np.sin(2 * np.pi * pt[1]),
            -2 * np.pi * np.sin(2 * np.pi * pt[0]) * np.cos(2 * np.pi * pt[1]),
            0,
        ]

    def fun(pt):
        return 8 * np.pi**2 * funP_ex(pt)

    f = np.array([fun(pt) for pt in g.cell_centers.T])

    b_faces = g.get_all_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.0210718223032, 0.00526933885613])
    assert np.allclose(errors, errors_known)
예제 #11
0
def darcy_dualVEM_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()

    T = cg.tangent_matrix(g.nodes)

    kxx = np.ones(g.num_cells)
    perm = tensor.SecondOrderTensor(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_all_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 = dual.DualVEM()
    data = {"perm": perm, "source": f, "bc": bnd, "bc_val": bnd_val}
    D, rhs = solver.matrix_rhs(g, data)

    up = sps.linalg.spsolve(D, rhs)
    u, p = solver.extract_u(g, up), solver.extract_p(g, up)
    P0u = solver.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)
예제 #12
0
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 = tensor.SecondOrder(g.dim, kxx)
    bound_faces = np.argwhere(
        np.abs(g.cell_faces).sum(axis=1).A.ravel('F') == 1)
    bound = bc.BoundaryCondition(g, bound_faces, ['dir'] * bound_faces.size)

    discr = tpfa.Tpfa()
    d = _assign_params(g, perm, bound)
    discr.discretize(g, d)
    flux, bound_flux = d['flux'], d['bound_flux']
예제 #13
0
    def test_unit_slip(self):
        """
        Unit slip of fractures
        """

        f = np.array([[0, 0, 1], [0, 2, 1], [2, 2, 1], [2, 0, 1]]).T
        g = meshing.cart_grid([f], [2, 2, 2]).grids_of_dimension(3)[0]
        data = {"param": Parameters(g)}

        bound = bc.BoundaryCondition(g, g.get_all_boundary_faces(), "dir")
        data["param"].set_bc("mechanics", bound)

        slip = np.ones(g.dim * g.num_faces)
        data["param"].set_slip_distance(slip)

        solver = StaticModel(g, data)
        solver.solve()

        solver.frac_displacement("d_f")
        solver.displacement("d_c")

        solver.save(["d_c"])

        # test cell displacent around fractures
        d_c = data["d_c"]
        d_c = d_c.reshape((3, -1), order="F")
        frac_faces = g.frac_pairs
        frac_left = frac_faces[0]
        frac_right = frac_faces[1]

        cell_left = np.ravel(np.argwhere(g.cell_faces[frac_left, :])[:, 1])
        cell_right = np.ravel(np.argwhere(g.cell_faces[frac_right, :])[:, 1])

        # Test traction
        solver.traction("T")
        T_left = data["T"][:, frac_left]
        T_right = data["T"][:, frac_right]

        self.assertTrue(np.allclose(T_left, T_right))

        # we have u_lhs - u_rhs = 1 so u_lhs should be positive
        self.assertTrue(np.all(d_c[:, cell_left] > 0))
        self.assertTrue(np.all(d_c[:, cell_right] < 0))

        # Test fracture displacement
        u_left = data["d_f"][:, :int(round(data["d_f"].shape[1] / 2))]
        u_right = data["d_f"][:, int(round(data["d_f"].shape[1] / 2)):]
        self.assertTrue(np.all(np.abs(u_left - u_right - 1) < 1e-10))
예제 #14
0
    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.BoundaryCondition(g, g.get_all_boundary_faces(), 'dir')
        data['param'].set_bc('mechanics', bound)

        solver = StaticModel(g, data)
        d = solver.solve()
        solver.traction('T')
        assert np.all(d == 0)
        assert np.all(data['T'] == 0)
예제 #15
0
    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.BoundaryCondition(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))
예제 #16
0
    def test_one_cell_a_time_node_keyword(self):
        # Update one and one cell, and verify that the result is the same as
        # with a single computation.
        # The test is similar to what will happen with a memory-constrained
        # splitting.
        g = CartGrid([3, 3])
        g.compute_geometry()

        # Assign random permeabilities, for good measure
        np.random.seed(42)
        kxx = np.random.random(g.num_cells)
        kyy = np.random.random(g.num_cells)
        # Ensure positive definiteness
        kxy = np.random.random(g.num_cells) * kxx * kyy
        perm = PermTensor(2, kxx=kxx, kyy=kyy, kxy=kxy)

        flux = sps.csr_matrix((g.num_faces, g.num_cells))
        bound_flux = sps.csr_matrix((g.num_faces, g.num_faces))
        faces_covered = np.zeros(g.num_faces, np.bool)

        bnd = bc.BoundaryCondition(g)

        cn = g.cell_nodes()
        for ci in range(g.num_cells):
            ind = np.zeros(g.num_cells)
            ind[ci] = 1
            nodes = np.squeeze(np.where(cn * ind > 0))
            partial_flux, partial_bound, _, _, active_faces = mpfa.mpfa_partial(
                g, perm, bnd, nodes=nodes, inverter="python")

            if np.any(faces_covered):
                partial_flux[faces_covered, :] *= 0
                partial_bound[faces_covered, :] *= 0
            faces_covered[active_faces] = True

            flux += partial_flux
            bound_flux += partial_bound

        flux_full, bound_flux_full, _, _ = mpfa.mpfa(g,
                                                     perm,
                                                     bnd,
                                                     inverter="python")

        self.assertTrue((flux_full - flux).max() < 1e-8)
        self.assertTrue((flux_full - flux).min() > -1e-8)
        self.assertTrue((bound_flux - bound_flux_full).max() < 1e-8)
        self.assertTrue((bound_flux - bound_flux_full).min() > -1e-8)
예제 #17
0
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()

    internal_flag = FaceTag.FRACTURE
    [g.remove_face_tag_if_tag(FaceTag.BOUNDARY, internal_flag) for g, _ in gb]

    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

    gb.add_edge_prop('kn')
    for e, d in gb.edges_props():
        g = gb.sorted_nodes_of_edge(e)[0]
        d['kn'] = 1 / gb.node_prop(g, 'param').get_aperture()

    return gb
예제 #18
0
    def test_one_cell_a_time_node_keyword(self):
        # Update one and one cell, and verify that the result is the same as
        # with a single computation. The test is similar to what will happen
        # with a memory-constrained splitting.
        g = CartGrid([3, 3])
        g.compute_geometry()

        # Assign random permeabilities, for good measure
        np.random.seed(42)
        mu = np.random.random(g.num_cells)
        lmbda = np.random.random(g.num_cells)
        stiffness = StiffnessTensor(2, mu=mu, lmbda=lmbda)

        stress = sps.csr_matrix((g.num_faces * g.dim, g.num_cells * g.dim))
        bound_stress = sps.csr_matrix(
            (g.num_faces * g.dim, g.num_faces * g.dim))
        faces_covered = np.zeros(g.num_faces, np.bool)

        bnd = bc.BoundaryCondition(g)
        stress_full, bound_stress_full = mpsa.mpsa(g,
                                                   stiffness,
                                                   bnd,
                                                   inverter='python')

        cn = g.cell_nodes()
        for ci in range(g.num_cells):
            ind = np.zeros(g.num_cells)
            ind[ci] = 1
            nodes = np.squeeze(np.where(cn * ind > 0))
            partial_stress, partial_bound, active_faces = \
                    mpsa.mpsa_partial(g, stiffness, bnd, nodes=nodes,
                                      inverter='python')

            if np.any(faces_covered):
                del_faces = self.expand_indices_nd(
                    np.where(faces_covered)[0], g.dim)
                partial_stress[del_faces, :] *= 0
                partial_bound[del_faces, :] *= 0
            faces_covered[active_faces] = True

            stress += partial_stress
            bound_stress += partial_bound

        assert (stress_full - stress).max() < 1e-8
        assert (stress_full - stress).min() > -1e-8
        assert (bound_stress - bound_stress_full).max() < 1e-8
        assert (bound_stress - bound_stress_full).min() > -1e-8
예제 #19
0
    def test_conservation_of_momentum(self):
        pts = np.random.rand(3, 9)
        corners = [
            [0, 0, 0, 0, 1, 1, 1, 1],
            [0, 0, 1, 1, 0, 0, 1, 1],
            [0, 1, 0, 1, 0, 1, 0, 1],
        ]
        pts = np.hstack((corners, pts))
        gt = simplex.TetrahedralGrid(pts)
        gc = structured.CartGrid([3, 3, 3], physdims=[1, 1, 1])
        g_list = [gt, gc]
        [g.compute_geometry() for g in g_list]
        for g in g_list:
            g.compute_geometry()
            bot = np.ravel(np.argwhere(g.face_centers[1, :] < 1e-10))
            left = np.ravel(np.argwhere(g.face_centers[0, :] < 1e-10))
            dir_faces = np.hstack((left, bot))
            bound = bc.BoundaryCondition(
                g, dir_faces.ravel("F"), ["dir"] * dir_faces.size
            )
            constit = setup_stiffness(g)

            # Python inverter is most efficient for small problems
            stress, bound_stress = mpsa.mpsa(g, constit, bound, inverter="python")

            div = fvutils.vector_divergence(g)
            a = div * stress

            bndr = g.get_all_boundary_faces()
            d_x = np.random.rand(bndr.size)
            d_y = np.random.rand(bndr.size)
            d_bound = np.zeros((g.dim, g.num_faces))
            d_bound[0, bndr] = d_x
            d_bound[1, bndr] = d_y

            rhs = div * bound_stress * d_bound.ravel("F")

            d = np.linalg.solve(a.todense(), -rhs)

            traction = stress * d + bound_stress * d_bound.ravel("F")
            traction_2d = traction.reshape((g.dim, -1), order="F")
            for cell in range(g.num_cells):
                fid, _, sgn = sps.find(g.cell_faces[:, cell])
                self.assertTrue(
                    np.all(np.sum(traction_2d[:, fid] * sgn, axis=1) < 1e-10)
                )
예제 #20
0
def solve_elliptic_problem(gb):
    for g, d in gb:
        if g.dim == 2:
            d['param'].set_source('flow', source(g, 0.0))

        dir_bound = np.argwhere(g.has_face_tag(FaceTag.DOMAIN_BOUNDARY))
        bc_cond = bc.BoundaryCondition(g, dir_bound, ['dir'] * dir_bound.size)
        d['param'].set_bc('flow', bc_cond)

    gb.add_edge_prop('param')
    for e, d in gb.edges_props():
        g_h = gb.sorted_nodes_of_edge(e)[1]
        d['param'] = Parameters(g_h)
    flux = elliptic.EllipticModel(gb)
    p = flux.solve()
    flux.split('pressure')
    fvutils.compute_discharges(gb)
def solve_elliptic_problem(gb):
    for g, d in gb:
        if g.dim == 2:
            d['param'].set_source('flow', source(g, 0.0))

        dir_bound = g.tags['domain_boundary_faces'].nonzero()[0]
        bc_cond = bc.BoundaryCondition(g, dir_bound, ['dir'] * dir_bound.size)
        d['param'].set_bc('flow', bc_cond)

    gb.add_edge_props('param')
    for e, d in gb.edges():
        g_h = gb.nodes_of_edge(e)[1]
        d['param'] = Parameters(g_h)
    flux = elliptic.EllipticModel(gb)
    p = flux.solve()
    flux.split('pressure')
    fvutils.compute_discharges(gb)
예제 #22
0
def add_data_transport(gb):

    gb.add_node_props(["bc", "bc_val", "discharge", "apertures"])
    for g, d in gb:
        b_faces = g.tags["domain_boundary_faces"].nonzero()[0]
        index = np.nonzero(
            abs(g.face_centers[:, b_faces]) == np.ones([3, b_faces.size]))[1]
        b_faces = b_faces[index]
        d["bc"] = bc.BoundaryCondition(g, b_faces, ["dir"] * b_faces.size)
        d["bc_val"] = {"dir": np.ones(b_faces.size)}
        d["apertures"] = np.ones(g.num_cells) * np.power(.01, float(g.dim < 3))
        d["discharge"] = upwind.Upwind().discharge(
            g, [1, 1, 2 * np.power(1000, g.dim < 2)], d["apertures"])

    gb.add_edge_prop("discharge")
    for e, d in gb.edges_props():
        g_h = gb.sorted_nodes_of_edge(e)[1]
        d["discharge"] = gb.node_prop(g_h, "discharge")
예제 #23
0
def add_data_transport(gb):

    gb.add_node_props(['bc', 'bc_val', 'discharge', 'apertures'])
    for g, d in gb:
        b_faces = g.tags['domain_boundary_faces'].nonzero()[0]
        index = np.nonzero(
            abs(g.face_centers[:, b_faces]) == np.ones([3, b_faces.size]))[1]
        b_faces = b_faces[index]
        d['bc'] = bc.BoundaryCondition(g, b_faces, ['dir'] * b_faces.size)
        d['bc_val'] = {'dir': np.ones(b_faces.size)}
        d['apertures'] = np.ones(g.num_cells) * np.power(.01, float(g.dim < 3))
        d['discharge'] = upwind.Upwind().discharge(
            g, [1, 1, 2 * np.power(1000, g.dim < 2)], d['apertures'])

    gb.add_edge_prop('discharge')
    for e, d in gb.edges_props():
        g_h = gb.sorted_nodes_of_edge(e)[1]
        d['discharge'] = gb.node_prop(g_h, 'discharge')
예제 #24
0
def add_data(g, advection):
    """
    Define the permeability, apertures, boundary conditions
    """

    b_faces = g.tags["domain_boundary_faces"].nonzero()[0]
    bnd = bc.BoundaryCondition(g, b_faces, ["dir"] * b_faces.size)
    bnd_val = np.zeros(g.num_faces)

    beta_n = advection.beta_n(g, [1, 0, 0])

    kxx = 1e-2 * np.ones(g.num_cells)
    diffusion = second_order_tensor.SecondOrderTensorTensor(g.dim, kxx)

    f = np.ones(g.num_cells) * g.cell_volumes

    data = {"beta_n": beta_n, "bc": bnd, "bc_val": bnd_val, "k": diffusion, "f": f}

    return data
예제 #25
0
    def test_zero_force(self):
        """
        test that nothing moves if nothing is touched
        """
        g = self.gb3d.grids_of_dimension(3)[0]

        data = {'param': Parameters(g)}
        bound = bc.BoundaryCondition(g, g.get_boundary_faces(), 'dir') 

        data['param'].set_bc('mechanics', bound)

        solver = mpsa.FracturedMpsa()
        
        A, b = solver.matrix_rhs(g, data)
        u = np.linalg.solve(A.A, b)
        T = solver.traction(g, data, u)

        assert np.all(np.abs(u) < 1e-10)
        assert np.all(np.abs(T) < 1e-10)
예제 #26
0
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
예제 #27
0
def test_uniform_flow_cart_2d():
    # Structured Cartesian grid
    g, perm = setup_cart_2d(np.array([10, 10]))
    bound_faces = np.argwhere(
        np.abs(g.cell_faces).sum(axis=1).A.ravel('F') == 1)
    bound = bc.BoundaryCondition(g, bound_faces.ravel('F'),
                                 ['dir'] * bound_faces.size)

    # Python inverter is most efficient for small problems
    flux, bound_flux = mpfa.mpfa(g, perm, bound, inverter='python')
    div = g.cell_faces.T

    a = div * flux

    pr_bound, pr_cell, gx, gy = setup_random_pressure_field(g)

    rhs = div * bound_flux * pr_bound
    pr = np.linalg.solve(a.todense(), -rhs)

    p_diff = pr - pr_cell
    assert np.max(np.abs(p_diff)) < 1e-8
예제 #28
0
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
예제 #29
0
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
예제 #30
0
def test_laplacian_stencil_cart_2d():
    """ Apply MPFA on Cartesian grid, should obtain Laplacian stencil. """

    # Set up 3 X 3 Cartesian grid
    g, perm = setup_cart_2d(np.array([3, 3]))

    bnd_faces = np.array([0, 3, 12])
    bound = bc.BoundaryCondition(g, bnd_faces, ['dir'] * bnd_faces.size)

    # Python inverter is most efficient for small problems
    flux, bound_flux = mpfa.mpfa(g, perm, bound, inverter='python')
    div = g.cell_faces.T
    A = div * flux

    # 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

    # The first cell should have two Dirichlet bnds
    assert A[0, 0] == 6
    assert A[0, 1] == -1
    assert A[0, 3] == -1

    # Cell 3 has one Dirichlet, one Neumann face
    assert A[2, 2] == 4
    assert A[2, 1] == -1
    assert A[2, 5] == -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

    return A