Пример #1
0
def adjoint_w(model, rec_coords, data, wavelet, space_order=8):
    """
    Adjoint/backward modeling of a shot record (receivers as source) for an
    extended source setup Pw*F^T*Pr^T*d_obs.

    Parameters
    ----------
    model: Model
        Physical model
    rec_coords: Array
        Coordiantes of the receiver(s)
    data: Array
        Shot gather
    wavelet: Array
        Time signature of the forward source for stacking along time
    space_order: Int (optional)
        Spatial discretization order, defaults to 8

    Returns
    ----------
    Array
        spatial distribution
    """
    w, _ = adjoint(model,
                   data,
                   None,
                   rec_coords,
                   ws=wavelet,
                   space_order=space_order)
    return w.data
Пример #2
0
def adjoint_no_rec(model, rec_coords, data, space_order=8):
    """
    Adjoint/backward modeling of a shot record (receivers as source)
    without source sampling F^T*Pr^T*d_obs.

    Parameters
    ----------
    model: Model
        Physical model
    rec_coords: Array
        Coordiantes of the receiver(s)
    data: Array
        Shot gather
    space_order: Int (optional)
        Spatial discretization order, defaults to 8

    Returns
    ----------
    Array
        Adjoint wavefield
    """
    _, v, _ = adjoint(model,
                      data,
                      None,
                      rec_coords,
                      space_order=space_order,
                      save=True)
    return v.data
Пример #3
0
def adjoint_rec(model, src_coords, rec_coords, data, space_order=8):
    """
    Adjoint/backward modeling of a shot record (receivers as source) Ps*F^T*Pr^T*d.

    Parameters
    ----------
    model: Model
        Physical model
    src_coords: Array
        Coordiantes of the source(s)
    rec_coords: Array
        Coordiantes of the receiver(s)
    data: Array
        Shot gather
    space_order: Int (optional)
        Spatial discretization order, defaults to 8

    Returns
    ----------
    Array
        Shot record (adjoint wavefield at source position(s))
    """
    rec, _, _ = adjoint(model,
                        data,
                        src_coords,
                        rec_coords,
                        space_order=space_order)
    return rec.data
Пример #4
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
Пример #5
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
Пример #6
0
def adjoint_w(model, rec_coords, data, wavelet, space_order=8,
              free_surface=False):
    """
    Adjoint/backward modeling of a shot record (receivers as source) for an
    extended source setup Pw*F^T*Pr^T*d_obs.

    Parameters
    ----------
    model: Model
        Physical model
    rec_coords: Array
        Coordiantes of the receiver(s)
    data: Array
        Shot gather
    wavelet: Array
        Time signature of the forward source for stacking along time
    space_order: Int (optional)
        Spatial discretization order, defaults to 8
    free_surface: Bool (optional)
        Whether or not to use a free surface

    Returns
    ----------
    Array
        spatial distribution
    """
    w = adjoint(model, data, None, rec_coords, ws=wavelet,
                space_order=space_order, free_surface=free_surface)
    slices = [slice(model.nbl, -model.nbl) for _ in range(model.dim)]
    return w.data[slices]
Пример #7
0
def wri_func(model, src_coords, wavelet, rec_coords, recin, yin, space_order=8,
             isic=False, ws=None, t_sub=1, grad="m", grad_corr=False,
             alpha_op=False, w_fun=None, eps=0):
    """
    Time domain wavefield reconstruction inversion wrapper
    """
    # F(m0) * q if y is not an input and compute y = r(m0)
    if yin is None or grad_corr:
        y, u0, _ = forward(model, src_coords, rec_coords, wavelet, save=grad_corr,
                           space_order=space_order, ws=ws)
        ydat = recin[:] - y.data[:]
    else:
        ydat = yin

    # Compute wavefield vy = adjoint(F(m0))*y and norm on the fly
    srca, v, norm_v, _ = adjoint(model, ydat, src_coords, rec_coords,
                                 norm_v=True, w_fun=w_fun,
                                 save=grad is not None)
    c1 = 1 / (recin.shape[1])
    c2 = np.log(np.prod(model.shape))
    # <PTy, d-F(m)*f> = <PTy, d>-<adjoint(F(m))*PTy, f>
    ndt = np.sqrt(model.critical_dt)
    PTy_dot_r = ndt**2 * (np.dot(ydat.reshape(-1), recin.reshape(-1)) -
                          np.dot(srca.data.reshape(-1), wavelet.reshape(-1)))
    norm_y = ndt * np.linalg.norm(ydat)

    # alpha
    α = compute_optalpha(c2*norm_y, c1*norm_v, eps, comp_alpha=alpha_op)

    # Lagrangian evaluation
    fun = -.5 * c1 * α**2 * norm_v + c2 * α * PTy_dot_r - eps * np.abs(α) * norm_y

    gradm = grady = None
    if grad is not None:
        w = weight_fun(w_fun, model, src_coords)
        w = c1*α/w**2 if w is not None else c1*α
        Q = wf_as_src(v, w=w)
        rcv, gradm, _ = forward_grad(model, src_coords, rec_coords, c2*wavelet, q=Q, v=v)

        # Compute gradient wrt y
        if grad_corr or grad in ["all", "y"]:
            grady = c2 * recin - rcv.data[:]
            if norm_y != 0:
                grady -= np.abs(eps) * ydat / norm_y

        # Correcting for reduced gradient
        if not grad_corr:
            gradm = gradm.data
        else:
            gradm_corr, _ = gradient(model, grady, rec_coords, u0)
            # Reduced gradient post-processing
            gradm = gradm.data + gradm_corr.data

    return fun, α * gradm, grady
Пример #8
0
t0 = 0.
tn = 1300.
dt = model.critical_dt
nt = int(1 + (tn - t0) / dt)
time_axis = np.linspace(t0, tn, nt)

# Source
f1 = 0.008
src1 = RickerSource(name='src', grid=model.grid, f0=f1, time=time_axis)
src1.coordinates.data[0, :] = np.array(model.domain_size) * 0.5
src1.coordinates.data[0, -1] = 20.

# Receiver for observed data
rec_t = Receiver(name='rec_t', grid=model.grid, npoint=301, ntime=nt)
rec_t.coordinates.data[:, 0] = np.linspace(0., 3000., num=301)
rec_t.coordinates.data[:, 1] = 20.

# Test data and source
d_hat, u1, _ = forward(model, src1.coordinates.data, rec_t.coordinates.data,
                       src1.data)

# Adjoint
q0, _, _ = adjoint(model, d_hat, src1.coordinates.data, rec_t.coordinates.data)

# Adjoint test
a = inner(d_hat, d_hat)
b = inner(q0, src1)
print("Adjoint test F")
print("a = %2.2e, b = %2.2e, diff = %2.2e: " % (a, b, a - b))
print("Relative error: ", a / b - 1)