예제 #1
0
def src_rec(v, tau, model, geometry):
    """
    Source injection and receiver interpolation
    """
    s = model.grid.time_dim.spacing
    # Source symbol with input wavelet
    src = PointSource(name='src',
                      grid=model.grid,
                      time_range=geometry.time_axis,
                      npoint=geometry.nsrc)
    rec1 = Receiver(name='rec1',
                    grid=model.grid,
                    time_range=geometry.time_axis,
                    npoint=geometry.nrec)
    rec2 = Receiver(name='rec2',
                    grid=model.grid,
                    time_range=geometry.time_axis,
                    npoint=geometry.nrec)

    # The source injection term
    src_xx = src.inject(field=tau[0, 0].forward, expr=src * s)
    src_zz = src.inject(field=tau[-1, -1].forward, expr=src * s)
    src_expr = src_xx + src_zz
    if model.grid.dim == 3:
        src_yy = src.inject(field=tau[1, 1].forward, expr=src * s)
        src_expr += src_yy

    # Create interpolation expression for receivers
    rec_term1 = rec1.interpolate(expr=tau[-1, -1])
    rec_term2 = rec2.interpolate(expr=div(v))

    return src_expr + rec_term1 + rec_term2
예제 #2
0
def src_rec(p, model, geometry, **kwargs):
    """
    Forward case: Source injection and receiver interpolation
    Adjoint case: Receiver injection and source interpolation
    """
    dt = model.grid.time_dim.spacing
    m = model.m
    # Source symbol with input wavelet
    src = PointSource(name="src", grid=model.grid, time_range=geometry.time_axis,
                      npoint=geometry.nsrc)
    rec = Receiver(name='rec', grid=model.grid, time_range=geometry.time_axis,
                   npoint=geometry.nrec)

    forward = kwargs.get('forward', True)
    time_order = p.time_order

    if forward:
        # The source injection term
        if(time_order == 1):
            src_term = src.inject(field=p.forward, expr=src * dt)
        else:
            src_term = src.inject(field=p.forward, expr=src * dt**2 / m)
        # Create interpolation expression for receivers
        rec_term = rec.interpolate(expr=p)
    else:
        # Construct expression to inject receiver values
        if(time_order == 1):
            rec_term = rec.inject(field=p.backward, expr=rec * dt)
        else:
            rec_term = rec.inject(field=p.backward, expr=rec * dt**2 / m)
        # Create interpolation expression for the adjoint-source
        src_term = src.interpolate(expr=p)

    return src_term + rec_term
예제 #3
0
파일: operators.py 프로젝트: opesci/devito
def src_rec(vx, vy, vz, txx, tyy, tzz, model, geometry):
    """
    Source injection and receiver interpolation
    """
    s = model.grid.time_dim.spacing
    # Source symbol with input wavelet
    src = PointSource(name='src', grid=model.grid, time_range=geometry.time_axis,
                      npoint=geometry.nsrc)
    rec1 = Receiver(name='rec1', grid=model.grid, time_range=geometry.time_axis,
                    npoint=geometry.nrec)
    rec2 = Receiver(name='rec2', grid=model.grid, time_range=geometry.time_axis,
                    npoint=geometry.nrec)

    # The source injection term
    src_xx = src.inject(field=txx.forward, expr=src * s)
    src_zz = src.inject(field=tzz.forward, expr=src * s)
    src_expr = src_xx + src_zz
    if model.grid.dim == 3:
        src_yy = src.inject(field=tyy.forward, expr=src * s)
        src_expr += src_yy

    # Create interpolation expression for receivers
    rec_term1 = rec1.interpolate(expr=tzz)
    if model.grid.dim == 2:
        rec_expr = vx.dx + vz.dy
    else:
        rec_expr = vx.dx + vy.dy + vz.dz
    rec_term2 = rec2.interpolate(expr=rec_expr)

    return src_expr + rec_term1 + rec_term2
예제 #4
0
def src_rec(vx, vy, vz, txx, tyy, tzz, model, geometry):
    """
    Source injection and receiver interpolation
    """
    s = model.grid.time_dim.spacing
    # Source symbol with input wavelet
    src = PointSource(name='src', grid=model.grid, time_range=geometry.time_axis,
                      npoint=geometry.nsrc)
    rec1 = Receiver(name='rec1', grid=model.grid, time_range=geometry.time_axis,
                    npoint=geometry.nrec)
    rec2 = Receiver(name='rec2', grid=model.grid, time_range=geometry.time_axis,
                    npoint=geometry.nrec)

    # The source injection term
    src_xx = src.inject(field=txx.forward, expr=src * s)
    src_zz = src.inject(field=tzz.forward, expr=src * s)
    src_expr = src_xx + src_zz
    if model.grid.dim == 3:
        src_yy = src.inject(field=tyy.forward, expr=src * s)
        src_expr += src_yy

    # Create interpolation expression for receivers
    rec_term1 = rec1.interpolate(expr=tzz)
    if model.grid.dim == 2:
        rec_expr = vx.dx + vz.dy
    else:
        rec_expr = vx.dx + vy.dy + vz.dz
    rec_term2 = rec2.interpolate(expr=rec_expr)

    return src_expr + rec_term1 + rec_term2
예제 #5
0
def ForwardOperator(model,
                    source,
                    receiver,
                    space_order=4,
                    save=False,
                    kernel='centered',
                    **kwargs):
    """
       Constructor method for the forward modelling operator in an acoustic media

       :param model: :class:`Model` object containing the physical parameters
       :param src: None ot IShot() (not currently supported properly)
       :param data: IShot() object containing the acquisition geometry and field data
       :param: time_order: Time discretization order
       :param: spc_order: Space discretization order
       """

    dt = model.grid.time_dim.spacing
    m = model.m
    time_order = 1 if kernel == 'staggered' else 2
    # Create symbols for forward wavefield, source and receivers
    u = TimeFunction(name='u',
                     grid=model.grid,
                     save=source.nt if save else None,
                     time_order=time_order,
                     space_order=space_order)
    v = TimeFunction(name='v',
                     grid=model.grid,
                     save=source.nt if save else None,
                     time_order=time_order,
                     space_order=space_order)
    src = PointSource(name='src',
                      grid=model.grid,
                      time_range=source.time_range,
                      npoint=source.npoint)
    rec = Receiver(name='rec',
                   grid=model.grid,
                   time_range=receiver.time_range,
                   npoint=receiver.npoint)

    # FD kernels of the PDE
    FD_kernel = kernels[(kernel, len(model.shape))]
    stencils = FD_kernel(model, u, v, space_order)

    # Source and receivers
    stencils += src.inject(field=u.forward,
                           expr=src * dt**2 / m,
                           offset=model.nbpml)
    stencils += src.inject(field=v.forward,
                           expr=src * dt**2 / m,
                           offset=model.nbpml)
    stencils += rec.interpolate(expr=u + v, offset=model.nbpml)

    # Substitute spacing terms to reduce flops
    return Operator(stencils,
                    subs=model.spacing_map,
                    name='ForwardTTI',
                    **kwargs)
예제 #6
0
파일: operators.py 프로젝트: opesci/devito
def ForwardOperator(model, geometry, space_order=4,
                    save=False, kernel='OT2', **kwargs):
    """
    Constructor method for the forward modelling operator in an acoustic media

    :param model: :class:`Model` object containing the physical parameters
    :param source: :class:`PointData` object containing the source geometry
    :param receiver: :class:`PointData` object containing the acquisition geometry
    :param space_order: Space discretization order
    :param save: Saving flag, True saves all time steps, False only the three
    """
    m, damp = model.m, model.damp

    # Create symbols for forward wavefield, source and receivers
    u = TimeFunction(name='u', grid=model.grid,
                     save=geometry.nt if save else None,
                     time_order=2, space_order=space_order)
    src = PointSource(name='src', grid=geometry.grid, time_range=geometry.time_axis,
                      npoint=geometry.nsrc)

    rec = Receiver(name='rec', grid=geometry.grid, time_range=geometry.time_axis,
                   npoint=geometry.nrec)

    s = model.grid.stepping_dim.spacing
    eqn = iso_stencil(u, m, s, damp, kernel)

    # Construct expression to inject source values
    src_term = src.inject(field=u.forward, expr=src * s**2 / m)

    # Create interpolation expression for receivers
    rec_term = rec.interpolate(expr=u)
    # Substitute spacing terms to reduce flops
    return Operator(eqn + src_term + rec_term, subs=model.spacing_map,
                    name='Forward', **kwargs)
예제 #7
0
def td_born_adjoint_op(model, geometry, time_order, space_order):

    nt = geometry.nt

    # Define the wavefields with the size of the model and the time dimension
    u = TimeFunction(
        name='u',
        grid=model.grid,
        time_order=time_order,
        space_order=space_order,
        save=nt
    )

    # Define the wave equation
    pde = model.m * u.dt2 - u.laplace + model.damp * u.dt.T

    # Use `solve` to rearrange the equation into a stencil expression
    stencil = Eq(u.backward, solve(pde, u.backward), subdomain=model.grid.subdomains['physdomain'])

    # Inject at receivers
    born_data_rec = PointSource(
        name='born_data_rec',
        grid=model.grid,
        time_range=geometry.time_axis,
        coordinates=geometry.rec_positions
    )
    dt = Constant(name='dt')
    rec_term = born_data_rec.inject(field=u.backward, expr=born_data_rec * (dt ** 2) / model.m)

    return Operator([stencil] + rec_term, subs=model.spacing_map)
예제 #8
0
def ImagingOperator(model, image):
    # Define the wavefield with the size of the model and the time dimension
    v = TimeFunction(name='v', grid=model.grid, time_order=2, space_order=4)

    u = TimeFunction(name='u',
                     grid=model.grid,
                     time_order=2,
                     space_order=4,
                     save=geometry.nt)

    # Define the wave equation, but with a negated damping term
    eqn = model.m * v.dt2 - v.laplace - model.damp * v.dt

    # Use `solve` to rearrange the equation into a stencil expression
    stencil = Eq(v.backward, solve(eqn, v.backward))

    # Define residual injection at the location of the forward receivers
    dt = model.critical_dt
    residual = PointSource(name='residual',
                           grid=model.grid,
                           time_range=geometry.time_axis,
                           coordinates=geometry.rec_positions)
    res_term = residual.inject(field=v, expr=residual * dt**2 / model.m)

    # Correlate u and v for the current time step and add it to the image
    image_update = Eq(image, image - u * v)

    return Operator([stencil] + res_term + [image_update],
                    subs=model.spacing_map)
예제 #9
0
def ImagingOperator(geometry, image, space_order, save=True):

    stagg_u = stagg_v = None

    u = TimeFunction(name='u', grid=geometry.model.grid, staggered=stagg_u,
                     save=geometry.nt if save
                     else None, time_order=2, space_order=space_order)
    v = TimeFunction(name='v', grid=geometry.model.grid, staggered=stagg_v,
                     save=geometry.nt if save
                     else None, time_order=2, space_order=space_order)

    uu = TimeFunction(name='uu', grid=geometry.model.grid, staggered=stagg_u,
                      save=None, time_order=2, space_order=space_order)
    vv = TimeFunction(name='vv', grid=geometry.model.grid, staggered=stagg_v,
                      save=None, time_order=2, space_order=space_order)

    dt = geometry.dt
    residual = PointSource(name='residual', grid=geometry.model.grid,
                           time_range=geometry.time_axis,
                           coordinates=geometry.rec_positions)

    stencils = kernel_centered_2d(geometry.model, uu, vv, space_order, forward=False)

    stencils += residual.inject(field=uu.backward, expr=residual * dt**2 / geometry.model.m)
    stencils += residual.inject(field=vv.backward, expr=residual * dt**2 / geometry.model.m)

    # Correlate u and v for the current time step and add it to the image
    image_update = Eq(image, image - (u.dt2*uu + v.dt2*vv))

    return Operator(stencils + [image_update], subs=geometry.model.spacing_map)
예제 #10
0
파일: operators.py 프로젝트: yuriyi/devito
def ForwardOperator(model, source, receiver, space_order=4,
                    save=False, kernel='OT2', **kwargs):
    """
    Constructor method for the forward modelling operator in an acoustic media

    :param model: :class:`Model` object containing the physical parameters
    :param source: :class:`PointData` object containing the source geometry
    :param receiver: :class:`PointData` object containing the acquisition geometry
    :param space_order: Space discretization order
    :param save: Saving flag, True saves all time steps, False only the three
    """
    m, damp = model.m, model.damp

    # Create symbols for forward wavefield, source and receivers
    u = TimeFunction(name='u', grid=model.grid,
                     save=source.nt if save else None,
                     time_order=2, space_order=space_order)
    src = PointSource(name='src', grid=model.grid, time_range=source.time_range,
                      npoint=source.npoint)
    rec = Receiver(name='rec', grid=model.grid, time_range=receiver.time_range,
                   npoint=receiver.npoint)

    s = model.grid.stepping_dim.spacing
    eqn = iso_stencil(u, m, s, damp, kernel)

    # Construct expression to inject source values
    src_term = src.inject(field=u.forward, expr=src * s**2 / m,
                          offset=model.nbpml)

    # Create interpolation expression for receivers
    rec_term = rec.interpolate(expr=u, offset=model.nbpml)

    # Substitute spacing terms to reduce flops
    return Operator(eqn + src_term + rec_term, subs=model.spacing_map,
                    name='Forward', **kwargs)
예제 #11
0
def BornOperator(model,
                 source,
                 receiver,
                 space_order=4,
                 kernel='OT2',
                 **kwargs):
    """
    Constructor method for the Linearized Born operator in an acoustic media

    :param model: :class:`Model` object containing the physical parameters
    :param source: :class:`PointData` object containing the source geometry
    :param receiver: :class:`PointData` object containing the acquisition geometry
    :param time_order: Time discretization order
    :param space_order: Space discretization order
    """
    m, damp = model.m, model.damp

    # Create source and receiver symbols
    src = PointSource(name='src',
                      grid=model.grid,
                      time_range=source.time_range,
                      npoint=source.npoint)
    rec = Receiver(name='rec',
                   grid=model.grid,
                   time_range=receiver.time_range,
                   npoint=receiver.npoint)

    # Create wavefields and a dm field
    u = TimeFunction(name="u",
                     grid=model.grid,
                     save=None,
                     time_order=2,
                     space_order=space_order)
    U = TimeFunction(name="U",
                     grid=model.grid,
                     save=None,
                     time_order=2,
                     space_order=space_order)
    dm = Function(name="dm", grid=model.grid, space_order=0)

    s = model.grid.stepping_dim.spacing
    eqn1 = iso_stencil(u, m, s, damp, kernel)
    eqn2 = iso_stencil(U, m, s, damp, kernel, q=-dm * u.dt2)

    # Add source term expression for u
    source = src.inject(field=u.forward,
                        expr=src * s**2 / m,
                        offset=model.nbpml)

    # Create receiver interpolation expression from U
    receivers = rec.interpolate(expr=U, offset=model.nbpml)

    # Substitute spacing terms to reduce flops
    return Operator(eqn1 + source + eqn2 + receivers,
                    subs=model.spacing_map,
                    name='Born',
                    **kwargs)
예제 #12
0
def ForwardOperator(model,
                    geometry,
                    space_order=4,
                    save=False,
                    kernel='OT2',
                    **kwargs):
    """
    Construct a forward modelling operator in an acoustic medium.

    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
        Saving flag, True saves all time steps. False saves three timesteps.
        Defaults to False.
    kernel : str, optional
        Type of discretization, 'OT2' or 'OT4'.
    """
    m = model.m

    # Create symbols for forward wavefield, source and receivers
    u = TimeFunction(name='u',
                     grid=model.grid,
                     save=geometry.nt if save else None,
                     time_order=2,
                     space_order=space_order)
    src = PointSource(name='src',
                      grid=geometry.grid,
                      time_range=geometry.time_axis,
                      npoint=geometry.nsrc)

    rec = Receiver(name='rec',
                   grid=geometry.grid,
                   time_range=geometry.time_axis,
                   npoint=geometry.nrec)

    s = model.grid.stepping_dim.spacing
    eqn = iso_stencil(u, model, kernel)

    # Construct expression to inject source values
    src_term = src.inject(field=u.forward, expr=src * s**2 / m)

    # Create interpolation expression for receivers
    rec_term = rec.interpolate(expr=u)

    # Substitute spacing terms to reduce flops
    return Operator(eqn + src_term + rec_term,
                    subs=model.spacing_map,
                    name='Forward',
                    **kwargs)
예제 #13
0
def src_rec(vx, vy, vz, qx, qy, qz, txx, tyy, tzz, p, model, geometry):
    """
    Source injection and receiver interpolation
    """
    dt = model.grid.time_dim.spacing
    # Source symbol with input wavelet
    src = PointSource(name='src',
                      grid=model.grid,
                      time_range=geometry.time_axis,
                      npoint=geometry.nsrc)
    rec1 = Receiver(name='rec1',
                    grid=model.grid,
                    time_range=geometry.time_axis,
                    npoint=geometry.nrec)
    rec2 = Receiver(name='rec2',
                    grid=model.grid,
                    time_range=geometry.time_axis,
                    npoint=geometry.nrec)
    M = model.M
    # The source injection term
    #src_xx = src.inject(field=txx.forward, expr=src * (1.0 - model.phi) * dt, offset=model.nbpml)
    #src_zz = src.inject(field=tzz.forward, expr=src * (1.0 - model.phi) * dt, offset=model.nbpml)
    #src_xx = src.inject(field=txx.forward, expr=src * dt)
    #src_zz = src.inject(field=tzz.forward, expr=src * dt)
    src_pp = src.inject(field=p.forward, expr=src * M)
    #src_expr = src_xx + src_zz + src_pp
    src_expr = src_pp
    if model.grid.dim == 3:
        src_yy = src.inject(field=tyy.forward,
                            expr=src * (1.0 - model.phi) * dt,
                            offset=model.nbpml)
        src_expr += src_yy

    # Create interpolation expression for receivers
    rec_term1 = rec1.interpolate(expr=p, offset=model.nbpml)
    if model.grid.dim == 2:
        rec_expr = vx.dx + vz.dy
    else:
        rec_expr = vx.dx + vy.dy + vz.dz
    rec_term2 = rec2.interpolate(expr=rec_expr, offset=model.nbpml)

    return src_expr + rec_term1 + rec_term2
예제 #14
0
def ForwardOperator(model, geometry, space_order=4,
                    save=False, kernel='centered', **kwargs):
    """
    Construct an forward modelling operator in an tti 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
        Saving flag, True saves all time steps. False saves three timesteps.
        Defaults to False.
    kernel : str, optional
        Type of discretization, centered or shifted
    """

    dt = model.grid.time_dim.spacing
    m = model.m
    time_order = 1 if kernel == 'staggered' else 2
    if kernel == 'staggered':
        stagg_u = stagg_v = NODE
    else:
        stagg_u = stagg_v = None

    # Create symbols for forward wavefield, source and receivers
    u = TimeFunction(name='u', grid=model.grid, staggered=stagg_u,
                     save=geometry.nt if save else None,
                     time_order=time_order, space_order=space_order)
    v = TimeFunction(name='v', grid=model.grid, staggered=stagg_v,
                     save=geometry.nt if save else None,
                     time_order=time_order, space_order=space_order)
    src = PointSource(name='src', grid=model.grid, time_range=geometry.time_axis,
                      npoint=geometry.nsrc)
    rec = Receiver(name='rec', grid=model.grid, time_range=geometry.time_axis,
                   npoint=geometry.nrec)

    # FD kernels of the PDE
    FD_kernel = kernels[(kernel, len(model.shape))]
    stencils = FD_kernel(model, u, v, space_order)

    # Source and receivers
    expr = src * dt / m if kernel == 'staggered' else src * dt**2 / m
    stencils += src.inject(field=u.forward, expr=expr)
    stencils += src.inject(field=v.forward, expr=expr)
    stencils += rec.interpolate(expr=u + v)

    # Substitute spacing terms to reduce flops
    return Operator(stencils, subs=model.spacing_map, name='ForwardTTI', **kwargs)
예제 #15
0
def ForwardOperator(model, geometry, space_order=4,
                    save=False, kernel='centered', **kwargs):
    """
    Construct an forward modelling 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.
    data : ndarray
        IShot() object containing the acquisition geometry and field data.
    time_order : int
        Time discretization order.
    space_order : int
        Space discretization order.
    """

    dt = model.grid.time_dim.spacing
    m = model.m
    time_order = 1 if kernel == 'staggered' else 2
    if kernel == 'staggered':
        dims = model.space_dimensions
        stagg_u = (-dims[-1])
        stagg_v = (-dims[0], -dims[1]) if model.grid.dim == 3 else (-dims[0])
    else:
        stagg_u = stagg_v = None

    # Create symbols for forward wavefield, source and receivers
    u = TimeFunction(name='u', grid=model.grid, staggered=stagg_u,
                     save=geometry.nt if save else None,
                     time_order=time_order, space_order=space_order)
    v = TimeFunction(name='v', grid=model.grid, staggered=stagg_v,
                     save=geometry.nt if save else None,
                     time_order=time_order, space_order=space_order)
    src = PointSource(name='src', grid=model.grid, time_range=geometry.time_axis,
                      npoint=geometry.nsrc)
    rec = Receiver(name='rec', grid=model.grid, time_range=geometry.time_axis,
                   npoint=geometry.nrec)

    # FD kernels of the PDE
    FD_kernel = kernels[(kernel, len(model.shape))]
    stencils = FD_kernel(model, u, v, space_order)

    # Source and receivers
    stencils += src.inject(field=u.forward, expr=src * dt**2 / m)
    stencils += src.inject(field=v.forward, expr=src * dt**2 / m)
    stencils += rec.interpolate(expr=u + v)

    # Substitute spacing terms to reduce flops
    return Operator(stencils, subs=model.spacing_map, name='ForwardTTI', **kwargs)
예제 #16
0
def ForwardOperator(model, source, receiver, time_order=2, space_order=4,
                    save=False, **kwargs):
    """
    Constructor method for the forward modelling operator in an acoustic media

    :param model: :class:`Model` object containing the physical parameters
    :param source: :class:`PointData` object containing the source geometry
    :param receiver: :class:`PointData` object containing the acquisition geometry
    :param time_order: Time discretization order
    :param space_order: Space discretization order
    :param save : Saving flag, True saves all time steps, False only the three
    """
    m, damp = model.m, model.damp

    # Create symbols for forward wavefield, source and receivers
    u = TimeData(name='u', shape=model.shape_domain, time_dim=source.nt,
                 time_order=time_order, space_order=space_order, save=save,
                 dtype=model.dtype)
    src = PointSource(name='src', ntime=source.nt, ndim=source.ndim,
                      npoint=source.npoint)
    rec = Receiver(name='rec', ntime=receiver.nt, ndim=receiver.ndim,
                   npoint=receiver.npoint)

    if time_order == 2:
        biharmonic = 0
        dt = model.critical_dt
    else:
        biharmonic = u.laplace2(1/m)
        dt = 1.73 * model.critical_dt

    # Derive both stencils from symbolic equation:
    # Create the stencil by hand instead of calling numpy solve for speed purposes
    # Simple linear solve of a u(t+dt) + b u(t) + c u(t-dt) = L for u(t+dt)
    stencil = 1 / (2 * m + s * damp) * (
        4 * m * u + (s * damp - 2 * m) * u.backward +
        2 * s**2 * (u.laplace + s**2 / 12 * biharmonic))
    eqn = [Eq(u.forward, stencil)]

    # Construct expression to inject source values
    # Note that src and field terms have differing time indices:
    #   src[time, ...] - always accesses the "unrolled" time index
    #   u[ti + 1, ...] - accesses the forward stencil value
    ti = u.indices[0]
    src_term = src.inject(field=u, u_t=ti + 1, offset=model.nbpml,
                          expr=src * dt**2 / m, p_t=time)

    # Create interpolation expression for receivers
    rec_term = rec.interpolate(expr=u, u_t=ti, offset=model.nbpml)

    return Operator(eqn + src_term + rec_term,
                    subs={s: dt, h: model.get_spacing()},
                    time_axis=Forward, name='Forward', **kwargs)
예제 #17
0
파일: operators.py 프로젝트: opesci/devito
def ForwardOperator(model, geometry, space_order=4,
                    save=False, kernel='centered', **kwargs):
    """
       Constructor method for the forward modelling operator in an acoustic media

       :param model: :class:`Model` object containing the physical parameters
       :param src: None ot IShot() (not currently supported properly)
       :param data: IShot() object containing the acquisition geometry and field data
       :param: time_order: Time discretization order
       :param: spc_order: Space discretization order
       """

    dt = model.grid.time_dim.spacing
    m = model.m
    time_order = 1 if kernel == 'staggered' else 2
    if kernel == 'staggered':
        dims = model.space_dimensions
        stagg_u = (-dims[-1])
        stagg_v = (-dims[0], -dims[1]) if model.grid.dim == 3 else (-dims[0])
    else:
        stagg_u = stagg_v = None

    # Create symbols for forward wavefield, source and receivers
    u = TimeFunction(name='u', grid=model.grid, staggered=stagg_u,
                     save=geometry.nt if save else None,
                     time_order=time_order, space_order=space_order)
    v = TimeFunction(name='v', grid=model.grid, staggered=stagg_v,
                     save=geometry.nt if save else None,
                     time_order=time_order, space_order=space_order)
    src = PointSource(name='src', grid=model.grid, time_range=geometry.time_axis,
                      npoint=geometry.nsrc)
    rec = Receiver(name='rec', grid=model.grid, time_range=geometry.time_axis,
                   npoint=geometry.nrec)

    # FD kernels of the PDE
    FD_kernel = kernels[(kernel, len(model.shape))]
    stencils = FD_kernel(model, u, v, space_order)

    # Source and receivers
    stencils += src.inject(field=u.forward, expr=src * dt**2 / m)
    stencils += src.inject(field=v.forward, expr=src * dt**2 / m)
    stencils += rec.interpolate(expr=u + v)

    # Substitute spacing terms to reduce flops
    return Operator(stencils, subs=model.spacing_map, name='ForwardTTI', **kwargs)
예제 #18
0
def BornOperator(model, source, receiver, time_order=2, space_order=4, **kwargs):
    """
    Constructor method for the Linearized Born operator in an acoustic media

    :param model: :class:`Model` object containing the physical parameters
    :param source: :class:`PointData` object containing the source geometry
    :param receiver: :class:`PointData` object containing the acquisition geometry
    :param time_order: Time discretization order
    :param space_order: Space discretization order
    """
    m, damp = model.m, model.damp

    # Create source and receiver symbols
    src = PointSource(name='src', ntime=source.nt, ndim=source.ndim,
                      npoint=source.npoint)
    rec = Receiver(name='rec', ntime=receiver.nt, ndim=receiver.ndim,
                   npoint=receiver.npoint)

    # Create wavefields and a dm field
    u = TimeData(name="u", shape=model.shape_domain, save=False,
                 time_order=time_order, space_order=space_order,
                 dtype=model.dtype)
    U = TimeData(name="U", shape=model.shape_domain, save=False,
                 time_order=time_order, space_order=space_order,
                 dtype=model.dtype)
    dm = DenseData(name="dm", shape=model.shape_domain,
                   dtype=model.dtype)

    if time_order == 2:
        biharmonicu = 0
        biharmonicU = 0
        dt = model.critical_dt
    else:
        biharmonicu = u.laplace2(1/m)
        biharmonicU = U.laplace2(1/m)
        dt = 1.73 * model.critical_dt

    # Derive both stencils from symbolic equation
    # first_eqn = m * u.dt2 - u.laplace + damp * u.dt
    # second_eqn = m * U.dt2 - U.laplace - dm* u.dt2 + damp * U.dt
    stencil1 = 1.0 / (2.0 * m + s * damp) * \
        (4.0 * m * u + (s * damp - 2.0 * m) *
         u.backward + 2.0 * s ** 2 * (u.laplace + s**2 / 12 * biharmonicu))
    stencil2 = 1.0 / (2.0 * m + s * damp) * \
        (4.0 * m * U + (s * damp - 2.0 * m) *
         U.backward + 2.0 * s ** 2 * (U.laplace +
                                      s**2 / 12 * biharmonicU - dm * u.dt2))
    eqn1 = Eq(u.forward, stencil1)
    eqn2 = Eq(U.forward, stencil2)

    # Add source term expression for u
    ti = u.indices[0]
    source = src.inject(field=u, u_t=ti + 1, offset=model.nbpml,
                        expr=src * dt * dt / m, p_t=time)

    # Create receiver interpolation expression from U
    receivers = rec.interpolate(expr=U, u_t=ti, offset=model.nbpml)

    return Operator([eqn1] + source + [eqn2] + receivers,
                    subs={s: dt, h: model.get_spacing()},
                    time_axis=Forward, name='Born', **kwargs)
예제 #19
0
def ForwardOperator(model,
                    source,
                    receiver,
                    time_order=2,
                    space_order=4,
                    save=False,
                    kernel='centered',
                    **kwargs):
    """
       Constructor method for the forward modelling operator in an acoustic media

       :param model: :class:`Model` object containing the physical parameters
       :param src: None ot IShot() (not currently supported properly)
       :param data: IShot() object containing the acquisition geometry and field data
       :param: time_order: Time discretization order
       :param: spc_order: Space discretization order
       """
    dt = model.critical_dt

    m, damp, epsilon, delta, theta, phi = (model.m, model.damp, model.epsilon,
                                           model.delta, model.theta, model.phi)

    # Create symbols for forward wavefield, source and receivers
    u = TimeData(name='u',
                 shape=model.shape_domain,
                 dtype=model.dtype,
                 save=save,
                 time_dim=source.nt if save else None,
                 time_order=time_order,
                 space_order=space_order)
    v = TimeData(name='v',
                 shape=model.shape_domain,
                 dtype=model.dtype,
                 save=save,
                 time_dim=source.nt if save else None,
                 time_order=time_order,
                 space_order=space_order)
    src = PointSource(name='src',
                      ntime=source.nt,
                      ndim=source.ndim,
                      npoint=source.npoint)
    rec = Receiver(name='rec',
                   ntime=receiver.nt,
                   ndim=receiver.ndim,
                   npoint=receiver.npoint)

    # Tilt and azymuth setup
    ang0 = cos(theta)
    ang1 = sin(theta)
    ang2 = 0
    ang3 = 0
    if len(model.shape) == 3:
        ang2 = cos(phi)
        ang3 = sin(phi)

    FD_kernel = kernels[(kernel, len(model.shape))]
    H0, Hz = FD_kernel(u, v, ang0, ang1, ang2, ang3, space_order)
    s = t.spacing
    # Stencils
    stencilp = 1.0 / (2.0 * m + s * damp) * \
        (4.0 * m * u + (s * damp - 2.0 * m) *
         u.backward + 2.0 * s ** 2 * (epsilon * H0 + delta * Hz))
    stencilr = 1.0 / (2.0 * m + s * damp) * \
        (4.0 * m * v + (s * damp - 2.0 * m) *
         v.backward + 2.0 * s ** 2 * (delta * H0 + Hz))
    first_stencil = Eq(u.forward, stencilp)
    second_stencil = Eq(v.forward, stencilr)
    stencils = [first_stencil, second_stencil]

    # Source and receivers
    stencils += src.inject(field=u.forward,
                           expr=src * dt * dt / m,
                           offset=model.nbpml)
    stencils += src.inject(field=v.forward,
                           expr=src * dt * dt / m,
                           offset=model.nbpml)
    stencils += rec.interpolate(expr=u + v, offset=model.nbpml)
    # Add substitutions for spacing (temporal and spatial)
    subs = dict([(t.spacing, dt)] + [(time.spacing, dt)] +
                [(i.spacing, model.get_spacing()[j])
                 for i, j in zip(u.indices[1:], range(len(model.shape)))])
    # Operator
    return Operator(stencils, subs=subs, name='ForwardTTI', **kwargs)
예제 #20
0
def ForwardOperator(model, geometry, space_order=4, time_order = 1, save=False, **kwargs):
    """
    Construct method for the forward modelling operator in an elastic 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
        Saving flag, True saves all time steps, False saves three buffered
        indices (last three time steps). Defaults to False.
    """

    v = VectorTimeFunction(name='v', grid=model.grid,
                           space_order=space_order, time_order=time_order)
    tau = TensorTimeFunction(name='tau', grid=model.grid,
                             space_order=space_order, time_order=time_order)

    ## Symbolic physical parameters used from the model
    irho = model.irho
    c11 = model.c11
    c33 = model.c33
    c44 = model.c44
    c66 = model.c66
    c13 = model.c13

    # Model critical timestep computed from CFL condition for VTI media
    ts = model.grid.stepping_dim.spacing 
    damp = model.damp.data

    # Particle Velocity for each direction
    u_vx = Eq(v[0].forward, damp*v[0] + damp*ts*irho*(tau[0,0].dx + tau[1,0].dy + tau[2,0].dz) )
    u_vy = Eq(v[1].forward, damp*v[1] + damp*ts*irho*(tau[0,1].dx + tau[1,1].dy + tau[1,2].dz) )
    u_vz = Eq(v[2].forward, damp*v[2] + damp*ts*irho*(tau[0,2].dx + tau[2,1].dy + tau[2,2].dz) )

    # Stress for each direction in VTI Media:
    u_txx = Eq(tau[0,0].forward, damp*tau[0,0] + damp*ts*(c11*v[0].forward.dx + c11*v[1].forward.dy - 2*c66*v[1].forward.dy + c13*v[2].forward.dz) )
    u_tyy = Eq(tau[1,1].forward, damp*tau[1,1] + damp*ts*(c11*v[0].forward.dx - 2*c66*v[0].forward.dx + c11*v[1].forward.dy + c13*v[2].forward.dz) )
    u_tzz = Eq(tau[2,2].forward, damp*tau[2,2] + damp*ts*(c13*v[0].forward.dx + c13*v[1].forward.dy + c33*v[2].forward.dz) )

    u_txz = Eq(tau[0,2].forward, damp*tau[0,2] + damp*ts*(c44*v[2].forward.dx + c44*v[0].forward.dz) )
    u_tyz = Eq(tau[1,2].forward, damp*tau[1,2] + damp*ts*(c44*v[2].forward.dy + c44*v[1].forward.dz) )
    u_txy = Eq(tau[0,1].forward, damp*tau[0,1] + damp*ts*(c66*v[1].forward.dx + c66*v[0].forward.dy) )
    
    stencil = [u_vx, u_vy, u_vz, u_txx, u_tyy, u_tzz, u_txz, u_tyz, u_txy]
    #srcrec = src_rec(v, tau, model, geometry)

    src = PointSource(name='src', grid=model.grid, time_range=geometry.time_axis,
                      npoint=geometry.nsrc)
                      
    rec = Receiver(name='rec', grid=geometry.grid, time_range=geometry.time_axis,
                   npoint=geometry.nrec)

    # The source injection term
    src_xx = src.inject(field=tau[0, 0].forward, expr=src * ts)
    src_zz = src.inject(field=tau[-1, -1].forward, expr=src * ts)
    src_term = src_xx + src_zz
    if model.grid.dim == 3:
        src_yy = src.inject(field=tau[1, 1].forward, expr=src * ts)
        src_term += src_yy

    # Create interpolation expression for receivers
    rec_term = rec.interpolate(expr=v)

    srcrec = src_term + rec_term
    pde = stencil + srcrec

    # Substitute spacing terms to reduce flops
    op = Operator(pde, subs=model.spacing_map, name="ForwardElasticVTI", **kwargs)

    
    return op
예제 #21
0
# Recs are distributed across model, at depth of 20 m.
z_extent, _ = model.domain_size
z_locations = np.linspace(0, z_extent, num=nreceivers)
rec_coords = np.array([(980, z) for z in z_locations])

# NOT FOR MANUSCRIPT
from examples.seismic import PointSource

residual = PointSource(name='residual',
                       ntime=nt,
                       grid=model.grid,
                       coordinates=rec_coords)

res_term = residual.inject(field=v.backward,
                           expr=residual * dt**2 / model.m,
                           offset=model.nbpml)

# NOT FOR MANUSCRIPT
rec = Receiver(name='rec',
               npoint=nreceivers,
               ntime=nt,
               grid=model.grid,
               coordinates=rec_coords)

# NOT FOR MANUSCRIPT
from examples.seismic import RickerSource

# At first, we want only a single shot.
# Src is 5% across model, at depth of 500 m.
z_locations = np.linspace(0, z_extent, num=nshots)
예제 #22
0
def ForwardOperator(model,
                    geometry,
                    space_order=4,
                    kernel='blanch_symes',
                    save=False,
                    **kwargs):
    """
    Construct method for the forward modelling operator in a viscoacoustic 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.
    kernel : selects a visco-acoustic equation from the options below:
        blanch_symes - Blanch and Symes (1995) / Dutta and Schuster (2014)
        viscoacoustic equation
        ren - Ren et al. (2014) viscoacoustic equation
        deng_mcmechan - Deng and McMechan (2007) viscoacoustic equation
        Defaults to blanch_symes.
    save : int or Buffer
        Saving flag, True saves all time steps, False saves three buffered
        indices (last three time steps). Defaults to False.
    """
    s = model.grid.stepping_dim.spacing

    # Create symbols for forward wavefield, particle velocity, source and receivers
    # Velocity:
    v = VectorTimeFunction(name="v",
                           grid=model.grid,
                           save=geometry.nt if save else None,
                           time_order=1,
                           space_order=space_order)

    p = TimeFunction(name="p",
                     grid=model.grid,
                     staggered=NODE,
                     save=geometry.nt if save else None,
                     time_order=1,
                     space_order=space_order)

    src = PointSource(name="src",
                      grid=model.grid,
                      time_range=geometry.time_axis,
                      npoint=geometry.nsrc)

    rec = Receiver(name="rec",
                   grid=model.grid,
                   time_range=geometry.time_axis,
                   npoint=geometry.nrec)

    # Equations kernels
    eq_kernel = kernels[kernel]
    eqn = eq_kernel(model, geometry, v, p, save=save)

    # The source injection term
    src_term = src.inject(field=p.forward, expr=src * s)

    # Create interpolation expression for receivers
    rec_term = rec.interpolate(expr=p)

    # Substitute spacing terms to reduce flops
    return Operator(eqn + src_term + rec_term,
                    subs=model.spacing_map,
                    name='Forward',
                    **kwargs)
예제 #23
0
def ForwardOperator(model,
                    source,
                    receiver,
                    space_order=4,
                    save=False,
                    kernel='centered',
                    **kwargs):
    """
       Constructor method for the forward modelling operator in an acoustic media

       :param model: :class:`Model` object containing the physical parameters
       :param src: None ot IShot() (not currently supported properly)
       :param data: IShot() object containing the acquisition geometry and field data
       :param: time_order: Time discretization order
       :param: spc_order: Space discretization order
       """
    dt = model.grid.time_dim.spacing

    m, damp, epsilon, delta, theta, phi = (model.m, model.damp, model.epsilon,
                                           model.delta, model.theta, model.phi)

    # Create symbols for forward wavefield, source and receivers
    u = TimeFunction(name='u',
                     grid=model.grid,
                     save=save,
                     time_dim=source.nt if save else None,
                     time_order=2,
                     space_order=space_order)
    v = TimeFunction(name='v',
                     grid=model.grid,
                     save=save,
                     time_dim=source.nt if save else None,
                     time_order=2,
                     space_order=space_order)
    src = PointSource(name='src',
                      grid=model.grid,
                      ntime=source.nt,
                      npoint=source.npoint)
    rec = Receiver(name='rec',
                   grid=model.grid,
                   ntime=receiver.nt,
                   npoint=receiver.npoint)

    # Tilt and azymuth setup
    ang0 = cos(theta)
    ang1 = sin(theta)
    ang2 = 0
    ang3 = 0
    if len(model.shape) == 3:
        ang2 = cos(phi)
        ang3 = sin(phi)

    FD_kernel = kernels[(kernel, len(model.shape))]
    H0, Hz = FD_kernel(u, v, ang0, ang1, ang2, ang3, space_order)

    # Stencils
    s = model.grid.stepping_dim.spacing
    stencilp = 1.0 / (2.0 * m + s * damp) * \
        (4.0 * m * u + (s * damp - 2.0 * m) *
         u.backward + 2.0 * s ** 2 * (epsilon * H0 + delta * Hz))
    stencilr = 1.0 / (2.0 * m + s * damp) * \
        (4.0 * m * v + (s * damp - 2.0 * m) *
         v.backward + 2.0 * s ** 2 * (delta * H0 + Hz))
    first_stencil = Eq(u.forward, stencilp)
    second_stencil = Eq(v.forward, stencilr)
    stencils = [first_stencil, second_stencil]

    # Source and receivers
    stencils += src.inject(field=u.forward,
                           expr=src * dt * dt / m,
                           offset=model.nbpml)
    stencils += src.inject(field=v.forward,
                           expr=src * dt * dt / m,
                           offset=model.nbpml)
    stencils += rec.interpolate(expr=u + v, offset=model.nbpml)

    # Substitute spacing terms to reduce flops
    return Operator(stencils,
                    subs=model.spacing_map,
                    name='ForwardTTI',
                    **kwargs)
예제 #24
0
def ForwardOperator(model,
                    source,
                    receiver,
                    time_order=2,
                    space_order=4,
                    save=False,
                    **kwargs):
    """
    Constructor method for the forward modelling operator in an acoustic media

    :param model: :class:`Model` object containing the physical parameters
    :param src: None ot IShot() (not currently supported properly)
    :param data: IShot() object containing the acquisition geometry and field data
    :param: time_order: Time discretization order
    :param: spc_order: Space discretization order
    :param: u_ini : wavefield at the three first time step for non-zero initial condition
    """
    dt = model.critical_dt

    m, damp, epsilon, delta, theta, phi = (model.m, model.damp, model.epsilon,
                                           model.delta, model.theta, model.phi)

    # Create symbols for forward wavefield, source and receivers
    u = TimeData(name='u',
                 shape=model.shape_domain,
                 time_dim=source.nt,
                 time_order=time_order,
                 space_order=space_order,
                 save=save,
                 dtype=model.dtype)
    v = TimeData(name='v',
                 shape=model.shape_domain,
                 time_dim=source.nt,
                 time_order=time_order,
                 space_order=space_order,
                 save=save,
                 dtype=model.dtype)
    src = PointSource(name='src',
                      ntime=source.nt,
                      ndim=source.ndim,
                      npoint=source.npoint)
    rec = Receiver(name='rec',
                   ntime=receiver.nt,
                   ndim=receiver.ndim,
                   npoint=receiver.npoint)

    ang0 = cos(theta)
    ang1 = sin(theta)
    if len(model.shape) == 3:
        ang2 = cos(phi)
        ang3 = sin(phi)

        # Derive stencil from symbolic equation
        Gyp = (ang3 * u.dx - ang2 * u.dyr)
        Gyy = (first_derivative(Gyp * ang3,
                                dim=x,
                                side=centered,
                                order=space_order,
                                matvec=transpose) -
               first_derivative(Gyp * ang2,
                                dim=y,
                                side=right,
                                order=space_order,
                                matvec=transpose))
        Gyp2 = (ang3 * u.dxr - ang2 * u.dy)
        Gyy2 = (first_derivative(Gyp2 * ang3,
                                 dim=x,
                                 side=right,
                                 order=space_order,
                                 matvec=transpose) -
                first_derivative(Gyp2 * ang2,
                                 dim=y,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose))

        Gxp = (ang0 * ang2 * u.dx + ang0 * ang3 * u.dyr - ang1 * u.dzr)
        Gzr = (ang1 * ang2 * v.dx + ang1 * ang3 * v.dyr + ang0 * v.dzr)
        Gxx = (first_derivative(Gxp * ang0 * ang2,
                                dim=x,
                                side=centered,
                                order=space_order,
                                matvec=transpose) +
               first_derivative(Gxp * ang0 * ang3,
                                dim=y,
                                side=right,
                                order=space_order,
                                matvec=transpose) -
               first_derivative(Gxp * ang1,
                                dim=z,
                                side=right,
                                order=space_order,
                                matvec=transpose))
        Gzz = (first_derivative(Gzr * ang1 * ang2,
                                dim=x,
                                side=centered,
                                order=space_order,
                                matvec=transpose) +
               first_derivative(Gzr * ang1 * ang3,
                                dim=y,
                                side=right,
                                order=space_order,
                                matvec=transpose) +
               first_derivative(Gzr * ang0,
                                dim=z,
                                side=right,
                                order=space_order,
                                matvec=transpose))
        Gxp2 = (ang0 * ang2 * u.dxr + ang0 * ang3 * u.dy - ang1 * u.dz)
        Gzr2 = (ang1 * ang2 * v.dxr + ang1 * ang3 * v.dy + ang0 * v.dz)
        Gxx2 = (first_derivative(Gxp2 * ang0 * ang2,
                                 dim=x,
                                 side=right,
                                 order=space_order,
                                 matvec=transpose) +
                first_derivative(Gxp2 * ang0 * ang3,
                                 dim=y,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose) -
                first_derivative(Gxp2 * ang1,
                                 dim=z,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose))
        Gzz2 = (first_derivative(Gzr2 * ang1 * ang2,
                                 dim=x,
                                 side=right,
                                 order=space_order,
                                 matvec=transpose) +
                first_derivative(Gzr2 * ang1 * ang3,
                                 dim=y,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose) +
                first_derivative(Gzr2 * ang0,
                                 dim=z,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose))
        Hp = -(.5 * Gxx + .5 * Gxx2 + .5 * Gyy + .5 * Gyy2)
        Hzr = -(.5 * Gzz + .5 * Gzz2)

    else:
        Gx1p = (ang0 * u.dxr - ang1 * u.dy)
        Gz1r = (ang1 * v.dxr + ang0 * v.dy)
        Gxx1 = (first_derivative(Gx1p * ang0,
                                 dim=x,
                                 side=right,
                                 order=space_order,
                                 matvec=transpose) -
                first_derivative(Gx1p * ang1,
                                 dim=y,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose))
        Gzz1 = (first_derivative(Gz1r * ang1,
                                 dim=x,
                                 side=right,
                                 order=space_order,
                                 matvec=transpose) +
                first_derivative(Gz1r * ang0,
                                 dim=y,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose))
        Gx2p = (ang0 * u.dx - ang1 * u.dyr)
        Gz2r = (ang1 * v.dx + ang0 * v.dyr)
        Gxx2 = (first_derivative(Gx2p * ang0,
                                 dim=x,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose) -
                first_derivative(Gx2p * ang1,
                                 dim=y,
                                 side=right,
                                 order=space_order,
                                 matvec=transpose))
        Gzz2 = (first_derivative(Gz2r * ang1,
                                 dim=x,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose) +
                first_derivative(Gz2r * ang0,
                                 dim=y,
                                 side=right,
                                 order=space_order,
                                 matvec=transpose))

        Hp = -(.5 * Gxx1 + .5 * Gxx2)
        Hzr = -(.5 * Gzz1 + .5 * Gzz2)

    stencilp = 1.0 / (2.0 * m + s * damp) * \
        (4.0 * m * u + (s * damp - 2.0 * m) *
         u.backward + 2.0 * s**2 * (epsilon * Hp + delta * Hzr))
    stencilr = 1.0 / (2.0 * m + s * damp) * \
        (4.0 * m * v + (s * damp - 2.0 * m) *
         v.backward + 2.0 * s**2 * (delta * Hp + Hzr))

    # Add substitutions for spacing (temporal and spatial)
    subs = {s: dt, h: model.get_spacing()}
    first_stencil = Eq(u.forward, stencilp)
    second_stencil = Eq(v.forward, stencilr)
    stencils = [first_stencil, second_stencil]

    ti = u.indices[0]
    stencils += src.inject(field=u,
                           u_t=ti + 1,
                           expr=src * dt * dt / m,
                           offset=model.nbpml)
    stencils += src.inject(field=v,
                           u_t=ti + 1,
                           expr=src * dt * dt / m,
                           offset=model.nbpml)
    stencils += rec.interpolate(expr=u, u_t=ti, offset=model.nbpml)
    stencils += rec.interpolate(expr=v, u_t=ti, offset=model.nbpml)

    return Operator(stencils, subs=subs, name='ForwardTTI', **kwargs)
예제 #25
0
def ForwardOperator(model,
                    source,
                    receiver,
                    space_order=4,
                    save=False,
                    **kwargs):
    """
    Constructor method for the forward modelling operator in an elastic media

    :param model: :class:`Model` object containing the physical parameters
    :param source: :class:`PointData` object containing the source geometry
    :param receiver: :class:`PointData` object containing the acquisition geometry
    :param space_order: Space discretization order
    :param save: Saving flag, True saves all time steps, False only the three buffered
                 indices (last three time steps)
    """
    vp, vs, rho, damp = model.vp, model.vs, model.rho, model.damp
    s = model.grid.stepping_dim.spacing
    x, z = model.grid.dimensions
    cp2 = vp * vp
    cs2 = vs * vs
    ro = 1 / rho

    mu = cs2 * rho
    l = rho * (cp2 - 2 * cs2)

    # Create symbols for forward wavefield, source and receivers
    vx = TimeFunction(name='vx',
                      grid=model.grid,
                      staggered=(0, 1, 0),
                      save=source.nt if save else None,
                      time_order=2,
                      space_order=space_order)
    vz = TimeFunction(name='vz',
                      grid=model.grid,
                      staggered=(0, 0, 1),
                      save=source.nt if save else None,
                      time_order=2,
                      space_order=space_order)
    txx = TimeFunction(name='txx',
                       grid=model.grid,
                       save=source.nt if save else None,
                       time_order=2,
                       space_order=space_order)
    tzz = TimeFunction(name='tzz',
                       grid=model.grid,
                       save=source.nt if save else None,
                       time_order=2,
                       space_order=space_order)
    txz = TimeFunction(name='txz',
                       grid=model.grid,
                       staggered=(0, 1, 1),
                       save=source.nt if save else None,
                       time_order=2,
                       space_order=space_order)
    # Source symbol with input wavelet
    src = PointSource(name='src',
                      grid=model.grid,
                      time_range=source.time_range,
                      npoint=source.npoint)
    rec1 = Receiver(name='rec1',
                    grid=model.grid,
                    time_range=receiver.time_range,
                    npoint=receiver.npoint)
    rec2 = Receiver(name='rec2',
                    grid=model.grid,
                    time_range=receiver.time_range,
                    npoint=receiver.npoint)
    # Stencils
    fd_vx = (staggered_diff(txx, dim=x, order=space_order, stagger=left) +
             staggered_diff(txz, dim=z, order=space_order, stagger=right))
    u_vx = Eq(vx.forward, damp * vx - damp * s * ro * fd_vx)

    fd_vz = (staggered_diff(txz, dim=x, order=space_order, stagger=right) +
             staggered_diff(tzz, dim=z, order=space_order, stagger=left))
    u_vz = Eq(vz.forward, damp * vz - damp * ro * s * fd_vz)

    vxdx = staggered_diff(vx.forward, dim=x, order=space_order, stagger=right)
    vzdz = staggered_diff(vz.forward, dim=z, order=space_order, stagger=right)
    u_txx = Eq(
        txx.forward,
        damp * txx - damp * (l + 2 * mu) * s * vxdx - damp * l * s * vzdz)
    u_tzz = Eq(
        tzz.forward,
        damp * tzz - damp * (l + 2 * mu) * s * vzdz - damp * l * s * vxdx)

    vxdz = staggered_diff(vx.forward, dim=z, order=space_order, stagger=left)
    vzdx = staggered_diff(vz.forward, dim=x, order=space_order, stagger=left)
    u_txz = Eq(txz.forward, damp * txz - damp * mu * s * (vxdz + vzdx))

    # The source injection term
    src_xx = src.inject(field=txx.forward, expr=src * s, offset=model.nbpml)
    src_zz = src.inject(field=tzz.forward, expr=src * s, offset=model.nbpml)

    # Create interpolation expression for receivers
    rec_term1 = rec1.interpolate(expr=txx, offset=model.nbpml)
    rec_term2 = rec2.interpolate(expr=tzz, offset=model.nbpml)
    # Substitute spacing terms to reduce flops
    return Operator([u_vx, u_vz, u_txx, u_tzz, u_txz] + src_xx + src_zz +
                    rec_term1 + rec_term2,
                    subs=model.spacing_map,
                    name='Forward',
                    **kwargs)
예제 #26
0
def ForwardOperator(model,
                    source,
                    receiver,
                    time_order=2,
                    space_order=4,
                    save=False,
                    **kwargs):
    """
    Constructor method for the forward modelling operator in an acoustic media

    :param model: :class:`Model` object containing the physical parameters
    :param source: :class:`PointData` object containing the source geometry
    :param receiver: :class:`PointData` object containing the acquisition geometry
    :param time_order: Time discretization order
    :param space_order: Space discretization order
    :param save: Saving flag, True saves all time steps, False only the three
    """
    m, damp = model.m, model.damp

    # Create symbols for forward wavefield, source and receivers
    u = TimeData(name='u',
                 shape=model.shape_domain,
                 dtype=model.dtype,
                 save=save,
                 time_dim=source.nt if save else None,
                 time_order=time_order,
                 space_order=space_order)
    src = PointSource(name='src',
                      ntime=source.nt,
                      ndim=source.ndim,
                      npoint=source.npoint)
    rec = Receiver(name='rec',
                   ntime=receiver.nt,
                   ndim=receiver.ndim,
                   npoint=receiver.npoint)

    if time_order == 2:
        biharmonic = 0
        dt = model.critical_dt
    else:
        biharmonic = u.laplace2(1 / m)
        dt = 1.73 * model.critical_dt

    # Derive both stencils from symbolic equation:
    # Create the stencil by hand instead of calling numpy solve for speed purposes
    # Simple linear solve of a u(t+dt) + b u(t) + c u(t-dt) = L for u(t+dt)

    s = t.spacing

    stencil = 1.0 / (2.0 * m + s * damp) * (
        4.0 * m * u + (s * damp - 2.0 * m) * u.backward + 2.0 * s**2 *
        (u.laplace + s**2 / 12.0 * biharmonic))
    eqn = [Eq(u.forward, stencil)]

    # Construct expression to inject source values
    src_term = src.inject(field=u.forward,
                          expr=src * dt**2 / m,
                          offset=model.nbpml)

    # Create interpolation expression for receivers
    rec_term = rec.interpolate(expr=u, offset=model.nbpml)
    subs = dict([(t.spacing, dt)] + [(time.spacing, dt)] +
                [(i.spacing, model.get_spacing()[j])
                 for i, j in zip(u.indices[1:], range(len(model.shape)))])
    return Operator(eqn + src_term + rec_term,
                    subs=subs,
                    time_axis=Forward,
                    name='Forward',
                    **kwargs)