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": 0}, {"normal_value": [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) res = tf.divergence([{"derivative": 0}, {"value": np.ones((2, 2))}]) 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_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_scalar_polar(): """compare derivatives of scalar fields for polar grids""" grid = PolarSymGrid(1, 32) sf = ScalarField.from_expression(grid, "r**3") # gradient res = sf.gradient([{"derivative": 0}, {"derivative": 3}]) expect = VectorField.from_expression(grid, ["3 * r**2", 0]) np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1) # gradient squared expect = ScalarField.from_expression(grid, "9 * r**4") for c in [True, False]: res = sf.gradient_squared([{ "derivative": 0 }, { "derivative": 3 }], central=c) np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1) # laplace res = sf.laplace([{"derivative": 0}, {"derivative": 3}]) expect = ScalarField.from_expression(grid, "9 * r") np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1)
def test_examples_scalar_cyl(): """compare derivatives of scalar fields for cylindrical grids""" grid = CylindricalSymGrid(1, [0, 2 * np.pi], 32) expr = "r**3 * sin(z)" sf = ScalarField.from_expression(grid, expr) bcs = [[{ "derivative": 0 }, { "value": expr }], [{ "value": expr }, { "value": expr }]] # gradient - The coordinates are ordered as (r, z, φ) in py-pde res = sf.gradient(bcs) expect = VectorField.from_expression( grid, ["3 * r**2 * sin(z)", "r**3 * cos(z)", 0]) np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1) # gradient squared expect = ScalarField.from_expression( grid, "r**6 * cos(z)**2 + 9 * r**4 * sin(z)**2") res = sf.gradient_squared(bcs, central=True) np.testing.assert_allclose(res.data, expect.data, rtol=0.1, atol=0.1) # laplace bcs[0][1] = { "curvature": "6 * sin(z)" } # adjust BC to fit laplacian better res = sf.laplace(bcs) expect = ScalarField.from_expression(grid, "9 * r * sin(z) - r**3 * sin(z)") 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_tensor_sph_symmetry(): """test treatment of symmetric tensor field""" grid = SphericalSymGrid(1, 16) vf = VectorField.from_expression(grid, ["r**2", 0, 0]) vf_grad = vf.gradient({"derivative": 2}) strain = vf_grad + vf_grad.transpose() bcs = [{"value": 0}, {"normal_derivative": [4, 0, 0]}] strain_div = strain.divergence(bcs, safe=False) np.testing.assert_allclose(strain_div.data[0], 8) np.testing.assert_allclose(strain_div.data[1:], 0)
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_divergence_field_cyl(): """test the divergence operator""" grid = CylindricalSymGrid(2 * np.pi, [0, 2 * np.pi], [16, 32], periodic_z=True) v = VectorField.from_expression(grid, ["cos(r) + sin(z)**2", "z * cos(r)**2", 0]) s = v.divergence(bc="natural") assert s.data.shape == grid.shape res = ScalarField.from_expression( grid, "cos(r)**2 - sin(r) + (cos(r) + sin(z)**2) / r" ) np.testing.assert_allclose( s.data[1:-1, 1:-1], res.data[1:-1, 1:-1], rtol=0.1, atol=0.1 )
def test_vector_boundary_conditions(): """test some boundary conditions of operators of vector fields""" grid = CartesianGrid([[0, 2 * np.pi], [0, 1]], 32, periodic=[False, True]) vf = VectorField.from_expression(grid, ["sin(x)", "0"]) bc_x = [{"derivative": [-1, 0]}, {"derivative": [1, 0]}] tf = vf.gradient(bc=[bc_x, "periodic"]) res = ScalarField.from_expression(grid, "cos(x)") np.testing.assert_allclose(tf[0, 0].data, res.data, atol=0.01, rtol=0.01) np.testing.assert_allclose(tf[0, 1].data, 0) np.testing.assert_allclose(tf[1, 0].data, 0) np.testing.assert_allclose(tf[1, 1].data, 0)
def test_vector_bcs(): """test boundary conditions on vector fields""" grid = UnitGrid([3, 3], periodic=False) v = VectorField.from_expression(grid, ["x", "cos(y)"]) bc_x = {"value": [0, 1]} bc_y = {"value": [2, 3]} bcs = [bc_x, bc_y] s1 = v.divergence(bcs, backend="scipy").data div = grid.make_operator("divergence", bcs) s2 = div(v.data) np.testing.assert_allclose(s1, s2)
def test_evaluate_func_vector(): """test the evaluate function with vector fields""" grid = UnitGrid([3]) field = ScalarField.from_expression(grid, "x") vec = VectorField.from_expression(grid, ["x"]) res = evaluate("inner(v, v)", {"v": vec}) assert isinstance(res, ScalarField) np.testing.assert_almost_equal(res.data, grid.axes_coords[0] ** 2) res = evaluate("outer(v, v)", {"v": vec}) assert isinstance(res, Tensor2Field) np.testing.assert_almost_equal(res.data, [[grid.axes_coords[0] ** 2]]) assert isinstance(evaluate("gradient(a)", {"a": field}), VectorField)
def test_from_expressions(): """test initializing vector fields with expressions""" grid = UnitGrid([4, 4]) vf = VectorField.from_expression(grid, ["x**2", "x * y"]) xs = grid.cell_coords[..., 0] ys = grid.cell_coords[..., 1] np.testing.assert_allclose(vf.data[0], xs**2) np.testing.assert_allclose(vf.data[1], xs * ys) # corner case vf = VectorField.from_expression(grid, ["1", "x * y"]) np.testing.assert_allclose(vf.data[0], 1) vf = VectorField.from_expression(grid, [1, "x * y"]) np.testing.assert_allclose(vf.data[0], 1) with pytest.raises(ValueError): VectorField.from_expression(grid, "xy") with pytest.raises(ValueError): VectorField.from_expression(grid, ["xy"]) with pytest.raises(ValueError): VectorField.from_expression(grid, ["x"] * 3)
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_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)
r""" Plotting a vector field ======================= This example shows how to initialize and visualize the vector field :math:`\boldsymbol u = \bigl(\sin(x), \cos(x)\bigr)`. """ from pde import CartesianGrid, VectorField grid = CartesianGrid([[-2, 2], [-2, 2]], 32) field = VectorField.from_expression(grid, ['sin(x)', 'cos(x)']) field.plot(method='streamplot', title='Stream plot')
r""" Plotting a vector field ======================= This example shows how to initialize and visualize the vector field :math:`\boldsymbol u = \bigl(\sin(x), \cos(x)\bigr)`. """ from pde import CartesianGrid, VectorField grid = CartesianGrid([[-2, 2], [-2, 2]], 32) field = VectorField.from_expression(grid, ["sin(x)", "cos(x)"]) field.plot(method="streamplot", title="Stream plot")