Beispiel #1
0
def adjoint(model,
            y,
            src_coords,
            rcv_coords,
            space_order=8,
            q=0,
            save=False,
            ws=None,
            norm_v=False,
            w_fun=None):
    """
    Low level propagator, to be used through `interface.py`
    Compute adjoint wavefield v = adjoint(F(m))*y
    and related quantities (||v||_w, v(xsrc))
    """
    # Number of time steps
    nt = as_tuple(q)[0].shape[0] if y is None else y.shape[0]

    # Setting adjoint wavefield
    v = wavefield(model, space_order, save=save, nt=nt, fw=False)

    # Set up PDE expression and rearrange
    pde = wave_kernel(model, v, q=q, fw=False)

    # Setup source and receiver
    geom_expr, _, rcv = src_rec(model,
                                v,
                                src_coords=rcv_coords,
                                nt=nt,
                                rec_coords=src_coords,
                                wavelet=y,
                                fw=False)

    # Extended source
    wsrc, ws_expr = extended_src_weights(model, ws, v)

    # Wavefield norm
    nv_t, nv_s = ([], [])
    if norm_v:
        weights = weight_fun(w_fun, model, src_coords)
        norm_v, (nv_t, nv_s) = weighted_norm(v, weight=weights)

    # Create operator and run
    subs = model.spacing_map
    op = Operator(pde + ws_expr + nv_t + geom_expr + nv_s,
                  subs=subs,
                  name="adjoint" + name(model),
                  opt=opt_op(model))

    # Run operator
    summary = op()

    # Output
    if wsrc:
        return wsrc, summary
    if norm_v:
        return rcv, v, norm_v.data[0], summary
    return rcv, v, summary
Beispiel #2
0
def forward(model,
            src_coords,
            rcv_coords,
            wavelet,
            space_order=8,
            save=False,
            q=None,
            return_op=False,
            freq_list=None,
            dft_sub=None,
            ws=None,
            t_sub=1,
            **kwargs):
    """
    Low level propagator, to be used through `interface.py`
    Compute forward wavefield u = A(m)^{-1}*f and related quantities (u(xrcv))
    """
    # Number of time steps
    nt = as_tuple(q)[0].shape[0] if wavelet is None else wavelet.shape[0]

    # Setting forward wavefield
    u = wavefield(model, space_order, save=save, nt=nt, t_sub=t_sub)

    # Expression for saving wavefield if time subsampling is used
    u_save, eq_save = wavefield_subsampled(model, u, nt, t_sub)

    # Add extended source
    q = q or wf_as_src(u, w=0)
    q = extented_src(model, ws, wavelet, q=q)

    # Set up PDE expression and rearrange
    pde = wave_kernel(model, u, q=q)

    # Setup source and receiver
    geom_expr, _, rcv = src_rec(model,
                                u,
                                src_coords=src_coords,
                                nt=nt,
                                rec_coords=rcv_coords,
                                wavelet=wavelet)

    # On-the-fly Fourier
    dft, dft_modes = otf_dft(u, freq_list, model.critical_dt, factor=dft_sub)

    # Create operator and run
    subs = model.spacing_map
    op = Operator(pde + geom_expr + dft + eq_save,
                  subs=subs,
                  name="forward" + name(model),
                  opt=opt_op(model))

    if return_op:
        return op, u, rcv

    summary = op()

    # Output
    return rcv, dft_modes or (u_save if t_sub > 1 else u), summary
Beispiel #3
0
def born(model,
         src_coords,
         rcv_coords,
         wavelet,
         space_order=8,
         save=False,
         q=None,
         isic=False,
         ws=None):
    """
    Low level propagator, to be used through `interface.py`
    Compute adjoint wavefield v = adjoint(F(m))*y
    and related quantities (||v||_w, v(xsrc))
    """
    # Setting adjoint wavefield
    u = wavefield(model, space_order, save=save, nt=wavelet.shape[0])
    ul = wavefield(model, space_order, name="l")

    # Extended source
    q = q or wf_as_src(u, w=0)
    q = extented_src(model, ws, wavelet, q=q)

    # Set up PDE expression and rearrange
    pde, tmpu = wave_kernel(model, u, q=q)
    pdel, tmpul = wave_kernel(model, ul, q=lin_src(model, u, isic=isic))

    # Setup source and receiver
    geom_expr, _, _ = src_rec(model, u, src_coords=src_coords, wavelet=wavelet)
    geom_exprl, _, rcvl = src_rec(model,
                                  ul,
                                  rec_coords=rcv_coords,
                                  nt=wavelet.shape[0])

    # Create operator and run
    subs = model.spacing_map
    op = Operator(tmpu + tmpul + pde + geom_expr + geom_exprl + pdel,
                  subs=subs,
                  name="born" + name(model),
                  opt=opt_op(model.fs, born_ws=ws is not None))

    op()

    # Output
    return rcvl.data, u
Beispiel #4
0
def gradient(model,
             residual,
             rcv_coords,
             u,
             return_op=False,
             space_order=8,
             t_sub=1,
             w=None,
             freq=None,
             dft_sub=None,
             isic=True):
    """
    Low level propagator, to be used through `interface.py`
    Compute adjoint wavefield v = adjoint(F(m))*y
    and related quantities (||v||_w, v(xsrc))
    """
    # Setting adjoint wavefieldgradient
    v = wavefield(model, space_order, fw=False)

    # Set up PDE expression and rearrange
    pde, tmp = wave_kernel(model, v, fw=False)

    # Setup source and receiver
    geom_expr, _, _ = src_rec(model,
                              v,
                              src_coords=rcv_coords,
                              wavelet=residual,
                              fw=False)

    # Setup gradient wrt m
    gradm = Function(name="gradm", grid=model.grid)
    g_expr = grad_expr(gradm,
                       u,
                       v,
                       model,
                       w=w,
                       freq=freq,
                       dft_sub=dft_sub,
                       isic=isic)

    # Create operator and run
    subs = model.spacing_map
    op = Operator(tmp + pde + geom_expr + g_expr,
                  subs=subs,
                  name="gradient" + name(model),
                  opt=opt_op(model.fs))

    if return_op:
        return op, gradm, v
    op()

    # Output
    return gradm.data
Beispiel #5
0
def forward_grad(model,
                 src_coords,
                 rcv_coords,
                 wavelet,
                 v,
                 space_order=8,
                 q=None,
                 ws=None,
                 isic=False,
                 w=None,
                 freq=None,
                 **kwargs):
    """
    Low level propagator, to be used through `interface.py`
    Compute forward wavefield u = A(m)^{-1}*f and related quantities (u(xrcv))
    """
    # Number of time steps
    nt = as_tuple(q)[0].shape[0] if wavelet is None else wavelet.shape[0]

    # Setting forward wavefield
    u = wavefield(model, space_order, save=False)

    # Add extended source
    q = q or wf_as_src(u, w=0)
    q = extented_src(model, ws, wavelet, q=q)

    # Set up PDE expression and rearrange
    pde = wave_kernel(model, u, q=q)

    # Setup source and receiver
    geom_expr, _, rcv = src_rec(model,
                                u,
                                src_coords=src_coords,
                                nt=nt,
                                rec_coords=rcv_coords,
                                wavelet=wavelet)

    # Setup gradient wrt m
    gradm = Function(name="gradm", grid=model.grid)
    g_expr = grad_expr(gradm, v, u, model, w=w, isic=isic, freq=freq)

    # Create operator and run
    subs = model.spacing_map
    op = Operator(pde + geom_expr + g_expr,
                  subs=subs,
                  name="forward_grad" + name(model),
                  opt=opt_op(model))

    summary = op()

    # Output
    return rcv, gradm, summary
Beispiel #6
0
def gradient(model,
             residual,
             rcv_coords,
             u,
             return_op=False,
             space_order=8,
             w=None,
             freq=None,
             dft_sub=None,
             isic=False):
    """
    Low level propagator, to be used through `interface.py`
    Compute the action of the adjoint Jacobian onto a residual J'* δ d.
    """
    # Setting adjoint wavefieldgradient
    v = wavefield(model, space_order, fw=False)

    # Set up PDE expression and rearrange
    pde = wave_kernel(model, v, fw=False)

    # Setup source and receiver
    geom_expr, _, _ = src_rec(model,
                              v,
                              src_coords=rcv_coords,
                              wavelet=residual,
                              fw=False)

    # Setup gradient wrt m
    gradm = Function(name="gradm", grid=model.grid)
    g_expr = grad_expr(gradm,
                       u,
                       v,
                       model,
                       w=w,
                       freq=freq,
                       dft_sub=dft_sub,
                       isic=isic)

    # Create operator and run
    subs = model.spacing_map
    op = Operator(pde + geom_expr + g_expr,
                  subs=subs,
                  name="gradient" + name(model),
                  opt=opt_op(model))

    if return_op:
        return op, gradm, v

    summary = op()

    # Output
    return gradm, summary
def forward(model,
            src_coords,
            rcv_coords,
            wavelet,
            dt=None,
            space_order=8,
            save=False,
            q=0,
            grad=False,
            u=None,
            return_op=False):
    """
    Compute forward wavefield u = A(m)^{-1}*f and related quantities (u(xrcv))
    """
    # Setting adjoint wavefield
    u = u or wavefield(model, space_order, save=save, nt=wavelet.shape[0])

    # Set up PDE expression and rearrange
    pde = wave_kernel(model, u, q=q)

    # Setup source and receiver
    geom_expr, _, rcv = src_rec(model,
                                u,
                                src_coords=src_coords,
                                rec_coords=rcv_coords,
                                wavelet=wavelet)
    # extras expressions
    extras = []
    if grad:
        gradm = Function(name="gradm", grid=model.grid)
        v = wavefield(model,
                      space_order,
                      save=True,
                      nt=wavelet.shape[0],
                      fw=False)
        w = Constant(name="w")
        extras = grad_expr(gradm, u, v, w=w)
    # Create operator and run
    subs = model.spacing_map
    op = create_op(pde + geom_expr + extras,
                   subs=subs,
                   name="forward" + name(model))
    if return_op:
        return op
    op()

    # Output
    if save:
        return rcv.data, u
    else:
        return rcv.data, None
Beispiel #8
0
def adjoint(model,
            y,
            src_coords,
            rcv_coords,
            space_order=8,
            q=0,
            save=False,
            ws=None):
    """
    Low level propagator, to be used through `interface.py`
    Compute adjoint wavefield v = adjoint(F(m))*y
    and related quantities (||v||_w, v(xsrc))
    """
    # Number of time steps
    nt = as_tuple(q)[0].shape[0] if y is None else y.shape[0]

    # Setting adjoint wavefield
    v = wavefield(model, space_order, save=save, nt=nt, fw=False)

    # Set up PDE expression and rearrange
    pde, tmp = wave_kernel(model, v, q=q, fw=False)

    # Setup source and receiver
    geom_expr, _, rcv = src_rec(model,
                                v,
                                src_coords=rcv_coords,
                                nt=nt,
                                rec_coords=src_coords,
                                wavelet=y,
                                fw=False)

    # Extended source
    wsrc, ws_expr = extended_src_weights(model, ws, v)

    # Create operator and run
    subs = model.spacing_map
    op = Operator(tmp + pde + ws_expr + geom_expr,
                  subs=subs,
                  name="adjoint" + name(model),
                  opt=opt_op(model.fs))

    op()

    # Output
    if wsrc:
        return wsrc
    return getattr(rcv, 'data', None), v
def adjoint_y(model,
              y,
              src_coords,
              rcv_coords,
              weight_fun_pars=None,
              dt=None,
              space_order=8,
              save=False,
              return_op=False):
    """
    Compute adjoint wavefield v = adjoint(F(m))*y
    and related quantities (||v||_w, v(xsrc))
    """
    # Setting adjoint wavefield
    v = wavefield(model, space_order, save=save, nt=y.shape[0], fw=False)

    # Set up PDE expression and rearrange
    pde = wave_kernel(model, v, fw=False)

    # Setup source and receiver
    geom_expr, _, rcv = src_rec(model,
                                v,
                                src_coords=rcv_coords,
                                rec_coords=src_coords,
                                wavelet=y,
                                fw=False)

    # Setup ||v||_w computation
    weights = weight_fun(weight_fun_pars, model, src_coords)
    norm_v, norm_v_expr = weighted_norm(v, weight=weights)
    # Create operator and run
    subs = model.spacing_map
    op = create_op(pde + geom_expr + norm_v_expr,
                   subs=subs,
                   name="adjoint_y" + name(model))
    if return_op:
        return op
    op()

    # Output
    if save:
        return norm_v.data[0], rcv.data, v
    else:
        return norm_v.data[0], rcv.data, None
def gradient(model,
             residual,
             rcv_coords,
             u,
             dt=None,
             space_order=8,
             w=1,
             return_op=False,
             w_symb=False):
    """
    Compute adjoint wavefield v = adjoint(F(m))*y
    and related quantities (||v||_w, v(xsrc))
    """
    if w_symb:
        w = Constant(name="w", value=w)
    # Setting adjoint wavefield
    v = wavefield(model, space_order, fw=False)
    u = u or wavefield(model, space_order, save=True, nt=residual.shape[0])

    # Set up PDE expression and rearrange
    pde = wave_kernel(model, v, fw=False)

    # Setup source and receiver
    geom_expr, _, _ = src_rec(model,
                              v,
                              src_coords=rcv_coords,
                              wavelet=residual,
                              fw=False)

    # Setup gradient wrt m
    gradm = Function(name="gradm", grid=model.grid)
    g_expr = grad_expr(gradm, u, v, w=w)

    # Create operator and run
    subs = model.spacing_map
    op = create_op(pde + g_expr + geom_expr,
                   subs=subs,
                   name="gradient" + name(model))
    if return_op:
        return op
    op()

    # Output
    return gradm.data
Beispiel #11
0
def born(model,
         src_coords,
         rcv_coords,
         wavelet,
         space_order=8,
         save=False,
         q=None,
         return_op=False,
         isic=False,
         freq_list=None,
         dft_sub=None,
         ws=None,
         t_sub=1,
         nlind=False):
    """
    Low level propagator, to be used through `interface.py`
    Compute linearized wavefield U = J(m)* δ m
    and related quantities.
    """
    nt = wavelet.shape[0]
    # Setting wavefield
    u = wavefield(model, space_order, save=save, nt=nt, t_sub=t_sub)
    ul = wavefield(model, space_order, name="l")

    # Expression for saving wavefield if time subsampling is used
    u_save, eq_save = wavefield_subsampled(model, u, nt, t_sub)

    # Extended source
    q = q or wf_as_src(u, w=0)
    q = extented_src(model, ws, wavelet, q=q)

    # Set up PDE expression and rearrange
    pde = wave_kernel(model, u, q=q)
    if model.dm == 0:
        pdel = []
    else:
        pdel = wave_kernel(model, ul, q=lin_src(model, u, isic=isic))
    # Setup source and receiver
    geom_expr, _, rcvnl = src_rec(model,
                                  u,
                                  rec_coords=rcv_coords if nlind else None,
                                  src_coords=src_coords,
                                  wavelet=wavelet)
    geom_exprl, _, rcvl = src_rec(model, ul, rec_coords=rcv_coords, nt=nt)

    # On-the-fly Fourier
    dft, dft_modes = otf_dft(u, freq_list, model.critical_dt, factor=dft_sub)

    # Create operator and run
    subs = model.spacing_map
    op = Operator(pde + geom_expr + geom_exprl + pdel + dft + eq_save,
                  subs=subs,
                  name="born" + name(model),
                  opt=opt_op(model))
    op.cfunction
    outrec = (rcvl, rcvnl) if nlind else rcvl
    if return_op:
        return op, u, outrec

    summary = op()

    # Output
    return outrec, dft_modes or (u_save if t_sub > 1 else u), summary