Ejemplo n.º 1
0
def Gzz_shifted_2d(field, costheta, sintheta, space_order):
    """
    2D rotated second order derivative in the direction z as an average of
    two non-centered rotated second order derivative in the direction z
    :param field: symbolic data whose derivative we are computing
    :param costheta: cosine of the tilt
    :param sintheta:  sine of the tilt
    :param space_order: discretization order
    :return: rotated second order derivative wrt z
    """
    x, y = field.space_dimensions[:2]
    Gz1r = (sintheta * field.dxr + costheta * field.dy)
    Gzz1 = (first_derivative(Gz1r * sintheta,
                             dim=x,
                             side=right,
                             order=space_order,
                             matvec=transpose) +
            first_derivative(Gz1r * costheta,
                             dim=y,
                             side=centered,
                             order=space_order,
                             matvec=transpose))
    Gz2r = (sintheta * field.dx + costheta * field.dyr)
    Gzz2 = (first_derivative(Gz2r * sintheta,
                             dim=x,
                             side=centered,
                             order=space_order,
                             matvec=transpose) +
            first_derivative(Gz2r * costheta,
                             dim=y,
                             side=right,
                             order=space_order,
                             matvec=transpose))

    return -.5 * (Gzz1 + Gzz2)
Ejemplo n.º 2
0
def Gyy_shifted(field, cosphi, sinphi, space_order):
    """
    3D rotated second order derivative in the direction y as an average of
    two non-centered rotated second order derivative in the direction y
    :param field: symbolic data whose derivative we are computing
    :param cosphi: cosine of the azymuth angle
    :param sinphi: sine of the azymuth angle
    :param space_order: discretization order
    :return: rotated second order derivative wrt y
    """
    x, y = field.space_dimensions[:2]
    Gyp = (sinphi * field.dx - cosphi * field.dyr)
    Gyy = (first_derivative(Gyp * sinphi,
                            dim=x,
                            side=centered,
                            order=space_order,
                            matvec=transpose) -
           first_derivative(Gyp * cosphi,
                            dim=y,
                            side=right,
                            order=space_order,
                            matvec=transpose))
    Gyp2 = (sinphi * field.dxr - cosphi * field.dy)
    Gyy2 = (first_derivative(
        Gyp2 * sinphi, dim=x, side=right, order=space_order, matvec=transpose)
            - first_derivative(Gyp2 * cosphi,
                               dim=y,
                               side=centered,
                               order=space_order,
                               matvec=transpose))
    return -.5 * (Gyy + Gyy2)
Ejemplo n.º 3
0
def Gxx_shifted_2d(field, costheta, sintheta, space_order):
    """
    2D rotated second order derivative in the direction x as an average of
    two non-centered rotated second order derivative in the direction x
    :param field: symbolic data whose derivative we are computing
    :param costheta: cosine of the tilt angle
    :param sintheta:  sine of the tilt angle
    :param space_order: discretization order
    :return: rotated second order derivative wrt x
    """
    x, y = field.space_dimensions[:2]
    Gx1 = (costheta * field.dxr - sintheta * field.dy)
    Gxx1 = (first_derivative(
        Gx1 * costheta, dim=x, side=right, order=space_order, matvec=transpose)
            - first_derivative(Gx1 * sintheta,
                               dim=y,
                               side=centered,
                               order=space_order,
                               matvec=transpose))
    Gx2p = (costheta * field.dx - sintheta * field.dyr)
    Gxx2 = (first_derivative(Gx2p * costheta,
                             dim=x,
                             side=centered,
                             order=space_order,
                             matvec=transpose) -
            first_derivative(Gx2p * sintheta,
                             dim=y,
                             side=right,
                             order=space_order,
                             matvec=transpose))

    return -.5 * (Gxx1 + Gxx2)
Ejemplo n.º 4
0
def Gzz_centered_2d(field, costheta, sintheta, space_order):
    """
    2D rotated second order derivative in the direction z
    :param field: symbolic data whose derivative we are computing
    :param costheta: cosine of the tilt angle
    :param sintheta:  sine of the tilt angle
    :param space_order: discretization order
    :return: rotated second order derivative wrt z
    """
    order1 = space_order / 2
    Gz = -(
        sintheta * first_derivative(field, dim=x, side=centered, order=order1)
        +
        costheta * first_derivative(field, dim=y, side=centered, order=order1))
    Gzz = (first_derivative(
        Gz * sintheta, dim=x, side=centered, order=order1, matvec=transpose
    ) + first_derivative(
        Gz * costheta, dim=y, side=centered, order=order1, matvec=transpose))
    return Gzz
Ejemplo n.º 5
0
def Gxx_shifted(field, costheta, sintheta, cosphi, sinphi, space_order):
    """
    3D rotated second order derivative in the direction x as an average of
    two non-centered rotated second order derivative in the direction x
    :param field: symbolic data whose derivative we are computing
    :param costheta: cosine of the tilt angle
    :param sintheta:  sine of the tilt angle
    :param cosphi: cosine of the azymuth angle
    :param sinphi: sine of the azymuth angle
    :param space_order: discretization order
    :return: rotated second order derivative wrt x
    """
    x, y, z = field.space_dimensions
    Gx1 = (costheta * cosphi * field.dx + costheta * sinphi * field.dyr -
           sintheta * field.dzr)
    Gxx1 = (first_derivative(Gx1 * costheta * cosphi,
                             dim=x,
                             side=centered,
                             order=space_order,
                             matvec=transpose) +
            first_derivative(Gx1 * costheta * sinphi,
                             dim=y,
                             side=right,
                             order=space_order,
                             matvec=transpose) -
            first_derivative(Gx1 * sintheta,
                             dim=z,
                             side=right,
                             order=space_order,
                             matvec=transpose))
    Gx2 = (costheta * cosphi * field.dxr + costheta * sinphi * field.dy -
           sintheta * field.dz)
    Gxx2 = (first_derivative(Gx2 * costheta * cosphi,
                             dim=x,
                             side=right,
                             order=space_order,
                             matvec=transpose) +
            first_derivative(Gx2 * costheta * sinphi,
                             dim=y,
                             side=centered,
                             order=space_order,
                             matvec=transpose) -
            first_derivative(Gx2 * sintheta,
                             dim=z,
                             side=centered,
                             order=space_order,
                             matvec=transpose))
    return -.5 * (Gxx1 + Gxx2)
Ejemplo n.º 6
0
def Gzz_shited(field, costheta, sintheta, cosphi, sinphi, space_order):
    """
    3D rotated second order derivative in the direction z as an average of
    two non-centered rotated second order derivative in the direction z
    :param field: symbolic data whose derivative we are computing
    :param costheta: cosine of the tilt angle
    :param sintheta:  sine of the tilt angle
    :param cosphi: cosine of the azymuth angle
    :param sinphi: sine of the azymuth angle
    :param space_order: discretization order
    :return: rotated second order derivative wrt z
    """
    x, y, z = field.space_dimensions
    Gzr = (sintheta * cosphi * field.dx + sintheta * sinphi * field.dyr +
           costheta * field.dzr)
    Gzz = (first_derivative(Gzr * sintheta * cosphi,
                            dim=x,
                            side=centered,
                            order=space_order,
                            matvec=transpose) +
           first_derivative(Gzr * sintheta * sinphi,
                            dim=y,
                            side=right,
                            order=space_order,
                            matvec=transpose) +
           first_derivative(Gzr * costheta,
                            dim=z,
                            side=right,
                            order=space_order,
                            matvec=transpose))
    Gzr2 = (sintheta * cosphi * field.dxr + sintheta * sinphi * field.dy +
            costheta * field.dz)
    Gzz2 = (first_derivative(Gzr2 * sintheta * cosphi,
                             dim=x,
                             side=right,
                             order=space_order,
                             matvec=transpose) +
            first_derivative(Gzr2 * sintheta * sinphi,
                             dim=y,
                             side=centered,
                             order=space_order,
                             matvec=transpose) +
            first_derivative(Gzr2 * costheta,
                             dim=z,
                             side=centered,
                             order=space_order,
                             matvec=transpose))
    return -.5 * (Gzz + Gzz2)
Ejemplo n.º 7
0
 def dzr(self):
     """Symbol for the derivative wrt to z with a right stencil"""
     return first_derivative(self,
                             order=self.space_order,
                             dim=z,
                             side=right)
Ejemplo n.º 8
0
 def dyl(self):
     """Symbol for the derivative wrt to y with a left stencil"""
     return first_derivative(self, order=self.space_order, dim=y, side=left)
Ejemplo n.º 9
0
 def dz(self):
     """Symbol for the first derivative wrt the z dimension"""
     return first_derivative(self,
                             order=self.space_order,
                             dim=z,
                             side=centered)
Ejemplo n.º 10
0
def ForwardOperator(model,
                    source,
                    receiver,
                    time_order=2,
                    space_order=4,
                    save=False,
                    **kwargs):
    """
    Constructor method for the forward modelling operator in an acoustic media

    :param model: :class:`Model` object containing the physical parameters
    :param src: None ot IShot() (not currently supported properly)
    :param data: IShot() object containing the acquisition geometry and field data
    :param: time_order: Time discretization order
    :param: spc_order: Space discretization order
    :param: u_ini : wavefield at the three first time step for non-zero initial condition
    """
    dt = model.critical_dt

    m, damp, epsilon, delta, theta, phi = (model.m, model.damp, model.epsilon,
                                           model.delta, model.theta, model.phi)

    # Create symbols for forward wavefield, source and receivers
    u = TimeData(name='u',
                 shape=model.shape_domain,
                 time_dim=source.nt,
                 time_order=time_order,
                 space_order=space_order,
                 save=save,
                 dtype=model.dtype)
    v = TimeData(name='v',
                 shape=model.shape_domain,
                 time_dim=source.nt,
                 time_order=time_order,
                 space_order=space_order,
                 save=save,
                 dtype=model.dtype)
    src = PointSource(name='src',
                      ntime=source.nt,
                      ndim=source.ndim,
                      npoint=source.npoint)
    rec = Receiver(name='rec',
                   ntime=receiver.nt,
                   ndim=receiver.ndim,
                   npoint=receiver.npoint)

    ang0 = cos(theta)
    ang1 = sin(theta)
    if len(model.shape) == 3:
        ang2 = cos(phi)
        ang3 = sin(phi)

        # Derive stencil from symbolic equation
        Gyp = (ang3 * u.dx - ang2 * u.dyr)
        Gyy = (first_derivative(Gyp * ang3,
                                dim=x,
                                side=centered,
                                order=space_order,
                                matvec=transpose) -
               first_derivative(Gyp * ang2,
                                dim=y,
                                side=right,
                                order=space_order,
                                matvec=transpose))
        Gyp2 = (ang3 * u.dxr - ang2 * u.dy)
        Gyy2 = (first_derivative(Gyp2 * ang3,
                                 dim=x,
                                 side=right,
                                 order=space_order,
                                 matvec=transpose) -
                first_derivative(Gyp2 * ang2,
                                 dim=y,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose))

        Gxp = (ang0 * ang2 * u.dx + ang0 * ang3 * u.dyr - ang1 * u.dzr)
        Gzr = (ang1 * ang2 * v.dx + ang1 * ang3 * v.dyr + ang0 * v.dzr)
        Gxx = (first_derivative(Gxp * ang0 * ang2,
                                dim=x,
                                side=centered,
                                order=space_order,
                                matvec=transpose) +
               first_derivative(Gxp * ang0 * ang3,
                                dim=y,
                                side=right,
                                order=space_order,
                                matvec=transpose) -
               first_derivative(Gxp * ang1,
                                dim=z,
                                side=right,
                                order=space_order,
                                matvec=transpose))
        Gzz = (first_derivative(Gzr * ang1 * ang2,
                                dim=x,
                                side=centered,
                                order=space_order,
                                matvec=transpose) +
               first_derivative(Gzr * ang1 * ang3,
                                dim=y,
                                side=right,
                                order=space_order,
                                matvec=transpose) +
               first_derivative(Gzr * ang0,
                                dim=z,
                                side=right,
                                order=space_order,
                                matvec=transpose))
        Gxp2 = (ang0 * ang2 * u.dxr + ang0 * ang3 * u.dy - ang1 * u.dz)
        Gzr2 = (ang1 * ang2 * v.dxr + ang1 * ang3 * v.dy + ang0 * v.dz)
        Gxx2 = (first_derivative(Gxp2 * ang0 * ang2,
                                 dim=x,
                                 side=right,
                                 order=space_order,
                                 matvec=transpose) +
                first_derivative(Gxp2 * ang0 * ang3,
                                 dim=y,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose) -
                first_derivative(Gxp2 * ang1,
                                 dim=z,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose))
        Gzz2 = (first_derivative(Gzr2 * ang1 * ang2,
                                 dim=x,
                                 side=right,
                                 order=space_order,
                                 matvec=transpose) +
                first_derivative(Gzr2 * ang1 * ang3,
                                 dim=y,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose) +
                first_derivative(Gzr2 * ang0,
                                 dim=z,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose))
        Hp = -(.5 * Gxx + .5 * Gxx2 + .5 * Gyy + .5 * Gyy2)
        Hzr = -(.5 * Gzz + .5 * Gzz2)

    else:
        Gx1p = (ang0 * u.dxr - ang1 * u.dy)
        Gz1r = (ang1 * v.dxr + ang0 * v.dy)
        Gxx1 = (first_derivative(Gx1p * ang0,
                                 dim=x,
                                 side=right,
                                 order=space_order,
                                 matvec=transpose) -
                first_derivative(Gx1p * ang1,
                                 dim=y,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose))
        Gzz1 = (first_derivative(Gz1r * ang1,
                                 dim=x,
                                 side=right,
                                 order=space_order,
                                 matvec=transpose) +
                first_derivative(Gz1r * ang0,
                                 dim=y,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose))
        Gx2p = (ang0 * u.dx - ang1 * u.dyr)
        Gz2r = (ang1 * v.dx + ang0 * v.dyr)
        Gxx2 = (first_derivative(Gx2p * ang0,
                                 dim=x,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose) -
                first_derivative(Gx2p * ang1,
                                 dim=y,
                                 side=right,
                                 order=space_order,
                                 matvec=transpose))
        Gzz2 = (first_derivative(Gz2r * ang1,
                                 dim=x,
                                 side=centered,
                                 order=space_order,
                                 matvec=transpose) +
                first_derivative(Gz2r * ang0,
                                 dim=y,
                                 side=right,
                                 order=space_order,
                                 matvec=transpose))

        Hp = -(.5 * Gxx1 + .5 * Gxx2)
        Hzr = -(.5 * Gzz1 + .5 * Gzz2)

    stencilp = 1.0 / (2.0 * m + s * damp) * \
        (4.0 * m * u + (s * damp - 2.0 * m) *
         u.backward + 2.0 * s**2 * (epsilon * Hp + delta * Hzr))
    stencilr = 1.0 / (2.0 * m + s * damp) * \
        (4.0 * m * v + (s * damp - 2.0 * m) *
         v.backward + 2.0 * s**2 * (delta * Hp + Hzr))

    # Add substitutions for spacing (temporal and spatial)
    subs = {s: dt, h: model.get_spacing()}
    first_stencil = Eq(u.forward, stencilp)
    second_stencil = Eq(v.forward, stencilr)
    stencils = [first_stencil, second_stencil]

    ti = u.indices[0]
    stencils += src.inject(field=u,
                           u_t=ti + 1,
                           expr=src * dt * dt / m,
                           offset=model.nbpml)
    stencils += src.inject(field=v,
                           u_t=ti + 1,
                           expr=src * dt * dt / m,
                           offset=model.nbpml)
    stencils += rec.interpolate(expr=u, u_t=ti, offset=model.nbpml)
    stencils += rec.interpolate(expr=v, u_t=ti, offset=model.nbpml)

    return Operator(stencils, subs=subs, name='ForwardTTI', **kwargs)
Ejemplo n.º 11
0
    def __init__(self, model, src, damp, data, time_order=2, spc_order=4, save=False,
                 **kwargs):
        nrec, nt = data.shape
        dt = model.get_critical_dt()
        u = TimeData(name="u", shape=model.get_shape_comp(),
                     time_dim=nt, time_order=time_order,
                     space_order=spc_order,
                     save=save, dtype=damp.dtype)
        v = TimeData(name="v", shape=model.get_shape_comp(),
                     time_dim=nt, time_order=time_order,
                     space_order=spc_order,
                     save=save, dtype=damp.dtype)
        m = DenseData(name="m", shape=model.get_shape_comp(),
                      dtype=damp.dtype)
        m.data[:] = model.padm()

        if model.epsilon is not None:
            epsilon = DenseData(name="epsilon", shape=model.get_shape_comp(),
                                dtype=damp.dtype)
            epsilon.data[:] = model.pad(model.epsilon)
        else:
            epsilon = 1.0

        if model.delta is not None:
            delta = DenseData(name="delta", shape=model.get_shape_comp(),
                              dtype=damp.dtype)
            delta.data[:] = model.pad(model.delta)
        else:
            delta = 1.0
        if model.theta is not None:
            theta = DenseData(name="theta", shape=model.get_shape_comp(),
                              dtype=damp.dtype)
            theta.data[:] = model.pad(model.theta)
        else:
            theta = 0

        if len(model.get_shape_comp()) == 3:
            if model.phi is not None:
                phi = DenseData(name="phi", shape=model.get_shape_comp(),
                                dtype=damp.dtype)
                phi.data[:] = model.pad(model.phi)
            else:
                phi = 0

        u.pad_time = save
        v.pad_time = save
        rec = SourceLike(name="rec", npoint=nrec, nt=nt, dt=dt,
                         h=model.get_spacing(),
                         coordinates=data.receiver_coords,
                         ndim=len(damp.shape),
                         dtype=damp.dtype,
                         nbpml=model.nbpml)

        def Bhaskarasin(angle):
            if angle == 0:
                return 0
            else:
                return (16.0 * angle * (3.1416 - abs(angle)) /
                        (49.3483 - 4.0 * abs(angle) * (3.1416 - abs(angle))))

        def Bhaskaracos(angle):
            if angle == 0:
                return 1.0
            else:
                return Bhaskarasin(angle + 1.5708)

        Hp, Hzr = symbols('Hp Hzr')
        if len(m.shape) == 3:
            ang0 = Function('ang0')(x, y, z)
            ang1 = Function('ang1')(x, y, z)
            ang2 = Function('ang2')(x, y, z)
            ang3 = Function('ang3')(x, y, z)
        else:
            ang0 = Function('ang0')(x, y)
            ang1 = Function('ang1')(x, y)

        s, h = symbols('s h')

        ang0 = Bhaskaracos(theta)
        ang1 = Bhaskarasin(theta)
        spc_brd = spc_order / 2
        # Derive stencil from symbolic equation
        if len(m.shape) == 3:
            ang2 = Bhaskaracos(phi)
            ang3 = Bhaskarasin(phi)

            Gy1p = (ang3 * u.dxl - ang2 * u.dyl)
            Gyy1 = (first_derivative(Gy1p, ang3, dim=x, side=right, order=spc_brd) -
                    first_derivative(Gy1p, ang2, dim=y, side=right, order=spc_brd))

            Gy2p = (ang3 * u.dxr - ang2 * u.dyr)
            Gyy2 = (first_derivative(Gy2p, ang3, dim=x, side=left, order=spc_brd) -
                    first_derivative(Gy2p, ang2, dim=y, side=left, order=spc_brd))

            Gx1p = (ang0 * ang2 * u.dxl + ang0 * ang3 * u.dyl - ang1 * u.dzl)
            Gz1r = (ang1 * ang2 * v.dxl + ang1 * ang3 * v.dyl + ang0 * v.dzl)
            Gxx1 = (first_derivative(Gx1p, ang0, ang2,
                                     dim=x, side=right, order=spc_brd) +
                    first_derivative(Gx1p, ang0, ang3,
                                     dim=y, side=right, order=spc_brd) -
                    first_derivative(Gx1p, ang1, dim=z, side=right, order=spc_brd))
            Gzz1 = (first_derivative(Gz1r, ang1, ang2,
                                     dim=x, side=right, order=spc_brd) +
                    first_derivative(Gz1r, ang1, ang3,
                                     dim=y, side=right, order=spc_brd) +
                    first_derivative(Gz1r, ang0, dim=z, side=right, order=spc_brd))

            Gx2p = (ang0 * ang2 * u.dxr + ang0 * ang3 * u.dyr - ang1 * u.dzr)
            Gz2r = (ang1 * ang2 * v.dxr + ang1 * ang3 * v.dyr + ang0 * v.dzr)
            Gxx2 = (first_derivative(Gx2p, ang0, ang2,
                                     dim=x, side=left, order=spc_brd) +
                    first_derivative(Gx2p, ang0, ang3,
                                     dim=y, side=left, order=spc_brd) -
                    first_derivative(Gx2p, ang1, dim=z, side=left, order=spc_brd))
            Gzz2 = (first_derivative(Gz2r, ang1, ang2,
                                     dim=x, side=left, order=spc_brd) +
                    first_derivative(Gz2r, ang1, ang3,
                                     dim=y, side=left, order=spc_brd) +
                    first_derivative(Gz2r, ang0,
                                     dim=z, side=left, order=spc_brd))
            parm = [m, damp, epsilon, delta, theta, phi, u, v]
        else:
            Gyy2 = 0
            Gyy1 = 0
            parm = [m, damp, epsilon, delta, theta, u, v]
            Gx1p = (ang0 * u.dxr - ang1 * u.dy)
            Gz1r = (ang1 * v.dxr + ang0 * v.dy)
            Gxx1 = (first_derivative(Gx1p * ang0, dim=x,
                                     side=left, order=spc_brd) -
                    first_derivative(Gx1p * ang1, dim=y,
                                     side=centered, order=spc_brd))
            Gzz1 = (first_derivative(Gz1r * ang1, dim=x,
                                     side=left, order=spc_brd) +
                    first_derivative(Gz1r * ang0, dim=y,
                                     side=centered, order=spc_brd))
            Gx2p = (ang0 * u.dx - ang1 * u.dyr)
            Gz2r = (ang1 * v.dx + ang0 * v.dyr)
            Gxx2 = (first_derivative(Gx2p * ang0, dim=x,
                                     side=centered, order=spc_brd) -
                    first_derivative(Gx2p * ang1, dim=y,
                                     side=left, order=spc_brd))
            Gzz2 = (first_derivative(Gz2r * ang1, dim=x,
                                     side=centered, order=spc_brd) +
                    first_derivative(Gz2r * ang0, dim=y,
                                     side=left, order=spc_brd))

        stencilp = 1.0 / (2.0 * m + s * damp) * \
            (4.0 * m * u + (s * damp - 2.0 * m) *
             u.backward + 2.0 * s**2 * (epsilon * Hp + delta * Hzr))
        stencilr = 1.0 / (2.0 * m + s * damp) * \
            (4.0 * m * v + (s * damp - 2.0 * m) *
             v.backward + 2.0 * s**2 * (delta * Hp + Hzr))

        Hp_val = -(.5 * Gxx1 + .5 * Gxx2 + .5 * Gyy1 + .5 * Gyy2)
        Hzr_val = -(.5 * Gzz1 + .5 * Gzz2)
        factorized = {Hp: Hp_val, Hzr: Hzr_val}
        # Add substitutions for spacing (temporal and spatial)
        subs = [{s: src.dt, h: src.h}, {s: src.dt, h: src.h}]
        first_stencil = Eq(u.forward, stencilp.xreplace(factorized))
        second_stencil = Eq(v.forward, stencilr.xreplace(factorized))
        stencils = [first_stencil, second_stencil]
        super(ForwardOperator, self).__init__(src.nt, m.shape,
                                              stencils=stencils,
                                              subs=subs,
                                              spc_border=spc_order/2 + 2,
                                              time_order=time_order,
                                              forward=True,
                                              dtype=m.dtype,
                                              input_params=parm,
                                              **kwargs)

        # Insert source and receiver terms post-hoc
        self.input_params += [src, src.coordinates, rec, rec.coordinates]
        self.output_params += [v, rec]
        self.propagator.time_loop_stencils_a = (src.add(m, u) + src.add(m, v) +
                                                rec.read2(u, v))
        self.propagator.add_devito_param(src)
        self.propagator.add_devito_param(src.coordinates)
        self.propagator.add_devito_param(rec)
        self.propagator.add_devito_param(rec.coordinates)