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)
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))
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
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]))
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
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)