def laplacian(k): ''' Calculate the laplacian matrix for the Dubiner basis. Returns L where \nabla^2 u = u . L for any vandermonde matrix u N.B. would be easy to generalise this to any polynomial basis (indeed, the calculation of the mass matrix is currently superfluous as the Dubiner basis is orthonomal) THIS IS NOT USED - see p.c.b.reference.py for the alternative implemenation ''' tp, tw = puq.trianglequadrature(k+1) dt = DubinerTriangle(k,tp) vtp = dt.values() dtp = dt.derivs() mass = np.tensordot(vtp * tw, vtp, (0,0)) stiffness = -np.tensordot(dtp * tw, dtp, ((0,1),(0,1))) ex, ew = puq.legendrequadrature(k+1) # Now do the boundary integrals ew = ew.reshape(-1,1) ep1 = np.hstack((ex, np.zeros_like(ex))) ep2 = np.hstack((np.zeros_like(ex),ex)) ep3 = np.hstack((ex,1-ex)) for p, n in ((ep1,[0,-1]),(ep2,[-1,0]), (ep3, [1,1])): dt = DubinerTriangle(k, p) vn = np.tensordot(dt.derivs(), np.array(n), (0,0)) stiffness+=np.tensordot(dt.values() * ew, vn, (0,0)) return np.linalg.solve(mass, stiffness)
def testEQ(self): for n in range(1, 6): mesh = tum.regularsquaremesh(n) mq = pmmu.MeshQuadratures(mesh, puq.legendrequadrature(6)) for i in range(6 * n ** 2): if i % 3 == 1: self.assertAlmostEquals(sum(mq.quadweights(i)), math.sqrt(2) / n) else: self.assertAlmostEquals(sum(mq.quadweights(i)), 1.0 / n)
def testEdge(self): N = 10 k = 10 D = 1 x,w = puq.legendrequadrature(3*N) x = np.hstack((x, np.zeros_like(x))) g = pcb.PlaneWaves(pcb.circleDirections(40)[15], k) bc = pcbd.generic_boundary_data([1j*k,1],[1j*k,1],g) # t1 = prp.findpw(prp.ImpedanceProd(bc, (x,w), [0,1], k), D, maxtheta = 1) t1 = prp.findpw(prp.L2Prod(bc.values, (x,w), k), D, maxtheta = 1) self.assertAlmostEqual(t1, (2 * math.pi * 15) / 40)
def testOrthogonal(self): N = 4 MaxAB = 4 x,w = puq.legendrequadrature(N + MaxAB) x = x.ravel() n = np.arange(N, dtype = float) for a in range(MaxAB): for b in range(MaxAB): # first lets test some orthogonality: P = pup.jacobidnorm(N-1, a, b, 0, x) # get the first N jacobi polynomials evaluated at x jw = w * x**b * (1-x)**a # combine quadrature weight with orthogonality weight PP = np.dot(P.T * jw, P) # norm2 = (1 /(2*n+a+b+1)) * (sso.poch(n + 1, a) / sso.poch(n + b + 1, a)) # np.testing.assert_almost_equal(PP, np.diag(norm2)) np.testing.assert_almost_equal(PP, np.eye(N,N))
def testLocalVandermondes(self): # This test is more about exercising the code than testing any results. We need a know simple mesh to do that dirs = numpy.array([[1,0]]) k = 3 pw = pcb.PlaneWaves(dirs, k) faceid = 0 numquads = 3 meshes = tum.examplemeshes2d() for mesh in meshes: mq = pmm.MeshQuadratures(mesh, puq.legendrequadrature(numquads)) e2b = pcb.constructBasis(mesh, pcb.UniformBasisRule([pw])) LV = pcv.LocalVandermondes(mesh, e2b, mq) for faceid in range(mesh.nfaces): v = LV.getValues(faceid) d = LV.getDerivs(faceid) self.assertEqual(v.shape, (numquads, 1)) self.assertEqual(d.shape, (numquads, 1)) self.assertEqual(LV.numbases[faceid], 1)
def testLegendre(self): for n in range(1, 10): x, w = puq.legendrequadrature(n) for m in range(0, 2 * n): # test integration of x^m self.assertAlmostEqual(np.dot(x.transpose() ** m, w), 1.0 / (m + 1))
def test2DQuadratures(self): """ Ensure quadratures on neighbouring faces of various 2D meshes match """ self.compareQuadratures(tum.meshes2d(), puq.legendrequadrature(6))
def __init__(self,n): self.n = n+1 self.volume = puq.legendrequadrature(n+1) self.face = puq.pointquadrature()
def __init__(self, k): self.k = k self.n = ((k+1) * (k+2)) / 2 self.volume = puq.trianglequadrature(k+1) self.face = puq.legendrequadrature(k+1)
boundaryentities = [10,11] #SM = StructureMatrices(mesh, boundaryentities) Nq = 20 Np = 15 dirs = circleDirections(Np) elttobasis = [[PlaneWaves(dirs, k)]] * mesh.nelements params={'alpha':.5, 'beta':.5,'delta':.5} bnddata={11:dirichlet(g), 10:zero_impedance(k)} quad=legendrequadrature(Nq) mqs = MeshQuadratures(mesh, quad) lv = LocalVandermondes(mesh, elttobasis, mqs, usecache=True) bndvs=[] for data in bnddata.values(): bndv = LocalVandermondes(mesh, [[data]] * mesh.nelements, mqs) bndvs.append(bndv) quad=legendrequadrature(Nq) S, f = assemble(mesh, k, lv, bndvs, mqs, elttobasis, bnddata, params) print "Solving system" from pymklpardiso.linsolve import solve
coeffs = sl.lstsq(bv, gv)[0] resids = np.dot(bv, coeffs) - gv errs[i] = math.sqrt(np.vdot(resids, resids)) return errs if __name__ == "__main__": k = 10 N = 40 FB = -1 # qxw = puq.trianglequadrature(N) # origin = [0.25,0.25] mesh = tum.regularsquaremesh() mqs = pmmu.MeshQuadratures(mesh, puq.legendrequadrature(N)) e = 0 qx = np.vstack([mqs.quadpoints(f) for f in mesh.etof[e]]) qw = np.concatenate([mqs.quadweights(f) for f in mesh.etof[e]]) qxw = (qx, qw) origin = pmmu.elementcentres(mesh)[e] # e = 0 # f = 0 # qx = mqs.quadpoints(mesh.etof[e][f]) # qw = mqs.quadweights(mesh.etof[e][f]) # qxw = (qx,qw) # origin = pmmu.elementcentres(mesh)[e] # g = pcb.PlaneWaves(np.array([[3.0/5, 4.0/5]]),k)