def test_findiff_cyl(): """test operator for a simple cylindrical grid. Note that we only really test the polar symmetry""" grid = CylindricalGrid(1.5, [0, 1], (3, 2), periodic_z=True) _, r1, r2 = grid.axes_coords[0] np.testing.assert_array_equal(grid.discretization, np.full(2, 0.5)) s = ScalarField(grid, [[1, 1], [2, 2], [4, 4]]) v = VectorField(grid, [[[1, 1], [2, 2], [4, 4]], [[0, 0]] * 3, [[0, 0]] * 3]) # test gradient grad = s.gradient(bc=["value", "periodic"]) np.testing.assert_allclose(grad.data[0], [[1, 1], [3, 3], [-6, -6]]) grad = s.gradient(bc=["derivative", "periodic"]) np.testing.assert_allclose(grad.data[0], [[1, 1], [3, 3], [2, 2]]) # test divergence div = v.divergence(bc=["value", "periodic"]) y1 = 3 + 2 / r1 y2 = -6 + 4 / r2 np.testing.assert_allclose(div.data, [[5, 5], [y1, y1], [y2, y2]]) div = v.divergence(bc=["derivative", "periodic"]) y2 = 2 + 4 / r2 np.testing.assert_allclose(div.data, [[5, 5], [y1, y1], [y2, y2]]) # test laplace lap = s.laplace(bc=[{"type": "value", "value": 3}, "periodic"]) y1 = 4 + 3 / r1 y2 = -16 np.testing.assert_allclose(lap.data, [[8, 8], [y1, y1], [y2, y2]]) lap = s.laplace(bc=[{"type": "derivative", "value": 3}, "periodic"]) y2 = -2 + 3.5 / r2 np.testing.assert_allclose(lap.data, [[8, 8], [y1, y1], [y2, y2]])
def test_expression_bc_derivative(dim): """test boundary conditions that use an expression to calculate the derivative""" grid = CartesianGrid([[0, 1]] * dim, 4) bc1 = grid.get_boundary_conditions({"derivative": 0}) bc2 = grid.get_boundary_conditions({"derivative_expression": "0"}) field = ScalarField(grid, 1) result = field.laplace(bc1) np.testing.assert_allclose(result.data, 0.0) result = field.laplace(bc2) np.testing.assert_allclose(result.data, 0.0)
def test_expression_bc_operator(dim): """test boundary conditions that use an expression in an operator""" grid = CartesianGrid([[0, 1]] * dim, 4) bc1 = grid.get_boundary_conditions({"value": 1}) bc2 = grid.get_boundary_conditions({"virtual_point": f"2 - value"}) field = ScalarField(grid, 1) result = field.laplace(bc1) np.testing.assert_allclose(result.data, 0.0) result = field.laplace(bc2) np.testing.assert_allclose(result.data, 0.0)
def test_expression_bc_value(dim): """test the boundary conditions that calculate the virtual point directly""" grid = CartesianGrid([[0, 1]] * dim, 4) bc1 = grid.get_boundary_conditions({"value": 1}) bc2 = grid.get_boundary_conditions({"value_expression": "1"}) field = ScalarField(grid, 1) result = field.laplace(bc1) np.testing.assert_allclose(result.data, 0.0) result = field.laplace(bc2) np.testing.assert_allclose(result.data, 0.0)
def test_expression_bc_value(dim): """test boundary conditions that use an expression to calculate the value""" grid = CartesianGrid([[0, 1]] * dim, 4) bc1 = grid.get_boundary_conditions({"value": 1}) bc2 = grid.get_boundary_conditions({"value_expression": "1"}) assert "field" in bc2.get_mathematical_representation("field") field = ScalarField(grid, 1) result = field.laplace(bc1) np.testing.assert_allclose(result.data, 0.0) result = field.laplace(bc2) np.testing.assert_allclose(result.data, 0.0)
def test_findiff_cyl(): """test operator for a simple cylindrical grid. Note that we only really test the polar symmetry""" grid = CylindricalSymGrid(1.5, [0, 1], (3, 2), periodic_z=True) _, r1, r2 = grid.axes_coords[0] np.testing.assert_array_equal(grid.discretization, np.full(2, 0.5)) s = ScalarField(grid, [[1, 1], [2, 2], [4, 4]]) # test laplace lap = s.laplace(bc=[{"type": "value", "value": 3}, "periodic"]) y1 = 4 + 3 / r1 y2 = -16 np.testing.assert_allclose(lap.data, [[8, 8], [y1, y1], [y2, y2]]) lap = s.laplace(bc=[{"type": "derivative", "value": 3}, "periodic"]) y2 = -2 + 3.5 / r2 np.testing.assert_allclose(lap.data, [[8, 8], [y1, y1], [y2, y2]])
def test_laplace_2d(): """test the implementation of the laplace operator""" for periodic in [True, False]: bcs = _get_random_grid_bcs(2, dx="uniform", periodic=periodic) a = np.random.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 res = ndimage.convolve(a, kernel, mode="wrap" if periodic else "reflect") field = ScalarField(bcs.grid, data=a) l1 = field.laplace(bcs, backend="scipy") np.testing.assert_allclose(l1.data, res) l2 = field.laplace(bcs, backend="numba") np.testing.assert_allclose(l2.data, res)
def test_laplacian_field_cyl(): """ test the gradient operator """ grid = CylindricalGrid(2 * np.pi, [0, 2 * np.pi], [8, 16], periodic_z=True) r, z = grid.cell_coords[..., 0], grid.cell_coords[..., 1] s = ScalarField(grid, data=np.cos(r) + np.sin(z)) s_lap = s.laplace(bc="natural") assert s_lap.data.shape == (8, 16) res = -np.cos(r) - np.sin(r) / r - np.sin(z) np.testing.assert_allclose(s_lap.data, res, rtol=0.1, atol=0.1)
def test_degenerated_grid(): """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) f2 = ScalarField(g2, f1.data.reshape(g2.shape)) res1 = f1.laplace("auto_periodic_neumann").data res2 = f2.laplace("auto_periodic_neumann").data np.testing.assert_allclose(res1.flat, res2.flat)
def test_rect_div_grad(): """compare div grad to laplacian""" grid = CartesianGrid([[0, 2 * np.pi], [0, 2 * np.pi]], [16, 16], periodic=True) x, y = grid.cell_coords[..., 0], grid.cell_coords[..., 1] field = ScalarField(grid, data=np.cos(x) + np.sin(y)) bcs = grid.get_boundary_conditions("auto_periodic_neumann") a = field.laplace(bcs) b = field.gradient(bcs).divergence("auto_periodic_curvature") np.testing.assert_allclose(a.data, -field.data, rtol=0.05, atol=0.01) np.testing.assert_allclose(b.data, -field.data, rtol=0.05, atol=0.01)
def test_div_grad_const(): """compare div grad to laplace operator""" grid = CartesianGrid([[-1, 1]], 32) # test constant y = ScalarField(grid, 3) for bc in [{"type": "derivative", "value": 0}, {"type": "value", "value": 3}]: bcs = grid.get_boundary_conditions(bc) lap = y.laplace(bcs) divgrad = y.gradient(bcs).divergence("auto_periodic_curvature") np.testing.assert_allclose(lap.data, np.zeros(32)) np.testing.assert_allclose(divgrad.data, np.zeros(32))
def test_singular_dimensions_3d(periodic): """test grids with singular dimensions""" dim = np.random.randint(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) expected = field.laplace("auto_periodic_neumann").data for g in [g3a, g3b]: f = ScalarField(g, data=field.data.reshape(g.shape)) res = f.laplace("auto_periodic_neumann").data.reshape(g1.shape) np.testing.assert_allclose(expected, res)
def test_div_grad_quadratic(): """ compare div grad to laplace operator """ grid = CartesianGrid([[-1, 1]], 32) x = grid.axes_coords[0] # test simple quadratic y = ScalarField(grid, x**2) bcs = grid.get_boundary_conditions({"type": "derivative", "value": 2}) lap = y.laplace(bcs) divgrad = y.gradient(bcs).divergence(bcs.differentiated) np.testing.assert_allclose(lap.data, np.full(32, 2.0)) np.testing.assert_allclose(divgrad.data, np.full(32, 2.0))
def test_div_grad_linear(): """ compare div grad to laplace operator """ grid = CartesianGrid([[-1, 1]], 32) x = grid.axes_coords[0] # test linear f = np.random.random() + 1 y = ScalarField(grid, f * x) b1 = [{"type": "neumann", "value": -f}, {"type": "neumann", "value": f}] b2 = [{"type": "value", "value": -f}, {"type": "value", "value": f}] for bs in [b1, b2]: bcs = y.grid.get_boundary_conditions(bs) lap = y.laplace(bcs) divgrad = y.gradient(bcs).divergence(bcs.differentiated) np.testing.assert_allclose(lap.data, np.zeros(32), atol=1e-10) np.testing.assert_allclose(divgrad.data, np.zeros(32), atol=1e-10)
def test_laplace_2d_nonuniform(): """test the implementation of the laplace operator for non-uniform coordinates""" for periodic in [True, False]: 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) mode = "wrap" if periodic else "reflect" res = ndimage.convolve1d(a, kernel_x, axis=0, mode=mode) res += ndimage.convolve1d(a, kernel_y, axis=1, mode=mode) field = ScalarField(bcs.grid, data=a) lap = field.laplace(bcs, backend="numba") np.testing.assert_allclose(lap.data, res)
def test_special_cases(): """test some special boundary conditions""" g = UnitGrid([5]) s = ScalarField(g, np.arange(5)) for bc in ["extrapolate", {"curvature": 0}]: np.testing.assert_allclose(s.laplace(bc).data, 0)