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