def generate_shotdata_i(src_coordinates, rec_coordinates, param, true_model): """ Inversion crime alert! Here the worker is creating the 'observed' data using the real model. For a real case the worker would be reading seismic data from disk. """ # Geometry geometry = AcquisitionGeometry(true_model, rec_coordinates, src_coordinates, param['t0'], param['tn'], src_type='Ricker', f0=param['f0']) geometry.resample(param['dt']) # Set up solver. solver = AcousticWaveSolver(true_model, geometry, space_order=param['space_order']) # Generate synthetic receiver data from true model. true_d, _, _ = solver.forward(m=true_model.m) return true_d.data
def run_acoustic_forward(dse=None): shape = (50, 50, 50) spacing = (10., 10., 10.) nbpml = 10 nrec = 101 t0 = 0.0 tn = 250.0 # Create two-layer model from preset model = demo_model(preset='layers-isotropic', vp_top=3., vp_bottom=4.5, spacing=spacing, shape=shape, nbpml=nbpml) # 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='Ricker', f0=0.010) solver = AcousticWaveSolver(model, geometry, dse=dse, dle='noop') rec, u, _ = solver.forward(save=False) return u, rec
def run_acoustic_forward(dse=None): shape = (50, 50, 50) spacing = (10., 10., 10.) nbpml = 10 nrec = 101 t0 = 0.0 tn = 250.0 # Create two-layer model from preset model = demo_model(preset='layers-isotropic', vp_top=3., vp_bottom=4.5, spacing=spacing, shape=shape, nbpml=nbpml) # Derive timestepping from model spacing dt = model.critical_dt 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.01, time_range=time_range) src.coordinates.data[0, :] = np.array(model.domain_size) * .5 src.coordinates.data[0, -1] = 20. # Define receiver geometry (same as source, but spread across x) 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:] solver = AcousticWaveSolver(model, source=src, receiver=rec, dse=dse, dle='basic') rec, u, _ = solver.forward(save=False) return u, rec
def run_acoustic_forward(dse=None): shape = (50, 50, 50) spacing = (10., 10., 10.) nbpml = 10 nrec = 101 t0 = 0.0 tn = 250.0 # Create two-layer model from preset model = demo_model(preset='layers-isotropic', vp_top=3., vp_bottom=4.5, spacing=spacing, shape=shape, nbpml=nbpml) # 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='Ricker', f0=0.010) solver = AcousticWaveSolver(model, geometry, dse=dse, dle='noop') rec, u, _ = solver.forward(save=False) return u, rec
def get_data(param): """ Returns source and receiver data for a single shot labeled 'shot_id'. """ true_model = get_true_model() dt = true_model.critical_dt # Time step from model grid spacing # Set up source data and geometry. nt = int(1 + (param['tn']-param['t0']) / dt) # Discrete time axis length src = RickerSource(name='src', grid=true_model.grid, f0=param['f0'], time=np.linspace(param['t0'], param['tn'], nt)) src.coordinates.data[0, :] = [30, param['shot_id']*1000./(param['nshots']-1)] # Set up receiver data and geometry. nreceivers = 101 # Number of receiver locations per shot rec = Receiver(name='rec', grid=true_model.grid, npoint=nreceivers, ntime=nt) rec.coordinates.data[:, 1] = np.linspace(0, true_model.domain_size[0], num=nreceivers) rec.coordinates.data[:, 0] = 980. # 20m from the right end # Set up solver - using model_in so that we have the same dt, # otherwise we should use pandas to resample the time series data. solver = AcousticWaveSolver(true_model, src, rec, space_order=4) # Generate synthetic receiver data from true model true_d, _, _ = solver.forward(src=src, m=true_model.m) return src, true_d, nt, solver
def test_acoustic(mkey, shape, kernel, space_order, nbpml): t0 = 0.0 # Start time tn = 500. # Final time nrec = 130 # Number of receivers # Create model from preset model = demo_model(spacing=[15. for _ in shape], dtype=np.float64, space_order=space_order, shape=shape, nbpml=nbpml, **(presets[mkey])) # Derive timestepping from model spacing dt = model.critical_dt * (1.73 if kernel == 'OT4' else 1.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.01, time_range=time_range) src.coordinates.data[0, :] = np.array(model.domain_size) * .5 src.coordinates.data[0, -1] = 30. # Define receiver geometry (same as source, but spread across x) 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) rec.coordinates.data[:, 1:] = src.coordinates.data[0, 1:] # Create solver object to provide relevant operators solver = AcousticWaveSolver(model, source=src, receiver=rec, kernel=kernel, space_order=space_order) # Create adjoint receiver symbol srca = Receiver(name='srca', grid=model.grid, time_range=solver.source.time_range, coordinates=solver.source.coordinates.data) # Run forward and adjoint operators rec, _, _ = solver.forward(save=False) solver.adjoint(rec=rec, srca=srca) # Adjoint test: Verify <Ax,y> matches <x, A^Ty> closely term1 = np.dot(srca.data.reshape(-1), solver.source.data) term2 = linalg.norm(rec.data)**2 info('<Ax,y>: %f, <x, A^Ty>: %f, difference: %12.12f, ratio: %f' % (term1, term2, (term1 - term2) / term1, term1 / term2)) assert np.isclose((term1 - term2) / term1, 0., rtol=1.e-10)
def test_position(shape): t0 = 0.0 # Start time tn = 500. # Final time nrec = 130 # Number of receivers # Create model from preset model = demo_model('constant-isotropic', spacing=[15. for _ in shape], shape=shape, nbpml=10) # 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 = RickerSource(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] = 30. # Define receiver geometry (same as source, but spread across x) 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:] # Create solver object to provide relevant operators solver = AcousticWaveSolver(model, source=src, receiver=rec, time_order=2, space_order=4) rec, u, _ = solver.forward(save=False) # Define source geometry (center of domain, just below surface) with 100. origin src = RickerSource(name='src', grid=model.grid, f0=0.01, time=time_values) src.coordinates.data[0, :] = np.array(model.domain_size) * .5 + 100. src.coordinates.data[0, -1] = 130. # Define receiver geometry (same as source, but spread across x) rec2 = Receiver(name='rec2', grid=model.grid, ntime=nt, npoint=nrec) rec2.coordinates.data[:, 0] = np.linspace(100., 100. + model.domain_size[0], num=nrec) rec2.coordinates.data[:, 1:] = src.coordinates.data[0, 1:] rec1, u1, _ = solver.forward(save=False, src=src, rec=rec2, o_x=100., o_y=100., o_z=100.) assert (np.allclose(rec.data, rec1.data, atol=1e-5))
def forward_modeling(dm, isrc, model, geometry, space_order): geometry_i = AcquisitionGeometry(model, geometry.rec_positions, geometry.src_positions[isrc, :], geometry.t0, geometry.tn, f0=geometry.f0, src_type=geometry.src_type) solver = AcousticWaveSolver(model, geometry_i, space_order=space_order) d_obs, _, _, _ = solver.born(dm) return (d_obs.resample(geometry.dt).data[:][0:geometry.nt, :]).flatten()
def test_acousticJ(shape, space_order): t0 = 0.0 # Start time tn = 500. # Final time nrec = shape[0] # Number of receivers nbpml = 10 + space_order / 2 spacing = [15. for _ in shape] # Create two-layer "true" model from preset with a fault 1/3 way down model = demo_model('layers-isotropic', ratio=3, vp_top=1.5, vp_bottom=2.5, spacing=spacing, space_order=space_order, shape=shape, nbpml=nbpml, dtype=np.float64) # Derive timestepping from model spacing dt = model.critical_dt 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.01, time_range=time_range) src.coordinates.data[0, :] = np.array(model.domain_size) * .5 src.coordinates.data[0, -1] = 30. # Define receiver geometry (same as source, but spread across x) 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:] # Create solver object to provide relevant operators solver = AcousticWaveSolver(model, source=src, receiver=rec, kernel='OT2', space_order=space_order) # Create initial model (m0) with a constant velocity throughout model0 = demo_model('layers-isotropic', ratio=3, vp_top=1.5, vp_bottom=1.5, spacing=spacing, space_order=space_order, shape=shape, nbpml=nbpml, dtype=np.float64) # Compute the full wavefield u0 _, u0, _ = solver.forward(save=True, m=model0.m) # Compute initial born perturbation from m - m0 dm = model.m.data - model0.m.data du, _, _, _ = solver.born(dm, m=model0.m) # Compute gradientfrom initial perturbation im, _ = solver.gradient(du, u0, m=model0.m) # Adjoint test: Verify <Ax,y> matches <x, A^Ty> closely term1 = np.dot(im.data.reshape(-1), dm.reshape(-1)) term2 = linalg.norm(du.data)**2 info('<Ax,y>: %f, <x, A^Ty>: %f, difference: %12.12f, ratio: %f' % (term1, term2, term1 - term2, term1 / term2)) assert np.isclose(term1 / term2, 1.0, atol=0.001)
def __init__(self, model, src, rec_geom, time_start, time_end, space_order=16, **kwargs): self.data = Receiver(name='rec', grid=model.grid, npoint=rec_geom.shape[0], time_range=src.time_range, coordinates=rec_geom) self.source = Receiver(name='src', grid=model.grid, npoint=src.npoint, time_range=src.time_range, coordinates=src.coordinates.data) self.source.data[:] = src.data[:] self.space_order = space_order self.kwargs = kwargs self.model = model self.time_start = time_start self.time_end = time_end self.space_order = space_order self.solver = AcousticWaveSolver(model, source=self.source, receiver=self.data, space_order=space_order, **kwargs) self.grid = copy.copy(self.model.grid) self.grid.shape = (self.model.grid.shape[0] * 3, self.model.grid.shape[1]) u = Function(name="u", grid=self.grid, space_order=space_order) domain = DevitoSet(u) im = DevitoSet(u) super(F, self).__init__(domain=domain, range=im) self.FT = FT(self.model, self.source, self.data.coordinates.data, self.data.data, self.time_start, self.time_end, space_order=self.space_order, **self.kwargs)
def acoustic_setup(shape=(50, 50, 50), spacing=(15.0, 15.0, 15.0), tn=500., kernel='OT2', space_order=4, nbpml=10, preset='layers-isotropic', **kwargs): nrec = kwargs.pop('nrec', shape[0]) model = demo_model(preset, space_order=space_order, shape=shape, nbpml=nbpml, dtype=kwargs.pop('dtype', np.float32), spacing=spacing) # 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) # Create solver object to provide relevant operators solver = AcousticWaveSolver(model, geometry, kernel=kernel, space_order=space_order, **kwargs) return solver
def acoustic_setup(shape=(50, 50, 50), spacing=(15.0, 15.0, 15.0), tn=500., kernel='OT2', space_order=4, nbl=10, preset='layers-isotropic', fs=False, **kwargs): model = demo_model(preset, space_order=space_order, shape=shape, nbl=nbl, dtype=kwargs.pop('dtype', np.float32), spacing=spacing, fs=fs, **kwargs) # Source and receiver geometries geometry = setup_geometry(model, tn) # Create solver object to provide relevant operators solver = AcousticWaveSolver(model, geometry, kernel=kernel, space_order=space_order, **kwargs) return solver
def acoustic_setup(shape=(50, 50, 50), spacing=(15.0, 15.0, 15.0), tn=500., time_order=2, space_order=4, nbpml=10, constant=False, **kwargs): nrec = shape[0] preset = 'constant-isotropic' if constant else 'layers-isotropic' model = demo_model(preset, shape=shape, spacing=spacing, nbpml=nbpml) # Derive timestepping from model spacing dt = model.critical_dt * (1.73 if time_order == 4 else 1.0) t0 = 0.0 nt = int(1 + (tn-t0) / dt) # Number of timesteps time = np.linspace(t0, tn, nt) # Discretized time axis # Define source geometry (center of domain, just below surface) src = RickerSource(name='src', grid=model.grid, f0=0.01, time=time) 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, just 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:] # Create solver object to provide relevant operators solver = AcousticWaveSolver(model, source=src, receiver=rec, time_order=time_order, space_order=space_order, **kwargs) return solver
def acoustic_setup(shape=(50, 50, 50), spacing=(15.0, 15.0, 15.0), tn=500., kernel='OT2', space_order=4, nbpml=10, constant=False, **kwargs): nrec = shape[0] preset = 'constant-isotropic' if constant else 'layers-isotropic' model = demo_model(preset, space_order=space_order, shape=shape, nbpml=nbpml, dtype=kwargs.pop('dtype', np.float32), spacing=spacing) # Derive timestepping from model spacing dt = model.critical_dt * (1.73 if kernel == 'OT4' else 1.0) 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.01, 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 solver = AcousticWaveSolver(model, source=src, receiver=rec, kernel=kernel, space_order=space_order, **kwargs) return solver
def test_position(shape): t0 = 0.0 # Start time tn = 500. # Final time nrec = 130 # Number of receivers # Create model from preset model = demo_model('constant-isotropic', spacing=[15. for _ in shape], shape=shape, nbl=10) # Derive timestepping from model spacing dt = model.critical_dt time_range = TimeAxis(start=t0, stop=tn, step=dt) # Source and receiver geometries src_coordinates = np.empty((1, len(shape))) src_coordinates[0, :] = np.array(model.domain_size) * .5 src_coordinates[0, -1] = 30. rec_coordinates = np.empty((nrec, len(shape))) 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='Ricker', f0=0.010) # Create solver object to provide relevant operators solver = AcousticWaveSolver(model, geometry, time_order=2, space_order=4) rec, u, _ = solver.forward(save=False) # Define source geometry (center of domain, just below surface) with 100. origin src = RickerSource(name='src', grid=model.grid, f0=0.01, time_range=time_range) src.coordinates.data[0, :] = np.array(model.domain_size) * .5 + 100. src.coordinates.data[0, -1] = 130. # Define receiver geometry (same as source, but spread across x) rec2 = Receiver(name='rec', grid=model.grid, time_range=time_range, npoint=nrec) rec2.coordinates.data[:, 0] = np.linspace(100., 100. + model.domain_size[0], num=nrec) rec2.coordinates.data[:, 1:] = src.coordinates.data[0, 1:] ox_g, oy_g, oz_g = tuple(o.dtype(o.data+100.) for o in model.grid.origin) rec1, u1, _ = solver.forward(save=False, src=src, rec=rec2, o_x=ox_g, o_y=oy_g, o_z=oz_g) assert(np.allclose(rec.data, rec1.data, atol=1e-5))
def test_adjoint_born(): tn = 1000. shape = (101, 101) nbl = 40 model = demo_model('layers-isotropic', origin=(0., 0.), shape=shape, spacing=(10., 10.), nbl=nbl, nlayers=2, space_order=8) model0 = demo_model('layers-isotropic', origin=(0., 0.), shape=shape, spacing=(10., 10.), nbl=nbl, nlayers=2, space_order=8) gaussian_smooth(model0.vp, sigma=(1, 1)) geometry0 = setup_geometry(model0, tn) # Pure Devito solver0 = AcousticWaveSolver(model0, geometry0, space_order=8) dm = model.vp.data**(-2) - model0.vp.data**(-2) grad_devito = np.array(solver0.jacobian(dm)[0].data) # Devito4PyTorch dm = torch.from_numpy(np.array(dm[nbl:-nbl, nbl:-nbl])).to(device) d_est = torch.zeros(geometry0.rec.data.shape, requires_grad=True, device=device) adjoint_born = AdjointBornLayer(model0, geometry0, device) loss = 0.5 * torch.norm(adjoint_born(d_est) - dm)**2 # Negative gradient to be compared with linearized data computed above grad = -torch.autograd.grad(loss, d_est, create_graph=False)[0] # Test rel_err = np.linalg.norm(grad.cpu().numpy() - grad_devito) / np.linalg.norm(grad_devito) assert np.isclose(rel_err, 0., atol=1.e-6)
def test_position(shape): t0 = 0.0 # Start time tn = 500. # Final time nrec = 130 # Number of receivers # Create model from preset model = demo_model('constant-isotropic', spacing=[15. for _ in shape], shape=shape, nbpml=10) # Derive timestepping from model spacing dt = model.critical_dt time_range = TimeAxis(start=t0, stop=tn, step=dt) # Source and receiver geometries src_coordinates = np.empty((1, len(shape))) src_coordinates[0, :] = np.array(model.domain_size) * .5 src_coordinates[0, -1] = 30. rec_coordinates = np.empty((nrec, len(shape))) 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='Ricker', f0=0.010) # Create solver object to provide relevant operators solver = AcousticWaveSolver(model, geometry, time_order=2, space_order=4) rec, u, _ = solver.forward(save=False) # Define source geometry (center of domain, just below surface) with 100. origin src = RickerSource(name='src', grid=model.grid, f0=0.01, time_range=time_range) src.coordinates.data[0, :] = np.array(model.domain_size) * .5 + 100. src.coordinates.data[0, -1] = 130. # Define receiver geometry (same as source, but spread across x) rec2 = Receiver(name='rec', grid=model.grid, time_range=time_range, npoint=nrec) rec2.coordinates.data[:, 0] = np.linspace(100., 100. + model.domain_size[0], num=nrec) rec2.coordinates.data[:, 1:] = src.coordinates.data[0, 1:] ox_g, oy_g, oz_g = tuple(o.dtype(o.data+100.) for o in model.grid.origin) rec1, u1, _ = solver.forward(save=False, src=src, rec=rec2, o_x=ox_g, o_y=oy_g, o_z=oz_g) assert(np.allclose(rec.data, rec1.data, atol=1e-5))
def overthrust_solver_iso(h5_file, kernel='OT2', tn=4000, src_coordinates=None, space_order=2, datakey='m0', nbl=40, dtype=np.float32, **kwargs): model = overthrust_model_iso(h5_file, datakey, space_order, nbl, dtype) geometry = create_geometry(model, tn, src_coordinates) solver = AcousticWaveSolver(model, geometry, kernel=kernel, space_order=space_order, dtype=dtype, **kwargs) return solver
def __init__(self, model, geometry, device): super(AdjointBornLayer, self).__init__() self.forward_born = devito_wrapper.AdjointBorn() self.model = model self.geometry = geometry self.device = device self.solver = AcousticWaveSolver(self.model, self.geometry, space_order=8)
def __init__(self, model, geometry, device): super(ForwardModelingLayer, self).__init__() self.forward_modeling = devito_wrapper.ForwardModeling() self.model = model self.geometry = geometry self.device = device self.solver = AcousticWaveSolver(self.model, self.geometry, space_order=8)
def run_acoustic_forward(dse=None): dimensions = (50, 50, 50) origin = (0., 0., 0.) spacing = (10., 10., 10.) nbpml = 10 # True velocity true_vp = np.ones(dimensions) + 2.0 true_vp[:, :, int(dimensions[0] / 2):int(dimensions[0])] = 4.5 model = Model(origin, spacing, dimensions, true_vp, nbpml=nbpml) # Define seismic data. f0 = .010 dt = model.critical_dt t0 = 0.0 tn = 250.0 nt = int(1 + (tn - t0) / dt) t = np.linspace(t0, tn, nt) r = (np.pi * f0 * (t - 1. / f0)) # Source geometry time_series = np.zeros((nt, 1)) time_series[:, 0] = (1 - 2. * r**2) * np.exp(-r**2) 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] # 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] src = PointSource(name='src', data=time_series, coordinates=location) rec = Receiver(name='rec', ntime=nt, coordinates=receiver_coords) acoustic = AcousticWaveSolver(model, source=src, receiver=rec) rec, u, _ = acoustic.forward(save=False, dse=dse, dle='basic') return u, rec
def one_shot_rtm(geometry, model0): # Devito objects for gradient and data residual grad = Function(name="grad", grid=geometry.model.grid) residual = Receiver(name='rec', grid=geometry.model.grid, time_range=geometry.time_axis, coordinates=geometry.rec_positions) solver = AcousticWaveSolver(geometry.model, geometry, space_order=4) # Predicted data and residual true_d, u0 = solver.forward(vp=geometry.model.vp, save=True)[0:2] smooth_d, _ = solver.forward(vp=model0.vp, save=True)[0:2] v = TimeFunction(name='v', grid=model.grid, time_order=2, space_order=4) residual = smooth_d.data - true_d.data return u0, v, residual
def test_forward(): tn = 1000. shape = (101, 101) nbl = 40 model = demo_model('layers-isotropic', origin=(0., 0.), shape=shape, spacing=(10., 10.), nbl=nbl, nlayers=2, space_order=8) model0 = demo_model('layers-isotropic', origin=(0., 0.), shape=shape, spacing=(10., 10.), nbl=nbl, nlayers=2, space_order=8) gaussian_smooth(model0.vp, sigma=(1, 1)) geometry0 = setup_geometry(model0, tn) geometry = setup_geometry(model, tn) # Pure Devito solver = AcousticWaveSolver(model, geometry, space_order=8) solver0 = AcousticWaveSolver(model0, geometry0, space_order=8) d = solver.forward()[0] d0, u0 = solver0.forward(save=True, vp=model0.vp)[:2] residual = d.data - d0.data rec = geometry0.rec rec.data[:] = -residual[:] grad_devito = solver0.jacobian_adjoint(rec, u0)[0].data grad_devito = np.array(grad_devito)[nbl:-nbl, nbl:-nbl] # Devito4PyTorch d = torch.from_numpy(np.array(d.data)).to(device) forward_modeling = ForwardModelingLayer(model0, geometry0, device) m0 = np.array(model0.vp.data**(-2))[nbl:-nbl, nbl:-nbl] m0 = torch.Tensor(m0).unsqueeze(0).unsqueeze(0).to(device) m0.requires_grad = True loss = 0.5 * torch.norm(forward_modeling(m0) - d)**2 grad = torch.autograd.grad(loss, m0, create_graph=False)[0] # Test rel_err = np.linalg.norm(grad.cpu().numpy() - grad_devito) / np.linalg.norm(grad_devito) assert np.isclose(rel_err, 0., atol=1.e-6)
def test_forward_born(): tn = 1000. shape = (101, 101) nbl = 40 model = demo_model('layers-isotropic', origin=(0., 0.), shape=shape, spacing=(10., 10.), nbl=nbl, nlayers=2, space_order=8) model0 = demo_model('layers-isotropic', origin=(0., 0.), shape=shape, spacing=(10., 10.), nbl=nbl, nlayers=2, space_order=8) gaussian_smooth(model0.vp, sigma=(1, 1)) geometry0 = setup_geometry(model0, tn) geometry = setup_geometry(model, tn) # Pure Devito solver = AcousticWaveSolver(model, geometry, space_order=8) solver0 = AcousticWaveSolver(model0, geometry0, space_order=8) d = solver.forward(vp=model.vp)[0] d0, u0 = solver0.forward(save=True, vp=model0.vp)[:2] d_lin = d.data - d0.data rec = geometry0.rec rec.data[:] = -d_lin[:] grad_devito = solver0.jacobian_adjoint(rec, u0)[0].data grad_devito = np.array(grad_devito)[nbl:-nbl, nbl:-nbl] # Devito4PyTorch d_lin = torch.from_numpy(np.array(d_lin)).to(device) forward_born = ForwardBornLayer(model0, geometry0, device) dm_est = torch.zeros([1, 1, shape[0], shape[1]], requires_grad=True, device=device) loss = 0.5 * torch.norm(forward_born(dm_est) - d_lin)**2 grad = torch.autograd.grad(loss, dm_est, create_graph=False)[0] # Test rel_err = np.linalg.norm(grad.cpu().numpy() - grad_devito) / np.linalg.norm(grad_devito) assert np.isclose(rel_err, 0., atol=1.e-6)
def setup(dimensions=(50, 50, 50), spacing=(15.0, 15.0, 15.0), tn=500., time_order=2, space_order=4, nbpml=10, **kwargs): ndim = len(dimensions) origin = tuple([0.]*ndim) spacing = spacing[: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:] # Define seismic data model = Model(origin, spacing, dimensions, true_vp, nbpml=int(nbpml)) f0 = .010 dt = model.critical_dt if time_order == 4: dt *= 1.73 t0 = 0.0 tn = tn nt = int(1+(tn-t0)/dt) # Set up the source as Ricker wavelet for f0 def 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), dtype=np.float32) time_series[:, 0] = source(np.linspace(t0, tn, nt), f0) # Define source and receivers and create acoustic wave solver src = PointSource(name='src', data=time_series, coordinates=location) rec = Receiver(name='rec', ntime=nt, coordinates=receiver_coords) return AcousticWaveSolver(model, source=src, receiver=rec, time_order=time_order, space_order=space_order, **kwargs)
def overthrust_setup(filename, kernel='OT2', tn=4000, src_coordinates=None, space_order=2, datakey='m0', nbpml=40, dtype=np.float32, **kwargs): model = from_hdf5(filename, space_order=space_order, nbpml=nbpml, datakey=datakey, dtype=dtype) shape = model.shape spacing = model.spacing nrec = shape[0] if src_coordinates is None: 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] # Create solver object to provide relevant operator geometry = AcquisitionGeometry(model, rec_coordinates, src_coordinates, t0=0.0, tn=tn, src_type='Ricker', f0=0.008) solver = AcousticWaveSolver(model, geometry, kernel=kernel, space_order=space_order, **kwargs) return solver
def overthrust_setup(filename, kernel='OT2', space_order=2, nbpml=40, **kwargs): model = from_hdf5(filename, space_order=space_order, nbpml=nbpml, datakey='m0', dtype=np.float64) spacing = model.spacing shape = model.vp.shape nrec = shape[0] tn = round(2 * max(model.domain_size) / np.min(model.vp)) # Derive timestepping from model spacing dt = model.critical_dt * (1.73 if kernel == 'OT4' else 1.0) 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.01, 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 solver = AcousticWaveSolver(model, source=src, receiver=rec, kernel=kernel, space_order=space_order, **kwargs) return solver
def overthrust_setup(filename, kernel='OT2', tn=4000, space_order=2, nbpml=40, dtype=np.float32, **kwargs): model = from_hdf5(filename, space_order=space_order, nbpml=nbpml, datakey='m0', dtype=dtype) shape = model.vp.shape spacing = model.spacing nrec = shape[0] # Derive timestepping from model spacing dt = model.critical_dt * (1.73 if kernel == 'OT4' else 1.0) t0 = 0.0 time_range = TimeAxis(start=t0, stop=tn, step=dt) 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] # Create solver object to provide relevant operator geometry = AcquisitionGeometry(model, rec_coordinates, src_coordinates, t0=0.0, tn=tn, src_type='Ricker', f0=0.010) solver = AcousticWaveSolver(model, geometry, kernel=kernel, space_order=space_order, **kwargs) return solver
def my_task(part, param, dobs, src_coor, rec_coor): error = 0. model_part = get_true_model(part * (1 / 1000.), param) tstart = time.time() # Geometry source_locations = numpy.empty((1, 2)) geometry = AcquisitionGeometry(model_part, rec_coordinates, source_locations, param['t0'], param['tn'], src_type='Ricker', f0=param['f0']) geometry.resample(param['dt']) #print(geometry.nt) # Set up solver. solver = AcousticWaveSolver(model_part, geometry, space_order=param['space_order']) #print("{:>30}: {:>8}".format('solver',sizeof_fmt(sys.getsizeof(solver)))) tracemalloc.start() start = tracemalloc.take_snapshot() prev = start for i in range(len(dobs[0][0])): dcalc = generate_shotdata_i(numpy.array([src_coor[i]]), geometry, solver, model_part) res = get_value(dcalc, dobs[:, :, i]) error += res trace_leak(start, prev) #print("{:>30}: {:>8}".format('dcalc',sizeof_fmt(sys.getsizeof(dcalc)))) #print("{:>30}: {:>8}".format('res',sizeof_fmt(sys.getsizeof(res)))) #print("{:>30}: {:>8}".format('error',sizeof_fmt(sys.getsizeof(error)))) clear_cache() dcalc = None del dcalc print("Forward modeling took {}".format(time.time() - tstart)) return (error, )
def f_df_single_shot(s, d_obs, ixsrc, geometry, model, space_order): # Geometry for current shot geometry_i = AcquisitionGeometry(model, geometry.rec_positions, geometry.src_positions[ixsrc, :], geometry.t0, geometry.tn, f0=geometry.f0, src_type=geometry.src_type) #set reflectivity dm = np.zeros(model.grid.shape, dtype=np.float32) dm[model.nbl:-model.nbl, model.nbl:-model.nbl] = s[:].reshape( (model.shape[0], model.shape[1])) # Devito objects for gradient and data residual grad = Function(name="grad", grid=model.grid) residual = Receiver(name='rec', grid=model.grid, time_range=geometry_i.time_axis, coordinates=geometry_i.rec_positions) solver = AcousticWaveSolver(model, geometry_i, space_order=space_order) # Predicted data and residual _, u0, _ = solver.forward(save=True) d_pred = solver.born(dm)[0] residual.data[:] = d_pred.data[:] - d_obs[:] fval = .5 * np.linalg.norm(residual.data.flatten())**2 # Function value and gradient solver.gradient(rec=residual, u=u0, vp=model.vp, grad=grad) # Convert to numpy array and remove absorbing boundaries grad_crop = np.array(grad.data[:], dtype=np.float32)[model.nbl:-model.nbl, model.nbl:-model.nbl] # Do not update water layer grad_crop[:, :36] = 0. return fval, grad_crop.flatten()
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 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 nbpml = 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, nbpml=nbpml, 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)