예제 #1
0
    def demo64(self, permeability, obs_case=1):
        mesh = UnitSquareMesh(63, 63)
        ak_values = permeability
        flux_order = 3
        s = scenarios.darcy_problem_1()
        DRT = fenics.FiniteElement("DRT", mesh.ufl_cell(), flux_order)
        # Lagrange
        CG = fenics.FiniteElement("CG", mesh.ufl_cell(), flux_order + 1)
        if s.integral_constraint:
            # From https://fenicsproject.org/qa/14184/how-to-solve-linear-system-with-constaint
            R = fenics.FiniteElement("R", mesh.ufl_cell(), 0)
            W = fenics.FunctionSpace(mesh, fenics.MixedElement([DRT, CG, R]))
            # Define trial and test functions
            (sigma, u, r) = fenics.TrialFunctions(W)
            (tau, v, r_) = fenics.TestFunctions(W)
        else:
            W = fenics.FunctionSpace(mesh, DRT * CG)
            # Define trial and test functions
            (sigma, u) = fenics.TrialFunctions(W)
            (tau, v) = fenics.TestFunctions(W)
        f = s.source_function
        g = s.g

        # Define property field function
        W_CG = fenics.FunctionSpace(mesh, "Lagrange", 1)
        if s.ak is None:
            ak = property_field.get_conductivity(W_CG, ak_values)
        else:
            ak = s.ak

        # Define variational form
        a = (fenics.dot(sigma, tau) + fenics.dot(ak * fenics.grad(u), tau) +
             fenics.dot(sigma, fenics.grad(v))) * fenics.dx
        L = -f * v * fenics.dx + g * v * fenics.ds
        # L = 0
        if s.integral_constraint:
            # Lagrange multiplier?  See above link.
            a += r_ * u * fenics.dx + v * r * fenics.dx
        # Define Dirichlet BC
        bc = fenics.DirichletBC(W.sub(1), s.dirichlet_bc, s.gamma_dirichlet)
        # Compute solution

        w = fenics.Function(W)
        fenics.solve(a == L, w, bc)
        # fenics.solve(a == L, w)
        if s.integral_constraint:
            (sigma, u, r) = w.split()
        else:
            (sigma, u) = w.split()
        x = u.compute_vertex_values(mesh)
        x2 = sigma.compute_vertex_values(mesh)
        p = x
        pre = p.reshape((64, 64))
        vx = x2[:4096].reshape((64, 64))
        vy = x2[4096:].reshape((64, 64))

        if obs_case == 1:
            dd = np.zeros([8, 8])
            pos = np.full((8 * 8, 2), 0)
            col = [4, 12, 20, 28, 36, 44, 52, 60]
            position = [4, 12, 20, 28, 36, 44, 52, 60]
            for i in range(8):
                for j in range(8):
                    row = position
                    pos[8 * i + j, :] = [col[i], row[j]]
                    dd[i, j] = pre[col[i], row[j]]
            like = dd.reshape(8 * 8, )
        return like, pre, vx, vy, ak_values, pos
예제 #2
0
    def demo16(self, permeability, obs_case=1):
        """This demo program solves the mixed formulation of Poisson's
        equation:

            sigma + grad(u) = 0    in Omega
                div(sigma) = f    in Omega
                    du/dn = g    on Gamma_N
                        u = u_D  on Gamma_D
        
        The corresponding weak (variational problem)
        
            <sigma, tau> + <grad(u), tau>   = 0
                                                    for all tau
                        - <sigma, grad(v)> = <f, v> + <g, v>
                                                    for all v
        
        is solved using DRT (Discontinuous Raviart-Thomas) elements
        of degree k for (sigma, tau) and CG (Lagrange) elements
        of degree k + 1 for (u, v) for k >= 1.
        """

        mesh = UnitSquareMesh(15, 15)
        ak_values = permeability
        flux_order = 3
        s = scenarios.darcy_problem_1()
        DRT = fenics.FiniteElement("DRT", mesh.ufl_cell(), flux_order)
        # Lagrange
        CG = fenics.FiniteElement("CG", mesh.ufl_cell(), flux_order + 1)
        if s.integral_constraint:
            # From https://fenicsproject.org/qa/14184/how-to-solve-linear-system-with-constaint
            R = fenics.FiniteElement("R", mesh.ufl_cell(), 0)
            W = fenics.FunctionSpace(mesh, fenics.MixedElement([DRT, CG, R]))
            # Define trial and test functions
            (sigma, u, r) = fenics.TrialFunctions(W)
            (tau, v, r_) = fenics.TestFunctions(W)
        else:
            W = fenics.FunctionSpace(mesh, DRT * CG)
            # Define trial and test functions
            (sigma, u) = fenics.TrialFunctions(W)
            (tau, v) = fenics.TestFunctions(W)
        f = s.source_function
        g = s.g

        # Define property field function
        W_CG = fenics.FunctionSpace(mesh, "Lagrange", 1)
        if s.ak is None:
            ak = property_field.get_conductivity(W_CG, ak_values)
        else:
            ak = s.ak

        # Define variational form
        a = (fenics.dot(sigma, tau) + fenics.dot(ak * fenics.grad(u), tau) +
             fenics.dot(sigma, fenics.grad(v))) * fenics.dx
        L = -f * v * fenics.dx + g * v * fenics.ds
        # L = 0
        if s.integral_constraint:
            # Lagrange multiplier?  See above link.
            a += r_ * u * fenics.dx + v * r * fenics.dx
        # Define Dirichlet BC
        bc = fenics.DirichletBC(W.sub(1), s.dirichlet_bc, s.gamma_dirichlet)
        # Compute solution
        w = fenics.Function(W)
        fenics.solve(a == L, w, bc)
        # fenics.solve(a == L, w)
        if s.integral_constraint:
            (sigma, u, r) = w.split()
        else:
            (sigma, u) = w.split()
        x = u.compute_vertex_values(mesh)
        x2 = sigma.compute_vertex_values(mesh)
        p = x
        pre = p.reshape((16, 16))
        vx = x2[:256].reshape((16, 16))
        vy = x2[256:].reshape((16, 16))

        if obs_case == 1:
            dd = np.zeros([8, 8])
            pos = np.full((8 * 8, 2), 0)
            col = [1, 3, 5, 7, 9, 11, 13, 15]
            position = [1, 3, 5, 7, 9, 11, 13, 15]
            for i in range(8):
                for j in range(8):
                    row = position
                    pos[8 * i + j, :] = [col[i], row[j]]
                    dd[i, j] = pre[col[i], row[j]]
            like = dd.reshape(8 * 8, )
        return like, pre, vx, vy, ak_values, pos