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