from sympy import Symbol, sin, S from function import Expression, Function from mesh import IntervalMesh from cg_space import FunctionSpace from lagrange_element import LagrangeElement import numpy as np x = Symbol("x") f = Expression(sin(2 * x)) meshf = IntervalMesh(a=-1, b=1, n_cells=4) # Just f fig = plot(f, mesh=meshf, label="f") # Two functions mesh = IntervalMesh(a=-1, b=1, n_cells=100) poly_set = [S(1), x, x ** 2, x ** 3] dof_set = np.array([-1, -0.5, 0.5, 1]) element = LagrangeElement(poly_set, dof_set) V = FunctionSpace(mesh, element) # Here's one g = V.interpolate(f) # Fake the other gg = Function(V) np.copyto(gg.vector, g.vector) gg.vector += 1 # Add fig = plot(g, fig=fig, label="g", color="r") fig = plot(gg, fig=fig, label="gg", color="g") plt.legend(loc="best") plt.show()
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