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 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()