Exemplo n.º 1
0
def forward_wf_src_norec(model, u, space_order=8):
    """
    Forward modeling of a full wavefield source without receiver F*u.

    Parameters
    ----------
    model: Model
        Physical model
    u: TimeFunction or Array
        Time-space dependent wavefield
    space_order: Int (optional)
        Spatial discretization order, defaults to 8

    Returns
    ----------
    Array
        Wavefield
    """
    wf_src = TimeFunction(name='wf_src',
                          grid=model.grid,
                          time_order=2,
                          space_order=space_order,
                          save=u.shape[0])
    if isinstance(u, TimeFunction):
        wf_src._data = u._data
    else:
        wf_src.data[:] = u[:]
    _, u, _ = forward(model,
                      None,
                      None,
                      None,
                      space_order=space_order,
                      save=True,
                      q=wf_src)
    return u.data
Exemplo n.º 2
0
def adjoint_wf_src_norec(model, u, space_order=8, free_surface=False):
    """
    Adjoint/backward modeling of a full wavefield (full wavefield as adjoint source)
    F^T*u.

    Parameters
    ----------
    model: Model
        Physical model
    u: Array or TimeFunction
        Time-space dependent source
    space_order: Int (optional)
        Spatial discretization order, defaults to 8
    free_surface: Bool (optional)
        Whether or not to use a free surface

    Returns
    ----------
    Array
        Adjoint wavefield
    """
    wf_src = TimeFunction(name='wf_src', grid=model.grid, time_order=2,
                          space_order=space_order, save=u.shape[0])
    if isinstance(u, TimeFunction):
        wf_src._data = u._data
    else:
        wf_src.data[:] = u[:]
    _, v = adjoint(model, None, None, None, space_order=space_order,
                   save=True, free_surface=free_surface, q=wf_src)
    return v.data
Exemplo n.º 3
0
def adjoint_wf_src(model, u, src_coords, space_order=8, free_surface=False):
    """
    Adjoint/backward modeling of a full wavefield (full wavefield as adjoint source)
    Ps*F^T*u.

    Parameters
    ----------
    model: Model
        Physical model
    u: Array or TimeFunction
        Time-space dependent source
    src_coords: Array
        Source coordinates
    space_order: Int (optional)
        Spatial discretization order, defaults to 8
    free_surface: Bool (optional)
        Whether or not to use a free surface

    Returns
    ----------
    Array
        Shot record (sampled at source position(s))
    """
    wf_src = TimeFunction(name='wf_src', grid=model.grid, time_order=2,
                          space_order=space_order, save=u.shape[0])
    if isinstance(u, TimeFunction):
        wf_src._data = u._data
    else:
        wf_src.data[:] = u[:]
    rec, _ = adjoint(model, None, src_coords, None, space_order=space_order,
                     free_surface=free_surface, q=wf_src)
    return rec.data
Exemplo n.º 4
0
def forward_wf_src(model, u, rec_coords, space_order=8, free_surface=False):
    """
    Forward modeling of a full wavefield source Pr*F*u.

    Parameters
    ----------
    model: Model
        Physical model
    u: TimeFunction or Array
        Time-space dependent wavefield
    rec_coords: Array
        Coordiantes of the receiver(s)
    space_order: Int (optional)
        Spatial discretization order, defaults to 8
    free_surface: Bool (optional)
        Whether or not to use a free surface

    Returns
    ----------
    Array
        Shot record
    """
    wf_src = TimeFunction(name='wf_src', grid=model.grid, time_order=2,
                          space_order=space_order, save=u.shape[0])
    if isinstance(u, TimeFunction):
        wf_src._data = u._data
    else:
        wf_src.data[:] = u[:]
    rec, _ = forward(model, None, rec_coords, None, space_order=space_order,
                     free_surface=free_surface, q=wf_src)
    return rec.data
def adjoint_modeling(model, src_coords, rec_coords, rec_data, space_order=8, free_surface=False, dt=None):
    clear_cache()

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

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

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

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

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

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

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

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

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

    # Create operator and run

    subs = model.spacing_map
    subs[v.grid.time_dim.spacing] = dt
    op = Operator(expression, subs=subs, dse='advanced', dle='advanced')
    cf = op.cfunction
    summary = op.apply()
    if src_coords is None:
        return v, summary
    else:
        return src.data, summary
Exemplo n.º 6
0
def forward_modeling(model,
                     src_coords,
                     wavelet,
                     rec_coords,
                     save=False,
                     space_order=8,
                     nb=40,
                     free_surface=False,
                     op_return=False,
                     dt=None):
    clear_cache()

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

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

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

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

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

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

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

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

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

    # Create operator and run
    set_log_level('ERROR')
    subs = model.spacing_map
    subs[u.grid.time_dim.spacing] = dt
    op = Operator(expression,
                  subs=subs,
                  dse='advanced',
                  dle='advanced',
                  name="Forward%s" % randint(1e5))
    if op_return is False:
        op()
        if rec_coords is None:
            return u
        else:
            return rec.data, u
    else:
        return op
Exemplo n.º 7
0
def adjoint_modeling(model,
                     src_coords,
                     rec_coords,
                     rec_data,
                     space_order=8,
                     nb=40,
                     free_surface=False,
                     dt=None):
    clear_cache()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    # For optimal checkpointing, return operator only
    else:
        return op