def src_rec(p, model, geometry, **kwargs): """ Forward case: Source injection and receiver interpolation Adjoint case: Receiver injection and source interpolation """ dt = model.grid.time_dim.spacing m = model.m # Source symbol with input wavelet src = PointSource(name="src", grid=model.grid, time_range=geometry.time_axis, npoint=geometry.nsrc) rec = Receiver(name='rec', grid=model.grid, time_range=geometry.time_axis, npoint=geometry.nrec) forward = kwargs.get('forward', True) time_order = p.time_order if forward: # The source injection term if(time_order == 1): src_term = src.inject(field=p.forward, expr=src * dt) else: src_term = src.inject(field=p.forward, expr=src * dt**2 / m) # Create interpolation expression for receivers rec_term = rec.interpolate(expr=p) else: # Construct expression to inject receiver values if(time_order == 1): rec_term = rec.inject(field=p.backward, expr=rec * dt) else: rec_term = rec.inject(field=p.backward, expr=rec * dt**2 / m) # Create interpolation expression for the adjoint-source src_term = src.interpolate(expr=p) return src_term + rec_term
def AdjointOperator(model, source, receiver, space_order=4, kernel='OT2', **kwargs): """ Constructor method for the adjoint modelling operator in an acoustic media :param model: :class:`Model` object containing the physical parameters :param source: :class:`PointData` object containing the source geometry :param receiver: :class:`PointData` object containing the acquisition geometry :param time_order: Time discretization order :param space_order: Space discretization order """ m, damp = model.m, model.damp v = TimeFunction(name='v', grid=model.grid, save=None, time_order=2, space_order=space_order) srca = PointSource(name='srca', grid=model.grid, time_range=source.time_range, npoint=source.npoint) rec = Receiver(name='rec', grid=model.grid, time_range=receiver.time_range, npoint=receiver.npoint) s = model.grid.stepping_dim.spacing eqn = iso_stencil(v, m, s, damp, kernel, forward=False) # Construct expression to inject receiver values receivers = rec.inject(field=v.backward, expr=rec * s**2 / m, offset=model.nbpml) # Create interpolation expression for the adjoint-source source_a = srca.interpolate(expr=v, offset=model.nbpml) # Substitute spacing terms to reduce flops return Operator(eqn + receivers + source_a, subs=model.spacing_map, name='Adjoint', **kwargs)
def AdjointOperator(model, geometry, space_order=4, kernel='OT2', **kwargs): """ Constructor method for the adjoint modelling operator in an acoustic media :param model: :class:`Model` object containing the physical parameters :param source: :class:`PointData` object containing the source geometry :param receiver: :class:`PointData` object containing the acquisition geometry :param time_order: Time discretization order :param space_order: Space discretization order """ m, damp = model.m, model.damp v = TimeFunction(name='v', grid=model.grid, save=None, time_order=2, space_order=space_order) srca = PointSource(name='srca', grid=model.grid, time_range=geometry.time_axis, npoint=geometry.nsrc) rec = Receiver(name='rec', grid=model.grid, time_range=geometry.time_axis, npoint=geometry.nrec) s = model.grid.stepping_dim.spacing eqn = iso_stencil(v, m, s, damp, kernel, forward=False) # Construct expression to inject receiver values receivers = rec.inject(field=v.backward, expr=rec * s**2 / m) # Create interpolation expression for the adjoint-source source_a = srca.interpolate(expr=v) # Substitute spacing terms to reduce flops return Operator(eqn + receivers + source_a, subs=model.spacing_map, name='Adjoint', **kwargs)
def AdjointOperator(model, geometry, space_order=4, **kwargs): """ Construct an adjoint modelling operator in an tti media. Parameters ---------- model : Model Object containing the physical parameters. geometry : AcquisitionGeometry Geometry object that contains the source (SparseTimeFunction) and receivers (SparseTimeFunction) and their position. space_order : int, optional Space discretization order. """ dt = model.grid.time_dim.spacing m = model.m time_order = 2 # Create symbols for forward wavefield, source and receivers p = TimeFunction(name='p', grid=model.grid, save=None, time_order=time_order, space_order=space_order) r = TimeFunction(name='r', grid=model.grid, save=None, time_order=time_order, space_order=space_order) srca = PointSource(name='srca', grid=model.grid, time_range=geometry.time_axis, npoint=geometry.nsrc) rec = Receiver(name='rec', grid=model.grid, time_range=geometry.time_axis, npoint=geometry.nrec) # FD kernels of the PDE FD_kernel = kernels[('centered', len(model.shape))] stencils = FD_kernel(model, p, r, space_order, forward=False) # Construct expression to inject receiver values stencils += rec.inject(field=p.backward, expr=rec * dt**2 / m) stencils += rec.inject(field=r.backward, expr=rec * dt**2 / m) # Create interpolation expression for the adjoint-source stencils += srca.interpolate(expr=p + r) # Substitute spacing terms to reduce flops return Operator(stencils, subs=model.spacing_map, name='AdjointTTI', **kwargs)
def AdjointOperator(model, geometry, space_order=4, kernel='OT2', **kwargs): """ Construct an adjoint modelling operator in an acoustic media. Parameters ---------- model : Model Object containing the physical parameters. geometry : AcquisitionGeometry Geometry object that contains the source (SparseTimeFunction) and receivers (SparseTimeFunction) and their position. space_order : int, optional Space discretization order. kernel : str, optional Type of discretization, centered or shifted. """ m, damp = model.m, model.damp v = TimeFunction(name='v', grid=model.grid, save=None, time_order=2, space_order=space_order) srca = PointSource(name='srca', grid=model.grid, time_range=geometry.time_axis, npoint=geometry.nsrc) rec = Receiver(name='rec', grid=model.grid, time_range=geometry.time_axis, npoint=geometry.nrec) s = model.grid.stepping_dim.spacing eqn = iso_stencil(v, m, s, damp, kernel, forward=False) # Construct expression to inject receiver values receivers = rec.inject(field=v.backward, expr=rec * s**2 / m) # Create interpolation expression for the adjoint-source source_a = srca.interpolate(expr=v) # Substitute spacing terms to reduce flops return Operator(eqn + receivers + source_a, subs=model.spacing_map, name='Adjoint', **kwargs)
def AdjointOperator(model, source, receiver, time_order=2, space_order=4, **kwargs): """ Constructor method for the adjoint modelling operator in an acoustic media :param model: :class:`Model` object containing the physical parameters :param source: :class:`PointData` object containing the source geometry :param receiver: :class:`PointData` object containing the acquisition geometry :param time_order: Time discretization order :param space_order: Space discretization order """ m, damp = model.m, model.damp v = TimeData(name='v', shape=model.shape_domain, save=False, time_order=time_order, space_order=space_order, dtype=model.dtype) srca = PointSource(name='srca', ntime=source.nt, ndim=source.ndim, npoint=source.npoint) rec = Receiver(name='rec', ntime=receiver.nt, ndim=receiver.ndim, npoint=receiver.npoint) if time_order == 2: biharmonic = 0 dt = model.critical_dt else: biharmonic = v.laplace2(1/m) dt = 1.73 * model.critical_dt # Derive both stencils from symbolic equation stencil = 1 / (2 * m + s * damp) * ( 4 * m * v + (s * damp - 2 * m) * v.forward + 2 * s**2 * (v.laplace + s**2 / 12 * biharmonic)) eqn = Eq(v.backward, stencil) # Construct expression to inject receiver values ti = v.indices[0] receivers = rec.inject(field=v, u_t=ti - 1, offset=model.nbpml, expr=rec * dt**2 / m, p_t=time) # Create interpolation expression for the adjoint-source source_a = srca.interpolate(expr=v, u_t=ti, offset=model.nbpml) return Operator([eqn] + receivers + source_a, subs={s: dt, h: model.get_spacing()}, time_axis=Backward, name='Adjoint', **kwargs)
def td_born_forward_op(model, geometry, time_order, space_order): nt = geometry.nt # Define the wavefields with the size of the model and the time dimension u0 = TimeFunction( name='u0', grid=model.grid, time_order=time_order, space_order=space_order, save=nt ) u = TimeFunction( name='u', grid=model.grid, time_order=time_order, space_order=space_order, save=nt ) dm = TimeFunction( name='dm', grid=model.grid, time_order=time_order, space_order=space_order, save=nt ) # Define the wave equation pde = model.m * u.dt2 - u.laplace + model.damp * u.dt - dm * u0 # Use `solve` to rearrange the equation into a stencil expression stencil = Eq(u.forward, solve(pde, u.forward), subdomain=model.grid.subdomains['physdomain']) # Sample at receivers born_data_rec = PointSource( name='born_data_rec', grid=model.grid, time_range=geometry.time_axis, coordinates=geometry.rec_positions ) rec_term = born_data_rec.interpolate(expr=u) return Operator([stencil] + rec_term, subs=model.spacing_map)