# Electromagnetism¶

Running Sage Math and sagemanifolds with jupyter notebooks tip: First, I've found that compiling from the github source the development Sage Math version (see my notes on this under the "Computers" section of my wordpress blog) works with sagemanifolds and either installing sagemanifolds into the binary that you unpack out (the click, download, double click), "breaks" Sage and so that it doesn't run. Also, following the Sage Math instructions on their website for building from the source didn't work for me (!!!???).

As a tip on how to run this jupyter notebook and have sagemanifolds available, you'd want to be in the working directory you desire (e.g. Propulsion/EM). But yet your Sage Math build is somewhere else (e.g. /home/topolo/Public/sage). Do this out of the working directory you're currently working out of: /home/topolo/Public/sage/sage -n jupyter

For the rationale, or the math, and how the math corresponds directly to the Sage Math code here, you're going to want to look at Gravity_Notes_grande.pdf in my Gravite repository, and in there, the $\mathbb{R}^3$ section, because I define the charts and atlases for Euclidean space $\mathbb{R}^3$ as a smooth manifold.

In [1]:
%display latex

In [2]:
M = Manifold(4,'M',r'M')
cart_ch = M.chart('t x y z')
U = M.open_subset('U',coord_def={cart_ch: (cart_ch[1]<0, cart_ch[2]!=0)})
cart_ch_U = cart_ch.restrict(U)
sph_ch = U.chart(r't:(-oo,oo):t rh:(0,+oo):\rho th:(0,pi):\theta ph:(0,2*pi):\phi')
t, rh,th,ph = [sph_ch[i[0]] for i in M.index_generator(1)]
transit_sph_to_cart = sph_ch.transition_map(cart_ch_U,
[t,rh*sin(th)*cos(ph),rh*sin(th)*sin(ph),rh*cos(th)])
Sphnorm = sqrt(sum([cart_ch_U[i]**2 for i in range(1,4)]))
transit_sph_to_cart.set_inverse( cart_ch[0], Sphnorm,
atan2(sqrt( sum([ cart_ch_U[i]**2 for i in range(1,3)])),cart_ch_U[3]),
atan2(cart_ch_U[2],cart_ch_U[1]))
cyl_ch = U.chart(r't:(-oo,oo):t r:(0,+oo) phi:(0,2*pi):\phi z:(-oo,oo):z')
t, r,phi,z = [cyl_ch[i[0]] for i in M.index_generator(1)]
transit_cyl_to_cart = cyl_ch.transition_map(cart_ch_U, [t,r*cos(phi),r*sin(phi),z])
transit_cyl_to_cart.set_inverse(cart_ch_U[0], sqrt(cart_ch_U[1]**2+cart_ch_U[2]**2),
atan2( cart_ch_U[2],cart_ch_U[1]), cart_ch_U[3])


Note the mostly positive (-+++) convention I use for the Minkowski metric.

In [3]:
g = M.lorentzian_metric('g')
g[0,0] = -1
for i in range(1,4): g[i,i] = 1


### Electric Field¶

In [4]:
def make_E(ch):
"""
make_E = make_E(ch)
make_E creates a time-INDEPENDENT electric field as a 1-form

INPUT/PARAMETER
ch = sagemanifold chart
"""
Ecomplst = []
for i in range(1,4):
Earglst = ['E'+str(i),] + list(ch[1:])
Ecomplst.append( function(Earglst[0])(*Earglst[1:]) )
Ecomplst = [0,]+Ecomplst
E = ch.domain().diff_form(1)
E[ch.frame(),:,ch] = Ecomplst
return E

def make_Et(ch):
"""
make_Et = make_Et(ch)
make_Et creates a time-DEPENDENT electric field as a 1-form

INPUT/PARAMETER
ch = sagemanifold chart
"""
Ecomplst = []
for i in range(1,4):
Earglst = ['E'+str(i),] + list(ch[:])
Ecomplst.append( function(Earglst[0])(*Earglst[1:]) )
Ecomplst = [0,]+Ecomplst
E = ch.domain().diff_form(1)
E[ch.frame(),:,ch] = Ecomplst
return E


Examples of using make_E, make_Et and displaying the results

In [5]:
print make_E(cart_ch).display()
make_Et(sph_ch).display(sph_ch.frame(),sph_ch)

E1(x, y, z) dx + E2(x, y, z) dy + E3(x, y, z) dz

Out[5]:

### Magnetic Field¶

Programming note: make_B and make_Bt

In [6]:
def make_B(ch):
"""
make_B = make_B(ch)
make_B creates a time-INDEPENDENT magnetic field as a 2-form

INPUT/PARAMETER
ch = sagemanifold chart
"""
B = ch.domain().diff_form(2)
farglst = list(ch[1:]) # function argument list, e.g. (x,y,z)

B[ch.frame(),1,2,ch] = function('B_12')(*farglst)
B[ch.frame(),2,3,ch] = function('B_23')(*farglst)
B[ch.frame(),3,1,ch] = function('B_31')(*farglst)

return B

def make_Bt(ch):
"""
make_Bt = make_Bt(ch)
make_Bt creates a time-DEPENDENT electric field as a 2-form

INPUT/PARAMETER
ch = sagemanifold chart
"""
B = ch.domain().diff_form(2)
farglst = list(ch[:]) # function argument list, e.g. (x,y,z)

B[ch.frame(),1,2,ch] = function('B_12')(*farglst)
B[ch.frame(),2,3,ch] = function('B_23')(*farglst)
B[ch.frame(),3,1,ch] = function('B_31')(*farglst)

return B

In [7]:
print make_Bt(cart_ch).display()
make_B(cyl_ch).display(cyl_ch.frame(),cyl_ch)

B_12(t, x, y, z) dx/\dy - B_31(t, x, y, z) dx/\dz + B_23(t, x, y, z) dy/\dz

Out[7]:

Notice that the orientation is correct (with the right hand rule).

## Electromagnetic field 2-form¶

In [8]:
EM_F = make_Bt(cart_ch) + make_Et(cart_ch).wedge(cart_ch.coframe()[0] )
EM_F.display()

Out[8]:
In [9]:
EM_F[:]

Out[9]:
In [10]:
EM_F.exterior_der()[:]

Out[10]:

And so
$dF = \left[\left[\left[0, 0, 0, 0\right], \left[0, 0, \frac{\partial\,B_{12}}{\partial {t}} - \frac{\partial\,E_{1}}{\partial y} + \frac{\partial\,E_{2}}{\partial x}, -\frac{\partial\,B_{31}}{\partial {t}} - \frac{\partial\,E_{1}}{\partial z} + \frac{\partial\,E_{3}}{\partial x}\right], \left[0, -\frac{\partial\,B_{12}}{\partial {t}} + \frac{\partial\,E_{1}}{\partial y} - \frac{\partial\,E_{2}}{\partial x}, 0, \frac{\partial\,B_{23}}{\partial {t}} - \frac{\partial\,E_{2}}{\partial z} + \frac{\partial\,E_{3}}{\partial y}\right], \left[0, \frac{\partial\,B_{31}}{\partial {t}} + \frac{\partial\,E_{1}}{\partial z} - \frac{\partial\,E_{3}}{\partial x}, -\frac{\partial\,B_{23}}{\partial {t}} + \frac{\partial\,E_{2}}{\partial z} - \frac{\partial\,E_{3}}{\partial y}, 0\right]\right], \left[\left[0, 0, -\frac{\partial\,B_{12}}{\partial {t}} + \frac{\partial\,E_{1}}{\partial y} - \frac{\partial\,E_{2}}{\partial x}, \frac{\partial\,B_{31}}{\partial {t}} + \frac{\partial\,E_{1}}{\partial z} - \frac{\partial\,E_{3}}{\partial x}\right], \left[0, 0, 0, 0\right], \left[\frac{\partial\,B_{12}}{\partial {t}} - \frac{\partial\,E_{1}}{\partial y} + \frac{\partial\,E_{2}}{\partial x}, 0, 0, \frac{\partial\,B_{12}}{\partial z} + \frac{\partial\,B_{23}}{\partial x} + \frac{\partial\,B_{31}}{\partial y}\right], \left[-\frac{\partial\,B_{31}}{\partial {t}} - \frac{\partial\,E_{1}}{\partial z} + \frac{\partial\,E_{3}}{\partial x}, 0, -\frac{\partial\,B_{12}}{\partial z} - \frac{\partial\,B_{23}}{\partial x} - \frac{\partial\,B_{31}}{\partial y}, 0\right]\right], \left[\left[0, \frac{\partial\,B_{12}}{\partial {t}} - \frac{\partial\,E_{1}}{\partial y} + \frac{\partial\,E_{2}}{\partial x}, 0, -\frac{\partial\,B_{23}}{\partial {t}} + \frac{\partial\,E_{2}}{\partial z} - \frac{\partial\,E_{3}}{\partial y}\right], \left[-\frac{\partial\,B_{12}}{\partial {t}} + \frac{\partial\,E_{1}}{\partial y} - \frac{\partial\,E_{2}}{\partial x}, 0, 0, -\frac{\partial\,B_{12}}{\partial z} - \frac{\partial\,B_{23}}{\partial x} - \frac{\partial\,B_{31}}{\partial y}\right], \left[0, 0, 0, 0\right], \left[\frac{\partial\,B_{23}}{\partial {t}} - \frac{\partial\,E_{2}}{\partial z} + \frac{\partial\,E_{3}}{\partial y}, \frac{\partial\,B_{12}}{\partial z} + \frac{\partial\,B_{23}}{\partial x} + \frac{\partial\,B_{31}}{\partial y}, 0, 0\right]\right], \left[\left[0, -\frac{\partial\,B_{31}}{\partial {t}} - \frac{\partial\,E_{1}}{\partial z} + \frac{\partial\,E_{3}}{\partial x}, \frac{\partial\,B_{23}}{\partial {t}} - \frac{\partial\,E_{2}}{\partial z} + \frac{\partial\,E_{3}}{\partial y}, 0\right], \left[\frac{\partial\,B_{31}}{\partial {t}} + \frac{\partial\,E_{1}}{\partial z} - \frac{\partial\,E_{3}}{\partial x}, 0, \frac{\partial\,B_{12}}{\partial z} + \frac{\partial\,B_{23}}{\partial x} + \frac{\partial\,B_{31}}{\partial y}, 0\right], \left[-\frac{\partial\,B_{23}}{\partial {t}} + \frac{\partial\,E_{2}}{\partial z} - \frac{\partial\,E_{3}}{\partial y}, -\frac{\partial\,B_{12}}{\partial z} - \frac{\partial\,B_{23}}{\partial x} - \frac{\partial\,B_{31}}{\partial y}, 0, 0\right], \left[0, 0, 0, 0\right]\right]\right] = 0$

In [11]:
EM_F.hodge_dual(g)[:]

Out[11]:

As a reminder, the Minkowski metric is a Lorentzian metric (not a Riemannian metric, which, in sagemanifolds, translates into using the lorentzian_metric module/function, not the riemannian_metric module/function) and is given by $g$:

In [12]:
g[:]

Out[12]:

$d*F$ (for $d*F = 4 \pi * J$)

In [13]:
EM_F.hodge_dual(g).exterior_der()[:]

Out[13]:

As a reminder, if you wanted the LaTeX code, use the latex function in Sage Math like such:

In [78]:
latex( EM_F.hodge_dual(g).exterior_der()[:] ); # delete the semi-colon ; and you can get the LaTeX code-I suppress it


And so
$d*F = \left[\left[\left[0, 0, 0, 0\right], \left[0, 0, i \, \frac{\partial\,B_{23}}{\partial y} - i \, \frac{\partial\,B_{31}}{\partial x} + i \, \frac{\partial\,E_{3}}{\partial {t}}, -i \, \frac{\partial\,B_{12}}{\partial x} + i \, \frac{\partial\,B_{23}}{\partial z} - i \, \frac{\partial\,E_{2}}{\partial {t}}\right], \left[0, -i \, \frac{\partial\,B_{23}}{\partial y} + i \, \frac{\partial\,B_{31}}{\partial x} - i \, \frac{\partial\,E_{3}}{\partial {t}}, 0, -i \, \frac{\partial\,B_{12}}{\partial y} + i \, \frac{\partial\,B_{31}}{\partial z} + i \, \frac{\partial\,E_{1}}{\partial {t}}\right], \left[0, i \, \frac{\partial\,B_{12}}{\partial x} - i \, \frac{\partial\,B_{23}}{\partial z} + i \, \frac{\partial\,E_{2}}{\partial {t}}, i \, \frac{\partial\,B_{12}}{\partial y} - i \, \frac{\partial\,B_{31}}{\partial z} - i \, \frac{\partial\,E_{1}}{\partial {t}}, 0\right]\right], \left[\left[0, 0, -i \, \frac{\partial\,B_{23}}{\partial y} + i \, \frac{\partial\,B_{31}}{\partial x} - i \, \frac{\partial\,E_{3}}{\partial {t}}, i \, \frac{\partial\,B_{12}}{\partial x} - i \, \frac{\partial\,B_{23}}{\partial z} + i \, \frac{\partial\,E_{2}}{\partial {t}}\right], \left[0, 0, 0, 0\right], \left[i \, \frac{\partial\,B_{23}}{\partial y} - i \, \frac{\partial\,B_{31}}{\partial x} + i \, \frac{\partial\,E_{3}}{\partial {t}}, 0, 0, i \, \frac{\partial\,E_{1}}{\partial x} + i \, \frac{\partial\,E_{2}}{\partial y} + i \, \frac{\partial\,E_{3}}{\partial z}\right], \left[-i \, \frac{\partial\,B_{12}}{\partial x} + i \, \frac{\partial\,B_{23}}{\partial z} - i \, \frac{\partial\,E_{2}}{\partial {t}}, 0, -i \, \frac{\partial\,E_{1}}{\partial x} - i \, \frac{\partial\,E_{2}}{\partial y} - i \, \frac{\partial\,E_{3}}{\partial z}, 0\right]\right], \left[\left[0, i \, \frac{\partial\,B_{23}}{\partial y} - i \, \frac{\partial\,B_{31}}{\partial x} + i \, \frac{\partial\,E_{3}}{\partial {t}}, 0, i \, \frac{\partial\,B_{12}}{\partial y} - i \, \frac{\partial\,B_{31}}{\partial z} - i \, \frac{\partial\,E_{1}}{\partial {t}}\right], \left[-i \, \frac{\partial\,B_{23}}{\partial y} + i \, \frac{\partial\,B_{31}}{\partial x} - i \, \frac{\partial\,E_{3}}{\partial {t}}, 0, 0, -i \, \frac{\partial\,E_{1}}{\partial x} - i \, \frac{\partial\,E_{2}}{\partial y} - i \, \frac{\partial\,E_{3}}{\partial z}\right], \left[0, 0, 0, 0\right], \left[-i \, \frac{\partial\,B_{12}}{\partial y} + i \, \frac{\partial\,B_{31}}{\partial z} + i \, \frac{\partial\,E_{1}}{\partial {t}}, i \, \frac{\partial\,E_{1}}{\partial x} + i \, \frac{\partial\,E_{2}}{\partial y} + i \, \frac{\partial\,E_{3}}{\partial z}, 0, 0\right]\right], \left[\left[0, -i \, \frac{\partial\,B_{12}}{\partial x} + i \, \frac{\partial\,B_{23}}{\partial z} - i \, \frac{\partial\,E_{2}}{\partial {t}}, -i \, \frac{\partial\,B_{12}}{\partial y} + i \, \frac{\partial\,B_{31}}{\partial z} + i \, \frac{\partial\,E_{1}}{\partial {t}}, 0\right], \left[i \, \frac{\partial\,B_{12}}{\partial x} - i \, \frac{\partial\,B_{23}}{\partial z} + i \, \frac{\partial\,E_{2}}{\partial {t}}, 0, i \, \frac{\partial\,E_{1}}{\partial x} + i \, \frac{\partial\,E_{2}}{\partial y} + i \, \frac{\partial\,E_{3}}{\partial z}, 0\right], \left[i \, \frac{\partial\,B_{12}}{\partial y} - i \, \frac{\partial\,B_{31}}{\partial z} - i \, \frac{\partial\,E_{1}}{\partial {t}}, -i \, \frac{\partial\,E_{1}}{\partial x} - i \, \frac{\partial\,E_{2}}{\partial y} - i \, \frac{\partial\,E_{3}}{\partial z}, 0, 0\right], \left[0, 0, 0, 0\right]\right]\right]$

In [14]:
EM_F.hodge_dual(g).exterior_der().hodge_dual(g)[:]

Out[14]:
In [81]:
latex(EM_F.hodge_dual(g).exterior_der().hodge_dual(g)[:]);
# delete the semi-colon ; and you can get the LaTeX code-I suppress it

Out[81]:
\left[\frac{\partial\,E_{1}}{\partial x} + \frac{\partial\,E_{2}}{\partial y} + \frac{\partial\,E_{3}}{\partial z}, -\frac{\partial\,B_{12}}{\partial y} + \frac{\partial\,B_{31}}{\partial z} + \frac{\partial\,E_{1}}{\partial {t}}, \frac{\partial\,B_{12}}{\partial x} - \frac{\partial\,B_{23}}{\partial z} + \frac{\partial\,E_{2}}{\partial {t}}, \frac{\partial\,B_{23}}{\partial y} - \frac{\partial\,B_{31}}{\partial x} + \frac{\partial\,E_{3}}{\partial {t}}\right]

And so
$*d*F = \left[\frac{\partial\,E_{1}}{\partial x} + \frac{\partial\,E_{2}}{\partial y} + \frac{\partial\,E_{3}}{\partial z}, -\frac{\partial\,B_{12}}{\partial y} + \frac{\partial\,B_{31}}{\partial z} + \frac{\partial\,E_{1}}{\partial {t}}, \frac{\partial\,B_{12}}{\partial x} - \frac{\partial\,B_{23}}{\partial z} + \frac{\partial\,E_{2}}{\partial {t}}, \frac{\partial\,B_{23}}{\partial y} - \frac{\partial\,B_{31}}{\partial x} + \frac{\partial\,E_{3}}{\partial {t}}\right]$

## Current 1-form, Current conservation, and the other side (Right-Hand Side (RHS)) of $d*F$¶

In [15]:
def make_J(ch):
"""
make_J = make_J(ch)
make_J creates a time-INDEPENDENT current as a 1-form

INPUT/PARAMETER
ch = sagemanifold chart
"""
Jcomplst = []
for i in range(1,4):
Jarglst = ['j'+str(i),] + list(ch[1:])
Jcomplst.append( function(Jarglst[0])(*Jarglst[1:]) )
Jcomplst = [-function('rho')(*list(ch[1:])),] +Jcomplst
J = ch.domain().diff_form(1)
J[ch.frame(),:,ch] = Jcomplst
return J

def make_Jt(ch):
"""
make_Jt = make_Jt(ch)
make_Jt creates a time-DEPENDENT current as a 1-form

INPUT/PARAMETER
ch = sagemanifold chart
"""
Jcomplst = []
for i in range(1,4):
Jarglst = ['j'+str(i),] + list(ch[:])
Jcomplst.append( function(Jarglst[0])(*Jarglst[1:]) )
Jcomplst = [-function('rho')(*list(ch[:])),]+Jcomplst
J = ch.domain().diff_form(1)
J[ch.frame(),:,ch] = Jcomplst
return J


In [16]:
print make_Jt(cart_ch).display() # these are examples of displaying the 4-current as 1-form in
# Cartesian and cylindrical coordinates
make_Jt(cyl_ch).display(cyl_ch.frame(),cyl_ch)

-rho(t, x, y, z) dt + j1(t, x, y, z) dx + j2(t, x, y, z) dy + j3(t, x, y, z) dz

Out[16]:
In [17]:
make_Jt(cart_ch).hodge_dual(g).hodge_dual(g).display()

Out[17]:

So here, I had successfully shown that $*d*F = **J$ or $*d*F = 4\pi ** J$ (in cgs units), thus recovering Gauss's law and Ampere's law.

In [115]:
latex( make_Jt(cart_ch).hodge_dual(g).hodge_dual(g)[:]);
# delete the semi-colon ; and you can get the LaTeX code-I suppress it


$\boxed{ \left[\frac{\partial\,E_{1}}{\partial x} + \frac{\partial\,E_{2}}{\partial y} + \frac{\partial\,E_{3}}{\partial z}, -\frac{\partial\,B_{12}}{\partial y} + \frac{\partial\,B_{31}}{\partial z} + \frac{\partial\,E_{1}}{\partial {t}}, \frac{\partial\,B_{12}}{\partial x} - \frac{\partial\,B_{23}}{\partial z} + \frac{\partial\,E_{2}}{\partial {t}}, \frac{\partial\,B_{23}}{\partial y} - \frac{\partial\,B_{31}}{\partial x} + \frac{\partial\,E_{3}}{\partial {t}}\right] = \left[\rho\left({t}, x, y, z\right), -j_{1}\left({t}, x, y, z\right), -j_{2}\left({t}, x, y, z\right), -j_{3}\left({t}, x, y, z\right)\right] }$

Current conservation is easily calculated, $*d*J=0$:

In [18]:
make_Jt(cart_ch).hodge_dual(g).exterior_der().hodge_dual(g).display(cart_ch)

Out[18]:

## Lorentz Force¶

In [19]:
def make_beta(ch):
"""
make_beta = make_beta(ch)
make_beta creates a time-INDEPENDENT velocity field

INPUT/PARAMETER
ch = sagemanifold chart
"""
betacomplst = []
for i in range(1,4):
betaarglst = ['beta'+str(i),] + list(ch[1:])
betacomplst.append( function(betaarglst[0])(*betaarglst[1:]) )
betacomplst = [1,]+betacomplst
beta = ch.domain().vector_field()
beta[ch.frame(),:,ch] = betacomplst
return beta

def make_betat(ch):
"""
make_betat = make_betat(ch)
make_betat creates a time-DEPENDENT velocity field

INPUT/PARAMETER
ch = sagemanifold chart
"""
betacomplst = []
for i in range(1,4):
betaarglst = ['beta'+str(i),] + list(ch[:])
betacomplst.append( function(betaarglst[0])(*betaarglst[1:]) )
betacomplst = [1,]+betacomplst
beta = ch.domain().vector_field()
beta[ch.frame(),:,ch] = betacomplst
return beta

In [20]:
make_beta(cart_ch).display()

Out[20]:

For interior products, you're going to have to dig into how sagemanifolds implements Tensor products, tensor contractions, and the use of index notation, as sagemanifolds doesn't have a "stand-alone" interior product function. From my EuclideanManifold.py implementation in sagemanifolds, look at my curl function (def curl) as a template for implementing interior products.

In [21]:
betaeg = make_betat(cart_ch)
Beg = make_Bt(cart_ch)
(betaeg['^i']*Beg['_ij']).display()

Out[21]:

So we now have a prescription on how to implement both the interior product and the curl of 2 "vectors" -
if you want this:

$-i_{\mathbf{\beta}} B$ which is the differential form version of $\mathbf{\beta} \times B$ (curl), then do this in sagemanifolds:

-betaeg['^i']*Beg['_ij']

In [22]:
q = var('q',domain="real") # define a single charge variable in Sage Math

In [23]:
LorentzForce1form =  make_Et(cart_ch) - make_beta(cart_ch)['^i']*make_Bt(cart_ch)['_ij']


You can multiply this differential 1-form with Sage Math variables.

In [24]:
LorentzForce1form = q * LorentzForce1form


The 1-form version of the Lorentz Force $F$ is given by the following, and keep in mind that we integrate 1-forms, we don't integrate vectors (because it goes back to how we transport vectors along a curve, and 1-forms either abscond, circumvent, this problem or is the most natural way to do integration on manifolds):

In [25]:
LorentzForce1form.display()

Out[25]:

And so
$f = \left( q B_{12}\left({t}, x, y, z\right) \beta_{2}\left(x, y, z\right) - q B_{31}\left({t}, x, y, z\right) \beta_{3}\left(x, y, z\right) + q E_{1}\left({t}, x, y, z\right) \right) \mathrm{d} x + \left( -q B_{12}\left({t}, x, y, z\right) \beta_{1}\left(x, y, z\right) + q B_{23}\left({t}, x, y, z\right) \beta_{3}\left(x, y, z\right) + q E_{2}\left({t}, x, y, z\right) \right) \mathrm{d} y + \left( q B_{31}\left({t}, x, y, z\right) \beta_{1}\left(x, y, z\right) - q B_{23}\left({t}, x, y, z\right) \beta_{2}\left(x, y, z\right) + q E_{3}\left({t}, x, y, z\right) \right) \mathrm{d} z$

## More "combinations": $F \wedge *F$¶

$F \wedge * F$

In [26]:
FwedgestarF = EM_F.wedge(EM_F.hodge_dual(g))

In [27]:
FwedgestarF.display()

Out[27]:

$E\cdot B$

In [28]:
Eteg = make_Et(cart_ch)
Bteg = make_Bt(cart_ch)
EdotB = Eteg.wedge( Bteg)
EdotB.display()

Out[28]:

### Poynting Vector¶

Try $E \wedge *B$

In [29]:
(Eteg.wedge( Bteg.hodge_dual(g))).display()

Out[29]: