Example #1
0
def dirichlet_ex5(n=16,
                  deg=1,
                  plot=True,
                  gauss=4,
                  diag='right'):  # <---------------------------- works
    """ Poisson w/ Dirichlet bc in 1D
    seems to work for P1, P2 and P3, but
    not correct conv rates due to very small errors """

    print "\nDirichlet ex5 in 1D"
    # data
    mesh = UnitIntMesh(n)
    f = 8.
    u_ex = lambda x: 4. * x[0] * (1. - x[0])

    # assemble
    fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss)
    A = fs.stiffness()
    rhs = fs.rhs(f)

    # solve
    bc = Dirichlet(fs)
    u = fem_solver(fs, A, rhs, bc)

    nodes = fs.node_to_coords()
    if plot:
        plot_sol(u, nodes, u_ex)

    # return error and mesh size
    U_ex = [u_ex(node) for node in nodes]
    return norm(U_ex - u), mesh.mesh_size()
Example #2
0
def dirichlet_ex2(n=16,
                  deg=1,
                  plot=True,
                  gauss=4,
                  diag='right'):  # <---------------------------- works
    """ Poisson w/ Dirichlet bc in 2D
    - P1 conv rate: ~2
    - P2 conv rate: ~8
    - P3 conv rate: ~.5 (not working) """

    print "\nDirichlet ex2 in 2D"
    # data
    mesh = UnitSquareMesh(n, n, diag=diag)
    f = lambda x: -6 * x[0] * x[1] * (1. - x[1]) + 2 * pow(x[0], 3)
    g = lambda x: x[1] * (1. - x[1])
    u_ex = lambda x: x[1] * (1. - x[1]) * pow(x[0], 3)

    # assemble
    fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss)
    A = fs.stiffness()
    rhs = fs.rhs(f)

    bc1 = Dirichlet(fs, 0, 'bottom', 'top', 'left')
    bc2 = Dirichlet(fs, g, 'right')

    # solve
    u = fem_solver(fs, A, rhs, [bc1, bc2])

    nodes = fs.node_to_coords()
    if plot:
        plot_sol(u, nodes, u_ex)

    # return error and mesh size
    U_ex = [u_ex(node) for node in nodes]
    return norm(U_ex - u), mesh.mesh_size()
Example #3
0
def mixed_ex1(n=16,
              deg=1,
              plot=True,
              gauss=4,
              diag='right'):  # <---------------------------- works
    """ Poisson w/ mixed bc in 1D
    seems to work for P1, P2 and P3, but
    not correct conv rates due to very small errors """

    print "\nMixed bc example in 1D"
    # data
    mesh = UnitIntMesh(n)
    d = 1
    c = 1
    u_ex = lambda x: 1. - x[0]**2 + d + c * (x[0] - 1.)
    f = 2

    # assemble
    fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss)
    A = fs.stiffness()
    rhs = fs.rhs(f)
    rhs[0] -= c  # Neuman on left boundary
    right_bc = Dirichlet(fs, d, 'right')  # Dirichlet on right boundary

    # solve
    u = fem_solver(fs, A, rhs, right_bc)

    nodes = fs.node_to_coords()
    if plot:
        plot_sol(u, nodes, u_ex)

    # return error and mesh size
    U_ex = [u_ex(node) for node in nodes]
    return norm(U_ex - u), mesh.mesh_size()
Example #4
0
def dirichlet_ex1(n=16,
                  deg=1,
                  plot=True,
                  gauss=4,
                  diag='right'):  # <---------------------------- works
    """ Poisson w/ homogenous Dirichlet bc in 2D
    - P1 conv rate: ~2
    - P2 conv rate: ~8
    - P3 conv rate: ~.5 (not working) """

    print "\nDirichlet ex1 in 2D"
    # data
    mesh = UnitSquareMesh(n, n, diag=diag)
    f = lambda x: 32. * (x[1] * (1. - x[1]) + x[0] * (1. - x[0]))
    u_ex = lambda x: 16. * x[0] * (1. - x[0]) * x[1] * (1. - x[1])

    # assemble
    fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss)
    A = fs.stiffness()
    rhs = fs.rhs(f)

    # solve w/ homogenous Dirichlet bc
    bc = Dirichlet(fs)
    u = fem_solver(fs, A, rhs, bc)

    nodes = fs.node_to_coords()
    if plot:
        plot_sol(u, nodes, u_ex)

    # return error and mesh size
    U_ex = [u_ex(node) for node in nodes]
    return norm(U_ex - u), mesh.mesh_size()
Example #5
0
    def mixed_test():
        """ Poisson problem 2D test with Neuman bc enforced by Lagrange multiplier,
        using mixed P1-P0 elements:
        ------------------------------------------------------------------
            find (u,c) such that
            (grad u, grad v) + (c,v) = (f,v) + (g,v)_gamma, forall v (P1)
                               (u,d) = 0,                   forall d (P0)
        ------------------------------------------------------------------
         """
        g = lambda x: -math.sin(math.pi * x[0])  # Neuman bc
        f = lambda x: 10 * math.exp(-(pow(x[0] - .5, 2) + pow(x[1] - .5, 2)) /
                                    .02)  # right hand side

        mesh = UnitSquareMesh(32, 32)  # mesh
        me = FiniteElement('lagrange', 1) * FiniteElement('lagrange',
                                                          0)  # mixed element
        fs = FunctionSpace(mesh, me, gauss=4)  # mixed space

        Auu = fs.stiffness()  # u stiffness matrix
        Auc = fs.assemble(derivative=[False, False], n=0,
                          m=1)  # mixed mass matrix
        rhs_u = fs.rhs(f) + fs.assemble_boundary(g)  # right hand side for u

        n = fs.n_nodes(0)
        m = fs.n_nodes(1)
        n_nodes = n + m
        print "n = {} (Solution), m = {} (Lagrange)".format(n, m)
        print "Auu: ", Auu.shape
        print "Auc: ", Auc.shape

        # assemble global linear system
        A = np.zeros((n_nodes, n_nodes))
        A[:n, :n] = Auu
        A[:n, n:] = Auc
        A[n:, :n] = Auc.T

        rhs = np.zeros(n_nodes)
        rhs[:n] = rhs_u

        u, c = fem_solver(fs, A, rhs, CG=True)
        print "u: ", u.shape
        print "c: ", c.shape

        plot_sol(u, fs.node_to_coords(0), contour=True, name='Solution')
        plot_sol(c, fs.node_to_coords(1), contour=True, name='Lagrange')
Example #6
0
    def assemble_boundary(self, g, *args):
        """ assemble over boundary in case of Neuman boundary conditions (only for 2D space)
        Input:
            g - function (or constant) to be integrated with shape functions over boundary
            args: (optional)
                m (int) - if mixed space, gives number of FE (default: 0)
                names (strings) - names for boundary dictionary (default: entire boundary)
        Output:
            array that can be added to RHS vector to incorporate Neuman boundary conditions
        """
        assert self.__dim == 2, 'Edge integration only for 2D function space.'

        # check args input
        if len(args) == 0:
            m = 0
            names = []
        elif isinstance(args[0], int):
            m = args[0]
            names = [args[k] for k in range(1, len(args))]
        else:
            m = 0
            names = args

        # get boundary data
        edge_to_nodes = self.belt_to_nodes(m, *names)
        edge_to_vcoords = self.edge_to_vcoords(*names)

        # assemble boundary
        fe = FiniteElement(self.__method[m], self.__deg[m])
        fe.initialize(1)
        b = np.zeros(self.n_nodes(m))
        for n in xrange(len(edge_to_nodes)):
            fe.set_vertices(edge_to_vcoords[n])
            b[edge_to_nodes[n]] += fe.rhs(g, self.__gauss, m)
        return b
Example #7
0
    def poisson_test_1d():
        """ Poisson problem 1D test with homogenous Dirichlet bc """
        u_ex = lambda x: 4. * x[0] * (1. - x[0])  # exact solution
        f = 8.  # right hand side

        mesh = UnitIntMesh(32)
        fs = FunctionSpace(mesh, FiniteElement('lagrange', 1), gauss=4)
        A = fs.stiffness()
        rhs = fs.rhs(f)

        bc = Dirichlet(fs)
        u = fem_solver(fs, A, rhs, bc)
        plot_sol(u, fs.node_to_coords(), u_ex)
Example #8
0
    def p0_test():
        """ test with P0 element """
        u_ex = lambda x: 16. * x[0] * (1. - x[0]) * x[1] * (1. - x[1]
                                                            )  # exact solution

        mesh = UnitSquareMesh(16, 16)
        fs = FunctionSpace(mesh, FiniteElement('lagrange', 0), gauss=4)

        A = fs.mass()
        rhs = fs.rhs(u_ex)

        #u = spsolve(A,rhs)
        #bc = Dirichlet(fs)
        u = fem_solver(fs, A, rhs, bcs=bc)
        plot_sol(u, fs.node_to_coords(), u_ex)
Example #9
0
def neuman_ex1(n=16, deg=1, plot=True, gauss=4, diag='right'):
    """ Poisson w/ Neuman bc in 2D
    ill conditioned -> use CG
    - P1 conv rate: ~2
    - P2 conv rate: ~6
    - P3 conv rate: ~.5 (not working)"""

    print "\nNeuman ex1 in 2D"
    # data
    mesh = UnitSquareMesh(n, n, diag=diag)
    c = 2 * math.pi
    f = lambda x: 2 * pow(c, 2) * math.sin(c * (x[0] + x[1]))
    u_ex = lambda x: math.sin(c * (x[0] + x[1]))

    g_bottom = lambda x: -c * math.cos(c * x[0])
    g_right = lambda x: c * math.cos(c * (1. + x[1]))
    g_top = lambda x: c * math.cos(c * (1. + x[0]))
    g_left = lambda x: -c * math.cos(c * x[1])

    # assemble
    fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss)
    A = fs.stiffness()
    rhs = fs.rhs(f)

    bottom = fs.assemble_boundary(g_bottom, 'bottom')
    right = fs.assemble_boundary(g_right, 'right')
    top = fs.assemble_boundary(g_top, 'top')
    left = fs.assemble_boundary(g_left, 'left')

    rhs += bottom + right + top + left

    #solve
    u = fem_solver(fs, A, rhs, CG=True)
    # u, info = cg(A, rhs)
    # if info == 0:
    #     print "CG convergence OK"
    # else:
    #     print "failed to converge"

    nodes = fs.node_to_coords()
    if plot:
        plot_sol(u, nodes, u_ex)

    # return error and mesh size
    U_ex = [u_ex(node) for node in nodes]
    return norm(U_ex - u), mesh.mesh_size()
Example #10
0
    def poisson_test_2d():
        """ Poisson problem 2D test with homogenous Dirichlet bc """
        u_ex = lambda x: 16. * x[0] * (1. - x[0]) * x[1] * (1. - x[1]
                                                            )  # exact solution
        f = lambda x: 32. * (x[1] * (1. - x[1]) + x[0] *
                             (1. - x[0]))  # right hand side

        mesh = UnitSquareMesh(16, 16, diag='right')
        #mesh = Gmesh('Meshes/square_P2.msh')
        fs = FunctionSpace(mesh, FiniteElement('lagrange', deg=1), gauss=4)

        A = fs.stiffness()
        rhs = fs.rhs(f)

        bc = Dirichlet(fs)
        u = fem_solver(fs, A, rhs, bc)
        plot_sol(u, fs.node_to_coords(), u_ex)
Example #11
0
def neuman_ex4(n=16,
               deg=1,
               plot=True,
               gauss=4,
               diag='right'):  # <---------------------------- works
    """ Poisson w/ Neuman bc in 2D
    ill conditioned -> use CG
    - P1 conv rate: ~1.5
    - P2 conv rate: ~1.1
    - P3 conv rate: ~.5 (not working) """

    print "\nNeuman ex4 in 2D"
    # data
    mesh = RegularMesh(box=[[0, math.pi], [0, math.pi]], res=[n, n], diag=diag)
    f = 0
    u_ex = lambda x: math.cos(2 * x[0]) * math.cosh(2 * x[1]) / 200
    g_top = lambda x: 2 * math.cos(2 * x[0]) * math.sinh(2 * math.pi) / 200

    # assemble
    fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss)
    A = fs.stiffness()
    rhs = fs.rhs(f)

    top = fs.assemble_boundary(g_top, 'top')
    rhs += top

    # solve
    u = fem_solver(fs, A, rhs, CG=True)
    #u = spsolve(A, rhs)
    # u, info = cg(A,rhs)
    # if info == 0:
    #     print "CG convergence OK"
    # else:
    #     print "failed to converge"

    nodes = fs.node_to_coords()
    if plot:
        plot_sol(u, nodes, u_ex)

    # return error and mesh size
    U_ex = [u_ex(node) for node in nodes]
    return norm(U_ex - u), mesh.mesh_size()
Example #12
0
def dirichlet_ex4(n=16,
                  deg=1,
                  plot=True,
                  gauss=4,
                  diag='right'):  # <---------------------------- works
    """ Poisson w/ Dirichlet bc in 2D
    - P1 conv rate: ~2
    - P2 conv rate: ~8
    - P3 conv rate: ~.5 (not working) """

    print "\nDirichlet ex4 in 2D"
    # data
    mesh = RegularMesh(box=[[0, math.pi], [0, math.pi]], res=[n, n], diag=diag)
    f = 0
    u_ex = lambda x: math.cosh(x[0]) * math.sin(x[1])
    g_left = lambda x: math.sin(x[1])
    g_right = lambda x: math.cosh(math.pi) * math.sin(x[1])
    g_bottom = 0
    g_top = 0

    # assemble
    fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss)
    A = fs.stiffness()
    rhs = fs.rhs(f)

    bc_left = Dirichlet(fs, g_left, 'left')
    bc_right = Dirichlet(fs, g_right, 'right')
    bc_bottom = Dirichlet(fs, g_bottom, 'bottom')
    bc_top = Dirichlet(fs, g_top, 'top')

    # solve
    u = fem_solver(fs, A, rhs, [bc_left, bc_right, bc_bottom, bc_top])

    nodes = fs.node_to_coords()
    if plot:
        plot_sol(u, nodes, u_ex)

    # return error and mesh size
    U_ex = [u_ex(node) for node in nodes]
    return norm(U_ex - u), mesh.mesh_size()
Example #13
0
def neuman_ex3(n=16,
               deg=1,
               plot=True,
               gauss=4,
               diag='right'):  # <---------------------------- works
    """ Poisson w/ homogenous Neuman bc in 2D
    ill conditioned -> use CG
    - P1 conv rate: ~2.3
    - P2 conv rate: ~6
    - P3 conv rate: ~.5 (not working)"""

    print "\nNeuman ex3 in 2D"
    # data
    mesh = UnitSquareMesh(n, n, diag=diag)
    pi = math.pi
    f = lambda x: pi * (math.cos(pi * x[0]) + math.cos(pi * x[1]))
    u_ex = lambda x: (math.cos(pi * x[0]) + math.cos(pi * x[1])) / pi

    # assemble
    fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss)
    A = fs.stiffness()
    rhs = fs.rhs(f)

    # solve
    u = fem_solver(fs, A, rhs, CG=True)
    # u, info = cg(A,rhs)
    # if info == 0:
    #     print "CG convergence OK"
    # else:
    #     print "failed to converge"

    nodes = fs.node_to_coords()
    if plot:
        plot_sol(u, nodes, u_ex)
    U_ex = [u_ex(node) for node in nodes]

    # return error and mesh size
    return norm(U_ex - u), mesh.mesh_size()
Example #14
0
def mixed_ex2(n=16,
              deg=1,
              plot=True,
              gauss=4,
              diag='right'):  # <---------------------------- works
    """ Poisson w/ mixed bc in 2D
    P1 conv rate: ~2.1
    P2 conv rate: ~6
    P3 conv rate: ~.5 (not working) """

    print "\nMixed bc example in 2D"
    # data
    mesh = UnitSquareMesh(n, n, diag=diag)
    f = lambda x: 2 * (2 * pow(x[1], 3) - 3 * pow(x[1], 2) + 1.) - 6 * (
        1. - pow(x[0], 2)) * (2 * x[1] - 1.)
    g = lambda x: 2 * pow(x[1], 3) - 3 * pow(x[1], 2) + 1.
    u_ex = lambda x: (1. - pow(x[0], 2)) * (2 * pow(x[1], 3) - 3 * pow(
        x[1], 2) + 1.)

    # assemble
    fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss)
    A = fs.stiffness()
    rhs = fs.rhs(f)

    bc1 = Dirichlet(fs, 0, 'right')
    bc2 = Dirichlet(fs, g, 'left')

    # solve (homogenous Neuman on top, bottom)
    u = fem_solver(fs, A, rhs, [bc1, bc2])

    nodes = fs.node_to_coords()
    if plot:
        plot_sol(u, nodes, u_ex)
    U_ex = [u_ex(node) for node in nodes]

    # return error and mesh size
    return norm(U_ex - u), mesh.mesh_size()
Example #15
0
def neuman_ex2(n=16,
               deg=1,
               plot=True,
               gauss=4,
               diag='right'):  # <---------------------------- works
    """ Poisson w/ homogenous Neuman bc in 1D
    ill conditioned -> use CG
    - P1 conv rate: ~1.5
    - P2 conv rate: ~1.5
    - P3 conv rate: ~1.5 """

    print "\nNeuman ex2 in 1D"
    # data
    mesh = UnitIntMesh(n)
    f = lambda x: pow(2 * math.pi, 2) * math.cos(2 * math.pi * x[0])
    u_ex = lambda x: math.cos(2 * math.pi * x[0])

    # assemble
    fs = FunctionSpace(mesh, FiniteElement('lagrange', deg), gauss)
    A = fs.stiffness()
    rhs = fs.rhs(f)

    # solve
    u = fem_solver(fs, A, rhs, CG=True)
    # u, info = cg(A, rhs)
    # if info == 0:
    #     print "CG convergence OK"
    # else:
    #     print "failed to converge"

    nodes = fs.node_to_coords()
    if plot:
        plot_sol(u, nodes, u_ex)

    # return error and mesh size
    U_ex = [u_ex(node) for node in nodes]
    return norm(U_ex - u), mesh.mesh_size()