示例#1
0
文件: test_asm.py 项目: mfkiwl/sp.fem
    def runTest(self):
        # solve Poisson by standard P1 method
        # and P1(dg) interior penalty method.
        #
        # this will test interior facet assembly and normal
        # vectors.
        from spfem.mesh import MeshTri
        from spfem.asm import AssemblerElement
        from spfem.element import ElementTriP1, ElementTriDG
        from spfem.utils import direct
        import numpy as np

        m = MeshTri()
        m.refine(3)

        e = ElementTriDG(ElementTriP1())
        e1 = ElementTriP1()
        a = AssemblerElement(m, e)
        a1 = AssemblerElement(m, e1)
        b1 = AssemblerElement(m, e1, e)

        A = a.iasm(lambda du, dv: du[0]*dv[0] + du[1]*dv[1])
        M = a.iasm(lambda u, v: u*v)
        b = a.iasm(lambda v, x: np.sin(2.0*np.pi*x[0])*v)

        B1 = a.fasm(lambda u1,u2,v1,v2,h: 1/h*(u1-u2)*(v1-v2), interior=True)
        B2 = a.fasm(lambda u,v,h: 1/h*u*v)
        B=B1+B2

        C1 = a.fasm(lambda du1,du2,v1,v2,n: 0.5*(du1[0]*n[0]*v1 - du2[0]*n[0]*v2
                                           + du1[1]*n[1]*v1 - du2[1]*n[1]*v2), interior=True)
        C2 = a.fasm(lambda du,v,n: (du[0]*n[0]+du[1]*n[1])*v)
        C=C1+C2

        D = C+C.T

        eps = 1e-3
        eta = 1e5
        x = direct(A + eta*B - 0*D, b)

        K = a1.iasm(lambda du, dv: du[0]*dv[0] + du[1]*dv[1])
        f = a1.iasm(lambda v, x: np.sin(2.0*np.pi*x[0])*v)

        y = direct(K, f, I=m.interior_nodes())

        P = b1.iasm(lambda u,v: u*v)

        self.assertAlmostEqual(np.linalg.norm(x-direct(M,P*y)),0,places=4)
示例#2
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)
示例#3
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)
示例#4
0
文件: test_asm.py 项目: mfkiwl/sp.fem
    def runTest(self):
        import numpy as np
        from spfem.mesh import MeshTri
        from spfem.asm import AssemblerAbstract, AssemblerElement
        from spfem.element import AbstractElementTriPp, ElementTriP1
        from spfem.utils import direct

        m = MeshTri()
        m.refine(3)

        e = AbstractElementTriPp(1)
        e1 = ElementTriP1()
        a = AssemblerAbstract(m,e)
        b = AssemblerElement(m,e1)

        A=a.iasm(lambda du,dv: du[0]*dv[0]+du[1]*dv[1])
        f=a.iasm(lambda v: 1.0*v)

        x=direct(A,f,I=m.boundary_nodes())

        K=a.inorm(lambda u: u[0], {0:x})

        self.assertAlmostEqual(np.sqrt(np.sum(K)),b.L2error(x,lambda X:0*X[0]))
示例#5
0
    def runTest(self, verbose=False):
        U = TensorFunction(dim=3, torder=1)
        V = TensorFunction(dim=3, torder=1, sym='v')

        # infinitesimal strain tensor
        def Eps(W):
            return 0.5 * (grad(W) + grad(W).T())

        # material parameters: Young's modulus and Poisson ratio
        E = 20
        Nu = 0.3

        # Lame parameters
        Lambda = E * Nu / ((1 + Nu) * (1 - 2 * Nu))
        Mu = E / (2 * (1 + Nu))

        # definition of the stress tensor
        def Sigma(W):
            return 2 * Mu * Eps(W) + Lambda * div(W) * IdentityMatrix(3)

        # define the weak formulation
        dudv = dotp(Sigma(U), Eps(V))
        dudv = dudv.handlify(verbose=verbose)

        # generate a mesh in the box
        m = fmsh.MeshTet()
        m.refine(4)

        # define the vectorial element
        e = felem.ElementH1Vec(felem.ElementTetP1())
        # create a FE-assembler object
        a = fasm.AssemblerElement(m, e)
        # assemble the stiffness matrix
        A = a.iasm(dudv)

        # define analytical solution and compute loading corresponding to it
        def exact(x):
            return -0.1 * np.sin(np.pi * x[0]) * np.sin(np.pi * x[1]) * np.sin(
                np.pi * x[2])

        def loading():
            global exactvonmises
            import sympy as sp
            x, y, z = sp.symbols('x y z')
            Ut = ConstantTensor(0.0, dim=3, torder=1)
            Ut.expr[0] = 0 * x
            Ut.expr[1] = 0 * x
            Ut.expr[2] = 0.1 * sp.sin(sp.pi * x) * sp.sin(sp.pi * y) * sp.sin(
                sp.pi * z)

            return dotp(div(Sigma(Ut)), V).handlify(verbose=verbose)

        # assemble the load vector
        f = a.iasm(loading())

        i1 = m.interior_nodes()
        I = a.dofnum_u.getdofs(N=i1)

        # solve the system
        u = futil.direct(A, f, I=I, use_umfpack=True)

        e1 = felem.ElementTetP1()
        c = fasm.AssemblerElement(m, e1)

        L2err = c.L2error(u[a.dofnum_u.n_dof[2, :]], exact)

        self.assertTrue(c.L2error(u[a.dofnum_u.n_dof[2, :]], exact) <= 1e-3)

        if verbose:
            # displaced mesh for drawing
            mdefo = copy.deepcopy(m)
            mdefo.p[0, :] += u[a.dofnum_u.n_dof[0, :]]
            mdefo.p[1, :] += u[a.dofnum_u.n_dof[1, :]]
            mdefo.p[2, :] += u[a.dofnum_u.n_dof[2, :]]

            # project von mises stress to scalar P1 element
            V = TensorFunction(dim=3, torder=0, sym='v')
            b = fasm.AssemblerElement(m, e, e1)

            S = Sigma(U)

            def vonmises(s):
                return np.sqrt(0.5*((s[0,0]-s[1,1])**2+(s[1,1]-s[2,2])**2+(s[2,2]-s[0,0])**2+\
                       6.0*(s[1,2]**2+s[2,0]**2+s[0,1]**2)))

            M = c.iasm(lambda u, v: u * v)

            # compute each component of stress tensor
            StressTensor = {}
            for itr in range(3):
                for jtr in range(3):
                    duv = (S[itr, jtr] * V).handlify(verbose=True)
                    P = b.iasm(duv)
                    StressTensor[(itr, jtr)] = fsol.direct(M,
                                                           P * u,
                                                           use_umfpack=True)

            # draw the von Mises stress
            mdefo.draw(u=vonmises(StressTensor), test=lambda x, y, z: x >= 0.5)
示例#6
0
        glue_unpack


displ = -0.2
x2 = np.zeros(K2.shape[0])
x2[2 * B2up + 1] = displ

K, b, D, unpack = glue_dofs(K1, K2, np.zeros(K1.shape[0]), -K2.dot(x2),
                            2 * B1up + 1, 2 * B2low + 1,
                            np.concatenate((2 * B1low + 1, 2 * B1low)),
                            np.concatenate((2 * B2up + 1, 2 * B2up)))

x = np.zeros(K.shape[0])

I = np.setdiff1d(np.arange(K.shape[0]), D)
x = direct(K, b, I=I)

X, Y = unpack(x)
Y[2 * B2up + 1] = displ

import copy
m1defo = copy.deepcopy(m1)
m2defo = copy.deepcopy(m2)

m1defo.p[0, :] += X[a1.dofnum_u.n_dof[0, :]]
m1defo.p[1, :] += X[a1.dofnum_u.n_dof[1, :]]
m2defo.p[0, :] += Y[a2.dofnum_u.n_dof[0, :]]
m2defo.p[1, :] += Y[a2.dofnum_u.n_dof[1, :]]

m1defo.draw()
plt.hold('on')
示例#7
0
    def runTest(self,verbose=False):
        U=TensorFunction(dim=3,torder=1)
        V=TensorFunction(dim=3,torder=1,sym='v')

        # infinitesimal strain tensor
        def Eps(W):
            return 0.5*(grad(W)+grad(W).T())

        # material parameters: Young's modulus and Poisson ratio
        E=20
        Nu=0.3

        # Lame parameters
        Lambda=E*Nu/((1+Nu)*(1-2*Nu))
        Mu=E/(2*(1+Nu))

        # definition of the stress tensor
        def Sigma(W):
            return 2*Mu*Eps(W)+Lambda*div(W)*IdentityMatrix(3)

        # define the weak formulation
        dudv=dotp(Sigma(U),Eps(V))
        dudv=dudv.handlify(verbose=verbose)

        # generate a mesh in the box
        m=fmsh.MeshTet()
        m.refine(4)

        # define the vectorial element
        e=felem.ElementH1Vec(felem.ElementTetP1())
        # create a FE-assembler object
        a=fasm.AssemblerElement(m,e)
        # assemble the stiffness matrix
        A=a.iasm(dudv)

        # define analytical solution and compute loading corresponding to it
        def exact(x):
            return -0.1*np.sin(np.pi*x[0])*np.sin(np.pi*x[1])*np.sin(np.pi*x[2])

        def loading():
            global exactvonmises
            import sympy as sp
            x,y,z=sp.symbols('x y z')
            Ut=ConstantTensor(0.0,dim=3,torder=1)
            Ut.expr[0]=0*x
            Ut.expr[1]=0*x
            Ut.expr[2]=0.1*sp.sin(sp.pi*x)*sp.sin(sp.pi*y)*sp.sin(sp.pi*z)

            return dotp(div(Sigma(Ut)),V).handlify(verbose=verbose)

        # assemble the load vector
        f=a.iasm(loading())

        i1=m.interior_nodes()
        I=a.dofnum_u.getdofs(N=i1)

        # solve the system
        u=futil.direct(A,f,I=I,use_umfpack=True)

        e1=felem.ElementTetP1()
        c=fasm.AssemblerElement(m,e1)

        L2err=c.L2error(u[a.dofnum_u.n_dof[2,:]],exact)

        self.assertTrue(c.L2error(u[a.dofnum_u.n_dof[2,:]],exact)<=1e-3)

        if verbose:
            # displaced mesh for drawing
            mdefo=copy.deepcopy(m)
            mdefo.p[0,:]+=u[a.dofnum_u.n_dof[0,:]]
            mdefo.p[1,:]+=u[a.dofnum_u.n_dof[1,:]]
            mdefo.p[2,:]+=u[a.dofnum_u.n_dof[2,:]]

            # project von mises stress to scalar P1 element
            V=TensorFunction(dim=3,torder=0,sym='v')
            b=fasm.AssemblerElement(m,e,e1)

            S=Sigma(U)
            def vonmises(s):
                return np.sqrt(0.5*((s[0,0]-s[1,1])**2+(s[1,1]-s[2,2])**2+(s[2,2]-s[0,0])**2+\
                       6.0*(s[1,2]**2+s[2,0]**2+s[0,1]**2)))

            M=c.iasm(lambda u,v:u*v)

            # compute each component of stress tensor
            StressTensor={}
            for itr in range(3):
                for jtr in range(3):
                    duv=(S[itr,jtr]*V).handlify(verbose=True)
                    P=b.iasm(duv)
                    StressTensor[(itr,jtr)]=fsol.direct(M,P*u,use_umfpack=True)

            # draw the von Mises stress
            mdefo.draw(u=vonmises(StressTensor),test=lambda x,y,z: x>=0.5)
示例#8
0
        glue_unpack


displ=-0.2
x2=np.zeros(K2.shape[0])
x2[2*B2up+1]=displ

K,b,D,unpack=glue_dofs(K1,K2,
        np.zeros(K1.shape[0]),-K2.dot(x2),
        2*B1up+1,2*B2low+1,
        np.concatenate((2*B1low+1,2*B1low)),np.concatenate((2*B2up+1,2*B2up)))

x=np.zeros(K.shape[0])

I=np.setdiff1d(np.arange(K.shape[0]),D)
x=direct(K,b,I=I)

X,Y=unpack(x)
Y[2*B2up+1]=displ

import copy
m1defo=copy.deepcopy(m1)
m2defo=copy.deepcopy(m2)

m1defo.p[0,:]+=X[a1.dofnum_u.n_dof[0,:]]
m1defo.p[1,:]+=X[a1.dofnum_u.n_dof[1,:]]
m2defo.p[0,:]+=Y[a2.dofnum_u.n_dof[0,:]]
m2defo.p[1,:]+=Y[a2.dofnum_u.n_dof[1,:]]

m1defo.draw()
plt.hold('on')