def test_tensor_div_div(conservative): """test double divergence of a tensor field by comparison with two divergences""" grid = SphericalSymGrid([0, 1], 64) expr = "r * tanh((0.5 - r) * 10)" bc = "auto_periodic_neumann" # test radial part tf = Tensor2Field.from_expression(grid, [[expr, 0, 0], [0, 0, 0], [0, 0, 0]]) res = tf._apply_operator("tensor_double_divergence", bc=bc, conservative=conservative) est = tf.divergence(bc).divergence(bc) np.testing.assert_allclose(res.data[2:-2], est.data[2:-2], rtol=0.02, atol=1) # test angular part tf = Tensor2Field.from_expression(grid, [[0, 0, 0], [0, expr, 0], [0, 0, expr]]) res = tf._apply_operator("tensor_double_divergence", bc=bc, conservative=conservative) est = tf.divergence(bc).divergence(bc) np.testing.assert_allclose(res.data[2:-2], est.data[2:-2], rtol=0.02, atol=1)
def test_tensor_div_div_analytical(): """test double divergence of a tensor field against analytical expression""" grid = SphericalSymGrid([0.5, 1], 12) tf = Tensor2Field.from_expression( grid, [["r**4", 0, 0], [0, "r**3", 0], [0, 0, "r**3"]]) res = tf._apply_operator("tensor_double_divergence", bc="curvature") expect = ScalarField.from_expression(grid, "2 * r * (15 * r - 4)") np.testing.assert_allclose(res.data[1:-1], expect.data[1:-1], rtol=0.01)
def test_examples_tensor_polar(): """compare derivatives of tensorial fields for polar grids""" grid = PolarSymGrid(1, 32) tf = Tensor2Field.from_expression(grid, [["r**3"] * 2] * 2) # tensor divergence res = tf.divergence([{"derivative_normal": 0}, {"value_normal": [1, 1]}]) expect = VectorField.from_expression(grid, ["3 * r**2", "5 * r**2"]) np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1)
def test_examples_tensor_sph(): """compare derivatives of tensorial fields for spherical grids""" grid = SphericalSymGrid(1, 32) tf = Tensor2Field.from_expression(grid, [["r**3"] * 3] * 3) tfd = tf.data tfd[0, 1] = tfd[1, 1] = tfd[1, 2] = tfd[2, 1] = tfd[2, 2] = 0 # tensor divergence res = tf.divergence([{"derivative_normal": 0}, {"value_normal": [1, 1, 1]}]) expect = VectorField.from_expression(grid, ["5 * r**2", "5 * r**2", "6 * r**2"]) np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1)
def test_from_expressions(): """test initializing tensor fields with expressions""" grid = UnitGrid([4, 4]) tf = Tensor2Field.from_expression(grid, [[1, 1], ["x**2", "x * y"]]) xs = grid.cell_coords[..., 0] ys = grid.cell_coords[..., 1] np.testing.assert_allclose(tf.data[0, 1], 1) np.testing.assert_allclose(tf.data[0, 1], 1) np.testing.assert_allclose(tf.data[1, 0], xs**2) np.testing.assert_allclose(tf.data[1, 1], xs * ys) # corner case with pytest.raises(ValueError): Tensor2Field.from_expression(grid, "xy") with pytest.raises(ValueError): Tensor2Field.from_expression(grid, ["xy"]) with pytest.raises(ValueError): Tensor2Field.from_expression(grid, ["x"] * 3) with pytest.raises(ValueError): Tensor2Field.from_expression(grid, [["x"], [1, 1]])
def test_examples_vector_sph(): """compare derivatives of vector fields for spherical grids""" grid = SphericalSymGrid(1, 32) # divergence vf = VectorField.from_expression(grid, ["r**3", 0, "r**2"]) res = vf.divergence([{"derivative": 0}, {"value": 1}]) expect = ScalarField.from_expression(grid, "5 * r**2") np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1) # vector gradient vf = VectorField.from_expression(grid, ["r**3", 0, 0]) res = vf.gradient([{"derivative": 0}, {"value": [1, 1, 1]}]) expr = [["3 * r**2", 0, 0], [0, "r**2", 0], [0, 0, "r**2"]] expect = Tensor2Field.from_expression(grid, expr) np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1)
def test_examples_tensor_sph(conservative): """compare derivatives of tensorial fields for spherical grids""" # test explicit expression for which we know the results grid = SphericalSymGrid(1, 32) expressions = [["r**4", 0, 0], [0, "r**3", 0], [0, 0, "r**3"]] tf = Tensor2Field.from_expression(grid, expressions) # tensor divergence bc = [{"derivative": 0}, {"normal_derivative": [4, 3, 3]}] res = tf.divergence(bc, conservative=conservative) expect = VectorField.from_expression(grid, ["2 * r**2 * (3 * r - 1)", 0, 0]) if conservative: np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1) else: np.testing.assert_allclose(res.data[:, 1:-1], expect.data[:, 1:-1], rtol=0.1, atol=0.1)
def test_examples_tensor_cyl(): """compare derivatives of tensorial fields for cylindrical grids""" grid = CylindricalSymGrid(1, [0, 2 * np.pi], 32, periodic_z=True) tf = Tensor2Field.from_expression(grid, [["r**3 * sin(z)"] * 3] * 3) # tensor divergence rs, zs = grid.axes_coords val_r_outer = np.broadcast_to(6 * rs * np.sin(zs), (3, 32)) bcs = [({"derivative": 0}, {"curvature": val_r_outer}), "periodic"] res = tf.divergence(bcs) expect = VectorField.from_expression( grid, [ "r**2 * (r * cos(z) + 3 * sin(z))", "r**2 * (r * cos(z) + 4 * sin(z))", "r**2 * (r * cos(z) + 5 * sin(z))", ], ) np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1)
def test_examples_vector_polar(): """compare derivatives of vector fields for polar grids""" grid = PolarSymGrid(1, 32) vf = VectorField.from_expression(grid, ["r**3", "r**2"]) # divergence res = vf.divergence([{"derivative": 0}, {"value": 1}]) expect = ScalarField.from_expression(grid, "4 * r**2") np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1) # # vector Laplacian # res = vf.laplace([{"derivative": 0}, {"value": 1}]) # expect = VectorField.from_expression(grid, ["8 * r", "3"]) # np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1) # vector gradient res = vf.gradient([{"derivative": 0}, {"value": [1, 1]}]) expr = [["3 * r**2", "-r"], ["2 * r", "r**2"]] expect = Tensor2Field.from_expression(grid, expr) np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1)
def test_examples_vector_cyl(): """compare derivatives of vector fields for cylindrical grids""" grid = CylindricalSymGrid(1, [0, 2 * np.pi], 32) e_r = "r**3 * sin(z)" e_φ = "r**2 * sin(z)" e_z = "r**4 * cos(z)" vf = VectorField.from_expression(grid, [e_r, e_z, e_φ]) bc_r = ({"derivative_normal": 0}, {"value_normal": "r**3 * sin(z)"}) bc_z = {"curvature_normal": "-r**4 * cos(z)"} bcs = [bc_r, bc_z] # divergence res = vf.divergence(bcs) expect = ScalarField.from_expression(grid, "4 * r**2 * sin(z) - r**4 * sin(z)") np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1) # vector Laplacian grid = CylindricalSymGrid(1, [0, 2 * np.pi], 32, periodic_z=True) vf = VectorField.from_expression(grid, ["r**3 * sin(z)"] * 3) val_r_outer = np.broadcast_to(6 * np.sin(grid.axes_coords[1]), (3, 32)) bcs = [({"derivative": 0}, {"curvature": val_r_outer}), "periodic"] res = vf.laplace(bcs) expr = [ "8 * r * sin(z) - r**3 * sin(z)", "9 * r * sin(z) - r**3 * sin(z)", "8 * r * sin(z) - r**3 * sin(z)", ] expect = VectorField.from_expression(grid, expr) np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1) # vector gradient bcs = [({"derivative": 0}, {"curvature": val_r_outer}), "periodic"] res = vf.gradient(bcs) expr = [ ["3 * r**2 * sin(z)", "r**3 * cos(z)", "-r**2 * sin(z)"], ["3 * r**2 * sin(z)", "r**3 * cos(z)", 0], ["3 * r**2 * sin(z)", "r**3 * cos(z)", "r**2 * sin(z)"], ] expect = Tensor2Field.from_expression(grid, expr) np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1)
def test_conservative_sph(): """test whether the integral over a divergence vanishes""" grid = SphericalSymGrid((0, 2), 50) expr = "1 / cosh((r - 1) * 10)" # test divergence of vector field vf = VectorField.from_expression(grid, [expr, 0, 0]) div = vf.divergence(bc="derivative", conservative=True) assert div.integral == pytest.approx(0, abs=1e-2) # test laplacian of scalar field lap = vf[0].laplace("derivative") assert lap.integral == pytest.approx(0, abs=1e-13) # test double divergence of tensor field expressions = [[expr, 0, 0], [0, expr, 0], [0, 0, expr]] tf = Tensor2Field.from_expression(grid, expressions) res = tf._apply_operator("tensor_double_divergence", bc="derivative", conservative=True) assert res.integral == pytest.approx(0, abs=1e-3)