Example #1
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)
Example #2
0
    def test_precomputed_interpolation_empty(self):
        shape = (101, 101)
        origin = (0, 0)

        grid = Grid(shape=shape, origin=origin)
        x, y = grid.dimensions
        #  because we interpolate across 2 neighbouring points in each dimension
        r = 2

        nt = 10

        m = TimeFunction(name="m",
                         grid=grid,
                         space_order=0,
                         save=nt,
                         time_order=0)
        for it in range(nt):
            m.data[it, :] = it

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

        eqn = sf.interpolate(m)
        op = Operator(eqn)

        sf.manual_scatter()
        op(time_m=0, time_M=9)
        sf.manual_gather()
Example #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
Example #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
Example #5
0
    def test_precomputed_interpolation(self):
        shape = (101, 101)
        points = [(0.05, 0.9), (0.01, 0.8), (0.07, 0.84)]
        origin = (0, 0)

        grid = Grid(shape=shape, origin=origin)
        x, y = grid.dimensions
        r = 2

        nt = 10

        m = TimeFunction(name="m",
                         grid=grid,
                         space_order=0,
                         save=nt,
                         time_order=0)
        for it in range(nt):
            m.data[it, :] = it

        gridpoints, coefficients = self._precompute_linear_interpolation(
            points, grid, origin)

        mat = scipy.sparse.eye(len(points), dtype=np.float32)

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

        sf.gridpoints.data[:] = gridpoints
        sf.interpolation_coefficients[x].data[:] = coefficients[:, 0, :]
        sf.interpolation_coefficients[y].data[:] = coefficients[:, 1, :]

        eqn = sf.interpolate(m)
        op = Operator(eqn)

        sf.manual_scatter()

        # args = op.arguments(time_m=0, time_M=9)
        op(time_m=0, time_M=9)

        sf.manual_gather()

        for it in range(nt):
            assert np.all(sf.data[it, :] == pytest.approx(it))
Example #6
0
    def test_precomputed2(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.eye(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.data[:] = 0.0

        step = [Eq(m.forward, m)]
        interp = sf.interpolate(m)
        op = Operator(step + interp)

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

        assert sf.data[0, 0] == 1.0
Example #7
0
    def test_empty_arrays(self):
        """
        MFE for issue #1641.
        """
        grid = Grid(shape=(4, 4), extent=(3.0, 3.0))

        f = TimeFunction(name='f', grid=grid, space_order=0)
        f.data[:] = 1.
        sf1 = SparseTimeFunction(name='sf1', grid=grid, npoint=0, nt=10)
        sf2 = SparseTimeFunction(name='sf2', grid=grid, npoint=0, nt=10)
        assert sf1.size == 0
        assert sf2.size == 0

        eqns = sf1.inject(field=f, expr=sf1 + sf2 + 1.)

        op = Operator(eqns)
        op.apply()
        assert np.all(f.data == 1.)

        # Again, but with a MatrixSparseTimeFunction
        mat = scipy.sparse.coo_matrix((0, 0), dtype=np.float32)
        sf = MatrixSparseTimeFunction(name="s",
                                      grid=grid,
                                      r=2,
                                      matrix=mat,
                                      nt=10)
        assert sf.size == 0

        eqns = sf.interpolate(f)

        op = Operator(eqns)

        sf.manual_scatter()
        op(time_m=0, time_M=9)
        sf.manual_gather()
        assert np.all(f.data == 1.)
Example #8
0
    def test_mpi(self):
        # Shape chosen to get a source in multiple ranks
        shape = (91, 91)
        grid = Grid(shape=shape)
        x, y = grid.dimensions
        #  because we interpolate across 2 neighbouring points in each dimension
        r = 2

        nt = 10

        # NOTE: halo on function (space_order//2?) must be at least >= r
        m = TimeFunction(name="m",
                         grid=grid,
                         space_order=4,
                         save=None,
                         time_order=1)

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

        # only rank 0 is allowed to have points
        if grid.distributor.myrank == 0:
            # A single dipole source - so two rows, one column
            matrix = scipy.sparse.coo_matrix(
                np.array([[1], [-1]], dtype=np.float32))
        else:
            matrix = scipy.sparse.coo_matrix((0, 0), dtype=np.float32)

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

        if grid.distributor.myrank == 0:
            # First component of the dipole at 40, 40
            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] = 50
            sf.gridpoints.data[1, 1] = 50
            sf.interpolation_coefficients[x].data[1, 0] = 2.0
            sf.interpolation_coefficients[x].data[1, 1] = 2.0
            sf.interpolation_coefficients[y].data[1, 0] = 2.0
            sf.interpolation_coefficients[y].data[1, 1] = 2.0

        op = Operator(sf.interpolate(m))
        sf.manual_scatter()
        args = op.arguments(time_m=0, time_M=9)
        print("rank %d: %s" % (grid.distributor.myrank, str(args)))
        op.apply(time_m=0, time_M=0)
        sf.manual_gather()

        for i in range(grid.distributor.nprocs):
            print("==== from rank %d" % i)
            if i == grid.distributor.myrank:
                print(repr(sf.data))
            grid.distributor.comm.Barrier()

        if grid.distributor.myrank == 0:
            assert sf.data[0,
                           0] == -3.0  # 1 * (1 * 1) * 1 + (-1) * (2 * 2) * 1
Example #9
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)