コード例 #1
0
    def test_default_dimension(self):
        d = Dimension(name='d')
        dd0 = DefaultDimension(name='d')
        assert d is not dd0

        dd1 = DefaultDimension(name='d')
        assert dd0 is not dd1
コード例 #2
0
def otf_dft(u, freq, dt, factor=None):
    """
    On the fly DFT wavefield (frequency slices) and expression

    Parameters
    ----------
    u: TimeFunction or Tuple
        Forward wavefield
    freq: Array
        Array of frequencies for on-the-fly DFT
    factor: int
        Subsampling factor for DFT
    """
    if freq is None:
        return [], None

    # init
    dft_modes = []

    # Subsampled dft time axis
    time = as_tuple(u)[0].grid.time_dim
    tsave, factor = sub_time(time, factor, dt=dt, freq=freq)

    # Frequencies
    nfreq = np.shape(freq)[0]
    freq_dim = DefaultDimension(name='freq_dim', default_value=nfreq)
    f = Function(name='f', dimensions=(freq_dim, ), shape=(nfreq, ))
    f.data[:] = np.array(freq[:])
    # Get fourier atoms to avoid shitty perf
    cf = TimeFunction(name="cf",
                      dimensions=(as_tuple(u)[0].grid.stepping_dim, freq_dim),
                      shape=(3, nfreq),
                      time_order=2)
    sf = TimeFunction(name="sf",
                      dimensions=(as_tuple(u)[0].grid.stepping_dim, freq_dim),
                      shape=(3, nfreq),
                      time_order=2)
    # Pulsation
    omega_t = 2 * np.pi * f * tsave * factor * dt
    dft = [Eq(cf, cos(omega_t)), Eq(sf, sin(omega_t))]
    for wf in as_tuple(u):
        ufr = Function(name='ufr%s' % wf.name,
                       dimensions=(freq_dim, ) + wf.indices[1:],
                       grid=wf.grid,
                       shape=(nfreq, ) + wf.shape[1:])
        ufi = Function(name='ufi%s' % wf.name,
                       dimensions=(freq_dim, ) + wf.indices[1:],
                       grid=wf.grid,
                       shape=(nfreq, ) + wf.shape[1:])
        dft += [Inc(ufr, factor * cf * wf)]
        dft += [Inc(ufi, -factor * sf * wf)]
        dft_modes += [(ufr, ufi)]
    return dft, dft_modes
コード例 #3
0
def freesurface(field, stencil_s, npml, forward=True):
    """
    Generate the stencil that mirrors the field as a free surface modeling for
    the acoustic wave equation
    """
    fs = DefaultDimension(name="fs", default_value=stencil_s)

    field_m = field.forward if forward else field.backward

    lhs = field_m.subs({field.indices[-1]: npml - fs - 1})
    rhs = -field_m.subs({field.indices[-1]: npml + fs + 1})
    return [Eq(lhs, rhs)]
コード例 #4
0
    def test_lower_func_as_ind(self):
        grid = Grid((11, 11))
        x, y = grid.dimensions
        t = grid.stepping_dim
        h = DefaultDimension("h", default_value=10)

        u = TimeFunction(name='u', grid=grid, time_order=2, space_order=2)
        oh = Function(name="ou", dimensions=(h, ), shape=(10, ), dtype=int)

        eq = [Eq(u.forward, u._subs(x, x + oh))]
        lowered = LoweredEq(
            Eq(u[t + 1, x + 2, y + 2], u[t, x + oh[h] + 2, y + 2]))

        with timed_region('x'):
            leq = Operator._lower_exprs(eq)

        assert leq[0] == lowered
コード例 #5
0
def otf_dft(u, freq, dt, factor=None):
    """
    On the fly DFT wavefield (frequency slices) and expression

    Parameters
    ----------
    u: TimeFunction or Tuple
        Forward wavefield
    freq: Array
        Array of frequencies for on-the-fly DFT
    factor: int
        Subsampling factor for DFT
    """
    if freq is None:
        return [], None

    # init
    dft = []
    dft_modes = []

    # Subsampled dft time axis
    time = as_tuple(u)[0].grid.time_dim
    tsave, factor = sub_time(time, factor, dt=dt, freq=freq)

    # Frequencies
    nfreq = freq.shape[0]
    freq_dim = DefaultDimension(name='freq_dim', default_value=nfreq)
    f = Function(name='f', dimensions=(freq_dim, ), shape=(nfreq, ))
    f.data[:] = freq[:]

    # Pulsation
    omega_t = 2 * np.pi * f * tsave * factor * dt
    for wf in as_tuple(u):
        ufr = Function(name='ufr%s' % wf.name,
                       dimensions=(freq_dim, ) + wf.indices[1:],
                       grid=wf.grid,
                       shape=(nfreq, ) + wf.shape[1:])
        ufi = Function(name='ufi%s' % wf.name,
                       dimensions=(freq_dim, ) + wf.indices[1:],
                       grid=wf.grid,
                       shape=(nfreq, ) + wf.shape[1:])
        dft += [Inc(ufr, factor * cos(omega_t) * wf)]
        dft += [Inc(ufi, -factor * sin(omega_t) * wf)]
        dft_modes += [(ufr, ufi)]
    return dft, dft_modes
コード例 #6
0
 def test_default_dimension(self):
     """Test that different DefaultDimensions have different hash value."""
     dd0 = DefaultDimension(name='dd')
     dd1 = DefaultDimension(name='dd')
     assert hash(dd0) != hash(dd1)
コード例 #7
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
コード例 #8
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