def tti_setup(shape=(50, 50, 50), spacing=(20.0, 20.0, 20.0), tn=250.0, space_order=4, nbpml=10, preset='layers-tti', **kwargs): nrec = 101 # Two layer model for true velocity model = demo_model(preset, shape=shape, spacing=spacing, nbpml=nbpml) # Source and receiver geometries src_coordinates = np.empty((1, len(spacing))) src_coordinates[0, :] = np.array(model.domain_size) * .5 if len(shape) > 1: src_coordinates[0, -1] = model.origin[-1] + 2 * spacing[-1] rec_coordinates = np.empty((nrec, len(spacing))) rec_coordinates[:, 0] = np.linspace(0., model.domain_size[0], num=nrec) if len(shape) > 1: rec_coordinates[:, 1] = np.array(model.domain_size)[1] * .5 rec_coordinates[:, -1] = model.origin[-1] + 2 * spacing[-1] geometry = AcquisitionGeometry(model, rec_coordinates, src_coordinates, t0=0.0, tn=tn, src_type='Ricker', f0=0.010) return AnisotropicWaveSolver(model, geometry, space_order=space_order, **kwargs)
def tti_operator(dse=False, space_order=4): nrec = 101 t0 = 0.0 tn = 250. nbpml = 10 shape = (50, 50, 50) spacing = (20., 20., 20.) # Two layer model for true velocity model = demo_model('layers-tti', ratio=3, nbpml=nbpml, shape=shape, spacing=spacing) # Derive timestepping from model spacing # Derive timestepping from model spacing dt = model.critical_dt nt = int(1 + (tn-t0) / dt) # Number of timesteps time_values = np.linspace(t0, tn, nt) # Discretized time axis # Define source geometry (center of domain, just below surface) src = GaborSource(name='src', grid=model.grid, f0=0.01, time=time_values) src.coordinates.data[0, :] = np.array(model.domain_size) * .5 src.coordinates.data[0, -1] = model.origin[-1] + 2 * spacing[-1] # Define receiver geometry (spread across x, lust below surface) rec = Receiver(name='nrec', grid=model.grid, ntime=nt, npoint=nrec) rec.coordinates.data[:, 0] = np.linspace(0., model.domain_size[0], num=nrec) rec.coordinates.data[:, 1:] = src.coordinates.data[0, 1:] return AnisotropicWaveSolver(model, source=src, receiver=rec, time_order=2, space_order=space_order, dse=dse)
def setup(dimensions=(50, 50, 50), spacing=(20.0, 20.0, 20.0), tn=250.0, time_order=2, space_order=4, nbpml=10, dse='advanced'): origin = (0., 0., 0.) # True velocity true_vp = np.ones(dimensions) + 1.0 true_vp[:, :, int(dimensions[0] / 3):int(2 * dimensions[0] / 3)] = 3.0 true_vp[:, :, int(2 * dimensions[0] / 3):int(dimensions[0])] = 4.0 model = Model(origin, spacing, dimensions, true_vp, nbpml=nbpml, epsilon=.4 * np.ones(dimensions), delta=-.1 * np.ones(dimensions), theta=-np.pi / 7 * np.ones(dimensions), phi=np.pi / 5 * np.ones(dimensions)) # Define seismic data. f0 = .010 dt = model.critical_dt t0 = 0.0 nt = int(1 + (tn - t0) / dt) # Set up the source as Ricker wavelet for f0 # Source geometry time_series = np.zeros((nt, 1)) time_series[:, 0] = source(np.linspace(t0, tn, nt), f0) location = np.zeros((1, 3)) location[0, 0] = origin[0] + dimensions[0] * spacing[0] * 0.5 location[0, 1] = origin[1] + dimensions[1] * spacing[1] * 0.5 location[0, 2] = origin[1] + 2 * spacing[2] src = PointSource(name='src', data=time_series, coordinates=location) # Receiver geometry receiver_coords = np.zeros((101, 3)) receiver_coords[:, 0] = np.linspace(0, origin[0] + dimensions[0] * spacing[0], num=101) receiver_coords[:, 1] = origin[1] + dimensions[1] * spacing[1] * 0.5 receiver_coords[:, 2] = location[0, 1] rec = Receiver(name='rec', ntime=nt, coordinates=receiver_coords) return AnisotropicWaveSolver(model, source=src, time_order=time_order, space_order=space_order, receiver=rec, dse=dse)
def test_tti_staggered(shape): spacing = [10. for _ in shape] nrec = 1 # Model model = demo_model('layers-tti', shape=shape, spacing=spacing) # Source and receiver geometries src_coordinates = np.empty((1, len(spacing))) src_coordinates[0, :] = np.array(model.domain_size) * .5 src_coordinates[0, -1] = model.origin[-1] + 2 * spacing[-1] rec_coordinates = np.empty((nrec, len(spacing))) rec_coordinates[:, 0] = np.linspace(0., model.domain_size[0], num=nrec) rec_coordinates[:, -1] = model.origin[-1] + 2 * spacing[-1] geometry = AcquisitionGeometry(model, rec_coordinates, src_coordinates, t0=0.0, tn=250., src_type='Ricker', f0=0.010) # Solvers solver_tti = AnisotropicWaveSolver(model, geometry, time_order=2, space_order=8) solver_tti2 = AnisotropicWaveSolver(model, geometry, time_order=2, space_order=8) # Solve configuration['dse'] = 'aggressive' configuration['dle'] = 'advanced' rec1, u1, v1, _ = solver_tti.forward(kernel='staggered') configuration['dle'] = 'basic' rec2, u2, v2, _ = solver_tti2.forward(kernel='staggered') res1 = np.linalg.norm(u1.data.reshape(-1) - u2.data.reshape(-1)) res2 = np.linalg.norm(v1.data.reshape(-1) - v2.data.reshape(-1)) log("DSE/DLE introduces error %2.4e, %2.4e in %d dimensions" % (res1, res2, len(shape))) assert np.isclose(res1, 0.0, atol=1e-8) assert np.isclose(res2, 0.0, atol=1e-8)
def tti_setup(shape=(50, 50, 50), spacing=(20.0, 20.0, 20.0), tn=250.0, space_order=4, nbl=10, preset='layers-tti', **kwargs): # Two layer model for true velocity model = demo_model(preset, shape=shape, spacing=spacing, space_order=space_order, nbl=nbl, **kwargs) # Source and receiver geometries geometry = setup_geometry(model, tn) return AnisotropicWaveSolver(model, geometry, space_order=space_order)
def overthrust_setup_tti(filename, tn=4000, space_order=2, nbpml=40, **kwargs): model = from_hdf5(filename, space_order=space_order, nbpml=nbpml, datakey='m0', dtype=np.float32) shape = model.vp.shape spacing = model.shape nrec = shape[0] # Derive timestepping from model spacing dt = model.critical_dt t0 = 0.0 time_range = TimeAxis(start=t0, stop=tn, step=dt) # Define source geometry (center of domain, just below surface) src = RickerSource(name='src', grid=model.grid, f0=0.015, time_range=time_range) src.coordinates.data[0, :] = np.array(model.domain_size) * .5 if len(shape) > 1: src.coordinates.data[0, -1] = model.origin[-1] + 2 * spacing[-1] # Define receiver geometry (spread across x, just below surface) rec = Receiver(name='rec', grid=model.grid, time_range=time_range, npoint=nrec) rec.coordinates.data[:, 0] = np.linspace(0., model.domain_size[0], num=nrec) if len(shape) > 1: rec.coordinates.data[:, 1:] = src.coordinates.data[0, 1:] # Create solver object to provide relevant operators return AnisotropicWaveSolver(model, source=src, receiver=rec, space_order=space_order, **kwargs)
def tti_setup(shape=(50, 50, 50), spacing=(20.0, 20.0, 20.0), tn=250.0, space_order=4, nbpml=10, preset='layers-tti', **kwargs): nrec = 101 # Two layer model for true velocity model = demo_model(preset, shape=shape, spacing=spacing, nbpml=nbpml) # Derive timestepping from model spacing dt = model.critical_dt t0 = 0.0 time_range = TimeAxis(start=t0, stop=tn, step=dt) # Define source geometry (center of domain, just below surface) src = RickerSource(name='src', grid=model.grid, f0=0.015, time_range=time_range) src.coordinates.data[0, :] = np.array(model.domain_size) * .5 src.coordinates.data[0, -1] = model.origin[-1] + 2 * spacing[-1] # Define receiver geometry (spread across x, lust below surface) rec = Receiver(name='nrec', grid=model.grid, time_range=time_range, npoint=nrec) rec.coordinates.data[:, 0] = np.linspace(0., model.domain_size[0], num=nrec) rec.coordinates.data[:, 1:] = src.coordinates.data[0, 1:] return AnisotropicWaveSolver(model, source=src, receiver=rec, space_order=space_order, **kwargs)
def tti_operator(dse=False, dle='advanced', space_order=4): nrec = 101 t0 = 0.0 tn = 250. nbpml = 10 shape = (50, 50, 50) spacing = (20., 20., 20.) # Two layer model for true velocity model = demo_model('layers-tti', ratio=3, nbpml=nbpml, space_order=space_order, shape=shape, spacing=spacing) # Source and receiver geometries src_coordinates = np.empty((1, len(spacing))) src_coordinates[0, :] = np.array(model.domain_size) * .5 src_coordinates[0, -1] = model.origin[-1] + 2 * spacing[-1] rec_coordinates = np.empty((nrec, len(spacing))) rec_coordinates[:, 0] = np.linspace(0., model.domain_size[0], num=nrec) rec_coordinates[:, 1:] = src_coordinates[0, 1:] geometry = AcquisitionGeometry(model, rec_coordinates, src_coordinates, t0=t0, tn=tn, src_type='Gabor', f0=0.010) return AnisotropicWaveSolver(model, geometry, space_order=space_order, dse=dse)
def test_tti(dimensions, space_order): nbpml = 10 ndim = len(dimensions) origin = tuple([0.] * ndim) spacing = tuple([10.] * ndim) # Velocity model, two layers true_vp = np.ones(dimensions) + .5 true_vp[..., int(dimensions[-1] / 3):dimensions[-1]] = 2.5 # Source location location = np.zeros((1, ndim), dtype=np.float32) location[0, :-1] = [ origin[i] + dimensions[i] * spacing[i] * .5 for i in range(ndim - 1) ] location[0, -1] = origin[-1] + 2 * spacing[-1] # Receivers locations receiver_coords = np.zeros((dimensions[0], ndim), dtype=np.float32) receiver_coords[:, 0] = np.linspace(0, origin[0] + (dimensions[0] - 1) * spacing[0], num=dimensions[0]) receiver_coords[:, 1:] = location[0, 1:] # True velocity true_vp = np.ones(dimensions) + .5 model = Model(origin, spacing, dimensions, true_vp, nbpml=nbpml, epsilon=0.0 * true_vp, delta=0.0 * true_vp, theta=0.0 * true_vp, phi=0.0 * true_vp) # Define seismic data. f0 = .010 dt = model.critical_dt t0 = 0.0 tn = 350.0 nt = int(1 + (tn - t0) / dt) last = (nt - 2) % 3 indlast = [(last + 1) % 3, last % 3, (last - 1) % 3] # Set up the source as Ricker wavelet for f0 def ricker_source(t, f0): r = (np.pi * f0 * (t - 1. / f0)) return (1 - 2. * r**2) * np.exp(-r**2) # Source geometry time_series = np.zeros((nt, 1)) time_series[:, 0] = ricker_source(np.linspace(t0, tn, nt), f0) # Adjoint test source = PointSource(name='src', data=time_series, coordinates=location) receiver = Receiver(name='rec', ntime=nt, coordinates=receiver_coords) acoustic = AcousticWaveSolver(model, source=source, receiver=receiver, time_order=2, space_order=space_order) rec, u1, _ = acoustic.forward(save=False) tn = 50.0 nt = int(1 + (tn - t0) / dt) # Source geometry time_series = np.zeros((nt, 1)) time_series[:, 0] = 0 * ricker_source(np.linspace(t0, tn, nt), f0) source = PointSource(name='src', data=time_series, coordinates=location) receiver = Receiver(name='rec', ntime=nt, coordinates=receiver_coords) acoustic = AcousticWaveSolver(model, source=source, receiver=receiver, time_order=2, space_order=space_order) solver_tti = AnisotropicWaveSolver(model, source=source, receiver=receiver, time_order=2, space_order=space_order) # Create new wavefield object restart forward computation u = TimeData(name='u', shape=model.shape_domain, save=False, time_order=2, space_order=space_order, dtype=model.dtype) u.data[0:3, :] = u1.data[indlast, :] rec, _, _ = acoustic.forward(save=False, u=u) utti = TimeData(name='u', shape=model.shape_domain, save=False, time_order=2, space_order=space_order, dtype=model.dtype) vtti = TimeData(name='v', shape=model.shape_domain, save=False, time_order=2, space_order=space_order, dtype=model.dtype) utti.data[0:3, :] = u1.data[indlast, :] vtti.data[0:3, :] = u1.data[indlast, :] rec_tti, u_tti, v_tti, _ = solver_tti.forward(u=utti, v=vtti) res = linalg.norm( u.data.reshape(-1) - .5 * u_tti.data.reshape(-1) - .5 * v_tti.data.reshape(-1)) res /= linalg.norm(u.data.reshape(-1)) log("Difference between acoustic and TTI with all coefficients to 0 %f" % res) assert np.isclose(res, 0.0, atol=1e-1)
def test_tti(shape, space_order, kernel): """ This first test compare the solution of the acoustic wave-equation and the TTI wave-eqatuon with all anisotropy parametrs to 0. The two solutions should be the same. """ if kernel == 'shifted': space_order *= 2 to = 2 so = space_order nbl = 10 origin = [0. for _ in shape] spacing = [10. for _ in shape] vp = 1.5 * np.ones(shape) nrec = shape[0] # Constant model for true velocity model = Model(origin=origin, shape=shape, vp=vp, spacing=spacing, nbl=nbl, space_order=space_order, epsilon=np.zeros(shape), delta=np.zeros(shape), theta=np.zeros(shape), phi=np.zeros(shape)) # Source and receiver geometries src_coordinates = np.empty((1, len(spacing))) src_coordinates[0, :] = np.array(model.domain_size) * .5 src_coordinates[0, -1] = model.origin[-1] + 2 * spacing[-1] rec_coordinates = np.empty((nrec, len(spacing))) rec_coordinates[:, 0] = np.linspace(0., model.domain_size[0], num=nrec) rec_coordinates[:, 1] = np.array(model.domain_size)[1] * .5 rec_coordinates[:, -1] = model.origin[-1] + 2 * spacing[-1] geometry = AcquisitionGeometry(model, rec_coordinates, src_coordinates, t0=0.0, tn=350., src_type='Ricker', f0=0.010) acoustic = AcousticWaveSolver(model, geometry, time_order=2, space_order=so) rec, u1, _ = acoustic.forward(save=False) # Solvers solver_tti = AnisotropicWaveSolver(model, geometry, time_order=2, space_order=space_order) # zero src src = geometry.src src.data.fill(0.) # last time index nt = geometry.nt last = (nt - 2) % 3 indlast = [(last + 1) % 3, last % 3, (last - 1) % 3] # Create new wavefield object restart forward computation u = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=so) u.data[0:3, :] = u1.data[indlast, :] acoustic.forward(save=False, u=u, time_M=10, src=src) utti = TimeFunction(name='u', grid=model.grid, time_order=to, space_order=so) vtti = TimeFunction(name='v', grid=model.grid, time_order=to, space_order=so) utti.data[0:to + 1, :] = u1.data[indlast[:to + 1], :] vtti.data[0:to + 1, :] = u1.data[indlast[:to + 1], :] solver_tti.forward(u=utti, v=vtti, kernel=kernel, time_M=10, src=src) normal_u = u.data[:] normal_utti = .5 * utti.data[:] normal_vtti = .5 * vtti.data[:] res = linalg.norm((normal_u - normal_utti - normal_vtti).reshape(-1))**2 res /= np.linalg.norm(normal_u.reshape(-1))**2 log("Difference between acoustic and TTI with all coefficients to 0 %2.4e" % res) assert np.isclose(res, 0.0, atol=1e-4)
def tti_operator(self, dse=False, space_order=4): return AnisotropicWaveSolver(self.model, self.geometry, space_order=space_order, dse=dse)
def test_tti(shape, space_order, kernel): """ This first test compare the solution of the acoustic wave-equation and the TTI wave-eqatuon with all anisotropy parametrs to 0. The two solutions should be the same. """ if kernel == 'shifted': space_order *= 2 to = 2 so = space_order // 2 if kernel == 'shifted' else space_order nbpml = 10 origin = [0. for _ in shape] spacing = [10. for _ in shape] vp = 1.5 * np.ones(shape) # Constant model for true velocity model = Model(origin=origin, shape=shape, vp=vp, spacing=spacing, nbpml=nbpml, space_order=space_order, epsilon=np.zeros(shape), delta=np.zeros(shape), theta=np.zeros(shape), phi=np.zeros(shape)) # Define seismic data and parameters f0 = .010 dt = model.critical_dt t0 = 0.0 tn = 350.0 time_range = TimeAxis(start=t0, stop=tn, step=dt) nt = time_range.num last = (nt - 2) % 3 indlast = [(last + 1) % 3, last % 3, (last - 1) % 3] # Generate a wavefield as initial condition source = RickerSource(name='src', grid=model.grid, f0=f0, time_range=time_range) source.coordinates.data[0, :] = np.array(model.domain_size) * .5 receiver = Receiver(name='rec', grid=model.grid, time_range=time_range, npoint=1) acoustic = AcousticWaveSolver(model, source=source, receiver=receiver, time_order=2, space_order=so) rec, u1, _ = acoustic.forward(save=False) source.data.fill(0.) # Solvers acoustic = AcousticWaveSolver(model, source=source, receiver=receiver, time_order=2, space_order=so) solver_tti = AnisotropicWaveSolver(model, source=source, receiver=receiver, time_order=2, space_order=space_order) # Create new wavefield object restart forward computation u = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=so) u.data[0:3, :] = u1.data[indlast, :] acoustic.forward(save=False, u=u, time_M=10, src=source) utti = TimeFunction(name='u', grid=model.grid, time_order=to, space_order=so) vtti = TimeFunction(name='v', grid=model.grid, time_order=to, space_order=so) utti.data[0:to + 1, :] = u1.data[indlast[:to + 1], :] vtti.data[0:to + 1, :] = u1.data[indlast[:to + 1], :] solver_tti.forward(u=utti, v=vtti, kernel=kernel, time_M=10, src=source) normal_u = u.data[:] normal_utti = .5 * utti.data[:] normal_vtti = .5 * vtti.data[:] res = linalg.norm((normal_u - normal_utti - normal_vtti).reshape(-1))**2 res /= np.linalg.norm(normal_u.reshape(-1))**2 log("Difference between acoustic and TTI with all coefficients to 0 %2.4e" % res) assert np.isclose(res, 0.0, atol=1e-4)
def forward_modeling_single_shot(record, table, par_files): "Serial modeling function" worker = get_worker() # The worker on which this task is running strng = '{} : {} =>'.format(worker.address, str(record).zfill(5)) filename = 'logfile_{}.txt'.format(str(record).zfill(5)) g = open(filename, 'w') g.write("This will show up in the worker logs") # Read velocity model f = segyio.open(par_files[-1], iline=segyio.tracefield.TraceField.FieldRecord, xline=segyio.tracefield.TraceField.CDP) xl, il, t = f.xlines, f.ilines, f.samples dz = t[1] - t[0] dx = f.header[1][segyio.TraceField.SourceX]-f.header[0][segyio.TraceField.SourceX] if len(il) != 1: dims = (len(xl), len(il), len(f.samples)) else: dims = (len(xl), len(f.samples)) vp = f.trace.raw[:].reshape(dims) vp *= 1./1000 # convert to km/sec epsilon = np.empty(dims) delta = np.empty(dims) theta = np.empty(dims) params = [epsilon, delta, theta] # Read Thomsem parameters for segyfile, par in zip(par_files, params): f = segyio.open(segyfile, iline=segyio.tracefield.TraceField.FieldRecord, xline=segyio.tracefield.TraceField.CDP) par[:] = f.trace.raw[:].reshape(dims) theta *= (np.pi/180.) # use radians g.write('{} Parameter model dims: {}\n'.format(strng, vp.shape)) origin = (0., 0.) shape = vp.shape spacing = (dz, dz) # Get a single shot as a numpy array filename = table[record]['filename'] position = table[record]['Trace_Position'] traces_in_shot = table[record]['Num_Traces'] src_coord = np.array(table[record]['Source']).reshape((1, len(dims))) rec_coord = np.array(table[record]['Receivers']) start = time.time() f = segyio.open(filename, ignore_geometry=True) num_samples = len(f.samples) samp_int = f.bin[segyio.BinField.Interval]/1000 retrieved_shot = np.zeros((traces_in_shot, num_samples)) shot_traces = f.trace[position:position+traces_in_shot] for i, trace in enumerate(shot_traces): retrieved_shot[i] = trace g.write('{} Shot loaded in: {} seconds\n'.format(strng, time.time()-start)) # Only keep receivers within the model' xmin = origin[0] idx_xrec = np.where(rec_coord[:, 0] < xmin)[0] is_empty = idx_xrec.size == 0 if not is_empty: g.write('{} in {}\n'.format(strng, rec_coord.shape)) idx_tr = np.where(rec_coord[:, 0] >= xmin)[0] rec_coord = np.delete(rec_coord, idx_xrec, axis=0) # For 3D shot records, scan also y-receivers if len(origin) == 3: ymin = origin[1] idx_yrec = np.where(rec_coord[:, 1] < ymin)[0] is_empty = idx_yrec.size == 0 if not is_empty: rec_coord = np.delete(rec_coord, idx_yrec, axis=0) if rec_coord.size == 0: g.write('all receivers outside of model\n') return np.zeros(vp.shape) space_order = 8 g.write('{} before: {} {} {}\n'.format(strng, params[0].shape, rec_coord.shape, src_coord.shape)) model = limit_model_to_receiver_area(rec_coord, src_coord, origin, spacing, shape, vp, params, space_order=space_order, nbl=80) g.write('{} shape_vp: {}\n'.format(strng, model.vp.shape)) model.smooth(('epsilon', 'delta', 'theta')) # Geometry for current shot geometry = AcquisitionGeometry(model, rec_coord, src_coord, 0, (num_samples-1)*samp_int, f0=0.018, src_type='Ricker') g.write("{} Number of samples modelled data & dt: {} & {}\n".format(strng, geometry.nt, model.critical_dt)) g.write("{} Samples & dt: {} & {}\n".format(strng, num_samples, samp_int)) # Set up solver. solver_tti = AnisotropicWaveSolver(model, geometry, space_order=space_order) # Create image symbol and instantiate the previously defined imaging operator image = Function(name='image', grid=model.grid) itemsize = np.dtype(np.float32).itemsize full_fld_mem = model.vp.size*itemsize*geometry.nt*2. checkpointing = True if checkpointing: op_imaging = ImagingOperator(geometry, image, space_order, save=False) n_checkpoints = 150 ckp_fld_mem = model.vp.size*itemsize*n_checkpoints*2. g.write('Mem full fld: {} == {} use ckp instead\n'.format(full_fld_mem, humanbytes(full_fld_mem))) g.write('Number of checkpoints/timesteps: {}/{}\n'.format(n_checkpoints, geometry.nt)) g.write('Memory saving: {}\n'.format(humanbytes(full_fld_mem-ckp_fld_mem))) u = TimeFunction(name='u', grid=model.grid, staggered=None, time_order=2, space_order=space_order) v = TimeFunction(name='v', grid=model.grid, staggered=None, time_order=2, space_order=space_order) vv = TimeFunction(name='vv', grid=model.grid, staggered=None, time_order=2, space_order=space_order) uu = TimeFunction(name='uu', grid=model.grid, staggered=None, time_order=2, space_order=space_order) cp = DevitoCheckpoint([u, v]) op_fwd = solver_tti.op_fwd(save=False) op_fwd.cfunction op_imaging.cfunction wrap_fw = CheckpointOperator(op_fwd, src=geometry.src, u=u, v=v, vp=model.vp, epsilon=model.epsilon, delta=model.delta, theta=model.theta, dt=model.critical_dt) time_range = TimeAxis(start=0, stop=(num_samples-1)*samp_int, step=samp_int) dobs = Receiver(name='dobs', grid=model.grid, time_range=time_range, coordinates=geometry.rec_positions) if not is_empty: dobs.data[:] = retrieved_shot[idx_tr, :].T else: dobs.data[:] = retrieved_shot[:].T dobs_resam = dobs.resample(num=geometry.nt) g.write('Shape of residual: {}\n'.format(dobs_resam.data.shape)) wrap_rev = CheckpointOperator(op_imaging, u=u, v=v, vv=vv, uu=uu, vp=model.vp, epsilon=model.epsilon, delta=model.delta, theta=model.theta, dt=model.critical_dt, residual=dobs_resam.data) # Run forward wrp = Revolver(cp, wrap_fw, wrap_rev, n_checkpoints, dobs_resam.shape[0]-2) g.write('Revolver storage: {}\n'.format(humanbytes(cp.size*n_checkpoints*itemsize))) wrp.apply_forward() g.write('{} run finished\n'.format(strng)) summary = wrp.apply_reverse() form = 'image_{}.bin'.format(str(record).zfill(5)) h = open(form, 'wb') g.write('{}\n'.format(str(image.data.shape))) np.transpose(image.data).astype('float32').tofile(h) else: # For illustrative purposes, assuming that there is enough memory g.write('enough memory to save full fld: {} == {}\n'.format(full_fld_mem, humanbytes(full_fld_mem))) op_imaging = ImagingOperator(geometry, image, space_order) vv = TimeFunction(name='vv', grid=model.grid, staggered=None, time_order=2, space_order=space_order) uu = TimeFunction(name='uu', grid=model.grid, staggered=None, time_order=2, space_order=space_order) time_range = TimeAxis(start=0, stop=(num_samples-1)*samp_int, step=samp_int) dobs = Receiver(name='dobs', grid=model.grid, time_range=time_range, coordinates=geometry.rec_positions) if not is_empty: dobs.data[:] = retrieved_shot[idx_tr, :].T else: dobs.data[:] = retrieved_shot[:].T dobs_resam = dobs.resample(num=geometry.nt) u, v = solver_tti.forward(vp=model.vp, epsilon=model.epsilon, delta=model.delta, theta=model.theta, dt=model.critical_dt, save=True)[1:-1] op_imaging(u=u, v=v, vv=vv, uu=uu, epsilon=model.epsilon, delta=model.delta, theta=model0.theta, vp=model.vp, dt=model.critical_dt, residual=dobs_resam) full_image = extend_image(origin, vp, model, image) return full_image
def test_tti(shape, space_order): nbpml = 10 ndim = len(shape) origin = [0. for _ in shape] spacing = [10. for _ in shape] # Source location location = np.zeros((1, ndim), dtype=np.float32) location[0, :-1] = [origin[i] + shape[i] * spacing[i] * .5 for i in range(ndim-1)] location[0, -1] = origin[-1] + 2 * spacing[-1] # Receivers locations receiver_coords = np.zeros((shape[0], ndim), dtype=np.float32) receiver_coords[:, 0] = np.linspace(0, origin[0] + (shape[0]-1) * spacing[0], num=shape[0]) receiver_coords[:, 1:] = location[0, 1:] # Two layer model for true velocity model = demo_model('layers-isotropic', ratio=3, shape=shape, spacing=spacing, nbpml=nbpml, epsilon=np.zeros(shape), delta=np.zeros(shape), theta=np.zeros(shape), phi=np.zeros(shape)) # Define seismic data and parameters f0 = .010 dt = model.critical_dt t0 = 0.0 tn = 350.0 nt = int(1+(tn-t0)/dt) last = (nt - 2) % 3 indlast = [(last + 1) % 3, last % 3, (last-1) % 3] # Set up the source as Ricker wavelet for f0 def ricker_source(t, f0): r = (np.pi * f0 * (t - 1./f0)) return (1-2.*r**2)*np.exp(-r**2) # Source geometry time_series = np.zeros((nt, 1)) time_series[:, 0] = ricker_source(np.linspace(t0, tn, nt), f0) # Adjoint test source = PointSource(name='src', grid=model.grid, data=time_series, coordinates=location) receiver = Receiver(name='rec', grid=model.grid, ntime=nt, coordinates=receiver_coords) acoustic = AcousticWaveSolver(model, source=source, receiver=receiver, time_order=2, space_order=space_order) rec, u1, _ = acoustic.forward(save=False) tn = 100.0 nt = int(1 + (tn - t0) / dt) # Source geometry time_series = np.zeros((nt, 1)) time_series[:, 0] = 0*ricker_source(np.linspace(t0, tn, nt), f0) source = PointSource(name='src', grid=model.grid, data=time_series, coordinates=location) receiver = Receiver(name='rec', grid=model.grid, ntime=nt, coordinates=receiver_coords) acoustic = AcousticWaveSolver(model, source=source, receiver=receiver, time_order=2, space_order=space_order) solver_tti = AnisotropicWaveSolver(model, source=source, receiver=receiver, time_order=2, space_order=space_order) # Create new wavefield object restart forward computation u = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=space_order, dtype=model.dtype) u.data[0:3, :] = u1.data[indlast, :] rec, _, _ = acoustic.forward(save=False, u=u) utti = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=space_order, dtype=model.dtype) vtti = TimeFunction(name='v', grid=model.grid, time_order=2, space_order=space_order, dtype=model.dtype) utti.data[0:3, :] = u1.data[indlast, :] vtti.data[0:3, :] = u1.data[indlast, :] rec_tti, u_tti, v_tti, _ = solver_tti.forward(u=utti, v=vtti) res = linalg.norm(u.data.reshape(-1) - .5 * u_tti.data.reshape(-1) - .5 * v_tti.data.reshape(-1)) res /= linalg.norm(u.data.reshape(-1)) log("Difference between acoustic and TTI with all coefficients to 0 %f" % res) assert np.isclose(res, 0.0, atol=1e-4)