Beispiel #1
0
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)
Beispiel #2
0
 def testTriangle(self):
     for n in range(1, 10):
         x, w = puq.trianglequadrature(n)
         # test integration of constants
         self.assertAlmostEqual(sum(w), 0.5)
         # integrate x
         self.assertAlmostEqual(np.dot(x[:, 0], w), 1.0 / 6)
         # integrate y
         self.assertAlmostEqual(np.dot(x[:, 1], w), 1.0 / 6)
Beispiel #3
0
 def testOrthonormal(self):
     ''' Test that the Dubiner polynomials are L^2-orthonormal over the reference triangle'''
     N = 8
     for k in range(0, N):
         x,w = puq.trianglequadrature(k+1)
         dt = pup.DubinerTriangle(k,x)
         dtV = dt.values()
         l2 = np.dot(dtV.T, w * dtV)
         np.testing.assert_almost_equal(l2, np.eye(dtV.shape[1],dtV.shape[1]))
Beispiel #4
0
 def testValues(self):
     N = 5        
     for k in range(N):
         x,w = puq.trianglequadrature(k+1)
         dt = pup.DubinerTriangle(k, x)
         V = dt.values()
         n = ((k+1)*(k+2))/2
         self.assertEquals(V.shape[1], n) # test that we get the correct number of basis functions
         VV = np.dot(V.T, w * V)
         np.testing.assert_almost_equal(VV, np.eye(n)) # test that they are orthonormal
Beispiel #5
0
 def testLaplacian(self):
     ''' Use finite differences to check the Lapalcian calculations'''
     N = 6
     h = 1E-4
     x,w = puq.trianglequadrature(5)
     for k in range(1,N):
         v = pup.DubinerTriangle(k, x).values()
         L = pup.laplacian(k)
         Lv = np.dot(v, L)
         Lhv = (sum([pup.DubinerTriangle(k, x+xh).values() for xh in ([0,h],[0,-h],[h,0],[-h,0])]) - 4*v)/(h**2)
         np.testing.assert_almost_equal(Lv, Lhv, decimal=3)
Beispiel #6
0
    def testOptimalBasis2(self):
        """ Can we find the right direction to approximate a plane wave?"""
        k = 4
        g = pcb.PlaneWaves(numpy.array([[3.0/5,4.0/5]]), k).values
#        g = pcb.FourierBessel(numpy.array([-2,-1]), numpy.array([5]),k)
        npw = 3
        nq = 8
        gen, ini = puo.pwbasisgeneration(k, npw)
        triquad = puq.trianglequadrature(nq)
        basis, (coeffs, l2err) = puo.optimalbasis2(g, gen, ini, triquad)
        self.assertAlmostEqual(sum(l2err),0)
Beispiel #7
0
    def testConstrainedOptimisation(self):
        k = 4
        g = pcb.PlaneWaves(numpy.array([[3.0/5,4.0/5]]), k).values
#        g = pcb.FourierBessel(numpy.array([-2,-1]), numpy.array([5]),k)
        npw = 3
        nq = 8
        ini = pcb.circleDirections(npw)
        triquad = puq.trianglequadrature(nq)
        linearopt = puo.LeastSquaresFit(g, triquad)
        pwpg = puo.PWPenaltyBasisGenerator(k, 1, 2)
        basis = puo.optimalbasis3(linearopt.optimise, pwpg.finalbasis, ini)
        (coeffs, l2err) = linearopt.optimise(basis)        
        self.assertAlmostEqual(sum(l2err),0)        
Beispiel #8
0
 def testDerivs(self):
     N = 5
     h = 1E-8
     for k in range(0,N):
         x,w = puq.trianglequadrature(k+1)
         dt = pup.DubinerTriangle(k,x)
         dtV = dt.values()
         dtxh = pup.DubinerTriangle(k, x+[h,0])
         dtxhV = dtxh.values()
         dtyh = pup.DubinerTriangle(k, x+[0,h])
         dtyhV = dtyh.values()
         dtD = dt.derivs()
         dtxhD = (dtxhV - dtV)/h
         dtyhD = (dtyhV - dtV)/h
         
         np.testing.assert_almost_equal(dtD[0],dtxhD, decimal=4)
         np.testing.assert_almost_equal(dtD[1],dtyhD, decimal=4)
Beispiel #9
0
def raytracesoln(problem, etods, pdeg = 2, npw = 15, radius = 0.5):
    quadpoints = 15
    k = problem.k
    rtpw = prb.OldRaytracedBasisRule(etods)
    
    fb = FourierBesselRule()
    shadow = RaytracedShadowRule(etods, fb)
    
    
    crt = SourceBasisRule()
        
    
    poly = pcbr.ReferenceBasisRule(pcbr.Dubiner(pdeg))

#   unonpw = pcbu.UnionBasisRule([shadow, crt])                         
#    polynonpw = pcb.ProductBasisRule(poly, unonpw)
#    basisrule = pcbu.UnionBasisRule([polynonpw,rtpw])
    
#    unionall = pcbu.UnionBasisRule([shadow, rtpw, crt])
#    polyall = pcb.ProductBasisRule(poly, unionall)
#    basisrule = polyall
    
    rt = pcbu.UnionBasisRule([rtpw, shadow])
    polyrt = pcb.ProductBasisRule(poly, rt)
    basisrule = polyrt
    
    
#    pw = pcb.planeWaveBases(2, k, nplanewaves=npw)
#    basisrule = CornerMultiplexBasisRule(pw, basisrule, radius)    
    
#    polyrt2 = pcbu.UnionBasisRule([rt,pcb.ProductBasisRule(poly, crt)])
    
#    basisrule = polyrt2
    basisrule = pcbred.SVDBasisReduceRule(puq.trianglequadrature(quadpoints), basisrule, threshold=1E-5)
    
    p = 1 if pdeg < 1 else pdeg
    h = 4.0/40
    alpha = ((p*1.0)**2 )  / (k*h)
    beta = np.min([(k*h) / (p * 1.0),1]) 
    computation = psc.Computation(problem, basisrule, pcp.HelmholtzSystem, quadpoints, alpha = alpha, beta = beta)
    
    solution = computation.solution(psc.DirectSolver().solve, dovolumes=True)
    bounds=array([[-2,2],[-2,2]],dtype='d')
    npoints=array([200,200])
    pos.standardoutput(computation, solution, 20, bounds, npoints, mploutput = True, cmap=pom.mp.cm.get_cmap('binary'))
Beispiel #10
0
 def testDubiner(self):
     # The Dubiner basis is L^2-orthogonal, so we can test that the SVN reduction doesn't do much to it
     # ... On reflection, this doesn't test very much.  But it at least exercises the code, so leaving it in
     k = 10
     N = 3
     bounds=np.array([[0.1,0.1],[0.9,0.9]],dtype='d')
     npoints=np.array([20,20])
     sp = pug.StructuredPoints(bounds, npoints)
     
     for n in range(1,4):
         mesh = tum.regularsquaremesh(n)
         dubrule = pcbr.ReferenceBasisRule(pcbr.Dubiner(N))
         problem = psp.Problem(mesh, k, {})
         dubbasis = psp.constructBasis(problem, dubrule)     
         refquad = puq.trianglequadrature(N+1)
         svnrule = pcbred.SVDBasisReduceRule(refquad, dubrule)
         svnbasis = psp.constructBasis(problem, svnrule)
         # The bases should be equivalent:
         testEquivalentBases(dubbasis, svnbasis, mesh, sp)
Beispiel #11
0
from pypwdg.output.vtk_output import VTKStructuredPoints
from pypwdg.output.vtk_output import VTKGrid
from pypwdg.mesh.meshutils import MeshQuadratures
from pypwdg.core.vandermonde import LocalVandermondes



mesh_dict=gmsh_reader('../../examples/3D/scattmesh.msh')
mesh=gmshMesh(mesh_dict,dim=3)
boundaryentities = [82, 83]


Nq = 16
Np = 3
dirs = cubeRotations(cubeDirections(Np))
quad=trianglequadrature(Nq)


elttobasis = [[PlaneWaves(dirs, k)]] * mesh.nelements

params={'alpha':.5, 'beta':.5,'delta':.5}

l_coeffs=[-1j*k, 1]
r_coeffs=[-1j*k, 1]
      
bnddata={82:zero_impedance(k), 83:dirichlet(g) }

mqs = MeshQuadratures(mesh, quad)
lv = LocalVandermondes(mesh, elttobasis, mqs, usecache=False)
bndvs=[]
for data in bnddata.values():
Beispiel #12
0
 def testMEQ(self):
     for n in range(1, 6):
         mesh = tum.regularsquaremesh(n)
         mq = pmmu.MeshElementQuadratures(mesh, puq.trianglequadrature(5))
         for i in range(2 * n ** 2):
             self.assertAlmostEquals(sum(mq.quadweights(i)), 1.0 / (2 * n ** 2))
Beispiel #13
0
 def test3DQuadratures(self):
     """ Ensure quadratures on neighbouring faces of various 3D meshes match """
     self.compareQuadratures(tum.meshes3d(), puq.trianglequadrature(4))
Beispiel #14
0
 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)
entityton ={9:1}
problem=psp.VariableNProblem(entityton, mesh,k, bnddata)
etods = prc.tracemesh(problem, {10:lambda x:direction})


etob = [[pcb.PlaneWaves(ds, k)] if len(ds) else [] for ds in etods]
pob.vtkbasis(mesh,etob,'soundsoftrays.vtu',None)

b0=pcbv.PlaneWaveVariableN(pcb.circleDirections(30))
b=pcb.PlaneWaveFromDirectionsRule(etods)
origins=np.array([[-.5,-.5],[-.5,.5],[.5,-.5],[.5,.5]])
h=pcb.FourierHankelBasisRule(origins,[0])
h2=pcb.ProductBasisRule(h,pcbr.ReferenceBasisRule(pcbr.Dubiner(p)))

b1=pcb.ProductBasisRule(b,pcbr.ReferenceBasisRule(pcbr.Dubiner(p)))
bh=pcb.UnionBasisRule([h2,b1])


b2=pcbr.ReferenceBasisRule(pcbr.Dubiner(p))

basisrule = pcbred.SVDBasisReduceRule(puq.trianglequadrature(quadpoints), bh, threshold=1E-5)


computation = psc.Computation(problem, basisrule, pcp.HelmholtzSystem, quadpoints,alpha=alpha,beta=beta,delta=delta)
solution = computation.solution(psc.DirectSolver().solve, dovolumes=True)
pos.standardoutput(computation, solution, quadpoints, bounds, npoints, 'soundsoft_pol', mploutput = True)
print solution.getError('Dirichlet')
print solution.getError('Neumann')
print solution.getError('Boundary')