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_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_expression_bc_setting(expr): """test boundary conditions that use an expression""" grid = CartesianGrid([[0, 1], [0, 1]], 4) bc1 = grid.get_boundary_conditions({"value": expr}) bc2 = grid.get_boundary_conditions( {"virtual_point": f"2 * ({expr}) - value"}) field = ScalarField.random_uniform(grid) f1 = field.copy() f1.set_ghost_cells(bc1) f2 = field.copy() f2.set_ghost_cells(bc2) f3 = field.copy() bc1.make_ghost_cell_setter()(f3._data_full) f4 = field.copy() bc2.make_ghost_cell_setter()(f4._data_full) np.testing.assert_almost_equal(f1._data_full, f2._data_full) np.testing.assert_almost_equal(f1._data_full, f3._data_full) np.testing.assert_almost_equal(f1._data_full, f4._data_full)
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_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] arr = np.cos(x) + np.sin(y) bcs = grid.get_boundary_conditions("natural") laplace = grid.get_operator("laplace", bcs) grad = grid.get_operator("gradient", bcs) div = grid.get_operator("divergence", bcs.differentiated) a = laplace(arr) b = div(grad(arr)) np.testing.assert_allclose(a, -arr, rtol=0.05, atol=0.01) np.testing.assert_allclose(b, -arr, rtol=0.05, atol=0.01)
def test_make_derivative(ndim, axis): """ 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) bcs = grid.get_boundary_conditions("natural") grad = field.gradient(bcs) for method in ["central", "forward", "backward"]: msg = f"method={method}, periodic={periodic}" diff = ops._make_derivative(bcs, axis=axis, method=method) np.testing.assert_allclose(grad.data[axis], diff(field.data), atol=0.1, rtol=0.1, err_msg=msg)
def test_make_derivative2(ndim, axis): """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) bcs = grid.get_boundary_conditions("auto_periodic_neumann") grad = field.gradient(bcs)[axis] grad2 = grad.gradient(bcs)[axis] diff = ops._make_derivative2(grid, axis=axis) res = field.copy() res.data[:] = 0 field.set_ghost_cells(bcs) diff(field._data_full, out=res.data) np.testing.assert_allclose(grad2.data, res.data, atol=0.1, rtol=0.1)
def _get_random_grid_bcs(ndim: int, dx="random", periodic="random", rank=0): """ create a random Cartesian grid with natural bcs """ shape = np.random.randint(2, 5, ndim) if dx == "random": dx = np.random.uniform(0.5, 1.5, ndim) elif dx == "uniform": dx = np.full(ndim, np.random.uniform(0.5, 1.5)) else: dx = np.broadcast_to(dx, shape) if periodic == "random": periodic = random.choice([True, False]) sizes = [(0, float(s * d)) for s, d in zip(shape, dx)] grid = CartesianGrid(sizes, shape, periodic=periodic) return grid.get_boundary_conditions("natural", rank=rank)
def test_make_derivative(ndim, axis): """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) bcs = grid.get_boundary_conditions("auto_periodic_neumann") grad = field.gradient(bcs) for method in ["central", "forward", "backward"]: msg = f"method={method}, periodic={periodic}" diff = ops._make_derivative(grid, axis=axis, method=method) res = field.copy() res.data[:] = 0 field.set_ghost_cells(bcs) diff(field._data_full, out=res.data) np.testing.assert_allclose( grad.data[axis], res.data, atol=0.1, rtol=0.1, err_msg=msg )
def test_expression_invalid_args(): """test boundary conditions use an expression with invalid data""" grid = CartesianGrid([[0, 1]], 4) with pytest.raises(BCDataError): grid.get_boundary_conditions({"derivative_expression": "heaviside(x)"})