Example #1
0
    def adjoint_y_run(self,
                      y,
                      src_coords,
                      rcv_coords,
                      weight_fun_pars=None,
                      save=False):
        v = wavefield(self.model,
                      self.space_order,
                      save=save,
                      nt=y.shape[0],
                      fw=False)
        kwargs = wf_kwargs(v)
        rcv = Receiver(name="rcv",
                       grid=self.model.grid,
                       ntime=y.shape[0],
                       coordinates=src_coords)
        src = PointSource(name="src",
                          grid=self.model.grid,
                          ntime=y.shape[0],
                          coordinates=rcv_coords)
        src.data[:, :] = y[:, :]

        adj = self.op_adj_y(weight_fun_pars=weight_fun_pars, save=save)

        i = Dimension(name="i", )
        norm_v = Function(name="nvy2",
                          shape=(1, ),
                          dimensions=(i, ),
                          grid=self.model.grid)

        adj(src=src, rcv=rcv, nvy2=norm_v, **kwargs)

        return norm_v.data[0], rcv.data, v
Example #2
0
 def forward_run(self,
                 wav,
                 src_coords,
                 rcv_coords,
                 save=False,
                 q=0,
                 v=None,
                 w=0,
                 grad=False):
     # Computing residual
     u = wavefield(self.model, self.space_order, save=save, nt=wav.shape[0])
     kwargs = wf_kwargs(u)
     rcv = Receiver(name="rcv",
                    grid=self.model.grid,
                    ntime=wav.shape[0],
                    coordinates=rcv_coords)
     src = PointSource(name="src",
                       grid=self.model.grid,
                       ntime=wav.shape[0],
                       coordinates=src_coords)
     src.data[:] = wav[:]
     fwd = self.op_fwd(save=save, q=q, grad=grad)
     if grad:
         w = Constant(name="w", value=w)
         gradm = Function(name="gradm", grid=self.model.grid)
         kwargs.update({as_tuple(v)[0].name: as_tuple(v)[0]})
         kwargs.update({w.name: w, gradm.name: gradm})
     fwd(rcv=rcv, src=src, **kwargs)
     if grad:
         return rcv.data, u, gradm
     return rcv.data, u
Example #3
0
# Time axis
t0 = 0.
tn = 1000.
dt = model.critical_dt
nt = int(1 + (tn - t0) / dt)
time_axis = np.linspace(t0, tn, nt)

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

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

# Interface (Level 1)
d_obs = forward_rec(model,
                    src.coordinates.data,
                    src.data,
                    rec_t.coordinates.data,
                    space_order=8,
                    free_surface=False)

N = 1000
a = .003
b = .030
Example #4
0
def J_adjoint_checkpointing(model,
                            src_coords,
                            wavelet,
                            rec_coords,
                            recin,
                            space_order=8,
                            is_residual=False,
                            n_checkpoints=None,
                            maxmem=None,
                            return_obj=False,
                            isic=False,
                            ws=None,
                            t_sub=1):
    """
    Jacobian (adjoint fo born modeling operator) operator on a shot record
    as a source (i.e data residual). Outputs the gradient with Checkpointing.

    Parameters
    ----------
    model: Model
        Physical model
    src_coords: Array
        Coordiantes of the source(s)
    wavelet: Array
        Source signature
    rec_coords: Array
        Coordiantes of the receiver(s)
    recin: Array
        Receiver data
    space_order: Int (optional)
        Spatial discretization order, defaults to 8
    checkpointing: Bool
        Whether or not to use checkpointing
    n_checkpoints: Int
        Number of checkpoints for checkpointing
    maxmem: Float
        Maximum memory to use for checkpointing
    isic : Bool
        Whether or not to use ISIC imaging condition
    ws : Array
        Extended source spatial distribution
    is_residual: Bool
        Whether to treat the input as the residual or as the observed data

    Returns
    ----------
     Array
        Adjoint jacobian on the input data (gradient)
    """
    # Optimal checkpointing
    op_f, u, rec_g = forward(model,
                             src_coords,
                             rec_coords,
                             wavelet,
                             space_order=space_order,
                             return_op=True,
                             ws=ws)
    op, g, v = gradient(model,
                        recin,
                        rec_coords,
                        u,
                        space_order=space_order,
                        return_op=True,
                        isic=isic)

    nt = wavelet.shape[0]
    rec = Receiver(name='rec',
                   grid=model.grid,
                   ntime=nt,
                   coordinates=rec_coords)
    cp = DevitoCheckpoint([uu for uu in as_tuple(u)])
    if maxmem is not None:
        memsize = (cp.size * u.data.itemsize)
        n_checkpoints = int(np.floor(maxmem * 10**6 / memsize))
    # Op arguments
    uk = {uu.name: uu for uu in as_tuple(u)}
    vk = {**uk, **{vv.name: vv for vv in as_tuple(v)}}
    uk.update({'rcv%s' % as_tuple(u)[0].name: rec_g})
    vk.update({'src%s' % as_tuple(v)[0].name: rec})
    # Wrapped ops
    wrap_fw = CheckpointOperator(op_f, vp=model.vp, **uk)
    wrap_rev = CheckpointOperator(op, vp=model.vp, **vk)

    # Run forward
    wrp = Revolver(cp, wrap_fw, wrap_rev, n_checkpoints, nt - 2)
    wrp.apply_forward()

    # Residual and gradient
    if is_residual is True:  # input data is already the residual
        rec.data[:] = recin[:]
    else:
        rec.data[:] = rec.data[:] - recin[:]  # input is observed data

    wrp.apply_reverse()

    if return_obj:
        return .5 * model.critical_dt * norm(rec)**2, g.data
    return g.data
Example #5
0
def gradient(model,
             save=False,
             space_order=12,
             sub=None,
             fs=False,
             isic=False):
    clear_cache()

    # Parameters
    s = model.grid.stepping_dim.spacing
    nt = 10
    time_range = TimeAxis(start=0, num=nt, step=1)
    m, damp, epsilon, delta, theta, phi, rho = (model.m, model.damp,
                                                model.epsilon, model.delta,
                                                model.theta, model.phi,
                                                model.rho)
    m = m * rho
    # Tilt and azymuth setup
    ang0 = cos(theta)
    ang1 = sin(theta)
    ang2 = cos(phi)
    ang3 = sin(phi)

    # Create the forward wavefield
    f_h = f_t = 1
    if sub is not None and (sub[0] > 1 or sub[1] > 1):
        f_h = sub[1]
        f_t = sub[0]
        u, v = subsampled(model,
                          nt,
                          space_order,
                          t_sub=sub[0],
                          space_sub=sub[1])
    else:
        u = TimeFunction(name='u',
                         grid=model.grid,
                         time_order=2,
                         space_order=space_order,
                         save=nt)
        v = TimeFunction(name='v',
                         grid=model.grid,
                         time_order=2,
                         space_order=space_order,
                         save=nt)
    p = TimeFunction(name='p',
                     grid=model.grid,
                     time_order=2,
                     space_order=space_order)
    q = TimeFunction(name='q',
                     grid=model.grid,
                     time_order=2,
                     space_order=space_order)

    H0, H1 = kernel_zhang_fwd(p, q, ang0, ang1, ang2, ang3, epsilon, delta,
                              rho)

    # Stencils
    s = model.grid.stepping_dim.spacing
    stencilp = damp * (2 * p - damp * p.forward + s**2 / m * H0)
    stencilr = damp * (2 * q - damp * q.forward + s**2 / m * H1)
    first_stencil = Eq(p.backward, stencilp)
    second_stencil = Eq(q.backward, stencilr)
    expression = [first_stencil, second_stencil]

    # Source symbol with input wavelet
    src = Receiver(name='src',
                   grid=model.grid,
                   time_range=time_range,
                   npoint=1)
    src_term = src.inject(field=p.backward, expr=src.dt * s**2 / m)
    src_term += src.inject(field=q.backward, expr=src.dt * s**2 / m)
    expression += src_term

    if fs:
        expression += freesurface(p, model.nbpml, forward=False)
        expression += freesurface(q, model.nbpml, forward=False)
    grad = Function(name="grad", grid=u.grid, space_order=0)
    expression += [
        Inc(grad,
            rho * f_t * f_h * imaging_condition(model, u, v, p, q, isic=isic))
    ]

    op = Operator(expression,
                  subs=model.spacing_map,
                  dse='aggressive',
                  dle='advanced',
                  name="gradient")

    return op
Example #6
0
def forward(model, save=False, space_order=12, sub=None, norec=False, fs=False):
    clear_cache()

    # Parameters
    s = model.grid.stepping_dim.spacing
    nt = 10
    time_range = TimeAxis(start=0, num=nt, step=1)
    m, damp, epsilon, delta, theta, phi, rho = (model.m, model.damp, model.epsilon,
                                                model.delta, model.theta, model.phi,
                                                model.rho)
    m = m * rho
    # Tilt and azymuth setup
    ang0 = cos(theta)
    ang1 = sin(theta)
    ang2 = cos(phi)
    ang3 = sin(phi)

    # Create the forward wavefield
    if sub is not None and (sub[0] > 1 or sub[1] > 1):
        usave, vsave = subsampled(model, nt, space_order, t_sub=sub[0], space_sub=sub[1])
        u = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=space_order)
        v = TimeFunction(name='v', grid=model.grid, time_order=2, space_order=space_order)
        eq_save = [Eq(usave, u), Eq(vsave, v)]
    elif save:
        u = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=space_order,
                         save=nt)
        v = TimeFunction(name='v', grid=model.grid, time_order=2, space_order=space_order,
                         save=nt)
        eq_save = []
    else:
        u = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=space_order)
        v = TimeFunction(name='v', grid=model.grid, time_order=2, space_order=space_order)
        eq_save = []

    H0, H1 = kernel_zhang_fwd(u, v, ang0, ang1, ang2, ang3, epsilon, delta, rho)

    # Stencils
    s = model.grid.stepping_dim.spacing
    stencilp = damp * (2 * u - damp * u.backward + s**2 / m * H0)
    stencilr = damp * (2 * v - damp * v.backward + s**2 / m * H1)
    first_stencil = Eq(u.forward, stencilp)
    second_stencil = Eq(v.forward, stencilr)
    expression = [first_stencil, second_stencil]

    # Source symbol with input wavelet
    src = Receiver(name='src', grid=model.grid, time_range=time_range, npoint=1)
    src_term = src.inject(field=u.forward, expr=src.dt * s**2 / m)
    src_term += src.inject(field=v.forward, expr=src.dt * s**2 / m)
    expression += src_term

    if fs:
        expression += freesurface(u, model.nbpml)
        expression += freesurface(v, model.nbpml)
    if not norec:
        rec = Receiver(name='rec', grid=model.grid, time_range=time_range, npoint=2)
        expression += rec.interpolate(expr=u + v)

    kwargs = {'dse': 'aggressive', 'dle': 'advanced'}
    op = Operator(expression + eq_save, subs=model.spacing_map,
                  name="forward", **kwargs)

    return op