En coordonnées cartésienne, le rotationnel prend la forme suivante:

$$ \nabla \times {\bf A} = \left| \begin{array}{ccc} \hat{\bf x} & \hat{\bf y} & \hat{\bf z}\\ \frac{\partial}{\partial x} & \frac{\partial}{\partial y} & \frac{\partial}{\partial z} \\ A_x & A_y & A_z \\ \end{array} \right| = \left(\frac{\partial A_z}{\partial y} - \frac{\partial A_y}{\partial z}\right)\hat{\mathbf x} - \left(\frac{\partial A_z}{\partial x} - \frac{\partial A_x}{\partial z}\right)\hat{\mathbf y} + \left(\frac{\partial A_y}{\partial x} - \frac{\partial A_x}{\partial y}\right)\hat{\mathbf z} $$

Pour un champ $\mathbf A$ uniquement dans le plan $x-y$, $A_z = 0$ et $A_x$ et $A_y$ ne dépendent pas de $z$ le rotationnel est donc simplement:

$$ \nabla \times {\bf A} = \left(\frac{\partial A_y}{\partial x} - \frac{\partial A_x}{\partial y}\right)\hat{\mathbf z} $$

In [1]:
%pylab inline
import numpy as np

pas = 0.01

# Le monde:
Y, X = np.mgrid[-3:3:pas, -3:3:pas]

def rotationnel_z(x, y,pas):
    """ Retourne la composante 'z' du rotationnel
    
    Note:
     - Dérivé par la méthode des différences finies. Peu d'erreur numérique si le pas est petit
       (http://en.wikipedia.org/wiki/Finite_difference_method)
     - La grille du 'monde' doit avoir un espacement (pas) uniforme en x et en y
     - l'axe 0 est 'y' et l'axe 1 est 'x', car le monde est définis par Y, X = mgrid()
       (l'inversion est nécessaire pour utiliser 'streamplot'
    """
    # l'opération de différence retourne un array de dimension plus courte vers 'axis'
    xp = np.diff(x,axis=0)/pas
    xp = xp[:,1:] # on tronque d'un élément pour conserver les matrices de même dimension
    yp = np.diff(y,axis=1)/pas
    yp = yp[1:,:] # on tronque d'un élément pour conserver les matrices de même dimension
    #print xp, yp
    #print xp.shape, yp.shape
    return  xp-yp


Populating the interactive namespace from numpy and matplotlib

Définissons un champ $\mathbf A$ très simple pour fins d'illustrations:

$$ \mathbf A = y \hat{\mathbf x} -x \hat{\mathbf y} $$

On superpose le champ vectoriel (flèches) et la valeur du rotationnel en $\hat{\mathbf z}$ (carte de couleur)


In [174]:
Ax = Y
Ay = -X
R = rotationnel_z(Ax,Ay,pas)

# figure
f,ax = subplots()
p = ax.pcolor(X[1:,1:],Y[1:,1:],R,cmap=cm.RdBu,vmin=0, vmax=3)
cb = f.colorbar(p,ax=ax)
sp = ax.streamplot(X,Y,Ax,Ay)


Définissons maintenant un champ $A$ un peu plus complexe:

$$ \mathbf A = \left(\sin^2(x) + y\right)\hat{\mathbf x} + \left(\cos\left(x+y^2\right)\right)\hat{\mathbf y} $$

et refaisons les mêmes figures:


In [175]:
Ax = np.sin(X)**2+Y
Ay = np.cos(X+Y**2)
R = rotationnel_z(Ax,Ay,pas)
# figure
f,ax = subplots()
p = ax.pcolor(X[1:,1:],Y[1:,1:],R,cmap=cm.RdBu,vmin=0, vmax=3)
cb = f.colorbar(p,ax=ax)
sp = ax.streamplot(X,Y,Ax,Ay,density = 1.5)


Une façon simple de visualiser la valeur du rotationnel est d'imaginer une petite sphère à un point donné du champ vectoriel et de voir les lignes de champs comme un flot agissant sur cette sphère. Si l'effet du flot cause une rotation de la sphère, le rotationnel est non nul. La valeur du rotationnel au point ou est situé la sphère est donné par l'angle et la vitesse de rotation.