示例#1
0
# ------------------------------------------------------------------------------

# Initializing and plotting the finite-difference model

# Initialize a blank finite-difference grid with a spacing of your choosing
# shape = BP_2004_vpModel_sq.shape
shape = cana_vel_clip.shape
ds = 0.15  # spacing in meters
area = [0, shape[0] * ds, 0, shape[1] * ds]

# Fill the velocity field
velocity = cana_vel_clip

# Instantiate the source
fc = 35. # The approximate frequency of the source
source = [wavefd.GaussSource((velocity.shape[0] / 2 -2) * ds,
         2 * ds, area, shape,  15000., fc)]
# source = [wavefd.MexHatSource(950 * ds, 2 * ds, area, shape, 400., fc)]
dt = wavefd.scalar_maxdt(area, shape, np.max(velocity))
duration = 1
maxit = int(duration / dt)

# Generate the stations and reciever location
num_stations = 2
spac = velocity.shape[0]/num_stations # station spacing
# stations = [velocity.shape[0] / 2 * ds, 3 * ds]
stations = [[i*spac*ds, 3 * ds] for i in range(1,num_stations)] # geophone coordinates (x,z)
seismogram_list = ['seis' + str(i) for i in range(1,num_stations)] # Supposed to be for labeling geophones

snapshots = 50  # number of iterations before the plot updates
simulation = wavefd.scalar(velocity, area, dt, maxit, source, stations, snapshots, padding = 500, taper = 0.0005)
示例#2
0
def pre_rtmshot(shot, dt, vdepth, area, fc, source):
    """
    Perform pre-stack reverse in time depth migration on a 2D shot gather,
    Forward and reverse modelling of shots are done using scalar wave equation.
    For image condition uses the normalized cross-correlation of every grid node.

    Parameters:

    * shot : 2D-array
        The shot gather, time x space
    * dt : float
        sample rate
    * vdepth : 2D-array
        The depth velocity field at all receiver positions
    * area : [xmin, xmax, zmin, zmax]
         The x, z limits of the shot/velocity area, e.g., the shallowest point is
         at zmin, the deepest at zmax
    * fc : source frequency
        Used for forward modelling based on a Gauss Source
    * source: (sx, sz)
        x, z coordinates of source source

     Returns:

    * migrated shot : 2D
        the depth migrated shot same shape as vdepth

    """
    # Basic parameters
    # Set the parameters of the finite difference grid
    nz, nx = vdepth.shape
    x1, x2, z1, z2 = area
    dz, dx = (z2 - z1) / (nz - 1), (x2 - x1) / (nx - 1)
    ns = shot.shape[0]  # number samples per trace

    # avoiding spatial alias and numerical dispersion based on plane waves v=l*f and Alford et al.
    # # and using at least 5 points per wavelength
    eps = 0.98 * 1. / (5 * max(dx, dz) * min(1. / (2 * dx), 1. / (2 * dz)))
    idealfc = eps * numpy.min(vdepth) / (max(2 * dx, 2 * dz))
    if fc > idealfc:
        sys.stdout.write(
            "Warning: the simulation might have strong numerical dispersion making it unusable\n"
        )
        sys.stdout.write("Warning: consider using a finer velocity model")

    simsource = [wavefd.GaussSource(source, area, (nz, nx), 1.,
                                    fc)]  # forward simulation source
    simdt = wavefd.scalar_maxdt(
        area, vdepth.shape, numpy.max(vdepth))  # forward simulation time step
    simit = int(numpy.floor(
        ns * dt /
        simdt))  # maximum number of iterations needed for forward modelling
    # run forward modelling of the shot
    fwdsimulation = wavefd.scalar(vdepth,
                                  area,
                                  simdt,
                                  simit,
                                  simsource,
                                  snapshot=1,
                                  padding=50)

    # dt from signal must be equal to dt from simulation, so resample it first
    # resample the input signal is better then resampling everything else
    simshot = shot
    if dt != simdt:  #  resample shot if needed
        if dt > simdt:  # low pass filtering on Nyquest first of shot sample rate
            # 1/(2*simdt) is equal of Nyquest=1 for the input signal
            b, a = signal.butter(8, dt / simdt)
            simshot = signal.filtfilt(b, a, shot, axis=0)
        simshot = signal.resample(simshot, simit, axis=0)

    # run the forward simulation and record every time step of the grid
    fwdfield = numpy.zeros((simit, nz, nx))
    for i, u, seismograms in fwdsimulation:
        fwdfield[i, :, :] = u
        sys.stdout.write("\rforward modeling progressing .. %.1f%% time %.3f" %
                         (100.0 * float(i) / simit, (simdt * i)))
        sys.stdout.flush()

    # Reverse in time shot basic parameters same from forward modelling
    rtmsimulation = rt_scalar(vdepth,
                              area,
                              simdt,
                              simit,
                              simshot,
                              snapshot=1,
                              padding=50)

    # run the reverse time simulation and record every time step of the grid
    rtmfield = numpy.zeros((simit, nz, nx))
    for i, u in rtmsimulation:
        rtmfield[i, :, :] = u
        sys.stdout.write(
            "\rreverse in time modeling progressing .. %.1f%% time %.3f" %
            (100.0 * float(i) / simit, (simdt * i)))
        sys.stdout.flush()

    # normalized cross-correlation image condition
    migratedshot = numpy.zeros((nz, nx))
    for i in xrange(nz):
        for j in xrange(nx):
            migratedshot[i, j] = numpy.dot(rtmfield[:, i, j], fwdfield[::-1, i,
                                                                       j])
            migratedshot[i, j] /= numpy.sum(fwdfield[:, i, j]**2)

    return migratedshot


# def rt_scalar(vel, area, dt, iterations, boundary, snapshot=None, padding=-1, taper=0.006):
#     """
#
#     Simulate reverse in time scalar waves using an explicit finite differences scheme 4th order
#     space. Uses a boundary condition at z=0, re-inserting the recorded values back on the
#     wave-field simulation from the last values to the first.
#     Used to make reverse time depth migration of zero-offset sections or shot gathers.
#
#     The top implements a free-surface boundary condition (TODO: change to absorbing).
#     For the left, right and lower uses boundaries uses Transparent condition of Reynolds, A. C.
#     (Boundary conditions for numerical solution of wave propagation problems Geophysics p 1099-1110 - 1978)
#
#     Parameters:
#
#     * vel : 2D-array (defines shape simulation)
#         The wave velocity at all the grid nodes, must be half the original velocity.
#         The depth velocity model.
#     * area : [xmin, xmax, zmin, zmax]
#         The x, z limits of the simulation area, e.g., the shallowest point is
#         at zmin, the deepest at zmax.
#     * dt : float
#         The time interval between iterations
#     * iterations : int
#         Number of time steps to take
#     * boundary : 2D-array
#         Those are the boundary values at z=0 for all iteration times.
#         For zero-offset section migration, shot-gather migration
#         this is a matrix of traces.
#         Boundary must have same shape as vel and sample rate must be equal of dt.
#     * snapshot : None or int
#         If not None, than yield a snapshot of the scalar quantity disturbed at every
#         *snapshot* iterations.
#     * padding : int
#         Number of grid nodes to use for the absorbing boundary region
#         default 5 percent nz
#     * taper : float  (TODO: implement real gaussian)
#         The intensity of the Gaussian taper function used for the absorbing
#         boundary conditions. Adjust it for better absorption.
#
#     Yields:
#
#     * i, u : int, 2D-array
#         The current iteration, the scalar quantity disturbed
#
#     The last iteration is the migrated section in depth
#
#     """
#
#     if boundary.shape[1] != vel.shape[1]:  # just x must be equal
#         raise IndexError("boundary must have same shape as velocity")
#     if iterations != boundary.shape[0]:
#         raise IndexError("Same number of interations needed for rtm")
#
#     nz, nx = numpy.shape(vel) # get simulation dimensions
#     x1, x2, z1, z2 = area
#     dz, dx = (z2 - z1)/(nz - 1), (x2 - x1)/(nx - 1)
#
#     # Add some padding to x and z. The padding region is where the wave is
#     # absorbed by gaussian dumping
#     pad = int(padding)
#     if pad == -1:   # default 5% percent nz
#         pad = int(0.05*nz) + 2  # plus 2 due 4th order
#     nx += 2*pad
#     nz += pad
#     # Pad the velocity as well
#     vel_pad = wavefd._add_pad(vel, pad, (nz, nx))
#     # Pack the particle position u at 3 different times in one 3d array
#     u = numpy.zeros((3, nz, nx), dtype=numpy.float)
#     # insert the zero-offset samples reversed in time last ones first. For utp1 at z=0 for every x
#     for j in xrange(nx-2*pad):  # tp1
#         u[0, 0, j + pad] = boundary[iterations-1, j]
#     if snapshot is not None:
#         yield 0, u[0, :-pad, pad:-pad]
#     for j in xrange(nx-2*pad):  # t
#         u[1, 0, j + pad] = boundary[iterations-2, j]
#     if snapshot is not None:
#         yield 1, u[1, :-pad, pad:-pad]
#     for iteration in xrange(2, iterations):
#         tm1, t, tp1 = iteration % 3, (iteration-1) % 3, (iteration-2) % 3  # to avoid copying between panels
#         # invert the order of the input parameters to make it reverse in time
#         wavefd._step_scalar(u[tm1], u[t], u[tp1], 2, nx - 2, 2, nz - 2,
#                      dt, dx, dz, vel_pad)
#         # _apply_damping(u[tp1], nx-2, nz-2, pad-2, taper)
#         # forth order +2-2 indexes needed
#         # apply Reynolds 1d plane wave absorbing condition
#         wavefd._nonreflexive_scalar_boundary_conditions(u[tm1], u[t], u[tp1], vel_pad, dt, dx, dz, nx, nz)
#         # insert the zero-offset samples reversed in time last ones first. For utp1 at z=0 for every x
#         for j in xrange(nx-2*pad):
#             u[t, 0, j + pad] = boundary[iterations-(iteration+1), j]
#         if snapshot is not None and iteration%snapshot == 0:
#             yield iteration, u[tm1, :-pad, pad:-pad]
#     yield iteration, u[tm1, :-pad, pad:-pad]
示例#3
0
pvel[int(600 / dz):int(600 / dz) + int(120 / dz), :] = 4800  # basalt flow 1
pvel[int(600 / dz) + int(120 / dz):int(600 / dz) +
     int(240 / dz), :] = 3540  # basalt flow 2
svel = 1600 * np.ones(shape)  # botucatu
svel[0:int(600 / dz), :] = 1166  # bauru
svel[int(600 / dz):int(600 / dz) + int(120 / dz), :] = 2611  # basalt flow 1
svel[int(600 / dz) + int(120 / dz):int(600 / dz) +
     int(240 / dz), :] = 1900  # basalt flow 2

mu = wavefd.lame_mu(svel, density)
lamb = wavefd.lame_lamb(pvel, svel, density)

# Make a wave source from a gauss derivative that vibrates in the z direction only
# (removes the shear component amplitude equals zero, simulating a default seismic acquisition)
sources = [
    [wavefd.GaussSource(2000, 0, area, shape, 0.0,
                        5.)],  # x source or shear source
    [wavefd.GaussSource(2000, 0, area, shape, 100.0, 25.)]
]  # z source or z compressional source

# Get the iterator for the simulation
dt = wavefd.maxdt(area, shape, np.max(pvel))
duration = 3.0
maxit = int(duration / dt)
stations = [[2200 + i * dx, 0]
            for i in range(220)]  # x, z coordinate of the seismometers
snapshot = int(0.004 /
               dt)  # Plot a snapshot of the simulation every 4 miliseconds
print "dt for simulation is ", dt
print "max iteration for simulation is ", maxit
print "duration for simulation is ", duration
simulation = wavefd.elastic_psv(lamb,
Geophysics  1974
"""
import numpy as np
from matplotlib import animation
from fatiando.seismic import wavefd
from fatiando.vis import mpl

# Set the parameters of the finite difference grid
shape = (200, 200)
ds = 100.  # spacing
area = [0, shape[0] * ds, 0, shape[1] * ds]
# Set the parameters of the finite difference grid
velocity = np.zeros(shape) + 6000.
velocity[100:, 100:] = 0.
fc = 15.
sources = [wavefd.GaussSource(125 * ds, 75 * ds, area, shape, 1., fc)]
dt = wavefd.scalar_maxdt(area, shape, np.max(velocity))
duration = 2.5
maxit = int(duration / dt)
stations = [[75 * ds, 125 * ds]]  # x, z coordinate of the seismometer
snapshots = 3  # every 3 iterations plots one
simulation = wavefd.scalar(velocity, area, dt, maxit, sources, stations,
                           snapshots)

# This part makes an animation using matplotlibs animation API
background = (velocity - 4000) * 10**-1
fig = mpl.figure(figsize=(8, 6))
mpl.subplots_adjust(right=0.98, left=0.11, hspace=0.5, top=0.93)
mpl.subplot2grid((4, 3), (0, 0), colspan=3, rowspan=3)
wavefield = mpl.imshow(np.zeros_like(velocity),
                       extent=area,
示例#5
0
"""
import numpy as np
import sys
from fatiando.seismic import wavefd

# Set the parameters of the finite difference grid 3D
shape = (100, 100, 100)
ds = 10.  # spacing
area = [0, shape[2]*ds, 0, shape[1]*ds, 0, shape[0]*ds]
# Set the parameters of the finite difference grid
velocity = np.ones(shape)*2500.  # m/s
velocity[50:100, 50:100, 50:100] = 1500. # m/s
# avoiding spatial alias, frequency of source should be smaller than this
fc = 0.5*np.min(velocity)/ds  # based on plane waves v=l*f
fc -= 0.5*fc
sources = [wavefd.GaussSource((40*ds, 40*ds, 30*ds), area, shape,  10**(-8), fc)]
dt = wavefd.maxdt(area, shape, np.max(velocity))
duration = 0.6
maxit = int(duration/dt)
# x, y, z coordinate of the seismometer
stations = [[45*ds, 45*ds, 65*ds], [65*ds, 65*ds, 30*ds]]
snapshots = 5  # every 1 iterations plots one
simulation = wavefd.scalar3(velocity, area, dt, maxit,
                                sources, stations, snapshots)
movie = np.zeros(((maxit/snapshots)+2, 100, 100, 100))
i = 0
for t, u, seismogram in simulation:
    movie[i] = u
    sys.stdout.write("\rprogressing .. %.1f%% time %.3f"%(100.0*float(t)/maxit, (dt*t)))
    sys.stdout.flush()
    i += 1