Ask Your Question

Differential forms on non-standard spherical coordinates

asked 2021-04-28 02:16:17 +0200

ripple_carry gravatar image

updated 2021-04-28 02:25:01 +0200

I'd like to compute an exterior derivative in spherical coordinates. So far I have the following:

E.<x,y,z> = EuclideanSpace(3)
Ec.<r,theta,phi> = E.spherical_coordinates()

EcM = Ec.manifold()


F = function('F')
F_1 = function('F_r')(r, theta, phi)
F_2 = function('F_theta')(r, theta, phi)
F_3 = function('F_phi')(r, theta, phi)

psi = EcM.diff_form(2, 'psi')

psi[2, 3] = F_1
psi[1, 3] = -F_2
psi[1, 2] = F_3


res = psi.exterior_derivative()

which works for the spherical coordinate transformation that is the default for Euclidean space. But, I see that Sagemath has a different spherical coordinate map than I do:

> print(E.coord_change(E.spherical_coordinates(), E.cartesian_coordinates()).display())
x = r*cos(phi)*sin(theta)
y = r*sin(phi)*sin(theta)
z = r*cos(theta)

Instead, I'd like:

x = r * cos(theta) * cos(phi)
y = r * sin(theta) * cos(phi)
z = r * sin(phi)

How can I supply a different change of coordinates function for this case?

edit retag flag offensive close merge delete


You probably mean

x = r * cos(theta) * cos(phi)
y = r * sin(theta) * cos(phi)
z = r * sin(phi)

in which case the change of coordinates from Sage's spherical coordinates to yours is "(theta, phi) = (phi, pi/2 - theta)".

slelievre gravatar imageslelievre ( 2021-04-28 02:24:20 +0200 )edit

Yes, I do -- thanks! How do I get a Manifold that has the right coordinate system attached?

ripple_carry gravatar imageripple_carry ( 2021-04-28 02:26:55 +0200 )edit

See @eric_g's answer below.

Having Sage provide various flavours of spherical coordinates is now tracked at:

slelievre gravatar imageslelievre ( 2021-04-28 13:46:58 +0200 )edit

1 Answer

Sort by ┬╗ oldest newest most voted

answered 2021-04-28 10:50:49 +0200

eric_g gravatar image

updated 2021-04-29 00:12:46 +0200

Simply use the method chart to define your own version of spherical coordinates and then relate them to Sage's default spherical coordinates via the method transition_map:

sage: E.<x,y,z> = EuclideanSpace()                                                                  
sage: Ec.<r,theta,phi> = E.chart(r"r:(0,+oo) theta:(0,2*pi):periodic:\theta phi:(-pi/2,pi/2):\phi") 
sage: Ec.coord_range()                                                                              
r: (0, +oo); theta: [0, 2*pi] (periodic); phi: (-1/2*pi, 1/2*pi)
sage: Ec0.<r,theta0,phi0> = E.spherical_coordinates()       # the default spherical coordinates                                        
sage: Ec0_to_Ec = Ec0.transition_map(Ec, (r, phi0, pi/2 - theta0))                                  
sage: Ec0_to_Ec.display()                                                                           
r = r
theta = phi0
phi = 1/2*pi - theta0
sage: Ec0_to_Ec.inverse().display()                                                                 
r = r
theta0 = 1/2*pi - phi
phi0 = theta
sage: E.set_default_chart(Ec)                                                                       
sage: E.set_default_frame(Ec.frame())

Then you can relate your spherical coordinates to the Cartesian ones as follows:

sage: Ec_to_cart = E.coord_change(Ec0, E.cartesian_coordinates()) * Ec0_to_Ec.inverse()             
sage: Ec_to_cart.display()                                                                          
x = r*cos(phi)*cos(theta)
y = r*cos(phi)*sin(theta)
z = r*sin(phi)

See E.chart? and Ec0.transition_map? for more details.


Another option is not to use Sage's standard spherical coordinates, but link your spherical coordinates directly to the Cartesian ones via transition_map:

sage: E.<x,y,z> = EuclideanSpace()                                                                  
sage: Ec.<r,theta,phi> = E.chart(r"r:(0,+oo) theta:(0,2*pi):periodic:\theta phi:(-pi/2,pi/2):\phi") 
sage: E.set_default_chart(Ec)                                                                                          
sage: E.set_default_frame(Ec.frame())                                                                                  
sage: cart = E.cartesian_coordinates()                                                              
sage: Ec_to_cart = Ec.transition_map(cart, (r*cos(theta)*cos(phi), r*sin(theta)*cos(phi), r*sin(phi)))                 
sage: Ec_to_cart.display()                                                                                             
x = r*cos(phi)*cos(theta)
y = r*cos(phi)*sin(theta)
z = r*sin(phi)

To complete the relation to Cartesian coordinates, you have to provide the inverse transition map (it is too involved for Sage to compute it automatically via the method inverse()). This is done by means of set_inverse:

sage: Ec_to_cart.set_inverse(sqrt(x^2 + y^2 + z^2), atan2(y, x), atan(z/sqrt(x^2 + y^2)))                              
Check of the inverse coordinate transformation:
  r == r  *passed*
  theta == arctan2(r*cos(phi)*sin(theta), r*cos(phi)*cos(theta))  **failed**
  phi == arctan(sin(phi)/cos(phi))  **failed**
  x == x  *passed*
  y == y  *passed*
  z == z  *passed*
NB: a failed report can reflect a mere lack of simplification.

You have then:

sage: Ec_to_cart.inverse().display()                                                                                   
r = sqrt(x^2 + y^2 + z^2)
theta = arctan2(y, x)
phi = arctan(z/sqrt(x^2 + y^2))

As a check that everything goes well with your version of spherical coordinates, you can ask Sage to display the Euclidean metric:

sage: E.metric().display()                                                                                             
g = dr*dr + r^2*cos(phi)^2 dtheta*dtheta + r^2 dphi*dphi

EDIT 2: orthonormal frame associated with the customized spherical coordinates

One may introduce the orthonormal frame $(e_r, e_{\theta}, e_{\phi})$ such that $e_r = \frac{\partial}{\partial r}$, $e_\theta = \frac{1}{r\cos\phi} \frac{\partial}{\partial\theta}$, $e_\phi = \frac{1}{r}\frac{\partial}{\partial\phi}$, as follows:

sage: e1 = E.vector_field(1, 0, 0, name='e_r')                                                      
sage: e2 = E.vector_field(0, 1/(r*cos(phi)), 0, name='e_theta')                                     
sage: e3 = E.vector_field(0, 0, 1/r, name='e_phi')                                                  
sage: e = E.vector_frame('e', (e1, e2, e3))


sage: for v in e: 
....:     v.display(Ec.frame()) 
e_1 = d/dr
e_2 = 1/(r*cos(phi)) d/dtheta
e_3 = 1/r d/dphi
sage: for v in e: 
....:     v.display(cart.frame()) 
e_1 = cos(phi)*cos(theta) e_x + cos(phi)*sin(theta) e_y + sin(phi) e_z
e_2 = -sin(theta) e_x + cos(theta) e_y
e_3 = -cos(theta)*sin(phi) e_x - sin(phi)*sin(theta) e_y + cos(phi) e_z

The dual coframe is

sage: e.coframe()                                                                                   
Coframe (E^3, (e^1,e^2,e^3))
sage: for f in e.coframe(): 
....:     f.display(Ec.frame()) 
e^1 = dr
e^2 = r*cos(phi) dtheta
e^3 = r dphi

We check that e is an orthonormal frame:

sage: E.metric().display(e)                                                                         
g = e^1*e^1 + e^2*e^2 + e^3*e^3
sage: E.metric()[e,:]                                                                               
[1 0 0]
[0 1 0]
[0 0 1]

and use it as the default vector frame on the Euclidean space E:

sage: E.set_default_frame(e)
edit flag offensive delete link more


How do I make sure the differential forms are on the right space? (Apologies if my vocabulary is not correct here). When I try this ( I end up with: dpsi = (d(F_phi)/dphi + d(F_r)/dr + d(F_theta)/dtheta) dr/\dtheta/\dphi which is not correct: it's missing scaling factors of e.g. 1/(r * cos(theta))

ripple_carry gravatar imageripple_carry ( 2021-04-28 15:41:50 +0200 )edit

It looks correct to me: in the coordinate basis dr/\dtheta/\dphi there should not be any scaling factor like 1/(r*cos(theta)). Do you intend to use an orthonormal basis instead? If yes, introduce it explicitly and make it the default frame. I have edited my answer to add the construction of the orthonormal basis (cf. EDIT 2).

eric_g gravatar imageeric_g ( 2021-04-28 18:23:29 +0200 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower


Asked: 2021-04-28 02:16:17 +0200

Seen: 51 times

Last updated: Apr 29