Exemple #1
0
    def computeTravelTimes(self, slowness, allSensors=True):
        """Compute the travel times and fill data and time matrix
        for later use of response and Jacobian, respectively.
        For response only active sources are needed, for Jacobian we need all.
        """
        # mesh = self.mesh()  # better but for now input mesh
        mesh = self.mesh_
        data = self.data_
        param_markers = np.unique(mesh.cellMarkers())
        param_count = len(param_markers)
        if len(slowness) == mesh.cellCount():
            self.mapModel(slowness)
        elif len(slowness) == param_count:
            # map the regions in the mesh to slowness
            slow_map = pg.stdMapF_F()
            min_reg_num = min(param_markers)
            for i, si in enumerate(slowness):
                slow_map.insert(float(i+min_reg_num), si)

            mesh.mapCellAttributes(slow_map)
        else:
            raise ValueError("Wrong no of parameters. Mesh size: {}, no "
                             "of regions: {}, and number of slowness values:"
                             "{}".format(self.mesh().cellCount(), param_count,
                                         len(slowness)))

        times = pg.RVector(self.nNodes, 0.)
        upTags = np.zeros(self.nNodes)
        downTags = np.zeros(mesh.nodeCount())
        for iSource in range(self.nSensors):
            # initial condition (reset vectors)
            times *= 0.0
            upTags *= 0
            downwind = set()
            source = self.data_.sensorPosition(iSource)
            cell = self.mesh_.findCell(source)
            # fill in nodes around source using local smoothness
            for i, n in enumerate(cell.nodes()):
                times[n.id()] = cell.attribute() * n.pos().distance(source)
                upTags[n.id()] = 1
            for i, n in enumerate(cell.nodes()):
                tmpNodes = pg.commonNodes(n.cellSet())
                for nn in tmpNodes:
                    if not upTags[nn.id()] and not downTags[nn.id()]:
                        downwind.add(nn)
                        downTags[nn.id()] = 1

            while len(downwind) > 0:  # start fast marching
                fastMarch(self.mesh_, downwind, times, upTags, downTags)

            self.dataMatrix[iSource] = pg.interpolate(mesh, times,
                                                      data.sensorPositions())
            self.timeMatrix[iSource] = pg.interpolate(mesh, times,
                                                      self.midPoints)

            sensor_idx = data("g")[data("s") == iSource]
Exemple #2
0
    def computeTravelTimes(self, slowness, allSensors=True):
        """Compute the travel times and fill data and time matrix
        for later use of response and Jacobian, respectively.
        For response only active sources are needed, for Jacobian we need all.
        """
        # mesh = self.mesh()  # better but for now input mesh
        mesh = self.mesh_
        data = self.data_
        param_markers = np.unique(mesh.cellMarkers())
        param_count = len(param_markers)
        if len(slowness) == mesh.cellCount():
            self.mapModel(slowness)
        elif len(slowness) == param_count:
            # map the regions in the mesh to slowness
            slow_map = pg.stdMapF_F()
            min_reg_num = min(param_markers)
            for i, si in enumerate(slowness):
                slow_map.insert(float(i + min_reg_num), si)

            mesh.mapCellAttributes(slow_map)
        else:
            raise ValueError("Wrong no of parameters. Mesh size: {}, no "
                             "of regions: {}, and number of slowness values:"
                             "{}".format(self.mesh().cellCount(), param_count,
                                         len(slowness)))

        times = pg.RVector(self.nNodes, 0.)
        upTags = np.zeros(self.nNodes)
        downTags = np.zeros(mesh.nodeCount())
        for iSource in range(self.nSensors):
            # initial condition (reset vectors)
            times *= 0.0
            upTags *= 0
            downwind = set()
            source = self.data_.sensorPosition(iSource)
            cell = self.mesh_.findCell(source)
            # fill in nodes around source using local smoothness
            for i, n in enumerate(cell.nodes()):
                times[n.id()] = cell.attribute() * n.pos().distance(source)
                upTags[n.id()] = 1
            for i, n in enumerate(cell.nodes()):
                tmpNodes = pg.commonNodes(n.cellSet())
                for nn in tmpNodes:
                    if not upTags[nn.id()] and not downTags[nn.id()]:
                        downwind.add(nn)
                        downTags[nn.id()] = 1

            while len(downwind) > 0:  # start fast marching
                fastMarch(self.mesh_, downwind, times, upTags, downTags)

            self.dataMatrix[iSource] = pg.interpolate(mesh, times,
                                                      data.sensorPositions())
            self.timeMatrix[iSource] = pg.interpolate(mesh, times,
                                                      self.midPoints)

            sensor_idx = data("g")[data("s") == iSource]
Exemple #3
0
    # initialize source position and trvel time vector
    source = pg.RVector3(0., 0.)
    times = pg.RVector(mesh.nodeCount(), 0.)

    # initialize sets and tags
    upwind, downwind = set(), set()
    upTags, downTags = np.zeros(mesh.nodeCount()), np.zeros(mesh.nodeCount())

    # define initial condition
    cell = mesh.findCell(source)

    for i, n in enumerate(cell.nodes()):
        times[n.id()] = cell.attribute() * n.pos().distance(source)
        upTags[n.id()] = 1
    for i, n in enumerate(cell.nodes()):
        tmpNodes = pg.commonNodes(n.cellSet())
        for nn in tmpNodes:
            if not upTags[nn.id()] and not downTags[nn.id()]:
                downwind.add(nn)
                downTags[nn.id()] = 1

    # start fast marching
    tic = time.time()
    while len(downwind) > 0:
        fastMarch(mesh, downwind, times, upTags, downTags)

    print(time.time() - tic, "s")

    # compare with analytical solution along the x axis
    x = np.arange(0., 100., 0.5)
    t = pg.interpolate(mesh, times, pg.asvector(x), x * 0., x * 0.)
Exemple #4
0
def fastMarch( mesh, downwind, times, upTags, downTags ):

    def findSlowness( edge ):
        if edge.leftCell() is None:
            slowness = edge.rightCell().attribute()
        elif edge.rightCell() is None:
            slowness = edge.leftCell().attribute()
        else:
            slowness = min( edge.leftCell().attribute(), edge.rightCell().attribute() )
        return slowness
    # def findSlowness( ... )

    upCandidate = []

    for node in downwind:
        neighNodes = pg.commonNodes( node.cellSet() )

        upNodes = []
        for n in neighNodes:
            if upTags[ n.id() ]:
                upNodes.append( n )

        if len( upNodes ) == 1:
            # this is the dijkstra case
            edge = pg.findBoundary( upNodes[0], node )
            tt = times[ upNodes[0].id() ] + findSlowness( edge ) * edge.shape().domainSize()

            heapq.heappush( upCandidate, (tt, node) )
        else:
            cells = node.cellSet()
            for c in cells:
                for i in range( c.nodeCount() ):
                    edge = pg.findBoundary( c.node( i ), c.node( (i + 1 )%3 ) )

                    a = edge.node( 0 )
                    b = edge.node( 1 )
                    ta = times[ a.id() ]
                    tb = times[ b.id() ]

                    if upTags[ a.id() ] and upTags[ b.id() ]:
                        line = pg.Line( a.pos(), b.pos() )
                        t = min( 1., max( 0., line.nearest( node.pos() ) ) )

                        ea = pg.findBoundary( a, node )
                        eb = pg.findBoundary( b, node )

                        if t == 0:
                            slowness = findSlowness( ea )
                        elif t == 1:
                            slowness = findSlowness( eb )
                        else:
                            slowness = c.attribute()

                        ttimeA = ( ta               + slowness * a.pos().distance( node.pos() ) )
                        ttimeQ = ( ta + t*(tb-ta) ) + slowness * line( t ).distance( node.pos() )
                        ttimeB = ( tb               + slowness * b.pos().distance( node.pos() ) )

                        heapq.heappush( upCandidate, (min(ttimeA,ttimeQ,ttimeB), node ) )

    #for c in upCandidate:
        #print c[1].id(), c[0]
    candidate = heapq.heappop( upCandidate )
    #print candidate
    newUpNode = candidate[1]
    times[ newUpNode.id() ] = candidate[0]
    upTags[ newUpNode.id() ] = 1
    #print newUpNode
    downwind.remove( newUpNode )

    newDownNodes = pg.commonNodes( newUpNode.cellSet() )
    for nn in newDownNodes:
        if not upTags[ nn.id() ] and not downTags[ nn.id() ]:
            downwind.add( nn )
            downTags[ nn.id() ] = 1
Exemple #5
0
def fastMarch(mesh, downwind, times, upT, downT):
    """Do one front marching."""
    upCandidate = []

    for node in downwind:
        neighNodes = pg.commonNodes(node.cellSet())

        upNodes = []
        for n in neighNodes:
            if upT[n.id()]:
                upNodes.append(n)

        if len(upNodes) == 1:  # the Dijkstra case
            edge = pg.findBoundary(upNodes[0], node)

            if edge is None:
                continue
                raise StandardError("no edge found")

            tt = times[upNodes[0].id()] + \
                findSlowness(edge) * edge.shape().domainSize()
            # use node id additionally in case of equal travel times
            heapq.heappush(upCandidate, (tt, node.id(), node))
        else:
            cells = node.cellSet()
            for c in cells:
                for i in range(c.nodeCount()):
                    edge = pg.findBoundary(c.node(i),
                                           c.node((i + 1) % c.nodeCount()))

                    a = edge.node(0)
                    b = edge.node(1)
                    ta = times[a.id()]
                    tb = times[b.id()]

                    if upT[a.id()] and upT[b.id()]:
                        line = pg.Line(a.pos(), b.pos())
                        t = min(1., max(0., line.nearest(node.pos())))

                        ea = pg.findBoundary(a, node)
                        eb = pg.findBoundary(b, node)

                        #if ea is None or eb is None:
                        #print(a, b, node)

                        if t == 0:
                            slowness = findSlowness(ea)
                        elif t == 1:
                            slowness = findSlowness(eb)
                        else:
                            slowness = c.attribute()

                        ttimeA = (ta + slowness * a.pos().distance(node.pos()))
                        ttimeQ = (ta + t * (tb - ta)) + \
                            slowness * line(t).distance(node.pos())
                        ttimeB = (tb + slowness * b.pos().distance(node.pos()))
                        tmin = min(ttimeA, ttimeQ, ttimeB)
                        heapq.heappush(upCandidate, (tmin, node.id(), node))

    candidate = heapq.heappop(upCandidate)
    newUpNode = candidate[2]  # original
    times[newUpNode.id()] = candidate[0]
    upT[newUpNode.id()] = 1
    downwind.remove(newUpNode)
    newDownNodes = pg.commonNodes(newUpNode.cellSet())
    #    newUpNodeId = candidate[1]  # original
    #    times[newUpNodeId] = candidate[0]
    #    upT[newUpNodeId] = 1
    #    downwind.remove(newUpNodeId)
    #    newDownNodes = pg.commonNodes(mesh.node(newUpNodeId).cellSet())
    for nn in newDownNodes:
        if not upT[nn.id()] and not downT[nn.id()]:
            downwind.add(nn)
            downT[nn.id()] = 1
Exemple #6
0
    def computeTravelTimes(self, slowness, calcOthers=False):
        """Compute the travel times and fill data and time matrix
        for later use of response and Jacobian, respectively.
        For response only active sources are needed, for Jacobian all.
        """
        mesh = self.mesh()
        nNodes = mesh.nodeCount()
        midPoints = self.mesh().cellCenters()
        param_markers = np.unique(mesh.cellMarkers())
        param_count = len(param_markers)
        data = self.data()
        if len(slowness) == mesh.cellCount():
            mesh.setCellAttributes(slowness)
            # self.mapModel(slowness)
        elif len(slowness) == param_count:
            # map the regions in the mesh to slowness
            slow_map = pg.stdMapF_F()
            min_reg_num = min(param_markers)
            for i, si in enumerate(slowness):
                slow_map.insert(float(i + min_reg_num), si)

            mesh.mapCellAttributes(slow_map)
        else:
            raise ValueError("Wrong no of parameters. Mesh size: {}, no "
                             "of regions: {}, and number of slowness values:"
                             "{}".format(mesh.cellCount(), param_count,
                                         len(slowness)))

        times = pg.RVector(nNodes, 0.)
        upTags = np.zeros(nNodes)
        downTags = np.zeros(nNodes)
        sourceIndices = np.unique(data("s"))
        if calcOthers:
            ns = len(sourceIndices)
            geophoneIndices = np.setxor1d(np.arange(data.sensorCount()),
                                          sourceIndices)
            sourceIndices = geophoneIndices
            #            geophoneIndices = np.unique(data("g"))
            if self.debug:
                print("{:d}-{:d}={:d}".format(data.sensorCount(), ns,
                                              len(sourceIndices)))


#        if self.debug:  # resize not working
#            self.solution().resize(self.mesh().nodeCount(), self.nSensors)
#            print(self.solution().rows(), self.solution().cols())
        for iSource in np.array(sourceIndices, dtype=int):
            if self.debug:
                print(iSource)
            # initial condition (reset vectors)
            times *= 0.0
            upTags *= 0
            downTags *= 0
            downwind = set()
            source = data.sensorPosition(int(iSource))
            cell = mesh.findCell(source)
            # fill in nodes around source using local smoothness
            for i, n in enumerate(cell.nodes()):
                times[n.id()] = cell.attribute() * n.pos().distance(source)
                upTags[n.id()] = 1
            for i, n in enumerate(cell.nodes()):
                tmpNodes = pg.commonNodes(n.cellSet())
                for nn in tmpNodes:
                    if not upTags[nn.id()] and not downTags[nn.id()]:
                        downwind.add(nn)
                        downTags[nn.id()] = 1

            while len(downwind) > 0:  # start fast marching
                fastMarch(mesh, downwind, times, upTags, downTags)

            self.dataMatrix[iSource] = pg.interpolate(
                mesh, times, destPos=data.sensorPositions())
            self.timeMatrix[iSource] = pg.interpolate(mesh,
                                                      times,
                                                      destPos=midPoints)

            if self.debug:
                print(self.solution().rows(), self.solution().cols())
                print(len(times), self.mesh())
                self.solution()[int(iSource)] = times
                self.solution().setCol(int(iSource), times)
    def response(self, slowness):
        """
        Response function. Returns the result of the forward calculation.
        Uses the shot- and sensor positions specified in the data container.
        """

        mesh = self.mesh()
        param_markers = np.unique(mesh.cellMarker())
        param_count = len(param_markers)
        if len(slowness) == mesh.cellCount():
            self.mapModel(slowness)
        elif len(slowness) == param_count:
            # map the regions in the mesh to slowness
            slow_map = pg.stdMapF_F()
            min_reg_num = min(param_markers)
            for i, si in enumerate(slowness):
                slow_map.insert(float(i+min_reg_num), si)

            mesh.mapCellAttributes(slow_map)
        else:
            raise ValueError("Wrong no of parameters. Mesh size: {}, no "
                             "of regions: {}, and number of slowness values:"
                             "{}".format(self.mesh().cellCount(), param_count,
                                         len(slowness)))

        data = self.data()
        n_data = data.size()
        t_fmm = np.zeros(n_data)
        idx = 0
        for source_idx in [0]:  # np.unique(data("s")):
            # initialize source position and trvel time vector
            n_sensors = np.sum(data("s") == source_idx)
            # maybe not always same number of sensors
            source = data.sensorPosition(int(source_idx))
            times = pg.RVector(mesh.nodeCount(), 0.)

            # initialize sets and tags
#            upwind, downwind = set(), set()
            downwind = set()
            upTags = np.zeros(mesh.nodeCount())
            downTags = np.zeros(mesh.nodeCount())

            # define initial condition
            cell = mesh.findCell(source)

            for i, n in enumerate(cell.nodes()):
                times[n.id()] = cell.attribute() * n.pos().distance(source)
                upTags[n.id()] = 1
            for i, n in enumerate(cell.nodes()):
                tmpNodes = pg.commonNodes(n.cellSet())
                for nn in tmpNodes:
                    if not upTags[nn.id()] and not downTags[nn.id()]:
                        downwind.add(nn)
                        downTags[nn.id()] = 1

            # start fast marching
            while len(downwind) > 0:
                fastMarch(mesh, downwind, times, upTags, downTags)
            self.timefields[source_idx] = np.array(times)

            sensor_idx = data("g")[data("s") == source_idx]

            t_fmm[idx:idx+n_sensors] = np.array(
                [times[mesh.findNearestNode(data.sensorPosition(int(i)))]
                 for i in sensor_idx])
            idx += n_sensors

        return t_fmm
def fastMarch(mesh, downwind, times, upT, downT):
    """WRITEME."""
    upCandidate = []
#    print('.', end='')

    for node in downwind:
        neighNodes = pg.commonNodes(node.cellSet())

        upNodes = []
        for n in neighNodes:
            if upT[n.id()]:
                upNodes.append(n)

        if len(upNodes) == 1:  # the Dijkstra case
            edge = pg.findBoundary(upNodes[0], node)
            tt = times[upNodes[0].id()] + \
                findSlowness(edge) * edge.shape().domainSize()

            heapq.heappush(upCandidate, (tt, node))
        else:
            cells = node.cellSet()
            for c in cells:
                for i in range(c.nodeCount()):
                    edge = pg.findBoundary(c.node(i), c.node((i + 1) % 3))

                    a = edge.node(0)
                    b = edge.node(1)
                    ta = times[a.id()]
                    tb = times[b.id()]

                    if upT[a.id()] and upT[b.id()]:
                        line = pg.Line(a.pos(), b.pos())
                        t = min(1., max(0., line.nearest(node.pos())))

                        ea = pg.findBoundary(a, node)
                        eb = pg.findBoundary(b, node)

                        if t == 0:
                            slowness = findSlowness(ea)
                        elif t == 1:
                            slowness = findSlowness(eb)
                        else:
                            slowness = c.attribute()

                        ttimeA = (ta + slowness * a.pos().distance(node.pos()))
                        ttimeQ = (ta + t * (tb - ta)) + \
                            slowness * line(t).distance(node.pos())
                        ttimeB = (tb + slowness * b.pos().distance(node.pos()))

                        heapq.heappush(upCandidate,
                                       (min(ttimeA, ttimeQ, ttimeB), node))

    # for c in upCandidate:
        # print c[1].id(), c[0]
    candidate = heapq.heappop(upCandidate)
    # print candidate
    newUpNode = candidate[1]
    times[newUpNode.id()] = candidate[0]
    upT[newUpNode.id()] = 1
    # print newUpNode
    downwind.remove(newUpNode)

    newDownNodes = pg.commonNodes(newUpNode.cellSet())
    for nn in newDownNodes:
        if not upT[nn.id()] and not downT[nn.id()]:
            downwind.add(nn)
            downT[nn.id()] = 1
def test():
    """WRITEME."""
    mesh = pg.Mesh('mesh/test2d')
    mesh.createNeighbourInfos()

    print(mesh)

    source = pg.RVector3(-80, 0.)
    times = pg.RVector(mesh.nodeCount(), 0.)

    for c in mesh.cells():
        if c.marker() == 1:
            c.setAttribute(1.)
        elif c.marker() == 2:
            c.setAttribute(0.5)
        # c.setAttribute(abs(1./c.center()[1]))

    fig = plt.figure()
    ax = fig.subplot(1, 1, 1)

    anaTimes = pg.RVector(mesh.nodeCount(), 0.0)

    for n in mesh.nodes():
        anaTimes[n.id()] = source.distance(n.pos())

    # d = pg.DataContainer()
    # dijk = pg.TravelTimeDijkstraModelling(mesh, d)

    # upwind = set()
    downwind = set()
    upTags = np.zeros(mesh.nodeCount())
    downTags = np.zeros(mesh.nodeCount())

    # define initial condition
    cell = mesh.findCell(source)

    for n in cell.nodes():
        times[n.id()] = cell.attribute() * n.pos().distance(source)
        upTags[n.id()] = 1

    for n in cell.nodes():
        tmpNodes = pg.commonNodes(n.cellSet())
        for nn in tmpNodes:
            if not upTags[nn.id()] and not downTags[nn.id()]:
                downwind.add(nn)
                downTags[nn.id()] = 1

    # start fast marching
    tic = time.time()
    while len(downwind) > 0:
        # model = pg.RVector(mesh.cellCount(), 0.0)

        # for c in upwind: model.setVal(2, c.id())
        # for c in downwind: model.setVal(1, c.id())
        # drawMesh(a, mesh)

        # a.plot(source[0], source[1], 'x')

        # for c in mesh.cells():
        # a.text(c.center()[0],c.center()[1], str(c.id()))

        # for n in mesh.nodes():
        # if upTags[n.id()]:
        # a.plot(n.pos()[0], n.pos()[1], 'o', color='black')

        # mindist = 9e99
        # for n in downwind:
        # a.plot(n.pos()[0], n.pos()[1], 'o', color='white')

        # if n.pos().distance(source) < mindist:
        # mindist = n.pos().distance(source)
        # nextPredict = n

        # print "next predicted ", n.id(), mindist
        # a.plot(nextPredict.pos()[0], nextPredict.pos()[1],
        # 'o', color='green')

        # drawField(a, mesh, times)
        # drawField(a, mesh, anaTimes, colors = 'white')
        # a.figure.canvas.draw()

        # a.figure.show()
        # raw_input('Press Enter...')
        # a.clear()

        fastMarch(mesh, downwind, times, upTags, downTags)

    print(time.time() - tic, "s")

    drawMesh(ax, mesh)
    drawField(ax, mesh, times, filled=True)
mesh.mapCellAttributes(slomap)  # map values to attributes using map

###############################################################################
# We initialize the source position and the travel time vector
# initialize sets and tags and define the initial condition.
source = pg.RVector3(0., 0.)  # does not have to be a node!
times = pg.RVector(mesh.nodeCount(), 0.)
upwind, downwind = set(), set()
upTags, downTags = np.zeros(mesh.nodeCount()), np.zeros(mesh.nodeCount())
cell = mesh.findCell(source)
for i, n in enumerate(cell.nodes()):
    times[n.id()] = cell.attribute() * n.pos().distance(source)
    upTags[n.id()] = 1
for i, n in enumerate(cell.nodes()):
    tmpNodes = pg.commonNodes(n.cellSet())
    for nn in tmpNodes:
        if not upTags[nn.id()] and not downTags[nn.id()]:
            downwind.add(nn)
            downTags[nn.id()] = 1

###############################################################################
# Then we start marching until all fields are filled.
tic = time.time()
while len(downwind) > 0:
    fastMarch(mesh, downwind, times, upTags, downTags)

print(time.time() - tic, "s")

###############################################################################
# First, we plot the traveltime field and streamlines
Exemple #11
0
def fastMarch(mesh, downwind, times, upT, downT):
    """Do one front marching."""
    upCandidate = []

    for node in downwind:
        neighNodes = pg.commonNodes(node.cellSet())

        upNodes = []
        for n in neighNodes:
            if upT[n.id()]:
                upNodes.append(n)

        if len(upNodes) == 1:  # the Dijkstra case
            edge = pg.findBoundary(upNodes[0], node)

            if edge is None:
                continue
                raise StandardError("no edge found")

            tt = times[upNodes[0].id()] + \
                findSlowness(edge) * edge.shape().domainSize()
            # use node id additionally in case of equal travel times
            heapq.heappush(upCandidate, (tt, node.id(), node))
        else:
            cells = node.cellSet()
            for c in cells:
                for i in range(c.nodeCount()):
                    edge = pg.findBoundary(c.node(i), c.node((i + 1) % c.nodeCount()))

                    a = edge.node(0)
                    b = edge.node(1)
                    ta = times[a.id()]
                    tb = times[b.id()]

                    if upT[a.id()] and upT[b.id()]:
                        line = pg.Line(a.pos(), b.pos())
                        t = min(1., max(0., line.nearest(node.pos())))

                        ea = pg.findBoundary(a, node)
                        eb = pg.findBoundary(b, node)

                        #if ea is None or eb is None:
                            #print(a, b, node)

                        if t == 0:
                            slowness = findSlowness(ea)
                        elif t == 1:
                            slowness = findSlowness(eb)
                        else:
                            slowness = c.attribute()

                        ttimeA = (ta + slowness * a.pos().distance(node.pos()))
                        ttimeQ = (ta + t * (tb - ta)) + \
                            slowness * line(t).distance(node.pos())
                        ttimeB = (tb + slowness * b.pos().distance(node.pos()))
                        tmin = min(ttimeA, ttimeQ, ttimeB)
                        heapq.heappush(upCandidate, (tmin, node.id(), node))

    candidate = heapq.heappop(upCandidate)
    newUpNode = candidate[2]  # original
    times[newUpNode.id()] = candidate[0]
    upT[newUpNode.id()] = 1
    downwind.remove(newUpNode)
    newDownNodes = pg.commonNodes(newUpNode.cellSet())
#    newUpNodeId = candidate[1]  # original
#    times[newUpNodeId] = candidate[0]
#    upT[newUpNodeId] = 1
#    downwind.remove(newUpNodeId)
#    newDownNodes = pg.commonNodes(mesh.node(newUpNodeId).cellSet())
    for nn in newDownNodes:
        if not upT[nn.id()] and not downT[nn.id()]:
            downwind.add(nn)
            downT[nn.id()] = 1
Exemple #12
0
    def computeTravelTimes(self, slowness, calcOthers=False):
        """Compute the travel times and fill data and time matrix
        for later use of response and Jacobian, respectively.
        For response only active sources are needed, for Jacobian all.
        """
        mesh = self.mesh()
        nNodes = mesh.nodeCount()
        midPoints = self.mesh().cellCenters()
        param_markers = np.unique(mesh.cellMarkers())
        param_count = len(param_markers)
        data = self.data()
        if len(slowness) == mesh.cellCount():
            mesh.setCellAttributes(slowness)
            # self.mapModel(slowness)
        elif len(slowness) == param_count:
            # map the regions in the mesh to slowness
            slow_map = pg.stdMapF_F()
            min_reg_num = min(param_markers)
            for i, si in enumerate(slowness):
                slow_map.insert(float(i+min_reg_num), si)

            mesh.mapCellAttributes(slow_map)
        else:
            raise ValueError("Wrong no of parameters. Mesh size: {}, no "
                             "of regions: {}, and number of slowness values:"
                             "{}".format(mesh.cellCount(), param_count,
                                         len(slowness)))

        times = pg.RVector(nNodes, 0.)
        upTags = np.zeros(nNodes)
        downTags = np.zeros(nNodes)
        sourceIndices = np.unique(data("s"))
        if calcOthers:
            ns = len(sourceIndices)
            geophoneIndices = np.setxor1d(np.arange(data.sensorCount()),
                                          sourceIndices)
            sourceIndices = geophoneIndices
#            geophoneIndices = np.unique(data("g"))
            if self.debug:
                print("{:d}-{:d}={:d}".format(
                    data.sensorCount(), ns, len(sourceIndices)))
#        if self.debug:  # resize not working
#            self.solution().resize(self.mesh().nodeCount(), self.nSensors)
#            print(self.solution().rows(), self.solution().cols())
        for iSource in np.array(sourceIndices, dtype=int):
            if self.debug:
                print(iSource)
            # initial condition (reset vectors)
            times *= 0.0
            upTags *= 0
            downTags *= 0
            downwind = set()
            source = data.sensorPosition(int(iSource))
            cell = mesh.findCell(source)
            # fill in nodes around source using local smoothness
            for i, n in enumerate(cell.nodes()):
                times[n.id()] = cell.attribute() * n.pos().distance(source)
                upTags[n.id()] = 1
            for i, n in enumerate(cell.nodes()):
                tmpNodes = pg.commonNodes(n.cellSet())
                for nn in tmpNodes:
                    if not upTags[nn.id()] and not downTags[nn.id()]:
                        downwind.add(nn)
                        downTags[nn.id()] = 1

            while len(downwind) > 0:  # start fast marching
                fastMarch(mesh, downwind, times, upTags, downTags)

            self.dataMatrix[iSource] = pg.interpolate(
                mesh, times, destPos=data.sensorPositions())
            self.timeMatrix[iSource] = pg.interpolate(
                mesh, times, destPos=midPoints)

            if self.debug:
                print(self.solution().rows(), self.solution().cols())
                print(len(times), self.mesh())
                self.solution()[int(iSource)] = times
                self.solution().setCol(int(iSource), times)