Ejemplo n.º 1
0
    def generate_2d_grid(self, n, xmax, ymax):
        g1 = pp.CartGrid([xmax * n, ymax * n], physdims=[xmax, ymax])
        g1.compute_geometry()
        gb = pp.GridBucket()

        gb.add_nodes(g1)
        tol = 1e-6
        left_faces = np.argwhere(g1.face_centers[1] > ymax - tol).ravel()
        right_faces = np.argwhere(g1.face_centers[1] < 0 + tol).ravel()
        val = np.ones(left_faces.size, dtype=np.bool)
        shape = [g1.num_faces, g1.num_faces]

        face_faces = sps.coo_matrix((val, (right_faces, left_faces)), shape=shape)

        gb.add_edge((g1, g1), face_faces)

        mg = pp.TensorGrid(np.linspace(0, xmax, n + 1))
        mg.nodes[1] = ymax

        mg.compute_geometry()

        d_e = gb.edge_props((g1, g1))
        d_e["mortar_grid"] = pp.BoundaryMortar(g1.dim - 1, mg, face_faces)
        gb.assign_node_ordering()
        return gb
Ejemplo n.º 2
0
    def generate_grid_with_fractures(self, n, xmax, ymax):
        x = [xmax / 3] * 2
        y = [0, ymax / 2]
        fracs = [np.array([x, y])]
        y = [ymax / 2, ymax]
        fracs.append(np.array([x, y]))

        gb = pp.meshing.cart_grid(fracs, [xmax * n, ymax * n],
                                  physdims=[xmax, ymax])

        tol = 1e-6
        for g, d in gb:
            # map right faces to left
            left = np.argwhere(g.face_centers[1] < tol).ravel()
            right = np.argwhere(g.face_centers[1] > ymax - tol).ravel()
            g.face_centers[1, right] = 0

            g.left = left
            g.right = right

        # now create mappings between two grids of equal dimension
        for dim in [2, 1]:
            grids = gb.grids_of_dimension(dim)
            for i, gi in enumerate(grids):
                if gi.left.size < 1:
                    continue
                for j, gj in enumerate(grids):
                    if gj.right.size < 1:
                        continue
                    face_faces = self.match_grids(gi, gj)

                    if np.sum(face_faces) == 0:
                        continue

                    gb.add_edge((gi, gj), face_faces)
                    d_e = gb.edge_props((gi, gj))

                    di = gb.node_props(gi)
                    dj = gb.node_props(gj)

                    if di["node_number"] < dj["node_number"]:
                        # gj is left
                        g_m, _, _ = pp.partition.extract_subgrid(gj,
                                                                 gj.right,
                                                                 faces=True)
                        face_faces = face_faces.T
                    else:
                        # gi is left
                        g_m, _, _ = pp.partition.extract_subgrid(gi,
                                                                 gi.left,
                                                                 faces=True)

                    side_g = {pp.grids.mortar_grid.LEFT_SIDE: g_m}
                    d_e["mortar_grid"] = pp.BoundaryMortar(
                        gi.dim - 1, side_g, face_faces)

        gb.compute_geometry()  # basically reset g.face_centers[,right]
        gb.assign_node_ordering()

        return gb
Ejemplo n.º 3
0
    def generate_grids(self, n, xmax, ymax, split):
        g1 = pp.CartGrid([split * n, ymax * n], physdims=[split, ymax])
        g2 = pp.CartGrid([(xmax - split) * n, ymax * n],
                         physdims=[xmax - split, ymax])
        g2.nodes[0] += split

        g1.compute_geometry()
        g2.compute_geometry()
        grids = [g2, g1]

        gb = pp.GridBucket()

        [gb.add_nodes(g) for g in grids]
        [g2, g1] = gb.grids_of_dimension(2)

        tol = 1e-6
        if np.any(g2.cell_centers[0] > split):
            right_grid = g2
            left_grid = g1
        else:
            right_grid = g1
            left_grid = g2

        gb.set_node_prop(left_grid, "node_number", 1)
        gb.set_node_prop(right_grid, "node_number", 0)
        left_faces = np.argwhere(
            left_grid.face_centers[0] > split - tol).ravel()
        right_faces = np.argwhere(
            right_grid.face_centers[0] < split + tol).ravel()
        val = np.ones(left_faces.size, dtype=np.bool)
        shape = [right_grid.num_faces, left_grid.num_faces]

        face_faces = sps.coo_matrix((val, (right_faces, left_faces)),
                                    shape=shape)

        gb.add_edge((right_grid, left_grid), face_faces)

        mg = pp.TensorGrid(np.array([split] * ((n + 1) * ymax)))
        mg.nodes[1] = np.linspace(0, ymax, (n + 1) * ymax)
        mg.compute_geometry()
        side_g = {pp.grids.mortar_grid.LEFT_SIDE: mg}

        d_e = gb.edge_props((g1, g2))
        d_e["mortar_grid"] = pp.BoundaryMortar(g1.dim - 1, side_g, face_faces)
        d_e["edge_number"] = 0

        return gb
def create_mortar_grids(gb):
    """
    Given a grid bucket, create new edges (in the grid bucket) that maps the slave side
    of the fractures to the master side.
    
    Arguments:
        gb : GridBucket
    """
    # First we add a edge from each grid to itself.
    for g, d in gb:
        # Define a mapping from faces to master and faces to slave
        master_id = g.frac_pairs[0]
        slave_id = g.frac_pairs[1]
        if master_id.size == 0:
            continue
        num_m = master_id.size
        if num_m != slave_id.size:
            raise ValueError("Mortar and slave side of fracture must match")
        rows = np.arange(num_m)
        master_face = sps.coo_matrix(
            (np.ones(num_m), (rows, master_id)), (num_m, g.num_faces)
        ).tocsc()
        slave_face = sps.coo_matrix(
            (np.ones(num_m), (rows, slave_id)), (num_m, g.num_faces)
        ).tocsc()
        # Find the mapping from slave to master
        slave_master = master_face.T * slave_face
        slave_grid, face_id, _ = pp.partition.extract_subgrid(g, slave_id, faces=True, is_planar=False)
        # do some checks that all mappings have been correct
        # Check that slave and master coincide

        if np.all(face_id != slave_id):
            raise AssertionError("Assume extract subgrid does not change ordering")

        if not np.all(
            [
                np.allclose((slave_face - master_face) * g.face_centers[dim], 0)
                for dim in range(g.dim)
            ]
        ):
            raise AssertionError("Slave and master do not conside")
        if not np.all(
            [
                np.allclose(
                    slave_master.T * g.face_centers[dim],
                    slave_face.T * g.face_centers[dim, slave_id]
                )
                for dim in range(g.dim)
            ]
        ):
            raise AssertionError("Slave faces do not coinside with mortar cells")

        if not np.all(
            [
                np.allclose(
                    slave_face * g.face_centers[dim], slave_grid.cell_centers[dim]
                )
                for dim in range(g.dim)
            ]
        ):
            raise AssertionError("Slave faces do not coinside with mortar cells")

        # Checks done.
        # Now create mortar grid
        mortar_grid = pp.BoundaryMortar(g.dim - 1, slave_grid, (slave_master.T))

        # Add edge to Grid bucket
        gb.add_edge((g, g), slave_master)
        d_e = gb.edge_props((g, g))
        d_e["mortar_grid"] = mortar_grid

    gb.assign_node_ordering()