def _compute_traveltime(vel: np.ndarray, SouPos: np.ndarray, RecPos: np.ndarray, dx: float, dz: float, data: np.ndarray, ishot: int): """Function to compute traveltimes by solving Eikonal equation""" nRec = RecPos.shape[0] velocity = pykonal.fields.ScalarField3D(coord_sys="cartesian") velocity.min_coords = 0.0, 0.0, 0.0 velocity.node_intervals = 1.0, dx, dz velocity.npts = 1, vel.shape[0], vel.shape[1] # Set Eikonal solver solver_ek = pykonal.EikonalSolver(coord_sys="cartesian") solver_ek.vv.min_coords = velocity.min_coords solver_ek.vv.node_intervals = velocity.node_intervals solver_ek.vv.npts = velocity.npts solver_ek.vv.values[:] = vel # Initial conditions solver_ek.tt.values[:] = np.inf solver_ek.known[:] = False solver_ek.unknown[:] = True # Source location initial conditions eq_iz = SouPos[ishot, 1] eq_iy = 0 eq_ix = SouPos[ishot, 0] src_idx = (eq_iy, eq_ix, eq_iz) solver_ek.tt.values[src_idx] = 0.0 solver_ek.unknown[src_idx] = False solver_ek.trial.push(*src_idx) solver_ek.solve() for iRec in range(nRec): data[iRec] += solver_ek.tt.values[0, RecPos[iRec, 0], RecPos[iRec, 1]] return data, solver_ek.tt.values[0, :, :]
def calc_refl(velocity, shotloc_x, shotloc_z, layer_idxs): """calculate the reflection tt in velocity grid with given shotloc off layer_idxs velocity is a pykonal velocity obj shotloc_[xz] are positions relative to velocity.min_coords layer_idxs is an array of depth indices (z) for each x node that denotes the reflection surface """ solver_dg = pykonal.EikonalSolver(coord_sys="cartesian") solver_dg.vv.min_coords = velocity.min_coords solver_dg.vv.node_intervals = velocity.node_intervals solver_dg.vv.npts = velocity.npts solver_dg.vv.values = velocity.values #shotloc = 2.56 # km src_idx = (int( (shotloc_x - velocity.min_coords[0]) / velocity.node_intervals[0]), int(shotloc_z / velocity.node_intervals[1]), 0) solver_dg.tt.values[src_idx] = 0 solver_dg.unknown[src_idx] = False solver_dg.trial.push(*src_idx) solver_dg.solve() solver_ug = pykonal.EikonalSolver(coord_sys="cartesian") solver_ug.vv.min_coords = solver_dg.vv.min_coords solver_ug.vv.node_intervals = solver_dg.vv.node_intervals solver_ug.vv.npts = solver_dg.vv.npts solver_ug.vv.values = solver_dg.vv.values for ix in range(solver_ug.tt.npts[0]): #idx = (ix, solver_ug.tt.npts[1]-1, 0) idx = (ix, layer_idxs[ix], 0) solver_ug.tt.values[idx] = solver_dg.tt.values[idx] #print(idx, solver_dg.tt.values[idx]) solver_ug.unknown[idx] = False solver_ug.trial.push(*idx) solver_ug.solve() ofs = np.linspace(solver_ug.tt.min_coords[0] - shotloc_x, solver_ug.tt.max_coords[0] - shotloc_x, num=solver_ug.tt.npts[0], endpoint=True) return ofs, solver_ug.tt.values[:, 0, 0]
def test_uniform_velocity_cartesian(self): fname = pkg_resources.resource_filename( 'pykonal', os.path.join('pykonal', 'tests', 'data', 'test_EikonalSolver_uniform_velocity_cartesian.npz')) solver = pykonal.EikonalSolver() with np.load(fname) as inf: uu = inf['uu'] solver.vgrid.min_coords = inf['vgrid_min_coords'] solver.vgrid.node_intervals = inf['vgrid_node_intervals'] solver.vgrid.npts = inf['vgrid_npts'] solver.vv = inf['vv'] solver.pgrid.min_coords = inf['pgrid_min_coords'] solver.pgrid.node_intervals = inf['pgrid_node_intervals'] solver.pgrid.npts = inf['pgrid_npts'] solver.add_source(inf['src']) solver.solve() np.testing.assert_array_almost_equal(uu, solver.uu)
def __init__(self, min_coords, intervals, ngrids, sources): """ The order of coordinate is x, z, y """ if len(min_coords) == 2: min_coords = [min_coords[0], min_coords[1], 0] if len(intervals) == 2: intervals = [intervals[0], intervals[1], 1] if len(ngrids) == 2: ngrids = [ngrids[0], ngrids[1], 1] self.min_coords = min_coords self.intervals = intervals self.ngrids = ngrids self.solver_tomo = pykonal.EikonalSolver() self.solver_tomo.vgrid.min_coords = min_coords self.solver_tomo.vgrid.node_intervals = intervals self.solver_tomo.vgrid.npts = ngrids self.solver_tomo.pgrid.min_coords = min_coords self.solver_tomo.pgrid.node_intervals = intervals self.solver_tomo.pgrid.npts = ngrids self.sources = sources
def checker_board_raw_data(self, outfname, wlon=1., wlat=1., v0=3.25, dv=0.25, sigma=5.): outdset = h5py.File(outfname, mode='a') #======================= # synthetic input model #======================= lon_npts = int(180 / (self.dlon)) lat_npts = int(180 / (self.dlat)) solver = pykonal.EikonalSolver(coord_sys="spherical") solver.velocity.min_coords = 6371., 0, 0 solver.velocity.node_intervals = 1, np.pi / lat_npts, np.pi / lon_npts solver.velocity.npts = 1, (lat_npts + 1), 2 * lon_npts lonlats = solver.velocity.nodes / np.pi * 180. lonlats[:, :, :, 1] = 90. - lonlats[:, :, :, 1] vlats = lonlats[0, :, 1, 1] vlons = lonlats[0, 1, :, 2] v0_arr = np.ones((1, lat_npts + 1, 2 * lon_npts)) * v0 vel_arr = v0_arr.copy() for ilon in range(2 * lon_npts): for ilat in range(lat_npts + 1): lat = lonlats[0, ilat, ilon, 1] lon = lonlats[0, ilat, ilon, 2] if lat <=self.maxlat and lat >= self.minlat \ and lon <=self.maxlon and lon >= self.minlon: tmplat = (int(np.floor((lat - self.minlat) / wlat)) % 2) tmplon = (int(np.floor((lon - self.minlon) / wlon)) % 2) clat = np.floor((lat - self.minlat) / wlat) * wlat + self.minlat + wlat / 2. clon = np.floor((lon - self.minlon) / wlon) * wlon + self.minlon + wlon / 2. if tmplon == tmplat: vel_arr[0, ilat, ilon] -= dv else: vel_arr[0, ilat, ilon] += dv vel_arr[0, :, :] = gaussian_filter(vel_arr[0, :, :], sigma=sigma) # save input model vel_grp = outdset.require_group(name='tomo_stack_0') vel_per_grp = vel_grp.create_group(name='10_sec') ind_vel_lat = np.where( (vlats >= self.minlat - 0.001) * (vlats <= self.maxlat + 0.001))[0] ind_vel_lon = np.where( (vlons >= self.minlon - 0.001) * (vlons <= self.maxlon + 0.001))[0] input_vel = ((vel_arr[0, ind_vel_lat, :])[:, ind_vel_lon]) ### # ind1 = input_vel > v0 # ind2 = input_vel < v0 # input_vel[ind1] = v0 - (input_vel[ind1] - v0) # input_vel[ind2] = v0 + (v0 - input_vel[ind2]) ### # # # vel_per_grp.create_dataset(name = 'input_velocity', data = input_vel) self.update_attrs() # create group for input data group = outdset.require_group(name='input_field_data') ingrp = self['input_field_data'] group.attrs.create(name='channel', data=ingrp.attrs['channel']) #--------------------------------- # get stations (virtual events) #--------------------------------- # loop over periods for per in self.pers: print('--- generating data for: ' + str(per) + ' sec') del_per = per - int(per) if del_per == 0.: per_name = str(int(per)) + 'sec' else: dper = str(del_per) per_name = str(int(per)) + 'sec' + dper.split('.')[1] in_per_grp = ingrp['%g_sec' % per] per_group = group.require_group(name='%g_sec' % per) # loop over events for evid in in_per_grp.keys(): in_evgrp = in_per_grp[evid] in_evla = in_evgrp.attrs['evla'] in_evlo = in_evgrp.attrs['evlo'] if in_evlo < 0.: in_evlo += 360. evlo = np.round(in_evlo / self.dlon) * self.dlon evla = np.round(in_evla / self.dlat) * self.dlat print('Event ' + evid, in_evla, evla, in_evlo, evlo) ### # eikonal solver ### solver = pykonal.EikonalSolver(coord_sys="spherical") solver.velocity.min_coords = 6371., 0, 0 solver.velocity.node_intervals = 1, np.pi / lat_npts, np.pi / lon_npts solver.velocity.npts = 1, (lat_npts + 1), 2 * lon_npts lonlats = solver.velocity.nodes / np.pi * 180. lonlats[:, :, :, 1] = 90. - lonlats[:, :, :, 1] solver.velocity.values = vel_arr # solve ind_evlo = int(np.round(in_evlo / self.dlon)) ind_evla = int(np.round(in_evla / self.dlat)) src_idx = (0, ind_evla, ind_evlo) solver.traveltime.values[src_idx] = 0 solver.unknown[src_idx] = False solver.trial.push(*src_idx) solver.solve() ### tmplats = lonlats[0, :, 1, 1] tmplons = lonlats[0, 1, :, 2] ind_out_lat = np.where( (tmplats >= self.minlat) * (tmplats <= self.maxlat))[0] ind_out_lon = np.where( (tmplons >= self.minlon) * (tmplons <= self.maxlon))[0] Nsize = ind_out_lon.size * ind_out_lat.size lats = ((lonlats[0, ind_out_lat, :, 1])[:, ind_out_lon]).reshape(Nsize) lons = ((lonlats[0, ind_out_lat, :, 2])[:, ind_out_lon]).reshape(Nsize) travel_t = ((solver.traveltime.values[0, ind_out_lat, :] )[:, ind_out_lon]).reshape(Nsize) # index_valid = travel_t != 0. travel_t = travel_t[index_valid] lons = lons[index_valid] lats = lats[index_valid] Nsize = lons.size # save data to hdf5 dataset event_group = per_group.create_group(name=evid) event_group.attrs.create(name='evlo', data=evlo) event_group.attrs.create(name='evla', data=evla) event_group.attrs.create(name='raw_num_data_points', data=Nsize) event_group.create_dataset(name='raw_lons', data=lons) event_group.create_dataset(name='raw_lats', data=lats) event_group.create_dataset(name='raw_travel_time', data=travel_t) event_group.create_dataset(name='raw_snr', data=np.ones(Nsize) * 20.) try: index_borrow = in_evgrp['index_borrow'][()] event_group.create_dataset(name='index_borrow', data=index_borrow) except: pass return
def checker_board_data_2(self, outfname, wlon=1., wlat=1., v0=3.25, dv=0.25, cdist=50.): outdset = h5py.File(outfname, mode='a') #======================= # synthetic input model #======================= solver = pykonal.EikonalSolver(coord_sys="spherical") solver.velocity.min_coords = 6371., 0, 0 solver.velocity.node_intervals = 1, np.pi / 1800, np.pi / 1800 solver.velocity.npts = 1, 1801, 3600 lonlats = solver.velocity.nodes / np.pi * 180. lonlats[:, :, :, 1] = 90. - lonlats[:, :, :, 1] vlats = lonlats[0, :, 1, 1] vlons = lonlats[0, 1, :, 2] v0_arr = np.ones((1, 1801, 3600)) * v0 vel_arr = v0_arr.copy() for ilon in range(3600): for ilat in range(1801): lat = lonlats[0, ilat, ilon, 1] lon = lonlats[0, ilat, ilon, 2] if lat <=self.maxlat and lat >= self.minlat \ and lon <=self.maxlon and lon >= self.minlon: tmplat = (int(np.floor((lat - self.minlat) / wlat)) % 2) tmplon = (int(np.floor((lon - self.minlon) / wlon)) % 2) clat = np.floor((lat - self.minlat) / wlat) * wlat + self.minlat + wlat / 2. clon = np.floor((lon - self.minlon) / wlon) * wlon + self.minlon + wlon / 2. dist, az, baz = obspy.geodetics.gps2dist_azimuth( lat, lon, clat, clon) dist /= 1000. if dist >= cdist: continue if tmplon == tmplat: vel_arr[0, ilat, ilon] -= dv * ( 1. + np.cos(np.pi / cdist * dist)) / 2. else: vel_arr[0, ilat, ilon] += dv * ( 1. + np.cos(np.pi / cdist * dist)) / 2. # save input model vel_grp = outdset.require_group(name='tomo_stack_0') vel_per_grp = vel_grp.create_group(name='10_sec') ind_vel_lat = np.where( (vlats >= self.minlat - 0.001) * (vlats <= self.maxlat + 0.001))[0] ind_vel_lon = np.where( (vlons >= self.minlon - 0.001) * (vlons <= self.maxlon + 0.001))[0] # # # # print (vlons[ind_vel_lon][0], vlons[ind_vel_lon][-1]) input_vel = ((vel_arr[0, ind_vel_lat, :])[:, ind_vel_lon]) vel_per_grp.create_dataset(name='input_velocity', data=input_vel) self.update_attrs() # create group for input data group = outdset.require_group(name='input_field_data') ingrp = self['input_field_data'] group.attrs.create(name='channel', data=ingrp.attrs['channel']) #--------------------------------- # get stations (virtual events) #--------------------------------- # loop over periods for per in self.pers: print('--- generating data for: ' + str(per) + ' sec') del_per = per - int(per) if del_per == 0.: per_name = str(int(per)) + 'sec' else: dper = str(del_per) per_name = str(int(per)) + 'sec' + dper.split('.')[1] in_per_grp = ingrp['%g_sec' % per] per_group = group.require_group(name='%g_sec' % per) # loop over events for evid in in_per_grp.keys(): in_evgrp = in_per_grp[evid] in_evla = in_evgrp.attrs['evla'] in_evlo = in_evgrp.attrs['evlo'] # if in_evlo < 0.: in_evlo += 360. evlo = np.round(in_evlo / self.dlon) * self.dlon evla = np.round(in_evla / self.dlat) * self.dlat print('Event ' + evid, in_evla, evla, in_evlo, evlo) ### # eikonal solver ### solver = pykonal.EikonalSolver(coord_sys="spherical") solver.velocity.min_coords = 6371., 0, 0 solver.velocity.node_intervals = 1, np.pi / 1800, np.pi / 1800 solver.velocity.npts = 1, 1801, 3600 lonlats = solver.velocity.nodes / np.pi * 180. lonlats[:, :, :, 1] = 90. - lonlats[:, :, :, 1] solver.velocity.values = vel_arr # solve ind_evlo = int(np.round(in_evlo / self.dlon)) ind_evla = int(np.round(in_evla / self.dlat)) src_idx = (0, ind_evla, ind_evlo) solver.traveltime.values[src_idx] = 0 solver.unknown[src_idx] = False solver.trial.push(*src_idx) solver.solve() ### tmplats = lonlats[0, :, 1, 1] tmplons = lonlats[0, 1, :, 2] ind_out_lat = np.where( (tmplats >= self.minlat) * (tmplats <= self.maxlat))[0] ind_out_lon = np.where( (tmplons >= self.minlon) * (tmplons <= self.maxlon))[0] Nsize = ind_out_lon.size * ind_out_lat.size lats = ((lonlats[0, ind_out_lat, :, 1])[:, ind_out_lon]).reshape(Nsize) lons = ((lonlats[0, ind_out_lat, :, 2])[:, ind_out_lon]).reshape(Nsize) travel_t = ((solver.traveltime.values[0, ind_out_lat, :] )[:, ind_out_lon]).reshape(Nsize) # index_valid = travel_t != 0. travel_t = travel_t[index_valid] lons = lons[index_valid] lats = lats[index_valid] Nsize = lons.size az, baz, dist = geodist.inv( np.ones(Nsize) * evlo, np.ones(Nsize) * evla, lons, lats) distance = dist / 1000. phase_velocity = distance / travel_t # save data to hdf5 dataset event_group = per_group.create_group(name=evid) event_group.attrs.create(name='evlo', data=evlo) event_group.attrs.create(name='evla', data=evla) event_group.attrs.create(name='num_data_points', data=Nsize) event_group.create_dataset(name='lons', data=lons) event_group.create_dataset(name='lats', data=lats) event_group.create_dataset(name='phase_velocity', data=phase_velocity) event_group.create_dataset(name='snr', data=np.ones(Nsize) * 20.) event_group.create_dataset(name='distance', data=distance) try: index_borrow = in_evgrp['index_borrow'][()] event_group.create_dataset(name='index_borrow', data=index_borrow) except: pass return
def get_input_vel(self, outfname, wlon=1., wlat=1., v0=3.25, dv=0.25, sigma=5., stadist=50.): outdset = h5py.File(outfname, mode='a') #======================= # synthetic input model #======================= lon_npts = int(180 / (self.dlon)) lat_npts = int(180 / (self.dlat)) solver = pykonal.EikonalSolver(coord_sys="spherical") solver.velocity.min_coords = 6371., 0, 0 solver.velocity.node_intervals = 1, np.pi / lat_npts, np.pi / lon_npts solver.velocity.npts = 1, (lat_npts + 1), 2 * lon_npts lonlats = solver.velocity.nodes / np.pi * 180. lonlats[:, :, :, 1] = 90. - lonlats[:, :, :, 1] vlats = lonlats[0, :, 1, 1] vlons = lonlats[0, 1, :, 2] v0_arr = np.ones((1, lat_npts + 1, 2 * lon_npts)) * v0 vel_arr = v0_arr.copy() for ilon in range(2 * lon_npts): for ilat in range(lat_npts + 1): lat = lonlats[0, ilat, ilon, 1] lon = lonlats[0, ilat, ilon, 2] if lat <=self.maxlat and lat >= self.minlat \ and lon <=self.maxlon and lon >= self.minlon: tmplat = (int(np.floor((lat - self.minlat) / wlat)) % 2) tmplon = (int(np.floor((lon - self.minlon) / wlon)) % 2) clat = np.floor((lat - self.minlat) / wlat) * wlat + self.minlat + wlat / 2. clon = np.floor((lon - self.minlon) / wlon) * wlon + self.minlon + wlon / 2. ########## if tmplon == tmplat: vel_arr[0, ilat, ilon] -= dv else: vel_arr[0, ilat, ilon] += dv vel_arr[0, :, :] = gaussian_filter(vel_arr[0, :, :], sigma=sigma) # save input model vel_grp = outdset.require_group(name='tomo_stack_0') vel_per_grp = vel_grp.create_group(name='10_sec') ind_vel_lat = np.where( (vlats >= self.minlat - 0.001) * (vlats <= self.maxlat + 0.001))[0] ind_vel_lon = np.where( (vlons >= self.minlon - 0.001) * (vlons <= self.maxlon + 0.001))[0] # # # # print (vlons[ind_vel_lon][0], vlons[ind_vel_lon][-1]) input_vel = ((vel_arr[0, ind_vel_lat, :])[:, ind_vel_lon]) ### ind1 = input_vel > v0 ind2 = input_vel < v0 input_vel[ind1] = v0 - (input_vel[ind1] - v0) input_vel[ind2] = v0 + (v0 - input_vel[ind2]) ### vel_per_grp.create_dataset(name='input_velocity', data=input_vel)
#m_s_km=[ 0.0, 150.0, 0.0] # cm/s/km #m_s_dp=[ 15, 24, 30] #m_s_km=[-112.5, 687.5, 0.0] # cm/s/km #m_s_dp=[ 15, 24, 30] #m_s_km=[ 307.5,-812.5, 0.0] # cm/s/km #m_s_dpB=[ 23, 24, 30] #m_s_kmB=[ 86.9,-702.0, 0.0] # cm/s/km #nlat,ndep,nlon=100,51,100#8000,8000,4000 #dlat,ddep,dlon=0.02,0.02,0.02 #slat,sdep,slon=50,50,50 #nlat,ndep,nlon=400,201,400#8000,8000,4000 #dlat,ddep,dlon=0.005,0.005,0.005 #slat,sdep,slon=200,200,200 #solverb = pykonal.EikonalSolver(coord_sys="cartesian") solverc = pykonal.EikonalSolver(coord_sys="cartesian") ########### base model #solverb.velocity.min_coords = 0, 0, 0 #solverb.velocity.node_intervals = dlat, ddep, dlon # This time we want a 3D computational grid, so set the number of grid nodes # in the z direction to 8 as well. #solverb.velocity.npts = nlat, ndep, nlon #solver.velocity.values = np.ones(solver.velocity.npts) #solver.velocity.values = np.full(solver.velocity.npts,1.480554) #solverb.velocity.values = np.array([[[1.480554] * nlon] * ndep] * nlat) svd = [[] for i in range(ndep)] for i in range(ndep): svd[i] = np.array([(sv.speed[i]+10.)*0.001] * nlon) svp = [svd[0]] for i in range(1,ndep):
##Initialize the solver. ##### ############################## slon1, sdep1, slat1 = slon, sdep, slat + asiz slon2, sdep2, slat2 = slon + asiz, sdep, slat slon3, sdep3, slat3 = slon, sdep, slat - asiz slon4, sdep4, slat4 = slon - asiz, sdep, slat ############################## tsv = 0. ai = 0 for i in range(1, ndep): tsv = tsv + float(sv.speed[i]) tov = np.arange(ndep) tsv = (tsv + (sv.speed[ndep] + sv.speed[0]) * 0.5) / float(ndep) tov = np.full(ndep, tsv, dtype="float64") solverb1 = pykonal.EikonalSolver(coord_sys="cartesian") solverc1 = pykonal.EikonalSolver(coord_sys="cartesian") solverb2 = pykonal.EikonalSolver(coord_sys="cartesian") solverc2 = pykonal.EikonalSolver(coord_sys="cartesian") solverb3 = pykonal.EikonalSolver(coord_sys="cartesian") solverc3 = pykonal.EikonalSolver(coord_sys="cartesian") solverb4 = pykonal.EikonalSolver(coord_sys="cartesian") solverc4 = pykonal.EikonalSolver(coord_sys="cartesian") ########### base model # This time we want a 3D computational grid, so set the number of grid nodes # in the z direction to 8 as well. solverb1.velocity.min_coords = 0, 0, 0 solverb1.velocity.node_intervals = dlon, ddep, dlat solverb1.velocity.npts = nlon, ndep, nlat solverb2.velocity.min_coords = 0, 0, 0
v2.node_intervals = d2.node_intervals = drho, dtheta, dphi v2.npts = d2.npts = nrho, ntheta, nphi v2.values = v2_new d2.values = d2_new velocity2 = v2 ### SRC_IDX = np.array([srh, sth, sph]) traveltime_fields = dict() traveltime2_fields = dict() for decimation_factor in range(7, -1, -1): decimation_factor = 2**decimation_factor vv = velocity.values[::decimation_factor, :, ::decimation_factor] solver = pykonal.EikonalSolver(coord_sys="spherical") solver.vv.min_coords = velocity.min_coords solver.vv.node_intervals = velocity.node_intervals * decimation_factor solver.vv.npts = vv.shape solver.vv.values = vv src_idx = tuple(SRC_IDX // decimation_factor - [1, 0, 1]) solver.traveltime.values[src_idx] = 0 solver.unknown[src_idx] = False solver.trial.push(*src_idx) solver.solve() traveltime_fields[decimation_factor] = solver.traveltime v2 = velocity2.values[::decimation_factor, :, ::decimation_factor] solver2 = pykonal.EikonalSolver(coord_sys="spherical") solver2.vv.min_coords = velocity2.min_coords solver2.vv.node_intervals = velocity2.node_intervals * decimation_factor
# In[262]: velocity = pykonal.fields.ScalarField3D(coord_sys="cartesian") velocity.min_coords = -2.56, 0, 0 velocity.node_intervals = 0.01, 0.001, 0.01 velocity.npts = 512, 1024, 1 #velocity.values = 3.8*np.ones(velocity.npts) #velocity.values[0:511,60:70] = 1.5 #velocity.values[0:511,71:127] = 4.5 velocity, icelay, waterlay = make_vel(velocity, 0.610, 0.55, 0.661, -4.2) #icelay = make_nodes(velocity, 0.61, 0) #waterlay = make_nodes(velocity, 0.655, -7, water=True) #scipy.ndimage.gaussian_filter(20. * np.random.randn(*velocity.npts) + 6., 10) solver_dg = pykonal.EikonalSolver(coord_sys="cartesian") solver_dg.vv.min_coords = velocity.min_coords solver_dg.vv.node_intervals = velocity.node_intervals solver_dg.vv.npts = velocity.npts solver_dg.vv.values = velocity.values shotloc_x = 2.56 # km shotloc_z = 0 src_idx = (int(shotloc_x / velocity.node_intervals[0]), int(shotloc_z / velocity.node_intervals[1]), 0) solver_dg.tt.values[src_idx] = 0 solver_dg.unknown[src_idx] = False solver_dg.trial.push(*src_idx) solver_dg.solve() solver_ug = pykonal.EikonalSolver(coord_sys="cartesian")