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, shape=shape, nbpml=nbpml, **(presets[mkey])) # Derive timestepping from model spacing dt = model.critical_dt * (1.73 if kernel == 'OT4' else 1.0) 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='rec', 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, kernel=kernel, space_order=space_order) # Create adjoint receiver symbol srca = Receiver(name='srca', grid=model.grid, ntime=solver.source.nt, 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_adjoint_F(self, mkey, shape, kernel, space_order, nbpml): """ Adjoint test for the forward modeling operator. The forward modeling operator F generates a shot record (measurements) from a source while the adjoint of F generates measurments at the source location from data. This test uses the conventional dot test: < Fx, y> = <x, F^T y> """ 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.reshape(-1))**2 info('<Ax,y>: %f, <x, A^Ty>: %f, difference: %4.4e, ratio: %f' % (term1, term2, (term1 - term2) / term1, term1 / term2)) assert np.isclose((term1 - term2) / term1, 0., rtol=1.e-10)
class FT(odl.Operator): def __init__(self, model, src, rec_geom, rec_data, 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.data.data[:] = rec_data 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.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(FT, self).__init__(domain=domain, range=im) def _call(self, x, out=None): u_data = copy.copy( x.data.reshape( (3, self.model.grid.shape[0], self.model.grid.shape[1]))) u_in = TimeFunction(name="u_in", grid=self.model.grid, time_order=2, space_order=self.space_order) u_in.data[:] = u_data self.solver.adjoint(m=self.model.m, rec=self.data, time_m=self.time_start, time=self.time_end, v=u_in) if out is not None: out.data[:] = u_in.data.reshape(1, self.grid.shape[0], self.grid.shape[1]) else: out = Function(name="u_out", grid=self.grid, space_order=self.space_order) out.data[:] = u_in.data.reshape(1, self.grid.shape[0], self.grid.shape[1]) return out @property def adjoint(self): return F(self.model, self.source, self.data.coordinates.data, space_order=self.space_order, **self.kwargs) def opnorm(self): return 1