Skip to main content

Tutorial 14

Binder Open In Colab

Interactive Notebooks

Click the badges above to run this tutorial interactively in your browser without installing anything!

  • Binder: Free cloud-based Jupyter environment
  • Colab: Google's free Jupyter notebook environment

Topics Covered​

This tutorial covers the following topics using Python and SymPy:

  • Stokes' theorem: ∮CF⋅dr=∬S(∇×F)⋅dS\displaystyle\oint_{C}\mathbf{F}\cdot d\mathbf{r}=\iint_{S}\left(\nabla\times\mathbf{F}\right)\cdot d\mathbf{S}
  • Choosing the easier side of the identity
  • Orientation: how the normal direction fixes the direction of travel around the boundary
  • Verifying both sides of the theorem
  • Surface integrals via a parametrisation

Introduction​

Stokes' theorem lets you replace a hard surface integral with an easy line integral along the boundary — or the other way round. The two sides are only equal when the orientations match: with the right-hand rule, the normal determines the positive direction of travel around CC.

import sympy as sy
from sympy.abc import x, y, z, t, u, v, r, theta
from sympy import (sqrt, sin, cos, tan, pi, ln, exp, integrate, diff, simplify,
Rational, N, Matrix, Symbol)
sy.init_printing(use_latex=True)

def curl(F):
"""Curl of a 3D field given as a list/Matrix of components."""
return Matrix([diff(F[2], y) - diff(F[1], z),
diff(F[0], z) - diff(F[2], x),
diff(F[1], x) - diff(F[0], y)])

def line_integral(F, rx, ry, rz, t, t0, t1):
"""Integral of F . dr along (x,y,z) = (rx, ry, rz) for t in [t0, t1]."""
Fx = F[0].subs({x: rx, y: ry, z: rz})
Fy = F[1].subs({x: rx, y: ry, z: rz})
Fz = F[2].subs({x: rx, y: ry, z: rz})
return integrate(Fx*diff(rx, t) + Fy*diff(ry, t) + Fz*diff(rz, t), (t, t0, t1))

Question 1​

F=⟨−y,x,z⟩\mathbf{F}=\langle-y,x,z\rangle, SS is the part of x2+y2+z2=25x^{2}+y^{2}+z^{2}=25 below z=4z=4, oriented with the outward normal. Compute ∬Scurl⁡F⋅dS\iint_{S}\operatorname{curl}\mathbf{F}\cdot d\mathbf{S}.

The boundary is the circle x2+y2=9x^{2}+y^{2}=9 in the plane z=4z=4. The natural parametrisation r(t)=⟨3cos⁡t,3sin⁡t,4⟩\mathbf{r}(t)=\langle3\cos t,3\sin t,4\rangle actually traverses −C-C, because with the outward normal the boundary must be walked clockwise.

F = Matrix([-y, x, z])
path = [3*cos(t), 3*sin(t), 4]

minus_C = line_integral(F, *path, t, 0, 2*pi)
display(minus_C) # 18*pi (this is the integral over -C)

display(-minus_C) # -18*pi (over C)

∬Scurl⁡F⋅dS=∫CF⋅dr=−18π\iint_{S}\operatorname{curl}\mathbf{F}\cdot d\mathbf{S}=\int_{C}\mathbf{F}\cdot d\mathbf{r}=-18\pi

Question 2​

F=z2i−3xy j+x3y3k\mathbf{F}=z^{2}\mathbf{i}-3xy\,\mathbf{j}+x^{3}y^{3}\mathbf{k}, SS is the part of z=5−x2−y2z=5-x^{2}-y^{2} above z=1z=1, oriented upwards.

The boundary is the circle x2+y2=4x^{2}+y^{2}=4 in the plane z=1z=1.

F = Matrix([z**2, -3*x*y, x**3*y**3])
I = line_integral(F, 2*cos(t), 2*sin(t), 1, t, 0, 2*pi)
display(simplify(I)) # 0

∬Scurl⁡F⋅dS=0\iint_{S}\operatorname{curl}\mathbf{F}\cdot d\mathbf{S}=0

Question 3​

F=z2i+y2j+xk\mathbf{F}=z^{2}\mathbf{i}+y^{2}\mathbf{j}+x\mathbf{k} and CC is the triangle with vertices (1,0,0)(1,0,0), (0,1,0)(0,1,0) and (0,0,1)(0,0,1), counterclockwise.

F = Matrix([z**2, y**2, x])
display(simplify(curl(F))) # <0, 2*z - 1, 0>

# the plane is x + y + z = 1, so z = 1 - x - y and the normal is <1, 1, 1>
integrand = simplify((curl(F).subs({z: 1 - x - y})).dot(Matrix([1, 1, 1])))
display(integrand) # 1 - 2*x - 2*y

I = integrate(integrand, (y, 0, 1 - x), (x, 0, 1))
display(I) # -1/6

∫CF⋅dr=−16\int_{C}\mathbf{F}\cdot d\mathbf{r}=-\frac{1}{6}

Question 4​

Verify Stokes' theorem for F=⟨x2,2x,z2⟩\mathbf{F}=\left\langle x^{2},2x,z^{2}\right\rangle on the ellipse S={4x2+y2≤4, z=0}S=\{4x^{2}+y^{2}\le4,\ z=0\}.

F = Matrix([x**2, 2*x, z**2])
path = [cos(t), 2*sin(t), 0] # counterclockwise ellipse, normal upwards

lhs = line_integral(F, *path, t, 0, 2*pi)
display(simplify(lhs)) # 4*pi

display(simplify(curl(F))) # <0, 0, 2>
rhs = 2 * (pi * 1 * 2) # 2 x area of the ellipse (pi*a*b)
display(rhs) # 4*pi

display(simplify(lhs - rhs)) # 0 -> verified

Both sides equal 4π4\pi, so Stokes' theorem is verified.

Question 5​

Verify Stokes' theorem for F=⟨y2,−x,5z⟩\mathbf{F}=\left\langle y^{2},-x,5z\right\rangle on the paraboloid z=x2+y2z=x^{2}+y^{2} with boundary x2+y2=1x^{2}+y^{2}=1.

F = Matrix([y**2, -x, 5*z])
display(simplify(curl(F))) # <0, 0, -1 - 2*y>

# surface side: normal < -2x, -2y, 1 >, integrand (-1 - 2y), over the unit disc
rhs = integrate((-1 - 2*r*sin(theta))*r, (r, 0, 1), (theta, 0, 2*pi))
display(simplify(rhs)) # -pi

# line side: x = cos t, y = sin t, z = 1
lhs = line_integral(F, cos(t), sin(t), 1, t, 0, 2*pi)
display(simplify(lhs)) # -pi

display(simplify(lhs - rhs)) # 0 -> verified

Both sides equal −π-\pi.

Question 6​

F=⟨xz2,x3,cos⁡(xz)⟩\mathbf{F}=\left\langle xz^{2},x^{3},\cos(xz)\right\rangle, SS is the part of the ellipsoid x2+y2+3z2=1x^{2}+y^{2}+3z^{2}=1 below the xyxy-plane, and n^\hat{n} is the lower normal.

The boundary is the circle x2+y2=1x^{2}+y^{2}=1 in the plane z=0z=0. A lower normal induces the clockwise orientation on the boundary.

F = Matrix([x*z**2, x**3, sy.cos(x*z)])

ccw = line_integral(F, cos(t), sin(t), 0, t, 0, 2*pi) # counterclockwise
display(ccw) # 3*pi/4

display(-ccw) # -3*pi/4 (clockwise)

∬S(∇×F)⋅n^ dS=−3π4\iint_{S}\left(\nabla\times\mathbf{F}\right)\cdot\hat{n}\,dS=-\frac{3\pi}{4}

note

The counterclockwise integral is +3π4+\frac{3\pi}{4}, but the lower normal induces the clockwise orientation, so the answer is −3π4-\frac{3\pi}{4}. The downloadable solution PDF still reports +3π4+\frac{3\pi}{4}, having missed the orientation flip.

Question 7​

F=(4ex2−y)i+(16sin⁡(y2)+3x)j+(4y−2x−ez)k\mathbf{F}=\left(4e^{x^{2}}-y\right)\mathbf{i}+\left(16\sin\left(y^{2}\right)+3x\right)\mathbf{j}+\left(4y-2x-e^{z}\right)\mathbf{k}, and CC is the intersection of the cylinder x2+y2=16x^{2}+y^{2}=16 with the plane z=2x+4yz=2x+4y, counterclockwise when viewed from above.

F = Matrix([4*exp(x**2) - y, 16*sin(y**2) + 3*x, 4*y - 2*x - exp(z)])
cF = curl(F)
display(simplify(cF)) # <4, 2, 4>

# the plane z = 2x + 4y gives N dS = < -2, -4, 1 > dA
N = Matrix([-2, -4, 1])
display(simplify(cF.dot(N))) # -12

I = -12 * (pi * 4**2) # area of the disc of radius 4
display(I) # -192*pi

∫CF⋅dr=∬R(−12) dA=−12×16π=−192π\int_{C}\mathbf{F}\cdot d\mathbf{r}=\iint_{R}(-12)\,dA=-12\times16\pi=-192\pi

note

Differentiating the field literally gives curl⁡F=⟨4,2,4⟩\operatorname{curl}\mathbf{F}=\langle4,2,4\rangle, so curl⁡F⋅⟨−2,−4,1⟩=−8−8+4=−12\operatorname{curl}\mathbf{F}\cdot\langle-2,-4,1\rangle=-8-8+4=-12 and the answer is −192π-192\pi. The downloadable solution PDF instead reports the curl as ⟨−4,−2,4⟩\langle-4,-2,4\rangle, giving +20+20 and 320π320\pi.

Question 8​

F(x,y,z)=⟨xy,2z,3y⟩\mathbf{F}(x,y,z)=\langle xy,2z,3y\rangle along CC, the intersection of the cylinder x2+y2=9x^{2}+y^{2}=9 with the plane x+z=5x+z=5.

Parametrise the enclosed surface by r(u,v)=(ucos⁡v, usin⁡v, 5−ucos⁡v)\mathbf{r}(u,v)=(u\cos v,\ u\sin v,\ 5-u\cos v) with 0≤u≤30\le u\le3, 0≤v≤2π0\le v\le2\pi.

rv = Matrix([u*cos(v), u*sin(v), 5 - u*cos(v)])
cross = rv.diff(u).cross(rv.diff(v))
display(simplify(cross)) # <u, 0, u>

F = Matrix([x*y, 2*z, 3*y])
display(simplify(curl(F))) # <1, 0, -x>

integrand = simplify(curl(F).subs({x: u*cos(v), y: u*sin(v), z: 5 - u*cos(v)}).dot(cross))
display(simplify(integrand)) # u - u**2*cos(v)

I = integrate(integrand, (v, 0, 2*pi), (u, 0, 3))
display(I) # 9*pi

∫CF⋅dr=9π\int_{C}\mathbf{F}\cdot d\mathbf{r}=9\pi

note

Differentiating the field literally gives curl⁡F=⟨1,0,−x⟩\operatorname{curl}\mathbf{F}=\langle1,0,-x\rangle. The downloadable solution PDF writes ⟨1,0,x⟩\langle1,0,x\rangle, dropping the minus sign. The cos⁡v\cos v term integrates to zero over a full period, so the answer 9π9\pi is unaffected by that sign error.

Question 9​

∬(∇×F)⋅n dS\iint\left(\nabla\times\mathbf{F}\right)\cdot\mathbf{n}\,dS where F(x,y,z)=⟨yz,xz,xy⟩\mathbf{F}(x,y,z)=\langle yz,xz,xy\rangle and SS is the part of x2+y2+z2=4x^{2}+y^{2}+z^{2}=4 inside x2+y2=1x^{2}+y^{2}=1 and above the xyxy-plane.

The boundary is the circle of radius 11 at height z=3z=\sqrt{3}.

F = Matrix([y*z, x*z, x*y])
display(simplify(curl(F))) # <0, 0, 0> -> conservative field

I = line_integral(F, cos(t), sin(t), sqrt(3), t, 0, 2*pi)
display(simplify(I)) # 0

∬S(∇×F)⋅n dS=0\iint_{S}\left(\nabla\times\mathbf{F}\right)\cdot\mathbf{n}\,dS=0


Extra Learning Resources​

Key Concepts to Master​

  1. Stokes' theorem: the flux of the curl through SS equals the circulation around ∂S\partial S
  2. The surface is your choice: any surface with the same boundary gives the same flux
  3. Orientation and the right-hand rule: with the normal up, the boundary is traversed counterclockwise
  4. Lower normal, clockwise boundary: reversing the normal reverses the direction of travel and flips the sign
  5. A zero curl means a conservative field, so the circulation around any closed loop is zero

SymPy Resources​

  • SymPy cross — for ru×rv\mathbf{r}_{u}\times\mathbf{r}_{v}
  • SymPy subs — substituting the surface or the parametrisation
  • SymPy integrate — the resulting single or double integral

Common Pitfalls​

  • Sign of the curl: differentiate each component literally; a dropped minus sign changes the answer (Q7)
  • Orientation: always check whether the given normal induces a clockwise or counterclockwise boundary
  • A surface integral over a disc is often just a constant times the area — recognise it before integrating
  • If curl⁡F=0\operatorname{curl}\mathbf{F}=\mathbf{0} the answer is 00 without any integration