Пример #1
0
def get_bubble(deg):
    x = Symbol('x')
    poly_set = leg.basis_functions(deg=deg)
    pts = np.r_[-1, 1, chebyshev_points(deg)[1:-1]]
    
    A = np.zeros((deg+1, deg+1))
    for col, f in enumerate(poly_set):
        A[:, col] = lambdify(x, poly_set[col], 'numpy')(pts)
    b = np.zeros(deg+1)
    nodal_pt_index = -1 if deg % 2 else -deg/2
    b[nodal_pt_index] = 1

    bubble = np.linalg.solve(A, b)
    bubble_dof = pts[nodal_pt_index]  # Point eval here
    # Return coefs of bubble w.r.t legendre and the node
    return bubble, bubble_dof
Пример #2
0
# 0 boundary values

x = Symbol('x')
poly_set = leg.basis_functions(deg=deg)

# f = a*l0 + b*l1 + c*l2
# Suppose we reure that the L-2 norm is 1
# [f(-1)=0] = [l0(-1), l1(-1), l2(-1) ] [a]
# [f(1)=0 ] = [l0(1), l1(1), l2(1) ] [b]
# [norm=1 ] = [(l0, l0), ...            [c]    
# suppose instead nodality at 0
# [f(0) = 1] = .....

A = np.zeros((deg+1, deg+1))

pts = np.r_[-1, 1, chebyshev_points(deg)[1:-1]]

for col, f in enumerate(poly_set):
    A[:, col] = lambdify(x, poly_set[col], 'numpy')(pts)

# norm
# A[2] = [float(integrate(f*f, (x, -1, 1))) for f in poly_set]
b = np.zeros(deg+1)
b[-1 if deg % 2 else -deg/2] = 1


coefs = np.linalg.solve(A, b)
f = sum(c*f for c, f in zip(coefs, poly_set))
#plot(f, (x, -1, 1))

Пример #3
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]
Пример #4
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
Пример #5
0
    import sys
    sys.path.append('../')
    from mesh import IntervalMesh
    from cg_space import FunctionSpace
    from function import Constant, Expression
    from lagrange_element import LagrangeElement
    from polynomials import legendre_basis as leg
    from points import chebyshev_points
    from sympy import Symbol
    from scipy.sparse import csr_matrix
    import numpy as np

    # Element
    degree = 2
    poly_set = leg.basis_functions(degree)
    dof_set = chebyshev_points(degree)
    element = LagrangeElement(poly_set, dof_set)

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

    # Space
    V = FunctionSpace(mesh, element)

    x = Symbol('x')
    bc = DirichletBC(V, Expression(x))
    # Hope that the map is okay. Check if applied correctly
    
    # No symmetry
    A = csr_matrix(np.random.rand(V.dim, V.dim))