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 test_geom(shape): vp = np.ones(shape) o = tuple([0] * len(shape)) d = tuple([10] * len(shape)) model = Model(o, d, shape, 4, vp, nbl=20, dt=1) assert model.critical_dt == 1 nrec = 31 nsrc = 4 rec_coordinates = np.ones((nrec, len(shape))) src_coordinates = np.ones((nsrc, len(shape))) geometry = AcquisitionGeometry(model, rec_coordinates, src_coordinates, t0=0.0, tn=250) assert geometry.grid == model.grid assert geometry.nrec == nrec assert geometry.nsrc == nsrc assert geometry.src_type is None assert geometry.rec.shape == (251, nrec) assert norm(geometry.rec) == 0 assert geometry.src.shape == (251, nsrc) assert norm(geometry.new_src(src_type=None)) == 0 assert norm(geometry.src) == 0 rec2 = geometry.rec.resample(num=501) assert rec2.shape == (501, nrec) assert rec2.grid == model.grid assert geometry.new_rec(name="bonjour").name == "bonjour" assert geometry.new_src(name="bonjour").name == "bonjour"
def multi_shots_rtm(geometry, model0): image = Function(name='image', grid=model.grid) op_imaging = ImagingOperator(model, image) futures = [] inicio = time.time() for i in range(geometry.nsrc): # Geometry for current shot geometry_i = AcquisitionGeometry(geometry.model, geometry.rec_positions, geometry.src_positions[i, :], geometry.t0, geometry.tn, f0=geometry.f0, src_type=geometry.src_type) # Call serial FWI objective function for each shot location futures.append(client.submit(one_shot_rtm, geometry_i, model0)) # Wait for all workers to finish and collect function values and gradients wait(futures) fim = time.time() tempo = fim - inicio print("Demorou - Dask: ", tempo) for i in range(geometry.nsrc): #print('iteração', (i+1)) # plot_image(np.diff(image.data, axis=1)) op_imaging(u=futures[i].result()[0], v=futures[i].result()[1], vp=model0.vp, dt=model0.critical_dt, residual=futures[i].result()[2]) return image.data
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): nrec = 101 # Two layer model for true velocity model = demo_model(preset, shape=shape, spacing=spacing, nbl=nbl) # 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 test_geometry(): shape = (50, 50, 50) spacing = [10. for _ in shape] nbl = 10 nrec = 10 tn = 150. # Create two-layer model from preset model = demo_model(preset='layers-isotropic', vp_top=1., vp_bottom=2., spacing=spacing, shape=shape, nbl=nbl) # 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) pkl_geom = pickle.dumps(geometry) new_geom = pickle.loads(pkl_geom) assert np.all(new_geom.src_positions == geometry.src_positions) assert np.all(new_geom.rec_positions == geometry.rec_positions) assert new_geom.f0 == geometry.f0 assert np.all(new_geom.src_type == geometry.src_type) assert np.all(new_geom.src.data == geometry.src.data) assert new_geom.t0 == geometry.t0 assert new_geom.tn == geometry.tn
def geometry(self): nrec = 101 t0 = 0.0 tn = 250. # Source and receiver geometries src_coordinates = np.empty((1, len(self.model.spacing))) src_coordinates[0, :] = np.array(self.model.domain_size) * .5 src_coordinates[ 0, -1] = self.model.origin[-1] + 2 * self.model.spacing[-1] rec_coordinates = np.empty((nrec, len(self.model.spacing))) rec_coordinates[:, 0] = np.linspace(0., self.model.domain_size[0], num=nrec) rec_coordinates[:, 1:] = src_coordinates[0, 1:] geometry = AcquisitionGeometry(self.model, rec_coordinates, src_coordinates, t0=t0, tn=tn, src_type='Gabor', f0=0.010) return geometry
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 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 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 create_geometry(model, tn, src_coordinates=None): 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] elif len(src_coordinates.shape) == 1: src_coordinates = np.expand_dims(src_coordinates, axis=0) 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.008).resample(1.75) return geometry
def viscoelastic_setup(shape=(50, 50), spacing=(15.0, 15.0), tn=500., space_order=4, nbl=10, constant=True, **kwargs): nrec = 2*shape[0] preset = 'constant-viscoelastic' if constant else 'layers-viscoelastic' model = demo_model(preset, space_order=space_order, shape=shape, nbl=nbl, 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.12) # Create solver object to provide relevant operators solver = ViscoelasticWaveSolver(model, geometry, 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 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 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 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 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 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 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 set_geometry(model, nsrc, nrec, f0, tn, t0=0): # Define acquisition geometry: sources # First, position source centrally in all dimensions, then set depth src_coordinates = np.empty((nsrc, 2)) src_coordinates[:, 0] = np.linspace(0, model.domain_size[0], num=nsrc) src_coordinates[:, 1] = 20. # Depth is 20m # Define acquisition geometry: receivers # Initialize receivers for synthetic and imaging data rec_coordinates = np.empty((nrec, 2)) rec_coordinates[:, 0] = np.linspace(0, model.domain_size[0], num=nrec) rec_coordinates[:, 1] = 20. # Geometry. Total simulation time, frequency and source type. geometry = AcquisitionGeometry(model, rec_coordinates, src_coordinates, t0, tn, f0=f0, src_type='Ricker') return geometry
origin = tuple([0. for _ in shape]) dtype = np.float32 kernel='OT2' space_order=6 m_i = to_model(np.array([4.0]*9), N_x=shape[0]).T model = Model(space_order=space_order, vp=m_i, origin=origin, shape=shape, dtype=dtype, spacing=spacing, nbpml=0) # Source and receiver geometries src_coordinates = np.zeros((1, len(spacing))) src_coordinates[0, :] = 0. src_coordinates[:, 0] = spacing[0]*500. rec_coordinates = np.zeros((num_receivers, len(spacing))) rec_coordinates[:, 0] = 500.*spacing[0]+dist_first_receiver+spacing_receivers*np.array(range(num_receivers)) rec_coordinates[0, :] = 0. geometry = AcquisitionGeometry(model, rec_coordinates, src_coordinates, t0=0.0, tn=tn, src_type='Ricker', f0=peak_frequency/1000.) # Create solver object to provide relevant operators solver = AcousticWaveSolver(model, geometry, kernel=kernel, space_order=space_order, autotune=args.autotune, dse=args.dse, dle=args.dle) save = False autotune = True print("Generating Amplitudes") for i, v in enumerate(vp): m = to_model(v, N_x=shape[0]).T #Define the basic Model container solver.model.vp = m rec, u, summary = solver.forward(save=save, autotune=args.autotune) #Resample to 'num_samples' samples and store amps.append(rec.resample(num=num_samples).data)
def processing1(): # Enable model presets here: preset = 'layers-isotropic' # A simple but cheap model (recommended) # preset = 'marmousi2d-isotropic' # A larger more realistic model # Standard preset with a simple two-layer model if preset == 'layers-isotropic': def create_model(grid=None): return demo_model('layers-isotropic', origin=(0., 0.), shape=(101, 101), spacing=(10., 10.), nbl=20, grid=grid, nlayers=2) filter_sigma = (1, 1) nshots = 21 nreceivers = 101 t0 = 0. tn = 1000. # Simulation last 1 second (1000 ms) f0 = 0.010 # Source peak frequency is 10Hz (0.010 kHz) # A more computationally demanding preset based on the 2D Marmousi model if preset == 'marmousi2d-isotropic': def create_model(grid=None): return demo_model('marmousi2d-isotropic', data_path='../../../../data/', grid=grid, nbl=20) filter_sigma = (6, 6) nshots = 301 # Need good covergae in shots, one every two grid points nreceivers = 601 # One recevier every grid point t0 = 0. tn = 3500. # Simulation last 3.5 second (3500 ms) f0 = 0.025 # Source peak frequency is 25Hz (0.025 kHz) #NBVAL_IGNORE_OUTPUT # Create true model from a preset model = create_model() # Create initial model and smooth the boundaries model0 = create_model(grid=model.grid) model0.vp = ndimage.gaussian_filter(model0.vp.data, sigma=filter_sigma, order=0) # Plot the true and initial model and the perturbation between them #plot_velocity(model) #plot_velocity(model0) #plot_perturbation(model0, model) #NBVAL_IGNORE_OUTPUT # Define acquisition geometry: source # First, position source centrally in all dimensions, then set depth src_coordinates = np.empty((nshots, 2), dtype=np.float32) src_coordinates[:, 0] = np.linspace(0., 1000, num=nshots) src_coordinates[:, 1] = 30. # Define acquisition geometry: receivers # Initialize receivers for synthetic and imaging data rec_coordinates = np.empty((nreceivers, 2)) rec_coordinates[:, 0] = np.linspace(0, model.domain_size[0], num=nreceivers) rec_coordinates[:, 1] = 30. # Geometry geometry = AcquisitionGeometry(model, rec_coordinates, src_coordinates, t0, tn, f0=.010, src_type='Ricker') # We can plot the time signature to see the wavelet #geometry.src.show() # Plot acquisition geometry #plot_velocity(model, source=geometry.src_positions, #receiver=geometry.rec_positions[::4, :]) # Compute synthetic data with forward operator solver = AcousticWaveSolver(model, geometry, space_order=4) true_d, _, _ = solver.forward(vp=model.vp) # Compute initial data with forward operator smooth_d, _, _ = solver.forward(vp=model0.vp) # Define gradient operator for imaging def ImagingOperator(model, image): # Define the wavefield with the size of the model and the time dimension v = TimeFunction(name='v', grid=model.grid, time_order=2, space_order=4) u = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=4, save=geometry.nt) # Defie the wave equation, but with a negated damping term eqn = model.m * v.dt2 - v.laplace + model.damp * v.dt.T # Use `solve` to rearrange the equation into a stencil expression stencil = Eq(v.backward, solve(eqn, v.backward)) # Define residual injection at the location of the forward receivers dt = model.critical_dt residual = PointSource(name='residual', grid=model.grid, time_range=geometry.time_axis, coordinates=geometry.rec_positions) res_term = residual.inject(field=v.backward, expr=residual * dt**2 / model.m) # Correlate u and v for the current time step and add it to the image image_update = Eq(image, image - u * v) return Operator([stencil] + res_term + [image_update], subs=model.spacing_map) # Start Dask cluster cluster = LocalCluster(n_workers=4, threads_per_worker=1) client = Client(cluster) all_current_workers = [w.pid for w in cluster.scheduler.workers.values()] #NBVAL_IGNORE_OUTPUT # Prepare the varying source locations source_locations = np.empty((nshots, 2), dtype=np.float32) source_locations[:, 0] = np.linspace(0., 1000, num=nshots) source_locations[:, 1] = 30. #plot_velocity(model, source=source_locations) #d_obs é o model.data 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 multi_shots_rtm(geometry, model0): image = Function(name='image', grid=model.grid) op_imaging = ImagingOperator(model, image) futures = [] inicio = time.time() for i in range(geometry.nsrc): # Geometry for current shot geometry_i = AcquisitionGeometry(geometry.model, geometry.rec_positions, geometry.src_positions[i, :], geometry.t0, geometry.tn, f0=geometry.f0, src_type=geometry.src_type) # Call serial FWI objective function for each shot location futures.append(client.submit(one_shot_rtm, geometry_i, model0)) # Wait for all workers to finish and collect function values and gradients wait(futures) fim = time.time() tempo = fim - inicio print("Demorou - Dask: ", tempo) for i in range(geometry.nsrc): #print('iteração', (i+1)) # plot_image(np.diff(image.data, axis=1)) op_imaging(u=futures[i].result()[0], v=futures[i].result()[1], vp=model0.vp, dt=model0.critical_dt, residual=futures[i].result()[2]) return image.data # Compute FWI gradient for 5 shots inicio = time.time() print("Começou Processing 1") imageData = multi_shots_rtm(geometry, model0) c = imageData.data fim = time.time() tempo = fim - inicio client.close() #NBVAL_IGNORE_OUTPUT #from examples.seismic import plot_image print("Demorou: ", tempo) # Plot the inverted image plot_image(np.diff(imageData, axis=1)) return imageData
else: src_coord[:, 0] = np.linspace(0, v.domain_size[0], num=params["Ns"]) src_coord[:, 1] = src_depth rec_coord = np.empty((params["Nr"], 2)) rec_coord[:, 0] = np.linspace(0, v.domain_size[0], num=params["Nr"]) rec_coord[:, 1] = rec_depth # Create the geometry objects for background velocity models src_dummy = np.empty((1, 2)) src_dummy[0, :] = src_coord[int(src_coord.shape[0] / 2), :] geometry = AcquisitionGeometry(v, rec_coord, src_dummy, t0, tn, f0=f0, src_type='Ricker') params["Nt"] = geometry.nt del src_dummy # Define a solver object solver = AcousticWaveSolver(v, geometry, space_order=params["so"]) ################################################################################################## # This part of the code generates the forward data using the two models and computes the residual ################################################################################################## dt = v.critical_dt
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
# First, position source centrally in all dimensions, then set depth src_coordinates = np.empty((1, 2)) src_coordinates[0, :] = np.array(model.domain_size) * .5 src_coordinates[0, 0] = 20. # Depth is 20m # Define acquisition geometry: receivers # Initialize receivers for synthetic and imaging data rec_coordinates = np.empty((nreceivers, 2)) rec_coordinates[:, 1] = np.linspace(0, model.domain_size[0], num=nreceivers) rec_coordinates[:, 0] = 980. # Geometry geometry = AcquisitionGeometry(model, rec_coordinates, src_coordinates, t0, tn, f0=f0, src_type='Ricker') # We can plot the time signature to see the wavelet geometry.src.show() # In[24]: # Plot acquisition geometry plot_velocity(model, source=geometry.src_positions, receiver=geometry.rec_positions[::4, :]) # ## True and smooth data # # We can generate shot records for the true and smoothed initial velocity models, since the difference between them will again form the basis of our imaging procedure.
def test_analytic_comparison_2d(self, dtype, so): """ Wnsure that the farfield response from the propagator matches analytic reponse in a wholespace. """ # Setup time / frequency nt = 1001 dt = 0.1 tmin = 0.0 tmax = dt * (nt - 1) fpeak = 0.090 t0w = 1.0 / fpeak omega = 2.0 * np.pi * fpeak # Model space_order = 8 npad = 50 dx = 0.5 shape = (801, 801) dtype = np.float64 qmin = 0.1 qmax = 100000 v0 = 1.5 init_damp = lambda fu, nbl: setup_w_over_q(fu, omega, qmin, qmax, nbl, sigma=0) o = tuple([0]*len(shape)) spacing = tuple([dx]*len(shape)) model = Model(origin=o, shape=shape, vp=v0, b=1.0, spacing=spacing, nbl=npad, space_order=space_order, bcs=init_damp) # Source and reciver coordinates src_coords = np.empty((1, 2), dtype=dtype) rec_coords = np.empty((1, 2), dtype=dtype) src_coords[0, :] = np.array(model.domain_size) * .5 rec_coords[0, :] = np.array(model.domain_size) * .5 + 60 geometry = AcquisitionGeometry(model, rec_coords, src_coords, t0=0.0, tn=tmax, src_type='Ricker', f0=fpeak) # Solver setup solver = SaIsoAcousticWaveSolver(model, geometry, space_order=space_order) # Numerical solution recNum, uNum, _ = solver.forward() # Analytic response def analytic_response(): """ Computes analytic solution of 2D acoustic wave-equation with Ricker wavelet peak frequency fpeak, temporal padding 20x per the accuracy notebook: examples/seismic/acoustic/accuracy.ipynb u(r,t) = 1/(2 pi) sum[ -i pi H_0^2(k,r) q(w) e^{i w t} dw where: r = sqrt{(x_s - x_r)^2 + (z_s - z_r)^2} w = 2 pi f q(w) = Fourier transform of Ricker source wavelet H_0^2(k,r) Hankel function of the second kind k = w/v (wavenumber) """ sx, sz = src_coords[0, :] rx, rz = rec_coords[0, :] ntpad = 20 * (nt - 1) + 1 tmaxpad = dt * (ntpad - 1) time_axis_pad = TimeAxis(start=tmin, stop=tmaxpad, step=dt) srcpad = RickerSource(name='srcpad', grid=model.grid, f0=fpeak, npoint=1, time_range=time_axis_pad, t0w=t0w) nf = int(ntpad / 2 + 1) df = 1.0 / tmaxpad faxis = df * np.arange(nf) # Take the Fourier transform of the source time-function R = np.fft.fft(srcpad.wavelet[:]) R = R[0:nf] nf = len(R) # Compute the Hankel function and multiply by the source spectrum U_a = np.zeros((nf), dtype=complex) for a in range(1, nf - 1): w = 2 * np.pi * faxis[a] r = np.sqrt((rx - sx)**2 + (rz - sz)**2) U_a[a] = -1j * np.pi * hankel2(0.0, w * r / v0) * R[a] # Do inverse fft on 0:dt:T and you have analytical solution U_t = 1.0/(2.0 * np.pi) * np.real(np.fft.ifft(U_a[:], ntpad)) # Note that the analytic solution is scaled by dx^2 to convert to pressure return (np.real(U_t) * (dx**2)), srcpad uAnaPad, srcpad = analytic_response() uAna = uAnaPad[0:nt] # Compute RMS and difference diff = (recNum.data - uAna) nrms = np.max(np.abs(recNum.data)) arms = np.max(np.abs(uAna)) drms = np.max(np.abs(diff)) info("Maximum absolute numerical,analytic,diff; %+12.6e %+12.6e %+12.6e" % (nrms, arms, drms)) # This isnt a very strict tolerance ... tol = 0.1 assert np.allclose(diff, 0.0, atol=tol)
src_coordinates[0, :] = np.array(model.domain_size) * .5 src_coordinates[0, -1] = 30. # Depth is 30m # Define acquisition geometry: receivers # Initialize receivers for synthetic and imaging data rec_coordinates = np.empty((nreceivers, 2)) rec_coordinates[:, 0] = np.linspace(0, model.domain_size[0], num=nreceivers) rec_coordinates[:, 1] = 30. # Geometry geometry = AcquisitionGeometry(model, rec_coordinates, src_coordinates, t0, tn, f0=.010, src_type='Ricker') # We can plot the time signature to see the wavelet geometry.src.show() # # True and smooth data # # We can now generate the shot record (receiver readings) corresponding to our true and initial models. The difference between these two records will be the basis of the imaging procedure. # # For this purpose we will use the same forward modelling operator that was introduced in the previous tutorial, provided by the `AcousticWaveSolver` utility class. This object instantiates a set of pre-defined operators according to an initial definition of the acquisition geometry, consisting of source and receiver symbols. The solver objects caches the individual operators and provides a slightly more high-level API that allows us to invoke the modelling modelling operators from the initial tutorial in a single line. In the following cells we use this to generate shot data by only specifying the respective model symbol `m` to use, and the solver will create and return a new `Receiver` object the represents the readings at the previously defined receiver coordinates. # In[5]: # Compute synthetic data with forward operator
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 demo_fwi(preset, **kwargs): # Method to return preset-setups for a fwi aplication shape = kwargs.pop('shape', (101, 101)) # Number of grid point (nx, nz) spacing = kwargs.pop('spacing', tuple([10. for _ in shape])) # Grid spacing in m origin = kwargs.pop('origin', tuple([0. for _ in shape])) # Defines relative source and receiver locations nshots = kwargs.pop('nshots', int(shape[0]/2)) # One every two grid points nreceivers = kwargs.pop('nreceivers', int(shape[0])) # One recevier every grid point t0 = kwargs.pop('t0', 0.) # Simulation starts at t=0 tn = kwargs.pop('tn', 3500.) # Simulation last 3.5 seconds (3500 ms) f0 = kwargs.pop('f0', 0.025) # Source peak frequency is 25Hz (0.025 kHz) if preset.lower() in ['marmousi2d-isotropic', 'm2d']: shape = (1601, 401) spacing = (7.5, 7.5) origin = (0., 0.) nshots = 301 nreceivers = 601 nbl = kwargs.pop('nbl', 20) resolution_scale = kwargs.pop('resolution_scale', 3.0) # Scale to which the shape is rescaled filter_sigma = kwargs.pop('filter_sigma', 2.0) # Sigma to which the data is smoothened # Build the model based on the preset data if resolution_scale != 1: true_model = low_res_marmousi(resolution_scale) else: true_model = demo_model('marmousi2d-isotropic', data_path='data/', grid=None, nbpml=20) # Create initial model by smooth the boundaries fwi_model0 = smoothen_model(true_model, filter_sigma) # Position source src_coordinates = np.empty((1, 2)) src_coordinates[0, :] = np.array(true_model.domain_size) * .5 src_coordinates[0, 1] = 20. # Depth is 20m # Initialize receivers for synthetic and imaging data rec_coordinates = np.empty((nreceivers, 2)) rec_coordinates[:, 0] = np.linspace(0, true_model.domain_size[0], num=nreceivers) rec_coordinates[:, 1] = 20. # Depth(m) # Prepare the varying source locations sources source_locations = np.empty((nshots, 2), dtype=np.float32) source_locations[:, 1] = 30. source_locations[:, 0] = np.linspace(0., 7500, num=nshots) # Ready up the Geometry geometry = AcquisitionGeometry(true_model, rec_coordinates, src_coordinates, t0, tn, f0=f0, src_type='Ricker') # Construct the Solver solver = AcousticWaveSolver(true_model, geometry, space_order=4) # Attribute the number of fwi iterations fwi_iterations = 20 elif preset.lower() in ['circle-isotropic', 'c2d']: nshots = 9 tn = 1000. f0 = 0.010 # Build the model based on the preset data true_model = demo_model('circle-isotropic', vp_circle=3.0, vp_background=2.5, origin=origin, shape=shape, spacing=spacing, nbl=40) # Create initial model by smooth the boundaries fwi_model0 = demo_model('circle-isotropic', vp_circle=2.5, vp_background=2.5, origin=origin, shape=shape, spacing=spacing, nbl=40, grid = true_model.grid) # Position source src_coordinates = np.empty((1, 2)) src_coordinates[0, :] = np.array(true_model.domain_size) * .5 src_coordinates[0, 0] = 20. # Depth is 20m # Initialize receivers for synthetic and imaging data rec_coordinates = np.empty((nreceivers, 2)) rec_coordinates[:, 1] = np.linspace(0, true_model.domain_size[0], num=nreceivers) rec_coordinates[:, 0] = 980. # Prepare the varying source locations sources source_locations = np.empty((nshots, 2), dtype=np.float32) source_locations[:, 0] = 30. source_locations[:, 1] = np.linspace(0., 1000, num=nshots) # Ready up the Geometry geometry = AcquisitionGeometry(true_model, rec_coordinates, src_coordinates, t0, tn, f0=f0, src_type='Ricker') # Construct the Solver solver = AcousticWaveSolver(true_model, geometry, space_order=4) # Attribute the number of fwi iterations fwi_iterations = 5 # Show the plots if kwargs.pop('show_plots', False): print("True Model:") plot_velocity(true_model) print("FWI Model 0:") plot_velocity(fwi_model0) #print("True Model ad FWI Model 0 difference:") #plot_perturbation(fwi_model0, true_model) print("Sources and receivers positions:") plot_velocity(true_model, source=geometry.src_positions, receiver=geometry.rec_positions[::4, :]) print("Sources locations:") plot_velocity(true_model, source=source_locations) print("Geometry:") geometry.src.show() return true_model, fwi_model0, nshots, nreceivers, src_coordinates, rec_coordinates,\ source_locations, geometry, solver, fwi_iterations