示例#1
0
def test_interpolation_msf():
    grid = Grid(shape=(4, 4))

    r = 2  # Because we interpolate across 2 neighbouring points in each dimension
    nt = 10

    m0 = TimeFunction(name="m0",
                      grid=grid,
                      space_order=0,
                      save=nt,
                      time_order=0)
    m1 = TimeFunction(name="m1",
                      grid=grid,
                      space_order=0,
                      save=nt,
                      time_order=0)

    mat = scipy.sparse.coo_matrix((0, 0), dtype=np.float32)
    sf = MatrixSparseTimeFunction(name="s", grid=grid, r=r, matrix=mat, nt=nt)

    eqns = sf.inject(field=m0.forward, expr=sf.dt2)
    eqns += sf.inject(field=m1.forward, expr=sf.dt2)

    op0 = Operator(eqns)
    op1 = Operator(eqns, opt=('advanced', {'linearize': True}))

    assert 'm0L0' in str(op1)

    # There used to be a bug causing the jit compilation to fail because of
    # the writing to `const int` variables
    assert op0.cfunction
    assert op1.cfunction
示例#2
0
    def test_precomputed_subpoints_inject_dt2(self):
        shape = (101, 101)
        grid = Grid(shape=shape)
        x, y = grid.dimensions
        r = 2  # Constant for linear interpolation
        #  because we interpolate across 2 neighbouring points in each dimension

        nt = 10

        m = TimeFunction(name="m",
                         grid=grid,
                         space_order=0,
                         save=None,
                         time_order=1)

        m.data[:] = 0.0
        m.data[:, 40, 40] = 1.0

        matrix = scipy.sparse.coo_matrix(np.array([[1], [1]],
                                                  dtype=np.float32))

        sf = MatrixSparseTimeFunction(name="s",
                                      grid=grid,
                                      r=r,
                                      matrix=matrix,
                                      nt=nt,
                                      time_order=2)

        # Lookup the exact point
        sf.gridpoints.data[0, 0] = 40
        sf.gridpoints.data[0, 1] = 40
        sf.interpolation_coefficients[x].data[0, 0] = 1.0
        sf.interpolation_coefficients[x].data[0, 1] = 2.0
        sf.interpolation_coefficients[y].data[0, 0] = 1.0
        sf.interpolation_coefficients[y].data[0, 1] = 2.0
        sf.gridpoints.data[1, 0] = 39
        sf.gridpoints.data[1, 1] = 39
        sf.interpolation_coefficients[x].data[1, 0] = 1.0
        sf.interpolation_coefficients[x].data[1, 1] = 2.0
        sf.interpolation_coefficients[y].data[1, 0] = 1.0
        sf.interpolation_coefficients[y].data[1, 1] = 2.0

        # Single timestep, -0.5*1e-6, so that with dt=0.001, the .dt2 == 1 at t=1
        sf.data[1, 0] = -5e-7

        step = [Eq(m.forward, m)]
        inject = sf.inject(field=m.forward, expr=sf.dt2)
        op = Operator(step + inject)

        sf.manual_scatter()
        op(time_m=1, time_M=1, dt=0.001)
        sf.manual_gather()

        assert m.data[0, 40, 40] == pytest.approx(6.0)  # 1 + 1 + 4
        assert m.data[0, 40, 41] == pytest.approx(2.0)
        assert m.data[0, 41, 40] == pytest.approx(2.0)
        assert m.data[0, 41, 41] == pytest.approx(4.0)
        assert m.data[0, 39, 39] == pytest.approx(1.0)
        assert m.data[0, 39, 40] == pytest.approx(2.0)
        assert m.data[0, 40, 39] == pytest.approx(2.0)
示例#3
0
def test_msf_interpolate():
    """ Test interpolation with MatrixSparseTimeFunction 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)

    matrix = scipy.sparse.eye(len(points))

    sf = MatrixSparseTimeFunction(
        name='s', grid=grid, r=r, matrix=matrix, nt=5
    )

    sf.gridpoints.data[:] = gridpoints
    sf.coefficients_x.data[:] = interpolation_coeffs[:, 0, :]
    sf.coefficients_y.data[:] = interpolation_coeffs[:, 0, :]

    assert sf.data.shape == (5, 3)

    eqn = sf.interpolate(u)
    op = Operator(eqn)
    print(op)

    sf.manual_scatter()
    op(time_m=0, time_M=4)
    sf.manual_gather()

    for it in range(5):
        assert np.allclose(sf.data[it, :], it)

    # Now test injection
    u.data[:] = 0

    eqn_inject = sf.inject(field=u, expr=sf)
    op2 = Operator(eqn_inject)
    print(op2)
    op2(time_m=0, time_M=4)

    # There should be 4 points touched for each source point
    # (5, 90), (1, 80), (7, 84) and x+1, y+1 for each
    nzt, nzx, nzy = np.nonzero(u.data)
    assert np.all(np.unique(nzx) == np.array([1, 2, 5, 6, 7, 8]))
    assert np.all(np.unique(nzy) == np.array([80, 81, 84, 85, 90, 91]))
    assert np.all(np.unique(nzt) == np.array([1, 2, 3, 4]))
    # 12 points x 4 timesteps
    assert nzt.size == 48
示例#4
0
    def test_precomputed_subpoints_inject(self):
        shape = (101, 101)
        grid = Grid(shape=shape)
        x, y = grid.dimensions
        r = 2  # Constant for linear interpolation
        #  because we interpolate across 2 neighbouring points in each dimension

        nt = 10

        m = TimeFunction(name="m",
                         grid=grid,
                         space_order=0,
                         save=None,
                         time_order=1)

        m.data[:] = 0.0
        m.data[:, 40, 40] = 1.0

        # Single two-component source with coefficients both +1
        matrix = scipy.sparse.coo_matrix(np.array([[1], [1]],
                                                  dtype=np.float32))

        sf = MatrixSparseTimeFunction(name="s",
                                      grid=grid,
                                      r=r,
                                      matrix=matrix,
                                      nt=nt)

        # Lookup the exact point
        sf.gridpoints.data[0, 0] = 40
        sf.gridpoints.data[0, 1] = 40
        sf.interpolation_coefficients[x].data[0, 0] = 1.0
        sf.interpolation_coefficients[x].data[0, 1] = 2.0
        sf.interpolation_coefficients[y].data[0, 0] = 1.0
        sf.interpolation_coefficients[y].data[0, 1] = 2.0
        sf.gridpoints.data[1, 0] = 39
        sf.gridpoints.data[1, 1] = 39
        sf.interpolation_coefficients[x].data[1, 0] = 1.0
        sf.interpolation_coefficients[x].data[1, 1] = 2.0
        sf.interpolation_coefficients[y].data[1, 0] = 1.0
        sf.interpolation_coefficients[y].data[1, 1] = 2.0
        sf.data[0, 0] = 1.0

        step = [Eq(m.forward, m)]
        inject = sf.inject(field=m.forward, expr=sf)
        op = Operator(step + inject)

        sf.manual_scatter()
        op(time_m=0, time_M=0)
        sf.manual_gather()

        assert m.data[1, 40, 40] == 6.0  # 1 + 1 + 4
        assert m.data[1, 40, 41] == 2.0
        assert m.data[1, 41, 40] == 2.0
        assert m.data[1, 41, 41] == 4.0
        assert m.data[1, 39, 39] == 1.0
        assert m.data[1, 39, 40] == 2.0
        assert m.data[1, 40, 39] == 2.0
示例#5
0
    def test_precomputed_subpoints_inject(self, rxy, par_dim_index):
        shape = (101, 101)
        grid = Grid(shape=shape)
        x, y = grid.dimensions

        if isinstance(rxy, tuple):
            r = {grid.dimensions[0]: rxy[0], grid.dimensions[1]: rxy[1]}
        else:
            r = rxy

        par_dim = grid.dimensions[par_dim_index]

        nt = 10

        m = TimeFunction(name="m",
                         grid=grid,
                         space_order=0,
                         save=None,
                         time_order=1)

        # Put some data in there to ensure it acts additively
        m.data[:] = 0.0
        m.data[:, 40, 40] = 1.0

        # Single two-component source with coefficients both +1
        matrix = scipy.sparse.coo_matrix(np.array([[1], [1]],
                                                  dtype=np.float32))
        sf = MatrixSparseTimeFunction(name="s",
                                      grid=grid,
                                      r=r,
                                      par_dim=par_dim,
                                      matrix=matrix,
                                      nt=nt)

        coeff_size_x = sf.interpolation_coefficients[x].data.shape[1]
        coeff_size_y = sf.interpolation_coefficients[y].data.shape[1]

        sf.gridpoints.data[0, 0] = 40
        sf.gridpoints.data[0, 1] = 40
        sf.gridpoints.data[1, 0] = 39
        sf.gridpoints.data[1, 1] = 39
        sf.interpolation_coefficients[x].data[
            0, :] = 1.0 + np.arange(coeff_size_x)
        sf.interpolation_coefficients[y].data[
            0, :] = 1.0 + np.arange(coeff_size_y)
        sf.interpolation_coefficients[x].data[
            1, :] = 1.0 + np.arange(coeff_size_x)
        sf.interpolation_coefficients[y].data[
            1, :] = 1.0 + np.arange(coeff_size_y)
        sf.data[0, 0] = 1.0

        step = [Eq(m.forward, m)]
        inject = sf.inject(field=m.forward, expr=sf)
        op = Operator(step + inject)

        sf.manual_scatter()
        op(time_m=0, time_M=0)
        sf.manual_gather()

        check_coeffs = self._pure_python_coeffs(sf)
        expected_data1 = (
            m.data[0] +
            np.tensordot(np.array(sf.data[0, :]), check_coeffs, axes=1))

        assert np.all(m.data[1] == expected_data1)