def compute_projection_error(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.tabulate_dof_coordinates()
    # Note: Not the same as x = mesh.coordinates() (apparently has been re-ordered)

    # 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 = project(u, V)
    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 i in range(len(x)):
        Eua[i] = 1 + 4 * x[i]**2 - 5 * x[i]**3

    # 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
def compute_projection_error(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 = project(u, V)
    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
def compute_interpolation_error(mesh_resolution=20):
    # Define domain and mesh
    a, b = 0, 1
    mesh = IntervalMesh(mesh_resolution, a, b)

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

    # Extract vertices of the mesh
    x = V.tabulate_dof_coordinates()
    # Note: Not the same as x = mesh.coordinates() (apparently has been re-ordered)

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

    # Interpolate u onto V and extract the values in the mesh nodes
    Iu = interpolate(u, V)
    Iua = Iu.vector().array()

    # Evaluate u at the mesh vertices
    Eua = np.empty(len(x))
    for i in range(len(x)):
        Eua[i] = 1 + x[i] * math.sin(10 * x[i])

    # Compute max interpolation error in the nodes
    e = Eua - Iua
    e_abs = np.absolute(e)
    error = np.amax(e_abs)
    return error
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")))
Exemple #5
0
def local_mass_matrix():
    # Define mesh
    mesh = UnitIntervalMesh(1)

    # Define function space
    V = FunctionSpace(mesh, "Lagrange", 1)

    # Define trial and test functions
    u = TrialFunction(V)
    v = TestFunction(V)

    # Define bilinear form
    a = (dot(grad(u), grad(v)) + u * v) * dx

    # Assemble matrix
    A = assemble(a)

    print(A.array())

    # Bilinear form for just the mass matrix part
    a2 = u * v * dx

    # Assemble mass matrix
    A2 = assemble(a2)
    print(6 * A2.array())
def compare_errors(p_order=1):
    # Express the analytical function
    u = Expression("1 + sin(10*x[0])", degree=5)

    mesh_resolutions = [10, 50, 100, 200]

    projection_errors = []
    interpolation_errors = []
    for mesh_resolution in mesh_resolutions:
        # Define mesh
        mesh = UnitIntervalMesh(mesh_resolution)

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

        # Compute projection
        up = project(u, V)

        # Compute interpolation
        ui = interpolate(u, V)

        # Compute errors
        projection_errors.append(compute_error(u, up))
        interpolation_errors.append(compute_error(u, ui))

    print(projection_errors)
    print(interpolation_errors)
def plot_basis_function():
    # Declare mesh and FEM functions
    mesh = UnitSquareMesh(10, 10)
    V = FunctionSpace(mesh, "CG", 1)

    phi = Function(V)
    phi.vector()[:] = 0.0
    phi.vector()[10] = 1.0

    # Plot the basis function
    fig = plt.figure()
    plot(phi, fig=fig)
    plt.show()

    val = assemble(phi * phi * dx)
    print(val)
def compute_error(u1, u2):
    # Reference mesh
    mesh_resolution_ref = 500
    mesh_ref = UnitIntervalMesh(mesh_resolution_ref)

    # Reference function space
    V_ref = FunctionSpace(mesh_ref, "CG", 1)

    # Evaluate the input functions on the reference mesh
    Iu1 = interpolate(u1, V_ref)
    Iu2 = interpolate(u2, V_ref)

    # Compute the error
    e = Iu1 - Iu2
    error = sqrt(assemble(e * e * dx))
    return error
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'))
Exemple #10
0
def global_stiffness_matrix():
    # Define mesh
    mesh = UnitIntervalMesh(10)

    # Define function space
    V = FunctionSpace(mesh, "Lagrange", 1)

    # Define trial and test functions
    u = TrialFunction(V)
    v = TestFunction(V)

    # Define bilinear form
    a = dot(grad(u), grad(v)) * dx

    # Assemble matrix
    A = assemble(a)

    h = 1 / 10
    print(h * A.array())
def automated_fenics_assembly():
    mesh = UnitSquareMesh(5, 5)
    mesh.init()

    A, b = myassemble(mesh)

    f = Constant(1)
    V = FunctionSpace(mesh, 'CG', 1)
    u = TrialFunction(V)
    v = TestFunction(V)

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

    B = A - A1.array()
    print("The norm of B is {}".format(np.linalg.norm(B)))
    print("A = ")
    print(A)
    print("A1 = ")
    print(A1.array())
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
Exemple #13
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_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_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
                    point_in_subdomain(v.point()) == num
                    for v in vertices(f_mesh)):
                facet_function[f_mesh] = num
                set = True
        if not set:
            facet_function[f_mesh] = 1  # wall

plot(facet_function)

f_mesh = HDF5File(mpi_comm_world(), 'meshes/' + meshName + '.hdf5', 'w')
f_mesh.write(mesh, 'mesh')
f_mesh.write(facet_function, 'facet_function')
f_mesh.close()

# compute volume of mesh
V = FunctionSpace(mesh, 'Lagrange', 1)
one = interpolate(Expression('1.'), V)
volume = assemble(one * dx)

# compute real areas of boudary parts
for obj in itertools.chain(inflows, outflows):
    dS = Measure("ds",
                 subdomain_id=obj['number'],
                 subdomain_data=facet_function)
    obj['S'] = assemble(one * dS)

# compute reference coefs
for inf in inflows:
    inf['reference_coef'] = inf['reference_radius'] * inf[
        'reference_radius'] / (inf['radius'] * inf['radius'])
Exemple #17
0
from dolfin import IntervalMesh
from dolfin.fem.interpolation import interpolate
from dolfin.functions import FunctionSpace, TestFunction, Function, Expression

# Define domain and mesh
a, b = 0, 1
mesh_resolution = 20
mesh = IntervalMesh(mesh_resolution, a, b)

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

# Interpolate function
u = Expression("1 + 4.0 * x[0] * x[0] - 5.0 * x[0] * x[0] * x[0]", degree=5)
Iu = interpolate(u, V)
Iua = Iu.vector().array()
print(Iua.max())