def test_precomputed_interpolation_time(): """ Test interpolation with PrecomputedSparseFunction which accepts precomputed values for interpolation coefficients, but this time with a TimeFunction """ shape = (101, 101) points = [(.05, .9), (.01, .8), (0.07, 0.84)] origin = (0, 0) grid = Grid(shape=shape, origin=origin) r = 2 # Constant for linear interpolation # because we interpolate across 2 neighbouring points in each dimension u = TimeFunction(name='u', grid=grid, space_order=0, save=5) for it in range(5): u.data[it, :] = it gridpoints, interpolation_coeffs = precompute_linear_interpolation(points, grid, origin) sf = PrecomputedSparseTimeFunction(name='s', grid=grid, r=r, npoint=len(points), nt=5, gridpoints=gridpoints, interpolation_coeffs=interpolation_coeffs) assert sf.data.shape == (5, 3) eqn = sf.interpolate(u) op = Operator(eqn) op(time_m=0, time_M=4) for it in range(5): assert np.allclose(sf.data[it, :], it)
def test_precomputed_interpolation_time(): """ Test interpolation with PrecomputedSparseFunction which accepts precomputed values for interpolation coefficients, but this time with a TimeFunction """ shape = (101, 101) points = [(.05, .9), (.01, .8), (0.07, 0.84)] origin = (0, 0) grid = Grid(shape=shape, origin=origin) r = 2 # Constant for linear interpolation # because we interpolate across 2 neighbouring points in each dimension u = TimeFunction(name='u', grid=grid, space_order=0, save=5) for it in range(5): u.data[it, :] = it gridpoints, interpolation_coeffs = precompute_linear_interpolation(points, grid, origin) sf = PrecomputedSparseTimeFunction(name='s', grid=grid, r=r, npoint=len(points), nt=5, gridpoints=gridpoints, interpolation_coeffs=interpolation_coeffs) assert sf.data.shape == (5, 3) eqn = sf.interpolate(u) op = Operator(eqn) op(time_m=0, time_M=4) for it in range(5): assert all(np.isclose(sf.data[it, :], it))
def run(r, srcpd, layout): initial_model_filename = "overthrust_3D_initial_model.h5" tn = 5 so = 6 dtype = np.float32 datakey = "m0" nbl = 40 dt = 1.75 time_axis = TimeAxis(start=0, stop=tn, step=dt) nt = time_axis.num model = overthrust_model_iso(initial_model_filename, datakey, so, nbl, dtype) shape = model.shape grid = model.grid origin = (0, 0, 0) spacing = model.spacing coeffs = kaiser(M=r, beta=6.31) # What we accepted as a parameter was sources per dimension. We are going to lay them out on a grid so square the number nsrc = srcpd * srcpd if layout == 'grid': src_coordinates = define_sources_grid(srcpd, model, r) elif layout == 'hemisphere': src_coordinates = define_sources_hemisphere(srcpd, model) else: print("Invalid layout: %s" % layout) return gridpoints = [ tuple((int(floor((point[i] - origin[i]) / grid.spacing[i])) - r / 2) for i in range(len(point))) for point in src_coordinates ] src = PrecomputedSparseTimeFunction(name="src", grid=grid, npoint=nsrc, r=r, gridpoints=gridpoints, interpolation_coeffs=coeffs, nt=nt) ricker = RickerSource(time_range=time_axis, grid=grid, name="ricker", f0=0.008) for p in range(nsrc): src.data[:, p] = ricker.wavelet m = model.m # Create symbols for forward wavefield, source and receivers u = TimeFunction(name='u', grid=grid, save=None, time_order=2, space_order=so) rec = Receiver(name='rec', grid=grid, time_range=time_axis, npoint=nsrc) s = model.grid.stepping_dim.spacing # Define PDE and update rule eq_time = solve(model.m * u.dt2 - u.laplace + model.damp * u.dt, u.forward) # Time-stepping stencil. eqns = [ Eq(u.forward, eq_time, subdomain=model.grid.subdomains['physdomain']) ] # Construct expression to inject source values src_term = src.inject(field=u.forward, expr=src * s**2 / m) # Create interpolation expression for receivers rec_term = rec.interpolate(expr=u) # Substitute spacing terms to reduce flops op = Operator(eqns + src_term + rec_term, subs=model.spacing_map, name='Forward') op.apply(dt=dt) print("u_norm", np.linalg.norm(u.data))