Beispiel #1
0
def GradientOperator(model,
                     geometry,
                     space_order=4,
                     save=True,
                     kernel='OT2',
                     **kwargs):
    """
    Construct a gradient operator in an acoustic media.

    Parameters
    ----------
    model : Model
        Object containing the physical parameters.
    geometry : AcquisitionGeometry
        Geometry object that contains the source (SparseTimeFunction) and
        receivers (SparseTimeFunction) and their position.
    space_order : int, optional
        Space discretization order.
    save : int or Buffer, optional
        Option to store the entire (unrolled) wavefield.
    kernel : str, optional
        Type of discretization, centered or shifted.
    """
    m, damp = model.m, model.damp

    # Gradient symbol and wavefield symbols
    grad = Function(name='grad', grid=model.grid)
    u = TimeFunction(name='u',
                     grid=model.grid,
                     save=geometry.nt if save else None,
                     time_order=2,
                     space_order=space_order)
    v = TimeFunction(name='v',
                     grid=model.grid,
                     save=None,
                     time_order=2,
                     space_order=space_order)
    rec = Receiver(name='rec',
                   grid=model.grid,
                   time_range=geometry.time_axis,
                   npoint=geometry.nrec)

    s = model.grid.stepping_dim.spacing
    eqn = iso_stencil(v, m, s, damp, kernel, forward=False)

    if kernel == 'OT2':
        gradient_update = Inc(grad, -u.dt2 * v)
    elif kernel == 'OT4':
        gradient_update = Inc(
            grad, -(u.dt2 + s**2 / 12.0 * u.biharmonic(m**(-2))) * v)
    # Add expression for receiver injection
    receivers = rec.inject(field=v.backward, expr=rec * s**2 / m)

    # Substitute spacing terms to reduce flops
    return Operator(eqn + receivers + [gradient_update],
                    subs=model.spacing_map,
                    name='Gradient',
                    **kwargs)
Beispiel #2
0
    def test_symbolic_constant_times_add(self):
        grid = Grid(shape=(10, 10))
        dt = grid.time_dim.spacing

        u = TimeFunction(name="u", grid=grid, space_order=4, time_order=2)
        f = Function(name='f', grid=grid)

        eq = Eq(u.forward, u.laplace + dt**0.2 * u.biharmonic(1 / f))
        leq = collect_derivatives.func([eq])[0]

        assert len(eq.rhs.args) == 3
        assert len(leq.rhs.args) == 2
        assert all(isinstance(i, Derivative) for i in leq.rhs.args)