From 6504a79584406e9ccc1d074cf0b7249c680f04c8 Mon Sep 17 00:00:00 2001 From: David Zwicker Date: Sat, 23 Sep 2023 17:48:53 +0200 Subject: [PATCH] Control seed of random number generator in test --- tests/fields/fixtures/fields.py | 5 +- tests/fields/test_field_collections.py | 38 ++--- tests/fields/test_generic_fields.py | 148 ++++++++++-------- tests/fields/test_scalar_fields.py | 94 +++++------ tests/fields/test_tensorial_fields.py | 28 ++-- tests/fields/test_vectorial_fields.py | 24 +-- .../grids/boundaries/test_axes_boundaries.py | 8 +- .../grids/boundaries/test_local_boundaries.py | 12 +- .../operators/test_cartesian_operators.py | 95 +++++------ .../operators/test_cylindrical_operators.py | 12 +- tests/grids/operators/test_polar_operators.py | 16 +- .../operators/test_spherical_operators.py | 16 +- tests/grids/test_cartesian_grids.py | 59 +++---- tests/grids/test_cylindrical_grids.py | 8 +- tests/grids/test_generic_grids.py | 16 +- tests/grids/test_grid_mesh.py | 26 ++- tests/grids/test_spherical_grids.py | 32 ++-- tests/pdes/test_diffusion_pdes.py | 24 +-- tests/pdes/test_generic_pdes.py | 8 +- tests/pdes/test_pde_class.py | 66 ++++---- tests/pdes/test_wave_pdes.py | 4 +- tests/solvers/test_explicit_mpi_solvers.py | 8 +- tests/solvers/test_explicit_solvers.py | 12 +- tests/solvers/test_generic_solvers.py | 8 +- tests/solvers/test_scipy_solvers.py | 4 +- tests/storage/test_file_storages.py | 10 +- tests/storage/test_generic_storages.py | 30 ++-- tests/storage/test_memory_storages.py | 4 +- tests/test_integration.py | 8 +- tests/tools/test_cuboid.py | 12 +- tests/tools/test_expressions.py | 8 +- tests/tools/test_math.py | 11 +- tests/tools/test_plotting_tools.py | 5 +- tests/tools/test_spectral.py | 12 +- tests/trackers/test_trackers.py | 38 ++--- tests/visualization/test_movies.py | 5 +- tests/visualization/test_plotting.py | 13 +- 37 files changed, 468 insertions(+), 459 deletions(-) diff --git a/tests/fields/fixtures/fields.py b/tests/fields/fixtures/fields.py index f4daee56..5a58a5c8 100644 --- a/tests/fields/fixtures/fields.py +++ b/tests/fields/fixtures/fields.py @@ -25,6 +25,7 @@ def iter_grids(): def get_cartesian_grid(dim=2, periodic=True): """return a random Cartesian grid of given dimension""" - bounds = [[0, 1 + np.random.random()] for _ in range(dim)] - shape = np.random.randint(32, 64, size=dim) + rng = np.random.default_rng(0) + bounds = [[0, 1 + rng.random()] for _ in range(dim)] + shape = rng.integers(32, 64, size=dim) return CartesianGrid(bounds, shape, periodic=periodic) diff --git a/tests/fields/test_field_collections.py b/tests/fields/test_field_collections.py index df22b3cf..11f65e51 100644 --- a/tests/fields/test_field_collections.py +++ b/tests/fields/test_field_collections.py @@ -12,10 +12,10 @@ @pytest.mark.parametrize("grid", iter_grids()) -def test_shapes_nfields(grid): +def test_shapes_nfields(grid, rng): """test single component field""" for num in [1, 3]: - fields = [ScalarField.random_uniform(grid) for _ in range(num)] + fields = [ScalarField.random_uniform(grid, rng=rng) for _ in range(num)] field = FieldCollection(fields) data_shape = (num,) + grid.shape np.testing.assert_equal(field.data.shape, data_shape) @@ -27,12 +27,12 @@ def test_shapes_nfields(grid): assert field.grid == field_c.grid -def test_collections(): +def test_collections(rng): """test field collections""" grid = UnitGrid([3, 4]) - sf = ScalarField.random_uniform(grid, label="sf") - vf = VectorField.random_uniform(grid, label="vf") - tf = Tensor2Field.random_uniform(grid, label="tf") + sf = ScalarField.random_uniform(grid, label="sf", rng=rng) + vf = VectorField.random_uniform(grid, label="vf", rng=rng) + tf = Tensor2Field.random_uniform(grid, label="tf", rng=rng) fields = FieldCollection([sf, vf, tf]) assert fields.data.shape == (7, 3, 4) assert isinstance(str(fields), str) @@ -176,14 +176,14 @@ def test_collections_operators(): np.testing.assert_allclose(fields.data, 4) -def test_smoothing_collection(): +def test_smoothing_collection(rng): """test smoothing of a FieldCollection""" grid = UnitGrid([3, 4], periodic=[True, False]) - sf = ScalarField.random_uniform(grid) - vf = VectorField.random_uniform(grid) - tf = Tensor2Field.random_uniform(grid) + sf = ScalarField.random_uniform(grid, rng=rng) + vf = VectorField.random_uniform(grid, rng=rng) + tf = Tensor2Field.random_uniform(grid, rng=rng) fields = FieldCollection([sf, vf, tf]) - sgm = 0.5 + np.random.random() + sgm = 0.5 + rng.random() out = fields.smooth(sigma=sgm) for i in range(3): @@ -225,11 +225,11 @@ def test_from_scalar_expressions(): @skipUnlessModule("napari") @pytest.mark.interactive -def test_interactive_collection_plotting(): +def test_interactive_collection_plotting(rng): """test the interactive plotting""" grid = UnitGrid([3, 3]) - sf = ScalarField.random_uniform(grid, 0.1, 0.9) - vf = VectorField.random_uniform(grid, 0.1, 0.9) + sf = ScalarField.random_uniform(grid, 0.1, 0.9, rng=rng) + vf = VectorField.random_uniform(grid, 0.1, 0.9, rng=rng) field = FieldCollection([sf, vf]) field.plot_interactive(viewer_args={"show": False, "close": True}) @@ -306,11 +306,11 @@ def test_collection_plotting(): fc.plot(arrangement="vertical") -def test_from_data(): +def test_from_data(rng): """test the `from_data` method""" grid = UnitGrid([3, 5]) - s = ScalarField.random_uniform(grid, label="s1") - v = VectorField.random_uniform(grid, label="v2") + s = ScalarField.random_uniform(grid, label="s1", rng=rng) + v = VectorField.random_uniform(grid, label="v2", rng=rng) f1 = FieldCollection([s, v]) f2 = FieldCollection.from_data( @@ -334,11 +334,11 @@ def test_from_data(): np.testing.assert_allclose(f1.data, f2.data) -def test_collection_apply(): +def test_collection_apply(rng): """test the `apply` method""" grid = UnitGrid([3, 5]) s = ScalarField(grid, 2, label="s1") - v = VectorField.random_uniform(grid, label="v2") + v = VectorField.random_uniform(grid, label="v2", rng=rng) f1 = FieldCollection([s, v]) np.testing.assert_allclose(f1.apply("s1 * v2").data, v.data * 2) diff --git a/tests/fields/test_generic_fields.py b/tests/fields/test_generic_fields.py index 3ac5c630..2f3d669f 100644 --- a/tests/fields/test_generic_fields.py +++ b/tests/fields/test_generic_fields.py @@ -40,17 +40,17 @@ def test_set_label(field_class): @pytest.mark.parametrize("grid", iter_grids()) @pytest.mark.parametrize("field_class", [ScalarField, Tensor2Field]) -def test_interpolation_natural(grid, field_class): +def test_interpolation_natural(grid, field_class, rng): """test some interpolation for natural boundary conditions""" msg = f"grid={grid}, field={field_class}" - f = field_class.random_uniform(grid) + f = field_class.random_uniform(grid, rng=rng) def get_point(): if isinstance(grid, CartesianGrid): - return grid.get_random_point(boundary_distance=0.5, coords="grid") + return grid.get_random_point(boundary_distance=0.5, coords="grid", rng=rng) else: return grid.get_random_point( - boundary_distance=1, avoid_center=True, coords="grid" + boundary_distance=1, avoid_center=True, coords="grid", rng=rng ) # interpolate at cell center @@ -62,9 +62,9 @@ def get_point(): @pytest.mark.parametrize("num", [1, 3]) @pytest.mark.parametrize("grid", iter_grids()) -def test_shapes_nfields(num, grid): +def test_shapes_nfields(num, grid, rng): """test single component field""" - fields = [ScalarField.random_uniform(grid) for _ in range(num)] + fields = [ScalarField.random_uniform(grid, rng=rng) for _ in range(num)] field = FieldCollection(fields) data_shape = (num,) + grid.shape np.testing.assert_equal(field.data.shape, data_shape) @@ -132,11 +132,11 @@ def test_arithmetics(field_class): np.testing.assert_allclose(f1_out.data, 8) -def test_scalar_arithmetics(): +def test_scalar_arithmetics(rng): """test simple arithmetics involving scalar fields""" grid = UnitGrid([3, 4]) s = ScalarField(grid, data=2) - v = VectorField.random_uniform(grid) + v = VectorField.random_uniform(grid, rng=rng) for f in [v, FieldCollection([v])]: f.data = s @@ -201,11 +201,11 @@ def test_data_managment(field_class): @pytest.mark.parametrize("field_class", [ScalarField, VectorField, Tensor2Field]) -def test_complex_fields(field_class): +def test_complex_fields(field_class, rng): """test operations on complex fields""" grid = UnitGrid([3]) - field = field_class.random_uniform(grid, 0, 1 + 1j) + field = field_class.random_uniform(grid, 0, 1 + 1j, rng=rng) assert field.is_complex assert field.dtype == np.dtype("complex") @@ -215,12 +215,12 @@ def test_complex_fields(field_class): @skipUnlessModule("h5py") -def test_hdf_input_output(tmp_path): +def test_hdf_input_output(tmp_path, rng): """test writing and reading files""" grid = UnitGrid([4, 4]) - s = ScalarField.random_uniform(grid, label="scalar") - v = VectorField.random_uniform(grid, label="vector") - t = Tensor2Field.random_uniform(grid, label="tensor") + s = ScalarField.random_uniform(grid, label="scalar", rng=rng) + v = VectorField.random_uniform(grid, label="vector", rng=rng) + t = Tensor2Field.random_uniform(grid, label="tensor", rng=rng) col = FieldCollection([s, v, t], label="collection") path = tmp_path / "test_hdf_input_output.hdf5" @@ -233,14 +233,14 @@ def test_hdf_input_output(tmp_path): assert isinstance(repr(f), str) -def test_writing_images(tmp_path): +def test_writing_images(tmp_path, rng): """test writing and reading files""" from matplotlib.pyplot import imread grid = UnitGrid([4, 4]) - s = ScalarField.random_uniform(grid, label="scalar") - v = VectorField.random_uniform(grid, label="vector") - t = Tensor2Field.random_uniform(grid, label="tensor") + s = ScalarField.random_uniform(grid, label="scalar", rng=rng) + v = VectorField.random_uniform(grid, label="vector", rng=rng) + t = Tensor2Field.random_uniform(grid, label="tensor", rng=rng) path = tmp_path / "test_writing_images.png" for f in [s, v, t]: @@ -274,10 +274,10 @@ def test_interpolation_to_grid_fields(ndim): @pytest.mark.parametrize("field_cls", [ScalarField, VectorField, Tensor2Field]) -def test_interpolation_values(field_cls): +def test_interpolation_values(field_cls, rng): """test whether data is interpolated correctly for different fields""" grid = UnitGrid([3, 4]) - f = field_cls.random_uniform(grid) + f = field_cls.random_uniform(grid, rng=rng) f.set_ghost_cells("auto_periodic_neumann") intp = f.make_interpolator() @@ -365,10 +365,10 @@ def test_get_cartesian_grid(grid): @pytest.mark.parametrize("grid", iter_grids()) -def test_simple_plotting(grid): +def test_simple_plotting(grid, rng): """test simple plotting of various fields on various grids""" - vf = VectorField.random_uniform(grid) - tf = Tensor2Field.random_uniform(grid) + vf = VectorField.random_uniform(grid, rng=rng) + tf = Tensor2Field.random_uniform(grid, rng=rng) sf = tf[0, 0] # test extraction of fields fc = FieldCollection([sf, vf]) for f in [sf, vf, tf, fc]: @@ -382,12 +382,12 @@ def test_simple_plotting(grid): @pytest.mark.parametrize("field_cls", [ScalarField, VectorField, Tensor2Field]) -def test_random_uniform(field_cls): +def test_random_uniform(field_cls, rng): """test whether random uniform fields behave correctly""" grid = UnitGrid([256, 256]) - a = np.random.random() - b = 2 + np.random.random() - f = field_cls.random_uniform(grid, a, b) + a = rng.random() + b = 2 + rng.random() + f = field_cls.random_uniform(grid, a, b, rng=rng) assert np.mean(f.average) == pytest.approx((a + b) / 2, rel=0.02) assert np.std(f.data) == pytest.approx(0.288675 * (b - a), rel=0.1) @@ -395,61 +395,73 @@ def test_random_uniform(field_cls): np.testing.assert_allclose(f.imag.data, 0) -def test_random_uniform_types(): +def test_random_uniform_types(rng): """test whether random uniform fields behave correctly for different types""" grid = UnitGrid([8]) for dtype in [bool, int, float, complex]: - field = VectorField.random_uniform(grid, dtype=dtype) + field = VectorField.random_uniform(grid, dtype=dtype, rng=rng) assert field.dtype == np.dtype(dtype) assert isinstance(field.data.flat[0].item(), dtype) - assert ScalarField.random_uniform(grid, 0, 1).dtype == np.dtype(float) - assert ScalarField.random_uniform(grid, vmin=0 + 0j).dtype == np.dtype(complex) - assert ScalarField.random_uniform(grid, vmax=1 + 0j).dtype == np.dtype(complex) - assert ScalarField.random_uniform(grid, 0 + 0j, 1 + 0j).dtype == np.dtype(complex) + assert ScalarField.random_uniform(grid, 0, 1, rng=rng).dtype == np.dtype(float) + assert ScalarField.random_uniform(grid, vmin=0 + 0j, rng=rng).dtype == np.dtype( + complex + ) + assert ScalarField.random_uniform(grid, vmax=1 + 0j, rng=rng).dtype == np.dtype( + complex + ) + assert ScalarField.random_uniform(grid, 0 + 0j, 1 + 0j, rng=rng).dtype == np.dtype( + complex + ) @pytest.mark.parametrize("field_cls", [ScalarField, VectorField, Tensor2Field]) -def test_random_normal(field_cls): +def test_random_normal(field_cls, rng): """test whether random normal fields behave correctly""" grid = UnitGrid([256, 256]) - m = np.random.random() - s = 1 + np.random.random() + m = rng.random() + s = 1 + rng.random() for scaling in ["none", "physical"]: - f = field_cls.random_normal(grid, mean=m, std=s, scaling=scaling) + f = field_cls.random_normal(grid, mean=m, std=s, scaling=scaling, rng=rng) assert np.mean(f.average) == pytest.approx(m, rel=0.1, abs=0.1) assert np.std(f.data) == pytest.approx(s, rel=0.1, abs=0.1) -def test_random_normal_types(): +def test_random_normal_types(rng): """test whether random normal fields behave correctly for different types""" grid = UnitGrid([8]) for dtype in [bool, int, float, complex]: - field = VectorField.random_normal(grid, dtype=dtype) + field = VectorField.random_normal(grid, dtype=dtype, rng=rng) assert field.dtype == np.dtype(dtype) assert isinstance(field.data.flat[0].item(), dtype) - assert ScalarField.random_normal(grid, 0, 1).dtype == np.dtype(float) - assert ScalarField.random_normal(grid, mean=0 + 0j).dtype == np.dtype(complex) - assert ScalarField.random_normal(grid, std=1 + 0j).dtype == np.dtype(complex) - assert ScalarField.random_normal(grid, 0 + 0j, 1 + 0j).dtype == np.dtype(complex) - - m = complex(np.random.random(), np.random.random()) - s = complex(1 + np.random.random(), 1 + np.random.random()) + assert ScalarField.random_normal(grid, 0, 1, rng=rng).dtype == np.dtype(float) + assert ScalarField.random_normal(grid, mean=0 + 0j, rng=rng).dtype == np.dtype( + complex + ) + assert ScalarField.random_normal(grid, std=1 + 0j, rng=rng).dtype == np.dtype( + complex + ) + assert ScalarField.random_normal(grid, 0 + 0j, 1 + 0j, rng=rng).dtype == np.dtype( + complex + ) + + m = complex(rng.random(), rng.random()) + s = complex(1 + rng.random(), 1 + rng.random()) grid = UnitGrid([256, 256]) - field = field.random_normal(grid, m, s) + field = field.random_normal(grid, m, s, rng=rng) assert np.mean(field.average) == pytest.approx(m, rel=0.1, abs=0.1) assert np.std(field.data.real) == pytest.approx(s.real, rel=0.1, abs=0.1) assert np.std(field.data.imag) == pytest.approx(s.imag, rel=0.1, abs=0.1) @pytest.mark.parametrize("field_cls", [ScalarField, VectorField, Tensor2Field]) -def test_random_colored(field_cls): +def test_random_colored(field_cls, rng): """test whether random colored fields behave correctly""" grid = UnitGrid([128, 128]) - exponent = np.random.uniform(-4, 4) - scale = 1 + np.random.random() - f = field_cls.random_colored(grid, exponent=exponent, scale=scale) + exponent = rng.uniform(-4, 4) + scale = 1 + rng.random() + f = field_cls.random_colored(grid, exponent=exponent, scale=scale, rng=rng) assert np.allclose(f.average, 0) @@ -463,36 +475,36 @@ def test_random_rng(): ScalarField.random_normal, ScalarField.random_uniform, ]: - f1 = create_random_field(grid, rng=np.random.default_rng(1)) - f2 = create_random_field(grid, rng=np.random.default_rng(1)) + f1 = create_random_field(grid, rng=np.random.default_rng(0)) + f2 = create_random_field(grid, rng=np.random.default_rng(0)) np.testing.assert_allclose(f1.data, f2.data) @pytest.mark.parametrize("dim", [1, 2]) @pytest.mark.parametrize("size", [256, 512]) -def test_fluctuations(dim, size): +def test_fluctuations(dim, size, rng): """test the scaling of fluctuations""" if dim == 1: size **= 2 grid = CartesianGrid([[0, 1]] * dim, [size] * dim) - std = 1 + np.random.random() + std = 1 + rng.random() for field_cls in [ScalarField, VectorField, Tensor2Field]: s = field_cls.random_normal( - grid, mean=np.random.random(), std=std, scaling="physical" + grid, mean=rng.random(), std=std, scaling="physical", rng=rng ) expect = np.full([dim] * field_cls.rank, std) np.testing.assert_allclose(s.fluctuations, expect, rtol=0.1) -def test_smoothing(): +def test_smoothing(rng): """test smoothing on different grids""" for grid in [ CartesianGrid([[-2, 3]], 4), UnitGrid(7, periodic=False), UnitGrid(7, periodic=True), ]: - f1 = ScalarField.random_uniform(grid) - sigma = 0.5 + np.random.random() + f1 = ScalarField.random_uniform(grid, rng=rng) + sigma = 0.5 + rng.random() # this assumes that the grid periodicity is the same for all axes mode = "wrap" if grid.periodic[0] else "reflect" @@ -507,12 +519,12 @@ def test_smoothing(): np.testing.assert_allclose(out.data, expected) # test one simple higher order smoothing - tf = Tensor2Field.random_uniform(grid) + tf = Tensor2Field.random_uniform(grid, rng=rng) assert tf.data.shape == tf.smooth(1).data.shape # test in-place smoothing g = UnitGrid([8, 8]) - f1 = ScalarField.random_normal(g) + f1 = ScalarField.random_normal(g, rng=rng) f2 = f1.smooth(3) f1.smooth(3, out=f1) np.testing.assert_allclose(f1.data, f2.data) @@ -534,10 +546,10 @@ def test_vector_from_scalars(): @pytest.mark.parametrize( "grid", [UnitGrid([3, 2]), UnitGrid([3]), CylindricalSymGrid(1, (0, 2), 3)] ) -def test_dot_product(grid): +def test_dot_product(grid, rng): """test dot products between vectors and tensors""" - vf = VectorField.random_normal(grid) - tf = Tensor2Field.random_normal(grid) + vf = VectorField.random_normal(grid, rng=rng) + tf = Tensor2Field.random_normal(grid, rng=rng) dot = vf.make_dot_operator() expected = np.einsum("i...,i...->...", vf.data, vf.data) @@ -557,7 +569,7 @@ def test_dot_product(grid): np.testing.assert_allclose(dot(tf.data, tf.data), expected) # test non-sensical dot product - sf = ScalarField.random_normal(grid) + sf = ScalarField.random_normal(grid, rng=rng) # vector dot with pytest.raises(TypeError): vf @ sf @@ -574,10 +586,10 @@ def test_dot_product(grid): @pytest.mark.parametrize("grid", iter_grids()) -def test_complex_operator(grid): +def test_complex_operator(grid, rng): """test using a complex operator on grid""" - r = ScalarField.random_normal(grid) - i = ScalarField.random_normal(grid) + r = ScalarField.random_normal(grid, rng=rng) + i = ScalarField.random_normal(grid, rng=rng) c = r + 1j * i assert c.is_complex assert np.iscomplexobj(c) diff --git a/tests/fields/test_scalar_fields.py b/tests/fields/test_scalar_fields.py index f9e76790..9f4560e0 100644 --- a/tests/fields/test_scalar_fields.py +++ b/tests/fields/test_scalar_fields.py @@ -47,9 +47,9 @@ def test_interpolation_edge(): @pytest.mark.parametrize("grid", iter_grids()) -def test_simple_shapes(grid): +def test_simple_shapes(grid, rng): """test simple scalar fields""" - pf = ScalarField.random_uniform(grid) + pf = ScalarField.random_uniform(grid, rng=rng) np.testing.assert_equal(pf.data.shape, grid.shape) pf_lap = pf.laplace("auto_periodic_neumann") np.testing.assert_equal(pf_lap.data.shape, grid.shape) @@ -64,7 +64,7 @@ def test_simple_shapes(grid): pf.plot() # simply test whether this does not cause errors -def test_scalars(): +def test_scalars(rng): """test some scalar fields""" grid = CartesianGrid([[0.1, 0.3], [-2, 3]], [3, 4]) s1 = ScalarField(grid, np.full(grid.shape, 1)) @@ -97,14 +97,14 @@ def test_scalars(): assert s1.grid is s3.grid # multiplication with numpy arrays - arr = np.random.randn(*grid.shape) + arr = rng.normal(size=grid.shape) np.testing.assert_allclose((arr * s1).data, (s1 * arr).data) -def test_laplacian(): +def test_laplacian(rng): """test the gradient operator""" grid = CartesianGrid([[0, 2 * np.pi], [0, 2 * np.pi]], [16, 16], periodic=True) - s = ScalarField.random_harmonic(grid, axis_combination=np.add, modes=1) + s = ScalarField.random_harmonic(grid, axis_combination=np.add, modes=1, rng=rng) s_lap = s.laplace("auto_periodic_neumann") assert s_lap.data.shape == (16, 16) @@ -134,9 +134,9 @@ def test_gradient(): @pytest.mark.parametrize("grid", iter_grids()) -def test_interpolation_to_grid(grid): +def test_interpolation_to_grid(grid, rng): """test whether data is interpolated correctly for different grids""" - sf = ScalarField.random_uniform(grid) + sf = ScalarField.random_uniform(grid, rng=rng) sf2 = sf.interpolate_to_grid(grid) np.testing.assert_allclose(sf.data, sf2.data, rtol=1e-6) @@ -151,12 +151,12 @@ def test_interpolation_bcs(): @pytest.mark.parametrize("grid", iter_grids()) @pytest.mark.parametrize("compiled", [True, False]) -def test_insert_scalar(grid, compiled): +def test_insert_scalar(grid, compiled, rng): """test the `insert` method""" f = ScalarField(grid) - a = np.random.random() + a = rng.random() - c = grid.get_random_point(coords="cell").astype(int) # pick a random cell + c = grid.get_random_point(coords="cell", rng=rng).astype(int) # pick a random cell p = grid.transform(c + 0.5, "cell", "grid") # point at cell center if compiled: insert = grid.make_inserter_compiled() @@ -165,16 +165,16 @@ def test_insert_scalar(grid, compiled): f.insert(p, a) # add material to cell center assert f.data[tuple(c)] == pytest.approx(a / grid.cell_volumes[tuple(c)]) - f.insert(grid.get_random_point(coords="grid"), a) + f.insert(grid.get_random_point(coords="grid", rng=rng), a) assert f.integral == pytest.approx(2 * a) -def test_insert_1d(): +def test_insert_1d(rng): """test the `insert` method for 1d systems""" grid = UnitGrid([2], periodic=True) f = ScalarField(grid) g = f.copy() - a = np.random.random() + a = rng.random() for r in np.linspace(0, 3, 8).reshape(8, 1): f.data = g.data = 0 f.insert(r, a) @@ -183,12 +183,12 @@ def test_insert_1d(): np.testing.assert_array_almost_equal(f.data, g.data) -def test_insert_polar(): +def test_insert_polar(rng): """test the `insert` method for polar systems""" grid = PolarSymGrid(3, 5) f = ScalarField(grid) g = f.copy() - a = np.random.random() + a = rng.random() for r in np.linspace(0, 3, 8).reshape(8, 1): f.data = g.data = 0 f.insert(r, a) @@ -197,19 +197,19 @@ def test_insert_polar(): np.testing.assert_array_almost_equal(f.data, g.data) -def test_random_harmonic(): +def test_random_harmonic(rng): """test whether random harmonic fields behave correctly""" grid = get_cartesian_grid(2) # get random Cartesian grid - x = ScalarField.random_harmonic(grid, modes=1) + x = ScalarField.random_harmonic(grid, modes=1, rng=rng) scaling = sum((2 * np.pi / L) ** 2 for L in grid.cuboid.size) y = -x.laplace("auto_periodic_neumann") / scaling np.testing.assert_allclose(x.data, y.data, rtol=1e-2, atol=1e-2) -def test_get_line_data(): +def test_get_line_data(rng): """test different extraction methods for line data""" grid = UnitGrid([16, 32]) - c = ScalarField.random_harmonic(grid) + c = ScalarField.random_harmonic(grid, rng=rng) np.testing.assert_equal( c.get_line_data(extract="cut_0"), c.get_line_data(extract="cut_x") @@ -241,10 +241,10 @@ def f(x, y): @skipUnlessModule("matplotlib") -def test_from_image(tmp_path): +def test_from_image(tmp_path, rng): from matplotlib.pyplot import imsave - img_data = np.random.uniform(size=(9, 8, 3)) + img_data = rng.uniform(size=(9, 8, 3)) img_data_gray = img_data @ np.array([0.299, 0.587, 0.114]) path = tmp_path / "test_from_image.png" imsave(path, img_data, vmin=0, vmax=1) @@ -252,14 +252,14 @@ def test_from_image(tmp_path): np.testing.assert_allclose(sf.data, img_data_gray.T[:, ::-1], atol=0.05) -def test_to_scalar(): +def test_to_scalar(rng): """test conversion to scalar field""" - sf = ScalarField.random_uniform(UnitGrid([3, 3])) + sf = ScalarField.random_uniform(UnitGrid([3, 3]), rng=rng) np.testing.assert_allclose(sf.to_scalar().data, sf.data) np.testing.assert_allclose(sf.to_scalar("norm_squared").data, sf.data**2) np.testing.assert_allclose(sf.to_scalar(lambda x: 2 * x).data, 2 * sf.data) - sf = ScalarField.random_uniform(UnitGrid([3, 3]), 0, 1 + 1j) + sf = ScalarField.random_uniform(UnitGrid([3, 3]), 0, 1 + 1j, rng=rng) np.testing.assert_allclose(sf.to_scalar().data, np.abs(sf.data)) np.testing.assert_allclose(sf.to_scalar("abs").data, sf.to_scalar("norm").data) np.testing.assert_allclose(sf.to_scalar("norm_squared").data, np.abs(sf.data) ** 2) @@ -271,9 +271,9 @@ def test_to_scalar(): @pytest.mark.parametrize("grid", (grid for grid in iter_grids() if grid.num_axes > 1)) @pytest.mark.parametrize("method", ["integral", "average"]) -def test_projection(grid, method): +def test_projection(grid, method, rng): """test scalar projection""" - sf = ScalarField.random_uniform(grid) + sf = ScalarField.random_uniform(grid, rng=rng) for ax in grid.axes: sp = sf.project(ax, method=method) assert sp.grid.dim < grid.dim @@ -288,10 +288,10 @@ def test_projection(grid, method): @pytest.mark.parametrize("grid", (grid for grid in iter_grids() if grid.num_axes > 1)) -def test_slice(grid): +def test_slice(grid, rng): """test scalar slicing""" sf = ScalarField(grid, 0.5) - p = grid.get_random_point(coords="grid") + p = grid.get_random_point(coords="grid", rng=rng) for i in range(grid.num_axes): sf_slc = sf.slice({grid.axes[i]: p[i]}) np.testing.assert_allclose(sf_slc.data, 0.5) @@ -357,13 +357,13 @@ def test_boundary_interpolation_1d(): np.testing.assert_allclose(b_field.data, bndry_val) -def test_boundary_interpolation_2d(): +def test_boundary_interpolation_2d(rng): """test boundary interpolation for 2d fields""" grid = CartesianGrid([[0.1, 0.3], [-2, 3]], [3, 3]) - field = ScalarField.random_normal(grid) + field = ScalarField.random_normal(grid, rng=rng) # test boundary interpolation - bndry_val = np.random.randn(3) + bndry_val = rng.normal(size=3) for bndry in grid._iter_boundaries(): val = field.get_boundary_values(*bndry, bc={"value": bndry_val}) np.testing.assert_allclose(val, bndry_val) @@ -375,10 +375,10 @@ def test_boundary_interpolation_2d(): np.testing.assert_allclose(b_field.data, bndry_val) -def test_numpy_ufuncs(): +def test_numpy_ufuncs(rng): """test numpy ufuncs""" grid = UnitGrid([2, 2]) - f1 = ScalarField.random_uniform(grid, 0.1, 0.9) + f1 = ScalarField.random_uniform(grid, 0.1, 0.9, rng=rng) f2 = np.sin(f1) np.testing.assert_allclose(f2.data, np.sin(f1.data)) @@ -392,19 +392,19 @@ def test_numpy_ufuncs(): np.sum(f1, 1) -def test_plotting_1d(): +def test_plotting_1d(rng): """test plotting of 1d scalar fields""" grid = UnitGrid([3]) - field = ScalarField.random_uniform(grid, 0.1, 0.9) + field = ScalarField.random_uniform(grid, 0.1, 0.9, rng=rng) ref = field.plot() field._update_plot(ref) -def test_plotting_2d(): +def test_plotting_2d(rng): """test plotting of 2d scalar fields""" grid = UnitGrid([3, 3]) - field = ScalarField.random_uniform(grid, 0.1, 0.9) + field = ScalarField.random_uniform(grid, 0.1, 0.9, rng=rng) ref = field.plot() field._update_plot(ref) @@ -412,14 +412,14 @@ def test_plotting_2d(): @skipUnlessModule("napari") @pytest.mark.interactive -def test_interactive_plotting(): +def test_interactive_plotting(rng): """test the interactive plotting""" grid = UnitGrid([3, 3]) - field = ScalarField.random_uniform(grid, 0.1, 0.9) + field = ScalarField.random_uniform(grid, 0.1, 0.9, rng=rng) field.plot_interactive(viewer_args={"show": False, "close": True}) grid = UnitGrid([3, 3, 3]) - field = ScalarField.random_uniform(grid, 0.1, 0.9) + field = ScalarField.random_uniform(grid, 0.1, 0.9, rng=rng) field.plot_interactive(viewer_args={"show": False, "close": True}) @@ -469,7 +469,7 @@ def test_complex_operators(): assert f.laplace("auto_periodic_neumann").magnitude == pytest.approx(0) -def test_interpolation_after_free(): +def test_interpolation_after_free(rng): """test whether interpolation is possible when the original field is removed""" f = ScalarField.from_expression(UnitGrid([5]), "x") intp = f.make_interpolator() @@ -479,7 +479,7 @@ def test_interpolation_after_free(): gc.collect() # hope that this overwrites the memory - f = ScalarField.random_uniform(UnitGrid([5])) + f = ScalarField.random_uniform(UnitGrid([5]), rng=rng) assert intp(np.array([2.3])) == pytest.approx(2.3) @@ -497,9 +497,9 @@ def test_corner_interpolation(): @pytest.mark.parametrize("grid", iter_grids()) -def test_generic_derivatives(grid): +def test_generic_derivatives(grid, rng): """test generic derivatives operators""" - sf = ScalarField.random_uniform(grid, rng=np.random.default_rng(0)) + sf = ScalarField.random_uniform(grid, rng=rng) sf_grad = sf.gradient("auto_periodic_neumann") sf_lap = ScalarField(grid) @@ -542,10 +542,10 @@ def test_boundary_expressions_with_t(): @pytest.mark.multiprocessing @pytest.mark.parametrize("decomp", [(-1, 1), (1, -1)]) -def test_field_split(decomp): +def test_field_split(decomp, rng): """test the field splitting function in an MPI context""" grid = UnitGrid([4, 4]) - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) # basic split subfield = field.split_mpi(decomposition=decomp) diff --git a/tests/fields/test_tensorial_fields.py b/tests/fields/test_tensorial_fields.py index 6b86e432..bdb9957a 100644 --- a/tests/fields/test_tensorial_fields.py +++ b/tests/fields/test_tensorial_fields.py @@ -10,7 +10,7 @@ from pde.fields.base import FieldBase -def test_tensors_basic(): +def test_tensors_basic(rng): """test some tensor calculations""" grid = CartesianGrid([[0.1, 0.3], [-2, 3]], [3, 4]) @@ -29,7 +29,7 @@ def test_tensors_basic(): t1 += t2 np.testing.assert_allclose(t1.data, 3) - field = Tensor2Field.random_uniform(grid) + field = Tensor2Field.random_uniform(grid, rng=rng) trace = field.trace() assert isinstance(trace, ScalarField) @@ -116,12 +116,12 @@ def test_tensor_symmetrize(): @pytest.mark.parametrize("grid", iter_grids()) @pytest.mark.parametrize("compiled", [True, False]) -def test_insert_tensor(grid, compiled): +def test_insert_tensor(grid, compiled, rng): """test the `insert` method""" f = Tensor2Field(grid) - a = np.random.random(f.data_shape) + a = rng.random(f.data_shape) - c = grid.get_random_point(coords="cell").astype(int) # pick a random cell + c = grid.get_random_point(coords="cell", rng=rng).astype(int) # pick a random cell c_data = (Ellipsis,) + tuple(c) p = grid.transform(c + 0.5, "cell", "grid") # point at cell center if compiled: @@ -131,25 +131,25 @@ def test_insert_tensor(grid, compiled): f.insert(p, a) # add material to cell center np.testing.assert_almost_equal(f.data[c_data], a / grid.cell_volumes[tuple(c)]) - f.insert(grid.get_random_point(coords="grid"), a) + f.insert(grid.get_random_point(coords="grid", rng=rng), a) np.testing.assert_almost_equal(f.integral, 2 * a) -def test_tensor_invariants(): +def test_tensor_invariants(rng): """test the invariants""" # dim == 1 - f = Tensor2Field.random_uniform(UnitGrid([3])) + f = Tensor2Field.random_uniform(UnitGrid([3]), rng=rng) np.testing.assert_allclose( f.to_scalar("invariant1").data, f.to_scalar("invariant3").data ) np.testing.assert_allclose(f.to_scalar("invariant2").data, 0) # dim == 2 - f = Tensor2Field.random_uniform(UnitGrid([3, 3])) + f = Tensor2Field.random_uniform(UnitGrid([3, 3]), rng=rng) invs = [f.to_scalar(f"invariant{i}").data for i in range(1, 4)] np.testing.assert_allclose(2 * invs[1], invs[2]) - a = np.random.uniform(0, 2 * np.pi) # pick random rotation angle + a = rng.uniform(0, 2 * np.pi) # pick random rotation angle rot = Tensor2Field(f.grid) rot.data[0, 0, ...] = np.cos(a) rot.data[0, 1, ...] = np.sin(a) @@ -167,9 +167,9 @@ def test_tensor_invariants(): # dim == 3 from scipy.spatial.transform import Rotation - f = Tensor2Field.random_uniform(UnitGrid([1, 1, 1])) + f = Tensor2Field.random_uniform(UnitGrid([1, 1, 1]), rng=rng) rot = Tensor2Field(f.grid) - rot_mat = Rotation.from_rotvec(np.random.randn(3)).as_matrix() + rot_mat = Rotation.from_rotvec(rng.normal(size=3)).as_matrix() rot.data = rot_mat.reshape(3, 3, 1, 1, 1) f_rot = rot @ f @ rot.transpose() # apply the transpose for i in range(1, 4): @@ -181,11 +181,11 @@ def test_tensor_invariants(): @pytest.mark.parametrize("backend", ["numba", "numpy"]) -def test_complex_tensors(backend): +def test_complex_tensors(backend, rng): """test some complex tensor fields""" grid = CartesianGrid([[0.1, 0.3], [-2, 3]], [3, 4]) shape = (2, 2, 2) + grid.shape - numbers = np.random.random(shape) + np.random.random(shape) * 1j + numbers = rng.random(shape) + rng.random(shape) * 1j t1 = Tensor2Field(grid, numbers[0]) t2 = Tensor2Field(grid, numbers[1]) assert t1.is_complex and t2.is_complex diff --git a/tests/fields/test_vectorial_fields.py b/tests/fields/test_vectorial_fields.py index c4ad9830..f39e3a69 100644 --- a/tests/fields/test_vectorial_fields.py +++ b/tests/fields/test_vectorial_fields.py @@ -202,31 +202,31 @@ def f(x, y): np.testing.assert_allclose(vf.data[1], xs * ys) -def test_vector_plot_quiver_reduction(): +def test_vector_plot_quiver_reduction(rng): """test whether quiver plots reduce the resolution""" grid = UnitGrid([6, 6]) - field = VectorField.random_normal(grid) + field = VectorField.random_normal(grid, rng=rng) ref = field.plot(method="quiver", max_points=4) assert len(ref.element.U) == 16 -def test_boundary_interpolation_vector(): +def test_boundary_interpolation_vector(rng): """test boundary interpolation""" grid = CartesianGrid([[0.1, 0.3], [-2, 3]], [3, 3]) - field = VectorField.random_normal(grid) + field = VectorField.random_normal(grid, rng=rng) # test boundary interpolation - bndry_val = np.random.randn(2, 3) + bndry_val = rng.normal(size=(2, 3)) for bndry in grid._iter_boundaries(): val = field.get_boundary_values(*bndry, bc={"value": bndry_val}) np.testing.assert_allclose(val, bndry_val) @pytest.mark.parametrize("transpose", [True, False]) -def test_vector_plotting_2d(transpose): +def test_vector_plotting_2d(transpose, rng): """test plotting of 2d vector fields""" grid = UnitGrid([3, 4]) - field = VectorField.random_uniform(grid, 0.1, 0.9) + field = VectorField.random_uniform(grid, 0.1, 0.9, rng=rng) for method in ["quiver", "streamplot"]: ref = field.plot(method=method, transpose=transpose) @@ -234,24 +234,24 @@ def test_vector_plotting_2d(transpose): # test sub-sampling grid = UnitGrid([32, 15]) - field = VectorField.random_uniform(grid, 0.1, 0.9) + field = VectorField.random_uniform(grid, 0.1, 0.9, rng=rng) field.get_vector_data(transpose=transpose, max_points=7) @skipUnlessModule("napari") @pytest.mark.interactive -def test_interactive_vector_plotting(): +def test_interactive_vector_plotting(rng): """test the interactive plotting""" grid = UnitGrid([3, 3]) - field = VectorField.random_uniform(grid, 0.1, 0.9) + field = VectorField.random_uniform(grid, 0.1, 0.9, rng=rng) field.plot_interactive(viewer_args={"show": False, "close": True}) -def test_complex_vectors(): +def test_complex_vectors(rng): """test some complex vector fields""" grid = CartesianGrid([[0.1, 0.3], [-2, 3]], [3, 4]) shape = (2, 2) + grid.shape - numbers = np.random.random(shape) + np.random.random(shape) * 1j + numbers = rng.random(shape) + rng.random(shape) * 1j v1 = VectorField(grid, numbers[0]) v2 = VectorField(grid, numbers[1]) assert v1.is_complex and v2.is_complex diff --git a/tests/grids/boundaries/test_axes_boundaries.py b/tests/grids/boundaries/test_axes_boundaries.py index 8cde70f0..79bc406e 100644 --- a/tests/grids/boundaries/test_axes_boundaries.py +++ b/tests/grids/boundaries/test_axes_boundaries.py @@ -78,10 +78,10 @@ def test_boundary_specifications(): assert bc1 == Boundaries.from_data(g, ["neumann", "dirichlet"]) -def test_mixed_boundary_condition(): +def test_mixed_boundary_condition(rng): """test limiting cases of the mixed boundary condition""" g = UnitGrid([2]) - d = np.random.random(2) + d = rng.random(2) g1 = g.make_operator("gradient", bc=[{"mixed": 0}, {"mixed": np.inf}]) g2 = g.make_operator("gradient", bc=["derivative", "value"]) np.testing.assert_allclose(g1(d), g2(d)) @@ -125,10 +125,10 @@ def test_bc_values(): @pytest.mark.parametrize("dim", [1, 2, 3]) @pytest.mark.parametrize("periodic", [True, False]) -def test_set_ghost_cells(dim, periodic): +def test_set_ghost_cells(dim, periodic, rng): """test setting values for ghost cells""" grid = UnitGrid([1] * dim, periodic=periodic) - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) bcs = grid.get_boundary_conditions("auto_periodic_neumann") arr1 = field._data_full.copy() diff --git a/tests/grids/boundaries/test_local_boundaries.py b/tests/grids/boundaries/test_local_boundaries.py index 43d979cf..23dbc25a 100644 --- a/tests/grids/boundaries/test_local_boundaries.py +++ b/tests/grids/boundaries/test_local_boundaries.py @@ -272,7 +272,7 @@ def test_inhomogeneous_bcs_2d(): @pytest.mark.parametrize("expr", ["1", "x + y**2"]) -def test_expression_bc_setting_value(expr): +def test_expression_bc_setting_value(expr, rng): """test boundary conditions that use an expression""" grid = CartesianGrid([[0, 1], [0, 1]], 4) @@ -292,7 +292,7 @@ def func(adjacent_value, dx, x, y, t): bc4 = grid.get_boundary_conditions({"virtual_point": f"2 * ({expr}) - value"}) bcs = [bc1, bc2, bc3, bc4] - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) f_ref = field.copy() f_ref.set_ghost_cells(bc1) @@ -307,7 +307,7 @@ def func(adjacent_value, dx, x, y, t): @pytest.mark.parametrize("expr", ["1", "x + y**2"]) -def test_expression_bc_setting_derivative(expr): +def test_expression_bc_setting_derivative(expr, rng): """test boundary conditions that use an expression""" grid = CartesianGrid([[0, 1], [0, 1]], 4) @@ -326,7 +326,7 @@ def func(adjacent_value, dx, x, y, t): bc3 = grid.get_boundary_conditions({"derivative_expression": func}) bcs = [bc1, bc2, bc3] - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) f_ref = field.copy() f_ref.set_ghost_cells(bc1) @@ -341,7 +341,7 @@ def func(adjacent_value, dx, x, y, t): @pytest.mark.parametrize("value_expr, const_expr", [["1", "1"], ["x", "y**2"]]) -def test_expression_bc_setting_mixed(value_expr, const_expr): +def test_expression_bc_setting_mixed(value_expr, const_expr, rng): """test boundary conditions that use an expression""" grid = CartesianGrid([[0, 1], [0, 1]], 4) @@ -376,7 +376,7 @@ def const_func(adjacent_value, dx, x, y, t): ) bcs = [bc1, bc2, bc3] - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) f_ref = field.copy() f_ref.set_ghost_cells(bc1) diff --git a/tests/grids/operators/test_cartesian_operators.py b/tests/grids/operators/test_cartesian_operators.py index 17743da9..a8c19e86 100644 --- a/tests/grids/operators/test_cartesian_operators.py +++ b/tests/grids/operators/test_cartesian_operators.py @@ -25,12 +25,13 @@ def _get_random_grid_bcs(ndim: int, dx="random", periodic="random", rank=0): """create a random Cartesian grid with natural bcs""" - shape = tuple(np.random.randint(2, 5, ndim)) + rng = np.random.default_rng(0) + shape = tuple(rng.integers(2, 5, ndim)) if dx == "random": - dx = np.random.uniform(0.5, 1.5, ndim) + dx = rng.uniform(0.5, 1.5, ndim) elif dx == "uniform": - dx = np.full(ndim, np.random.uniform(0.5, 1.5)) + dx = np.full(ndim, rng.uniform(0.5, 1.5)) else: dx = np.broadcast_to(dx, shape) @@ -43,14 +44,14 @@ def _get_random_grid_bcs(ndim: int, dx="random", periodic="random", rank=0): @pytest.mark.parametrize("periodic", [True, False]) -def test_singular_dimensions_2d(periodic): +def test_singular_dimensions_2d(periodic, rng): """test grids with singular dimensions""" - dim = np.random.randint(3, 5) + dim = rng.integers(3, 5) g1 = UnitGrid([dim], periodic=periodic) g2a = UnitGrid([dim, 1], periodic=periodic) g2b = UnitGrid([1, dim], periodic=periodic) - field = ScalarField.random_uniform(g1) + field = ScalarField.random_uniform(g1, rng=rng) expected = field.laplace("auto_periodic_neumann").data for g in [g2a, g2b]: f = ScalarField(g, data=field.data.reshape(g.shape)) @@ -59,14 +60,14 @@ def test_singular_dimensions_2d(periodic): @pytest.mark.parametrize("periodic", [True, False]) -def test_singular_dimensions_3d(periodic): +def test_singular_dimensions_3d(periodic, rng): """test grids with singular dimensions""" - dim = np.random.randint(3, 5) + dim = rng.integers(3, 5) g1 = UnitGrid([dim], periodic=periodic) g3a = UnitGrid([dim, 1, 1], periodic=periodic) g3b = UnitGrid([1, 1, dim], periodic=periodic) - field = ScalarField.random_uniform(g1) + field = ScalarField.random_uniform(g1, rng=rng) expected = field.laplace("auto_periodic_neumann").data for g in [g3a, g3b]: f = ScalarField(g, data=field.data.reshape(g.shape)) @@ -75,10 +76,10 @@ def test_singular_dimensions_3d(periodic): @pytest.mark.parametrize("periodic", [True, False]) -def test_laplace_1d(periodic): - """test the implementation of the laplace operator""" +def test_laplace_1d(periodic, rng): + """test the implementatio,rngn of the laplace operator""" bcs = _get_random_grid_bcs(1, periodic=periodic) - field = ScalarField.random_colored(bcs.grid, -6) + field = ScalarField.random_colored(bcs.grid, -6, rng=rng) l1 = field.laplace(bcs, backend="scipy") l2 = field.laplace(bcs, backend="numba") np.testing.assert_allclose(l1.data, l2.data) @@ -89,7 +90,7 @@ def test_laplace_1d(periodic): @pytest.mark.parametrize("dtype", [float, complex]) def test_laplace_spectral(ndim, dtype, rng): """test the implementation of the spectral laplace operator""" - shape = np.c_[np.random.uniform(-10, -20, ndim), np.random.uniform(10, 20, ndim)] + shape = np.c_[rng.uniform(-20, -10, ndim), rng.uniform(10, 20, ndim)] grid = CartesianGrid(shape, 30, periodic=True) field = ScalarField.random_colored(grid, -8, dtype=dtype, rng=rng) if dtype is complex: @@ -101,10 +102,10 @@ def test_laplace_spectral(ndim, dtype, rng): @pytest.mark.parametrize("periodic", [True, False]) -def test_laplace_2d(periodic): +def test_laplace_2d(periodic, rng): """test the implementation of the laplace operator""" bcs = _get_random_grid_bcs(2, dx="uniform", periodic=periodic) - a = np.random.random(bcs.grid.shape) # test data + a = rng.random(bcs.grid.shape) # test data dx = np.mean(bcs.grid.discretization) kernel = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]]) / dx**2 @@ -119,14 +120,14 @@ def test_laplace_2d(periodic): @pytest.mark.parametrize("periodic", [True, False]) -def test_laplace_2d_nonuniform(periodic): +def test_laplace_2d_nonuniform(periodic, rng): """test the implementation of the laplace operator for non-uniform coordinates""" bcs = _get_random_grid_bcs(ndim=2, dx="random", periodic=periodic) dx = bcs.grid.discretization kernel_x = np.array([1, -2, 1]) / dx[0] ** 2 kernel_y = np.array([1, -2, 1]) / dx[1] ** 2 - a = np.random.random(bcs.grid.shape) + a = rng.random(bcs.grid.shape) mode = "wrap" if periodic else "reflect" res = ndimage.convolve1d(a, kernel_x, axis=0, mode=mode) @@ -138,10 +139,10 @@ def test_laplace_2d_nonuniform(periodic): @pytest.mark.parametrize("periodic", [True, False]) -def test_laplace_3d(periodic): +def test_laplace_3d(periodic, rng): """test the implementation of the laplace operator""" bcs = _get_random_grid_bcs(ndim=3, dx="uniform", periodic=periodic) - field = ScalarField.random_uniform(bcs.grid) + field = ScalarField.random_uniform(bcs.grid, rng=rng) l1 = field.laplace(bcs, backend="scipy") l2 = field.laplace(bcs, backend="numba") np.testing.assert_allclose(l1.data, l2.data) @@ -168,10 +169,10 @@ def test_gradient_1d(): @pytest.mark.parametrize("ndim", [1, 2, 3]) @pytest.mark.parametrize("periodic", [True, False]) -def test_gradient_cart(ndim, periodic): +def test_gradient_cart(ndim, periodic, rng): """test different gradient operators""" bcs = _get_random_grid_bcs(ndim, dx="uniform", periodic=periodic) - field = ScalarField.random_uniform(bcs.grid) + field = ScalarField.random_uniform(bcs.grid, rng=rng) res1 = field.gradient(bcs, backend="scipy").data res2 = field.gradient(bcs, backend="numba").data assert res1.shape == (ndim,) + bcs.grid.shape @@ -180,20 +181,20 @@ def test_gradient_cart(ndim, periodic): @pytest.mark.parametrize("ndim", [1, 2, 3]) @pytest.mark.parametrize("periodic", [True, False]) -def test_divergence_cart(ndim, periodic): +def test_divergence_cart(ndim, periodic, rng): """test different divergence operators""" bcs = _get_random_grid_bcs(ndim, dx="uniform", periodic=periodic, rank=1) - field = VectorField.random_uniform(bcs.grid) + field = VectorField.random_uniform(bcs.grid, rng=rng) res1 = field.divergence(bcs, backend="scipy").data res2 = field.divergence(bcs, backend="numba").data np.testing.assert_allclose(res1, res2) @pytest.mark.parametrize("ndim", [1, 2, 3]) -def test_vector_gradient(ndim): +def test_vector_gradient(ndim, rng): """test different vector gradient operators""" bcs = _get_random_grid_bcs(ndim, dx="uniform", periodic="random", rank=1) - field = VectorField.random_uniform(bcs.grid) + field = VectorField.random_uniform(bcs.grid, rng=rng) res1 = field.gradient(bcs, backend="scipy").data res2 = field.gradient(bcs, backend="numba").data assert res1.shape == (ndim, ndim) + bcs.grid.shape @@ -201,10 +202,10 @@ def test_vector_gradient(ndim): @pytest.mark.parametrize("ndim", [1, 2, 3]) -def test_vector_laplace_cart(ndim): +def test_vector_laplace_cart(ndim, rng): """test different vector laplace operators""" bcs = _get_random_grid_bcs(ndim, dx="uniform", periodic="random", rank=1) - field = VectorField.random_uniform(bcs.grid) + field = VectorField.random_uniform(bcs.grid, rng=rng) res1 = field.laplace(bcs, backend="scipy").data res2 = field.laplace(bcs, backend="numba").data assert res1.shape == (ndim,) + bcs.grid.shape @@ -212,10 +213,10 @@ def test_vector_laplace_cart(ndim): @pytest.mark.parametrize("ndim", [1, 2, 3]) -def test_tensor_divergence_cart(ndim): +def test_tensor_divergence_cart(ndim, rng): """test different tensor divergence operators""" bcs = _get_random_grid_bcs(ndim, dx="uniform", periodic="random", rank=2) - field = Tensor2Field.random_uniform(bcs.grid) + field = Tensor2Field.random_uniform(bcs.grid, rng=rng) res1 = field.divergence(bcs, backend="scipy").data res2 = field.divergence(bcs, backend="numba").data assert res1.shape == (ndim,) + bcs.grid.shape @@ -236,13 +237,13 @@ def test_div_grad_const(): np.testing.assert_allclose(divgrad.data, np.zeros(32)) -def test_div_grad_linear(): +def test_div_grad_linear(rng): """compare div grad to laplace operator""" grid = CartesianGrid([[-1, 1]], 32) x = grid.axes_coords[0] # test linear - f = np.random.random() + 1 + f = rng.random() + 1 y = ScalarField(grid, f * x) b1 = [{"type": "neumann", "value": -f}, {"type": "neumann", "value": f}] @@ -272,14 +273,14 @@ def test_div_grad_quadratic(): @pytest.mark.parametrize("dim", [1, 2, 3]) -def test_gradient_squared_cart(dim): +def test_gradient_squared_cart(dim, rng): """compare gradient squared operator""" grid = CartesianGrid( [[0, 2 * np.pi]] * dim, - shape=np.random.randint(30, 35, dim), - periodic=np.random.choice([False, True], dim), + shape=rng.integers(30, 35, dim), + periodic=rng.choice([False, True], dim), ) - field = ScalarField.random_harmonic(grid, modes=1, axis_combination=np.add) + field = ScalarField.random_harmonic(grid, modes=1, axis_combination=np.add, rng=rng) s1 = field.gradient("auto_periodic_neumann").to_scalar("squared_sum") s2 = field.gradient_squared("auto_periodic_neumann", central=True) np.testing.assert_allclose(s1.data, s2.data, rtol=0.1, atol=0.1) @@ -302,11 +303,11 @@ def test_rect_div_grad(): np.testing.assert_allclose(b.data, -field.data, rtol=0.05, atol=0.01) -def test_degenerated_grid(): +def test_degenerated_grid(rng): """test operators on grids with singular dimensions""" g1 = CartesianGrid([[0, 1]], 4) g2 = CartesianGrid([[0, 1], [0, 0.1]], [4, 1], periodic=[False, True]) - f1 = ScalarField.random_uniform(g1) + f1 = ScalarField.random_uniform(g1, rng=rng) f2 = ScalarField(g2, f1.data.reshape(g2.shape)) res1 = f1.laplace("auto_periodic_neumann").data @@ -314,19 +315,19 @@ def test_degenerated_grid(): np.testing.assert_allclose(res1.flat, res2.flat) -def test_2nd_order_bc(): +def test_2nd_order_bc(rng): """test whether 2nd order boundary conditions can be used""" grid = UnitGrid([8, 8]) - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) field.laplace([{"value": "sin(y)"}, {"value": "x"}]) @pytest.mark.parametrize("ndim,axis", [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)]) -def test_make_derivative(ndim, axis): +def test_make_derivative(ndim, axis, rng): """test the _make_derivative function""" periodic = random.choice([True, False]) grid = CartesianGrid([[0, 6 * np.pi]] * ndim, 16, periodic=periodic) - field = ScalarField.random_harmonic(grid, modes=1, axis_combination=np.add) + field = ScalarField.random_harmonic(grid, modes=1, axis_combination=np.add, rng=rng) bcs = grid.get_boundary_conditions("auto_periodic_neumann") grad = field.gradient(bcs) @@ -343,11 +344,11 @@ def test_make_derivative(ndim, axis): @pytest.mark.parametrize("ndim,axis", [(1, 0), (2, 0), (2, 1), (3, 0), (3, 1), (3, 2)]) -def test_make_derivative2(ndim, axis): +def test_make_derivative2(ndim, axis, rng): """test the _make_derivative2 function""" periodic = random.choice([True, False]) grid = CartesianGrid([[0, 6 * np.pi]] * ndim, 16, periodic=periodic) - field = ScalarField.random_harmonic(grid, modes=1, axis_combination=np.add) + field = ScalarField.random_harmonic(grid, modes=1, axis_combination=np.add, rng=rng) bcs = grid.get_boundary_conditions("auto_periodic_neumann") grad = field.gradient(bcs)[axis] @@ -362,7 +363,7 @@ def test_make_derivative2(ndim, axis): @pytest.mark.parametrize("ndim", [1, 2]) -def test_laplace_matrix(ndim): +def test_laplace_matrix(ndim, rng): """test laplace operator implemented using matrix multiplication""" if ndim == 1: periodic, bc = [False], [{"value": "sin(x)"}] @@ -372,7 +373,7 @@ def test_laplace_matrix(ndim): bcs = grid.get_boundary_conditions(bc) laplace = make_laplace_from_matrix(*ops._get_laplace_matrix(bcs)) - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) res1 = field.laplace(bcs) res2 = laplace(field.data) @@ -381,10 +382,10 @@ def test_laplace_matrix(ndim): @pytest.mark.parametrize("grid", [UnitGrid([12]), CartesianGrid([[0, 1], [4, 5.5]], 8)]) @pytest.mark.parametrize("bc_val", ["auto_periodic_neumann", {"value": "sin(x)"}]) -def test_poisson_solver_cartesian(grid, bc_val): +def test_poisson_solver_cartesian(grid, bc_val, rng): """test the poisson solver on cartesian grids""" bcs = grid.get_boundary_conditions(bc_val) - d = ScalarField.random_uniform(grid) + d = ScalarField.random_uniform(grid, rng=rng) d -= d.average # balance the right hand side sol = solve_poisson_equation(d, bcs) test = sol.laplace(bcs) diff --git a/tests/grids/operators/test_cylindrical_operators.py b/tests/grids/operators/test_cylindrical_operators.py index 606fef05..1b30f84d 100644 --- a/tests/grids/operators/test_cylindrical_operators.py +++ b/tests/grids/operators/test_cylindrical_operators.py @@ -114,10 +114,10 @@ def test_grid_laplace(): np.testing.assert_allclose(b_2d_3.data, b_3d.data, rtol=0.2, atol=0.2) -def test_gradient_squared_cyl(): +def test_gradient_squared_cyl(rng): """compare gradient squared operator""" grid = CylindricalSymGrid(2 * np.pi, [0, 2 * np.pi], 64) - field = ScalarField.random_harmonic(grid, modes=1) + field = ScalarField.random_harmonic(grid, modes=1, rng=rng) s1 = field.gradient("auto_periodic_neumann").to_scalar("squared_sum") s2 = field.gradient_squared("auto_periodic_neumann", central=True) np.testing.assert_allclose(s1.data, s2.data, rtol=0.2, atol=0.2) @@ -234,7 +234,7 @@ def test_examples_tensor_cyl(): @pytest.mark.parametrize("r_inner", (0, 1)) -def test_laplace_matrix(r_inner): +def test_laplace_matrix(r_inner, rng): """test laplace operator implemented using matrix multiplication""" grid = CylindricalSymGrid((r_inner, 2), (2.5, 4.3), 16) if r_inner == 0: @@ -244,7 +244,7 @@ def test_laplace_matrix(r_inner): bcs = grid.get_boundary_conditions(bcs) laplace = make_laplace_from_matrix(*_get_laplace_matrix(bcs)) - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) res1 = field.laplace(bcs) res2 = laplace(field.data) @@ -252,14 +252,14 @@ def test_laplace_matrix(r_inner): @pytest.mark.parametrize("r_inner", (0, 1)) -def test_poisson_solver_cylindrical(r_inner): +def test_poisson_solver_cylindrical(r_inner, rng): """test the poisson solver on Cylindrical grids""" grid = CylindricalSymGrid((r_inner, 2), (2.5, 4.3), 16) if r_inner == 0: bcs = ["neumann", {"value": "cos(r) + z"}] else: bcs = [{"value": "sin(r)"}, {"derivative": "cos(r) + z"}] - d = ScalarField.random_uniform(grid) + d = ScalarField.random_uniform(grid, rng=rng) d -= d.average # balance the right hand side sol = solve_poisson_equation(d, bcs) test = sol.laplace(bcs) diff --git a/tests/grids/operators/test_polar_operators.py b/tests/grids/operators/test_polar_operators.py index abd393c4..67ccb5e1 100644 --- a/tests/grids/operators/test_polar_operators.py +++ b/tests/grids/operators/test_polar_operators.py @@ -38,10 +38,10 @@ def test_findiff_polar(): np.testing.assert_allclose(div.data, [5, 17 / 3, 2 + 4 / r2]) -def test_conservative_laplace_polar(): +def test_conservative_laplace_polar(rng): """test and compare the two implementation of the laplace operator""" grid = PolarSymGrid(1.5, 8) - f = ScalarField.random_uniform(grid) + f = ScalarField.random_uniform(grid, rng=rng) res = f.laplace("auto_periodic_neumann") np.testing.assert_allclose(res.integral, 0, atol=1e-12) @@ -56,7 +56,7 @@ def test_conservative_laplace_polar(): ("tensor_divergence", Tensor2Field), ], ) -def test_small_annulus_polar(op_name, field): +def test_small_annulus_polar(op_name, field, rng): """test whether a small annulus gives the same result as a sphere""" grids = [ PolarSymGrid((0, 1), 8), @@ -64,7 +64,7 @@ def test_small_annulus_polar(op_name, field): PolarSymGrid((0.1, 1), 8), ] - f = field.random_uniform(grids[0]) + f = field.random_uniform(grids[0], rng=rng) res = [ field(g, data=f.data).apply_operator(op_name, "auto_periodic_neumann") @@ -120,10 +120,10 @@ def test_grid_div_grad_polar(): @pytest.mark.parametrize("grid", [PolarSymGrid(4, 8), PolarSymGrid([2, 4], 8)]) @pytest.mark.parametrize("bc_val", ["auto_periodic_neumann", {"value": 1}]) -def test_poisson_solver_polar(grid, bc_val): +def test_poisson_solver_polar(grid, bc_val, rng): """test the poisson solver on Polar grids""" bcs = grid.get_boundary_conditions(bc_val) - d = ScalarField.random_uniform(grid) + d = ScalarField.random_uniform(grid, rng=rng) d -= d.average # balance the right hand side sol = solve_poisson_equation(d, bcs) test = sol.laplace(bcs) @@ -191,7 +191,7 @@ def test_examples_tensor_polar(): @pytest.mark.parametrize("r_inner", (0, 1)) -def test_laplace_matrix(r_inner): +def test_laplace_matrix(r_inner, rng): """test laplace operator implemented using matrix multiplication""" grid = PolarSymGrid((r_inner, 2), 16) if r_inner == 0: @@ -200,7 +200,7 @@ def test_laplace_matrix(r_inner): bcs = grid.get_boundary_conditions({"value": "sin(r)"}) laplace = make_laplace_from_matrix(*_get_laplace_matrix(bcs)) - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) res1 = field.laplace(bcs) res2 = laplace(field.data) diff --git a/tests/grids/operators/test_spherical_operators.py b/tests/grids/operators/test_spherical_operators.py index 3876f32d..b17dac66 100644 --- a/tests/grids/operators/test_spherical_operators.py +++ b/tests/grids/operators/test_spherical_operators.py @@ -69,7 +69,7 @@ def test_conservative_sph(): ("gradient", ScalarField), ], ) -def test_small_annulus_sph(op_name, field): +def test_small_annulus_sph(op_name, field, rng): """test whether a small annulus gives the same result as a sphere""" grids = [ SphericalSymGrid((0, 1), 8), @@ -77,7 +77,7 @@ def test_small_annulus_sph(op_name, field): SphericalSymGrid((0.1, 1), 8), ] - f = field.random_uniform(grids[0]) + f = field.random_uniform(grids[0], rng=rng) if field is VectorField: f.data[1] = 0 @@ -109,10 +109,10 @@ def test_grid_laplace(): @pytest.mark.parametrize("r_inner", (0, 1)) -def test_gradient_squared(r_inner): +def test_gradient_squared(r_inner, rng): """compare gradient squared operator""" grid = SphericalSymGrid((r_inner, 5), 64) - field = ScalarField.random_harmonic(grid, modes=1) + field = ScalarField.random_harmonic(grid, modes=1, rng=rng) s1 = field.gradient("auto_periodic_neumann").to_scalar("squared_sum") s2 = field.gradient_squared("auto_periodic_neumann", central=True) np.testing.assert_allclose(s1.data, s2.data, rtol=0.1, atol=0.1) @@ -137,10 +137,10 @@ def test_grid_div_grad_sph(): @pytest.mark.parametrize("grid", [SphericalSymGrid(4, 8), SphericalSymGrid([2, 4], 8)]) @pytest.mark.parametrize("bc_val", ["auto_periodic_neumann", {"value": 1}]) -def test_poisson_solver_spherical(grid, bc_val): +def test_poisson_solver_spherical(grid, bc_val, rng): """test the poisson solver on Spherical grids""" bcs = grid.get_boundary_conditions(bc_val) - d = ScalarField.random_uniform(grid) + d = ScalarField.random_uniform(grid, rng=rng) d -= d.average # balance the right hand side sol = solve_poisson_equation(d, bcs) test = sol.laplace(bcs) @@ -280,7 +280,7 @@ def test_tensor_div_div(conservative): @pytest.mark.parametrize("r_inner", (0, 1)) -def test_laplace_matrix(r_inner): +def test_laplace_matrix(r_inner, rng): """test laplace operator implemented using matrix multiplication""" grid = SphericalSymGrid((r_inner, 2), 16) if r_inner == 0: @@ -289,7 +289,7 @@ def test_laplace_matrix(r_inner): bcs = grid.get_boundary_conditions({"value": "sin(r)"}) laplace = make_laplace_from_matrix(*_get_laplace_matrix(bcs)) - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) res1 = field.laplace(bcs) res2 = laplace(field.data) diff --git a/tests/grids/test_cartesian_grids.py b/tests/grids/test_cartesian_grids.py index ed038257..05d82d4b 100644 --- a/tests/grids/test_cartesian_grids.py +++ b/tests/grids/test_cartesian_grids.py @@ -14,8 +14,9 @@ def _get_cartesian_grid(dim=2, periodic=True): """return a random Cartesian grid of given dimension""" - bounds = [[0, 1 + np.random.random()] for _ in range(dim)] - shape = np.random.randint(32, 64, size=dim) + rng = np.random.default_rng(0) + bounds = [[0, 1 + rng.random()] for _ in range(dim)] + shape = rng.integers(32, 64, size=dim) return CartesianGrid(bounds, shape, periodic=periodic) @@ -28,12 +29,12 @@ def test_degenerated_grid(): @pytest.mark.parametrize("dim", [1, 2, 3]) -def test_generic_cartesian_grid(dim): +def test_generic_cartesian_grid(dim, rng): """test generic cartesian grid functions""" periodic = random.choices([True, False], k=dim) - shape = np.random.randint(2, 8, size=dim) - a = np.random.random(dim) - b = a + np.random.random(dim) + shape = rng.integers(2, 8, size=dim) + a = rng.random(dim) + b = a + rng.random(dim) cases = [ UnitGrid(shape, periodic=periodic), @@ -48,15 +49,15 @@ def test_generic_cartesian_grid(dim): assert grid.volume == pytest.approx(vol) assert grid.uniform_cell_volumes - assert grid.contains_point(grid.get_random_point(coords="grid")) + assert grid.contains_point(grid.get_random_point(coords="grid", rng=rng)) w = 0.499 * (b - a).min() - p = grid.get_random_point(boundary_distance=w, coords="grid") + p = grid.get_random_point(boundary_distance=w, coords="grid", rng=rng) assert grid.contains_point(p) assert "laplace" in grid.operators @pytest.mark.parametrize("periodic", [True, False]) -def test_unit_grid_1d(periodic): +def test_unit_grid_1d(periodic, rng): """test 1D grids""" grid = UnitGrid(4, periodic=periodic) assert grid.dim == 1 @@ -95,7 +96,7 @@ def norm_numba_wrap(x): # test conversion between polar and Cartesian coordinates c1 = grid.cell_coords - p = np.random.random(1) * grid.shape + p = rng.random(1) * grid.shape d, a = grid.polar_coordinates_real(p, ret_angle=True) c2 = grid.from_polar_coordinates(d, a, p) assert np.allclose(grid.distance_real(c1, c2), 0) @@ -105,7 +106,7 @@ def norm_numba_wrap(x): np.testing.assert_equal(grid._boundary_coordinates(0, True), np.array([8])) -def test_unit_grid_2d(): +def test_unit_grid_2d(rng): """test 2D grids""" # test special case grid = UnitGrid([4, 4], periodic=True) @@ -115,7 +116,7 @@ def test_unit_grid_2d(): np.testing.assert_array_equal(grid.discretization, np.ones(2)) assert grid.get_image_data(np.zeros(grid.shape))["extent"] == [0, 4, 0, 4] for _ in range(10): - p = np.random.randn(2) + p = rng.normal(size=2) assert np.all(grid.polar_coordinates_real(p) < np.sqrt(8)) large_enough = grid.polar_coordinates_real((0, 0)) > np.sqrt(4) assert np.any(large_enough) @@ -133,7 +134,7 @@ def test_unit_grid_2d(): # test conversion between polar and Cartesian coordinates c1 = grid.cell_coords - p = np.random.random(2) * grid.shape + p = rng.random(2) * grid.shape d, a = grid.polar_coordinates_real(p, ret_angle=True) c2 = grid.from_polar_coordinates(d, a, p) assert np.allclose(grid.distance_real(c1, c2), 0) @@ -157,7 +158,7 @@ def test_unit_grid_2d(): ) -def test_unit_grid_3d(): +def test_unit_grid_3d(rng): """test 3D grids""" grid = UnitGrid([4, 4, 4]) assert grid.dim == 3 @@ -177,7 +178,7 @@ def test_unit_grid_3d(): assert grid.dim == 3 assert grid.volume == 64 for _ in range(10): - p = np.random.randn(3) + p = rng.normal(size=3) not_too_large = grid.polar_coordinates_real(p) < np.sqrt(12) assert np.all(not_too_large) large_enough = grid.polar_coordinates_real((0, 0, 0)) > np.sqrt(6) @@ -188,7 +189,7 @@ def test_unit_grid_3d(): assert grid._boundary_coordinates(*bndry).shape == (4, 4, 3) -def test_rect_grid_1d(): +def test_rect_grid_1d(rng): """test 1D grids""" grid = CartesianGrid([32], 16, periodic=False) assert grid.dim == 1 @@ -211,23 +212,23 @@ def test_rect_grid_1d(): np.testing.assert_allclose(grid.normalize_point(16 + 1e-10), -16 + 1e-10) for periodic in [True, False]: - a, b = np.random.random(2) + a, b = rng.random(2) grid = CartesianGrid([[a, a + b]], 8, periodic=periodic) # test conversion between polar and Cartesian coordinates c1 = grid.cell_coords - p = np.random.random(1) * grid.shape + p = rng.random(1) * grid.shape d, a = grid.polar_coordinates_real(p, ret_angle=True) c2 = grid.from_polar_coordinates(d, a, p) assert np.allclose(grid.distance_real(c1, c2), 0) -def test_rect_grid_2d(): +def test_rect_grid_2d(rng): """test 2D grids""" grid = CartesianGrid([[2], [2]], 4, periodic=True) assert grid.get_image_data(np.zeros(grid.shape))["extent"] == [0, 2, 0, 2] for _ in range(10): - p = np.random.randn(2) + p = rng.normal(size=2) assert np.all(grid.polar_coordinates_real(p) < np.sqrt(2)) periodic = random.choices([True, False], k=2) @@ -246,14 +247,14 @@ def test_rect_grid_2d(): # test conversion between polar and Cartesian coordinates c1 = grid.cell_coords - p = np.random.random(2) * grid.shape + p = rng.random(2) * grid.shape d, a = grid.polar_coordinates_real(p, ret_angle=True) c2 = grid.from_polar_coordinates(d, a, p) assert np.allclose(grid.distance_real(c1, c2), 0) -def test_rect_grid_3d(): +def test_rect_grid_3d(rng): """test 3D grids""" grid = CartesianGrid([4, 4, 4], 4) assert grid.dim == 3 @@ -272,15 +273,15 @@ def test_rect_grid_3d(): grid = CartesianGrid([[2], [2], [2]], 4, periodic=True) for _ in range(10): - p = np.random.randn(3) + p = rng.normal(size=3) assert np.all(grid.polar_coordinates_real(p) < np.sqrt(3)) @pytest.mark.parametrize("periodic", [True, False]) -def test_unit_rect_grid(periodic): +def test_unit_rect_grid(periodic, rng): """test whether the rectangular grid behaves like a unit grid in special cases""" dim = random.randrange(1, 4) - shape = np.random.randint(2, 10, size=dim) + shape = rng.integers(2, 10, size=dim) g1 = UnitGrid(shape, periodic=periodic) g2 = CartesianGrid(np.c_[np.zeros(dim), shape], shape, periodic=periodic) volume = np.prod(shape) @@ -294,19 +295,19 @@ def test_unit_rect_grid(periodic): assert g1.typical_discretization == pytest.approx(g2.typical_discretization) for _ in range(10): - p1, p2 = np.random.normal(scale=10, size=(2, dim)) + p1, p2 = rng.normal(scale=10, size=(2, dim)) assert g1.distance_real(p1, p2) == pytest.approx(g2.distance_real(p1, p2)) - p0 = np.random.normal(scale=10, size=dim) + p0 = rng.normal(scale=10, size=dim) np.testing.assert_allclose( g1.polar_coordinates_real(p0), g2.polar_coordinates_real(p0) ) -def test_conversion_unit_rect_grid(): +def test_conversion_unit_rect_grid(rng): """test the conversion from unit to rectangular grid""" dim = random.randrange(1, 4) - shape = np.random.randint(2, 10, size=dim) + shape = rng.integers(2, 10, size=dim) periodic = random.choices([True, False], k=dim) g1 = UnitGrid(shape, periodic=periodic) g2 = g1.to_cartesian() diff --git a/tests/grids/test_cylindrical_grids.py b/tests/grids/test_cylindrical_grids.py index b0312fc1..1975fe7f 100644 --- a/tests/grids/test_cylindrical_grids.py +++ b/tests/grids/test_cylindrical_grids.py @@ -11,7 +11,7 @@ @pytest.mark.parametrize("periodic", [True, False]) @pytest.mark.parametrize("r_inner", [0, 2]) -def test_cylindrical_grid(periodic, r_inner): +def test_cylindrical_grid(periodic, r_inner, rng): """test simple cylindrical grid""" grid = CylindricalSymGrid((r_inner, 4), (-1, 2), (8, 9), periodic_z=periodic) if r_inner == 0: @@ -37,10 +37,10 @@ def test_cylindrical_grid(periodic, r_inner): np.testing.assert_array_equal(grid.discretization, np.array([0.25, 1 / 3])) np.testing.assert_allclose(rs, np.linspace(2.125, 3.875, 8)) - assert grid.contains_point(grid.get_random_point(coords="cartesian")) - ps = [grid.get_random_point(coords="cartesian") for _ in range(2)] + assert grid.contains_point(grid.get_random_point(coords="cartesian", rng=rng)) + ps = [grid.get_random_point(coords="cartesian", rng=rng) for _ in range(2)] assert all(grid.contains_point(ps)) - ps = grid.get_random_point(coords="cartesian", boundary_distance=1.49) + ps = grid.get_random_point(coords="cartesian", boundary_distance=1.49, rng=rng) assert grid.contains_point(ps) assert "laplace" in grid.operators diff --git a/tests/grids/test_generic_grids.py b/tests/grids/test_generic_grids.py index c0b6138d..61ed45ea 100644 --- a/tests/grids/test_generic_grids.py +++ b/tests/grids/test_generic_grids.py @@ -38,11 +38,11 @@ def test_basic_grid_properties(grid): grid.shape = 12 -def test_discretize(): +def test_discretize(rng): """test the discretize function""" - x_min = np.random.uniform(0, 1) - x_max = np.random.uniform(2, 3) - num = np.random.randint(5, 8) + x_min = rng.uniform(0, 1) + x_max = rng.uniform(2, 3) + num = rng.integers(5, 8) x, dx = discretize_interval(x_min, x_max, num) assert dx == pytest.approx((x_max - x_min) / num) x_expect = np.linspace(x_min + dx / 2, x_max - dx / 2, num) @@ -85,12 +85,12 @@ def test_iter_mirror_points(): @pytest.mark.parametrize("grid", iter_grids()) -def test_coordinate_conversion(grid): +def test_coordinate_conversion(grid, rng): """test the conversion between cells and points""" p_empty = np.zeros((0, grid.dim)) c_empty = np.zeros((0, grid.num_axes)) - p = grid.get_random_point(coords="grid") + p = grid.get_random_point(coords="grid", rng=rng) for coords in ["cartesian", "cell", "grid"]: # test empty conversion assert grid.transform(p_empty, "cartesian", coords).size == 0 @@ -106,9 +106,9 @@ def test_coordinate_conversion(grid): @pytest.mark.parametrize("grid", iter_grids()) -def test_integration_serial(grid): +def test_integration_serial(grid, rng): """test integration of fields""" - arr = np.random.randn(*grid.shape) + arr = rng.normal(size=grid.shape) res = grid.make_integrator()(arr) assert np.isscalar(res) assert res == pytest.approx(grid.integrate(arr)) diff --git a/tests/grids/test_grid_mesh.py b/tests/grids/test_grid_mesh.py index 9dcaa505..25836b3b 100644 --- a/tests/grids/test_grid_mesh.py +++ b/tests/grids/test_grid_mesh.py @@ -45,13 +45,13 @@ def test_generic_meshes(grid, decomposition): @pytest.mark.parametrize("decomp", [(1, 1), (2, 1), (1, 2), (2, 2)]) -def test_split_fields(decomp): +def test_split_fields(decomp, rng): """test splitting and recombining fields""" grid = UnitGrid([8, 8]) mesh = GridMesh.from_grid(grid, decomp) field = ScalarField(grid) - field._data_full = np.random.uniform(size=grid._shape_full) + field._data_full = rng.uniform(size=grid._shape_full) subfields = [mesh.extract_subfield(field, node_id) for node_id in range(len(mesh))] field_comb = mesh.combine_field_data([f.data for f in subfields]) @@ -61,14 +61,13 @@ def test_split_fields(decomp): @pytest.mark.multiprocessing @pytest.mark.parametrize("decomp", [(-1,), (-1, 1), (1, -1)]) @pytest.mark.parametrize("dtype", [int, float, complex]) -def test_split_fields_mpi(decomp, dtype): +def test_split_fields_mpi(decomp, dtype, rng): """test splitting and recombining fields using multiprocessing""" dim = len(decomp) grid = UnitGrid([8] * dim) mesh = GridMesh.from_grid(grid, decomp) field = ScalarField(grid, dtype=dtype) - rng = np.random.default_rng(0) if dtype == int: field._data_full = rng.integers(0, 10, size=grid._shape_full) elif dtype == complex: @@ -109,13 +108,12 @@ def test_split_fields_mpi(decomp, dtype): @pytest.mark.multiprocessing @pytest.mark.parametrize("decomp", [(-1,), (-1, 1), (1, -1)]) -def test_split_fieldcollections_mpi(decomp): +def test_split_fieldcollections_mpi(decomp, rng): """test splitting and recombining field collections using multiprocessing""" dim = len(decomp) grid = UnitGrid([8] * dim) mesh = GridMesh.from_grid(grid, decomp) - rng = np.random.default_rng(0) sf = ScalarField.random_uniform(grid, rng=rng) vf = VectorField.random_uniform(grid, rng=rng) fc = FieldCollection([sf, vf], labels=["s", "v"]) @@ -157,12 +155,12 @@ def test_split_fieldcollections_mpi(decomp): @pytest.mark.multiprocessing @pytest.mark.parametrize("bc", ["periodic", "value", "derivative", "curvature"]) -def test_boundary_conditions_numpy(bc): +def test_boundary_conditions_numpy(bc, rng): """test setting boundary conditions using numpy""" grid = UnitGrid([8, 8], periodic=(bc == "periodic")) mesh = GridMesh.from_grid(grid) - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) # split without ghost cells f1 = mesh.split_field_mpi(field) @@ -178,12 +176,12 @@ def test_boundary_conditions_numpy(bc): @pytest.mark.multiprocessing @pytest.mark.parametrize("bc", ["periodic", "value", "derivative", "curvature"]) -def test_boundary_conditions_numba(bc): +def test_boundary_conditions_numba(bc, rng): """test setting boundary conditions using numba""" grid = UnitGrid([8, 8], periodic=(bc == "periodic")) mesh = GridMesh.from_grid(grid) - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) # split without ghost cells f1 = mesh.split_field_mpi(field) @@ -200,12 +198,12 @@ def test_boundary_conditions_numba(bc): @pytest.mark.multiprocessing -def test_vector_boundary_conditions(): +def test_vector_boundary_conditions(rng): """test setting vectorial boundary conditions""" grid = UnitGrid([8, 8]) mesh = GridMesh.from_grid(grid) - field = VectorField.random_uniform(grid) + field = VectorField.random_uniform(grid, rng=rng) # split without ghost cells f1 = mesh.split_field_mpi(field) @@ -221,9 +219,9 @@ def test_vector_boundary_conditions(): @pytest.mark.multiprocessing @pytest.mark.parametrize("grid, decomposition", GRIDS) -def test_noncartesian_grids(grid, decomposition): +def test_noncartesian_grids(grid, decomposition, rng): """test whether we can deal with non-cartesian grids""" - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) eq = DiffusionPDE() args = { diff --git a/tests/grids/test_spherical_grids.py b/tests/grids/test_spherical_grids.py index 09fcb281..1cac3645 100644 --- a/tests/grids/test_spherical_grids.py +++ b/tests/grids/test_spherical_grids.py @@ -9,7 +9,7 @@ from pde.grids.boundaries.local import NeumannBC -def test_polar_grid(): +def test_polar_grid(rng): """test simple polar grid""" grid = PolarSymGrid(4, 8) assert grid.dim == 2 @@ -25,17 +25,17 @@ def test_polar_grid(): np.testing.assert_allclose(grid.axes_coords[0], np.linspace(0.25, 3.75, 8)) - a = grid.make_operator("laplace", "auto_periodic_neumann")(np.random.random(8)) + a = grid.make_operator("laplace", "auto_periodic_neumann")(rng.random(8)) assert a.shape == (8,) assert np.all(np.isfinite(a)) - assert grid.contains_point(grid.get_random_point(coords="cartesian")) - p = grid.get_random_point(boundary_distance=3.99, coords="cartesian") + assert grid.contains_point(grid.get_random_point(coords="cartesian", rng=rng)) + p = grid.get_random_point(boundary_distance=3.99, coords="cartesian", rng=rng) assert grid.contains_point(p) assert "laplace" in grid.operators -def test_polar_annulus(): +def test_polar_annulus(rng): """test simple polar grid with a hole""" grid = PolarSymGrid((2, 4), 8) assert grid.dim == 2 @@ -52,12 +52,12 @@ def test_polar_annulus(): np.testing.assert_allclose(grid.axes_coords[0], np.linspace(2.125, 3.875, 8)) - a = grid.make_operator("laplace", "auto_periodic_neumann")(np.random.random(8)) + a = grid.make_operator("laplace", "auto_periodic_neumann")(rng.random(8)) assert a.shape == (8,) assert np.all(np.isfinite(a)) - assert grid.contains_point(grid.get_random_point(coords="cartesian")) - p = grid.get_random_point(boundary_distance=1.99, coords="cartesian") + assert grid.contains_point(grid.get_random_point(coords="cartesian", rng=rng)) + p = grid.get_random_point(boundary_distance=1.99, coords="cartesian", rng=rng) assert grid.contains_point(p) # test boundary points @@ -79,7 +79,7 @@ def test_polar_to_cartesian(): np.testing.assert_allclose(pf_cart1.data, pf_cart2.data, atol=0.1) -def test_spherical_grid(): +def test_spherical_grid(rng): """test simple spherical grid""" grid = SphericalSymGrid(4, 8) assert grid.dim == 3 @@ -95,17 +95,17 @@ def test_spherical_grid(): np.testing.assert_allclose(grid.axes_coords[0], np.linspace(0.25, 3.75, 8)) - a = grid.make_operator("laplace", "auto_periodic_neumann")(np.random.random(8)) + a = grid.make_operator("laplace", "auto_periodic_neumann")(rng.random(8)) assert a.shape == (8,) assert np.all(np.isfinite(a)) - assert grid.contains_point(grid.get_random_point(coords="cartesian")) - p = grid.get_random_point(boundary_distance=3.99, coords="cartesian") + assert grid.contains_point(grid.get_random_point(coords="cartesian", rng=rng)) + p = grid.get_random_point(boundary_distance=3.99, coords="cartesian", rng=rng) assert grid.contains_point(p) assert "laplace" in grid.operators -def test_spherical_annulus(): +def test_spherical_annulus(rng): """test simple spherical grid with a hole""" grid = SphericalSymGrid((2, 4), 8) assert grid.dim == 3 @@ -122,12 +122,12 @@ def test_spherical_annulus(): np.testing.assert_allclose(grid.axes_coords[0], np.linspace(2.125, 3.875, 8)) - a = grid.make_operator("laplace", "auto_periodic_neumann")(np.random.random(8)) + a = grid.make_operator("laplace", "auto_periodic_neumann")(rng.random(8)) assert a.shape == (8,) assert np.all(np.isfinite(a)) - assert grid.contains_point(grid.get_random_point(coords="cartesian")) - p = grid.get_random_point(boundary_distance=1.99, coords="cartesian") + assert grid.contains_point(grid.get_random_point(coords="cartesian", rng=rng)) + p = grid.get_random_point(boundary_distance=1.99, coords="cartesian", rng=rng) assert grid.contains_point(p) # test boundary points diff --git a/tests/pdes/test_diffusion_pdes.py b/tests/pdes/test_diffusion_pdes.py index d686aafb..46202119 100644 --- a/tests/pdes/test_diffusion_pdes.py +++ b/tests/pdes/test_diffusion_pdes.py @@ -9,7 +9,7 @@ from pde import CartesianGrid, DiffusionPDE, MemoryStorage, ScalarField, UnitGrid -def test_diffusion_single(): +def test_diffusion_single(rng): """test some methods of the simple diffusion model""" eq = DiffusionPDE() assert isinstance(str(eq), str) @@ -17,17 +17,17 @@ def test_diffusion_single(): assert not eq.explicit_time_dependence grid = UnitGrid([4, 4]) - state = ScalarField.random_uniform(grid) + state = ScalarField.random_uniform(grid, rng=rng) field = eq.evolution_rate(state) assert isinstance(field, ScalarField) assert field.grid == grid -def test_simple_diffusion_value(): +def test_simple_diffusion_value(rng): """test a simple diffusion equation with constant boundaries""" grid = CartesianGrid([[0, 1]], [16]) - c = ScalarField.random_uniform(grid, 0, 1) + c = ScalarField.random_uniform(grid, 0, 1, rng=rng) b_l = {"type": "value", "value": 0} b_r = {"type": "value", "value": 1} pde = DiffusionPDE(bc=[b_l, b_r]) @@ -36,10 +36,10 @@ def test_simple_diffusion_value(): np.testing.assert_allclose(sol.data, grid.axes_coords[0], rtol=5e-3) -def test_simple_diffusion_flux_right(): +def test_simple_diffusion_flux_right(rng): """test a simple diffusion equation with flux boundary on the right""" grid = CartesianGrid([[0, 1]], [16]) - c = ScalarField.random_uniform(grid, 0, 1) + c = ScalarField.random_uniform(grid, 0, 1, rng=rng) b_l = {"type": "value", "value": 0} b_r = {"type": "derivative", "value": 3} pde = DiffusionPDE(bc=[b_l, b_r]) @@ -47,10 +47,10 @@ def test_simple_diffusion_flux_right(): np.testing.assert_allclose(sol.data, 3 * grid.axes_coords[0], rtol=5e-3) -def test_simple_diffusion_flux_left(): +def test_simple_diffusion_flux_left(rng): """test a simple diffusion equation with flux boundary on the left""" grid = CartesianGrid([[0, 1]], [16]) - c = ScalarField.random_uniform(grid, 0, 1) + c = ScalarField.random_uniform(grid, 0, 1, rng=rng) b_l = {"type": "derivative", "value": 2} b_r = {"type": "value", "value": 0} pde = DiffusionPDE(bc=[b_l, b_r]) @@ -58,10 +58,10 @@ def test_simple_diffusion_flux_left(): np.testing.assert_allclose(sol.data, 2 - 2 * grid.axes_coords[0], rtol=5e-3) -def test_diffusion_cached(): +def test_diffusion_cached(rng): """test some caching of rhs of the simple diffusion model""" grid = UnitGrid([8]) - c0 = ScalarField.random_uniform(grid) + c0 = ScalarField.random_uniform(grid, rng=rng) # first run without cache eq1 = DiffusionPDE(diffusivity=1) @@ -109,11 +109,11 @@ def test_diffusion_time_dependent_bcs(backend): @pytest.mark.parametrize("backend", ["numpy", "numba"]) -def test_diffusion_sde(backend, rng): +def test_diffusion_sde(backend): """test scaling of noise using a stochastic diffusion equation""" # we disable diffusivity to have a simple analytical solution var_local, t_range = 0.35, 0.1 - eq = DiffusionPDE(diffusivity=0, noise=var_local, rng=rng) + eq = DiffusionPDE(diffusivity=0, noise=var_local) grid = CartesianGrid([[0, 1000]], 3700) field = ScalarField(grid) sol = eq.solve(field, t_range=t_range, dt=1e-4, backend=backend, tracker=None) diff --git a/tests/pdes/test_generic_pdes.py b/tests/pdes/test_generic_pdes.py index 94eba131..64f41563 100644 --- a/tests/pdes/test_generic_pdes.py +++ b/tests/pdes/test_generic_pdes.py @@ -20,7 +20,7 @@ pdes.SwiftHohenbergPDE, ], ) -def test_pde_consistency(pde_class, dim): +def test_pde_consistency(pde_class, dim, rng): """test some methods of generic PDE models""" eq = pde_class() assert isinstance(str(eq), str) @@ -28,7 +28,7 @@ def test_pde_consistency(pde_class, dim): # compare numba to numpy implementation grid = UnitGrid([4] * dim) - state = ScalarField.random_uniform(grid) + state = ScalarField.random_uniform(grid, rng=rng) field = eq.evolution_rate(state) assert field.grid == grid rhs = eq._make_pde_rhs_numba(state) @@ -41,7 +41,7 @@ def test_pde_consistency(pde_class, dim): np.testing.assert_allclose(field.data, eq2.evolution_rate(state).data) -def test_pde_consistency_test(): +def test_pde_consistency_test(rng): """test whether the consistency of a pde implementation is checked""" class TestPDE(pdes.PDEBase): @@ -55,6 +55,6 @@ def impl(state_data, t): return impl eq = TestPDE() - state = ScalarField.random_uniform(UnitGrid([4])) + state = ScalarField.random_uniform(UnitGrid([4]), rng=rng) with pytest.raises(AssertionError): eq.solve(state, t_range=5, tracker=None) diff --git a/tests/pdes/test_pde_class.py b/tests/pdes/test_pde_class.py index e197f32a..69979ac3 100644 --- a/tests/pdes/test_pde_class.py +++ b/tests/pdes/test_pde_class.py @@ -23,7 +23,7 @@ def iter_grids(): yield grids.PolarSymGrid(2, 2) -def test_pde_critical_input(): +def test_pde_critical_input(rng): """test some wrong input and edge cases""" # test whether reserved symbols can be used as variables grid = grids.UnitGrid([4]) @@ -43,24 +43,24 @@ def test_pde_critical_input(): eq = PDE({"u": 1, "v": 2}) assert eq.expressions == {"u": "1.0", "v": "2.0"} with pytest.raises(ValueError): - eq.evolution_rate(ScalarField.random_uniform(grid)) + eq.evolution_rate(ScalarField.random_uniform(grid, rng=rng)) eq = PDE({"u": "a"}) with pytest.raises(RuntimeError): - eq.evolution_rate(ScalarField.random_uniform(grid)) + eq.evolution_rate(ScalarField.random_uniform(grid, rng=rng)) eq = PDE({"x": "x"}) with pytest.raises(ValueError): eq.evolution_rate(ScalarField(grid)) -def test_pde_scalar(): +def test_pde_scalar(rng): """test PDE with a single scalar field""" eq = PDE({"u": "laplace(u) + exp(-t) + sin(t)"}) assert eq.explicit_time_dependence assert not eq.complex_valued grid = grids.UnitGrid([8]) - field = ScalarField.random_normal(grid) + field = ScalarField.random_normal(grid, rng=rng) res_a = eq.solve(field, t_range=1, dt=0.01, backend="numpy", tracker=None) res_b = eq.solve(field, t_range=1, dt=0.01, backend="numba", tracker=None) @@ -69,13 +69,13 @@ def test_pde_scalar(): np.testing.assert_allclose(res_a.data, res_b.data) -def test_pde_vector(): +def test_pde_vector(rng): """test PDE with a single vector field""" eq = PDE({"u": "vector_laplace(u) + exp(-t)"}) assert eq.explicit_time_dependence assert not eq.complex_valued grid = grids.UnitGrid([8, 8]) - field = VectorField.random_normal(grid).smooth(1) + field = VectorField.random_normal(grid, rng=rng).smooth(1) res_a = eq.solve(field, t_range=1, dt=0.01, backend="numpy", tracker=None) res_b = eq.solve(field, t_range=1, dt=0.01, backend="numba", tracker=None) @@ -85,13 +85,13 @@ def test_pde_vector(): @pytest.mark.multiprocessing -def test_pde_vector_mpi(): +def test_pde_vector_mpi(rng): """test PDE with a single vector field using multiprocessing""" eq = PDE({"u": "vector_laplace(u) + exp(-t)"}) assert eq.explicit_time_dependence assert not eq.complex_valued grid = grids.UnitGrid([8, 8]) - field = VectorField.random_normal(grid).smooth(1) + field = VectorField.random_normal(grid, rng=rng).smooth(1) args = { "state": field, @@ -123,7 +123,7 @@ def test_pde_2scalar(): @pytest.mark.slow -def test_pde_vector_scalar(): +def test_pde_vector_scalar(rng): """test PDE with a vector and a scalar field""" eq = PDE({"u": "vector_laplace(u) - u + gradient(v)", "v": "- divergence(u)"}) assert not eq.explicit_time_dependence @@ -131,8 +131,8 @@ def test_pde_vector_scalar(): grid = grids.UnitGrid([8, 8]) field = FieldCollection( [ - VectorField.random_uniform(grid).smooth(1), - ScalarField.random_uniform(grid).smooth(1), + VectorField.random_uniform(grid, rng=rng).smooth(1), + ScalarField.random_uniform(grid, rng=rng).smooth(1), ] ) @@ -144,9 +144,9 @@ def test_pde_vector_scalar(): @pytest.mark.parametrize("grid", iter_grids()) -def test_compare_swift_hohenberg(grid): +def test_compare_swift_hohenberg(grid, rng): """compare custom class to swift-Hohenberg""" - rate, kc2, delta = np.random.uniform(0.5, 2, size=3) + rate, kc2, delta = rng.uniform(0.5, 2, size=3) eq1 = SwiftHohenbergPDE(rate=rate, kc2=kc2, delta=delta) eq2 = PDE( { @@ -157,7 +157,7 @@ def test_compare_swift_hohenberg(grid): assert eq1.explicit_time_dependence == eq2.explicit_time_dependence assert eq1.complex_valued == eq2.complex_valued - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) res1 = eq1.solve(field, t_range=1, dt=0.01, backend="numpy", tracker=None) res2 = eq2.solve(field, t_range=1, dt=0.01, backend="numpy", tracker=None) @@ -165,10 +165,10 @@ def test_compare_swift_hohenberg(grid): np.testing.assert_allclose(res1.data, res2.data) -def test_custom_operators(): +def test_custom_operators(rng): """test using a custom operator""" grid = grids.UnitGrid([32]) - field = ScalarField.random_normal(grid) + field = ScalarField.random_normal(grid, rng=rng) eq = PDE({"u": "undefined(u)"}) with pytest.raises(ValueError): @@ -190,18 +190,18 @@ def op(arr, out): @pytest.mark.parametrize("backend", ["numpy", "numba"]) -def test_pde_noise(backend, rng): +def test_pde_noise(backend): """test noise operator on PDE class""" grid = grids.UnitGrid([128, 128]) state = FieldCollection([ScalarField(grid), ScalarField(grid)]) var_local = 0.5 - eq = PDE({"a": 0, "b": 0}, noise=var_local, rng=rng) + eq = PDE({"a": 0, "b": 0}, noise=var_local) res = eq.solve(state, t_range=1, backend=backend, dt=1, tracker=None) dist = stats.norm(scale=np.sqrt(var_local)).cdf assert stats.kstest(np.ravel(res.data), dist).pvalue > 0.001 - eq = PDE({"a": 0, "b": 0}, noise=[0.01, 2.0], rng=rng) + eq = PDE({"a": 0, "b": 0}, noise=[0.01, 2.0]) res = eq.solve(state, t_range=1, backend=backend, dt=1, tracker=None) dist_a = stats.norm(scale=np.sqrt(0.01)).cdf @@ -210,7 +210,7 @@ def test_pde_noise(backend, rng): assert stats.kstest(np.ravel(res[1].data), dist_b).pvalue > 0.001 with pytest.raises(ValueError): - eq = PDE({"a": 0}, noise=[0.01, 2.0], rng=rng) + eq = PDE({"a": 0}, noise=[0.01, 2.0]) eq.solve(ScalarField(grid), t_range=1, backend=backend, dt=1, tracker=None) @@ -235,11 +235,11 @@ def test_pde_spatial_args(backend): rhs(field.data, 0.0) -def test_pde_user_funcs(): +def test_pde_user_funcs(rng): """test user supplied functions""" # test a simple case eq = PDE({"u": "get_x(gradient(u))"}, user_funcs={"get_x": lambda arr: arr[0]}) - field = ScalarField.random_colored(grids.UnitGrid([32, 32])) + field = ScalarField.random_colored(grids.UnitGrid([32, 32]), rng=rng) rhs = eq.evolution_rate(field) np.testing.assert_allclose( rhs.data, field.gradient("auto_periodic_neumann").data[0] @@ -250,13 +250,13 @@ def test_pde_user_funcs(): ) -def test_pde_complex_serial(): +def test_pde_complex_serial(rng): """test complex valued PDE""" eq = PDE({"p": "I * laplace(p)"}) assert not eq.explicit_time_dependence assert eq.complex_valued - field = ScalarField.random_uniform(grids.UnitGrid([4])) + field = ScalarField.random_uniform(grids.UnitGrid([4]), rng=rng) assert not field.is_complex res1 = eq.solve(field, t_range=1, dt=0.1, backend="numpy", tracker=None) assert res1.is_complex @@ -267,13 +267,13 @@ def test_pde_complex_serial(): @pytest.mark.multiprocessing -def test_pde_complex_mpi(): +def test_pde_complex_mpi(rng): """test complex valued PDE""" eq = PDE({"p": "I * laplace(p)"}) assert not eq.explicit_time_dependence assert eq.complex_valued - field = ScalarField.random_uniform(grids.UnitGrid([4])) + field = ScalarField.random_uniform(grids.UnitGrid([4]), rng=rng) assert not field.is_complex args = { @@ -349,13 +349,13 @@ def test_pde_consts(): @pytest.mark.parametrize("bc", ["auto_periodic_neumann", {"value": 1}]) -def test_pde_bcs(bc): +def test_pde_bcs(bc, rng): """test PDE with boundary conditions""" eq = PDE({"u": "laplace(u)"}, bc=bc) assert not eq.explicit_time_dependence assert not eq.complex_valued grid = grids.UnitGrid([8]) - field = ScalarField.random_normal(grid) + field = ScalarField.random_normal(grid, rng=rng) res_a = eq.solve(field, t_range=1, dt=0.01, backend="numpy", tracker=None) res_b = eq.solve(field, t_range=1, dt=0.01, backend="numba", tracker=None) @@ -378,11 +378,11 @@ def test_pde_bcs_warning(caplog): @pytest.mark.parametrize("bc", ["asdf", [{"value": 1}] * 3]) -def test_pde_bcs_error(bc): +def test_pde_bcs_error(bc, rng): """test PDE with wrong boundary conditions""" eq = PDE({"u": "laplace(u)"}, bc=bc) grid = grids.UnitGrid([8, 8]) - field = ScalarField.random_normal(grid) + field = ScalarField.random_normal(grid, rng=rng) for backend in ["numpy", "numba"]: with pytest.raises(BCDataError): @@ -404,10 +404,10 @@ def test_pde_time_dependent_bcs(backend): @pytest.mark.parametrize("backend", ["numpy", "numba"]) -def test_pde_integral(backend): +def test_pde_integral(backend, rng): """test PDE with integral""" grid = grids.UnitGrid([16]) - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) eq = PDE({"c": "-integral(c)"}) # test rhs diff --git a/tests/pdes/test_wave_pdes.py b/tests/pdes/test_wave_pdes.py index 9057cc02..d7dcb8ca 100644 --- a/tests/pdes/test_wave_pdes.py +++ b/tests/pdes/test_wave_pdes.py @@ -9,7 +9,7 @@ @pytest.mark.parametrize("dim", [1, 2]) -def test_wave_consistency(dim): +def test_wave_consistency(dim, rng): """test some methods of the wave model""" eq = WavePDE() assert isinstance(str(eq), str) @@ -17,7 +17,7 @@ def test_wave_consistency(dim): # compare numba to numpy implementation grid = UnitGrid([4] * dim) - state = eq.get_initial_condition(ScalarField.random_uniform(grid)) + state = eq.get_initial_condition(ScalarField.random_uniform(grid, rng=rng)) field = eq.evolution_rate(state) assert field.grid == grid rhs = eq._make_pde_rhs_numba(state) diff --git a/tests/solvers/test_explicit_mpi_solvers.py b/tests/solvers/test_explicit_mpi_solvers.py index 804f29b7..584d0e38 100644 --- a/tests/solvers/test_explicit_mpi_solvers.py +++ b/tests/solvers/test_explicit_mpi_solvers.py @@ -14,11 +14,11 @@ @pytest.mark.parametrize( "scheme, decomposition", [("euler", [1, -1]), ("runge-kutta", [-1, 1])] ) -def test_simple_pde_mpi(scheme, decomposition): +def test_simple_pde_mpi(scheme, decomposition, rng): """test setting boundary conditions using numba""" grid = UnitGrid([8, 8], periodic=[True, False]) - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) eq = DiffusionPDE() args = { @@ -54,9 +54,9 @@ def test_simple_pde_mpi(scheme, decomposition): @pytest.mark.multiprocessing @pytest.mark.parametrize("backend", ["numba", "numpy"]) -def test_stochastic_mpi_solvers(backend): +def test_stochastic_mpi_solvers(backend, rng): """test simple version of the stochastic solver""" - field = ScalarField.random_uniform(UnitGrid([16]), -1, 1) + field = ScalarField.random_uniform(UnitGrid([16]), -1, 1, rng=rng) eq = DiffusionPDE() seq = DiffusionPDE(noise=1e-10) diff --git a/tests/solvers/test_explicit_solvers.py b/tests/solvers/test_explicit_solvers.py index 340deb72..64f1b5fe 100644 --- a/tests/solvers/test_explicit_solvers.py +++ b/tests/solvers/test_explicit_solvers.py @@ -95,9 +95,9 @@ def test_solvers_time_dependent(scheme, adaptive): @pytest.mark.parametrize("backend", ["numba", "numpy"]) -def test_stochastic_solvers(backend): +def test_stochastic_solvers(backend, rng): """test simple version of the stochastic solver""" - field = ScalarField.random_uniform(UnitGrid([16]), -1, 1) + field = ScalarField.random_uniform(UnitGrid([16]), -1, 1, rng=rng) eq = DiffusionPDE() seq = DiffusionPDE(noise=1e-10) @@ -117,9 +117,9 @@ def test_stochastic_solvers(backend): assert not solver2.info.get("dt_adaptive", False) -def test_stochastic_adaptive_solver(caplog): +def test_stochastic_adaptive_solver(caplog, rng): """test using an adaptive, stochastic solver""" - field = ScalarField.random_uniform(UnitGrid([16]), -1, 1) + field = ScalarField.random_uniform(UnitGrid([16]), -1, 1, rng=rng) eq = DiffusionPDE(noise=1e-6) with pytest.raises(RuntimeError): @@ -128,9 +128,9 @@ def test_stochastic_adaptive_solver(caplog): c.run(field, dt=1e-2) -def test_unsupported_stochastic_solvers(): +def test_unsupported_stochastic_solvers(rng): """test some solvers that do not support stochasticity""" - field = ScalarField.random_uniform(UnitGrid([16]), -1, 1) + field = ScalarField.random_uniform(UnitGrid([16]), -1, 1, rng=rng) eq = DiffusionPDE(noise=1) with pytest.raises(RuntimeError): diff --git a/tests/solvers/test_generic_solvers.py b/tests/solvers/test_generic_solvers.py index 697d10ff..3a66f0e7 100644 --- a/tests/solvers/test_generic_solvers.py +++ b/tests/solvers/test_generic_solvers.py @@ -24,17 +24,17 @@ def test_solver_registration(): assert "scipy" in solvers -def test_solver_in_pde_class(): +def test_solver_in_pde_class(rng): """test whether solver instances can be used in pde instances""" - field = ScalarField.random_uniform(UnitGrid([16, 16]), -1, 1) + field = ScalarField.random_uniform(UnitGrid([16, 16]), -1, 1, rng=rng) eq = DiffusionPDE() eq.solve(field, t_range=1, solver=ScipySolver, tracker=None) @pytest.mark.parametrize("solver_class", [ExplicitSolver, ImplicitSolver, ScipySolver]) -def test_compare_solvers(solver_class): +def test_compare_solvers(solver_class, rng): """compare several solvers""" - field = ScalarField.random_uniform(UnitGrid([8, 8]), -1, 1) + field = ScalarField.random_uniform(UnitGrid([8, 8]), -1, 1, rng=rng) eq = DiffusionPDE() # ground truth diff --git a/tests/solvers/test_scipy_solvers.py b/tests/solvers/test_scipy_solvers.py index d20df710..7816ad58 100644 --- a/tests/solvers/test_scipy_solvers.py +++ b/tests/solvers/test_scipy_solvers.py @@ -8,10 +8,10 @@ from pde.solvers import Controller, ScipySolver -def test_scipy_no_dt(): +def test_scipy_no_dt(rng): """test scipy solver without timestep""" grid = UnitGrid([16]) - field = ScalarField.random_uniform(grid, -1, 1) + field = ScalarField.random_uniform(grid, -1, 1, rng=rng) eq = DiffusionPDE() c1 = Controller(ScipySolver(eq), t_range=1, tracker=None) diff --git a/tests/storage/test_file_storages.py b/tests/storage/test_file_storages.py index 4e0589a8..759641a9 100644 --- a/tests/storage/test_file_storages.py +++ b/tests/storage/test_file_storages.py @@ -78,7 +78,7 @@ def assert_storage_content(storage, expect): @skipUnlessModule("h5py") @pytest.mark.parametrize("compression", [True, False]) -def test_simulation_persistence(compression, tmp_path): +def test_simulation_persistence(compression, tmp_path, rng): """test whether a tracker can accurately store information about simulation""" path = tmp_path / "test_simulation_persistence.hdf5" storage = FileStorage(path, compression=compression) @@ -86,7 +86,7 @@ def test_simulation_persistence(compression, tmp_path): # write some simulation data pde = DiffusionPDE() grid = UnitGrid([16, 16]) # generate grid - state = ScalarField.random_uniform(grid, 0.2, 0.3) + state = ScalarField.random_uniform(grid, 0.2, 0.3, rng=rng) pde.solve(state, t_range=0.11, dt=0.001, tracker=storage.tracker(interval=0.05)) storage.close() @@ -182,14 +182,14 @@ def test_keep_opened(tmp_path): @skipUnlessModule("h5py") @pytest.mark.parametrize("dtype", [bool, float, complex]) -def test_write_types(dtype, tmp_path): +def test_write_types(dtype, tmp_path, rng): """test whether complex data can be written""" path = tmp_path / "test_type_writing.hdf5" grid = UnitGrid([32]) - c = ScalarField.random_uniform(grid).copy(dtype=dtype) + c = ScalarField.random_uniform(grid, rng=rng).copy(dtype=dtype) if dtype == complex: - c += 1j * ScalarField.random_uniform(grid) + c += 1j * ScalarField.random_uniform(grid, rng=rng) storage = FileStorage(path, keep_opened=False) storage.start_writing(c) diff --git a/tests/storage/test_generic_storages.py b/tests/storage/test_generic_storages.py index 465659d4..745fb9b9 100644 --- a/tests/storage/test_generic_storages.py +++ b/tests/storage/test_generic_storages.py @@ -65,7 +65,7 @@ def test_storage_write(storage_factory): np.testing.assert_allclose(storage.times, np.arange(3)) -def test_storage_truncation(tmp_path): +def test_storage_truncation(tmp_path, rng): """test whether simple trackers can be used""" file = tmp_path / "test_storage_truncation.hdf5" for truncate in [True, False]: @@ -75,7 +75,7 @@ def test_storage_truncation(tmp_path): tracker_list = [s.tracker(interval=0.01) for s in storages] grid = UnitGrid([8, 8]) - state = ScalarField.random_uniform(grid, 0.2, 0.3) + state = ScalarField.random_uniform(grid, 0.2, 0.3, rng=rng) eq = DiffusionPDE() eq.solve(state, t_range=0.1, dt=0.001, tracker=tracker_list) @@ -136,12 +136,12 @@ def test_storing_extract_range(storage_factory): @pytest.mark.parametrize("storage_class", STORAGE_CLASSES) -def test_storing_collection(storage_factory): +def test_storing_collection(storage_factory, rng): """test methods specific to FieldCollections in memory storage""" grid = UnitGrid([2, 2]) - f1 = ScalarField.random_uniform(grid, 0.1, 0.4, label="a") - f2 = VectorField.random_uniform(grid, 0.1, 0.4, label="b") - f3 = Tensor2Field.random_uniform(grid, 0.1, 0.4, label="c") + f1 = ScalarField.random_uniform(grid, 0.1, 0.4, label="a", rng=rng) + f2 = VectorField.random_uniform(grid, 0.1, 0.4, label="b", rng=rng) + f3 = Tensor2Field.random_uniform(grid, 0.1, 0.4, label="c", rng=rng) fc = FieldCollection([f1, f2, f3]) # store some data @@ -223,12 +223,12 @@ def test_storage_copy(storage_factory): @pytest.mark.parametrize("storage_class", STORAGE_CLASSES) @pytest.mark.parametrize("dtype", [bool, complex]) -def test_storage_types(storage_factory, dtype): +def test_storage_types(storage_factory, dtype, rng): """test storing different types""" grid = UnitGrid([32]) - field = ScalarField.random_uniform(grid).copy(dtype=dtype) + field = ScalarField.random_uniform(grid, rng=rng).copy(dtype=dtype) if dtype == complex: - field += 1j * ScalarField.random_uniform(grid) + field += 1j * ScalarField.random_uniform(grid, rng=rng) s = storage_factory() s.start_writing(field) @@ -244,11 +244,11 @@ def test_storage_types(storage_factory, dtype): @pytest.mark.multiprocessing @pytest.mark.parametrize("storage_class", STORAGE_CLASSES) -def test_storage_mpi(storage_factory): +def test_storage_mpi(storage_factory, rng): """test writing data using MPI""" eq = DiffusionPDE() grid = UnitGrid([8]) - field = ScalarField.random_normal(grid).smooth(1) + field = ScalarField.random_normal(grid, rng=rng).smooth(1) storage = storage_factory() res = eq.solve( @@ -261,10 +261,10 @@ def test_storage_mpi(storage_factory): @pytest.mark.parametrize("storage_class", STORAGE_CLASSES) -def test_storing_transformation_collection(storage_factory): +def test_storing_transformation_collection(storage_factory, rng): """test transformation yielding field collections in storage classes""" grid = UnitGrid([8]) - field = ScalarField.random_normal(grid).smooth(1) + field = ScalarField.random_normal(grid, rng=rng).smooth(1) def trans1(field, t): return FieldCollection([field, 2 * field + t]) @@ -287,10 +287,10 @@ def trans1(field, t): @pytest.mark.parametrize("storage_class", STORAGE_CLASSES) -def test_storing_transformation_scalar(storage_factory): +def test_storing_transformation_scalar(storage_factory, rng): """test transformations yielding scalar fields in storage classes""" grid = UnitGrid([8]) - field = ScalarField.random_normal(grid).smooth(1) + field = ScalarField.random_normal(grid, rng=rng).smooth(1) storage = storage_factory() eq = DiffusionPDE(diffusivity=0) diff --git a/tests/storage/test_memory_storages.py b/tests/storage/test_memory_storages.py index cb48cdb9..4c3982ca 100644 --- a/tests/storage/test_memory_storages.py +++ b/tests/storage/test_memory_storages.py @@ -37,11 +37,11 @@ def test_memory_storage(): np.testing.assert_allclose(np.ravel(s3.data), np.arange(4)) -def test_field_type_guessing(): +def test_field_type_guessing(rng): """test the ability to guess the field type""" for cls in [ScalarField, VectorField, Tensor2Field]: grid = UnitGrid([3]) - field = cls.random_normal(grid) + field = cls.random_normal(grid, rng=rng) s = MemoryStorage() s.start_writing(field) s.append(field, 0) diff --git a/tests/test_integration.py b/tests/test_integration.py index 83bd9662..f136532b 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -12,9 +12,9 @@ @misc.skipUnlessModule("h5py") -def test_writing_to_storage(tmp_path): +def test_writing_to_storage(tmp_path, rng): """test whether data is written to storage""" - state = ScalarField.random_uniform(UnitGrid([3])) + state = ScalarField.random_uniform(UnitGrid([3]), rng=rng) pde = DiffusionPDE() path = tmp_path / "test_writing_to_storage.hdf5" data = FileStorage(filename=path) @@ -65,7 +65,7 @@ def bc_value(adjacent_value, dx, x, y, t): @pytest.mark.multiprocessing -def test_custom_pde_mpi(caplog): +def test_custom_pde_mpi(caplog, rng): """test a custom PDE using the parallelized solver""" class TestPDE(PDEBase): @@ -91,7 +91,7 @@ def pde_rhs(state_data, t): return pde_rhs grid = UnitGrid([16, 16]) - field = ScalarField.random_uniform(grid) + field = ScalarField.random_uniform(grid, rng=rng) eq = TestPDE() args = { diff --git a/tests/tools/test_cuboid.py b/tests/tools/test_cuboid.py index c4419c9a..eeaddebf 100644 --- a/tests/tools/test_cuboid.py +++ b/tests/tools/test_cuboid.py @@ -80,11 +80,11 @@ def test_cuboid_add(): Cuboid([1], [2]) + Cuboid([1, 2], [1, 1]) -def test_cuboid_nd(): +def test_cuboid_nd(rng): """test Cuboid class in n dimensions""" - dim = np.random.randint(5, 10) - size = np.random.randn(dim) - c = Cuboid(np.random.randn(dim), size) + dim = rng.integers(5, 10) + size = rng.normal(size=dim) + c = Cuboid(rng.normal(size=dim), size) assert c.dim == dim assert c.diagonal == pytest.approx(np.linalg.norm(size)) c2 = Cuboid.from_bounds(c.bounds) @@ -101,11 +101,11 @@ def test_cuboid_nd(): assert c.surface_area == 2 * n * 3 ** (n - 1) -def test_asanyarray_flags(): +def test_asanyarray_flags(rng): """test the asanyarray_flags function""" assert np.arange(3) is not asanyarray_flags(range(3)) - a = np.random.random(3).astype(np.double) + a = rng.random(3).astype(np.double) assert a is asanyarray_flags(a) assert a is asanyarray_flags(a, np.double) assert a is asanyarray_flags(a, writeable=True) diff --git a/tests/tools/test_expressions.py b/tests/tools/test_expressions.py index 0a695b67..c5049003 100644 --- a/tests/tools/test_expressions.py +++ b/tests/tools/test_expressions.py @@ -91,7 +91,7 @@ def test_const(caplog): e.get_compiled()() -def test_single_arg(): +def test_single_arg(rng): """test simple expressions""" e = ScalarExpression("2 * a") assert not e.constant @@ -109,7 +109,7 @@ def test_single_arg(): with pytest.raises(TypeError): e.value - arr = np.random.random(5) + arr = rng.random(5) np.testing.assert_allclose(e(arr), 2 * arr) np.testing.assert_allclose(e.get_compiled()(arr), 2 * arr) @@ -123,7 +123,7 @@ def test_single_arg(): ScalarExpression(np.exp) -def test_two_args(): +def test_two_args(rng): """test simple expressions""" e = ScalarExpression("2 * a ** b") assert e.depends_on("b") @@ -137,7 +137,7 @@ def test_two_args(): assert e.rank == 0 assert e == ScalarExpression(e.expression) - for x in [np.random.random(2), np.random.random((2, 5))]: + for x in [rng.random(2), rng.random((2, 5))]: res = 2 * x[0] ** x[1] np.testing.assert_allclose(e(*x), res) np.testing.assert_allclose(e.get_compiled()(*x), res) diff --git a/tests/tools/test_math.py b/tests/tools/test_math.py index ddece8a5..afd3a573 100644 --- a/tests/tools/test_math.py +++ b/tests/tools/test_math.py @@ -8,23 +8,22 @@ from pde.tools.math import OnlineStatistics, SmoothData1D -def test_SmoothData1D(): +def test_SmoothData1D(rng): """test smoothing""" - rng = np.random.default_rng(1) - x = rng.uniform(0, 1, 128) + x = rng.uniform(0, 1, 500) xs = np.linspace(0, 1, 16)[1:-1] - s = SmoothData1D(x, np.ones_like(x)) + s = SmoothData1D(x, np.ones_like(x), 0.1) np.testing.assert_allclose(s(xs), 1) np.testing.assert_allclose(s.derivative(xs), 0, atol=1e-14) - s = SmoothData1D(x, x, 0.05) + s = SmoothData1D(x, x, 0.02) np.testing.assert_allclose(s(xs), xs, atol=0.1) np.testing.assert_allclose(s.derivative(xs), 1, atol=0.3) s = SmoothData1D(x, np.sin(x), 0.05) np.testing.assert_allclose(s(xs), np.sin(xs), atol=0.1) - np.testing.assert_allclose(s.derivative(xs), np.cos(xs), atol=0.3) + np.testing.assert_allclose(s.derivative(xs)[1:-1], np.cos(xs)[1:-1], atol=0.3) assert -0.1 not in s assert x.min() in s diff --git a/tests/tools/test_plotting_tools.py b/tests/tools/test_plotting_tools.py index 9221a612..85721a0a 100644 --- a/tests/tools/test_plotting_tools.py +++ b/tests/tools/test_plotting_tools.py @@ -4,7 +4,6 @@ import matplotlib.pyplot as plt import matplotlib.testing.compare -import numpy as np import pytest from pde.tools.plotting import add_scaled_colorbar, plot_on_axes, plot_on_figure @@ -37,9 +36,9 @@ def plot(fig): @pytest.mark.interactive -def test_plot_colorbar(tmp_path): +def test_plot_colorbar(tmp_path, rng): """test the plot_on_axes decorator""" - data = np.random.randn(3, 3) + data = rng.normal(size=(3, 3)) # do not specify axis img = plt.imshow(data) diff --git a/tests/tools/test_spectral.py b/tests/tools/test_spectral.py index 3a332c2a..928904d4 100644 --- a/tests/tools/test_spectral.py +++ b/tests/tools/test_spectral.py @@ -37,11 +37,11 @@ def spectral_density(data, dx=1.0): return np.sqrt(k2s), np.abs(res) ** 2 -def test_colored_noise(): +def test_colored_noise(rng): """test the implementation of the colored noise""" grid = UnitGrid([64, 64], periodic=True) for exponent in [0, -1, 2]: - scale = np.random.uniform(1, 10) + scale = rng.uniform(1, 10) noise = make_colored_noise(grid.shape, grid.discretization, exponent, scale) x = noise() assert ( @@ -49,12 +49,12 @@ def test_colored_noise(): ), f"Colored noise with exp={exponent} is not normal distributed" -def test_noise_scaling(): +def test_noise_scaling(rng): """compare the noise strength (in terms of the spectral density of two different noise sources that should be equivalent)""" # create a grid - x, w = 2 + 10 * np.random.random(2) - size = np.random.randint(128, 256) + x, w = 2 + 10 * rng.random(2) + size = rng.integers(128, 256) grid = CartesianGrid([[x, x + w]], size, periodic=True) # colored noise @@ -65,7 +65,7 @@ def test_noise_scaling(): div = grid.make_operator("divergence", bc="auto_periodic_neumann") def noise_div(): - return div(np.random.randn(*shape)) + return div(rng.normal(size=shape)) # calculate spectral densities of the two noises result = [] diff --git a/tests/trackers/test_trackers.py b/tests/trackers/test_trackers.py index f8f469c9..d11d25e2 100644 --- a/tests/trackers/test_trackers.py +++ b/tests/trackers/test_trackers.py @@ -17,7 +17,7 @@ from pde.visualization.movies import Movie -def test_plot_tracker(tmp_path): +def test_plot_tracker(tmp_path, rng): """test whether the plot tracker creates files without errors""" output_file = tmp_path / "img.png" @@ -25,7 +25,7 @@ def get_title(state, t): return f"{state.integral:g} at {t:g}" grid = UnitGrid([4, 4]) - state = ScalarField.random_uniform(grid) + state = ScalarField.random_uniform(grid, rng=rng) eq = DiffusionPDE() tracker = trackers.PlotTracker( output_file=output_file, @@ -41,12 +41,12 @@ def get_title(state, t): @pytest.mark.skipif(not Movie.is_available(), reason="no ffmpeg") -def test_plot_movie_tracker(tmp_path): +def test_plot_movie_tracker(tmp_path, rng): """test whether the plot tracker creates files without errors""" output_file = tmp_path / "movie.mov" grid = UnitGrid([4, 4]) - state = ScalarField.random_uniform(grid) + state = ScalarField.random_uniform(grid, rng=rng) eq = DiffusionPDE() tracker = trackers.PlotTracker( movie=output_file, interval=0.1, show=False, tight_layout=True @@ -66,7 +66,7 @@ def test_simple_progress(): pbar.finalize() -def test_trackers(): +def test_trackers(rng): """test whether simple trackers can be used""" times = [] @@ -88,7 +88,7 @@ def get_data(state): tracker_list.append(trackers.PlotTracker(interval=0.1, show=False)) grid = UnitGrid([16, 16]) - state = ScalarField.random_uniform(grid, 0.2, 0.3) + state = ScalarField.random_uniform(grid, 0.2, 0.3, rng=rng) eq = DiffusionPDE() eq.solve(state, t_range=1, dt=0.005, tracker=tracker_list) @@ -101,7 +101,7 @@ def get_data(state): np.testing.assert_allclose(df["integral"], state.integral) -def test_callback_tracker(): +def test_callback_tracker(rng): """test trackers that support a callback""" data = [] @@ -112,7 +112,7 @@ def get_mean_data(state): return state.average grid = UnitGrid([4, 4]) - state = ScalarField.random_uniform(grid, 0.2, 0.3) + state = ScalarField.random_uniform(grid, 0.2, 0.3, rng=rng) eq = DiffusionPDE() data_tracker = trackers.DataTracker(get_mean_data, interval=0.1) callback_tracker = trackers.CallbackTracker(store_mean_data, interval=0.1) @@ -130,7 +130,7 @@ def get_time(state, t): return t grid = UnitGrid([4, 4]) - state = ScalarField.random_uniform(grid, 0.2, 0.3) + state = ScalarField.random_uniform(grid, 0.2, 0.3, rng=rng) eq = DiffusionPDE() data_tracker = trackers.DataTracker(get_time, interval=0.1) tracker_list = [trackers.CallbackTracker(store_time, interval=0.1), data_tracker] @@ -182,30 +182,30 @@ def test_steady_state_tracker(): assert len(storage) < 20 # finished early -def test_small_tracker_dt(): +def test_small_tracker_dt(rng): """test the case where the dt of the tracker is smaller than the dt of the simulation""" storage = MemoryStorage() eq = DiffusionPDE() - c0 = ScalarField.random_uniform(UnitGrid([4, 4]), 0.1, 0.2) + c0 = ScalarField.random_uniform(UnitGrid([4, 4]), 0.1, 0.2, rng=rng) eq.solve( c0, 1e-2, dt=1e-3, solver="explicit", tracker=storage.tracker(interval=1e-4) ) assert len(storage) == 11 -def test_runtime_tracker(): +def test_runtime_tracker(rng): """test the RuntimeTracker""" - s = ScalarField.random_uniform(UnitGrid([128])) + s = ScalarField.random_uniform(UnitGrid([128]), rng=rng) tracker = trackers.RuntimeTracker("0:01") sol = ExplicitSolver(DiffusionPDE()) con = Controller(sol, t_range=1e4, tracker=["progress", tracker]) con.run(s, dt=1e-3) -def test_consistency_tracker(): +def test_consistency_tracker(rng): """test the ConsistencyTracker""" - s = ScalarField.random_uniform(UnitGrid([128])) + s = ScalarField.random_uniform(UnitGrid([128]), rng=rng) sol = ExplicitSolver(DiffusionPDE(1e3)) con = Controller(sol, t_range=1e5, tracker=["consistency"]) with np.errstate(all="ignore"): @@ -213,9 +213,9 @@ def test_consistency_tracker(): assert con.info["t_final"] < con.info["t_end"] -def test_material_conservation_tracker(): +def test_material_conservation_tracker(rng): """test the MaterialConservationTracker""" - state = ScalarField.random_uniform(UnitGrid([8, 8]), 0, 1) + state = ScalarField.random_uniform(UnitGrid([8, 8]), 0, 1, rng=rng) solver = ExplicitSolver(CahnHilliardPDE()) controller = Controller(solver, t_range=1, tracker=["material_conservation"]) @@ -236,14 +236,14 @@ def test_get_named_trackers(): assert isinstance(tracker, cls) -def test_double_tracker(): +def test_double_tracker(rng): """simple test for using a custom tracker twice""" interval = ConstantInterrupts(1) times1, times2 = [], [] t1 = trackers.CallbackTracker(lambda s, t: times1.append(t), interval=interval) t2 = trackers.CallbackTracker(lambda s, t: times2.append(t), interval=interval) - field = ScalarField.random_uniform(UnitGrid([3])) + field = ScalarField.random_uniform(UnitGrid([3]), rng=rng) DiffusionPDE().solve(field, t_range=4, dt=0.1, tracker=[t1, t2]) np.testing.assert_allclose(times1, np.arange(5)) diff --git a/tests/visualization/test_movies.py b/tests/visualization/test_movies.py index c52821bd..7ca7b41f 100644 --- a/tests/visualization/test_movies.py +++ b/tests/visualization/test_movies.py @@ -35,11 +35,10 @@ def test_movie_class(tmp_path): @pytest.mark.skipif(not movies.Movie.is_available(), reason="no ffmpeg") @pytest.mark.parametrize("movie_func", [movies.movie_scalar, movies.movie]) -def test_movie_scalar(movie_func, tmp_path): +def test_movie_scalar(movie_func, tmp_path, rng): """test Movie class""" - # create some data - state = ScalarField.random_uniform(UnitGrid([4, 4])) + state = ScalarField.random_uniform(UnitGrid([4, 4]), rng=rng) eq = DiffusionPDE() storage = MemoryStorage() tracker = storage.tracker(interval=1) diff --git a/tests/visualization/test_plotting.py b/tests/visualization/test_plotting.py index 98b757f5..7eefef71 100644 --- a/tests/visualization/test_plotting.py +++ b/tests/visualization/test_plotting.py @@ -12,12 +12,12 @@ @skipUnlessModule("matplotlib") -def test_scalar_field_plot(tmp_path): +def test_scalar_field_plot(tmp_path, rng): """test ScalarFieldPlot class""" path = tmp_path / "test_scalar_field_plot.png" # create some data - state = ScalarField.random_uniform(UnitGrid([16, 16])) + state = ScalarField.random_uniform(UnitGrid([16, 16]), rng=rng) for scale in [(0, 1), 1, "automatic", "symmetric", "unity"]: sfp = plotting.ScalarFieldPlot(state, scale=scale) sfp.savefig(path) @@ -29,12 +29,12 @@ def test_scalar_field_plot(tmp_path): @skipUnlessModule("matplotlib") -def test_scalar_plot(tmp_path): +def test_scalar_plot(tmp_path, rng): """test Simple simulation""" path = tmp_path / "test_scalar_plot.png" # create some data - state = ScalarField.random_uniform(UnitGrid([16, 16]), label="test") + state = ScalarField.random_uniform(UnitGrid([16, 16]), label="test", rng=rng) with get_memory_storage(state) as storage: storage.append(state, 0) storage.append(state, 1) @@ -109,11 +109,10 @@ def test_kymograph_collection(tmp_path): @skipUnlessModule("napari") @pytest.mark.interactive -def test_interactive_plotting(): +def test_interactive_plotting(rng): """test plot_interactive""" - # create some data - field = ScalarField.random_uniform(UnitGrid([8])) + field = ScalarField.random_uniform(UnitGrid([8]), rng=rng) with get_memory_storage(field) as storage: for i in range(8): field.data = i