Calculate curl of a vector field in Python and plot it with matplotlib

To calculate the curl of a vector function you can also use numdifftools for automatic numerical differentiation without a detour through symbolic differentiation. Numdifftools doesn't provide a curl() function, but it does compute the Jacobian matrix of a vector valued function of one or more variables, and this provides the derivatives of all components of a vector field with respect to all of the variables; this is all that's necessary for the calculation of the curl.

import import scipy as sp
import numdifftools as nd

def h(x):
    return sp.array([3*x[0]**2,4*x[1]*x[2]**3, 2*x[0]])

def curl(f,x):
    jac = nd.Jacobian(f)(x)
    return sp.array([jac[2,1]-jac[1,2],jac[0,2]-jac[2,0],jac[1,0]-jac[0,1]])

x = sp.array([1,2,3)]
curl(h,x)

This returns the value of the curl at x: array([-216., -2., 0.]) Plotting is as suggested above.


You can use sympy.curl() to calculate the curl of a vector field.

Example:

Suppose F(x,y,z) = y2zi - xyj + z2k, then:

  • y would be R[1], x is R[0] and z is R[2]
  • the unit vectors i, j, k of the 3 axes, would be respectively R.x, R.y, R.z.

The code to calculate the vector field curl is:

from sympy.physics.vector import ReferenceFrame
from sympy.physics.vector import curl
R = ReferenceFrame('R')

F = R[1]**2 * R[2] * R.x - R[0]*R[1] * R.y + R[2]**2 * R.z

G = curl(F, R)  

In that case G would be equal to R_y**2*R.y + (-2*R_y*R_z - R_y)*R.z or, in other words,
G = 0i + y2j + (-2yz-y)k.

To plot it you need to convert the above result into 3 separate functions; u,v,w.

(example below adapted from this matplotlib example):

from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.gca(projection='3d')

x, y, z = np.meshgrid(np.arange(-0.8, 1, 0.2),
                      np.arange(-0.8, 1, 0.2),
                      np.arange(-0.8, 1, 0.8))

u = 0
v = y**2
w = -2*y*z - y

ax.quiver(x, y, z, u, v, w, length=0.1)

plt.show()

And the final result is this:

enter image description here