Esempio n. 1
0
    def test_upwind_example1(self, if_export=False):
        #######################
        # Simple 2d upwind problem with implicit Euler scheme in time
        #######################
        T = 1
        Nx, Ny = 10, 1
        g = structured.CartGrid([Nx, Ny], [1, 1])
        g.compute_geometry()

        advect = upwind.Upwind("transport")
        param = Parameters(g)
        dis = advect.discharge(g, [1, 0, 0])

        b_faces = g.get_all_boundary_faces()
        bc = BoundaryCondition(g, b_faces, ['dir'] * b_faces.size)
        bc_val = np.hstack(([1], np.zeros(g.num_faces - 1)))
        param.set_bc("transport", bc)
        param.set_bc_val("transport", bc_val)

        data = {'param': param, 'discharge': dis}
        data['deltaT'] = advect.cfl(g, data)

        U, rhs = advect.matrix_rhs(g, data)
        M, _ = mass_matrix.MassMatrix().matrix_rhs(g, data)

        conc = np.zeros(g.num_cells)

        # Perform an LU factorization to speedup the solver
        IE_solver = sps.linalg.factorized((M + U).tocsc())

        # Loop over the time
        Nt = int(T / data['deltaT'])
        time = np.empty(Nt)
        folder = 'example1'
        save = Exporter(g, "conc_IE", folder)
        for i in np.arange(Nt):

            # Update the solution
            # Backward and forward substitution to solve the system
            conc = IE_solver(M.dot(conc) + rhs)
            time[i] = data['deltaT'] * i
            if if_export:
                save.write_vtk({"conc": conc}, time_step=i)

        if if_export:
            save.write_pvd(time)

        known = np.array([
            0.99969927, 0.99769441, 0.99067741, 0.97352474, 0.94064879,
            0.88804726, 0.81498958, 0.72453722, 0.62277832, 0.51725056
        ])
        assert np.allclose(conc, known)
Esempio n. 2
0
    def test_upwind_2d_beta_positive(self):

        f = np.array([[2, 2],
                      [0, 2]])
        gb = meshing.cart_grid([f], [4, 2])
        gb.assign_node_ordering()
        gb.compute_geometry()

        solver = upwind.UpwindMixedDim('transport')

        gb.add_node_props(['param'])

        for g, d in gb:
            param = Parameters(g)
            aperture = np.ones(g.num_cells)*np.power(1e-2, gb.dim_max() - g.dim)
            param.set_aperture(aperture)
            d['discharge'] = solver.discr.discharge(g, [2, 0, 0], aperture)

            bf = g.get_boundary_faces()
            bc = BoundaryCondition(g, bf, bf.size * ['neu'])
            param.set_bc('transport', bc)
            d['param'] = param

        # Assign coupling discharge
        gb.add_edge_prop('param')
        for e, d in gb.edges_props():
            g_h = gb.sorted_nodes_of_edge(e)[1]
            discharge = gb.node_prop(g_h,'discharge')
            d['param'] = Parameters(g_h)
            d['discharge'] = discharge

        M = solver.matrix_rhs(gb)[0].todense()

        M_known = np.array([[ 2,  0,  0,  0,  0,  0,  0,  0,  0,  0.],
                            [-2,  2,  0,  0,  0,  0,  0,  0,  0,  0.],
                            [ 0,  0,  2,  0,  0,  0,  0,  0,  0, -2.],
                            [ 0,  0, -2,  0,  0,  0,  0,  0,  0,  0.],
                            [ 0,  0,  0,  0,  2,  0,  0,  0,  0,  0.],
                            [ 0,  0,  0,  0, -2,  2,  0,  0,  0,  0.],
                            [ 0,  0,  0,  0,  0,  0,  2,  0, -2,  0.],
                            [ 0,  0,  0,  0,  0,  0, -2,  0,  0,  0.],
                            [ 0,  0,  0,  0,  0, -2,  0,  0,  2,  0.],
                            [ 0, -2,  0,  0,  0,  0,  0,  0,  0,  2.]])

        rtol = 1e-15
        atol = rtol
        assert np.allclose(M, M_known, rtol, atol)
Esempio n. 3
0
    def test_mono_equals_multi(self):
        """
        test that the mono_dimensional elliptic solver gives the same answer as
        the grid bucket elliptic
        """
        g = CartGrid([10, 10])
        g.compute_geometry()
        gb = meshing.cart_grid([], [10, 10])
        param_g = Parameters(g)

        def bc_val(g):
            left = g.face_centers[0] < 1e-6
            right = g.face_centers[0] > 10 - 1e-6

            bc_val = np.zeros(g.num_faces)
            bc_val[left] = -1
            bc_val[right] = 1
            return bc_val

        def bc_labels(g):
            bound_faces = g.get_boundary_faces()
            bound_face_centers = g.face_centers[:, bound_faces]
            left = bound_face_centers[0] < 1e-6
            right = bound_face_centers[0] > 10 - 1e-6

            labels = np.array(['neu'] * bound_faces.size)
            labels[np.logical_or(right, left)] = 'dir'
            bc_labels = bc.BoundaryCondition(g, bound_faces, labels)

            return bc_labels

        param_g.set_bc_val('flow', bc_val(g))
        param_g.set_bc('flow', bc_labels(g))

        gb.add_node_props(['param'])
        for sub_g, d in gb:
            d['param'] = Parameters(sub_g)
            d['param'].set_bc_val('flow', bc_val(g))
            d['param'].set_bc('flow', bc_labels(sub_g))

        problem_mono = elliptic.EllipticModel(g, {'param': param_g})
        problem_mult = elliptic.EllipticModel(gb)

        p_mono = problem_mono.solve()
        p_mult = problem_mult.solve()

        assert np.allclose(p_mono, p_mult)
Esempio n. 4
0
    def test_upwind_example0(self, if_export=False):
        #######################
        # Simple 2d upwind problem with explicit Euler scheme in time
        #######################
        T = 1
        Nx, Ny = 4, 1
        g = structured.CartGrid([Nx, Ny], [1, 1])
        g.compute_geometry()

        advect = upwind.Upwind("transport")
        param = Parameters(g)
        dis = advect.discharge(g, [1, 0, 0])

        b_faces = g.get_all_boundary_faces()
        bc = BoundaryCondition(g, b_faces, ['dir'] * b_faces.size)
        bc_val = np.hstack(([1], np.zeros(g.num_faces - 1)))
        param.set_bc("transport", bc)
        param.set_bc_val("transport", bc_val)

        data = {'param': param, 'discharge': dis}
        data['deltaT'] = advect.cfl(g, data)

        U, rhs = advect.matrix_rhs(g, data)
        OF = advect.outflow(g, data)
        M, _ = mass_matrix.MassMatrix().matrix_rhs(g, data)

        conc = np.zeros(g.num_cells)

        M_minus_U = M - U
        invM, _ = mass_matrix.InvMassMatrix().matrix_rhs(g, data)

        # Loop over the time
        Nt = int(T / data['deltaT'])
        time = np.empty(Nt)
        folder = 'example0'
        production = np.zeros(Nt)
        save = Exporter(g, "conc_EE", folder)
        for i in np.arange(Nt):

            # Update the solution
            production[i] = np.sum(OF.dot(conc))
            conc = invM.dot((M_minus_U).dot(conc) + rhs)
            time[i] = data['deltaT'] * i
            if if_export:
                save.write_vtk({"conc": conc}, time_step=i)

        if if_export:
            save.write_pvd(time)

        known = 1.09375
        assert np.sum(production) == known
Esempio n. 5
0
    def test_zero_force(self):
        """
        test that nothing moves if nothing is touched
        """
        g = self.gb3d.grids_of_dimension(3)[0]

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

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

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

        assert np.all(np.abs(u) < 1e-10)
        assert np.all(np.abs(T) < 1e-10)
Esempio n. 6
0
def add_data_advection(gb, domain, tol):

    for g, d in gb:
        param = d['param']

        source = np.zeros(g.num_cells)
        param.set_source("transport", source)

        param.set_porosity(1)
        param.set_discharge(d['discharge'])

        bound_faces = g.tags['domain_boundary_faces'].nonzero()[0]
        if bound_faces.size != 0:
            bound_face_centers = g.face_centers[:, bound_faces]

            top = bound_face_centers[2, :] > domain['zmax'] - tol
            bottom = bound_face_centers[2, :] < domain['zmin'] + tol
            boundary = np.logical_or(top, bottom)
            labels = np.array(['neu'] * bound_faces.size)
            labels[boundary] = ['dir']

            bc_val = np.zeros(g.num_faces)
            bc_val[bound_faces[bottom]] = 1

            param.set_bc("transport",
                         BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val("transport", bc_val)
        else:
            param.set_bc("transport",
                         BoundaryCondition(g, np.empty(0), np.empty(0)))
        d['param'] = param

    # Assign coupling discharge
    gb.add_edge_prop('param')
    for e, d in gb.edges_props():
        g_h = gb.sorted_nodes_of_edge(e)[1]
        discharge = gb.node_prop(g_h, 'param').get_discharge()
        d['param'] = Parameters(g_h)
        d['param'].set_discharge(discharge)
Esempio n. 7
0
    def test_upwind_example2(self, if_export=False):
        #######################
        # Simple 2d upwind problem with explicit Euler scheme in time coupled with
        # a Darcy problem
        #######################
        T = 2
        Nx, Ny = 10, 10
        folder = 'example2'

        def funp_ex(pt):
            return -np.sin(pt[0]) * np.sin(pt[1]) - pt[0]

        g = structured.CartGrid([Nx, Ny], [1, 1])
        g.compute_geometry()

        param = Parameters(g)

        # Permeability
        perm = tensor.SecondOrderTensor(g.dim, kxx=np.ones(g.num_cells))
        param.set_tensor("flow", perm)

        # Source term
        param.set_source("flow", np.zeros(g.num_cells))

        # Boundaries
        b_faces = g.get_all_boundary_faces()
        bc = BoundaryCondition(g, b_faces, ['dir'] * b_faces.size)
        bc_val = np.zeros(g.num_faces)
        bc_val[b_faces] = funp_ex(g.face_centers[:, b_faces])
        param.set_bc("flow", bc)
        param.set_bc_val("flow", bc_val)

        # Darcy solver
        data = {'param': param}
        solver = vem_dual.DualVEM("flow")
        D_flow, b_flow = solver.matrix_rhs(g, data)

        solver_source = vem_source.DualSource('flow')
        D_source, b_source = solver_source.matrix_rhs(g, data)

        up = sps.linalg.spsolve(D_flow + D_source, b_flow + b_source)

        p, u = solver.extract_p(g, up), solver.extract_u(g, up)
        P0u = solver.project_u(g, u, data)

        save = Exporter(g, "darcy", folder)

        if if_export:
            save.write_vtk({'pressure': p, "P0u": P0u})

        # Discharge
        dis = u

        # Boundaries
        bc = BoundaryCondition(g, b_faces, ['dir'] * b_faces.size)
        bc_val = np.hstack(([1], np.zeros(g.num_faces - 1)))
        param.set_bc("transport", bc)
        param.set_bc_val("transport", bc_val)

        data = {'param': param, 'discharge': dis}

        # Advect solver
        advect = upwind.Upwind("transport")

        U, rhs = advect.matrix_rhs(g, data)

        data['deltaT'] = advect.cfl(g, data)
        M, _ = mass_matrix.MassMatrix().matrix_rhs(g, data)

        conc = np.zeros(g.num_cells)
        M_minus_U = M - U
        invM, _ = mass_matrix.InvMassMatrix().matrix_rhs(g, data)

        # Loop over the time
        Nt = int(T / data['deltaT'])
        time = np.empty(Nt)
        save.change_name("conc_darcy")
        for i in np.arange(Nt):

            # Update the solution
            conc = invM.dot((M_minus_U).dot(conc) + rhs)
            time[i] = data['deltaT'] * i
            if if_export:
                save.write_vtk({"conc": conc}, time_step=i)

        if if_export:
            save.write_pvd(time)

        known = \
            np.array([9.63168200e-01,   8.64054875e-01,   7.25390695e-01,
                      5.72228235e-01,   4.25640080e-01,   2.99387331e-01,
                      1.99574336e-01,   1.26276876e-01,   7.59011550e-02,
                      4.33431230e-02,   3.30416807e-02,   1.13058617e-01,
                      2.05372538e-01,   2.78382057e-01,   3.14035373e-01,
                      3.09920132e-01,   2.75024694e-01,   2.23163145e-01,
                      1.67386939e-01,   1.16897527e-01,   1.06111312e-03,
                      1.11951850e-02,   3.87907727e-02,   8.38516119e-02,
                      1.36617802e-01,   1.82773271e-01,   2.10446545e-01,
                      2.14651936e-01,   1.97681518e-01,   1.66549151e-01,
                      3.20751341e-05,   9.85780113e-04,   6.07062715e-03,
                      1.99393042e-02,   4.53237556e-02,   8.00799828e-02,
                      1.17199623e-01,   1.47761481e-01,   1.64729339e-01,
                      1.65390555e-01,   9.18585872e-07,   8.08267622e-05,
                      8.47227168e-04,   4.08879583e-03,   1.26336029e-02,
                      2.88705048e-02,   5.27841497e-02,   8.10459333e-02,
                      1.07956484e-01,   1.27665318e-01,   2.51295298e-08,
                      6.29844122e-06,   1.09361990e-04,   7.56743783e-04,
                      3.11384414e-03,   9.04446601e-03,   2.03443897e-02,
                      3.75208816e-02,   5.89595194e-02,   8.11457277e-02,
                      6.63498510e-10,   4.73075468e-07,   1.33728945e-05,
                      1.30243418e-04,   7.01905707e-04,   2.55272292e-03,
                      6.96686157e-03,   1.52290448e-02,   2.78607282e-02,
                      4.40402650e-02,   1.71197497e-11,   3.47118057e-08,
                      1.57974045e-06,   2.13489614e-05,   1.48634295e-04,
                      6.68104990e-04,   2.18444135e-03,   5.58646819e-03,
                      1.17334966e-02,   2.09744728e-02,   4.37822313e-13,
                      2.52373622e-09,   1.83589660e-07,   3.40553325e-06,
                      3.02948532e-05,   1.66504215e-04,   6.45119867e-04,
                      1.90731440e-03,   4.53436628e-03,   8.99977737e-03,
                      1.12627412e-14,   1.84486857e-10,   2.13562387e-08,
                      5.39492977e-07,   6.08223906e-06,   4.05535296e-05,
                      1.84731221e-04,   6.25871542e-04,   1.66459389e-03,
                      3.59980231e-03])

        assert np.allclose(conc, known)
Esempio n. 8
0
    def test_0d_elimination_2d_1d_cross(self):
        """
        Simplest case possible:
        2d case with two fractures intersecting in a single 0d grid
        at the center of the domain.
        """
        f1 = np.array([[0, 1], [.5, .5]])
        f2 = np.array([[.5, .5], [0, 1]])

        gb = meshing.cart_grid([f1, f2], [2, 2], **{'physdims': [1, 1]})
        gb.compute_geometry()
        gb.assign_node_ordering()

        tol = 1e-3
        solver = tpfa.Tpfa()
        gb.add_node_props(['param'])
        a = 1e-2
        for g, d in gb:
            param = Parameters(g)

            a_dim = np.power(a, gb.dim_max() - g.dim)
            aperture = np.ones(g.num_cells) * a_dim
            param.set_aperture(aperture)

            kxx = np.ones(g.num_cells) * np.power(1e3, g.dim < gb.dim_max())

            p = tensor.SecondOrderTensor(3, kxx, kyy=kxx, kzz=kxx)
            param.set_tensor('flow', p)
            bound_faces = g.tags['domain_boundary_faces'].nonzero()[0]
            if bound_faces.size != 0:
                bound_face_centers = g.face_centers[:, bound_faces]

                right = bound_face_centers[0, :] > 1 - tol
                left = bound_face_centers[0, :] < tol

                labels = np.array(['neu'] * bound_faces.size)
                labels[right] = ['dir']

                bc_val = np.zeros(g.num_faces)
                bc_dir = bound_faces[right]
                bc_neu = bound_faces[left]
                bc_val[bc_dir] = g.face_centers[0, bc_dir]
                bc_val[bc_neu] = -g.face_areas[bc_neu] * a_dim

                param.set_bc(solver,
                             bc.BoundaryCondition(g, bound_faces, labels))
                param.set_bc_val(solver, bc_val)
            else:
                param.set_bc("flow",
                             bc.BoundaryCondition(g, np.empty(0), np.empty(0)))
            d['param'] = param

        coupling_conditions = tpfa.TpfaCoupling(solver)
        solver_coupler = coupler.Coupler(solver, coupling_conditions)
        A, rhs = solver_coupler.matrix_rhs(gb)

        p = sps.linalg.spsolve(A, rhs)
        p_cond, _, _, _ = condensation.solve_static_condensation(A,
                                                                 rhs,
                                                                 gb,
                                                                 dim=0)

        solver_coupler.split(gb, 'pressure', p)
        solver_coupler.split(gb, "p_cond", p_cond)

        tol = 1e-10
        assert ((np.amax(np.absolute(p - p_cond))) < tol)
        assert (np.sum(
            error.error_L2(g, d['pressure'], d['p_cond'])
            for g, d in gb) < tol)
Esempio n. 9
0
def add_data_darcy(gb, domain, tol):
    gb.add_node_props(["param", "is_tangent"])

    apert = 1e-2

    km = 7.5 * 1e-11
    kf_t = 1e-5 * km
    kf_n = 1e-5 * km

    for g, d in gb:
        param = Parameters(g)

        rock = g.dim == gb.dim_max()
        kxx = km if rock else kf_t
        d["is_tangential"] = True
        perm = tensor.SecondOrderTensor(g.dim, kxx * np.ones(g.num_cells))
        param.set_tensor("flow", perm)

        param.set_source("flow", np.zeros(g.num_cells))

        param.set_aperture(np.power(apert, gb.dim_max() - g.dim))

        bound_faces = g.tags["domain_boundary_faces"].nonzero()[0]
        if bound_faces.size != 0:
            bound_face_centers = g.face_centers[:, bound_faces]

            top = bound_face_centers[1, :] > domain["ymax"] - tol
            bottom = bound_face_centers[1, :] < domain["ymin"] + tol
            left = bound_face_centers[0, :] < domain["xmin"] + tol
            right = bound_face_centers[0, :] > domain["xmax"] - tol
            boundary = np.logical_or(left, right)

            labels = np.array(["neu"] * bound_faces.size)
            labels[boundary] = ["dir"]

            bc_val = np.zeros(g.num_faces)
            bc_val[bound_faces[left]] = 30 * 1e6

            param.set_bc("flow", BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val("flow", bc_val)
        else:
            param.set_bc("flow", BoundaryCondition(g, np.empty(0),
                                                   np.empty(0)))

        d["param"] = param

    # Assign coupling permeability
    gb.add_edge_prop("kn")
    for e, d in gb.edges_props():
        g = gb.sorted_nodes_of_edge(e)[0]
        d["kn"] = kf_n / gb.node_prop(g, "param").get_aperture()
Esempio n. 10
0
def compute_discharges(gb,
                       physics='flow',
                       d_name='discharge',
                       p_name='pressure',
                       data=None):
    """
    Computes discharges over all faces in the entire grid /grid bucket given
    pressures for all nodes, provided as node properties.

    Parameter:
    gb: grid bucket with the following data fields for all nodes/grids:
        'flux': Internal discretization of fluxes.
        'bound_flux': Discretization of boundary fluxes.
        'pressure': Pressure values for each cell of the grid (overwritten by p_name).
        'bc_val': Boundary condition values.
            and the following edge property field for all connected grids:
        'coupling_flux': Discretization of the coupling fluxes.
    physics (string): defaults to 'flow'. The physic regime
    d_name (string): defaults to 'discharge'. The keyword which the computed
                     discharge will be stored by in the dictionary.
    p_name (string): defaults to 'pressure'. The keyword that the pressure
                     field is stored by in the dictionary
    data (dictionary): defaults to None. If gb is mono-dimensional grid the
                       data dictionary must be given. If gb is a
                       multi-dimensional grid, this variable has no effect

    Returns:
        gb, the same grid bucket with the added field 'discharge' added to all
        node data fields. Note that the fluxes between grids will be added only
        at the gb edge, not at the node fields. The sign of the discharges
        correspond to the directions of the normals, in the edge/coupling case
        those of the higher grid. For edges beteween grids of equal dimension,
        there is an implicit assumption that all normals point from the second
        to the first of the sorted grids (gb.sorted_nodes_of_edge(e)).
    """
    if not isinstance(gb, GridBucket):
        pa = data['param']
        if data.get('flux') is not None:
            dis = data['flux'] * data[p_name] + data['bound_flux'] \
                               * pa.get_bc_val(physics)
        else:
            dis = np.zeros(g.num_faces)
        data[d_name] = dis
        return

    for g, d in gb:
        if g.dim > 0:
            pa = d['param']
            if d.get('flux') is not None:
                dis = d['flux'] * d[p_name] + d['bound_flux'] \
                    * pa.get_bc_val(physics)
            else:
                dis = np.zeros(g.num_faces)
            d[d_name] = dis

    for e, d in gb.edges():
        # According to the sorting convention, g2 is the higher dimensional grid,
        # the one to who's faces the fluxes correspond
        g1, g2 = gb.nodes_of_edge(e)
        try:
            pa = d['param']
        except KeyError:
            pa = Parameters(g2)
            d['param'] = pa

        if g1.dim != g2.dim and d['face_cells'] is not None:
            coupling_flux = gb.edge_props(e, 'coupling_flux')
            pressures = [gb.node_props(g, p_name) for g in [g2, g1]]
            dis = coupling_flux * np.concatenate(pressures)
            d[d_name] = dis

        elif g1.dim == g2.dim and d['face_cells'] is not None:
            # g2 is now only the "higher", but still the one defining the faces
            # (cell-cells connections) in the sense that the normals are assumed
            # outward from g2, "pointing towards the g1 cells". Note that in
            # general, there are g2.num_cells x g1.num_cells connections/"faces".
            cc = d['face_cells']
            cells_1, cells_2 = cc.nonzero()
            coupling_flux = gb.edge_props(e, 'coupling_flux')

            pressures = [gb.node_props(g, p_name) for g in [g2, g1]]
            p2 = pressures[0][cells_2]
            p1 = pressures[1][cells_1]
            contribution_2 = np.multiply(coupling_flux[cc], p2)
            contribution_1 = np.multiply(coupling_flux[cc], p1)
            dis = contribution_2 - contribution_1
            # Store flux at the edge only. This means that the flux will remain
            # zero in the data of both g1 and g2
            d[d_name] = np.ravel(dis)
Esempio n. 11
0
 def test_background_stress_default(self):
     p = Parameters(self.g)
     self.assertTrue(np.allclose(p.background_stress_mechanics, 0))
     for name in p.known_physics:
         self.assertTrue(np.allclose(p.get_background_stress(name), 0))
Esempio n. 12
0
def add_data(gb, domain, solver, case):

    if case == 1:
        kf = 1e4
    else:
        kf = 1e-4
    data = {"domain": domain, "aperture": 1e-4, "km": 1, "kf": kf}

    if_solver = solver == "vem" or solver == "rt0" or solver == "p1"
    if_p1 = solver == "p1"

    gb.add_node_props(["param", "is_tangential"])
    for g, d in gb:
        param = Parameters(g)

        if g.dim == 3:
            kxx = np.ones(g.num_cells) * data["km"]
            perm = pp.SecondOrderTensor(3, kxx=kxx)
        else:
            kxx = np.ones(g.num_cells) * data["kf"]
            if if_solver:
                if g.dim == 2:
                    perm = pp.SecondOrderTensor(g.dim, kxx=kxx, kyy=kxx, kzz=1)
                elif g.dim == 1:
                    perm = pp.SecondOrderTensor(g.dim, kxx=kxx, kyy=1, kzz=1)
                else:  # g.dim == 0
                    perm = pp.SecondOrderTensor(g.dim, kxx=kxx, kyy=1, kzz=1)
            else:
                perm = pp.SecondOrderTensor(3, kxx=kxx)

        param.set_tensor("flow", perm)

        aperture = np.power(data["aperture"], gb.dim_max() - g.dim)
        param.set_aperture(aperture * np.ones(g.num_cells))

        param.set_source("flow", np.zeros(g.num_cells))

        if if_p1:  # for P1 a different handling of the boundary conditions
            bound_nodes = g.get_boundary_nodes()
            if bound_nodes.size == 0:
                bc = pp.BoundaryConditionNode(g, np.empty(0), np.empty(0))
                bc_val = np.empty(0)
            else:
                p_press, b_in, b_out = b_pressure_node(g)

                labels = np.array(["neu"] * bound_nodes.size)
                labels[p_press] = "dir"

                bc_val = np.zeros(g.num_nodes)
                bc_val[bound_nodes[b_in]] = 1
                bc_val[bound_nodes[b_out]] = -1
                param.set_bc_val("flow", bc_val)

                bc = pp.BoundaryConditionNode(g, bound_nodes, labels)
        else:
            bound_faces = g.tags["domain_boundary_faces"].nonzero()[0]
            if bound_faces.size == 0:
                bc = BoundaryCondition(g, np.empty(0), np.empty(0))
                param.set_bc("flow", bc)
            else:
                p_press, b_in, b_out = b_pressure(g)

                labels = np.array(["neu"] * bound_faces.size)
                labels[p_press] = "dir"

                bc_val = np.zeros(g.num_faces)
                bc_val[bound_faces[b_in]] = 1
                bc_val[bound_faces[b_out]] = -1
                param.set_bc_val("flow", bc_val)

                bc = BoundaryCondition(g, bound_faces, labels)

        param.set_bc("flow", bc)

        d["is_tangential"] = True
        d["param"] = param

    gb.add_edge_props("kn")
    for e, d in gb.edges():
        g_l = gb.nodes_of_edge(e)[0]
        mg = d["mortar_grid"]
        check_P = mg.low_to_mortar_avg()

        kxx = data["kf"]
        gamma = np.power(
            check_P * gb.node_props(g_l, "param").get_aperture(),
            1. / (gb.dim_max() - g_l.dim),
        )
        d["kn"] = kxx * np.ones(mg.num_cells) / gamma
Esempio n. 13
0
def new_coupling_fluxes(gb_old, gb_el, neighbours_old, neighbours_el,
                        node_old):
    """
    Adds new coupling_flux data fields to the new gb edges arising through
    the removal of one node.
    Idea: set up a condensation for the local system of old coupling_fluxes
    for the removed nodes and its n_neighbours neighbour nodes/grids.
    """
    neighbours_old = gb_old.sort_multiple_nodes(neighbours_old)
    neighbours_el = gb_el.sort_multiple_nodes(neighbours_el)
    n_cells_l = node_old.num_cells
    n_neighbours = len(neighbours_old)

    # Initialize coupling matrix (see coupler.py, matrix_rhs)
    all_cc = np.empty((n_neighbours + 1, n_neighbours + 1), dtype=np.object)
    pos_i = 0
    for g_i in neighbours_old:
        pos_j = 0
        for g_j in neighbours_old:
            all_cc[pos_i, pos_j] = sps.coo_matrix(
                (g_i.num_cells, g_j.num_cells))
            pos_j += 1

        all_cc[pos_i, n_neighbours] = sps.coo_matrix(
            (g_i.num_cells, node_old.num_cells))
        all_cc[n_neighbours, pos_i] = sps.coo_matrix(
            (node_old.num_cells, g_i.num_cells))
        pos_i += 1

    all_cc[n_neighbours, n_neighbours] = sps.coo_matrix(
        (node_old.num_cells, node_old.num_cells))
    dofs = np.zeros(n_neighbours)

    # Assemble original system:
    for i in range(n_neighbours):
        cc = gb_old.edge_props((neighbours_old[i], node_old),
                               'coupling_discretization')
        idx = np.ix_([i, n_neighbours], [i, n_neighbours])
        all_cc[idx] += cc
        dofs[i] = cc[0][0].shape[0]
    global_idx = np.r_[0, np.cumsum(dofs)].astype(int)
    all_cc = sps.bmat(all_cc, 'csr')

    # Eliminate "node"
    n_dof = all_cc.shape[0]
    to_be_eliminated = np.zeros(n_dof, dtype=bool)
    to_be_eliminated[range(n_dof - n_cells_l, n_dof)] = True
    all_cc, _, _, _, _ = eliminate_dofs(all_cc, np.zeros(n_dof),
                                        to_be_eliminated)

    # Extract the new coupling fluxes from the eliminated system and map to
    # faces of the first grid
    for i, g_0 in enumerate(neighbours_el):
        id_0 = slice(global_idx[i], global_idx[i + 1])
        # Get the internal contribution (grids that have an internal hole after
        # the elimination), to be added to the node g_0. This contribution
        # is found at the off-diagonal part of the diagonal blocks
        cc_00 = all_cc.tocsr()[id_0, :].tocsc()[:, id_0]

        # Keep only one connection, the one from the "first/higher" cell(s) to
        # the "second/lower". Fluxes from higher to lower, so entries should be
        # positive (coming from off-diagonal, they are now negative)
        c_f = -np.triu(cc_00.todense(), k=1)

        # Check whether there is an internal hole in the grid. If so, add
        # connections between the cells on either side
        if not np.allclose(c_f, 0, 1e-10, 1e-12):
            cell_cells = np.array(c_f > 0, dtype=bool)
            # The fluxes c_f*p go from cells_1 to cells_2:
            # c_1, c_2, _ = sparse.find(cell_cells)
            gb_el.add_edge([g_0, g_0], cell_cells)
            d_edge = gb_el.edge_props([g_0, g_0])
            d_edge['coupling_flux'] = sps.csr_matrix(c_f)
            d_edge['param'] = Parameters(g_0)

        # Get the contribution between different grids
        for j in range(i + 1, n_neighbours):
            g_1 = neighbours_el[j]
            id_1 = slice(global_idx[j], global_idx[j + 1])
            cc_01 = all_cc.tocsr()[id_0, :].tocsc()[:, id_1]
            gb_el.add_edge_props('coupling_flux', [[g_0, g_1]])
            gb_el.edge_props([g_0, g_1])['coupling_flux'] = -cc_01
Esempio n. 14
0
    def test_non_zero_bc_val(self):
        """
        We mixed bc_val on domain boundary and fracture displacement in
        x-direction.
        """
        frac = np.array([[1,1,1], [1,2,1], [2,2,1], [2,1,1]]).T
        physdims = np.array([3,3,2])

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


        # Define boundary conditions 
        bc_val = np.zeros((g.dim, g.num_faces))
        frac_slip = np.zeros((g.dim, g.num_faces))        

        frac_bnd = g.has_face_tag(FaceTag.FRACTURE)
        dom_bnd = g.has_face_tag(FaceTag.DOMAIN_BOUNDARY)        

        frac_slip[0, frac_bnd] = np.ones(np.sum(frac_bnd))
        bc_val[:, dom_bnd] = g.face_centers[:, dom_bnd]

        bound = bc.BoundaryCondition(g, g.get_boundary_faces(), 'dir')

        data['param'].set_bc('mechanics', bound)
        data['param'].set_bc_val('mechanics', bc_val.ravel('F'))
        data['param'].set_slip_distance(frac_slip.ravel('F'))
        solver = mpsa.FracturedMpsa()        

        A, b = solver.matrix_rhs(g, data)
        u = np.linalg.solve(A.A, b)
        
        u_f = solver.extract_frac_u(g, u)
        u_c = solver.extract_u(g, u)
        u_c = u_c.reshape((3, -1), order='F')

        # Test traction
        frac_faces = g.frac_pairs
        frac_left = frac_faces[0]
        frac_right = frac_faces[1]

        T = solver.traction(g, data, u)
        T = T.reshape((3, -1),order='F')
        T_left = T[:, frac_left]
        T_right = T[:, frac_right]

        assert np.allclose(T_left, T_right)


        # we have u_lhs - u_rhs = 1 so u_lhs should be positive
        mid_ind = int(round(u_f.size/2))
        u_left = u_f[:mid_ind]
        u_right = u_f[mid_ind:]

        true_diff = np.atleast_2d(np.array([1,0,0])).T
        u_left = u_left.reshape((3, -1), order='F')
        u_right = u_right.reshape((3, -1), order='F')
        assert np.all(np.abs(u_left - u_right - true_diff) < 1e-10)
     
        # should have a positive displacement for all cells
        assert np.all(u_c > 0)
Esempio n. 15
0
def add_data_darcy(gb, domain, tol, a):
    gb.add_node_props(['param'])

    kf = 1e4
    for g, d in gb:
        param = Parameters(g)

        kxx = np.ones(g.num_cells) * np.power(kf, g.dim < gb.dim_max())
        perm = tensor.SecondOrderTensor(g.dim, kxx)
        param.set_tensor("flow", perm)

        param.set_source("flow", np.zeros(g.num_cells))

        aperture = np.power(a, gb.dim_max() - g.dim)
        param.set_aperture(np.ones(g.num_cells) * aperture)

        bound_faces = g.tags['domain_boundary_faces'].nonzero()[0]
        if bound_faces.size != 0:
            bound_face_centers = g.face_centers[:, bound_faces]

            top = bound_face_centers[1, :] > domain['ymax'] - tol
            bottom = bound_face_centers[1, :] < domain['ymin'] + tol
            left = bound_face_centers[0, :] < domain['xmin'] + tol
            right = bound_face_centers[0, :] > domain['xmax'] - tol
            boundary = np.logical_or(left, right)

            labels = np.array(['neu'] * bound_faces.size)
            labels[boundary] = ['dir']

            bc_val = np.zeros(g.num_faces)
            bc_val[bound_faces[right]] = 1

            param.set_bc("flow", BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val("flow", bc_val)
        else:
            param.set_bc("flow", BoundaryCondition(g, np.empty(0),
                                                   np.empty(0)))

        d['param'] = param

    # Assign coupling permeability
    gb.add_edge_prop('kn')
    for e, d in gb.edges_props():
        gn = gb.nodes_of_edge(e)
        aperture = np.power(a, gb.dim_max() - gn[0].dim)
        d['kn'] = np.ones(gn[0].num_cells) / aperture * kf
Esempio n. 16
0
def add_data(gb, domain, direction, tol):
    """
    Define the permeability, apertures, boundary conditions
    """
    gb.add_node_props(["param", "Aavatsmark_transmissibilities"])

    for g, d in gb:
        param = Parameters(g)
        d["Aavatsmark_transmissibilities"] = True

        if g.dim == 2:

            # Permeability
            kxx = np.ones(g.num_cells)
            param.set_tensor("flow", tensor.SecondOrder(3, kxx))

            # Source term
            param.set_source("flow", np.zeros(g.num_cells))

            # Boundaries
            bound_faces = g.get_boundary_faces()
            if bound_faces.size != 0:
                bound_face_centers = g.face_centers[:, bound_faces]

                if direction == "left_right":
                    left = bound_face_centers[0, :] < domain["xmin"] + tol
                    right = bound_face_centers[0, :] > domain["xmax"] - tol
                    bc_dir = np.logical_or(left, right)
                    bc_one = right
                elif direction == "bottom_top":
                    bottom = bound_face_centers[2, :] < domain["zmin"] + tol
                    top = bound_face_centers[2, :] > domain["zmax"] - tol
                    bc_dir = np.logical_or(top, bottom)
                    bc_one = top
                elif direction == "back_front":
                    back = bound_face_centers[1, :] < domain["ymin"] + tol
                    front = bound_face_centers[1, :] > domain["ymax"] - tol
                    bc_dir = np.logical_or(back, front)
                    bc_one = front

                labels = np.array(["neu"] * bound_faces.size)
                labels[bc_dir] = "dir"

                bc_val = np.zeros(g.num_faces)
                bc_val[bound_faces[bc_one]] = 1

                param.set_bc("flow", BoundaryCondition(g, bound_faces, labels))
                param.set_bc_val("flow", bc_val)
            else:
                param.set_bc("flow",
                             BoundaryCondition(g, np.empty(0), np.empty(0)))

        d["param"] = param

    gb.add_edge_props(["param", "Aavatsmark_transmissibilities"])
    for e, d in gb.edges_props():
        g_h = gb.sorted_nodes_of_edge(e)[1]
        d["param"] = Parameters(g_h)
        d["Aavatsmark_transmissibilities"] = True
Esempio n. 17
0
 def _set_data(self):
     if "param" not in self._data:
         self._data["param"] = Parameters(self.grid())
Esempio n. 18
0
def add_data(gb, tol):
    """
    Define the permeability, apertures, boundary conditions
    """
    gb.add_node_props(['param', 'Aavatsmark_transmissibilities'])

    for g, d in gb:
        param = Parameters(g)
        d['Aavatsmark_transmissibilities'] = True

        if g.dim == 2:

            # Permeability
            kxx = np.ones(g.num_cells)
            param.set_tensor("flow", tensor.SecondOrder(g.dim, kxx))

            # Source term
            param.set_source("flow", np.zeros(g.num_cells))

            # Boundaries
            bound_faces = g.get_domain_boundary_faces()
            if bound_faces.size != 0:
                bound_face_centers = g.face_centers[:, bound_faces]

                bottom = bound_face_centers[1, :] < tol

                labels = np.array(['neu'] * bound_faces.size)
                labels[bottom] = 'dir'

                bc_val = np.zeros(g.num_faces)
                mask = bound_face_centers[0, :] < tol
                bc_val[bound_faces[np.logical_and(bottom, mask)]] = 1

                param.set_bc("flow", BoundaryCondition(g, bound_faces, labels))
                param.set_bc_val("flow", bc_val)
            else:
                param.set_bc("flow",
                             BoundaryCondition(g, np.empty(0), np.empty(0)))

        d['param'] = param

    # Assign coupling discharge
    gb.add_edge_props(['param', 'Aavatsmark_transmissibilities'])
    for e, d in gb.edges_props():
        g_h = gb.sorted_nodes_of_edge(e)[1]
        d['param'] = Parameters(g_h)
        d['Aavatsmark_transmissibilities'] = True
Esempio n. 19
0
    def test_tpfa_coupling_2d_1d_left_right_dir(self):
        """
        Grid: 2 x 2 cells in matrix + 2 cells in the fracture from left to right.
        Dirichlet + no-flow, conductive fracture.
        """
        f = np.array([[0, 1],
                      [.5, .5]])
        gb = meshing.cart_grid( [f], [2, 2], **{'physdims': [1, 1]})
        gb.compute_geometry()
        gb.assign_node_ordering()

        tol = 1e-3
        solver = tpfa.Tpfa(physics='flow')
        gb.add_node_props(['param'])
        a = 1e-2
        for g, d in gb:
            param = Parameters(g)

            aperture = np.ones(g.num_cells)*np.power(a, gb.dim_max() - g.dim)
            param.set_aperture(aperture)

            p = tensor.SecondOrder(3,np.ones(g.num_cells)* np.power(1e3, g.dim<gb.dim_max()))
            param.set_tensor('flow', p)
            bound_faces = g.get_boundary_faces()
            bound_face_centers = g.face_centers[:, bound_faces]

            left = bound_face_centers[0, :] > 1 - tol
            right = bound_face_centers[0, :] < tol

            labels = np.array(['neu'] * bound_faces.size)
            labels[np.logical_or(left, right)] = ['dir']

            bc_val = np.zeros(g.num_faces)
            bc_dir = bound_faces[np.logical_or(left, right)]
            bc_val[bc_dir] = g.face_centers[0,bc_dir]

            param.set_bc(solver, bc.BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val(solver, bc_val)

            d['param'] = param

       

        coupling_conditions = tpfa.TpfaCoupling(solver)
        solver_coupler = coupler.Coupler(solver, coupling_conditions)
        A, rhs = solver_coupler.matrix_rhs(gb)

        A_known = np.array(
            [[  4.99996,  -1.     ,   0.     ,   0.     ,   0.     ,  -1.99996],
             [ -1.     ,   4.99996,   0.     ,   0.     ,  -1.99996,   0.     ],
             [  0.     ,   0.     ,   4.99996,  -1.     ,   0.     ,  -1.99996],
             [  0.     ,   0.     ,  -1.     ,   4.99996,  -1.99996,   0.     ],
             [  0.     ,  -1.99996,   0.     ,  -1.99996,  63.99992, -20.     ],
             [ -1.99996,   0.     ,  -1.99996,   0.     , -20.     ,  63.99992]])

        rhs_known = np.array([  0.,   2.,   0.,   2.,  40.,   0.])

       
        rtol = 1e-6
        atol = rtol
        
        
        assert np.allclose(A.todense(), A_known, rtol, atol)
        assert np.allclose(rhs, rhs_known, rtol, atol)
Esempio n. 20
0
 def test_fluid_compr_assertion(self):
     p = Parameters(self.g)
     with self.assertRaises(ValueError):
         p.set_fluid_compr(-1)
Esempio n. 21
0
def add_data(gb, domain, kf):
    """
    Define the permeability, apertures, boundary conditions
    """
    gb.add_node_props(['param'])
    tol = 1e-5
    a = 1e-3

    for g, d in gb:
        param = Parameters(g)

        # Permeability
        kxx = np.ones(g.num_cells) * np.power(kf, g.dim < gb.dim_max())
        if g.dim == 2:
            perm = tensor.SecondOrderTensor(3, kxx=kxx, kyy=kxx, kzz=1)
        else:
            perm = tensor.SecondOrderTensor(3, kxx=kxx, kyy=1, kzz=1)
            if g.dim == 1:
                R = cg.project_line_matrix(g.nodes, reference=[1, 0, 0])
                perm.rotate(R)

        param.set_tensor("flow", perm)

        # Source term
        param.set_source("flow", np.zeros(g.num_cells))

        # Assign apertures
        aperture = np.power(a, gb.dim_max() - g.dim)
        param.set_aperture(np.ones(g.num_cells) * aperture)

        # Boundaries
        bound_faces = g.tags['domain_boundary_faces'].nonzero()[0]
        if bound_faces.size != 0:
            bound_face_centers = g.face_centers[:, bound_faces]

            bottom_corner = np.logical_and(bound_face_centers[0, :] < 0.1,
                                           bound_face_centers[1, :] < 0.1)

            top_corner = np.logical_and(bound_face_centers[0, :] > 0.9,
                                        bound_face_centers[1, :] > 0.9)

            labels = np.array(['neu'] * bound_faces.size)
            dir_faces = np.logical_or(bottom_corner, top_corner)
            labels[dir_faces] = 'dir'

            bc_val = np.zeros(g.num_faces)
            bc_val[bound_faces[bottom_corner]] = 1
            bc_val[bound_faces[top_corner]] = -1

            param.set_bc("flow", BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val("flow", bc_val)
        else:
            param.set_bc("flow", BoundaryCondition(g, np.empty(0),
                                                   np.empty(0)))

        d['param'] = param

    # Assign coupling permeability
    gb.add_edge_prop('kn')
    for e, d in gb.edges_props():
        g = gb.sorted_nodes_of_edge(e)[0]
        d['kn'] = kf / gb.node_prop(g, 'param').get_aperture()
Esempio n. 22
0
    def test_tpfa_coupling_2d_1d_left_right_dir_neu(self):
        """
        Grid: 2 x 2 cells in matrix + 2 cells in the fracture from left to right.
        Dirichlet + inflow + no-flow, conductive fracture.
        Tests pressure solution as well as matrix and rhs.
        """
        f = np.array([[0, 1],
                      [.5, .5]])
        gb = meshing.cart_grid( [f], [2, 2], **{'physdims': [1, 1]})
        gb.compute_geometry()
        gb.assign_node_ordering()

        tol = 1e-3
        solver = tpfa.Tpfa(physics='flow')
        gb.add_node_props(['param'])
        a = 1e-2
        for g, d in gb:
            param = Parameters(g)

            a_dim = np.power(a, gb.dim_max() - g.dim)
            aperture = np.ones(g.num_cells)*a_dim
            param.set_aperture(aperture)

            p = tensor.SecondOrder(3,np.ones(g.num_cells)* np.power(1e3, g.dim<gb.dim_max()))
            param.set_tensor('flow', p)
            bound_faces = g.get_boundary_faces()
            bound_face_centers = g.face_centers[:, bound_faces]

            right = bound_face_centers[0, :] > 1 - tol
            left = bound_face_centers[0, :] < tol

            labels = np.array(['neu'] * bound_faces.size)
            labels[right] = ['dir']

            bc_val = np.zeros(g.num_faces)
            bc_dir = bound_faces[right]
            bc_neu = bound_faces[left]
            bc_val[bc_dir] = g.face_centers[0,bc_dir]
            bc_val[bc_neu] = -g.face_areas[bc_neu]*a_dim

            param.set_bc(solver, bc.BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val(solver, bc_val)

            d['param'] = param

       

        coupling_conditions = tpfa.TpfaCoupling(solver)
        solver_coupler = coupler.Coupler(solver, coupling_conditions)
        A, rhs = solver_coupler.matrix_rhs(gb)

        A_known = np.array(\
            [[  2.99996,  -1.     ,   0.     ,   0.     ,   0.     ,  -1.99996],
             [ -1.     ,   4.99996,   0.     ,   0.     ,  -1.99996,   0.     ],
             [  0.     ,   0.     ,   2.99996,  -1.     ,   0.     ,  -1.99996],
             [  0.     ,   0.     ,  -1.     ,   4.99996,  -1.99996,   0.     ],
             [  0.     ,  -1.99996,   0.     ,  -1.99996,  63.99992, -20.     ],
             [ -1.99996,   0.     ,  -1.99996,   0.     , -20.     ,  23.99992]] )
                           
        rhs_known = np.array([ 5.00000000e-01,   2.00000000e+00,   5.00000000e-01,
                               2.00000000e+00,   4.00000000e+01,   1.00000000e-02])
        p_known = np.array([ 1.21984244,  1.05198918,  1.21984244,  1.05198918,
                             1.02005108,  1.05376576])

        p = sps.linalg.spsolve(A, rhs)
        
        rtol = 1e-6
        atol = rtol
       
        assert np.allclose(A.todense(), A_known, rtol, atol)
        assert np.allclose(rhs, rhs_known, rtol, atol)
        assert np.allclose(p, p_known, rtol, atol)
Esempio n. 23
0
def edge_params(gb):
    gb.add_edge_prop('param')
    for e, d in gb.edges_props():
        g_h = gb.sorted_nodes_of_edge(e)[1]
        d['param'] = Parameters(g_h)
Esempio n. 24
0
    def test_tpfa_coupling_2d_1d_left_right_cross_dir_neu(self):
        f1 = np.array([[0, 2],
                       [.5, .5]])
        f2 = np.array([[.5, .5],
                       [0, 2]])

        gb = meshing.cart_grid( [f1, f2], [2, 2], **{'physdims': [1, 1]})
        gb.compute_geometry()
        gb.assign_node_ordering()
        
        # Enforce node orderning because of Python 3.5 and 2.7.
        # Don't do it in general.
        cell_centers_1 = np.array([[  7.50000000e-01, 2.500000000e-01],
                                   [  5.00000000e-01, 5.00000000e-01],
                                   [ -5.55111512e-17, 5.55111512e-17]])
        cell_centers_2 = np.array([[  5.00000000e-01, 5.00000000e-01],
                                   [  7.50000000e-01, 2.500000000e-01],
                                   [ -5.55111512e-17, 5.55111512e-17]])

        for g, d in gb:
            if g.dim == 1:
                if np.allclose(g.cell_centers, cell_centers_1):
                    d['node_number'] = 1
                elif np.allclose(g.cell_centers, cell_centers_2):
                    d['node_number'] = 2
                else:
                    raise ValueError('Grid not found')
        
        tol = 1e-3
        solver = tpfa.Tpfa()
        gb.add_node_props(['param'])
        a = 1e-2
        for g, d in gb:
            param = Parameters(g)

            a_dim = np.power(a, gb.dim_max() - g.dim)
            aperture = np.ones(g.num_cells)*a_dim
            param.set_aperture(aperture)

            kxx = np.ones(g.num_cells) * np.power(1e3, g.dim<gb.dim_max())
            #print(kxx, 'dim', g.dim)
            p = tensor.SecondOrder(3,kxx,kyy=kxx,kzz=kxx)
            #print(p.perm)
            param.set_tensor('flow', p)
            bound_faces = g.get_boundary_faces()
            bound_face_centers = g.face_centers[:, bound_faces]

            right = bound_face_centers[0, :] > 1 - tol
            left = bound_face_centers[0, :] < tol

            labels = np.array(['neu'] * bound_faces.size)
            labels[right] = ['dir']

            bc_val = np.zeros(g.num_faces)
            bc_dir = bound_faces[right]
            bc_neu = bound_faces[left]
            bc_val[bc_dir] = g.face_centers[0,bc_dir]
            bc_val[bc_neu] = -g.face_areas[bc_neu]*a_dim
            
            param.set_bc(solver, bc.BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val(solver, bc_val)

            d['param'] = param

       

        coupling_conditions = tpfa.TpfaCoupling(solver)
        solver_coupler = coupler.Coupler(solver, coupling_conditions)
        A, rhs = solver_coupler.matrix_rhs(gb)

        A_known, rhs_known = matrix_rhs_for_2d_1d_cross()
        
        rtol = 1e-6
        atol = rtol
       
        assert np.allclose(A.todense(), A_known, rtol, atol)
        assert np.allclose(rhs, rhs_known, rtol, atol)
Esempio n. 25
0
def add_data(gb, tol):
    """
    Define the permeability, apertures, boundary conditions
    """
    gb.add_node_props(["param"])

    # Aavatsmark_transmissibilities only for tpfa intra-dimensional coupling

    for g, d in gb:
        d["Aavatsmark_transmissibilities"] = True

        if g.dim < 2:
            continue

        param = Parameters(g)

        # Permeability
        kxx = np.array([perm(*pt) for pt in g.cell_centers.T])
        param.set_tensor("flow", tensor.SecondOrderTensor(3, kxx))

        # Source term
        frac_id = d["frac_id"][0]
        source = np.array([source_f[frac_id](*pt) for pt in g.cell_centers.T])
        param.set_source("flow", g.cell_volumes * source)

        # Boundaries
        bound_faces = g.tags["domain_boundary_faces"].nonzero()[0]
        if bound_faces.size != 0:
            bound_face_centers = g.face_centers[:, bound_faces]

            labels = np.array(["dir"] * bound_faces.size)

            bc_val = np.zeros(g.num_faces)
            bc = [sol_f[frac_id](*pt) for pt in bound_face_centers.T]
            bc_val[bound_faces] = np.array(bc)

            param.set_bc("flow", BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val("flow", bc_val)
        else:
            param.set_bc("flow", BoundaryCondition(g, np.empty(0),
                                                   np.empty(0)))

        d["param"] = param

    gb.add_edge_prop("Aavatsmark_transmissibilities")
    for _, d in gb.edges_props():
        d["Aavatsmark_transmissibilities"] = True
Esempio n. 26
0
    def test_tpfa_coupling_3d_2d_1d_0d_dir(self):
        f1 = np.array([[ 0,  1,  1,  0],
                       [ 0,  0,  1,  1],
                       [.5, .5, .5, .5]])
        f2 = np.array([[.5, .5, .5, .5],
                       [ 0,  1,  1,  0],
                       [ 0,  0,  1,  1]])
        f3 = np.array([[ 0,  1,  1,  0],
                       [.5, .5, .5, .5],
                       [ 0,  0,  1,  1]])

        gb = meshing.cart_grid([f1, f2, f3], [2, 2, 2],
                               **{'physdims': [1, 1, 1]})
        gb.compute_geometry()
        gb.assign_node_ordering()
        # Remove flag for dual
        cell_centers1 = np.array([[ 0.25 , 0.75 , 0.25 , 0.75],
                                  [ 0.25 , 0.25 , 0.75 , 0.75],
                                  [ 0.5  , 0.5  , 0.5  , 0.5 ]])
        cell_centers2 = np.array([[ 0.5  , 0.5  , 0.5  , 0.5 ],
                                  [ 0.25 , 0.25 , 0.75 , 0.75],
                                  [ 0.75 , 0.25 , 0.75 , 0.25]])
        cell_centers3 = np.array([[ 0.25 , 0.75 , 0.25 , 0.75],
                                  [ 0.5  , 0.5  , 0.5  , 0.5 ],
                                  [ 0.25 , 0.25 , 0.75 , 0.75]])
        cell_centers4 = np.array([[ 0.5 ], [ 0.25], [ 0.5 ]])
        cell_centers5 = np.array([[ 0.5 ], [ 0.75], [ 0.5 ]])
        cell_centers6 = np.array([[ 0.75], [ 0.5 ], [ 0.5 ]])
        cell_centers7 = np.array([[ 0.25], [ 0.5 ], [ 0.5 ]])
        cell_centers8 = np.array([[ 0.5 ], [ 0.5 ], [ 0.25]])
        cell_centers9 = np.array([[ 0.5 ], [ 0.5 ], [ 0.75]])

        for g, d in gb:
            if np.allclose(g.cell_centers[:, 0], cell_centers1[:, 0]):
                d['node_number'] = 1
            elif np.allclose(g.cell_centers[:, 0], cell_centers2[:, 0]):
                d['node_number'] = 2
            elif np.allclose(g.cell_centers[:, 0], cell_centers3[:, 0]):
                d['node_number'] = 3
            elif np.allclose(g.cell_centers[:, 0], cell_centers4[:, 0]):
                d['node_number'] = 4
            elif np.allclose(g.cell_centers[:, 0], cell_centers5[:, 0]):
                d['node_number'] = 5
            elif np.allclose(g.cell_centers[:, 0], cell_centers6[:, 0]):
                d['node_number'] = 6
            elif np.allclose(g.cell_centers[:, 0], cell_centers7[:, 0]):
                d['node_number'] = 7
            elif np.allclose(g.cell_centers[:, 0], cell_centers8[:, 0]):
                d['node_number'] = 8
            elif np.allclose(g.cell_centers[:, 0], cell_centers9[:, 0]):
                d['node_number'] = 9
            else:
                pass

        tol = 1e-3
        solver = tpfa.Tpfa()
        gb.add_node_props(['param'])

        a = 1e-2
        for g, d in gb:
            param = Parameters(g)

            aperture = np.ones(g.num_cells)*np.power(a, gb.dim_max() - g.dim)
            param.set_aperture(aperture)

            p = tensor.SecondOrder(3,np.ones(g.num_cells)* np.power(1e3, g.dim<gb.dim_max()))
            param.set_tensor('flow', p)
            bound_faces = g.get_boundary_faces()
            bound_face_centers = g.face_centers[:, bound_faces]

            left = bound_face_centers[0, :] > 1 - tol
            right = bound_face_centers[0, :] < tol

            labels = np.array(['neu'] * bound_faces.size)
            labels[np.logical_or(left, right)] = ['dir']

            bc_val = np.zeros(g.num_faces)
            bc_dir = bound_faces[np.logical_or(left, right)]
            bc_val[bc_dir] = g.face_centers[0,bc_dir]

            param.set_bc(solver, bc.BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val(solver, bc_val)

            d['param'] = param

       

        coupling_conditions = tpfa.TpfaCoupling(solver)
        solver_coupler = coupler.Coupler(solver, coupling_conditions)
        A, rhs = solver_coupler.matrix_rhs(gb)

        A_known, rhs_known, p_known = \
                matrix_rhs_pressure_for_test_tpfa_coupling_3d_2d_1d_0d()
        
        p = sps.linalg.spsolve(A, rhs)
        
        rtol = 1e-6
        atol = rtol
    
        assert np.allclose(A.todense(), A_known, rtol, atol)
        assert np.allclose(rhs, rhs_known, rtol, atol)
        assert np.allclose(p, p_known, rtol, atol)
Esempio n. 27
0
def add_data(gb, domain, kf):
    """
    Define the permeability, apertures, boundary conditions
    """
    gb.add_node_props(['param'])
    tol = 1e-5
    a = 1e-4

    for g, d in gb:
        param = Parameters(g)

        # Permeability
        kxx = np.ones(g.num_cells) * np.power(kf, g.dim < gb.dim_max())
        if g.dim == 2:
            perm = tensor.SecondOrderTensor(3, kxx=kxx, kyy=kxx, kzz=1)
        else:
            perm = tensor.SecondOrderTensor(3, kxx=kxx, kyy=1, kzz=1)
            if g.dim == 1:
                R = cg.project_line_matrix(g.nodes, reference=[1, 0, 0])
                perm.rotate(R)

        param.set_tensor("flow", perm)

        # Source term
        param.set_source("flow", np.zeros(g.num_cells))

        # Assign apertures
        aperture = np.power(a, gb.dim_max() - g.dim)
        param.set_aperture(np.ones(g.num_cells) * aperture)

        # Boundaries
        bound_faces = g.tags['domain_boundary_faces'].nonzero()[0]
        if bound_faces.size != 0:
            bound_face_centers = g.face_centers[:, bound_faces]

            left = bound_face_centers[0, :] < domain['xmin'] + tol
            right = bound_face_centers[0, :] > domain['xmax'] - tol

            labels = np.array(['neu'] * bound_faces.size)
            labels[right] = 'dir'

            bc_val = np.zeros(g.num_faces)
            bc_val[bound_faces[left]] = -aperture \
                * g.face_areas[bound_faces[left]]
            bc_val[bound_faces[right]] = 1

            param.set_bc("flow", BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val("flow", bc_val)
        else:
            param.set_bc("flow", BoundaryCondition(g, np.empty(0),
                                                   np.empty(0)))

        d['param'] = param

    # Assign coupling permeability
    gb.add_edge_prop('kn')
    for e, d in gb.edges_props():
        gn = gb.sorted_nodes_of_edge(e)
        aperture = np.power(a, gb.dim_max() - gn[0].dim)
        d['kn'] = np.ones(gn[0].num_cells) * kf / aperture
Esempio n. 28
0
    def test_tpfa_coupling_2d_1d_bottom_top_dir_neu(self):
        """
        Grid: 1 x 2 cells in matrix + 1 cell in the fracture from left to right.
        Dirichlet + inflow + no-flow, blocking fracture.
        """
        f = np.array([[0, 1],
                      [.5, .5]])
        gb = meshing.cart_grid( [f], [1, 2], **{'physdims': [1, 1]})
        gb.compute_geometry()
        gb.assign_node_ordering()

        tol = 1e-3
        solver = tpfa.Tpfa(physics='flow')
        solver = tpfa.Tpfa(physics='flow')
        gb.add_node_props(['param'])
        a = 1e-2
        for g, d in gb:
            param = Parameters(g)

            a_dim = np.power(a, gb.dim_max() - g.dim)
            aperture = np.ones(g.num_cells)*a_dim
            param.set_aperture(aperture)

            p = tensor.SecondOrder(3,np.ones(g.num_cells)* np.power(1e-3, g.dim<gb.dim_max()))
            param.set_tensor('flow', p)
            bound_faces = g.get_boundary_faces()
            bound_face_centers = g.face_centers[:, bound_faces]

            top = bound_face_centers[1, :] > 1 - tol
            bottom = bound_face_centers[1, :] < tol

            labels = np.array(['neu'] * bound_faces.size)
            labels[bottom] = ['dir']

            bc_val = np.zeros(g.num_faces)
            bc_dir = bound_faces[bottom]
            bc_neu = bound_faces[top]
            bc_val[bc_dir] = g.face_centers[1,bc_dir]
            bc_val[bc_neu] = -g.face_areas[bc_neu]*a_dim

            param.set_bc(solver, bc.BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val(solver, bc_val)

            d['param'] = param

       

        coupling_conditions = tpfa.TpfaCoupling(solver)
        solver_coupler = coupler.Coupler(solver, coupling_conditions)
        A, rhs = solver_coupler.matrix_rhs(gb)

        A_known = np.array([[ 4.19047619,  0.        , -0.19047619],
        [ 0.        ,  0.19047619, -0.19047619],
        [-0.19047619, -0.19047619,  0.38095238]])

        rhs_known = np.array([0, 1, 0])

        rtol = 1e-6
        atol = rtol
        
        assert np.allclose(A.todense(), A_known, rtol, atol)
        assert np.allclose(rhs, rhs_known, rtol, atol)
Esempio n. 29
0
    def test_no_dynamics_2d(self):
        g_list = setup_grids.setup_2d()
        for g in g_list:
            discr = biot.Biot()

            bound_faces = g.get_all_boundary_faces()
            bound = bc.BoundaryCondition(
                g, bound_faces.ravel("F"), ["dir"] * bound_faces.size
            )

            mu = np.ones(g.num_cells)
            c = tensor.FourthOrderTensor(g.dim, mu, mu)
            k = tensor.SecondOrderTensor(g.dim, np.ones(g.num_cells))

            bound_val = np.zeros(g.num_faces)

            param = Parameters(g)
            param.set_bc("flow", bound)
            param.set_bc("mechanics", bound)
            param.set_tensor("flow", k)
            param.set_tensor("mechanics", c)
            param.set_bc_val("mechanics", np.tile(bound_val, g.dim))
            param.set_bc_val("flow", bound_val)
            param.porosity = np.ones(g.num_cells)
            param.biot_alpha = 1
            data = {"param": param, "inverter": "python", "dt": 1}

            A, b = discr.matrix_rhs(g, data)
            sol = np.linalg.solve(A.todense(), b)

            self.assertTrue(np.isclose(sol, np.zeros(g.num_cells * (g.dim + 1))).all())
Esempio n. 30
0
    def test_0d_elimination_3d_2d_1d_0d(self):
        """
        3d case with a single 0d grid.
        """
        f1 = np.array([[0, 1, 1, 0], [0, 0, 1, 1], [.5, .5, .5, .5]])
        f2 = np.array([[.5, .5, .5, .5], [0, 1, 1, 0], [0, 0, 1, 1]])
        f3 = np.array([[0, 1, 1, 0], [.5, .5, .5, .5], [0, 0, 1, 1]])

        gb = meshing.cart_grid([f1, f2, f3], [2, 2, 2],
                               **{'physdims': [1, 1, 1]})
        gb.compute_geometry()
        gb.assign_node_ordering()

        cell_centers1 = np.array([[0.25, 0.75, 0.25, 0.75],
                                  [0.25, 0.25, 0.75, 0.75],
                                  [0.5, 0.5, 0.5, 0.5]])
        cell_centers2 = np.array([[0.5, 0.5, 0.5, 0.5],
                                  [0.25, 0.25, 0.75, 0.75],
                                  [0.75, 0.25, 0.75, 0.25]])
        cell_centers3 = np.array([[0.25, 0.75, 0.25,
                                   0.75], [0.5, 0.5, 0.5, 0.5],
                                  [0.25, 0.25, 0.75, 0.75]])
        cell_centers4 = np.array([[0.5], [0.25], [0.5]])
        cell_centers5 = np.array([[0.5], [0.75], [0.5]])
        cell_centers6 = np.array([[0.75], [0.5], [0.5]])
        cell_centers7 = np.array([[0.25], [0.5], [0.5]])
        cell_centers8 = np.array([[0.5], [0.5], [0.25]])
        cell_centers9 = np.array([[0.5], [0.5], [0.75]])

        for g, d in gb:
            if np.allclose(g.cell_centers[:, 0], cell_centers1[:, 0]):
                d['node_number'] = 1
            elif np.allclose(g.cell_centers[:, 0], cell_centers2[:, 0]):
                d['node_number'] = 2
            elif np.allclose(g.cell_centers[:, 0], cell_centers3[:, 0]):
                d['node_number'] = 3
            elif np.allclose(g.cell_centers[:, 0], cell_centers4[:, 0]):
                d['node_number'] = 4
            elif np.allclose(g.cell_centers[:, 0], cell_centers5[:, 0]):
                d['node_number'] = 5
            elif np.allclose(g.cell_centers[:, 0], cell_centers6[:, 0]):
                d['node_number'] = 6
            elif np.allclose(g.cell_centers[:, 0], cell_centers7[:, 0]):
                d['node_number'] = 7
            elif np.allclose(g.cell_centers[:, 0], cell_centers8[:, 0]):
                d['node_number'] = 8
            elif np.allclose(g.cell_centers[:, 0], cell_centers9[:, 0]):
                d['node_number'] = 9
            else:
                pass

        tol = 1e-3
        solver = tpfa.Tpfa()
        gb.add_node_props(['param'])

        a = 1e-2
        for g, d in gb:
            param = Parameters(g)

            aperture = np.ones(g.num_cells) * np.power(a, gb.dim_max() - g.dim)
            param.set_aperture(aperture)

            p = tensor.SecondOrderTensor(
                3,
                np.ones(g.num_cells) * np.power(1e3, g.dim < gb.dim_max()))
            param.set_tensor('flow', p)
            bound_faces = g.tags['domain_boundary_faces'].nonzero()[0]
            if bound_faces.size != 0:

                bound_face_centers = g.face_centers[:, bound_faces]

                left = bound_face_centers[0, :] > 1 - tol
                right = bound_face_centers[0, :] < tol

                labels = np.array(['neu'] * bound_faces.size)
                labels[np.logical_or(left, right)] = ['dir']

                bc_val = np.zeros(g.num_faces)
                bc_dir = bound_faces[np.logical_or(left, right)]
                bc_val[bc_dir] = g.face_centers[0, bc_dir]

                param.set_bc(solver,
                             bc.BoundaryCondition(g, bound_faces, labels))
                param.set_bc_val(solver, bc_val)
            else:
                param.set_bc("flow",
                             bc.BoundaryCondition(g, np.empty(0), np.empty(0)))
            d['param'] = param

        coupling_conditions = tpfa.TpfaCoupling(solver)
        solver_coupler = coupler.Coupler(solver, coupling_conditions)
        A, rhs = solver_coupler.matrix_rhs(gb)

        p = sps.linalg.spsolve(A, rhs)
        p_cond, _, _, _ = condensation.solve_static_condensation(A,
                                                                 rhs,
                                                                 gb,
                                                                 dim=0)

        solver_coupler.split(gb, 'pressure', p)
        solver_coupler.split(gb, "p_cond", p_cond)

        tol = 1e-10
        assert ((np.amax(np.absolute(p - p_cond))) < tol)
        assert (np.sum(
            error.error_L2(g, d['pressure'], d['p_cond'])
            for g, d in gb) < tol)