示例#1
0
def test_poisson_solver_1d():
    """ test the poisson solver on 1d grids """
    # solve Laplace's equation
    grid = UnitGrid([4])
    field = ScalarField(grid)
    res = field.solve_poisson([{"value": -1}, {"value": 3}])
    np.testing.assert_allclose(res.data, grid.axes_coords[0] - 1)

    res = field.solve_poisson([{"value": -1}, {"derivative": 1}])
    np.testing.assert_allclose(res.data, grid.axes_coords[0] - 1)

    # test Poisson equation with 2nd Order BC
    res = field.solve_poisson([{"value": -1}, "extrapolate"])

    # solve Poisson's equation
    grid = CartesianGrid([[0, 1]], 4)
    field = ScalarField(grid, data=1)

    res = field.copy()
    field.solve_poisson([{"value": 1}, {"derivative": 1}], out=res)
    xs = grid.axes_coords[0]
    np.testing.assert_allclose(res.data, 1 + 0.5 * xs**2, rtol=1e-2)

    # test inconsistent problem
    field.data = 1
    with pytest.raises(RuntimeError, match="Neumann"):
        field.solve_poisson({"derivative": 0})
示例#2
0
def test_scalars():
    """test some scalar fields"""
    grid = CartesianGrid([[0.1, 0.3], [-2, 3]], [3, 4])
    s1 = ScalarField(grid, np.full(grid.shape, 1))
    s2 = ScalarField(grid, np.full(grid.shape, 2))
    assert s1.average == pytest.approx(1)
    assert s1.magnitude == pytest.approx(1)

    s3 = s1 + s2
    assert s3.grid == grid
    np.testing.assert_allclose(s3.data, 3)
    s1 += s2
    np.testing.assert_allclose(s1.data, 3)

    s2 = FieldBase.from_state(s1.attributes, data=s1.data)
    assert s1 == s2
    assert s1.grid is s2.grid

    attrs = ScalarField.unserialize_attributes(s1.attributes_serialized)
    s2 = FieldBase.from_state(attrs, data=s1.data)
    assert s1 == s2
    assert s1.grid is not s2.grid

    # test options for plotting images
    if module_available("matplotlib"):
        s1.plot(transpose=True, colorbar=True)

    s3 = ScalarField(grid, s1)
    assert s1 is not s3
    assert s1 == s3
    assert s1.grid is s3.grid

    # multiplication with numpy arrays
    arr = np.random.randn(*grid.shape)
    np.testing.assert_allclose((arr * s1).data, (s1 * arr).data)
示例#3
0
def test_complex_methods():
    """test special methods for complex data type"""
    grid = UnitGrid([2, 2])
    f = ScalarField(grid, 1j)
    for backend in ["scipy", "numba"]:
        val = f.interpolate([1, 1], backend=backend)
        np.testing.assert_allclose(val, np.array([1j, 1j]))

    f = ScalarField(grid, 1 + 2j)
    np.testing.assert_allclose(f.project("x").data, np.full((2,), 2 + 4j))
    np.testing.assert_allclose(f.slice({"x": 1}).data, np.full((2,), 1 + 2j))
示例#4
0
def test_interpolation_singular():
    """ test interpolation on singular dimensions """
    grid = UnitGrid([1])
    field = ScalarField(grid, data=3)

    # test constant boundary conditions
    bc = [{"type": "value", "value": 1}, {"type": "value", "value": 5}]
    x = np.linspace(0, 1, 7).reshape((7, 1))
    y = field.interpolate(x, method="numba", bc=bc)
    np.testing.assert_allclose(y, 1 + 4 * x.ravel())

    # test derivative boundary conditions
    bc = [{
        "type": "derivative",
        "value": -2
    }, {
        "type": "derivative",
        "value": 2
    }]
    x = np.linspace(0, 1, 7).reshape((7, 1))
    y = field.interpolate(x, method="numba", bc=bc)
    np.testing.assert_allclose(y, 2 + 2 * x.ravel())

    # test boundary interpolation
    for upper in [True, False]:
        val = field.get_boundary_values(axis=0, upper=upper, bc=[{"value": 1}])
        assert val == pytest.approx(1)
示例#5
0
def test_interpolation_inhomogeneous_bc():
    """test field interpolation with inhomogeneous boundary condition"""
    sf = ScalarField(UnitGrid([3, 3], periodic=False))
    x = 1 + np.random.random()
    bc = ["natural", {"type": "value", "value": "x"}]
    v = sf.interpolate([x, 0], backend="numba", bc=bc)
    assert x == pytest.approx(v)
示例#6
0
def test_interpolation_singular():
    """test interpolation on singular dimensions"""
    grid = UnitGrid([1])
    field = ScalarField(grid, data=3)

    # test constant boundary conditions
    x = np.linspace(0, 1, 7).reshape((7, 1))
    y = field.interpolate(x, backend="numba")
    np.testing.assert_allclose(y, 3)
示例#7
0
def test_complex_dtype():
    """test the support of a complex data type"""
    grid = UnitGrid([2])
    f = ScalarField(grid, 1j)
    assert f.is_complex
    np.testing.assert_allclose(f.data, np.array([1j, 1j]))

    f = ScalarField(grid, 1)
    assert not f.is_complex
    with pytest.raises(np.core._exceptions.UFuncTypeError):
        f += 1j

    f = f + 1j
    assert f.is_complex
    np.testing.assert_allclose(f.data, np.full((2,), 1 + 1j))
    assert f.integral == pytest.approx(2 + 2j)
    assert f.average == pytest.approx(1 + 1j)
    np.testing.assert_allclose(f.to_scalar("abs").data, np.full((2,), np.sqrt(2)))
    assert f.magnitude == pytest.approx(np.sqrt(2))
示例#8
0
def test_corner_interpolation():
    """test whether the field can also be interpolated up to the corner of the grid"""
    grid = UnitGrid([1, 1], periodic=False)
    field = ScalarField(grid)
    field.set_ghost_cells({"value": 1})

    assert field.interpolate(np.array([0.5, 0.5])) == pytest.approx(0.0)
    assert field.interpolate(np.array([0.0, 0.5])) == pytest.approx(0.0)
    assert field.interpolate(np.array([0.5, 0.0])) == pytest.approx(0.0)
    assert field.interpolate(np.array([0.0, 0.0])) == pytest.approx(0.0)
示例#9
0
def test_boundary_interpolation_1d():
    """test boundary interpolation for 1d fields"""
    grid = UnitGrid([5])
    field = ScalarField(grid, np.arange(grid.shape[0]))

    # test boundary interpolation
    bndry_val = 0.25
    for bndry in grid._iter_boundaries():
        val = field.get_boundary_values(*bndry, bc={"value": bndry_val})
        np.testing.assert_allclose(val, bndry_val)
示例#10
0
def test_insert_polar():
    """test the `insert` method for polar systems"""
    grid = PolarSymGrid(3, 5)
    f = ScalarField(grid)
    g = f.copy()
    a = np.random.random()
    for r in np.linspace(0, 3, 8).reshape(8, 1):
        f.data = g.data = 0
        f.insert(r, a)
        assert f.integral == pytest.approx(a)
        grid.make_inserter_compiled()(g.data, r, a)
        np.testing.assert_array_almost_equal(f.data, g.data)
示例#11
0
def test_slice_positions():
    """test scalar slicing at standard positions"""
    grid = UnitGrid([3, 1])
    sf = ScalarField(grid, np.arange(3).reshape(3, 1))
    assert sf.slice({"x": "min"}).data == 0
    assert sf.slice({"x": "mid"}).data == 1
    assert sf.slice({"x": "max"}).data == 2

    with pytest.raises(ValueError):
        sf.slice({"x": "foo"})
    with pytest.raises(ValueError):
        sf.slice({"x": 0}, method="nonsense")
示例#12
0
def test_slice(example_grid_nd):
    """test scalar slicing"""
    sf = ScalarField(example_grid_nd, 0.5)
    p = example_grid_nd.get_random_point()
    for i in range(example_grid_nd.num_axes):
        sf_slc = sf.slice({example_grid_nd.axes[i]: p[i]})
        np.testing.assert_allclose(sf_slc.data, 0.5)
        assert sf_slc.grid.dim < example_grid_nd.dim
        assert sf_slc.grid.num_axes == example_grid_nd.num_axes - 1

    with pytest.raises(boundaries.DomainError):
        sf.slice({example_grid_nd.axes[0]: -10})
    with pytest.raises(ValueError):
        sf.slice({"q": 0})
示例#13
0
def test_interpolation_singular():
    """test interpolation on singular dimensions"""
    grid = UnitGrid([1])
    field = ScalarField(grid, data=3)

    # test constant boundary conditions
    x = np.linspace(0, 1, 7).reshape((7, 1))
    y = field.interpolate(x, backend="numba")
    np.testing.assert_allclose(y, 3)

    # # test boundary interpolation
    for upper in [True, False]:
        val = field.get_boundary_values(axis=0, upper=upper, bc=[{"value": 1}])
        assert val == pytest.approx(1)
示例#14
0
def test_interpolation_mutable():
    """test interpolation on mutable fields"""
    grid = UnitGrid([2], periodic=True)
    field = ScalarField(grid)

    for backend in ["numba", "scipy"]:
        field.data = 1
        np.testing.assert_allclose(field.interpolate([0.5], backend=backend), 1)
        field.data = 2
        np.testing.assert_allclose(field.interpolate([0.5], backend=backend), 2)

    # test overwriting field values
    data = np.full_like(field.data, 3)
    intp = field.make_interpolator(backend="numba")
    np.testing.assert_allclose(intp(np.array([0.5]), data), 3)
示例#15
0
def test_gradient():
    """test the gradient operator"""
    grid = CartesianGrid([[0, 2 * np.pi], [0, 2 * np.pi]], [16, 16], periodic=True)
    x, y = grid.cell_coords[..., 0], grid.cell_coords[..., 1]
    data = np.cos(x) + np.sin(y)

    s = ScalarField(grid, data)
    v = s.gradient("natural")
    assert v.data.shape == (2, 16, 16)
    np.testing.assert_allclose(v.data[0], -np.sin(x), rtol=0.1, atol=0.1)
    np.testing.assert_allclose(v.data[1], np.cos(y), rtol=0.1, atol=0.1)

    s.gradient("natural", out=v)
    assert v.data.shape == (2, 16, 16)
    np.testing.assert_allclose(v.data[0], -np.sin(x), rtol=0.1, atol=0.1)
    np.testing.assert_allclose(v.data[1], np.cos(y), rtol=0.1, atol=0.1)
示例#16
0
def test_boundary_interpolation_1d():
    """test boundary interpolation for 1d fields"""
    grid = UnitGrid([5])
    field = ScalarField(grid, np.arange(grid.shape[0]))

    # test boundary interpolation
    bndry_val = 0.25
    for bndry in grid._iter_boundaries():
        val = field.get_boundary_values(*bndry, bc={"value": bndry_val})
        np.testing.assert_allclose(val, bndry_val)

        # boundary conditions have already been enforced
        ev = field.make_get_boundary_values(*bndry)
        out = ev()
        np.testing.assert_allclose(out, bndry_val)
        ev(data_full=field._data_full, out=out)
        np.testing.assert_allclose(out, bndry_val)
示例#17
0
def test_poisson_solver_2d():
    """ test the poisson solver on 2d grids """
    grid = CartesianGrid([[0, 2 * np.pi]] * 2, 16)
    bcs = [{"value": "sin(y)"}, {"value": "sin(x)"}]

    # solve Laplace's equation
    field = ScalarField(grid)
    res = field.solve_poisson(bcs)
    xs = grid.cell_coords[..., 0]
    ys = grid.cell_coords[..., 1]

    # analytical solution was obtained with Mathematica
    expect = (np.cosh(np.pi - ys) * np.sin(xs) +
              np.cosh(np.pi - xs) * np.sin(ys)) / np.cosh(np.pi)
    np.testing.assert_allclose(res.data, expect, atol=1e-2, rtol=1e-2)

    # test more complex case for exceptions
    res = field.solve_poisson([{"value": "sin(y)"}, {"curvature": "sin(x)"}])
示例#18
0
def test_insert_scalar(example_grid):
    """test the `insert` method"""
    f = ScalarField(example_grid)
    a = np.random.random()

    c = tuple(example_grid.point_to_cell(example_grid.get_random_point()))
    p = example_grid.cell_to_point(c, cartesian=False)
    f.insert(p, a)
    assert f.data[c] == pytest.approx(a / example_grid.cell_volumes[c])

    f.insert(example_grid.get_random_point(cartesian=False), a)
    assert f.integral == pytest.approx(2 * a)

    f.data = 0  # reset
    insert = example_grid.make_inserter_compiled()
    c = tuple(example_grid.point_to_cell(example_grid.get_random_point()))
    p = example_grid.cell_to_point(c, cartesian=False)
    insert(f.data, p, a)
    assert f.data[c] == pytest.approx(a / example_grid.cell_volumes[c])

    insert(f.data, example_grid.get_random_point(cartesian=False), a)
    assert f.integral == pytest.approx(2 * a)
示例#19
0
def test_insert_scalar(grid):
    """test the `insert` method"""
    f = ScalarField(grid)
    a = np.random.random()

    c = tuple(grid.get_random_point(coords="cell"))
    p = grid.transform(c, "cell", "grid")
    f.insert(p, a)
    assert f.data[c] == pytest.approx(a / grid.cell_volumes[c])

    f.insert(grid.get_random_point(coords="grid"), a)
    assert f.integral == pytest.approx(2 * a)

    f.data = 0  # reset
    insert = grid.make_inserter_compiled()
    c = tuple(grid.get_random_point(coords="cell"))
    p = grid.transform(c, "cell", "grid")
    insert(f.data, p, a)
    assert f.data[c] == pytest.approx(a / grid.cell_volumes[c])

    insert(f.data, grid.get_random_point(coords="grid"), a)
    assert f.integral == pytest.approx(2 * a)
示例#20
0
def test_generic_derivatives(grid):
    """test generic derivatives operators"""
    sf = ScalarField.random_uniform(grid, rng=np.random.default_rng(0))
    sf_grad = sf.gradient("auto_periodic_neumann")
    sf_lap = ScalarField(grid)

    # iterate over all grid axes
    for axis_id, axis in enumerate(grid.axes):
        # test first derivatives
        sf_deriv = sf._apply_operator(f"d_d{axis}", bc="auto_periodic_neumann")
        assert isinstance(sf_deriv, ScalarField)
        np.testing.assert_allclose(sf_deriv.data, sf_grad.data[axis_id])

        # accumulate second derivatives for Laplacian
        sf_lap += sf._apply_operator(f"d2_d{axis}2",
                                     bc="auto_periodic_neumann")

    sf_laplace = sf.laplace("auto_periodic_neumann")
    if isinstance(grid, CartesianGrid):
        # Laplacian is the sum of second derivatives in Cartesian coordinates
        np.testing.assert_allclose(sf_lap.data, sf_laplace.data)
    else:
        # the two deviate in curvilinear coordinates
        assert not np.allclose(sf_lap.data, sf_laplace.data)
示例#21
0
def test_complex_operators():
    """test differential operators for complex data type"""
    f = ScalarField(UnitGrid([2, 2]), 1j)
    assert f.laplace("natural").magnitude == pytest.approx(0)
示例#22
0
def test_complex_plotting():
    """test plotting of complex fields"""
    for dim in (1, 2):
        f = ScalarField(UnitGrid([3] * dim), 1j)
        f.plot()