def solve_equation():
    mesh = UnitSquareMesh(32, 32)
    V = FunctionSpace(mesh, "Lagrange", 1)

    def boundary(x, on_boundary):
        return on_boundary

    u0 = Expression("cos(10 * x[0])", degree=2)
    bc = DirichletBC(V, u0, boundary)

    u = TrialFunction(V)
    v = TestFunction(V)
    f = Expression("(x[0] - 0.5)*(x[0] - 0.5)", degree=2)

    a = inner(grad(u), grad(v)) * dx
    L = f * v * dx

    u = Function(V)
    solve(a == L, u, bc)

    # Plot solution at current time step
    fig = plt.figure()
    plot(u, fig=fig)
    plt.show()

    print("The norm of u is {}".format(u.vector().norm("l2")))
Example #2
0
    def solve(self, spaceV):
        u = TrialFunction(spaceV)
        v = TestFunction(spaceV)
        solution = Function(spaceV)

        a = self.kappa.expression * np.inner(nabla_grad(u), nabla_grad(v)) * dx
        L = self.rhs_f * v * dx

        bc = DirichletBC(spaceV, self.bcExpression, self.bcBoundary)

        solve(a == L, solution, bc)

        return solution
def simple_test():
    # Declare mesh and FEM functions
    mesh = UnitSquareMesh(10, 10)
    V = FunctionSpace(mesh, "CG", 1)
    f = Expression("1.0 + sin(10 * x[0]) * cos(7 * x[1])", degree=3)
    v = TestFunction(V)
    u = Function(V)  # FEM solution

    # Weak form of L2 projection
    r = (u - f) * v * dx

    # Solving the linear system generated by the L2 projection
    solve(r == 0, u)

    # Plot the FEM solution
    fig = plt.figure()
    plot(u, fig=fig)
    plt.show()
    print(u.vector().norm('linf'))
def compute_projection_error_solve(mesh_resolution=20, p_order=1):
    # Define domain and mesh
    a, b = 0, 1
    mesh = IntervalMesh(mesh_resolution, a, b)

    # Define finite element function space
    V = FunctionSpace(mesh, "CG", p_order)

    # Extract vertices of the mesh
    x = V.dofmap().tabulate_all_coordinates(mesh)
    indices = np.argsort(x)

    # Express the analytical function
    u = Expression("1 + 4 * x[0] * x[0] - 5 * x[0] * x[0] * x[0]", degree=5)

    # Project u onto V and extract the values in the mesh nodes
    Pu = Function(V)
    v = TestFunction(V)
    r = inner(Pu - u, v)*dx
    solve(r == 0, Pu)
    Pua = Pu.vector().array()

    # Create a function in the finite element function space V
    Eu = Function(V)
    Eua = Eu.vector().array()

    # Evaluate function in the mesh nodes
    for j in indices:
        Eua[j] = 1 + 4 * x[j] * x[j] - 5 * x[j] * x[j] * x[j]

    # Compute sum of projection error in the nodes
    e = Eua - Pua
    error = 0
    for i in range(len(e)):
        error += abs(e[i])
    return error
Example #5
0
def solve_navier_stokes_equation(interior_circle=True, num_mesh_refinements=0):
    """
    Solve the Navier-Stokes equation on a hard-coded mesh with hard-coded initial and boundary conditions
    """
    mesh, om, im, nm, ymax, sub_domains = setup_geometry(
        interior_circle, num_mesh_refinements)
    dsi = Measure("ds", domain=mesh, subdomain_data=sub_domains)

    # Setup FEM function spaces
    # Function space for the velocity
    V = VectorFunctionSpace(mesh, "CG", 1)
    # Function space for the pressure
    Q = FunctionSpace(mesh, "CG", 1)
    # Mixed function space for velocity and pressure
    W = V * Q

    # Setup FEM functions
    v, q = TestFunctions(W)
    w = Function(W)
    (u, p) = (as_vector((w[0], w[1])), w[2])
    u0 = Function(V)

    # Inlet velocity
    uin = Expression(("4*(x[1]*(YMAX-x[1]))/(YMAX*YMAX)", "0."),
                     YMAX=ymax,
                     degree=1)

    # Viscosity and stabilization parameters
    nu = 1e-6
    h = CellSize(mesh)
    d = 0.2 * h**(3.0 / 2.0)

    # Time parameters
    time_step = 0.1
    t_start, t_end = 0.0, 10.0

    # Penalty parameter
    gamma = 10 / h

    # Time stepping
    t = t_start
    step = 0
    while t < t_end:
        # Time discretization (Crank–Nicolson method)
        um = 0.5 * u + 0.5 * u0

        # Navier-Stokes equations in weak residual form (stabilized FEM)
        # Basic residual
        r = (inner((u - u0) / time_step + grad(p) + grad(um) * um, v) +
             nu * inner(grad(um), grad(v)) + div(um) * q) * dx
        # Weak boundary conditions
        r += gamma * (om * p * q + im * inner(u - uin, v) +
                      nm * inner(u, v)) * ds
        # Stabilization
        r += d * (inner(grad(p) + grad(um) * um,
                        grad(q) + grad(um) * v) + inner(div(um), div(v))) * dx

        # Solve the Navier-Stokes equation (one time step)
        solve(r == 0, w)

        if step % 5 == 0:
            # Plot norm of velocity at current time step
            nov = project(sqrt(inner(u, u)), Q)
            fig = plt.figure()
            plot(nov, fig=fig)
            plt.show()

            # Compute drag force on circle
            n = FacetNormal(mesh)
            drag_force_measure = p * n[0] * dsi(1)  # Drag (only pressure)
            drag_force = assemble(drag_force_measure)
            print("Drag force = " + str(drag_force))

        # Shift to next time step
        t += time_step
        step += 1
        u0 = project(u, V)
def solve_wave_equation(a, symmetric=True):
    """
    Solve the wave equation on a hard-coded mesh with a hard-coded initial and boundary conditions

    :param a: Wave propagation factor
    :param symmetric: Whether or not the problem is symmetric
    """
    mesh, boundary = setup_geometry()

    # Exact solution
    if symmetric:
        ue = Expression(
            "(1-pow(a*t-x[0],2))*exp(-pow(a*t-x[0],2)) + (1-pow(a*t+x[0],2))*exp(-pow(a*t+x[0],2))",
            a=a,
            t=0,
            domain=mesh,
            degree=2)
        ve = Expression(
            "2*a*(a*t-x[0])*(pow(a*t-x[0],2)-2)*exp(-pow(a*t-x[0],2))"
            "+ 2*a*(a*t+x[0])*(pow(a*t+x[0],2)-2)*exp(-pow(a*t+x[0],2))",
            a=a,
            t=0,
            domain=mesh,
            degree=2)
    else:
        ue = Expression("(1-pow(a*t+x[0],2))*exp(-pow(a*t+x[0],2))",
                        a=a,
                        t=0,
                        domain=mesh,
                        degree=2)
        ve = Expression(
            "2*a*(a*t+x[0])*(pow(a*t+x[0],2)-2)*exp(-pow(a*t+x[0],2))",
            a=a,
            t=0,
            domain=mesh,
            degree=2)

    # Polynomial degree
    r = 1

    # Setup FEM function spaces
    Q = FunctionSpace(mesh, "CG", r)
    W = VectorFunctionSpace(mesh, "CG", r, dim=2)

    # Create boundary conditions
    bcu = DirichletBC(W.sub(0), ue, boundary)
    bcv = DirichletBC(W.sub(1), ve, boundary)
    bcs = [bcu, bcv]

    # Setup FEM functions
    p, q = TestFunctions(W)
    w = Function(W)
    u, v = w[0], w[1]

    # Time parameters
    time_step = 0.05
    t_start, t_end = 0.0, 5.0

    # Time stepping
    t = t_start
    u0 = ue
    v0 = ve
    step = 0
    while t < t_end:
        # Weak form of the wave equation
        um = 0.5 * (u + u0)
        vm = 0.5 * (v + v0)
        a1 = (u - u0) / time_step * p * dx - vm * p * dx
        a2 = (v - v0) / time_step * q * dx + a**2 * inner(grad(um),
                                                          grad(q)) * dx

        # Solve the wave equation (one time step)
        solve(a1 + a2 == 0, w, bcs)

        # Advance time in exact solution
        t += time_step
        ue.t = t
        ve.t = t

        if step % 10 == 0:
            # Plot solution at current time step
            fig = plt.figure()
            plot(u, fig=fig)
            plt.show()

            # Compute max error at vertices
            vertex_values_ue = ue.compute_vertex_values(mesh)
            vertex_values_w = w.compute_vertex_values(mesh)
            vertex_values_u = np.split(vertex_values_w, 2)[0]
            error_max = np.max(np.abs(vertex_values_ue - vertex_values_u))
            # Print error
            print(error_max)

        # Shift to next time step
        u0 = project(u, Q)
        v0 = project(v, Q)
        step += 1
def solve_heat_equation(k, time_stepping_method):
    """
    Solve the heat equation on a hard-coded mesh with a hard-coded initial and boundary conditions

    :param k: Thermal conductivity
    :param time_stepping_method: Time stepping method. Can be one of ["forward_euler", "backward_euler", "trapezoidal"]
    """
    mesh, boundary = setup_geometry()

    # Exact solution (Gauss curve)
    ue = Expression("exp(-(x[0]*x[0]+x[1]*x[1])/(4*a*t))/(4*pi*a*t)",
                    a=k,
                    t=1e-7,
                    domain=mesh,
                    degree=1)

    # Polynomial degree
    r = 1

    # Setup FEM function space
    V = FunctionSpace(mesh, "CG", r)

    # Create boundary condition
    bc = DirichletBC(V, ue, boundary)

    # Setup FEM functions
    v = TestFunction(V)
    u = Function(V)

    # Time parameters
    time_step = 0.001
    t_start, t_end = 0.0, 20.0

    # Time stepping
    t = t_start
    if time_stepping_method == "forward_euler":
        theta = 0.0
    if time_stepping_method == "backward_euler":
        theta = 1.0
    if time_stepping_method == "trapezoidal":
        theta = 0.5
    u0 = ue
    step = 0
    while t < t_end:
        # Intermediate value for u (depending on the chosen time stepping method)
        um = (1.0 - theta) * u0 + theta * u

        # Weak form of the heat equation
        a = (u - u0) / time_step * v * dx + k * inner(grad(um), grad(v)) * dx

        # Solve the heat equation (one time step)
        solve(a == 0, u, bc)

        # Advance time in exact solution
        t += time_step
        ue.t = t

        if step % 100 == 0:
            # Compute error in L2 norm
            error_L2 = errornorm(ue, u, 'L2')
            # or equivalently
            # sqrt(assemble((ue - u) * (ue - u) * dx))
            # Compute norm of exact solution
            nue = norm(ue)
            # Print relative error
            print("Relative error = {}".format(error_L2 / nue))

        # Shift to next time step
        u0 = project(u, V)
        step += 1
def solve_heat_equation(k):
    """
    Solve the heat equation on a hard-coded mesh with a hard-coded initial and boundary conditions
    
    :param k: Thermal conductivity
    """
    mesh, boundary = setup_geometry()

    # Exact solution (Gauss curve)
    ue = Expression("exp(-(x[0]*x[0]+x[1]*x[1])/(4*a*t))/(4*pi*a*t)",
                    a=k,
                    t=1e-7,
                    domain=mesh,
                    degree=2)

    # Polynomial degree
    r = 1

    # Setup FEM function space
    V = FunctionSpace(mesh, "CG", r)

    # Create boundary condition
    bc = DirichletBC(V, ue, boundary)

    # Setup FEM functions
    v = TestFunction(V)
    u = Function(V)

    # Time parameters
    time_step = 0.5
    t_start, t_end = 0.0, 20.0

    # Time stepping
    t = t_start
    u0 = ue
    step = 0
    while t < t_end:
        # Weak form of the heat equation
        a = (u - u0) / time_step * v * dx + k * inner(grad(u), grad(v)) * dx

        # Solve the heat equation (one time step)
        solve(a == 0, u, bc)

        # Advance time in exact solution
        t += time_step
        ue.t = t

        if step % 5 == 0:
            # Plot solution at current time step
            fig = plt.figure()
            plot(u, fig=fig)
            plt.show()

            # Compute error in L2 norm
            error_L2 = errornorm(ue, u, 'L2')
            # or equivalently
            # sqrt(assemble((ue - u) * (ue - u) * dx))
            # Print error
            print(error_L2)

        # Shift to next time step
        u0 = project(u, V)
        step += 1