Example #1
0
def trivialwavefront(c, N = 50):
    slowness = lambda x: np.ones(len(x)) /c
    gradslowness = lambda x: np.zeros_like(x)
    x0 = np.vstack((np.linspace(0,1,N), np.zeros(N))).T
    p0 = np.vstack((np.zeros(N), np.ones(N))).T
    wfs, idxs = prw.wavefront(x0, p0, slowness, gradslowness, 0.05, 1.0/c, 1)
    plotwavefront(wfs, idxs)
Example #2
0
def bubblematerial(c=1, N=20, dt=0.05, gridpoints=100, plotoutput=True):
    """ Calculate first arrival times for a wave travelling through NicolasBubble using a wavefront method
        that is then interpolated onto a grid
        Args:
            c: baseline wave speed
            N: number of points to put on initial wavefront
            dt: timestep (the wavefront implementation uses forward Euler)
            gridpoints: number of points to resolve on the grid
            plotoutput: whether to display output
        Returns:
            A 2D array containing the first arrival times at the points on the grid
            
    """
    bounds = [[0, 1], [0, 1]]  # The x-axis and y-axis bounds for the domain
    npoints = [gridpoints, gridpoints]  # The number of points to (eventually) resolve in the grid

    speed = NicolasBubble()
    if plotoutput:
        pom.output2dfn(bounds, speed, npoints, show=False)  # plot the speed function
    slowness = lambda x: 1 / speed(x)
    gradslowness = prw.gradient(slowness, 1e-6)  # A very crude numerical gradient

    #    These two lines would initialise a plane wave entering the domain
    #    x0 = np.vstack((np.linspace(0,1,N), np.zeros(N))).T
    #    p0 = np.vstack((np.zeros(N), np.ones(N))).T

    #    These three lines initialise a source
    angles = np.linspace(-1e-2, math.pi + 1e-2, N)
    p0 = np.vstack((np.cos(angles), np.sin(angles))).T
    x0 = np.array([0.5, 0]) + dt * p0

    #    Perform the wavefront tracking
    wfs, idxs = prw.wavefront(x0, p0, slowness, gradslowness, dt, 1.25 / c, 0.1)
    if plotoutput:
        erw.plotwavefront(wfs, idxs, bounds)  # plot the wavefronts

    #    Use SciPy's interpolation (which doesn't work well when there are multiple arrival times)
    #    phasefn = interpolatephase(wfs, dt)
    #    pom.output2dfn(bounds, phasefn, npoints, show=False, type='contour')

    #    Home-brew interpolation:
    sp = pug.StructuredPoints(np.array(bounds).T, npoints)  # Define the points onto which we're going to interpolate
    initialbox = [[0.4, 0], [0.6, 0.1]]  # The vertices of a box that contain (some of) the first wave front
    pointinfo = prw.StructuredPointInfo(
        sp, sp.getPoints(initialbox)[0]
    )  # Obtain the indices of the points that are in the initial box
    h = np.max((sp.upper - sp.lower) / sp.npoints)  # The (maximum) grid spacing
    _, phases = prw.nodesToDirsAndPhases(
        wfs, idxs, pointinfo, lookback=int(math.ceil(h / (c * dt)))
    )  # perform the interpolation

    firstphase = (
        np.array([p[0] if len(p) > 0 else -1 for p in phases]) * dt
    )  # We only care about the first phase found per point

    #    pom.image(firstphase, (M+1,M+1), np.array(bounds))
    if plotoutput:
        pom.contour(pointinfo.points, firstphase, npoints)
    return firstphase.reshape(npoints)
Example #3
0
def linearmaterial():
    N = 50
    speed = lambda x: 1 + x[:,0]
    slowness = lambda x: 1 / speed(x)
    gradslowness = prw.gradient(slowness, 1E-6)
    x0 = np.vstack((np.linspace(0,1,N), np.zeros(N))).T
    p0 = np.vstack((np.zeros(N), np.ones(N))).T
    wfs, idxs = prw.wavefront(x0, p0, slowness, gradslowness, 0.05, 1.5, 1)
    plotwavefront(wfs, idxs)
Example #4
0
def bubblematerial(c = 1, N = 20):
#    slowness, gradslowness = bubble(c)
    slowness, gradslowness = hump(c)
    x0 = np.vstack((np.linspace(0,1,N), np.zeros(N))).T
    p0 = np.vstack((np.zeros(N), np.ones(N))).T
    wfs, idxs = prw.wavefront(x0, p0, slowness, gradslowness, 0.1, 1.2/c, 0.1)
    mp.subplot(1,2,1)
    plotwavefront(wfs, idxs)
    mesh = ptum.regularsquaremesh(12, "BDY")
    etob = prb.getetob(wfs, idxs, mesh, "BDY")
    mp.subplot(1,2,2)
    pom.showmesh(mesh)
    pom.showdirections(mesh, etob,scale=20)
Example #5
0
 def testRaytraceMesh(self):
     c = 0.5
     for (Nmesh, Nrt) in [(10,10), (20,4), (4, 20)]:
         mesh = ptum.regularsquaremesh(Nmesh, "BDY")
         x0 = np.vstack((np.linspace(-0.2,1.2,Nrt), np.ones(Nrt)*(-0.2))).transpose()
         p0 = np.vstack((np.zeros(Nrt), np.ones(Nrt))).transpose()
         slowness = lambda x: np.ones(len(x))/c
         gradslowness = lambda x: np.zeros_like(x)
         
         wfs, fidxs = prw.wavefront(x0, p0, slowness, gradslowness, 1/(c * Nrt), 1.4 / c, 1/(c * Nrt))
         phases = prw.nodesToPhases(wfs, fidxs, mesh, ["BDY"])
         self.assertEqual(len(phases), (Nmesh+1)**2)
         for vp in phases:
             self.assertGreaterEqual(len(vp), 1)
             for p in vp:
                 np.testing.assert_array_almost_equal(p, [0,1/c])
Example #6
0
pdeg = 2

c = 1
N = 20    

slow = w.GaussianBubble(c)
gradslow = prw.gradient(slow, 1E-6)
#speed = Recip(slow)
speed = lambda p: 1.0/slow(p)
#slow, gradslow = w.hump(c,0.2,0.1,0.3)

#entityton = {6:1}

x0 = np.vstack((np.linspace(0,1,N),np.zeros(N))).T
p0 = np.vstack((np.zeros(N),np.ones(N))).T
wavefronts, forwardidxs = prw.wavefront(x0, p0, slow, gradslow, 0.1, 1.6/c, 0.1)

# Original basis:
pw = pcbv.PlaneWaveVariableN(pcb.uniformdirs(2,npw))

# Polynomials only:
poly = pcbr.ReferenceBasisRule(pcbr.Dubiner(pdeg))
prodpw = pcb.ProductBasisRule(pw, poly)

# Product basis:
#basisrule = pcb.ProductBasisRule(pcb.planeWaveBases(2,k,npw), pcbr.ReferenceBasisRule(pcbr.Dubiner(1)))

#basisrule=pcb.ProductBasisRule(pw,pcbr.ReferenceBasisRule(pcbr.Dubiner(0)))
#basisrule = pcbred.SVDBasisReduceRule(puq.trianglequadrature(quadpoints), basisrule)