Contact Us!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

| Download
Views: 88
Image: ubuntu2204
Kernel: SageMath 10.1

Vector Calculus with SageMath

print(version()) %display latex
SageMath version 10.1, Release Date: 2023-08-20

The 3-dimensional Euclidean space

We can declare the 3D Euclidean space E3\mathbb{E}^3, with (x,y,z)(x,y,z) as cartesian coordinates.

E.<x,y,z> = EuclideanSpace() print(E) E
Euclidean space E^3

E3\displaystyle \mathbb{E}^{3}

# Change the notations to i, j, and k, which is consistent with the textbook. frame = E.cartesian_frame() frame.set_name(('hx', 'hy', 'hz'), latex_symbol=(r'\mathbf{i}', r'\mathbf{j}', r'\mathbf{k}')) frame

(E3,(i,j,k))\displaystyle \left(\mathbb{E}^{3}, \left(\mathbf{i},\mathbf{j},\mathbf{k}\right)\right)

Vector fields

We define a vector field on E3\mathbb{E}^3 from its components in the vector frame (i,j,k)(\mathbf{i}, \mathbf{j}, \mathbf{k}).

# We define a vector field with three functions v = E.vector_field(-y, x, sin(x*y*z), name='v') v.display()

v=yi+xj+sin(xyz)k\displaystyle v = -y \mathbf{i} + x \mathbf{j} + \sin\left(x y z\right) \mathbf{k}

We can access to the components of the vector field vv via the square bracket operator.

print(v[1]) print(v[:])
-y [-y, x, sin(x*y*z)]

A vector field can evaluate at any point of E3\mathbb{E}^3.

(x,y,z)=(3,2,1),v=2i+3j+sin(6)k(x,y,z)=(3,-2,1),\qquad v=2\mathbf{i}+3\mathbf{j}+\sin(-6)\mathbf{k}
p = E((3,-2,1), name='p') print(p, ', whose coordiante are') print(p.coordinates()) vp = v.at(p) print(vp, 'is') vp.display()
Point p on the Euclidean space E^3 , whose coordiante are (3, -2, 1) Vector v at Point p on the Euclidean space E^3 is

v=2i+3jsin(6)k\displaystyle v = 2 \mathbf{i} + 3 \mathbf{j} -\sin\left(6\right) \mathbf{k}

Vector fields can be plotted (see the list of options for customizing the plot).

v.plot(max_range=1.5, scale=0.5, viewer='threejs', online=True)
Graphics3d Object

We may define a vector field with generic components.

u = E.vector_field(function('u_x')(x,y,z), function('u_y')(x,y,z), function('u_z')(x,y,z), name='u') print(u.display()) print(u[:]) up = u.at(p) up.display()
u = u_x(x, y, z) hx + u_y(x, y, z) hy + u_z(x, y, z) hz [u_x(x, y, z), u_y(x, y, z), u_z(x, y, z)]

u=ux(3,2,1)i+uy(3,2,1)j+uz(3,2,1)k\displaystyle u = u_{x}\left(3, -2, 1\right) \mathbf{i} + u_{y}\left(3, -2, 1\right) \mathbf{j} + u_{z}\left(3, -2, 1\right) \mathbf{k}

Algebraic operations on vector fields

Dot product

The dot (or scalar) product of the vector fields uu and vv is obtained by the method dot_product, which admits dot as a shortcut alias:

s = u.dot(v) print(s) s
Scalar field u.v on the Euclidean space E^3

uv\displaystyle {u}\cdot{v}

s.display()

uv:E3R(x,y,z)yux(x,y,z)+xuy(x,y,z)+sin(xyz)uz(x,y,z)\displaystyle \begin{array}{llcl} {u}\cdot{v}:& \mathbb{E}^{3} & \longrightarrow & \mathbb{R} \\ & \left(x, y, z\right) & \longmapsto & -y u_{x}\left(x, y, z\right) + x u_{y}\left(x, y, z\right) + \sin\left(x y z\right) u_{z}\left(x, y, z\right) \end{array}

s(p)

sin(6)uz(3,2,1)+2ux(3,2,1)+3uy(3,2,1)\displaystyle -\sin\left(6\right) u_{z}\left(3, -2, 1\right) + 2 \, u_{x}\left(3, -2, 1\right) + 3 \, u_{y}\left(3, -2, 1\right)

s.expr()

yux(x,y,z)+xuy(x,y,z)+sin(xyz)uz(x,y,z)\displaystyle -y u_{x}\left(x, y, z\right) + x u_{y}\left(x, y, z\right) + \sin\left(x y z\right) u_{z}\left(x, y, z\right)

Norm

The norm of a vector field is

s = norm(u) print(s) s.display()
Scalar field |u| on the Euclidean space E^3

u:E3R(x,y,z)ux(x,y,z)2+uy(x,y,z)2+uz(x,y,z)2\displaystyle \begin{array}{llcl} \left\|u\right\|:& \mathbb{E}^{3} & \longrightarrow & \mathbb{R} \\ & \left(x, y, z\right) & \longmapsto & \sqrt{u_{x}\left(x, y, z\right)^{2} + u_{y}\left(x, y, z\right)^{2} + u_{z}\left(x, y, z\right)^{2}} \end{array}

s.expr()

ux(x,y,z)2+uy(x,y,z)2+uz(x,y,z)2\displaystyle \sqrt{u_{x}\left(x, y, z\right)^{2} + u_{y}\left(x, y, z\right)^{2} + u_{z}\left(x, y, z\right)^{2}}

norm(u)^2 == u.dot(u)

True\displaystyle \mathrm{True}

norm(v).expr()

x2+y2+sin(xyz)2\displaystyle \sqrt{x^{2} + y^{2} + \sin\left(x y z\right)^{2}}

Cross product

s = u.cross(v) print(s) s.display()
Vector field u x v on the Euclidean space E^3

u×v=(sin(xyz)uy(x,y,z)xuz(x,y,z))i+(sin(xyz)ux(x,y,z)yuz(x,y,z))j+(xux(x,y,z)+yuy(x,y,z))k\displaystyle {u}\times{v} = \left( \sin\left(x y z\right) u_{y}\left(x, y, z\right) - x u_{z}\left(x, y, z\right) \right) \mathbf{i} + \left( -\sin\left(x y z\right) u_{x}\left(x, y, z\right) - y u_{z}\left(x, y, z\right) \right) \mathbf{j} + \left( x u_{x}\left(x, y, z\right) + y u_{y}\left(x, y, z\right) \right) \mathbf{k}

Scalar triple product

Let us introduce a third vector field. As a example, we do not pass the components as arguments of vector_field, as we did for uu and vv; instead, we set them in a second stage, via the square bracket operator, any unset component being assumed to be zero.

w = E.vector_field(name='w') w[1] = x*z w[2] = y*z w.display()

w=xzi+yzj\displaystyle w = x z \mathbf{i} + y z \mathbf{j}

The scalar triple product of the vector fields uu, vv, and ww is obtained as follows.

triple_product = E.scalar_triple_product() s = triple_product(u, v, w) print(s) s.expr()
Scalar field epsilon(u,v,w) on the Euclidean space E^3

(yux(x,y,z)xuy(x,y,z))zsin(xyz)(x2uz(x,y,z)+y2uz(x,y,z))z\displaystyle -{\left(y u_{x}\left(x, y, z\right) - x u_{y}\left(x, y, z\right)\right)} z \sin\left(x y z\right) - {\left(x^{2} u_{z}\left(x, y, z\right) + y^{2} u_{z}\left(x, y, z\right)\right)} z

Let us check that the scalar triple product of u, vu,~v and ww is u(v×w)u\cdot (v\times w).

print(s == u.dot(v.cross(w))) print(s == v.dot(w.cross(u))) print(s == w.dot(u.cross(v)))
True True True

Differential operators

While the standard operators grad, div, curl, etc. involved in vector calculus are accessible via the dot notation (e.g. v.div()), let us import functions grad, div, curl, etc. that allow for using standard mathematical notations (e.g. div(v)).

from sage.manifolds.operators import *

Gradient of a scalar field

We first introduce a scalar field, via its expression in terms of Cartesian coordinates. In this example, we consider a unspecified function of (x,y,z)(x,y,z).

F = E.scalar_field(function('f')(x,y,z), name='F') F.display()

F:E3R(x,y,z)f(x,y,z)\displaystyle \begin{array}{llcl} F:& \mathbb{E}^{3} & \longrightarrow & \mathbb{R} \\ & \left(x, y, z\right) & \longmapsto & f\left(x, y, z\right) \end{array}

# The value of F at a point p F(p)

f(3,2,1)\displaystyle f\left(3, -2, 1\right)

# The gradient of F print(grad(F)) grad(F).display()
Vector field grad(F) on the Euclidean space E^3

grad(F)=fxi+fyj+fzk\displaystyle \mathrm{grad}\left(F\right) = \frac{\partial\,f}{\partial x} \mathbf{i} + \frac{\partial\,f}{\partial y} \mathbf{j} + \frac{\partial\,f}{\partial z} \mathbf{k}

# The norm of the gradient of F norm(grad(F)).display()

grad(F):E3R(x,y,z)(fx)2+(fy)2+(fz)2\displaystyle \begin{array}{llcl} \left\|\mathrm{grad}\left(F\right)\right\|:& \mathbb{E}^{3} & \longrightarrow & \mathbb{R} \\ & \left(x, y, z\right) & \longmapsto & \sqrt{\left(\frac{\partial\,f}{\partial x}\right)^{2} + \left(\frac{\partial\,f}{\partial y}\right)^{2} + \left(\frac{\partial\,f}{\partial z}\right)^{2}} \end{array}

Divergence

# The divergence of a vector field s = div(u) s.display()

div(u):E3R(x,y,z)uxx+uyy+uzz\displaystyle \begin{array}{llcl} \mathrm{div}\left(u\right):& \mathbb{E}^{3} & \longrightarrow & \mathbb{R} \\ & \left(x, y, z\right) & \longmapsto & \frac{\partial\,u_{x}}{\partial x} + \frac{\partial\,u_{y}}{\partial y} + \frac{\partial\,u_{z}}{\partial z} \end{array}

# The divergence of the vector field v = (-y,x,sin(xyz)) print(v.display()) div(v).expr()
v = -y hx + x hy + sin(x*y*z) hz

xycos(xyz)\displaystyle x y \cos\left(x y z\right)

# The divergence of the vector field w = (xz,yz) print(w.display()) div(w).expr()
w = x*z hx + y*z hy

2z\displaystyle 2 \, z

# An identity valid for any scalar field F and any vector field u. print(F.display()) print(u.display()) div(F*u) == F*div(u) + u.dot(grad(F))
F: E^3 → ℝ (x, y, z) ↦ f(x, y, z) u = u_x(x, y, z) hx + u_y(x, y, z) hy + u_z(x, y, z) hz

True\displaystyle \mathrm{True}

Curl

# The curl of a vector field: s = curl(u) print(s) s.display()
Vector field curl(u) on the Euclidean space E^3

curl(u)=(uyz+uzy)i+(uxzuzx)j+(uxy+uyx)k\displaystyle \mathrm{curl}\left(u\right) = \left( -\frac{\partial\,u_{y}}{\partial z} + \frac{\partial\,u_{z}}{\partial y} \right) \mathbf{i} + \left( \frac{\partial\,u_{x}}{\partial z} - \frac{\partial\,u_{z}}{\partial x} \right) \mathbf{j} + \left( -\frac{\partial\,u_{x}}{\partial y} + \frac{\partial\,u_{y}}{\partial x} \right) \mathbf{k}

# To use the notation rot instead of curl from sage.manifolds.operators import curl as rot
# The curl of the vector field u print(u.display()) rot(u).display()
u = u_x(x, y, z) hx + u_y(x, y, z) hy + u_z(x, y, z) hz

curl(u)=(uyz+uzy)i+(uxzuzx)j+(uxy+uyx)k\displaystyle \mathrm{curl}\left(u\right) = \left( -\frac{\partial\,u_{y}}{\partial z} + \frac{\partial\,u_{z}}{\partial y} \right) \mathbf{i} + \left( \frac{\partial\,u_{x}}{\partial z} - \frac{\partial\,u_{z}}{\partial x} \right) \mathbf{j} + \left( -\frac{\partial\,u_{x}}{\partial y} + \frac{\partial\,u_{y}}{\partial x} \right) \mathbf{k}

curl(v).display()

curl(v)=xzcos(xyz)iyzcos(xyz)j+2k\displaystyle \mathrm{curl}\left(v\right) = x z \cos\left(x y z\right) \mathbf{i} -y z \cos\left(x y z\right) \mathbf{j} + 2 \mathbf{k}

curl(w).display()

curl(w)=yi+xj\displaystyle \mathrm{curl}\left(w\right) = -y \mathbf{i} + x \mathbf{j}

# The curl of a gradient is always zero: curl(grad(F)).display()

curl(grad(F))=0\displaystyle \mathrm{curl}\left(\mathrm{grad}\left(F\right)\right) = 0

# The divergence of a curl is always zero: div(curl(u)).display()

div(curl(u)):E3R(x,y,z)0\displaystyle \begin{array}{llcl} \mathrm{div}\left(\mathrm{curl}\left(u\right)\right):& \mathbb{E}^{3} & \longrightarrow & \mathbb{R} \\ & \left(x, y, z\right) & \longmapsto & 0 \end{array}

# An identity valid for any scalar field F and any vector field u. print(F.display()) print(u.display()) curl(F*u) == grad(F).cross(u) + F*curl(u)
F: E^3 → ℝ (x, y, z) ↦ f(x, y, z) u = u_x(x, y, z) hx + u_y(x, y, z) hy + u_z(x, y, z) hz

True\displaystyle \mathrm{True}

Laplacian

# The Laplacian of a scalar field: s = laplacian(F) s.display()

Δ(F):E3R(x,y,z)2fx2+2fy2+2fz2\displaystyle \begin{array}{llcl} \Delta\left(F\right):& \mathbb{E}^{3} & \longrightarrow & \mathbb{R} \\ & \left(x, y, z\right) & \longmapsto & \frac{\partial^2\,f}{\partial x ^ 2} + \frac{\partial^2\,f}{\partial y ^ 2} + \frac{\partial^2\,f}{\partial z ^ 2} \end{array}

# For a scalar field, the Laplacian is nothing but the divergence of the gradient: laplacian(F) == div(grad(F))

True\displaystyle \mathrm{True}

# The Laplacian of a vector field: laplacian(u).display()

Δ(u)=(2uxx2+2uxy2+2uxz2)i+(2uyx2+2uyy2+2uyz2)j+(2uzx2+2uzy2+2uzz2)k\displaystyle \Delta\left(u\right) = \left( \frac{\partial^2\,u_{x}}{\partial x ^ 2} + \frac{\partial^2\,u_{x}}{\partial y ^ 2} + \frac{\partial^2\,u_{x}}{\partial z ^ 2} \right) \mathbf{i} + \left( \frac{\partial^2\,u_{y}}{\partial x ^ 2} + \frac{\partial^2\,u_{y}}{\partial y ^ 2} + \frac{\partial^2\,u_{y}}{\partial z ^ 2} \right) \mathbf{j} + \left( \frac{\partial^2\,u_{z}}{\partial x ^ 2} + \frac{\partial^2\,u_{z}}{\partial y ^ 2} + \frac{\partial^2\,u_{z}}{\partial z ^ 2} \right) \mathbf{k}

# In the Cartesian frame, the components of the Laplacian of a vector field are nothing but the Laplacians of the components of the vector field, as we can check: e = E.cartesian_frame() laplacian(u) == sum(laplacian(u[[i]])*e[i] for i in E.irange())

True\displaystyle \mathrm{True}

In the above formula, u[[i]] return the ii-th component of uu as a scalar field, while u[i]u[i] would have returned the coordinate expression of this scalar field; besides, ee is the Cartesian frame.

u[1]

ux(x,y,z)\displaystyle u_{x}\left(x, y, z\right)

# For v and w, we have laplacian(v).display()

Δ(v)=(x2y2+(x2+y2)z2)sin(xyz)k\displaystyle \Delta\left(v\right) = -{\left(x^{2} y^{2} + {\left(x^{2} + y^{2}\right)} z^{2}\right)} \sin\left(x y z\right) \mathbf{k}

curl(curl(u)).display()

curl(curl(u))=(2uxy22uxz2+2uyxy+2uzxz)i+(2uxxy2uyx22uyz2+2uzyz)j+(2uxxz+2uyyz2uzx22uzy2)k\displaystyle \mathrm{curl}\left(\mathrm{curl}\left(u\right)\right) = \left( -\frac{\partial^2\,u_{x}}{\partial y ^ 2} - \frac{\partial^2\,u_{x}}{\partial z ^ 2} + \frac{\partial^2\,u_{y}}{\partial x\partial y} + \frac{\partial^2\,u_{z}}{\partial x\partial z} \right) \mathbf{i} + \left( \frac{\partial^2\,u_{x}}{\partial x\partial y} - \frac{\partial^2\,u_{y}}{\partial x ^ 2} - \frac{\partial^2\,u_{y}}{\partial z ^ 2} + \frac{\partial^2\,u_{z}}{\partial y\partial z} \right) \mathbf{j} + \left( \frac{\partial^2\,u_{x}}{\partial x\partial z} + \frac{\partial^2\,u_{y}}{\partial y\partial z} - \frac{\partial^2\,u_{z}}{\partial x ^ 2} - \frac{\partial^2\,u_{z}}{\partial y ^ 2} \right) \mathbf{k}

grad(div(u)).display()

grad(div(u))=(2uxx2+2uyxy+2uzxz)i+(2uxxy+2uyy2+2uzyz)j+(2uxxz+2uyyz+2uzz2)k\displaystyle \mathrm{grad}\left(\mathrm{div}\left(u\right)\right) = \left( \frac{\partial^2\,u_{x}}{\partial x ^ 2} + \frac{\partial^2\,u_{y}}{\partial x\partial y} + \frac{\partial^2\,u_{z}}{\partial x\partial z} \right) \mathbf{i} + \left( \frac{\partial^2\,u_{x}}{\partial x\partial y} + \frac{\partial^2\,u_{y}}{\partial y ^ 2} + \frac{\partial^2\,u_{z}}{\partial y\partial z} \right) \mathbf{j} + \left( \frac{\partial^2\,u_{x}}{\partial x\partial z} + \frac{\partial^2\,u_{y}}{\partial y\partial z} + \frac{\partial^2\,u_{z}}{\partial z ^ 2} \right) \mathbf{k}

# another identity curl(curl(u)) == grad(div(u)) - laplacian(u)

True\displaystyle \mathrm{True}