def forward(model, src_coords, rcv_coords, wavelet, space_order=8, save=False, q=None, return_op=False, freq_list=None, dft_sub=None, ws=None, t_sub=1, **kwargs): """ Low level propagator, to be used through `interface.py` Compute forward wavefield u = A(m)^{-1}*f and related quantities (u(xrcv)) """ # Number of time steps nt = as_tuple(q)[0].shape[0] if wavelet is None else wavelet.shape[0] # Setting forward wavefield u = wavefield(model, space_order, save=save, nt=nt, t_sub=t_sub) # Expression for saving wavefield if time subsampling is used u_save, eq_save = wavefield_subsampled(model, u, nt, t_sub) # Add extended source q = q or wf_as_src(u, w=0) q = extented_src(model, ws, wavelet, q=q) # Set up PDE expression and rearrange pde = wave_kernel(model, u, q=q) # Setup source and receiver geom_expr, _, rcv = src_rec(model, u, src_coords=src_coords, nt=nt, rec_coords=rcv_coords, wavelet=wavelet) # On-the-fly Fourier dft, dft_modes = otf_dft(u, freq_list, model.critical_dt, factor=dft_sub) # Create operator and run subs = model.spacing_map op = Operator(pde + dft + geom_expr + eq_save, subs=subs, name="forward" + name(model), opt=opt_op(model)) op.cfunction if return_op: return op, u, rcv summary = op() # Output return rcv, dft_modes or (u_save if t_sub > 1 else u), summary
def adjoint(model, y, src_coords, rcv_coords, space_order=8, q=0, dft_sub=None, save=False, ws=None, norm_v=False, w_fun=None, freq_list=None): """ Low level propagator, to be used through `interface.py` Compute adjoint wavefield v = adjoint(F(m))*y and related quantities (||v||_w, v(xsrc)) """ # Number of time steps nt = as_tuple(q)[0].shape[0] if y is None else y.shape[0] # Setting adjoint wavefield v = wavefield(model, space_order, save=save, nt=nt, fw=False) # Set up PDE expression and rearrange pde = wave_kernel(model, v, q=q, fw=False) # On-the-fly Fourier dft, dft_modes = otf_dft(v, freq_list, model.critical_dt, factor=dft_sub) # Setup source and receiver geom_expr, _, rcv = src_rec(model, v, src_coords=rcv_coords, nt=nt, rec_coords=src_coords, wavelet=y, fw=False) # Extended source wsrc, ws_expr = extended_src_weights(model, ws, v) # Wavefield norm nv_t, nv_s = ([], []) if norm_v: weights = weight_fun(w_fun, model, src_coords) norm_v, (nv_t, nv_s) = weighted_norm(v, weight=weights) # Create operator and run subs = model.spacing_map op = Operator(pde + ws_expr + nv_t + dft + geom_expr + nv_s, subs=subs, name="adjoint" + name(model), opt=opt_op(model)) op.cfunction # Run operator summary = op() # Output if wsrc: return wsrc, summary if norm_v: return rcv, dft_modes or v, norm_v.data[0], summary return rcv, v, summary
def born(model, src_coords, rcv_coords, wavelet, space_order=8, save=False, q=None, return_op=False, isic=False, freq_list=None, dft_sub=None, ws=None, t_sub=1, nlind=False): """ Low level propagator, to be used through `interface.py` Compute linearized wavefield U = J(m)* δ m and related quantities. """ nt = wavelet.shape[0] # Setting wavefield u = wavefield(model, space_order, save=save, nt=nt, t_sub=t_sub) ul = wavefield(model, space_order, name="l") # Expression for saving wavefield if time subsampling is used u_save, eq_save = wavefield_subsampled(model, u, nt, t_sub) # Extended source q = q or wf_as_src(u, w=0) q = extented_src(model, ws, wavelet, q=q) # Set up PDE expression and rearrange pde = wave_kernel(model, u, q=q) if model.dm == 0: pdel = [] else: pdel = wave_kernel(model, ul, q=lin_src(model, u, isic=isic)) # Setup source and receiver geom_expr, _, rcvnl = src_rec(model, u, rec_coords=rcv_coords if nlind else None, src_coords=src_coords, wavelet=wavelet) geom_exprl, _, rcvl = src_rec(model, ul, rec_coords=rcv_coords, nt=nt) # On-the-fly Fourier dft, dft_modes = otf_dft(u, freq_list, model.critical_dt, factor=dft_sub) # Create operator and run subs = model.spacing_map op = Operator(pde + geom_expr + geom_exprl + pdel + dft + eq_save, subs=subs, name="born" + name(model), opt=opt_op(model)) op.cfunction outrec = (rcvl, rcvnl) if nlind else rcvl if return_op: return op, u, outrec summary = op() # Output return outrec, dft_modes or (u_save if t_sub > 1 else u), summary