Exemple #1
0
 def test_boundary_faces_cart(self):
     g = pp.CartGrid([2, 1])
     int_faces = g.get_internal_faces()
     self.assertTrue(int_faces.size == 1)
     self.assertTrue(int_faces[0] == 1)
def test_2d_horizontal_periodic_ambient_dim_2(method):
    # Cartesian grid in xy-plane with periodic boundary conditions.

    # Random size of the domain
    dx = np.random.rand(1)[0]

    # 2x2 grid of the random size
    g = pp.CartGrid([2, 2], [2 * dx, 2 * dx])

    # The vector source is a 2-vector per cell
    ambient_dim = 2

    # Discretization
    flux, vector_source_discr, div = set_params_disrcetize(
        g, ambient_dim, method, True)

    # Prepare to solve problem
    A = div * flux
    rhs = -div * vector_source_discr

    # Make source strength another random number
    grav_strength = np.random.rand(1)

    # introduce a source term in x-direction
    g_x = np.zeros(g.num_cells * ambient_dim)
    g_x[::ambient_dim] = -1 * grav_strength
    p_x = np.linalg.pinv(A.toarray()).dot(rhs * g_x)

    # The solution should be higher in the first x-row of cells, with magnitude
    # controlled by grid size and source stregth
    assert np.allclose(p_x[0] - p_x[1], dx * grav_strength)
    assert np.allclose(p_x[2] - p_x[3], dx * grav_strength)
    # The solution should be equal for equal x-coordinate
    assert np.allclose(p_x[0], p_x[2])
    assert np.allclose(p_x[1], p_x[3])

    flux_x = flux * p_x + vector_source_discr * g_x
    # The net flux should still be zero
    assert np.allclose(flux_x, 0)

    # Check matrices:
    A_known = np.array([
        [3.0, -1.0, -2.0, 0.0],
        [-1.0, 3.0, 0.0, -2.0],
        [-2.0, 0.0, 3.0, -1.0],
        [0.0, -2.0, -1.0, 3.0],
    ])
    # why 0.5?
    vct_src_known = (0.5 * dx * np.array([
        [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        [1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        [0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0],
        [0.0, 0.0, 0.0, 0.0, 0.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, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0],
        [0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
        [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0],
        [0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0],
        [0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0],
    ]))

    assert np.allclose(A.A, A_known)
    assert np.allclose(vector_source_discr.A, vct_src_known)
Exemple #3
0
    def test_mixed_condition(self):
        nx = 2
        ny = 1
        g = pp.CartGrid([nx, ny], physdims=[1, 1])
        g.compute_geometry()

        bot = g.face_centers[1] < 1e-10
        top = g.face_centers[1] > 1 - 1e-10
        left = g.face_centers[0] < 1e-10
        right = g.face_centers[0] > 1 - 1e-10

        bnd = pp.BoundaryConditionVectorial(g)
        bnd.is_neu[:] = False

        bnd.is_dir[0, left] = True
        bnd.is_neu[1, left] = True

        bnd.is_rob[0, right] = True
        bnd.is_dir[1, right] = True

        bnd.is_neu[0, bot] = True
        bnd.is_rob[1, bot] = True

        bnd.is_rob[0, top] = True
        bnd.is_dir[1, top] = True

        sc_top = pp.fvutils.SubcellTopology(g)
        bnd_excl = pp.fvutils.ExcludeBoundaries(sc_top, bnd, g.dim)

        rhs = pp.numerics.fv.mpsa.create_bound_rhs_nd(bnd, bnd_excl, sc_top, g)
        rhs_known = np.array(
            [
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0.5, 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0.5, 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0., 0., 0., 0.],
                [0., 0.5, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0.5, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0.5, 0., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0.5, 0., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0.],
                [0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0., 0., 0.],
                [-1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
                [-1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 1., 0., 0., 0., 0., 0., 0., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
                [0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1.],
            ]
        )
        self.assertTrue(np.all(np.abs(rhs_known - rhs) < 1e-12))
 def test_overlap_2_layers(self):
     g = pp.CartGrid([5, 5])
     ci = np.array([0, 1, 5, 6])
     ci_overlap = np.array(
         [0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18])
     assert np.array_equal(pp.partition.overlap(g, ci, 2), ci_overlap)
Exemple #5
0
 def test_2d(self):
     g = pp.CartGrid([1, 1])
     z = np.arange(2)
     gn, *rest = pp.grid_extrusion.extrude_grid(g, z)
     self.assertTrue(gn.dim == 3)
Exemple #6
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 = pp.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 = pp.FourthOrderTensor(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 = pp.BoundaryConditionVectorial(g)
        specified_data = {
            "fourth_order_tensor": stiffness,
            "bc": bnd,
            "inverter": "python",
        }
        keyword = "mechanics"
        data = pp.initialize_default_data(g, {},
                                          keyword,
                                          specified_parameters=specified_data)

        discr = pp.Mpsa(keyword)
        discr.discretize(g, data)

        stress_full = data[pp.DISCRETIZATION_MATRICES][keyword][
            discr.stress_matrix_key]
        bound_stress_full = data[pp.DISCRETIZATION_MATRICES][keyword][
            discr.bound_stress_matrix_key]

        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))

            data[pp.PARAMETERS][keyword]["specified_nodes"] = nodes

            discr.discretize(g, data)

            partial_stress = data[pp.DISCRETIZATION_MATRICES][keyword][
                discr.stress_matrix_key]
            partial_bound = data[pp.DISCRETIZATION_MATRICES][keyword][
                discr.bound_stress_matrix_key]

            active_faces = data[pp.PARAMETERS][keyword]["active_faces"]

            if np.any(faces_covered):
                del_faces = self.expand_indices_nd(
                    np.where(faces_covered)[0], g.dim)
                # del_faces is already expanded, set dimension to 1
                pp.fvutils.remove_nonlocal_contribution(
                    del_faces, 1, partial_stress, partial_bound)
            faces_covered[active_faces] = True

            stress += partial_stress
            bound_stress += partial_bound

        self.assertTrue((stress_full - stress).max() < 1e-8)
        self.assertTrue((stress_full - stress).min() > -1e-8)
        self.assertTrue((bound_stress - bound_stress_full).max() < 1e-8)
        self.assertTrue((bound_stress - bound_stress_full).min() > -1e-8)
Exemple #7
0
 def setUp(self):
     self.g = pp.CartGrid([3, 2])
Exemple #8
0
    def test_mass_matrix_2d(self):
        """
        Test mass matrix in 2d for a simple geometry
        """
        g = pp.CartGrid([3, 2], [1, 1])
        g.compute_geometry()

        # Mass weight is scaled by aperture 0.01
        specified_parameters = {"mass_weight": 0.5 * 1e-2}
        data = pp.initialize_default_data(g, {}, "flow", specified_parameters)

        discr = pp.MixedMassMatrix()
        discr.discretize(g, data)
        lhs, rhs = discr.assemble_matrix_rhs(g, data)

        lhs_known = (
            1.0
            / 1200
            * np.array(
                [
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        1.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        1.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        1.0,
                        0.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        1.0,
                        0.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        1.0,
                        0.0,
                    ],
                    [
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        0.0,
                        1.0,
                    ],
                ]
            )
        )

        self.assertTrue(np.allclose(lhs.toarray(), lhs_known))
        self.assertTrue(np.allclose(rhs, 0))
Exemple #9
0
Single grid only. The UpwindCouplingAd is not implemented yet
(should be simple), and this example should be updated accordingly.

Contact person: Eirik Keilegavlen

"""
import numpy as np
import scipy.sparse as sps
import scipy.sparse.linalg as spla

import porepy as pp


transport_key = "transport"

g = pp.CartGrid([10])
g.compute_geometry()
gb = pp.GridBucket()
gb.add_nodes(g)


data = gb.node_props(g)

bc = pp.BoundaryCondition(g, np.array([0]), np.array(["dir"]))
bc_values = np.zeros(g.num_faces)
bc_values[0] = 1

transport_data = {
    "darcy_flux": np.ones(g.num_faces),
    "bc": bc,
    "bc_values": bc_values,
Exemple #10
0
def _cart_grid_2d(fracs, nx, physdims=None):
    """
    Create grids for a domain with possibly intersecting fractures in 2d.

    Based on lines describing the individual fractures, the method
    constructs grids in 2d (whole domain), 1d (individual fracture), and 0d
    (fracture intersections).

    Parameters
    ----------
    fracs (list of np.ndarray, each 2x2): Vertexes of the line for each
        fracture. The fracture lines must align to the coordinat axis.
        The fractures will snap to the closest grid nodes.
    nx (np.ndarray): Number of cells in each direction. Should be 2D.
    physdims (np.ndarray): Physical dimensions in each direction.
        Defaults to same as nx, that is, cells of unit size.

    Returns
    -------
    list (length 3): For each dimension (2 -> 0), a list of all grids in
        that dimension.

    Examples
    --------
    frac1 = np.array([[1, 4], [2, 2]])
    frac2 = np.array([[2, 2], [1, 4]])
    fracs = [frac1, frac2]
    gb = cart_grid_2d(fracs, [5, 5])
    """
    nx = np.asarray(nx)
    if physdims is None:
        physdims = nx
    elif np.asarray(physdims).size != nx.size:
        raise ValueError("Physical dimension must equal grid dimension")
    else:
        physdims = np.asarray(physdims)

    g_2d = pp.CartGrid(nx, physdims=physdims)
    g_2d.global_point_ind = np.arange(g_2d.num_nodes)
    g_2d.compute_geometry()
    g_1d = []
    g_0d = []

    # 1D grids:
    shared_nodes = np.zeros(g_2d.num_nodes)
    for f in fracs:
        is_x_frac = f[1, 0] == f[1, 1]
        is_y_frac = f[0, 0] == f[0, 1]
        assert is_x_frac != is_y_frac, "Fracture must align to x- or y-axis"
        if f.shape[0] == 2:
            f = np.vstack((f, np.zeros(f.shape[1])))
        nodes = _find_nodes_on_line(g_2d, nx, f[:, 0], f[:, 1])
        # nodes = np.unique(nodes)
        loc_coord = g_2d.nodes[:, nodes]
        g = mesh_2_grid.create_embedded_line_grid(loc_coord, nodes)
        g_1d.append(g)
        shared_nodes[nodes] += 1

    # Create 0-D grids
    if np.any(shared_nodes > 1):
        for global_node in np.argwhere(shared_nodes > 1).ravel():
            g = pp.PointGrid(g_2d.nodes[:, global_node])
            g.global_point_ind = np.asarray(global_node)
            g_0d.append(g)

    grids = [[g_2d], g_1d, g_0d]
    return grids
Exemple #11
0
    def test_3d_coarse_dims_specified_unequal_size(self):
        g = pp.CartGrid(np.array([6, 5, 4]))
        coarse_dims = np.array([3, 2, 2])

        p = pp.partition.partition_structured(g, coarse_dims)
        # This just happens to be correct
        p_known = np.array([
            0,
            0,
            1,
            1,
            2,
            2,
            0,
            0,
            1,
            1,
            2,
            2,
            3,
            3,
            4,
            4,
            5,
            5,
            3,
            3,
            4,
            4,
            5,
            5,
            3,
            3,
            4,
            4,
            5,
            5,
            0,
            0,
            1,
            1,
            2,
            2,
            0,
            0,
            1,
            1,
            2,
            2,
            3,
            3,
            4,
            4,
            5,
            5,
            3,
            3,
            4,
            4,
            5,
            5,
            3,
            3,
            4,
            4,
            5,
            5,
            6,
            6,
            7,
            7,
            8,
            8,
            6,
            6,
            7,
            7,
            8,
            8,
            9,
            9,
            10,
            10,
            11,
            11,
            9,
            9,
            10,
            10,
            11,
            11,
            9,
            9,
            10,
            10,
            11,
            11,
            6,
            6,
            7,
            7,
            8,
            8,
            6,
            6,
            7,
            7,
            8,
            8,
            9,
            9,
            10,
            10,
            11,
            11,
            9,
            9,
            10,
            10,
            11,
            11,
            9,
            9,
            10,
            10,
            11,
            11,
        ])

        self.assertTrue(np.allclose(p, p_known))
Exemple #12
0
def _cart_grid_3d(fracs, nx, physdims=None):
    """
    Create grids for a domain with possibly intersecting fractures in 3d.

    Based on rectangles describing the individual fractures, the method
    constructs grids in 3d (the whole domain), 2d (one for each individual
    fracture), 1d (along fracture intersections), and 0d (meeting between
    intersections).

    Parameters
    ----------
    fracs (list of np.ndarray, each 3x4): Vertexes in the rectangle for each
        fracture. The vertices must be sorted and aligned to the axis.
        The fractures will snap to the closest grid faces.
    nx (np.ndarray): Number of cells in each direction. Should be 3D.
    physdims (np.ndarray): Physical dimensions in each direction.
        Defaults to same as nx, that is, cells of unit size.

    Returns
    -------
    list (length 4): For each dimension (3 -> 0), a list of all grids in
        that dimension.

    Examples
    --------
    frac1 = np.array([[1, 1, 4, 4], [1, 4, 4, 1], [2, 2, 2, 2]])
    frac2 = np.array([[2, 2, 2, 2], [1, 1, 4, 4], [1, 4, 4, 1]])
    fracs = [frac1, frac2]
    gb = cart_grid_3d(fracs, [5, 5, 5])
    """

    nx = np.asarray(nx)
    if physdims is None:
        physdims = nx
    elif np.asarray(physdims).size != nx.size:
        raise ValueError("Physical dimension must equal grid dimension")
    else:
        physdims = np.asarray(physdims)

    # We create a 3D cartesian grid. The global node mapping is trivial.
    g_3d = pp.CartGrid(nx, physdims=physdims)
    g_3d.global_point_ind = np.arange(g_3d.num_nodes)
    g_3d.compute_geometry()
    g_2d = []
    g_1d = []
    g_0d = []
    # We set the tolerance for finding points in a plane. This can be any
    # small number, that is smaller than .25 of the cell sizes.
    tol = 0.1 * physdims / nx

    # Create 2D grids
    for fi, f in enumerate(fracs):
        assert np.all(f.shape == (3, 4)), "fractures must have shape [3,4]"
        is_xy_frac = np.allclose(f[2, 0], f[2])
        is_xz_frac = np.allclose(f[1, 0], f[1])
        is_yz_frac = np.allclose(f[0, 0], f[0])
        assert (is_xy_frac + is_xz_frac +
                is_yz_frac == 1), "Fracture must align to x-, y- or z-axis"
        # snap to grid
        f_s = (np.round(f * nx[:, np.newaxis] / physdims[:, np.newaxis]) *
               physdims[:, np.newaxis] / nx[:, np.newaxis])
        if is_xy_frac:
            flat_dim = [2]
            active_dim = [0, 1]
        elif is_xz_frac:
            flat_dim = [1]
            active_dim = [0, 2]
        else:
            flat_dim = [0]
            active_dim = [1, 2]
        # construct normal vectors. If the rectangle is ordered
        # clockwise we need to flip the normals so they point
        # outwards.
        sign = 2 * pp.geometry_property_checks.is_ccw_polygon(
            f_s[active_dim]) - 1
        tangent = f_s.take(np.arange(f_s.shape[1]) + 1, axis=1,
                           mode="wrap") - f_s
        normal = tangent
        normal[active_dim] = tangent[active_dim[1::-1]]
        normal[active_dim[1]] = -normal[active_dim[1]]
        normal = sign * normal
        # We find all the faces inside the convex hull defined by the
        # rectangle. To find the faces on the fracture plane, we remove any
        # faces that are further than tol from the snapped fracture plane.
        in_hull = pp.utils.half_space.half_space_int(normal, f_s,
                                                     g_3d.face_centers)
        f_tag = np.logical_and(
            in_hull,
            np.logical_and(
                f_s[flat_dim, 0] - tol[flat_dim] <=
                g_3d.face_centers[flat_dim],
                g_3d.face_centers[flat_dim] < f_s[flat_dim, 0] + tol[flat_dim],
            ),
        )
        f_tag = f_tag.ravel()
        nodes = sps.find(g_3d.face_nodes[:, f_tag])[0]
        nodes = np.unique(nodes)
        loc_coord = g_3d.nodes[:, nodes]
        g = _create_embedded_2d_grid(loc_coord, nodes)

        g.frac_num = fi
        g_2d.append(g)

    # Create 1D grids:
    # Here we make use of the network class to find the intersection of
    # fracture planes. We could maybe avoid this by doing something similar
    # as for the 2D-case, and count the number of faces belonging to each edge,
    # but we use the FractureNetwork class for now.
    frac_list = []
    for f in fracs:
        frac_list.append(pp.Fracture(f))
    # Combine the fractures into a network
    network = pp.FractureNetwork3d(frac_list)
    # Impose domain boundary. For the moment, the network should be immersed in
    # the domain, or else gmsh will complain.
    box = {
        "xmin": 0,
        "ymin": 0,
        "zmin": 0,
        "xmax": physdims[0],
        "ymax": physdims[1],
        "zmax": physdims[2],
    }
    network.impose_external_boundary(box)

    # Find intersections and split them.
    network.find_intersections()
    network.split_intersections()

    # Extract geometrical network information.
    pts = network.decomposition["points"]
    edges = network.decomposition["edges"]
    poly = network._poly_2_segment()
    # And tags identifying points and edges corresponding to normal
    # fractures, domain boundaries and subdomain boundaries. Only the
    # entities corresponding to normal fractures should actually be gridded.

    # TODO: Constraints have not been implemented for structured DFM grids.
    # Simply pass nothing for now, not sure how do deal with this, or if it at all is
    # meaningful.
    edge_tags, _, _ = network._classify_edges(poly, [])

    const = constants.GmshConstants()
    auxiliary_points, edge_tags = network._on_domain_boundary(edges, edge_tags)
    bound_and_aux = np.array([const.DOMAIN_BOUNDARY_TAG, const.AUXILIARY_TAG])

    # From information of which lines are internal, we can find intersection points.
    # This part will become more elaborate if we introduce constraints, see the
    # FractureNetwork3d class.

    # Find all points on fracture intersection lines
    isect_p = edges[:,
                    edge_tags == const.FRACTURE_INTERSECTION_LINE_TAG].ravel()
    # Count the number of occurences
    num_occ_pt = np.bincount(isect_p)
    # Intersection poitns if
    intersection_points = np.where(num_occ_pt > 1)[0]

    edges = np.vstack((edges, edge_tags))

    # Loop through the edges to make 1D grids. Ommit the auxiliary edges.
    for e in np.ravel(
            np.where(edges[2] == const.FRACTURE_INTERSECTION_LINE_TAG)):
        # We find the start and end point of each fracture intersection (1D
        # grid) and then the corresponding global node index.
        if np.isin(edge_tags[e], bound_and_aux):
            continue
        s_pt = pts[:, edges[0, e]]
        e_pt = pts[:, edges[1, e]]
        nodes = _find_nodes_on_line(g_3d, nx, s_pt, e_pt)
        loc_coord = g_3d.nodes[:, nodes]
        assert (loc_coord.shape[1] > 1), "1d grid in intersection should span\
            more than one node"

        g = mesh_2_grid.create_embedded_line_grid(loc_coord, nodes)
        g_1d.append(g)

    # Create 0D grids
    # Here we also use the intersection information from the FractureNetwork
    # class. No grids for auxiliary points.
    for p in intersection_points:
        if auxiliary_points[p] == const.DOMAIN_BOUNDARY_TAG:
            continue
        node = np.argmin(pp.distances.point_pointset(pts[:, p], g_3d.nodes))
        assert np.allclose(g_3d.nodes[:, node], pts[:, p])
        g = pp.PointGrid(g_3d.nodes[:, node])
        g.global_point_ind = np.asarray(node)
        g_0d.append(g)

    grids = [[g_3d], g_2d, g_1d, g_0d]
    return grids
Exemple #13
0
 def test_get_internal_nodes_empty(self):
     g = pp.CartGrid([2, 1])
     int_nodes = g.get_internal_nodes()
     self.assertTrue(int_nodes.size == 0)
Exemple #14
0
 def test_get_internal_nodes_cart(self):
     g = pp.CartGrid([2, 2])
     int_nodes = g.get_internal_nodes()
     self.assertTrue(int_nodes.size == 1)
     self.assertTrue(int_nodes[0] == 4)
def conv_test(n):

    # Analytical solution
    def mandel_solution(g, Nx, Ny, times, F, B, nu_u, nu, c_f, mu_s):

        # Some needed parameters
        a = np.max(g.face_centers[0])  # a = Lx
        x_cntr = g.cell_centers[0][:Nx]  # [m] vector of x-centers
        y_cntr = g.cell_centers[1][::Nx]  # [m] vector of y-centers

        # Solutions to tan(x) - ((1-nu)/(nu_u-nu)) x = 0
        """
        This is somehow tricky, we have to solve the equation numerically in order to
        find all the positive solutions to the equation. Later we will use them to 
        compute the infinite sums. Experience has shown that 200 roots are more than enough to
        achieve accurate results. Note that we find the roots using the bisection method.
        """
        f = lambda x: np.tan(x) - (
            (1 - nu) /
            (nu_u - nu)) * x  # define the algebraic eq. as a lambda function
        n_series = 200  # number of roots
        a_n = np.zeros(n_series)  # initializing roots array
        x0 = 0  # initial point
        for i in range(0, len(a_n)):
            a_n[i] = opt.bisect(
                f,  # function
                x0 + np.pi / 4,  # left point 
                x0 + np.pi / 2 -
                10000 * 2.2204e-16,  # right point (a tiny bit less than pi/2)
                xtol=1e-30,  # absolute tolerance
                rtol=1e-15  # relative tolerance
            )
            x0 += np.pi  # apply a phase change of pi to get the next root

        # Creating dictionary to store analytical solutions
        mandel_sol = dict()
        mandel_sol['p'] = np.zeros((len(times), len(x_cntr)))
        mandel_sol['u_x'] = np.zeros((len(times), len(x_cntr)))
        mandel_sol['u_y'] = np.zeros((len(times), len(y_cntr)))
        mandel_sol['sigma_yy'] = np.zeros((len(times), len(x_cntr)))

        # Terms needed to compute the solutions (these are constants)
        p0 = (2 * F * B * (1 + nu_u)) / (3 * a)
        ux0_1 = ((F * nu) / (2 * mu_s * a))
        ux0_2 = -((F * nu_u) / (mu_s * a))
        ux0_3 = F / mu_s
        uy0_1 = (-F * (1 - nu)) / (2 * mu_s * a)
        uy0_2 = (F * (1 - nu_u) / (mu_s * a))
        sigma0_1 = -F / a
        sigma0_2 = (-2 * F * B * (nu_u - nu)) / (a * (1 - nu))
        sigma0_3 = (2 * F) / a

        # Saving solutions for the initial conditions
        mandel_sol['p'][0] = ((F * B * (1 + nu_u)) / (3 * a)) * np.ones(Nx)
        mandel_sol['u_x'][0] = (F * nu_u * x_cntr) / (2 * mu_s * a)
        mandel_sol['u_y'][0] = ((-F * (1 - nu_u)) / (2 * mu_s * a)) * y_cntr

        # Storing solutions for the subsequent time steps
        for ii in range(1, len(times)):

            # Analytical Pressures
            p_sum = 0
            for n in range(len(a_n)):
                p_sum += (((np.sin(a_n[n])) /
                           (a_n[n] - (np.sin(a_n[n]) * np.cos(a_n[n])))) *
                          (np.cos((a_n[n] * x_cntr) / a) - np.cos(a_n[n])) *
                          np.exp((-(a_n[n]**2) * c_f * times[ii]) / (a**2)))

            mandel_sol['p'][ii] = p0 * p_sum

            # Analytical horizontal displacements
            ux_sum1 = 0
            ux_sum2 = 0
            for n in range(len(a_n)):
                ux_sum1 += ((np.sin(a_n[n]) * np.cos(a_n[n])) /
                            (a_n[n] - np.sin(a_n[n]) * np.cos(a_n[n])) *
                            np.exp((-(a_n[n]**2) * c_f * times[ii]) / (a**2)))
                ux_sum2 += ((np.cos(a_n[n]) /
                             (a_n[n] - (np.sin(a_n[n]) * np.cos(a_n[n])))) *
                            np.sin(a_n[n] * (x_cntr / a)) * np.exp(
                                (-(a_n[n]**2) * c_f * times[ii]) / (a**2)))
            mandel_sol['u_x'][ii] = (
                ux0_1 + ux0_2 * ux_sum1) * x_cntr + ux0_3 * ux_sum2

            # Analytical vertical displacements
            uy_sum = 0
            for n in range(len(a_n)):
                uy_sum += (((np.sin(a_n[n]) * np.cos(a_n[n])) /
                            (a_n[n] - np.sin(a_n[n]) * np.cos(a_n[n]))) *
                           np.exp((-(a_n[n]**2) * c_f * times[ii]) / (a**2)))
            mandel_sol['u_y'][ii] = (uy0_1 + uy0_2 * uy_sum) * y_cntr

            # Analitical vertical stress
            sigma_sum1 = 0
            sigma_sum2 = 0
            for n in range(len(a_n)):
                sigma_sum1 += (((np.sin(a_n[n])) /
                                (a_n[n] - (np.sin(a_n[n]) * np.cos(a_n[n])))) *
                               np.cos(a_n[n] * (x_cntr / a)) * np.exp(
                                   (-(a_n[n]**2) * c_f * times[ii]) / (a**2)))
                sigma_sum2 += (((np.sin(a_n[n]) * np.cos(a_n[n])) /
                                (a_n[n] - np.sin(a_n[n]) * np.cos(a_n[n]))) *
                               np.exp(
                                   (-(a_n[n]**2) * c_f * times[ii]) / (a**2)))
            mandel_sol['sigma_yy'][ii] = (sigma0_1 + sigma0_2 * sigma_sum1) + (
                sigma0_3 * sigma_sum2)

        return mandel_sol

    # Computing the initial condition

    def get_mandel_init_cond(g, F, B, nu_u, mu_s):

        # Initialing pressure and displacement arrays
        p0 = np.zeros(g.num_cells)
        u0 = np.zeros(g.num_cells * 2)

        # Some needed parameters
        a = np.max(g.face_centers[0])  # a = Lx

        p0 = ((F * B * (1 + nu_u)) / (3 * a)) * np.ones(g.num_cells)
        u0[::2] = (F * nu_u * g.cell_centers[0]) / (2 * mu_s * a)
        u0[1::2] = ((-F * (1 - nu_u)) / (2 * mu_s * a)) * g.cell_centers[1]

        return p0, u0

    # Getting the time-dependent boundary condition

    def get_mandel_bc(g, y_max, times, F, B, nu_u, nu, c_f, mu_s):

        # Initializing top boundary array
        u_top = np.zeros((len(times), len(y_max)))

        # Some needed parameters
        a = np.max(g.face_centers[0])  # a = Lx
        b = np.max(g.face_centers[1])  # b = Ly
        y_top = g.face_centers[1][
            y_max]  # [m] y-coordinates at the top boundary

        # Solutions to tan(x) - ((1-nu)/(nu_u-nu)) x = 0
        """
        This is somehow tricky, we have to solve the equation numerically in order to
        find all the positive solutions to the equation. Later we will use them to 
        compute the infinite sums. Experience has shown that 200 roots are more than enough to
        achieve accurate results. Note that we find the roots using the bisection method.
        """
        f = lambda x: np.tan(x) - (
            (1 - nu) /
            (nu_u - nu)) * x  # define the algebraic eq. as a lambda function
        n_series = 200  # number of roots
        a_n = np.zeros(n_series)  # initializing roots array
        x0 = 0  # initial point
        for i in range(0, len(a_n)):
            a_n[i] = opt.bisect(
                f,  # function
                x0 + np.pi / 4,  # left point 
                x0 + np.pi / 2 -
                10000 * 2.2204e-16,  # right point (a tiny bit less than pi/2)
                xtol=1e-30,  # absolute tolerance
                rtol=1e-15  # relative tolerance
            )
            x0 += np.pi  # apply a phase change of pi to get the next root

        # Terms needed to compute the solutions (these are constants)
        uy0_1 = (-F * (1 - nu)) / (2 * mu_s * a)
        uy0_2 = (F * (1 - nu_u) / (mu_s * a))

        # For the initial condition:
        u_top[0] = ((-F * (1 - nu_u)) / (2 * mu_s * a)) * b

        for i in range(1, len(times)):
            # Analytical vertical displacements at the top boundary
            uy_sum = 0
            for n in range(len(a_n)):
                uy_sum += (((np.sin(a_n[n]) * np.cos(a_n[n])) /
                            (a_n[n] - np.sin(a_n[n]) * np.cos(a_n[n]))) *
                           np.exp((-(a_n[n]**2) * c_f * times[i]) / (a**2)))

            u_top[i] = (uy0_1 + uy0_2 * uy_sum) * y_top

        # Returning array of u_y at the top boundary
        return u_top

    # Getting mechanics boundary conditions

    def get_bc_mechanics(g, u_top, times, b_faces, x_min, x_max, west, east,
                         y_min, y_max, south, north):

        # Setting the tags at each boundary side for the mechanics problem
        labels_mech = np.array([None] * b_faces.size)
        labels_mech[west] = 'dir_x'  # roller
        labels_mech[east] = 'neu'  # traction free
        labels_mech[south] = 'dir_y'  # roller
        labels_mech[
            north] = 'dir_y'  # roller (with non-zero displacement in the vertical direction)

        # Constructing the bc object for the mechanics problem
        bc_mech = pp.BoundaryConditionVectorial(g, b_faces, labels_mech)

        # Constructing the boundary values array for the mechanics problem
        bc_val_mech = np.zeros((
            len(times),
            g.num_faces * g.dim,
        ))

        for i in range(len(times)):

            # West side boundary conditions (mech)
            bc_val_mech[i][2 * x_min] = 0  # [m]
            bc_val_mech[i][2 * x_min + 1] = 0  # [Pa]

            # East side boundary conditions (mech)
            bc_val_mech[i][2 * x_max] = 0  # [Pa]
            bc_val_mech[i][2 * x_max + 1] = 0  # [Pa]

            # South Side boundary conditions (mech)
            bc_val_mech[i][2 * y_min] = 0  # [Pa]
            bc_val_mech[i][2 * y_min + 1] = 0  # [m]

            # North Side boundary conditions (mech)
            bc_val_mech[i][2 * y_max] = 0  # [Pa]
            bc_val_mech[i][2 * y_max + 1] = u_top[i]  # [m]

        return bc_mech, bc_val_mech

    # Getting flow boundary conditions

    def get_bc_flow(g, b_faces, x_min, x_max, west, east, y_min, y_max, south,
                    north):

        # Setting the tags at each boundary side for the mechanics problem
        labels_flow = np.array([None] * b_faces.size)
        labels_flow[west] = 'neu'  # no flow
        labels_flow[east] = 'dir'  # constant pressure
        labels_flow[south] = 'neu'  # no flow
        labels_flow[north] = 'neu'  # no flow

        # Constructing the bc object for the flow problem
        bc_flow = pp.BoundaryCondition(g, b_faces, labels_flow)

        # Constructing the boundary values array for the flow problem
        bc_val_flow = np.zeros(g.num_faces)

        # West side boundary condition (flow)
        bc_val_flow[x_min] = 0  # [Pa]

        # East side boundary condition (flow)
        bc_val_flow[x_max] = 0  # [m^3/s]

        # South side boundary condition (flow)
        bc_val_flow[y_min] = 0  # [m^3/s]

        # North side boundary condition (flow)
        bc_val_flow[y_max] = 0  # [m^3/s]

        return bc_flow, bc_val_flow

    # ## Setting up the grid

    # In[7]:

    Nx = 40
    Ny = 40
    Lx = 100
    Ly = 10
    g = pp.CartGrid([Nx, Ny], [Lx, Ly])
    #g.nodes = g.nodes + 1E-7*np.random.randn(3, g.num_nodes)
    g.compute_geometry()
    V = g.cell_volumes

    # Physical parameters

    # Skeleton parameters
    mu_s = 2.475E+09  # [Pa] Shear modulus
    lambda_s = 1.65E+09  # [Pa] Lame parameter
    K_s = (2 / 3) * mu_s + lambda_s  # [Pa] Bulk modulus
    E_s = mu_s * ((9 * K_s) / (3 * K_s + mu_s))  # [Pa] Young's modulus
    nu_s = (3 * K_s - 2 * mu_s) / (2 * (3 * K_s + mu_s)
                                   )  # [-] Poisson's coefficient
    k_s = 100 * 9.869233E-13  # [m^2] Permeabiliy

    # Fluid parameters
    mu_f = 10.0E-3  # [Pa s] Dynamic viscosity

    # Porous medium parameters
    alpha_biot = 1.  # [m^2] Intrinsic permeability
    S_m = 6.0606E-11  # [1/Pa] Specific Storage
    K_u = K_s + (alpha_biot**2) / S_m  # [Pa] Undrained bulk modulus
    B = alpha_biot / (S_m * K_u)  # [-] Skempton's coefficient
    nu_u = (3 * nu_s + B *
            (1 - 2 * nu_s)) / (3 - B *
                               (1 - 2 * nu_s))  # [-] Undrained Poisson's ratio
    c_f = (2 * k_s * (B**2) * mu_s * (1 - nu_s) *
           (1 + nu_u)**2) / (9 * mu_f * (1 - nu_u) *
                             (nu_u - nu_s))  # [m^2/s] Fluid diffusivity

    # Creating second and fourth order tensors

    # Permeability tensor
    perm = pp.SecondOrderTensor(g.dim, k_s * np.ones(g.num_cells))
    # Stiffness matrix
    constit = pp.FourthOrderTensor(g.dim, mu_s * np.ones(g.num_cells),
                                   lambda_s * np.ones(g.num_cells))
    # Time parameters

    t0 = 0  # [s] Initial time
    tf = 100  # [s] Final simulation time
    tLevels = 100  # [-] Time levels
    times = np.linspace(t0, tf, tLevels + 1)  # [s] Vector of time evaluations
    dt = np.diff(times)  # [s] Vector of time steps

    # Boundary conditions pre-processing

    b_faces = g.tags['domain_boundary_faces'].nonzero()[0]

    # Extracting indices of boundary faces w.r.t g
    x_min = b_faces[g.face_centers[0, b_faces] < 0.0001]
    x_max = b_faces[g.face_centers[0, b_faces] > 0.9999 * Lx]
    y_min = b_faces[g.face_centers[1, b_faces] < 0.0001]
    y_max = b_faces[g.face_centers[1, b_faces] > 0.9999 * Ly]

    # Extracting indices of boundary faces w.r.t b_faces
    west = np.in1d(b_faces, x_min).nonzero()
    east = np.in1d(b_faces, x_max).nonzero()
    south = np.in1d(b_faces, y_min).nonzero()
    north = np.in1d(b_faces, y_max).nonzero()

    # Applied load and top boundary condition
    F_load = 6.8E+8  # [N/m] Applied load
    u_top = get_mandel_bc(g, y_max, times, F_load, B, nu_u, nu_s, c_f,
                          mu_s)  # [m] Vector of imposed vertical displacements

    # MECHANICS BOUNDARY CONDITIONS
    bc_mech, bc_val_mech = get_bc_mechanics(g, u_top, times, b_faces, x_min,
                                            x_max, west, east, y_min, y_max,
                                            south, north)
    # FLOW BOUNDARY CONDITIONS
    bc_flow, bc_val_flow = get_bc_flow(g, b_faces, x_min, x_max, west, east,
                                       y_min, y_max, south, north)

    # Initialiazing solution and solver dicitionaries

    # Solution dictionary
    sol = dict()
    sol['time'] = np.zeros(tLevels + 1, dtype=float)
    sol['displacement'] = np.zeros((tLevels + 1, g.num_cells * g.dim),
                                   dtype=float)
    sol['displacement_faces'] = np.zeros(
        (tLevels + 1, g.num_faces * g.dim * 2), dtype=float)
    sol['pressure'] = np.zeros((tLevels + 1, g.num_cells), dtype=float)
    sol['traction'] = np.zeros((tLevels + 1, g.num_faces * g.dim), dtype=float)
    sol['flux'] = np.zeros((tLevels + 1, g.num_faces), dtype=float)
    sol['iter'] = np.array([], dtype=int)
    sol['time_step'] = np.array([], dtype=float)
    sol['residual'] = np.array([], dtype=float)

    # Solver dictionary
    newton_param = dict()
    newton_param['tol'] = 1E-6  # maximum tolerance
    newton_param['max_iter'] = 20  # maximum number of iterations
    newton_param['res_norm'] = 1000  # initializing residual
    newton_param['iter'] = 1  # iteration

    # Discrete operators and discrete equations

    # Flow operators

    F = lambda x: biot_F * x  # Flux operator
    boundF = lambda x: biot_boundF * x  # Bound Flux operator
    compat = lambda x: biot_compat * x  # Compatibility operator (Stabilization term)
    divF = lambda x: biot_divF * x  # Scalar divergence operator

    # Mechanics operators

    S = lambda x: biot_S * x  # Stress operator
    boundS = lambda x: biot_boundS * x  # Bound Stress operator
    divU = lambda x: biot_divU * x  # Divergence of displacement field
    divS = lambda x: biot_divS * x  # Vector divergence operator
    gradP = lambda x: biot_divS * biot_gradP * x  # Pressure gradient operator
    boundDivU = lambda x: biot_boundDivU * x  # Bound Divergence of displacement operator
    boundUCell = lambda x: biot_boundUCell * x  # Contribution of displacement at cells -> Face displacement
    boundUFace = lambda x: biot_boundUFace * x  # Contribution of bc_mech at the boundaries -> Face displacement
    boundUPressure = lambda x: biot_boundUPressure * x  # Contribution of pressure at cells -> Face displacement

    # Discrete equations

    # Generalized Hooke's law
    T = lambda u, bc_val_mech: S(u) + boundS(bc_val_mech)

    # Momentum conservation equation (I)
    u_eq1 = lambda u, bc_val_mech: divS(T(u, bc_val_mech))

    # Momentum conservation equation (II)
    u_eq2 = lambda p: -gradP(p)

    # Darcy's law
    Q = lambda p: (1. / mu_f) * (F(p) + boundF(bc_val_flow))

    # Mass conservation equation (I)
    p_eq1 = lambda u, u_n, bc_val_mech, bc_val_mech_n: alpha_biot * (divU(
        u - u_n) + boundDivU(bc_val_mech - bc_val_mech_n))

    # Mass conservation equation (II)
    p_eq2 = lambda p, p_n, dt: (p - p_n) * S_m * V + divF(Q(
        p)) * dt + alpha_biot * compat(p - p_n)

    # Creating AD variables

    # Retrieve initial conditions
    p_init, u_init = get_mandel_init_cond(g, F_load, B, nu_u, mu_s)

    # Create displacement AD-variable
    u_ad = Ad_array(u_init.copy(), sps.diags(np.ones(g.num_cells * g.dim)))

    # Create pressure AD-variable
    p_ad = Ad_array(p_init.copy(), sps.diags(np.ones(g.num_cells)))

    # The time loop

    tt = 0  # time counter

    while times[tt] < times[-1]:

        ################################
        # Initializing data dictionary #
        ################################

        d = dict()  # initialize dictionary to store data

        ################################
        #  Creating the data objects   #
        ################################

        # Mechanics data object
        specified_parameters_mech = {
            "fourth_order_tensor": constit,
            "bc": bc_mech,
            "biot_alpha": 1.,
            "bc_values": bc_val_mech[tt],
            "mass_weight": S_m
        }

        pp.initialize_default_data(g, d, "mechanics",
                                   specified_parameters_mech)

        # Flow data object
        specified_parameters_flow = {
            "second_order_tensor": perm,
            "bc": bc_flow,
            "biot_alpha": 1.,
            "bc_values": bc_val_flow,
            "mass_weight": S_m,
            "time_step": dt[tt - 1]
        }

        pp.initialize_default_data(g, d, "flow", specified_parameters_flow)

        ################################
        #  CALLING MPFA/MPSA ROUTINES  #
        ################################

        # Biot discretization
        solver_biot = pp.Biot("mechanics", "flow")
        solver_biot.discretize(g, d)

        # Mechanics discretization matrices
        biot_S = d['discretization_matrices']['mechanics']['stress']
        biot_boundS = d['discretization_matrices']['mechanics']['bound_stress']
        biot_divU = d['discretization_matrices']['mechanics']['div_d']
        biot_gradP = d['discretization_matrices']['mechanics']['grad_p']
        biot_boundDivU = d['discretization_matrices']['mechanics'][
            'bound_div_d']
        biot_boundUCell = d['discretization_matrices']['mechanics'][
            'bound_displacement_cell']
        biot_boundUFace = d['discretization_matrices']['mechanics'][
            'bound_displacement_face']
        biot_boundUPressure = d['discretization_matrices']['mechanics'][
            'bound_displacement_pressure']
        biot_divS = pp.fvutils.vector_divergence(g)

        # Flow discretization matrices
        biot_F = d['discretization_matrices']['flow']['flux']
        biot_boundF = d['discretization_matrices']['flow']['bound_flux']
        biot_compat = d['discretization_matrices']['flow'][
            'biot_stabilization']
        biot_divF = pp.fvutils.scalar_divergence(g)

        ################################
        #  Saving Initial Condition    #
        ################################

        if times[tt] == 0:
            sol['pressure'][tt] = p_ad.val
            sol['displacement'][tt] = u_ad.val
            sol['displacement_faces'][tt] = (
                boundUCell(sol['displacement'][tt]) +
                boundUFace(bc_val_mech[tt]) +
                boundUPressure(sol['pressure'][tt]))
            sol['time'][tt] = times[tt]
            sol['traction'][tt] = T(u_ad.val, bc_val_mech[tt])
            sol['flux'][tt] = Q(p_ad.val)

        tt += 1  # increasing time counter

        ################################
        #  Solving the set of PDE's    #
        ################################

        # Displacement and pressure at the previous time step
        u_n = u_ad.val.copy()
        p_n = p_ad.val.copy()

        # Updating residual and iteration at each time step
        newton_param.update({'res_norm': 1000, 'iter': 1})

        # Newton loop
        while newton_param['res_norm'] > newton_param['tol'] and newton_param[
                'iter'] <= newton_param['max_iter']:

            # Calling equations
            eq1 = u_eq1(u_ad, bc_val_mech[tt])
            eq2 = u_eq2(p_ad)
            eq3 = p_eq1(u_ad, u_n, bc_val_mech[tt], bc_val_mech[tt - 1])
            eq4 = p_eq2(p_ad, p_n, dt[tt - 1])

            # Assembling Jacobian of the coupled system
            J_mech = np.hstack(
                (eq1.jac, eq2.jac))  # Jacobian blocks (mechanics)
            J_flow = np.hstack((eq3.jac, eq4.jac))  # Jacobian blocks (flow)
            J = sps.bmat(np.vstack((J_mech, J_flow)),
                         format='csc')  # Jacobian (coupled)

            # Determining residual of the coupled system
            R_mech = eq1.val + eq2.val  # Residual (mechanics)
            R_flow = eq3.val + eq4.val  # Residual (flow)
            R = np.hstack((R_mech, R_flow))  # Residual (coupled)

            y = sps.linalg.spsolve(J, -R)  #
            u_ad.val = u_ad.val + y[:g.dim * g.num_cells]  # Newton update
            p_ad.val = p_ad.val + y[g.dim * g.num_cells:]  #

            newton_param['res_norm'] = np.linalg.norm(R)  # Updating residual

            if newton_param['res_norm'] <= newton_param[
                    'tol'] and newton_param['iter'] <= newton_param['max_iter']:
                print('Iter: {} \t Error: {:.8f} [m]'.format(
                    newton_param['iter'], newton_param['res_norm']))
            elif newton_param['iter'] > newton_param['max_iter']:
                print('Error: Newton method did not converge!')
            else:
                newton_param['iter'] += 1

        ################################
        #      Saving the variables    #
        ################################
        sol['iter'] = np.concatenate(
            (sol['iter'], np.array([newton_param['iter']])))
        sol['residual'] = np.concatenate(
            (sol['residual'], np.array([newton_param['res_norm']])))
        sol['time_step'] = np.concatenate((sol['time_step'], dt))
        sol['pressure'][tt] = p_ad.val
        sol['displacement'][tt] = u_ad.val
        sol['displacement_faces'][tt] = (boundUCell(sol['displacement'][tt]) +
                                         boundUFace(bc_val_mech[tt]) +
                                         boundUPressure(sol['pressure'][tt]))
        sol['time'][tt] = times[tt]
        sol['traction'][tt] = T(u_ad.val, bc_val_mech[tt])
        sol['flux'][tt] = Q(p_ad.val)

    # Calling analytical solution

    sol_mandel = mandel_solution(g, Nx, Ny, times, F_load, B, nu_u, nu_s, c_f,
                                 mu_s)

    # Creating analytical and numerical results arrays

    p_num = (Lx * sol['pressure'][-1][:Nx]) / F
    p_ana = (Lx * sol_mandel['p'][-1]) / F

    # Returning values

    return p_num, p_ana
Exemple #16
0
    def test_dir_neu_rob(self):
        nx = 2
        ny = 1
        g = pp.CartGrid([nx, ny], physdims=[1, 1])
        g.compute_geometry()

        bot = g.face_centers[1] < 1e-10
        top = g.face_centers[1] > 1 - 1e-10
        left = g.face_centers[0] < 1e-10
        right = g.face_centers[0] > 1 - 1e-10

        is_dir = left
        is_neu = top
        is_rob = right + bot

        bnd = pp.BoundaryConditionVectorial(g)
        bnd.is_neu[:] = False

        bnd.is_dir[:, is_dir] = True
        bnd.is_rob[:, is_rob] = True
        bnd.is_neu[:, is_neu] = True

        sc_top = pp.fvutils.SubcellTopology(g)
        bnd = pp.fvutils.boundary_to_sub_boundary(bnd, sc_top)
        bnd_excl = pp.fvutils.ExcludeBoundaries(sc_top, bnd, g.dim)

        rhs = pp.Mpsa("")._create_bound_rhs(bnd, bnd_excl, sc_top, g, True)
        hf2f = pp.fvutils.map_hf_2_f(sc_top.fno_unique, sc_top.subfno_unique,
                                     g.dim)
        rhs = rhs * hf2f.T

        rhs_known = np.array([
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                1.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                1.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 1.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.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, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.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, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
            [
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                0.0, 0.0
            ],
        ])

        self.assertTrue(np.all(np.abs(rhs_known - rhs) < 1e-12))
Exemple #17
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 = pp.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 = pp.SecondOrderTensor(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))
        vc = sps.csr_matrix((g.num_faces, g.num_cells * g.dim))
        faces_covered = np.zeros(g.num_faces, np.bool)

        bnd = pp.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))

            specified_data = {
                "second_order_tensor": perm,
                "bc": bnd,
                "inverter": "python",
                "specified_nodes": nodes,
            }

            keyword = "flow"
            data = pp.initialize_default_data(
                g, {}, keyword, specified_parameters=specified_data)

            discr = pp.Mpfa(keyword)
            discr.discretize(g, data)

            partial_flux = data[pp.DISCRETIZATION_MATRICES][keyword][
                discr.flux_matrix_key]
            partial_bound = data[pp.DISCRETIZATION_MATRICES][keyword][
                discr.bound_flux_matrix_key]
            partial_vector_source = data[pp.DISCRETIZATION_MATRICES][keyword][
                discr.vector_source_matrix_key]

            active_faces = data[pp.PARAMETERS][keyword]["active_faces"]

            if np.any(faces_covered):
                fi = np.where(faces_covered)[0]
                pp.fvutils.remove_nonlocal_contribution(
                    fi, 1, partial_flux, partial_bound, partial_vector_source)

            faces_covered[active_faces] = True

            flux += partial_flux
            bound_flux += partial_bound
            vc += partial_vector_source

        flux_full, bound_flux_full, *_, vc_full, _ = pp.Mpfa(
            "flow")._flux_discretization(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)
        self.assertTrue((vc - vc_full).max() < 1e-8)
        self.assertTrue((vc - vc_full).min() > -1e-8)
Exemple #18
0
    def test_tag_3d_cart(self):
        g = pp.CartGrid([4] * 3, [1] * 3)

        self.assertTrue(
            np.array_equal(g.tags["fracture_faces"], [False] * g.num_faces))
        self.assertTrue(
            np.array_equal(g.tags["fracture_nodes"], [False] * g.num_nodes))
        self.assertTrue(
            np.array_equal(g.tags["tip_faces"], [False] * g.num_faces))
        self.assertTrue(
            np.array_equal(g.tags["tip_nodes"], [False] * g.num_nodes))
        known = np.array(
            [
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                True,
                True,
                True,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                False,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
            ],
            dtype=bool,
        )
        self.assertTrue(np.array_equal(g.tags["domain_boundary_faces"], known))
        known = np.array(
            [
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                False,
                False,
                False,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
                True,
            ],
            dtype=bool,
        )
        self.assertTrue(np.array_equal(g.tags["domain_boundary_nodes"], known))
Exemple #19
0
    def _test_one_cell_a_time_node_keyword(self):
        # EK: this test makes less sense after the notion of partial updates were
        # changed (git commit 41f754940). Decactive the test for now, pending an update
        # of the notion of discretization updates for FV methods.

        # 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 = pp.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 = pp.FourthOrderTensor(mu=mu, lmbda=lmbda)

        nd = g.dim
        nf = g.num_faces
        nc = g.num_cells

        grad_p = sps.csr_matrix((nf * nd, nc))
        div_u = sps.csr_matrix((nc, nc * nd))
        bound_div_u = sps.csr_matrix((nc, nf * nd))
        stab = sps.csr_matrix((nc, nc))
        bound_displacement_pressure = sps.csr_matrix((nf * nd, nc))

        faces_covered = np.zeros(g.num_faces, np.bool)
        cells_covered = np.zeros(g.num_cells, np.bool)

        bnd = pp.BoundaryConditionVectorial(g)
        specified_data = {
            "fourth_order_tensor": stiffness,
            "bc": bnd,
            #            "inverter": "python",
            "biot_alpha": 1,
        }
        keyword_mech = "mechanics"
        keyword_flow = "flow"
        data = pp.initialize_default_data(g, {},
                                          keyword_mech,
                                          specified_parameters=specified_data)
        data = pp.initialize_default_data(g, data, keyword_flow)

        discr = pp.Biot()
        discr.discretize(g, data)

        div_u_full = data[pp.DISCRETIZATION_MATRICES][keyword_flow][
            discr.div_u_matrix_key]
        bound_div_u_full = data[pp.DISCRETIZATION_MATRICES][keyword_flow][
            discr.bound_div_u_matrix_key]
        stab_full = data[pp.DISCRETIZATION_MATRICES][keyword_flow][
            discr.stabilization_matrix_key]
        grad_p_full = data[pp.DISCRETIZATION_MATRICES][keyword_mech][
            discr.grad_p_matrix_key]
        bound_pressure_full = data[pp.DISCRETIZATION_MATRICES][keyword_mech][
            discr.bound_pressure_matrix_key]

        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))

            data[pp.PARAMETERS][keyword_mech]["specified_nodes"] = nodes

            discr.discretize(g, data)

            partial_div_u = data[pp.DISCRETIZATION_MATRICES][keyword_flow][
                discr.div_u_matrix_key]
            partial_bound_div_u = data[pp.DISCRETIZATION_MATRICES][
                keyword_flow][discr.bound_div_u_matrix_key]
            partial_grad_p = data[pp.DISCRETIZATION_MATRICES][keyword_mech][
                discr.grad_p_matrix_key]
            partial_stab = data[pp.DISCRETIZATION_MATRICES][keyword_flow][
                discr.stabilization_matrix_key]
            partial_bound_pressure = data[pp.DISCRETIZATION_MATRICES][
                keyword_mech][discr.bound_pressure_matrix_key]

            active_faces = data[pp.PARAMETERS][keyword_mech]["active_faces"]

            if np.any(faces_covered):
                del_faces = self.expand_indices_nd(
                    np.where(faces_covered)[0], g.dim)
                del_cells = np.where(cells_covered)[0]
                pp.fvutils.remove_nonlocal_contribution(
                    del_cells, 1, partial_div_u, partial_bound_div_u,
                    partial_stab)
                # del_faces is already expanded, set dimension to 1
                pp.fvutils.remove_nonlocal_contribution(
                    del_faces, 1, partial_grad_p, partial_bound_pressure)

            faces_covered[active_faces] = True
            cells_covered[ci] = True

            div_u += partial_div_u
            bound_div_u += partial_bound_div_u
            grad_p += partial_grad_p
            stab += partial_stab
            bound_displacement_pressure += partial_bound_pressure

        self.assertTrue((div_u_full - div_u).max() < 1e-8)
        self.assertTrue((bound_div_u_full - bound_div_u).min() > -1e-8)
        self.assertTrue((grad_p_full - grad_p).max() < 1e-8)
        self.assertTrue((stab_full - stab).min() > -1e-8)
        self.assertTrue(
            (bound_displacement_pressure - bound_pressure_full).min() > -1e-8)
Exemple #20
0
    def test_2d(self):
        """
        The domain consists of a 3x3 mesh.
        Bottom faces are dirichlet
        Left and right faces are rolling along y (dir_x and neu_y)
        Top mid face is rolling along x (neu_x and dir_y)
        Top left and right faces are neumann
        """

        g = pp.CartGrid([3, 3])
        g.compute_geometry()
        nd = g.dim

        dir_x = np.array([0, 3, 4, 7, 8, 11])
        dir_y = np.array([22])
        dir_both = np.array([12, 13, 14])

        bound = pp.BoundaryConditionVectorial(g)

        bound.is_dir[0, dir_x] = True
        bound.is_neu[0, dir_x] = False
        bound.is_dir[1, dir_y] = True
        bound.is_neu[1, dir_y] = False
        bound.is_dir[:, dir_both] = True
        bound.is_neu[:, dir_both] = False

        subcell_topology = pp.fvutils.SubcellTopology(g)
        # Move the boundary conditions to sub-faces
        bound.is_dir = bound.is_dir[:, subcell_topology.fno_unique]
        bound.is_rob = bound.is_rob[:, subcell_topology.fno_unique]
        bound.is_neu = bound.is_neu[:, subcell_topology.fno_unique]
        bound.robin_weight = bound.robin_weight[:, :,
                                                subcell_topology.fno_unique]
        bound.basis = bound.basis[:, :, subcell_topology.fno_unique]

        # Obtain the face number for each coordinate
        subfno = subcell_topology.subfno_unique
        subfno_nd = np.tile(subfno,
                            (nd, 1)) * nd + np.atleast_2d(np.arange(0, nd)).T

        bound_exclusion = pp.fvutils.ExcludeBoundaries(subcell_topology, bound,
                                                       nd)

        # expand the indices
        # Define right hand side for Neumann boundary conditions
        # First row indices in rhs matrix
        # Pick out the subface indices
        subfno_neu = bound_exclusion.exclude_robin_dirichlet(
            subfno_nd.ravel("C")).ravel("F")
        # Pick out the Neumann boundary

        is_neu_nd = (bound_exclusion.exclude_robin_dirichlet(
            bound.is_neu.ravel("C")).ravel("F").astype(np.bool))

        neu_ind = np.argsort(subfno_neu)
        neu_ind = neu_ind[is_neu_nd[neu_ind]]

        self.assertTrue(
            np.alltrue(neu_ind == [
                30,
                31,
                36,
                37,
                38,
                39,
                44,
                45,
                46,
                47,
                52,
                53,
                24,
                66,
                25,
                67,
                26,
                27,
                28,
                68,
                29,
                69,
            ]))

        subfno_dir = bound_exclusion.exclude_neumann_robin(
            subfno_nd.ravel("C")).ravel("F")
        is_dir_nd = (bound_exclusion.exclude_neumann_robin(
            bound.is_dir.ravel("C")).ravel("F").astype(np.bool))

        dir_ind = np.argsort(subfno_dir)
        dir_ind = dir_ind[is_dir_nd[dir_ind]]

        self.assertTrue(
            np.alltrue(dir_ind == [
                0,
                1,
                6,
                7,
                8,
                9,
                14,
                15,
                16,
                17,
                22,
                23,
                24,
                54,
                25,
                55,
                26,
                56,
                27,
                57,
                28,
                58,
                29,
                59,
                72,
                73,
            ]))
 def test_overlap_1_layer(self):
     g = pp.CartGrid([5, 5])
     ci = np.array([0, 1, 5, 6])
     ci_overlap = np.array([0, 1, 2, 5, 6, 7, 10, 11, 12])
     assert np.array_equal(pp.partition.overlap(g, ci, 1), ci_overlap)
    r1 = np.ravel(np.argwhere((g.nodes[0] < domain[0] - 1e-10) & (g.nodes[0] > 1e-10) & (g.nodes[1] < hi - alpha) & (g.nodes[1] > 1e-10)))
    r2 = np.ravel(np.argwhere((g.nodes[0] < domain[0] - 1e-10) & (g.nodes[0] > 1e-10) & (g.nodes[1] < ht - 1e-10) & (g.nodes[1] > hi + alpha)))
    #r3 = np.ravel(np.argwhere((g.nodes[0] < 1 - 1e-10) & (g.nodes[0] > 1e-10) & (g.nodes[1] < 0.75 - 1e-10) & (g.nodes[1] > 0.5 + 1e-10)))
    #r4 = np.ravel(np.argwhere((g.nodes[0] < 1 - 1e-10) & (g.nodes[0] > 1e-10) & (g.nodes[1] < 1.0 - 1e-10) & (g.nodes[1] > 0.75 + 1e-10)))
    pert_nodes = np.concatenate((r1, r2))
    npertnodes = pert_nodes.size
    rand = np.vstack((np.random.rand(g.dim, npertnodes), np.repeat(0., npertnodes)))
    g.nodes[:,pert_nodes] += rate * dx * (rand - 0.5)
    # Ensure there are no perturbations in the z-coordinate
    if g.dim == 2:
        g.nodes[2, :] = 0

    np.random.seed(42)
    return g

g = pp.CartGrid(grid_dims, domain)

dx = np.max(domain / grid_dims)
alpha = 0.5 * dx

if pert != 0:
    g = perturb(g, pert, dx, alpha)

g.compute_geometry()

t, s, p, q = solve_two_phase_flow_upwind(g)

# Create a workbook and add a worksheet.
workbook = xlsxwriter.Workbook('upwind_hperm_n64.xlsx')
worksheet = workbook.add_worksheet()
 def setup(self):
     g = pp.CartGrid([4, 4])
     p = pp.partition.partition_structured(g, np.array([2, 2]))
     return g, p
    def test_cart_2d(self):
        nx = 1
        ny = 1
        g = pp.CartGrid([nx, ny], physdims=[2, 2])
        g.compute_geometry()
        g = make_true_2d(g)
        sc_top = pp.fvutils.SubcellTopology(g)

        D_g, CC = pp.numerics.fv.mpsa.reconstruct_displacement(g,
                                                               sc_top,
                                                               eta=0)

        D_g_known = np.array([
            [
                -1.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                0.0,
                0.0,
                -1.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                -1.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                -1.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                0.0,
                0.0,
                0.0,
                0.0,
                1.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                1.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                1.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                1.0,
                0.0,
            ],
            [
                0.0,
                -1.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                0.0,
                0.0,
                0.0,
                -1.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                -1.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                -1.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                1.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                1.0,
                0.0,
                0.0,
                0.0,
                0.0,
            ],
            [
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                1.0,
                0.0,
                0.0,
            ],
            [
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                0.0,
                1.0,
            ],
        ])

        CC_known = np.array([
            [1, 0.0],
            [0, 1.0],
            [1, 0.0],
            [0, 1.0],
            [1, 0.0],
            [0, 1.0],
            [1, 0.0],
            [0, 1.0],
            [1, 0.0],
            [0, 1.0],
            [1, 0.0],
            [0, 1.0],
            [1, 0.0],
            [0, 1.0],
            [1, 0.0],
            [0, 1.0],
        ])

        self.assertTrue(np.all(np.abs(D_g - D_g_known) < 1e-12))
        self.assertTrue(np.all(np.abs(CC - CC_known) < 1e-12))
Exemple #25
0
 def test_3d(self):
     g = pp.CartGrid([1, 1, 1])
     z = np.arange(2)
     self.assertRaises(ValueError, pp.grid_extrusion.extrude_grid, g, z)
    def test_cart_3d(self):
        g = pp.CartGrid([1, 1, 1], physdims=[2, 2, 2])
        g.compute_geometry()
        sc_top = pp.fvutils.SubcellTopology(g)

        D_g, CC = pp.numerics.fv.mpsa.reconstruct_displacement(g,
                                                               sc_top,
                                                               eta=1)

        data = np.array([
            -1.0,
            -1.0,
            -1.0,
            -1.0,
            -1.0,
            -1.0,
            -1.0,
            -1.0,
            -1.0,
            1.0,
            -1.0,
            -1.0,
            1.0,
            -1.0,
            -1.0,
            1.0,
            -1.0,
            -1.0,
            -1.0,
            1.0,
            -1.0,
            -1.0,
            1.0,
            -1.0,
            -1.0,
            1.0,
            -1.0,
            1.0,
            1.0,
            -1.0,
            1.0,
            1.0,
            -1.0,
            1.0,
            1.0,
            -1.0,
            -1.0,
            -1.0,
            1.0,
            -1.0,
            -1.0,
            1.0,
            -1.0,
            -1.0,
            1.0,
            1.0,
            -1.0,
            1.0,
            1.0,
            -1.0,
            1.0,
            1.0,
            -1.0,
            1.0,
            -1.0,
            1.0,
            1.0,
            -1.0,
            1.0,
            1.0,
            -1.0,
            1.0,
            1.0,
            1.0,
            1.0,
            1.0,
            1.0,
            1.0,
            1.0,
            1.0,
            1.0,
            1.0,
        ])

        indices = np.array([
            0,
            24,
            48,
            1,
            25,
            49,
            2,
            26,
            50,
            12,
            33,
            51,
            13,
            34,
            52,
            14,
            35,
            53,
            3,
            36,
            57,
            4,
            37,
            58,
            5,
            38,
            59,
            15,
            45,
            54,
            16,
            46,
            55,
            17,
            47,
            56,
            9,
            27,
            60,
            10,
            28,
            61,
            11,
            29,
            62,
            21,
            30,
            63,
            22,
            31,
            64,
            23,
            32,
            65,
            6,
            39,
            69,
            7,
            40,
            70,
            8,
            41,
            71,
            18,
            42,
            66,
            19,
            43,
            67,
            20,
            44,
            68,
        ])

        indptr = np.array([
            0,
            1,
            2,
            3,
            4,
            5,
            6,
            7,
            8,
            9,
            10,
            11,
            12,
            13,
            14,
            15,
            16,
            17,
            18,
            19,
            20,
            21,
            22,
            23,
            24,
            25,
            26,
            27,
            28,
            29,
            30,
            31,
            32,
            33,
            34,
            35,
            36,
            37,
            38,
            39,
            40,
            41,
            42,
            43,
            44,
            45,
            46,
            47,
            48,
            49,
            50,
            51,
            52,
            53,
            54,
            55,
            56,
            57,
            58,
            59,
            60,
            61,
            62,
            63,
            64,
            65,
            66,
            67,
            68,
            69,
            70,
            71,
            72,
        ])

        CC_known = np.array([
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
            [1.0, 0.0, 0.0],
            [0.0, 1.0, 0.0],
            [0.0, 0.0, 1.0],
        ])

        D_g_known = sps.csc_matrix((data, indices, indptr))

        self.assertTrue(np.all(np.abs(D_g - D_g_known).A < 1e-12))
        self.assertTrue(np.all(np.abs(CC - CC_known) < 1e-12))
def make_grid(grid, grid_dims, domain):
    if grid.lower() == "cart":
        return pp.CartGrid(grid_dims, domain)
    elif grid.lower() == "triangular":
        return pp.StructuredTriangleGrid(grid_dims, domain)
        #        print(norm_now)
        x_prev = x_new
        f_prev = f_new

        if norm_now < norm_orig * 1e-10:
            return x_new

    # If we get here, convergence has not been achieved. Not sure what to do then.
    # Take a break before continuing?
    breakpoint()
    return x_new


# Define a grid, and wrap it in a GridBucket (this makes the future extension to true
# md problems easier).
g = pp.CartGrid([150])
g.compute_geometry()
gb = pp.GridBucket()
gb.add_nodes(g)

# Use the above functions to find intial composition of the system, based on
# given values for total concentrations T.
# NOTE: For Momas, insert medium B will have a different composition init_T_B.
init_T_A = np.array([0, -2, 0, 2, 0])

# Initial guess.
guess_x0 = np.array([1, -1, 1, 0.3, 0.01])
# Initial values for X_i on log form
init_X_A_log = newton_on_function(equilibration_func, guess_x0, init_T_A)
# .. and on standard form
init_X_A = np.exp(init_X_A_log)
Exemple #29
0
    def test_cart_3d(self):
        g = pp.CartGrid([1, 1, 1])
        g.compute_geometry()

        bot = g.face_centers[2] < 1e-10
        top = g.face_centers[2] > 1 - 1e-10
        south = g.face_centers[1] < 1e-10
        north = g.face_centers[1] > 1 - 1e-10
        west = g.face_centers[0] < 1e-10
        east = g.face_centers[0] > 1 - 1e-10

        is_dir = south + top
        is_neu = east + west
        is_rob = north + bot

        bnd = pp.BoundaryConditionVectorial(g)
        bnd.is_neu[:] = False

        bnd.is_dir[:, is_dir] = True
        bnd.is_rob[:, is_rob] = True
        bnd.is_neu[:, is_neu] = True

        sc_top = pp.fvutils.SubcellTopology(g)
        bnd_excl = pp.fvutils.ExcludeBoundaries(sc_top, bnd, g.dim)

        rhs = pp.numerics.fv.mpsa.create_bound_rhs_nd(bnd, bnd_excl, sc_top, g)

        rhs_indptr = np.array(
            [
                0,
                1,
                2,
                3,
                4,
                5,
                6,
                7,
                8,
                9,
                10,
                11,
                12,
                13,
                14,
                15,
                16,
                17,
                18,
                19,
                20,
                21,
                22,
                23,
                24,
                25,
                26,
                27,
                28,
                29,
                30,
                31,
                32,
                33,
                34,
                35,
                36,
                37,
                38,
                39,
                40,
                41,
                42,
                43,
                44,
                45,
                46,
                47,
                48,
                49,
                50,
                51,
                52,
                53,
                54,
                55,
                56,
                57,
                58,
                59,
                60,
                61,
                62,
                63,
                64,
                65,
                66,
                67,
                68,
                69,
                70,
                71,
                72,
            ],
            dtype=np.int32,
        )
        rhs_indices = np.array(
            [
                0,
                0,
                0,
                0,
                3,
                3,
                3,
                3,
                1,
                1,
                1,
                1,
                4,
                4,
                4,
                4,
                2,
                2,
                2,
                2,
                5,
                5,
                5,
                5,
                9,
                9,
                9,
                9,
                12,
                12,
                12,
                12,
                10,
                10,
                10,
                10,
                13,
                13,
                13,
                13,
                11,
                11,
                11,
                11,
                14,
                14,
                14,
                14,
                6,
                6,
                6,
                6,
                15,
                15,
                15,
                15,
                7,
                7,
                7,
                7,
                16,
                16,
                16,
                16,
                8,
                8,
                8,
                8,
                17,
                17,
                17,
                17,
            ],
            dtype=np.int32,
        )
        rhs_data = np.array(
            [
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                0.25,
                -1.,
                -1.,
                -1.,
                -1.,
                1.,
                1.,
                1.,
                1.,
                -1.,
                -1.,
                -1.,
                -1.,
                1.,
                1.,
                1.,
                1.,
                -1.,
                -1.,
                -1.,
                -1.,
                1.,
                1.,
                1.,
                1.,
            ]
        )
        rhs_known = sps.csr_matrix((rhs_data, rhs_indices, rhs_indptr), shape=(72, 18))
        self.assertTrue(np.all(np.abs((rhs_known - rhs).data) < 1e-12))
Exemple #30
0
 def test_bounary_node_cart(self):
     g = pp.CartGrid([2, 2])
     bound_ind = g.get_boundary_nodes()
     known_bound = np.array([0, 1, 2, 3, 5, 6, 7, 8])
     self.assertTrue(np.allclose(np.sort(bound_ind), known_bound))