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_ 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 = 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]
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.) tdirect = x / v[0] # direct wave alfa = asin(v[0] / v[1]) # critically refracted wave angle xreflec = tan(alfa) * zlay * 2. # first critically refracted trefrac = (x - xreflec) / v[1] + xreflec * v[1] / v[0]**2 tana = np.where(trefrac < tdirect, trefrac, tdirect) # minimum of both print("min(dt)=", min(t - tana) * 1000, "ms max(dt)=", max(t - tana) * 1000,
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
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, x, x * 0., x * 0.) tdirect = x / v[0] # direct wave alfa = asin(v[0] / v[1]) # critically refracted wave angle xreflec = tan(alfa) * zlay * 2. # first critically refracted trefrac = (x - xreflec) / v[1] + xreflec * v[1] / v[0]**2 tana = np.where(trefrac < tdirect, trefrac, tdirect) # minimum of both print("min(dt)=", min(t - tana) * 1000, "ms max(dt)=", max(t - tana) * 1000, "ms")