示例#1
0
def test_uniform_displacement():

    g_list = setup_grids.setup_2d()

    for g in g_list:
        bound_faces = np.argwhere(
            np.abs(g.cell_faces).sum(axis=1).A.ravel('F') == 1)
        bound = bc.BoundaryCondition(g, bound_faces.ravel(1),
                                     ['dir'] * bound_faces.size)
        constit = setup_stiffness(g)

        # Python inverter is most efficient for small problems
        stress, bound_stress = mpsa.mpsa(g, constit, bound, inverter='python')

        div = fvutils.vector_divergence(g)
        a = div * stress

        d_x = np.random.rand(1)
        d_y = np.random.rand(1)
        d_bound = np.zeros((g.dim, g.num_faces))
        d_bound[0, bound.is_dir] = d_x
        d_bound[1, bound.is_dir] = d_y

        rhs = div * bound_stress * d_bound.ravel('F')

        d = np.linalg.solve(a.todense(), rhs)

        traction = stress * d - bound_stress * d_bound.ravel('F')

        assert np.max(np.abs(d[::2] - d_x)) < 1e-8
        assert np.max(np.abs(d[1::2] - d_y)) < 1e-8
        assert np.max(np.abs(traction)) < 1e-8
示例#2
0
def tpfa_matrix(g, perm=None, faces=None):
    """
    Compute a two-point flux approximation matrix useful related to a call of
    create_partition.

    Parameters
    ----------
    g: the grid
    perm: (optional) permeability, the it is not given unitary tensor is assumed
    faces (np.array, int): Index of faces where TPFA should be applied.
            Defaults all faces in the grid.

    Returns
    -------
    out: sparse matrix
        Two-point flux approximation matrix

    """
    if perm is None:
        perm = second_order_tensor.SecondOrderTensor(g.dim,
                                                     np.ones(g.num_cells))

    bound = bc.BoundaryCondition(g, np.empty(0), '')
    trm, _ = tpfa.tpfa(g, perm, bound, faces)
    div = g.cell_faces.T
    return div * trm
示例#3
0
    def test_no_dynamics_2d(self):
        g_list = setup_grids.setup_2d()
        for g in g_list:
            bound_faces = g.get_boundary_faces()
            bound = bc.BoundaryCondition(g, bound_faces.ravel('F'),
                                         ['dir'] * bound_faces.size)
            flux, bound_flux, div_flow = self.mpfa_discr(g, bound)

            a_flow = div_flow * flux

            stress, bound_stress, grad_p, div_d, \
                stabilization, div_mech = self.mpsa_discr(g, bound)

            a_mech = div_mech * stress

            a_biot = sps.bmat([[a_mech, grad_p],
                               [div_d, a_flow + stabilization]])

            bval_mech = np.ones(g.num_faces * g.dim)
            bval_flow = np.ones(g.num_faces)
            rhs = np.hstack((div_mech * bound_stress * bval_mech,
                             div_flow * bound_flux * bval_flow))
            sol = np.linalg.solve(a_biot.todense(), rhs)

            assert np.isclose(sol, np.ones(g.num_cells * (g.dim + 1))).all()
示例#4
0
def upwind_example2(**kwargs):
    #######################
    # Simple 2d upwind problem with explicit Euler scheme in time coupled with
    # a Darcy problem
    #######################
    T = 2
    Nx, Ny = 10, 10
    g = structured.CartGrid([Nx, Ny], [1, 1])
    g.compute_geometry()

    kxx = np.ones(g.num_cells)
    perm = second_order_tensor.SecondOrderTensor(g.dim, kxx)

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

    f = np.zeros(g.num_cells)

    b_faces = g.get_boundary_faces()
    bnd = bc.BoundaryCondition(g, b_faces, ['dir'] * b_faces.size)
    bnd_val = {'dir': funp_ex(g.face_centers[:, b_faces])}

    solver = dual.DualVEM()
    data = {'k': perm, 'f': f, 'bc': bnd, 'bc_val': bnd_val}
    D, rhs = solver.matrix_rhs(g, data)

    up = sps.linalg.spsolve(D, rhs)
    beta_n = solver.extractU(g, up)

    u, p = solver.extractU(g, up), solver.extractP(g, up)
    P0u = solver.projectU(g, u, data)
    export_vtk(g, "darcy", {"p": p, "P0u": P0u})

    advect = upwind.Upwind()

    bnd_val = {'dir': np.hstack(([1], np.zeros(b_faces.size - 1)))}
    data = {'beta_n': beta_n, 'bc': bnd, 'bc_val': bnd_val}

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

    data = {'deltaT': advect.cfl(g, data)}
    M, _ = mass_matrix.Mass().matrix_rhs(g, data)

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

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

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

    export_pvd(g, "conc_darcy", time)
示例#5
0
def test_uniform_flow_cart_2d():
    nx = np.array([13, 13])
    g = structured.CartGrid(nx)
    g.compute_geometry()

    kxx = np.ones(g.num_cells)
    perm = second_order_tensor.SecondOrderTensor(g.dim, kxx)
    bound_faces = np.argwhere(np.abs(g.cell_faces).sum(axis=1).A.ravel(1) == 1)
    bound = bc.BoundaryCondition(g, bound_faces, ['dir'] * bound_faces.size)

    flux = tpfa.tpfa(g, perm, bound)
示例#6
0
def test_tpfa_cart_2d():
    """ Apply TPFA on Cartesian grid, should obtain Laplacian stencil. """

    # Set up 3 X 3 Cartesian grid
    nx = np.array([3, 3])
    g = structured.CartGrid(nx)
    g.compute_geometry()

    kxx = np.ones(g.num_cells)
    perm = second_order_tensor.SecondOrderTensor(g.dim, kxx)

    bound_faces = np.array([0, 3, 12])
    bound = bc.BoundaryCondition(g, bound_faces, ['dir'] * bound_faces.size)

    trm, bound_flux = tpfa.tpfa(g, perm, bound)
    div = g.cell_faces.T
    a = div * trm
    b = (div * bound_flux).A
    print(b)
    # Checks on interior cell
    mid = 4
    assert a[mid, mid] == 4
    assert a[mid - 1, mid] == -1
    assert a[mid + 1, mid] == -1
    assert a[mid - 3, mid] == -1
    assert a[mid + 3, mid] == -1

    assert np.all(b[mid, :] == 0)

    # The first cell should have two Dirichlet bnds
    assert a[0, 0] == 6
    assert a[0, 1] == -1
    assert a[0, 3] == -1

    assert b[0, 0] == 2
    assert b[0, 12] == 2

    # Cell 3 has one Dirichlet, one Neumann face
    assert a[2, 2] == 4
    assert a[2, 1] == -1
    assert a[2, 5] == -1

    assert b[2, 3] == 2
    assert b[2, 14] == 1
    # Cell 2 has one Neumann face
    assert a[1, 1] == 3
    assert a[1, 0] == -1
    assert a[1, 2] == -1
    assert a[1, 4] == -1

    assert b[1, 13] == 1

    return a
示例#7
0
def test_uniform_strain():
    g_list = setup_grids.setup_2d()

    for g in g_list:
        bound_faces = np.argwhere(
            np.abs(g.cell_faces).sum(axis=1).A.ravel('F') == 1)
        bound = bc.BoundaryCondition(g, bound_faces.ravel('F'),
                                     ['dir'] * bound_faces.size)
        mu = 1
        l = 1
        constit = setup_stiffness(g, mu, l)

        # Python inverter is most efficient for small problems
        stress, bound_stress = mpsa.mpsa(g, constit, bound, inverter='python')

        div = fvutils.vector_divergence(g)
        a = div * stress

        xc = g.cell_centers
        xf = g.face_centers

        gx = np.random.rand(1)
        gy = np.random.rand(1)

        dc_x = np.sum(xc * gx, axis=0)
        dc_y = np.sum(xc * gy, axis=0)
        df_x = np.sum(xf * gx, axis=0)
        df_y = np.sum(xf * gy, axis=0)

        d_bound = np.zeros((g.dim, g.num_faces))
        d_bound[0, bound.is_dir] = df_x[bound.is_dir]
        d_bound[1, bound.is_dir] = df_y[bound.is_dir]

        rhs = div * bound_stress * d_bound.ravel('F')

        d = np.linalg.solve(a.todense(), rhs)

        traction = stress * d - bound_stress * d_bound.ravel('F')

        s_xx = (2 * mu + l) * gx + l * gy
        s_xy = mu * (gx + gy)
        s_yx = mu * (gx + gy)
        s_yy = (2 * mu + l) * gy + l * gx

        n = g.face_normals
        traction_ex_x = s_xx * n[0] + s_xy * n[1]
        traction_ex_y = s_yx * n[0] + s_yy * n[1]

        assert np.max(np.abs(d[::2] - dc_x)) < 1e-8
        assert np.max(np.abs(d[1::2] - dc_y)) < 1e-8
        assert np.max(np.abs(traction[::2] - traction_ex_x)) < 1e-8
        assert np.max(np.abs(traction[1::2] - traction_ex_y)) < 1e-8
示例#8
0
    def __init__(self, grid, perm, stiffness, poro, bound_flow=None,
                 bound_mech=None, water_compr=1, water_viscosity=1, verbose=0,
                inverter='cython', eta=0):

        self.g = grid
        self.perm = perm
        self.stiffness = stiffness
        self.poro = poro


        # Boundaries and boundary conditions
        bound_faces = grid.get_boundary_faces()

        if bound_flow is None:
            self.bound_flow = bc.BoundaryCondition(grid, bound_faces.ravel('F'),
                                          ['neu'] * bound_faces.size)
        elif isinstance(bound_flow, str) \
                and (bound_flow.lower().strip() == 'dir'
                     or bound_flow.lower().strip() == 'dirichlet'):
            self.bound_flow = bc.BoundaryCondition(grid, bound_faces.ravel('F'),
                                          ['dir'] * bound_faces.size)
        elif isinstance(bound_flow, str) \
                and (bound_flow.lower().strip() == 'neu'
                     or bound_flow.lower().strip() == 'neumann'):
            self.bound_flow = bc.BoundaryCondition(grid, bound_faces.ravel('F'),
                                          ['neu'] * bound_faces.size)
        else:
            self.bound_flow = bound_flow

        if bound_mech is None:
            self.bound_mech = bc.BoundaryCondition(grid, bound_faces.ravel('F'),
                                          ['neu'] * bound_faces.size)
        elif isinstance(bound_mech, str) \
                and (bound_mech.lower().strip() == 'dir'
                     or bound_mech.lower().strip() == 'dirichlet'):
            self.bound_mech = bc.BoundaryCondition(grid, bound_faces.ravel('F'),
                                          ['dir'] * bound_faces.size)
        elif isinstance(bound_mech, str) \
                and (bound_mech.lower().strip() == 'neu'
                     or bound_mech.lower().strip() == 'neumann'):
            self.bound_mech = bc.BoundaryCondition(grid, bound_faces.ravel('F'),
                                          ['neu'] * bound_faces.size)
        else:
            self.bound_mech = bound_mech

        self.water_compr = water_compr
        self.water_viscosity = water_viscosity
        self.inverter = inverter
        self.eta = eta
        self.verbose = verbose
        self.biot_alpha = 1
示例#9
0
def upwind_example1(**kwargs):
    #######################
    # 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()
    beta_n = advect.beta_n(g, [1, 0, 0])

    b_faces = g.get_boundary_faces()
    bnd = bc.BoundaryCondition(g, b_faces, ['dir'] * b_faces.size)
    bnd_val = {'dir': np.hstack(([1], np.zeros(b_faces.size - 1)))}
    data = {'beta_n': beta_n, 'bc': bnd, 'bc_val': bnd_val}

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

    data = {'deltaT': 2 * advect.cfl(g, data)}
    M, _ = mass_matrix.Mass().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)
    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
        export_vtk(g, "conc_IE", {"conc": conc}, time_step=i)

    export_pvd(g, "conc_IE", time)
示例#10
0
def upwind_example0(**kwargs):
    #######################
    # Simple 2d upwind problem with explicit Euler scheme in time
    #######################
    T = 1
    Nx, Ny = 10, 1
    g = structured.CartGrid([Nx, Ny], [1, 1])
    g.compute_geometry()

    advect = upwind.Upwind()
    beta_n = advect.beta_n(g, [1, 0, 0])

    b_faces = g.get_boundary_faces()
    bnd = bc.BoundaryCondition(g, b_faces, ['dir'] * b_faces.size)
    bnd_val = {'dir': np.hstack(([1], np.zeros(b_faces.size - 1)))}
    data = {'beta_n': beta_n, 'bc': bnd, 'bc_val': bnd_val}

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

    data = {'deltaT': advect.cfl(g, data)}
    M, _ = mass_matrix.Mass().matrix_rhs(g, data)

    conc = np.zeros(g.num_cells)

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

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

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

    export_pvd(g, "conc_EE", time)