Exemplo n.º 1
0
    # Generate synthetic data from true model
    true_d, _, _ = solver.forward(vp=model.vp)

    # Compute smooth data and full forward wavefield u0
    u0.data.fill(0.)
    smooth_d, _, _ = solver.forward(vp=model0.vp, save=True, u=u0)

    # Compute gradient from the data residual
    v = TimeFunction(name='v', grid=model.grid, time_order=2, space_order=4)
    residual = smooth_d.data - true_d.data
    op_imaging(u=u0,
               v=v,
               vp=model0.vp,
               dt=model0.critical_dt,
               residual=residual)

# In[12]:

#NBVAL_IGNORE_OUTPUT
from examples.seismic import plot_image

# Plot the inverted image
plot_image(np.diff(image.data[:, 50:], axis=1), vmin=100, vmax=100000)

# And we have an image of the subsurface with a strong reflector at the original location.

# ## References
#
# [1] _Versteeg, R.J. & Grau, G. (eds.) (1991): The Marmousi experience. Proc. EAGE workshop on Practical Aspects of Seismic Data Inversion (Copenhagen, 1990), Eur. Assoc. Explor. Geophysicists, Zeist._
Exemplo n.º 2
0
#NBVAL_IGNORE_OUTPUT

# Compute gradient of initial model
ff, update = fwi_gradient(model0.vp)
print('Objective value is %f ' % ff)


# In[31]:


#NBVAL_IGNORE_OUTPUT
from examples.seismic import plot_image

# Plot the FWI gradient
plot_image(update, vmin=-1e4, vmax=1e4, cmap="jet")

# Plot the difference between the true and initial model.
# This is not known in practice as only the initial model is provided.
plot_image(model0.vp.data - model.vp.data, vmin=-1e-1, vmax=1e-1, cmap="jet")

# Show what the update does to the model
alpha = .5 / np.abs(update).max()
plot_image(model0.vp.data - alpha*update, vmin=2.5, vmax=3.0, cmap="jet")


# We see that the gradient and the true perturbation have the same sign, therefore, with an appropriate scaling factor, we will update the model in the correct direction.

# In[32]:

Exemplo n.º 3
0
        objective += .5*np.linalg.norm(residual.data.flatten())**2
        solver.gradient(rec=residual, u=u0, m=m_in, grad=grad)
    
    return objective, grad.data

    #NBVAL_IGNORE_OUTPUT

# Compute gradient of initial model
ff, update = fwi_gradient(model0.m)
print('Objective value is %f ' % ff)

#NBVAL_IGNORE_OUTPUT
from examples.seismic import plot_image

# Plot the FWI gradient
plot_image(update, vmin=-1e4, vmax=1e4, cmap="jet")

# Plot the difference between the true and initial model.
# This is not known in practice as only the initial model is provided.
plot_image(model0.m.data - model.m.data, vmin=-1e-1, vmax=1e-1, cmap="jet")

# Show what the update does to the model
alpha = .005 / np.abs(update).max()
plot_image(model0.m.data - alpha*update, vmin=.1, vmax=.2, cmap="jet")

# Define bounding box constraints on the solution.
def apply_box_constraint(m):
    # Maximum possible 'realistic' velocity is 3.5 km/sec
    # Minimum possible 'realistic' velocity is 2 km/sec
    return np.clip(m, 1/3.5**2, 1/2**2)
mu = cs2 * ro
l = (cp2 * ro - 2 * mu)

# fdelmodc reference implementation
u_vx = Eq(vx.forward, vx - dt * ro * (txx.dx + txz.dz))

u_vz = Eq(vz.forward, vz - ro * dt * (txz.dx + tzz.dz))

u_txx = Eq(txx.forward,
           txx - (l + 2 * mu) * dt * vx.forward.dx - l * dt * vz.forward.dz)
u_tzz = Eq(tzz.forward,
           tzz - (l + 2 * mu) * dt * vz.forward.dz - l * dt * vx.forward.dx)

u_txz = Eq(txz.forward, txz - mu * dt * (vx.forward.dz + vz.forward.dx))

op = Operator([u_vx, u_vz, u_txx, u_tzz, u_txz] + src_xx + src_zz)

# Reset the fields
vx.data[:] = 0.
vz.data[:] = 0.
txx.data[:] = 0.
tzz.data[:] = 0.
txz.data[:] = 0.

op()

plot_image(vx.data[0], vmin=-.5 * 1e-2, vmax=.5 * 1e-2, cmap="seismic")
plot_image(vz.data[0], vmin=-.5 * 1e-2, vmax=.5 * 1e-2, cmap="seismic")
plot_image(txx.data[0], vmin=-.5 * 1e-2, vmax=.5 * 1e-2, cmap="seismic")
plot_image(tzz.data[0], vmin=-.5 * 1e-2, vmax=.5 * 1e-2, cmap="seismic")
plot_image(txz.data[0], vmin=-.5 * 1e-2, vmax=.5 * 1e-2, cmap="seismic")
Exemplo n.º 5
0
    smooth_d, _, _ = solver.forward(vp=model0.vp, save=True, u=u0)

    # Compute gradient from the data residual
    v = TimeFunction(name='v', grid=model.grid, time_order=2, space_order=4)
    residual = smooth_d.data - true_d.data
    op_imaging(u=u0,
               v=v,
               vp=model0.vp,
               dt=model0.critical_dt,
               residual=residual)

# In[1]:

#NBVAL_IGNORE_OUTPUT
from examples.seismic import plot_image

# Plot the inverted image
plot_image(np.diff(image.data, axis=1))

# And we have an image of the subsurface with a strong reflector at the original location.

# ## References
#
# [1] _Versteeg, R.J. & Grau, G. (eds.) (1991): The Marmousi experience. Proc. EAGE workshop on Practical Aspects of Seismic Data Inversion (Copenhagen, 1990), Eur. Assoc. Explor. Geophysicists, Zeist._

# In[ ]:

# In[ ]:

# In[ ]:
Exemplo n.º 6
0
# vistagrid = pv.UniformGrid()
# vistagrid.dimensions = np.array(values.shape) + 1
# vistagrid.origin = (0, 0, 0)  # The bottom left corner of the data set
# vistagrid.spacing = (1, 1, 1)  # These are the cell sizes along each axis
# vistagrid.cell_arrays["values"] = values.flatten(order="F")  # Flatten the array!

# vistagrid.plot(show_edges=True)
# vistaslices = vistagrid.slice_orthogonal()
# vistaslices.plot(cmap=cmap)

# import pdb; pdb.set_trace()
# Uncomment to plot a slice of the field
# plt.imshow(usol.data[2, int(nx/2) ,:, :]); pause(1)

if args.plotting:
    plot_image(v[0].data[0, :, int(ny / 2), :], cmap="seismic")
    pause(1)
    plot_image(v_sol[0].data[0, :, int(ny / 2), :], cmap="seismic")
    pause(1)

    plot_image(v[1].data[0, :, :, int(nz / 2)], cmap="seismic")
    pause(1)
    plot_image(v_sol[1].data[0, :, :, int(nz / 2)], cmap="seismic")
    pause(1)

    plot_image(v[2].data[0, :, :, int(nz / 2)], cmap="seismic")
    pause(1)
    plot_image(v_sol[2].data[0, :, :, int(nz / 2)], cmap="seismic")
    pause(1)

    plot_image(tau[0, 0].data[0, int(nx / 2), :, :], cmap="seismic")
Exemplo n.º 7
0
def processing1():
    # Enable model presets here:
    preset = 'layers-isotropic'  # A simple but cheap model (recommended)
    # preset = 'marmousi2d-isotropic'  # A larger more realistic model

    # Standard preset with a simple two-layer model
    if preset == 'layers-isotropic':

        def create_model(grid=None):
            return demo_model('layers-isotropic',
                              origin=(0., 0.),
                              shape=(101, 101),
                              spacing=(10., 10.),
                              nbl=20,
                              grid=grid,
                              nlayers=2)

        filter_sigma = (1, 1)
        nshots = 21
        nreceivers = 101
        t0 = 0.
        tn = 1000.  # Simulation last 1 second (1000 ms)
        f0 = 0.010  # Source peak frequency is 10Hz (0.010 kHz)

    # A more computationally demanding preset based on the 2D Marmousi model
    if preset == 'marmousi2d-isotropic':

        def create_model(grid=None):
            return demo_model('marmousi2d-isotropic',
                              data_path='../../../../data/',
                              grid=grid,
                              nbl=20)

        filter_sigma = (6, 6)
        nshots = 301  # Need good covergae in shots, one every two grid points
        nreceivers = 601  # One recevier every grid point
        t0 = 0.
        tn = 3500.  # Simulation last 3.5 second (3500 ms)
        f0 = 0.025  # Source peak frequency is 25Hz (0.025 kHz)

        #NBVAL_IGNORE_OUTPUT

    # Create true model from a preset
    model = create_model()

    # Create initial model and smooth the boundaries
    model0 = create_model(grid=model.grid)
    model0.vp = ndimage.gaussian_filter(model0.vp.data,
                                        sigma=filter_sigma,
                                        order=0)

    # Plot the true and initial model and the perturbation between them
    #plot_velocity(model)
    #plot_velocity(model0)
    #plot_perturbation(model0, model)

    #NBVAL_IGNORE_OUTPUT
    # Define acquisition geometry: source

    # First, position source centrally in all dimensions, then set depth
    src_coordinates = np.empty((nshots, 2), dtype=np.float32)
    src_coordinates[:, 0] = np.linspace(0., 1000, num=nshots)
    src_coordinates[:, 1] = 30.

    # Define acquisition geometry: receivers

    # Initialize receivers for synthetic and imaging data
    rec_coordinates = np.empty((nreceivers, 2))
    rec_coordinates[:, 0] = np.linspace(0,
                                        model.domain_size[0],
                                        num=nreceivers)
    rec_coordinates[:, 1] = 30.

    # Geometry

    geometry = AcquisitionGeometry(model,
                                   rec_coordinates,
                                   src_coordinates,
                                   t0,
                                   tn,
                                   f0=.010,
                                   src_type='Ricker')
    # We can plot the time signature to see the wavelet
    #geometry.src.show()

    # Plot acquisition geometry
    #plot_velocity(model, source=geometry.src_positions,
    #receiver=geometry.rec_positions[::4, :])

    # Compute synthetic data with forward operator

    solver = AcousticWaveSolver(model, geometry, space_order=4)
    true_d, _, _ = solver.forward(vp=model.vp)

    # Compute initial data with forward operator
    smooth_d, _, _ = solver.forward(vp=model0.vp)

    # Define gradient operator for imaging

    def ImagingOperator(model, image):
        # Define the wavefield with the size of the model and the time dimension
        v = TimeFunction(name='v',
                         grid=model.grid,
                         time_order=2,
                         space_order=4)

        u = TimeFunction(name='u',
                         grid=model.grid,
                         time_order=2,
                         space_order=4,
                         save=geometry.nt)

        # Defie the wave equation, but with a negated damping term
        eqn = model.m * v.dt2 - v.laplace + model.damp * v.dt.T

        # Use `solve` to rearrange the equation into a stencil expression
        stencil = Eq(v.backward, solve(eqn, v.backward))

        # Define residual injection at the location of the forward receivers
        dt = model.critical_dt
        residual = PointSource(name='residual',
                               grid=model.grid,
                               time_range=geometry.time_axis,
                               coordinates=geometry.rec_positions)
        res_term = residual.inject(field=v.backward,
                                   expr=residual * dt**2 / model.m)

        # Correlate u and v for the current time step and add it to the image
        image_update = Eq(image, image - u * v)

        return Operator([stencil] + res_term + [image_update],
                        subs=model.spacing_map)

    # Start Dask cluster
    cluster = LocalCluster(n_workers=4, threads_per_worker=1)
    client = Client(cluster)
    all_current_workers = [w.pid for w in cluster.scheduler.workers.values()]

    #NBVAL_IGNORE_OUTPUT

    # Prepare the varying source locations
    source_locations = np.empty((nshots, 2), dtype=np.float32)
    source_locations[:, 0] = np.linspace(0., 1000, num=nshots)
    source_locations[:, 1] = 30.

    #plot_velocity(model, source=source_locations)

    #d_obs é o model.data

    def one_shot_rtm(geometry, model0):

        # Devito objects for gradient and data residual
        grad = Function(name="grad", grid=geometry.model.grid)
        residual = Receiver(name='rec',
                            grid=geometry.model.grid,
                            time_range=geometry.time_axis,
                            coordinates=geometry.rec_positions)
        solver = AcousticWaveSolver(geometry.model, geometry, space_order=4)

        # Predicted data and residual
        true_d, u0 = solver.forward(vp=geometry.model.vp, save=True)[0:2]
        smooth_d, _ = solver.forward(vp=model0.vp, save=True)[0:2]

        v = TimeFunction(name='v',
                         grid=model.grid,
                         time_order=2,
                         space_order=4)
        residual = smooth_d.data - true_d.data

        return u0, v, residual

    def multi_shots_rtm(geometry, model0):
        image = Function(name='image', grid=model.grid)
        op_imaging = ImagingOperator(model, image)
        futures = []
        inicio = time.time()
        for i in range(geometry.nsrc):

            # Geometry for current shot
            geometry_i = AcquisitionGeometry(geometry.model,
                                             geometry.rec_positions,
                                             geometry.src_positions[i, :],
                                             geometry.t0,
                                             geometry.tn,
                                             f0=geometry.f0,
                                             src_type=geometry.src_type)

            # Call serial FWI objective function for each shot location
            futures.append(client.submit(one_shot_rtm, geometry_i, model0))

        # Wait for all workers to finish and collect function values and gradients
        wait(futures)
        fim = time.time()
        tempo = fim - inicio
        print("Demorou - Dask: ", tempo)
        for i in range(geometry.nsrc):
            #print('iteração', (i+1))
            # plot_image(np.diff(image.data, axis=1))

            op_imaging(u=futures[i].result()[0],
                       v=futures[i].result()[1],
                       vp=model0.vp,
                       dt=model0.critical_dt,
                       residual=futures[i].result()[2])

        return image.data

    # Compute FWI gradient for 5 shots
    inicio = time.time()
    print("Começou Processing 1")
    imageData = multi_shots_rtm(geometry, model0)
    c = imageData.data

    fim = time.time()
    tempo = fim - inicio
    client.close()
    #NBVAL_IGNORE_OUTPUT
    #from examples.seismic import plot_image
    print("Demorou: ", tempo)
    # Plot the inverted image
    plot_image(np.diff(imageData, axis=1))

    return imageData