示例#1
0
def solve(n_cells, degree=3, with_plot=False):
    # Space
    # element = HermiteElement(degree)
    poly_set = leg.basis_functions(degree)
    dof_set = equidistant_points(degree)
    element = LagrangeElement(poly_set, dof_set)

    a, b = -1., 1.
    mesh = IntervalMesh(a=a, b=b, n_cells=n_cells)
    V = FunctionSpace(mesh, element)

    # Need mass matrix to intefrate the rhs
    Mget_geom_tensor = lambda cell: 1./cell.Jac
    M = assemble_matrix(V, 'mass', Mget_geom_tensor, timer=0)
    
    # Stiffness matrix for Laplacian
    Aget_geom_tensor = lambda cell: cell.Jac
    A = assemble_matrix(V, 'stiff', Aget_geom_tensor, timer=0)

    print 'M sym', is_symmetric(M)
    print 'A sym', is_symmetric(A)

    ew, ev = eigh(A.toarray(), M.toarray())
    ew = np.abs(ew)

    # Now add inner(dot(grad(u), n), v)*ds
    G = get_G(V)
    # A = A - G

    # print 'A sym', is_symmetric(A)
    # ew, ev = eig(A.toarray())#, M.toarray())
    # ew = np.sort(np.abs(ew))[:3]
    # print ew

    # from sympy import symbols, sqrt, S

    # x = symbols('x')
    # nullspace = map(Expression, [S(1/2.), sqrt(3/2.)*x])

    # Z = [V.interpolate(f).vector for f in nullspace]

    # print [np.inner(pi_z, A.dot(pi_z)) for pi_z in Z]

    print 'xxx'
    print M.toarray()
    print
    print A.toarray()
    print
    print G.toarray()
示例#2
0
def solve(n_cells, degree=3, with_plot=False):
    # Problem
    x = Symbol('x')
    vvvv = -0.0625*x**3/pi**3 + 0.0625*x/pi**3 + sin(2*pi*x)/(16*pi**4)
    u = -vvvv.diff(x, 2)
    f = sin(2*pi*x)

    # As Expr
    u = Expression(u)
    f = Expression(f)
    vvvv = Expression(vvvv)

    # Space
    element = HermiteElement(degree)

    mesh = IntervalMesh(a=-1, b=1, n_cells=n_cells)
    V = FunctionSpace(mesh, element)
    bc = DirichletBC(V, vvvv)

    # Need mass matrix to intefrate the rhs
    M = assemble_matrix(V, 'mass', get_geom_tensor=None, timer=0)
    # NOTE We cannot you apply the alpha transform idea because the functions
    # are mapped with this selective weight on 2nd, 3rd functions. So some rows
    # of alpha would have to be multiplied by weights which are cell specific.
    # And then on top of this there would be a dx = J*dy term. Better just to
    # use the qudrature representations
    # Mpoly_matrix = leg.mass_matrix(degree)
    # M_ = assemble_matrix(V, Mpoly_matrix, Mget_geom_tensor, timer=0)
    
    # Stiffness matrix for Laplacian
    A = assemble_matrix(V, 'bending', get_geom_tensor=None, timer=0)
    # NOTE the above
    # Apoly_matrix = leg.stiffness_matrix(degree)
    # A_ = assemble_matrix(V, Apoly_matrix, Aget_geom_tensor, timer=0)
  
    # Interpolant of source
    fV = V.interpolate(f)
    # Integrate in L2 to get the vector
    b = M.dot(fV.vector)
    
    # Apply boundary conditions
    bc.apply(A, b, True)
    x = spsolve(A, b)

    print '>>>>', np.linalg.norm(x - V.interpolate(vvvv).vector)

    ALaplace = assemble_matrix(V, 'stiffness', get_geom_tensor=None, timer=0)

    c = ALaplace.dot(x)
    y = spsolve(M, c)
    uh = Function(V, y)

    # This is a (slow) way of plotting the high order
    if with_plot:
        fig = plt.figure()
        ax = fig.gca()
        uV = V.interpolate(u)
        
        for cell in Cells(mesh):
            a, b = cell.vertices[0, 0], cell.vertices[1, 0]
            x = np.linspace(a, b, 100)

            y = uh.eval_cell(x, cell)
            ax.plot(x, y, color=random.choice(['b', 'g', 'm', 'c']))
            
            y = uV.eval_cell(x, cell)
            ax.plot(x, y, color='r')

            y = u.eval_cell(x, cell)
            ax.plot(x, y, color='k')

        plt.show()

    # Error norm
    fine_degree = degree + 3
    element = HermiteElement(fine_degree)
    
    V_fine = FunctionSpace(mesh, element)
    # Interpolate exact solution to fine
    u_fine = V_fine.interpolate(u)
    # Interpolate approx solution fine
    uh_fine = V_fine.interpolate(uh)

    # Difference vector
    e = u_fine.vector - uh_fine.vector

    # Integrate the error
    A_fine = assemble_matrix(V_fine, 'mass', get_geom_tensor=None, timer=0)
    e = sqrt(np.sum(e*A_fine.dot(e)))
    # Mesh size
    hmin = mesh.hmin()

    # Add the cond number
    kappa = np.linalg.cond(A.toarray())

    return hmin, e, kappa, A.shape[0]
示例#3
0
def _solve(mode, points, degree, n_cells, u, f):
    '''
    In mode == convergence:
    Solve -u`` = f with dirichet bcs bdry of (-1, 1) given by exact solution.
    The Vh space is CG_space of degree elements and n_cells. Return hmin, error
    for convergence computation.

    In mode == cond:
    Just return h and the matrix A.
    '''
    # Element. The polynomial space is spanned by Legendre basis
    poly_set = leg.basis_functions(degree)
    dof_set = points(degree)
    element = LagrangeElement(poly_set, dof_set)

    # Mesh
    mesh = IntervalMesh(a=-1, b=1, n_cells=n_cells)

    # Space
    V = FunctionSpace(mesh, element)
    bc = DirichletBC(V, u)

    # Need mass matrix to intefrate the rhs
    Mpoly_matrix = leg.mass_matrix(degree)
    Mget_geom_tensor = lambda cell: 1./cell.Jac
    M = assemble_matrix(V, Mpoly_matrix, Mget_geom_tensor, timer=0)
    
    # Stiffness matrix for Laplacian
    Apoly_matrix = leg.stiffness_matrix(degree)
    Aget_geom_tensor = lambda cell: cell.Jac
    A = assemble_matrix(V, Apoly_matrix, Aget_geom_tensor, timer=0)
   
    # Interpolant of source
    fV = V.interpolate(f)
    # Integrate in L2 to get the vector
    b = M.dot(fV.vector)
    
    # Apply boundary conditions
    bc.apply(A, b, True)
    x = spsolve(A, b)

    if mode == 'condition':
        return mesh.hmin(), A

    # As function
    uh = Function(V, x)
   
    # Error norm
    # Higher order DG element
    fine_degree = degree + 3
    poly_set = leg.basis_functions(fine_degree)
    dof_set = chebyshev_points(fine_degree)
    element = LagrangeElement(poly_set, dof_set)
    # THe space
    V_fine = FunctionSpace(mesh, element, 'L2')
    # Interpolate exact solution to fine
    u_fine = V_fine.interpolate(u)
    # Interpolate approx solution fine
    uh_fine = V_fine.interpolate(uh)

    # Difference vector
    e = u_fine.vector - uh_fine.vector
    # Need matrix for integration of H10 norm
    Apoly_matrix = leg.stiffness_matrix(fine_degree)
    A_fine = assemble_matrix(V_fine, Apoly_matrix, Aget_geom_tensor, timer=1)
    # Integrate the error
    e = sqrt(np.sum(e*A_fine.dot(e)))
    # Mesh size
    hmin = mesh.hmin()

    return hmin, e
示例#4
0
def solve(n_cells, degree=3, with_plot=False):
    # Problem
    w = 3 * np.pi
    x = Symbol("x")
    u = sin(w * x)
    f = -u.diff(x, 2)

    # As Expr
    u = Expression(u)
    f = Expression(f)

    # Space
    # element = HermiteElement(degree)
    poly_set = leg.basis_functions(degree)
    dof_set = chebyshev_points(degree)
    element = LagrangeElement(poly_set, dof_set)

    mesh = IntervalMesh(a=-1, b=1, n_cells=n_cells)
    V = FunctionSpace(mesh, element)
    bc = DirichletBC(V, u)

    # Need mass matrix to intefrate the rhs
    M = assemble_matrix(V, "mass", get_geom_tensor=None, timer=0)
    # NOTE We cannot you apply the alpha transform idea because the functions
    # are mapped with this selective weight on 2nd, 3rd functions. So some rows
    # of alpha would have to be multiplied by weights which are cell specific.
    # And then on top of this there would be a dx = J*dy term. Better just to
    # use the qudrature representations
    # Mpoly_matrix = leg.mass_matrix(degree)
    # M_ = assemble_matrix(V, Mpoly_matrix, Mget_geom_tensor, timer=0)

    # Stiffness matrix for Laplacian
    A = assemble_matrix(V, "stiffness", get_geom_tensor=None, timer=0)
    # NOTE the above
    # Apoly_matrix = leg.stiffness_matrix(degree)
    # A_ = assemble_matrix(V, Apoly_matrix, Aget_geom_tensor, timer=0)

    # Interpolant of source
    fV = V.interpolate(f)
    # Integrate in L2 to get the vector
    b = M.dot(fV.vector)

    # Apply boundary conditions
    bc.apply(A, b, True)
    x = spsolve(A, b)

    # As function
    uh = Function(V, x)

    # This is a (slow) way of plotting the high order
    if with_plot:
        fig = plt.figure()
        ax = fig.gca()
        uV = V.interpolate(u)

        for cell in Cells(mesh):
            a, b = cell.vertices[0, 0], cell.vertices[1, 0]
            x = np.linspace(a, b, 100)

            y = uh.eval_cell(x, cell)
            ax.plot(x, y, color=random.choice(["b", "g", "m", "c"]))

            y = uV.eval_cell(x, cell)
            ax.plot(x, y, color="r")

            y = u.eval_cell(x, cell)
            ax.plot(x, y, color="k")

        plt.show()

    # Error norm in CG high order
    fine_degree = degree + 3
    poly_set = leg.basis_functions(fine_degree)
    dof_set = chebyshev_points(fine_degree)
    element = LagrangeElement(poly_set, dof_set)

    V_fine = FunctionSpace(mesh, element)
    # Interpolate exact solution to fine
    u_fine = V_fine.interpolate(u)
    # Interpolate approx solution fine
    uh_fine = V_fine.interpolate(uh)

    # Difference vector
    e = u_fine.vector - uh_fine.vector

    # L2
    if False:
        Apoly_matrix = leg.mass_matrix(fine_degree)
        get_geom_tensor = lambda cell: 1.0 / cell.Jac

    # Need matrix for integration of H10 norm
    else:
        Apoly_matrix = leg.stiffness_matrix(fine_degree)
        get_geom_tensor = lambda cell: cell.Jac

    A_fine = assemble_matrix(V_fine, Apoly_matrix, get_geom_tensor, timer=0)

    # Integrate the error
    e = sqrt(np.sum(e * A_fine.dot(e)))
    # Mesh size
    hmin = mesh.hmin()

    # Add the cond number
    kappa = np.linalg.cond(A.toarray())

    return hmin, e, kappa, A.shape[0]