Esempio n. 1
0
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)
Esempio n. 2
0
    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