Shenfun supports solving equations in curvilinear coordinates (e.g., polar, cylindrical, spherical) by providing a map (position vector) between the new coordinates and Cartesian coordinates.
Important: Basis Vectors
By default, Shenfun uses non-normalized natural (covariant) basis vectors. This means the equations you write may differ from standard textbook formulations that use normalized (physical) basis vectors.
To switch between basis types, configure the basisvectors parameter in your shenfun.yaml file. Supported values are:
covariant: Non-normalized natural basis vectors (default).normal: Normalized physical basis vectors.
Automatic Operators
Once a curvilinear map is defined, Shenfun's core operators—.div, .grad, and .curl—automatically handle the coordinate transformations. You do not need to manually implement the complex coordinate-specific differential equations.
from shenfun import *
import sympy as sp
# Define symbols and the position vector (map) for cylindrical coordinates
r, theta, z = psi = sp.symbols('x,y,z', real=True, positive=True)
rv = (r*sp.cos(theta), r*sp.sin(theta), z)
N = 10
F0 = FunctionSpace(N, 'F', dtype='d')
F1 = FunctionSpace(N, 'F', dtype='D')
L = FunctionSpace(N, 'L', domain=(0, 1))
# Create the TensorProductSpace using the map 'rv'
T = TensorProductSpace(comm, (L, F1, F0), coordinates=(psi, rv))
V = VectorSpace(T)
u = TrialFunction(V)
# The vector Laplacian is implemented simply via div(grad(u))
du = div(grad(u))