Ejemplo n.º 1
0
 def diffusive_disc(self):
     'Discretization of term \nabla K \nabla T'
     if self.is_GridBucket:
         diffusive_discr = tpfa.TpfaMixedDim(physics=self.physics)
     else:
         diffusive_discr = tpfa.Tpfa(physics=self.physics)
     return diffusive_discr
Ejemplo n.º 2
0
 def flux_disc(self):
     if self.mp:
         return mpfa.MpfaMixedDim(physics=self.physics)
     elif self.mix:
         return MixedDiscretization(self.physics)
     else:
         return tpfa.TpfaMixedDim(physics=self.physics)
Ejemplo n.º 3
0
    def test_tpfa_matching_grids_no_flow(self):
        gb = self.set_grids(N=[1, 2], num_nodes_mortar=2, num_nodes_1d=2)
        self.set_param_flow(gb, no_flow=True)

        solver_flow = tpfa.TpfaMixedDim("flow")
        A_flow, b_flow = solver_flow.matrix_rhs(gb)

        p = sps.linalg.spsolve(A_flow, b_flow)
        self.assertTrue(np.all(p[:3] == 1))
        self.assertTrue(np.all(p[3:] == 0))
Ejemplo n.º 4
0
def solve_tpfa(gb, folder):

    # Choose and define the solvers and coupler
    solver_flow = tpfa.TpfaMixedDim("flow")
    A_flow, b_flow = solver_flow.matrix_rhs(gb)

    solver_source = source.IntegralMixedDim("flow")
    A_source, b_source = solver_source.matrix_rhs(gb)

    p = sps.linalg.spsolve(A_flow + A_source, b_flow + b_source)
    solver_flow.split(gb, "pressure", p)

    save = Exporter(gb, "sol", folder=folder)
    save.write_vtk(["pressure"])
Ejemplo n.º 5
0
    def test_tpfa_matching_grids_refine_2d_uniform_flow(self):

        kn = 1e4
        gb = self.set_grids(N=[2, 2], num_nodes_mortar=2, num_nodes_1d=2)
        self.set_param_flow(gb, no_flow=False, kn=kn)

        solver_flow = tpfa.TpfaMixedDim("flow")
        A_flow, b_flow = solver_flow.matrix_rhs(gb)

        p = sps.linalg.spsolve(A_flow, b_flow)
        solver_flow.split(gb, "pressure", p)
        g_2d = gb.grids_of_dimension(2)[0]
        p_2d = gb.node_props(g_2d, "pressure")
        # NOTE: This will not be entirely correct due to impact of normal permeability at fracture
        self.assertTrue(np.allclose(p_2d, g_2d.cell_centers[1], rtol=1e-4))

        g_1d = gb.grids_of_dimension(1)[0]
        p_1d = gb.node_props(g_1d, "pressure")
        # NOTE: This will not be entirely correct,
        self.assertTrue(np.allclose(p_1d, g_1d.cell_centers[1]))
Ejemplo n.º 6
0
def main(kf, description, multi_point, if_export=False):

    # Define the geometry and produce the meshes
    mesh_kwargs = {}
    mesh_size = 0.045
    mesh_kwargs['mesh_size'] = {
        'mode': 'constant',
        'value': mesh_size,
        'bound_value': mesh_size
    }
    domain = {'xmin': 0, 'xmax': 1, 'ymin': 0, 'ymax': 1}

    file_name = 'network_geiger.csv'
    write_network(file_name)
    gb = importer.dfm_2d_from_csv(file_name, mesh_kwargs, domain)
    gb.compute_geometry()
    gb.assign_node_ordering()

    # Assign parameters
    add_data(gb, domain, kf, mesh_size)

    # Choose discretization and define the solver
    if multi_point:
        solver = mpfa.MpfaMixedDim('flow')
    else:
        solver = tpfa.TpfaMixedDim('flow')

    # Discretize
    A, b = solver.matrix_rhs(gb)

    # Solve the linear system
    p = sps.linalg.spsolve(A, b)

    # Store the solution
    gb.add_node_props(['pressure'])
    solver.split(gb, 'pressure', p)

    if if_export:
        save = Exporter(gb, "fv", folder="fv_" + description)
        save.write_vtk(['pressure'])
Ejemplo n.º 7
0
 def flux_disc(self):
     if self.multi_point:
         return mpfa.MpfaMixedDim(physics=self.physics)
     else:
         return tpfa.TpfaMixedDim(physics=self.physics)
Ejemplo n.º 8
0
for g, d in gb:
    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
        flow_rate = d['u'][bound_faces[left]]
        total_flow_rate += np.sum(flow_rate)

print("total flow rate", total_flow_rate)
exporter.export_vtk(gb, 'darcy', ['pressure', "P0u"], folder=export_folder)

#################################################################

physics = 'transport'
advection = upwind.UpwindMixedDim(physics)
diffusion = tpfa.TpfaMixedDim(physics)
mass = mass_matrix.MassMatrixMixedDim(physics)
invMass = mass_matrix.InvMassMatrixMixedDim(physics)

# Assign parameters
add_data_advection_diffusion(gb, domain, tol, a)

T = 1
deltaT = 0.01
gb.add_node_prop('deltaT', prop=deltaT)

U, rhs_u = advection.matrix_rhs(gb)
D, rhs_d = diffusion.matrix_rhs(gb)
M, _ = mass.matrix_rhs(gb)
OF = advection.outflow(gb)
Ejemplo n.º 9
0
    def test_upwind_2d_1d_cross_with_elimination(self):
        """
        Simplest possible elimination scenario, one 0d-grid removed. Check on upwind
        matrix, rhs, solution and time step estimate. Full solution included
        (as comments) for comparison purposes if test breaks.
        """
        f1 = np.array([[0, 1], [.5, .5]])
        f2 = np.array([[.5, .5], [0, 1]])
        domain = {'xmin': 0, 'ymin': 0, 'xmax': 1, 'ymax': 1}
        mesh_size = 0.4
        mesh_kwargs = {}
        mesh_kwargs['mesh_size'] = {
            'mode': 'constant',
            'value': mesh_size,
            'bound_value': mesh_size
        }
        gb = meshing.cart_grid([f1, f2], [2, 2], **{'physdims': [1, 1]})
        #gb = meshing.simplex_grid( [f1, f2],domain,**mesh_kwargs)
        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.TpfaMixedDim()
        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.SecondOrder(3, kxx, kyy=kxx, kzz=kxx)
            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('flow', bc.BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val('flow', bc_val)

            # Transport:
            source = g.cell_volumes * a_dim
            param.set_source("transport", source)

            bound_faces = g.get_boundary_faces()
            bound_face_centers = g.face_centers[:, bound_faces]

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

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

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

            param.set_bc('transport',
                         bc.BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val('transport', bc_val)
            d['param'] = param

        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)

        A, rhs = solver.matrix_rhs(gb)
        # p = sps.linalg.spsolve(A,rhs)
        _, p_red, _, _ = condensation.solve_static_condensation(A,
                                                                rhs,
                                                                gb,
                                                                dim=0)
        dim_to_remove = 0
        gb_r, elimination_data = gb.duplicate_without_dimension(dim_to_remove)
        condensation.compute_elimination_fluxes(gb, gb_r, elimination_data)

        solver.split(gb_r, "pressure", p_red)

        # fvutils.compute_discharges(gb)
        fvutils.compute_discharges(gb_r)

        #------Transport------#
        advection_discr = upwind.Upwind(physics="transport")
        advection_coupling_conditions = upwind.UpwindCoupling(advection_discr)
        advection_coupler = coupler.Coupler(advection_discr,
                                            advection_coupling_conditions)
        U_r, rhs_u_r = advection_coupler.matrix_rhs(gb_r)
        _, rhs_src_r = IntegralMixedDim(physics='transport').matrix_rhs(gb_r)
        rhs_u_r = rhs_u_r + rhs_src_r
        deltaT = np.amin(
            gb_r.apply_function(advection_discr.cfl,
                                advection_coupling_conditions.cfl).data)

        theta_r = sps.linalg.spsolve(U_r, rhs_u_r)

        U_known, rhs_known, theta_known, deltaT_known = known_for_elimination()
        tol = 1e-7
        assert (np.isclose(deltaT, deltaT_known, tol, tol))
        assert ((np.amax(np.absolute(U_r - U_known))) < tol)
        assert ((np.amax(np.absolute(rhs_u_r - rhs_known))) < tol)
        assert ((np.amax(np.absolute(theta_r - theta_known))) < tol)
Ejemplo n.º 10
0
 def flux_disc(self):
     if self.is_GridBucket:
         return tpfa.TpfaMixedDim(physics=self.physics)
     else:
         return tpfa.Tpfa(physics=self.physics)
Ejemplo n.º 11
0
    def test_tpfa_fluxes_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 and fluxes.
        """
        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.TpfaMixedDim(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]

            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('flow', bc.BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val('flow', bc_val)

            d['param'] = param

        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)

        A, rhs = solver.matrix_rhs(gb)
        p = sps.linalg.spsolve(A, rhs)
        solver.split(gb, "pressure", p)
        fvutils.compute_discharges(gb)

        p_known = np.array([
            1.7574919, 1.25249747, 1.7574919, 1.25249747, 1.25250298,
            1.80993337
        ])

        # Known discharges
        d_0, d_1 = fluxes_2d_1d_left_right_dir_neu()

        rtol = 1e-6
        atol = rtol

        for _, d in gb:
            if d['node_number'] == 0:
                assert np.allclose(d['discharge'], d_0, rtol, atol)
            if d['node_number'] == 1:
                assert np.allclose(d['discharge'], d_1, rtol, atol)

        assert np.allclose(p, p_known, rtol, atol)
Ejemplo n.º 12
0
    def test_tpfa_fluxes_2d_1d_cross_with_elimination(self):
        f1 = np.array([[0, 1], [.5, .5]])
        f2 = np.array([[.5, .5], [0, 1]])
        domain = {'xmin': 0, 'ymin': 0, 'xmax': 1, 'ymax': 1}
        mesh_size = 0.4
        mesh_kwargs = {}
        mesh_kwargs['mesh_size'] = {
            'mode': 'constant',
            'value': mesh_size,
            'bound_value': mesh_size
        }
        gb = meshing.cart_grid([f1, f2], [2, 2], **{'physdims': [1, 1]})
        #gb = meshing.simplex_grid( [f1, f2],domain,**mesh_kwargs)
        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.TpfaMixedDim('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)

            kxx = np.ones(g.num_cells) * np.power(1e3, g.dim < gb.dim_max())
            p = tensor.SecondOrder(3, kxx, kyy=kxx, kzz=kxx)
            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('flow', bc.BoundaryCondition(g, bound_faces, labels))
            param.set_bc_val('flow', bc_val)

            d['param'] = param

        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)

        A, rhs = solver.matrix_rhs(gb)
        p = sps.linalg.spsolve(A, rhs)

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

        solver.split(gb, "p_cond", p_cond)
        solver.split(gb, "pressure", p)

        # Make a copy of the grid bucket without the 0d grid
        dim_to_remove = 0
        gb_r, elimination_data = gb.duplicate_without_dimension(dim_to_remove)
        # Compute the flux discretization on the new edges
        condensation.compute_elimination_fluxes(gb, gb_r, elimination_data)
        # Compute the discharges from the flux discretizations and computed pressures
        solver.split(gb_r, "pressure", p_red)
        fvutils.compute_discharges(gb)
        fvutils.compute_discharges(gb_r)

        # Known discharges
        d_0, d_1, d_2 = fluxes_2d_1d_cross_with_elimination()

        # Check node fluxes, ...
        rtol = 1e-6
        atol = rtol
        for g, d in gb:
            if d['node_number'] == 0:
                assert np.allclose(d['discharge'], d_0, rtol, atol)
            if d['node_number'] == 1:
                assert np.allclose(d['discharge'], d_1, rtol, atol)
            if d['node_number'] == 2:
                assert np.allclose(d['discharge'], d_2, rtol, atol)
        for g, d in gb_r:

            if d['node_number'] == 0:
                assert np.allclose(d['discharge'], d_0, rtol, atol)
            if d['node_number'] == 1:
                assert np.allclose(d['discharge'], d_1, rtol, atol)
            if d['node_number'] == 2:
                assert np.allclose(d['discharge'], d_2, rtol, atol)

        # ... edge fluxes ...
        d_01, d_10, d_02, d_20, d_13, d_23 = coupling_fluxes_2d_1d_cross_no_el(
        )

        for e, data in gb.edges_props():
            g1, g2 = gb.sorted_nodes_of_edge(e)
            pa = data['param']
            node_numbers = gb.nodes_prop([g2, g1], 'node_number')
            if pa is not None:

                if node_numbers == (0, 1):
                    assert np.allclose( data['discharge'], d_01, rtol, atol) or \
                        np.allclose( data['discharge'], d_10, rtol, atol)
                if node_numbers == (0, 2):
                    assert np.allclose( data['discharge'], d_02, rtol, atol) or \
                        np.allclose( data['discharge'], d_20, rtol, atol)
                if node_numbers == (1, 3):
                    assert np.allclose(data['discharge'], d_13, rtol, atol)
                if node_numbers == (2, 3):
                    assert np.allclose(data['discharge'], d_23, rtol, atol)

        d_11, d_21, d_22 = coupling_fluxes_2d_1d_cross_with_el()
        for e, data in gb_r.edges_props():
            g1, g2 = gb_r.sorted_nodes_of_edge(e)
            pa = data['param']
            node_numbers = gb_r.nodes_prop([g2, g1], 'node_number')
            if pa is not None:

                if node_numbers == (0, 1):
                    assert np.allclose( data['discharge'], d_01, rtol, atol) or \
                        np.allclose( data['discharge'], d_10, rtol, atol)
                if node_numbers == (0, 2):
                    assert np.allclose( data['discharge'], d_02, rtol, atol) or \
                        np.allclose( data['discharge'], d_20, rtol, atol)
                if node_numbers == (1, 1):
                    assert np.allclose(data['discharge'], d_11, rtol, atol)
                if node_numbers == (2, 1):
                    assert np.allclose(data['discharge'], d_21, rtol, atol)
                if node_numbers == (2, 2):
                    assert np.allclose(data['discharge'], d_22, rtol, atol)
        # ... and pressures
        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)