def forward_wf_src_norec(model, u, space_order=8): """ Forward modeling of a full wavefield source without receiver F*u. Parameters ---------- model: Model Physical model u: TimeFunction or Array Time-space dependent wavefield space_order: Int (optional) Spatial discretization order, defaults to 8 Returns ---------- Array Wavefield """ wf_src = TimeFunction(name='wf_src', grid=model.grid, time_order=2, space_order=space_order, save=u.shape[0]) if isinstance(u, TimeFunction): wf_src._data = u._data else: wf_src.data[:] = u[:] _, u, _ = forward(model, None, None, None, space_order=space_order, save=True, q=wf_src) return u.data
def adjoint_wf_src_norec(model, u, space_order=8, free_surface=False): """ Adjoint/backward modeling of a full wavefield (full wavefield as adjoint source) F^T*u. Parameters ---------- model: Model Physical model u: Array or TimeFunction Time-space dependent source space_order: Int (optional) Spatial discretization order, defaults to 8 free_surface: Bool (optional) Whether or not to use a free surface Returns ---------- Array Adjoint wavefield """ wf_src = TimeFunction(name='wf_src', grid=model.grid, time_order=2, space_order=space_order, save=u.shape[0]) if isinstance(u, TimeFunction): wf_src._data = u._data else: wf_src.data[:] = u[:] _, v = adjoint(model, None, None, None, space_order=space_order, save=True, free_surface=free_surface, q=wf_src) return v.data
def adjoint_wf_src(model, u, src_coords, space_order=8, free_surface=False): """ Adjoint/backward modeling of a full wavefield (full wavefield as adjoint source) Ps*F^T*u. Parameters ---------- model: Model Physical model u: Array or TimeFunction Time-space dependent source src_coords: Array Source coordinates space_order: Int (optional) Spatial discretization order, defaults to 8 free_surface: Bool (optional) Whether or not to use a free surface Returns ---------- Array Shot record (sampled at source position(s)) """ wf_src = TimeFunction(name='wf_src', grid=model.grid, time_order=2, space_order=space_order, save=u.shape[0]) if isinstance(u, TimeFunction): wf_src._data = u._data else: wf_src.data[:] = u[:] rec, _ = adjoint(model, None, src_coords, None, space_order=space_order, free_surface=free_surface, q=wf_src) return rec.data
def forward_wf_src(model, u, rec_coords, space_order=8, free_surface=False): """ Forward modeling of a full wavefield source Pr*F*u. Parameters ---------- model: Model Physical model u: TimeFunction or Array Time-space dependent wavefield rec_coords: Array Coordiantes of the receiver(s) space_order: Int (optional) Spatial discretization order, defaults to 8 free_surface: Bool (optional) Whether or not to use a free surface Returns ---------- Array Shot record """ wf_src = TimeFunction(name='wf_src', grid=model.grid, time_order=2, space_order=space_order, save=u.shape[0]) if isinstance(u, TimeFunction): wf_src._data = u._data else: wf_src.data[:] = u[:] rec, _ = forward(model, None, rec_coords, None, space_order=space_order, free_surface=free_surface, q=wf_src) return rec.data
def adjoint_modeling(model, src_coords, rec_coords, rec_data, space_order=8, 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) # Input data is wavefield full_q = 0 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 full_q = wf_rec stencil = damp * (2.0 * v - damp * v.forward + dt**2 * rho / m * (vlaplace + full_q)) expression = [Eq(v.backward, stencil)] # Free surface if free_surface is True: expression += freesurface(v, space_order//2, model.nbpml, forward=False) # 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, 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) expression += adj_rec # Create operator and run subs = model.spacing_map subs[v.grid.time_dim.spacing] = dt op = Operator(expression, subs=subs, dse='advanced', dle='advanced') cf = op.cfunction summary = op.apply() if src_coords is None: return v, summary else: return src.data, summary
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
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
def forward_modeling(model, src_coords, wavelet, rec_coords, save=False, space_order=8, nb=40, free_surface=False, op_return=False, u_return=False, dt=None, tsub_factor=1): 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) eqsave = [] elif save is True and tsub_factor > 1: u = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=space_order) time_subsampled = ConditionalDimension(name='t_sub', parent=u.grid.time_dim, factor=tsub_factor) nsave = (nt-1)//tsub_factor + 2 usave = TimeFunction(name='us', grid=model.grid, time_order=2, space_order=space_order, time_dim=time_subsampled, save=nsave) eqsave = [Eq(usave.forward, u.forward)] else: u = TimeFunction(name='u', grid=model.grid, time_order=2, space_order=space_order, save=nt) eqsave = [] # Set up PDE ulaplace, rho = acoustic_laplacian(u, rho) stencil = damp * ( 2.0 * u - damp * u.backward + dt**2 * rho / m * ulaplace) # 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 stencil -= wf_src # Rearrange expression expression = [Eq(u.forward, stencil)] # 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) expression += rec_term # Create operator and run if save: expression += eqsave # Free surface kwargs = dict() if free_surface is True: expression += freesurface(u, space_order//2, model.nbpml) # 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, expr=src * rho * dt**2 / m) expression += src_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') # Return data and wavefields if op_return is False: op() if save is True and tsub_factor > 1: if rec_coords is None: return usave else: return rec.data, usave else: if rec_coords is None: return u else: return rec.data, u # For optimal checkpointing, return operator only else: return op