Esempio n. 1
0
    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)
Esempio n. 2
0
def Poisson_triP1():
    mesh = MeshTri()
    mesh.refine(1)
    # mesh.draw()
    # mesh.draw_debug()
    # mesh.draw_nodes(6)
    # mesh.plot(z=[0, 0, 0, 0, 0, 0, 1, 0, 0])
    # mesh.plot3(z=[0, 0, 0, 0, 0, 0, 1, 0, 0])
    # plt.show()
    # print(mesh._neighbors()) # TODO 弄懂邻居

    # boundary and interior node sets
    D1 = np.nonzero(mesh.p[0, :] == 0)[0] # x坐标为0的点
    D2 = np.nonzero(mesh.p[1, :] == 0)[0] # y坐标为0的点
    D3 = np.nonzero(mesh.p[0, :] == 1)[0] # x坐标为1的点
    D4 = np.nonzero(mesh.p[1, :] == 1)[0] # y坐标为1的点

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

    I = np.setdiff1d(np.arange(0, mesh.p.shape[1]), D) # 位于内部的点的编号,这里暗示了节点编号必须从0开始,依次递增

    bilin = lambda u, v, du, dv, x, h: du[0] * dv[0] + du[1] * dv[1]
    lin = lambda v, dv, x, h: 1 * v

    a = AssemblerElement(mesh, ElementTriP1()) # 用这个例子好好理解 mesh._build_mappings(), FIXME 重要

    # 只在编号为1的单元计算单刚
    A_ = a.iasm(bilin, tind=[1])
    f_ = a.iasm(lin, tind=[1])
    A = a.iasm(bilin)
    f = a.iasm(lin)

    x = np.zeros(A.shape[0])
    I = I
    x[I] = spsolve(A[np.ix_(I, I)], f[I])

    # assert np.round(np.max(x) - 0.073614737354524146, 8) == 0 # 需要将初始网格加密5次
    print(np.max(x))
Esempio n. 3
0
def contact_mesh(h, nref=0):
    points = [
        (-1.0, 0.0),
        (-1.0, -1.0),
        (1.0, -1.0),
        (1.0, 0.0),  # lower block
        (-scale, 0.0),
        (-scale, 1.0),
        (scale, 1.0),
        (scale, 0.0)
    ]  # upper block
    facets = [(0, 1), (1, 2), (2, 3), (3, 0), (4, 5), (5, 6), (6, 7), (7, 4)]
    g = GeometryMeshPyTriangle(points, facets)
    m = g.mesh(h)
    if nref > 0:
        m.refine(nref)
    my = .3333 * np.sum(m.p[1, m.t], axis=0)
    ixlower = np.nonzero(my < 0.0)[0]
    ixupper = np.nonzero(my > 0.0)[0]
    mupper = MeshTri(*m.remove_elements(ixlower))
    mlower = MeshTri(*m.remove_elements(ixupper))
    return mlower, mupper
Esempio n. 4
0
    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]))
Esempio n. 5
0
def example():
    mesh = MeshLine()
    mesh.refine(2)
    print(mesh.boundary_nodes())
    print(mesh.interior_nodes())
    # u = np.array([1, 5, 3, 2, 4]) # 在网格节点上的函数值,有顺序
    # mesh.plot(u)
    # plt.show()
    mapping = mesh.mapping() # 对一维没什么内容,重点看二维,三维

    tri = MeshTri(initmesh="reftri")
    tri.refine(1)
    tri.draw()
    mapping = tri.mapping() # CONTINUE

    pass
Esempio n. 6
0
def TriP2Test():
    """Test triangular h-refinement.
    Also test facet assembly."""
    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

    mesh=MeshTri()
    mesh.draw()
    mesh.refine(1)
    mesh.draw()
    hs=np.array([])
    H1errs=np.array([])
    L2errs=np.array([])

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

        a=AssemblerElement(mesh,ElementTriP2())

        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=np.append(hs,mesh.param())
        L2errs=np.append(L2errs,a.L2error(u,U))
        H1errs=np.append(H1errs,a.H1error(u,dexact))

    # https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.polyfit.html
    pfit=np.polyfit(np.log10(hs),np.log10(H1errs),1)

    assert (pfit[0] >= 0.95*2)