Пример #1
0
 def solve(self, save_as=None, save_every=1):
     """
     Solve both problems.
     """
     p = self.flow.step()
     self.flow.pressure()
     if self.flow.el:
         SC.compute_elimination_fluxes(self.flow.full_grid,
                                       self.flow.grid(), self.flow.el_data)
     self.flow.discharge()
     s = self.transport.solve(save_as=save_as, save_every=save_every)
     return p, s[self.transport.physics]
Пример #2
0
    def solve(self, transport_save_as=None, flow_save_as=None, save_every=1):
        """
        Solve both problems.

        Arguments:
        save_as (string), defaults to None. If a string is given, the solution
                          variable is saved to a vtk-file as save_as
        save_every (int), defines which time steps to save. save_every=2 will
                          store every second time step.
        """
        self.flow.step()
        if flow_save_as is not None:
            self.flow.pressure(flow_save_as)
            self.flow.split(flow_save_as)
            self.flow.save(variables=[flow_save_as])
        else:
            self.flow.pressure()

        if self.flow.el:
            SC.compute_elimination_fluxes(
                self.flow.full_grid, self.flow.grid(), self.flow.el_data
            )
        self.flow.discharge()
        self.transport.solve(transport_save_as, save_every)
Пример #3
0
    # gb = meshing.cart_grid(f, [2, 4], physdims=[2, 4])
    Nx, Ny = 10, 10
    # gb = meshing.cart_grid([np.array([[Nx / 2, Nx / 2], [1, Ny]])],
    #                       [Nx, Ny], physdims=[Nx, Ny])
    # gb = meshing.cart_grid(f_set, [Nx, Nx, Nx])
    path_to_gmsh = '~/gmsh-2.16.0-Linux/bin/gmsh'

    gb = meshing.simplex_grid(f_set, domain, gmsh_path=path_to_gmsh)
    gb.assign_node_ordering()

    ################## Transport solver ##################

    print("Compute global matrix and rhs for the advection problem")
    gb_r, elimination_data = gb.duplicate_without_dimension(0)
    condensation.compute_elimination_fluxes(gb, gb_r, elimination_data)

    add_data_transport(gb)
    add_data_transport(gb_r)

    upwind_solver = upwind.Upwind()
    upwind_cc = upwind.UpwindCoupling(upwind_solver)
    coupler_solver = coupler.Coupler(upwind_solver, upwind_cc)
    U, rhs = coupler_solver.matrix_rhs(gb)
    U_r, rhs_r = coupler_solver.matrix_rhs(gb_r)

    deltaT = np.amin([upwind_solver.cfl(g, d) for g, d in gb])
    deltaT_r = np.amin([upwind_solver.cfl(g, d) for g, d in gb_r])

    T = deltaT * max(Nx, Ny) * 4
Пример #4
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]])

        gb = pp.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 = pp.TpfaMixedDim('flow')
        gb.add_node_props(['param'])
        a = 1e-2
        for g, d in gb:
            param = pp.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 = pp.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('flow',
                             pp.BoundaryCondition(g, bound_faces, labels))
                param.set_bc_val('flow', bc_val)
            else:
                param.set_bc("flow",
                             pp.BoundaryCondition(g, np.empty(0), np.empty(0)))
            d['param'] = param

        gb.add_edge_props('param')
        for e, d in gb.edges():
            g_h = gb.nodes_of_edge(e)[1]
            d['param'] = pp.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)
        pp.fvutils.compute_discharges(gb)
        pp.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():
            g1, g2 = gb.nodes_of_edge(e)
            pa = data['param']
            node_numbers = [gb.node_props(g, 'node_number') for g in [g2, g1]]
            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():
            g1, g2 = gb_r.nodes_of_edge(e)
            pa = data['param']
            node_numbers = [
                gb_r.node_props(g, 'node_number') for g in [g2, g1]
            ]
            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(
            pp.error.error_L2(g, d['pressure'], d['p_cond'])
            for g, d in gb) < tol)
Пример #5
0
    def atest_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 = pp.meshing.cart_grid([f1, f2], [2, 2], **{"physdims": [1, 1]})
        # gb = pp.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 = pp.TpfaMixedDim()
        gb.add_node_props(["param"])
        a = 1e-2
        for g, d in gb:
            param = pp.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 = pp.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("flow",
                             pp.BoundaryCondition(g, bound_faces, labels))
                param.set_bc_val("flow", bc_val)
                # Transport
                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)

                param.set_bc("transport",
                             pp.BoundaryCondition(g, bound_faces, labels))
                param.set_bc_val("transport", bc_val)
            else:
                param.set_bc("transport",
                             pp.BoundaryCondition(g, np.empty(0), np.empty(0)))
                param.set_bc("flow",
                             pp.BoundaryCondition(g, np.empty(0), np.empty(0)))
            # Transport:
            source = g.cell_volumes * a_dim
            param.set_source("transport", source)

            d["param"] = param

        gb.add_edge_props("param")
        for e, d in gb.edges():
            g_h = gb.nodes_of_edge(e)[1]
            d["param"] = pp.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)

        # pp.fvutils.compute_discharges(gb)
        pp.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 = pp.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
        self.assertTrue(np.isclose(deltaT, deltaT_known, tol, tol))
        self.assertTrue((np.amax(np.absolute(U_r - U_known))) < tol)
        self.assertTrue((np.amax(np.absolute(rhs_u_r - rhs_known))) < tol)
        self.assertTrue((np.amax(np.absolute(theta_r - theta_known))) < tol)
Пример #6
0
    edge_params(gb)
    gb_el, el_data = gb.duplicate_without_dimension(1)

    problem = FlowModel(gb)
    problem_el = FlowModel(gb_el, el='_el')

    Both = BothProblems(problem, problem_el)
    k_h = 10**4
    k_v = 10**-4
    p, p_el = Both.solve(k_h, k_v)
    problem.flux_disc().split(gb, 'pressure', p)
    problem_el.flux_disc().split(gb_el, 'pressure', p_el)
    Both.save()

    SC.compute_elimination_fluxes(gb, gb_el, el_data)
    compute_discharges(gb_el)
    compute_discharges(gb)

    assign_data(gb, TransportData, 'transport_data')
    transport_problem = TransportSolver(gb)
    sol = transport_problem.solve()

    ndof_el = problem_el.flux_disc().ndof(gb_el)
    assign_data(gb_el, TransportData, 'transport_data')
    transport_problem_el = TransportSolver(gb_el, el='_el')
    sol_el = transport_problem_el.solve()

    t = sol['transport']
    t_el = sol_el['transport']
    transport_problem.split(x_name='solution')