def test_boundary_interpolation_2d(): """test boundary interpolation for 2d fields""" grid = CartesianGrid([[0.1, 0.3], [-2, 3]], [3, 3]) field = ScalarField.random_normal(grid) # test boundary interpolation bndry_val = np.random.randn(3) for bndry in grid._iter_boundaries(): val = field.get_boundary_values(*bndry, bc={"value": bndry_val}) np.testing.assert_allclose(val, bndry_val)
def test_interpolation_to_grid_fields(): """ test whether data is interpolated correctly for different fields """ grid = CartesianGrid([[0, 2 * np.pi]] * 2, 6) grid2 = CartesianGrid([[0, 2 * np.pi]] * 2, 8) vf = VectorField.from_expression(grid, ["sin(y)", "cos(x)"]) sf = vf[0] # test extraction of fields fc = FieldCollection([sf, vf]) for f in [sf, vf, fc]: f2 = f.interpolate_to_grid(grid2, method="numba") f3 = f2.interpolate_to_grid(grid, method="numba") np.testing.assert_allclose(f.data, f3.data, atol=0.2, rtol=0.2)
def test_smoothing(): """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() # this assumes that the grid periodicity is the same for all axes mode = "wrap" if grid.periodic[0] else "reflect" s = sigma / grid.typical_discretization expected = ndimage.gaussian_filter(f1.data, sigma=s, mode=mode) out = f1.smooth(sigma) np.testing.assert_allclose(out.data, expected) out.data = 0 # reset data f1.smooth(sigma, out=out).data np.testing.assert_allclose(out.data, expected) # test one simple higher order smoothing tf = Tensor2Field.random_uniform(grid) assert tf.data.shape == tf.smooth(1).data.shape # test in-place smoothing g = UnitGrid([8, 8]) f1 = ScalarField.random_normal(g) f2 = f1.smooth(3) f1.smooth(3, out=f1) np.testing.assert_allclose(f1.data, f2.data)
def test_scalars(): """test some scalar fields""" grid = CartesianGrid([[0.1, 0.3], [-2, 3]], [3, 4]) s1 = ScalarField(grid, np.full(grid.shape, 1)) s2 = ScalarField(grid, np.full(grid.shape, 2)) assert s1.average == pytest.approx(1) assert s1.magnitude == pytest.approx(1) s3 = s1 + s2 assert s3.grid == grid np.testing.assert_allclose(s3.data, 3) s1 += s2 np.testing.assert_allclose(s1.data, 3) s2 = FieldBase.from_state(s1.attributes, data=s1.data) assert s1 == s2 assert s1.grid is s2.grid attrs = ScalarField.unserialize_attributes(s1.attributes_serialized) s2 = FieldBase.from_state(attrs, data=s1.data) assert s1 == s2 assert s1.grid is not s2.grid # test options for plotting images if module_available("matplotlib"): s1.plot(transpose=True, colorbar=True) s3 = ScalarField(grid, s1) assert s1 is not s3 assert s1 == s3 assert s1.grid is s3.grid # multiplication with numpy arrays arr = np.random.randn(*grid.shape) np.testing.assert_allclose((arr * s1).data, (s1 * arr).data)
def test_get_length_scale(): """test determining the length scale""" grid = CartesianGrid([[0, 8 * np.pi]], 64, periodic=True) c = ScalarField(grid, np.sin(grid.axes_coords[0])) for method in ["structure_factor_mean", "structure_factor_maximum"]: s = image_analysis.get_length_scale(c, method=method) assert s == pytest.approx(2 * np.pi, rel=0.1)
def test_localization_perturbed_3d(periodic): """tests localization of perturbed 3d droplets""" size = 8 pos = np.random.uniform(-2, 2, size=3) radius = np.random.uniform(2, 3) width = np.random.uniform(0.5, 1.5) ampls = np.random.uniform(-0.01, 0.01, size=3) d1 = PerturbedDroplet3D(pos, radius, interface_width=width, amplitudes=ampls) a = np.random.random(3) - size / 2 b = np.random.random(3) + size / 2 grid = CartesianGrid(np.c_[a, b], 2 * size, periodic=periodic) assert grid.dim == 3 field = d1.get_phase_field(grid) emulsion = image_analysis.locate_droplets(field, refine=True, modes=d1.modes) assert len(emulsion) == 1 d2 = emulsion[0] msg = "size=%d, periodic=%s, %s != %s" % (size, periodic, d1, d2) np.testing.assert_almost_equal(d1.position, d2.position, decimal=1, err_msg=msg) assert d1.radius == pytest.approx(d2.radius, rel=1e-4) assert d1.interface_width == pytest.approx(d2.interface_width, rel=1e-3) np.testing.assert_allclose( d1.amplitudes[3:], d2.amplitudes[3:], rtol=0.5, err_msg=msg )
def test_poisson_solver_1d(): """ test the poisson solver on 1d grids """ # solve Laplace's equation grid = UnitGrid([4]) field = ScalarField(grid) res = field.solve_poisson([{"value": -1}, {"value": 3}]) np.testing.assert_allclose(res.data, grid.axes_coords[0] - 1) res = field.solve_poisson([{"value": -1}, {"derivative": 1}]) np.testing.assert_allclose(res.data, grid.axes_coords[0] - 1) # test Poisson equation with 2nd Order BC res = field.solve_poisson([{"value": -1}, "extrapolate"]) # solve Poisson's equation grid = CartesianGrid([[0, 1]], 4) field = ScalarField(grid, data=1) res = field.copy() field.solve_poisson([{"value": 1}, {"derivative": 1}], out=res) xs = grid.axes_coords[0] np.testing.assert_allclose(res.data, 1 + 0.5 * xs**2, rtol=1e-2) # test inconsistent problem field.data = 1 with pytest.raises(RuntimeError, match="Neumann"): field.solve_poisson({"derivative": 0})
def test_boundary_interpolation_2d(): """test boundary interpolation for 2d fields""" grid = CartesianGrid([[0.1, 0.3], [-2, 3]], [3, 3]) field = ScalarField.random_normal(grid) # test boundary interpolation bndry_val = np.random.randn(3) for bndry in grid._iter_boundaries(): val = field.get_boundary_values(*bndry, bc={"value": bndry_val}) np.testing.assert_allclose(val, bndry_val) # boundary conditions have already been enforced ev = field.make_get_boundary_values(*bndry) out = ev() np.testing.assert_allclose(out, bndry_val) ev(data_full=field._data_full, out=out) np.testing.assert_allclose(out, bndry_val)
def test_piecewise_expressions(): """test special expressions for creating fields""" grid = CartesianGrid([[0, 4]], 32) field = ScalarField.from_expression(grid, "Piecewise((x**2, x>2), (1+x, x<=2))") x = grid.axes_coords[0] field_data = np.piecewise(x, [x > 2, x <= 2], [lambda x: x**2, lambda x: 1 + x]) np.testing.assert_allclose(field.data, field_data)
def test_interpolation_to_grid_fields(ndim): """test whether data is interpolated correctly for different fields""" grid = CartesianGrid([[0, 2 * np.pi]] * ndim, 6) grid2 = CartesianGrid([[0, 2 * np.pi]] * ndim, 8) if ndim == 1: vf = VectorField.from_expression(grid, ["cos(x)"]) elif ndim == 2: vf = VectorField.from_expression(grid, ["sin(y)", "cos(x)"]) sf = vf[0] # test extraction of fields fc = FieldCollection([sf, vf]) for f in [sf, vf, fc]: # test self-interpolation f0 = f.interpolate_to_grid(grid, backend="numba") np.testing.assert_allclose(f.data, f0.data, atol=1e-15) # test interpolation to finer grid and back f2 = f.interpolate_to_grid(grid2, backend="numba") f3 = f2.interpolate_to_grid(grid, backend="numba") np.testing.assert_allclose(f.data, f3.data, atol=0.2, rtol=0.2)
def test_laplacian(): """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_lap = s.laplace("natural") assert s_lap.data.shape == (16, 16) np.testing.assert_allclose(s_lap.data, -s.data, rtol=0.1, atol=0.1) s.laplace("natural", out=s_lap) assert s_lap.data.shape == (16, 16) np.testing.assert_allclose(s_lap.data, -s.data, rtol=0.1, atol=0.1)
def test_structure_factor_random(): """test the structure factor function for random input""" g1 = CartesianGrid([[0, 10]] * 2, 64, periodic=True) f1 = ScalarField.random_colored(g1, -2) # test invariance with re-meshing g2 = CartesianGrid([[0, 10]] * 2, [128, 64], periodic=True) f2 = f1.interpolate_to_grid(g2) ks = np.linspace(0.2, 3) k1, s1 = image_analysis.get_structure_factor(f1, wave_numbers=ks) k2, s2 = image_analysis.get_structure_factor(f2, wave_numbers=ks) np.testing.assert_equal(ks, k1) np.testing.assert_equal(ks, k2) np.testing.assert_allclose(s1, s2, atol=0.05) # test invariance with respect to scaling k2, s2 = image_analysis.get_structure_factor(100 * f1, wave_numbers=ks) np.testing.assert_equal(ks, k2) np.testing.assert_allclose(s1, s2, atol=0.05)
def test_fluctuations(): """test the scaling of fluctuations""" for dim in [1, 2]: for size in [256, 512]: if dim == 1: size **= 2 grid = CartesianGrid([[0, 1]] * dim, [size] * dim) std = 1 + np.random.random() for field_cls in [ScalarField, VectorField, Tensor2Field]: s = field_cls.random_normal( grid, mean=np.random.random(), std=std, scaling="physical" ) expect = np.full([dim] * field_cls.rank, std) np.testing.assert_allclose(s.fluctuations, expect, rtol=0.1)
def test_gradient(): """test the gradient operator""" grid = CartesianGrid([[0, 2 * np.pi], [0, 2 * np.pi]], [16, 16], periodic=True) x, y = grid.cell_coords[..., 0], grid.cell_coords[..., 1] data = np.cos(x) + np.sin(y) s = ScalarField(grid, data) v = s.gradient("natural") assert v.data.shape == (2, 16, 16) np.testing.assert_allclose(v.data[0], -np.sin(x), rtol=0.1, atol=0.1) np.testing.assert_allclose(v.data[1], np.cos(y), rtol=0.1, atol=0.1) s.gradient("natural", out=v) assert v.data.shape == (2, 16, 16) np.testing.assert_allclose(v.data[0], -np.sin(x), rtol=0.1, atol=0.1) np.testing.assert_allclose(v.data[1], np.cos(y), rtol=0.1, atol=0.1)
def test_poisson_solver_2d(): """ test the poisson solver on 2d grids """ grid = CartesianGrid([[0, 2 * np.pi]] * 2, 16) bcs = [{"value": "sin(y)"}, {"value": "sin(x)"}] # solve Laplace's equation field = ScalarField(grid) res = field.solve_poisson(bcs) xs = grid.cell_coords[..., 0] ys = grid.cell_coords[..., 1] # analytical solution was obtained with Mathematica expect = (np.cosh(np.pi - ys) * np.sin(xs) + np.cosh(np.pi - xs) * np.sin(ys)) / np.cosh(np.pi) np.testing.assert_allclose(res.data, expect, atol=1e-2, rtol=1e-2) # test more complex case for exceptions res = field.solve_poisson([{"value": "sin(y)"}, {"curvature": "sin(x)"}])
def test_localization_sym_rect(periodic): """tests simple droplets localization in 2d with a rectangular grid""" size = 16 pos = np.random.uniform(-4, 4, size=2) radius = np.random.uniform(2, 5) width = np.random.uniform(0.5, 1.5) d1 = DiffuseDroplet(pos, radius, interface_width=width) a = np.random.random(2) - size / 2 b = np.random.random(2) + size / 2 grid = CartesianGrid(np.c_[a, b], 3 * size, periodic=periodic) field = d1.get_phase_field(grid) emulsion = image_analysis.locate_droplets(field, refine=True) assert len(emulsion) == 1 d2 = emulsion[0] np.testing.assert_almost_equal(d1.position, d2.position) assert d1.radius == pytest.approx(d2.radius, rel=1e-5) assert d1.interface_width == pytest.approx(d2.interface_width) emulsion = image_analysis.locate_droplets(ScalarField(grid)) assert len(emulsion) == 0