示例#1
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.)
示例#2
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
示例#3
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
示例#4
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)