def forward_born(model, src_coords, wavelet, rec_coords, space_order=8, nb=40, isic=False, dt=None, free_surface=False):
    clear_cache()

    # Parameters
    nt = wavelet.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, rho, dm, damp = model.m, model.rho, model.dm, model.damp

    # Create the forward and linearized wavefield
    u = TimeFunction(name="u", grid=model.grid, time_order=2, space_order=space_order)
    du = TimeFunction(name="du", grid=model.grid, time_order=2, space_order=space_order)
    if len(model.shape) == 2:
        x,y = u.space_dimensions
    else:
        x,y,z = u.space_dimensions

    # Set up PDEs and rearrange
    ulaplace, rho = acoustic_laplacian(u, rho)
    dulaplace, _ = acoustic_laplacian(du, rho)

    if isic:
        # Sum ((u.dx * d, / rho).dx for x in dimensions)
        # space_order//2  so that u.dx.dx has the same radius as u.laplace
        du_aux = sum([first_derivative(first_derivative(u, dim=d, fd_order=space_order//2) * dm / rho, fd_order=space_order//2, dim=d)
                      for d in u.space_dimensions])
        lin_source = dm /rho * u.dt2 * m - du_aux
    else:
        lin_source = dm / rho * u.dt2

    stencil_u = damp * (2.0 * u - damp * u.backward + dt**2 * rho / m * ulaplace)
    stencil_du = damp * (2.0 * du - damp * du.backward + dt**2 * rho / m * (dulaplace - lin_source))

    expression_u = [Eq(u.forward, stencil_u)]
    expression_du = [Eq(du.forward, stencil_du)]

    # Define source symbol with wavelet
    src = PointSource(name='src', grid=model.grid, ntime=nt, coordinates=src_coords)
    src.data[:] = wavelet[:]
    src_term = src.inject(field=u.forward, expr=src * rho * dt**2 / m)

    # Define receiver symbol
    rec = Receiver(name='rec', grid=model.grid, ntime=nt, coordinates=rec_coords)
    rec_term = rec.interpolate(expr=du)

    expression = expression_u + expression_du + src_term + rec_term

    # Free surface
    if free_surface is True:
        expression += freesurface(u, space_order//2, model.nbpml)
        expression += freesurface(du, space_order//2, model.nbpml)

    # Create operator and run
    set_log_level('ERROR')
    subs = model.spacing_map
    subs[u.grid.time_dim.spacing] = dt
    op = Operator(expression, subs=subs, dse='advanced', dle='advanced')
    op()

    return rec.data
Ejemplo n.º 2
0
    def __init__(self,
                 model,
                 data,
                 source,
                 nbpml=40,
                 t_order=2,
                 s_order=8,
                 tsave=4.0):
        set_log_level('ERROR')
        self.model = model
        self.t_order = t_order
        self.s_order = s_order
        self.data = data
        self.source = source
        self.dtype = np.float32
        # Time step can be \sqrt{3}=1.73 bigger with 4th order
        self.dt = self.model.critical_dt
        self.tsave = tsave

        if len(self.model.shape
               ) == 2 and self.source.receiver_coords.shape[1] == 3:
            self.source.receiver_coords = np.delete(
                self.source.receiver_coords, 1, 1)
        if len(self.model.shape
               ) == 2 and self.data.receiver_coords.shape[1] == 3:
            self.data.receiver_coords = np.delete(self.data.receiver_coords, 1,
                                                  1)
def adjoint_modeling(model, src_coords, rec_coords, rec_data, space_order=8, nb=40, free_surface=False, dt=None):
    clear_cache()

    # If wavelet is file, read it
    if isinstance(rec_data, str):
        rec_data = np.load(rec_data)

    # Parameters
    nt = rec_data.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, rho, damp = model.m, model.rho, model.damp

    # Create the adjoint wavefield
    if src_coords is not None:
        v = TimeFunction(name="v", grid=model.grid, time_order=2, space_order=space_order)
    else:
        v = TimeFunction(name="v", grid=model.grid, time_order=2, space_order=space_order, save=nt)

    # Set up PDE and rearrange
    vlaplace, rho = acoustic_laplacian(v, rho)

    # Input data is wavefield
    full_q = 0
    if isinstance(rec_data, TimeFunction):
        wf_rec = TimeFunction(name='wf_rec', grid=model.grid, time_order=2, space_order=space_order, save=nt)
        wf_rec._data = rec_data._data
        full_q = wf_rec

    stencil = damp * (2.0 * v - damp * v.forward + dt**2 * rho / m * (vlaplace + full_q))
    expression = [Eq(v.backward, stencil)]

    # Free surface
    if free_surface is True:
       expression += freesurface(v, space_order//2, model.nbpml, forward=False)

    # Adjoint source is injected at receiver locations
    if rec_coords is not None:
        rec = Receiver(name='rec', grid=model.grid, ntime=nt, coordinates=rec_coords)
        rec.data[:] = rec_data[:]
        adj_src = rec.inject(field=v.backward, expr=rec * rho * dt**2 / m)
        expression += adj_src

    # Data is sampled at source locations
    if src_coords is not None:
        src = PointSource(name='src', grid=model.grid, ntime=nt, coordinates=src_coords)
        adj_rec = src.interpolate(expr=v)
        expression += adj_rec

    # Create operator and run
    set_log_level('ERROR')
    subs = model.spacing_map
    subs[v.grid.time_dim.spacing] = dt
    op = Operator(expression, subs=subs, dse='advanced', dle='advanced')
    op()
    if src_coords is None:
        return v
    else:
        return src.data
def forward_freq_modeling(model, src_coords, wavelet, rec_coords, freq, space_order=8, nb=40, dt=None, factor=None):
    # Forward modeling with on-the-fly DFT of forward wavefields
    clear_cache()

    # Parameters
    nt = wavelet.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, rho, damp = model.m, model.rho, model.damp

    freq_dim = Dimension(name='freq_dim')
    time = model.grid.time_dim
    if factor is None:
        factor = int(1 / (dt*4*np.max(freq)))
        tsave = ConditionalDimension(name='tsave', parent=model.grid.time_dim, factor=factor)
    if factor==1:
        tsave = time
    else:
        tsave = ConditionalDimension(name='tsave', parent=model.grid.time_dim, factor=factor)
    print("DFT subsampling factor: ", factor)

    # Create wavefields
    nfreq = freq.shape[0]
    u = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=space_order)
    f = Function(name='f', dimensions=(freq_dim,), shape=(nfreq,))
    f.data[:] = freq[:]
    ufr = Function(name='ufr', dimensions=(freq_dim,) + u.indices[1:], shape=(nfreq,) + model.shape_domain)
    ufi = Function(name='ufi', dimensions=(freq_dim,) + u.indices[1:], shape=(nfreq,) + model.shape_domain)

    ulaplace, rho = acoustic_laplacian(u, rho)

    # Set up PDE and rearrange
    stencil = damp * (2.0 * u - damp * u.backward + dt**2 * rho / m * ulaplace)
    expression = [Eq(u.forward, stencil)]
    expression += [Inc(ufr, factor*u*cos(2*np.pi*f*tsave*factor*dt))]
    expression += [Inc(ufi, -factor*u*sin(2*np.pi*f*tsave*factor*dt))]

    # Source symbol with input wavelet
    src = PointSource(name='src', grid=model.grid, ntime=nt, coordinates=src_coords)
    src.data[:] = wavelet[:]
    src_term = src.inject(field=u.forward, expr=src * dt**2 / m)

    # Data is sampled at receiver locations
    rec = Receiver(name='rec', grid=model.grid, ntime=nt, coordinates=rec_coords)
    rec_term = rec.interpolate(expr=u)

    # Create operator and run
    set_log_level('ERROR')
    expression += src_term + rec_term
    subs = model.spacing_map
    subs[u.grid.time_dim.spacing] = dt
    op = Operator(expression, subs=subs, dse='advanced', dle='advanced',
                  name="Forward%s" % randint(1e5))
    op()

    return rec.data, ufr, ufi
Ejemplo n.º 5
0
def test_timesteps_per_at_run():
    """
    Check that each autotuning run (ie with a given block shape) takes
    ``autotuning.options['at_squeezer'] - data.time_order`` timesteps.
    in an operator performing an increment such as
    ``a[t + timeorder, ...] = f(a[t, ...], ...)``.
    """

    buffer = StringIO()
    temporary_handler = logging.StreamHandler(buffer)
    logger.addHandler(temporary_handler)
    set_log_level('DEBUG')

    shape = (30, 30, 30)
    grid = Grid(shape=shape)
    x, y, z = grid.dimensions
    t = grid.stepping_dim

    # Function
    infield = Function(name='infield', grid=grid)
    infield.data[:] = np.arange(reduce(mul, shape),
                                dtype=np.int32).reshape(shape)
    outfield = Function(name='outfield', grid=grid)
    stencil = Eq(outfield.indexify(),
                 outfield.indexify() + infield.indexify() * 3.0)
    op = Operator(stencil, dle=('blocking', {'blockalways': True}))
    op(infield=infield, outfield=outfield, autotune=True)
    out = [i for i in buffer.getvalue().split('\n') if 'AutoTuner:' in i]
    assert len(out) == 4
    assert all('in 1 time steps' in i for i in out)
    buffer.truncate(0)

    # TimeFunction with increasing time order
    for to in [1, 2, 4]:
        infield = TimeFunction(name='infield', grid=grid, time_order=to)
        infield.data[:] = np.arange(reduce(mul, infield.shape),
                                    dtype=np.int32).reshape(infield.shape)
        outfield = TimeFunction(name='outfield', grid=grid, time_order=to)
        stencil = Eq(outfield.indexed[t + to, x, y, z],
                     outfield.indexify() + infield.indexify() * 3.0)
        op = Operator(stencil, dle=('blocking', {'blockalways': True}))
        op(infield=infield, outfield=outfield, autotune=True)
        out = [i for i in buffer.getvalue().split('\n') if 'AutoTuner:' in i]
        expected = options['at_squeezer'] - to
        assert len(out) == 4
        assert all('in %d time steps' % expected in i for i in out)
        buffer.truncate(0)

    logger.removeHandler(temporary_handler)

    temporary_handler.flush()
    temporary_handler.close()
    buffer.flush()
    buffer.close()
    set_log_level('INFO')
Ejemplo n.º 6
0
def adjoint_modeling(model,
                     src_coords,
                     rec_coords,
                     rec_data,
                     space_order=8,
                     nb=40,
                     dt=None):
    clear_cache()

    # Parameters
    nt = rec_data.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, damp = model.m, model.damp

    # Create the adjoint wavefield
    v = TimeFunction(name="v",
                     grid=model.grid,
                     time_order=2,
                     space_order=space_order)

    # Set up PDE and rearrange
    eqn = m * v.dt2 - v.laplace - damp * v.dt
    stencil = solve(eqn, v.backward)[0]
    expression = [Eq(v.backward, stencil)]

    # Adjoint source is injected at receiver locations
    rec = Receiver(name='rec',
                   grid=model.grid,
                   ntime=nt,
                   coordinates=rec_coords)
    rec.data[:] = rec_data[:]
    adj_src = rec.inject(field=v.backward,
                         offset=model.nbpml,
                         expr=rec * dt**2 / m)

    # Data is sampled at source locations
    src = PointSource(name='src',
                      grid=model.grid,
                      ntime=nt,
                      coordinates=src_coords)
    adj_rec = src.interpolate(expr=v, offset=model.nbpml)

    # Create operator and run
    set_log_level('ERROR')
    expression += adj_src + adj_rec
    op = Operator(expression,
                  subs=model.spacing_map,
                  dse='advanced',
                  dle='advanced',
                  name="Backward%s" % randint(1e5))
    op(dt=dt)

    return src.data
Ejemplo n.º 7
0
def test_at_is_actually_working(shape, expected):
    """
    Check that autotuning is actually running when switched on,
    in both 2D and 3D operators.
    """
    grid = Grid(shape=shape)

    buffer = StringIO()
    temporary_handler = logging.StreamHandler(buffer)
    logger.addHandler(temporary_handler)
    set_log_level('DEBUG')

    infield = Function(name='infield', grid=grid)
    infield.data[:] = np.arange(reduce(mul, shape),
                                dtype=np.int32).reshape(shape)
    outfield = Function(name='outfield', grid=grid)
    stencil = Eq(outfield.indexify(),
                 outfield.indexify() + infield.indexify() * 3.0)
    op = Operator(stencil,
                  dle=('blocking', {
                      'blockinner': True,
                      'blockalways': True
                  }))

    # Expected 3 AT attempts for the given shape
    op(infield=infield, outfield=outfield, autotune=True)
    out = [i for i in buffer.getvalue().split('\n') if 'AutoTuner:' in i]
    assert len(out) == 4

    # Now try the same with aggressive autotuning, which tries 9 more cases
    configuration.core['autotuning'] = 'aggressive'
    op(infield=infield, outfield=outfield, autotune=True)
    out = [i for i in buffer.getvalue().split('\n') if 'AutoTuner:' in i]
    assert len(out) == expected
    configuration.core['autotuning'] = configuration.core._defaults[
        'autotuning']

    logger.removeHandler(temporary_handler)

    temporary_handler.flush()
    temporary_handler.close()
    buffer.flush()
    buffer.close()
    set_log_level('INFO')
def forward_modeling(model, src_coords, wavelet, rec_coords, save=False, space_order=8, nb=40, free_surface=False, op_return=False, u_return=False, dt=None, tsub_factor=1):
    clear_cache()

    # If wavelet is file, read it
    if isinstance(wavelet, str):
        wavelet = np.load(wavelet)

    # Parameters
    nt = wavelet.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, rho, damp = model.m, model.rho, model.damp

    # Create the forward wavefield
    if save is False and rec_coords is not None:
        u = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=space_order)
        eqsave = []
    elif save is True and tsub_factor > 1:
        u = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=space_order)
        time_subsampled = ConditionalDimension(name='t_sub', parent=u.grid.time_dim, factor=tsub_factor)
        nsave = (nt-1)//tsub_factor + 2
        usave = TimeFunction(name='us', grid=model.grid, time_order=2, space_order=space_order, time_dim=time_subsampled, save=nsave)
        eqsave = [Eq(usave.forward, u.forward)]
    else:
        u = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=space_order, save=nt)
        eqsave = []

    # Set up PDE
    ulaplace, rho = acoustic_laplacian(u, rho)
    stencil = damp * ( 2.0 * u - damp * u.backward + dt**2 * rho / m * ulaplace)

    # Input source is wavefield
    if isinstance(wavelet, TimeFunction):
        wf_src = TimeFunction(name='wf_src', grid=model.grid, time_order=2, space_order=space_order, save=nt)
        wf_src._data = wavelet._data
        stencil -= wf_src

    # Rearrange expression
    expression = [Eq(u.forward, stencil)]

     # Data is sampled at receiver locations
    if rec_coords is not None:
        rec = Receiver(name='rec', grid=model.grid, ntime=nt, coordinates=rec_coords)
        rec_term = rec.interpolate(expr=u)
        expression += rec_term

    # Create operator and run
    if save:
        expression += eqsave

    # Free surface
    kwargs = dict()
    if free_surface is True:
        expression += freesurface(u, space_order//2, model.nbpml)

    # Source symbol with input wavelet
    if src_coords is not None:
        src = PointSource(name='src', grid=model.grid, ntime=nt, coordinates=src_coords)
        src.data[:] = wavelet[:]
        src_term = src.inject(field=u.forward, expr=src * rho * dt**2 / m)
        expression += src_term

    # Create operator and run
    set_log_level('ERROR')
    subs = model.spacing_map
    subs[u.grid.time_dim.spacing] = dt
    op = Operator(expression, subs=subs, dse='advanced', dle='advanced')

    # Return data and wavefields
    if op_return is False:
        op()
        if save is True and tsub_factor > 1:
            if rec_coords is None:
                return usave
            else:
                return rec.data, usave
        else:
            if rec_coords is None:
                return u
            else:
                return rec.data, u

    # For optimal checkpointing, return operator only
    else:
        return op
Ejemplo n.º 9
0
def adjoint_freq_born(model,
                      rec_coords,
                      rec_data,
                      freq,
                      ufr,
                      ufi,
                      space_order=8,
                      nb=40,
                      dt=None,
                      isic=False,
                      factor=None):
    clear_cache()

    # Parameters
    nt = rec_data.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, damp = model.m, model.damp
    nfreq = ufr.shape[0]
    time = model.grid.time_dim
    if factor is None:
        factor = int(1 / (dt * 4 * np.max(freq)))
        tsave = ConditionalDimension(name='tsave',
                                     parent=model.grid.time_dim,
                                     factor=factor)
    if factor == 1:
        tsave = time
    else:
        tsave = ConditionalDimension(name='tsave',
                                     parent=model.grid.time_dim,
                                     factor=factor)
    dtf = factor * dt
    ntf = factor / nt
    print("DFT subsampling factor: ", factor)

    # Create the forward and adjoint wavefield
    v = TimeFunction(name='v',
                     grid=model.grid,
                     time_order=2,
                     space_order=space_order)
    f = Function(name='f', dimensions=(ufr.indices[0], ), shape=(nfreq, ))
    f.data[:] = freq[:]
    gradient = Function(name="gradient", grid=model.grid)

    # Set up PDE and rearrange
    eqn = m * v.dt2 - v.laplace - damp * v.dt
    stencil = solve(eqn, v.backward, simplify=False, rational=False)[0]
    expression = [Eq(v.backward, stencil)]

    # Data at receiver locations as adjoint source
    rec = Receiver(name='rec',
                   grid=model.grid,
                   ntime=nt,
                   coordinates=rec_coords)
    rec.data[:] = rec_data[:]
    adj_src = rec.inject(field=v.backward,
                         offset=model.nbpml,
                         expr=rec * dt**2 / m)

    # Gradient update
    if isic is True:
        if len(model.shape) == 2:
            gradient_update = [
                Eq(
                    gradient, gradient + (2 * np.pi * f)**2 * ntf *
                    (ufr * cos(2 * np.pi * f * tsave * dtf) -
                     ufi * sin(2 * np.pi * f * tsave * dtf)) * v * model.m -
                    (ufr.dx * cos(2 * np.pi * f * tsave * dtf) -
                     ufi.dx * sin(2 * np.pi * f * tsave * dtf)) * v.dx * ntf -
                    (ufr.dy * cos(2 * np.pi * f * tsave * dtf) -
                     ufi.dy * sin(2 * np.pi * f * tsave * dtf)) * v.dy * ntf)
            ]
        else:
            gradient_update = [
                Eq(
                    gradient, gradient + (2 * np.pi * f)**2 * ntf *
                    (ufr * cos(2 * np.pi * f * tsave * dtf) -
                     ufi * sin(2 * np.pi * f * tsave * dtf)) * v * model.m -
                    (ufr.dx * cos(2 * np.pi * f * tsave * dtf) -
                     ufi.dx * sin(2 * np.pi * f * tsave * dtf)) * v.dx * ntf -
                    (ufr.dy * cos(2 * np.pi * f * tsave * dtf) -
                     ufi.dy * sin(2 * np.pi * f * tsave * dtf)) * v.dy * ntf -
                    (ufr.dz * cos(2 * np.pi * f * tsave * dtf) -
                     ufi.dz * sin(2 * np.pi * f * tsave * dtf)) * v.dz * ntf)
            ]
    else:
        gradient_update = [
            Eq(
                gradient, gradient + (2 * np.pi * f)**2 / nt *
                (ufr * cos(2 * np.pi * f * tsave * dtf) -
                 ufi * sin(2 * np.pi * f * tsave * dtf)) * v)
        ]

    # Create operator and run
    set_log_level('ERROR')
    expression += adj_src + gradient_update
    subs = model.spacing_map
    subs[v.grid.time_dim.spacing] = dt
    op = Operator(expression,
                  subs=subs,
                  dse='advanced',
                  dle='advanced',
                  name="Gradient%s" % randint(1e5))
    op()
    clear_cache()
    return gradient.data
Ejemplo n.º 10
0
def adjoint_born(model,
                 rec_coords,
                 rec_data,
                 u=None,
                 op_forward=None,
                 is_residual=False,
                 space_order=8,
                 nb=40,
                 isic=False,
                 dt=None,
                 n_checkpoints=None,
                 maxmem=None):
    clear_cache()

    # Parameters
    nt = rec_data.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, rho, damp = model.m, model.rho, model.damp

    # Create adjoint wavefield and gradient
    v = TimeFunction(name='v',
                     grid=model.grid,
                     time_order=2,
                     space_order=space_order)
    gradient = Function(name='gradient', grid=model.grid)

    # Set up PDE and rearrange
    vlaplace, rho = acoustic_laplacian(v, rho)
    H = symbols('H')
    eqn = m / rho * v.dt2 - H - damp * v.dt
    stencil = solve(eqn, v.backward, simplify=False, rational=False)[0]
    expression = [Eq(v.backward, stencil.subs({H: vlaplace}))]

    # Data at receiver locations as adjoint source
    rec_g = Receiver(name='rec_g',
                     grid=model.grid,
                     ntime=nt,
                     coordinates=rec_coords)
    if op_forward is None:
        rec_g.data[:] = rec_data[:]
    adj_src = rec_g.inject(field=v.backward,
                           offset=model.nbpml,
                           expr=rec_g * rho * dt**2 / m)

    # Gradient update
    if u is None:
        u = TimeFunction(name='u',
                         grid=model.grid,
                         time_order=2,
                         space_order=space_order)
    if isic is not True:
        gradient_update = [Eq(gradient, gradient - dt * u.dt2 / rho * v)]
    else:
        # sum u.dx * v.dx fo x in dimensions.
        # space_order//2
        diff_u_v = sum([
            first_derivative(u, dim=d, order=space_order // 2) *
            first_derivative(v, dim=d, order=space_order // 2)
            for d in u.space_dimensions
        ])
        gradient_update = [
            Eq(gradient, gradient - dt * (u * v.dt2 * m + diff_u_v) / rho)
        ]

    # Create operator and run
    set_log_level('ERROR')
    expression += adj_src + gradient_update
    subs = model.spacing_map
    subs[u.grid.time_dim.spacing] = dt
    op = Operator(expression,
                  subs=subs,
                  dse='advanced',
                  dle='advanced',
                  name="Gradient%s" % randint(1e5))

    # Optimal checkpointing
    if op_forward is not None:
        rec = Receiver(name='rec',
                       grid=model.grid,
                       ntime=nt,
                       coordinates=rec_coords)
        cp = DevitoCheckpoint([u])
        if maxmem is not None:
            n_checkpoints = int(
                np.floor(maxmem * 10**6 / (cp.size * u.data.itemsize)))
        wrap_fw = CheckpointOperator(op_forward, u=u, m=model.m, rec=rec)
        wrap_rev = CheckpointOperator(op, u=u, v=v, m=model.m, rec_g=rec_g)

        # Run forward
        wrp = Revolver(cp, wrap_fw, wrap_rev, n_checkpoints, nt - 2)
        wrp.apply_forward()

        # Residual and gradient
        if is_residual is True:  # input data is already the residual
            rec_g.data[:] = rec_data[:]
        else:
            rec_g.data[:] = rec.data[:] - rec_data[:]  # input is observed data
            fval = .5 * np.dot(rec_g.data[:].flatten(),
                               rec_g.data[:].flatten()) * dt
        wrp.apply_reverse()
    else:
        op()
    clear_cache()

    if op_forward is not None and is_residual is not True:
        return fval, gradient.data
    else:
        return gradient.data
Ejemplo n.º 11
0
def adjoint_freq_born(model,
                      rec_coords,
                      rec_data,
                      freq,
                      ufr,
                      ufi,
                      space_order=8,
                      nb=40,
                      dt=None):
    clear_cache()

    # Parameters
    nt = rec_data.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, damp = model.m, model.damp
    nfreq = ufr.shape[0]
    time = model.grid.time_dim

    # Create the forward and adjoint wavefield
    v = TimeFunction(name='v',
                     grid=model.grid,
                     time_order=2,
                     space_order=space_order)
    f = Function(name='f', dimensions=(ufr.indices[0], ), shape=(nfreq, ))
    f.data[:] = freq[:]
    gradient = Function(name="gradient", grid=model.grid)

    # Set up PDE and rearrange
    eqn = m * v.dt2 - v.laplace - damp * v.dt
    stencil = solve(eqn, v.backward)[0]
    expression = [Eq(v.backward, stencil)]

    # Data at receiver locations as adjoint source
    rec = Receiver(name='rec',
                   grid=model.grid,
                   ntime=nt,
                   coordinates=rec_coords)
    rec.data[:] = rec_data[:]
    adj_src = rec.inject(field=v.backward,
                         offset=model.nbpml,
                         expr=rec * dt**2 / m)

    # Gradient update
    gradient_update = [
        Eq(
            gradient, gradient + (2 * np.pi * f)**2 / nt *
            (ufr * cos(2 * np.pi * f * time * dt) -
             ufi * sin(2 * np.pi * f * time * dt)) * v)
    ]

    # Create operator and run
    set_log_level('ERROR')
    expression += adj_src + gradient_update
    op = Operator(expression,
                  subs=model.spacing_map,
                  dse='advanced',
                  dle='advanced',
                  name="Gradient%s" % randint(1e5))
    op(dt=dt)
    clear_cache()

    return gradient.data
Ejemplo n.º 12
0
def forward_freq_modeling(model,
                          src_coords,
                          wavelet,
                          rec_coords,
                          freq,
                          space_order=8,
                          nb=40,
                          dt=None):
    # Forward modeling with on-the-fly DFT of forward wavefields
    clear_cache()

    # Parameters
    nt = wavelet.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, damp = model.m, model.damp
    freq_dim = Dimension(name='freq_dim')
    time = model.grid.time_dim

    # Create wavefields
    nfreq = freq.shape[0]
    u = TimeFunction(name='u',
                     grid=model.grid,
                     time_order=2,
                     space_order=space_order)
    f = Function(name='f', dimensions=(freq_dim, ), shape=(nfreq, ))
    f.data[:] = freq[:]
    ufr = Function(name='ufr',
                   dimensions=(freq_dim, ) + u.indices[1:],
                   shape=(nfreq, ) + model.shape_domain)
    ufi = Function(name='ufi',
                   dimensions=(freq_dim, ) + u.indices[1:],
                   shape=(nfreq, ) + model.shape_domain)

    # Set up PDE and rearrange
    eqn = m * u.dt2 - u.laplace + damp * u.dt
    stencil = solve(eqn, u.forward)[0]
    expression = [Eq(u.forward, stencil)]
    expression += [Eq(ufr, ufr + u * cos(2 * np.pi * f * time * dt))]
    expression += [Eq(ufi, ufi - u * sin(2 * np.pi * f * time * dt))]

    # Source symbol with input wavelet
    src = PointSource(name='src',
                      grid=model.grid,
                      ntime=nt,
                      coordinates=src_coords)
    src.data[:] = wavelet[:]
    src_term = src.inject(field=u.forward,
                          offset=model.nbpml,
                          expr=src * dt**2 / m)

    # Data is sampled at receiver locations
    rec = Receiver(name='rec',
                   grid=model.grid,
                   ntime=nt,
                   coordinates=rec_coords)
    rec_term = rec.interpolate(expr=u, offset=model.nbpml)

    # Create operator and run
    set_log_level('ERROR')
    expression += src_term + rec_term
    op = Operator(expression,
                  subs=model.spacing_map,
                  dse='advanced',
                  dle='advanced',
                  name="Forward%s" % randint(1e5))
    op(dt=dt)

    return rec.data, ufr, ufi
Ejemplo n.º 13
0
def adjoint_born(model,
                 rec_coords,
                 rec_data,
                 u=None,
                 op_forward=None,
                 is_residual=False,
                 space_order=8,
                 nb=40,
                 isic=False,
                 dt=None):
    clear_cache()

    # Parameters
    nt = rec_data.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, damp = model.m, model.damp

    # Create adjoint wavefield and gradient
    v = TimeFunction(name='v',
                     grid=model.grid,
                     time_order=2,
                     space_order=space_order)
    gradient = Function(name='gradient', grid=model.grid)

    # Set up PDE and rearrange
    eqn = m * v.dt2 - v.laplace - damp * v.dt
    stencil = solve(eqn, v.backward)[0]
    expression = [Eq(v.backward, stencil)]

    # Data at receiver locations as adjoint source
    rec_g = Receiver(name='rec_g',
                     grid=model.grid,
                     ntime=nt,
                     coordinates=rec_coords)
    if op_forward is None:
        rec_g.data[:] = rec_data[:]
    adj_src = rec_g.inject(field=v.backward,
                           offset=model.nbpml,
                           expr=rec_g * dt**2 / m)

    # Gradient update
    if u is None:
        u = TimeFunction(name='u',
                         grid=model.grid,
                         time_order=2,
                         space_order=space_order)

    if isic is not True:
        gradient_update = [Eq(gradient, gradient - u * v.dt2)
                           ]  # zero-lag cross-correlation imaging condition
    else:
        # linearized inverse scattering imaging condition (Op't Root et al. 2010; Whitmore and Crawley 2012)
        if len(model.shape) == 2:
            gradient_update = [
                Eq(gradient,
                   gradient - (u * v.dt2 * m + u.dx * v.dx + u.dy * v.dy))
            ]
        else:
            gradient_update = [
                Eq(
                    gradient, gradient -
                    (u * v.dt2 * m + u.dx * v.dx + u.dy * v.dy + u.dz * v.dz))
            ]

    # Create operator and run
    set_log_level('ERROR')
    expression += adj_src + gradient_update
    op = Operator(expression,
                  subs=model.spacing_map,
                  dse='advanced',
                  dle='advanced',
                  name="Gradient%s" % randint(1e5))

    # Optimal checkpointing
    if op_forward is not None:
        rec = Receiver(name='rec',
                       grid=model.grid,
                       ntime=nt,
                       coordinates=rec_coords)
        cp = DevitoCheckpoint([u])
        n_checkpoints = None
        wrap_fw = CheckpointOperator(op_forward,
                                     u=u,
                                     m=model.m.data,
                                     rec=rec,
                                     dt=dt)
        wrap_rev = CheckpointOperator(op,
                                      u=u,
                                      v=v,
                                      m=model.m.data,
                                      rec_g=rec_g,
                                      dt=dt)

        # Run forward
        wrp = Revolver(cp, wrap_fw, wrap_rev, n_checkpoints, nt - 2)
        wrp.apply_forward()

        # Residual and gradient
        if is_residual is True:  # input data is already the residual
            rec_g.data[:] = rec_data[:]
        else:
            rec_g.data[:] = rec.data[:] - rec_data[:]  # input is observed data
            fval = .5 * np.linalg.norm(rec_g.data[:])**2
        wrp.apply_reverse()
    else:
        op(dt=dt)
    clear_cache()

    if op_forward is not None and is_residual is not True:
        return fval, gradient.data
    else:
        return gradient.data
Ejemplo n.º 14
0
def forward_modeling(model,
                     src_coords,
                     wavelet,
                     rec_coords,
                     save=False,
                     space_order=8,
                     nb=40,
                     op_return=False,
                     dt=None):
    clear_cache()

    # Parameters
    nt = wavelet.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, damp = model.m, model.damp

    # Create the forward wavefield
    if save is False:
        u = TimeFunction(name='u',
                         grid=model.grid,
                         time_order=2,
                         space_order=space_order)
    else:
        u = TimeFunction(name='u',
                         grid=model.grid,
                         time_order=2,
                         space_order=space_order,
                         save=nt)

    # Set up PDE and rearrange
    eqn = m * u.dt2 - u.laplace + damp * u.dt
    stencil = solve(eqn, u.forward)[0]
    expression = [Eq(u.forward, stencil)]

    # Source symbol with input wavelet
    src = PointSource(name='src',
                      grid=model.grid,
                      ntime=nt,
                      coordinates=src_coords)
    src.data[:] = wavelet[:]
    src_term = src.inject(field=u.forward,
                          offset=model.nbpml,
                          expr=src * dt**2 / m)

    # Data is sampled at receiver locations
    rec = Receiver(name='rec',
                   grid=model.grid,
                   ntime=nt,
                   coordinates=rec_coords)
    rec_term = rec.interpolate(expr=u, offset=model.nbpml)

    # Create operator and run
    set_log_level('ERROR')
    expression += src_term + rec_term
    op = Operator(expression,
                  subs=model.spacing_map,
                  dse='advanced',
                  dle='advanced',
                  name="Forward%s" % randint(1e5))
    if op_return is False:
        op(dt=dt)
        return rec.data, u
    else:
        return op
Ejemplo n.º 15
0
def forward_born(model,
                 src_coords,
                 wavelet,
                 rec_coords,
                 space_order=8,
                 nb=40,
                 isic=False,
                 dt=None):
    clear_cache()

    # Parameters
    nt = wavelet.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, dm, damp = model.m, model.dm, model.damp

    # Create the forward and linearized wavefield
    u = TimeFunction(name="u",
                     grid=model.grid,
                     time_order=2,
                     space_order=space_order)
    du = TimeFunction(name="du",
                      grid=model.grid,
                      time_order=2,
                      space_order=space_order)
    if len(model.shape) == 2:
        x, y = u.space_dimensions
    else:
        x, y, z = u.space_dimensions

    # Set up PDEs and rearrange
    eqn = m * u.dt2 - u.laplace + damp * u.dt
    stencil1 = solve(eqn, u.forward)[0]
    if isic is not True:
        eqn_lin = m * du.dt2 - du.laplace + damp * du.dt + dm * u.dt2  # born modeling
    else:
        du_aux = sum([
            first_derivative(
                first_derivative(u, dim=d, order=space_order // 2) * dm,
                order=space_order // 2,
                dim=d) for d in u.space_dimensions
        ])
        eqn_lin = m * du.dt2 - du.laplace + damp * du.dt + (dm * u.dt2 * m -
                                                            du_aux)

    if isic is not True:
        stencil2 = solve(eqn_lin, du.forward)[0]
    else:
        stencil2 = solve(eqn_lin, du.forward, simplify=False,
                         rational=False)[0]

    expression_u = [Eq(u.forward, stencil1)]
    expression_du = [Eq(du.forward, stencil2)]

    # Define source symbol with wavelet
    src = PointSource(name='src',
                      grid=model.grid,
                      ntime=nt,
                      coordinates=src_coords)
    src.data[:] = wavelet[:]
    src_term = src.inject(field=u.forward,
                          offset=model.nbpml,
                          expr=src * dt**2 / m)

    # Define receiver symbol
    rec = Receiver(name='rec',
                   grid=model.grid,
                   ntime=nt,
                   coordinates=rec_coords)
    rec_term = rec.interpolate(expr=du, offset=model.nbpml)

    # Create operator and run
    set_log_level('ERROR')
    expression = expression_u + src_term + expression_du + rec_term
    op = Operator(expression,
                  subs=model.spacing_map,
                  dse='advanced',
                  dle='advanced',
                  name="Born%s" % randint(1e5))
    op(dt=dt)

    return rec.data
Ejemplo n.º 16
0
def adjoint_modeling(model,
                     src_coords,
                     rec_coords,
                     rec_data,
                     space_order=8,
                     nb=40,
                     free_surface=False,
                     dt=None):
    clear_cache()

    # If wavelet is file, read it
    if isinstance(rec_data, str):
        rec_data = np.load(rec_data)

    # Parameters
    nt = rec_data.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, rho, damp = model.m, model.rho, model.damp

    # Create the adjoint wavefield
    if src_coords is not None:
        v = TimeFunction(name="v",
                         grid=model.grid,
                         time_order=2,
                         space_order=space_order)
    else:
        v = TimeFunction(name="v",
                         grid=model.grid,
                         time_order=2,
                         space_order=space_order,
                         save=nt)

    # Set up PDE and rearrange
    vlaplace, rho = acoustic_laplacian(v, rho)
    H = symbols('H')
    eqn = m / rho * v.dt2 - H - damp * v.dt

    # Input data is wavefield
    if isinstance(rec_data, TimeFunction):
        wf_rec = TimeFunction(name='wf_rec',
                              grid=model.grid,
                              time_order=2,
                              space_order=space_order,
                              save=nt)
        wf_rec._data = rec_data._data
        eqn -= wf_rec

    stencil = solve(eqn, v.backward, simplify=False, rational=False)[0]
    expression = [Eq(v.backward, stencil.subs({H: vlaplace}))]

    # Free surface
    if free_surface is True:
        fs = DefaultDimension(name="fs", default_value=int(space_order / 2))
        expression += [
            Eq(v.forward.subs({v.indices[-1]: model.nbpml - fs - 1}),
               -v.forward.subs({v.indices[-1]: model.nbpml + fs + 1}))
        ]

    # Adjoint source is injected at receiver locations
    if rec_coords is not None:
        rec = Receiver(name='rec',
                       grid=model.grid,
                       ntime=nt,
                       coordinates=rec_coords)
        rec.data[:] = rec_data[:]
        adj_src = rec.inject(field=v.backward,
                             offset=model.nbpml,
                             expr=rec * rho * dt**2 / m)
        expression += adj_src

    # Data is sampled at source locations
    if src_coords is not None:
        src = PointSource(name='src',
                          grid=model.grid,
                          ntime=nt,
                          coordinates=src_coords)
        adj_rec = src.interpolate(expr=v, offset=model.nbpml)
        expression += adj_rec

    # Create operator and run
    set_log_level('ERROR')
    subs = model.spacing_map
    subs[v.grid.time_dim.spacing] = dt
    op = Operator(expression,
                  subs=subs,
                  dse='advanced',
                  dle='advanced',
                  name="Backward%s" % randint(1e5))
    op()
    if src_coords is None:
        return v
    else:
        return src.data
Ejemplo n.º 17
0
def forward_born(model,
                 src_coords,
                 wavelet,
                 rec_coords,
                 space_order=8,
                 nb=40,
                 isic=False,
                 dt=None):
    clear_cache()

    # Parameters
    nt = wavelet.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, rho, dm, damp = model.m, model.rho, model.dm, model.damp

    # Create the forward and linearized wavefield
    u = TimeFunction(name="u",
                     grid=model.grid,
                     time_order=2,
                     space_order=space_order)
    du = TimeFunction(name="du",
                      grid=model.grid,
                      time_order=2,
                      space_order=space_order)
    if len(model.shape) == 2:
        x, y = u.space_dimensions
    else:
        x, y, z = u.space_dimensions

    # Set up PDEs and rearrange
    ulaplace, rho = acoustic_laplacian(u, rho)
    dulaplace, _ = acoustic_laplacian(du, rho)
    H = symbols('H')
    S = symbols('S')
    eqn = m / rho * u.dt2 - H + damp * u.dt
    stencil1 = solve(eqn, u.forward, simplify=False, rational=False)[0]
    eqn_lin = m / rho * du.dt2 - H + damp * du.dt + S
    if isic:
        # Sum ((u.dx * d, / rho).dx for x in dimensions)
        # space_order//2  so that u.dx.dx has the same radius as u.laplace
        du_aux = sum([
            first_derivative(
                first_derivative(u, dim=d, order=space_order // 2) * dm / rho,
                order=space_order // 2,
                dim=d) for d in u.space_dimensions
        ])
        lin_source = dm / rho * u.dt2 * m - du_aux
    else:
        lin_source = dm / rho * u.dt2

    stencil2 = solve(eqn_lin, du.forward, simplify=False, rational=False)[0]
    expression_u = [Eq(u.forward, stencil1.subs({H: ulaplace}))]
    expression_du = [
        Eq(du.forward, stencil2.subs({
            H: dulaplace,
            S: lin_source
        }))
    ]

    # Define source symbol with wavelet
    src = PointSource(name='src',
                      grid=model.grid,
                      ntime=nt,
                      coordinates=src_coords)
    src.data[:] = wavelet[:]
    src_term = src.inject(field=u.forward,
                          offset=model.nbpml,
                          expr=src * rho * dt**2 / m)

    # Define receiver symbol
    rec = Receiver(name='rec',
                   grid=model.grid,
                   ntime=nt,
                   coordinates=rec_coords)
    rec_term = rec.interpolate(expr=du, offset=model.nbpml)

    # Create operator and run
    set_log_level('ERROR')
    expression = expression_u + src_term + expression_du + rec_term
    subs = model.spacing_map
    subs[u.grid.time_dim.spacing] = dt
    op = Operator(expression,
                  subs=subs,
                  dse='advanced',
                  dle='advanced',
                  name="Born%s" % randint(1e5))
    op()

    return rec.data
Ejemplo n.º 18
0
configuration.add('platform', 'cpu64', list(platform_registry),
                  callback=lambda i: platform_registry[i]())
configuration.add('compiler', 'custom', list(compiler_registry),
                  callback=lambda i: compiler_registry[i]())
configuration.add('backend', 'core', list(backends_registry), callback=init_backend)

# Should Devito run a first-touch Operator upon data allocation?
configuration.add('first-touch', 0, [0, 1], lambda i: bool(i), False)

# Should Devito ignore any unknown runtime arguments supplied to Operator.apply(),
# or rather raise an exception (the default behaviour)?
configuration.add('ignore-unknowns', 0, [0, 1], lambda i: bool(i), False)

# Setup log level
configuration.add('log-level', 'INFO', list(logger_registry),
                  lambda i: set_log_level(i), False)

# Escape hatch for custom kernels. The typical use case is as follows: one lets
# Devito generate code for an Operator; then, once the session is over, the
# generated file is manually modified (e.g., for debugging or for performance
# experimentation); finally, when re-running the same program, Devito won't
# overwrite the user-modified files (thus entirely bypassing code generation),
# and will instead use the custom kernel
configuration.add('jit-backdoor', 0, [0, 1], lambda i: bool(i), False)

# Execution mode setup
def _reinit_compiler(val):  # noqa
    # Force re-build the compiler
    configuration['compiler'].__init__(suffix=configuration['compiler'].suffix,
                                       mpi=configuration['mpi'])
    return bool(val) if isinstance(val, int) else val
Ejemplo n.º 19
0
def forward_modeling(model,
                     src_coords,
                     wavelet,
                     rec_coords,
                     save=False,
                     space_order=8,
                     nb=40,
                     free_surface=False,
                     op_return=False,
                     dt=None):
    clear_cache()

    # If wavelet is file, read it
    if isinstance(wavelet, str):
        wavelet = np.load(wavelet)

    # Parameters
    nt = wavelet.shape[0]
    if dt is None:
        dt = model.critical_dt
    m, rho, damp = model.m, model.rho, model.damp

    # Create the forward wavefield
    if save is False and rec_coords is not None:
        u = TimeFunction(name='u',
                         grid=model.grid,
                         time_order=2,
                         space_order=space_order)
    else:
        u = TimeFunction(name='u',
                         grid=model.grid,
                         time_order=2,
                         space_order=space_order,
                         save=nt)

    # Set up PDE and rearrange
    ulaplace, rho = acoustic_laplacian(u, rho)
    H = symbols('H')
    eqn = m / rho * u.dt2 - H + damp * u.dt

    # Input source is wavefield
    if isinstance(wavelet, TimeFunction):
        wf_src = TimeFunction(name='wf_src',
                              grid=model.grid,
                              time_order=2,
                              space_order=space_order,
                              save=nt)
        wf_src._data = wavelet._data
        eqn -= wf_src

    # Rearrange expression
    stencil = solve(eqn, u.forward, simplify=False, rational=False)[0]
    expression = [Eq(u.forward, stencil.subs({H: ulaplace}))]

    # Free surface
    if free_surface is True:
        fs = DefaultDimension(name="fs", default_value=int(space_order / 2))
        expression += [
            Eq(u.forward.subs({u.indices[-1]: model.nbpml - fs - 1}),
               -u.forward.subs({u.indices[-1]: model.nbpml + fs + 1}))
        ]

    # Source symbol with input wavelet
    if src_coords is not None:
        src = PointSource(name='src',
                          grid=model.grid,
                          ntime=nt,
                          coordinates=src_coords)
        src.data[:] = wavelet[:]
        src_term = src.inject(field=u.forward,
                              offset=model.nbpml,
                              expr=src * rho * dt**2 / m)
        expression += src_term

    # Data is sampled at receiver locations
    if rec_coords is not None:
        rec = Receiver(name='rec',
                       grid=model.grid,
                       ntime=nt,
                       coordinates=rec_coords)
        rec_term = rec.interpolate(expr=u, offset=model.nbpml)
        expression += rec_term

    # Create operator and run
    set_log_level('ERROR')
    subs = model.spacing_map
    subs[u.grid.time_dim.spacing] = dt
    op = Operator(expression,
                  subs=subs,
                  dse='advanced',
                  dle='advanced',
                  name="Forward%s" % randint(1e5))
    if op_return is False:
        op()
        if rec_coords is None:
            return u
        else:
            return rec.data, u
    else:
        return op
Ejemplo n.º 20
0
import os
import sys

if not "DEVITO_OPENMP" in os.environ or os.environ["DEVITO_OPENMP"] != "1":
    print(
        "*** WARNING: Devito OpenMP environment variable has not been set ***",
        file=sys.stderr)

import numpy as np
from sympy import Matrix, Eq, solve
import progressbar
from devito import TimeData, Operator, t, x, y, z, logger as devito_logger, parameters as devito_parameters

from . import sim

devito_logger.set_log_level('WARNING')


def vector_laplacian(u):
    return Matrix([
        u[0].dx2 + u[0].dy2 + u[0].dz2, u[1].dx2 + u[1].dy2 + u[1].dz2,
        u[2].dx2 + u[2].dy2 + u[2].dz2
    ])


def vector_gradient(u):
    return u[0].dx**2 + u[0].dy**2 + u[0].dz**2 + u[1].dx**2 + u[1].dy**2 + u[
        1].dz**2 + u[2].dx**2 + u[2].dy**2 + u[2].dz**2


def curl(u):
Ejemplo n.º 21
0
                  callback=lambda i: compiler_registry[i]())
configuration.add('backend',
                  'core',
                  list(backends_registry),
                  callback=init_backend)

# Should Devito run a first-touch Operator upon data allocation?
configuration.add('first-touch', 0, [0, 1], lambda i: bool(i), False)

# Should Devito ignore any unknown runtime arguments supplied to Operator.apply(),
# or rather raise an exception (the default behaviour)?
configuration.add('ignore-unknowns', 0, [0, 1], lambda i: bool(i), False)

# Setup log level
configuration.add('log-level', 'INFO', list(logger_registry),
                  lambda i: set_log_level(i), False)

# Escape hatch for custom kernels. The typical use case is as follows: one lets
# Devito generate code for an Operator; then, once the session is over, the
# generated file is manually modified (e.g., for debugging or for performance
# experimentation); finally, when re-running the same program, Devito won't
# overwrite the user-modified files (thus entirely bypassing code generation),
# and will instead use the custom kernel
configuration.add('jit-backdoor', 0, [0, 1], lambda i: bool(i), False)

# Enable/disable automatic padding for allocated data
configuration.add('autopadding', False, [False, True])


# Execution mode setup
def _reinit_compiler(val):  # noqa
Ejemplo n.º 22
0
    raise NotImplementedError("Devito doesn't support configuration via file.")

# Parameters casting and checking
for k, v in list(configuration.items()):
    try:
        val = int(v)
    except (TypeError, ValueError):
        val = v
    if val not in accepted[k]:
        raise ValueError("Illegal configuration parameter (%s, %s). "
                         "Accepted: %s" % (k, val, str(accepted[k])))
    configuration[k] = val

# Global setup
# - Logger
configuration.set_update_function('log_level', lambda i: set_log_level(i))
# - Compilation toolchain
configuration['compiler'] = set_compiler(configuration['compiler'],
                                         configuration['openmp'])
configuration['openmp'] = bool(configuration['openmp'])

configuration.initialize()


def print_defaults():
    """Print the environment variables accepted by Devito, their default value,
    as well as all of the accepted values."""
    for k, v in env_vars_mapper.items():
        debug('%s: %s. Default: %s' % (k, accepted[v], defaults[v]))