예제 #1
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)
예제 #2
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)
예제 #3
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)
예제 #4
0
파일: operators.py 프로젝트: opesci/devito
def AdjointOperator(model, geometry, space_order=4,
                    kernel='OT2', **kwargs):
    """
    Constructor method for the adjoint 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
    """
    m, damp = model.m, model.damp

    v = TimeFunction(name='v', grid=model.grid, save=None,
                     time_order=2, space_order=space_order)
    srca = PointSource(name='srca', 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)

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

    # Construct expression to inject receiver values
    receivers = rec.inject(field=v.backward, expr=rec * s**2 / m)

    # Create interpolation expression for the adjoint-source
    source_a = srca.interpolate(expr=v)

    # Substitute spacing terms to reduce flops
    return Operator(eqn + receivers + source_a, subs=model.spacing_map,
                    name='Adjoint', **kwargs)
예제 #5
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
예제 #6
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
예제 #7
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)
예제 #8
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
예제 #9
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)
예제 #10
0
파일: operators.py 프로젝트: yuriyi/devito
def AdjointOperator(model, source, receiver, space_order=4,
                    kernel='OT2', **kwargs):
    """
    Constructor method for the adjoint 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
    """
    m, damp = model.m, model.damp

    v = TimeFunction(name='v', grid=model.grid, save=None,
                     time_order=2, space_order=space_order)
    srca = PointSource(name='srca', 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(v, m, s, damp, kernel, forward=False)

    # Construct expression to inject receiver values
    receivers = rec.inject(field=v.backward, expr=rec * s**2 / m,
                           offset=model.nbpml)

    # Create interpolation expression for the adjoint-source
    source_a = srca.interpolate(expr=v, offset=model.nbpml)

    # Substitute spacing terms to reduce flops
    return Operator(eqn + receivers + source_a, subs=model.spacing_map,
                    name='Adjoint', **kwargs)
예제 #11
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
예제 #12
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)
예제 #13
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)
예제 #14
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)
예제 #15
0
def AdjointOperator(model, geometry, space_order=4, **kwargs):
    """
    Construct an adjoint 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.
    """

    dt = model.grid.time_dim.spacing
    m = model.m
    time_order = 2

    # Create symbols for forward wavefield, source and receivers
    p = TimeFunction(name='p',
                     grid=model.grid,
                     save=None,
                     time_order=time_order,
                     space_order=space_order)
    r = TimeFunction(name='r',
                     grid=model.grid,
                     save=None,
                     time_order=time_order,
                     space_order=space_order)
    srca = PointSource(name='srca',
                       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[('centered', len(model.shape))]
    stencils = FD_kernel(model, p, r, space_order, forward=False)

    # Construct expression to inject receiver values
    stencils += rec.inject(field=p.backward, expr=rec * dt**2 / m)
    stencils += rec.inject(field=r.backward, expr=rec * dt**2 / m)

    # Create interpolation expression for the adjoint-source
    stencils += srca.interpolate(expr=p + r)

    # Substitute spacing terms to reduce flops
    return Operator(stencils,
                    subs=model.spacing_map,
                    name='AdjointTTI',
                    **kwargs)
예제 #16
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)
예제 #17
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)
예제 #18
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)
예제 #19
0
    def adjoint(self, rec, srca=None, v=None, m=None, **kwargs):
        """
        Adjoint modelling function that creates the necessary
        data objects for running an adjoint modelling operator.

        :param rec: Symbol with stored receiver data. Please note that
                    these act as the source term in the adjoint run.
        :param srca: Symbol to store the resulting data for the
                     interpolated at the original source location.
        :param v: (Optional) Symbol to store the computed wavefield
        :param m: (Optional) Symbol for the time-constant square slowness

        :returns: Adjoint source, wavefield and performance summary
        """
        # Create a new adjoint source and receiver symbol
        srca = srca or PointSource(name='srca', grid=self.model.grid,
                                   time_range=self.geometry.time_axis,
                                   coordinates=self.geometry.src_positions)

        # Create the adjoint wavefield if not provided
        v = v or TimeFunction(name='v', grid=self.model.grid,
                              time_order=2, space_order=self.space_order)

        # Pick m from model unless explicitly provided
        m = m or self.model.m

        # Execute operator and return wavefield and receiver data
        summary = self.op_adj().apply(srca=srca, rec=rec, v=v, m=m,
                                      dt=kwargs.pop('dt', self.dt), **kwargs)
        return srca, v, summary
예제 #20
0
def setup(dimensions=(50, 50, 50),
          spacing=(20.0, 20.0, 20.0),
          tn=250.0,
          time_order=2,
          space_order=4,
          nbpml=10,
          dse='advanced'):

    origin = (0., 0., 0.)

    # True velocity
    true_vp = np.ones(dimensions) + 1.0
    true_vp[:, :, int(dimensions[0] / 3):int(2 * dimensions[0] / 3)] = 3.0
    true_vp[:, :, int(2 * dimensions[0] / 3):int(dimensions[0])] = 4.0

    model = Model(origin,
                  spacing,
                  dimensions,
                  true_vp,
                  nbpml=nbpml,
                  epsilon=.4 * np.ones(dimensions),
                  delta=-.1 * np.ones(dimensions),
                  theta=-np.pi / 7 * np.ones(dimensions),
                  phi=np.pi / 5 * np.ones(dimensions))

    # Define seismic data.

    f0 = .010
    dt = model.critical_dt
    t0 = 0.0
    nt = int(1 + (tn - t0) / dt)
    # Set up the source as Ricker wavelet for f0

    # Source geometry
    time_series = np.zeros((nt, 1))

    time_series[:, 0] = source(np.linspace(t0, tn, nt), f0)

    location = np.zeros((1, 3))
    location[0, 0] = origin[0] + dimensions[0] * spacing[0] * 0.5
    location[0, 1] = origin[1] + dimensions[1] * spacing[1] * 0.5
    location[0, 2] = origin[1] + 2 * spacing[2]
    src = PointSource(name='src', data=time_series, coordinates=location)

    # Receiver geometry
    receiver_coords = np.zeros((101, 3))
    receiver_coords[:, 0] = np.linspace(0,
                                        origin[0] + dimensions[0] * spacing[0],
                                        num=101)
    receiver_coords[:, 1] = origin[1] + dimensions[1] * spacing[1] * 0.5
    receiver_coords[:, 2] = location[0, 1]
    rec = Receiver(name='rec', ntime=nt, coordinates=receiver_coords)

    return AnisotropicWaveSolver(model,
                                 source=src,
                                 time_order=time_order,
                                 space_order=space_order,
                                 receiver=rec,
                                 dse=dse)
예제 #21
0
    def adjoint(self, rec, srca=None, p=None, r=None, vp=None,
                epsilon=None, delta=None, theta=None, phi=None,
                save=None, **kwargs):
        """
        Adjoint modelling function that creates the necessary
        data objects for running an adjoint modelling operator.

        Parameters
        ----------
        geometry : AcquisitionGeometry
            Geometry object that contains the source (SparseTimeFunction) and
            receivers (SparseTimeFunction) and their position.
        p : TimeFunction, optional
            The computed wavefield first component.
        r : TimeFunction, optional
            The computed wavefield second component.
        vp : Function or float, optional
            The time-constant velocity.
        epsilon : Function or float, optional
            The time-constant first Thomsen parameter.
        delta : Function or float, optional
            The time-constant second Thomsen parameter.
        theta : Function or float, optional
            The time-constant Dip angle (radians).
        phi : Function or float, optional
            The time-constant Azimuth angle (radians).

        Returns
        -------
        Adjoint source, wavefield and performance summary.
        """

        time_order = 2
        stagg_p = stagg_r = None
        # Source term is read-only, so re-use the default
        srca = srca or PointSource(name='srca', grid=self.model.grid,
                                   time_range=self.geometry.time_axis,
                                   coordinates=self.geometry.src_positions)
        # Create the wavefield if not provided
        if p is None:
            p = TimeFunction(name='p', grid=self.model.grid, staggered=stagg_p,
                             time_order=time_order,
                             space_order=self.space_order)
        # Create the wavefield if not provided
        if r is None:
            r = TimeFunction(name='r', grid=self.model.grid, staggered=stagg_r,
                             time_order=time_order,
                             space_order=self.space_order)

        # Pick vp and Thomsen parameters from model unless explicitly provided
        kwargs.update(self.model.physical_params(
            vp=vp, epsilon=epsilon, delta=delta, theta=theta, phi=phi)
        )
        if self.model.dim < 3:
            kwargs.pop('phi', None)
        # Execute operator and return wavefield and receiver data
        summary = self.op_adj().apply(srca=srca, rec=rec, p=p, r=r,
                                      dt=kwargs.pop('dt', self.dt), **kwargs)
        return srca, p, r, summary
예제 #22
0
def AdjointOperator(model, geometry, space_order=4, kernel='OT2', **kwargs):
    """
    Construct an adjoint 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.
    space_order : int, optional
        Space discretization order.
    kernel : str, optional
        Type of discretization, centered or shifted.
    """
    m, damp = model.m, model.damp

    v = TimeFunction(name='v',
                     grid=model.grid,
                     save=None,
                     time_order=2,
                     space_order=space_order)
    srca = PointSource(name='srca',
                       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)

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

    # Construct expression to inject receiver values
    receivers = rec.inject(field=v.backward, expr=rec * s**2 / m)

    # Create interpolation expression for the adjoint-source
    source_a = srca.interpolate(expr=v)

    # Substitute spacing terms to reduce flops
    return Operator(eqn + receivers + source_a,
                    subs=model.spacing_map,
                    name='Adjoint',
                    **kwargs)
예제 #23
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)
예제 #24
0
def AdjointOperator(model, source, receiver, time_order=2, space_order=4, **kwargs):
    """
    Constructor method for the adjoint 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
    """
    m, damp = model.m, model.damp

    v = TimeData(name='v', shape=model.shape_domain, save=False,
                 time_order=time_order, space_order=space_order,
                 dtype=model.dtype)
    srca = PointSource(name='srca', 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 = v.laplace2(1/m)
        dt = 1.73 * model.critical_dt

    # Derive both stencils from symbolic equation
    stencil = 1 / (2 * m + s * damp) * (
        4 * m * v + (s * damp - 2 * m) * v.forward +
        2 * s**2 * (v.laplace + s**2 / 12 * biharmonic))
    eqn = Eq(v.backward, stencil)

    # Construct expression to inject receiver values
    ti = v.indices[0]
    receivers = rec.inject(field=v, u_t=ti - 1, offset=model.nbpml,
                           expr=rec * dt**2 / m, p_t=time)

    # Create interpolation expression for the adjoint-source
    source_a = srca.interpolate(expr=v, u_t=ti, offset=model.nbpml)

    return Operator([eqn] + receivers + source_a,
                    subs={s: dt, h: model.get_spacing()},
                    time_axis=Backward, name='Adjoint', **kwargs)
예제 #25
0
def td_born_forward_op(model, geometry, time_order, space_order):

    nt = geometry.nt

    # Define the wavefields with the size of the model and the time dimension
    u0 = TimeFunction(
        name='u0',
        grid=model.grid,
        time_order=time_order,
        space_order=space_order,
        save=nt
    )
    u = TimeFunction(
        name='u',
        grid=model.grid,
        time_order=time_order,
        space_order=space_order,
        save=nt
    )
    dm = TimeFunction(
        name='dm',
        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 - dm * u0

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

    # Sample at receivers
    born_data_rec = PointSource(
        name='born_data_rec',
        grid=model.grid,
        time_range=geometry.time_axis,
        coordinates=geometry.rec_positions
    )
    rec_term = born_data_rec.interpolate(expr=u)

    return Operator([stencil] + rec_term, subs=model.spacing_map)
예제 #26
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
예제 #27
0
    def adjoint(self,
                rec,
                src=None,
                b=None,
                v=None,
                damp=None,
                vp=None,
                save=None,
                **kwargs):
        """
        Adjoint modeling function that creates the necessary
        data objects for running a adjoint modeling operator.
        Required parameters: rec.

        Parameters
        ----------
        rec : SparseTimeFunction
            The interpolated receiver data to be injected.
        src : SparseTimeFunction
            Time series data for the adjoint source term.
        b : Function or float
            The time-constant buoyancy.
        v : Function or float
            The time-constant velocity.
        damp : Function or float
            The time-constant dissipation only attenuation w/Q field.
        ua : Function or float
            Stores the computed adjoint wavefield.
        save : int or Buffer, optional
            Whether (int nt) or not (None) to save the wavefield time history.

        Returns
        ----------
        Adjoint source time series data, wavefield TimeFunction ua,
        and performance summary
        """
        # Create a new adjoint source and receiver symbol
        srca = src or PointSource(name='srca',
                                  grid=self.model.grid,
                                  time_range=self.geometry.time_axis,
                                  coordinates=self.geometry.src_positions)
        # Create the adjoint wavefield if not provided
        v = v or TimeFunction(name='v',
                              grid=self.model.grid,
                              time_order=2,
                              space_order=self.space_order)

        # Pick input physical parameters
        kwargs.update(self.model.physical_params(vp=vp, damp=damp, b=b))
        kwargs.update({'dt': kwargs.pop('dt', self.dt)})

        # Execute operator and return wavefield and receiver data
        summary = self.op_adj(save).apply(src=srca, rec=rec, v=v, **kwargs)
        return srca, v, summary
예제 #28
0
def test_acoustic(dimensions, time_order, space_order):
    solver = setup(dimensions=dimensions, time_order=time_order,
                   space_order=space_order, nbpml=10+space_order/2)
    srca = PointSource(name='srca', ntime=solver.source.nt,
                       coordinates=solver.source.coordinates.data)

    # Run forward and adjoint operators
    rec, _, _ = solver.forward(save=False)
    solver.adjoint(rec=rec, srca=srca)

    # Actual adjoint test
    term1 = np.dot(srca.data.reshape(-1), solver.source.data)
    term2 = linalg.norm(rec.data) ** 2
    print(term1, term2, ("%12.12f") % (term1 - term2), term1 / term2)
    assert np.isclose(term1 / term2, 1.0, atol=0.001)
예제 #29
0
def src_freq_filt(src, cutoff_freq, filt_type='lowpass', filt_order=2):
    """
    Lowpass frequency filter function for the source.

    Parameters
    ----------
    src : Source
        Object with the source information.
    cutoff_freq : float or 2-tuple
        Cutoff frequency or frequencies. For lowpass and highpass filters,
        cutoff_freq is a float. For bandpass and bandstop filters,
        cutoff_freq is a 2-tuple.
    filt_type : str, optional
        The type of the filter (‘lowpass’, ‘highpass’, ‘bandpass’
        or ‘bandstop’). Default is 'lowpass'.
    filt_order : int, optional
        The order of the filter. Default is 2.

    Returns
    -------
    Filtered source.
    """

    src_filtered = PointSource(name='src',
                               grid=src.grid,
                               npoint=1,
                               time_range=src.time_range)

    sos = signal.butter(filt_order,
                        cutoff_freq,
                        btype=filt_type,
                        fs=1 / (src.time_range.step * 0.001),
                        output='sos')
    src_filtered.data[:, 0] = signal.sosfiltfilt(sos, src.data[:, 0])

    return src_filtered
예제 #30
0
def setup(dimensions=(50, 50, 50), spacing=(15.0, 15.0, 15.0), tn=500.,
          time_order=2, space_order=4, nbpml=10, **kwargs):

    ndim = len(dimensions)
    origin = tuple([0.]*ndim)
    spacing = spacing[:ndim]
    # Velocity model, two layers
    true_vp = np.ones(dimensions) + .5
    true_vp[..., int(dimensions[-1] / 3):dimensions[-1]] = 2.5
    # Source location
    location = np.zeros((1, ndim), dtype=np.float32)
    location[0, :-1] = [origin[i] + dimensions[i] * spacing[i] * .5
                        for i in range(ndim-1)]
    location[0, -1] = origin[-1] + 2 * spacing[-1]
    # Receivers locations
    receiver_coords = np.zeros((dimensions[0], ndim), dtype=np.float32)
    receiver_coords[:, 0] = np.linspace(0, origin[0] +
                                        (dimensions[0]-1) * spacing[0],
                                        num=dimensions[0])
    receiver_coords[:, 1:] = location[0, 1:]

    # Define seismic data
    model = Model(origin, spacing, dimensions, true_vp, nbpml=int(nbpml))

    f0 = .010
    dt = model.critical_dt
    if time_order == 4:
        dt *= 1.73
    t0 = 0.0
    tn = tn
    nt = int(1+(tn-t0)/dt)

    # Set up the source as Ricker wavelet for f0
    def source(t, f0):
        r = (np.pi * f0 * (t - 1./f0))
        return (1-2.*r**2)*np.exp(-r**2)

    # Source geometry
    time_series = np.zeros((nt, 1), dtype=np.float32)
    time_series[:, 0] = source(np.linspace(t0, tn, nt), f0)

    # Define source and receivers and create acoustic wave solver
    src = PointSource(name='src', data=time_series, coordinates=location)
    rec = Receiver(name='rec', ntime=nt, coordinates=receiver_coords)
    return AcousticWaveSolver(model, source=src, receiver=rec,
                              time_order=time_order, space_order=space_order,
                              **kwargs)
예제 #31
0
    def adjoint(self, rec, srca=None, v=None, vp=None, **kwargs):
        """
        Adjoint modelling function that creates the necessary
        data objects for running an adjoint modelling operator.

        Parameters
        ----------
        rec : SparseTimeFunction or array-like
            The receiver data. Please note that
            these act as the source term in the adjoint run.
        srca : SparseTimeFunction or array-like
            The resulting data for the interpolated at the
            original source location.
        v: TimeFunction, optional
            The computed wavefield.
        vp : Function or float, optional
            The time-constant velocity.

        Returns
        -------
        Adjoint source, wavefield and performance summary.
        """
        # Create a new adjoint source and receiver symbol
        srca = srca or PointSource(name='srca',
                                   grid=self.model.grid,
                                   time_range=self.geometry.time_axis,
                                   coordinates=self.geometry.src_positions)

        # Create the adjoint wavefield if not provided
        v = v or TimeFunction(name='v',
                              grid=self.model.grid,
                              time_order=2,
                              space_order=self.space_order)

        # Pick vp from model unless explicitly provided
        vp = vp or self.model.vp

        # Execute operator and return wavefield and receiver data
        summary = self.op_adj().apply(srca=srca,
                                      rec=rec,
                                      v=v,
                                      vp=vp,
                                      dt=kwargs.pop('dt', self.dt),
                                      **kwargs)
        return srca, v, summary
 def element(self, inp=None):
     """Return an element from ``inp`` or from scratch.
     This method should be overridden by subclasses.
     """
     if isinstance(self.input, Function):
         # from IPython import embed; embed()
         new = Function(name=self.name + '_out',
                        grid=self.input.grid,
                        space_order=self.input.space_order)
     elif isinstance(self.input, PointSource):
         new = PointSource(name=self.name + '_new',
                           grid=self.input.grid,
                           coordinates=self.input.coordinates.data[:],
                           time_range=self.input.time_range,
                           npoint=self.input.npoint)
     if inp is not None:
         new.data[:] = inp
     return new
예제 #33
0
def run_acoustic_forward(dse=None):
    dimensions = (50, 50, 50)
    origin = (0., 0., 0.)
    spacing = (10., 10., 10.)
    nbpml = 10

    # True velocity
    true_vp = np.ones(dimensions) + 2.0
    true_vp[:, :, int(dimensions[0] / 2):int(dimensions[0])] = 4.5

    model = Model(origin, spacing, dimensions, true_vp, nbpml=nbpml)

    # Define seismic data.
    f0 = .010
    dt = model.critical_dt
    t0 = 0.0
    tn = 250.0
    nt = int(1 + (tn - t0) / dt)

    t = np.linspace(t0, tn, nt)
    r = (np.pi * f0 * (t - 1. / f0))
    # Source geometry
    time_series = np.zeros((nt, 1))
    time_series[:, 0] = (1 - 2. * r**2) * np.exp(-r**2)

    location = np.zeros((1, 3))
    location[0, 0] = origin[0] + dimensions[0] * spacing[0] * 0.5
    location[0, 1] = origin[1] + dimensions[1] * spacing[1] * 0.5
    location[0, 2] = origin[1] + 2 * spacing[2]

    # Receiver geometry
    receiver_coords = np.zeros((101, 3))
    receiver_coords[:, 0] = np.linspace(0,
                                        origin[0] + dimensions[0] * spacing[0],
                                        num=101)
    receiver_coords[:, 1] = origin[1] + dimensions[1] * spacing[1] * 0.5
    receiver_coords[:, 2] = location[0, 1]

    src = PointSource(name='src', data=time_series, coordinates=location)
    rec = Receiver(name='rec', ntime=nt, coordinates=receiver_coords)
    acoustic = AcousticWaveSolver(model, source=src, receiver=rec)
    rec, u, _ = acoustic.forward(save=False, dse=dse, dle='basic')

    return u, rec
예제 #34
0
    def adjoint(self, rec, srca=None, v=None, m=None, **kwargs):
        """
        Adjoint modelling function that creates the necessary
        data objects for running an adjoint modelling operator.

        :param rec: Symbol with stored receiver data. Please note that
                    these act as the source term in the adjoint run.
        :param srca: Symbol to store the resulting data for the
                     interpolated at the original source location.
        :param v: (Optional) Symbol to store the computed wavefield
        :param m: (Optional) Symbol for the time-constant square slowness

        :returns: Adjoint source, wavefield and performance summary
        """
        # Create a new adjoint source and receiver symbol
        if srca is None:
            srca = PointSource(name='srca',
                               ntime=self.source.nt,
                               coordinates=self.source.coordinates.data)

        # Create the adjoint wavefield if not provided
        if v is None:
            v = TimeData(name='v',
                         shape=self.model.shape_domain,
                         save=False,
                         time_order=self.time_order,
                         space_order=self.space_order,
                         dtype=self.model.dtype)

        # Pick m from model unless explicitly provided
        if m is None:
            m = self.model.m

        # Execute operator and return wavefield and receiver data
        summary = self.op_adj.apply(srca=srca, rec=rec, v=v, m=m, **kwargs)
        return srca, v, summary