Пример #1
0
    def runTest(self):
        m=fmsh.MeshTri()
        m.refine(4)
        # split mesh into two sets of triangles
        I1=np.arange(m.t.shape[1]/2)
        I2=np.setdiff1d(np.arange(m.t.shape[1]),I1)

        bix=m.boundary_facets()
        bix1=bix[0:len(bix)/2]
        bix2=np.setdiff1d(bix,bix1)

        a=fasm.AssemblerElement(m,felem.ElementTriP1())

        def dudv(du,dv):
            return du[0]*dv[0]+du[1]*dv[1]

        A=a.iasm(dudv)
        A1=a.iasm(dudv,tind=I1)
        A2=a.iasm(dudv,tind=I2)

        B=a.fasm(dudv)
        B1=a.fasm(dudv,find=bix1)
        B2=a.fasm(dudv,find=bix2)

        f=a.iasm(lambda v: 1*v)

        I=m.interior_nodes()

        x=np.zeros(A.shape[0])
        x[I]=scipy.sparse.linalg.spsolve((A+B)[I].T[I].T,f[I])

        X=np.zeros(A.shape[0])
        X[I]=scipy.sparse.linalg.spsolve((A1+B1)[I].T[I].T+(A2+B2)[I].T[I].T,f[I])

        self.assertAlmostEqual(np.linalg.norm(x-X),0.0,places=10)
Пример #2
0
 def plot_refined(self, mesh, dofnum, sol, minval, maxval, nref=2):
     """Draw a discrete function on refined mesh."""
     print "Plotting on a refined mesh. This is slowish due to loop over elements..."
     import copy
     import spfem.mesh as fmsh
     plt.figure()
     for itr in range(mesh.t.shape[1]):
         m = fmsh.MeshTri(
             np.array([[
                 mesh.p[0, mesh.t[0, itr]], mesh.p[0, mesh.t[1, itr]],
                 mesh.p[0, mesh.t[2, itr]]
             ],
                       [
                           mesh.p[1, mesh.t[0, itr]],
                           mesh.p[1, mesh.t[1, itr]], mesh.p[1, mesh.t[2,
                                                                       itr]]
                       ]]), np.array([[0], [1], [2]]))
         M = copy.deepcopy(m)
         m.refine(nref)
         qps = {}
         qps[0] = np.array([m.p[0, :]])
         qps[1] = np.array([m.p[1, :]])
         u, _, _, _ = self.evalbasis(M, qps, [0])
         newu = u[0].flatten() * 0.0
         for jtr in range(len(u)):
             newu += sol[dofnum.t_dof[jtr, itr]] * u[jtr].flatten()
         m.plot(newu, nofig=True, smooth=True, zlim=(minval, maxval))
         plt.hold('on')
     plt.colorbar()
Пример #3
0
    def visualize_basis_tri(self, save_figures=False, draw_derivatives=False):
        """Draw the basis functions given by self.evalbasis.
        Only for triangular elements. For debugging purposes."""
        if self.dim != 2:
            raise NotImplementedError("visualize_basis_tri supports "
                                      "only triangular elements.")
        import copy
        import spfem.mesh as fmsh
        m = fmsh.MeshTri(np.array([[0, 1.0, 0.0], [0.0, 0.0, 1.0]]),
                         np.array([[0], [1], [2]]))
        M = copy.deepcopy(m)
        m.refine(4)
        qps = {}
        qps[0] = np.array([m.p[0, :]])
        qps[1] = np.array([m.p[1, :]])
        u, du, ddu = self.evalbasis(M, qps, [0])

        for itr in range(len(u)):
            m.plot3(u[itr].flatten())
            if save_figures:
                plt.savefig('bfun' + str(itr) + '.pdf')

        if draw_derivatives:
            for itr in range(len(u)):
                m.plot3(ddu[itr][0][0].flatten())
                if save_figures:
                    plt.savefig('bfun' + str(itr) + '.pdf')

        if not save_figures:
            m.show()
Пример #4
0
    def runTest(self, verbose=False):
        m = fmsh.MeshTri()
        m.refine(6)

        e = felem.AbstractElementArgyris()
        a = fasm.AssemblerAbstract(m, e)

        A = a.iasm(lambda ddu, ddv: ddu[0][0] * ddv[0][0] + ddu[1][0] * ddv[1][
            0] + ddu[0][1] * ddv[0][1] + ddu[1][1] * ddv[1][1])

        # construct a loading that corresponds to the analytical solution uex
        import sympy as sp
        from sympy.abc import x, y, z
        uex = (sp.sin(sp.pi * x) * sp.sin(sp.pi * y))**2
        uexfun = sp.lambdify((x, y), uex, "numpy")
        load = sp.diff(uex, x, 4) + sp.diff(
            uex, y, 4) + 2 * sp.diff(sp.diff(uex, x, 2), y, 2)
        loadfun = sp.lambdify((x, y), load, "numpy")

        def F(x):
            return loadfun(x[0], x[1])

        f = a.iasm(lambda v, x: F(x) * v)

        D = a.dofnum_u.getdofs(N=m.boundary_nodes(), F=m.boundary_facets())
        I = np.setdiff1d(np.arange(a.dofnum_u.N), D)

        x = futil.direct(A, f, I=I)

        Linferror = np.max(
            np.abs(x[a.dofnum_u.n_dof[0, :]] - uexfun(m.p[0, :], m.p[1, :])))

        self.assertTrue(Linferror <= 5e-3)
Пример #5
0
 def plot_lagmult(self,
                  mesh,
                  dofnum,
                  sol,
                  minval,
                  maxval,
                  lambdaeval,
                  nref=2,
                  cbar=True):
     """Draw plate obstacle lagrange multiplier on refined mesh."""
     print "Plotting on a refined mesh. This is slowish due to loop over elements..."
     import copy
     import spfem.mesh as fmsh
     plt.figure()
     totmaxval = 0
     for itr in range(mesh.t.shape[1]):
         m = fmsh.MeshTri(
             np.array([[
                 mesh.p[0, mesh.t[0, itr]], mesh.p[0, mesh.t[1, itr]],
                 mesh.p[0, mesh.t[2, itr]]
             ],
                       [
                           mesh.p[1, mesh.t[0, itr]],
                           mesh.p[1, mesh.t[1, itr]], mesh.p[1, mesh.t[2,
                                                                       itr]]
                       ]]), np.array([[0], [1], [2]]))
         M = copy.deepcopy(m)
         m.refine(nref)
         qps = {}
         qps[0] = np.array([m.p[0, :]])
         qps[1] = np.array([m.p[1, :]])
         u, _, _, d4u = self.evalbasis(M, qps, [0])
         newu = u[0].flatten() * 0.0
         #newd4u = d4u[0].flatten()*0.0
         newd4u = const_cell(0 * qps[0], self.dim, self.dim)
         for jtr in range(len(u)):
             newu += sol[dofnum.t_dof[jtr, itr]] * u[jtr].flatten()
             newd4u[0][0] += sol[dofnum.t_dof[
                 jtr, itr]] * d4u[jtr][0][0].flatten()
             newd4u[0][1] += sol[dofnum.t_dof[
                 jtr, itr]] * d4u[jtr][0][1].flatten()
             newd4u[1][0] += sol[dofnum.t_dof[
                 jtr, itr]] * d4u[jtr][1][0].flatten()
             newd4u[1][1] += sol[dofnum.t_dof[
                 jtr, itr]] * d4u[jtr][1][1].flatten()
         tmp = lambdaeval(newu, newd4u, qps, M.param())
         #print tmp.shape
         if np.max(tmp) > totmaxval:
             totmaxval = np.max(tmp)
         m.plot(tmp.flatten(),
                nofig=True,
                smooth=True,
                zlim=(minval, maxval))
         plt.hold('on')
     print "Maximum value: " + str(totmaxval)
     if cbar:
         plt.colorbar()
Пример #6
0
    def setUp(self):
        self.mesh=fmsh.MeshTri()
        self.mesh.refine(5)

        # boundary and interior node sets
        D1=np.nonzero(self.mesh.p[0,:]==0)[0]
        D2=np.nonzero(self.mesh.p[1,:]==0)[0]
        D3=np.nonzero(self.mesh.p[0,:]==1)[0]
        D4=np.nonzero(self.mesh.p[1,:]==1)[0]

        D=np.union1d(D1,D2);
        D=np.union1d(D,D3);
        self.D=np.union1d(D,D4);

        self.I=np.setdiff1d(np.arange(0,self.mesh.p.shape[1]),self.D)
Пример #7
0
    def runTest(self):
        m=fmsh.MeshTri()
        m.refine(5)

        a=fasm.AssemblerAbstract(m,felem.AbstractElementTriPp(2))
        b=fasm.AssemblerElement(m,felem.ElementTriP2())

        A=a.iasm(lambda u,v: u*v)
        B=b.iasm(lambda u,v: u*v)

        self.assertAlmostEqual(np.sum(A.data),np.sum(B.data),places=10)

        C=a.iasm(lambda du,v: du[0]*v)
        D=b.iasm(lambda du,v: du[0]*v)

        self.assertAlmostEqual(C.data[0],D.data[0],places=10)
Пример #8
0
    def runTest(self):
        m=fmsh.MeshTri()
        m.refine(3)
        a=fasm.AssemblerElement(m,felem.ElementTriP1())

        def G(x,y):
            return np.sin(np.pi*x)
        u=G(m.p[0,:],m.p[1,:])

        # interpolate just the values and compare
        def v1(v,w):
            return w[0]*v
        def v2(u,v):
            return u*v
        f=a.fasm(v1,interp={0:u})
        A=a.fasm(v2)

        self.assertAlmostEqual(np.linalg.norm(f-A*u),0.0,places=10)
Пример #9
0
    def runTest(self):
        mesh = fmsh.MeshTri()
        mesh.refine(2)

        def G(x, y):
            return x**3 * np.sin(20.0 * y)

        def U(x):
            return G(x[0], x[1])

        def dUdx(x):
            return 3.0 * x[0]**2 * np.sin(20.0 * x[1])

        def dUdy(x):
            return 20.0 * x[0]**3 * np.cos(20.0 * x[1])

        dU = {0: dUdx, 1: dUdy}

        def dudv(du, dv):
            return du[0] * dv[0] + du[1] * dv[1]

        gamma = 100

        def uv(u, v, du, dv, x, h, n):
            return gamma * 1 / h * u * v - du[0] * n[0] * v - du[1] * n[
                1] * v - u * dv[0] * n[0] - u * dv[1] * n[1]

        def fv(v, dv, x):
            return (-6.0 * x[0] * np.sin(20.0 * x[1]) +
                    400.0 * x[0]**3 * np.sin(20.0 * x[1])) * v

        def gv(v, dv, x, h, n):
            return G(x[0], x[1]) * v + gamma * 1 / h * G(
                x[0], x[1]) * v - dv[0] * n[0] * G(
                    x[0], x[1]) - dv[1] * n[1] * G(x[0], x[1])

        hs = np.array([])
        errs = np.array([])

        for itr in range(4):
            mesh.refine()
            a = fasm.AssemblerElement(mesh, felem.ElementTriP1())
            D = mesh.boundary_nodes()
            I = mesh.interior_nodes()

            K = a.iasm(dudv)
            B = a.fasm(uv, normals=True)
            f = a.iasm(fv)
            g = a.fasm(gv, normals=True)

            x = np.zeros(K.shape[0])
            x = spsolve(K + B, f + g)

            hs = np.append(hs, mesh.param())
            errs = np.append(errs,
                             np.sqrt(a.L2error(x, U)**2 + a.H1error(x, dU)**2))

        pfit = np.polyfit(np.log10(hs), np.log10(errs), 1)

        # check that the convergence rate matches theory
        self.assertTrue(pfit[0] >= 0.99)
Пример #10
0
    def runTest(self):
        def U(x):
            return 1 + x[0] - x[0]**2 * x[1]**2

        def dUdx(x):
            return 1 - 2 * x[0] * x[1]**2

        def dUdy(x):
            return -2 * x[0]**2 * x[1]

        def dudv(du, dv):
            return du[0] * dv[0] + du[1] * dv[1]

        def uv(u, v):
            return u * v

        def F(x, y):
            return 2 * x**2 + 2 * y**2

        def fv(v, x):
            return F(x[0], x[1]) * v

        def G(x, y):
            return (x==1)*(3-3*y**2)+\
                    (x==0)*(0)+\
                    (y==1)*(1+x-3*x**2)+\
                    (y==0)*(1+x)

        def gv(v, x):
            return G(x[0], x[1]) * v

        dexact = {}
        dexact[0] = dUdx
        dexact[1] = dUdy

        hs = {}
        H1errs = {}
        L2errs = {}

        for p in range(1, 3):
            mesh = fmsh.MeshTri()
            mesh.refine(1)
            hs[p - 1] = np.array([])
            H1errs[p - 1] = np.array([])
            L2errs[p - 1] = np.array([])

            for itr in range(4):
                mesh.refine()

                a = fasm.AssemblerElement(mesh, felem.ElementTriPp(p))

                A = a.iasm(dudv)
                f = a.iasm(fv)

                B = a.fasm(uv)
                g = a.fasm(gv)

                u = np.zeros(a.dofnum_u.N)
                u = spsolve(A + B, f + g)

                hs[p - 1] = np.append(hs[p - 1], mesh.param())
                L2errs[p - 1] = np.append(L2errs[p - 1], a.L2error(u, U))
                H1errs[p - 1] = np.append(H1errs[p - 1], a.H1error(u, dexact))

            pfit = np.polyfit(np.log10(hs[p - 1]), np.log10(H1errs[p - 1]), 1)

            self.assertTrue(pfit[0] >= 0.95 * p)
Пример #11
0
    def runTest(self):
        mesh = fmsh.MeshTri()
        mesh.refine(2)

        a = fasm.AssemblerElement(mesh, felem.ElementTriRT0())
        b = fasm.AssemblerElement(mesh, felem.ElementTriRT0(),
                                  felem.ElementP0())
        c = fasm.AssemblerElement(mesh, felem.ElementP0())

        def sigtau(u, v):
            sig = u
            tau = v
            return sig[0] * tau[0] + sig[1] * tau[1]

        def divsigv(du, v):
            divsig = du
            return divsig * v

        def fv(v, x):
            return 2 * np.pi**2 * np.sin(np.pi * x[0]) * np.sin(
                np.pi * x[1]) * v

        def uv(u, v):
            return u * v

        def exact(x):
            return np.sin(np.pi * x[0]) * np.sin(np.pi * x[1])

        hs = np.array([])
        L2err = np.array([])

        for itr in range(1, 4):
            mesh.refine()
            a = fasm.AssemblerElement(mesh, felem.ElementTriRT0())
            b = fasm.AssemblerElement(mesh, felem.ElementTriRT0(),
                                      felem.ElementP0())
            c = fasm.AssemblerElement(mesh, felem.ElementP0())

            A = a.iasm(sigtau)
            B = b.iasm(divsigv)
            C = c.iasm(uv)
            f = c.iasm(fv)

            K1 = spsp.hstack((-A, -B.T))
            K2 = spsp.hstack((-B, 0 * C))
            K = spsp.vstack((K1, K2)).tocsr()

            F = np.hstack((np.zeros(A.shape[0]), f))

            u = np.zeros(a.dofnum_u.N + c.dofnum_u.N)

            u = spsolve(K, F)

            Iu = np.arange(C.shape[0], dtype=np.int64) + A.shape[0]

            hs = np.append(hs, mesh.param())
            L2err = np.append(L2err, c.L2error(u[Iu], exact))

        pfit = np.polyfit(np.log10(hs), np.log10(L2err), 1)
        self.assertTrue(pfit[0] >= 0.95)
        self.assertTrue(pfit[0] <= 1.15)